home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
KERMIT
/
CP411SRC.ARK
/
cpxpcw.asm
< prev
next >
Wrap
Assembly Source File
|
1991-04-23
|
24KB
|
913 lines
IF NOT lasm
.printx * CPXPCW.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.08
;
; 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.
;
; This file contains the system-dependent code and data for KERMIT
; on the Amstrad range of personal computers.
;
;
; Revision history:
;
;edit 9, 22-Jan-1991 by MF. Added "sysinit" code at "init04" from Kermit
; version 4.08 which had been left out of version 4.09 to reserve
; space for the Amstrad's I/O buffers. Amstrad Kermit now stores
; files correctly (version 4.09 had garbled files). Again,
; this fix comes from Mr. D. P. Arnot of the Scottish Agricultural
; College in the UK.
;edit 8, 16-Jan-1991 by MF. Added a "bs" left out of "delstr" per
; instruction from David P. Arnot of Scottish Agricultural
; College, Auchincruive, Ayr, UK.
; E-mail: <D.P.Arnot@edinburgh.ac.uk>
; edit 7, 22 July 1987 by OBSchou to massage code to fit with CPXCOM.ASM
; Had to rename bcnout to bcnot as the former label clashed with
; one of the same name in CPXCOM.ASM. Sorry, folks.
;
; edit 6, 14th July, 1987 by OBSchou for Phillip Wade, Hull University
; Computer Centre. Change to delchr routine for PCW machines,
; as character 127 decimal is a printing character on
; the Amstrad PCW. The routine has been replaced
; by a bs,space,bs,bs string. (OBS Comment - why a total of THREE bs?)
;
; edit 5 9 May 1987 by C.J.MILES@UK.AC.UMRCC
; Hangup phone and clear screen options added to
; terminal mode.
;
; edit 4 23 March 1987 by C.J.MILES@UK.AC.UMRCC
; Use direct input drom SIO for CPC machines instead
; of using BDOS. Improvement reduces time for file
; transfer to 65% of time used by BDOS method.
; Add reverse Prestel baud rate.
;
; edit 3 20 March 1987 by Chris Miles (C.J.MILES@UK.AC.UMRCC)
; (Greater Manchester Archaeological Unit, Manchester Univ.).
; Added support for Amstrad CPC CP/M Plus machines,
; Added 31250 baud rate option,
; Bug fixed in sending BREAK,
; Bug fixed in 1200/75 baud setup
; Machine and CP/M version checks added.
;
; edit 2 11 Febuary, 1987 by OBSchou for Ian Young.
; Changes to the send break routine to change two lines of code from
; ori 018h ; send break, Tx enable
; and ori 0008h ; Tx enable
;
; to ori 01ah ; send break, Tx enable, RTS
; and ori 00ah ; Tx enable, RTS
;
; This is a bug fix to hopefully keep RTS actve during breaks.
;
; [Ed. (OBSchou) 21/1/87.
; This file linked FROM cpxsys.asm, so do NOT rename this
; file. The diffculty of needing a HUGE CPXSYS.ASM file on your floppy
; only to act as a switcher remains, but hopefully will be better in
; the future. If you ARE stuck, then rename this CPXSYS.ASM but add the
; label SYSEDT: to the FAMILY label. A bit messy.]
;
;
; The "author" of this system-dependent file is:
;
; Ian A. Young
; Lattice Logic Ltd
; 9 Wemyss Place
; Edinburgh
;
; Some other addresses:
;
; ian@latlog.uucp
; ...seismo!mcvax!ukc!latlog!ian
; or c/o OBSchou@uk.ac.lut.multics
;
; ... although much of the code concerned was written by others.
;
; Keep module name, edit number, and last revision date in memory.
;sysedt: db 'CPXSYS.ASM (36) 20-Mar-87$'
family: db 'CPXPCW.ASM (9) 22-Jan-1991$'
;
; Assembly-time message announcing which version we are building
;
IF pcw
.printx * Assembling Amstrad PCW Kermit-80 *
ENDIF
IF cpc
.printx * Assembling Amstrad CPC Kermit-80 *
ENDIF
;
; Miscellany of parameter settings
;
z80 EQU TRUE ; all Amstrads have a Z80.
defesc EQU '\'-100O ; The default escape character.
vtval EQU 0 ; we don't need VT52 emulation
;
; Amstrad CPC machines use 16 bit I/O address decoding and therefore
; the Z80 instructions OUT (C),A and IN A,(C) must be defined.
;
outc EQU 79edh ; IN A,(C)
inpc EQU 78edh ; OUT (C),A
;
; hardware information
;
; There is a Z80-DART (Mostek/SGS 8470) at I/O addresses E0..E3 (PCW)
; and FADC..FADD (CPC), and a 8253 programmable divider running it at
; E4..E7 (PCW) and FBDC..FBDF (CPC)
;
input EQU 01h ; input data available
output EQU 04h ; output buffer ready
IF pcw
mnport EQU 0E0h ; data register for SIO
mnprts EQU 0E1h ; control register for SIO
ctc0 EQU 0E4h ; 8253 load counter 0
ctc1 EQU 0E5h ; 8253 load counter 1
ctcmod EQU 0E7h ; 8253 write mode word
ENDIF
IF cpc
mnport EQU 0FADCh ; data register for SIO
mnprts EQU 0FADDh ; control register for SIO
ctc0 EQU 0FBDCh ; 8253 load counter 0
ctc1 EQU 0FBDDh ; 8253 load counter 1
ctcmod EQU 0FBDFh ; 8253 write mode word
ENDIF
;
; SIO input buffering
;
siosz EQU 4096 ; size of SIO input buffer
siomsk EQU 4095 ; mask for wrapping buffer round
;
; Extended BIOS jump-block addresses; reached through USERF
;
sainit EQU 00B6h ; initialise SIO
sabaud EQU 00B9h ; set baud rate
saparm EQU 00BCh ; fetch SIO parameters
teask EQU 00BFh ; find out cursor position
cdvers EQU 00E3h ; get version numbers
cdinfo EQU 00E6h ; get BIOS system information
;
; System-dependent initialization
; Called once at program start.
sysxin: ; continuation of system initialzation
;
; check for correct CP/M version
;
mvi c,12 ; get CP/M version BDOS call
call bdos
mov a,l ; check if CP/M Plus
cpi 31h
jz init08
lxi d,wrong2 ; point to error message
call prtstr
mvi c,0 ; warm boot
call bdos
;
init08: ;[OBS] Moved the Cinfigured for message out as
;[OBS] it is in CPXCOM.ASM
;
; get addresses of BIOS routines
;
; BIOS USERF is used to get to extended BIOS routines
;
lhld 1 ; warm boot vector
lxi d,87 ; offset to USERF vector
dad d ; DE now has USERF vector address
shld userf+1 ; ready for jumping to...
;
; BIOS routines for fast character I/O
;
lhld 1 ; warm boot vector (#1)
lxi d,3
dad d ; next is #2, CONST
shld bcnst+1
dad d ; next is #3, CONIN
shld bcnin+1
dad d ; next is #4, CONOUT
shld bcnot+1 ;[obs] Was bcnout, but this conflicts
;[obs] with a label in CPXCOM.ASM
dad d ; next is #5, LIST
shld blist+1
dad d ; next is #6, AUXOUT
dad d ; next is #7, AUXIN
shld baxin+1
lhld 1 ; warm boot vector again
lxi d,002Ah ; offset to LISTST (#15)
dad d
shld lptstat+1
lhld 1 ; warm boot vector again
lxi d,0033h ; offset to AUXIST (#18)
dad d
shld baxist+1
;
; check if running on correct Amstrad
;
call userf
dw cdvers
IF pcw
cpi 0
ENDIF
IF cpc
cpi 1
ENDIF
jnz init06
lxi d,wrong1 ; point to error message
call prtstr
mvi c,0
call bdos
;
; verify presence of SIO board by asking the BIOS.
;
init06: call userf ; C gets 00 if not fitted
dw cdinfo
xra a ; a <- 0
ora c ; zero => no serial port
jnz init03 ; non-zero => OK
lxi d,nosio ; snooty message...
call prtstr
mvi c,0 ; warm boot out of here
call bdos
init03:
;
; find initial baud rate and other information
;
call userf ; gives B=rx baud, C=tx baud, D=stop bits,
; E=parity, H=rx bits, L=tx bits.
dw saparm ; get SIO parameters
push h ; save bit settings
mov a,b ; if TX and RX speeds same, they are OK
cmp c
jz init01
cpi 8 ; rx=1200?
jnz init02 ; no, can't be Prestel
mov a,c
cpi 2 ; tx=75?
jnz init02 ; no, can't be Prestel
lxi b,0 ; otherwise 1200/75 comes out as 0s.
init01: push b ; assign value to SPEED
pop h
shld speed
init02: ; here if we leave it as is
pop h ; get bit settings
mov a,l ; no of TX data bits set
sui 5 ; make into 00, 01, 10, 11.
rrc
rrc
rrc
sta txbits ; we may need it later
;
; set handshake mode: there are two parts to this, interrupts and
; hardware handshake. The MODE byte used by the firmware expresses
; this combination as -(int*2 + hand*1). Thus, both options on would
; be (-3) or 0FDh.
;
; Here, we set the interrupt part of the mode on; it helps the BIOS cope.
; Unfortunately, >sigh<, according to Soft971, this will only work
; if you have BIOS V1.4 or higher. I have no idea what would happen
; if we tried random hanshake mode flags with lower versions, so we
; just skip over if it would be dangerous...
;
call userf ; fetch all parameters
dw saparm
sta orgmode ; remember original mode for later
call userf ; get BIOS version to B,C
dw cdvers
mov a,b ; BIOS major version number (eg 1)
ora a ; if zero, too low...
jz init04
cpi 1 ; if not 1, definitely OK
jnz init05
mov a,c ; otherwise, its 1.X; want >= 4
cpi 4
jm init04 ; <4 => too low
init05: call userf ; get the original flags back
dw saparm
xri 0FFh ; make mode into bit mask
inr a
ori 2 ; set interrupt mode
xri 0FFh ; turn back into mode value
inr a
call userf ; feed change back to BIOS
dw sainit
init04: ; come here if not setting mode
; Locate large buffers for multi-sector I/O and SIO input buffering.
; Space above ovlend is available for buffers; we have pretty well the machine
; to ourselves in an Amstrad PCW because they all gave 61K TPAs. We don't even
; bother to perform any checking.
; We don't want to use more than maxsec for disk buffers because
; if we use too many, the remote end could time out while we're
; writing to disk. maxsec is system-dependent, but for now we'll just
; use 8Kbytes. If you get retransmissions and other protocol errors after
; transferring the first maxsec sectors, lower maxsec.
;
maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
lxi h,ovlend+siosz ; get start of buffer
shld bufadr ; store in linkage section
mvi a,maxsec ; get size of buffer, in sectors
sta bufsec ; store that, too.
ret ; return from system-dependent routine
;
; message complaining about wrong Amstrad machine
;
wrong1: db 'Error - This Kermit will only run on the Amstrad '
IF pcw
db 'PCW 8256/8512'
ENDIF
IF cpc
db 'CPC 464/664/6128'
ENDIF
db cr,lf,'$'
;
; message complaining about version of CP/M being used
;
wrong2: db 'Error - Incorrect CP/M version, needs CP/M 3.x'
db cr,lf,'$'
;
; message complaining of no SIO board
;
nosio: db 'Error - No SIO option fitted to this machine'
db cr, lf, '$'
;
; jumps to BIOS character I/O routines.
; Addresses filled in by initialisation code above.
;
bcnst: jmp $-$ ; console status
bcnin: jmp $-$ ; console input
bcnot: jmp $-$ ; console output [obs - was bcnout]
blist: jmp $-$ ; printer output
baxin: jmp $-$ ; aux port input
baxist: jmp $-$ ; aux port status
lptstat:jmp $-$ ; printer status
;
; Other BIOS routines
;
userf: jmp $-$ ; call extended BIOS function
;
; saved value of some original parameters
;
orgmode:ds 1
txbits: ds 1
;
; system-dependent termination processing
; If we've changed anything, this is our last chance to put it back.
sysexit:
call userf ; fetch firmware parameters
dw saparm
lda orgmode ; replace with original mode
call userf ; inform BIOS
dw sainit
ret
;
; system-dependent processing for start of CONNECT command
;
syscon:
lxi d,conmsg ; how to get escape char message
call prtstr
ret
conmsg: ; Messages printed when entering transparent (CONNECT) mode:
IF pcw
db '(Use boxed minus key next to space bar to generate a Control-\)'
ENDIF
db cr,lf,'$'
;
; 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:
lxi d,inhlps ; we got options...
call prtstr ; print them.
ret
;
; additional, system-dependent help for transparent mode
; (two-character escape sequences)
;
inhlps:
db cr,lf,'B Transmit a BREAK'
db cr,lf,'H Hangup using DTR'
db cr,lf,'W Wipe screen clear'
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...
cpi 'B' ; send break ?
jz sendbr ; yes, go do it. return nonskip when through.
cpi 'H' ; hang up ?
jz hangup
cpi 'W' ; clear screen ?
jz clrtop
jmp rskp ; take skip return - command not recognized.
;
; Hangup (drop DTR) and Break send routine
;
hangup:
mvi d,0ah ; set up hangup bit mask
mvi e,255 ; time for hangup is 2 1/2 secs
jmp setbit ; skip Tx empty test
sendbr:
mvi d,9ah ; set up break bit mask
mvi e,30 ; time for break is 300 ms
sndbr1: mvi a,1 ; select Read Register 1
IF pcw ; allow 8 bit I/O instructions
out mnprts
in mnprts ; read the contents
ENDIF
IF cpc ; use 16 bit I/O instructions
lxi b,mnprts
dw outc ; OUT (C),A
dw inpc ; IN A,(C)
ENDIF
ani 1 ; test "all done" flag
jz sndbr1 ; loop until it's nonzero.
;
; Next, set the break or hangup bit on the SIO.
;
setbit:
mvi a,5 ; select Write Register 5
IF pcw
out mnprts
ENDIF
IF cpc
dw outc ; OUT (C),A
ENDIF
lda txbits ; get txbits (already in correct bit positions)
ora d ; send break, Tx Enable, RTS
IF pcw
out mnprts
ENDIF
IF cpc
dw outc ; OUT (C),A
ENDIF
;
; Now, delay for duration of hangup or break
;
mov a,e ; delay count
call delay
;
; Time's up. Put transmitter back in normal state and return.
;
mvi a,5 ; select Write Register 5
IF pcw
out mnprts
ENDIF
IF cpc
lxi b,mnprts
dw outc ; OUT (C),A
ENDIF
lda txbits ; get txbits again
ori 8ah ; Reset break, Tx Enable, RTS
IF pcw
out mnprts
ENDIF
IF cpc
dw outc ; OUT (C),A
ENDIF
ret ; done.
;
; 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
;
; 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; this
; value is also stored in 'speed'.
;
sysspd:
push d ; move to HL for firmware
pop h
mov a,h ; if h=0 then Prestel rates
ora a
jnz spd01 ; if not 1200/75 then skip
lxi h,0802H ; else set 1200/75 into HL
jmp spd03 ; jump to normal setup
spd01: cpi 11h ; if h=11h then reverse Prestel
jnz spd02 ; if not 75/1200 then skip
lxi h,0208h ; else set 75/1200 into HL
jmp spd03 ; jump to normal setup
spd02: cpi 10h ; if h=10h then 31250 baud
jnz spd03 ; if not 31250 then skip to normal setup
mvi a,36h ; set 8253 for mode 2 binary count
lxi b,ctcmod ; output to CTC mode register
dw outc
lxi b,ctc0 ; select transmit clock
mov a,4 ; timer value for 31250 (04h)
dw outc
mov a,0 ; timer value for 31250 (04h)
dw outc
lxi b,ctc0 ; select receive clock
mov a,4 ; timer value for 31250 (04h)
dw outc
mov a,0 ; timer value for 31250 (04h)
dw outc
ret
spd03: call userf ; set whatever we have now...
dw sabaud ; using BIOS routine
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)
;
spdtbl: db 12h ;18 entries
db 03h,'110$', 03h,03h
db 04h,'1200$', 08h,08h
db 07h,'1200/75$', 00h,00h ; real values faked up when required
db 05h,'134.5$', 04h,04h
db 03h,'150$', 05h,05h
db 04h,'1800$', 09h,09h
db 05h,'19200$', 0fh,0fh
db 04h,'2400$', 0ah,0ah
db 03h,'300$', 06h,06h
db 05h,'31250$',10h,10h ; flag to direct setup routine
db 04h,'3600$', 0bh,0bh
db 04h,'4800$', 0ch,0ch
db 02h,'50$', 01h,01h
db 03h,'600$', 07h,07h
db 04h,'7200$', 0dh,0dh
db 02h,'75$', 02h,02h
db 07h,'75/1200$',11h,11h ; real values faked up when required
db 04h,'9600$', 0eh,0eh
sphtbl: db cr,lf,lf
db 'Normal rates: 50 75 110 134.5 150 300 600'
db cr,lf
db ' 1200 1800 2400 3600 4800 7200 9600 19200'
db cr,lf,lf
db 'High speed : 31250 (only between Amstrads)'
db cr,lf,lf
db 'Split rates : 1200/75 (Rx=1200, Tx= 75)'
db cr,lf
db ' 75/1200 (Rx= 75, Tx=1200)'
db cr,lf,'$'
;
; 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.
; preserves bc, de, hl.
;
selmdm:
selcon:
ret
;
; Get character from console, or return zero.
; result is returned in A. destroys bc, de, hl.
;
inpcon:
call bcnst ; get console status
ora a ; anything there?
rz ; no, forget it
jmp bcnin ; yes, get the character
;
; Output character in E to the console.
; destroys bc, de, hl
;
outcon:
mov a,e ; TAB?
cpi tab
jz out001
mov c,e ; set correct arg register
jmp bcnot ; output to console via BIOS [obs was bcnout]
;
; perform tab expansion ourselves
;
out001: call userf ; get column in L
dw teask
mov a,l ; a <- column 0..n
ani 7 ; column 0..7
xri 0FFh ; not(col 0..7)
adi 9 ; a is 8-(colf7)
out002: ora a ; any left?
rz ; return if not
dcr a ; one less now, anyhow
push psw ; save over BIOS call (just in case)
mvi c,' ' ; print one space
call bcnot ;[obs was bcnout]
call suck ; in case any stuff coming in
pop psw ; fetch count back
jmp out002 ; and go round again
;
; 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 cpc
push b ; save BC for CPC 16 bit I/O
ENDIF
outmd1:
call xsuck ; keep checking for incoming characters
IF pcw
in mnprts ; get the output done flag.
ENDIF
IF cpc
lxi b,mnprts
dw inpc ; IN A,(C)
ENDIF
ani output ; is it set?
jz outmd1 ; if not, loop until it is.
mov a,e
IF pcw
out mnport ; output it.
ENDIF
IF cpc
lxi b,mnport
dw outc ; OUT (C),A
pop b ; restore BC
ENDIF
ret
;
; get character from modem; return zero if none available.
; destroys bc, de, hl.
;
inpmdm:
call suck ; get any characters pending
lhld sioct ; count of chars in buffer
mov a,h ; or together to get result
ora l
rz ; not got any, return now
dcx h ; down count
shld sioct
lhld siord ; read pointer
mov c,m ; fetch character ** NB TO C FOR NOW **
lxi d,1-ovlend ; bump pointer, subtract base
dad d
mov a,h ; mask high byte of offset
ani siomsk/256
mov h,a
lxi d,ovlend ; add in base again
dad d
shld siord
mov a,c ; get to proper register
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.
;
; SIO input buffer handling. The buffer pointers are held as pointers into
; the buffer. The read pointer
; is to the next unused character, the write pointer to the next unused space.
;
siord: dw ovlend ; next char to read
siowr: dw ovlend ; next char to write
sioct: dw 0 ; number in buffer
xsuck: push d ; save regs version of suck
push b
push h
call suck
pop h
pop b
pop d
ret
;
; suck
;
; this routine is called whenever it would be possible that some
; characters might be available in the SIO device; they are all
; transferred (there may be up to 4 pending) to the buffer.
;
; all registers are destroyed
;
suck:
IF pcw
call baxist ; check input status via BDOS
ora a ; check if zero
ENDIF
IF cpc
lxi b,mnprts ; get input status directly
dw inpc ; IN A,(C)
ani input ; mask for Rx ready
ENDIF
rz ; return if no
IF pcw
call baxin ; fetch character via BDOS
ENDIF
IF cpc
lxi b,mnport ; fetch character directly from SIO
dw inpc ; IN A,(C)
ENDIF
lhld siowr ; write pointer
mov m,a ; put character
lxi d,1-ovlend ; take off base, bump pointer
dad d
mov a,h ; top byte of offset
ani siomsk/256 ; masked off
mov h,a
lxi d,ovlend ; add on base again
dad d
shld siowr ; replace pointer
lhld sioct ; bump count in buffer
inx h
shld sioct
jmp suck ; go round in case any more
;
; outlpt - output character in E to printer
; console is selected.
; preserves de.
outlpt:
push d ; save DE in either case
mov c,e ; correct arg register
call blist
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.)
; or (row) and (column)
;
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:
IF pcw ;[6] OBS for Phillip Wade
lxi d,delstr ;[5] send a string rather than a single character
call prtstr
delstr: db bs,' ',bs,'$' ;[OBS] Was bs,space,bs,bs
ENDIF ;pcw
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 pcw
sysver: db 'Amstrad PCW with SIO option$'
ENDIF
IF cpc
sysver: db 'Amstrad CPC with CP/M Plus$'
ENDIF
outlin: db esc,'H',esc,'J',cr,lf,' $'
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 '$',0,0,0 ;Enter Graphics Mode
tg: db '$',0,0,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.
ovlend equ $ ; End of overlay
END