; **** SUPERVISOR **** boot equ 0000h ; system reboot bdos equ 0005h ; bdos entry point fcb equ 005ch ; -> Primary File Control Block ctl equ 01d0h ; -> System Control Block ps equ 0c3fch ; SP save area & stack for printer interrupt count equ 0e7fch ; Seconds Counter tick equ 0e7ffh ; Slow Timer Status kbsw equ 0fe52h ; Keyboard switch status attr equ 0fe7ah ; VDU character attributes ; ; Z80 OP Codes-- ldir equ 0b0edh djnz equ 00010h ; ; Significant ASCII characters-- nul equ 00h etx equ 03h bel equ 07h bs equ 08h lf equ 0ah ff equ 0ch cr equ 0dh dc3 equ 13h ; [PAUSE] key esc equ 1bh time equ 7fh s equ 80h ; ; Define External Task locations-- tasku equ 01000h ; System Utilities tasko equ 01C00h ; Options taski equ 02000h ; Initial Task tasky equ 05000h ; non-resident taskm overlay area name equ 07C00h ; Job Text area taskx equ 0E000h ; OS Utilities ev0 equ 0E701h ; 1st Event Control Block stack equ 0E7C0h ; Scheduler Stack: Ready Count, ROC, -> Runner rdy0 equ stack+4 ; Ready Task Q ; ; Allocate Input Buffers-- bufe equ 0d000h buf0 equ bufe-2048 ; Com0 Input Buffer buf3 equ buf0-512 ; Com3 Input Buffer buf4 equ buf3-512 ; Com4 Input Buffer ; org 100h call init !jmp go ; External entry points to Supervisor Services-- jmp stop ; Terminate Program jmp suspend ; Block Task voluntarily jmp char ; Keystroke -> A vdu jmp rtn ; A -> Screen jmp test0 ; Z: Com0 -> A jmp out0 ; A -> Com0 jmp in3 ; Com3 -> A jmp out3 ; A -> Com3 jmp in4 ; Com4 -> A jmp out4 ; A -> Com4 jmp rtn ; MOUT Mainframe Output Driver (option) testk jmp rtn ; Z: Keystroke -> A jmp listen3 ; Z: Com3 -> A jmp listen4 ; Z: Com4 -> A io jmp rtn ; Screenhandler clock jmp rtn ; Date & Time -> String @ DE jmp rtn ; OUTPUT String (HL) -> Mainframe pout jmp outl ; A -> Logging Printer jmp fetch ; Overlay (HL) -> (DE) stow jmp rtn ; STOW Write System Control Record jmp rtn ; SPOOL (DE) -> Next Sector jmp rtn ; UNSPOOL Oldest Sector -> (DE) jmp spawn ; Initiate Task at (DE) jmp timer ; Slow Timer Interrupt after DE units jmp rtn ; SCREEN A -> Mainframe Terminal Screen jmp rtn ; KYBD Translate A to M18 code jmp rtn ; USER Keyboard Exit Routine jmp open3 ; Open Com3 Port jmp close3 ; Close Com3 Port jmp open0 ; Open Com0 Port jmp open4 ; Open Com4 Port jmp sleep ; Suspend for DE seconds jmp idler ; Suspend taskm with escape option jmp taskm ; Mainframe Task input jmp rtn ; Mainframe String -> (HL) jmp spawni ; Initiate & count Task at (DE) echo jmp rtn ; A -> Mainframe Electronic Mode jmp openf ; Open fcb (DE) with name (HL) jmp closef ; Close fcb (DE) jmp rtn ; RESET Disc System jmp trace ; A -> Screen if [SF1] lit jmp rtn ; EXITM (Terminate Mainframe Job) jmp bmap ; Map A buffers each of BC bytes at (HL)-2 jmp print ; Print Line jmp cboot ; Cold Start term jmp rtn ; Mainframe Terminal kybd task jmp rtn ; MARK jmp rtn ; ERROR jmp rtn ; BYTE (Next IBMpc file byte -> A, or Z=EOF) jmp wait ; Block Task until Event (DE) ready jmp rtn ; Unblock Task awaiting Event (HL) (Int Off) waitp jmp rtn ; Block Printer Channel Prog until interrupt jmp rtn ; INJECT (HL) -> Mainframe (terminal) jmp rtn ; NEXTDIR (HL)=Next IBM Directory entry, or Z=no match jmp rtn ; Z=Password Correct jmp rtn jmp rtn ; org 1c0h cword db 0 ; Pending Control Code key db s ; current Keystroke label dw 0 ; -> Spool Diskette Label dw 0 ; (not used) kew dw kev0+1 ; -> current Keyboard Event Word mname dw name ; -> taskm current Electronic pgm name mask0 db 0 ; Com0 Data Mask mask3 db 0 ; Com3 Data Mask mask4 db 0 ; Com4 Data Mask db 0 ; (spare) config db 1 ; B0: Parallel printer available ; B1: Com3 & Com4 (Telecomms) available ; B2: Mainframe Emulator running ; B3: Mainframe Kybd Task running ; B7: Autodial Modem swreg db 0 ; initial Switch Register mask ; ; System Control Block-- org ctl hstate db 0 ; hstate (HX20 task idle) db 0,0,0,0,0,0,0 dw 08000h ; -> Record Area dw 64 ; = Record Length (bytes) mstate db 0,0 ; mstate, mlines dw 0,0 ; mtimer, tstate db 0 ; B7: [BREAK] pressed dw name+40h; -> A/C name & address msub db 0 ; Mainframe subtask count db 0 ; Telecomms subtask count db 0,0 ; xstate light db 0 ; Cursor Control dw 0,0,0,0,0,0,0,0,0,0,0 ; ; Buffer Control-- dw buf4,buf3,buf0,bufe ; -> Input Buffers put4 dw buf4,buf4 ; put4, get4 put3 dw buf3,buf3 ; put3, get3 put0 dw buf0,buf0 ; put0, get0 ; ; ******************* Task Scheduler ********************** suspend push psw !push b !push h ; Block Task voluntarily su0 dw 073edh,0 ; LD (0),SP go lxi sp,stack !di !pop b !pop h ; B=ROC, C=Ready Count, HL -> Run inx h !inx h !dcr b !jnz $+7 !mov b,c !lxi h,rdy0 ; wrap around push h !push b !ei !shld su0+2 !shld go0+2 go0 dw 07bedh,0 ; LD SP,(0) ; next Task SP pop h !pop b !pop psw rtn ret ; Schedule next Task ; wait push psw !push b !push h ; Block Task until Event (DE) xchg !di !mov a,m !mvi m,0ffh !cpi 80h !jz su0 !dcx h block shld $+5 !dw 073edh,0 ; LD ((HL)),SP ; Remove Task from Ready Q lxi sp,stack !di !pop b !pop d ; B=ROC, C=Ready Count, DE -> Runner dcr c !lxi h,-2 !dad d !push h !push b !cz halt !dcr b !jz go lxi h,2 !dad d ; Shunt Ready Q left 1 entry mov c,b !mvi b,0 !dw 021cbh,ldir ; SLA C ; LDIR jmp go halt ei !hlt !di !lda stack !ora a !rnz !jmp halt ; spawni shld savehl !lxi h,msub !inr m !lxi h,ttermi !jmp sp1 spawn shld savehl !lxi h,tterm ; Create Task with entry point (DE) sp1 push h !lhld free !shld sp2+6 !inx h !inx h !shld free !pop h sp2 dw 073edh,savesp,07bedh,0 ; LD (savesp),SP ; LD SP,(0) push h !lhld savehl !push d !push psw !push b !push h dw 073edh,savehl,07bedh,savesp ; LD (savehl),SP ; LD SP,(savesp) push h !push psw !lxi h,savehl+1 di !call ready !ei !pop psw !pop h !ret ; ttermi lxi h,msub !dcr m tterm lhld free !dcx h !dcx h !shld free !jmp block ; Terminate Task ; free dw rdy0+2 ; -> next free stack area savesp ds 2 savehl ds 2 ; ; in3 call test3 !rz !call suspend !jmp in3 ; Com3 -> A listen3 call suspend !jmp test3 ; Z: Com3 -> A ; in4 call test4 !rz !call suspend !jmp in4 ; Com4 -> A listen4 call suspend !jmp test4 ; Z: Com4 -> A ; om0 call suspend out0 mov e,a !in 13h !ani 4 !mov a,e !jz om0 ; wait for Tx empty out 11h !ret ; oh0 call suspend out3 mov e,a !in 0c5h !ani 4 !mov a,e !jz oh0 ; wait for Tx empty out 0c4h !push h !lxi h,kbsw !dw 05ecbh ; BIT 3,(HL) ; [SF1] cnz tlo !pop h !ret tlo lxi h,attr !dw 056cbh,096cbh ; BIT 2,(HL) ; RES 2,(HL) push psw !ori s !call vdu !pop psw !rz !dw 0d6cbh ; SET 2,(HL) ret ; od0 call suspend out4 mov e,a !in 0c7h !ani 4 !mov a,e !jz od0 ; wait for Tx empty out 0c6h !ret ; ol0 call suspend outl mov e,a !in 15h !ani 20h !mov a,e !jnz ol0 ; not ready out 14h !xra a !out 17h !inr a !out 17h ; strobe mov a,e !ret ; test0 push h !lhld put0+2 !xchg !lhld put0 !ora a !dw 052edh ; SBC HL,DE jnz tm1 !inr h !pop h !ret ; Z=0 (no data) tm1 ldax d !inx d !lxi h,bufe !ora a !dw 052edh ; SBC HL,DE jnz $+6 !lxi d,buf0 !xchg !shld put0+2 pop h !cmp a !ret ; Z=1 (data) ; test3 push h !lhld put3+2 !xchg !lhld put3 !ora a !dw 052edh ; SBC HL,DE jnz th1 !inr h !pop h !ret ; Z=0 (no data) th1 ldax d !inx d !lxi h,buf0 !ora a !dw 052edh ; SBC HL,DE jnz $+6 !lxi d,buf3 !xchg !shld put3+2 lxi h,kbsw !dw 05ecbh ; BIT 3,(HL) cnz thi !pop h !cmp a !ret ; Z=1 (data) thi lxi h,attr !dw 056cbh,0d6cbh ; BIT 2,(HL) ; SET 2,(HL) push psw !ori s !call vdu !pop psw !rnz !dw 096cbh ; RES 2,(HL) ret ; test4 push h !lhld put4+2 !xchg !lhld put4 !ora a !dw 052edh ; SBC HL,DE jnz td1 !inr h !pop h !ret ; Z=0 (no data) td1 ldax d !inx d !lxi h,buf3 !ora a !dw 052edh ; SBC HL,DE jnz $+6 !lxi d,buf4 !xchg !shld put4+2 pop h !cmp a !ret ; Z=1 (data) ; close3 mvi c,0c5h ; Com3 close mvi a,18h !dw 079edh ; OUT (C),A ; Channel Reset ret ; open0 push h !xchg !di ; RS232 Com0 mvi c,06h !mvi a,0b6h !di !out 07h ; Counter 2 Square Wave lxi h,rate !call start+3 !mvi a,18h !out 13h ; Channel Reset mvi a,2 !out 13h !xra a !out 13h ; WR2B in 0cch !ani 40h !push psw ; Isolate Com4 notDSR mvi c,013h !call setup0 !sta mask0 in 0cch !ani 40h !mov c,a pop psw !xra c !pop h !rz ; no change in Com4 DSR open4 xchg !di ; RS232 Com4 mvi c,0c9h !mvi a,076h !out 0cbh !call start ; Counter 1 mvi c,0c7h !call setup !sta mask4 !ret ; Z=0 ; open3 xchg !di ; RS232 Com3 mvi c,0cah !mvi a,0b6h !out 0cbh !call start ; Counter 2 (Tx) mvi c,0c8h !mvi a,036h !out 0cbh !call start ; Counter 0 (Rx) mvi c,0c5h !call setup !sta mask3 !ret ; setup mvi a,18h !dw 079edh ; OUT (C),A ; Channel Reset mvi a,2 !out 0c5h !xra a !out 0c5h ; WR2A mvi a,2 !out 0c7h !xra a !out 0c7h ; WR2B setup0 ldax d !inx d !ani 3 !mov b,a ; Bits per Char jz $+5 !cpi 3 !jz $+5 !xri 3 !rrc !rrc !mov l,a ; bits/c mask mvi a,0fh !rlc !dcr b !jp $-2 !ori 0fh !push psw ; save data mask ldax d !inx d !ani 3 !mov b,a ; Parity ldax d !inx d !ani 3 !rlc !rlc ; Stop Bits ora b !ori 40h !sta cmnd+1 ; Clock x16 ldax d !ani 20h !ori 1 !ora l !mov h,a !sta cmnd+7 ; WR3 ldax d !ani 3 !dw 0dcbh,047cbh ; RRC L ; BIT 0,A jz $+5 !ori 80h !ani 82h !ori 8 !ora l !mov l,a !sta cmnd+5 ; WR5 xchg !lxi h,cmnd !mvi b,8 !dw 0b3edh ; OTIR ; WR4, WR1, WR5, WR3 ei !pop psw !ret ; A=data mask, D=WR3, E=WR5 cmnd db 4,000h,1,010h,5,000h,3,000h ; start lxi h,rate+2 ; Start Counter ldax d !inx d !rlc !rlc !push b !mvi b,0 !mov c,a !dad b !pop b mvi b,2 !dw 0b3edh ; OTIR ret ; trace push psw !push h !lxi h,kbsw !dw 05ecbh ; BIT 3,(HL) pop h !cnz vdu !pop psw !ret ; pr0 call suspend print lda pfree !inr a !jnz pr0 !sta pfree lxi d,pdriver !dw 073edh,ps+2 ; LD (ps+2),SP ; Start Driver lxi sp,ps !push d !push h !push b ; pass HL, BC to Driver DE dw 073edh,ps,07bedh,ps+2 ; LD (ps),SP ; LD SP,(ps+2) mvi a,0dh !out 17h ; printer interrupt ON lxi d,ev0+4 !call wait !lxi h,pfree !mvi m,0ffh !lhld now !ret pfree db 0ffh ; ; Printer Channel Program (keep off BC)-- pdriver dw 07ecbh ; BIT 7,(HL) ; test for embedded control byte jz $+7 !mov d,m !inx h !dw 0bacbh ; RES 7,D ; pickup control byte dcr d !jpe itext !cnz feed !call text mvi a,lf !call strobe !mvi a,cr !call strobe pdone shld now !lxi h,ev0+4 !di !call ready !jmp waitp ; done ; feed mvi a,ff !jm strobe fe1 mvi a,lf !call strobe !dcr d !rz !jmp fe1 ; itext mov a,m !inx h !ora a !jz pdone !call strobe !jmp itext te0 call strobe text mov a,m !inx h !ora a !rz cpi cr !jz $+5 !cpi lf !jnz $+5 !mvi a,' ' !cpi time !jnz te0 lxi d,now !call clock !push h !lxi h,now !mvi e,22 te1 mov a,m !inx h !call strobe !dcr e !jnz te1 !pop h !jmp text strobe out 14h !xra a !out 17h !inr a !out 17h ; data & strobe mvi a,0dh !di !out 17h !jmp waitp ; printer interrupt ON ; ; Read Overlay (HL) into (DE)-- fetch mvi a,0c9h !stax d !push d ; Preset RET instr. lxi d,fcb !lxi b,12 !dw ldir ; Title -> FCB lxi h,fcb+32 !xra a !mov m,a ; Current Record=0 lxi d,fcb !mvi c,15 !call bdos ; Open File for Input pop d !cpi 255 !rz ; Overlay not found ; Load code from file-- f2 lxi h,128 !dad d !push h ; Update DMA pointer mvi c,26 !call bdos ; Set DMA Address lxi d,fcb !mvi c,20 !call bdos ; Read Sector pop d !cpi 0 !jz f2 !ret ; ; Open .$$$ file with fcb (DE) and name (HL)-- openf push d !lxi b,9 !dw ldir push h !lxi h,sss !lxi b,3 !dw ldir mov h,d !mov l,e !mvi m,0 !inx d !lxi b,20 !dw ldir ; zeroise fcb pop h !lxi b,3 !dw ldir ; save type suffix pop d !push d !mvi c,19 !call bdos ; delete any previous work file pop d !mvi c,22 !call bdos ; enter in directory inr a !ret ; Z=directory full ; Close work file with fcb (DE)-- closef push d !mvi c,16 !call bdos ; close file pop d !push d !lxi h,9 !dad d !xchg !lxi h,bak !lxi b,3 !dw ldir pop d !push d !mvi c,19 !call bdos ; delete old .BAK pop d !push d !lxi h,16 !dad d !xchg !lxi b,16 !dw ldir pop h !push h !lxi b,9 !dad b !xchg !inx h !lxi b,3 !dw ldir pop d !push d !mvi c,23 !call bdos ; rename old .xxx as .BAK pop d !push d !lxi h,16 !dad d !xchg !lxi b,16 !dw ldir pop d !push d !lxi h,9 !dad d !xchg !lxi h,sss !lxi b,3 !dw ldir pop d !mvi c,23 !jmp bdos ; rename .$$$ as .xxx sss db '$$$' bak db 'BAK' ; ; Map A buffers each of BC bytes at (HL)-2 using 6+A*(BC+2) bytes-- bmap mov d,h !mov e,l !dcx h !mov m,d !dcx h !mov m,e !xchg mvi m,0 !inx h !mov m,a !inx h !xchg mvi h,0 !mov l,a !dad h !inx h !inx h !dad d bm1 xchg !mov m,e !inx h !mov m,d !inx h !xchg !dad b dcr a !jnz bm1 !stax d !inx d !stax d inx h !inx h !ret ; ; Set Slow Timer to interrupt after DE units-- timer xra a !sta tick mov a,e !out 1 !mov a,d !out 1 !ret ; ; Suspend task for DE seconds-- sleep push psw !push h !ora a !lxi h,0 !dw 052edh ; SBC HL,DE shld count !pop h sl10 call suspend !lda count+1 !ora a !jm sl10 pop psw !ret ; puc mov a,m !ora a !jnz $+6 !mvi a,' ' !ret !inx h uc cpi 'a' !rc !cpi 'z'+1 !rnc !sui 20h !ret ; upper case ; con lxi h,light !dcr m !lxi h,csw !jmp io ; cursor on coff lxi h,light !inr m !lxi h,csw !jmp io ; cursor off ; led push psw !in 12h !ani 4 !jz led+1 !pop psw !out 10h !ret ; ddt lhld 0006h !lxi d,0d000h !ora a !dw 052edh ; SBC HL,DE ret ; hl pchl ; stop push h !call wrapup !mvi a,0c9h !sta 0109h ; disable Suspend rtn pop h !call io !jmp boot ; cboot lda mstate !ani 1 !cnz tmode !ora m !mov m,a lxi d,80h !lxi b,16 !dw ldir call wrapup !lxi d,8100h !lxi h,gofile !call fetch lxi d,8000h !lxi h,code !lxi b,32 !dw ldir jmp 8000h tmode push h !lhld mname !lxi d,90h !lxi b,4 !dw ldir ; save pgm name lxi h,mstate !dw 0e6cbh ; SET 4,(HL) tr1 call suspend !dw 046cbh ; BIT 0,(HL) ; wait for Terminal Mode jnz tr1 !call suspend !mvi a,80h !pop h !ret code lxi d,0100h !lxi h,8100h !lxi b,0f00h !dw ldir jmp 0100h ; wrapup mvi c,013h !call close !mvi c,0c7h !call close !call close3 ; 0,4,3 mvi e,0ah !call wclock ; disable clock interrupts lhld masko !mov a,h !out 09h !mov a,l !out 0dh ; restore Epson mask in 34h !ani 1fh !jnz $-4 ; FDC busy lxi h,0fc02h !shld 0fd9ah ; Restore Epson FDC interrupt rtn lxi h,0fbfdh !shld 0fd92h ; Restore Epson SIO interrupt rtn lxi h,epson !lxi d,0fda0h !lxi b,32 !dw ldir ; restore int vector ret ; wclock mvi a,10 !out 3dh !in 3ch !ora a !jm wclock ; update in progress mvi a,11 !out 3dh !mov a,e !out 3ch !ret ; write RAM byte 0bh ; epson ei !jmp 0fc30h ; Printer push h !jmp 0fc16h ; Option Slot 1 nop !jmp 0fc32h ; Clock push h !jmp 0fc1bh ; Option Slot 2 push h !jmp 0fc20h ; Option Slot 3 ei !jmp 0fc31h ; Software Timer (slow) push h !jmp 0fc25h ; Option Slot 4 push h !jmp 0fc2ah ; Option Slot 5 ; ; RS232 Clock: MAIN OPTION rate dw 09c0h,0780h ; 0 50 Baud dw 0680h,0500h ; 1 75 Baud dw 046fh,0369h ; 2 110 Baud dw 039ch,02c7h ; 3 135 Baud dw 0340h,0280h ; 4 150 Baud dw 0270h,01e0h ; 5 200 Baud dw 01a0h,0140h ; 6 300 Baud dw 0138h,00f0h ; 7 400 Baud dw 00d0h,00a0h ; 8 600 Baud dw 008bh,006bh ; 9 900 Baud dw 0068h,0050h ; 10 1200 Baud dw 0045h,0035h ; 11 1800 Baud dw 0034h,0028h ; 12 2400 Baud dw 001ah,0014h ; 13 4800 Baud dw 000dh,000ah ; 14 9600 Baud dw 0006h,0005h ; 15 19200 Baud ; ; *********************** Mainframe Task *********************** ; taskm dw 073edh,msp ; LD (msp),SP mov e,m !inx h !mov d,m !inx h !shld list ; -> Mainframe rtns lxi h,rtn !mov a,d !ora e !jz $+4 !xchg !push h ; -> Emulator lxi h,mparms !lda swreg !dw 057cbh ; BIT 2,A ; SW3 (4800 baud) jz $+5 !mvi m,0dh !inx h !dw 047cbh ; BIT 0,A ; SW1 (8 N) jz $+5 !mvi m,3 !inx h !ani 3 !xri 3 !mov m,a !dcx h !dcx h call open0 !pop d !jz m01 ; Emulator not connected call spawn !lxi h,config !dw 0d6cbh ; SET 2,(HL) m01 lhld term+1 !mov a,m !cpi 0c9h !jz m06 ; immediate ret instruction lxi h,config !dw 0decbh ; SET 3,(HL); Mainframe Kybd running lxi d,term !call spawn ; Mainframe Terminal kybd m06 call off !call prog !shld fn ; wait for electronic pgm call on !lxi h,mstate !dw 0c6cbh ; SET 0,(HL); block KYBD m08 call suspend !lda mstate !ani 10h !jnz i10 lxi h,msub !mov a,m !ora a !jnz m08 ; previous job incomplete inr m !lhld fn !call hl ; Go lxi h,msub !dcr m ; terminated lda mstate !ani 01h !jnz m08 !jmp m06 ; off lda config !ani 8 !cnz con !mvi a,44h !jmp led ; off-line on lda config !ani 8 !cnz coff !mvi a,45h !jmp led ; on-line ; idler lda mstate !ani 10h !jz suspend !lxi h,msub !dcr m ; Revert to Terminal Mode-- i10 lda mstate !ani 0eeh !sta mstate ; B0, B4 off mvi a,esc !call echo !dw 07bedh,msp ; LD SP,(msp) jmp m06 ; prog lhld mname !call input lhld mname !lxi d,pgm+1 !lxi b,4 !dw ldir ; Scan name table-- lhld list t40 mov a,m !ora a !jz link ; not in list xchg !push d !call match !pop d !rz lxi h,6 !dad d !jmp t40 ; try next entry ; Fetch and link to overlay-- link lxi h,pgm !lxi d,tasky !call fetch !lxi h,tasky !ret ; Test name against table entry-- match lxi h,pgm+1 !mvi b,4 m90 ldax d !cmp m !inx d !inx h !rnz !dw djnz+(m90-$-2)*256 ldax d !mov l,a !inx d !ldax d !mov h,a !ret ; ; ********************* Keyboard Task *********************** taskk call chr !sta key !lhld kew !di !call ready !ei ; unblock user task lxi h,key !mvi a,s !mvi b,16 ; B=timer limit tk1 call suspend !cmp m !jz taskk !dw djnz+(tk1-$-2)*256 mov m,a !mvi a,bel !call vdu !jmp taskk ; discard (timed out) ; char push h !lhld kew !push h !inx h !inx h !shld kew ch1 lhld kew !xchg !call wait !lxi h,key !mov a,m !cpi s !jz ch1 mvi m,s !pop h !shld kew !pop h !ret ; kev0 dw 0ffffh,0ffffh,0ffffh,0ffffh,0ffffh ; Keyboard Event list ; debug lxi h,0109h !mvi m,0c9h ; disable Suspend Rtn call con !lxi h,01c0h !call 38h !call coff ; ddt lxi h,0109h !mvi m,0c3h ; enable Suspend Rtn chr call ink !cpi dc3 !jz opt ; [OPTION] key cpi etx !rnz ; [BREAK] key call ddt !jz debug !lda tstate !ori 80h !sta tstate !jmp chr ; opt lxi h,light !mov a,m !push psw !mvi m,0 !lxi h,msg2 !call io call ink !call uc !sta cword !sta msg3+4 pop psw !sta light !lxi h,msg3 !call io !lda cword cpi 'X' !lxi h,msg0 !jz stop cpi 'Q' !cz queue !jmp chr ink call testk !rz !lxi d,ev0+6 !call wait !jmp ink ; queue xra a !sta cword !lxi h,mstate !dw 046cbh ; BIT 0,(HL) mvi a,esc !jz echo ; Terminal Mode dw 0e6cbh ; SET 4,(HL) ; request Terminal Mode call suspend !dw 0a6cbh,046cbh ; RES 4,(HL) ; BIT 0,(HL) rz !mvi a,bel !jmp vdu ; ; ************** Initial Task Control Program *************** tcpi push h !lxi h,form0 !call io !pop h !call io call taski !lxi h,null !call taskm !jmp stop ; printx xra a !lxi b,0 !dw 0b1edh ; CPIR ; null print routine ret ; ; ************************ Initiator ************************ init in 18h !sta swreg !call ddt ; Z=debug running lxi h,80h !jnz $+8 !xra a !mov m,a !inx h !mov m,a !dcx h call iname lxi h,ev0-1 !mvi m,0ffh !lxi d,ev0 !lxi b,191 !dw ldir ; events lxi d,stack !lxi h,work !lxi b,30 !dw ldir ; initialize Qs in 09h !mov h,a !in 0dh !mov l,a !shld masko ; initial mask lxi h,ivec !lxi d,0fda0h !lxi b,32 !dw ldir ; interrupt vector mvi a,'X' !lxi d,taskx !call load ; OS Utilities mvi a,'U' !lxi d,tasku !call load ; System Utilities mvi a,'O' !lxi d,tasko !call load ; Options call taskx !call tasku !call tasko ; Patch BIOS, OS, Options lxi h,0 !shld count !shld count+2 mvi e,03ah !call wclock ; enable clock interrupts mvi a,070h !out 3 !sta tick ; Initialize Slow Timer mvi a,00ch !out 17h ; disable printer interrupts lhld mask !mov a,h !out 09h !mov a,l !out 0dh ; setup int mask out 0cch !mvi a,8 !dcr a !jnz $-1 ; Find Aux RS232 card lhld vect !cmp h !jz i4 ; not found dcx h !dcx h !dcx h !mov a,l !sui 09ch !rrc !rrc mov b,a !mvi a,80h !rlc !dcr b !jnz $-2 ; set Slave Mask bit in A xchg !lxi h,aux !lxi b,4 !dw ldir ; install interrupt vector lxi h,config !dw 0cecbh ; SET 1,(HL); Com3 & Com4 available i4 mov b,a !lda mask !ori 0dah !xra b !out 0dh ; mask other slots lxi h,ifile !lxi d,taski !call fetch lxi d,taskk !call spawn ; Keyboard Task lxi d,tcpi !lxi h,csw ; Initial Task in 15h !ani 68h !cpi 48h !jz spawn ; printer ready lxi h,msg7 !cpi 68h !jnz spawn ; printer not ready mvi a,0c9h !sta pout !lxi h,printx !shld 0188h lxi h,config !dw 086cbh ; RES 0,(HL); no parallel printer lxi h,msg6 !jmp spawn ; aux push h !jmp 0e003h trap push psw !in 0cch !pop psw !xthl !shld vect !xthl !ei !ret vect dw 0 ; load lxi h,file+1 !mov m,a !dcx h !call fetch !rnz lxi d,msg1 !mvi c,9 !call bdos !jmp boot ; iname mov a,m !ani 7fh !rz !lxi d,ifile+1 !mvi b,8 i1 inx h !mov a,m !cpi ' ' !jz i1 ; skip spaces i2 call puc !stax d !inx d !dw djnz+(i2-$-2)*256 ret ; mparms db 0eh,2,3,1,0dfh ; 9600 7 E 1 form0 db 1,1,0e2h,'Joe',27h,'s OS V72 ',7fh,s,3,1,nul null db nul csw db 0,0,nul ; Cursor Switch string msg0 db 0,1,0c0h,time,' OS Shutdown',nul msg1 db cr,lf,'Cannot find X.OVL, U.OVL &/or O.OVL$' msg2 db 1,28,91h,' Option: ',bs,bs,bs,nul msg3 db 1,36,81h,'= ',nul msg6 db 1,40,81h,'No Printer',nul msg7 db 1,40,84h,'Printer unready',nul file db 0,' OVL' ifile db 0,'I OVL' gofile db 0,'GO COM' pgm db 0,'xxxx OVL' ; Main Electronic Overlay name mask dw 02e00h ; masko ds 2 ; original interrupt mask list ds 2 ; -> taskm resident pgm name/address table fn ds 2 ; -> taskm current Electronic pgm msp ds 2 ; taskm save SP now ds 22 ; Printer Driver w/s ; Stack Control (12 Task stacks each of 30 levels)-- work dw 0100h,rdy0-2 ; Task Ready Count, ROC, -> Runner dw 0,work+60*1,work+60*2,work+60*3,work+60*4 dw work+60*5,work+60*6,work+60*7,work+60*8 dw work+60*9,work+60*10,work+60*11,work+60*12 ivec push h !jmp 0 ; Printer call trap !ret ; Option Slot 1 push psw !jmp 0fc32h ; Clock call trap !ret ; Option Slot 2 call trap !ret ; Option Slot 3 push psw !jmp 0fc32h ; Software Timer (slow) call trap !ret ; Option Slot 4 call trap !ret ; Option Slot 5 end