Example program for the Cidco MailStation Z80 computer
at main 175 lines 4.1 kB view raw
1; vim:syntax=z8a:ts=8 2; 3; WiFiStation parallel port routines 4; Copyright (c) 2019-2021 joshua stein <jcs@jcs.org> 5; 6; Permission to use, copy, modify, and distribute this software for any 7; purpose with or without fee is hereby granted, provided that the above 8; copyright notice and this permission notice appear in all copies. 9; 10; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17; 18 19 .module wifi 20 21 .include "mailstation.inc" 22 23 .area _CODE 24 25 .equ CONTROL_DIR, #0x0a 26 .equ CONTROL_DIR_OUT, #0xff 27 .equ CONTROL_DIR_IN, #0 28 29 .equ CONTROL_PORT, #0x9 30 .equ CONTROL_STATUS_MASK, #0xf0 31 .equ CONTROL_STROBE_BIT, #0 32 .equ CONTROL_STROBE, #(1 << CONTROL_STROBE_BIT) 33 .equ CONTROL_LINEFEED_BIT, #1 34 .equ CONTROL_LINEFEED, #(1 << CONTROL_LINEFEED_BIT) 35 .equ CONTROL_INIT, #(1 << 2) 36 .equ CONTROL_SELECT, #(1 << 3) 37 38 .equ DATA_DIR, #0x2c 39 .equ DATA_DIR_OUT, #0xff 40 .equ DATA_DIR_IN, #0 41 .equ DATA_PORT, #0x2d 42 43 .equ STATUS_PORT, #0x21 44 .equ STATUS_BUSY, #(1 << 7) 45 .equ STATUS_ACK, #(1 << 6) 46 47; void wifi_init(void); 48_wifi_init:: 49 ; lower control lines 50 ld a, #CONTROL_DIR_OUT 51 out (#CONTROL_DIR), a 52 in a, (#CONTROL_PORT) 53 and #CONTROL_STATUS_MASK 54 out (#CONTROL_PORT), a 55 ret 56 57; at idle, lower all control lines 58; writer: reader: 59; raise strobe 60; see high strobe as high busy 61; raise linefeed 62; see high linefeed as high ack 63; write all data pins 64; lower strobe 65; see low strobe as low busy 66; read data 67; lower linefeed 68; see lower linefeed as high ack 69 70; int wifi_write(char); -1 on error, 0 on success 71_wifi_write:: 72 push ix 73 ld ix, #0 74 add ix, sp 75 push bc 76 push de 77 ld c, 4(ix) ; char to send 78 ld a, #DATA_DIR_OUT 79 out (#DATA_DIR), a ; we're sending out 80 in a, (#CONTROL_PORT) 81 and #CONTROL_STATUS_MASK 82 set #CONTROL_STROBE_BIT, a 83 out (#CONTROL_PORT), a ; raise strobe 84 ld de, #0xffff 85wait_for_ack: 86 in a, (#STATUS_PORT) 87 and #STATUS_ACK ; is ack high? 88 jr nz, got_ack ; yes, break 89 dec de ; no, de-- 90 ld a, d 91 cp #0 92 jr nz, wait_for_ack 93 ld a, e 94 cp #0 95 jr nz, wait_for_ack 96 jr abort_send ; de == 0, fail 97got_ack: 98 ld a, c 99 out (#DATA_PORT), a ; write data 100 xor a 101 in a, (#CONTROL_PORT) 102 and #CONTROL_STATUS_MASK 103 out (#CONTROL_PORT), a ; lower strobe 104 ld de, #0xffff 105wait_for_final_ack: 106 in a, (#STATUS_PORT) 107 and #STATUS_ACK ; is ack low? 108 jr z, got_final_ack ; yes, break 109 dec de ; no, de-- 110 ld a, d 111 cp #0 112 jr nz, wait_for_final_ack 113 ld a, e 114 cp #0 115 jr nz, wait_for_final_ack 116got_final_ack: 117 pop de 118 pop bc 119 pop ix 120 ld hl, #0 ; return 0 121 ret 122abort_send: 123 in a, (#CONTROL_PORT) 124 and #CONTROL_STATUS_MASK 125 out (#CONTROL_PORT), a ; lower strobe 126 pop de 127 pop bc 128 pop ix 129 ld hl, #-1 ; return -1 130 ret 131 132 133; int wifi_read(void); -1 on nothing read, >= 0 on success returning char 134_wifi_read:: 135 push ix 136 ld ix, #0 137 add ix, sp 138 push de 139 ld hl, #-1 ; return -1 unless we read something 140 in a, (#STATUS_PORT) 141 and #STATUS_BUSY ; is busy high? 142 jr z, recv_done ; no, bail 143 and #STATUS_ACK ; but is ack high too? probably bogus 144 jr nz, recv_done 145 ld a, #DATA_DIR_IN 146 out (#DATA_DIR), a ; we're reading in 147 in a, (#CONTROL_PORT) 148 and #CONTROL_STATUS_MASK 149 set #CONTROL_LINEFEED_BIT, a ; raise linefeed 150 out (#CONTROL_PORT), a 151 ld de, #0xffff 152wait_for_busy_ack: 153 in a, (#STATUS_PORT) 154 and #STATUS_BUSY ; is busy high? 155 jr z, read_data ; no, break 156 dec de ; no, de-- 157 ld a, d 158 cp #0 159 jr nz, wait_for_busy_ack 160 ld a, e 161 cp #0 162 jr nz, wait_for_busy_ack 163 jr recv_done ; de == 0, fail 164read_data: 165 in a, (#DATA_PORT) 166 ld h, #0 167 ld l, a 168raise_lf: 169 in a, (#CONTROL_PORT) 170 and #CONTROL_STATUS_MASK 171 out (#CONTROL_PORT), a ; lower linefeed 172recv_done: 173 pop de 174 pop ix 175 ret