;CPMLDR.ASM DISASSEMBLY OF CPMLDR.COM ;28 MAY 85 RHP ; THIS PROGRAM READS THE FILE 'CPM3.SYS' OFF OF THE DISK ; AND RELOCATES THE FILE TO THE OPERATING POSITION. ;BIOS JUMP TABLE ; 0B00 = BIOS$START EQU 0B00H ; 0B00 = ?BOOT EQU BIOS$START + 000H ;COLD BOOT 0B0C = ?CONOT EQU BIOS$START + 00CH ;CONSOLE OUT 0B18 = ?HOME EQU BIOS$START + 018H ;HOME TO TRACK 0 0B1B = ?SLDSK EQU BIOS$START + 01BH ;SELECT DISK 0B1E = ?STTRK EQU BIOS$START + 01EH ;SET TRACK 0B21 = ?STSEC EQU BIOS$START + 021H ;SET SECTOR 0B24 = ?STDMA EQU BIOS$START + 024H ;SET DMA ADDRESS 0B27 = ?READ EQU BIOS$START + 027H ;READ A SECTOR 0B30 = ?SCTRN EQU BIOS$START + 030H ;TRANSLATE A PHYSICAL SECTOR 0B4B = ?MOV EQU BIOS$START + 04BH ;MOVE BETWEEN BANKS ; ; BDOS CALL FUNCTIONS ; 0009 = PRINT$STRING EQU 009H ;DE=STRING ADDRESS 000D = DISK$RESET EQU 00DH ;NO PARAMETERS 000F = SRCH$FIRST EQU 00FH ;DE=FCB ADDR, A=DIR CODE 0014 = READ$SEQUENT EQU 014H ;DE=FCB ADDR, A=ERROR CODE 001A = SET$DMA$ADDR EQU 01AH ;DE=DMA ADDRESS ; 005C = FCB EQU 0005CH 0080 = TBUFF EQU 00080H ; 0100 ORG 00100H ; ; 0100 318102 LXI SP,STACK1 ;SET UP THE STACK 0103 CD000B CALL ?BOOT ;COLD BOOT ; 0106 0E0D MVI C,DISK$RESET ;RESET DISK 0108 CD8D02 CALL BDOS ; ; 010B 0E09 MVI C,PRINT$STRING ;PRINT STRING 010D 112502 LXI D,MSBANR ;SIGN ON BANNER 0110 CD8D02 CALL BDOS ; 0113 0E0F MVI C,SRCH$FIRST ;LOCATE FILE ON DISK 0115 11AB01 LXI D,FCBT 0118 CD8D02 CALL BDOS ; 011B FEFF CPI 0FFH ;CHECK FOR ERROR 011D 11CF01 LXI D,MSOPEN ;OPEN ERROR MESSAGE 0120 CAA201 JZ QUITS ;HALT ; 0123 118000 LXI D,TBUFF ;POINT TO TEMP BUFFER 0126 CD8F01 CALL DMASET ;IDENTIFY AS DMA ADDR 0129 CD9501 CALL READSECT 012C 218000 LXI H,TBUFF ;POINT TO TEMP BUFFER 012F 118102 LXI D,HEDR1 ;POINT TO NEW STORAGE 0132 0E06 MVI C,006H ;MOVE 6 BYTES ; 0134 7E MOVER: MOV A,M ;MOVE MEMORY BLOCK 0135 12 STAX D 0136 13 INX D 0137 23 INX H 0138 0D DCR C 0139 C23401 JNZ MOVER ; 013C CD9501 CALL READSECT ;PUT SECTOR INTO TEMP BUFFER 013F 0E09 MVI C,PRINT$STRING ;PRINT OUT THE CONTENTS OF 0141 118000 LXI D,TBUFF ;THE STRING JUST READ 0144 CD8D02 CALL BDOS ; 0147 3A8202 LDA HEDR2 ;GET 2ND GYTE OF HEADER 014A 67 MOV H,A ;PUT IN H 014B 3A8102 LDA HEDR1 ;GET FIRST BYTE OF HEADER 014E CD7301 CALL READFILE ; 0151 3A8402 LDA HEDR4 ;GET 4TH BYTE OF HEADER 0154 B7 ORA A ;SET FLAGS 0155 CA5F01 JZ SKIPRD ;SKIP IF EMPTY 0158 67 MOV H,A 0159 3A8302 LDA HEDR3 015C CD7301 CALL READFILE ; 015F 215D00 SKIPRD: LXI H,FCB+1 ;1ST CHAR OF FILENAME 0162 7E MOV A,M ;GET IT 0163 FE24 CPI 024H ;IS IT A $? 0165 C26F01 JNZ SKIP2 ;IF NOT THEN SKIP 0168 23 INX H ;2ND CHAR OF FILENAME 0169 7E MOV A,M ;GET IT 016A FE42 CPI 042H ;IS IT A 'B'? 016C CCA901 CZ REBOOT ;THEN GO TO REBOOT 016F 318502 SKIP2: LXI SP,HEDR5 ;ELSE JUMP TO ADDRESS OF 0172 C9 RET ; BYTES 5,6 OF HEADER READFILE: 0173 B7 ORA A ;SET FLAGS 0174 57 MOV D,A ;FIRST BYTE TO D 0175 1E00 MVI E,000H ;E=0 0177 7C MOV A,H ;SECOND BYTE TO A 0178 17 RAL ;X2 0179 67 MOV H,A ;BACK TO H READLOOP: 017A EB XCHG ;SWAP DE,HL 017B 0180FF LXI B,0FF80H ; -80 017E 09 DAD B ;SUBTRACT 80 FROM 2ND BYTE 017F EB XCHG ;SWAP AGAIN 0180 D5 PUSH D ;SAVE REGISTERS 0181 E5 PUSH H 0182 CD8F01 CALL DMASET ;POINT TO NEW ADDRESS 0185 CD9501 CALL READSECT ;READ DISK INTO THERE 0188 E1 POP H ;RESTORE REGISTERS 0189 D1 POP D 018A 25 DCR H ;H-1 018B C27A01 JNZ READLOOP ;LOOP TIL H=0 018E C9 RET 018F 0E1A DMASET: MVI C,SET$DMA$ADDR 0191 CD8D02 CALL BDOS 0194 C9 RET READSECT: 0195 0E14 MVI C,READ$SEQUENT 0197 11AB01 LXI D,FCBT ;POINT TO FILE CONTROL BLOCK 019A CD8D02 CALL BDOS ; 019D B7 ORA A ;SET FLAGS 019E 11FA01 LXI D,MSREAD ;READ ERROR MESSAGE 01A1 C8 RZ ;NO ERROR 01A2 0E09 QUITS: MVI C,PRINT$STRING ;ELSE PRINT ERROR MSG 01A4 CD8D02 CALL BDOS ; 01A7 F3 DI ;KILL INTERRUPTS 01A8 76 HLT ;FREEZE ; 01A9 FF REBOOT: RST 07 01AA C9 RET ; 01AB 00 FCBT: DB 000H 01AC 43504D3320 DB 'CPM3 SYS' 01B7 0000000000 DB 0,0,0,0,0,0,0,0 01BF 0000000000 DB 0,0,0,0,0,0,0,0 01C7 0000000000 DB 0,0,0,0,0,0,0,0 ; 01CF 0D0A MSOPEN: DB 00DH,00AH 01D1 43504D4C44 DB 'CPMLDR error: failed to open CPM3.SYS' 01F7 0D0A DB 00DH,00AH 01F9 24 DB '$' ; 01FA 0D0A MSREAD: DB 00DH,00AH 01FC 43504D4C44 DB 'CPMLDR error: failed to read CPM3.SYS' 0222 0D0A DB 00DH,00AH 0224 24 DB '$' ; 0225 0D MSBANR: DB 00DH 0226 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 022C 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 0232 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 0238 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 023E 43502F4D20 DB 'CP/M V3.0 Loader' 024E 0D0A DB 00DH,00AH 0250 436F707972 DB 'Copyright (C) 1982, Digital Research' 0274 0D0A DB 00DH,00AH 0276 24 DB '$' 0277 3032313138 DB '021182' 027D 00000000 DB 0,0,0,0 STACK1: ;STACK WALKS OVER THE BANNER ; 0281 00 HEDR1: DB 000H 0282 00 HEDR2: DB 000H 0283 00 HEDR3: DB 000H 0284 00 HEDR4: DB 000H 0285 0000000000HEDR5: DB 0,0,0,0,0,0,0,0 ; 028D EB BDOS: XCHG ;MSG POINTER IN HL 028E 22DF09 SHLD INFO ;STORE MSG LOCATION 0291 EB XCHG ;MSG POINTER BACK TO DE 0292 79 MOV A,C 0293 FE0E CPI 00EH 0295 DAA502 JC BDOS1 0298 32E209 STA SAVEC ;SAVE # IN C 029B AF XRA A ;CLEAR ACCUMULATOR 029C 32B709 STA ZERO3 ;SET TO FALSE 029F 32DE09 STA CURDSK 02A2 32BE09 STA ZERO4 02A5 7B BDOS1: MOV A,E ;GET LO BYTE OF MEM ADDRESS 02A6 32BA09 STA LINFO ;SAVE IT 02A9 210000 LXI H,00000H ;CLEAR HL 02AC 220904 SHLD ARET ;RETURN VALUE DEFAULTS TO 0000 02AF 22E109 SHLD FCBDSK ; SAVE USERS STACK PTR, SET TO LOCAL STACK 02B2 39 DAD SP ;MOVE SP TO HL 02B3 224003 SHLD ENTSP ;ENTSP=STACK POINTER 02B6 319203 LXI SP,LSTACK ;POINT STACK TO END OF C7 TABLE 02B9 214E09 LXI H,GOBACK ;RETURN HERE AFTER ALL FUNCTIONS 02BC E5 PUSH H ;JUMP GOBACK EQUIV TO RETURN 02BD 79 MOV A,C 02BE FE32 CPI 032H ;NUMBER OF FUNCTIONS 02C0 D2CA02 JNC BDOS2 ;INVALID NUMBER 02C3 4B MOV C,E ;POSSIBLE OUTPUT CHAR. TO C 02C4 21DC02 LXI H,FUNCTAB ;POINT TO FUNCTION TABLE 02C7 C3CF02 JMP BDOS3 ; 02CA DE64 BDOS2: SBI 064H 02CC DA9B07 JC SEARCH$FIN 02CF 5F BDOS3: MOV E,A ;E GETS A 02D0 1600 MVI D,000H ;DE=FUNCTION, HL=.CIOTAR 02D2 19 DAD D ;ADD DE, HL 02D3 19 DAD D ;ADD DE, HL 02D4 5E MOV E,M ;MEMORY WORD TO DE 02D5 23 INX H 02D6 56 MOV D,M ;DE=FUNCTION ARGUMENT 02D7 2ADF09 LHLD INFO ;POINT TO MESSAGE WITH HL 02DA EB XCHG ;DE POINTS MSG, HL TO DEST. 02DB E9 PCHL ;JUMP TO ROUTINE ; 02DC E803 FUNCTAB:DW FNC$RET ;FUNCTION 0= 02DE E803 DW FNC$RET ;FUNCTION 1= 02E0 BB03 DW FUNCT02 ;FUNCTION 2=CONSOLE OUTPUT 02E2 E803 DW FNC$RET ;FUNCTION 3= 02E4 E803 DW FNC$RET ;FUNCTION 4= 02E6 E803 DW FNC$RET ;FUNCTION 5= 02E8 E803 DW FNC$RET ;FUNCTION 6= 02EA E803 DW FNC$RET ;FUNCTION 7= 02EC E803 DW FNC$RET ;FUNCTION 8= 02EE DF03 DW FUNCT09 ;FUNCTION 9=PRINT STRING 02F0 E803 DW FNC$RET ;FUNCTION A= 02F2 E803 DW FNC$RET ;FUNCTION B= 02F4 E803 DW FNC$RET ;FUNCTION C= 02F6 0009 DW FUNCT0D ;FUNCTION D=RESET DISK 02F8 1709 DW FUNCT0E ;FUNCTION E=SELECT DISK 02FA 1D09 DW FUNCT0F ;FUNCTION F=OPEN FILE 02FC E803 DW FNC$RET ;FUNCTION 10= 02FE E803 DW FNC$RET ;FUNCTION 11= 0300 E803 DW FNC$RET ;FUNCTION 12= 0302 E803 DW FNC$RET ;FUNCTION 13= 0304 3B09 DW FUNCT14 ;FUNCTION 14=READ SEQUENTIAL 0306 E803 DW FNC$RET ;FUNCTION 15= 0308 E803 DW FNC$RET ;FUNCTION 16= 030A E803 DW FNC$RET ;FUNCTION 17= 030C E803 DW FNC$RET ;FUNCTION 18= 030E 4109 DW FUNCT19 ;FUNCTION 19=RETURN CURRENT DISK 0310 4709 DW FUNCT1A ;FUNCTION 1A=SET DMA ADDRESS 0312 E803 DW FNC$RET ;FUNCTION 1B= 0314 E803 DW FNC$RET ;FUNCTION 1D= 0316 E803 DW FNC$RET ;FUNCTION 1E= 0318 E803 DW FNC$RET ;FUNCTION 1F= 031A E803 DW FNC$RET ;FUNCTION 20= 031C E803 DW FNC$RET ;FUNCTION 21= 031E E803 DW FNC$RET ;FUNCTION 22= 0320 E803 DW FNC$RET ;FUNCTION 23= 0322 E803 DW FNC$RET ;FUNCTION 24= 0324 E803 DW FNC$RET ;FUNCTION 25= 0326 E803 DW FNC$RET ;FUNCTION 26= 0328 E803 DW FNC$RET ;FUNCTION 27= 032A E803 DW FNC$RET ;FUNCTION 28= 032C E803 DW FNC$RET ;FUNCTION 29= 032E E803 DW FNC$RET ;FUNCTION 2A= 0330 E803 DW FNC$RET ;FUNCTION 2B= 0332 E803 DW FNC$RET ;FUNCTION 2C= 0334 E803 DW FNC$RET ;FUNCTION 2D= 0336 E803 DW FNC$RET ;FUNCTION 2E= 0338 E803 DW FNC$RET ;FUNCTION 2F= 033A E803 DW FNC$RET ;FUNCTION 30= 033C E803 DW FNC$RET ;FUNCTION 31= 033E E803 DW FNC$RET ;FUNCTION 32= ; 0340 0000 ENTSP: DB 0,0 ; 0342 DS 80 LSTACK: ; ; COMPUTE CHARACTER POSITION/WRITE CONSOLE ; CHARACTER FROM C ; COMPCOL = TRUE IF COMPUTING COLUMN POSITION ; 0392 3AEE03 CONOUT: LDA COMPCOL 0395 B7 ORA A 0396 C29E03 JNZ COMPOUT ;WRT CHAR FROM C, THEN COMP COL. 0399 C5 PUSH B 039A CD0C0B CALL ?CONOT ;PRINT CHARACTER ON CONSOLE 039D C1 POP B 039E 79 COMPOUT:MOV A,C ;RECALL CHAR & COMPUTE COL POSIT 039F 21DA09 LXI H,COLUMN ;A=CHAR, HL=.COLUMN 03A2 FE7F CPI 07FH ;RUBOUT? 03A4 C8 RZ ;NO COL CHANGE IF NULLS 03A5 34 INR M ;NEXT COLUMN 03A6 FE20 CPI 020H ;SPACE? 03A8 D0 RNC ;RETURN IF GRAPHIC,ELSE RESET COL. 03A9 35 DCR M ;NEXT COLUMN 03AA 7E MOV A,M 03AB B7 ORA A 03AC C8 RZ ;RET IF ZERO, ELSE MAYBE BS OR EOL 03AD 79 MOV A,C ;CHAR IN A 03AE FE08 CPI 008H ;CTL H? 03B0 C2B503 JNZ NOTBACKSP ;ELSE BACKSPACE 03B3 35 DCR M ;NEXT COLUMN 03B4 C9 RET ; ; NOT A BACKSPACE CHARACTER, EOL? ; NOTBACKSP: 03B5 FE0A CPI 00AH ;LINEFEED? 03B7 C0 RNZ 03B8 3600 MVI M,000H ;END OF LINE, COL=0 03BA C9 RET ; ; CONSOLE OUTPUT E=ASCII CHARACTER ; 03BB 79 FUNCT02:MOV A,C 03BC FE09 CPI 009H ;TAB? 03BE C29203 JNZ CONOUT ;IF NO TAB, DIRECT TO CONOUT 03C1 0E20 TAB0: MVI C,020H ;ELSE CHANGE TO SPACE 03C3 CD9203 CALL CONOUT 03C6 3ADA09 LDA COLUMN 03C9 E607 ANI 007H ;COLUMN MOD 8 = 0 7 03CB C2C103 JNZ TAB0 ;BACK FOR ANOTHER IF NOT 03CE C9 RET ; ; PRINT MESSAGE UNTIL M(BC) = $ ; 03CF 21DB09 PRINT: LXI H,DOLLAR 03D2 0A LDAX B 03D3 BE CMP M ;$? 03D4 C8 RZ ;STOP ON $, ELSE MORE TO PRINT 03D5 03 INX B 03D6 C5 PUSH B 03D7 4F MOV C,A ;CHAR IN C 03D8 CDBB03 CALL FUNCT02 ;PRINT CHAR ON CONSOLE 03DB C1 POP B 03DC C3CF03 JMP PRINT ; ; PRINT STRING DE=STRING ADDRESS, ENDS IN $ ; 03DF EB FUNCT09:XCHG ;WAS LHLD INFO 03E0 4D MOV C,L 03E1 44 MOV B,H ;BC=STRING ADDRESS 03E2 C3CF03 JMP PRINT ;OUT TO CONSOLE ; ; STORE THE REGISTER TO ARET ; 03E5 320904 STA$RET:STA ARET ; ; JMP GOBACK (POP STACK FOR NON CPM FUNCTIONS) ; 03E8 C9 FNC$RET:RET ; 03E9 3E01 DISKEOF:MVI A,001H ;SET LRET=1 03EB C3E503 JMP STA$RET ; ; STORAGE LOCATIONS AND MESSAGES ; 03EE 00 COMPCOL:DB 000H 03EF 0D0A MSBDOS: DB 00DH,00AH 03F1 42444F5320 DB 'BDOS ERR: $' 03FC 53656C6563MSSLCT: DB 'Select$' 0403 5065726D2EMSPERM: DB 'Perm.$' 0409 0000 ARET: DW 0000H SEL$ERROR: 040B 01EF03 LXI B,MSBDOS ;BDOS ERROR MESSAGE 040E CDCF03 CALL PRINT 0411 01FC03 LXI B,MSSLCT ;SELECT MSG 0414 C32004 JMP QUIT2 ; 0417 01EF03 PERMSG: LXI B,MSBDOS ;BDOS ERROR MESSAGE 041A CDCF03 CALL PRINT 041D 010304 LXI B,MSPERM ;PERMANENT MSG 0420 CDCF03 QUIT2: CALL PRINT ; 0423 F3 DI ;KILL INTERRUPTS 0424 76 HLT ;FREEZE ; 0425 7B SUBDH: MOV A,E ;SUBTRACT HL = DE-HL 0426 95 SUB L 0427 5F MOV E,A 0428 7A MOV A,D 0429 9C SBB H 042A 57 MOV D,A 042B D0 RNC 042C 05 DCR B 042D C9 RET ; 042E 7B ADDEHL: MOV A,E ;ADD HL AND DE 042F 85 ADD L 0430 5F MOV E,A 0431 7A MOV A,D 0432 8C ADC H 0433 57 MOV D,A 0434 D0 RNC 0435 04 INR B 0436 C9 RET ; 0437 0C ATRAN0: INR C 0438 0D ATRAN1: DCR C 0439 C8 RZ 043A 29 DAD H 043B 8F ADC A 043C C33804 JMP ATRAN1 ; 043F 1A RECOK8: LDAX D ;A GETS MEMORY POINTED BY DE 0440 BE CMP M ;COMPARE TO MEMORY POINTED BY HL 0441 C0 RNZ ;QUIT IF DIFFERENT 0442 23 INX H ;NEXT HL 0443 13 INX D ;NEXT DE 0444 0D DCR C ;TIL COUNT IN C 0445 C8 RZ ; DROPS TO ZERO 0446 C33F04 JMP RECOK8 ;ELSE TRY AGAIN ; ; MOVE DATA OF LENGTH C FROM DE TO HL ; 0449 0C MOVE: INR C ;IN CASE IT IS ZERO 044A 0D MOVE0: DCR C ;FOR COUNT IN C 044B C8 RZ ;DONE? 044C 1A LDAX D ;MEMORY POINTED BY DE TO A 044D 77 MOV M,A ;MOVE TO MEMORAY POINTED BY HL 044E 13 INX D ;NEXT DE 044F 23 INX H ;NEXT HL 0450 C34A04 JMP MOVE0 ;KEEP LOOPING TIL C=0 ; ; SELECT DISK DRIVE AT CURDSK, FILL THE BASE ADDRESS ; CURTKA-ALLOCA, THEN FILL VALUES IN DISK PARAMETER BLOCK ; SELECTDISK: 0453 4A MOV C,D ;CURRENT DISK TO C ;LSB OF C=0 IF NOT YET LOGGED IN 0454 CD1B0B CALL ?SLDSK ;SELECT DISK, SETS HL 0457 7C MOV A,H 0458 B5 ORA L 0459 C8 RZ ;HL=0 FOR ERROR ELSE DISK HEADER 045A 5E MOV E,M 045B 23 INX H 045C 56 MOV D,M 045D 23 INX H ;DE=.TRAN 045E 23 INX H 045F 23 INX H ;.CDRMAX 0460 229009 SHLD CURTRKA 0463 23 INX H 0464 23 INX H ;HL=.CURREC 0465 229209 SHLD CURRECA 0468 23 INX H 0469 23 INX H 046A 23 INX H 046B 23 INX H 046C 23 INX H 046D 23 INX H 046E EB XCHG 046F 22B809 SHLD TRANV ;.TRAN VECTOR 0472 219809 LXI H,BUFFB ;DE=SOURCE, HL=DEST FOR MOVE 0475 0E0D MVI C,00DH ;ADDLIST 0477 CD4904 CALL MOVE ;ADDLIST FILLED 047A 2A9809 LHLD BUFFB ;NOW FILL DPB 047D EB XCHG ;DE IS SOURCE 047E 21A509 LXI H,SECTPT ;HL IS DEST. 0481 0E11 MVI C,011H ;DPBLIST 0483 CD4904 CALL MOVE ;DATA FILLED 0486 2AAA09 LHLD MAXALL ;LARGEST ALLOC NUMBER 0489 7C MOV A,H ;00 INDICATES <255 048A 21BD09 LXI H,SINGLE 048D 36FF MVI M,0FFH ;FF=TRUE, ASSUME A=00 048F B7 ORA A 0490 CA9504 JZ RETSELECT 0493 3600 MVI M,000H ;M=FALSE RETSELECT: ;HIGH ORDER OF MAXALL NOT 0 ; USE DOUBLE DM 0495 37 STC 0496 C9 RET ; ; MOVE TO TRACK 0 ; 0497 CD180B HOME: CALL ?HOME ;HOME THE DISK 049A AF XRA A ;ZERO THE ACCCUM 049B 2A9009 LHLD CURTRKA 049E 77 MOV M,A 049F 23 INX H 04A0 77 MOV M,A ;CURTRAK=0000 04A1 2A9209 LHLD CURRECA 04A4 77 MOV M,A 04A5 23 INX H 04A6 77 MOV M,A ;CURREC=0000 04A7 23 INX H 04A8 77 MOV M,A 04A9 C9 RET ; ; RDBUFF1: 04AA 21C309 LXI H,ARECORD 04AD 5E MOV E,M 04AE 23 INX H 04AF 56 MOV D,M 04B0 23 INX H 04B1 46 MOV B,M 04B2 C9 RET ; ; ; 04B3 CDAA04 RDBUFF: CALL RDBUFF1 04B6 CD270B CALL ?READ ;READ A SECTOR 04B9 B7 ORA A ;SET FLAGS 04BA C8 RZ ;OK 04BB 4F MOV C,A ;SAVE ERROR 04BC FE03 CPI 003H ;CHECK ERROR 04BE DA1704 JC PERMSG ;PERMANENT BDOS ERROR 04C1 0E01 MVI C,001H ;ELSE CHANGE ERROR FLAG 04C3 C31704 JMP PERMSG ;PERMANENT BDOS ERROR ; ; SEEK RECORD CONTAINING THE CURRENT DIRECTORY ENTRY ; 04C6 2AE309 SEEKDIR:LHLD DCNT ;DIRECTORY COUNTER TO COUNTER 04C9 0E02 MVI C,002H ;DSKSHF 04CB CD2606 CALL HLROTR ;VALUE TO HL 04CE 0600 MVI B,000H 04D0 EB XCHG 04D1 21C309 LXI H,ARECORD 04D4 73 MOV M,E ;STORE ARECORD 04D5 23 INX H 04D6 72 MOV M,D ;STORE DREC 04D7 23 INX H 04D8 70 MOV M,B 04D9 C9 RET ; ; SEEK THE TRACK GIVEN BY ARECORD (ACTUAL RECORD) ; 04DA 2A9009 SEEK: LHLD CURTRKA 04DD 4E MOV C,M 04DE 23 INX H 04DF 46 MOV B,M 04E0 C5 PUSH B 04E1 2A9209 LHLD CURRECA 04E4 5E MOV E,M 04E5 23 INX H 04E6 56 MOV D,M 04E7 23 INX H 04E8 46 MOV B,M 04E9 2AC309 LHLD ARECORD 04EC 3AC509 LDA SHIFTED 04EF 4F MOV C,A 04F0 7D SEEK0: MOV A,L ;LOOP WHILE ARECORD < CURREC 04F1 93 SUB E 04F2 7C MOV A,H 04F3 9A SBB D 04F4 79 MOV A,C 04F5 98 SBB B 04F6 E5 PUSH H 04F7 D20705 JNC SEEK1 ;SKIP IF ARECORD >= CURREC 04FA 2AA509 LHLD SECTPT ;CURREC = SECTPT 04FD CD2504 CALL SUBDH ;SUBTRACT HL FROM DE 0500 E1 POP H 0501 E3 XTHL 0502 2B DCX H ;CURTRK = CURTRK-1 0503 E3 XTHL 0504 C3F004 JMP SEEK0 ;FOR ANOTHER TRY ; 0507 2AA509 SEEK1: LHLD SECTPT ;LOOK WHILE ARECORD >= (T:CURREC+SECTP) 050A CD2E04 CALL ADDEHL ;ADD DE AND HL 050D E1 POP H 050E 7D MOV A,L 050F 93 SUB E 0510 7C MOV A,H 0511 9A SBB D 0512 79 MOV A,C 0513 98 SBB B 0514 DA1E05 JC SEEK2 ;SKIP IF T>ARECORD, CURREC=T, 0517 E3 XTHL ; CURTRK=CURTRK+1 0518 23 INX H 0519 E3 XTHL 051A E5 PUSH H 051B C30705 JMP SEEK1 ;FOR ANOTHER TRY ; 051E E3 SEEK2: XTHL 051F E5 PUSH H 0520 2AA509 LHLD SECTPT 0523 CD2504 CALL SUBDH ;SUBTRACT HL FROM DE 0526 E1 POP H ;ARRIVE HERE WITH UPDATED VALUES ; IN EACH REGISTER 0527 D5 PUSH D 0528 C5 PUSH B 0529 E5 PUSH H ;TO STACK FOR LATER ;STACK=BC=ARECORD, DE=CURREC, HL=CURTRK 052A EB XCHG 052B 2AB209 LHLD OFFSET 052E 19 DAD D ;HL=CURTRK+OFFSET 052F 44 MOV B,H 0530 4D MOV C,L 0531 22CE09 SHLD TRACK 0534 CD1E0B CALL ?STTRK ;TRACK SET UP. NOTE THAT BC-CURTRK ; IS DIFFERENCE TO MOVE IN BIOS 0537 D1 POP D ;RECALL CURTRK 0538 2A9009 LHLD CURTRKA 053B 73 MOV M,E 053C 23 INX H 053D 72 MOV M,D ;CURTRK UPDATED ; NOW COMPUTE SECTOR AS ARECORD-CURREC 053E C1 POP B 053F D1 POP D ;RECALL CURREC 0540 2A9209 LHLD CURRECA 0543 73 MOV M,E 0544 23 INX H 0545 72 MOV M,D 0546 23 INX H 0547 70 MOV M,B 0548 C1 POP B ;BC=ARECORD, DE=CURREC 0549 79 MOV A,C 054A 93 SUB E 054B 6F MOV L,A 054C 78 MOV A,B 054D 9A SBB D 054E 67 MOV H,A 054F CD6B05 CALL SEEK3 0552 44 MOV B,H 0553 4D MOV C,L 0554 2AB809 LHLD TRANV 0557 EB XCHG ;BC=SECTOR#, DE=.TRAN 0558 CD300B CALL ?SCTRN ;HL=TRAN (SECTOR) 055B 4D MOV C,L 055C 44 MOV B,H 055D 22D009 SHLD SAVSEC 0560 CD210B CALL ?STSEC ;SECTOR SELECTED 0563 2A8A09 LHLD DMAADDR 0566 4D MOV C,L 0567 44 MOV B,H 0568 C3240B JMP ?STDMA ;SET DMA ; 056B 3AB409 SEEK3: LDA ZERO1 056E 4F MOV C,A 056F C32606 JMP HLROTR ; ; COMPUTE DISK MAP POSITION FOR VRECORD TO HL ; DM$POSITION: 0572 21A709 LXI H,BLKSHF 0575 4E MOV C,M ;SHIFT COUNT TO C 0576 3AC109 LDA VRECORD ;CURRENT VIRTUAL RECORD TO A 0579 B7 DMPOS0: ORA A 057A 1F RAR 057B 0D DCR C 057C C27905 JNZ DMPOS0 ;A=SBR(VRECORD,BLKSHF)= ; VRECORD/2**(SEC/BLOCK) 057F 47 MOV B,A ;SAVE IT FOR LATER ADDITION 0580 3E08 MVI A,008H 0582 96 SUB M ;8-BLKSHF TO ACCUMULATOR 0583 4F MOV C,A ;EXTENT SHIFT COUNT IN REGISTER C 0584 3AC009 LDA EXTVAL ;EXTENT VALUE ANI EXTMASK ; ; BLKSHF=3,4,5,6,7, C=5,4,3,2,1 ; SHIFT IS 4,3,2,1,0 ; 0587 0D DMPOS1: DCR C 0588 CA9005 JZ DMPOS2 058B B7 ORA A 058C 17 RAL 058D C38705 JMP DMPOS1 ; ; ARRIVE HERE WITH A=SHL(EXT AND EXTMSK), 7-BLKSHF) ; 0590 80 DMPOS2: ADD B ;ADD THE PREVIOUS SHR(VRECORD,BLKSHF) ;VALUE. A IS ONE OF THE VALUES, ;DEPENDING ON ALLOC BKS BLKSHF ;1K 3 V/8+EXTVAL*16 ;2K 4 V/16+EXTVAL*8 ;4K 5 V/32+EXTVAL*4 ;8K 6 V/64+EXTVAL*2 ;16K 7 V/128+EXTVAL*1 0591 C9 RET ;WITH DM$POSITION IN A ; 0592 2ADF09 GETDM1: LHLD INFO ;BASE ADDRESS OF FCB 0595 111000 LXI D,00010H ;DSKMAP 0598 19 DAD D ;HL=.DSKMAP 0599 C9 RET ; ; GET DISK MAP VALUE FROM POSITION GIVEN BY BC ; 059A CD9205 GETDM: CALL GETDM1 ;POINT TO 16TH CHAR IN INFO 059D 09 DAD B ;INDEX BY SINGLE BYTE VALUE 059E 3ABD09 LDA SINGLE ;SINGLE BYTE/MAP ENTRY? 05A1 B7 ORA A 05A2 CAA805 JZ GETDMD ;GET DISK MAP SINGLE BYTE 05A5 6E MOV L,M 05A6 60 MOV H,B 05A7 C9 RET ;WITH HL=00BB ; 05A8 09 GETDMD: DAD B ;HL=.FCB(DM+I*2) ; DOUBLE PRECISION VALUE RETURNED 05A9 7E MOV A,M 05AA 23 INX H 05AB 66 MOV H,M 05AC 6F MOV L,A 05AD C9 RET ; ; COMPUTE DISK BLOCK NUMBER FROM CURRENT FCB ; 05AE CD7205 INDEX: CALL DM$POSITION ;0....15 IN REGISTER A 05B1 32BB09 STA DMPOS 05B4 4F MOV C,A 05B5 0600 MVI B,000H 05B7 CD9A05 CALL GETDM ;VALUE TO HL 05BA 22C309 SHLD ARECORD 05BD 7D MOV A,L 05BE B4 ORA H 05BF C9 RET ; ; COMPUTE ACTUAL RECORD ADDRESS, ASSUMING INDEX CALLED ; 05C0 3AA709 ATRAN: LDA BLKSHF ;SHIFT COUNT TO REG A 05C3 4F MOV C,A 05C4 2AC309 LHLD ARECORD 05C7 AF XRA A 05C8 CD3704 CALL ATRAN0 05CB 22C309 SHLD ARECORD 05CE 32C509 STA SHIFTED 05D1 22C609 SHLD SHAREC 05D4 3AA809 LDA BLKMSK 05D7 4F MOV C,A ;MASK VALUE TO C 05D8 3AC109 LDA VRECORD 05DB A1 ANA C ;MASKED VALUE IN A 05DC 47 MOV B,A 05DD 32B609 STA MSKVREC 05E0 21C309 LXI H,ARECORD ;ARECORD=HL OR (VRECORD AND BLKMSK) 05E3 B6 ORA M 05E4 77 MOV M,A 05E5 C9 RET ; ; GET CURRENT EXTENT FIELD ADDRESS TO A ; 05E6 2ADF09 GETEXTA:LHLD INFO 05E9 110C00 LXI D,0000CH ;EXTNUM 05EC 19 DAD D ;HL=.FCB(EXTNUM) 05ED C9 RET 05EE 2ADF09 GETFCBB: LHLD INFO 05F1 110F00 LXI D,0000FH 05F4 19 DAD D 05F5 C9 RET ; ; COMPUTE RECCNT AND NXTREC ADDRESSES FOR GET/SETFCB ; 05F6 CDEE05 GETFCBA:CALL GETFCBB 05F9 EB XCHG ;DE=.FCB(NXTREC) 05FA 211100 LXI H,00011H ;NXTREC-RECC 05FD 19 DAD D ;HL=.FCB(NXTREC) 05FE C9 RET ; ; SET VARIABLES FROM CURRENTLY ADDRESSED FCB ; 05FF CDF605 GETFCB: CALL GETFCBA ;ADDRESSES IN DE, HL 0602 7E MOV A,M 0603 32C109 STA VRECORD ;VRECORD=FCB(NXTREC) 0606 EB XCHG 0607 7E MOV A,M 0608 32BF09 STA RCOUNT ;RCOUNT=FCB(RECCNT) 060B CDE605 CALL GETEXTA ;HL=.FCB(EXTNUM) 060E 3AA909 LDA EXTMSK ;EXTENT MASK TO A 0611 A6 ANA M ;FCB(EXTNUM) AND EXTMASK 0612 32C009 STA EXTVAL 0615 C9 RET ; ; PLACE VALUES BACK IN CURRENT FCB ; 0616 CDF605 SETFCB: CALL GETFCBA ;ADDRESSES TO DE, HL 0619 0E01 MVI C,001H 061B 3AC109 LDA VRECORD 061E 81 ADD C 061F 77 MOV M,A ;FCB(NXTREC)=VRECORD+SEQIO 0620 EB XCHG 0621 3ABF09 LDA RCOUNT 0624 77 MOV M,A ;FCB(RECCNT)=RCOUNT 0625 C9 RET ; ; HL ROTATE RIGHT BY AMOUNT C ; 0626 0C HLROTR: INR C ;IN CASE 0 0627 0D HLROTR0:DCR C 0628 C8 RZ ;RETURN WHEN C=0 0629 7C MOV A,H 062A B7 ORA A 062B 1F RAR 062C 67 MOV H,A ;HIGH BYTE 062D 7D MOV A,L 062E 1F RAR 062F 6F MOV L,A ;LOW BYTE 0630 C32706 JMP HLROTR0 ; ; ROTATE THE MASK IN HL BY THE AMOUNT IN C ; 0633 0C HLROTL: INR C ;MAY BE ZERO 0634 0D HLROTL0:DCR C 0635 C8 RZ ;RETURN WHEN C=0 0636 29 DAD H 0637 C33406 JMP HLROTL0 ; ; SET A "1" VALUE IN CURDSK POSITION OF BC ; SET$DISK: 063A 3ADE09 LDA CURDSK 063D C5 PUSH B ;SAVE INPUT PARAMETER 063E 4F MOV C,A ;READY PARAMETER FOR SHIFT 063F 210100 LXI H,00001H 0642 CD3306 CALL HLROTL ;HL=MASK TO INTEGRATE 0645 C1 POP B ;ORIGINAL MASK 0646 79 MOV A,C 0647 B5 ORA L 0648 6F MOV L,A 0649 78 MOV A,B 064A B4 ORA H 064B 67 MOV H,A ;HL=MASK OR ROL(1,CURDSK) 064C C9 RET ; ; RETURN TRUE IF DIR CHECKSUM ; 064D 3ADE09 NOWRITE:LDA CURDSK 0650 4F MOV C,A 0651 CD2606 CALL HLROTR 0654 7D MOV A,L 0655 E601 ANI 001H 0657 C9 RET ;NOW 0 IF NOWRITE ; ; COMPUTE THE ADDRESS OF A DIRECTORY ELEMENT AT ; POSITION DPTR IN THE BUFFER ; GETDPTRA: 0658 2A8C09 LHLD BUFFA 065B 3AC909 LDA DPTR 065E 85 ADD L ;HL=HL+A 065F 6F MOV L,A 0660 D0 RNC ;OVERFLOW TO H 0661 24 INR H 0662 C9 RET ; 0663 CDE605 RSEL3: CALL GETEXTA 0666 7E MOV A,M 0667 E61F ANI 01FH 0669 77 MOV M,A 066A C9 RET ; 066B 7B READDIR1: MOV A,E 066C 95 SUB L 066D 6F MOV L,A 066E 7A MOV A,D 066F 9C SBB H 0670 67 MOV H,A 0671 C9 RET ; 0672 D5 RDDIR2: PUSH D 0673 110A00 LXI D,0000AH 0676 19 DAD D 0677 5E MOV E,M 0678 23 INX H 0679 56 MOV D,M 067A EB XCHG 067B D1 POP D 067C C9 RET ; 067D CDC604 READDIR3: CALL SEEKDIR 0680 3AB509 LDA ZERO2 0683 B7 ORA A 0684 CA8F06 JZ RD$DIR 0687 3E03 MVI A,003H 0689 CDE809 CALL READDIR4 068C C39B06 JMP SETDATA ; ; READ A DIRECTORY ENTRY INTO THE DIRECTORY BUFFER ; 068F CDA106 RD$DIR: CALL RDDIR1 0692 228C09 SHLD BUFFA 0695 CDDA04 CALL SEEK 0698 CDB304 CALL RDBUFF ;DIRECTORY ENTRY LOADED ; ; SET DATA DMA ADDRESS ; 069B 2ADC09 SETDATA:LHLD DMAAD 069E C3A706 JMP SETDMA ; 06A1 2A9E09 RDDIR1: LHLD ALLOCA 06A4 CD7206 CALL RDDIR2 ; ; HL=ADDRESS TO SET (I.E., BUFFA OR DMAAD) ; 06A7 228A09 SETDMA: SHLD DMAADDR 06AA C9 RET ; ; RETURN ZERO FLAG IF AT END OF DIRECTORY, NON ZERO ; IF NOT AT END (END OF DIR IF DCNT=0FFFFH) ; 06AB 21E309 END$OF$DIR: LXI H,DCNT 06AE 7E MOV A,M ;MAY BE 0FFH 06AF 23 INX H 06B0 BE CMP M ;LOW(DCNT)=HIGH(DCNT)? 06B1 C0 RNZ ;NOW ZERO RETURNED IF DIFFERENT ;HIGH AND LOW THE SAME,=0FFH? 06B2 3C INR A ;0FFH BECOMES 00 IF SO 06B3 C9 RET ; ; SET DCNT TO THE END OF THE DIRECTORY ; SET$END$DIR: 06B4 21FFFF LXI H,0FFFFH ;(ENDDIR) 06B7 22E309 SHLD DCNT 06BA C9 RET ; READ$DIR: 06BB 2AAC09 LHLD DIRMAX 06BE EB XCHG 06BF 2AE309 LHLD DCNT 06C2 23 INX H 06C3 22E309 SHLD DCNT 06C6 CD6B06 CALL READDIR1 06C9 DAB406 JC SET$END$DIR 06CC 3AE309 LDA DCNT 06CF E603 ANI 003H 06D1 0605 MVI B,005H READDIR2: 06D3 87 ADD A 06D4 05 DCR B 06D5 C2D306 JNZ READDIR2 06D8 32C909 STA DPTR 06DB B7 ORA A 06DC C0 RNZ 06DD C5 PUSH B 06DE CD7D06 CALL READDIR3 06E1 C1 POP B 06E2 C9 RET ; ; COMPARE EXTENT# IN A TO THAT IN C, RETURN NONZERO ; IF NO MATCH ; COMPEXT: 06E3 C5 PUSH B ;SAVE C'S ORIGINAL VALUE 06E4 F5 PUSH PSW 06E5 3AA909 LDA EXTMSK 06E8 2F CMA 06E9 47 MOV B,A ;B HAS NEGATED FORM OF EXTENT MASK 06EA 79 MOV A,C 06EB A0 ANA B 06EC 4F MOV C,A ;LOW BITS REMOVED FROM C 06ED F1 POP PSW 06EE A0 ANA B ;LOW BITS REMOVED FROM A 06EF 91 SUB C 06F0 E61F ANI 01FH ;(MAXEXT) SET FLAGS 06F2 C1 POP B ;RESTORE ORIGINAL VALUES 06F3 C9 RET ; 06F4 CDF605 OPENER: CALL GETFCBA 06F7 0E10 MVI C,010H 06F9 41 MOV B,C 06FA 0C INR C 06FB C5 PUSH B OPENER1: 06FC C1 POP B 06FD 0D DCR C 06FE AF XRA A OPENER2: 06FF 2B DCX H 0700 05 DCR B 0701 BE CMP M 0702 C20907 JNZ OPENER3 0705 0D DCR C 0706 C2FF06 JNZ OPENER2 OPENER3: 0709 79 MOV A,C 070A 32BB09 STA DMPOS 070D 3ABD09 LDA SINGLE 0710 B7 ORA A 0711 78 MOV A,B 0712 C21607 JNZ OPENER4 0715 1F RAR OPENER4: 0716 C5 PUSH B 0717 E5 PUSH H 0718 6F MOV L,A 0719 2600 MVI H,000H 071B 3AA709 LDA BLKSHF 071E 57 MOV D,A 071F 3E07 MVI A,007H 0721 92 SUB D 0722 4F MOV C,A 0723 CD2606 CALL HLROTR 0726 45 MOV B,L 0727 3AA909 LDA EXTMSK 072A B8 CMP B 072B E1 POP H 072C DAFC06 JC OPENER1 072F CDE605 CALL GETEXTA 0732 4E MOV C,M 0733 2F CMA 0734 E61F ANI 01FH 0736 A1 ANA C 0737 B0 ORA B 0738 C1 POP B 0739 C9 RET ; ; SEARCH FOR DIRECTORY ELEMENT OF LENGTH C AT INFO ; 073A 2ADF09 SEARCH: LHLD INFO 073D 22E509 SHLD SEARCHA ;SEARCHA=INFO 0740 79 MOV A,C 0741 32E709 STA SEARCHL 0744 CDB406 CALL SET$END$DIR ;DCNT=ENDIR 0747 CD9704 CALL HOME ;TO START AT THE BEGINNING ;(DROP THROUGH TO SEARCHN) ; SEARCHN: ;SEARCH FOR THE NEXT DIRECTORY ;ELEMENT, ASSUMING A PREVIOUS ;CALL ON SEARCH WHICH SETS ;SEARCHA AND SEARCHL 074A 0E00 MVI C,000H ;(FALSE) 074C CDBB06 CALL READ$DIR ;READ NEXT DIRECTORY ELEMENT 074F CDAB06 CALL END$OF$DIR 0752 CA9B07 JZ SEARCH$FIN ;SKIP TO END IF SO ;NOT END OF DIRECTORY, SCAN FOR MATCH 0755 2AE509 LHLD SEARCHA 0758 EB XCHG 0759 CD5806 CALL GETDPTRA ;HL=BUFFA+DPTR 075C 3AE709 LDA SEARCHL 075F 4F MOV C,A ;LENGTH OF SEARCH TO C 0760 0600 MVI B,000H ;B COUNTS UP, C COUNTS DOWN 0762 7E MOV A,M 0763 FEE5 CPI 0E5H ;(EMPTY) 0765 CA4A07 JZ SEARCHN SEARCHLOOP: 0768 79 MOV A,C 0769 B7 ORA A 076A CA9407 JZ ENDSEARCH 076D 78 MOV A,B 076E FE0D CPI 00DH ;(UBYTES) 0770 CA8D07 JZ SEARCHOK ; ;NOT THE UBYTES FIELD, EXTENT FIELD? 0773 FE0C CPI 00CH ;(EXTNUM) MAY BE EXTENT FIELD 0775 CA8207 JZ SEARCHEXT ;SKIP TO SEARCH EXTENT 0778 1A LDAX D ;FCB CHARACTER 0779 96 SUB M 077A E67F ANI 07FH ;MASK-OUT FLAGS/EXTENT MODULE 077C C24A07 JNZ SEARCHN ;SKIP IF NOT MATCHED 077F C38D07 JMP SEARCHOK ;MATCHED CHARACTER SEARCHEXT: ;A HAS FCB CHARACTER ;ATTEMPT AN EXTENT # MATCH 0782 1A LDAX D 0783 C5 PUSH B ;SAVE COUNTERS 0784 4E MOV C,M ;DIRECTORY CHARACTER TO C 0785 CDE306 CALL COMPEXT ;COMPARE USER/DIR CHAR 0788 C1 POP B ;RECALL COUNTERS 0789 B7 ORA A 078A C24A07 JNZ SEARCHN ;SKIP IF NO MATCH ; SEARCHOK: ;CURRENT CHARACTER MATCHES 078D 13 INX D 078E 23 INX H 078F 04 INR B 0790 0D DCR C 0791 C36807 JMP SEARCHLOOP ; ENDSEARCH: 0794 AF XRA A 0795 320904 STA ARET 0798 47 MOV B,A 0799 04 INR B 079A C9 RET ; ; END OF DIRECTORY OR EMPTY NAME ; SEARCH$FIN: 079B 3EFF MVI A,0FFH 079D 47 MOV B,A 079E 04 INR B 079F C3E503 JMP STA$RET ; ; SEARCH FOR THE DIRECTORY ENTRY, COPY TO FCB ; 07A2 0E0F OPEN: MVI C,00FH ;NAMLEN 07A4 CD3A07 CALL SEARCH 07A7 C8 RZ ;RETURN WITH ARET=255 IF END ;NOT END OF DIRECTORY. COPY FCB ;INFORMATION (REFERENCED BELOW ;TO COPY FCB INFO) OPEN$COPY: 07A8 CDE605 CALL GETEXTA 07AB 7E MOV A,M 07AC F5 PUSH PSW 07AD CD5806 CALL GETDPTRA 07B0 EB XCHG ;DE=.BUFF(DPTR) 07B1 2ADF09 LHLD INFO ;HL=.FCB(0) 07B4 0E20 MVI C,020H ;(NXTREC) LENGTH OF MOVE OPERATION 07B6 CD4904 CALL MOVE ;FROM .BUFF(DPTR) TO .FCB(0) ;NOTE THAT ENTIRE FCB IS COPIED, ; INCLUDING INDICATORS 07B9 CDF406 CALL OPENER 07BC 4F MOV C,A 07BD F1 POP PSW 07BE 77 MOV M,A OPEN$COPY1: 07BF 0600 MVI B,000H 07C1 EB XCHG 07C2 210300 LXI H,00003H 07C5 19 DAD D 07C6 1A LDAX D 07C7 91 SUB C 07C8 CAD807 JZ OPEN$COPY2 07CB 78 MOV A,B 07CC D2D207 JNC OPEN$RCNT ;USER IS LARGER 07CF 3E80 MVI A,080H ;DIRECTORY IS LARGER 07D1 46 MOV B,M OPEN$RCNT: ;A HAS RECORD COUNT TO FILL 07D2 77 MOV M,A 07D3 78 MOV A,B 07D4 32BC09 STA RECCNT 07D7 C9 RET OPEN$COPY2: 07D8 32BC09 STA RECCNT 07DB 7E MOV A,M 07DC B7 ORA A 07DD C0 RNZ 07DE 3ABB09 LDA DMPOS 07E1 B7 ORA A 07E2 C8 RZ 07E3 3AE209 LDA SAVEC 07E6 FE0F CPI 00FH 07E8 C8 RZ 07E9 3680 MVI M,080H 07EB C9 RET ; OPEN$REEL3: 07EC E5 PUSH H 07ED 3ABC09 LDA RECCNT 07F0 B7 ORA A 07F1 CAFD07 JZ OPEN$REEL4 07F4 110300 LXI D,00003H 07F7 19 DAD D 07F8 77 MOV M,A 07F9 AF XRA A 07FA 32BC09 STA RECCNT OPEN$REEL4: 07FD E1 POP H 07FE C9 RET ; ; CLOSE THE CURRENT EXTENT, AND OPEN THE NEXT ONE ; IF POSSIBLE. RMF IS TRUE IF IN READ MODE ; OPEN$REEL: 07FF CDE605 CALL GETEXTA 0802 7E MOV A,M 0803 4F MOV C,A 0804 0C INR C 0805 CDE306 CALL COMPEXT 0808 CA2108 JZ OPEN$REEL1 080B 3E1F MVI A,01FH 080D A1 ANA C 080E 77 MOV M,A 080F 0E0F MVI C,00FH 0811 CD3A07 CALL SEARCH 0814 CDA807 CALL OPEN$COPY OPEN$REEL0: 0817 CDFF05 CALL GETFCB 081A AF XRA A 081B 32C109 STA VRECORD 081E C3E503 JMP STA$RET OPEN$REEL1: 0821 34 INR M 0822 CDF406 CALL OPENER 0825 4F MOV C,A 0826 BE CMP M 0827 D22E08 JNC OPEN$REEL2 082A 35 DCR M 082B C3E903 JMP DISKEOF ; OPEN$REEL2: 082E CDEC07 CALL OPEN$REEL3 0831 CDBF07 CALL OPEN$COPY1 0834 C31708 JMP OPEN$REEL0 ; ; SEQUENTIAL DISK READ OPERATION ; SEQDISKREAD: 0837 CDFF05 CALL GETFCB ;SETS PARAMETERS FOR THE READ 083A 3AC109 LDA VRECORD 083D 21BF09 LXI H,RCOUNT 0840 BE CMP M ;VRECORD-RCOUNT,SKIP IF RCOUNT>VRECORD 0841 DA5308 JC RECORDOK ;NOT ENOUGH RECORDS IN THE EXTENT, ; RECORD COUNT MUST BE 128 TO CONTINUE 0844 FE80 CPI 080H ;VRECORD=128 0846 C2E903 JNZ DISKEOF ;SKIP IF VRECORD<>128 0849 CDFF07 CALL OPEN$REEL ;GO TO NEXT EXTENT IF SO 084C 3A0904 LDA ARET 084F B7 ORA A 0850 C2E903 JNZ DISKEOF ;STOP AT EOF ; ; ARRIVE WITH FCB ADDRESSING A RECORD TO READ ; RECORDOK: 0853 CDAE05 CALL INDEX ;ERROR 2 IF READING UNWRITTEN DATA ; (RETURNS 1 TO BE COMPATABLE WITH 1.4) 0856 CAE903 JZ DISKEOF ;RECORD HAS BEEN ALLOCATED, READ IT 0859 CDC005 CALL ATRAN ;ARECORD NOW A DISK ADDRESS 085C 3AB509 LDA ZERO2 085F B7 ORA A 0860 C2D209 JNZ RECORDOK1 0863 CD9B06 CALL SETDATA 0866 CDDA04 CALL SEEK ;TO PROPER TRACK, SECTOR 0869 CDB304 CALL RDBUFF ;TO DMA ADDRESS 086C C31606 JMP SETFCB ;REPLACE PARAMETER 086F 3ADE09 SELECT: LDA CURDSK 0872 3C INR A 0873 CA0B04 JZ SEL$ERROR 0876 3D DCR A 0877 21C209 LXI H,SELSTR 087A BE CMP M 087B C8 RZ ;SKIP IN LINFO=CURDSK 087C 77 MOV M,A 087D 57 MOV D,A 087E 2A8809 LHLD DLOG 0881 CD4D06 CALL NOWRITE 0884 5F MOV E,A 0885 D5 PUSH D 0886 CD5304 CALL SELECTDISK 0889 E1 POP H ;RECALL DLOG VECTOR 088A D20B04 JNC SEL$ERROR 088D 2D DCR L 088E C8 RZ 088F 2A8809 LHLD DLOG 0892 4D MOV C,L 0893 44 MOV B,H ;CALL READY 0894 CD3A06 CALL SET$DISK 0897 228809 SHLD DLOG 089A C9 RET ; CURSELECT: 089B 3ABA09 LDA LINFO 089E 32DE09 STA CURDSK 08A1 C9 RET ; CLRMODNUM: 08A2 AF XRA A 08A3 32C809 STA MODNUM 08A6 C3D208 JMP RSEL1 ; ; CHECK CURRENT FCB TO SEE IF RESELECTION NECESSARY ; RESELECT: 08A9 3E80 MVI A,080H 08AB 47 MOV B,A 08AC 3D DCR A 08AD 4F MOV C,A 08AE 2ADF09 LHLD INFO 08B1 110700 LXI D,00007H 08B4 EB XCHG 08B5 19 DAD D 08B6 7E MOV A,M 08B7 A0 ANA B 08B8 7E MOV A,M 08B9 A1 ANA C 08BA 77 MOV M,A 08BB 23 INX H 08BC 7E MOV A,M 08BD A0 ANA B 08BE 32C809 STA MODNUM 08C1 7E MOV A,M 08C2 A1 ANA C 08C3 77 MOV M,A 08C4 CD6306 CALL RSEL3 08C7 CDEE05 CALL GETFCBB 08CA 7E MOV A,M 08CB A0 ANA B 08CC CAD208 JZ RSEL1 08CF 7E MOV A,M 08D0 A1 ANA C 08D1 70 MOV M,B 08D2 32BC09 RSEL1: STA RECCNT 08D5 210000 LXI H,00000H 08D8 22CA09 SHLD OLDDSK 08DB 3EFF MVI A,0FFH 08DD 32E109 STA FCBDSK 08E0 2ADF09 LHLD INFO 08E3 7E MOV A,M 08E4 E61F ANI 01FH 08E6 3D DCR A 08E7 32BA09 STA LINFO 08EA FEFF CPI 0FFH 08EC CAF608 JZ RSEL2 08EF 7E MOV A,M 08F0 32CA09 STA OLDDSK 08F3 CD9B08 CALL CURSELECT 08F6 CD6F08 RSEL2: CALL SELECT 08F9 3E00 MVI A,000H 08FB 2ADF09 LHLD INFO 08FE 77 MOV M,A 08FF C9 RET ; ; RESET DISK SYSTEM TO DISK 0 SEVERAL PARAMETERS RETURNED ; 0900 210000 FUNCT0D:LXI H,00000H 0903 228809 SHLD DLOG 0906 AF XRA A 0907 32DE09 STA CURDSK ;NOTE THAT USER CODE IS UNCHANGED 090A 3D DCR A 090B 32C209 STA SELSTR 090E 218000 LXI H,TBUFF 0911 22DC09 SHLD DMAAD ;DMAAD=TBUFF 0914 C39B06 JMP SETDATA ;TO DATA DMA ADDR ; ; SELECT DISK E=DISK NUMBER ; 0917 CD9B08 FUNCT0E:CALL CURSELECT 091A C36F08 JMP SELECT ; ; OPEN FILE DE=FCB ADDRESS A=DIRECTORY CODE ; 091D CDA208 FUNCT0F:CALL CLRMODNUM ;(CLRMODNUM) 0920 CDA207 CALL OPEN 0923 CD2709 CALL OPENX 0926 C9 RET ; 0927 CDAB06 OPENX: CALL END$OF$DIR 092A C8 RZ 092B CDF605 CALL GETFCBA 092E 7E MOV A,M 092F 3C INR A 0930 C23709 JNZ OPENX1 0933 1B DCX D 0934 1B DCX D 0935 1A LDAX D 0936 77 MOV M,A 0937 E1 OPENX1: POP H 0938 0E40 MVI C,040H 093A C9 RET ; ; READ SEQUENTIAL DE=FCB A=ERROR CODE ; 093B CDA908 FUNCT14:CALL RESELECT 093E C33708 JMP SEQDISKREAD ; ; RETURN CURRENT DISK HL=CURRENT DISK NUMBER ; 0941 3ADE09 FUNCT19:LDA CURDSK 0944 C3E503 JMP STA$RET ; ; SET DMA ADDRESS DE=DMA ADDRESS ; SET SUBSEQUENT DMA ADDRESS TO INFO ; 0947 EB FUNCT1A:XCHG ;WAS LHLD INFO 0948 22DC09 SHLD DMAAD ;DMAAD=INFO 094B C39B06 JMP SETDATA ;TO DATA DMA ADDRESS ; ; ARRIVE HERE AT END OF PROCESSING TO RETURN TO USER ; 094E 3AE209 GOBACK: LDA SAVEC 0951 FE0F CPI 00FH 0953 DA7E09 JC RETMON ;RESELECTION MAY HAVE TAKEN PLACE 0956 3ABE09 LDA ZERO4 0959 32DE09 STA CURDSK 095C 3AE109 LDA FCBDSK 095F B7 ORA A 0960 CA7E09 JZ RETMON ;RESTORE DISK NUMBER 0963 2ADF09 LHLD INFO 0966 3600 MVI M,000H ;FCB(0)=0 0968 3ACA09 LDA OLDDSK 096B B7 ORA A 096C CA7009 JZ GOBACK1 096F 77 MOV M,A ;FCB(0)=FCBDSK 0970 23 GOBACK1:INX H 0971 3AC809 LDA MODNUM 0974 B6 ORA M 0975 77 MOV M,A 0976 CDEE05 CALL GETFCBB 0979 3ABC09 LDA RECCNT 097C B6 ORA M 097D 77 MOV M,A ; ; RETURN FROM THE DISK MONITOR ; 097E 2A4003 RETMON: LHLD ENTSP ;GET OLD STACK POINTER 0981 F9 SPHL ;RESTORE THE STACK 0982 2A0904 LHLD ARET 0985 7D MOV A,L 0986 44 MOV B,H ;BA=HL=ARET 0987 C9 RET 0988 0000 DLOG: DW 0000H 098A 0000 DMAADDR:DW 0000H 098C 0000 BUFFA: DW 0000H 098E 0000 DW 0000H 0990 0000 CURTRKA:DW 0000H 0992 0000 CURRECA:DW 0000H 0994 0000 DW 0000H 0996 0000 DW 0000H 0998 0000 BUFFB: DW 0000H 099A 0000 DW 0000H 099C 0000 DW 0000H 099E 0000 ALLOCA: DW 0000H 09A0 0000000000ZERO5: DB 0,0,0,0,0 09A5 0000 SECTPT: DW 0000H 09A7 00 BLKSHF: DB 000H 09A8 00 BLKMSK: DB 000H 09A9 00 EXTMSK: DB 000H 09AA 0000 MAXALL: DW 0000H 09AC 0000 DIRMAX: DW 0000H 09AE 0000 DW 0000H 09B0 0000 DW 0000H 09B2 0000 OFFSET: DW 0000H 09B4 00 ZERO1: DB 000H 09B5 00 ZERO2: DB 000H 09B6 00 MSKVREC:DB 000H 09B7 00 ZERO3: DB 000H 09B8 0000 TRANV: DW 0000H 09BA 00 LINFO: DB 000H 09BB 00 DMPOS: DB 000H 09BC 00 RECCNT: DB 000H 09BD 00 SINGLE: DB 000H 09BE 00 ZERO4: DB 000H 09BF 00 RCOUNT: DB 000H 09C0 00 EXTVAL: DB 000H 09C1 00 VRECORD:DB 000H 09C2 FF SELSTR: DB 0FFH 09C3 0000 ARECORD:DW 0000H 09C5 00 SHIFTED:DB 000H 09C6 0000 SHAREC: DW 0000H 09C8 00 MODNUM: DB 000H 09C9 00 DPTR: DB 000H 09CA 00 OLDDSK: DB 000H 09CB 00 SOMREC: DB 000H 09CC 0000 RECADR: DW 0000H 09CE 0000 TRACK: DW 0000H 09D0 0000 SAVSEC: DW 0000H RECORDOK1: 09D2 3E01 MVI A,001H 09D4 CDEE09 CALL RECORDOK2 09D7 C31606 JMP SETFCB 09DA 00 COLUMN: DB 000H ;COLUMN NUMBER 09DB 24 DOLLAR: DB 024H ;$ 09DC 8000 DMAAD: DB 080H,000H ;DMA ADDRESS 09DE 00 CURDSK: DB 000H ;CURRENT DISK 09DF 0000 INFO: DW 0000H ;MESSAGE LOCATION 09E1 00 FCBDSK: DB 000H 09E2 00 SAVEC: DB 000H 09E3 0000 DCNT: DW 0000H 09E5 0000 SEARCHA:DW 0000H 09E7 00 SEARCHL:DB 000H READDIR4: 09E8 2A9E09 LHLD ALLOCA 09EB C3F109 JMP READDIR5 RECORDOK2: 09EE 2AA009 LHLD ZERO5 READDIR5: 09F1 F5 PUSH PSW 09F2 CD540A CALL RECOK1 09F5 3AC309 LDA ARECORD 09F8 5F MOV E,A 09F9 A0 ANA B 09FA 32CB09 STA SOMREC 09FD 7B MOV A,E 09FE A1 ANA C 09FF 32C309 STA ARECORD 0A02 22CC09 SHLD RECADR 0A05 CD7206 CALL RDDIR2 0A08 228A09 SHLD DMAADDR 0A0B CD5B0A CALL RECOK5 0A0E F1 POP PSW 0A0F F5 PUSH PSW 0A10 FE04 CPI 004H 0A12 D21C0A JNC RECOK2 0A15 CD3F04 CALL RECOK8 0A18 CA2C0A JZ RECOK3 0A1B AF XRA A 0A1C CD640A RECOK2: CALL RECOK6 0A1F 3E02 MVI A,002H 0A21 CD6C0A CALL RECOK7 0A24 CD5B0A CALL RECOK5 0A27 CD4904 CALL MOVE 0A2A 3600 MVI M,000H 0A2C 3ACB09 RECOK3: LDA SOMREC 0A2F 3C INR A 0A30 118000 LXI D,TBUFF 0A33 2180FF LXI H,0FF80H 0A36 19 RECOK4: DAD D 0A37 3D DCR A 0A38 C2360A JNZ RECOK4 0A3B EB XCHG 0A3C 2A8A09 LHLD DMAADDR 0A3F 19 DAD D 0A40 F1 POP PSW 0A41 FE03 CPI 003H 0A43 C24A0A JNZ BNKMOV 0A46 228C09 SHLD BUFFA 0A49 C9 RET ; 0A4A EB BNKMOV: XCHG 0A4B 2ADC09 LHLD DMAAD 0A4E 018000 LXI B,TBUFF 0A51 C34B0B JMP ?MOV ;MOVE BETWEEN BANKS ; 0A54 3AB509 RECOK1: LDA ZERO2 0A57 47 MOV B,A 0A58 2F CMA 0A59 4F MOV C,A 0A5A C9 RET ; 0A5B 2ACC09 RECOK5: LHLD RECADR 0A5E 11C209 LXI D,SELSTR 0A61 0E04 MVI C,004H 0A63 C9 RET ; 0A64 110400 RECOK6: LXI D,00004H 0A67 2ACC09 LHLD RECADR 0A6A 19 DAD D 0A6B C9 RET ; 0A6C F5 RECOK7: PUSH PSW 0A6D CDDA04 CALL SEEK 0A70 F1 POP PSW 0A71 3D DCR A 0A72 F4B304 CP RDBUFF 0A75 CD640A CALL RECOK6 0A78 23 INX H 0A79 23 INX H 0A7A 11CE09 LXI D,TRACK 0A7D 0E04 MVI C,004H 0A7F C34904 JMP MOVE ; 0A82 DS 126D ;F1LL OUT TO THE END OF THE BLOCK ; 0B00 END