; **** Initial Task & Telecoms Controller - ALPHA II ****
base	equ	2000h
suspend equ	0109h	; Block Voluntarily
put0	equ	0115h	; A -> Mainframe
put3	equ	011bh	; A -> Telecomms
listen	equ	012ah	; Z = Telecomms -> A
io	equ	0130h	; Screenhandler
clock	equ	0133h	; Date & Time -> (DE)
fetch	equ	013ch	; Overlay (HL) -> (DE)
stow	equ	013fh	; Write Spool Control Record
spool	equ	0142h	; (DE) -> next spool sector
spawn	equ	0148h	; Spawn Task
taskm	equ	0169h	; Mainframe Terminal Task
openf	equ	0175h	; Open fcb (DE) with name (HL)
closef	equ	0178h	; Close fcb (DE)
resetf	equ	017bh	; Reset Disc System
print	equ	0187h	; (HL) -> Printer
cboot	equ	018ah	; Cold Start
inject	equ	01a2h	; (HL) -> Mainframe (terminal)
kbsw	equ	0fe52h	; Keyboard Switch Status
;
bdos	equ	0005h
fcb	equ	005ch
;
nul	equ	00h
soh	equ	01h
bel	equ	07h
bs	equ	08h
cr	equ	0dh
so	equ	0eh
time	equ	7fh
s	equ	80h
;
; Z80 OP Codes--
djnz	equ	00010h
ldir	equ	0b0edh
cpir	equ	0b1edh
;
; Define External Task locations--
flop	equ	02800h	; SDA Floppy Diskette Transfer
taskr	equ	03200h	; Reporter Task
eoe	equ	03800h	; Electronic Order Entry
taskv	equ	04000h	; VDU Task
taskk	equ	04600h	; Telecomms Process control
tasko	equ	05800h	; Overlay Task
alpha	equ	05c00h	; Alpha A2:A4 Protocol Handler
alpha0	equ	06000h	; Alpha0 Protocol Handler
ve	equ	06800h	; Vestric Link Protocol Handler
ri	equ	07000h	; Richardson Protocol Handler
taske	equ	0b800h	; Emulator Task
;
; Inter-Task Communication--
cword	equ	01c0h
label	equ	01c2h	; -> spool Diskette Label
mname	equ	01c8h	; -> taskm current Electronic pgm name
config	equ	01ceh	; B7: Autodial Modem
ctl	equ	01d0h	; System Control Block
hstate	equ	ctl	; B0: Call connected
			; B1: Order Spooled
			; B2: Long Fields/LOGON Double Key
			; B3: Rx done
			; B4: Tx done
			; B5: Call disconnected
			; B6: Cancelled, incorrectly received
			; B7: Telecomms process terminated
rxrecs	equ	ctl+1	; Rx Records Received count
sxrecs	equ	ctl+7	; Tx Records Sent count
area	equ	ctl+8	; -> data storage area
lrecl	equ	ctl+10	; = record length (bytes)
mstate	equ	ctl+12	; B0: Electronic (not Terminal) Mode
			; B1: Passing Rx data to M18
			; B2: Despooling Rx data
			; B3: Spooling Rx data
			; B4: KYBD requests M18 Terminal Mode
			; B5: M18 has refused order
			; B6: Electronic Mode axed
			; B7: Done
txrecs	equ	ctl+13	; Tx Records ready count
tstate	equ	ctl+18	; B0: M18/Modem Direct Connection
			; B1: Buffer Area in use
			; B2:
			; B4: Tx inhibit
			; B5: System Update permitted
			; B6: (Receive State) Request RVI
msub	equ	ctl+21	; Mainframe Subtask count
tsub	equ	ctl+22	; Telecomms Subtask count
htrk	equ	ctl+28	; Spool Header Track/Sector (3 bytes)
;
	org	base
	jmp	start
; Telecomms Protocol support--
	jmp	launch
	jmp	rtn	; K:exit (replaced)
