]>
Commit | Line | Data |
---|---|---|
e58a7a25 L |
1 | IF NOT lasm\r |
2 | .printx * CPXAPP.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 | ; 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 | |
37 | family: db 'CPXAPP.ASM (2) 22-jul-87$' ; Used for family versions....\r | |
38 | ;\r | |
39 | \r | |
40 | IF apple\r | |
41 | .printx * Assembling KERMIT-80 for the Apple ][ *\r | |
42 | ENDIF;apple\r | |
43 | IF apmmdm\r | |
44 | .printx * with Z80 Softcard & Micromodem II *\r | |
45 | ENDIF;apmmdm\r | |
46 | IF ap6551\r | |
47 | .printx * with Z80 Softcard & 6551 ACIA *\r | |
48 | ENDIF;ap6551\r | |
49 | IF ap6850;[32]\r | |
50 | .printx * with Z80 Softcard & 6850 ACIA *\r | |
51 | ENDIF;ap6850 [32]\r | |
52 | IF apcps;[22]\r | |
53 | .printx * with Softcard & CPS Multifunction card *\r | |
54 | ENDIF;apcps\r | |
55 | \r | |
56 | ;\r | |
57 | \r | |
58 | IF ap6551 OR ap6850 OR apcps;[9] [14]\r | |
59 | ;jb eg. Apple SSC, Videx PSIO, Basis 108\r | |
60 | apslot EQU 2 ;jb set equal to slot containing serial card\r | |
61 | ;jb set to 1 for Basis built-in port\r | |
62 | ENDIF;jb ap6551 [9] apcps ap6850 [14]\r | |
63 | IF 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 | |
65 | apdat EQU 0DH ;data reg.=0E080h+apslot*10h*apdat\r | |
66 | apstat EQU 0CH ;comm/stat reg.=0E080h+apslot*10h+apstat\r | |
67 | ENDIF;ap6850\r | |
68 | \r | |
69 | \r | |
70 | IF apmmdm\r | |
71 | ;APPLE Slot 2 contains Micromodem II.\r | |
72 | MNPORT EQU 0E0A7H ;Communications Port.\r | |
73 | mnprts EQU 0E0A6H ;Communications Port Status.\r | |
74 | mnmodm EQU 0E0A5H ;Modem Control Port.\r | |
75 | orgmod EQU 8EH ;Modem Originate Mode.\r | |
76 | OUTPUT EQU 02H ;Output Buffer Empty.\r | |
77 | INPUT EQU 01H ;Input Register Full.\r | |
78 | apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)\r | |
79 | apinc2 EQU 11H ;Second Init Character for ACIA (8-bits)\r | |
80 | apoffh EQU 80H ;Set if OFFHOOK\r | |
81 | AP300 EQU 1 ;300 Baud\r | |
82 | z80 EQU TRUE ;Z80 Softcard\r | |
83 | ENDIF;apmmdm\r | |
84 | \r | |
85 | IF ap6551 ;jb\r | |
86 | mnport EQU 0E088H+(10H*apslot) ;jb Communications Port.\r | |
87 | mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status.\r | |
88 | mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control\r | |
89 | mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command)\r | |
90 | output EQU 10H ;jb Output Buffer Empty.\r | |
91 | input EQU 08H ;jb Input Register Full.\r | |
92 | mncinb EQU 18H ;jb Control Port Initialization Byte\r | |
93 | ;jb (8-bit, no parity, 1-stop, 1200 baud)\r | |
94 | mnminb EQU 0BH ;jb Master Port Initialization Byte\r | |
95 | ;jb (DTR, RTS, no interrupts)\r | |
96 | z80 EQU TRUE ;Z80 Softcard\r | |
97 | ENDIF;ap6551\r | |
98 | \r | |
99 | IF ap6850 ;[32]\r | |
100 | mnport EQU 0E080H+(10H*apslot)+apdat ;Communications Port.\r | |
101 | mnprts EQU 0E080H+(10H*apslot)+apstat ;Communications Port Status.\r | |
102 | OUTPUT EQU 02H ;Output Buffer Empty.\r | |
103 | INPUT EQU 01H ;Input Register Full.\r | |
104 | apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)\r | |
105 | apinc2 EQU 15H ;Second Init Character for ACIA (8 data, 1 stop bit)\r | |
106 | z80 EQU TRUE ;Z80 Softcard\r | |
107 | ENDIF;[32] ap6850\r | |
108 | \r | |
109 | IF apcps ;[22]\r | |
110 | mnport EQU 0E0FAH+(100H*apslot) ; Communications Port.\r | |
111 | mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status.\r | |
112 | mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control\r | |
113 | output EQU 1 ; Output Buffer Empty.\r | |
114 | input EQU 2 ; Input Register Full.\r | |
115 | TxEmpty EQU 04h ; Transmitter empty flag\r | |
116 | apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x)\r | |
117 | ; Mode Byte 2 is speed control byte\r | |
118 | apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE)\r | |
119 | z80 EQU TRUE ;Z80 Softcard\r | |
120 | ENDIF;[22] apcps\r | |
121 | \r | |
122 | IF apple \r | |
123 | defesc EQU ']'-100O ;The default escape character.\r | |
124 | ENDIF;apple \r | |
125 | \r | |
126 | \r | |
127 | ; default to VT52-EMULATION ON.\r | |
128 | \r | |
129 | vtval EQU 1\r | |
130 | \r | |
131 | \r | |
132 | \r | |
133 | sysxin: ; continuation of systemm dependent initialisation code\r | |
134 | \r | |
135 | IF 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 | |
145 | ENDIF;ap6551\r | |
146 | \r | |
147 | IF 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 | |
152 | ENDIF;[32] ap6850\r | |
153 | \r | |
154 | IF 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 | |
159 | ENDIF;[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 | |
168 | sysexit:\r | |
169 | \r | |
170 | ret\r | |
171 | \r | |
172 | ;\r | |
173 | ; system-dependent processing for start of CONNECT command\r | |
174 | ;\r | |
175 | syscon:\r | |
176 | IF apmmdm\r | |
177 | call ckdial ;See if dialing is required.\r | |
178 | jmp kermit ;Go to command loop if aborted.\r | |
179 | ENDIF;apmmdm\r | |
180 | \r | |
181 | ret\r | |
182 | \r | |
183 | conmsg: ; Messages printed when entering transparent (CONNECT) mode:\r | |
184 | ;\f\r | |
185 | \r | |
186 | IF 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 | |
196 | ckdial: 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 | |
218 | gtdial: 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 | |
229 | dialnz: mov e,a ;count pulses in E-reg\r | |
230 | dopuls: 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 | |
243 | dialed: 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 | |
249 | tictoc: 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 | |
265 | nodial: xra a ;Hangup the modem.\r | |
266 | sta mnmodm\r | |
267 | ret ;Return to abort the command.\r | |
268 | ;\r | |
269 | holdd: db 0 ;Modem setup code\r | |
270 | dialms: DB 'Number to Dial: $'\r | |
271 | dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$'\r | |
272 | dialm3: DB cr,lf,'Connected.',CR,LF,'$'\r | |
273 | ;\r | |
274 | ;DELAY wait for the number of millisecs in B,C\r | |
275 | ;\r | |
276 | delay: push b ;save B,C\r | |
277 | push d ;save D,E\r | |
278 | inr b ;bump B for later DCR\r | |
279 | ;\r | |
280 | delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80\r | |
281 | ;clock=2.041MHz)\r | |
282 | ;\r | |
283 | delay2: 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 | |
293 | ENDIF;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 | |
300 | syscls:\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 | |
309 | sysinh:\r | |
310 | IF apmmdm OR apcps OR ap6850 ;\r | |
311 | lxi d,inhlps ; we got options...\r | |
312 | call prtstr ; print them.\r | |
313 | ENDIF ;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 | |
320 | inhlps:\r | |
321 | \r | |
322 | IF apcps OR ap6850\r | |
323 | db cr,lf,'B Transmit a BREAK'\r | |
324 | ENDIF;apcps OR ap6850\r | |
325 | \r | |
326 | IF apmmdm \r | |
327 | db cr,lf,'D Drop the line'\r | |
328 | ENDIF;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 | |
339 | sysint: ani 137O ; convert lower case to upper, for testing...\r | |
340 | IF 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 | |
346 | intc00:\r | |
347 | ENDIF;apmmdm\r | |
348 | \r | |
349 | IF 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 | |
352 | ENDIF;[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 | |
359 | IF ap6850 ;[32]\r | |
360 | sendbr:\r | |
361 | ;\r | |
362 | ; Ensure that the transmitter has finished sending buffered chars\r | |
363 | sndbr1: 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 | |
381 | ENDIF;[32] ap6850\r | |
382 | \r | |
383 | IF apcps ;[22]\r | |
384 | sendbr:\r | |
385 | ;\r | |
386 | ; Ensure that the transmitter has finished sending buffered chars\r | |
387 | sndbr1: 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 | |
412 | ENDIF;[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 | |
422 | sysflt:\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 | |
432 | mdmflt:\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 | |
446 | prtflt:\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 | |
457 | sysbye:\r | |
458 | IF apmmdm\r | |
459 | xra a ;Hangup our end, too.\r | |
460 | sta mnmodm\r | |
461 | ENDIF;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 | |
469 | sysspd:\r | |
470 | \r | |
471 | ; Set the speed for Apple with 6551 ACIA\r | |
472 | IF 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 | |
478 | ENDIF;ap6551\r | |
479 | \r | |
480 | ; Set the speed for Apple with CPS Multifunction card\r | |
481 | IF 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 | |
488 | spdwt: 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 | |
497 | ENDIF;[22] apcps\r | |
498 | \r | |
499 | \r | |
500 | IF ap6551 ;jb\r | |
501 | spdtbl: 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 | |
516 | sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800'\r | |
517 | db cr,lf,' 2400 3600 4800 7200 9600 19200$'\r | |
518 | ENDIF;ap6551\r | |
519 | \r | |
520 | IF apcps ;[22]\r | |
521 | spdtbl: 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 | |
539 | sphtbl: 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 | |
541 | ENDIF;[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 | |
549 | IF apmmdm OR ap6850 ;[32]\r | |
550 | spdtbl equ 0 ; SET BAUD not supported.\r | |
551 | sphtbl equ 0\r | |
552 | ENDIF;appmdm OR ap6850 [32]\r | |
553 | ;\r | |
554 | ;\r | |
555 | ; no ports available for Apple\r | |
556 | prttbl EQU 0 ;SET PORT not supported\r | |
557 | prhtbl 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 | |
564 | sysprt:\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 | |
579 | selmdm:\r | |
580 | ret\r | |
581 | \r | |
582 | selcon:\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 | |
589 | inpcon:\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 | |
600 | outcon:\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 | |
611 | outmdm:\r | |
612 | IF apple \r | |
613 | push h\r | |
614 | outmd1: lxi h,mnprts ;address of the port status register\r | |
615 | outmd2: mov a,m ; get port status in A\r | |
616 | ani output ;Loop till ready.\r | |
617 | jz outmd2\r | |
618 | outmd3: lxi h,mnport ;address of port data register\r | |
619 | mov m,e ; write the character\r | |
620 | pop h\r | |
621 | ret\r | |
622 | ENDIF;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 | |
633 | inpmdm:\r | |
634 | IF apple \r | |
635 | inpmd1: 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 | |
638 | inpmd2: lda mnport ;If so, get the char.\r | |
639 | ENDIF;apple\r | |
640 | \r | |
641 | \r | |
642 | ret ; 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 | |
650 | flsmdm: 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 | |
658 | lptstat:\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 | |
666 | outlpt:\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 | |
675 | outlp1: 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 | |
686 | csrpos: 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 | |
707 | delchr:\r | |
708 | \r | |
709 | lxi d,delstr\r | |
710 | jmp prtstr\r | |
711 | \r | |
712 | ; erase the character at the current cursor position\r | |
713 | clrspc: 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 | |
719 | clrlin: lxi d,eralin\r | |
720 | jmp prtstr\r | |
721 | \r | |
722 | ; erase the whole screen, and go home. preserves b (but not c)\r | |
723 | clrtop: lxi d,erascr\r | |
724 | jmp prtstr\r | |
725 | \r | |
726 | IF apple\r | |
727 | sysver: db 'Apple II CP/M$'\r | |
728 | outlin: db ('^'-100O),esc,'Y',cr,lf,' $'\r | |
729 | erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home.\r | |
730 | eralin: db cr,esc,'T$' ;Clear line.\r | |
731 | delstr: db bs,bs,'$' ; Adjust for delete\r | |
732 | curldn: db esc,'=$' ;Cursor lead-in\r | |
733 | ttab: ;Table start location.\r | |
734 | ta: db ('K'-100O),'$',0,0 ;Cursor up.\r | |
735 | tb: db 12O,'$',0,0 ;Cursor down.\r | |
736 | tc: db ('F'-100O),'$',0,0 ;Cursor right.\r | |
737 | td: db '$',0,0,0 ;(can't) Cursor left\r | |
738 | te: db '$',0,0,0 ;(can't) Clear display\r | |
739 | tf: db '$',0,0,0 ;(can't) Enter graphics mode\r | |
740 | tg: db '$',0,0,0 ;(can't) Exit graphics mode\r | |
741 | th: db ('^'-100O),'$',0,0 ;Cursor home.\r | |
742 | ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.\r | |
743 | tj: db esc,'Y$',0 ;Clear to end of screen.\r | |
744 | tk: db esc,'T$',0 ;Clear to end of line.\r | |
745 | ENDIF;apple\r | |
746 | \r | |
747 | ovlend equ $ ; End of overlay\r | |
748 | \r | |
749 | END\r |