]> cloudbase.mooo.com Git - kermit-80.git/blame - cpxbbi.asm
Add AVR-CP/M system (cpxac.asm) and a Makefile
[kermit-80.git] / cpxbbi.asm
CommitLineData
e58a7a25
L
1IF NOT lasm\r
2.printx * CPXBBI.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.08\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; revision history:\r
24;\r
25;edit 4, 7-Jan-1991 by MF. Added code to support the Ampro Little Board.\r
26; The code was contributed by Jay S. Rouman; 913 North Drive;\r
27; Mt. Pleasant, MI 48858 (voice (517)773-7887).\r
28; edit 3, 23 July by OBSchou to massage file to suit CPXCOM.ASM\r
29;\r
30; edit 2 23 May 1987 by C.J.MILES@UMRCC.\r
31; Reorganised file to be similar in structure to that\r
32; of the Amstrad sys-dep file. Added hangup in clear\r
33; screen options in CONNECT mode.\r
34;\r
35; edit 1 10 May 1987 by Chris Miles (C.J.MILES@UMRCC)\r
36; Removed Kaypro, Xerox and Big Board from CPXSYS.ASM\r
37; and grouped them into this file as CPXBBI.ASM.\r
38;\r
39;\r
40;\r
41; Original code broken off and modified by:\r
42;\r
43; Chris Miles\r
44; 344, Claremont Road,\r
45; Rusholme,\r
46; MANCHESTER,\r
47; M14 6WB.\r
48;\r
49; Tel: (061) 226 7839\r
50;\r
51\r
52;\r
53; *** MAIN CODE START ***\r
54;\r
55;\r
56; Keep module name, edit number, and last revision date in memory.\r
57\r
58sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$'\r
59family: db 'CPXBBI.ASM (4) 7-Jan-1991$'\r
60\r
61\r
62; Assembly time message announcing which version we're building\r
63\r
64IF kpii\r
65.printx * Assembling Kaypro II KERMIT-80 *\r
66ENDIF\r
67\r
68IF xer820\r
69.printx * Assembling Xerox 820 KERMIT-80 *\r
70ENDIF\r
71\r
72IF bbII\r
73.printx * Assembling BigBoard II KERMIT-80 *\r
74ENDIF\r
75\r
76IF ampro\r
77.printx * Assembling Ampro Little Board KERMIT-80 *\r
78ENDIF\r
79\r
80z80 EQU TRUE ; They all use Z80s\r
81\r
82IF xer820\r
83defesc EQU ']'-100O ;The default escape character for Xerox\r
84ENDIF;xer820\r
85\r
86IF kpII\r
87defesc EQU '\'-100O ;The default escape character for Kaypro\r
88ENDIF;kpII\r
89\r
90; If one of the above, default to VT52-EMULATION ON.\r
91IF kpII OR xer820\r
92vtval EQU 1\r
93ENDIF;kpII OR xer820\r
94\r
95\r
96;\r
97; Specific machine hardware information\r
98;\r
99IF bbI\r
100mnport equ 04h ; Modem data port\r
101mnprts equ 06h ; Modem status port\r
102output equ 04h ; Transmit buffer empty\r
103input equ 01h ; Receive data available\r
104baudrt equ 00h ; Baud rate port for channel A\r
105ENDIF;bbI\r
106\r
107\r
108IF bbII\r
109mnport equ 80h ; Modem data port (SIO channel A)\r
110mnprts equ 81h ; Modem status port\r
111output equ 04h ; Transmit buffer empty\r
112input equ 01h ; Receive data available\r
113baudrt equ 89h ; Baud rate port for channel A\r
114ENDIF;bbII\r
115\r
116IF ampro\r
117mnport equ 88h ; Modem data port (SIO channel B)\r
118mnprts equ 8Ch ; Modem status port\r
119output equ 04h ; Transmit buffer empty\r
120input equ 01h ; Receive data available\r
121baudrt equ 50h ; Baud rate port for channel B\r
122ENDIF;ampro\r
123;\r
124\r
125sysxin: ;continuation of system initialisation code\r
126 lxi d,siotbl ; Load the address of the status able\r
127 mvi c,siolen ; Length of status table\r
128siolup: ; Loop back here for each command byte\r
129 ldax d ; Load the first byte into A\r
130 inx d ; Index the pointer\r
131 out mnprts ; Send it to the status port\r
132 dcr c ; Decrement the byte counter\r
133 jnz siolup ; Jump back for more commands\r
134 ret ; return from system-dependent routine\r
135\r
136; List of commands to set up SIO channel A for asynchronous operation.\r
137\r
138siotbl: DB 18H ; Channel reset\r
139 DB 18H ; another, in case register 0 wasn't selected\r
140 DB 04H ; Select register 4\r
141 DB 44H ; 1 stop bit, clock*16\r
142 DB 01H ; Select register 1\r
143 DB 00H ; No interrupts enabled\r
144 DB 03H ; Select register 3\r
145 DB 0C1H ; Rx enable, 8 bit Rx character\r
146 DB 05H ; Select register 5\r
147 DB 0EAH ; Tx enable, 8 bit Tx character,\r
148 ; raise DTR and RTS\r
149siolen equ $-siotbl ; length of command list\r
150\r
151\r
152;\r
153; sysexit - System-dependent termination processing\r
154; if we've changed anything, this is our last\r
155; chance to put it back.\r
156;\r
157sysexit:\r
158 ret\r
159\r
160;\r
161; syscon - System-dependent processing for start\r
162; of CONNECT command.\r
163;\r
164syscon:\r
165 lxi d,conmsg\r
166 call prtstr\r
167 ret\r
168\r
169conmsg: ; Messages printed when entering transparent (CONNECT) mode:\r
170 db cr,lf,'$'\r
171;\r
172; syscls - system-dependent close routine\r
173; called when exiting transparent session.\r
174;\r
175syscls:\r
176 ret\r
177;\r
178; sysinh - help for system-dependent special functions.\r
179; called in response to <escape>?, after listing\r
180; all the system-independent escape sequences.\r
181;\r
182sysinh:\r
183 lxi d,inhlps ; we got options...\r
184 call prtstr ; print them.\r
185 ret\r
186\r
187\r
188; additional, system-dependent help for transparent mode\r
189; (two-character escape sequences)\r
190inhlps:\r
191 db cr,lf,'B Transmit a BREAK'\r
192 db cr,lf,'H Hangup using DTR'\r
193 db cr,lf,'W Wipe screen clear'\r
194 db '$'\r
195\r
196; sysint - system dependent special functions\r
197; called when transparent escape character has been typed;\r
198; the second character of the sequence is in A (and in B).\r
199; returns:-\r
200; non-skip: sequence has been processed\r
201; skip : sequence was not recognized\r
202;\r
203sysint: ani 137O ; convert lower case to upper, for testing...\r
204 cpi 'B' ; send break ?\r
205 jz sendbr ; then jump to send break routine\r
206 cpi 'H' ; hang up ?\r
207 jz hangup ; then jump to hangup routine\r
208 cpi 'W' ; clear screen ?\r
209 jz clrtop ; then jump to clear screen routine\r
210 jmp rskp ; take skip return - command not recognized.\r
211\r
212;\r
213; Hangup and Break routines\r
214;\r
215hangup:\r
216 mvi d,0ah ; set up hangup bit mask\r
217 mvi e,255 ; time for hangup is 2 1/2 secs\r
218 jmp setbit ; skip Tx empty test\r
219\r
220sendbr:\r
221 mvi d,9ah ; set up break bit mask\r
222 mvi e,30 ; time for break is 300 ms\r
223\r
224sndbr1: mvi a,1 ; select Read Register 1\r
225 out mnprts\r
226 in mnprts ; read the contents\r
227 ani 1 ; test "all done" flag\r
228 jz sndbr1 ; loop until it's nonzero.\r
229;\r
230; Next, set the break or DTR bit on the SIO\r
231;\r
232setbit: \r
233 mvi a,5 ; select Write Register 5\r
234 out mnprts\r
235 mvi a,6ah ; Tx enable, 8 bit Tx character,\r
236 ora d ; OR with appropriate bit mask\r
237 out mnprts ; \r
238;\r
239; Now, delay for duration of hangup or break\r
240 mov a,e ; delay count\r
241 call delay\r
242;\r
243; Time's up. Put transmitter back in normal state and return.\r
244 mvi a,5 ; select Write Register 5\r
245 out mnprts\r
246 mvi a,0eah ; Tx enable, 8 bit Tx character,\r
247 out mnprts ;.\r
248 ret ; done.\r
249\r
250; sysflt - system-dependent filter\r
251; called with character in E.\r
252; if this character should not be printed, return with A = zero.\r
253; preserves bc, de, hl.\r
254; note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r
255;\r
256sysflt:\r
257 mov a,e ; get character for testing\r
258 ret\r
259\r
260;\r
261; sysbye - system-dependent processing for BYE command.\r
262;\r
263sysbye:\r
264 ret\r
265;\r
266; This is the system-dependent command to change the baud rate.\r
267; DE contains the two-byte value from the baud rate table; this\r
268; value is also stored in 'speed'.\r
269;\r
270sysspd:\r
271\r
272; Set the speed for bigboard II\r
273IF bbII\r
274 di ; don't let anything between the data bytes\r
275 mvi a,01000111b ; get the command byte (load time constant)\r
276 out baudrt ; output it to CTC\r
277 mov a,e ; Get the parsed value.\r
278 out baudrt ; Tell the baud rate generator.\r
279 ei ; end of critical section\r
280 ret\r
281ENDIF;bbII\r
282\r
283\r
284; Set the speed for bigboard I\r
285IF bbI\r
286 mov a,e ; get the parsed value\r
287 out baudrt ; Tell the baud rate generator.\r
288 ret\r
289ENDIF;bbI\r
290\r
291; set the speed for the Ampro Little Board\r
292if ampro\r
293 mvi e,3fh ; offset to port b ctc 3f hex bytes\r
294 call getbios\r
295 mvi a,47h ; counter mode,ctc reset,value follows\r
296 mov m,a ; store value\r
297 lda speed+1 ; get ctc divisor\r
298 inx h ; location of ctc divisor\r
299 mov m,a ; store new divisor\r
300;\r
301; set up wr4 clock divisor according to mspeed\r
302;\r
303 mvi e,50h ; offset to dart wr4\r
304 call getbios\r
305 mvi a,3fh ; mask for wr4 clock bits\r
306 ana m ; mask off bits\r
307 mov m,a ; and save to wr4\r
308 lda speed ; get clock flag\r
309 ora a ; set flags, zero = 300 bps\r
310 mvi a,80h ; x32 clock bit\r
311 jz lbps ; setup wr4 for 300 bps x32 clock\r
312;\r
313; set up wr4 value for 1200 bps x16 clock 'hl' has wr4 loc\r
314;\r
315hbps: mvi a,40h ; x16 clock\r
316;\r
317; setup wr4 value for 300 bps x32 clock 'hl' has wr4 loc\r
318;\r
319lbps: ora m ; set clock bits saving parity\r
320 mov m,a ; store new clock divisor to wr4 value\r
321;\r
322; initialize sio/dart\r
323;\r
324intsio: lxi h,intend\r
325 push h ; set up for return\r
326 mvi e,36h ; offset to ioinit\r
327 call getbios\r
328 pchl ; we pushed return address\r
329intend: ret\r
330\r
331;\r
332; return bios location in 'hl' called with offset in 'e'\r
333;\r
334getbios:\r
335 lhld 1 ; get bios location\r
336 mvi d,0 ; clear 'd'\r
337 dad d\r
338 ret\r
339;\r
340ENDIF;ampro\r
341\r
342;\r
343; Speed tables\r
344; (Note that speed tables MUST be in alphabetical order for later\r
345; lookup procedures, and must begin with a value showing the total\r
346; number of entries. The speed help tables are just for us poor\r
347; humans.\r
348\r
349; db string length,string,divisor (2 identical bytes or 1 word)\r
350; [Toad Hall]\r
351\r
352IF bbI\r
353spdtbl: db 10h ;16 entries\r
354 db 03h,'110$', 02h,02h\r
355 db 04h,'1200$', 07h,07h\r
356 db 05h,'134.5$', 03h,03h\r
357 db 03h,'150$', 04h,04h\r
358 db 04h,'1800$', 08h,08h\r
359 db 05h,'19200$', 0fh,0fh\r
360 db 04h,'2000$', 09h,09h\r
361 db 04h,'2400$', 0ah,0ah\r
362 db 03h,'300$', 05h,05h\r
363 db 04h,'3600$', 0bh,0bh\r
364 db 04h,'4800$', 0ch,0ch\r
365 db 02h,'50$', 00h,00h\r
366 db 03h,'600$', 06h,06h\r
367 db 04h,'7200$', 0dh,0dh\r
368 db 02h,'75$', 01h,01h\r
369 db 04h,'9600$', 0eh,0eh\r
370\r
371sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'\r
372 db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'\r
373ENDIF;bbI\r
374\r
375IF bbII\r
376spdtbl: db 8 ; 8 entries\r
377 db 04h,'1200$', 20h,20h\r
378 db 05h,'19200$', 02h,02h\r
379 db 04h,'2400$', 10h,10h\r
380 db 03h,'300$', 80h,80h\r
381 db 05h,'38400$', 01h,01h\r
382 db 04h,'4800$', 08h,08h\r
383 db 03h,'600$', 40h,40h\r
384 db 04h,'9600$', 04h,04h\r
385\r
386sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$'\r
387ENDIF;bbII\r
388\r
389\r
390IF ampro\r
391spdtbl: db 6 ; 6 entries\r
392 db 04h,'1200$', 1,104\r
393 db 04h,'2400$', 1,52\r
394 db 03h,'300$', 0,208\r
395 db 04h,'4800$', 1,26\r
396 db 03h,'600$', 1,208\r
397 db 04h,'9600$', 1,13\r
398\r
399sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'\r
400ENDIF;ampro\r
401\r
402; This is the system-dependent SET PORT command.\r
403; HL contains the argument from the command table.\r
404;\r
405sysprt:\r
406 ret\r
407;\r
408\r
409prttbl equ 0 ; SET PORT is not supported\r
410prhtbl equ 0\r
411\r
412;\r
413; selmdm - select modem port\r
414; selcon - select console port\r
415; selmdm is called before using inpmdm or outmdm;\r
416; selcon is called before using inpcon or outcon.\r
417; preserves BC, DE, HL.\r
418;\r
419selmdm:\r
420selcon:\r
421 ret\r
422;\r
423; Get character from console, or return zero.\r
424; result is returned in A. destroys bc, de, hl.\r
425;\r
426inpcon:\r
427 mvi c,dconio ;Direct console I/O BDOS call.\r
428 mvi e,0FFH ;Input.\r
429 call BDOS\r
430 ret\r
431;\r
432;\r
433; Output character in E to the console.\r
434; destroys bc, de, hl\r
435;\r
436outcon:\r
437\r
438 mvi c,dconio ;Console output bdos call.\r
439 call bdos ;Output the char to the console.\r
440\r
441 ret\r
442;\r
443;\r
444; outmdm - output a char from E to the modem.\r
445; the parity bit has been set as necessary.\r
446; returns nonskip; bc, de, hl preserved.\r
447outmdm:\r
448 in mnprts ;Get the output done flag.\r
449 ani output ;Is it set?\r
450 jz outmdm ;If not, loop until it is.\r
451 mov a,e\r
452 out mnport ;Output it.\r
453 ret\r
454\r
455\r
456;\r
457; get character from modem; return zero if none available.\r
458; destroys bc, de, hl.\r
459inpmdm:\r
460 in mnprts ;Get the port status into A.\r
461 ani input ;See if the input ready bit is on.\r
462 rz ;If not then return.\r
463 in mnport ;If so, get the char.\r
464\r
465 ret ; return with character in A\r
466\r
467\r
468;\r
469; flsmdm - flush comm line.\r
470; Modem is selected.\r
471; Currently, just gets characters until none are available.\r
472\r
473flsmdm: call inpmdm ; Try to get a character\r
474 ora a ; Got one?\r
475 jnz flsmdm ; If so, try for another\r
476 ret ; Receiver is drained. Return.\r
477;\r
478; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.\r
479lptstat:\r
480 xra a ; assume it is ok.. this may not be necessary\r
481 ret\r
482\r
483;\r
484; outlpt - output character in E to printer\r
485; console is selected.\r
486; preserves de.\r
487outlpt:\r
488 push d ; save DE in either case\r
489 ana a ; if A = 0 do nothing,\r
490 jz outlp1 ; [30] if a=0 do nothing\r
491 mvi c,lstout\r
492 call bdos ;Char to printer\r
493outlp1: pop d ; restore saved register pair\r
494 ret\r
495;\f\r
496\r
497;\r
498; Screen manipulation routines\r
499; csrpos - move to row B, column C\r
500;\r
501; csrpos for terminals that use a leadin sequence followed\r
502; by (row + 31.) and (column + 31.)\r
503;\r
504IF NOT (bbII OR ampro) ;[obs I think ]\r
505csrpos: push b ; save coordinates\r
506 lxi d,curldn ; get cursor leadin sequence\r
507 call prtstr ; print it\r
508 pop h ; restore coordinates\r
509 mov a,h ; get row\r
510 adi (' '-1) ; space is row one\r
511 mov e,a\r
512 push h\r
513 call outcon ; output row\r
514 pop h\r
515 mov a,l ; get column\r
516 adi (' '-1) ; space is column one\r
517 mov e,a\r
518 jmp outcon ; output it and return\r
519ENDIF ; NOT bbII OR ampro\r
520\r
521;\r
522; delchr - make delete look like a backspace. Unless delete is a\r
523; printing character, we just need to print a backspace\r
524; (we'll output clrsp afterwards)\r
525delchr:\r
526\r
527IF bbI\r
528 lxi d,delstr\r
529 jmp prtstr\r
530ENDIF;bbI\r
531\r
532\r
533IF NOT bbI\r
534 mvi e,bs ;get a backspace\r
535 jmp outcon\r
536ENDIF;NOT bbI\r
537\r
538; erase the character at the current cursor position\r
539clrspc: mvi e,' '\r
540 call outcon\r
541 mvi e,bs ;get a backspace\r
542 jmp outcon\r
543\r
544; erase the current line\r
545clrlin: lxi d,eralin\r
546 jmp prtstr\r
547\r
548; erase the whole screen, and go home. preserves b (but not c)\r
549clrtop: lxi d,erascr\r
550 jmp prtstr\r
551\r
552; If its a BigBoard or Ampro, we need a terminal, so link to CPXVDU.ASM\r
553IF bbII\r
554sysver: db 'Big Board II$'\r
555ENDIF;bbII\r
556\r
557IF ampro\r
558sysver: db 'Ampro Little Board$'\r
559ENDIF;ampro\r
560\r
561IF (bbII AND lasm) ; we need a terminal as well\r
562LINK CPXVDU.ASM\r
563ENDIF ;(bbII AND lasm)\r
564\r
565IF (ampro AND lasm) ; we need a terminal as well\r
566LINK CPXVDU.ASM\r
567ENDIF ;(ampro AND lasm)\r
568\r
569;If here, we are Kaypro or Xerox 820, or if from M80, we should skip\r
570; a few lines if Bigboard.\r
571\r
572IF kpii\r
573sysver:\r
574ttytyp: db 'Kaypro II$'\r
575outlin: db subt,cr,lf,tab,tab,'$'\r
576erascr: db subt,'$' ;Clear screen and home.\r
577eralin: db cr,18H,'$' ;Clear line.\r
578curldn: db esc,'=$' ;Cursor lead-in\r
579delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character\r
580ttab: ;Table start location.\r
581ta: db 0BH,'$',0,0 ;Cursor up.\r
582tb: db 0AH,'$',0,0 ;Cursor down.\r
583tc: db 0CH,'$',0,0 ;Cursor right.\r
584td: db bs,'$',0,0 ;Cursor left\r
585te: db subt,'$',0,0 ;Clear display\r
586tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek)\r
587tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII)\r
588th: db 1EH,'$',0,0 ; Cursor home. [UTK016]\r
589ti: db esc,'E','$',0 ; Reverse linefeed. (insert line)\r
590tj: db 'W'-100O,'$',0,0 ; Clear to end of screen.\r
591tk: db 'X'-100O,'$',0,0 ; Clear to end of line.\r
592ENDIF ; kpii\r
593;\f\r
594\r
595IF xer820\r
596ttytyp:\r
597sysver: db 'Xerox 820$'\r
598outlin: db subt,cr,lf,tab,tab,'$'\r
599erascr: db subt,'$' ;Clear screen and home.\r
600eralin: db cr,18H,'$' ;Clear line.\r
601curldn: db esc,'=$' ;Cursor lead-in\r
602delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character\r
603ttab: ;Table start location.\r
604ta: db 0BH,'$',0,0 ;Cursor up.\r
605tb: db 0AH,'$',0,0 ;Cursor down.\r
606tc: db 0CH,'$',0,0 ;Cursor right.\r
607td: db bs,'$',0,0 ;Cursor left\r
608te: db subt,'$',0,0 ;Clear display\r
609tf: db '$',0,0,0 ; Enter Graphics Mode (can't)\r
610tg: db '$',0,0,0 ; Exit Graphics mode (can't)\r
611th: db 1EH,'$',0,0 ; Cursor home. [UTK016]\r
612ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up)\r
613tj: db 11H,'$',0,0 ; Clear to end of screen.\r
614tk: db 18H,'$',0,0 ; Clear to end of line.\r
615ENDIF ; xer820\r
616ovlend equ $ ; End of overlay\r
617\r
618 END\r