txz	jmp	rtn	; K:Transmit (HL) until nul
rx	jmp	rtn	; K:
tx	jmp	rtn	; K:Transmit (HL) for BC bytes
	jmp	spooler
	jmp	rtn	; K:wait
	jmp	rtn	; K:putif
dsc	jmp	rtn	; K:
cut	jmp	rtn	; K:
hunt	jmp	rtn	; K:
waiti	jmp	rtn	; K:
	jmp	session ; Telecomms Session Procedure
insert	jmp	rtn	; K:Insert Telecomms Session parms
rtn	ret
;
start	lxi	h,7E00h !shld area !lxi h,66 !shld lrecl
	call	resetf !call ovlys
	lxi	d,taskm !lxi h,mlist !call spawn; Mainframe Terminal Task
	lhld	label !lxi d,34h !dad d !lxi b,2*256 !call io ; System Id
	lxi	h,0090h !lda 0080h !ora a !cm reload
	lxi	d,driver !call spawn	; Telecomms Driver
isl	call	suspend !lda cword !ora a !jz isl
	cpi	'D' !jz link	; Download HX20 program
	cpi	'L' !jz link	; List Spooled Data
	cpi	'P' !jz link	; Print Password Table
	cpi	'C' !jz cfigm	; Configure Modem
	jmp	isl
;
cfigm	xra	a !sta cword !lxi h,cfig !call insert !jmp isl
;
link	push	psw !call resv !pop psw !lxi d,tasko !call load !call tasko
	lxi	h,msub !dcr m !jmp isl
;
; Wait for exclusive access to printer etc.--
resv	call	suspend !lda msub !ora a !jnz resv
	sta	cword !inr a !sta msub !jmp resetf
;
; Load resident overlays--
ovlys	mvi	a,'R' !lxi d,taskr !call load	; Reporter Task
	mvi	a,'V' !lxi d,taskv !call load	; VDU Task
	mvi	a,'T' !lxi d,alpha !call load	; Alpha Session Procedure
	mvi	a,'A' !lxi d,alpha0 !call load	; Alpha0 Protocol Handler
	mvi	a,'H' !lxi d,ve    !call load	; Vestric Link Protocol Handler
	mvi	a,'G' !lxi d,ri    !call load	; Richardson Protocol Handler
	mvi	a,'K' !lxi d,taskk !call load	; Telecomms Driver
	lxi	h,mlist+2
o1	mov	a,m !ora a !rz !lxi d,ovl4+1 !lxi b,4 !dw ldir
	mov	e,m !inx h !mov d,m !inx h
	push	h !lxi h,ovl4 !call fetch !pop h !jmp o1
;
load	lxi	h,ovl+1 !mov m,a !dcx h !jmp fetch
;
ovl	db	0,'        OVL'
ovl4	db	0,'        OVL'
mlist	dw	emu	; Mainframe Emulator Task
	dw	'RI','NG',eoe+1
	dw	'EO','E ',eoe
	dw	'BU','S ',flop	; PH Bureau Service
	dw	'FL','OP',flop
	db	0
;
; ************	Mainframe Emulator *************
emu	mvi	a,'E' !lxi d,taske !call load !jmp taske
;
; ************	Write Order to Diskette ********
spooler lxi	h,mstate !dw 0decbh ; SET 3,(HL); Rx Data being spooled
	xra	a !sta sprecs !lhld label !lxi d,19 !dad d
	lxi	d,htrk !lxi b,3 !dw ldir	; save Header slot
	lxi	h,sector !mvi m,0 !inx h !lda rxrecs !mov m,a !inx h
	xchg	!lhld area !shld rptr !lxi b,30 !dw ldir
	call	sbump !mvi b,6	; slots left in 1st sector
s10	lhld	rptr !push b !lxi b,16 !dw ldir
	call	sbump !pop b !jz s20 !dw djnz+(s10-$-2)*256
	lxi	d,sector !call spool	; buffer full
	lxi	d,sector !mvi b,8 !jmp s10	; onto next buffer
