]> cloudbase.mooo.com Git - kermit-80.git/blame - cpxapp.asm
Bugfix in outmdm (output buffer flush)
[kermit-80.git] / cpxapp.asm
CommitLineData
e58a7a25
L
1IF NOT lasm\r
2.printx * CPXAPP.ASM *\r
3ENDIF ;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; This file contains the system-dependent code and data for KERMIT.\r
22; It will be probably be broken into independent files to generate\r
23; overlays for the various systems, one or more overlay possible\r
24; from each file. For now, we will leave it in one piece.\r
25;\r
26; revision history:\r
27; edit 2, 22 July, 1987 by OBSchou. Massaged code to work with CPXCOM.ASM\r
28;\r
29; edit 1, 2nd June, 1987 by OBSchou. Extracted all Apple related code.\r
30;\r
31;\f\r
32; Family is the string used in VERSION to say which of several \r
33; smaller overlay files are used. These are (will be) derived from \r
34; the juge CPXSYS.ASM file, in which case we will never get here. \r
35; Just a Dollar, but put a sting in for a family of machines.\r
36;\r
37family: db 'CPXAPP.ASM (2) 22-jul-87$' ; Used for family versions....\r
38;\r
39 \r
40IF apple\r
41.printx * Assembling KERMIT-80 for the Apple ][ *\r
42ENDIF;apple\r
43IF apmmdm\r
44.printx * with Z80 Softcard & Micromodem II *\r
45ENDIF;apmmdm\r
46IF ap6551\r
47.printx * with Z80 Softcard & 6551 ACIA *\r
48ENDIF;ap6551\r
49IF ap6850;[32]\r
50.printx * with Z80 Softcard & 6850 ACIA *\r
51ENDIF;ap6850 [32]\r
52IF apcps;[22]\r
53.printx * with Softcard & CPS Multifunction card *\r
54ENDIF;apcps\r
55\r
56;\r
57\r
58IF ap6551 OR ap6850 OR apcps;[9] [14]\r
59 ;jb eg. Apple SSC, Videx PSIO, Basis 108\r
60apslot EQU 2 ;jb set equal to slot containing serial card\r
61 ;jb set to 1 for Basis built-in port\r
62ENDIF;jb ap6551 [9] apcps ap6850 [14]\r
63IF ap6850 ;[14] offset in slot I/O space for ACIA registers\r
64 ;e.g. PACT=00,01: AIO-I=05,04: AIO-II=0D,0C: Aristocard=0B,0A\r
65apdat EQU 0DH ;data reg.=0E080h+apslot*10h*apdat\r
66apstat EQU 0CH ;comm/stat reg.=0E080h+apslot*10h+apstat\r
67ENDIF;ap6850\r
68\r
69\r
70IF apmmdm\r
71;APPLE Slot 2 contains Micromodem II.\r
72MNPORT EQU 0E0A7H ;Communications Port.\r
73mnprts EQU 0E0A6H ;Communications Port Status.\r
74mnmodm EQU 0E0A5H ;Modem Control Port.\r
75orgmod EQU 8EH ;Modem Originate Mode.\r
76OUTPUT EQU 02H ;Output Buffer Empty.\r
77INPUT EQU 01H ;Input Register Full.\r
78apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)\r
79apinc2 EQU 11H ;Second Init Character for ACIA (8-bits)\r
80apoffh EQU 80H ;Set if OFFHOOK\r
81AP300 EQU 1 ;300 Baud\r
82z80 EQU TRUE ;Z80 Softcard\r
83ENDIF;apmmdm\r
84\r
85IF ap6551 ;jb\r
86mnport EQU 0E088H+(10H*apslot) ;jb Communications Port.\r
87mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status.\r
88mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control\r
89mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command)\r
90output EQU 10H ;jb Output Buffer Empty.\r
91input EQU 08H ;jb Input Register Full.\r
92mncinb EQU 18H ;jb Control Port Initialization Byte\r
93 ;jb (8-bit, no parity, 1-stop, 1200 baud)\r
94mnminb EQU 0BH ;jb Master Port Initialization Byte\r
95 ;jb (DTR, RTS, no interrupts)\r
96z80 EQU TRUE ;Z80 Softcard\r
97ENDIF;ap6551\r
98\r
99IF ap6850 ;[32]\r
100mnport EQU 0E080H+(10H*apslot)+apdat ;Communications Port.\r
101mnprts EQU 0E080H+(10H*apslot)+apstat ;Communications Port Status.\r
102OUTPUT EQU 02H ;Output Buffer Empty.\r
103INPUT EQU 01H ;Input Register Full.\r
104apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)\r
105apinc2 EQU 15H ;Second Init Character for ACIA (8 data, 1 stop bit)\r
106z80 EQU TRUE ;Z80 Softcard\r
107ENDIF;[32] ap6850\r
108\r
109IF apcps ;[22]\r
110mnport EQU 0E0FAH+(100H*apslot) ; Communications Port.\r
111mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status.\r
112mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control\r
113output EQU 1 ; Output Buffer Empty.\r
114input EQU 2 ; Input Register Full.\r
115TxEmpty EQU 04h ; Transmitter empty flag\r
116apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x)\r
117 ; Mode Byte 2 is speed control byte\r
118apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE)\r
119z80 EQU TRUE ;Z80 Softcard\r
120ENDIF;[22] apcps\r
121\r
122IF apple \r
123defesc EQU ']'-100O ;The default escape character.\r
124ENDIF;apple \r
125\r
126\r
127; default to VT52-EMULATION ON.\r
128\r
129vtval EQU 1\r
130\r
131\r
132\r
133sysxin: ; continuation of systemm dependent initialisation code\r
134\r
135IF ap6551\r
136 lda mnprtc ; read control port\r
137 ani 0fH ; extract low order nybble\r
138 sta speed ; store as comm line speed\r
139 sta speed+1 ; (16 bits, to match speed table entries)\r
140 mvi a,mnminb ;jb initialization routine\r
141 sta mnprts ;jb\r
142 sta mnprtm ;jb initialize master (command) port\r
143 mvi a,mncinb ;jb\r
144 sta mnprtc ;jb initialize control port\r
145ENDIF;ap6551\r
146\r
147IF ap6850 ;[32]\r
148 mvi a,apinc1 ;Init ACIA\r
149 sta mnprts\r
150 mvi a,apinc2 ;Set ACIA bits per character\r
151 sta mnprts\r
152ENDIF;[32] ap6850\r
153\r
154IF apcps ;[22]\r
155 lxi h,3737h ;Default 1200 baud\r
156 shld speed ;Store as port speed\r
157 xchg\r
158 call sysspd ;Initialise the port\r
159ENDIF;[22] apcps\r
160\r
161 ret ; return from system-dependent routine\r
162\r
163;\f\r
164\r
165;\r
166; system-dependent termination processing\r
167; If we've changed anything, this is our last chance to put it back.\r
168sysexit:\r
169\r
170 ret\r
171\r
172;\r
173; system-dependent processing for start of CONNECT command\r
174;\r
175syscon:\r
176IF apmmdm\r
177 call ckdial ;See if dialing is required.\r
178 jmp kermit ;Go to command loop if aborted.\r
179ENDIF;apmmdm\r
180\r
181 ret\r
182\r
183conmsg: ; Messages printed when entering transparent (CONNECT) mode:\r
184;\f\r
185\r
186IF apmmdm\r
187;This code was mostly taken from\r
188; APMODEM.ASM V2.1\r
189; Based on MODEM.ASM by Ward Christensen\r
190; Modified for the Apple ][ by Gordon Banks 1-Jan-81\r
191; Micromodem ][ dialer option by Dav Holle 2-Feb-81\r
192; Code modified for KERMIT by Scott Robinson 14-Oct-82\r
193;\r
194;Come here to see if we need to dial a number.\r
195;\r
196ckdial: lda mnport ;access the data port\r
197 lda mnprts ;check status\r
198 ani 4 ;do we already have carrier?\r
199 jz rskp ;Yes, just continue\r
200 xra a ;Hangup Phone for starters\r
201 sta mnmodm\r
202 lxi b,1000 ;Delay for a second\r
203 call delay\r
204 mvi a,8FH ;orgmod+ap300+apoffh\r
205 sta holdd ;storing mode for after dialing\r
206 mvi A,8DH ;Go Offhook to start dialing sequence\r
207 sta mnmodm\r
208 mvi a,apinc1 ;Init ACIA\r
209 sta mnport\r
210 mvi a,apinc2 ;Set ACIA bits per character\r
211 sta mnport\r
212\r
213 lxi b,2500 ;wait 2.5 seconds for dial tone\r
214 call delay\r
215 lxi d,dialms ;Ask the user for the number\r
216 call prtstr\r
217;\r
218gtdial: mvi c,conin ;Get a character\r
219 call bdos\r
220 push psw ;save it\r
221 cpi 30H ;is it big enough to dial?\r
222 jc dialed ;no\r
223 cpi 3AH ;is it too big to dial?\r
224 jnc dialed ;yes\r
225 ani 0FH ;ok, it's a digit, get its value\r
226 jnz dialnz ;dial nonzero digits as-is\r
227 mvi A,10 ;dial zero as ten\r
228;\r
229dialnz: mov e,a ;count pulses in E-reg\r
230dopuls: mvi a,0DH ;put it on-hook\r
231 sta mnmodm\r
232 lxi b,61 ;61-millisec pulse\r
233 call delay\r
234 mvi a,8DH ;take it off-hook again...\r
235 sta mnmodm\r
236 lxi b,39 ;39-millisec delay between pulses\r
237 call delay\r
238 dcr e ;any more pulses to do?\r
239 jnz dopuls ;yep, do 'em\r
240 lxi b,600 ;delay 600 msecs between digits\r
241 call delay\r
242;\r
243dialed: pop psw ;get back the char\r
244 cpi cr ;do we have a CR (done dialing)?\r
245 jnz gtdial ;no, keep on dialin'\r
246 lxi d,dialm2\r
247 call prtstr\r
248\r
249tictoc: mvi c,dconio ;Direct console input.\r
250 mvi e,0FFH\r
251 call bdos\r
252 ora a ;Have a charcter?\r
253 jnz nodial ;If so we abort\r
254 lda mnport ;access the data port\r
255 lda mnprts ;get modem status\r
256 ani 4 ;carrier?\r
257 jnz tictoc ;No\r
258;\r
259 lda holdd ;get the old modem control byte\r
260 sta mnmodm ;turn our carrier on\r
261\r
262 lxi d,dialm3\r
263 call prtstr\r
264 jmp rskp\r
265nodial: xra a ;Hangup the modem.\r
266 sta mnmodm\r
267 ret ;Return to abort the command.\r
268;\r
269holdd: db 0 ;Modem setup code\r
270dialms: DB 'Number to Dial: $'\r
271dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$'\r
272dialm3: DB cr,lf,'Connected.',CR,LF,'$'\r
273;\r
274;DELAY wait for the number of millisecs in B,C\r
275;\r
276delay: push b ;save B,C\r
277 push d ;save D,E\r
278 inr b ;bump B for later DCR\r
279;\r
280delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80\r
281 ;clock=2.041MHz)\r
282;\r
283delay2: dcr e ;count\r
284 jnz delay2 ;down\r
285;\r
286 dcr c ;more millisecs?\r
287 jnz delay1 ;yes\r
288 dcr b ;no - more in hi byte?\r
289 jnz delay1 ;yes\r
290 pop d ;no, restore D,E\r
291 pop b ; restore B,C\r
292 ret\r
293ENDIF;apmmdm\r
294;\f\r
295\r
296;\r
297; syscls - system-dependent close routine\r
298; called when exiting transparent session.\r
299;\r
300syscls:\r
301 ret\r
302;\f\r
303\r
304;\r
305; sysinh - help for system-dependent special functions.\r
306; called in response to <escape>?, after listing all the\r
307; system-independent escape sequences.\r
308;\r
309sysinh:\r
310IF apmmdm OR apcps OR ap6850 ;\r
311 lxi d,inhlps ; we got options...\r
312 call prtstr ; print them.\r
313ENDIF ;apmmdm OR apcps OR ap6850\r
314\r
315 ret\r
316\r
317\r
318;additional, system-dependent help for transparent mode\r
319; (two-character escape sequences)\r
320inhlps:\r
321\r
322IF apcps OR ap6850\r
323 db cr,lf,'B Transmit a BREAK'\r
324ENDIF;apcps OR ap6850\r
325\r
326IF apmmdm \r
327 db cr,lf,'D Drop the line'\r
328ENDIF;apmmdm \r
329\r
330 db '$' ;[hh] table terminator\r
331\r
332;\r
333; sysint - system dependent special functions\r
334; called when transparent escape character has been typed;\r
335; the second character of the sequence is in A (and in B).\r
336; returns:\r
337; non-skip: sequence has been processed\r
338; skip: sequence was not recognized\r
339sysint: ani 137O ; convert lower case to upper, for testing...\r
340IF apmmdm\r
341 cpi 'D' ;Disconnect Modem?\r
342 jnz intc00 ;No.\r
343 xra a ;Yes, hangup the modem\r
344 sta mnmodm\r
345 ret ; command has been executed\r
346intc00:\r
347ENDIF;apmmdm\r
348\r
349IF ap6850 OR apcps ; [22] [25] ... some more\r
350 cpi 'B' ; send break?\r
351 jz sendbr ; yes, go do it. return nonskip when through.\r
352ENDIF;[22] ap6850 OR apcps \r
353\r
354 jmp rskp ; take skip return - command not recognized.\r
355\r
356\r
357;\f\r
358\r
359IF ap6850 ;[32]\r
360sendbr:\r
361;\r
362; Ensure that the transmitter has finished sending buffered chars\r
363sndbr1: lda mnprts ; get UART status\r
364 ani output ; everything sent?\r
365 jz sndbr1 ; no, wait a bit more\r
366;\r
367; Begin sending a break\r
368 mvi a,apinc2\r
369 ori 60h ;transmit break level, CTS high\r
370 sta mnprts\r
371;\r
372; Wait for 250 milliseconds (using hundredths second delay routine)\r
373 mvi a,25\r
374 call delay\r
375;\r
376; Resume normal operation\r
377 mvi a,apinc2\r
378 sta mnprts\r
379;\r
380 ret ;done\r
381ENDIF;[32] ap6850\r
382\r
383IF apcps ;[22]\r
384sendbr:\r
385;\r
386; Ensure that the transmitter has finished sending buffered chars\r
387sndbr1: lda mnprts ; get UART status\r
388 ani TxEmpty ; everything sent?\r
389 jz sndbr1 ; no, wait a bit more\r
390;\r
391; Unmask command register\r
392 mvi a,80h\r
393 sta mnprtc\r
394;\r
395; Begin sending a break by setting bit in UART command register\r
396 mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS\r
397 sta mnprts\r
398;\r
399; Wait for 250 milliseconds (using hundredths second delay routine)\r
400 mvi a,25\r
401 call delay\r
402;\r
403; Resume normal operation by clearing the SendBreak command bit\r
404 mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS\r
405 sta mnprts\r
406;\r
407; Remask command register\r
408 mvi a,0\r
409 sta mnprtc\r
410;\r
411 ret ;done\r
412ENDIF;[22] apcps\r
413\r
414;\f\r
415\r
416;\r
417; sysflt - system-dependent filter\r
418; called with character in E.\r
419; if this character should not be printed, return with A = zero.\r
420; preserves bc, de, hl.\r
421; note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r
422sysflt:\r
423 mov a,e ; get character for testing\r
424\r
425 ret\r
426\r
427; mdmflt - modem filter [30]\r
428; called with character to be sent to printer in E\r
429; with parity set as appropriate.\r
430; return with accumulator = 0 do do nothing,\r
431; <> 0 to send char in E.\r
432mdmflt:\r
433 mov a,e ;[30] get character to test\r
434 ret\r
435\r
436\r
437\r
438; prtflt - printer filter [30]\r
439; called with character to be sent to printer in E\r
440; returns with a = 0 to do nothing\r
441; a <> 0 to print it.\r
442;\r
443; this routine for those printer that automatically insert\r
444; a lf on cr, or cr for lf. Should this be shifted to \r
445; the system indep. stuff, in say 4.06?\r
446prtflt:\r
447 mov a,e ; [30] get character to test\r
448\r
449 ret\r
450\r
451\r
452;\f\r
453\r
454;\r
455; system-dependent processing for BYE command.\r
456; for apmmdm, heath, and lobo, hang up the phone.\r
457sysbye:\r
458IF apmmdm\r
459 xra a ;Hangup our end, too.\r
460 sta mnmodm\r
461ENDIF;apmmdm\r
462\r
463 ret\r
464;\f\r
465\r
466; This is the system-dependent command to change the baud rate.\r
467; DE contains the two-byte value from the baud rate table; this\r
468; value is also stored in 'speed'.\r
469sysspd:\r
470\r
471; Set the speed for Apple with 6551 ACIA\r
472IF ap6551\r
473 lda mnprtc ;jb read control port\r
474 ani 0F0H ;jb zap low order nybble\r
475 ora e ;jb put rate in low order nybble\r
476 sta mnprtc ;jb send to control port\r
477 ret\r
478ENDIF;ap6551\r
479\r
480; Set the speed for Apple with CPS Multifunction card\r
481IF apcps ;[22]\r
482 mvi a,80h\r
483 sta mnprtc\r
484 lda mnprts ;read command register to reset 2651\r
485 mvi a,apmod1 ;first mode byte\r
486 sta mnport\r
487 mvi a,4 ;waste some time before sending second byte\r
488spdwt: dcr a ; 4 T-states\r
489 jnz spdwt ; 10 T-states\r
490 mov a,e ;second mode byte is speed byte\r
491 sta mnport\r
492 mvi a,apcmd ;command byte\r
493 sta mnprts\r
494 xra a\r
495 sta mnprtc\r
496 ret\r
497ENDIF;[22] apcps\r
498\r
499\r
500IF ap6551 ;jb\r
501spdtbl: db 0DH ;jb 13 entries\r
502 db 03H,'110$', 03H,03H ;jb\r
503 db 04H,'1200$', 08H,08H ;jb\r
504 db 05H,'134.5$', 04H,04H ;jb\r
505 db 03H,'150$', 05H,05H ;jb\r
506 db 04H,'1800$', 09H,09H ;jb\r
507 db 05H,'19200$', 0FH,0FH ;jb\r
508 db 04H,'2400$', 0AH,0AH ;jb\r
509 db 03H,'300$', 06H,06H ;jb\r
510 db 04H,'3600$', 0BH,0BH ;jb\r
511 db 04H,'4800$', 0CH,0CH ;jb\r
512 db 03H,'600$', 07H,07H ;jb\r
513 db 04H,'7200$', 0DH,0DH ;jb\r
514 db 04H,'9600$', 0EH,0EH ;jb\r
515\r
516sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800'\r
517 db cr,lf,' 2400 3600 4800 7200 9600 19200$'\r
518ENDIF;ap6551\r
519\r
520IF apcps ;[22]\r
521spdtbl: db 10H ; 16 entries\r
522 db 03H,'110$', 32h,32h\r
523 db 04H,'1200$', 37h,37h\r
524 db 05H,'134.5$', 33h,33h\r
525 db 03H,'150$', 34h,34h\r
526 db 04H,'1800$', 38h,38h\r
527 db 05H,'19200$', 3fh,3fh\r
528 db 04H,'2000$', 39h,39h\r
529 db 04H,'2400$', 3ah,3ah\r
530 db 03H,'300$', 35h,35h\r
531 db 04H,'3600$', 3bh,3bh\r
532 db 04H,'4800$', 3ch,3ch\r
533 db 02H,'50$', 30h,30h\r
534 db 03H,'600$', 36h,36h\r
535 db 04H,'7200$', 3dh,3dh\r
536 db 02H,'75$', 31h,31h\r
537 db 04H,'9600$', 3eh,3eh\r
538\r
539sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'\r
540 db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'\r
541ENDIF;[22] apcps\r
542\r
543\r
544\r
545; The following conditionals were once a huge if not statement. There\r
546; wasn't enough room to add the lobo to the list, so it had to be broken\r
547; into 2, which you can't do with an if not. I redid it as two ifs and\r
548; applied them to those that wouldn't set baud. [Hal Hostetler]\r
549IF apmmdm OR ap6850 ;[32]\r
550spdtbl equ 0 ; SET BAUD not supported.\r
551sphtbl equ 0\r
552ENDIF;appmdm OR ap6850 [32]\r
553;\r
554;\r
555; no ports available for Apple\r
556prttbl EQU 0 ;SET PORT not supported\r
557prhtbl EQU 0\r
558\r
559;\r
560;\f\r
561\r
562; This is the system-dependent SET PORT command.\r
563; HL contains the argument from the command table.\r
564sysprt:\r
565\r
566 ret\r
567;\f\r
568\r
569;\r
570; selmdm - select modem port\r
571; selcon - select console port\r
572; selmdm is called before using inpmdm or outmdm;\r
573; selcon is called before using inpcon or outcon.\r
574; For iobyt systems, diddle the I/O byte to select console or comm port;\r
575; For Decision I, switches Multi I/O board to console or modem serial\r
576; port. [Toad Hall]\r
577; For the rest, does nothing.\r
578; preserves bc, de, hl.\r
579selmdm:\r
580 ret\r
581\r
582selcon:\r
583 ret\r
584;\f\r
585\r
586; Get character from console, or return zero.\r
587; result is returned in A. destroys bc, de, hl.\r
588;\r
589inpcon:\r
590 mvi c,dconio ;Direct console I/O BDOS call.\r
591 mvi e,0FFH ;Input.\r
592 call BDOS\r
593 ret\r
594;\f\r
595\r
596;\r
597; Output character in E to the console.\r
598; destroys bc, de, hl\r
599;\r
600outcon:\r
601\r
602 mvi c,dconio ;Console output bdos call.\r
603 call bdos ;Output the char to the console.\r
604 ret\r
605;\f\r
606\r
607;\r
608; outmdm - output a char from E to the modem.\r
609; the parity bit has been set as necessary.\r
610; returns nonskip; bc, de, hl preserved.\r
611outmdm:\r
612IF apple \r
613 push h\r
614outmd1: lxi h,mnprts ;address of the port status register\r
615outmd2: mov a,m ; get port status in A\r
616 ani output ;Loop till ready.\r
617 jz outmd2\r
618outmd3: lxi h,mnport ;address of port data register\r
619 mov m,e ; write the character\r
620 pop h\r
621 ret\r
622ENDIF;apple \r
623\r
624\r
625\r
626\r
627;\f\r
628\r
629;\r
630; get character from modem; return zero if none available.\r
631; for IOBYT systems, the modem port has already been selected.\r
632; destroys bc, de, hl.\r
633inpmdm:\r
634IF apple \r
635inpmd1: lda mnprts ;Get the port status into A.\r
636 ani input ;See if the input ready bit is on.\r
637 rz ;If not then return.\r
638inpmd2: lda mnport ;If so, get the char.\r
639ENDIF;apple\r
640\r
641\r
642ret ; return with character in A\r
643\r
644\r
645;\r
646; flsmdm - flush comm line.\r
647; Modem is selected.\r
648; Currently, just gets characters until none are available.\r
649\r
650flsmdm: call inpmdm ; Try to get a character\r
651 ora a ; Got one?\r
652 jnz flsmdm ; If so, try for another\r
653 ret ; Receiver is drained. Return.\r
654;\f\r
655\r
656;\r
657; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.\r
658lptstat:\r
659 xra a\r
660 ret\r
661\r
662;\r
663; outlpt - output character in E to printer\r
664; console is selected.\r
665; preserves de.\r
666outlpt:\r
667 push d ; save DE in either case\r
668 call prtflt ; go through printer filter [30]\r
669 ana a ; if A = 0 do nothing,\r
670 jz outlp1 ; [30] if a=0 do nothing\r
671\r
672 mvi c,lstout\r
673 call bdos ;Char to printer\r
674\r
675outlp1: pop d ; restore saved register pair\r
676 ret\r
677;\f\r
678\r
679;\r
680; Screen manipulation routines\r
681; csrpos - move to row B, column C\r
682;\r
683; csrpos for terminals that use a leadin sequence followed\r
684; by (row + 31.) and (column + 31.)\r
685;\r
686csrpos: push b ; save coordinates\r
687 lxi d,curldn ; get cursor leadin sequence\r
688 call prtstr ; print it\r
689 pop h ; restore coordinates\r
690 mov a,h ; get row\r
691 adi (' '-1) ; space is row one\r
692 mov e,a\r
693 push h\r
694 call outcon ; output row\r
695 pop h\r
696 mov a,l ; get column\r
697 adi (' '-1) ; space is column one\r
698 mov e,a\r
699 jmp outcon ; output it and return\r
700\r
701;\r
702; delchr - make delete look like a backspace. Unless delete is a printing\r
703; character, we just need to print a backspace. (we'll output clrspc\r
704; afterwards)\r
705; For Kaypro and Vector General, delete puts a blotch on the screen.\r
706; For Apple and Osborne 1, delete moves but doesn't print.\r
707delchr:\r
708\r
709 lxi d,delstr\r
710 jmp prtstr\r
711\r
712; erase the character at the current cursor position\r
713clrspc: mvi e,' '\r
714 call outcon\r
715 mvi e,bs ;get a backspace\r
716 jmp outcon\r
717\r
718; erase the current line\r
719clrlin: lxi d,eralin\r
720 jmp prtstr\r
721\r
722; erase the whole screen, and go home. preserves b (but not c)\r
723clrtop: lxi d,erascr\r
724 jmp prtstr\r
725\r
726IF apple\r
727sysver: db 'Apple II CP/M$'\r
728outlin: db ('^'-100O),esc,'Y',cr,lf,' $'\r
729erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home.\r
730eralin: db cr,esc,'T$' ;Clear line.\r
731delstr: db bs,bs,'$' ; Adjust for delete\r
732curldn: db esc,'=$' ;Cursor lead-in\r
733ttab: ;Table start location.\r
734ta: db ('K'-100O),'$',0,0 ;Cursor up.\r
735tb: db 12O,'$',0,0 ;Cursor down.\r
736tc: db ('F'-100O),'$',0,0 ;Cursor right.\r
737td: db '$',0,0,0 ;(can't) Cursor left\r
738te: db '$',0,0,0 ;(can't) Clear display\r
739tf: db '$',0,0,0 ;(can't) Enter graphics mode\r
740tg: db '$',0,0,0 ;(can't) Exit graphics mode\r
741th: db ('^'-100O),'$',0,0 ;Cursor home.\r
742ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.\r
743tj: db esc,'Y$',0 ;Clear to end of screen.\r
744tk: db esc,'T$',0 ;Clear to end of line.\r
745ENDIF;apple\r
746\r
747ovlend equ $ ; End of overlay\r
748\r
749 END\r