; **** OPERATING SYSTEM UTILITIES - Memory Bank Independent Area
base	equ	0E000h
min	equ	00042h
max	equ	00044h
mout	equ	00124h	; M Output Driver
ps	equ	0C3FCh	; SP save area & stack for printer interrupt
istack	equ	0E2FEh	; SP at interrupt & top of interrupt stack
ev0	equ	0E701h	; Event List
stack	equ	0E7C0h	; Scheduler Stack top: Ready Count, ROC, -> Runner
rdy0	equ	stack+4 ; Ready Task Q & Free Stack list
mkc	equ	0E7FBh	; M18 Kicker counter
count	equ	0E7FCh	; Seconds counter
tick	equ	0E7FFh	; Slow Timer Status word
shelt	equ	0FBB5h	; Borrow BIOS2 stack
pfkptr	equ	0FE27h	; Function Key pointer
pfkcnt	equ	0FE3Fh	; Function Key remains of count
ans	equ	0FEE0h	; FDC result string
;
mask0	equ	01cah	; Com0 Data Mask
mask3	equ	01cbh	; Com3 Data Mask
mask4	equ	01cch	; Com4 Data Mask
blist	equ	00200h	; -> D, H, M buffers
put4	equ	blist+8 ; put4, get4
put3	equ	blist+12; put3, get3
put0	equ	blist+16; put0, get0
putk	equ	0fe21h	; -> Kybd output pointer
getk	equ	0fe23h	; -> Kybd input pointer
bufk	equ	0fe2eh	; -> Kybd Buffer
;
; Z80 OP Codes--
ldir	equ	0b0edh
djnz	equ	00010h
;
; ASCII characters--
nul	equ	00h
esc	equ	1bh
;
	org	base
	jmp	init
; Auxiliary RS232 Interrupt Handler--
auxint	push	psw !push d !in 30h !ani 0f0h !sta ibank ; save memory bank
	mvi	a,10h !out 18h !dw 073edh,istack ; LD (istack),SP ; Main Bank
	lxi	sp,istack
au0	in	0c5h !rrc !cc in3 !in 0c7h !rrc !cc in4
	mvi	a,38h !out 0c5h 		; end of interrupt
	in	0c5h !mov e,a !in 0c7h !ora e !ani 1 !jz done !jmp au0
;
; Keyboard & RS232 Interrupt Handler--
rsint	push	psw !push d !in 30h !ani 0f0h !sta ibank ; save memory bank
	mvi	a,10h !out 18h !dw 073edh,istack ; LD (istack),SP ; Main Bank
	lxi	sp,istack
rs0	in	12h !rrc !cc kybd !in 13h !rrc !cc in0
	call	mout !mvi a,038h !out 12h	; end of interrupt
	in	12h !mov e,a !in 13h !ora e !ani 1 !jnz rs0
done	dw	07bedh,istack ; LD SP,(istack)
	lda	ibank !out 18h !pop d !pop psw !pop h !ei !ret
;
; Get RS232 Com3 character--
in3	in	0c4h !lxi h,mask3 !ana m !lhld put3 !inx h !xchg
	lhld	blist+4 !ora a !dw 052edh ; SBC HL,DE ; check for buffer end
	jnz	$+7 !lhld blist+2 !xchg ; wrap-around to buffer start
	lhld	put3+2 !ora a !dw 052edh ; SBC HL,DE ; check for overflow
	rz	!lhld put3 !mov m,a !xchg !shld put3 !ret
;
; Get RS232 Com4 character--
in4	in	0c6h !lxi h,mask4 !ana m !lhld put4 !inx h !xchg
	lhld	blist+2 !ora a !dw 052edh ; SBC HL,DE ; check for buffer end
	jnz	$+7 !lhld blist !xchg ; wrap-around to buffer start
	lhld	put4+2 !ora a !dw 052edh ; SBC HL,DE ; check for overflow
	rz	!lhld put4 !mov m,a !xchg !shld put4 !ret
;
; Get RS232 Com0 character--
in0	in	11h !lxi h,mask0 !ana m !lhld put0 !inx h !xchg
	lhld	blist+6 !ora a !dw 052edh ; SBC HL,DE ; check for buffer end
	jnz	$+7 !lhld blist+4 !xchg ; wrap-around to buffer start
	lhld	put0+2 !ora a !dw 052edh ; SBC HL,DE ; check for overflow
	rz	!lhld put0 !mov m,a !xchg !shld put0 !ret
;
; Get keystroke--
kybd	in	10h !cpi 09h !jnz $+6 !sta 0fe43h ; 09=[BREAK]
	lhld	putk !mov m,a !inx h !mov a,l !cpi (bufk+16) and 0ffh
	jnz	$+6 !lxi h,bufk !shld putk !lxi h,ev0+6 !jmp go
;
testk	dw	073edh,shelt ; LD (shelt),SP	; Z: Keystroke -> A
	lxi	sp,shelt !mvi a,20h !out 18h !call key	; System Bank
	mov	e,a !mvi a,10h !out 18h !dw 07bedh,shelt ; LD SP,(shelt)
	mov	a,e !jnc $+4 !inr e !cmp e !ret
;
key	call	pfk !rnc !call 0ac6h !rnc	; C: No Keystroke
pfk	lda	pfkcnt !sui 1 !rc !sta pfkcnt
	lhld	pfkptr !mov a,m !inx h !shld pfkptr !ret