s20	lxi	d,sector !call spool !call stow
	lxi	h,hstate !dw 0cecbh ; SET 1,(HL); Order Spooled
	ret
sbump	push	d !lhld lrecl !xchg !lhld rptr !dad d !shld rptr !pop d
	lxi	h,sprecs !inr m !lda rxrecs !dcr a !cmp m !ret
;
; ************	Telecomms Driver  ***********
driver	lxi	h,stdby !jmp taskk	; V21 Autoanswer
;
session mov	a,m !cpi 'C' !jz blank	; configure modem only
	cpi	'S' !cz system	; enable System Update
	lxi	h,exit !shld 2007h !call init !call decode
mp	call	rx !shld item !call exit	; await next Header
	call	match !lxi h,p0 !mvi a,s+'A' !jz cut ; unknown process
	lhld	item !xchg !call hl !lxi h,hstate !dw 0fecbh ; SET 7,(HL)
	jmp	mp
;
blank	xra	a !jmp cut	; don't log
;
system	lxi	h,tstate !dw 0eecbh ; SET 5,(HL); System Update enable
	ret
;
decode	lxi	h,black !mvi m,20	; retry count
de1	lxi	h,black !call hunt !rz	; protocol identified
	call	split !jnz de1 !call exit !jmp decode
;
split	rpe		; mixed parity frame
	jm	ve	; odd parity frame
	mov	a,m !cpi soh !jnz ri	; even parity frame
	inx	h !mov a,m !cpi 'd' !jnz alpha0 !inx h
	xchg	!lhld label !lxi b,32 !dad b !mvi b,9 ; HL-> password
ev1	ldax	d !cmp m !inx d !inx h !jnz ev2 !dw djnz+(ev1-$-2)*256
ev2	cz	logon !ori 1 !ret	; Z=0, unsucessful LOGON
;
logon	call	rqterm !rnz !lxi h,tstate !dw 0c6cbh ; SET 0,(HL)
	lxi	h,v1 !call io !lxi h,p4 !call print
ln1	call	listen !cz put0e !call dsc !jmp ln1 ; relay to mainframe
;
put0e	lxi	h,hstate !dw 056cbh ; BIT 2,(HL); Double Key mode
	cnz	dkey !ora a !jpo pu1 !ani 7fh !jmp put0
pu1	mvi	a,s+bel !jmp put3	; echo beep on odd parity
;
dkey	cma	!mov b,a !call waiti !jnz $+5 !cmp b !rz !mvi a,1 !ret
;
rqterm	lxi	h,null !shld epgm	; preset no reload pgm
	lxi	h,mstate !dw 046cbh ; BIT 0,(HL)
	rz	!dw 0e6cbh ; SET 4,(HL) ; request Terminal Mode
	call	suspend !dw 0a6cbh,046cbh ; RES 4,(HL) ; BIT 0,(HL)
	lhld	mname !shld epgm !ret	; Z=Terminal Mode
;
; ************	LOGON to Mainframe
s0	inx	d !inx d !ldax d	; pickup mode
	cpi	'1' !jnz $+8 !lxi h,hstate !dw 0d6cbh ; SET 2,(HL)
	call	txbid !jz block !call logon !mvi a,'3' !jmp done ; abort
;
; ************	System Logon
sl	inx	d !inx d !lhld label !lxi b,32 !dad b !mvi b,9 ; HL->password
sl1	ldax	d !cmp m !inx d !inx h !jnz sl2 !dw djnz+(sl1-$-2)*256
sl2	push	psw !call txbid !pop psw !jnz block ; wrong password
	call	signon !mvi a,'3' !jnz ditch	; wrong signature
	lxi	h,tstate !dw 0eecbh ; SET 5,(HL); enable supy state
	call	ops !lxi h,tx0 !jmp txz
;
signon	lda	config !rlc !ani 1 !ori '0' !sta tx3 ; "1"=autodial
	lxi	h,tx3+6 !mvi b,6	; generate random key
