]> cloudbase.mooo.com Git - kermit-80.git/blobdiff - cpxsb.asm
Convert line endings to CP/M format (cr/lf).
[kermit-80.git] / cpxsb.asm
index 3beefe7b2a8a183fdd5d4b48b1d4842ed06a7394..18056d4e23526cee55abb8f2af2478a519591502 100644 (file)
--- a/cpxsb.asm
+++ b/cpxsb.asm
-IF NOT lasm
-.printx * CPXSB.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 created 16 July, 1987 by OBSchou from code submitted
-;      by William Rose for the Micromint SB180 systems (as featured in
-;      BYTE magazine, 1986).  This file has been modified to fit in with
-;      Kermit-80 V4.08 etc.  His file KERSYS.ASM is a stripped down version
-;      of CPXSYS.ASM (formerly CP4SYS.ASM).
-;
-; revision history:
-; KERSYS.ASM - version 0.8 dated 13 Jul 87.
-;
-; Cutdown CP4SYS.ASM for SB-180/Ampro 230.
-;
-;
-; While this is a single CPU version (to ease editing) the assembler
-; conditionals have been kept to identify machine specific code.
-;
-; Note that the baud setting routine also sets parity, but this does not
-; change the parity given by Kermit's 'stat' command.  I assume that the
-; main body of the program does its own parity check.
-;
-; Revision history (last entry first)
-;
-; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM.
-;
-; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted
-;      the code for Kermit-80 V 4.05.  Modified code as appropriate 
-;      for 4.08 compatability.
-;
-
-delfac EQU     150     ; Delay factor in SB-180 input loop - a fudge
-
-;
-; Keep module name, edit number, and last revision date in memory.
-;
-;sysedt:       db      'KERSYS.ASM (03) 12-FEB-87 $'   ; last SB-180 revision
-;sysedt:       db      'KERSYS.ASM (04) 12-APR-87 $'   ; Telecom Merlin added
-;sysedt:       db      'KERSYS.ASM (5)  9-May-87 $'    ; Minor tidying
-;sysedt:       db      'KERSYS.ASM (6A) 17-Jun-87 $'   ; BT Merlin M2215 only
-;sysedt:       db      'KERSYS.ASM (7)  19-Jun-87 $'   ; SB-180 only
-;sysedt:       db      'KERSYS.ASM (8)  13-Jul-87 $'   ; 6/9 MHz version
-family:        db      'CPXSB.ASM (2)  22-Jul-87$'     ; First entry for V4.08/9
-
-;
-; Assembly time message to let me know I'm building the right version.
-;
-
-IF sb180
-.printx * Assembling Kermit-80 for Micromint SB-180 *
-ENDIF
-
-
-IF sb180
-mnctrla        EQU     000H    ;Modem control port - CNTLA0
-mnctrlb        EQU     002H    ;Modem control port - CNTLB0
-mnstat EQU     004H    ;Modem status port - STAT0
-mntxdat        EQU     006H    ;Modem output port - TDR0
-mnrddat        EQU     008H    ;Modem input port - RDR0
-output EQU     002H    ;Transmit data register empty mask - TDRE
-input  EQU     080H    ;Receive data register full mask - RDRF
-z80    EQU     TRUE    ;This one's an HD64180, but Z80 will do 
-ENDIF
-
-
-sysxin:                ; continuation of system initialisation from sysinit
-
-IF sb180
-       lxi     h, porbuf       ; park the original settings
-       db      0EDh, 038h, mnctrla     ; HD64180 code IN0 g,(m)
-       mov     m, a
-       inx     h
-       db      0EDh, 038h, mnctrlb
-       mov     m, a
-       inx     h
-       db      0EDh, 038h, mnstat
-       mov     m, a
-ENDIF
-                               ; re-initialise for KERMIT
-IF sb6
-       mvi     h, 08h          ; 0000$1001 - 9600 baud, (even) parity
-       mvi     l, 08h          ; 'speed' is two bytes
-ENDIF
-
-IF sb9
-       mvi     h, 21h          ; 0010$0001 - 9600 baud, (even) parity
-       mvi     l, 21h          ; 'speed' is two bytes
-ENDIF
-
-IF sb180
-       shld    speed
-       lxi     h, parind
-       mvi     m, 8            ; index for 8 bits, no parity, 2 stop
-       call    setpor
-ENDIF
-
-       ret
-
-porbuf:        ds      3               ; original port settings
-   
-;
-;      system-dependent KERMIT termination processing
-;      If we've changed anything, this is our last chance to put it back.
-;
-sysexit:
-
-IF sb180
-       lxi     h, porbuf
-       mov     a, m            ; output parity
-       db      0EDh, 039h, mnctrla     ; HD64180 code OUT0 (m),g
-       inx     h
-       mov     a, m            ; output baud rate
-       db      0EDh, 039h, mnctrlb
-       inx     h
-       mov     a, m            ; output to clear error flags 
-       db      0EDh, 039h, mnstat
-                               ; read twice to reset DCD0 ?
-       db      0EDh, 038h, mnstat
-       db      0EDh, 038h, mnstat
-ENDIF
-
-       ret
-
-;
-;      system-dependent processing for start of CONNECT command
-;
-syscon:
-       ret
-
-conmsg:                ; Messages printed when entering transparent (CONNECT) mode:
-
-       db      '$'
-
-;
-;      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 sb180 
-       lxi     d, inhlps
-       call    prtstr
-ENDIF
-
-       ret
-
-; Additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-IF sb180
-       db      cr, lf, 'V  Cycle port parameters'
-ENDIF
-
-       db      '$'                     ; string 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:   seqence was not recognized
-;
-sysint:
-;      ani     137O            ; convert lower case to upper, for testing...
-                               ; does this work?
-IF sb180
-       cpi     'V'             ; cycle port ?
-       jz pcycl
-       cpi     'v'
-       jz pcycl
-ENDIF
-
-       jmp     rskp            ; take skip return - command not recognised
-
-; Actual commands
-
-IF sb180
-pcycl:
-       lxi     h, parind       ; increment parval, modulo 12
-       mov     a, m
-       adi     1
-       cpi     13
-       jnz     pcy1
-       mvi     a, 1
-pcy1:  mov     m, a            ; update the storage
-                               ; get index of name in parstr
-       ora     a               ; clear flags
-       dcr     a
-       rlc
-       rlc
-       mov     c, a
-       mvi     b, 0
-       lxi     h, parstr
-       inx     h
-       dad     b
-       push    h
-       lxi     d, cgmsg1
-       call    prtstr
-       pop     d
-       call    prtstr
-       lxi     d, cgmsg2
-       call    prtstr
-       call    setpor          ; reset the port
-
-       ret
-
-cgmsg1:        db      '<$'
-cgmsg2: db     '>$'
-ENDIF
-
-       ret
-
-;
-;      Delay routine.  Called with time (hundredths of seconds) in A.
-;      The inner loop delays 1001 T-states, assuming no wait states are
-;      inserted; this is repeated CPUSPD times, for a total delay of just
-;      over 0.01 second. (CPUSPD should be set to the system clock rate,
-;      in units of 100KHz: for an unmodified Kaypro II, that's 25 for
-;      2.5 MHz.  Some enterprising soul could determine whether or not the
-;      Kaypro actually inserts a wait state on instruction fetch (a common
-;      practice); if so, the magic number at delay2 needs to be decreased.
-;      (We also neglect to consider time spent at interrupt level).
-;
-;      called by: sendbr
-;      destroys BC
-;
-;delay:        mvi     c,cpuspd        ; Number of times to wait 1000 T-states to
-;                              ;  make .01 second delay
-;delay2:       mvi     b,70            ; Number of times to execute inner loop to
-;                              ;  make 1000 T-state delay
-;delay3:       dcr     b               ; 4 T-states (* 70 * cpuspd)
-;      jnz     delay3          ; 10 T-states (* 70 * cpuspd)
-;      dcr     c               ; 4 T-states (* cpuspd)
-;      jnz     delay2          ; 10 T-states (* cpuspd)
-;                              ; total delay: ((14 * 70) + 14) * cpuspd
-;                              ;  = 1001 * cpuspd
-;      dcr     a               ; 4 T-states
-;      jnz     delay           ; 10 T-states
-;
-;      ret                     ; grand total: ((1001 * cpuspd) + 14) * a
-
-;
-;      sysflt - system-dependent filter
-;      called with character in E.
-;      if this character should not be printed, return with A = zero.
-;      preserves bc, de, hl.
-;      note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
-       mov     a,e             ; get character for testing
-       ret
-
-;
-;      mdmflt - modem filter
-;      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             ; get character to test
-       ret
-
-;
-;      prtflt - printer filter
-;      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             ; get character to test
-
-IF FALSE                       ; strip out lf from printer stream
-       ani     7fh             ; make sure it is parity less
-       cpi     lf              ; is it a line feed?
-       rnz                     ; no, print it
-;      xra     a               ; yes, don't.
-       
-ENDIF
-
-       ret
-
-;
-; system-dependent processing for BYE command.
-;
-sysbye:
-       ret
-
-;
-;      This is the system-dependent command to change the baud rate.
-;      DE contains the two-byte value from the baud rate table; both
-;      bytes of this value are also stored in 'speed'.
-;
-sysspd:
-
-IF sb180
-       lxi     d, prtmsg       ; ask for variables
-       call    prtstr
-
-       lxi     d, tbuf         ; get suitable string
-       mvi     c, 10
-       call    bdos
-
-       lxi     h, tbuf1
-       mov     a, m
-       ora     a
-       jz      setpor          ; leave unchanged if string zero length
-
-       cpi     3               ; check given length
-       jnz     spd1            ; error - wrong length
-       inx     h
-       inx     h
-       mov     a, m
-       ani     137O            ; convert parity code to upper case
-       mov     m, a
-
-       lxi     d, tbuf1        ; get index of given parameter
-       lxi     h, parstr
-       call    sposn
-       ora     a
-       jnz     spd2            ; or fall through if error
-spd1:  lxi     d, invmsg       ; invalid input - try again
-       call    prtstr
-       jmp     sysspd
-
-spd2:  adi     3               ; get index to parval table
-       rrc                     ; by dividing by 4 
-       rrc
-       ani     15              ; mask out high bits
-       lxi     h, parind
-       mov     m, a            ; and store it
-       call    setpor          ; set up port iaw index and speed bytes
-
-       ret
-
-prtmsg:        db      cr,lf,'Enter bit/char, parity, and stop bits required.'
-       db      cr,lf,'(Bit 7/8   Parity N/O/E   Stop 1/2  - CR same) : $'
-invmsg: db     cr,lf,'Invalid parameters$'
-
-parind:        db      8               ; default <8N2> index
-parstr:        db      48,'7N1$7N2$7O1$7O2$7E1$7E2$'
-       db         '8N1$8N2$8O1$8O2$8E1$8E2$'
-parval:        db      0,1,16+2,16+3,2,3
-       db      4,5,16+6,16+7,6,7
-tbuf   db      6
-tbuf1  db      3,'8N2','$$$$'
-
-;
-; Set up the port using the table index in parind and the speed byte
-;
-setpor:
-       lxi     h, parind
-       mov     a, m
-       dcr     a
-       lxi     h, parval       ; table base
-       mvi     b, 0
-       mov     c, a
-       dad     b               ; HL points at parameter value
-       mov     a, m
-       mov     b, a            ; park parval
-
-       ani     16              ; the parity switch bit
-       lxi     h, speed
-       add     m               ; this is now the baud rate byte
-       mov     c, a            ; park it
-
-       mov     a, b            ; sort out the parameter byte
-       ani     7               ; b/p/s only wanted
-       adi     96              ; RE, TE enable
-       db      0EDh,039h,mnctrla       ; output parity etc.
-       mov     a, c
-       db      0EDh,039h,mnctrlb       ; output baud rate
-       mvi     a, 0
-       db      0EDh,039h,mnstat        ; clear status
-       db      0EDh,038h,mnstat        ; read twice to reset DCD0
-       db      0EDh,038h,mnstat
-       ret
-
-;
-; Find substring position - Leventhal page 293, modified
-; enter with subtring in DE and string in HL
-; returns index in A or 0 for failure
-;
-sposn:
-       mov     a, m            ; exit if either string length zero
-       ora     a
-       jz      notfnd
-       sta     slen
-       mov     b, a
-       inx     h
-       shld    string
-       xchg
-       mov     a, m
-       ora     a
-       jz      notfnd
-       sta     sublen
-       mov     c, a
-       inx     h
-       shld    substg
-       mov     a, b
-
-; no of searches = stringlen - substrlen + 1
-; if substr longer than string quit immediately
-
-       sub     c
-       jc      notfnd
-       inr     a
-       mov     c, a
-       xra     a
-       sta     index
-
-; search until remaining string shorter than substring
-
-slp1:  lxi     h, index
-       inr     m
-       lda     sublen
-       mov     b, a
-       lhld    substg
-       xchg
-       lhld    string
-
-; try to match substring starting at index
-
-cmplp: ldax    d
-       cmp     m
-       jnz     slp2
-       dcr     b
-       jz      found
-       inx     h
-       inx     d
-       jmp     cmplp
-
-; arrive here if match fails
-
-slp2:  dcr     c
-       jz      notfnd
-       lhld    string
-       inx     h
-       shld    string
-       jmp     slp1
-
-; found, return index
-
-found: lda     index
-       ret
-
-; not found, return zero
-
-notfnd:        sub     a
-       ret
-
-string:        ds      2
-substg:        ds      2
-slen:  ds      1
-sublen:        ds      1
-index: ds      1
-ENDIF
-
-       ret
-
-;
-;      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 bytes or 1 word, ab)
-;              the data byte a is return in A and E, and b in D
-;              only byte 'a' is the key for the table
-
-IF sb6
-spdtbl:        db      9                       ; 9 entries
-       db      04h,'1200$',    0Bh,0Bh
-       db      03h,'150$',     0Eh,0Eh
-       db      05h,'19200$',   01h,01h
-       db      04h,'2400$',    0Ah,0Ah
-       db      03h,'300$',     0Dh,0Dh
-       db      05h,'38400$',   00h,00h
-       db      04h,'4800$',    09h,09h
-       db      03h,'600$',     0Ch,0Ch
-       db      04h,'9600$',    08h,08h
-
-sphtbl: db     cr,lf
-       db '   150  300  600  1200  2400  4800  9600  19200  38400$'
-ENDIF
-
-IF sb9
-spdtbl:        db      7                       ; 7 entries
-       db      04h,'1200$',    24h,24h
-       db      05h,'19200$',   20h,20h
-       db      04h,'2400$',    23h,23h
-       db      03h,'300$',     26h,26h
-       db      04h,'4800$',    22h,22h
-       db      03h,'600$',     25h,25h
-       db      04h,'9600$',    21h,21h
-
-sphtbl: db     cr,lf
-       db '   300  600  1200  2400  4800  9600  19200$'
-ENDIF
-
-
-;
-;      This is the system-dependent SET PORT command.
-;      HL contains the argument from the command table.
-;
-sysprt:
-       ret
-
-IF sb180
-prttbl EQU     0               ; SET PORT is not supported
-prhtbl EQU     0
-ENDIF
-
-;
-;      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 the rest, does nothing.
-;      preserves bc, de, hl.
-;
-selmdm:
-       ret
-
-selcon:
-       ret
-
-;
-;      Get character from console, or return zero.
-;      result is returned in A.  destroys bc, de, hl.
-;
-inpcon:
-       mvi     c,dconio        ;Direct console I/O BDOS call.
-       mvi     e,0FFH          ;Input.
-       call    BDOS
-
-       ret
-
-;
-;      Output character in E to the console.
-;      destroys bc, de, hl
-;
-outcon:
-       mvi     c,dconio        ;Console output bdos call.
-       call    bdos            ;Output the char to the console.
-
-       ret
-
-;
-;      outmdm - output a char from E to the modem.
-;              the parity bit has been set as necessary.
-;      returns nonskip; bc, de, hl preserved.
-;
-outmdm:
-
-IF sb180
-       db      0EDh,038h,mnstat
-       ani     output          ; check status
-       jz      outmdm          ; wait until port is available
-       mov     a, e
-       db      0EDh,039h,mntxdat       ; transmit
-ENDIF
-
-       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:
-
-IF sb180
-       lxi     h, delfac       ; loops to give delay
-inpm1: db      0EDh,038h,mnstat
-       ani     input           ; check status  
-       jz      inpm2
-       db      0EDh,038h,mnrddat       ; get a byte
-       ret
-
-inpm2: dcx     h               ; no data
-       mov     h, a
-       ora     l
-       jnz     inpm1           ; still tries left
-       ret                     ; with zero in A
-ENDIF
-
-       ret
-
-;
-;      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
-;
-;      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          ; if a=0 do nothing
-
-outlp1:        pop     d               ; restore saved register pair
-       ret
-
-; 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)
-delchr:
-
-       mvi     e,bs            ;get a backspace
-       jmp     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 sb180
-sysver:        db      'MicroMint SB 180 '
-ENDIF
-
-IF sb6
-       db      ' (6 MHz)'
-ENDIF
-
-IF sb9
-       db      ' (9 MHz)'
-ENDIF
-       db      '$'
-
-IF lasm
-LINK CPXVDU.ASM                ; get terminal defs etc
-ENDIF  ;lasm
+IF NOT lasm\r
+.printx * CPXSB.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 created 16 July, 1987 by OBSchou from code submitted\r
+;      by William Rose for the Micromint SB180 systems (as featured in\r
+;      BYTE magazine, 1986).  This file has been modified to fit in with\r
+;      Kermit-80 V4.08 etc.  His file KERSYS.ASM is a stripped down version\r
+;      of CPXSYS.ASM (formerly CP4SYS.ASM).\r
+;\r
+; revision history:\r
+; KERSYS.ASM - version 0.8 dated 13 Jul 87.\r
+;\r
+; Cutdown CP4SYS.ASM for SB-180/Ampro 230.\r
+;\r
+;\r
+; While this is a single CPU version (to ease editing) the assembler\r
+; conditionals have been kept to identify machine specific code.\r
+;\r
+; Note that the baud setting routine also sets parity, but this does not\r
+; change the parity given by Kermit's 'stat' command.  I assume that the\r
+; main body of the program does its own parity check.\r
+;\r
+; Revision history (last entry first)\r
+;\r
+; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM.\r
+;\r
+; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted\r
+;      the code for Kermit-80 V 4.05.  Modified code as appropriate \r
+;      for 4.08 compatability.\r
+;\r
+\r
+delfac EQU     150     ; Delay factor in SB-180 input loop - a fudge\r
+\r
+;\r
+; Keep module name, edit number, and last revision date in memory.\r
+;\r
+;sysedt:       db      'KERSYS.ASM (03) 12-FEB-87 $'   ; last SB-180 revision\r
+;sysedt:       db      'KERSYS.ASM (04) 12-APR-87 $'   ; Telecom Merlin added\r
+;sysedt:       db      'KERSYS.ASM (5)  9-May-87 $'    ; Minor tidying\r
+;sysedt:       db      'KERSYS.ASM (6A) 17-Jun-87 $'   ; BT Merlin M2215 only\r
+;sysedt:       db      'KERSYS.ASM (7)  19-Jun-87 $'   ; SB-180 only\r
+;sysedt:       db      'KERSYS.ASM (8)  13-Jul-87 $'   ; 6/9 MHz version\r
+family:        db      'CPXSB.ASM (2)  22-Jul-87$'     ; First entry for V4.08/9\r
+\r
+;\r
+; Assembly time message to let me know I'm building the right version.\r
+;\r
+\r
+IF sb180\r
+.printx * Assembling Kermit-80 for Micromint SB-180 *\r
+ENDIF\r
+\r
+\r
+IF sb180\r
+mnctrla        EQU     000H    ;Modem control port - CNTLA0\r
+mnctrlb        EQU     002H    ;Modem control port - CNTLB0\r
+mnstat EQU     004H    ;Modem status port - STAT0\r
+mntxdat        EQU     006H    ;Modem output port - TDR0\r
+mnrddat        EQU     008H    ;Modem input port - RDR0\r
+output EQU     002H    ;Transmit data register empty mask - TDRE\r
+input  EQU     080H    ;Receive data register full mask - RDRF\r
+z80    EQU     TRUE    ;This one's an HD64180, but Z80 will do \r
+ENDIF\r
+\r
+\r
+sysxin:                ; continuation of system initialisation from sysinit\r
+\r
+IF sb180\r
+       lxi     h, porbuf       ; park the original settings\r
+       db      0EDh, 038h, mnctrla     ; HD64180 code IN0 g,(m)\r
+       mov     m, a\r
+       inx     h\r
+       db      0EDh, 038h, mnctrlb\r
+       mov     m, a\r
+       inx     h\r
+       db      0EDh, 038h, mnstat\r
+       mov     m, a\r
+ENDIF\r
+                               ; re-initialise for KERMIT\r
+IF sb6\r
+       mvi     h, 08h          ; 0000$1001 - 9600 baud, (even) parity\r
+       mvi     l, 08h          ; 'speed' is two bytes\r
+ENDIF\r
+\r
+IF sb9\r
+       mvi     h, 21h          ; 0010$0001 - 9600 baud, (even) parity\r
+       mvi     l, 21h          ; 'speed' is two bytes\r
+ENDIF\r
+\r
+IF sb180\r
+       shld    speed\r
+       lxi     h, parind\r
+       mvi     m, 8            ; index for 8 bits, no parity, 2 stop\r
+       call    setpor\r
+ENDIF\r
+\r
+       ret\r
+\r
+porbuf:        ds      3               ; original port settings\r
+   \r
+;\r
+;      system-dependent KERMIT termination processing\r
+;      If we've changed anything, this is our last chance to put it back.\r
+;\r
+sysexit:\r
+\r
+IF sb180\r
+       lxi     h, porbuf\r
+       mov     a, m            ; output parity\r
+       db      0EDh, 039h, mnctrla     ; HD64180 code OUT0 (m),g\r
+       inx     h\r
+       mov     a, m            ; output baud rate\r
+       db      0EDh, 039h, mnctrlb\r
+       inx     h\r
+       mov     a, m            ; output to clear error flags \r
+       db      0EDh, 039h, mnstat\r
+                               ; read twice to reset DCD0 ?\r
+       db      0EDh, 038h, mnstat\r
+       db      0EDh, 038h, mnstat\r
+ENDIF\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
+\r
+       db      '$'\r
+\r
+;\r
+;      syscls - system-dependent close routine\r
+;      called when exiting transparent session.\r
+;\r
+syscls:\r
+       ret\r
+\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:\r
+\r
+IF sb180 \r
+       lxi     d, inhlps\r
+       call    prtstr\r
+ENDIF\r
+\r
+       ret\r
+\r
+; Additional, system-dependent help for transparent mode\r
+; (two-character escape sequences)\r
+inhlps:\r
+\r
+IF sb180\r
+       db      cr, lf, 'V  Cycle port parameters'\r
+ENDIF\r
+\r
+       db      '$'                     ; string 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:   seqence was not recognized\r
+;\r
+sysint:\r
+;      ani     137O            ; convert lower case to upper, for testing...\r
+                               ; does this work?\r
+IF sb180\r
+       cpi     'V'             ; cycle port ?\r
+       jz pcycl\r
+       cpi     'v'\r
+       jz pcycl\r
+ENDIF\r
+\r
+       jmp     rskp            ; take skip return - command not recognised\r
+\r
+; Actual commands\r
+\r
+IF sb180\r
+pcycl:\r
+       lxi     h, parind       ; increment parval, modulo 12\r
+       mov     a, m\r
+       adi     1\r
+       cpi     13\r
+       jnz     pcy1\r
+       mvi     a, 1\r
+pcy1:  mov     m, a            ; update the storage\r
+                               ; get index of name in parstr\r
+       ora     a               ; clear flags\r
+       dcr     a\r
+       rlc\r
+       rlc\r
+       mov     c, a\r
+       mvi     b, 0\r
+       lxi     h, parstr\r
+       inx     h\r
+       dad     b\r
+       push    h\r
+       lxi     d, cgmsg1\r
+       call    prtstr\r
+       pop     d\r
+       call    prtstr\r
+       lxi     d, cgmsg2\r
+       call    prtstr\r
+       call    setpor          ; reset the port\r
+\r
+       ret\r
+\r
+cgmsg1:        db      '<$'\r
+cgmsg2: db     '>$'\r
+ENDIF\r
+\r
+       ret\r
+\r
+;\r
+;      Delay routine.  Called with time (hundredths of seconds) in A.\r
+;      The inner loop delays 1001 T-states, assuming no wait states are\r
+;      inserted; this is repeated CPUSPD times, for a total delay of just\r
+;      over 0.01 second. (CPUSPD should be set to the system clock rate,\r
+;      in units of 100KHz: for an unmodified Kaypro II, that's 25 for\r
+;      2.5 MHz.  Some enterprising soul could determine whether or not the\r
+;      Kaypro actually inserts a wait state on instruction fetch (a common\r
+;      practice); if so, the magic number at delay2 needs to be decreased.\r
+;      (We also neglect to consider time spent at interrupt level).\r
+;\r
+;      called by: sendbr\r
+;      destroys BC\r
+;\r
+;delay:        mvi     c,cpuspd        ; Number of times to wait 1000 T-states to\r
+;                              ;  make .01 second delay\r
+;delay2:       mvi     b,70            ; Number of times to execute inner loop to\r
+;                              ;  make 1000 T-state delay\r
+;delay3:       dcr     b               ; 4 T-states (* 70 * cpuspd)\r
+;      jnz     delay3          ; 10 T-states (* 70 * cpuspd)\r
+;      dcr     c               ; 4 T-states (* cpuspd)\r
+;      jnz     delay2          ; 10 T-states (* cpuspd)\r
+;                              ; total delay: ((14 * 70) + 14) * cpuspd\r
+;                              ;  = 1001 * cpuspd\r
+;      dcr     a               ; 4 T-states\r
+;      jnz     delay           ; 10 T-states\r
+;\r
+;      ret                     ; grand total: ((1001 * cpuspd) + 14) * a\r
+\r
+;\r
+;      sysflt - system-dependent filter\r
+;      called with character in E.\r
+;      if this character should not be printed, return with A = zero.\r
+;      preserves bc, de, hl.\r
+;      note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r
+;\r
+sysflt:\r
+       mov     a,e             ; get character for testing\r
+       ret\r
+\r
+;\r
+;      mdmflt - modem filter\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             ; get character to test\r
+       ret\r
+\r
+;\r
+;      prtflt - printer filter\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
+;\r
+prtflt:\r
+       mov     a,e             ; get character to test\r
+\r
+IF FALSE                       ; strip out lf from printer stream\r
+       ani     7fh             ; make sure it is parity less\r
+       cpi     lf              ; is it a line feed?\r
+       rnz                     ; no, print it\r
+;      xra     a               ; yes, don't.\r
+       \r
+ENDIF\r
+\r
+       ret\r
+\r
+;\r
+; system-dependent processing for BYE command.\r
+;\r
+sysbye:\r
+       ret\r
+\r
+;\r
+;      This is the system-dependent command to change the baud rate.\r
+;      DE contains the two-byte value from the baud rate table; both\r
+;      bytes of this value are also stored in 'speed'.\r
+;\r
+sysspd:\r
+\r
+IF sb180\r
+       lxi     d, prtmsg       ; ask for variables\r
+       call    prtstr\r
+\r
+       lxi     d, tbuf         ; get suitable string\r
+       mvi     c, 10\r
+       call    bdos\r
+\r
+       lxi     h, tbuf1\r
+       mov     a, m\r
+       ora     a\r
+       jz      setpor          ; leave unchanged if string zero length\r
+\r
+       cpi     3               ; check given length\r
+       jnz     spd1            ; error - wrong length\r
+       inx     h\r
+       inx     h\r
+       mov     a, m\r
+       ani     137O            ; convert parity code to upper case\r
+       mov     m, a\r
+\r
+       lxi     d, tbuf1        ; get index of given parameter\r
+       lxi     h, parstr\r
+       call    sposn\r
+       ora     a\r
+       jnz     spd2            ; or fall through if error\r
+spd1:  lxi     d, invmsg       ; invalid input - try again\r
+       call    prtstr\r
+       jmp     sysspd\r
+\r
+spd2:  adi     3               ; get index to parval table\r
+       rrc                     ; by dividing by 4 \r
+       rrc\r
+       ani     15              ; mask out high bits\r
+       lxi     h, parind\r
+       mov     m, a            ; and store it\r
+       call    setpor          ; set up port iaw index and speed bytes\r
+\r
+       ret\r
+\r
+prtmsg:        db      cr,lf,'Enter bit/char, parity, and stop bits required.'\r
+       db      cr,lf,'(Bit 7/8   Parity N/O/E   Stop 1/2  - CR same) : $'\r
+invmsg: db     cr,lf,'Invalid parameters$'\r
+\r
+parind:        db      8               ; default <8N2> index\r
+parstr:        db      48,'7N1$7N2$7O1$7O2$7E1$7E2$'\r
+       db         '8N1$8N2$8O1$8O2$8E1$8E2$'\r
+parval:        db      0,1,16+2,16+3,2,3\r
+       db      4,5,16+6,16+7,6,7\r
+tbuf   db      6\r
+tbuf1  db      3,'8N2','$$$$'\r
+\r
+;\r
+; Set up the port using the table index in parind and the speed byte\r
+;\r
+setpor:\r
+       lxi     h, parind\r
+       mov     a, m\r
+       dcr     a\r
+       lxi     h, parval       ; table base\r
+       mvi     b, 0\r
+       mov     c, a\r
+       dad     b               ; HL points at parameter value\r
+       mov     a, m\r
+       mov     b, a            ; park parval\r
+\r
+       ani     16              ; the parity switch bit\r
+       lxi     h, speed\r
+       add     m               ; this is now the baud rate byte\r
+       mov     c, a            ; park it\r
+\r
+       mov     a, b            ; sort out the parameter byte\r
+       ani     7               ; b/p/s only wanted\r
+       adi     96              ; RE, TE enable\r
+       db      0EDh,039h,mnctrla       ; output parity etc.\r
+       mov     a, c\r
+       db      0EDh,039h,mnctrlb       ; output baud rate\r
+       mvi     a, 0\r
+       db      0EDh,039h,mnstat        ; clear status\r
+       db      0EDh,038h,mnstat        ; read twice to reset DCD0\r
+       db      0EDh,038h,mnstat\r
+       ret\r
+\r
+;\r
+; Find substring position - Leventhal page 293, modified\r
+; enter with subtring in DE and string in HL\r
+; returns index in A or 0 for failure\r
+;\r
+sposn:\r
+       mov     a, m            ; exit if either string length zero\r
+       ora     a\r
+       jz      notfnd\r
+       sta     slen\r
+       mov     b, a\r
+       inx     h\r
+       shld    string\r
+       xchg\r
+       mov     a, m\r
+       ora     a\r
+       jz      notfnd\r
+       sta     sublen\r
+       mov     c, a\r
+       inx     h\r
+       shld    substg\r
+       mov     a, b\r
+\r
+; no of searches = stringlen - substrlen + 1\r
+; if substr longer than string quit immediately\r
+\r
+       sub     c\r
+       jc      notfnd\r
+       inr     a\r
+       mov     c, a\r
+       xra     a\r
+       sta     index\r
+\r
+; search until remaining string shorter than substring\r
+\r
+slp1:  lxi     h, index\r
+       inr     m\r
+       lda     sublen\r
+       mov     b, a\r
+       lhld    substg\r
+       xchg\r
+       lhld    string\r
+\r
+; try to match substring starting at index\r
+\r
+cmplp: ldax    d\r
+       cmp     m\r
+       jnz     slp2\r
+       dcr     b\r
+       jz      found\r
+       inx     h\r
+       inx     d\r
+       jmp     cmplp\r
+\r
+; arrive here if match fails\r
+\r
+slp2:  dcr     c\r
+       jz      notfnd\r
+       lhld    string\r
+       inx     h\r
+       shld    string\r
+       jmp     slp1\r
+\r
+; found, return index\r
+\r
+found: lda     index\r
+       ret\r
+\r
+; not found, return zero\r
+\r
+notfnd:        sub     a\r
+       ret\r
+\r
+string:        ds      2\r
+substg:        ds      2\r
+slen:  ds      1\r
+sublen:        ds      1\r
+index: ds      1\r
+ENDIF\r
+\r
+       ret\r
+\r
+;\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 bytes or 1 word, ab)\r
+;              the data byte a is return in A and E, and b in D\r
+;              only byte 'a' is the key for the table\r
+\r
+IF sb6\r
+spdtbl:        db      9                       ; 9 entries\r
+       db      04h,'1200$',    0Bh,0Bh\r
+       db      03h,'150$',     0Eh,0Eh\r
+       db      05h,'19200$',   01h,01h\r
+       db      04h,'2400$',    0Ah,0Ah\r
+       db      03h,'300$',     0Dh,0Dh\r
+       db      05h,'38400$',   00h,00h\r
+       db      04h,'4800$',    09h,09h\r
+       db      03h,'600$',     0Ch,0Ch\r
+       db      04h,'9600$',    08h,08h\r
+\r
+sphtbl: db     cr,lf\r
+       db '   150  300  600  1200  2400  4800  9600  19200  38400$'\r
+ENDIF\r
+\r
+IF sb9\r
+spdtbl:        db      7                       ; 7 entries\r
+       db      04h,'1200$',    24h,24h\r
+       db      05h,'19200$',   20h,20h\r
+       db      04h,'2400$',    23h,23h\r
+       db      03h,'300$',     26h,26h\r
+       db      04h,'4800$',    22h,22h\r
+       db      03h,'600$',     25h,25h\r
+       db      04h,'9600$',    21h,21h\r
+\r
+sphtbl: db     cr,lf\r
+       db '   300  600  1200  2400  4800  9600  19200$'\r
+ENDIF\r
+\r
+\r
+;\r
+;      This is the system-dependent SET PORT command.\r
+;      HL contains the argument from the command table.\r
+;\r
+sysprt:\r
+       ret\r
+\r
+IF sb180\r
+prttbl EQU     0               ; SET PORT is not supported\r
+prhtbl EQU     0\r
+ENDIF\r
+\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 the rest, does nothing.\r
+;      preserves bc, de, hl.\r
+;\r
+selmdm:\r
+       ret\r
+\r
+selcon:\r
+       ret\r
+\r
+;\r
+;      Get character from console, or return zero.\r
+;      result is returned in A.  destroys bc, de, hl.\r
+;\r
+inpcon:\r
+       mvi     c,dconio        ;Direct console I/O BDOS call.\r
+       mvi     e,0FFH          ;Input.\r
+       call    BDOS\r
+\r
+       ret\r
+\r
+;\r
+;      Output character in E to the console.\r
+;      destroys bc, de, hl\r
+;\r
+outcon:\r
+       mvi     c,dconio        ;Console output bdos call.\r
+       call    bdos            ;Output the char to the console.\r
+\r
+       ret\r
+\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
+;\r
+outmdm:\r
+\r
+IF sb180\r
+       db      0EDh,038h,mnstat\r
+       ani     output          ; check status\r
+       jz      outmdm          ; wait until port is available\r
+       mov     a, e\r
+       db      0EDh,039h,mntxdat       ; transmit\r
+ENDIF\r
+\r
+       ret\r
+\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
+;\r
+inpmdm:\r
+\r
+IF sb180\r
+       lxi     h, delfac       ; loops to give delay\r
+inpm1: db      0EDh,038h,mnstat\r
+       ani     input           ; check status  \r
+       jz      inpm2\r
+       db      0EDh,038h,mnrddat       ; get a byte\r
+       ret\r
+\r
+inpm2: dcx     h               ; no data\r
+       mov     h, a\r
+       ora     l\r
+       jnz     inpm1           ; still tries left\r
+       ret                     ; with zero in A\r
+ENDIF\r
+\r
+       ret\r
+\r
+;\r
+;      flsmdm - flush comm line.\r
+;      Modem is selected.\r
+;      Currently, just gets characters until none are available.\r
+;\r
+flsmdm:\r
+       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
+;\f\r
+\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
+;\r
+;      outlpt - output character in E to printer\r
+;      console is selected.\r
+;      preserves de.\r
+;\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          ; if a=0 do nothing\r
+\r
+outlp1:        pop     d               ; restore saved register pair\r
+       ret\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
+delchr:\r
+\r
+       mvi     e,bs            ;get a backspace\r
+       jmp     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
+IF sb180\r
+sysver:        db      'MicroMint SB 180 '\r
+ENDIF\r
+\r
+IF sb6\r
+       db      ' (6 MHz)'\r
+ENDIF\r
+\r
+IF sb9\r
+       db      ' (9 MHz)'\r
+ENDIF\r
+       db      '$'\r
+\r
+IF lasm\r
+LINK CPXVDU.ASM                ; get terminal defs etc\r
+ENDIF  ;lasm\r