;
; Printer Interrupt Handler--
print	push	psw !push d !in 30h !ani 0f0h !sta ibank+1 ; save memory bank
	mvi	a,10h !out 18h !mvi a,0ch !out 17h ; Main Bank, int. off
	dw	073edh,ps+2,07bedh,ps ; LD (ps+2),SP ; LD SP,(ps)
	ei	!pop d !pop h !ret	; resume channel program
waitp	push	h !push d !dw 073edh,ps,07bedh,ps+2 ; LD (ps),SP ; LD SP,(ps+2)
	lda	ibank+1 !out 18h !pop d !pop psw !pop h !ei !ret
;
; Slow Timer Interrupt Handler--
slow	mvi	a,1 !sta tick !pop psw !ei !ret
;
; Clock Interrupt Handler--
alarm	push	h !mvi a,12 !out 3dh !in 3ch ; acknowledge
	lhld	count !inx h !shld count !lxi h,mkc !dcr m
	ani	20h !jz am1 !push d !lxi h,ev0+8 !call go !pop d ; alarm due
am1	pop	h !pop psw !ei !ret
;
; Floppy Disc Interrupt Handler--
fdint	push	psw !push d !dw 073edh,istack ; LD (istack),SP
	lxi	sp,istack
	lxi	h,ans+1 !mvi e,0 !call res	; get any result
	mov	a,e !ora a !cz sis !lxi h,ev0 !cnz go
	dw	07bedh,istack ; LD SP,(istack)
	pop	d !pop psw !pop h !ei !dw 04dedh ; RETI
sis	mvi	a,08h !out 35h !lxi h,ans+8 !call res ; Sense Interrupt Status
	lda	ans+8 !dw 06fcbh ; BIT 5,A	; End Seek/Recalb
	rz	!sta ans+1 !ret 		; ignore Ready Line change
res	in	34h !ora a !jp res !ani 40h !rz ; get result data
	in	35h !mov m,a !inx h !inr e !jmp res
;
; Replace Blocked Task in Ready Queue (interrupts must be disabled)--
go	mov	a,m !mvi m,80h !ora a !rm ; no task waiting
	mov	d,a !mvi m,0ffh !dcx h !mov e,m !push d
	lhld	stack !mvi d,0 !mov e,l !inr h !inr l !shld stack
	lxi	h,rdy0 !dad d !dad d !pop d !mov m,e !inx h !mov m,d !ret
;
vdu	push	psw !push b !push h !mov c,a !dw 073edh,shelt ; LD (shelt),SP
	lxi	sp,shelt !mvi a,20h !out 18h !call 0ecdh ; System Bank
	mvi	a,10h !out 18h !dw 07bedh,shelt ; LD SP,(shelt)
	pop	h !pop b !pop psw !ret
;
; Time Subroutine with 1.536MHz clock (2.6 Z80 clock cycles)
rst6	dw	0d908h ; EX AF,AF' ; EXX
	pop	h !shld s1+1 !inx h !inx h !push h
s1	lhld	0 !shld s2+1		; move rtn address
	mvi	a,0b0h !out 0cbh	; Terminal Count
	xra	a !out 0cah !out 0cah	; Start counting
	dw	0d908h ; EX AF,AF' ; EXX
s2	call	0
	dw	0d908h ; EX AF,AF' ; EXX
	mvi	a,080h !out 0cbh	; Latch
	mvi	a,0b0h !out 0cbh	; 2-byte R/W
	in	0cah !mov e,a !in 0cah !mov d,a
	lxi	h,-37 !ora a !dw 052edh ; SBC HL,DE ; 37=timer overhead
	shld	00040h
	xchg	!lhld max !ora a !dw 052edh ; SBC HL,DE
	jnc	s3 !xchg !shld max !jmp s4
s3	lhld	min !ora a !dw 052edh ; SBC HL,DE
	jc	s4 !xchg !shld min
s4	dw	0d908h ; EX AF,AF' ; EXX
	ret
;
ibank	equ	$	; Interrupt Handler workspace
p1	in	30h !ani 0f0h !ori 1 !out 18h !ret ; patch BEEP rtn
p2	jmp	rst6			; RST 6
p3	equ	$
init	lxi	h,p1 !lxi d,0f951h !lxi b,p2-p1 !dw ldir
	lxi	h,p2 !lxi d,00030h !lxi b,p3-p2 !dw ldir
	mvi	a,20h !out 18h			; System Bank
	mvi	a,0c9h !sta 04a8dh		; stop printer interrupt
	xra	a !sta 0278ch !sta 027cch	; patch Clear Screen
       ;sta	06cfh ;sta 06d0h		; patch Disc Command
	mvi	a,10h !out 18h			; Main Bank
	lxi	h,slow !shld 0fdb6h	; -> Slow Timer Interrupt Service
	lxi	h,alarm !shld 0fdaah	; -> Alarm Clock Interrupt Service
	lxi	h,fdint !shld 0feech	; -> Floppy Disc Interrupt Service
	lxi	h,rsint !shld 0fd92h	; -> RS232 Interrupt Service
	lxi	h,print !shld 0fda2h	; -> Printer Interrupt Service
	lxi	h,vdu	!shld 0110h
	lxi	h,testk !shld 0128h
	lxi	h,go	!shld 019dh
	lxi	h,waitp !shld 01a0h
	ret
	end	base

The QX10 Archive