; ******* System Options - M18 *********
axer	equ	0
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
enq	equ	05h
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
;
; Molecular Control Codes--
plus	equ	29
minus	equ	28
leftk	equ	8
rightk	equ	21
lit	equ	26
cmnd	equ	22
error	equ	3
;
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
;
	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 -> M18 with wait for echo & kick option--
echo	call	trace0 !cpi esc !jz exitm
	push	psw !mvi a,14 !sta mkc	; 12 seconds timeout
ec1	call	listen0 !jnz ec2 !pop psw !ret	; echo received
ec2	call	suspend !call axe !ani 3 !cpi 3 !jnz ec1
	lda	mkc !dcr a !sta mkc	; clear kicker time out
	mvi	a,153 !call trace !pop psw !call trace0 !push psw !jmp ec1
trace0	push	psw !ori 80h !call trace !pop psw !jmp put0
;
axe	lda	mkc !ora a !rp
	IF	not axer
	ret				; disable axe
	ENDIF
	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 !jmp in2
in3	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	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 !adi 33 !call vdu !lda col !adi 32 !jmp vdu
esc2	mvi	c,7 !sta col !ret
esc1	mvi	c,3 !mvi e,'=' !cpi 'P' !jz esce !mvi c,0
esc0	cpi	' ' !jnc vdu
	cpi	cr !jz sc1 !cpi lf !jz vdu
	cpi	bs !jz vdu !cpi bel !jz vdu
	cpi	so !jz sc2 !cpi etb !jz sc2 !cpi si !jz sc3
	cpi	can !jz sc0
	cpi	syn !mvi e,enq !jz vdue ; clear to end of line
	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
sc2	mvi	e,'0' !jmp esce 	; start Highlight
sc3	mvi	e,'1'			; end Highlight
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
;
; ************************* 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 !rnz !jmp c1 ; timed out
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
;
; Translate Keystroke to M18 code--
kybd	mvi	c,plus	!cpi cr !jz i5	; [CARRIAGE RETURN]
			!cpi 31 !jz i5	; [DOWN ARROW]
	mvi	c,minus !cpi 30 !jz i5	; [UP ARROW]
	mvi	c,cr	!cpi lf !jz i5	; [LINE FEED]
	mvi	c,leftk !cpi 29 !jz i5	; [LEFT ARROW]
	mvi	c,rightk!cpi 28 !jz i5	; [RIGHT ARROW]
	mvi	c,cmnd	!cpi  9 !jz i5	; [TAB]
	mvi	c,error !cpi 127 !jz i5 ; [DEL]
	mvi	c,lit	!cpi 11 !jz i5	; [HOME]
	ret
i5	mov	a,c !ret
;
inject	shld	string !lhld kev !di !call go !ei !ret ; simulate keystroke
;
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