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
/
ENTERPRS
/
CPM
/
UTILS
/
A
/
28MAY87.ARK
/
CXVT.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-27
|
19KB
|
1,035 lines
title 'Terminal Emulation (VT-100) 18 Feb 86'
maclib cxequ
if use$VT100
maclib z80
lines equ 24
public VT100
;
; VT-100
;
; NUL 00h ignored
; ENQ 05h transmit answer back message
; BEL 07h ring bell
; BS 08h back space. stop at left margin
; HT 09h do TAB
; LF 0Ah do line feed scroll at bottom
; VT 0Bh same as LF
; FF 0Ch same as LF
; CR 0Dh do CR
; SO 0Eh invoke G1 set
; SI 0Fh invoke G0 set
; XON 11h ignored
; XOFF 13h ignored
; CAN 18h abort ESC seq (disp error character)
; SUB 1Ah same as CAN
; ESC 1Bh control seq
; DEL 7Fh not used
;
;
; ESC = Keypad mode
; ESC > Keypad mode
; ESC 7 Save current cursor post and char set
; ESC 8 Restore cursor position and char set
; ESC D move cursor down one line
; ESC E move cursor to start of next line
; ESC H set horizontal tab
; ESC M move cursor up one line
; ESC Z same as ESC [ Pn c
; ESC c reset
; ESC # 3 Double height line Top
; ESC # 4 Double height line Bottom
; ESC # 5 set single width line
; ESC # 6 Double width line
; ESC # 8 files screen with E's
; ESC [ Pn A cursor up
; ESC [ Pn B cursor down
; ESC [ Pn C cursor right
; ESC [ Pn D cursor left
; ESC [ Pn ; Pn H cursor positioning
; ESC [ Ps J erase display
; ESC [ Ps K erase line
; ESC [ Pn c device attributes request
; ESC [ Pn ; Pn f cursor positioning
; ESC [ Ps g clear tab stop(s)
; ESC [ Ps;..;Ps h set mode
; ESC [ Ps;..;Ps l reset attributes
; ESC [ Ps;..;Ps m set attributes
; ESC [ Ps n Device status report
; ESC [ Ps q set LED's
; ESC [ Pn ; Pn r Set Top and Bottom Margins
; ESC [ 2 ; Ps y invoke confidence test
; ESC [ x Report / Req parameters
;; ESC ( A select char set
;; ESC ( B select char set
;; ESC ( 0 select char set
;; ESC ( 1 select char set
;; ESC ( 2 select char set
;; ESC ) A select char set
;; ESC ) B select char set
;; ESC ) 0 select char set
;; ESC ) 1 select char set
;; ESC ) 2 select char set
;
page
dseg
;
; VT-100 terminal emulation
;
VT100:
lhld parm$base ; 1st parm is exec adr (2 bytes)
mov a,m
inx h
mov h,m
mov l,a
ora h ; L is in A already, test HL=0
mov a,c ; C is char to output
jrz start$checking
pchl
;
;
;
start$checking:
lxi h,control$table
lxi b,cnt$tbl$lng
ccir
lxi h,control$exec$adr
jrz find$exec$adr
cpi 20h
rc
do$direct:
mov d,a
TJMP FR$wr$char
page
;
;
;
do$ESC: ; ESC control seq
call cont$later
;
; ESC char look for char in the ESC table
;
call remove$exec$adr
lxi h,esc$table
lxi b,esc$tbl$lng
ccir
rnz ; bad esc sequence
lxi h,esc$exec$adr
find$exec$adr:
dad b
dad b
mov a,m
inx h
mov h,m
mov l,a
pchl
page
;
; ESC #
;
esc$pn: ; ESC # control seq
call cont$later
;
; ESC # char look for char in the ESC table
;
call remove$exec$adr
lxi h,esc$pnd$table
lxi b,esc$pnd$tbl$lng
ccir
rnz ; bad esc sequence
lxi h,esc$pnd$exec$adr
jr find$exec$adr
page
;
; ESC [
;
esc$br: ; ESC [
call clear$parm
call cont$later
;
; ESC [ char look for char in the ESC table
;
cpi '9'+1 ; input char a parameter
jrc put$buffer ; yes, save parameters in buffer
call remove$exec$adr
lxi h,esc$br$table
lxi b,esc$br$tbl$lng
ccir
rnz ; bad esc sequence
lxi h,esc$br$exec$adr
jr find$exec$adr
;
; put byte in buffer pointed to by the put pointer+1 (advance pointer)
;
put$buffer:
mov c,a ; save character in C
call get$par ; get address of parameter buffer
mov e,m ; get low byte adr of input buffer
inx h
mov d,m ; get high byte adr of input buffer
inx h
inr m ; advance input count
mov l,m ; get current count (with input)
mvi h,0 ;
dad d ; compute adr in buf to place input
mov m,c ; place input character into buffer
; stc
ret
;
; get byte from buffer pointed to by the get pointer+1 (advance pointer)
;
get$buffer:
call get$par
mov e,m
inx h
mov d,m
inx h
mov a,m ; recover put counter
inx h
sub m ; test for end
rz
inr m ; advance get counter
mov l,m ; get the get counter
mvi h,0
dad d
mov a,m
do$DEL: ; DEL not used
ret
page
;
;
;
do$CAN: ; CAN SUB abort ESC seq (disp error character)
;
; Invoke G0 char set
;
do$SI: ; SI invoke G0 set
ret
;
; Invoke G1 char set
;
do$SO: ; SO invoke G1 set
ret
;
; move cursor to margin on current line
;
do$CR: ; CR do CR
TJMP FR$do$cr
;
;
;
do$LF: ; FF VT LF do line feed scroll at bottom
TJMP FR$cursor$down
;
; move cursor to next tab stop or right margin if none
;
do$HT: ; HT do TAB
ret
;
; move cursor to left but not past left margin
;
do$BS: ; BS back space. stop at left margin
TJMP FR$cursor$left
;
; Sound bell tone
;
do$BEL: ; BEL ring bell
RJMP FR$bell
;
; transmit answerback message
;
do$ENQ: ; ENQ transmit answer back message
ret
;
;
;
esc$pn$8: ; ESC # 8 files screen with E's
lxi d,024*256+0 ; set row (D) and col (E)
mvi c,24 ; set # of rows (C)
out$next$line$E:
mvi b,80 ; set # of col (B)
dcr d ; start with row 0
push d
push b
TCALL FR$cursor$pos
pop b
out$next$E:
push b
mvi d,'E'
TCALL FR$wr$char
pop b
djnz out$next$E
pop d
dcr c
jrnz out$next$line$E
ret
;
;
;
esc$pn$6: ; ESC # 6 Double width line
ret
;
;
;
esc$pn$5: ; ESC # 5 set single width line
ret
;
;
;
esc$pn$4: ; ESC # 4 Double height line Bottom
ret
;
;
;
esc$pn$3: ; ESC # 3 Double height line Top
ret
;
; Set tab at current cursor column
;
esc$HH: ; ESC H set horizontal tab
ret
;
; Move cursor down one line, scroll if on bottom margin
;
esc$DD: ; ESC D move cursor down one line
ret
;
; Move cursor to start of next line, scroll up if cursor
; is on the bottom margin
;
esc$EE: ; ESC E move cursor to start of next line
ret
;
; Move cursor up one line, if on top margin scroll down
;
esc$MM: ; ESC M move cursor up one line
ret
;
; reset VT100 to initial state (causes INIT H to be asserted
; briefly ???)
;
esc$c: ; ESC c reset
ret
;
;
;
esc$8: ; ESC 8 Restore cursor position and char set
ret
;
;
;
esc$7: ; ESC 7 Save current cursor post and char set
ret
;
; place Keypad into Numeric mode
;
esc$gt: ; ESC > Keypad mode
ret
;
; place Keypad into Application mode
;
esc$equ: ; ESC = Keypad mode
ret
;
;
;
esc$br$y: ; ESC [2;Ps y invoke confidence test
ret
;
;
;
esc$br$x: ; ESC [ x Report / Req parameters
ret
;
;
;
esc$br$r: ; ESC [Pn;Pn r Set Top and Bottom Margins
ret
;
; Ps=0 clear all LED's (default)
; PS=1 set LED 1
; Ps=2 set LED 2
; Ps=3 set LED 3
; Ps=4 set LED 4
;
esc$br$q: ; ESC [Ps q set LED's
ret
;
; Ps=5 Status Report
; responce is: ESC [0n (terminal OK)
; ESC [3n (terminal not OK)
; Ps=6 Report cursor position
; responce is: ESC [ Pl ; Pc R
; where Pl is the line number
; and Pc is column number
;
esc$br$n: ; ESC [Ps n Device status report
ret
;
; Ps=0 attributes off (default)
; Ps=1 bold or increased intensity
; Ps=4 underscore
; Ps=5 blink
; Ps=7 reverse video
;
esc$br$m: ; ESC [Ps;;Ps m set character attributes
call get$Pn$def0$init
check$br$m:
dcr c ; check # of parameters used
rz ; exit if None
ana a ; Ps=0 ?
jrz set$atr$off ; set attributes off
dcr a ; Ps=1
jrz bold$on ;
dcr a ; Ps=2
dcr a ; Ps=3
dcr a ; Ps=4
jrz underline$on ;
dcr a ; Ps=5
jrz blink$on ;
dcr a ; Ps=6
dcr a ; Ps=7
jrz reverse$on ;
call get$Pn$def0
jr check$br$m
set$atr$off:
bold$on:
underline$on:
blink$on:
reverse$on:
ret
;
; Ps=1 cursor key (l=cursor ; h=application)
; Ps=2 ANSI/VT52 (l=VT52 not supported)
; Ps=3 Column (l=80 col ; h=132 col) 80 only
; Ps=4 Scrolling (l=jump ; h=smooth) smooth only
; Ps=5 Screen (l=normal ; h=reverse)
; Ps=6 Origin (l=Absolute ; h=Relative)
; Ps=7 Auto wrap (l=off ; h=on)
; Ps=8 Auto Repeat (l=off ; h=on)
; Ps=9 interlace (l=off ; h=on)
; Ps=20 LF/NL (l=line feed ; h=new line)
;
esc$br$l: ; ESC [Ps;;Ps l reset mode
ret
;
; see esc$br$l
;
esc$br$h: ; ESC [Ps;;Ps h set mode
ret
;
; Ps=0 clear tab stop at current column (default)
; Ps=3 clear ALL tab stops
;
esc$br$g: ; ESC [Ps g clear tab stop(s)
ret
;
; Pn default =1 missing Pn uses default value(s)
; position cursor to line (1st) and column (2nd)
; uses DECOM parm to set origin mode (within margin
; or full screen)
;
esc$br$f: ; ESC [Pn;Pn f cursor positioning
esc$br$HH: ; ESC [Pn;Pn H cursor positioning
call get$Pn$def1$init
dcr a
mov d,a
call get$Pn$def1 ; DE are not changed by this call
dcr a
mov e,a
TJMP FR$cursor$pos
;
; What are you
; response is: ESC [?1; Ps c
; where Ps is:
; 0=base VT100, no options
; 1=processor option (STP)
; 2=advanced video option (AVO)
; 3=AVO and STP
; 4=graphics processor option (GPO)
; 5=GPO and STP
; 6=GPO and AVO
; 7=GPO, STP and AVO
;
esc$ZZ: ; ESC Z same as ESC [ Pn c
esc$br$c: ; ESC [Pn c device attributes request
ret
;
; Ps=0 from cursor to end of line (default)
; Ps=1 from start of line to cursor
; Ps=2 all of cursor line
;
esc$br$KK: ; ESC [Ps K erase line
ret
;
; Ps=0 from cursor to end of screen
; Ps=1 from start of screen to cursor
; Ps=2 all of screen (cursor is not moved)
;
esc$br$JJ: ; ESC [Ps J erase display
ret
;
;
;
esc$br$DD: ; ESC [Pn D cursor left
ret
;
;
;
esc$br$CC: ; ESC [Pn C cursor right
ret
;
;
;
esc$br$BB: ; ESC [Pn B cursor down
ret
;
;
;
esc$br$AA: ; ESC [Pn A cursor up
ret
page
;
; convert number to binary
; stop conversion at end or any none number
; (DE may not be changed)
;
get$Pn$def0$init:
call init$get ; set up to read buffer
;
get$Pn$def0:
call get$in$parm
mov a,b ; get input data to A
ret
;
;***** NOTE ESC [ ;4;A is the same as ESC [ 0;4;5A
;
;
; convert number to binary
; stop conversion at end or any none number
; return 1 if input is missing or a zero
; (DE may not changed)
;
get$Pn$def1$init:
call init$get ; set up to read buffer
;
get$Pn$def1:
call get$in$parm
mov a,b ; get input data to A
ora a ; is input =0?
rnz ; no, then use it
inr a ; yes, then use default of 1
ret
;
; B=converted number in binary (from input string)
; C=number of digits converted+1
; A=0 if ran out of input else A=last character read from string
; (DE may not be changed)
;
get$in$parm:
lxi b,1 ; B=0, C=1
get$next$num:
lda save$count
dcr a
rz
sta save$count
lhld buff$pointer ; get input buffer adr
inx h ; PRE incr adr
shld buff$pointer
mov a,m
call test$num
rc
slar b ; 2x
add b ; A=A+2B
slar b ; 4x
slar b ; 8x
add b ; A=A+2B+8B=A+10B
mov b,a ; save in B
inr c ; advance parmeter count
jr get$next$num
;
; return with carry set (Cy=1) if not a number (A=input Char)
; return bianary number in A if it was a number (Cy=0)
;
test$num:
cpi '0'
rc
cpi '9'+1
cmc
rc
sui '0'
ret
;
; set up local values to use buffer parameters
;
init$get:
call get$par ; get pointer to buffer(s)
mov e,m
inx h
mov d,m
inx h
mov a,m
inr a ; adjust for PRE decr
sta save$count
; inx h
; mov a,m
; sta get$count
xchg
shld buff$pointer
ret
save$count:
db 0
buff$pointer:
dw 0
page
;
; set buffer back to start
;
clear$parm:
call get$par
inx h
inx h
mvi m,0 ; zero out the input count
ret
;
;
;
get$par:
lxi h,vt100$par$80
lda fun$offset
ana a
rz
lxi h,vt100$par$40
ret
;
;
;
vt100$par$80:
dw buffer$80
db 0 ; current put pointer into buffer
;
;
;
vt100$par$40:
dw buffer$40
db 0 ; current put pointer into buffer
buffer$80 equ $-1
ds 20
buffer$40 equ $-1
ds 20
page
;
;
;
cont$later:
pop h ; get address to cont at in H
jr save$exec$adr ; save it
;
;
;
remove$exec$adr:
lxi h,0
save$exec$adr:
xchg
lhld parm$base
mov m,e
inx h
mov m,d
ret
page
;
; table scanned top to bottom
;
control$table:
db 05h ; ENQ transmit answer back message
db 07h ; BEL ring bell
db 08h ; BS back space. stop at left margin
db 09h ; HT do TAB
db 0Ah ; LF do line feed scroll at bottom
db 0Bh ; VT same as LF
db 0Ch ; FF same as LF
db 0Dh ; CR do CR
db 0Eh ; SO invoke G1 set
db 0Fh ; SI invoke G0 set
db 18h ; CAN abort ESC seq (disp error character)
db 1Ah ; SUB same as CAN
db 1Bh ; ESC control seq
db 7Fh ; DEL not used
cnt$tbl$lng equ $-control$table
;
; table scanned bottom to top
;
control$exec$adr:
dw do$DEL ; DEL not used
dw do$ESC ; ESC control seq
dw do$CAN ; SUB same as CAN
dw do$CAN ; CAN abort ESC seq (disp error character)
dw do$SI ; SI invoke G0 set
dw do$SO ; SO invoke G1 set
dw do$CR ; CR do CR
dw do$LF ; FF same as LF
dw do$LF ; VT same as LF
dw do$LF ; LF do line feed scroll at bottom
dw do$HT ; HT do TAB
dw do$BS ; BS back space. stop at left margin
dw do$BEL ; BEL ring bell
dw do$ENQ ; ENQ transmit answer back message
page
;
; table scanned top to bottom
;
esc$table:
db '=' ; ESC = Keypad mode
db '>' ; ESC > Keypad mode
db '7' ; ESC 7 Save current cursor post and char set
db '8' ; ESC 8 Restore cursor position and char set
db 'D' ; ESC D move cursor down one line
db 'E' ; ESC E move cursor to start of next line
db 'H' ; ESC H set horizontal tab
db 'M' ; ESC M move cursor up one line
db 'Z' ; ESC Z same as ESC [ Pn c
db 'c' ; ESC c reset
db '#' ; ESC # control seq
db '[' ; ESC [ cursor up
esc$tbl$lng equ $-esc$table
;
; table scanned bottom to top
;
esc$exec$adr:
dw esc$br ; ESC [ cursor up
dw esc$pn ; ESC # control seq
dw esc$c ; ESC c reset
dw esc$ZZ ; ESC Z same as ESC [ Pn c
dw esc$MM ; ESC M move cursor up one line
dw esc$HH ; ESC H set horizontal tab
dw esc$EE ; ESC E move cursor to start of next line
dw esc$DD ; ESC D move cursor down one line
dw esc$8 ; ESC 8 Restore cursor position and char set
dw esc$7 ; ESC 7 Save current cursor post and char set
dw esc$gt ; ESC > Keypad mode
dw esc$equ ; ESC = Keypad mode
;
;
;
esc$pnd$table:
db '3' ; ESC # 3 Double height line Top
db '4' ; ESC # 4 Double height line Bottom
db '5' ; ESC # 5 set single width line
db '6' ; ESC # 6 Double width line
db '8' ; ESC # 8 files screen with E's
esc$pnd$tbl$lng equ $-esc$pnd$table
esc$pnd$exec$adr:
dw esc$pn$8 ; ESC # 8 files screen with E's
dw esc$pn$6 ; ESC # 6 Double width line
dw esc$pn$5 ; ESC # 5 set single width line
dw esc$pn$4 ; ESC # 4 Double height line Bottom
dw esc$pn$3 ; ESC # 3 Double height line Top
;
;
;
esc$br$table:
db 'A' ; ESC [ Pn A cursor up
db 'B' ; ESC [ Pn B cursor down
db 'C' ; ESC [ Pn C cursor right
db 'D' ; ESC [ Pn D cursor left
db 'H' ; ESC [ Pn ; Pn H cursor positioning
db 'J' ; ESC [ Ps J erase display
db 'K' ; ESC [ Ps K erase line
db 'c' ; ESC [ Pn c device attributes request
db 'f' ; ESC [ Pn ; Pn f cursor positioning
db 'g' ; ESC [ Ps g clear tab stop(s)
db 'h' ; ESC [ Ps;..;Ps h set mode
db 'l' ; ESC [ Ps;..;Ps l reset attributes
db 'm' ; ESC [ Ps;..;Ps m set attributes
db 'n' ; ESC [ Ps n Device status report
db 'q' ; ESC [ Ps q set LED's
db 'r' ; ESC [ Pn ; Pn r Set Top and Bottom Margins
db 'x' ; ESC [ x Report / Req parameters
db 'y' ; ESC [ 2 ; Ps y invoke confidence test
esc$br$tbl$lng equ $-esc$br$table
esc$br$exec$adr:
dw esc$br$y ; ESC [2;Ps y invoke confidence test
dw esc$br$x ; ESC [ x Report / Req parameters
dw esc$br$r ; ESC [Pn;Pn r Set Top and Bottom Margins
dw esc$br$q ; ESC [Ps q set LED's
dw esc$br$n ; ESC [Ps n Device status report
dw esc$br$m ; ESC [Ps;;Ps m set attributes
dw esc$br$l ; ESC [Ps;;Ps l reset attributes
dw esc$br$h ; ESC [Ps;;Ps h set mode
dw esc$br$g ; ESC [Ps g clear tab stop(s)
dw esc$br$f ; ESC [Pn;Pn f cursor positioning
dw esc$br$c ; ESC [Pn c device attributes request
dw esc$br$KK ; ESC [Ps K erase line
dw esc$br$JJ ; ESC [Ps J erase display
dw esc$br$HH ; ESC [Pn;Pn H cursor positioning
dw esc$br$DD ; ESC [Pn D cursor left
dw esc$br$CC ; ESC [Pn C cursor right
dw esc$br$BB ; ESC [Pn B cursor down
dw esc$br$AA ; ESC [Pn A cursor up
endif
end
;
;
;
esc$esc:
call cont$later
;
; check for ESC ESC ESC
;
cpi esc ; check if 3rd char is an ESC
jrnz remove$exec$adr
call cont$later
;
; set current character as the attr
;
mov b,a
TCALL FR$color
jr remove$exec$adr
;
;
;
esc$equ:
call cont$later
;
; ESC = R
;
lhld parm$base
inx h
inx h
sui ' ' ; remove ascii bias
mov m,a
cpi '8'-' ' ; test for line 25 (A=24?)
jrnz not$status$line ; no, jmp
inr a ; yes, A=25
sta paint$size ; set 40 column repaint to 25 lines
not$status$line:
call cont$later
;
; ESC = R C (go do it)
;
sui ' '
mov e,a ; column # to E
lhld parm$base
inx h
inx h
mov d,m ; row # to D
TCALL FR$cursor$pos
jr remove$exec$adr
page
;
;
;
char$cnt$z: ; ^Z home and clear screen
lxi d,lines*256+0 ; B=24(row) C=0(col)
TCALL FR$cursor$pos
call esc$t ; clear the status line
lxi d,0
TCALL FR$cursor$pos
esc$y:
TJMP FR$CES ; clear to end of screen
home$cursor:
lxi d,0
TJMP FR$cursor$pos
esc$t:
TJMP FR$CEL ; clear to end of line
;
;
;
cursor$rt:
TJMP FR$cursor$rt
;
;
;
cursor$up:
TJMP FR$cursor$up
page
;
; delete character
;
esc$W:
TJMP FR$char$del
;
; delete line
;
esc$R:
TJMP FR$line$del
;
; insert character
;
esc$Q:
TJMP FR$char$ins
;
; insert line
;
esc$E:
TJMP FR$line$ins
page
;
; Half Intensity Off
;
esc$lfp:
mvi c,00000001b ; turn intensity up
jr set$FR$atr$c
;
; Half Intensity On
;
esc$rtp:
mvi c,00000000b ; turn intensity down
parn$cont:
mvi b,00000001b ; attribute bit to change
jr set$FR$attr
;
; Set Attribute sequence
;
esc$G:
call cont$later
;
; ESC G char
;
call remove$exec$adr
sui '4' ; '4' reverse video on
jrz esc$G$4
inr a ; '3' underline attr on
jrz esc$G$3
inr a ; '2' blink attr on
jrz esc$G$2
inr a ; '1' alt char set
jrz esc$G$1
inr a ; '0' clear attributes
rnz
;
; Rev. Video, blink, atl char set, and underline off
;
esc$G$0:
mvi c,10000000b ; turn attributes off
mvi b,11110000b ; attribute bit to change
jr set$FR$attr
;
; Select alt character set
;
esc$G$1:
mvi c,00000000b ; select alt character set
mvi b,10000000b
jr set$FR$attr
;
; Blinking On
;
esc$G$2:
mvi c,00010000b ; turn on blink attr
jr set$FR$atr$c
;
; Under line
;
esc$G$3:
mvi c,00100000b ; turn on underline bit
jr set$FR$atr$c
;
; Reverse Video On
;
esc$G$4:
mvi c,01000000b ; turn attributes on
set$FR$atr$c:
mov b,c ; reverse attr
set$FR$attr:
TJMP FR$attr