; ******* System Options - Convergent Technology *********
base	equ	1c00h
suspend equ	0109h	; Block task voluntarily
vdu	equ	010fh	; A -> Screen
listen0 equ	0112h	; Z: Mainframe -> A
put0	equ	0115h	; A -> Mainframe
put3	equ	011bh	; A -> Telecomms
io	equ	0130h	; Screenhandler
user	equ	0154h	; KYBD User Exit Routine
idler	equ	0166h	; Suspend with Escape option
trace	equ	017eh	; A -> screen if [SF1] lit
exitm	equ	0181h	; Terminate Mainframe Job
wait	equ	0199h	; Block Task until Event (DE)
go	equ	019ch	; Unblock Task awaiting Event (HL) (Int Off)
;
swreg	equ	01cfh	; Initial Switch Register mask
ev0	equ	0e701h	; Event List
mkc	equ	0e7fbh	; M18 kicker timeout counter
;
djnz	equ	00010h
ldir	equ	0b0edh
;
nul	equ	00h
stx	equ	02h
etx	equ	03h
bel	equ	07h
bs	equ	08h
lf	equ	0ah
ff	equ	0ch
cr	equ	0dh
so	equ	0eh
si	equ	0fh
syn	equ	16h
etb	equ	17h
can	equ	18h
esc	equ	1bh
time	equ	7fh
s	equ	80h
;
key	equ	01c1h	; current Keystroke
kew	equ	01c6h	; -> current Keyboard Event Word
ctl	equ	01d0h	; System Control Block
mstate	equ	ctl+12	; B0: Electronic (not Terminal) Mode
			; B4: Terminal Mode request
			; B6: Electronic Mode axed
tstate	equ	ctl+18	; B0: LOGON busy
			; B3: Screenhandler busy
uline	equ	1A00h	; User Line workspace
;
	org	base
	lxi	h,screen  !shld 014fh
	lxi	h,kybd    !shld 0152h
	lxi	h,input   !shld 016dh
	lxi	h,echo    !shld 0173h
	lxi	h,k0      !shld 018eh
	lxi	h,inject  !shld 01a3h
	lhld	kew !shld kev !ret
;
; A -> CT--
echo	push	psw !cpi ' ' !jnc ec0 !cpi esc !jc ec1 !jz ec2
	call	putr !pop psw !ret
ec0	call	trace0 !pop psw !ret
ec1	cpi	etx !jz ec3 !cpi stx !cnz trace0 !pop psw !ret
ec2	call	putr !pop psw !jmp exitm
ec3	call	putcr !pop psw !ret
;
putr	call	trace0
putcr	mvi	a,80h+cr !call trace !mvi a,cr !call put0
	mvi	a,6 !sta mkc
cr1	call	listen0 !jz cr2 !lda mkc !ora a !jp cr1 !jmp putcr
cr2	cpi	esc !jnz tr0 !call tr0 !call tr0 !jmp tr0	; discard chars
;
trace0	push	psw !ori 80h !call trace !pop psw !call put0
tr0	push	psw !mvi a,6 !sta mkc	; 6.5 secs av time out
tr1	call	listen0 !jnz tr2 !pop psw !ret
tr2	lda	mkc !ora a !jp tr1
	mvi	a,153 !call trace !pop psw !jmp trace0
;
axe	lda	mkc !ora a !rp
	ret		; (disabled)
	lda	mstate !ori 0d0h !sta mstate !jmp idler ; timed out
;
; Variable length field from Mainframe -> (HL)--
input	shld	savehl !mvi a,11 !sta mkc !call term ; 12 seconds timeout
in1	mvi	a,cr !call trace !mvi a,lf !call trace !mvi a,'[' !call trace
	lhld	savehl !lxi b,0
in2	call	get !jz in1 !cpi etx !jz in3
	mov	m,a !inx h !inx b !call trace
	cpi	cr !jnz in2 !call get !call trace !jmp in2 ; discard LF
in3	call	get !call get	; discard CR LF
	mvi	a,']' !call trace !mov a,b !ora c !ret
;
term	mvi	c,0	; not processing Escape
te1	mvi	b,8 !call get !jnz te2 !dw 041cbh ; BIT 0,C
	rz		; STX received
te2	lxi	h,tstate !dw 05ecbh ; BIT 3,(HL) ; Screenhandler busy?
	cz	screen !dcr b !jnz te1+2 !call suspend !jmp te1
;
get	call	listen0 !jz ge1 !call suspend
	lda	mstate !ani 1 !cnz axe !jmp get
ge1	push	h !lxi h,tstate !dw 046cbh ; BIT 0,(HL) ; LOGON?
	pop	h !jnz ge2 !cpi stx !ret
ge2	push	psw !ora a !jpe $+5 !ori 80h !call put3 !pop psw !ret
;
; M18 character -> Screen
screen	lxi	h,mstate !dw 046cbh ; BIT 0,(HL) ; DDE Mode?
	rnz	!dw 041cbh ; BIT 0,C	; processing Escape?
	jz	esc0 !dw 049cbh ; BIT 1,C
	jz	esc1 !dw 051cbh ; BIT 2,C
	jz	esc2 !mvi c,0 !jmp vdu	; Col
esc2	dw	079cbh ; BIT 7,C	; switch intensity?
	jnz	esch !mvi c,7 !jmp vdu	; Row
