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