; **** 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