esc1	mvi	c,3 !mvi e,'=' !cpi '=' !jz esce ; Row, Col coords follow
	mvi	c,s+3 !cpi '0' !rz	; High/Low Intensity switch follows
	mvi	c,0 !mvi e,05h !cpi 'T' !jz vdue ; clear to end of line
	mvi	e,1ah !cpi 'Y' !jz vdue ; clear to end of screen
	cpi	'g' !jz uput	; display User Line
	cpi	'f' !jz uload	; load User Line
	ret		; ignore all others
esc0	cpi	' ' !jnc vdu
	cpi	cr !jz sc1 !cpi lf !jz vdu !cpi bel !jz vdu
	mvi	e,1dh !cpi bs !jz vdue	; cursor left
	mvi	e,1eh !cpi 11 !jz vdue	; cursor up one line
	mvi	e,1ch !cpi 12 !jz vdue	; cursor right
	mvi	e,0bh !cpi 30 !jz vdue	; home cursor
	cpi	1ah !jz sc0
	cpi	esc !rnz !mvi c,1 !ret	; process Escape
sc0	push	psw !mvi a,ff !call vdu !mvi e,'=' !call esce ; Clear Screen
	mvi	a,33 !call vdu !mvi a,32 !call vdu !pop psw !ret
sc1	push	psw !lda swreg !ani 08h !mvi a,lf !cnz vdu !pop psw !jmp vdu
esch	mvi	c,0 !mvi e,'6' !cpi '@' !jz esce ; start Highlight
	mvi	e,'7' !cpi 'A' !jz esce ; end Highlight
	jmp	esc0
esce	push	psw !mvi a,esc !push d !call vdu !pop d !jmp $+4
vdue	push	psw !mov a,e !call vdu !pop psw !ret
;
uload	lxi	h,uline !mvi m,1 !inx h !mvi m,1 !inx h !mvi m,0a2h !inx h
ul1	call	get !cpi cr !jz ul2 !mov m,a !inx h !jmp ul1
ul2	mvi	m,nul !ret
;
uput	lxi	h,uline !call io !mvi c,0 !ret
;
; ************************* KYBD Task **************************
k3	mvi	a,bel !call vdu 	; reject keystroke
k0	call	char !lxi h,mstate !dw 046cbh ; BIT 0,(HL) ; Electronic Mode
	jz	k1 !cpi esc !jnz k3 !mov a,m !ani 82h !cpi 2 !jz k3 ; busy
	dw	0e6cbh ; SET 4,(HL)	; request Terminal Mode
	call	suspend  !dw 0a6cbh,046cbh ; RES 4,(HL) ; BIT 0,(HL)
	jnz	k3 !jmp k0
; Terminal Mode--
k1	lxi	h,tstate !dw 046cbh ; BIT 0,(HL); LOGON Mode
	jnz	k3 !cpi 80h !call user !jz k2
	call	kybd !call put0 !call delay !jmp k0
k2	mov	a,m !ora a !jz k3 !shld string !jmp k0 ; setup user string
;
delay	mvi	b,8 !call suspend !dw djnz-5*256 ; slow down for M18
	ret
;
char	call	str !rnz
c1	lhld	kev !xchg !call wait !call str !rnz
	lxi	h,key !mov a,m !mvi m,s !cpi s !jz c1 ; timed out
	call	scan !rnz
str	lhld	string !mov a,m !ora a !rz !inx h !shld string
	cpi	s !rnz !mvi a,1 !sta mkc ; average delay 1.5 secs
sr1	call	suspend !lda mkc !ora a !jp sr1 !jmp str ; resume
;
; Control Code modifier for function key simulation--
scan	lxi	h,mstate !dw 046cbh ; BIT 0,(HL) ; Electronic Mode
	rnz
	lxi	h,f11 !cpi 01 !jz sa1	; ^A (Add)
	cpi	02 !jnz $+5 !mvi a,01
	lxi	h,f12 !cpi 24 !jz sa1	; ^X (Change)
	lxi	h,f13 !cpi 04 !jz sa1	; ^D (Delete)
	lxi	h,f14 !cpi 05 !jz sa1	; ^E (Enquire)
	lxi	h,f16 !cpi 17 !jz sa1	; ^Q (Quick)
	lxi	h,f17 !cpi 00 !jz sa1	; [HELP] (Command)
	lxi	h,f02 !cpi 25 !jz sa1	; ^Y
	lxi	h,f01 !cpi 26 !jz sa1	; ^Z
	lxi	h,fee !cpi 27 !jz sa1	; Esc
	ret
sa1	shld	string !ret
;
; Translate Keystroke to CT code--
kybd	mvi	c,10 !cpi 31 !jz i5	; [DOWN ARROW]
	mvi	c,11 !cpi 30 !jz i5	; [UP ARROW]
	mvi	c,8  !cpi 29 !jz i5	; [LEFT ARROW]
	mvi	c,12 !cpi 28 !jz i5	; [RIGHT ARROW]
	mvi	c,4  !cpi 11 !jz i5	; [CTRL]+K
	mvi	c,24 !cpi 08 !jz i5	; [BS]
	ret
i5	mov	a,c !ret
;
inject	shld	string !lhld kev !di !call go !ei !ret ; simulate keystroke
;
fee	db	esc,esc,nul
f01	db	1,'@',cr,nul
f02	db	1,'A',cr,nul
f11	db	1,'J',cr,nul
f12	db	1,'K',cr,nul
f13	db	1,'L',cr,nul
f14	db	1,'M',cr,nul
f16	db	1,'O',cr,nul
f17	db	1,60h,cr,nul
string	dw	null	; User String input pointer
null	db	nul
kev	ds	2	; Keyboard Event Word
savehl	ds	2
col	ds	1	; Save Column Number for Cursor Addressing
	end	base

The QX10 Archive