···11+; vim:syntax=z8a:ts=8
22+;
33+; msTERM
44+; WiFiStation parallel port routines
55+;
66+; Copyright (c) 2019-2021 joshua stein <jcs@jcs.org>
77+;
88+; Permission to use, copy, modify, and distribute this software for any
99+; purpose with or without fee is hereby granted, provided that the above
1010+; copyright notice and this permission notice appear in all copies.
1111+;
1212+; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1313+; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1414+; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1515+; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1616+; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1717+; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1818+; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1919+;
2020+2121+ .module wifi
2222+2323+ .include "mailstation.inc"
2424+2525+ .area _CODE
2626+2727+ .equ CONTROL_DIR, #0x0a
2828+ .equ CONTROL_DIR_OUT, #0xff
2929+ .equ CONTROL_DIR_IN, #0
3030+3131+ .equ CONTROL_PORT, #0x9
3232+ .equ CONTROL_STROBE_BIT, #0
3333+ .equ CONTROL_STROBE, #(1 << CONTROL_STROBE_BIT)
3434+ .equ CONTROL_LINEFEED_BIT, #1
3535+ .equ CONTROL_LINEFEED, #(1 << CONTROL_LINEFEED_BIT)
3636+ .equ CONTROL_INIT, #(1 << 2)
3737+ .equ CONTROL_SELECT, #(1 << 3)
3838+3939+ .equ DATA_DIR, #0x2c
4040+ .equ DATA_DIR_OUT, #0xff
4141+ .equ DATA_DIR_IN, #0
4242+ .equ DATA_PORT, #0x2d
4343+4444+ .equ STATUS_PORT, #0x21
4545+ .equ STATUS_BUSY, #(1 << 7)
4646+ .equ STATUS_ACK, #(1 << 6)
4747+ .equ STATUS_PAPEROUT, #(1 << 5)
4848+4949+; void wifi_init(void);
5050+_wifi_init::
5151+ ; lower control lines
5252+ ld a, #CONTROL_DIR_OUT
5353+ out (#CONTROL_DIR), a
5454+ xor a
5555+ out (#CONTROL_PORT), a
5656+ ret
5757+5858+; at idle, lower all control lines
5959+; writer: reader:
6060+; raise strobe
6161+; see high strobe as high busy
6262+; raise linefeed
6363+; see high linefeed as high ack
6464+; write all data pins
6565+; lower strobe
6666+; see low strobe as low busy
6767+; read data
6868+; lower linefeed
6969+; see lower linefeed as high ack
7070+7171+; int wifi_write(char); -1 on error, 0 on success
7272+_wifi_write::
7373+ push ix
7474+ ld ix, #0
7575+ add ix, sp
7676+ push bc
7777+ push de
7878+ ld c, 4(ix) ; char to send
7979+ ld a, #DATA_DIR_OUT
8080+ out (#DATA_DIR), a ; we're sending out
8181+ ld a, #CONTROL_STROBE
8282+ out (#CONTROL_PORT), a ; raise strobe
8383+ ld de, #0xffff
8484+wait_for_ack:
8585+ in a, (#STATUS_PORT)
8686+ and #STATUS_ACK ; is ack high?
8787+ jr nz, got_ack ; yes, break
8888+ dec de ; no, de--
8989+ ld a, d
9090+ cp #0
9191+ jr nz, wait_for_ack
9292+ ld a, e
9393+ cp #0
9494+ jr nz, wait_for_ack
9595+ jr abort_send ; de == 0, fail
9696+got_ack:
9797+ ld a, c
9898+ out (#DATA_PORT), a ; write data
9999+ xor a
100100+ out (#CONTROL_PORT), a ; lower strobe
101101+ ld de, #0xffff
102102+wait_for_final_ack:
103103+ in a, (#STATUS_PORT)
104104+ and #STATUS_ACK ; is ack low?
105105+ jr z, got_final_ack ; yes, break
106106+ dec de ; no, de--
107107+ ld a, d
108108+ cp #0
109109+ jr nz, wait_for_final_ack
110110+ ld a, e
111111+ cp #0
112112+ jr nz, wait_for_final_ack
113113+got_final_ack:
114114+ pop de
115115+ pop bc
116116+ pop ix
117117+ ld hl, #0 ; return 0
118118+ ret
119119+abort_send:
120120+ xor a
121121+ out (#CONTROL_PORT), a ; lower strobe
122122+ pop de
123123+ pop bc
124124+ pop ix
125125+ ld hl, #-1 ; return -1
126126+ ret
127127+128128+129129+; int wifi_read(void); -1 on nothing read, >= 0 on success returning char
130130+_wifi_read::
131131+ push ix
132132+ ld ix, #0
133133+ add ix, sp
134134+ push de
135135+ ld hl, #-1 ; return -1 unless we read something
136136+ in a, (#STATUS_PORT)
137137+ and #STATUS_BUSY ; is busy high?
138138+ jr z, recv_done ; no, bail
139139+ ld a, #DATA_DIR_IN
140140+ out (#DATA_DIR), a ; we're reading in
141141+ ld a, #CONTROL_LINEFEED ; raise linefeed
142142+ out (#CONTROL_PORT), a
143143+ ld de, #0xffff
144144+wait_for_busy_ack:
145145+ in a, (#STATUS_PORT)
146146+ and #STATUS_BUSY ; is busy high?
147147+ jr z, read_data ; no, break
148148+ dec de ; no, de--
149149+ ld a, d
150150+ cp #0
151151+ jr nz, wait_for_busy_ack
152152+ ld a, e
153153+ cp #0
154154+ jr nz, wait_for_busy_ack
155155+ jr recv_done ; de == 0, fail
156156+read_data:
157157+ in a, (#DATA_PORT)
158158+ ld h, #0
159159+ ld l, a
160160+raise_lf:
161161+ xor a
162162+ out (#CONTROL_PORT), a ; lower linefeed
163163+recv_done:
164164+ pop de
165165+ pop ix
166166+ ret