X-Git-Url: http://cloudbase.mooo.com/gitweb/kermit-80.git/blobdiff_plain/c25f6a44a6e2266617af2f326fa5dc0c4864035f..b0db08390d94c94270ef78aa154a502f8ea4a65b:/cpxcif.asm?ds=sidebyside diff --git a/cpxcif.asm b/cpxcif.asm index d4568c4..f6ce1e8 100644 --- a/cpxcif.asm +++ b/cpxcif.asm @@ -1,746 +1,746 @@ -IF NOT lasm -.printx * CPXCIF.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 part for Cifer systems, and -; is based on code contributed by John Shearwood of Birmingham -; University. This file was originally CPXTOR.ASM but now an -; FAMILY file on its own. -; -; This file has code that supports Cifer 1886/2886 systems, running -; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port. -; xxx is a three letter abbrev. for the system you are adding. -; -; revision history: -; -; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with -; CPXCOM.ASM. -; -; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK. -; His edits ar based on the former CPXTOR.ASM family file. -; -; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port. -; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus -; -; Keep module name, edit number, and last revision date in memory. -family: db 'CPXCIF.ASM (2) 14-Jul-87 $' -; -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - -IF cifer -.printx * Assembling Kermit-80 for Cifer 1886 * -ENDIF - -IF cifer3 -.printx * with CP/M Plus -ENDIF - -IF cifaux -.printx * with AUX port -ENDIF - -; -;========================================================================= -; I/O Byte assignments (2-bit fields for 4 devices at loc 3) -; -;bits 6+7 LIST field -; 0 LIST is Teletype device (TTY:) -; 1 LIST is CRT device (CRT:) -; 2 LIST is Lineprinter (LPT:) -; 3 LIST is user defined (UL1:) -; -;bits 4+5 PUNCH field -; 0 PUNCH is Teletype device (TTY:) -; 1 PUNCH is high speed punch (PUN:) -; 2 PUNCH is user defined #1 (UP1:) -; 3 PUNCH is user defined #2 (UP2:) -; -;bits 2+3 READER field -; 0 READER is Teletype device (TTY:) -; 1 READER is high speed reader (RDR:) -; 2 READER is user defined #1 (UR1:) -; 3 READER is user defined #2 (UR2:) -; -;bits 0+1 CONSOLE field -; 0 CONSOLE is console printer (TTY:) -; 1 CONSOLE is CRT device (CRT:) -; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, -; LIST = Output -; 3 CONSOLE is user defined (UC1:) -; -;========================================================================= - -iobyte EQU 03H ;Location of I/O byte - -IF cifer ;[13] -batio equ 80h ; tty: as console -defio equ 81h ; crt: as console -z80 SET TRUE ; although it really is... -ENDIF;cifer [13] - -defesc EQU ']'-100O ;The default escape character. - -; Select initial setting for VT-52 emulation flag. -vtval EQU 1 - -IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM - ; rest use this one -coniob: db 0 ; default console bit pattern -ENDIF ;iobyt - - - -sysxin: ;system initialisation not covered by sysinit - mvi a,defio - sta coniob - -IF cifer AND NOT cifaux ; [JAS] Not if AUX port - lxi d,ciferi - call prtstr -ENDIF ;cifer AND NOT cifaux - -IF cifaux ; [JAS] Only Aux Port - lhld 00047h ; Get address of CIOPS table - lxi d,6fh - dad d ; Calculate address of SETLNSPD - shld cifiop - inx h - inx h - inx h - shld ciflod ; Next entry LODEF - lxi d,81h-72h - dad d ; Calculate address of LIDEF - shld ciflid - lhld 00045h ; Get address of SYSPTRS table - lxi d,12h ; Offset for LIDEF pointer - dad d ; Add to table address - mov e,m ; Get low byte LIDEF pointer - inx h - mov d,m ; Get high byte LIDEF pointer - push d - inx h ; LIPARM pointer next - mov a,m ; Get low byte of LIPARM pointer - sta ciptbl ; Keep - inx h - mov a,m ; Get high byte - sta ciptbl+1 ; Keep - lxi d,1eh-15h ; Offset to LODEF - dad d - mov e,m ; Low byte - inx h - mov d,m ; High byte - inx h ; LOPARM is next entry - mov a,m - sta coptbl ; Keep low byte LOPARM - inx h - mov a,m - sta coptbl+1 ; Keep high byte -; Now set up port for no parity 8 bits xon/xoff protocol both ways - xchg ; LODEF into hl register - push h ; Needed later - mvi a,0 - mov m,a ; Clear byte 0 - inx h - mov m,a ; Clear byte 1 - inx h - mvi a,099h ; XON/XOFF protocol, 8bits, no parity - mov m,a ; Flag into byte 2 - pop h ; Restore address of LODEF -ciflod equ $+1 - call $ ; LODEF routine (poked above) - pop h ; LIDEF (PUSHed from de earlier) - push h ; Needed later - mvi a,0 - mov m,a ; Clear byte 0 - inx h - mov m,a ; Clear byte 1 - inx h - mvi a,099h ; XON/XOFF protocol, 8bits, no parity - mov m,a ; Flag into byte 2 - pop h ; Restore address of LIDEF -ciflid equ $+1 - call $ ; LIDEF routine (poked above) - lhld ciptbl ; Get current input speed - mov a,m - sta speed - sta speed+1 - mov e,a - mov d,a - call sysspd ; Make sure ip and op are the same -ENDIF; cifer AND cifaux - - 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: - -IF cifer AND NOT cifaux - lxi d,cifero - call prtstr -ENDIF;cifer AND NOT cifaux - - 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 ?, 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: - -; [16] [18] have added super brain and Torch to the list of Breaking machines. - -IF (cifer AND NOT cifaux) - db cr,lf,'B Transmit a BREAK' -ENDIF ;(cifer AND NOT cifaux) - 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... - -; [19] have added superbrain and torch to the list - -IF (cifer AND NOT cifaux) - cpi 'B' ; send break? - jz sendbr ; yes, go do it. return nonskip when through. -ENDIF ;(cifer AND NOT cifaux) - - jmp rskp ; take skip return - command not recognized. - -; - -IF (cifer AND NOT cifaux) -sendbr: lxi d,brkmes ; send a break by sending esc * " - call prtstr ; send to screen => breaks to port - ret -ENDIF;cifer - -; sysflt - system-dependent filter. -; called with the character in E. -; preserves bc, de, hl. -; note: ,,, and are always discarded. -sysflt: - mov a,e ; get character for testing - 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 (cifer AND NOT cifaux); This one is wierd.. - ; send an escape string to the screen to set rate. - push d ; Save the data returned - lxi d,cifbrt ; send the start of the escape string (esc ?) - call prtstr ; - pop psw ; get data into a (and flags>..) - inr a ; need to send (a+1-1) 'N' to screen - push psw ; we will need the data again - call cifnos ; send a set of Ns to the screen - pop psw ; (which then sets the VL line on the screen - call cifnos ; processor card) - call prcrlf ; cr will terminate.. a crlf is handy - ret - -cifnos: dcr a ; if result = 0 then done - jz cifno1 ; if done then say 'Y' for yes. - push psw - mvi e,'N' ; else send a string of Ns to screen processor - mvi c,dconio - call bdos - pop psw - jmp cifnos -cifno1: mvi e,'Y' - mvi c,dconio - call bdos - ret ; sent a sring of 0 or more N then a Y - -cifbrt: db esc,'?$' ; start setting baud rate string -ENDIF ;cifer AND NOT cifaux - -IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling - ;CIOPS routine -; Set up speed byte in first location of tables - lhld coptbl ; Now sort out baud rate - mov a,e ; That's output speed - mov m,a - xchg - lhld ciptbl - mov m,a ; Input speed -; Call CIOPS routine SETLNSPD with tables in appropriate rp's -cifiop equ $+1 - call $ ; Poked by sysinit - ret - -coptbl: dw 0 -ciptbl: dw 0 -ENDIF; cifaux - -; -; 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 cifer -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;cifer - -; 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] -; -; This is the system-dependent SET PORT command. -; HL contains the argument from the command table. -sysprt: -IF iobyt - mov a,m ;Get the I/O byte - sta prtiob ;Save the desired IO byte for this port - inx h ;Point at next entry - mov a,m ;Get the output function - sta prtfun ;Save it -ENDIF;iobyt - - ret -; -; -; -; Port tables for GENERIC CPM 2.2 -IF gener -; help text -prhtbl: db cr,lf,'CRT device' - db cr,lf,'PTR device' - db cr,lf,'TTY device' - db cr,lf,'UC1 device' - db cr,lf,'UR1 device' - db cr,lf,'UR2 device$' - -; command table -prttbl: db 06H ;Six devices to choose from - db 03H,'CRT$' - dw crtptb - db 03H,'PTR$' - dw ptrptb - db 03H,'TTY$' - dw ttyptb - db 03H,'UC1$' - dw uc1ptb - db 03H,'UR1$' - dw ur1ptb - db 03H,'UR2$' - dw ur2ptb - -; port entry table -; table entries are: -; db iobyte-value, BDOS output function, reserved -crtptb: db crtio,conout,0 -ptrptb: db ptrio,punout,0 -ttyptb: db ttyio,conout,0 -uc1ptb: db uc1io,conout,0 -ur1ptb: db ur1io,punout,0 -ur2ptb: db ur2io,punout,0 -ENDIF;gener - -; -; -IF cifer ; no ports yet... -prttbl EQU 0 -prhtbl EQU 0 ; -ENDIF; cifer - -IF iobyt -prtfun: db punout ;Function to use for output to comm port -prtiob: db batio ;I/O byte to use for communicating -ENDIF;iobyt - -IF NOT (iobyt OR lobo OR cifer) ;[hh] -prttbl equ 0 ; SET PORT is not supported -prhtbl equ 0 -ENDIF;NOT (iobyt OR lobo OR cifer) - -; -; -; 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: -IF iobyt - lda prtiob ;Set up for output to go to the comm port - sta iobyte ;Switch byte directly -ENDIF;iobyt - - ret - -selcon: -IF iobyt - lda coniob ;Set up for output to go to the console port - sta iobyte ;Switch directly -ENDIF;iobyt - - ret -; -; Get character from console, or return zero. -; result is returned in A. destroys bc, de, hl. -; -inpcon: -IF NOT iobyt - mvi c,dconio ;Direct console I/O BDOS call. - mvi e,0FFH ;Input. - call BDOS -ENDIF;NOT iobyt - -IF iobyt - call bconst ;Get the status - ora a ;Anything there? - rz ;No, forget it - call bconin ;Yes, get the character -ENDIF;iobyt - ret -; -; -; Output character in E to the console. -; destroys bc, de, hl -; -outcon: - -IF NOT iobyt - mvi c,dconio ;Console output bdos call. - call bdos ;Output the char to the console. -ENDIF;NOT iobyt - -IF iobyt - mov c,e ;Character - call bcnout ;to Console -ENDIF;iobyt - 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: -IF inout - 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 -ENDIF;inout - -IF iobyt -;**** Note that we enter from outpkt with the I/O byte already set up for -; output to go to the comm port - push h - push b - lda prtfun ;Get the output function - mov c,a ;Into C - call bdos ;And output the character - pop b - pop h - ret -ENDIF;iobyt - -IF cifer3 ; [JAS] - push h - push b - mvi c,auxout ;Output to the aux output device - call bdos - pop b - pop h - ret -ENDIF;cifer3 - - -; -; -; get character from modem; return zero if none available. -; for IOBYT systems, the modem port has already been selected. -; destroys bc, de, hl. -inpmdm: -IF iobyt - call bconst ;Is Char at COMM-Port? - ora a ;something there? - rz ; return if nothing there - call bconin ; data present. read data. -ENDIF;iobyt - -IF inout -;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. -ENDIF;inout - -IF cifer3 ; [JAS] - mvi c,auxist - call bdos ;is char at auxin? - ora a ;something there? - rz ;no - mvi c,auxin - call bdos ;read char from auxin -ENDIF;cifer3 - -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=0 if ok, or 0ffh if not. -lptstat: -IF iobyte ;[33] - call bprtst ; get status -ENDIF ;iobyte[33] -IF NOT iobyte ;[33] - xra a ; assume it is ok.. this may not be necessary -ENDIF ;iobyte [33] - 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 - -IF NOT iobyte - mvi c,lstout - call bdos ;Char to printer -ENDIF;NOT iobyt -IF iobyt - mov c,e - call blsout -ENDIF;iobyt - -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 cifer ; [14] cifer does it colums then rows.. swap b and c -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; restore coordinates - mov a,l ; [obs] get column - adi (' '-1) ; space is column one - mov e,a - push h - call outcon ; output row - pop h - mov a,h ; [obs] get row - adi (' '-1) ; space is row one - mov e,a - jmp outcon ; output it and return -ENDIF; cifer - -; -; -; 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: - mvi e,bs - call outcon - -; 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 cifer AND NOT cifaux ;[13] -ttytyp: db 'Cifer 1886 (Parity set to space only)$' -ENDIF; cifer AND NOT cifaux - -IF cifaux ;JAS -ttytyp: db ' Cifer 1886 $' -ENDIF; cifaux - -IF cifer ;[JAS] -sysver: db ' Cifer 1886 $' ; -outlin: db esc,'J',cr,lf,tab,tab,'$' -eralin: db esc,'^K$' ;Clear to end of line. -erascr: db esc,'J$' ;Clear screen and go home. -curldn: db esc,'P$' ;Cursor lead-in -ttab: ;Table start location. -ta: db esc,'A$',0 ;Cursor up. -tb: db esc,'@$',0 ;Cursor down. -tc: db esc,'C$',0 ;Cursor right. -td: db esc,'D$',0 ;Cursor left. -te: db esc,'J',0,0 ;Clear screen and home cursor -tf: db '$',0,0,0 ;(can't) Enter Graphics mode -tg: db '$',0,0,0 ;(can't) Exit Graphics mode -th: db esc,'H$',0 ;Cursor home. -ti: db esc,'@$',0 ;reverse linfeed -tj: db esc,'B$',0 ;Clear to end of screen -tk: db esc,'K$',0 ;Clear to end of line. -ENDIF;cifer -; -IF cifer AND NOT cifaux ;[JAS] -; Setup string for the Cifer.. called as a prtstr param. from sysinit -ciferi: db esc,'/' ;Setup cifer for on line - db esc,'*[' ; direct mode on - db esc,'%' ; protocol on host line on - db esc,'*~x' ; protocol is xon/xoff - db esc,'*(' ; protocol out on host is xon/xoff - db esc,'? NNNY',cr ; set VL port to space parity - ; It cannot do NONE.. Thanks a lot - db '$' ; all done -; Finish string for the Cifer.. called as a prtstr param. from sysexit -cifero: db esc,'&' ; Host input protocol off - db esc,'*)' ; Host output protocol off - db esc,'*]' ; Direct mode off - db esc,'\' ; Setup cifer for off line - db '$' -; Break string for cifer VL port. -brkmes: db esc,'*"$' ;Send a break command string -ENDIF;cifer AND NOT cifaux [13] - -ovlend equ $ ; End of overlay - - END - +IF NOT lasm +.printx * CPXCIF.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 part for Cifer systems, and +; is based on code contributed by John Shearwood of Birmingham +; University. This file was originally CPXTOR.ASM but now an +; FAMILY file on its own. +; +; This file has code that supports Cifer 1886/2886 systems, running +; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port. +; xxx is a three letter abbrev. for the system you are adding. +; +; revision history: +; +; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with +; CPXCOM.ASM. +; +; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK. +; His edits ar based on the former CPXTOR.ASM family file. +; +; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port. +; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus +; +; Keep module name, edit number, and last revision date in memory. +family: db 'CPXCIF.ASM (2) 14-Jul-87 $' +; +; Assembly time message to let me know I'm building the right version. +; LASM generates an 'S' error along with the message, which is messy, but +; better than trying to put everything inside a IF m80 OR mac80 conditional, +; because LASM doesn't like nested IF's, either. + +IF cifer +.printx * Assembling Kermit-80 for Cifer 1886 * +ENDIF + +IF cifer3 +.printx * with CP/M Plus +ENDIF + +IF cifaux +.printx * with AUX port +ENDIF + +; +;========================================================================= +; I/O Byte assignments (2-bit fields for 4 devices at loc 3) +; +;bits 6+7 LIST field +; 0 LIST is Teletype device (TTY:) +; 1 LIST is CRT device (CRT:) +; 2 LIST is Lineprinter (LPT:) +; 3 LIST is user defined (UL1:) +; +;bits 4+5 PUNCH field +; 0 PUNCH is Teletype device (TTY:) +; 1 PUNCH is high speed punch (PUN:) +; 2 PUNCH is user defined #1 (UP1:) +; 3 PUNCH is user defined #2 (UP2:) +; +;bits 2+3 READER field +; 0 READER is Teletype device (TTY:) +; 1 READER is high speed reader (RDR:) +; 2 READER is user defined #1 (UR1:) +; 3 READER is user defined #2 (UR2:) +; +;bits 0+1 CONSOLE field +; 0 CONSOLE is console printer (TTY:) +; 1 CONSOLE is CRT device (CRT:) +; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, +; LIST = Output +; 3 CONSOLE is user defined (UC1:) +; +;========================================================================= + +iobyte EQU 03H ;Location of I/O byte + +IF cifer ;[13] +batio equ 80h ; tty: as console +defio equ 81h ; crt: as console +z80 SET TRUE ; although it really is... +ENDIF;cifer [13] + +defesc EQU ']'-100O ;The default escape character. + +; Select initial setting for VT-52 emulation flag. +vtval EQU 1 + +IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM + ; rest use this one +coniob: db 0 ; default console bit pattern +ENDIF ;iobyt + + + +sysxin: ;system initialisation not covered by sysinit + mvi a,defio + sta coniob + +IF cifer AND NOT cifaux ; [JAS] Not if AUX port + lxi d,ciferi + call prtstr +ENDIF ;cifer AND NOT cifaux + +IF cifaux ; [JAS] Only Aux Port + lhld 00047h ; Get address of CIOPS table + lxi d,6fh + dad d ; Calculate address of SETLNSPD + shld cifiop + inx h + inx h + inx h + shld ciflod ; Next entry LODEF + lxi d,81h-72h + dad d ; Calculate address of LIDEF + shld ciflid + lhld 00045h ; Get address of SYSPTRS table + lxi d,12h ; Offset for LIDEF pointer + dad d ; Add to table address + mov e,m ; Get low byte LIDEF pointer + inx h + mov d,m ; Get high byte LIDEF pointer + push d + inx h ; LIPARM pointer next + mov a,m ; Get low byte of LIPARM pointer + sta ciptbl ; Keep + inx h + mov a,m ; Get high byte + sta ciptbl+1 ; Keep + lxi d,1eh-15h ; Offset to LODEF + dad d + mov e,m ; Low byte + inx h + mov d,m ; High byte + inx h ; LOPARM is next entry + mov a,m + sta coptbl ; Keep low byte LOPARM + inx h + mov a,m + sta coptbl+1 ; Keep high byte +; Now set up port for no parity 8 bits xon/xoff protocol both ways + xchg ; LODEF into hl register + push h ; Needed later + mvi a,0 + mov m,a ; Clear byte 0 + inx h + mov m,a ; Clear byte 1 + inx h + mvi a,099h ; XON/XOFF protocol, 8bits, no parity + mov m,a ; Flag into byte 2 + pop h ; Restore address of LODEF +ciflod equ $+1 + call $ ; LODEF routine (poked above) + pop h ; LIDEF (PUSHed from de earlier) + push h ; Needed later + mvi a,0 + mov m,a ; Clear byte 0 + inx h + mov m,a ; Clear byte 1 + inx h + mvi a,099h ; XON/XOFF protocol, 8bits, no parity + mov m,a ; Flag into byte 2 + pop h ; Restore address of LIDEF +ciflid equ $+1 + call $ ; LIDEF routine (poked above) + lhld ciptbl ; Get current input speed + mov a,m + sta speed + sta speed+1 + mov e,a + mov d,a + call sysspd ; Make sure ip and op are the same +ENDIF; cifer AND cifaux + + 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: + +IF cifer AND NOT cifaux + lxi d,cifero + call prtstr +ENDIF;cifer AND NOT cifaux + + 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 ?, 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: + +; [16] [18] have added super brain and Torch to the list of Breaking machines. + +IF (cifer AND NOT cifaux) + db cr,lf,'B Transmit a BREAK' +ENDIF ;(cifer AND NOT cifaux) + 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... + +; [19] have added superbrain and torch to the list + +IF (cifer AND NOT cifaux) + cpi 'B' ; send break? + jz sendbr ; yes, go do it. return nonskip when through. +ENDIF ;(cifer AND NOT cifaux) + + jmp rskp ; take skip return - command not recognized. + +; + +IF (cifer AND NOT cifaux) +sendbr: lxi d,brkmes ; send a break by sending esc * " + call prtstr ; send to screen => breaks to port + ret +ENDIF;cifer + +; sysflt - system-dependent filter. +; called with the character in E. +; preserves bc, de, hl. +; note: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + 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 (cifer AND NOT cifaux); This one is wierd.. + ; send an escape string to the screen to set rate. + push d ; Save the data returned + lxi d,cifbrt ; send the start of the escape string (esc ?) + call prtstr ; + pop psw ; get data into a (and flags>..) + inr a ; need to send (a+1-1) 'N' to screen + push psw ; we will need the data again + call cifnos ; send a set of Ns to the screen + pop psw ; (which then sets the VL line on the screen + call cifnos ; processor card) + call prcrlf ; cr will terminate.. a crlf is handy + ret + +cifnos: dcr a ; if result = 0 then done + jz cifno1 ; if done then say 'Y' for yes. + push psw + mvi e,'N' ; else send a string of Ns to screen processor + mvi c,dconio + call bdos + pop psw + jmp cifnos +cifno1: mvi e,'Y' + mvi c,dconio + call bdos + ret ; sent a sring of 0 or more N then a Y + +cifbrt: db esc,'?$' ; start setting baud rate string +ENDIF ;cifer AND NOT cifaux + +IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling + ;CIOPS routine +; Set up speed byte in first location of tables + lhld coptbl ; Now sort out baud rate + mov a,e ; That's output speed + mov m,a + xchg + lhld ciptbl + mov m,a ; Input speed +; Call CIOPS routine SETLNSPD with tables in appropriate rp's +cifiop equ $+1 + call $ ; Poked by sysinit + ret + +coptbl: dw 0 +ciptbl: dw 0 +ENDIF; cifaux + +; +; 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 cifer +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;cifer + +; 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] +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: +IF iobyt + mov a,m ;Get the I/O byte + sta prtiob ;Save the desired IO byte for this port + inx h ;Point at next entry + mov a,m ;Get the output function + sta prtfun ;Save it +ENDIF;iobyt + + ret +; +; +; +; Port tables for GENERIC CPM 2.2 +IF gener +; help text +prhtbl: db cr,lf,'CRT device' + db cr,lf,'PTR device' + db cr,lf,'TTY device' + db cr,lf,'UC1 device' + db cr,lf,'UR1 device' + db cr,lf,'UR2 device$' + +; command table +prttbl: db 06H ;Six devices to choose from + db 03H,'CRT$' + dw crtptb + db 03H,'PTR$' + dw ptrptb + db 03H,'TTY$' + dw ttyptb + db 03H,'UC1$' + dw uc1ptb + db 03H,'UR1$' + dw ur1ptb + db 03H,'UR2$' + dw ur2ptb + +; port entry table +; table entries are: +; db iobyte-value, BDOS output function, reserved +crtptb: db crtio,conout,0 +ptrptb: db ptrio,punout,0 +ttyptb: db ttyio,conout,0 +uc1ptb: db uc1io,conout,0 +ur1ptb: db ur1io,punout,0 +ur2ptb: db ur2io,punout,0 +ENDIF;gener + +; +; +IF cifer ; no ports yet... +prttbl EQU 0 +prhtbl EQU 0 ; +ENDIF; cifer + +IF iobyt +prtfun: db punout ;Function to use for output to comm port +prtiob: db batio ;I/O byte to use for communicating +ENDIF;iobyt + +IF NOT (iobyt OR lobo OR cifer) ;[hh] +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 +ENDIF;NOT (iobyt OR lobo OR cifer) + +; +; +; 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: +IF iobyt + lda prtiob ;Set up for output to go to the comm port + sta iobyte ;Switch byte directly +ENDIF;iobyt + + ret + +selcon: +IF iobyt + lda coniob ;Set up for output to go to the console port + sta iobyte ;Switch directly +ENDIF;iobyt + + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: +IF NOT iobyt + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS +ENDIF;NOT iobyt + +IF iobyt + call bconst ;Get the status + ora a ;Anything there? + rz ;No, forget it + call bconin ;Yes, get the character +ENDIF;iobyt + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + +IF NOT iobyt + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. +ENDIF;NOT iobyt + +IF iobyt + mov c,e ;Character + call bcnout ;to Console +ENDIF;iobyt + 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: +IF inout + 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 +ENDIF;inout + +IF iobyt +;**** Note that we enter from outpkt with the I/O byte already set up for +; output to go to the comm port + push h + push b + lda prtfun ;Get the output function + mov c,a ;Into C + call bdos ;And output the character + pop b + pop h + ret +ENDIF;iobyt + +IF cifer3 ; [JAS] + push h + push b + mvi c,auxout ;Output to the aux output device + call bdos + pop b + pop h + ret +ENDIF;cifer3 + + +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF iobyt + call bconst ;Is Char at COMM-Port? + ora a ;something there? + rz ; return if nothing there + call bconin ; data present. read data. +ENDIF;iobyt + +IF inout +;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. +ENDIF;inout + +IF cifer3 ; [JAS] + mvi c,auxist + call bdos ;is char at auxin? + ora a ;something there? + rz ;no + mvi c,auxin + call bdos ;read char from auxin +ENDIF;cifer3 + +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=0 if ok, or 0ffh if not. +lptstat: +IF iobyte ;[33] + call bprtst ; get status +ENDIF ;iobyte[33] +IF NOT iobyte ;[33] + xra a ; assume it is ok.. this may not be necessary +ENDIF ;iobyte [33] + 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 + +IF NOT iobyte + mvi c,lstout + call bdos ;Char to printer +ENDIF;NOT iobyt +IF iobyt + mov c,e + call blsout +ENDIF;iobyt + +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 cifer ; [14] cifer does it colums then rows.. swap b and c +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,l ; [obs] get column + adi (' '-1) ; space is column one + mov e,a + push h + call outcon ; output row + pop h + mov a,h ; [obs] get row + adi (' '-1) ; space is row one + mov e,a + jmp outcon ; output it and return +ENDIF; cifer + +; +; +; 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: + mvi e,bs + call outcon + +; 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 cifer AND NOT cifaux ;[13] +ttytyp: db 'Cifer 1886 (Parity set to space only)$' +ENDIF; cifer AND NOT cifaux + +IF cifaux ;JAS +ttytyp: db ' Cifer 1886 $' +ENDIF; cifaux + +IF cifer ;[JAS] +sysver: db ' Cifer 1886 $' ; +outlin: db esc,'J',cr,lf,tab,tab,'$' +eralin: db esc,'^K$' ;Clear to end of line. +erascr: db esc,'J$' ;Clear screen and go home. +curldn: db esc,'P$' ;Cursor lead-in +ttab: ;Table start location. +ta: db esc,'A$',0 ;Cursor up. +tb: db esc,'@$',0 ;Cursor down. +tc: db esc,'C$',0 ;Cursor right. +td: db esc,'D$',0 ;Cursor left. +te: db esc,'J',0,0 ;Clear screen and home cursor +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db esc,'H$',0 ;Cursor home. +ti: db esc,'@$',0 ;reverse linfeed +tj: db esc,'B$',0 ;Clear to end of screen +tk: db esc,'K$',0 ;Clear to end of line. +ENDIF;cifer +; +IF cifer AND NOT cifaux ;[JAS] +; Setup string for the Cifer.. called as a prtstr param. from sysinit +ciferi: db esc,'/' ;Setup cifer for on line + db esc,'*[' ; direct mode on + db esc,'%' ; protocol on host line on + db esc,'*~x' ; protocol is xon/xoff + db esc,'*(' ; protocol out on host is xon/xoff + db esc,'? NNNY',cr ; set VL port to space parity + ; It cannot do NONE.. Thanks a lot + db '$' ; all done +; Finish string for the Cifer.. called as a prtstr param. from sysexit +cifero: db esc,'&' ; Host input protocol off + db esc,'*)' ; Host output protocol off + db esc,'*]' ; Direct mode off + db esc,'\' ; Setup cifer for off line + db '$' +; Break string for cifer VL port. +brkmes: db esc,'*"$' ;Send a break command string +ENDIF;cifer AND NOT cifaux [13] + +ovlend equ $ ; End of overlay + + END +