]>
Commit | Line | Data |
---|---|---|
b0db0839 L |
1 | IF NOT lasm\r |
2 | .printx * CPXAC.ASM *\r | |
3 | ENDIF ;NOT lasm\r | |
4 | ; KERMIT - (Celtic for "FREE")\r | |
5 | ;\r | |
6 | ; This is the CP/M-80 implementation of the Columbia University\r | |
7 | ; KERMIT file transfer protocol.\r | |
8 | ;\r | |
9 | ; Version 4.0\r | |
10 | ;\r | |
11 | ; Copyright June 1981,1982,1983,1984,1985\r | |
12 | ; Columbia University\r | |
13 | ;\r | |
14 | ; Originally written by Bill Catchings of the Columbia University Center for\r | |
15 | ; Computing Activities, 612 W. 115th St., New York, NY 10025.\r | |
16 | ;\r | |
17 | ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,\r | |
18 | ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many\r | |
19 | ; others.\r | |
20 | ;\r | |
21 | ;\r | |
22 | ;\r | |
23 | \r | |
24 | ;\r | |
25 | ; Keep module name, edit number, and last revision date in memory.\r | |
26 | ;\r | |
27 | family: db 'CPXCP.ASM (1) 3-DEC-2015$' ; First entry for V4.11\r | |
28 | \r | |
29 | ;\r | |
30 | ; Assembly time message to let me know I'm building the right version.\r | |
31 | ;\r | |
32 | \r | |
33 | .printx * Assembling Kermit-80 for AVR-CP/M *\r | |
34 | \r | |
35 | \r | |
36 | \r | |
37 | SC16IS740_ADDR equ 90H ;SC16IS740 I2C address. (8bit, A0=VDD, A1=VDD)\r | |
38 | OUTSIZE equ 64\r | |
39 | \r | |
40 | ; Virtual I2C Interface\r | |
41 | \r | |
42 | VI2C_STAT equ 05h\r | |
43 | VI2C_CTRL equ 05h\r | |
44 | VI2C_BLEN equ 06h\r | |
45 | VI2C_ADR equ 07h\r | |
46 | VI2C_BSIZ equ 66 ;largest message size including address byte (SLA)\r | |
47 | \r | |
48 | ;----------------------------- ISC16IS740 UART -------------------------------\r | |
49 | I2C_UART_PORT equ 50H\r | |
50 | \r | |
51 | I2C_UART_RHR equ I2C_UART_PORT+00H ;R Receive Holding\r | |
52 | I2C_UART_THR equ I2C_UART_PORT+00H ;W Transmit Holding\r | |
53 | I2C_UART_IER equ I2C_UART_PORT+01H ;R/W Interrupt Enable\r | |
54 | I2C_UART_FCR equ I2C_UART_PORT+02H ;W FIFO Control\r | |
55 | TX_FIFO_RES equ 04H ; TX FIFO reset\r | |
56 | RX_FIFO_RES equ 02H ; RX FIFO reset\r | |
57 | FIFO_ENABLE equ 01H ; FIFO enable\r | |
58 | \r | |
59 | I2C_UART_IIR equ I2C_UART_PORT+02H ;R Interrupt Identification\r | |
60 | I2C_UART_LCR equ I2C_UART_PORT+03H ;R/W Line Control\r | |
61 | DLAB equ 80H ; Devisor latch enable\r | |
62 | WLS0 equ 01H ; Word Length Select Bit 0\r | |
63 | WLS1 equ 02H ; Word Length Select Bit 1 for 8 bit word\r | |
64 | STB equ 04H ; Stop bit count - 2 stop bits\r | |
65 | \r | |
66 | I2C_UART_MCR equ I2C_UART_PORT+04H ;R/W Modem Control\r | |
67 | RTS equ 02H ;RTS pin, 1 = active (low)\r | |
68 | DTR equ 01H ;DTR pin (not on '740)\r | |
69 | I2C_UART_LSR equ I2C_UART_PORT+05H ;R Line Status\r | |
70 | TXE equ 40H ; THR and TSR empty\r | |
71 | TXRDY equ 20H ; THR empty\r | |
72 | RX_FE equ 08H ; Framig error\r | |
73 | RX_PE equ 04H ; Parity error\r | |
74 | RX_OE equ 02H ; Overrun error\r | |
75 | RXRDY equ 01H ; Receved byte available\r | |
76 | I2C_UART_MSR equ I2C_UART_PORT+06H ;R Modem Status\r | |
77 | I2C_UART_SPR equ I2C_UART_PORT+07H ;R/W Scratchpad\r | |
78 | I2C_UART_TCR equ I2C_UART_PORT+06H ;R/W Transmission Control\r | |
79 | I2C_UART_TLR equ I2C_UART_PORT+07H ;R/W Trigger Level\r | |
80 | I2C_UART_TXLVL equ I2C_UART_PORT+08H ;R Transmit FIFO Level\r | |
81 | I2C_UART_RXLVL equ I2C_UART_PORT+09H ;R Receive FIFO Level\r | |
82 | I2C_UART_EFCR equ I2C_UART_PORT+0FH ;R/W Extra Features\r | |
83 | I2C_UART_DLL equ I2C_UART_PORT+00H ;R/W divisor latch LSB\r | |
84 | I2C_UART_DLH equ I2C_UART_PORT+01H ;R/W divisor latch MSB\r | |
85 | I2C_UART_EFR equ I2C_UART_PORT+02H ;R/W Enhanced Feature\r | |
86 | I2C_UART_XON1 equ I2C_UART_PORT+04H ;R/W Xon1 word\r | |
87 | I2C_UART_XON2 equ I2C_UART_PORT+05H ;R/W Xon2 word\r | |
88 | I2C_UART_XOFF1 equ I2C_UART_PORT+06H ;R/W Xoff1 word\r | |
89 | I2C_UART_XOFF2 equ I2C_UART_PORT+07H ;R/W Xoff2 word\r | |
90 | \r | |
91 | \r | |
92 | \r | |
93 | z80 set TRUE ;This one emulates an Z80.\r | |
94 | \r | |
95 | \r | |
96 | .z80\r | |
97 | \r | |
98 | sysxin: ; continuation of system initialisation from sysinit\r | |
99 | \r | |
100 | call speedtest\r | |
101 | call prspeedmsg\r | |
102 | \r | |
103 | ld hl,6 ;set default baud rate\r | |
104 | ld (speed),hl\r | |
105 | ex de,hl\r | |
106 | call sysspd\r | |
107 | \r | |
108 | ld a,RTS+DTR\r | |
109 | out (I2C_UART_MCR),a\r | |
110 | ret\r | |
111 | \r | |
112 | ; ld a,07H ;Enable and clear fifos\r | |
113 | ; out (I2C_UART_FCR),a ;\r | |
114 | ; ld a,03H ;8N1\r | |
115 | ; out (I2C_UART_LCR),a ;\r | |
116 | \r | |
117 | prspeedmsg:\r | |
118 | push af\r | |
119 | ld de,freqmsg\r | |
120 | call prtstr\r | |
121 | pop af\r | |
122 | cp 13+1\r | |
123 | jr c,$+3\r | |
124 | xor a\r | |
125 | ld e,a\r | |
126 | ld d,0\r | |
127 | ld hl,fm_tab\r | |
128 | add hl,de\r | |
129 | add hl,de\r | |
130 | ld e,(hl)\r | |
131 | inc hl\r | |
132 | ld d,(hl)\r | |
133 | call prtstr\r | |
134 | ld de,fdimmsg\r | |
135 | call prtstr\r | |
136 | ret\r | |
137 | \r | |
138 | mkftab macro x\r | |
139 | irp y,<x>\r | |
140 | fm&y:\r | |
141 | db '&y','$'\r | |
142 | endm\r | |
143 | fm_tab:\r | |
144 | irp y,<x>\r | |
145 | dw fm&y\r | |
146 | endm\r | |
147 | endm\r | |
148 | \r | |
149 | \r | |
150 | freqmsg:\r | |
151 | db 'UART crystal frequency: ','$'\r | |
152 | mkftab <?,1.8432,3.6864,5.5296,7.3728,9.216,11.0592,12.9024,14.7456,16.5888,18.432,20.2752,22.1184,23.9616>\r | |
153 | fdimmsg:\r | |
154 | db ' MHz.',cr,lf,'$'\r | |
155 | \r | |
156 | \r | |
157 | ;\r | |
158 | ; system-dependent KERMIT termination processing\r | |
159 | ; If we've changed anything, this is our last chance to put it back.\r | |
160 | ;\r | |
161 | sysexit:\r | |
162 | ret\r | |
163 | \r | |
164 | ;\r | |
165 | ; system-dependent processing for start of CONNECT command\r | |
166 | ;\r | |
167 | syscon:\r | |
168 | ret\r | |
169 | \r | |
170 | conmsg: ; Messages printed when entering transparent (CONNECT) mode:\r | |
171 | \r | |
172 | db '$'\r | |
173 | \r | |
174 | ;\r | |
175 | ; syscls - system-dependent close routine\r | |
176 | ; called when exiting transparent session.\r | |
177 | ;\r | |
178 | syscls:\r | |
179 | ret\r | |
180 | \r | |
181 | .8080\r | |
182 | \r | |
183 | ;\r | |
184 | ; sysinh - help for system-dependent special functions.\r | |
185 | ; called in response to <escape>?, after listing all the\r | |
186 | ; system-independent escape sequences.\r | |
187 | ;\r | |
188 | sysinh:\r | |
189 | lxi d, inhlps\r | |
190 | call prtstr\r | |
191 | ret\r | |
192 | \r | |
193 | ; Additional, system-dependent help for transparent mode\r | |
194 | ; (two-character escape sequences)\r | |
195 | inhlps:\r | |
196 | db cr,lf,'B Transmit a BREAK (0.3s)'\r | |
197 | db cr,lf,'L Transmit a LONG BREAK (1.8s)'\r | |
198 | db '$' ; string terminator\r | |
199 | \r | |
200 | .z80\r | |
201 | ;\r | |
202 | ; sysint - system dependent special functions\r | |
203 | ; called when transparent escape character has been typed;\r | |
204 | ; the second character of the sequence is in A (and in B).\r | |
205 | ; returns:\r | |
206 | ; non-skip: sequence has been processed\r | |
207 | ; skip: seqence was not recognized\r | |
208 | ;\r | |
209 | sysint:\r | |
210 | and 5FH ; convert lower case to upper, for testing...\r | |
211 | cp 'B' ; send break ?\r | |
212 | jr z,sendbr ; then jump to send break routine\r | |
213 | cp 'L' ; long break ?\r | |
214 | jr z,longbr ; then jump to long break routine\r | |
215 | jp rskp ; take skip return - command not recognised\r | |
216 | \r | |
217 | ;\r | |
218 | ; Break routines\r | |
219 | ;\r | |
220 | longbr:\r | |
221 | ld e,180 ; time for long break is 1800 ms\r | |
222 | jr setbit\r | |
223 | \r | |
224 | sendbr:\r | |
225 | ld e,25 ; time for break is 300 ms\r | |
226 | \r | |
227 | setbit:\r | |
228 | in a,(I2C_UART_LCR)\r | |
229 | set 6,a ; Break contol bit\r | |
230 | out (I2C_UART_LCR),a\r | |
231 | ;\r | |
232 | ; Now, delay for duration of hangup or break\r | |
233 | ld a,e ; delay count\r | |
234 | call delay\r | |
235 | ;\r | |
236 | ; Time's up. Put transmitter back in normal state and return.\r | |
237 | \r | |
238 | in a,(I2C_UART_LCR)\r | |
239 | res 6,a ; Break contol bit\r | |
240 | out (I2C_UART_LCR),a\r | |
241 | ret ; done.\r | |
242 | \r | |
243 | .8080\r | |
244 | ;\r | |
245 | ; sysflt - system-dependent filter\r | |
246 | ; called with character in E.\r | |
247 | ; if this character should not be printed, return with A = zero.\r | |
248 | ; preserves bc, de, hl.\r | |
249 | ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r | |
250 | ;\r | |
251 | sysflt:\r | |
252 | mov a,e ; get character for testing\r | |
253 | ret\r | |
254 | \r | |
255 | ;\r | |
256 | ; mdmflt - modem filter\r | |
257 | ; called with character to be sent to printer in E\r | |
258 | ; with parity set as appropriate.\r | |
259 | ; return with accumulator = 0 do do nothing,\r | |
260 | ; <> 0 to send char in E.\r | |
261 | mdmflt:\r | |
262 | mov a,e ; get character to test\r | |
263 | ret\r | |
264 | \r | |
265 | ;\r | |
266 | ; prtflt - printer filter\r | |
267 | ; called with character to be sent to printer in E\r | |
268 | ; returns with a = 0 to do nothing\r | |
269 | ; a <> 0 to print it.\r | |
270 | ;\r | |
271 | ; this routine for those printer that automatically insert\r | |
272 | ; a lf on cr, or cr for lf. Should this be shifted to\r | |
273 | ; the system indep. stuff, in say 4.06?\r | |
274 | ;\r | |
275 | prtflt:\r | |
276 | mov a,e ; get character to test\r | |
277 | \r | |
278 | IF FALSE ; strip out lf from printer stream\r | |
279 | ani 7fh ; make sure it is parity less\r | |
280 | cpi lf ; is it a line feed?\r | |
281 | rnz ; no, print it\r | |
282 | ; xra a ; yes, don't.\r | |
283 | \r | |
284 | ENDIF\r | |
285 | \r | |
286 | ret\r | |
287 | \r | |
288 | ;\r | |
289 | ; system-dependent processing for BYE command.\r | |
290 | ;\r | |
291 | sysbye:\r | |
292 | ret\r | |
293 | \r | |
294 | ;\r | |
295 | ; This is the system-dependent command to change the baud rate.\r | |
296 | ; DE contains the two-byte value from the baud rate table; both\r | |
297 | ; bytes of this value are also stored in 'speed'.\r | |
298 | ;\r | |
299 | .z80\r | |
300 | sysspd:\r | |
301 | ld hl,0\r | |
302 | ld a,(clk_div)\r | |
303 | ld b,a\r | |
304 | sysspd_1:\r | |
305 | add hl,de\r | |
306 | djnz sysspd_1\r | |
307 | ld a,l\r | |
308 | ld (sysspd_dll),a\r | |
309 | ld a,h\r | |
310 | ld (sysspd_dlh),a\r | |
311 | \r | |
312 | ld hl,sysspd_tab\r | |
313 | call ioinil\r | |
314 | \r | |
315 | in a,(I2C_UART_MSR) ;Clear Modem Status Register\r | |
316 | in a,(I2C_UART_LSR) ;Clear Line Status Register\r | |
317 | in a,(I2C_UART_RHR) ;Clear Receiver Buffers\r | |
318 | in a,(I2C_UART_RHR)\r | |
319 | ret\r | |
320 | \r | |
321 | sysspd_tab:\r | |
322 | db (sysspd_tab_end - ($+1))/2\r | |
323 | db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit\r | |
324 | db I2C_UART_DLL\r | |
325 | sysspd_dll:\r | |
326 | ds 1 ;1200 bit/s at 1.832 MHz\r | |
327 | db I2C_UART_DLH\r | |
328 | sysspd_dlh:\r | |
329 | ds 1 ;Out to the MSB divisor port\r | |
330 | db I2C_UART_LCR, 03H ;Disable Divisor Access Latch\r | |
331 | db I2C_UART_FCR, 07H ;Clear and enable fifos\r | |
332 | db I2C_UART_MCR, 00H ;Enable loopback\r | |
333 | db I2C_UART_IER, 0 ;Set no interrupts\r | |
334 | sysspd_tab_end:\r | |
335 | \r | |
336 | \r | |
337 | \r | |
338 | ;\r | |
339 | ; Speed tables\r | |
340 | ; (Note that speed tables MUST be in alphabetical order for later\r | |
341 | ; lookup procedures, and must begin with a value showing the total\r | |
342 | ; number of entries. The speed help tables are just for us poor\r | |
343 | ; humans.\r | |
344 | ;\r | |
345 | ; db string length, string, divisor (2 bytes or 1 word, ab)\r | |
346 | ; the data byte a is return in A and E, and b in D\r | |
347 | ; only byte 'a' is the key for the table\r | |
348 | \r | |
349 | spdtbl: db 15 ; Number of entries\r | |
350 | db 3,'110$'\r | |
351 | dw 1047\r | |
352 | db 6,'115200$'\r | |
353 | dw 1\r | |
354 | db 4,'1200$'\r | |
355 | dw 96\r | |
356 | db 3,'150$'\r | |
357 | dw 768\r | |
358 | db 5,'19200$'\r | |
359 | dw 6\r | |
360 | db 4,'2400$'\r | |
361 | dw 48\r | |
362 | db 5,'28800$'\r | |
363 | dw 5\r | |
364 | db 3,'300$'\r | |
365 | dw 384\r | |
366 | db 5,'38400$'\r | |
367 | dw 3\r | |
368 | db 3,'450$'\r | |
369 | dw 288\r | |
370 | db 4,'4800$'\r | |
371 | dw 24\r | |
372 | db 5,'57600$'\r | |
373 | dw 2\r | |
374 | db 3,'600$'\r | |
375 | dw 192\r | |
376 | db 2,'75$'\r | |
377 | dw 1536\r | |
378 | db 4,'9600$'\r | |
379 | dw 12\r | |
380 | IF 0\r | |
381 | sphtbl: db cr,lf,' 75 110 150 300 450 600 1200 2400'\r | |
382 | db cr,lf,'4800 9600 19200 28800 38400 57600 115200$'\r | |
383 | ENDIF\r | |
384 | \r | |
385 | sphtbl: db cr,lf,' 110 300 600 2400 9600 28800 57600'\r | |
386 | db cr,lf,' 75 150 450 1200 4800 19200 38400 115200$'\r | |
387 | \r | |
388 | \r | |
389 | speedtest:\r | |
390 | ld hl,spt_tab\r | |
391 | call ioinil\r | |
392 | \r | |
393 | in a,(I2C_UART_MSR) ;Clear Modem Status Register\r | |
394 | in a,(I2C_UART_LSR) ;Clear Line Status Register\r | |
395 | in a,(I2C_UART_RHR) ;Clear Receiver Buffers\r | |
396 | in a,(I2C_UART_RHR)\r | |
397 | \r | |
398 | ld a,2 ;start write transaction\r | |
399 | out (VI2C_CTRL),a\r | |
400 | \r | |
401 | ; get time stamp\r | |
402 | in a,(41H) ;lsb ms\r | |
403 | ld e,a\r | |
404 | in a,(42H) ;msb ms\r | |
405 | ld d,a\r | |
406 | in a,(43H) ;lsb seconds\r | |
407 | ld c,a\r | |
408 | \r | |
409 | spt_1:\r | |
410 | in a,(I2C_UART_RXLVL)\r | |
411 | cp 60\r | |
412 | jr nz,spt_1\r | |
413 | \r | |
414 | ; get 2nd time stamp\r | |
415 | in a,(41H) ;lsb ms\r | |
416 | ld l,a\r | |
417 | in a,(42H) ;msb ms\r | |
418 | ld h,a\r | |
419 | in a,(43H) ;lsb seconds\r | |
420 | sub c\r | |
421 | jr z,spt_3\r | |
422 | ld bc,1000\r | |
423 | spt_2:\r | |
424 | add hl,bc\r | |
425 | dec a\r | |
426 | jr nz,spt_2\r | |
427 | spt_3:\r | |
428 | sbc hl,de\r | |
429 | ld d,h\r | |
430 | ld e,l\r | |
431 | inc hl\r | |
432 | srl h\r | |
433 | rr l\r | |
434 | ld bc,500\r | |
435 | add hl,bc\r | |
436 | \r | |
437 | xor a ;clear carry\r | |
438 | spt_4:\r | |
439 | inc a\r | |
440 | sbc hl,de\r | |
441 | jr nc,spt_4\r | |
442 | dec a\r | |
443 | ld (clk_div),a\r | |
444 | ret\r | |
445 | \r | |
446 | spt_tab:\r | |
447 | db (spt_tab_end - ($+1))/2\r | |
448 | db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit\r | |
449 | db I2C_UART_DLL, low 96 ;1200 bit/s at 1.832 MHz\r | |
450 | db I2C_UART_DLH, high 96 ;Out to the MSB divisor port\r | |
451 | db I2C_UART_LCR, 03H ;Disable Divisor Access Latch\r | |
452 | db I2C_UART_FCR, 07H ;Clear and enable fifos\r | |
453 | db I2C_UART_MCR, 10H ;Enable loopback\r | |
454 | db I2C_UART_IER, 0 ;Set no interrupts\r | |
455 | db VI2C_ADR+0, low outbuf\r | |
456 | db VI2C_ADR+1, high outbuf\r | |
457 | db VI2C_BLEN, 60+2\r | |
458 | spt_tab_end:\r | |
459 | \r | |
460 | ;----------------------------------------------------------------------\r | |
461 | ; output bytes to ports\r | |
462 | ;\r | |
463 | ; hl: tables of port,value pairs:\r | |
464 | ; db n ;number of pairs\r | |
465 | ; db port1,val1, port2,val2,... portn,valn\r | |
466 | ; ...\r | |
467 | ; db 0 ; Terminate table\r | |
468 | \r | |
469 | ioinil:\r | |
470 | push bc\r | |
471 | ld b,(hl) ;count\r | |
472 | inc hl\r | |
473 | io1_lp:\r | |
474 | ld c,(hl) ;port address\r | |
475 | inc hl\r | |
476 | outi\r | |
477 | jr nz,io1_lp\r | |
478 | pop bc\r | |
479 | ret\r | |
480 | \r | |
481 | ;\r | |
482 | ; This is the system-dependent SET PORT command.\r | |
483 | ; HL contains the argument from the command table.\r | |
484 | ;\r | |
485 | sysprt:\r | |
486 | ret\r | |
487 | \r | |
488 | prttbl EQU 0 ; SET PORT is not supported\r | |
489 | prhtbl EQU 0\r | |
490 | \r | |
491 | ;\r | |
492 | ; selmdm - select modem port\r | |
493 | ; selcon - select console port\r | |
494 | ; selmdm is called before using inpmdm or outmdm;\r | |
495 | ; selcon is called before using inpcon or outcon.\r | |
496 | ; For iobyt systems, diddle the I/O byte to select console or comm port;\r | |
497 | ; For the rest, does nothing.\r | |
498 | ; preserves bc, de, hl.\r | |
499 | ;\r | |
500 | selmdm:\r | |
501 | ret\r | |
502 | \r | |
503 | selcon:\r | |
504 | IF 1\r | |
505 | jr omflush\r | |
506 | ELSE\r | |
507 | ret\r | |
508 | ENDIF\r | |
509 | \r | |
510 | ;\r | |
511 | ; Get character from console, or return zero.\r | |
512 | ; result is returned in A. destroys bc, de, hl.\r | |
513 | ;\r | |
514 | inpcon:\r | |
515 | ld c,dconio ;Direct console I/O BDOS call.\r | |
516 | ld e,0FFH ;Input.\r | |
517 | call BDOS\r | |
518 | \r | |
519 | ret\r | |
520 | \r | |
521 | ;\r | |
522 | ; Output character in E to the console.\r | |
523 | ; destroys bc, de, hl\r | |
524 | ;\r | |
525 | outcon:\r | |
526 | ld c,dconio ;Console output bdos call.\r | |
527 | call bdos ;Output the char to the console.\r | |
528 | \r | |
529 | ret\r | |
530 | \r | |
531 | ;\r | |
532 | ; outmdm - output a char from E to the modem.\r | |
533 | ; the parity bit has been set as necessary.\r | |
534 | ; returns nonskip; bc, de, hl preserved.\r | |
535 | ;\r | |
536 | outmdm:\r | |
537 | IF 0\r | |
538 | in a,(I2C_UART_LSR) ;Get the output done flag.\r | |
539 | and TXRDY ;Is it set?\r | |
540 | jr z,outmdm ;If not, loop until it is.\r | |
541 | ld a,e\r | |
542 | out (I2C_UART_THR),a ;Output it.\r | |
543 | ENDIF\r | |
544 | IF 1\r | |
545 | \r | |
546 | push hl\r | |
547 | ld hl,(outptr)\r | |
548 | ld (hl),e ;return buffered char\r | |
549 | inc hl\r | |
550 | ld (outptr),hl\r | |
551 | ld a,(outcnt)\r | |
552 | inc a\r | |
553 | ld (outcnt),a\r | |
554 | cp OUTSIZE\r | |
555 | jr nc,omflush_1 ;buffer full\r | |
556 | pop hl\r | |
557 | ret\r | |
558 | \r | |
559 | omflush:\r | |
560 | ld a,(outcnt)\r | |
561 | or a\r | |
562 | ret z\r | |
563 | \r | |
564 | scf\r | |
565 | push hl\r | |
566 | omflush_1:\r | |
567 | push bc\r | |
568 | ld c,a ;outcnt\r | |
569 | ld b,a\r | |
570 | jr c,$+4\r | |
571 | ld b,1\r | |
572 | ld hl,outbuf\r | |
573 | ld a,h\r | |
574 | out (VI2C_ADR+1),a\r | |
575 | ld a,l\r | |
576 | out (VI2C_ADR+0),a\r | |
577 | omf_0:\r | |
578 | in a,(I2C_UART_TXLVL)\r | |
579 | cp b\r | |
580 | jr c,omf_0\r | |
581 | cp c\r | |
582 | jr nc,omf_2\r | |
583 | ld c,a\r | |
584 | omf_2:\r | |
585 | ld a,c\r | |
586 | add a,2\r | |
587 | out (VI2C_BLEN),a\r | |
588 | ld a,2 ;start write transaction\r | |
589 | out (VI2C_CTRL),a\r | |
590 | \r | |
591 | ld hl,outbuf+2\r | |
592 | ld (outptr),hl\r | |
593 | ld a,(outcnt)\r | |
594 | sub c\r | |
595 | ld (outcnt),a\r | |
596 | jr z,omfex\r | |
597 | \r | |
598 | push de\r | |
599 | ld d,h\r | |
600 | ld e,l\r | |
601 | ld b,0\r | |
602 | add hl,bc\r | |
603 | ld c,a\r | |
604 | ldir\r | |
605 | pop de\r | |
606 | omfex:\r | |
607 | pop bc\r | |
608 | pop hl\r | |
609 | ret\r | |
610 | ENDIF\r | |
611 | ;\r | |
612 | ; get character from modem; return zero if none available.\r | |
613 | ; for IOBYT systems, the modem port has already been selected.\r | |
614 | ; destroys bc, de, hl.\r | |
615 | ;\r | |
616 | inpmdm:\r | |
617 | if 0\r | |
618 | in a,(I2C_UART_LSR) ;Get the port status into A.\r | |
619 | and RXRDY ;See if the input ready bit is on.\r | |
620 | ret z ;If not then return.\r | |
621 | \r | |
622 | in a,(I2C_UART_MCR) ;debug\r | |
623 | xor RTS\r | |
624 | out (I2C_UART_MCR),a\r | |
625 | \r | |
626 | in a,(I2C_UART_RHR);If so, get the char.\r | |
627 | ret\r | |
628 | endif\r | |
629 | \r | |
630 | if 1\r | |
631 | ld a,(inpcnt)\r | |
632 | dec a\r | |
633 | jp m,imdrdi2c ;buffer empty\r | |
634 | ld (inpcnt),a\r | |
635 | ld hl,(inpptr)\r | |
636 | ld a,(hl) ;return buffered char\r | |
637 | inc hl\r | |
638 | ld (inpptr),hl\r | |
639 | ret\r | |
640 | \r | |
641 | imdrdi2c:\r | |
642 | in a,(I2C_UART_RXLVL) ;get rx fifo count\r | |
643 | or a\r | |
644 | ret z ;fifo is empty, return 0\r | |
645 | \r | |
646 | ; prepare fifo read\r | |
647 | inc a ;+ slave address\r | |
648 | ld (VI2C_BLEN),a\r | |
649 | ld hl,inbuf\r | |
650 | ld a,h\r | |
651 | out (VI2C_ADR+1),a\r | |
652 | ld a,l\r | |
653 | out (VI2C_ADR+0),a\r | |
654 | inc hl\r | |
655 | ld (hl),0 ;select subaddr 0 (RHR) for next read\r | |
656 | ld a,3 ;write 1 byte (subaddr.), then read fifo\r | |
657 | ld (VI2C_CTRL),a\r | |
658 | in a,(VI2C_CTRL) ;get i2c result\r | |
659 | xor 01h\r | |
660 | and 11h ;transfer completed?\r | |
661 | jr nz,imrdex\r | |
662 | in a,(VI2C_BLEN) ;get actual transfer count\r | |
663 | \r | |
664 | sub 2 ;- (slave address + char to return now)\r | |
665 | jr c,imrdex\r | |
666 | ld (inpcnt),a ;save new buffer count\r | |
667 | ld a,(hl)\r | |
668 | inc hl\r | |
669 | ld (inpptr),hl\r | |
670 | ret\r | |
671 | \r | |
672 | imrdex:\r | |
673 | xor a\r | |
674 | ret\r | |
675 | endif\r | |
676 | \r | |
677 | .8080\r | |
678 | \r | |
679 | ;\r | |
680 | ; flsmdm - flush comm line.\r | |
681 | ; Modem is selected.\r | |
682 | ; Currently, just gets characters until none are available.\r | |
683 | ;\r | |
684 | flsmdm:\r | |
685 | call inpmdm ; Try to get a character\r | |
686 | ora a ; Got one?\r | |
687 | jnz flsmdm ; If so, try for another\r | |
688 | ret ; Receiver is drained. Return.\r | |
689 | \r | |
690 | \r | |
691 | ;\r | |
692 | ; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.\r | |
693 | lptstat:\r | |
694 | IF iobyte ;[33]\r | |
695 | call bprtst ; get status\r | |
696 | ENDIF ;iobyte[33]\r | |
697 | IF NOT iobyte ;[33]\r | |
698 | xra a ; assume it is ok.. this may not be necessary\r | |
699 | ENDIF ;iobyte [33]\r | |
700 | ret\r | |
701 | ;\r | |
702 | ; outlpt - output character in E to printer\r | |
703 | ; console is selected.\r | |
704 | ; preserves de.\r | |
705 | ;\r | |
706 | outlpt:\r | |
707 | push d ; save DE in either case\r | |
708 | call prtflt ; go through printer filter [30]\r | |
709 | ana a ; if A = 0 do nothing,\r | |
710 | jz outlp1 ; if a=0 do nothing\r | |
711 | \r | |
712 | outlp1: pop d ; restore saved register pair\r | |
713 | ret\r | |
714 | \r | |
715 | ; delchr - make delete look like a backspace. Unless delete is a printing\r | |
716 | ; character, we just need to print a backspace. (we'll output clrspc\r | |
717 | ; afterwards)\r | |
718 | delchr:\r | |
719 | \r | |
720 | mvi e,bs ;get a backspace\r | |
721 | jmp outcon\r | |
722 | \r | |
723 | ; erase the character at the current cursor position\r | |
724 | clrspc: mvi e,' '\r | |
725 | call outcon\r | |
726 | mvi e,bs ;get a backspace\r | |
727 | jmp outcon\r | |
728 | \r | |
729 | ; erase the current line\r | |
730 | clrlin: lxi d,eralin\r | |
731 | jmp prtstr\r | |
732 | \r | |
733 | ; erase the whole screen, and go home. preserves b (but not c)\r | |
734 | clrtop: lxi d,erascr\r | |
735 | jmp prtstr\r | |
736 | \r | |
737 | \r | |
738 | sysver: db 'AVR-CP/M'\r | |
739 | db '$'\r | |
740 | \r | |
741 | \r | |
742 | clk_div:\r | |
743 | db 1 ;default div\r | |
744 | \r | |
745 | inpptr: dw 0\r | |
746 | inpcnt: db 0\r | |
747 | inbuf:\r | |
748 | db SC16IS740_ADDR\r | |
749 | ds VI2C_BSIZ-1\r | |
750 | \r | |
751 | \r | |
752 | outptr: dw outbuf+2\r | |
753 | outcnt: db 0\r | |
754 | outbuf:\r | |
755 | db SC16IS740_ADDR\r | |
756 | db 0 ;RHR subaddress\r | |
757 | ds OUTSIZE\r | |
758 | \r | |
759 | \r | |
760 | IF lasm\r | |
761 | LINK CPXVDU.ASM ; get terminal defs etc\r | |
762 | ENDIF ;lasm\r |