diff options
| author | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
|---|---|---|
| committer | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
| commit | ebb2ff2af569d5822b70ee555a32d27cf7494816 (patch) | |
| tree | 7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpxbbi.asm | |
| download | kermit-80-main.tar.gz kermit-80-main.zip | |
Diffstat (limited to 'src/cpxbbi.asm')
| -rw-r--r-- | src/cpxbbi.asm | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/src/cpxbbi.asm b/src/cpxbbi.asm new file mode 100644 index 0000000..ffbdc14 --- /dev/null +++ b/src/cpxbbi.asm @@ -0,0 +1,618 @@ +IF NOT lasm +.printx * CPXBBI.ASM * +ENDIF ;NOT lasm +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.08 +; +; Copyright June 1981,1982,1983,1984,1985 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; +; +; revision history: +; +;edit 4, 7-Jan-1991 by MF. Added code to support the Ampro Little Board. +; The code was contributed by Jay S. Rouman; 913 North Drive; +; Mt. Pleasant, MI 48858 (voice (517)773-7887). +; edit 3, 23 July by OBSchou to massage file to suit CPXCOM.ASM +; +; edit 2 23 May 1987 by C.J.MILES@UMRCC. +; Reorganised file to be similar in structure to that +; of the Amstrad sys-dep file. Added hangup in clear +; screen options in CONNECT mode. +; +; edit 1 10 May 1987 by Chris Miles (C.J.MILES@UMRCC) +; Removed Kaypro, Xerox and Big Board from CPXSYS.ASM +; and grouped them into this file as CPXBBI.ASM. +; +; +; +; Original code broken off and modified by: +; +; Chris Miles +; 344, Claremont Road, +; Rusholme, +; MANCHESTER, +; M14 6WB. +; +; Tel: (061) 226 7839 +; + +; +; *** MAIN CODE START *** +; +; +; Keep module name, edit number, and last revision date in memory. + +sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$' +family: db 'CPXBBI.ASM (4) 7-Jan-1991$' + + +; Assembly time message announcing which version we're building + +IF kpii +.printx * Assembling Kaypro II KERMIT-80 * +ENDIF + +IF xer820 +.printx * Assembling Xerox 820 KERMIT-80 * +ENDIF + +IF bbII +.printx * Assembling BigBoard II KERMIT-80 * +ENDIF + +IF ampro +.printx * Assembling Ampro Little Board KERMIT-80 * +ENDIF + +z80 EQU TRUE ; They all use Z80s + +IF xer820 +defesc EQU ']'-100O ;The default escape character for Xerox +ENDIF;xer820 + +IF kpII +defesc EQU '\'-100O ;The default escape character for Kaypro +ENDIF;kpII + +; If one of the above, default to VT52-EMULATION ON. +IF kpII OR xer820 +vtval EQU 1 +ENDIF;kpII OR xer820 + + +; +; Specific machine hardware information +; +IF bbI +mnport equ 04h ; Modem data port +mnprts equ 06h ; Modem status port +output equ 04h ; Transmit buffer empty +input equ 01h ; Receive data available +baudrt equ 00h ; Baud rate port for channel A +ENDIF;bbI + + +IF bbII +mnport equ 80h ; Modem data port (SIO channel A) +mnprts equ 81h ; Modem status port +output equ 04h ; Transmit buffer empty +input equ 01h ; Receive data available +baudrt equ 89h ; Baud rate port for channel A +ENDIF;bbII + +IF ampro +mnport equ 88h ; Modem data port (SIO channel B) +mnprts equ 8Ch ; Modem status port +output equ 04h ; Transmit buffer empty +input equ 01h ; Receive data available +baudrt equ 50h ; Baud rate port for channel B +ENDIF;ampro +; + +sysxin: ;continuation of system initialisation code + lxi d,siotbl ; Load the address of the status able + mvi c,siolen ; Length of status table +siolup: ; Loop back here for each command byte + ldax d ; Load the first byte into A + inx d ; Index the pointer + out mnprts ; Send it to the status port + dcr c ; Decrement the byte counter + jnz siolup ; Jump back for more commands + ret ; return from system-dependent routine + +; List of commands to set up SIO channel A for asynchronous operation. + +siotbl: DB 18H ; Channel reset + DB 18H ; another, in case register 0 wasn't selected + DB 04H ; Select register 4 + DB 44H ; 1 stop bit, clock*16 + DB 01H ; Select register 1 + DB 00H ; No interrupts enabled + DB 03H ; Select register 3 + DB 0C1H ; Rx enable, 8 bit Rx character + DB 05H ; Select register 5 + DB 0EAH ; Tx enable, 8 bit Tx character, + ; raise DTR and RTS +siolen equ $-siotbl ; length of command list + + +; +; sysexit - System-dependent termination processing +; if we've changed anything, this is our last +; chance to put it back. +; +sysexit: + ret + +; +; syscon - System-dependent processing for start +; of CONNECT command. +; +syscon: + lxi d,conmsg + call prtstr + ret + +conmsg: ; Messages printed when entering transparent (CONNECT) mode: + db cr,lf,'$' +; +; syscls - system-dependent close routine +; called when exiting transparent session. +; +syscls: + ret +; +; sysinh - help for system-dependent special functions. +; called in response to <escape>?, after listing +; all the system-independent escape sequences. +; +sysinh: + lxi d,inhlps ; we got options... + call prtstr ; print them. + ret + + +; additional, system-dependent help for transparent mode +; (two-character escape sequences) +inhlps: + db cr,lf,'B Transmit a BREAK' + db cr,lf,'H Hangup using DTR' + db cr,lf,'W Wipe screen clear' + db '$' + +; sysint - system dependent special functions +; called when transparent escape character has been typed; +; the second character of the sequence is in A (and in B). +; returns:- +; non-skip: sequence has been processed +; skip : sequence was not recognized +; +sysint: ani 137O ; convert lower case to upper, for testing... + cpi 'B' ; send break ? + jz sendbr ; then jump to send break routine + cpi 'H' ; hang up ? + jz hangup ; then jump to hangup routine + cpi 'W' ; clear screen ? + jz clrtop ; then jump to clear screen routine + jmp rskp ; take skip return - command not recognized. + +; +; Hangup and Break routines +; +hangup: + mvi d,0ah ; set up hangup bit mask + mvi e,255 ; time for hangup is 2 1/2 secs + jmp setbit ; skip Tx empty test + +sendbr: + mvi d,9ah ; set up break bit mask + mvi e,30 ; time for break is 300 ms + +sndbr1: mvi a,1 ; select Read Register 1 + out mnprts + in mnprts ; read the contents + ani 1 ; test "all done" flag + jz sndbr1 ; loop until it's nonzero. +; +; Next, set the break or DTR bit on the SIO +; +setbit: + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,6ah ; Tx enable, 8 bit Tx character, + ora d ; OR with appropriate bit mask + out mnprts ; +; +; Now, delay for duration of hangup or break + mov a,e ; delay count + call delay +; +; Time's up. Put transmitter back in normal state and return. + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,0eah ; Tx enable, 8 bit Tx character, + out mnprts ;. + ret ; done. + +; sysflt - system-dependent filter +; called with character in E. +; if this character should not be printed, return with A = zero. +; preserves bc, de, hl. +; note: <xon>,<xoff>,<del>, and <nul> are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret + +; +; sysbye - system-dependent processing for BYE command. +; +sysbye: + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +; +sysspd: + +; Set the speed for bigboard II +IF bbII + di ; don't let anything between the data bytes + mvi a,01000111b ; get the command byte (load time constant) + out baudrt ; output it to CTC + mov a,e ; Get the parsed value. + out baudrt ; Tell the baud rate generator. + ei ; end of critical section + ret +ENDIF;bbII + + +; Set the speed for bigboard I +IF bbI + mov a,e ; get the parsed value + out baudrt ; Tell the baud rate generator. + ret +ENDIF;bbI + +; set the speed for the Ampro Little Board +if ampro + mvi e,3fh ; offset to port b ctc 3f hex bytes + call getbios + mvi a,47h ; counter mode,ctc reset,value follows + mov m,a ; store value + lda speed+1 ; get ctc divisor + inx h ; location of ctc divisor + mov m,a ; store new divisor +; +; set up wr4 clock divisor according to mspeed +; + mvi e,50h ; offset to dart wr4 + call getbios + mvi a,3fh ; mask for wr4 clock bits + ana m ; mask off bits + mov m,a ; and save to wr4 + lda speed ; get clock flag + ora a ; set flags, zero = 300 bps + mvi a,80h ; x32 clock bit + jz lbps ; setup wr4 for 300 bps x32 clock +; +; set up wr4 value for 1200 bps x16 clock 'hl' has wr4 loc +; +hbps: mvi a,40h ; x16 clock +; +; setup wr4 value for 300 bps x32 clock 'hl' has wr4 loc +; +lbps: ora m ; set clock bits saving parity + mov m,a ; store new clock divisor to wr4 value +; +; initialize sio/dart +; +intsio: lxi h,intend + push h ; set up for return + mvi e,36h ; offset to ioinit + call getbios + pchl ; we pushed return address +intend: ret + +; +; return bios location in 'hl' called with offset in 'e' +; +getbios: + lhld 1 ; get bios location + mvi d,0 ; clear 'd' + dad d + ret +; +ENDIF;ampro + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF bbI +spdtbl: db 10h ;16 entries + db 03h,'110$', 02h,02h + db 04h,'1200$', 07h,07h + db 05h,'134.5$', 03h,03h + db 03h,'150$', 04h,04h + db 04h,'1800$', 08h,08h + db 05h,'19200$', 0fh,0fh + db 04h,'2000$', 09h,09h + db 04h,'2400$', 0ah,0ah + db 03h,'300$', 05h,05h + db 04h,'3600$', 0bh,0bh + db 04h,'4800$', 0ch,0ch + db 02h,'50$', 00h,00h + db 03h,'600$', 06h,06h + db 04h,'7200$', 0dh,0dh + db 02h,'75$', 01h,01h + db 04h,'9600$', 0eh,0eh + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF;bbI + +IF bbII +spdtbl: db 8 ; 8 entries + db 04h,'1200$', 20h,20h + db 05h,'19200$', 02h,02h + db 04h,'2400$', 10h,10h + db 03h,'300$', 80h,80h + db 05h,'38400$', 01h,01h + db 04h,'4800$', 08h,08h + db 03h,'600$', 40h,40h + db 04h,'9600$', 04h,04h + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$' +ENDIF;bbII + + +IF ampro +spdtbl: db 6 ; 6 entries + db 04h,'1200$', 1,104 + db 04h,'2400$', 1,52 + db 03h,'300$', 0,208 + db 04h,'4800$', 1,26 + db 03h,'600$', 1,208 + db 04h,'9600$', 1,13 + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' +ENDIF;ampro + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +; +sysprt: + ret +; + +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; preserves BC, DE, HL. +; +selmdm: +selcon: + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret + + +; +; get character from modem; return zero if none available. +; destroys bc, de, hl. +inpmdm: + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. + + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +; + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +IF NOT (bbII OR ampro) ;[obs I think ] +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return +ENDIF ; NOT bbII OR ampro + +; +; delchr - make delete look like a backspace. Unless delete is a +; printing character, we just need to print a backspace +; (we'll output clrsp afterwards) +delchr: + +IF bbI + lxi d,delstr + jmp prtstr +ENDIF;bbI + + +IF NOT bbI + mvi e,bs ;get a backspace + jmp outcon +ENDIF;NOT bbI + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +; If its a BigBoard or Ampro, we need a terminal, so link to CPXVDU.ASM +IF bbII +sysver: db 'Big Board II$' +ENDIF;bbII + +IF ampro +sysver: db 'Ampro Little Board$' +ENDIF;ampro + +IF (bbII AND lasm) ; we need a terminal as well +LINK CPXVDU.ASM +ENDIF ;(bbII AND lasm) + +IF (ampro AND lasm) ; we need a terminal as well +LINK CPXVDU.ASM +ENDIF ;(ampro AND lasm) + +;If here, we are Kaypro or Xerox 820, or if from M80, we should skip +; a few lines if Bigboard. + +IF kpii +sysver: +ttytyp: db 'Kaypro II$' +outlin: db subt,cr,lf,tab,tab,'$' +erascr: db subt,'$' ;Clear screen and home. +eralin: db cr,18H,'$' ;Clear line. +curldn: db esc,'=$' ;Cursor lead-in +delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db subt,'$',0,0 ;Clear display +tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek) +tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII) +th: db 1EH,'$',0,0 ; Cursor home. [UTK016] +ti: db esc,'E','$',0 ; Reverse linefeed. (insert line) +tj: db 'W'-100O,'$',0,0 ; Clear to end of screen. +tk: db 'X'-100O,'$',0,0 ; Clear to end of line. +ENDIF ; kpii +; + +IF xer820 +ttytyp: +sysver: db 'Xerox 820$' +outlin: db subt,cr,lf,tab,tab,'$' +erascr: db subt,'$' ;Clear screen and home. +eralin: db cr,18H,'$' ;Clear line. +curldn: db esc,'=$' ;Cursor lead-in +delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db subt,'$',0,0 ;Clear display +tf: db '$',0,0,0 ; Enter Graphics Mode (can't) +tg: db '$',0,0,0 ; Exit Graphics mode (can't) +th: db 1EH,'$',0,0 ; Cursor home. [UTK016] +ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up) +tj: db 11H,'$',0,0 ; Clear to end of screen. +tk: db 18H,'$',0,0 ; Clear to end of line. +ENDIF ; xer820 +ovlend equ $ ; End of overlay + + END |
