; DISK OPERATING SYSTEM ; OF MP/M ( BDOS ) ; ; 1980.10.31. VER.1.0 ; 1980.11.11. VER.1.1 ; ; ; BDOS FUNCTION CODES ; CRCNIN EQU 3 ;RAW CONSOLE INPUT CRCNOT EQU 4 ;RAW CONSOLE OUTPUT CLIST EQU 5 ;LIST OUTPUT CDKRST EQU 13 ;DISK SYSTEM RESET CSELDSK EQU 14 ;SELECT DISK CSETDMA EQU 26 ;SET DMA ADDRESS CSETUSR EQU 32 ;SET USER NUMBER ; ; XDOS FUNCTION CODES ; CMKQU EQU 134 ;MAKE QUEUE CRDQU EQU 137 ;READ QUEUE CCRDQU EQU 138 ;CONDITIONAL READ QUEUE CWTQU EQU 139 ;WRITE QUEUE CCWTQU EQU 140 ;CONDITIONAL WRITE QUEUE CDISP EQU 142 ;DISPATCH CTERM EQU 143 ;TERMINATE PROGRAM CATACH EQU 146 ;ATTACH CONSOLE CDETACH EQU 147 ;DETACH CONSOLE CGSDA EQU 154 ;GET SYSTEM DATA ADDRESS ; ; OTHER DATA ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED ; ; LINKS TO XDOS ; DISP EQU $-3 ;DISPATCH ENTRY XDOS EQU DISP-3 ;EXTENDED ROUTINE ENTRY ; ; JUMP VECTORS ; JMP XBDOS ;XDOS BDOS ENTRY JMP XIOS ;XIOS LINK ; ; BDOS INITIALIZE ROUTINE ; INPUT ; HL:SYSTEM DATA AREA ; INITL: SHLD SYSDT ;SAVE SYSTEM DATA AREA MOV C,H ;SAVE SYSTEM DATA AREA TOP MVI L,0FCH MOV A,M INX H MOV H,M ;GET PARAMETER TABLE POINTER MOV L,A LXI D,5 DAD D SHLD PDPNT ;SAVE PROCESS DESCRIPTOR POINTER POINT MOV H,C MVI L,3 MOV A,M ;GET STACK MODE STA STKMD ;SAVE STACK MODE DCR L MOV L,M ;GET RESTART NUMBER MVI H,0 MOV C,L DAD H DAD H DAD H MVI M,0C3H ;SET RESTART ENTRY INX H LXI D,RSTENT MOV M,E ;SET VECTOR INX H MOV M,D MVI A,0C3H STA 0 LXI H,JWBOOT ;TO WORM BOOT SHLD 1 ;SET JUMP VECTOR TO BIOS DUMMY CALL SYSIN ;TO SYSTEM INITIALIZE EI MVI C,CMKQU LXI D,QMXDISK CALL XDOS ;MAKE "MXDISK " QUEUE FOR DISK SCHEDULE MVI C,CWTQU LXI D,UMXDISK CALL XDOS ;WRITE ONE PRIVILEGE MVI C,CMKQU LXI D,QMXLIST CALL XDOS ;MAKE "MXLIST " QUEUE FOR LISTER SCHEDULE MVI C,CWTQU LXI D,UMXLIST CALL XDOS ;WRITE ONE PRIVILEGE JMP MINBD ;DISK RESET ; ; DB 'COPYRIGHT (C) 1980,' DB ' DIGITAL RESEARCH ' ; ; USER CODE ; DB 0 ;OEM CODE DB 11 ;VERSION 1.1 DB 1 ;MP/M DB 0,0,0 ;USER CODE ; ; BDOS SYSTEM STACK BOTTOM ; INSTK EQU $-2 ;USER STACK SAVE AREA & STACK ; ; DUMMY CONSOLE STATUS ; CONSTD: CALL DBIOS ;GET PROCESS DESCRIPTOR TOP & SET FLAG LXI H,14 DAD D MOV D,M ;GET CONSOLE NUMBER JMP CONSTB ; ; DUMMY CONSOLE INPUT ; CONIND: CALL DBIOS ;SET FLAG MVI C,CRCNIN JMP XBDOS ;RAW CONSOLE INPUT ; ; DUMMY CONSOLE OUTPUT ; CONOTD: CALL DBIOS ;SET FLAG MOV E,C MVI C,CRCNOT JMP XBDOS ;RAW CONSOLE OUTPUT ; ; DUMMY LIST OUTPUT ; LISTD: MOV E,C MVI C,CLIST CALL XBDOS ;LIST OUT ; ; GET PROCESS DESCRIPTOR TOP & SET DUMMY BIOS ENTRY FLAG ; OUTPUT ; DE:P.D. TOP ; DBIOS: LHLD PDPNT MOV E,M INX H MOV D,M LXI H,6 DAD D MOV A,M ORI 80H ;SET FLAG MOV M,A RET ; ; QUEUE CONTROL BLOCKS ; QMXDISK: DS 2 ;QL DB 'MXD' ;NAME DB 69H,73H,6BH,' ' DW 0 ;MESSAGE LENGTH DW 1 ;NUMBER OF MESSAGE DS 2 ;DQ PROCESS HEADER DS 2 ;NQ PROCESS HEADER DS 2 ;NEXT MESSAGE IN DS 2 ;NEXT MESSAGE OUT DS 2 ;NUMBER OF MESSAGE TO BE READ DS 2 ;BUFFER DUMMY ; UMXDISK: DW QMXDISK ;POINTER TO QCB QMXLIST: DS 2 ;QL DB 'MXL' DB 69H,73H,74H,' ' DW 0 ;MESSAGE LENGTH DW 1 ;NUMBER OF MESSAGE DS 2 ;DQ DS 2 ;NQ DS 2 ;NEXT MSG IN DS 2 ;NEXT MSG OUT DS 2 ;NUMBER OF MSG DS 2 ;BUFFER DUMMY ; UMXLIST: DW QMXLIST ;POINTER TO QCB ; ; XDOS LINK DATA ; PDPNT: DS 2 ;PROCESS DESCRIPTOR POINTER POINT SYSDT: DS 2 ;SYSEM DATA ADDRESS STKMD: DS 1 ;SYSTEM STACK MODE 0 NOT USED ; ; BREAK POINT DATA SAVE AREA ; RSVHL: DS 2 ;HL SAVE AREA RSVPC: DS 2 ;PC SAVE AREA ; ; BIOS DUMMY JUMP TABLE ; DS 1 ;ADJUST TO THE PAGE TOP JMP BOOT ;TO COLD START DUMMY JWBOOT: ;WARM BOOT POINT JMP WBOOT ;TO WARM BOOT JMP CONSTD ;CONSOLE STATUS JMP CONIND ;CONSOLE INPUT JMP CONOTD ;CONSOLE OUTPUT JMP LISTD ;LIST OUT ; ; DOS FUNCTION CALL ENTRY FOR XDOS OR BDOS ; INPUT ; C:COMMAND CODE ; DE:INPUT PARAMETER ; XBDOS: MOV A,C ORA C JZ SRESET ;TERMINATE CURRENT PROCESS JP BDOS ;BDOS FUNCTIONS CALL XDOS ;XDOS FUNCTIONS MOV A,L RET ; ; BDOS FUNCTION NUMBER ERROR ; BDOSR: LXI H,-1 MOV A,L RET ; ; RESTART ENTRY ; RSTENT: DI SHLD RSVHL ;SAVE HL POP H SHLD RSVPC ;SAVE RETURN ADDRESS PUSH PSW LHLD PDPNT ;GET PROCESS DESCRIPTOR POINTER MOV A,M INX H MOV H,M ;GET CURRENT DESCRIPTOR TOP MOV L,A MVI A,15 ADD L MOV L,A MVI A,0 ADC H MOV H,A MOV A,M ;GET MEMORY SEGMENT ADD A ADI 30H ;GET B.P. VECTOR TABLE BIAS LHLD SYSDT ;GET SYSTEM DATA ADDRESS MOV L,A MOV A,M INX H MOV H,M ;GET B.P. VECTOR MOV L,A SHLD BPRTN ;SAVE VECTOR POP PSW LHLD RSVPC ;GET RETURN ADDRESS PUSH H LHLD RSVHL ;RESTORE HL JMP 0 BPRTN EQU $-2 ;JUMP VECTOR ; ; GET ORIGINAL STACK POINRER ; GETSP: XCHG ;SAVE HL POP H ;GET SP SPHL ;SET SP XCHG ;RESTORE HL RET ; ; BDOS FUNCTION CALL ENTRY ; BDOS: LDA STKMD ;GET STACK MODE ORA A JZ BDOSP ;NO USER STACK MODE LHLD PDPNT MOV A,M INX H MOV H,M MOV L,A ;GET P.D. TOP MVI A,15 ADD L MOV L,A MVI A,0 ADC H MOV H,A MOV A,M ;GET MEMORY SEGMENT INR A JZ BDOSP ;SYSTEM MODE DCR A ;SET STACK FOR USER SYSTEM CALL ADD A ADI 50H ;GET BIAS TO STACK VECTOR LHLD SYSDT MOV L,A MOV A,D MOV B,E ;SAVE INPUT PARAMETERS MOV E,M INX H MOV D,M LXI H,0 DAD SP ;GET CURRENT STACK XCHG SPHL ;SET STACK FOR SYSTEM CALL PUSH D ;SAVE USER STACK POINTER LXI H,GETSP PUSH H ;SAVE STACK RESTORE ROUTINE POINT MOV D,A MOV E,B ;RESTORE INPUT PARAMETER ; BDOSP: MOV A,C CPI 12 JC BDOSS ;SIMPLE I/O OPERATIONS CPI 40 JNC BDOSR ;FUNCTION NUMBER ERROR PUSH D ;FILE OPERATIONS PUSH B CALL GETPD LXI B,6 DAD B MOV A,M ANI 80H ;GET DUMMY BIOS CALL MODE CZ MSNCN ;CHECK CONSOLE MVI C,CRDQU LXI D,UMXDISK CALL XDOS ;WAIT FOR GETTING FILE OPERATION PRIVILEGE CALL GETPD LXI B,20 DAD B MOV E,M INX H MOV D,M ;GET CURRENT DMA OF PROCESS DESCRIPTOR PUSH H XCHG SHLD DMADD ;SAVE DMA ADDRESS MOV B,H MOV C,L CALL SETDM ;SET DMA ADDRESS POP H INX H PUSH H MOV A,M ;GET DISK SELECT CODE OF P.D. RRC RRC RRC RRC ANI 0FH MOV E,A MVI C,CSELDSK LDA NDRIV ;GET CURRENT DISK CMP E CNZ BDOST ;SELECT DISK POP H PUSH H MOV A,M ANI 0FH MOV E,A MVI C,CSETUSR LDA MDUSR ;GET CURRENT USER CODE CMP E CNZ BDOST ;SET USER CODE POP H INX H PUSH H LXI D,DIRCT CALL COPYP ;COPY DISK PARAMETERS POP H POP B POP D PUSH H CALL BDOST ;MAKE TARGET COMMAND POP D PUSH PSW PUSH H LXI H,DIRCT CALL COPYP ;RESTORE DISK PARAMETERS MVI C,CWTQU LXI D,UMXDISK CALL XDOS ;RELEASE THE FILE OPERATION PRIVILEGE POP H POP PSW RET ; ; MAIN ROUTINE OF BDOS ; INPUT ; C:NUMBER OF BDOS FUNCTION ; DE:INPUT PARAMETER ; OUTPUT ; A:OUTPUT PARAMETER ONE BYTE DATA OR LOWER DATA ; B:OUTPUT PARAMETER HIGHER DATA WHEN DOUBLE BYTES ; HL:PARAMETER OF DOUBLE BYTES ; BDOST: XCHG SHLD INPAR ;SAVE INPUT PARAMETER XCHG MOV A,E STA OUTSP ;SET ONE BYTE PARAMETER LXI H,0 SHLD OTPAR ;CLEAR OUTPUT PARAMETERS DAD SP ;GET USER STACK POINTER SHLD INSTK ;SAVE USER STACK POINTER LXI SP,INSTK ;SET BDOS STACK XRA A STA ENTYP ;ENTRY TYPE STA FLMOD ;CLEAR FILE COMMAND MODE STA DIRMD ;CLEAR DIRECTORY BUFFER MODE LXI H,BDOSE ;COMMAND END ROUTINE PUSH H ;SET RETURN ADDRESS TO END ROUTINE BDOSS: ;SIMPLE I/O ROUTINE ENTRY MOV A,C MOV C,E ;SAVE INPUT DATA MOV B,D LXI H,MINDX ;MAIN INDEX OF FUNCTION MOV E,A MVI D,0 DAD D DAD D MOV E,M INX H MOV D,M ;GET EACH FUNCTION ROUTINE ADDRESS XCHG PCHL ;TO EACH ROUTINE ; ; MAIN INDEX OF BODS FUNCTIONS ; MINDX: DW BOOT ;SYSTEM RESET NOT USED 0 DW MCNIN ;CONSOLE INPUT DW MCNOT ;CONSOLE OUTPUT DW MRCNIN ;RAW CONSOLE INPUT DW MRCNOT ;RAW CONSOLE OUTPUT DW LIST ;LIST OUTPUT 5 DW MDCIO ;DIRECT CONSOLE I/O DW MGIOB ;GET I/O BYTE DW MSIOB ;SET I/O BYTE DW MBFPR ;PRINT STRING DW MBFRD ;READ CONSOLE BUFFER 10 DW MSNCN ;GET CONSOLE STATUS DW MVSNM ;RETURN VERSION NUMBER DW MINBD ;RESET DISK SYSTEM DW MDVSL ;SELECT DISK DW MOPEN ;OPEN FILE 15 DW MCLOS ;CLOSE FILE DW MSERH ;SEARCH FOR FIRST DW MSENX ;SEARCH FOR NEXT DW MDELE ;DELETE FILE DW MRDNX ;READ SEQUENTIAL 20 DW MWTNX ;WRITE SEQUENTIAL DW MAKFL ;MAKE FILE DW MRNAM ;RENAME FILE DW MLIVC ;RETURN LOG-IN VECTOR DW MNDIV ;RETURN CURRENT DISK 25 DW MSDMA ;SET DMA ADDRESS DW MALOC ;GET ALLOCATION MAP POINT DW MWTPR ;SET DISK R/O VECTOR DW MGWPR ;GET DISK R/O VECTOR DW MSFAT ;SET FILE ATTRIBUTES 30 DW MGDPR ;GET DISK PARAMETER ADDRESS DW MUSER ;SET OR GET USER CODE DW MRDRN ;READ RANDOM DW MWTRN ;WRITE RANDOM DW MCFSZ ;COMPUTE FILE SIZE 35 DW MSRRC ;SET RANDOM RECODE DW MRSDV ;RESET DISK DW MACDV ;ACCESS DRIVE DW MFRDV ;FREE DRIVE ; ; 1:CONSOLE INPUT ; MCNIN: CALL CONAC ;ACTIVATE CONSOLE CALL CONCI ;CONSOLE INPUT MOV L,A RET ; ; 2:CONSOLE OUTPUT ; MCNOT: CALL CONAC ;ACTIVAE CONSOLE JMP PRINS ; ; 3:RAW CONSOLE INPUT ; MRCNIN: CALL GETCM ;GET CONSOLE MODE JMP MDCIN ; ; 4:RAW CONSOLE OUTPUT ; MRCNOT: CALL GETCM ;GET CONSOLE MODE JMP CONOTB ; ; 6:DIRECT CONSOLE I/O ; INPUT ; C:-1 INPUT -2 GET STATUS OTHER OUTPUT ; MDCIO: CALL CONAC ;ACTIVATE CONSOLE MOV A,C INR A JZ MDCIN ;INPUT MODE INR A JZ MDCIS ;STATUS MODE JMP CONOTB ;OUTPUT MODE ; MDCIN: ;INPUT MODE LXI H,INCON CALL GETCP MOV A,M ;GET BUFFERED CODE MVI M,0 ;CLEAR BUFFER ORA A CZ CONINB ;GET CODE IF NOT BUFFERED MOV L,A RET MDCIS: ;STATUS MODE CALL CONSTB MOV L,A RET ; ; 7:GET I/O BYTE ; MGIOB: ;NOT IMPREMENTED MOW XRA A MOV L,A RET ; ; 9:PRINT STRING ; MBFPR: CALL CONAC ;ACTIVATE CONSOLE JMP BUFPR ; ; 10:READ CONSOLE BUFFER ; MBFRD: CALL CONAC JMP STRED ; ; 11:GET CONSOLE STATUS ; MSNCN: CALL GETCM ;GET CONSOLE MODE JZ MSNCS ;NOW ACTIVE MVI C,CDISP CALL XDOS ;DISPATCH XRA A MOV L,A ;NOT READY RET ; MSNCS: ;NOW ACTIVE CALL CONIS MOV L,A MSIOB: ;DUMMY FOR SET I/O BYTE RET ; ; ERROR COMMENT OUT ROUTINES ; ; DISK READ WRITE ERROR ; EFLRW: LXI H,CFLRW ;"BAD SECTOR" JMP ERPRN ; ; DRIVE SELECT ERROR ; EDRIV: LXI H,CDRIV ;"SELECT" JMP ERPRN ; ; DISK WRITE PROTECT ERROR ; EDKCG: LXI H,CDKCG ;"R/O" JMP ERPRN ; ; FILE WRITE PROTECT ERROR ; EFLRO: LXI H,CDKCH ;"FILE R/O" ; ; ERROR COMMENT OU & KEY RESPONSE WAIT ; INPUT ; HL:ADDRESS OF COMMENT ; ERPRN: PUSH H ;SAVE COMMENT POINT CALL GETPD ;GET PROCESS DESCRIPTOR POINT LXI D,14 DAD D MOV D,M ;GET CONSOLE NUMBER CALL CRLFM ;CR & LF LDA NDRIV ;GET DISK NUMBER ADI 'A' STA CERPN+12 ;SET CODE TO COMMENT LXI B,CERPN CALL BFPRN ;"BDOS ERR ON "X": " POP B CALL BFPRN ;PRINT EACH COMMENT LXI H,-1 SHLD OTPAR ;SET OUTPUT PARAMETER CALL GETPD ;GET P.D.POINT LXI D,15 DAD D MOV A,M ;GET MEMORY SEGMENT INR A JZ BDOSF ;NOW SYSTEM MODE ; ; SYSTEM RESET TERMINATION OF CURRENT PROCESS ; SRESET: MVI C,CTERM LXI D,0 JMP XDOS ;TERMINATE ; ; ERROR COMMENT CODES ; CERPN: ;"BDOS ERR ON : " DB 42H,64H,6FH,73H,20H,45H,72H,72H DB 20H,4FH,6EH,' : $' CFLRW: ;"BAD SECTOR" DB 42H,61H,64H,20H DB 53H,65H,63H,74H,6FH,72H,'$' CDRIV: ;"SELECT" DB 53H,65H,6CH,65H,63H,74H,'$' CDKCH: ;"FILE R/O" DB 46H,69H,6CH,65H,' ' CDKCG: ;"R/O" DB 'R/O$' ; ; GET PROCESS DESCRIPTOR POINT ; OUTPUT ; HL:P.D. POINT ; GETPD: LHLD PDPNT MOV A,M INX H MOV H,M MOV L,A ;GET P.D. POINT RET ; ; GET MEMORY SEGMENT ; OUTPUT ; A:DATA ; HL:CODE POINTER ; GETMS: CALL GETPD ;GET P.D. POINT MVI A,15 ADD L MOV L,A MVI A,0 ADC H MOV H,A ;GET MEMORY SEGMENT POINT MOV A,M RET ; ; GET CONSOLE MODE ; OUTPUT ; D:CONSOLE NUMBER ; ZF:ON CURRENT P.D. ; GETCM: CALL GETPD XCHG LXI H,14 DAD D MOV A,M ;GET CONSOLE PUSH PSW PUSH B LHLD PDPNT LXI B,15 DAD B ADD A MOV C,A MVI B,0 DAD B ;GET P.D. POINT OF CURRENT CONSOLE MOV A,M CMP E JNZ $+6 ;NOT CURRENT P.D. INX H MOV A,M CMP D ;CHECK CURRENT P.D. POP B POP D MVI E,0 RET ; ; ACTIVATE CONSOLE ; OUTPUT ; E:-1 FOR DETACH WAIT ; CONAC: CALL GETCM ;CONSOLE MODE MVI E,-1 RZ ;CURRENT P.D. PUSH B PUSH D MVI C,CATACH CALL XDOS ;ATTACH CONSOLE POP D POP B RET ; ; GET CONSOLE DATA POSITION ; INPUT ; HL:DATA TOP POINT ; D:CONSOLE NUMBER ; OUTPUT ; HL:NOW CONSOLE DATA POINT ; GETCP: PUSH PSW MOV A,D ADD L MOV L,A MVI A,0 ADC H MOV H,A POP PSW RET ; ; CONSOLE STATUS ; CONST: PUSH D CALL CONSTB POP D RET ; ; CONSOLE INPUT ; OUTPUT ; A:CODE ; ZF:OFF DUMMY BIOS CALL EXIST ; CONIN: PUSH D CALL GETPD LXI D,6 DAD D POP D PUSH D MOV A,M ANI 80H ;GET DUMMY BIOS CALL MODE PUSH PSW CALL CONINB MOV B,A POP PSW MOV A,B POP D RET ; ; CONSOLE OUTPUT ; CONOT: PUSH D CALL CONOTB POP D RET ; ; CONSOLE I/O ROUTINES ; ; CONSOLE INPUT WITH CONSOLE INTERRUPT CODE CHECK ; OUTPUT ; A:CODE OF INPUT ; CONSI: LXI H,INCON ;CONSOLE INTERRUPT CODE CALL GETCP MOV A,M ;GET CODE MVI M,0 ;CLEAR CODE ORA A RNZ ;NOW CODE EXISTS CALL CONIT ;CHECK INPUT JMP CONSI ; ; CONSOLE INPUT WITHOUT ECHO BACK OF CONTROL CODE ; CONCI: CALL CONSI ;CONSOLE INPUT CALL CONCK ;CONTROL CODE CHECK RC ;CONTROL CODE PUSH PSW ;NORMAL CODE MOV C,A CALL PRINS ;PRINT WITH TAB POP PSW RET ; ; CONTROL CODE CHECK EXCEPT CR,LF,HTAB,BACK SPACE ; INPUT ; A:CODE ; OUTPUT ; CF:ON CONTROL CODE ; CONCK: CPI 0DH ;CARRIAGE RETURN RZ CPI 0AH ;LINE FEED RZ CPI 09H ;HORIZONTAL TAB RZ CPI 08H ;BACK SPACE RZ CPI 20H ;SPACE RET ; ; CHECK CONSOLE STATUS ; INPUT ; D:CONSOLE NUMBER ; E:0 SYSTEM POLL MODE ; OUTPUT ; 0:NOT READY ; 1:READY ; CONIS: CALL CONST ;GET CONSOLE STATUS ANI 1 LXI H,INCON CALL GETCP ;GET INPUT DATA POINT JNZ CONIR ;READY MOV A,M ;NOT READY NOW ORA A ;CHECK STORED CODE RZ ;NOT READY JMP CONID ;READY ; CONIR: ;GET NEXT CODE MVI M,0 ;CLEAR BUFFER ; CONIT: CALL CONIN ;CONSOLE INPUT JNZ CONIE ;DUMMY BIOS CALLED CPI 13H ;CONTROL-S JNZ CONIF CALL CONIN ;FREEZE CPI 03H ;CONTOL-C JZ CONIA ;ABORT XRA A RET ; CONIF: CPI 04H ;CONTROL-D JNZ CONIC PUSH D ;DETACH MVI C,CDETACH CALL XDOS ;DETACH CONSOLE & WAIT POP D MOV A,E ORA A RZ ;POLLING MODE PUSH D ;ATTACHED ENYRT MODE MVI C,CATACH CALL XDOS ;ATTACH CONSOLE POP D LXI B,MATACH CALL BFPRN ;"ATTACH: " CALL GETPD CONIV: ;PRINT PROGRAM NAME LXI B,6 DAD B MVI E,8 CONIP: ;PROCESS NAME PRINT LOOP MOV C,M PUSH H PUSH D CALL CONOT POP D POP H INX H DCR E JNZ CONIP INR E ; ; CR & LF OF SYSTEM MODE ; CRLFM: MVI C,0DH ;CR CALL CONOT MVI C,0AH ;LF CALL CONOT XRA A RET ; CONIC: CPI 03H ;CONTROL-C JNZ CONIE ; CONIA: ;ABORT CALL GETMS ;GET MEMORY SEGMENT INR A RZ ;SYSTEM MODE LXI B,MABORT CALL CONAB ;CHECK ABORT JZ SRESET ;TERMINATE PROCESS XRA A RET ; CONIE: LXI H,INCON CALL GETCP ;GET DATD POINT MOV M,A ;SET INPUT CODE CONID: MVI A,1 ;SET READY FLAG RET ; ; CHECK ABORT ; CONAB: CALL BFPRN ;COMMENT OUT CALL CONIN ;GET INPUT FOR CHECK PUSH PSW MOV C,A CALL CONOT ;ECHO BACK MVI C,CR CALL CONOT MVI C,LF CALL CONOT POP PSW ANI 5FH CPI 'Y' RET ; ; PRINT TO CONSOLE ; INPUT ; C:CODE ; PRINT: LXI H,ECHKL CALL GETCP MOV A,M ;GET ECHO KILL MODE ORA A JNZ PRINK ;KILL MODE PUSH B CALL CONOT ;CONSOLE OUTPUT CALL CONIS ;CHECK CONSOLE STATUS POP B PUSH B PUSH D LXI H,OTLST CALL GETCP MOV A,M ;GET LSITER ECHO MODE ANI 1 CNZ LIST POP D POP B PRINK: MOV A,C LXI H,PCARI CALL GETCP ;GET CARRIAGE POSITION DATA POINT CPI 7FH RZ ;DELETE CODE INR M ;UP OF CARRIAGE POSITION COUNTER CPI 20H RNC ;NORMAL CODE DCR M ;CONTROL CODE MOV A,M ORA A RZ ;ZERO POSITION MOV A,C CPI 8 ;BACK SPACE JNZ $+5 DCR M ;DOWN OF COUNT RET ; CPI 0AH ;NEW LINE RNZ MVI M,0 ;CLEAR RET ; ; PRINT WITH CONTROL CODE VISIBLE ; INPUT ; C:CODE ; PRINC: MOV A,C CALL CONCK ;CONTROL CODE CHECK JNC PRINS ;NORMAL CODE PUSH PSW ;CONTROL CODE MVI C,5EH ;UPER ARROW IS CONTROL CODE MARK CALL PRINT POP PSW ORI 40H ;MAKE TO VISIBLE CODE MOV C,A ; ; CONSOLE OUTPUT ; INPUT ; C:CODE ; PRINS: MOV A,C CPI 09H ;HORIZONTAL TAB JNZ PRINT ;OTHER CODE MVI C,' ' CALL PRINT ;SPACE PRINT CALL GETCR ;GET CARRIAGE POSITION ANI 07H ;CHECK CARRIAGE POSITION JNZ $-10 ;TO TAB LOOP RET ; ; BACK SPACE WITH ERASE ON CRT ; BACKS: CALL BACK MVI C,' ' CALL CONOT ;ERASE BACK: MVI C,08H JMP CONOT ; ; PRINT "#" & CRLF FOR LINE CANCEL (CONTOL-U OR ...) ; NCRLF: MVI C,'#' CALL PRINT CALL CRLF NCRLL: ;LOOP FOR MOVING TO PROMPT POSITION CALL GETCR ;GET CARRIAGE POSITION LXI H,PPROM CALL GETCP ;GET PROMPT POSITION CMP M ;COMPARE WITH PROMPT POSITION RNC MVI C,' ' ;MOVE TO PROMPT POSITION CALL PRINT JMP NCRLL ; ; CARRIAGE RETURN & LINE FEED ; CRLF: MVI C,0DH ;CARRIAGE RETURN CALL PRINT MVI C,0AH ;LINE FEED JMP PRINT ; ; BUFFERED STRING PRINT END BY "$" ; INPUT ; BC:BUFFER TOP ADDRESS ; ; FOR SYSTEM MODE ; BFPRN: LDAX B ;GET CODE CPI '$' RZ ;END PUSH B MOV C,A CALL CONOT ;PRINT ONE CODE POP B INX B JMP BFPRN ; ; FOR BDOS FUNCTION MODE ; BUFPR: LDAX B ;GET CODE CPI '$' RZ ;END CODE INX B PUSH B MOV C,A CALL PRINS ;PRINT WITH TAB POP B JMP BUFPR ;TO NEXT CODE ; ; READ CONSOLE BUFFER ; INPUT ; BC:BUFFER POINTER ; POP B STRED: PUSH B CALL GETCR ;GET CARRIAGE POSITION LXI H,PPROM CALL GETCP ;GET PROMPT POSITION MOV M,A ;SET PROMPT POSITION MOV H,B MOV L,C MOV C,M ;GET MAXIMUM BUFFER LENGTH INX H PUSH H ;SAVE POINTER OF CURRENT LENGTH COUNTER MVI B,0 ;RESET COUNTER STREL: ;ONE CHARACTER LOOP PUSH B PUSH H CALL CONSI ANI 7FH ;CUT OF PARITY POP H POP B CPI 0DH ;CARRIAGE RETURN JZ STREE ;GET END CODE CPI 0AH ;LINE FEED JZ STREE ;GET END CODE CPI 08H ;BACK SPACE JNZ STREK MOV A,B ;BACK SPACE ORA A JZ STREL ;COUNT IS ZERO SO NO MEANING DCR B CALL GETCR LXI H,ECHKL CALL GETCP MOV M,A ;SAVE NOW POSITION JMP STREI STREK: CPI 7FH ;RUBOUT IS LAST CHARACTER DELETE JNZ STREA MOV A,B ORA A ;COUNTER CHECK JZ STREL ;THERE IS NO CHARACTER MOV A,M ;GET LAST CODE DCR B ;DOWN OF POINTER & COUNTER DCX H JMP STRES ;TO PRINT STREA: CPI 05H ;CONTROL-E "ONLY LINE CHANGE" JNZ STREB PUSH B PUSH H CALL CRLF ;LINE CHANGE LXI H,PPROM CALL GETCP XRA A MOV M,A ;PROMPT POSITION TO TOP JMP STREL+2 ;TO NEXT READ STREB: CPI 10H ;CONTROL-P "LIST MODE CHANGE" JNZ $+8 MVI A,1 JMP $+10 ; CPI 11H ;CONTROL-Q "OBTAIN OWNERSHIP OF PRINTER" JNZ STREC MVI A,80H PUSH H PUSH B PUSH D LXI H,OTLST CALL GETCP XRA M MOV M,A ;CHANGE LIST ECHO MODE PUSH H JNZ STRET ;TO ECHO MODE STREQ: ;CUT OFF OF ECHO MODE MVI M,0 MVI C,CCWTQU LXI D,UMXLIST CALL XDOS ;SET QUEUE POP H JMP STREP ; STRET: ;TO LIST ECHO MODE CPI 81H JZ STREQ ;^Q & ^P THEN OFF THE MODE MVI C,CCRDQU LXI D,UMXLIST CALL XDOS ;GET QUEUE MOV A,L ORA A POP H JZ STREP ;GET MODE MVI M,0 ;NOW BUSY LXI B,MPRBSY POP D PUSH D ;GET & SAVE CONSOLE NUMBER CALL BFPRN ;"PRINTER BUSY" STREP: POP D POP B POP H JMP STREL ;TO NEXT STREC: CPI 18H ;CONTROL-X CANCEL OF NOW SET JNZ STREY POP H STREX: ;CANSEL BY ERASE LXI H,PPROM CALL GETCP MOV A,M ;GET PROMPT LXI H,PCARI CALL GETCP CMP M JNC STRED-1 ;NOW TO TOP DCR M CALL BACKS ;ERASE BACK JMP STREX ;ERASE LOOP STREY: CPI 15H ;CONTROL-U "CANCEL OF NOW SET" JNZ STREF CALL NCRLF ;"#" & CR,LF POP H JMP STRED-1 ;TO START POINT STREF: CPI 12H ;CONTROL-R "CHANGE LINE & PRINT LEFT CODES" JNZ STREN ;NORMAL CODE STREI: PUSH B CALL NCRLF ;"#" & CR,LF POP B POP H ;GET READ BUFFER TOP +1 PUSH H PUSH B STREG: ;PRINT LEFT CODES MOV A,B ;COUNT OF LEFT CODES ORA A JZ STREH ;END OF PRINT INX H MOV C,M ;GET CODE DCR B PUSH B PUSH H CALL PRINC ;PRINT WITH CONTROL CODE VISIBLE POP H POP B JMP STREG ;TO NEXT CHARACTER PRINT STREH: PUSH H LXI H,ECHKL CALL GETCP MOV A,M ;GET ECHO KILL MODE ORA A JZ STREL+2 ;NORMAL MODE LXI H,PCARI CALL GETCP SUB M LXI H,ECHKL CALL GETCP MOV M,A ;SET CLEAR COUNT CALL BACKS ;BACK TO LAST POSITION LXI H,ECHKL CALL GETCP DCR M JNZ $-10 JMP STREL+2 STREN: ;NORMAL CODES INX H MOV M,A ;SET CODE & POINTER UP INR B ;COUNTER UP STRES: ;ECHO PRINT PUSH B PUSH H MOV C,A CALL PRINC ;PRINT WITH CONTROL CODE VISIBLE POP H POP B MOV A,B CMP C JC STREL ;TO NEXT READ STREE: POP H ;BUFFER FULL OR END MOV M,B ;SET COUNT POP H MVI C,0DH JMP PRINT ;PRINT CARRIAGE RETURN & END ; ; GET CARRIAGE POSITION ; OUTPUT ; A:PSITION COUNT ; HL:DATA POINTER ; GETCR: LXI H,PCARI CALL GETCP MOV A,M RET ; ; COMMENTS ; MPRBSY: ;PRINTER BUSY DB CR,LF,50H,72H,69H,6EH,74H DB 65H,72H,20H,42H,75H,73H,79H DB 2EH,CR,LF,24H ; MABORT: ;ABORT (Y/N) ? DB CR,LF,41H,62H,6FH,72H,74H DB ' (Y/N) ?$' ; MATACH: ;ATTACH: DB CR,LF,41H,74H,74H,61H DB 63H,68H,3AH,24H ; ; DATA AREA FOR BASIC I/O ; ECHKL: DB 0,0,0,0,0,0,0,0 ;ECHO KILL MODE COUNT DB 0,0,0,0,0,0,0,0 PPROM: DB 0,0,0,0,0,0,0,0 ;PROMPT POSITION DB 0,0,0,0,0,0,0,0 PCARI: DB 0,0,0,0,0,0,0,0 ;CONSOLE CARRIAGE POSITION COUNTER DB 0,0,0,0,0,0,0,0 OTLST: DB 0,0,0,0,0,0,0,0 ;LIST OUTPUT MODE 0 NOT OUT DB 0,0,0,0,0,0,0,0 INCON: DB 0,0,0,0,0,0,0,0 ;CONSOLE INTERRUPT CODE DB 0,0,0,0,0,0,0,0 MDUSR: DB 0 ;USER CODE NDRIV: DB 0 ;DISK NUMBER INPAR: DW 0000H ;INPUT PARAMETER BUFFER OTPAR: DW 0000H ;OUTPUT PARAMETER BUFFER ; ; DISK OPERATION ROUTINES ; ; COPY PROCESS DESCRIPTOR PARAMETERS ; COPYP: MVI C,5 XCHG ; ; COPY DATA ; INPUT ; DE:SOURCE POINTER ; HL:DESTINATION POINTER ; C:COUNT ; COPY: INR C DCR C RZ LDAX D MOV M,A INX D INX H JMP COPY+1 ; ; SELECT & GET DISK PARAMETER ; OUTPUT ; ZF:ON NOT AVAILABLE DISK ; GDTBL: LDA NDRIV ;GET CURRENT DISK MOV C,A CALL SELDK ;SELECT DISK MOV A,H ORA L RZ ;NOT AVAILABLE DISK MOV E,M INX H MOV D,M ;GET TRANSLATE TABLE POINTER INX H SHLD PHLEV ;GET TEMPORARY FOR HASH CHECK LEVEL INX H INX H SHLD PTRAK ;GET TRACK NUMBER AREA INX H INX H SHLD PSECT ;GET SECTOR CALCULATION AREA INX H INX H XCHG SHLD XTL ;SAVE TRANSLATE TABLE POINT LXI H,DIRBF ;DISK PARAMETER HEADER SAVE AREA MVI C,8 CALL COPY ;COPY DISK PARAMETER HEADER LHLD DPB ;GET DISK PARAMETER BLOCK POINTER XCHG ;DISK PARAMETER BLOCK SAVE AREA LXI H,SPT MVI C,15 CALL COPY ;COPY DISK PARAMETER BLOCK LHLD DSM ;GET MAXIMUM DISK BLOCK SIZE MOV A,H LXI H,DSMMD ;DISK SIZE MODE MVI M,-1 ORA A JZ $+5 ;<256 MVI M,0 ;>255 MVI A,-1 ORA A ;ZF OFF FOR NORML END RET ; ; SET UP FOR DIRECTORY READ ; DRDMD: CALL HOME ;TO HOME POSITION LXI H,OFF MOV C,M INX H MOV B,M ;GET OFF SET CALL SETRK ;SEEK TO DIRECTORY TOP XRA A LHLD PTRAK ;GET TRACK BUFFER POINTER MOV M,A INX H MOV M,A ;CLEAR TRACK NUMBER LHLD PSECT ;GET SECTOR BUFFER POINTER MOV M,A INX H MOV M,A ;CLEAR SECTOR CALCULATE AREA RET ; ; ONE SECTOR READ ; FREAD: CALL READ ;READ BY BIOS ROUTINE ORA A JNZ EFLRW ;ERROR RET ; ; ONE SECTOR WRITE ; FWRIT: CALL WRITE ;WRITE BY BIOS ROUTINE ORA A JNZ EFLRW ;ERROR RET ; ; SET DIRECTORY TRACK & SECTOR ; SDIRT: LHLD DIRCT ;DIRECTORY COUNTER MVI C,2 CALL DSHFR ;1/4 SHLD TSECT ;SAVE TO TARGET SECTOR BUFFER SHLD DIRSC ;SAVE TO DIRECTORY SECTOR BUFFER ; ; TRACK & SECTOR SET FROM LOGICAL ; "TSECT" TARGET SECTOR NUMBER ; TSSET: LXI H,TSECT MOV C,M INX H MOV B,M ;GET TARGET SECTOR LHLD PSECT ;GET SECTOR BUFFER POINTER MOV E,M INX H MOV D,M ;GET CURRENT SECTOR LHLD PTRAK ;GET TRACK BUFFER POINTER MOV A,M INX H MOV H,M MOV L,A ;GET CURRENT TRACK TSSEL: ;TRACK COUNT DOWN LOOP MOV A,C SUB E MOV A,B SBB D ;COMPARE SECTOR COUNT WITH TARGET SECTOR JNC TSSES ;UNDER SO CHECK COUNT UP PUSH H ;OVER SO COUNT DOWN LHLD SPT ;SECTOR / TRACK MOV A,E SUB L MOV E,A MOV A,D SBB H MOV D,A ;SUBTRUCT SECTOR COUNT OF ONE TRACK POP H DCX H ;DOWN ONE TRACK JMP TSSEL ;TO DOWN LOOP TSSES: ;TRACK COUNT UP LOOP PUSH H LHLD SPT DAD D ;ADD SECTOR OF ONE TRACK JC TSSEN MOV A,C SUB L MOV A,B SBB H JC TSSEN XCHG POP H INX H ;UP ONE TRACK JMP TSSES ;TO UP LOOP TSSEN: ;TARGET SECTOR IN THE TRACK POP H ;GET TRACK NUMBER PUSH B ;SAVE TARGET SECTOR PUSH D ;SAVE SECTOR NUMBER PUSH H ;SAVE TRACK NUMBER XCHG LHLD OFF ;GET OFFSET OF DIRECTORY DAD D ;GET PHYSICAL TRACK MOV B,H MOV C,L CALL SETRK ;SET TRACK POP D ;GET TRACK NUMBER LHLD PTRAK ;GET TRACK NUMBER BUFFER POINTER MOV M,E INX H MOV M,D ;SAVE TRACK TO TEMPORARY BUFFER POP D ;GET SECTOR NUMBER OF THE TRACK TOP LHLD PSECT ;GET SCTOR BUFFER POINTER MOV M,E INX H MOV M,D ;SAVE SECTOR POP B MOV A,C SUB E MOV C,A MOV A,B SBB D ;SUBTRUCT SECTOR COUNT OF THE TRACK TOP MOV B,A ;GET LOGICAL SECTOR LHLD XTL ;GET SECTOR TRANSLATE TABLE POINTER XCHG CALL SCTRN ;TRANSLATE TO PHYSICAL SECTOR MOV C,L MOV B,H JMP SETSC ;SET SECTOR ; ; GET BIAS IN DIRECTORY BLOCK MAP ; OUTPUT ; A:BIAS ; GBSDM: LXI H,BSH MOV C,M ;GET BLOCK SHIFT FACTOR LDA CRCNT ;GET CURRENT RECODE COUNT 0 TO 7FH ORA A RAR ;SHIFT & GET COUNT BY BLOCK DCR C JNZ $-3 MOV B,A ;SAVE COUNT BY RECODE COUNT MVI A,8 SUB M ;GET EXTENT SHIFT FACTOR MOV C,A LDA EXTNT ;GET EXTENT OF COUNT GBSDL: ;SHIFT LOOP FOR COUNT BY BLOCK DCR C JZ GBSDE ORA A RAL ;SHIFT OF EXTENT COUNT JMP GBSDL GBSDE: ADD B ;GET TOTAL COUNT BY BLOCK RET ; ; GET BLOCK NUMBER ; INPUT ; BC:BIAS IN DIRECTORY BLOCK MAP ; OUTPUT ; HL:BLOCK NUMBER ; GBLNM: LHLD INPAR LXI D,16 DAD D ;TOP OF DIRECTORY BLOCK MAP DAD B LDA DSMMD ;GET DISK SIZE MODE ORA A JZ GBLNS ;DOUBLE BYTES DSM > 255 MOV L,M ;SINGLE BYTE DSM < 256 MVI H,0 RET GBLNS: ;DOUBLE BYTES DAD B ;SO ADD BIAS TWICE MOV E,M INX H MOV D,M ;GET BLOCK NUMBER XCHG RET ; ; GET TARGET BLOCK ; GBLOK: CALL GBSDM ;GET BIAS IN DM MOV C,A MVI B,0 CALL GBLNM ;GET BLOCK NUMBER SHLD TSECT ;SAVE BLOCK NUMBER RET ; ; CHECK BLOCK EMPTY ; OUTPUT ; ZF:ON EMPTY ; CKBLK: LHLD TSECT MOV A,L ORA H RET ; ; BLOCK NUMBER TO TARGET SECTOR CONVERSION ; BLSCV: LDA BSH ;GET SHIFT FACTOR LHLD TSECT DAD H ;MAKE BASE DCR A JNZ $-2 SHLD BTSEC ;SAVE BLOCK TOP SECOR LDA BLM ;IN ONE BLOCK MOV C,A LDA CRCNT ;GET CURRENT RECODE COUNT ANA C ;GET BIAS IN ONE BLOCK ORA L MOV L,A SHLD TSECT ;SET TARGET SECTOR RET ; ; GET FILE EXTENT POINT ; OUTPUT ; HL:POINT ; EXTPT: LHLD INPAR LXI D,12 DAD D RET ; ; GET RECODE COUNT POINTS ; OUTPUT ; HL:CURRENT RECODE COUNT POINT ; DE:RECODE COUNT POINT ; GRCPT: LHLD INPAR LXI D,15 DAD D ;GET RECODE COUNT POINT XCHG LXI H,17 DAD D ;GET CURRENT RECODE COUNT POINT RET ; ; GET RECODE COUNTERS ; GRCNT: CALL GRCPT ;GET RECODE COUNTER POINTER MOV A,M STA CRCNT ;SET CURRENT RECODE COUNT XCHG MOV A,M STA RECNT ;SET RECODE COUNT CALL EXTPT ;GET FILE EXTENT POINT LDA EXM ;GET FILE EXTENT MASK ANA M STA EXTNT ;SAVE EXTENT OF RECODE COUNT RET ; ; UP & SET RECODE COUNTERS TO FCB ; SRCNT: CALL GRCPT ;GET RECODE COUNT POINTS LDA URCNT ;GET UP COUNT MODE CPI 2 JNZ $+4 ;NORMAL MODE XRA A ;RANDOM WRITE WITH ZERO FILL MOV C,A ;SAVE UP COUNT LDA CRCNT ;NOW COUNT ADD C ;UP THE COUNT MOV M,A ;SAVE CURRENT RECODE COUNT XCHG LDA RECNT MOV M,A ;SET RECODE COUNT RET ; ; DOUBLE BYTE SHIFT RIGHT ; HL:DATA ; INPUT ; C:COUNT ; DSHFR: INR C DCR C RZ MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A JMP DSHFR+1 ; ; GET DIRECTORY BUFFER ; OUTPUT ; HL:DIRECTORY BUFFER ; GDRBF: LHLD DIRBF LDA DIRMD ;GET DIRECTORY BUFFER MODE ORA A RZ LHLD DMADD RET ; ; GET HASH TOTAL OF DIRECTORY TO CHECK DISK CHANGE ; HASH: MVI C,128 ;COUNT OF ONE SECTOR CALL GDRBF ;GET BUFFER XRA A ADD M INX H DCR C JNZ $-3 RET ; ; DOUBLE BYTE SHIFT LEFT ; HL:DATA ; INPUT ; C:COUNT ; DSHFL: INR C DCR C RZ DAD H JMP DSHFL+1 ; ; SET DISK VECTOR ; INPUT ; BC:LAST VECTOR ; OUTPUT ; HL:NEW VECTOR ; SDFLG: PUSH B LDA NDRIV ;GET NOW DISK MOV C,A LXI H,1 CALL DSHFL ;GET DISK BIT POP B MOV A,C ORA L MOV L,A MOV A,B ORA H MOV H,A ;GET NEW VECTOR RET ; ; CHECK READ ONLY VECTOR ; OUTPUT ; ZF:ON READ WRITE DISK ; HSCHK: LHLD DROVC ;GET R/O VECTOR LDA NDRIV MOV C,A ;GET NOW DISK CALL DSHFR ;SHIFT RIGHT MOV A,L ANI 1 ;CHECK BIT RET ; ; SET DISK WRITE PROTECT FLAG ; SHSER: LXI H,DROVC MOV C,M INX H MOV B,M ;GET NOW R/O VECTOR CALL SDFLG ;SET FLAG SHLD DROVC ;SAVE NEW VECTOR LHLD DRM INX H XCHG LHLD PHLEV MOV M,E INX H MOV M,D ;SET DIRECTORY BLOCK MAX RET ; ; CHECK WRITE PROTECT FILE ; CHTPF: CALL GDRPT ;GET DIRECTORY TOP CHTEM: LXI D,9 DAD D MOV A,M ;GET FILE TYPE TOP RAL RNC ;READ WRITE FILE JMP EFLRO ;READ ONLY FILE ; ; CHECK CHANGE OR WRITE PROTECT DISK ; HSERT: CALL HSCHK ;CHECK R/O VECTOR RZ ;READ WRITE DISK JMP EDKCG ;READ ONLY DISK ; ; GET DIRECTORY POINT ; OUTPUT ; HL:POINT ; GDRPT: CALL GDRBF ;DIRECTORY BUFFER LDA BIDIR ;BIAS ; ; DOUBLE BYTES & SINGLE BYTE ADD ; A:ADDEND ; HL:DESTINATION ; DSADD: ADD L MOV L,A RNC INR H RET ; ; GET RECODE READ / WRITE MODE ; MODE BIT 7:R/W MODE H READ ONLY ; BIT 6:H RANDOM R/W ERROR ; BIT 0-4:EXTENTION OF FILE ; OUTPUT ; A:MODE ; HL:POINT OF MODE ; MDPNT: LHLD INPAR LXI D,14 DAD D MOV A,M RET ; ; CLEAR READ WRITE MODE TO WRITE MODE ; MDCLS: CALL MDPNT MVI M,0 RET ; ; INITIALIZE READ WRITE MODE TO READ ONLY ; MDOPN: CALL MDPNT ORI 80H MOV M,A RET ; ; SET ERROR FLAG TO OUTPUT PARAMETER AREA ; STOTP: MVI A,1 STA OTPAR RET ; ; CHECK HASH CHECK LEVEL ; OUTPUT ; CF:ON UNDER LEVEL ; DE:NOW LEVEL ; HL:LEVEL BUFFER POINT +1 ; CHLEV: LHLD DIRCT XCHG LHLD PHLEV MOV A,E SUB M INX H MOV A,D SBB M RET ; ; SET HASH CHECK LEVEL ; STHLV: CALL CHLEV RC ;UNDER LEVEL INX D MOV M,D DCX H MOV M,E ;SET NEW LEVEL RET ; ; SUBTRUCT DOUBLE BYTE ; HL = DE - HL ; DSUB: MOV A,E SUB L MOV L,A MOV A,D SBB H MOV H,A RET ; ; MAKE HASH OR CHECK ROUTINE ; INPUT ; C: 0= CHECK -1= SET ; HSHTS: MVI C,-1 ;FOR SET MODE HSHTR: LHLD DIRSC ;GET BIAS BY SECTOR IN DIRECTORY XCHG LHLD CKS ;SIZE OF HASH CHECK TABLE CALL DSUB RNC ;OVER OF CHECK TABLE PUSH B CALL HASH ;GET HASH TOTAL LHLD CSV ;GET HASH CHECK AREA XCHG LHLD DIRSC ;GET BIAS DAD D POP B INR C JZ HSHTT ;SET MODE CMP M RZ ;GOOD CALL CHLEV ;NOT MATCH ,SO CHECK THE LEVEL RNC ;HASH DATA WAS NOT ALREADY SET CALL SHSER ;SET R/O VECTOR FOR ERROR(CHANGE DISK) RET HSHTT: MOV M,A ;SET HASH DATA RET ; ; WRITE DIRECTORY WITH SET UP OF ITS HASH DATA ; DIWRT: CALL HSHTS ;SET UP OF HASH CHECK DATA CALL STDMD ;TO DIRECTORY DMA AREA MVI C,1 CALL FWRIT ;WRITE STDMA: ;SET NORMAL DMA ADDRESS LXI H,DMADD ;NORMAL DMA AREA STDMS: MOV C,M INX H MOV B,M ;GET DMA AREA ADDRESS JMP SETDM STDMD: LXI H,DIRBF ;DIRECTORY READ BUFFER POINTER JMP STDMS ; ; READ DIRECTORY ONE SECTOR ; DREAD: LDA DIRMD ORA A CZ STDMD ;TO DIRECTORY AREA CALL FREAD ;READ ONE SECTOR JMP STDMA ;TO NORMAL DMA ; ; CHECK DIRECTORY END ; OUTPUT ; ZF:ON END ; DICHK: LXI H,DIRCT ;DIRECTORY COUNTER AREA MOV A,M INX H CMP M RNZ ;NOT TO END INR A ;IF DATA IS 0FFFFH, ZF BECOMES ON RET ; ; INITIALIZE DIRECTORY COUNTER ; DIRCI: LXI H,-1 SHLD DIRCT ;INCREMENT AT FIRST IN THE DIRECTORY READ RET ; ; GET NEXT DIRECTORY ; INPUT ; C:0 HASH CHECK 1 SET ; DIRED: LHLD DRM ;GET MAX OF DIRECTORY NUMBER XCHG LHLD DIRCT INX H SHLD DIRCT ;DIRECTORY COUNTER UP CALL DSUB ;COMPARE WITH LENGTH JNC DIRES ;IN DIRECTORY DATA CALL DIRCI ;DIRECTORY OVER RET DIRES: LDA DIRCT ANI 3 ;GET BIAS BASE IN ONE SECTOR 8 DIRECTORIES MVI B,5 ADD A ;ONE DIRECTORY IS CONSTRUCTED FROM 32 BYTES DCR B JNZ $-2 ;*32 STA BIDIR ;SAVE BIAS IN ONE SECTOR ORA A RNZ ;IN THE SAME SECTOR PUSH B CALL SDIRT ;TO NEW SECTOR, SO SET DIRECTORY T & S CALL DREAD ;READ NEXT TO DIRECTORY BUFFER POP B JMP HSHTR ;TO HASH CHECK OR SET ; ; GET DISK ALLOCATION MAP BIT ; INPUT ; BC:TARGET BLOCK NUBER ; OUTPUT ; A:BIT 0 IS TARGET BIT ; D:ROTATION FOR SET ; HL:ALLOCATION MAP POINT OF TARGET BYTE ; DMBGT: MOV A,C ANI 7 INR A MOV E,A ;GET ROTATION IN ONE BYTE MOV D,A MOV A,C RRC RRC RRC ANI 1FH ;1/8 TO BYTE COUNT MOV C,A MOV A,B ADD A ADD A ADD A ADD A ADD A ;*32 ORA C ;GET BYTE BIAS LOWER BYTE MOV C,A MOV A,B RRC RRC RRC ANI 1FH ;GET BYTE BIAS HIGER BYTE MOV B,A LHLD ALV ;ALLOCATION MAP AREA DAD B MOV A,M ;GET TARGET BYTE RLC ;ROTATE DCR E JNZ $-2 RET ; ; CHANGE DISK ALLOCATION MAP BIT ; INPUT ; BC:BLOCK NUMBER ; E:0 DELETE 1 TO USE ; DMTRT: PUSH D CALL DMBGT ;GET BYTE ANI 0FEH ;DELETE BIT POP B ;SET BIT FOR USE OR NOT SET FOR DELETE ORA C ; ; SET DISK ALLOCATION MAP BIT ; INPUT ; A:MAP CODE ; D:ROTATION ; HL:ALLOCATION MAP POINT OF THE BYTE ; DMBST: RRC ;ROTATE TO THE NORMAL DATA DCR D JNZ DMBST MOV M,A ;SET DATA TO ALLOCATION MAP RET ; ; CHANGE DISK ALLOCATION MAP BIT OF ONE DIRECTORY ; INPUT ; C:0 DELETE 1 TO USE ; DMCHG: CALL GDRPT ;SET DIRECTORY POINT LXI D,16 DAD D ;GET DM POINT PUSH B MVI C,17 ;DM COUNT +1 DMCHL: ;NE BLOCK LOOP POP D DCR C RZ ;END OF ONE DIRCTORY PUSH D LDA DSMMD ;GET DISK SIZE MODE ORA A JZ DMCHD ;DOUBLE BYTES PUSH B ;SINGLE BYTE PUSH H MOV C,M ;GET BLOCK NUMBER MVI B,0 JMP DMCHS DMCHD: ;DOUBLE BYTES DCR C ;ONE MORE COUNT DOWN FOR USING DOUBLE BYTES PUSH B MOV C,M INX H MOV B,M ;GET BLOCK NUMBER PUSH H DMCHS: MOV A,C ORA B JZ DMCHB ;NOT USING BLOCK LHLD DSM ;GET MAX OF DISK STRAGE SIZE MOV A,L SUB C MOV A,H SBB B ;CHECK OVER SIZE CNC DMTRT ;SET OR DELETE IF IN THE SIZE DMCHB: POP H INX H POP B JMP DMCHL ;TO NEXT BLOCK ; ; INITIALIZE OF DISK ALLOCATION MAP & HASH CHECK TABLE ; INDMP: LHLD DSM MVI C,3 CALL DSHFR ;TO BYTE LENGTH AS MAP IS BIT STRING INX H ;GET ALLOCATION MAP BYTE LENGTH MOV B,H MOV C,L LHLD ALV ;GET ALLOCATION MAP AREA MVI M,0 ;CLEAR MAP INX H DCX B MOV A,B ORA C JNZ $-6 LHLD AL0 ;GET RESERVED ALLOCATION FOR DIRECTORY XCHG LHLD ALV MOV M,E INX H MOV M,D ;SET RESERVED ALLOCATION CALL DRDMD ;TO DIRECTORY READ MODE LHLD PHLEV MVI M,3 INX H MVI M,0 ;INITIALIZE HASH CHECK LEVEL CALL DIRCI ;INITIALIZE DIRECTORY COUNTER INDML: ;DISK ALLOCATION MAP SETTING LOOP MVI C,-1 ;HASH SET MODE CALL DIRED ;READ DIRECTORY CALL DICHK ;DIRECTORY END CHECK RZ ;ALL DIRECTORIES HAVE BEEN READ CALL GDRPT ;GET DIRECTORY POINT MVI A,0E5H ;DELETED CODE CMP M JZ INDML ;DELETED DIRECTORY LDA MDUSR CMP M ;CHECK USER CODE JNZ INDMS ;NOT SAME CODE INX H ;GET AVAILABLE FILE MOV A,M SUI 24H ;"$" IS SUBMIT FILE JNZ INDMS ;NOT SUBMIT FILE DCR A STA OTPAR ;SET SUBMIT FLAG INDMS: MVI C,1 ;TO USE MODE CALL DMCHG ;SET DISK ALLOCATION MAP CALL STHLV ;SET HASH CHECK LEVEL TO NOW LEVEL JMP INDML ;TO NEXT DIERCTORY ; ; SET DIRECTORY CODE -1 NOT FOUND ; SDCNT: LDA DIRCC STA OTPAR RET ; ; COMPARE DIRECTORY EXTENTION ; INPUT ; A:EXTENT CODE 1 ; C:EXTENT CODE 2 ; OUTPUT ; ZF:ON SAME DIRECTORY ; CONSTRUCTED FROM EXTENT OF RECODE COUNT AND EXTENT OF DIRECTORY BLOCK ; EXMCK: PUSH B PUSH PSW LDA EXM ;GET EXTENT MASK CMA ;TO DIRECTORY EXTENTION MASK MOV B,A MOV A,C ANA B ;GET EXTENTION OF DIRECTORY BLOCK MOV C,A POP PSW ANA B ;GET EXTENTIN OF 1 SUB C ;COMPARE THE EXTENTION OF DIRECTORY BLOCK ANI 1FH POP B RET ; ; DIRECTORY SEARCH ROUTINE ; INPUT ; C:LENGTH OF COMPARE ; DRSRH: MVI A,-1 STA DIRCC ;ITIALIZE DIRECTORY CODE LXI H,DRSLN MOV M,C ;SAVE LENGTH LHLD INPAR SHLD FCBPN ;SET FCB POINT CALL DIRCI ;INITIALIZE DIRECTORY COUNTER CALL DRDMD ;SET DIRECTORY READ PARAMETER ; ; MATCHING OF DIRECTORY ; DRMAT: MVI C,0 ;SET HASH MODE TO CHECK CALL DIRED ;READ DIRECTORY CALL DICHK ;END CHECK JZ DRMAE ;END LHLD FCBPN XCHG LDAX D ;GET ENTRY TYPE CPI 0E5H JZ DRMAD ;DELETE PUSH D CALL CHLEV ;CHECK HASH LEVEL POP D JNC DRMAE ;OVER THE DRECTORY AREA DRMAD: CALL GDRPT ;GET DIRECTORY POINT LDA DRSLN ;GET COMPARE LENGTH MOV C,A MVI B,0 DRMAL: ;ONE BYTE LOOP MOV A,C ORA A JZ DRMAO ;GET MATCH DIRECTORY LDAX D CPI '?' JZ DRMAI ;WILD CARD MOV A,B ORA A JNZ DRMAU+1 LDAX D ;USER CODE CPI 0E5H JZ DRMAU ;DELETE DIRECTORY MOV A,M ORA A JZ DRMAI ;0 CAN USER IN ALL USER DRMAU: MOV A,B CPI 13 JZ DRMAI ;NOT USE CODE CPI 12 LDAX D JZ DRMAX ;FILE EXTENT SUB M ANI 7FH JNZ DRMAT ;MISS MATCH TO NEXT DIRECTORY BLOCK JMP DRMAI ;MATCH TO NEXT BYTE DRMAX: ;FILE EXTENT PUSH B MOV C,M ;GET DIRECTORY EXTENT CALL EXMCK ;COMPARE DIRECTORY EXTENT POP B JNZ DRMAT ;NOT MATCH TO NEXT BLOCK DRMAI: ;TO NEXT BYTE INX D INX H INR B DCR C JMP DRMAL DRMAO: ;GET MATCH DIRECTORY LDA DIRCT ANI 3 ;GET BIAS IN SECTOR STA OTPAR ;SET DIRECTORY BIAS LXI H,DIRCC MOV A,M RAL RNC ;NOW SET SOME CODE XRA A MOV M,A ;CLEAR CODE RET DRMAE: ;NOT MATCH CALL DIRCI ;COUNTER INITIALIZE MVI A,-1 STA OTPAR ;NOT MATCH RET ; ; DELETE DIRECTORY & DISK ALLOCATION MAP BITS ; DEDMP: CALL HSERT ;CHECK DISK R/O & ERROR IF R/O MVI C,12 ;COMPARE ONLY NAME PART CALL DRSRH ;SEARCH THE TARGET DIRECTORY DEDML: CALL DICHK ;CHECK END RZ ;AL SEARCHED CALL CHTPF ;CHECK WRITE PROTECT FILE ERROR IF PROTECTED CALL GDRPT ;GET DIRECTORY POINT LDA MDUSR ;GET USER CODE CMP M JNZ DEDMS ;USER CODE MISS MATCH MVI M,0E5H ;DELETE CODE MVI C,0 ;DELETE BIT MODE CALL DMCHG ;DELETE DISK ALLOCATION BITS CALL DIWRT ;WRITE DIRECTORY DEDMS: ;TO NEXT CALL DRMAT ;SEARCH NEXT JMP DEDML ;TO NEXT DIRECTORY ; ; GET AVAILABLE BLOCK BY SEARCHING NEAREST BLOCK ; INPUT ; BC:LAST BLOCK NUMBER ; :0 WHEN FIRST BLOCK ; OUTPUT ; HL:AVAILABLE BLOCK NUMBER ; 0 NO AVAILABLE BLOCK ; GAVAI: MOV D,B MOV E,C GAVAL: ;SEARCH LOOP BC DOWN SEARCH DE UP SEARCH MOV A,C ORA B JZ GAVAS ;NOW BECOME TOP, SO TO UP SEARCH DCX B ;DOWN SEARCH PUSH D PUSH B CALL DMBGT ;GET ALLOCATION MAP BIT RAR JNC GAVAA ;GET AVAILABLE BLOCK POP B POP D GAVAS: LHLD DSM ;GET MAXIMUM SIZE MOV A,E SUB L MOV A,D SBB H JNC GAVAE ;NO AVAILABLE BY UP SEARCH INX D ;UP SEARCH PUSH B PUSH D MOV B,D MOV C,E CALL DMBGT ;GET ALLOCATION MAP BIT RAR JNC GAVAA ;GET AVAILABLE BLOCK POP D POP B JMP GAVAL ;CHECK NEXT GAVAA: ;GET AVAILABLE BLOCK RAL INR A CALL DMBST ;SET USE FLAG POP H ;GET AVAILABLE BLOCK NUMBER POP D RET GAVAE: MOV A,C ORA B JNZ GAVAL+5 ;NOT TO TOP, SO CHECK NEXT LXI H,0 ;NO AVAILABLE BLOCK RET ; ; ALL FCB DATA COPY TO DIRECTORY & WRITE ; COPYA: MVI C,0 MVI E,32 ; ; COPY TO DIRECTORY & WRITE ; INPUT ; C:BIAS OF FCB TO DIRECTORY ; :16 RENAME 0 SET ATTRIBUTE ; E:COPY LENGTH ; CPDIR: PUSH D MVI B,0 LHLD INPAR DAD B ;GET FCB COPY AREA TOP XCHG CALL GDRPT ;GET DIRECTORY TOP POP B CALL COPY CPDIE: CALL SDIRT ;SET DIRECTORY TRACK & SECTOR JMP DIWRT ;WRITE DIRECTORY ; ; RENAME ; RENAM: CALL HSERT ;CHECK DISK R/O MVI C,12 ;CHECK ONLY NAME CALL DRSRH ;SEARCH DIRECTORY LHLD INPAR MOV A,M LXI D,16 DAD D MOV M,A ;SET ENTRY TYPE RENAL: ;LOOP OF DIRECTORY BLOCK RENAME CALL DICHK ;CHECK DIRECTORY END RZ ;NOT FOUND OR END CALL CHTPF ;CHECK WRITE PROTECT FILE CALL GDRPT ;GET DIRECTORY POINT LDA MDUSR CMP M JNZ RENAS ;USER CODE MISS MATCH MVI C,16 ;BIAS IN FCB MVI E,12 ;COPY ONLY NAME CALL CPDIR ;COPY OF DIRECTORY & WRITE RENAS: ;TO NEXT CALL DRMAT ;SEARCH NEXT JMP RENAL ;TO NEXT DIRECTORY BLOCK ; ; SET ATTRIBUTE ; SFATR: MVI C,12 ;ONLY NAME CALL DRSRH ;SEARCH DIRECTORY SFATL: ;LOOP OF DIRECTORY BLOCK CALL DICHK ;CHECK DIRECTORY END RZ ;ALL OVER MVI C,0 MVI E,12 CALL CPDIR ;COPY TO DIRECTORY AND WRITE CALL DRMAT ;SEARCH NEXT JMP SFATL ;TO NEXT DIRECTORY BLOCK ; ; OPEN FILE ; OPEN: MVI C,15 ;SEARCH WITH EXTENT CALL DRSRH ;SEARCH DIRECTORY CALL DICHK ;CHECK EXISTENCE OF FILE RZ ;NOT EXIST CALL SETAC ;SET ACCESS MODE OPENS: CALL EXTPT ;GET FILE EXTENT POINT MOV A,M PUSH PSW PUSH H ;SAVE ENTRY FILE EXTENT CALL GDRPT ;GET DIRECTORY POINT XCHG LHLD INPAR ;GET FCB POINT MVI C,32 PUSH D CALL COPY ;COPY DIRECTORY TO FCB CALL MDOPN ;INITIALIZE R/W MODE POP D LXI H,12 DAD D MOV C,M ;GET FILE EXTENT LXI H,15 DAD D MOV B,M ;GET RECODE COUNT POP H POP PSW MOV M,A ;RESTORE FILE EXTENT MOV A,C CMP M MOV A,B JZ OPENE ;MATCH EXTENT, SO RECODE COUNT IS AVAILABLE MVI A,0 JC OPENE ;UNDER FILE EXTENT MVI A,80H ;OVER FILE EXTENT OPENE: LHLD INPAR LXI D,15 DAD D MOV M,A ;SET RECODE COUNT RET ; ; DIRECTORY CHECK OF DISK ALLOCATION MAP ; FOR LARGE STRAGE SIZE ; INPUT ; HL:DESTINATION ; DE:SOURCE ; DMCHK: MOV A,M INX H ORA M DCX H RNZ ;SOME DATA EXISTS LDAX D MOV M,A INX D INX H LDAX D MOV M,A ;COPY SOURCE DATA TO DESTINATION DCX D DCX H RET ; ; CLOSE A FILE ; CLOSE: LXI H,0 SHLD OTPAR ;CLEAR OUTPUT PARAMETER SHLD DIRCT ;CLEAR DIRECTORY COUNTER CALL HSCHK ;CHECK DISK R/O VECTOR RNZ ;ERROR OF R/O DISK CALL MDPNT ;GET MODE BYTE ANI 80H ;ONLY READ OPERATION, SO END RNZ MVI C,15 CALL DRSRH ;SEARCH DIRECTORY CALL DICHK ;CHECK EXISTENCE RZ ;NOT EXIST LXI B,16 CALL GDRPT ;GET DIRECTORY POINT DAD B XCHG LXI H,-5 DAD D ;GET T3 POINT MOV A,M ANI 7FH MOV M,A ;SET FILE UPDATE MODE LHLD INPAR DAD B MVI C,16 CLOSC: ;LOOP OF CHECK & MAKE DIRECTORY MAP LDA DSMMD ;GET STRAGE SIZE MODE ORA A JZ CLOSL ;DOUBLE BYTES DSM>255 MOV A,M ;SINGLE BYTE DSM<256 ORA A LDAX D JNZ $+4 ;SOME DATA EXISTS MOV M,A ;NO DATA ORA A JNZ $+5 ;SOME DATA EXISTS MOV A,M ;NEW BLOCK NUMBER STAX D CMP M JNZ CLOSR ;ERROR OF MISS MATCH JMP CLOSS ;TO NEW DIRECTORY MAP CLOSL: ;DOUBLE BYTE MODE CALL DMCHK XCHG CALL DMCHK ;DATA CHECK & COPY XCHG LDAX D CMP M JNZ CLOSR ;ERROR OF MISS MATCH INX D INX H LDAX D CMP M JNZ CLOSR ;ERROR OF MISS MATCH DCR C CLOSS: INX D INX H DCR C JNZ CLOSC ;TO NEXT DM LXI B,-20 ;ALL CHECKED DAD B XCHG DAD B LDAX D CMP M ;COMPARE FILE EXTENT JC CLOST MOV M,A LXI B,3 DAD B XCHG DAD B MOV A,M STAX D ;SET RECODE COUNT CLOST: ;SET TO DIRECTORY MVI A,-1 STA EXMOD ;SET ENTRY MODE CALL CPDIE ;DIRECTORY WRITE RET CLOSR: LXI H,OTPAR DCR M ;MISS MATCH ERROR RET ; ; GET AVAILABLE DIRECTORY ; GADIR: CALL HSERT ;CHECK DISK R/O LHLD INPAR PUSH H ;SAVE FCB POINT LXI H,DLCOD ;DELETE MARK SHLD INPAR MVI C,1 CALL DRSRH ;SEARCH DELETE DIRECTORY CALL DICHK ;CHECK DIRECTORY END POP H SHLD INPAR ;RESTORE FCB POINT RZ ;NO AVAILABLE XCHG LXI H,15 DAD D MVI C,17 XRA A MOV M,A ;CLEAR DM AREA INX H DCR C JNZ $-3 LXI H,13 DAD D MOV M,A ;CLEAR CURRENT RECODE COUNT CALL STHLV ;SET UP OF HASH CHECK LEVEL CALL COPYA ;WRITE NEW DIRECTORY CALL MDOPN ;TO INITIALIZE OF R/W MODE ; ; ACCESS CURRENT DRIVE ; SETAC: LXI H,1 LDA OUTSP MOV C,A CALL DSHFL ;GET DRIVE BIT JMP MACDV+3 ;TO ACCESS DRIVE ; ; ; ONE DIRECTORY OVER TO NEXT ; DOVER: XRA A STA EXMOD ;CLEAR CLOSE WRITE MODE CALL CLOSE ;LOSE NOW DIRECTORY CALL DICHK RZ ;CLOSE DIRECTORY NOT FOUND LHLD INPAR LXI B,12 DAD B ;GET FILE EXTENT MOV A,M INR A ANI 1FH MOV M,A JZ DOVEN ;UP OF EXTENTION MOV B,A LDA EXM ;EXTENT MASK ANA B LXI H,EXMOD ANA M JZ DOVES ;OVER TO NEXT JMP DOVEO ;OR THE SAME DIRECTORY DOVEN: LXI B,2 DAD B INR M ;UP OF EXTENTION MOV A,M ANI 0FH JZ DOVEL ;TOO LONG DOVES: MVI C,15 CALL DRSRH ;DIRECTORY SEARCH CALL DICHK JNZ DOVEO ;GET NEXT LDA DOVMD ;GET READ MODE INR A JZ DOVEL ;FILE END, AS NOW READ MODE CALL GADIR ;GET AVAILABLE DIRECTORY CALL DICHK JZ DOVEL ;NO AVAILABLE JMP DOVEO+3 DOVEO: CALL OPENS ;SET OPEN PARAMETER CALL GRCNT ;GET RECODE COUNTS XRA A STA OTPAR ;SUCCEED RET DOVEL: ;OVER OF FILE CALL STOTP ;SET OVER FLAG JMP MDOPN ; ; READ NEXT RECODE ; RNEXT: MVI A,1 STA URCNT ;UP COUNT OF RECODE COUNT RNEXR: ;RANDOM READ ENTRY MVI A,-1 STA DOVMD ;TO READ MODE CALL GRCNT ;GET RECODE COUNT LDA CRCNT ;CURRENT RECODE COUNT LXI H,RECNT CMP M JC RNEXS ;GET IN THE SAME DIRECTORY CPI 80H JNZ RNEXN ;OVER THE RECODE COUNT CALL DOVER ;TO NEXT DIRECTORY XRA A STA CRCNT ;CLERAR RECODE COUNT LDA OTPAR ORA A JNZ RNEXN ;NEXT DIRECTORY ERROR RNEXS: ;GET NEXT SECTOR CALL GBLOK ;GET TARGET BLOCK CALL CKBLK ;BLOCK EMPTY CHECK JZ RNEXN ;EMPTY CALL BLSCV ;BLOCK TO SECTOR CONVERSION CALL TSSET ;SET TRACK & SECTOR CALL FREAD ;READ ONE SECTOR CALL SRCNT ;SET COUNTS TO FCB RET RNEXN: ;SOME ERROR JMP STOTP ;SET ERROR FLAG ; ; WRITE NEXT RECODE ; WNEXT: MVI A,1 STA URCNT ;UP COUNT OF RECODE COUNT TO SEQUENTIAL WRITE WNEXR: ;RANDOM WRITE ENTRY MVI A,0 STA DOVMD ;MODE TO WRITE CALL HSERT ;CHECK WRITE PROTECT OF DISK LHLD INPAR CALL CHTEM ;CHECK WRITE PROTECT OF FILE CALL GRCNT ;GET RECODE COUNTS LDA CRCNT CPI 80H JC $+7 CALL STOTP ;FILE EXTENT ERROR RET CALL GBLOK ;GET TARGET BLOCK CALL CKBLK ;CHECK EMPTY MVI C,0 ;SET CURRENT BLOCK MODE JNZ WNEXS ;IN THE CURRENT BLOCK CALL GBSDM ;TO NEXT BLOCK STA DRBSW ;SAME DIRECTORY BIAS FOR WRITE LXI B,0 ORA A JZ WNEXF ;FIRST BLOCK MOV C,A DCX B CALL GBLNM ;GET LAST BLOCK NUMBER MOV B,H MOV C,L WNEXF: CALL GAVAI ;SEARCH AVAILABLE BLOCK MOV A,L ORA H JNZ WNEXG ;GET BLOCK MVI A,2 ;NO AVAILABLE STA OTPAR RET WNEXG: SHLD TSECT XCHG LHLD INPAR LXI B,16 DAD B ;DM TOP LDA DSMMD ;GET STRAGE SIZE MODE ORA A LDA DRBSW ;BIAS JZ WNEXD ;DOUBLE BYTES DSM>255 CALL DSADD ;SINGLE BYTE DSM<256 MOV M,E ;SAVE BLOCK NUMBER JMP WNEXS-2 WNEXD: ;DOUBLE BYTES MOV C,A MVI B,0 DAD B DAD B MOV M,E INX H MOV M,D ;SAVE BLOCK NUMBER MVI C,2 ;SET NEW BLOCK MODE WNEXS: LDA OTPAR ORA A RNZ ;SOME ERROR PUSH B CALL BLSCV ;TO SECTOR LDA URCNT ;GET COUNT UP MODE DCR A DCR A JNZ WNEXN ;NOT WRITE WITH ZERO POP B ;WRITE WITH ZERO FILL MODE PUSH B MOV A,C DCR A DCR A JNZ WNEXN ;NOT WRITE ZERO AS NOT NEW BLOCK PUSH H ;FILL ZERO TO THE BLOCK LHLD DIRBF ;GET BUFFER MOV D,A MOV M,A ;CLEAR DATA INX H INR D JP $-3 CALL STDMD ;SET DMA ADDRESS LHLD BTSEC ;BLOCK TOP SECTOR MVI C,2 ;SET NEW BLOCK MODE WNEXZ: ;FILL LOOP SHLD TSECT PUSH B CALL TSSET ;SET TRACK & SECTOR POP B CALL FWRIT ;WRITE DATA LHLD TSECT MVI C,0 ;SET CURRENT BLOCK MODE LDA BLM ;GET MASK CODE MOV B,A ANA L CMP B ;CHECK BLOCK END INX H JNZ WNEXZ ;FILL TO BLOCK END POP H SHLD TSECT ;RESTORE TARGET SECTOR CALL STDMA ;TO NORMAL DMA ADDRESS WNEXN: ;WRITE OF ONE SECTOR CALL TSSET ;SET TRACK & SECTOR POP B PUSH B CALL FWRIT ;WRITE ONE SECTOR POP B LDA CRCNT LXI H,RECNT CMP M JC $+7 MOV M,A ;UP OF COUNT INR M MVI C,2 ;SET NEW BLOCK MODE NOP NOP NOP NOP NOP PUSH PSW CALL MDPNT ;GET R/W MODE ANI 7FH MOV M,A ;SET TO WRITEN MODE POP PSW WNEXV: CPI 7FH JNZ WNEXE ;RECODE COUNT IN RANGE (0-127) LDA URCNT ORA A JZ WNEXE ;!!!!!!!!! ; UPSER TWO LINES MUST BE ; CPI 1 ; JNZ WNEXE ;!!!!!!!!! CALL SRCNT ;SET NOW RECODE COUNT CALL DOVER ;TO NEXT DIRECTORY LXI H,OTPAR MOV A,M ORA A JNZ WNEXE-2 ;SOME ERROR IN DIRECTORY EXTENTION DCR A STA CRCNT ;INITIALIZE OF CURRENT RECODE MVI M,0 WNEXE: JMP SRCNT ; ; DIRECTORY READ & COUNT FOR RANDOM FILE ACCESS ; INPUT ; C:-1 READ MODE ; OUTPUT ; ZF:ON SUCCESS ; RNDIR: XRA A STA URCNT ;NOT UP COUNT MODE RNDIS: PUSH B LHLD INPAR XCHG LXI H,33 DAD D ;GET COUNTER POINT MOV A,M ANI 7FH ;GET COUNT IN LAST DIRECTORY PUSH PSW MOV A,M RAL INX H MOV A,M RAL ANI 1FH MOV C,A ;SAVE FILE EXTENT COUNT MOV A,M RAR RAR RAR RAR ANI 0FH MOV B,A ;EXTENTION POP PSW INX H MOV L,M ;GET THIRD BYTE INR L DCR L MVI L,6 ;PASSED PHYSICAL END JNZ RNDIE ;THIRD BYTE MUST BE ZERO LXI H,32 DAD D MOV M,A ;SET NEXT RECODE COUNT LXI H,12 DAD D ;FILE EXTENT MOV A,C SUB M JNZ RNDIN ;NOT MATCH LXI H,14 DAD D ;EXTENTION MOV A,B SUB M ANI 7FH JZ RNDIM ;GET MATCH DIRECTORY RNDIN: ;NOT MATCH, SO SEARCH DIRECTORY PUSH B PUSH D CALL CLOSE POP D POP B MVI L,3 LDA OTPAR INR A JZ RNIDC ;CAN NOT CLOSE LXI H,12 DAD D MOV M,C ;SET TARGET FILE EXTENT LXI H,14 DAD D MOV M,B ;SET TARGET EXTENTION CALL OPEN LDA OTPAR INR A JNZ RNDIM ;GET MATCH DIRECTORY POP B PUSH B MVI L,4 INR C ;READ MODE IS C -1 JZ RNIDC ;UNWRITEN EXTENT CALL GADIR ;WRITE MODE, SO SEARCH AVAILABLE DIRECTORY MVI L,5 LDA OTPAR INR A JZ RNIDC ;DIRECTORY OVERFLOW RNDIM: ;GET MATCH DIRECTORY POP B XRA A STA OTPAR RET RNIDC: ;ERROR L IS ERROR CODE PUSH H CALL MDPNT MVI M,0C0H ;SET ERROR CODE POP H RNDIE: POP B MOV A,L STA OTPAR JMP MDOPN ; ; RANDOM READ ; RREAD: MVI C,-1 ;READ MODE CALL RNDIR CZ RNEXR ;READ WHEN NOT ERROR RET ; ; RANDOM WRITE ; RWRIT: MVI C,0 ;WRITE MODE CALL RNDIR CZ WNEXR ;WRITE WHEN NOT ERROR RET ; ; COMPUTE SIZE FROM FCB DATA ; INPUT ; HL:DIRECTORY TOP ; DE:BIAS ; OUTPUT ; ABC:COUNT ; DRSIZ: XCHG DAD D MOV C,M ;GET RECODE COUNT OR CURRENT RECODE COUNT MVI B,0 LXI H,12 DAD D MOV A,M ;GET EXTENT RRC ANI 80H ADD C MOV C,A ;GET LOWER 8 BITS MVI A,0 ADC B ;SAVE CARRY MOV B,A MOV A,M RRC ANI 0FH ADD B MOV B,A ;GET HIGHER 4 BITS LXI H,14 DAD D MOV A,M ;GET EXTENTION ADD A ADD A ADD A ADD A PUSH PSW ;SAVE CF ADD B ;GET HIGHER BYTE MOV B,A PUSH PSW POP H MOV A,L ;GET FLAG BYTE POP H ORA L ANI 1 ;GET OVER FLOW BIT RET ; ; COMPUTE FILE LENGTH BY DIRECTORY SEARCH ; CFSIZ: MVI C,12 CALL DRSRH ;GET DIRECTORY ONLY NAME LHLD INPAR LXI D,33 DAD D PUSH H MOV M,D INX H MOV M,D INX H MOV M,D ;CLEAR COUNTER CFSIC: CALL DICHK JZ CFSIE ;END CALL GDRPT ;GET DIRECTORY POINT LXI D,15 CALL DRSIZ ;GET SIZE BY RECODE COUNT POP H PUSH H MOV E,A MOV A,C SUB M INX H MOV A,B SBB M INX H MOV A,E SBB M ;COMPARE WITH NOW MAX COUNT JC CFSIS ;NOW IS SMALL, SO NOT MATCH MOV M,E DCX H MOV M,B DCX H MOV M,C ;SET LARGER NUMBER CFSIS: CALL DRMAT ;MATCHING OF DIRECTORY JMP CFSIC CFSIE: ;END POP H RET ; ; 36:SET RANDOM RECODE COUNT ; MSRRC: LHLD INPAR LXI D,32 ;CURRENT RECODE CALL DRSIZ ;GET COUNT BY CURRENT RECODE COUNT LXI H,33 DAD D MOV M,C INX H MOV M,B INX H MOV M,A ;SET COUNT OF NOW RET ; ; LOG-IN & SELECT DRIVE ; DVSET: LDA OUTSP ;NEW DRIVE LXI H,NDRIV ;CURRENT DRIVE MOV M,A ;CHANGE DRIVE ; ; DRIVE SELECT ; DVSEL: LHLD DLOGI ;GET DISK LOG-IN VETCOR LDA NDRIV ;GET CORRENT DRIVE MOV C,A CALL DSHFR ;SHIFT TO VECTOR BIT PUSH H XCHG CALL GDTBL ;GET DISK PARAMETERS POP H CZ EDRIV ;NO DISK SELECT ERROR MOV A,L RAR ;GET LOG-IN VECTOR RC ;ALREADY LOG-IN DISK LHLD DLOGI MOV C,L MOV B,H CALL SDFLG ;SET LOG-IN BIT SHLD DLOGI ;SAVE NEW VECTOR JMP INDMP ;INITIALIZE OF DISK ALLOCATION MAP ; ; CHECK ENTRY TYPE & SELECT ; ENTRY: MVI A,-1 STA FLMOD ;SET FILE MODE LHLD INPAR MOV A,M ANI 1FH DCR A STA OUTSP ;SAVE REQUIRED DISK CODE CPI 10H JC ENTRE ;CURRENT DRIVE LDA NDRIV STA OUTSP ENTRE: LDA NDRIV ;GET CURRENT DISK STA ENTDV ;SAVE DISK NUMBER MOV A,M STA ENTYP ;SAVE ENTRY TYPE ANI 0E0H MOV M,A ;OFF THE REQUEST CALL DVSET ;CHANGE DISK LDA MDUSR LHLD INPAR ORA M MOV M,A ;SET USER NUMBER RET ; ; FREE DRIVE & CHECK ; DVCHK: CALL MFRDV ;FREE DRIVE LHLD INPAR ;GET DRIVE CODE DVCHW: ;FOR WRITE PROTECT CHECK XCHG LHLD PDPNT LXI B,12 DAD B ;GET THREAD TOP POINTER DVCHL: ;ONE P.D. CHECK LOOP MOV C,M INX H MOV B,M ;GET P.D. MOV A,C ORA B RZ ;END OF P.D. ALL FREE OK LXI H,28 DAD B MOV A,M ;GET DRVACT ANA E INX H JNZ DVCHS MOV A,M ANA D JNZ DVCHT LXI H,18 DAD B ;GET THREAD POINT JMP DVCHL ; DVCHS: MVI L,-1 JMP DVCHT+2 ; DVCHT: MVI L,7 INR L ;SEARCH DRIVE NUMBER RAR JNC $-2 MVI A,'A' ADD L ;GET DRIVE NAME PUSH B PUSH PSW CALL GETPD LXI D,14 DAD D MOV D,M ;GET CONSOLE LXI B,CDVCK CALL BFPRN ;"DISK RESET DENIED DRIVE " POP PSW MOV C,A CALL CONOT ;PRINT DRIVE NAME MVI C,':' CALL CONOT LXI B,CDVCN CALL BFPRN ;" CONSOLE " POP H PUSH H LXI B,14 DAD B MOV A,M ;GET CONSOLE ADI '0' MOV C,A CALL CONOT LXI B,CDVCP CALL BFPRN ;" PROGRAM " POP H CALL CONIV ;PRINT PROGRAM NAME POP H LXI H,-1 SHLD OTPAR ;SET FAIL END FLAG RET ; ; CDVCK: DB CR,LF,'D',69H,73H,6BH DB ' ',72H,65H,73H,65H,74H DB ' ',64H,65H,6EH,69H,65H,64H DB ', D',72H,69H,76H,65H,' $' CDVCN: DB ' C',6FH,6EH,73H,6FH,6CH,65H,' $' CDVCP: DB ' P',72H,6FH,67H,72H,61H,6DH,' $' ; ; 12:GET VERSION NUMBER ; MVSNM: LXI H,0122H SHLD OTPAR ;NOW VERSION NUMBER IS MP/M 1.1 RET ; ; 13:RESET DISK SYSTEM ; MINBD: LXI H,-1 SHLD INPAR CALL DVCHK ;RESET ALL DRIVE & CHECK LXI H,0 SHLD DROVC ;CLEAR R/O VECTOR SHLD DLOGI ;CLEAR LOG-IN VECTOR XRA A STA NDRIV ;CURRENT DRIVE TO 0 CALL GETMS ;GET MEMORY SEGMENT LHLD PDPNT LXI B,145 DAD B ADD A ADD A MOV E,A MVI D,0 DAD D MOV H,M ;GET MEMORY SEGMENT TOP MVI L,80H JMP MSDMA+3;SET DMA ADDRESS ; ; 14:SELECT DISK ; MDVSL: LDA INPAR ANI 0FH PUSH PSW CALL DVSET ;SELECT DISK CALL GETPD ;GET P.D. POINT LXI B,22 DAD B ;GET DRIVE CODE POINT MOV A,M ANI 0FH ;GET USER CODE RRC RRC RRC RRC MOV B,A POP PSW ORA B ;GET NEW CODE RRC RRC RRC RRC MOV M,A ;SAVE NEW CODE RET ; ; 15:OPEN FILE ; MOPEN: CALL MDCLS ;CLEAR R/W MODE CALL ENTRY ;CHECK ENTRY MODE JMP OPEN ;OPEN OF FILE ; ; 16:CLOSE FILE ; MCLOS: CALL ENTRY JMP CLOSE ;CLOSE OF FILE ; ; 17:SEARCH FIRST ; IF ENTRY TYPE IS "?", ALL DIRECTORY ; MSERH: MVI A,-1 STA DIRMD ;DIRECTORY BUFFER MODE TO DMA BUFFER MVI C,0 ;LENGTH ZERO FOR ALL DIRECTORY LHLD INPAR MOV A,M CPI '?' JZ MSERS ;ALL DIRECTORY CALL EXTPT MOV A,M CPI '?' CNZ MDCLS ;TO WRITE MODE CALL ENTRY MVI C,15 ;COMPARE LENGTH FULL MSERS: JMP DRSRH ;SEARCH FILE ; ; 18:SEARCH FOR NEXT OCCURRENCE ; MSENX: MVI A,-1 STA DIRMD ;DIRECTORY MODE TO DMA BUFFER LHLD FCBPN ;GET IMPLICIT FCB POINTER SHLD INPAR ;SET TO PARAMETER CALL ENTRY ;CHECK ENTRY TYPE JMP DRMAT ;DIRECTORY MATCHING ; ; 19:DELETE FILE ; MDELE: CALL ENTRY CALL DEDMP ;DELETE JMP SDCNT ;GET DIRECTORY CODE ; ; 20:READ NEXT RECODE ; MRDNX: CALL ENTRY JMP RNEXT ;READ NEXT ; ; 21:WRITE NEXT RECODE ; MWTNX: CALL ENTRY JMP WNEXT ;WRITE NEXT ; ; 22:MAKE FILE ; MAKFL: CALL MDCLS ;CLEAR R/W MODE TO WRITE CALL ENTRY JMP GADIR ;GET AVAILABLE DIRECTORY ; ; 23:RENAME ; MRNAM: CALL ENTRY CALL RENAM ;RENAME JMP SDCNT ; ; 24:INTERROGATE LOG-IN VECTOR ; MLIVC: LHLD DLOGI ;GET LOG-IN VECTOR SHLD OTPAR RET ; ; 25:INTERROGATE DISK NUMBER ; MNDIV: LDA NDRIV ;CURRENT DISK STA OTPAR RET ; ; 26:SET DMA ADDRESS ; MSDMA: LHLD INPAR XCHG CALL GETPD ;GET P.D. POINT LXI B,20 DAD B MOV M,E INX H MOV M,D ;SET TO P.D. XCHG SHLD DMADD JMP STDMA ; ; 27:INTERROGATE ALLOCATION MAP POSITION ; MALOC: LHLD ALV SHLD OTPAR RET ; ; 28:WRITE PROTECT DISK ; MWTPR: LDA NDRIV ;GET CURRENT DISK MOV C,A LXI H,1 CALL DSHFL ;GET BIT CALL DVCHW ;CHECK P.D. JMP SHSER ;SET FLAG ; ; 29:GET R/O VECTOR ; MGWPR: LHLD DROVC SHLD OTPAR RET ; ; 30:SET FILE ATTRIBUTE ; MSFAT: CALL ENTRY CALL SFATR ;SET ATTRIBUTE JMP SDCNT ; ; 31:GET DISK PARAMETER ADDRESS ; MGDPR: LHLD DPB SHLD OTPAR RET ; ; 32:SET OR GET USER CODE ; MUSER: LDA OUTSP CPI -1 JNZ MUSES ;SET MODE LDA MDUSR ;GET MODE STA OTPAR RET MUSES: ;SET MODE ANI 0FH STA MDUSR CALL GETPD LXI B,22 DAD B LDA MDUSR MOV B,A MOV A,M ANI 0F0H ORA B ;GET NEW CODE MOV M,A ;SET NEW CODE TO P.D. RET ; ; 33:READ RANDOM ; MRDRN: CALL ENTRY JMP RREAD ; ; 34:WRITE RANDOM ; MWTRN: CALL ENTRY JMP RWRIT ; ; 35:COMPUTE FILE SIZE ; MCFSZ: CALL ENTRY JMP CFSIZ ; ; 37:RESET DISK ; MRSDV: CALL DVCHK ;FREE DRIVE & CHECK LHLD INPAR MOV A,L CMA MOV E,A MOV A,H CMA ;GET MASK LHLD DLOGI ;GET LOG-IN VETCOR ANA H MOV D,A MOV A,L ANA E MOV E,A ;OFF THE BIT OF LOG-IN LHLD DROVC ;GET R/O VECTOR XCHG SHLD DLOGI MOV A,L ANA E MOV L,A MOV A,H ANA D MOV H,A ;OFF THE BIT OF R/O VECTOR SHLD DROVC RET ; ; 38:ACCESS DRIVE ; MACDV: LHLD INPAR XCHG CALL GETPD LXI B,28 DAD B ;GET DRIVE POINT MOV A,M ORA E MOV M,A INX H MOV A,M ORA D MOV M,A ;SET DRVACT CODE RET ; ; 39:FREE DRIVE ; MFRDV: LHLD INPAR MOV A,H CMA MOV D,A MOV A,L CMA MOV E,A ;INVERT THE VECTOR CALL GETPD LXI B,28 DAD B ;GET DRVACT POINT MOV A,M ANA E MOV M,A INX H MOV A,M ANA D MOV M,A ;OFF THE ACTIVE BIT RET ; ; 40:WRITE RANDOM WITH ZERO FILL ; MWTRZ: CALL ENTRY MVI A,2 STA URCNT ;SET MODE MVI C,0 CALL RNDIS ;GET TERGET DIRECTORY JZ WNEXR ;WRITE IF NO ERROR RET ;SOME ERROR ; ; BDOS END PROCESS ; BDOSE: LDA FLMOD ;GET FILE MODE ORA A JZ BDOSF ;NOT FILE COMMAND LHLD INPAR MVI M,0 ;CLEAR USER CODE & DATA LDA ENTYP ;GET ENTRY TYPE ORA A JZ BDOSF ;SIMPLE ENTRY TYPE MOV M,A ;SET ENTRY TYPE LDA ENTDV ;GET ENTRY DISK STA OUTSP ;SET DISK CALL DVSET ;TO ENTRIED DISK BDOSF: LHLD INSTK SPHL ;RESTORE STACK POINTER LHLD OTPAR MOV A,L MOV B,H ;SET RETURN PARAMETER RET ; ; DLCOD: DB 0E5H ;DELETE CODE ; ; DISK OPERATION DATA AREA ; ; DISK VECTORS ; DROVC: DS 2 ;R/O VECTOR DLOGI: DS 2 ;LOG-IN VECTOR ; ; DISK PARAMETERS ; DMADD: DS 2 ;DMA ADDRESS POINTER ; PHLEV: DS 2 ;HASH CHECK LEVEL SCRATCHPAD POINTER PTRAK: DS 2 ;TRACK CALCULATE SCRATCHPAD POINTER PSECT: DS 2 ;SECTOR CALCULATE SCRATCHPAD POINTER ; ; EACH DISK PARAMETER COPY AREA ; DIRBF: DS 2 ;ADDRESS OF DIRECTORY READ BUFFER DPB: DS 2 ;ADDRESS OF DISK PARAMETER BLOCK CSV: DS 2 ;ADDRESS OF HASH CHECK TABLE AREA ALV: DS 2 ;ADDRESS OF ALLOCATION MAP AREA ; SPT: DS 2 ;SECTOR / TRACK THIS VALUE IS COPY OF D.P.B. BSH: DS 1 ;BLOCK SHIFT FACTOR BLM: DS 1 ;BLOCK MASK EXM: DS 1 ;EXTENT MASK DSM: DS 2 ;TOTAL STRAGE CAPACITY -1 DRM: DS 2 ;TOTAL NUMBER OF DIRECTORY ENTRY -1 AL0: DS 1 ;ALLOCATION MAP MASK FOR DIRECTORY AREA AL1: DS 1 CKS: DS 2 ;SIZE OF HASH CHECK TABLE OFF: DS 2 ;OFFSET OF THE DISK BEGINNING POINT FOR FILES ; XTL: DS 2 ;LOGICAL TO PHYSICAL SECTOR TRANSFER VECTOR ; ; OTHER DATA ; EXMOD: DS 1 ;CLOSE MODE -1 CLOSED DOVMD: DS 1 ;READ OR WRITE MODE OF FILE 0 WRITE DIRCC: DS 1 ;DIRECTORY CODE URCNT: DS 1 ;UP COUNT OF RECODE COUNT & FLAG OF WRITE WITH ZERO OUTSP: DS 1 ;SCRATCHPAD FOR INPUT OUTPUT DATA DRBSW: DS 1 ;DIRECTORY BIAS FOR WRITE ; DS 2 ;NOT USED ; DSMMD: DS 1 ;DISK SIZE MODE DSM < 256 = -1 FLMOD: DS 1 ;FILE MODE 0 NOT FILE COMMAND ENTDV: DS 1 ;LAST DISK SAVE AREA FOR ENTRY ENTYP: DS 1 ;ENTRY TYPE SAVE AREA RECNT: DS 1 ;RECODE COUNT EXTNT: DS 1 ;EXTENT OF RECODE COUNT CRCNT: DS 2 ;CURRENT RECODE COUNT TSECT: DS 2 ;TARGET SECTOR BTSEC: DS 2 ;TARGET BLOCK TOP SECTOR DIRMD: DS 1 ;DIRECTORY BUFFER MODE BIDIR: DS 1 ;BIAS IN SECTOR DIRSC: DS 2 ;SECTOR NUMBER IN DIRECTORY ; ; PROCESS DEPEND DATA BLOCK ; DIRCT: DS 2 ;DIREDTORY NUMBER DRSLN: DS 1 ;LENGTH FOR COMPARISION TO DIRECTORY FCBPN: DS 2 ;FCB POINTER ; ; ORG 13FAH ;$ AND 0FF00H OR 0FAH ; ; XDOS BDOS ENTRY ; JMP XBDOS ; ; DISPATCHER ENTRY ; JMP DISP ; ; ; LINKS TO EXTENDED I/O SYSTEM ; XIOS: BOOT: DS 3 ;COLD START BOOTING WBOOT: DS 3 ;WARM BOOTING CONSTB: DS 3 ;CONSOLE STATUS CONINB: DS 3 ;CONSOLE INPUT CONOTB: DS 3 ;CONSOLE OUTPUT LIST: DS 3 ;LIST OUTPUT PUNCH: DS 3 ;PUNCH OUTPUT READR: DS 3 ;READER INPUT HOME: DS 3 ;MOVE DISK TO TRACK ZERO SELDK: DS 3 ;SELECT DISK SETRK: DS 3 ;SET TRACK NUMBER SETSC: DS 3 ;SET SECTOR NUMBER SETDM: DS 3 ;SET DMA ADDRESS READ: DS 3 ;READ ONE SECTOR WRITE: DS 3 ;WRITE ONE SECTOR LISTS: DS 3 ;LIST STATUS SCTRN: DS 3 ;SECTOR TRANSLATION ; ; EXTENDED ROUTINES ; DS 18 ;NOT USED IN BDOS ; SYSIN: DS 3 ;INITIALIZE I/O SYSTEM ; ; END