aboutsummaryrefslogtreecommitdiff
path: root/src/cpxhea.asm
diff options
context:
space:
mode:
authorJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
committerJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
commitebb2ff2af569d5822b70ee555a32d27cf7494816 (patch)
tree7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpxhea.asm
downloadkermit-80-main.tar.gz
kermit-80-main.zip
Initial import of 4.11HEADmain
Diffstat (limited to 'src/cpxhea.asm')
-rw-r--r--src/cpxhea.asm921
1 files changed, 921 insertions, 0 deletions
diff --git a/src/cpxhea.asm b/src/cpxhea.asm
new file mode 100644
index 0000000..e78d9df
--- /dev/null
+++ b/src/cpxhea.asm
@@ -0,0 +1,921 @@
+IF NOT lasm
+.printx * CPXHEA.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for KERMIT
+; specific to the Heath/Zenith H89 and Z100, the Telcon Zorba,
+; and the OEM ScreenTyper. All but the latter use VT52 (or a
+; replica thereof) for screen output; the ScreenTyper uses the
+; same serial port chip as the H89 (an Intel 8250).
+;
+; revision history:
+;
+; Edit 4, 31-Aug-1989 by Mike Freeman, 301 N.E. 107th Street; Vancouver wa
+; 98685 USA; Telephone (206)574-8221: Added Baud-rate Selection and
+; Break-sending ability for the Telcon Zorba portable.
+;
+; edit 3, 22 July, 1987 by OBSchou to massage code to conform to new set
+; of overlay files (stripping out common code to CPXCOM.ASM)
+;
+; edit 2 by OBSchou to add in old Kermit-80 V3.5 heath-8 code, formerly
+; in CPM directory. Entry from CP/M file:
+;
+; This file contains an upgrade to the CPMBASE.M80 KERMIT
+; to allow setting and display of baud rates, a bug fix in
+; telnet, and an extension of the HELP to show GET (which works
+; in this release, on the H8). Look for the new symbol "h8quad"
+; (for the heath quad i/o board that it uses) in the conditionals.
+; Note that the Heath H8 is NOT the same machine as the H89. The H89
+; code does not run 'as is' on the H8, and does NOT initialize the
+; UART. Also there was a bug in the telnet section that is fixed
+; here, though I expect that it has already been found and fixed
+; by now - this is from the DECUS FALL 83 tape. The comments were
+; stripped out of this file to make it small enough for my H8 to
+; assemble, however, I have put the first section back in to make
+; it easier for you to identify. Thanks for a nice product to use
+; and work on. Major insertions are heavily commented, edit as needed.
+;
+; This modification done by John Mealing, InteCom Inc, 601 Intecom Dr.,
+; Allen, TX 75002 (214)797-9141, x-2493, 5 Nov 84.
+;
+; [OBSchou notes: This is the header, and the bugs in telnet are
+; unknown. telnet routine has been substantially changed anyway with
+; 4.08-4.09 revision. As for the major insertions: they probably went
+; with the 4.xx re-write. I am unable to test this version: can
+; anyone else do so??]
+;
+;
+; edit 01 5th Mar 1987 by M J Carter, Nottingham Uni [majoc]
+; Split off from CPXSYS.ASM, in order to install support for
+; the OEM ScreenTyper. I can't test anything other than the
+; ScreenTyper as I haven't the hardware. Any offers?
+; Thanks are due to Paul Bartlett of John Elmer
+; Electronics Ltd, who provided me with his modified sources
+; for (a slightly antiquated) CP/M 4.05 Kermit on which this
+; is based.
+;
+; Keep module name, edit number, and last revision date in memory.
+;sysedt: db 'CPXSYS.ASM (35) 01-Dec-86 $'
+; [majoc 870305] Now in CPXFRK. I'll have to consult on this ...
+;
+;
+;
+; 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 heath
+.printx * Assembling KERMIT-80 for the Heath/Zenith 89 *
+ENDIF
+
+IF h8quad
+.printx * Assembling KERMIT-80 for the Heath-8 with Quad IO board *
+ENDIF
+
+IF z100
+.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 *
+ENDIF
+
+IF telcon
+.printx * Assembling KERMIT-80 for the Telcon Zorba *
+ENDIF
+
+IF scntpr
+.printx * Assembling KERMIT-80 for the OEM ScreenTyper *
+ENDIF
+;
+
+;
+
+IF heath
+mnport EQU 330O ;Modem data port
+ENDIF ; heath
+
+IF h8quad
+mnport EQU 330O ;all port addresses can be set by user -
+mnprts EQU mnport + 05 ; in octal cause heath wrote documents that
+output EQU 20H ; way -- relative addressing on the UART
+input EQU 01H ; registers, just to be nice
+baudls EQU mnport ;ls baud divisor latch when DALB set
+baudms EQU mnport + 1 ;ms baud divisor latch when DALB set
+linctl EQU mnport + 3 ;line control register
+modctl EQU mnport + 4 ;MODEM control register
+dalbon EQU 80H ;enables speed selection
+linset EQU 03H ;force hardware 8 bit, even parity
+;
+; The line control register (linctl) is bit mapped as follows:
+; bit # function value
+; 0,1 select word size 00 -> 5 bit, 10 -> 7 bit
+; 01 -> 6 bit, 11 -> 8 bit
+; 2 select stop bits 0 -> 1 stop bit, 1 -> 1 1/2 for 5 bit,
+; 1 -> 2 for 6 bit words
+; 3 parity enable 0 -> no parity, 1 -> parity as set by 4
+; 4 Even parity select 0 -> Odd parity, 1 -> Even parity
+; 5 Stick parity 1 -> Parity of bit 4 is inverted
+; 6 Break control 1 -> output forced to spacing (break)
+; 7 DALB 1 -> access divisor latches to set baud rate
+;
+; The value in linset is loaded into linctl when KERMIT comes up.
+;
+ms300 EQU 001O ;set for 300 baud as default
+ls300 EQU 200O
+rtsoff EQU 20O ;direct control of modem lines
+rtson EQU 11O
+z80 EQU FALSE ;[2] or is it?
+ENDIF ;h8quad
+
+IF scntpr
+mnport EQU 8 ;Modem data port
+ENDIF ; scntpr
+IF heath OR scntpr
+
+; Definitions for the 8250 ACE
+
+acerbr EQU 0 ; ACE Receiver Buffer Register offset (R/O) (DLAB = 0)
+acethr EQU 0 ; ACE Transmitter Holding Register offset (W/O)
+acedll EQU 0 ; ACE Divisor Latch (Low) (DLAB = 1)
+acedlh EQU 1 ; ACE Divisor Latch (High) (DLAB = 1)
+aceier EQU 1 ; ACE Interrupt Enable Register (DLAB = 0)
+aceiir EQU 2 ; ACE Interrupt Identification Register
+acelcr EQU 3 ; ACE Line Control Register
+acemcr EQU 4 ; ACE Modem Control Register
+acelsr EQU 5 ; ACE Line Status Register offset
+acemsr EQU 6 ; ACE Modem Status Register
+
+ace8bw EQU 00000011b ; 8 bit words
+acesb EQU 01000000b ; set break
+acedla EQU 10000000b ; divisor latch access
+acedtr EQU 00000001b ; data terminal ready
+aceloo EQU 00010000b ; loopback mode
+acedr EQU 00000001b ; data ready
+acethe EQU 00100000b ; transmitter holding register empty
+
+;mnport EQU 330O ;Modem data port
+; [35a: majoc 870305] Shifted up above joint IF, to save nesting.
+mnprts EQU mnport+acelsr ;Modem status port
+output EQU acethe ;Transmitter empty
+input EQU acedr ;Input data available
+z80 EQU TRUE ;H89 uses the Z80
+ENDIF;heath OR scntpr
+
+IF z100
+mnport EQU 0ECH ;Modem data port
+mnprts EQU 0EDH ;Modem status port
+output EQU 01H ;Transmitter empty
+input EQU 02H ;Input data available
+z80 EQU FALSE ;[hh] this one's an 8085.
+ENDIF;z100
+
+
+IF telcon
+MNPORT EQU 20H ;Modem data port
+MNPRTS EQU 21H ;Modem status port
+OUTPUT EQU 01H ;Transmitter empty
+INPUT EQU 02H ;Input data available
+BRPORT EQU 00H ;8254-2 Baud Rate Generator Timer for Port A
+COMMND EQU 03H ;8254-2 Timer Control Port
+z80 EQU TRUE ;[MF]A real Z80
+ENDIF;telcon
+;
+
+IF telcon
+defesc EQU ']'-100O ;The default escape character.
+ENDIF;telcon
+
+IF heath OR h8quad OR z100 OR scntpr
+defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
+ENDIF;heath OR h8quad OR z100 OR scntpr
+
+; Select initial setting for VT-52 emulation flag.
+IF (heath OR h8quad OR z100 OR telcon)
+vtval EQU 0 ; we don't need VT52 emulation
+ENDIF;heath OR h8quad OR z100 OR telcon OR vt52 [OBS question - ok for h8quad?]
+; If none of the above, default to VT52-EMULATION ON.
+IF scntpr
+vtval EQU 1 ; we do VT52 emulation
+ENDIF;scntpr
+
+
+;
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the juge CPXSYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXHEA.ASM (4) 31-Aug-1989$' ; Used for family versions....
+
+;
+sysxin: ; continuation of initialisation code
+IF heath OR scntpr
+;
+; System dependent startup for H89 and OEM ScreenTyper
+;
+
+ call mdmofl ; keep the line safe from garbage
+
+; First, tell Kermit the modem port's current speed
+ in mnport+acelcr
+ ori acedla
+ out mnport+acelcr ; access the ACE's divisor latch
+ in mnport+acedll ; get the low byte
+ sta speed
+ in mnport+acedlh ; and the high byte
+ sta speed+1
+
+; Now set up the port for Kermit
+ mvi a,ace8bw ; 8 data bits, 1 stop bit, no parity
+ out mnport+acelcr
+ in mnport+acemcr
+ ori acedtr ; raise DTR (just in case)
+ out mnport+acemcr
+ call mdmonl ; and put the ACE back on line
+ ret
+
+; Take the ACE off line before modifying its state
+mdmofl:
+ in mnport+aceier ; save the ACE's interrupt state
+ sta iersav
+ xra a
+ out mnport+aceier ; and disable ACE interrupts
+ in mnport+acemcr ; now put the ACE in loopback mode
+ ori aceloo
+ out mnport+acemcr
+ ret
+
+; Put the ACE back on line
+mdmonl:
+ in mnport ; flush left-over garbage in the receive buffer
+ mvi a,7 ; wait about 2 300-baud character times
+ call delay
+ in mnport ; and flush more garbage
+ in mnport+acemcr ; take the ACE out of loopback mode
+ ani 0FFH-aceloo
+ out mnport+acemcr
+ lda iersav
+ out mnport+aceier ; and restore the ACE's interrupt state
+ ret
+
+iersav: ds 1
+ENDIF;heath OR scntpr
+
+IF h8quad
+h8init: lxi d,180h ; [2] set up for 300 baud
+h8baud: mvi a,rtsoff ;disable modem for now
+ out modctl
+ mvi a,dalbon ;set for UART speed programming
+ out linctl
+ mov a,d ; [2] get ms bits for rate
+ out baudms
+ mov a,e ; [2] get ls bits for rate
+ out baudls
+ mvi a,linset ;force 8 bit, no parity and clear dalb
+ out linctl
+ in mnport ;clear the recieve side
+ mvi a,rtson ;get ready
+ out modctl ;modem is on and ready to go
+ENDIF ;h8quad
+
+ ret ; return from system-dependent routine
+
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF heath OR scntpr OR telcon;[4]
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;heath OR scntpr OR telcon
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+IF heath OR scntpr OR telcon;[4]
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;heath OR scntpr OR telcon
+
+IF heath OR scntpr
+ db cr,lf,'D Drop the line'
+ENDIF;heath OR scntpr
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+IF heath OR scntpr
+ cpi 'D' ; drop line?
+ jnz intc00 ; no: try next function character
+
+mdmdrp: in mnport+acemcr ; (we also get here from sysbye)
+ ani 0FFH-acedtr
+ out mnport+acemcr ; yes: drop DTR
+ mvi a,50 ; for half a second
+ call delay
+ in mnport+acemcr
+ ori acedtr
+ out mnport+acemcr ; and then restore it
+ ret
+intc00:
+ENDIF;heath OR scntpr
+
+IF heath OR scntpr OR telcon;[4]
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF;heath OR scntpr OR telcon
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+IF heath OR scntpr
+;
+; Send BREAK on H89 or ScreenTyper
+;
+sendbr: in mnport+acelcr
+ ori acesb
+ out mnport+acelcr ; set ACE break condition
+ mvi a,30
+ call delay ; wait 300 milliseconds
+ in mnport+acelcr
+ ani 0FFH-acesb
+ out mnport+acelcr ; and clear ACE break condition
+ ret
+
+ENDIF;heath OR scntpr
+;
+IF telcon ;[4]
+;
+; Send break on Telcon Zorba
+;
+sendbr: mvi a,3fH ;DTR normal, break on
+ out mnprts ;Set break on
+ mvi a,30 ;Wait 300 ms
+ call delay ;...
+ mvi a,37h ;DTR normal, tx, rx enabled
+ out mnprts ;Restore normal condition
+ ret ;and return
+;
+ENDIF ;telcon
+
+;
+;
+; 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 [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, scntpr, and lobo, hang up the phone.
+sysbye:
+IF heath OR scntpr
+ call mdmdrp ; Sleazy but effective
+ENDIF;heath OR scntpr
+
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+IF heath OR scntpr
+;
+; Set speed for H89
+;
+ call mdmofl ; keep the line safe from garbage
+ in mnport+acelcr
+ ori acedla
+ out mnport+acelcr ; access the ACE's divisor latch
+ mov a,e ; low byte of speed is in E
+ out mnport+acedll ; set the low byte
+ mov a,d ; high byte of speed is in D
+ out mnport+acedlh ; set the high byte
+ in mnport+acelcr
+ ani 0FFH-acedla
+ out mnport+acelcr ; de-access the ACE's divisor latch
+ call mdmonl ; and put the ACE back on line
+ENDIF;heath OR scntpr
+
+IF h8quad ;[2][obs] A bit of guesswork this. Enter with date in de
+ call h8baud ; [2] routine is in initialisation bit
+ENDIF ; h8quad[2]
+;
+IF telcon ;[4]
+ MVI A,36H ;Set square wave
+ OUT COMMND ;...
+ MOV A,E ;Get LSB of Baud rate
+ OUT BRPORT ;Send to generator
+ MOV A,D ;Get msb of baud rate
+ OUT BRPORT ;Send to Baud rate generator
+ENDIF ;telcon
+;
+ 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 identical bytes or 1 word)
+; [Toad Hall]
+
+IF heath
+;
+; Speed selection table for H89 (OK, so I got a little carried away...)
+;
+
+spdtbl: db 19 ; 19 entries
+ db 3,'110$'
+ dw 1047
+ db 4,'1200$'
+ dw 96
+ db 5,'134.5$'
+ dw 857
+ db 4,'1800$'
+ dw 64
+ db 5,'19200$'
+ dw 6
+ db 3,'200$'
+ dw 576
+ db 4,'2400$'
+ dw 48
+ db 3,'300$'
+ dw 384
+ db 4,'3600$'
+ dw 32
+ db 5,'38400$'
+ dw 3
+ db 3,'450$'
+ dw 256
+ db 4,'4800$'
+ dw 24
+ db 2,'50$'
+ dw 2304
+ db 5,'56000$'
+ dw 2
+ db 3,'600$'
+ dw 192
+ db 4,'7200$'
+ dw 16
+ db 2,'75$'
+ dw 1536
+ db 3,'900$'
+ dw 128
+ db 4,'9600$'
+ dw 12
+
+sphtbl: db cr,lf
+ db ' 50 75 110 134.5 200 300 450 600 900 1200'
+ db cr,lf,' 1800 2400 3600 4800 7200 9600 19200 38400 56000$'
+ENDIF;heath
+
+IF h8quad
+spdtbl: db 6 ;[2] 6 entries
+ db 3,'300$', 1,80h ; divisor for 300 baud
+ db 3,'600$', 0,0c0h
+ db 4,'1200$', 0,60h
+ db 4,'2400$', 0,30h
+ db 4,'4800$', 0,18h
+ db 4,'9600$', 0,0ch
+;
+; The strings to display the speed selected from the table above
+;
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
+ENDIF ;h8quad
+
+IF scntpr
+; [35a: majoc 870305]
+;
+; Speed selection table for ScreenTyper
+;
+
+spdtbl: db 14 ; 14 entries
+ db 3,'110$'
+ dw 470H
+ db 4,'1200$'
+ dw 68H
+ db 5,'134.5$'
+ dw 3a1H
+ db 4,'1800$'
+ dw 45H
+ db 5,'19200$' ; This was in PB's table, but not in the
+ dw 7H ; accompanying text string. Oversight?
+; db 3,'200$'
+; dw 576
+ db 4,'2400$'
+ dw 34H
+ db 3,'300$'
+ dw 1a1H
+ db 4,'3600$'
+ dw 23H
+; db 5,'38400$'
+; dw 3
+; db 3,'450$'
+; dw 256
+ db 4,'4800$'
+ dw 1aH
+ db 2,'50$'
+ dw 964H
+; db 5,'56000$'
+; dw 2
+ db 3,'600$'
+ dw 0d0H
+ db 4,'7200$'
+ dw 11H
+ db 2,'75$'
+ dw 683H
+; db 3,'900$'
+; dw 128
+ db 4,'9600$'
+ dw 0dH
+
+sphtbl: db cr,lf,' 50 75 110 134.5 300 600 1200'
+ db cr,lf,' 1800 2400 3600 4800 7200 9600 (19200?)$'
+ENDIF;scntpr
+;
+IF telcon ;[4]
+;
+; Speed selection tables for the Telcon Zorba (I overdid it, also)
+;
+; **NOTE** that when Kermit is first executed, the baud rate is
+; unknown to Kermit, having been set by CP/M upon cold-boot, SETUP.COM,
+; another communications program, etc. The easiest way to insure that
+; the baud rate is known upon Kermit start-up is to set it
+; in KERMIT.INI.
+;
+spdtbl: db 20 ;[4]Number of entries (some of these
+ ;speeds are *weird* but the Zorba
+ ;supports them so I'll put them in
+ db 3,'110$'
+ dw 4545
+ db 4,'1200$'
+ dw 417
+ db 5,'134.5$'
+ dw 3717
+ db 3,'150$'
+ dw 3333
+ db 4,'1760$'
+ dw 284
+ db 4,'1800$'
+ dw 278
+ db 5,'19200$'
+ dw 26
+ db 3,'200$'
+ dw 2500
+ db 4,'2000$'
+ dw 250
+ db 4,'2400$'
+ dw 208
+ db 3,'300$'
+ dw 1667
+ db 4,'3520$'
+ dw 142
+ db 4,'3600$'
+ dw 139
+ db 4,'4800$'
+ dw 104
+ db 2,'50$'
+ dw 10000
+ db 3,'600$'
+ dw 833
+ db 4,'62.5$'
+ dw 8000
+ db 4,'7200$'
+ dw 69
+ db 2,'75$'
+ dw 6667
+ db 4,'9600$'
+ dw 52
+;
+; Help table
+;
+sphtbl: db cr,lf
+ db ' 50 62.5 75 110 134.5 150 200 300 600 1200'
+ db cr,lf,' 1760 1800 2000 2400 3520 3600 4800 7200'
+ db cr,lf,' 9600 19200$'
+;
+ENDIF ;Telcon
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+IF z100
+spdtbl equ 0 ; SET BAUD not supported.
+sphtbl equ 0
+ENDIF;z100
+;
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+;
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+;
+;
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; 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:
+ ret
+
+selcon:
+ ret
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+IF NOT iobyt
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ENDIF;NOT iobyt
+
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+IF NOT iobyt
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ENDIF;NOT iobyt
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF inout
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout
+
+IF iobyt
+;**** Note that we enter from outpkt with the I/O byte already set up for
+; output to go to the comm port
+ push h
+ push b
+ lda prtfun ;Get the output function
+ mov c,a ;Into C
+ call bdos ;And output the character
+ pop b
+ pop h
+ ret
+ENDIF;iobyt
+
+;
+;
+; 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 NOT iobyt ;[2] this routine not in submitted file, so I guess
+ ; guess this is what it is supposed to do.
+ in mnprts ; input status port
+ ani input ; anything t read in?
+ rz ; nope
+ in mnport ; else read in the data
+ ret ; return with character in A
+ENDIF ; NOT iobyte [2]
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ call bprtst ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+IF NOT iobyt
+ mvi c,lstout
+ call bdos ;Char to printer
+ENDIF;NOT iobyt
+outlp1: pop d ; restore saved register pair
+ ret
+;
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; 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 ;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 telcon
+sysver: db 'Telcon Zorba$'
+ENDIF;telcon
+
+IF heath
+sysver: db 'Heath/Zenith 89$'
+ENDIF;heath
+
+IF h8quad
+sysver: db 'Heath H8 with quad I/O card$'
+ENDIF
+
+IF z100
+sysver: db 'Heath/Zenith Z-100 CP/M$'
+ENDIF;z100
+
+IF scntpr
+; [35a: majoc 870305]
+sysver: db 'OEM ScreenTyper: 4MHz Z80 running OS/M$'
+ENDIF;scntpr
+
+IF heath OR h8quad OR z100 OR telcon
+outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
+erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
+eralin: db cr,esc,'K$' ;Clear line.
+curldn: db esc,'Y$' ;cursor leadin
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'B$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left
+te: db esc,'E$',0 ;Clear display
+tf: db esc,'F$',0 ;Enter Graphics Mode
+tg: db esc,'G$',0 ;Exit Graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'I$',0 ;Reverse linefeed.
+tj: db esc,'J$',0 ;Clear to end of screen.
+tk: db esc,'K$',0 ;Clear to end of line.
+ENDIF;heath OR h8quad OR z100 OR telcon
+;
+
+IF scntpr ; [35a: majoc 870305]
+outlin: db 1aH, cr, lf, '$'
+erascr: db 1aH, '$' ;Clear screen and go home.
+eralin: db cr,esc,'*$' ;Clear line.
+curldn: db esc,'=$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 1eH,'$',0,0 ;Cursor up.
+tb: db 1fH,'$',0,0 ;Cursor down.
+tc: db 1cH,'$',0,0 ;Cursor right.
+td: db 1dH,'$',0,0 ;Cursor left
+te: db 1aH,'$',0,0 ;Clear display
+tf: db 0,0,0,0 ;(Can't)Enter Graphics Mode
+tg: db 0,0,0,0 ;(Can't)Exit Graphics mode
+th: db 15H,'$',0,0 ;Cursor home.
+ti: db 1eH,'$',0,0 ;Reverse linefeed.
+tj: db esc,'%$',0 ;Clear to end of screen.
+tk: db esc,'*$',0 ;Clear to end of line.
+ENDIF;scntpr
+
+ovlend EQU $ ; End of overlay
+ END ; Phew ... [majoc 870305]