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 ?, 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: ,,, and are always discarded. sysflt: mov a,e ; get character for testing ret ; mdmflt - modem filter [30] ; called with character to be sent to printer in E ; with parity set as appropriate. ; return with accumulator = 0 do do nothing, ; <> 0 to send char in E. mdmflt: mov a,e ;[30] get character to test ret ; prtflt - printer filter [30] ; called with character to be sent to printer in E ; returns with a = 0 to do nothing ; a <> 0 to print it. ; ; this routine for those printer that automatically insert ; a lf on cr, or cr for lf. Should this be shifted to ; the system indep. stuff, in say 4.06? prtflt: mov a,e ; [30] get character to test ret ; ; ; system-dependent processing for BYE command. ; for apmmdm, heath, 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]