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/cpxnor.asm | |
| download | kermit-80-main.tar.gz kermit-80-main.zip | |
Diffstat (limited to 'src/cpxnor.asm')
| -rw-r--r-- | src/cpxnor.asm | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/src/cpxnor.asm b/src/cpxnor.asm new file mode 100644 index 0000000..2648060 --- /dev/null +++ b/src/cpxnor.asm @@ -0,0 +1,587 @@ +IF NOT LASM +.printx * CPXNOR.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.0 +; +; 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. +; +; This file contains the system-dependent code and data for various +; NorthStar KERMITs. This has the Family name of CPXNOR.ASM. +; +; revision history (last edit first) +; +;edit 4, 16-Jan-1991 by MF. Fixed a bug in OUTCON wherein the final RET +; was missing (bug reported by David P. Arnot of Scottish +; Agricultural College). +;edit 3, 12-Oct-1990 by MF. Added a semicolon before the comment +; beginning "Family is the string so we don't get errors +; edit 2, 23 July, 1987 by OBSchou to massage file to suit CPXCOM.ASM. +; +; edit 1: 1 June, 1986 by OBSchou, Loughborogh University, UK. +; Hived off northstar and Comart system dependent modules from +; CPXSYS.ASM. This assembles ok, but I cannot test it. Any comments? + + +IF norths +.printx * Assembling for NorthStar Horizon with HSIO-4 board * +ENDIF;norths + +IF horizon ;[25] +.printx * Assembling KERMIT-80 for the NorthStar Horizon * +ENDIF;horizon + +IF advant ;[22] +.printx * Assembling kermit-80 for North Star Advantage * +ENDIF ;[22] + +IF basicns ;[29] +.printx * Assembling KERMIT-80 for the Northstar Horizon using printer port * +ENDIF ;basicns [29] + +IF comart +.printx * Assembling KERMIT-80 for Comart Communicator * +ENDIF ; comart + +; the basics... +IF norths ;The basic Northstar Horizon BIOS does not access ports 2-5 +port0d equ 02h ;Port 0 data (console) +port0s equ 03h ;Port 0 status +port1d equ 04h ;Port 1 data (printer) +port1s equ 05h ;Port 1 status + +port2b equ 10h ;Port 2 baud +port2i equ 11h ;Port 2 interrupt mask +port2d equ 12h ;Port 2 data +port2s equ 13h ;Port 2 status + +port3b equ 14h ;Port 3 baud +port3i equ 15h ;Port 3 interrupt mask +port3d equ 16h ;Port 3 data +port3s equ 17h ;Port 3 status + +port4b equ 18h ;Port 4 baud +port4i equ 19h ;Port 4 interrupt mask +port4d equ 1Ah ;Port 4 data +port4s equ 1Bh ;Port 4 status + +port5b equ 1Ch ;Port 5 baud +port5i equ 1Dh ;Port 5 interrupt mask +port5d equ 1Eh ;Port 5 data +port5s equ 1Fh ;Port 5 status + +NS19K2 EQU 00H ;19.2 kilobaud +NS9600 EQU 01H ;9600 baud +NS4800 EQU 02H ;4800 baud +NS2400 EQU 03H ;2400 baud +NS1200 EQU 04H ;1200 baud +NS0600 EQU 05H ; 600 baud +NS0300 EQU 06H ; 300 baud +NS0110 EQU 07H ; 110 baud +;; Set to use port 5 at 1200 baud +mnport equ port5d ;Data port +mnprts equ port5s ;Status port +baudrt equ port5b ;Baud rate port +baudini equ ns1200 ;Initial baud rate +output EQU 1 ;Bit of UART status for transmitter ready +input EQU 2 ;Bit of UART status for receiver ready +z80 EQU TRUE ;This one's a Z80. +ENDIF;norths + +IF basicns ;[29] +mnport equ 04h ;printer port data +mnprts equ 05h ; printer port status +output equ 1 ;transmitter ready +input equ 2 ;receiver ready +z80 equ FALSE ; not important +ENDIF ;basicns [29] + +IF horizon ;[25] +mnport EQU 004H ;Modem data port +mnprts EQU 005H ;Modem status port +output EQU 01H ;Transmitter empty +input EQU 02H ;Input data available +TxEmpty EQU 04h ;Transmitter empty +;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) +z80 EQU TRUE ;This one's a Z80. +ENDIF;horizon + +IF advant ;[22] +vtval EQU 1 ; we do emulation of VT52s +slot EQU 1 ;SIO card slot +mnport EQU (6-slot)*16 ;Modem data port +mnprts EQU mnport+1 ;Modem status port +baudrt EQU mnport+8 ;Baud rate register +output EQU 01H ;Transmitter buffer empty +input EQU 02H ;Input data available +TxEmpty EQU 04h ;Transmitter empty flag +z80 EQU TRUE +ENDIF;[22] advant + +IF comart ;[25] +mnport EQU 002H ;Modem data port +mnprts EQU 003H ;Modem status port +output EQU 01H ;Transmitter empty +input EQU 02H ;Input data available +TxEmpty EQU 04h ;Transmitter empty +;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) +z80 EQU TRUE ;This one's a Z80. +ENDIF;comart + + +IF advant +defesc EQU '\'-100O +ENDIF;advant + +; +; Family is the string used in VERSION to say which of several +; smaller overlay files are used. These are (will be) derived from +; the juge CP4SYS.ASM file, in which case we will never get here. +; Just a Dollar, but put a sting in for a family of machines. +; +family: db 'CPXNOR.ASM (4) 16-Jan-1991$' ; Used for family versions.... + + + +sysxin: ; continuation of system dependent initialisation code +IF advant ;[22] + mvi a,40h + out mnprts ; Reset USART + lxi h,7070h ; Default to 1200 baud + shld speed ; store current speed + xchg + call sysspd ; set default baud rate + mvi a,4Eh ; Set UART mode to async 16x clock, 8 data + out mnprts ; bits, no parity, and 1 stop bit + mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, + out mnprts ; break off, error reset, and RTS on +ENDIF;[22] advant + +IF norths + mvi a,baudini ;Get initial speed + out baudrt + sta speed ;save for status display + sta speed+1 +ENDIF;norths + +IF comart OR horizon ;[25] +; The PD8251/PD8251A is reset by three successive 00 Hex or two +; successive 80 Hex command instructions followed by a software +; reset command instruction (40 Hex). + mvi a,80h ; Send UART reset + out mnprts + mvi a,80h + out mnprts + mvi a,40h + out mnprts + mvi a,4Eh ; Set UART mode to async 16x clock, 8 data + out mnprts ; bits, no parity, and 1 stop bit + mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, + out mnprts ; break off, error reset, and RTS on +ENDIF;comart OR horizon + + + ret ; return from system-dependent routine +; + +; +; system-dependent termination processing +; If we've changed anything, this is our last chance to put it back. +sysexit: + + ret + +; +; system-dependent processing for start of CONNECT command +; +syscon: + ret + +conmsg: ; Messages printed when entering transparent (CONNECT) mode: +; + +; +; 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: +IF advant OR comart OR horizon ; some more + lxi d,inhlps ; we got options... + call prtstr ; print them. +ENDIF;[22] advant OR comart OR horizon [29] + + ret + + +;additional, system-dependent help for transparent mode +; (two-character escape sequences) +inhlps: + +; [16] [18] have added super brain and Torch to the list of Breaking machines. +IF advant OR comart OR horizon ; ... some more + db cr,lf,'B Transmit a BREAK' +ENDIF;[22] advant OR comart OR horizon + + db '$' ;[hh] table terminator + +; +; 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... +IF advant OR comart OR horizon ; [22] [25] ... some more + cpi 'B' ; send break? + jz sendbr ; yes, go do it. return nonskip when through. +ENDIF;advant OR comart OR horizon [32] + + jmp rskp ; take skip return - command not recognized. + + +; + +IF advant OR comart OR horizon ;[lmj] +sendbr: +; +; Ensure that the transmitter has finished sending buffered chars +sndbr1: in mnprts ; get UART status + ani TxEmpty ; everything sent? + jz sndbr1 ; no, wait a bit more +; +; Begin sending a break by setting bit in UART command register + mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS + out mnprts +; +; Wait for 250 milliseconds (using hundredths second delay routine) + mvi a,25 + call delay +; +; Resume normal operation by clearing the SendBreak command bit + mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS + out mnprts +; + ret ;done +ENDIF;advant OR comart OR horizon + +; + +; +; 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 +IF advant ;[22] + cpi 'D'-100O ;Control-D's reset video + rnz ; if not control-D, it's ok. + xra a ; don't allow control-D out. +ENDIF;[22] advant + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +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: +IF norths OR advant ; + mov a,e ; get the parsed value + out baudrt ; Tell the baud rate generator. + ret +ENDIF;norths OR advant + +IF advant ;[22] +spdtbl: db 6 ; 6 entries + db 04,'1200$', 70h,70h + db 04,'2400$', 78h,78h + db 03,'300$', 40h,40h + db 04,'4800$', 7Ch,7Ch + db 03,'600$', 60h,60h + db 04,'9600$', 7Eh,7Eh + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' +ENDIF;[22] advant + + +IF norths +spdtbl: db 8 ; 8 entries + db 3,'110$', 07H,07H + db 4,'1200$', 04H,04H + db 5,'19200$', 00H,00H + db 4,'2400$', 03H,03H + db 3,'300$', 06H,06H + db 4,'4800$', 02H,02H + db 3,'600$', 05H,05H + db 4,'9600$', 01H,01H + + +sphtbl: db cr,lf + db ' 110 300 600 12000 2400 4800 9600 19200$' +ENDIF;norths + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +IF NOT (advant OR norths) +spdtbl EQU 0 ;[hh] SET BAUD not supported. +sphtbl EQU 0 ;[hh] ran out of room above... +ENDIF ;NOT (advant OR norths) +; +; + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret + +prttbl equ 0 ; SET PORT 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. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; 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 ;[MF]per David P. Arnot +; + +; +; 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. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +;Note: modem port should already be selected for mdI. [Toad Hall] + 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 + call prtflt ; go through printer filter [30] + 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 +IF advant ; all others require terminals +; + +; +; 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.) +; +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 ;advant + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: +IF advant ;[22] + ret +ENDIF;advant +IF NOT (advant );[22] + mvi e,bs ;get a backspace + jmp outcon +ENDIF;NOT (advant) [22] + +; 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 norths +sysver: db 'Northstar Horizon$' +ENDIF;norths + +IF basicns ;[29] +sysver: db 'Northstar using printer port$' +ENDIF ;basicns [29] + +IF comart ;[25] +sysver: db 'Comart Communicator$' +ENDIF;comart + +IF horizon ;[25] +sysver: db 'Northstar Horizon$' +ENDIF;horizon + +IF advant ;[22] +sysver: db 'North Star Advantage$' +outlin: db 04H,cr,lf,tab,'$' +erascr: db 04H,'$' ;Clear screen and go home. +eralin: db cr,0EH,'$' ;Clear line. +curldn: db esc,'=$' ;cursor leadin +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 04H,'$',0,0 ;Clear display +tf: db 12H,'$',0,0 ;Enter Graphics Mode +tg: db 13H,'$',0,0 ;Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home. +ti: db 0BH,'$',0,0 ;Reverse linefeed. +tj: db 0FH,'$',0,0 ;Clear to end of screen. +tk: db 0EH,'$',0,0 ;Clear to end of line. +ENDIF;[22] advant +IF lasm AND (NOT advant) +LINK CPXVDU.ASM +ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM + +IF lasm ; here if not a terminal selected and in LASM +ovlend equ $ + END +ENDIF ;lasm |
