]> cloudbase.mooo.com Git - kermit-80.git/blobdiff - cpxcif.asm
Add AVR-CP/M system (cpxac.asm) and a Makefile
[kermit-80.git] / cpxcif.asm
index d4568c49b229bcc443012dc49c7cbc301cfc9dfd..f6ce1e870acb97ef15f106b03bdf1d381a207be9 100644 (file)
-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 $'
-;\f
-; 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
-
-;\f
-;=========================================================================
-;       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
-
-;\f
-;
-;       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:
-;\f
-;
-;       syscls - system-dependent close routine
-;       called when exiting transparent session.
-;
-syscls:
-        ret
-;\f
-;
-;       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:
-
-; [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.
-
-;\f
-
-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: <xon>,<xoff>,<del>, and <nul> 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
-
-
-;\f
-;
-; system-dependent processing for BYE command.
-;  for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
-        ret
-;\f
-;       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
-
-;\f
-;       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]
-;\f
-;       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
-;\f
-;
-;
-;       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
-
-;\f
-;
-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)
-
-;\f
-;
-;       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
-;\f
-;       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
-;\f
-;
-;       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
-;\f
-;
-;       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
-
-
-;\f
-;
-;       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.
-
-
-;\f
-;
-;       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
-;\f
-;
-;       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
-;\f
-;
-;       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
-\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a
+IF NOT lasm\r
+.printx * CPXCIF.ASM *\r
+ENDIF  ;NOT lasm\r
+;       KERMIT - (Celtic for "FREE")\r
+;\r
+;       This is the CP/M-80 implementation of the Columbia University\r
+;       KERMIT file transfer protocol.\r
+;\r
+;       Version 4.0\r
+;\r
+;       Copyright June 1981,1982,1983,1984,1985\r
+;       Columbia University\r
+;\r
+; Originally written by Bill Catchings of the Columbia University Center for\r
+; Computing Activities, 612 W. 115th St., New York, NY 10025.\r
+;\r
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,\r
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many\r
+; others.\r
+;\r
+;       This file contains the system dependent part for Cifer systems, and\r
+;       is based on code contributed by John Shearwood of Birmingham\r
+;       University.  This file was originally CPXTOR.ASM but now an \r
+;       FAMILY file on its own.\r
+;\r
+;       This file has code that supports Cifer 1886/2886 systems, running \r
+;       either CP/M Version 2.2 or 3.0, and driving the VL or AUX port.\r
+;       xxx is a three letter abbrev. for the system you are adding.\r
+;\r
+; revision history:\r
+;\r
+; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with \r
+;      CPXCOM.ASM.\r
+;\r
+; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK.\r
+;      His edits ar based on the former CPXTOR.ASM family file.\r
+;\r
+;      edit 4, Apr 7 1987, JA Shearwood.  Add support for Cifer Aux port.\r
+;      edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus\r
+;\r
+; Keep module name, edit number, and last revision date in memory.\r
+family: db      'CPXCIF.ASM (2)  14-Jul-87 $'\r
+;\f\r
+; Assembly time message to let me know I'm building the right version.\r
+; LASM generates an 'S' error along with the message, which is messy, but\r
+; better than trying to put everything inside a IF m80 OR mac80 conditional,\r
+; because LASM doesn't like nested IF's, either.\r
+\r
+IF cifer\r
+.printx * Assembling Kermit-80 for Cifer 1886 *\r
+ENDIF\r
+\r
+IF cifer3\r
+.printx * with CP/M Plus\r
+ENDIF\r
+\r
+IF cifaux\r
+.printx * with AUX port\r
+ENDIF\r
+\r
+;\f\r
+;=========================================================================\r
+;       I/O Byte assignments (2-bit fields for 4 devices at loc 3)\r
+;\r
+;bits 6+7               LIST field\r
+;       0               LIST is Teletype device (TTY:)\r
+;       1               LIST is CRT device (CRT:)\r
+;       2               LIST is Lineprinter (LPT:)\r
+;       3               LIST is user defined (UL1:)\r
+;\r
+;bits 4+5               PUNCH field\r
+;       0               PUNCH is Teletype device (TTY:)\r
+;       1               PUNCH is high speed punch (PUN:)\r
+;       2               PUNCH is user defined #1 (UP1:)\r
+;       3               PUNCH is user defined #2 (UP2:)\r
+;\r
+;bits 2+3               READER field\r
+;       0               READER is Teletype device (TTY:)\r
+;       1               READER is high speed reader (RDR:)\r
+;       2               READER is user defined #1 (UR1:)\r
+;       3               READER is user defined #2 (UR2:)\r
+;\r
+;bits 0+1               CONSOLE field\r
+;       0               CONSOLE is console printer (TTY:)\r
+;       1               CONSOLE is CRT device (CRT:)\r
+;       2               CONSOLE is in Batch-mode (BAT:);READER = Input,\r
+;                       LIST = Output\r
+;       3               CONSOLE is user defined (UC1:)\r
+;\r
+;=========================================================================\r
+\r
+iobyte  EQU     03H     ;Location of I/O byte\r
+\r
+IF cifer        ;[13]\r
+batio   equ     80h             ; tty: as console\r
+defio   equ     81h             ; crt: as console\r
+z80     SET     TRUE           ; although it really is...\r
+ENDIF;cifer [13]\r
+\r
+defesc EQU     ']'-100O        ;The default escape character.\r
+\r
+; Select initial setting for VT-52 emulation flag.\r
+vtval   EQU    1\r
+\r
+IF iobyt       ; only CP/M 2.2 and VL port use coniob in CPXCOM\r
+               ; rest use this one\r
+coniob:        db      0               ; default console bit pattern\r
+ENDIF  ;iobyt\r
+\r
+\r
+\r
+sysxin:        ;system initialisation not covered by sysinit\r
+       mvi     a,defio\r
+       sta     coniob\r
+\r
+IF cifer AND NOT cifaux                ; [JAS] Not if AUX port\r
+        lxi     d,ciferi\r
+        call    prtstr\r
+ENDIF   ;cifer AND NOT cifaux\r
+\r
+IF cifaux                      ; [JAS] Only Aux Port\r
+        lhld    00047h         ; Get address of CIOPS table\r
+        lxi     d,6fh\r
+        dad     d              ; Calculate address of SETLNSPD\r
+        shld    cifiop\r
+        inx     h\r
+        inx     h\r
+        inx     h\r
+        shld    ciflod         ; Next entry LODEF\r
+        lxi     d,81h-72h\r
+        dad     d              ; Calculate address of LIDEF\r
+        shld    ciflid\r
+        lhld    00045h         ; Get address of SYSPTRS table\r
+        lxi     d,12h          ; Offset for LIDEF pointer\r
+        dad     d              ; Add to table address\r
+        mov     e,m            ; Get low byte LIDEF pointer\r
+        inx     h\r
+        mov     d,m            ; Get high byte LIDEF pointer\r
+        push    d\r
+        inx     h              ; LIPARM pointer next\r
+        mov     a,m            ; Get low byte of LIPARM pointer\r
+        sta     ciptbl         ; Keep\r
+        inx     h\r
+        mov     a,m            ; Get high byte\r
+        sta     ciptbl+1       ; Keep\r
+        lxi     d,1eh-15h      ; Offset to LODEF\r
+        dad     d\r
+        mov     e,m            ; Low byte\r
+        inx     h\r
+        mov     d,m            ; High byte\r
+        inx     h              ; LOPARM is next entry\r
+        mov     a,m\r
+        sta     coptbl         ; Keep low byte LOPARM\r
+        inx     h\r
+        mov     a,m\r
+        sta     coptbl+1       ; Keep high byte\r
+; Now set up port for no parity 8 bits xon/xoff protocol both ways\r
+        xchg                   ; LODEF into hl register\r
+        push    h              ; Needed later\r
+        mvi     a,0\r
+        mov     m,a            ; Clear byte 0\r
+        inx     h\r
+        mov     m,a            ; Clear byte 1\r
+        inx     h\r
+        mvi     a,099h         ; XON/XOFF protocol, 8bits, no parity\r
+        mov     m,a            ; Flag into byte 2\r
+        pop     h              ; Restore address of LODEF\r
+ciflod  equ     $+1\r
+        call    $              ; LODEF routine (poked above)\r
+        pop     h              ; LIDEF (PUSHed from de earlier)\r
+        push    h              ; Needed later\r
+        mvi     a,0\r
+        mov     m,a            ; Clear byte 0\r
+        inx     h\r
+        mov     m,a            ; Clear byte 1\r
+        inx     h\r
+        mvi     a,099h         ; XON/XOFF protocol, 8bits, no parity\r
+        mov     m,a            ; Flag into byte 2\r
+        pop     h              ; Restore address of LIDEF\r
+ciflid  equ     $+1\r
+        call    $              ; LIDEF routine (poked above)\r
+        lhld    ciptbl         ; Get current input speed\r
+        mov     a,m\r
+        sta     speed\r
+        sta     speed+1\r
+        mov     e,a\r
+        mov     d,a\r
+        call    sysspd         ; Make sure ip and op are the same\r
+ENDIF; cifer AND cifaux \r
+\r
+        ret                     ; return from system-dependent routine\r
+\r
+;\f\r
+;\r
+;       system-dependent termination processing\r
+;       If we've changed anything, this is our last chance to put it back.\r
+sysexit:\r
+\r
+IF cifer AND NOT cifaux\r
+        lxi     d,cifero\r
+        call    prtstr\r
+ENDIF;cifer AND NOT cifaux\r
+\r
+        ret\r
+\r
+;\r
+;       system-dependent processing for start of CONNECT command\r
+;\r
+syscon:\r
+        ret\r
+\r
+conmsg:         ; Messages printed when entering transparent (CONNECT) mode:\r
+;\f\r
+;\r
+;       syscls - system-dependent close routine\r
+;       called when exiting transparent session.\r
+;\r
+syscls:\r
+        ret\r
+;\f\r
+;\r
+;       sysinh - help for system-dependent special functions.\r
+;       called in response to <escape>?, after listing all the\r
+;       system-independent escape sequences.\r
+;\r
+sysinh:        lxi     d,inhlps        ; we got options...\r
+       call    prtstr          ; print them.\r
+\r
+        ret\r
+\r
+\r
+;additional, system-dependent help for transparent mode\r
+; (two-character escape sequences)\r
+inhlps:\r
+\r
+; [16] [18] have added super brain and Torch to the list of Breaking machines.\r
+\r
+IF (cifer AND NOT cifaux)\r
+        db      cr,lf,'B  Transmit a BREAK'\r
+ENDIF   ;(cifer AND NOT cifaux)\r
+        db      '$'                     ;[hh] table terminator\r
+\r
+;\r
+;       sysint - system dependent special functions\r
+;       called when transparent escape character has been typed;\r
+;       the second character of the sequence is in A (and in B).\r
+;       returns:\r
+;       non-skip: sequence has been processed\r
+;       skip:   sequence was not recognized\r
+sysint: ani     137O            ; convert lower case to upper, for testing...\r
+\r
+; [19] have added superbrain and torch to the list\r
+\r
+IF (cifer AND NOT cifaux)\r
+        cpi     'B'             ; send break?\r
+        jz      sendbr          ; yes, go do it.  return nonskip when through.\r
+ENDIF   ;(cifer AND NOT cifaux)\r
+\r
+        jmp     rskp            ; take skip return - command not recognized.\r
+\r
+;\f\r
+\r
+IF (cifer AND NOT cifaux)\r
+sendbr: lxi     d,brkmes        ; send a break by sending esc * "\r
+        call    prtstr          ; send to screen => breaks to port\r
+        ret\r
+ENDIF;cifer\r
+\r
+;      sysflt - system-dependent filter.\r
+;      called with the character in E.\r
+;       preserves bc, de, hl.\r
+;       note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r
+sysflt:\r
+        mov     a,e             ; get character for testing\r
+        ret\r
+\r
+;       mdmflt - modem filter [30]\r
+;       called with character to be sent to printer in E\r
+;       with parity set as appropriate.\r
+;       return with accumulator = 0 do do nothing,\r
+;                               <> 0 to send char in E.\r
+mdmflt:\r
+        mov     a,e             ;[30] get character to test\r
+        ret\r
+\r
+\r
+\r
+;       prtflt - printer filter [30]\r
+;       called with character to be sent to printer in E\r
+;       returns with a = 0 to do nothing\r
+;                    a <> 0 to print it.\r
+;\r
+;       this routine for those printer that automatically insert\r
+;       a lf on cr, or cr for lf.  Should this be shifted to \r
+;       the system indep. stuff, in say 4.06?\r
+prtflt:\r
+        mov     a,e             ; [30] get character to test\r
+        ret\r
+\r
+\r
+;\f\r
+;\r
+; system-dependent processing for BYE command.\r
+;  for apmmdm, heath, and lobo, hang up the phone.\r
+sysbye:\r
+        ret\r
+;\f\r
+;       This is the system-dependent command to change the baud rate.\r
+;       DE contains the two-byte value from the baud rate table; this\r
+;       value is also stored in 'speed'.\r
+sysspd:\r
+\r
+IF (cifer AND NOT cifaux); This one is wierd.. \r
+                               ; send an escape string to the screen to set rate.\r
+        push    d               ; Save the data returned\r
+        lxi     d,cifbrt                ; send the start of the escape string (esc ?)\r
+        call    prtstr          ;\r
+        pop     psw             ; get data into a (and flags>..)\r
+        inr     a               ; need to send (a+1-1) 'N' to screen\r
+        push    psw             ; we will need the data again\r
+        call    cifnos          ; send a set of Ns to the screen\r
+        pop     psw             ; (which then sets the VL line on the screen \r
+        call    cifnos          ; processor card)\r
+        call    prcrlf          ; cr will terminate.. a crlf is handy\r
+        ret\r
+\r
+cifnos: dcr     a               ; if result = 0 then done\r
+        jz      cifno1          ; if done then say 'Y' for yes.\r
+        push    psw\r
+        mvi     e,'N'           ; else send a string of Ns to screen processor\r
+        mvi     c,dconio\r
+        call    bdos\r
+        pop     psw\r
+        jmp     cifnos\r
+cifno1: mvi     e,'Y'\r
+        mvi     c,dconio\r
+        call    bdos\r
+        ret                     ; sent a sring of 0 or more N then a Y\r
+\r
+cifbrt: db      esc,'?$'        ; start setting baud rate string\r
+ENDIF ;cifer AND NOT cifaux\r
+\r
+IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling\r
+                               ;CIOPS routine\r
+; Set up speed byte in first location of tables\r
+        lhld    coptbl         ; Now sort out baud rate\r
+        mov     a,e            ; That's output speed\r
+        mov     m,a\r
+        xchg\r
+        lhld    ciptbl\r
+        mov     m,a            ; Input speed\r
+; Call CIOPS routine SETLNSPD with tables in appropriate rp's\r
+cifiop  equ     $+1\r
+        call    $              ; Poked by sysinit\r
+        ret\r
+\r
+coptbl: dw      0\r
+ciptbl: dw      0\r
+ENDIF; cifaux\r
+\r
+;\f\r
+;       Speed tables\r
+; (Note that speed tables MUST be in alphabetical order for later\r
+; lookup procedures, and must begin with a value showing the total\r
+; number of entries.  The speed help tables are just for us poor\r
+; humans.\r
+\r
+;       db      string length,string,divisor (2 identical bytes or 1 word)\r
+; [Toad Hall]\r
+\r
+IF cifer \r
+spdtbl: db      10h                     ;16 entries\r
+        db      03h,'110$',     02h,02h\r
+        db      04h,'1200$',    07h,07h\r
+        db      05h,'134.5$',   03h,03h\r
+        db      03h,'150$',     04h,04h\r
+        db      04h,'1800$',    08h,08h\r
+        db      05h,'19200$',   0fh,0fh\r
+        db      04h,'2000$',    09h,09h\r
+        db      04h,'2400$',    0ah,0ah\r
+        db      03h,'300$',     05h,05h\r
+        db      04h,'3600$',    0bh,0bh\r
+        db      04h,'4800$',    0ch,0ch\r
+        db      02h,'50$',      00h,00h\r
+        db      03h,'600$',     06h,06h\r
+        db      04h,'7200$',    0dh,0dh\r
+        db      02h,'75$',      01h,01h\r
+        db      04h,'9600$',    0eh,0eh\r
+\r
+sphtbl: db      cr,lf,'   50     75    110    134.5  150    300    600   1200'\r
+        db      cr,lf,' 1800   2000   2400   3600   4800   7200   9600  19200$'\r
+ENDIF;cifer \r
+\r
+; The following conditionals were once a huge if not statement.  There\r
+; wasn't enough room to add the lobo to the list, so it had to be broken\r
+; into 2, which you can't do with an if not.  I redid it as two ifs and\r
+; applied them to those that wouldn't set baud. [Hal Hostetler]\r
+;\f\r
+;       This is the system-dependent SET PORT command.\r
+;       HL contains the argument from the command table.\r
+sysprt:\r
+IF iobyt\r
+        mov     a,m             ;Get the I/O byte\r
+        sta     prtiob          ;Save the desired IO byte for this port\r
+        inx     h               ;Point at next entry\r
+        mov     a,m             ;Get the output function\r
+        sta     prtfun          ;Save it\r
+ENDIF;iobyt\r
+\r
+        ret\r
+;\f\r
+;\r
+;\r
+;       Port tables for GENERIC CPM 2.2\r
+IF gener\r
+; help text\r
+prhtbl: db      cr,lf,'CRT device'\r
+        db      cr,lf,'PTR device'\r
+        db      cr,lf,'TTY device'\r
+        db      cr,lf,'UC1 device'\r
+        db      cr,lf,'UR1 device'\r
+        db      cr,lf,'UR2 device$'\r
+\r
+; command table\r
+prttbl: db      06H             ;Six devices to choose from\r
+        db      03H,'CRT$'\r
+                dw      crtptb\r
+        db      03H,'PTR$'\r
+                dw      ptrptb\r
+        db      03H,'TTY$'\r
+                dw      ttyptb\r
+        db      03H,'UC1$'\r
+                dw      uc1ptb\r
+        db      03H,'UR1$'\r
+                dw      ur1ptb\r
+        db      03H,'UR2$'\r
+                dw      ur2ptb\r
+\r
+; port entry table\r
+; table entries are:\r
+;       db      iobyte-value, BDOS output function, reserved\r
+crtptb: db      crtio,conout,0\r
+ptrptb: db      ptrio,punout,0\r
+ttyptb: db      ttyio,conout,0\r
+uc1ptb: db      uc1io,conout,0\r
+ur1ptb: db      ur1io,punout,0\r
+ur2ptb: db      ur2io,punout,0\r
+ENDIF;gener\r
+\r
+;\f\r
+;\r
+IF cifer                        ; no ports yet...\r
+prttbl   EQU     0\r
+prhtbl   EQU     0               ;\r
+ENDIF; cifer\r
+\r
+IF iobyt\r
+prtfun: db      punout          ;Function to use for output to comm port\r
+prtiob: db      batio           ;I/O byte to use for communicating\r
+ENDIF;iobyt\r
+\r
+IF NOT (iobyt OR lobo OR cifer)          ;[hh]\r
+prttbl  equ     0               ; SET PORT is not supported\r
+prhtbl  equ     0\r
+ENDIF;NOT (iobyt OR lobo OR cifer)\r
+\r
+;\f\r
+;\r
+;       selmdm - select modem port\r
+;       selcon - select console port\r
+;       selmdm is called before using inpmdm or outmdm;\r
+;       selcon is called before using inpcon or outcon.\r
+;       For iobyt systems, diddle the I/O byte to select console or comm port;\r
+;       For Decision I, switches Multi I/O board to console or modem serial\r
+;       port.  [Toad Hall]\r
+;       For the rest, does nothing.\r
+;       preserves bc, de, hl.\r
+selmdm:\r
+IF iobyt\r
+        lda     prtiob          ;Set up for output to go to the comm port\r
+        sta     iobyte          ;Switch byte directly\r
+ENDIF;iobyt\r
+\r
+        ret\r
+\r
+selcon:\r
+IF iobyt\r
+        lda     coniob          ;Set up for output to go to the console port\r
+        sta     iobyte          ;Switch directly\r
+ENDIF;iobyt\r
+\r
+        ret\r
+;\f\r
+;       Get character from console, or return zero.\r
+;       result is returned in A.  destroys bc, de, hl.\r
+;\r
+inpcon:\r
+IF NOT iobyt\r
+        mvi     c,dconio        ;Direct console I/O BDOS call.\r
+        mvi     e,0FFH          ;Input.\r
+        call    BDOS\r
+ENDIF;NOT iobyt\r
+\r
+IF iobyt\r
+        call    bconst          ;Get the status\r
+        ora     a               ;Anything there?\r
+        rz                      ;No, forget it\r
+        call    bconin          ;Yes, get the character\r
+ENDIF;iobyt\r
+        ret\r
+;\f\r
+;\r
+;       Output character in E to the console.\r
+;       destroys bc, de, hl\r
+;\r
+outcon:\r
+\r
+IF NOT iobyt\r
+        mvi     c,dconio        ;Console output bdos call.\r
+        call    bdos            ;Output the char to the console.\r
+ENDIF;NOT iobyt\r
+\r
+IF iobyt\r
+        mov     c,e             ;Character\r
+        call    bcnout          ;to Console\r
+ENDIF;iobyt\r
+        ret\r
+;\f\r
+;\r
+;       outmdm - output a char from E to the modem.\r
+;               the parity bit has been set as necessary.\r
+;       returns nonskip; bc, de, hl preserved.\r
+outmdm:\r
+IF inout\r
+        in      mnprts          ;Get the output done flag.\r
+        ani     output          ;Is it set?\r
+        jz      outmdm          ;If not, loop until it is.\r
+        mov     a,e\r
+        out     mnport          ;Output it.\r
+        ret\r
+ENDIF;inout\r
+\r
+IF iobyt\r
+;**** Note that we enter from outpkt with the I/O byte already set up for\r
+;  output to go to the comm port\r
+        push    h\r
+        push    b\r
+        lda     prtfun          ;Get the output function\r
+        mov     c,a             ;Into C\r
+        call    bdos            ;And output the character\r
+        pop     b\r
+        pop     h\r
+        ret\r
+ENDIF;iobyt\r
+\r
+IF cifer3                      ; [JAS]\r
+        push    h\r
+        push    b\r
+        mvi     c,auxout        ;Output to the aux output device\r
+        call    bdos\r
+        pop     b\r
+        pop     h\r
+        ret\r
+ENDIF;cifer3\r
+\r
+\r
+;\f\r
+;\r
+;       get character from modem; return zero if none available.\r
+;       for IOBYT systems, the modem port has already been selected.\r
+;       destroys bc, de, hl.\r
+inpmdm:\r
+IF iobyt\r
+        call    bconst          ;Is Char at COMM-Port?\r
+        ora     a               ;something there?\r
+        rz                      ; return if nothing there\r
+        call    bconin          ; data present. read data.\r
+ENDIF;iobyt\r
+\r
+IF inout\r
+;Note: modem port should already be selected for mdI.  [Toad Hall]\r
+        in      mnprts          ;Get the port status into A.\r
+        ani     input           ;See if the input ready bit is on.\r
+        rz                      ;If not then return.\r
+        in      mnport          ;If so, get the char.\r
+ENDIF;inout\r
+\r
+IF cifer3                      ; [JAS]\r
+        mvi     c,auxist\r
+        call    bdos            ;is char at auxin?\r
+        ora     a               ;something there?\r
+        rz                      ;no\r
+        mvi     c,auxin\r
+        call    bdos            ;read char from auxin\r
+ENDIF;cifer3\r
+\r
+ret                     ; return with character in A\r
+\r
+\r
+;\r
+;       flsmdm - flush comm line.\r
+;       Modem is selected.\r
+;       Currently, just gets characters until none are available.\r
+\r
+flsmdm: call    inpmdm          ; Try to get a character\r
+        ora     a               ; Got one?\r
+        jnz     flsmdm          ; If so, try for another\r
+        ret                     ; Receiver is drained.  Return.\r
+\r
+\r
+;\f\r
+;\r
+;       lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.\r
+lptstat:\r
+IF iobyte       ;[33]\r
+        call    bprtst          ; get status\r
+ENDIF   ;iobyte[33]\r
+IF NOT iobyte   ;[33]\r
+        xra     a               ; assume it is ok.. this may not be necessary\r
+ENDIF   ;iobyte [33]\r
+        ret\r
+;\f\r
+;\r
+;       outlpt - output character in E to printer\r
+;       console is selected.\r
+;       preserves de.\r
+outlpt:\r
+        push    d               ; save DE in either case\r
+        call    prtflt          ; go through printer filter [30]\r
+        ana     a               ; if A = 0 do nothing,\r
+        jz      outlp1          ; [30] if a=0 do nothing\r
+\r
+IF NOT iobyte\r
+        mvi     c,lstout\r
+        call    bdos            ;Char to printer\r
+ENDIF;NOT iobyt\r
+IF iobyt\r
+        mov     c,e\r
+        call    blsout\r
+ENDIF;iobyt\r
+\r
+outlp1: pop     d               ; restore saved register pair\r
+        ret\r
+;\f\r
+;\r
+;       Screen manipulation routines\r
+;       csrpos - move to row B, column C\r
+;\r
+;       csrpos for terminals that use a leadin sequence followed\r
+;        by (row + 31.) and (column + 31.)\r
+;\r
+IF cifer                        ; [14] cifer does it colums then rows.. swap b and c\r
+csrpos: push    b               ; save coordinates\r
+        lxi     d,curldn        ; get cursor leadin sequence\r
+        call    prtstr          ; print it\r
+        pop     h               ; restore coordinates\r
+        mov     a,l             ; [obs] get column\r
+        adi     (' '-1)         ; space is column one\r
+        mov     e,a\r
+        push    h\r
+        call    outcon          ; output row\r
+        pop     h\r
+        mov     a,h             ; [obs] get row\r
+        adi     (' '-1)         ; space is row one\r
+        mov     e,a\r
+        jmp     outcon          ; output it and return\r
+ENDIF; cifer \r
+\r
+;\r
+;\r
+; delchr - make delete look like a backspace.  Unless delete is a printing\r
+;       character, we just need to print a backspace. (we'll output clrspc\r
+;       afterwards)\r
+;       For Kaypro and Vector General, delete puts a blotch on the screen.\r
+;       For Apple and Osborne 1, delete moves but doesn't print.\r
+delchr:\r
+       mvi     e,bs\r
+       call    outcon\r
+\r
+; erase the character at the current cursor position\r
+clrspc: mvi     e,' '\r
+        call    outcon\r
+        mvi     e,bs            ;get a backspace\r
+        jmp     outcon\r
+\r
+; erase the current line\r
+clrlin: lxi     d,eralin\r
+        jmp     prtstr\r
+\r
+; erase the whole screen, and go home. preserves b (but not c)\r
+clrtop: lxi     d,erascr\r
+        jmp     prtstr\r
+\r
+\r
+IF cifer AND NOT cifaux        ;[13]\r
+ttytyp: db      'Cifer 1886 (Parity set to space only)$'\r
+ENDIF; cifer AND NOT cifaux\r
+\r
+IF cifaux                      ;JAS\r
+ttytyp: db      ' Cifer 1886 $'\r
+ENDIF; cifaux\r
+\r
+IF cifer                       ;[JAS]\r
+sysver: db      ' Cifer 1886 $'         ;\r
+outlin: db      esc,'J',cr,lf,tab,tab,'$'\r
+eralin: db      esc,'^K$'               ;Clear to end of line.\r
+erascr: db      esc,'J$'                ;Clear screen and go home.\r
+curldn: db      esc,'P$'                ;Cursor lead-in\r
+ttab:                                   ;Table start location.\r
+ta:     db      esc,'A$',0              ;Cursor up.\r
+tb:     db      esc,'@$',0              ;Cursor down.\r
+tc:     db      esc,'C$',0              ;Cursor right.\r
+td:     db      esc,'D$',0              ;Cursor left.\r
+te:     db      esc,'J',0,0             ;Clear screen and home cursor\r
+tf:     db      '$',0,0,0               ;(can't) Enter Graphics mode\r
+tg:     db      '$',0,0,0               ;(can't) Exit Graphics mode\r
+th:     db      esc,'H$',0              ;Cursor home.\r
+ti:     db      esc,'@$',0              ;reverse linfeed\r
+tj:     db      esc,'B$',0              ;Clear to end of screen\r
+tk:     db      esc,'K$',0              ;Clear to end of line.\r
+ENDIF;cifer\r
+;\r
+IF cifer AND NOT cifaux                        ;[JAS]\r
+; Setup string for the Cifer.. called as a prtstr param. from sysinit\r
+ciferi: db      esc,'/'                 ;Setup cifer for on line\r
+        db      esc,'*['                ; direct mode on\r
+        db      esc,'%'                 ; protocol on host line on\r
+        db      esc,'*~x'               ; protocol is xon/xoff\r
+        db      esc,'*('                ; protocol out on host is xon/xoff\r
+        db      esc,'?  NNNY',cr        ; set VL port to space parity\r
+                                        ; It cannot do NONE.. Thanks a lot\r
+        db      '$'                     ; all done\r
+; Finish string for the Cifer.. called as a prtstr param. from sysexit\r
+cifero: db      esc,'&'                        ; Host input protocol off\r
+        db      esc,'*)'               ; Host output protocol off\r
+        db      esc,'*]'               ; Direct mode off\r
+        db      esc,'\'                        ; Setup cifer for off line\r
+        db      '$'\r
+; Break string for cifer VL port.\r
+brkmes: db      esc,'*"$'               ;Send a break command string\r
+ENDIF;cifer AND NOT cifaux     [13]\r
+\r
+ovlend equ     $       ; End of overlay\r
+\r
+       END\r
+\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\r