si1	in	4 !mov m,a !in 4 !dcx h !call suspend !dw djnz+(si1-$-2)*256
	lxi	b,7 !call tx !call rx	; send key, get signature
	lda	tstate !ani 20h !xri 20h !rz	; already supy state
	mov	a,m !cpi 'J' !ret	; vet signature
;
ops	call	rx !rz !mov a,m !inx h
	cpi	'F' !jnz op2	; F: Telecomms Follow-on Parms
	lda	config !ora a !cm insert !jmp ops ; ignore if cannot autodial
;
op2	cpi	'I' !jnz op3	; I: Inject String to Mainframe
	lxi	d,parmi !lxi b,16 !dw ldir
	lxi	h,parmi !call inject !jmp ops
;
op3	cpi	'T' !jnz ops	; T: Reset System Clock
	lxi	d,p3+1 !call clock !xchg !lxi b,10*256+3dh
at1	dw	041edh ; OUT (C),B	; write RAM Address
	in	3ch !ora a !jm at1 !lxi h,clist ; update in progress
	lxi	h,clist
	mvi	a,8ah !mvi b,4 !call cout	; stop, hh:mm:ss
	call	char !mvi b,4 !call cout	; day, mm/dd/yy
	mvi	a,3ah !mvi b,1 !call cout	; start clock
	lxi	h,p3 !call print !jmp ops
cout	dw	0a3edh ; OUTI	; write RAM Address
	push	psw !xchg !dcr c !dw 079edh ; OUT (C),A ; write RAM Data
	inr	c !xchg !pop psw !rz !call char !rlc !rlc !rlc !rlc
	push	b !mov c,a !call char !ora c !pop b !jmp cout
char	ldax	d !inx d !cpi '0' !jc char !cpi '9'+1 !jnc char ; non-numeric
	ani	0fh !ret
clist	db	11,4,2,0,6,8,7,9,11
;
; ************	Rx System Reset Request
sx	xchg	!inx h !inx h !lxi d,parmi !lxi b,16 !dw ldir
	call	txbid !jz block !lxi d,boot !call spawn !jmp txz
;
boot	call	suspend !lda hstate !rrc !jc boot ; await disconnection
	lxi	h,p1 !call print !lxi h,parmi !jmp cboot
;
; ************	Rx File
s1	lda	tstate !ani 20h !mvi a,'9' !jz ditch
	xchg	!inx h !inx h !push h	; -> drive
	lxi	d,p2+16 !inx h !lxi b,11 !dw ldir ; file name -> print line
	call	resetf !pop h !lxi d,fcb !call openf !mvi a,'1' !jz ditch
	call	s1rx !jnz ditch !lxi d,fcb !call closef
	lxi	h,p2 !call print !mvi a,'0' !jmp done
;
s1rx	call	rx !rz !mov a,c !cpi 128 !mvi a,'3' !rnz ; wrong record length
	xchg	!mvi c,26 !call bdos ; set DMA addr
	lxi	d,fcb !mvi c,21 !call bdos	; write sector
	ora	a !jz s1rx !mvi a,'2' !ret	; disc full
;
; ************	Rx Message
sm	xchg	!mvi m,time !inx h !mvi m,so !dcx h !mvi b,1 !call print
	call	txbid !jmp txz
;
txbid	call	rx !jz ms2 !push h !lxi h,d1 !call io !pop h
ms1	mvi	b,1 !call print !call rx !jnz ms1
ms2	lxi	d,tx1+2 !call clock
	lxi	h,tx1 !lda mstate !ani 1 !ori '0' !mov m,a !sta tx0
	lda	tstate !ani 20h !ret	; Z=0 if System Updates Enabled
;
block	mvi	a,'9' !jmp done
ditch	lxi	h,tstate !dw 0f6cbh ; SET 6,(HL); request RVI
	push	psw !call rx !jnz $-3 !pop psw	; flush any more Rx
