Terminal program for MailStation devices
at master 239 lines 4.4 kB view raw
1; vim:syntax=z8a:ts=8 2; 3; msTERM 4; parallel port routines 5; 6; Copyright (c) 2019 joshua stein <jcs@jcs.org> 7; 8; Permission to use, copy, modify, and distribute this software for any 9; purpose with or without fee is hereby granted, provided that the above 10; copyright notice and this permission notice appear in all copies. 11; 12; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19; 20 21 .module lpt 22 23 .include "mailstation.inc" 24 25 .equ CONTROL, #0x2c 26 .equ DATA, #0x2d 27 .equ STATUS, #0x21 28 29 .equ LPT_BUSY_IN, #0x40 30 .equ LPT_BUSY_OUT, #0x08 31 .equ LPT_STROBE_IN, #0x80 32 .equ LPT_STROBE_OUT, #0x10 33 .equ LPT_TRIB_MASK, #0x07 34 .equ LPT_DIB_MASK, #0x03 35 36 .area _CODE 37 38; receive a tribble byte from host, return h=1 l=0 on error, else h=0, l=(byte) 39lptrecv_tribble: 40 push bc 41 ld hl, #0 ; h will contain error, l result 42 xor a 43 out (DATA), a ; drop busy/ack, wait for strobe 44 ld b, #0xff ; try a bunch before bailing 45wait_for_strobe: 46 in a, (STATUS) 47 and #LPT_STROBE_IN ; inb(STATUS) & stbin 48 jr nz, got_strobe 49 djnz wait_for_strobe 50strobe_failed: 51 ld h, #1 52 ld l, #0 53 jr lptrecv_tribble_out 54got_strobe: 55 in a, (STATUS) 56 sra a 57 sra a 58 sra a 59 and #LPT_TRIB_MASK ; & tribmask 60 ld l, a 61 ld a, #LPT_BUSY_OUT ; raise busy/ack 62 out (DATA), a 63 ld b, #0xff ; retry 255 times 64wait_for_unstrobe: 65 in a, (STATUS) 66 and #LPT_STROBE_IN ; inb(STATUS) & stbin 67 jr z, lptrecv_tribble_out 68 djnz wait_for_unstrobe 69 ; if we never get unstrobe, that's ok 70lptrecv_tribble_out: 71 ld a, #LPT_BUSY_OUT ; raise busy/ack 72 out (DATA), a 73 pop bc 74 ret 75 76 77; unsigned char lptrecv(void) 78; receive a full byte from host in three parts 79; return h=1 l=0 on error, otherwise h=0, l=(byte) 80_lptrecv:: 81 push bc 82 call lptrecv_tribble 83 ld a, h 84 cp #1 85 jr z, lptrecv_err ; bail early if h has an error 86 ld b, l 87 call lptrecv_tribble 88 ld a, h 89 cp #1 90 jr z, lptrecv_err 91 ld a, l 92 sla a 93 sla a 94 sla a 95 add b 96 ld b, a ; += tribble << 3 97 call lptrecv_tribble 98 ld a, h 99 cp #1 100 jr z, lptrecv_err 101 ld a, l 102 and #LPT_DIB_MASK ; dibmask 103 sla a 104 sla a 105 sla a 106 sla a 107 sla a 108 sla a 109 add b ; += (tribble & dibmask) << 6 110 ld h, #0 111 ld l, a 112lptrecv_out: 113 pop bc 114 ret 115lptrecv_err: 116 pop bc 117 ld hl, #0x0100 118 ret 119 120 121; send a tribble byte in register l to host, return l=0 on success 122lptsend_tribble: 123 push bc 124 ld h, #1 125 ld c, #0xff ; 255*255 tries before bailing 126wait_for_busy_drop_outer: 127 ld b, #0xff 128wait_for_busy_drop: 129 in a, (STATUS) 130 and #LPT_BUSY_IN ; inb(STATUS) & bsyin 131 jr z, got_busy_drop 132 djnz wait_for_busy_drop 133 dec c 134 ld a, c 135 cp #0 136 jr nz, wait_for_busy_drop_outer 137busy_drop_failed: 138 jr lptsend_tribble_out 139got_busy_drop: 140 ld a, l 141 and #LPT_TRIB_MASK 142 or #LPT_STROBE_OUT 143 out (DATA), a 144 ld c, #0xff ; try 255*255 tries before bailing 145wait_for_ack_outer: 146 ld b, #0xff 147wait_for_ack: 148 in a, (STATUS) 149 and #LPT_BUSY_IN ; inb(STATUS) & stbin 150 jr nz, lptsend_unstrobe 151 djnz wait_for_ack 152 dec c 153 ld a, c 154 cp #0 155 jr nz, wait_for_ack_outer 156 jr lptsend_tribble_out 157lptsend_unstrobe: 158 ld a, #1 159 out (DATA), a 160 ld h, #0 ; success 161lptsend_tribble_out: 162 ld a, #LPT_BUSY_OUT ; raise busy/ack 163 out (DATA), a 164 pop bc 165 ld l, h ; l=1 error, l=0 success 166 ld h, #0 167 ret 168 169 170; unsigned int lptsend(unsigned char b) 171; returns 0 on success 172_lptsend:: 173 push ix 174 ld ix, #0 175 add ix, sp 176 ld l, 4(ix) ; char to send 177 push hl 178 call lptsend_tribble 179 ld a, l 180 pop hl 181 cp #0 182 jr z, tribble2 183 ld hl, #0x1 184 jr lptsend_error 185tribble2: 186 push hl 187 sra l 188 sra l 189 sra l ; b >> 3 190 call lptsend_tribble 191 ld a, l 192 pop hl 193 cp #0 194 jr z, tribble3 195 ld hl, #0x2 196 jr lptsend_error 197tribble3: 198 sra l 199 sra l 200 sra l 201 sra l 202 sra l 203 sra l ; b >> 6 204 call lptsend_tribble 205 ld a, l 206 cp #0 207 jr z, lptsend_out 208 ld hl, #0x3 209 jr lptsend_error 210lptsend_out: 211 ld hl, #0 212 ld sp, ix 213 pop ix 214 ret 215lptsend_error: 216 ld sp, ix 217 pop ix 218 ret 219 220 221; send pushed 16-bit as two bytes 222_lptsend16:: 223 push ix 224 ld ix, #0 225 add ix, sp 226 push hl 227 ld h, #0 228 ld l, 5(ix) 229 push hl 230 call _lptsend 231 pop hl 232 ld l, 4(ix) 233 push hl 234 call _lptsend 235 pop hl 236 pop hl 237 ld sp, ix 238 pop ix 239 ret