done	lxi	h,tx0 !mov m,a !jmp txz
;
launch	lxi	h,rxrecs !inr m 	; Order Header received
	lxi	h,tsub !inr m !inr m	; 2 subtasks
	lxi	h,taskv !lxi d,tcp !call spawn
	lxi	h,taskr !lxi d,tcp !jmp spawn
;
tcp	call	hl !lxi h,tsub !dcr m !ret	; Subtask Control Program
;
exit	call	online !lda mstate !ani 82h !cpi 2 !jz exit ; wait for M
	lda	mstate !ani 40h !cnz axed	; ensure spooled if cut off
	lxi	h,hstate !dw 0fecbh ; SET 7,(HL); ensure subtasks complete
ex1	call	online !lda tsub !ora a !jnz ex1; wait for subtasks
init	xra	a !sta rxrecs !sta txrecs !sta sxrecs
	lda	mstate !ani 11h !sta mstate	; clear for next process
	lda	hstate !ani 21h !sta hstate !ani 20h !rz
	lxi	h,tstate !dw 08ecbh ; RES 1,(HL); free buffers (no DTR)
	ret
;
axed	lda	hstate !ani 0ah !cpi 8 !rnz !jmp spooler
;
online	call	suspend !lda hstate !ani 20h !jz dsc !lxi h,tstate
	dw	046cbh,086cbh ; BIT 0,(HL) ; RES 0,(HL) ; cancel any LOGON
	rz	!lxi h,v2 !call io !lhld epgm
reload	mov	a,m !ora a !rz !lxi d,name+2 !lxi b,4 !dw ldir
	lxi	h,name !jmp inject
;
; Set (HL) -> Process--
match	lhld	item !mov c,m !inx h !mov b,m !lxi h,plist ; BC=id
ma1	mov	a,m !ora a !rz	; BC not in plist
	inx	h !cmp c !mov a,m !inx h !mov e,m !inx h !mov d,m !inx h
	jnz	ma1 !cmp b !jnz ma1 !ori 1 !ret ; Z=0
;
hl	pchl
;
plist	dw	'A4',alpha	; Electronic Order, protocol A4
	dw	'A3',alpha	; Electronic Order, protocol A3
	dw	'A2',alpha	; Electronic Order, protocol A2
	dw	'S0',s0 	; LOGON to Mainframe
	dw	'S1',s1 	; Receive File
	dw	'SM',sm 	; Receive Message
	dw	'SX',sx 	; Reboot on disconnection
	dw	'SL',sl 	; System Logon
tx0	db	0,nul	; Completion Code
tx1	db	'x ddd dd mmm yy hh:mm:ss',nul ; System Status
tx3	db	'xkkkkkk',nul
d1	db	1,1,85h,'Message printed ',time,nul
p0	db	82h,'****** ',time,so,' Unknown process requested:-',nul
p1	db	81h,'****** ',time,' System Reset by telecommed command',nul
p2	db	81h,'****** ',time,'  File 12345678123 received & saved',nul
p3	db	81h,'ddd dd mmm yy hh:mm:ss'
	db	' Clock adjusted to ',time,nul
p4	db	82h,'****** ',time,'  M18 LOGON call connected',nul
v1	db	1,01,0a9h,time,' LOGON Call Busy',nul
v2	db	1,41,0a9h,time,' LOGON Call Done',nul
null	db	nul
stdby	db	'UwA',nul	; User, repeat Wait, V21 Answer
cfig	db	'CN2Z',cr,'EVS2=106S10=40S26=10',nul
black	db	0,9ah,nul
name	db	127,s,'1234',cr,nul
epgm	ds	2	; -> Electronic pgm name
rptr	ds	2	; -> current record in buffer area
item	ds	2	; -> Telecomms Line Buffer
sprecs	ds	1	; Records Spooled count
parmi	ds	16	; Reboot Parameters
sector	ds	128	; Spool Buffer
	end	base

The QX10 Archive