;LOADSYS.ASM REASSEMBLY OF CPMLDR.COM ;28 MAY 85 RHP ; THIS PROGRAM READS THE FILE 'SYSTEM.FIL' OFF OF THE DISK ; AND RELOCATES THE FILE TO THE OPERATING POSITION. ; ;APPEND A TRUNKATED BIOS THAT NEED ONLY DO CONSOLE WRITE, AND DISK ; READ FUNCTIONS. ; ;THIS PROGRAM MAY BE RESIDENT ON THE SYSTEM TRACKS OR RUN ; AS A TRANSIENT PROGRAM. ;BIOS JUMP TABLE ; 0B00 = BIOSS EQU 0B00H ; 0B00 = @BOOT EQU BIOSS + 000H ;COLD BOOT 0B0C = @CONOT EQU BIOSS + 00CH ;CONSOLE OUT 0B18 = @HOME EQU BIOSS + 018H ;HOME TO TRACK 0 0B1B = @SLDSK EQU BIOSS + 01BH ;SELECT DISK 0B1E = @STTRK EQU BIOSS + 01EH ;SET TRACK 0B21 = @STSEC EQU BIOSS + 021H ;SET SECTOR 0B24 = @STDMA EQU BIOSS + 024H ;SET DMA ADDRESS 0B27 = @READ EQU BIOSS + 027H ;READ A SECTOR 0B30 = @SCTRN EQU BIOSS + 030H ;TRANSLATE A PHYSICAL SECTOR 0B4B = @MOV EQU BIOSS + 04BH ;MOVE BETWEEN BANKS ; ; BDOS CALL FUNCTIONS ; 0000 = PRINT$STRING EQU 000H ;DE=STRING ADDRESS 0001 = DISK$RESET EQU 001H ;NO PARAMETERS 0002 = SEL$DISK EQU 002H ; WAS FUNCT E 0003 = SRCH$FIRST EQU 003H ;DE=FCB ADDR, A=DIR CODE 0004 = READ$SEQUENT EQU 004H ;DE=FCB ADDR, A=ERROR CODE 0005 = RETURN$CUR$DSK EQU 005H ; WAS FUNCT 19 0006 = SET$DMA$ADDR EQU 006H ;DE=DMA ADDRESS ; 005C = FCB EQU 0005CH 0080 = TBUFF EQU 00080H ; 0100 ORG 00100H ; ; 0100 315509 LXI SP,STACK1 ;SET UP THE STACK 0103 CD000B CALL @BOOT ;COLD BOOT ; 0106 0E01 MVI C,DISK$RESET ;RESET DISK 0108 CDAB01 CALL BDOS ; ; 010B 0E00 MVI C,PRINT$STRING ;PRINT STRING 010D 11F908 LXI D,MSBANR ;SIGN ON BANNER 0110 CDAB01 CALL BDOS ; 0113 0E03 MVI C,SRCH$FIRST ;LOCATE FILE ON DISK 0115 117F08 LXI D,FCBT 0118 CDAB01 CALL BDOS ; 011B FEFF CPI 0FFH ;CHECK FOR ERROR 011D 11A308 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 115509 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 0E00 MVI C,PRINT$STRING ;PRINT OUT THE CONTENTS OF 0141 118000 LXI D,TBUFF ;THE STRING JUST READ 0144 CDAB01 CALL BDOS ; 0147 3A5609 LDA HEDR2 ;GET 2ND GYTE OF HEADER 014A 67 MOV H,A ;PUT IN H 014B 3A5509 LDA HEDR1 ;GET FIRST BYTE OF HEADER 014E CD7301 CALL READFILE ; 0151 3A5809 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 3A5709 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 315909 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 0E06 DMASET: MVI C,SET$DMA$ADDR 0191 CDAB01 CALL BDOS 0194 C9 RET READSECT: 0195 0E04 MVI C,READ$SEQUENT 0197 117F08 LXI D,FCBT ;POINT TO FILE CONTROL BLOCK 019A CDAB01 CALL BDOS ; 019D B7 ORA A ;SET FLAGS 019E 11CE08 LXI D,MSREAD ;READ ERROR MESSAGE 01A1 C8 RZ ;NO ERROR 01A2 0E00 QUITS: MVI C,PRINT$STRING ;ELSE PRINT ERROR MSG 01A4 CDAB01 CALL BDOS ; 01A7 F3 DI ;KILL INTERRUPTS 01A8 76 HLT ;FREEZE ; 01A9 FF REBOOT: RST 07 01AA C9 RET ; 01AB EB BDOS: XCHG ;MSG POINTER IN HL 01AC 22AA09 SHLD INFO ;STORE MSG LOCATION 01AF EB XCHG ;MSG POINTER BACK TO DE 01B0 79 MOV A,C 01B1 FE0E CPI 00EH 01B3 DAC301 JC BDOS1 01B6 32AD09 STA SAVEC ;SAVE # IN C 01B9 AF XRA A ;CLEAR ACCUMULATOR 01BA 328A09 STA ZERO3 ;SET TO FALSE 01BD 32A909 STA CURDSK 01C0 329109 STA ZERO4 01C3 7B BDOS1: MOV A,E ;GET LO BYTE OF MEM ADDRESS 01C4 328D09 STA LINFO ;SAVE IT 01C7 210000 LXI H,00000H ;CLEAR HL 01CA 227D08 SHLD ARET ;RETURN VALUE DEFAULTS TO 0000 01CD 22AC09 SHLD FCBDSK ; SAVE USERS STACK PTR, SET TO LOCAL STACK 01D0 39 DAD SP ;MOVE SP TO HL 01D1 226109 SHLD ENTSP ;ENTSP=STACK POINTER 01D4 31030A LXI SP,LSTACK ;POINT STACK TO END OF C7 TABLE 01D7 218907 LXI H,GOBACK ;RETURN HERE AFTER ALL FUNCTIONS 01DA E5 PUSH H ;JUMP GOBACK EQUIV TO RETURN 01DB 79 MOV A,C 01DC FE06 CPI 006H ;NUMBER OF FUNCTIONS 01DE D2E801 JNC BDOS2 ;INVALID NUMBER 01E1 4B MOV C,E ;POSSIBLE OUTPUT CHAR. TO C 01E2 21FA01 LXI H,FUNCTAB ;POINT TO FUNCTION TABLE 01E5 C3ED01 JMP BDOS3 ; 01E8 DE64 BDOS2: SBI 064H 01EA DAD605 JC SEARCH$FIN 01ED 5F BDOS3: MOV E,A ;E GETS A 01EE 1600 MVI D,000H ;DE=FUNCTION, HL=.CIOTAR 01F0 19 DAD D ;ADD DE, HL 01F1 19 DAD D ;ADD DE, HL 01F2 5E MOV E,M ;MEMORY WORD TO DE 01F3 23 INX H 01F4 56 MOV D,M ;DE=FUNCTION ARGUMENT 01F5 2AAA09 LHLD INFO ;POINT TO MESSAGE WITH HL 01F8 EB XCHG ;DE POINTS MSG, HL TO DEST. 01F9 E9 PCHL ;JUMP TO ROUTINE ; FUNCTAB: 01FA 3102 DW FUNCT00 ;FUNCTION 9=PRINT STRING 01FC 3F07 DW FUNCT01 ;FUNCTION D=RESET DISK 01FE 5607 DW FUNCT02 ;FUNCTION E=SELECT DISK 0200 5C07 DW FUNCT03 ;FUNCTION F=OPEN FILE 0202 7607 DW FUNCT04 ;FUNCTION 14=READ SEQUENTIAL 0204 7C07 DW FUNCT05 ;FUNCTION 19=RETURN CURRENT DISK 0206 8207 DW FUNCT06 ;FUNCTION 1A=SET DMA ADDRESS ; ; COMPUTE CHARACTER POSITION/WRITE CONSOLE ; CHARACTER FROM C ; COMPCOL = TRUE IF COMPUTING COLUMN POSITION ; 0208 3A6208 CONOUT: LDA COMPCOL 020B B7 ORA A 020C C21402 JNZ COMPOUT ;WRT CHAR FROM C, THEN COMP COL. 020F C5 PUSH B 0210 CD0C0B CALL @CONOT ;PRINT CHARACTER ON CONSOLE 0213 C1 POP B 0214 79 COMPOUT:MOV A,C ;RECALL CHAR & COMPUTE COL POSIT 0215 21A509 LXI H,COLUMN ;A=CHAR, HL=.COLUMN 0218 FE7F CPI 07FH ;RUBOUT? 021A C8 RZ ;NO COL CHANGE IF NULLS 021B 34 INR M ;NEXT COLUMN 021C FE20 CPI 020H ;SPACE? 021E D0 RNC ;RETURN IF GRAPHIC,ELSE RESET COL. 021F 35 DCR M ;NEXT COLUMN 0220 7E MOV A,M 0221 B7 ORA A 0222 C8 RZ ;RET IF ZERO, ELSE MAYBE BS OR EOL 0223 79 MOV A,C ;CHAR IN A 0224 FE08 CPI 008H ;CTL H? 0226 C22B02 JNZ NOTBACKSP ;ELSE BACKSPACE 0229 35 DCR M ;NEXT COLUMN 022A C9 RET ; ; NOT A BACKSPACE CHARACTER, EOL? ; NOTBACKSP: 022B FE0A CPI 00AH ;LINEFEED? 022D C0 RNZ 022E 3600 MVI M,000H ;END OF LINE, COL=0 0230 C9 RET ; ; PRINT STRING DE=STRING ADDRESS, ENDS IN $ ; 0231 EB FUNCT00:XCHG ;WAS LHLD INFO 0232 4D MOV C,L 0233 44 MOV B,H ;BC=STRING ADDRESS ; ; PRINT MESSAGE UNTIL M(BC) = $ ; 0234 21A609 PRINT: LXI H,DOLLAR 0237 0A LDAX B 0238 BE CMP M ;$? 0239 C8 RZ ;STOP ON $, ELSE MORE TO PRINT 023A 03 INX B 023B C5 PUSH B 023C 4F MOV C,A 023D 79 MOV A,C 023E FE09 CPI 009H ;TAB? 0240 C20802 JNZ CONOUT ;IF NO TAB, DIRECT TO CONOUT 0243 0E20 TAB0: MVI C,020H ;ELSE CHANGE TO SPACE 0245 CD0802 CALL CONOUT 0248 3AA509 LDA COLUMN 024B E607 ANI 007H ;COLUMN MOD 8 = 0 7 024D C24302 JNZ TAB0 ;BACK FOR ANOTHER IF NOT 0250 C1 POP B 0251 C33402 JMP PRINT ; 0254 3E01 DISKEOF:MVI A,001H ;SET LRET=1 0256 327D08 STA$RET:STA ARET ;STORE THE REGISTER TO ARET 0259 C9 FNC$RET:RET ;JMP GOBACK (POP STACK FOR NON CPM FUNCTIONS) ; SEL$ERROR: 025A 016308 LXI B,MSBDOS ;BDOS ERROR MESSAGE 025D CD3402 CALL PRINT 0260 017008 LXI B,MSSLCT ;SELECT MSG 0263 C36F02 JMP QUIT2 ; 0266 016308 PERMSG: LXI B,MSBDOS ;BDOS ERROR MESSAGE 0269 CD3402 CALL PRINT 026C 017708 LXI B,MSPERM ;PERMANENT MSG 026F CD3402 QUIT2: CALL PRINT ; 0272 F3 DI ;KILL INTERRUPTS 0273 76 HLT ;FREEZE ; 0274 7B SUBDH: MOV A,E ;SUBTRACT HL = DE-HL 0275 95 SUB L 0276 5F MOV E,A 0277 7A MOV A,D 0278 9C SBB H 0279 57 MOV D,A 027A D0 RNC 027B 05 DCR B 027C C9 RET ; 027D 1A RECOK8: LDAX D ;A GETS MEMORY POINTED BY DE 027E BE CMP M ;COMPARE TO MEMORY POINTED BY HL 027F C0 RNZ ;QUIT IF DIFFERENT 0280 23 INX H ;NEXT HL 0281 13 INX D ;NEXT DE 0282 0D DCR C ;TIL COUNT IN C 0283 C8 RZ ; DROPS TO ZERO 0284 C37D02 JMP RECOK8 ;ELSE TRY AGAIN ; ; MOVE DATA OF LENGTH C FROM DE TO HL ; 0287 0C MOVE: INR C ;IN CASE IT IS ZERO 0288 0D MOVE0: DCR C ;FOR COUNT IN C 0289 C8 RZ ;DONE? 028A 1A LDAX D ;MEMORY POINTED BY DE TO A 028B 77 MOV M,A ;MOVE TO MEMORAY POINTED BY HL 028C 13 INX D ;NEXT DE 028D 23 INX H ;NEXT HL 028E C38802 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: 0291 4A MOV C,D ;CURRENT DISK TO C ;LSB OF C=0 IF NOT YET LOGGED IN 0292 CD1B0B CALL @SLDSK ;SELECT DISK, SETS HL 0295 7C MOV A,H 0296 B5 ORA L 0297 C8 RZ ;HL=0 FOR ERROR ELSE DISK HEADER 0298 5E MOV E,M 0299 23 INX H 029A 56 MOV D,M 029B 23 INX H ;DE=.TRAN 029C 23 INX H 029D 23 INX H ;.CDRMAX 029E 226B09 SHLD CURTRKA 02A1 23 INX H 02A2 23 INX H ;HL=.CURREC 02A3 226D09 SHLD CURRECA 02A6 23 INX H 02A7 23 INX H 02A8 23 INX H 02A9 23 INX H 02AA 23 INX H 02AB 23 INX H 02AC EB XCHG 02AD 228B09 SHLD TRANV ;.TRAN VECTOR 02B0 216F09 LXI H,BUFFB ;DE=SOURCE, HL=DEST FOR MOVE 02B3 0E0D MVI C,00DH ;ADDLIST 02B5 CD8702 CALL MOVE ;ADDLIST FILLED 02B8 2A6F09 LHLD BUFFB ;NOW FILL DPB 02BB EB XCHG ;DE IS SOURCE 02BC 217C09 LXI H,SECTPT ;HL IS DEST. 02BF 0E11 MVI C,011H ;DPBLIST 02C1 CD8702 CALL MOVE ;DATA FILLED 02C4 2A8109 LHLD MAXALL ;LARGEST ALLOC NUMBER 02C7 7C MOV A,H ;00 INDICATES <255 02C8 219009 LXI H,SINGLE 02CB 36FF MVI M,0FFH ;FF=TRUE, ASSUME A=00 02CD B7 ORA A 02CE CAD302 JZ RETSELECT 02D1 3600 MVI M,000H ;M=FALSE RETSELECT: ;HIGH ORDER OF MAXALL NOT 0 ; USE DOUBLE DM 02D3 37 STC 02D4 C9 RET ; ; MOVE TO TRACK 0 ; 02D5 CD180B HOME: CALL @HOME ;HOME THE DISK 02D8 AF XRA A ;ZERO THE ACCCUM 02D9 2A6B09 LHLD CURTRKA 02DC 77 MOV M,A 02DD 23 INX H 02DE 77 MOV M,A ;CURTRAK=0000 02DF 2A6D09 LHLD CURRECA 02E2 77 MOV M,A 02E3 23 INX H 02E4 77 MOV M,A ;CURREC=0000 02E5 23 INX H 02E6 77 MOV M,A 02E7 C9 RET ; ; RDBUFF1: 02E8 219609 LXI H,ARECORD 02EB 5E MOV E,M 02EC 23 INX H 02ED 56 MOV D,M 02EE 23 INX H 02EF 46 MOV B,M 02F0 C9 RET ; ; ; 02F1 CDE802 RDBUFF: CALL RDBUFF1 02F4 CD270B CALL @READ ;READ A SECTOR 02F7 B7 ORA A ;SET FLAGS 02F8 C8 RZ ;OK 02F9 4F MOV C,A ;SAVE ERROR 02FA FE03 CPI 003H ;CHECK ERROR 02FC DA6602 JC PERMSG ;PERMANENT BDOS ERROR 02FF 0E01 MVI C,001H ;ELSE CHANGE ERROR FLAG 0301 C36602 JMP PERMSG ;PERMANENT BDOS ERROR ; ; SEEK RECORD CONTAINING THE CURRENT DIRECTORY ENTRY ; 0304 2AAE09 SEEKDIR:LHLD DCNT ;DIRECTORY COUNTER TO COUNTER 0307 0E02 MVI C,002H ;DSKSHF 0309 CD6D04 CALL HLROTR ;VALUE TO HL 030C 0600 MVI B,000H 030E EB XCHG 030F 219609 LXI H,ARECORD 0312 73 MOV M,E ;STORE ARECORD 0313 23 INX H 0314 72 MOV M,D ;STORE DREC 0315 23 INX H 0316 70 MOV M,B 0317 C9 RET ; ; SEEK THE TRACK GIVEN BY ARECORD (ACTUAL RECORD) ; 0318 2A6B09 SEEK: LHLD CURTRKA 031B 4E MOV C,M 031C 23 INX H 031D 46 MOV B,M 031E C5 PUSH B 031F 2A6D09 LHLD CURRECA 0322 5E MOV E,M 0323 23 INX H 0324 56 MOV D,M 0325 23 INX H 0326 46 MOV B,M 0327 2A9609 LHLD ARECORD 032A 3A9809 LDA SHIFTED 032D 4F MOV C,A 032E 7D SEEK0: MOV A,L ;LOOP WHILE ARECORD < CURREC 032F 93 SUB E 0330 7C MOV A,H 0331 9A SBB D 0332 79 MOV A,C 0333 98 SBB B 0334 E5 PUSH H 0335 D24503 JNC SEEK1 ;SKIP IF ARECORD >= CURREC 0338 2A7C09 LHLD SECTPT ;CURREC = SECTPT 033B CD7402 CALL SUBDH ;SUBTRACT HL FROM DE 033E E1 POP H 033F E3 XTHL 0340 2B DCX H ;CURTRK = CURTRK-1 0341 E3 XTHL 0342 C32E03 JMP SEEK0 ;FOR ANOTHER TRY ; 0345 2A7C09 SEEK1: LHLD SECTPT ;LOOK WHILE ARECORD >= (T:CURREC+SECTP) 0348 7B MOV A,E ;ADD HL AND DE 0349 85 ADD L 034A 5F MOV E,A 034B 7A MOV A,D 034C 8C ADC H 034D 57 MOV D,A 034E D0 RNC 034F 04 INR B 0350 E1 POP H 0351 7D MOV A,L 0352 93 SUB E 0353 7C MOV A,H 0354 9A SBB D 0355 79 MOV A,C 0356 98 SBB B 0357 DA6103 JC SEEK2 ;SKIP IF T>ARECORD, CURREC=T, 035A E3 XTHL ; CURTRK=CURTRK+1 035B 23 INX H 035C E3 XTHL 035D E5 PUSH H 035E C34503 JMP SEEK1 ;FOR ANOTHER TRY ; 0361 E3 SEEK2: XTHL 0362 E5 PUSH H 0363 2A7C09 LHLD SECTPT 0366 CD7402 CALL SUBDH ;SUBTRACT HL FROM DE 0369 E1 POP H ;ARRIVE HERE WITH UPDATED VALUES ; IN EACH REGISTER 036A D5 PUSH D 036B C5 PUSH B 036C E5 PUSH H ;TO STACK FOR LATER ;STACK=BC=ARECORD, DE=CURREC, HL=CURTRK 036D EB XCHG 036E 2A8509 LHLD OFFSET 0371 19 DAD D ;HL=CURTRK+OFFSET 0372 44 MOV B,H 0373 4D MOV C,L 0374 22A109 SHLD TRACK 0377 CD1E0B CALL @STTRK ;TRACK SET UP. NOTE THAT BC-CURTRK ; IS DIFFERENCE TO MOVE IN BIOS 037A D1 POP D ;RECALL CURTRK 037B 2A6B09 LHLD CURTRKA 037E 73 MOV M,E 037F 23 INX H 0380 72 MOV M,D ;CURTRK UPDATED ; NOW COMPUTE SECTOR AS ARECORD-CURREC 0381 C1 POP B 0382 D1 POP D ;RECALL CURREC 0383 2A6D09 LHLD CURRECA 0386 73 MOV M,E 0387 23 INX H 0388 72 MOV M,D 0389 23 INX H 038A 70 MOV M,B 038B C1 POP B ;BC=ARECORD, DE=CURREC 038C 79 MOV A,C 038D 93 SUB E 038E 6F MOV L,A 038F 78 MOV A,B 0390 9A SBB D 0391 67 MOV H,A 0392 CDAE03 CALL SEEK3 0395 44 MOV B,H 0396 4D MOV C,L 0397 2A8B09 LHLD TRANV 039A EB XCHG ;BC=SECTOR#, DE=.TRAN 039B CD300B CALL @SCTRN ;HL=TRAN (SECTOR) 039E 4D MOV C,L 039F 44 MOV B,H 03A0 22A309 SHLD SAVSEC 03A3 CD210B CALL @STSEC ;SECTOR SELECTED 03A6 2A6509 LHLD DMAADDR 03A9 4D MOV C,L 03AA 44 MOV B,H 03AB C3240B JMP @STDMA ;SET DMA ; 03AE 3A8709 SEEK3: LDA ZERO1 03B1 4F MOV C,A 03B2 C36D04 JMP HLROTR ; ; COMPUTE DISK MAP POSITION FOR VRECORD TO HL ; DM$POSITION: 03B5 217E09 LXI H,BLKSHF 03B8 4E MOV C,M ;SHIFT COUNT TO C 03B9 3A9409 LDA VRECORD ;CURRENT VIRTUAL RECORD TO A 03BC B7 DMPOS0: ORA A 03BD 1F RAR 03BE 0D DCR C 03BF C2BC03 JNZ DMPOS0 ;A=SBR(VRECORD,BLKSHF)= ; VRECORD/2**(SEC/BLOCK) 03C2 47 MOV B,A ;SAVE IT FOR LATER ADDITION 03C3 3E08 MVI A,008H 03C5 96 SUB M ;8-BLKSHF TO ACCUMULATOR 03C6 4F MOV C,A ;EXTENT SHIFT COUNT IN REGISTER C 03C7 3A9309 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 ; 03CA 0D DMPOS1: DCR C 03CB CAD303 JZ DMPOS2 03CE B7 ORA A 03CF 17 RAL 03D0 C3CA03 JMP DMPOS1 ; ; ARRIVE HERE WITH A=SHL(EXT AND EXTMSK), 7-BLKSHF) ; 03D3 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 03D4 C9 RET ;WITH DM$POSITION IN A ; ; GET DISK MAP VALUE FROM POSITION GIVEN BY BC ; GETDM: ;POINT TO 16TH CHAR IN INFO 03D5 2AAA09 LHLD INFO ;BASE ADDRESS OF FCB 03D8 111000 LXI D,00010H ;DSKMAP 03DB 19 DAD D ;HL=.DSKMAP 03DC 09 DAD B ;INDEX BY SINGLE BYTE VALUE 03DD 3A9009 LDA SINGLE ;SINGLE BYTE/MAP ENTRY? 03E0 B7 ORA A 03E1 CAE703 JZ GETDMD ;GET DISK MAP SINGLE BYTE 03E4 6E MOV L,M 03E5 60 MOV H,B 03E6 C9 RET ;WITH HL=00BB ; 03E7 09 GETDMD: DAD B ;HL=.FCB(DM+I*2) ; DOUBLE PRECISION VALUE RETURNED 03E8 7E MOV A,M 03E9 23 INX H 03EA 66 MOV H,M 03EB 6F MOV L,A 03EC C9 RET ; ; COMPUTE DISK BLOCK NUMBER FROM CURRENT FCB ; 03ED CDB503 INDEX: CALL DM$POSITION ;0....15 IN REGISTER A 03F0 328E09 STA DMPOS 03F3 4F MOV C,A 03F4 0600 MVI B,000H 03F6 CDD503 CALL GETDM ;VALUE TO HL 03F9 229609 SHLD ARECORD 03FC 7D MOV A,L 03FD B4 ORA H 03FE C9 RET ; ; COMPUTE ACTUAL RECORD ADDRESS, ASSUMING INDEX CALLED ; 03FF 3A7E09 ATRAN: LDA BLKSHF ;SHIFT COUNT TO REG A 0402 4F MOV C,A 0403 2A9609 LHLD ARECORD 0406 AF XRA A 0407 CD2504 CALL ATRAN0 040A 229609 SHLD ARECORD 040D 329809 STA SHIFTED 0410 229909 SHLD SHAREC 0413 3A7F09 LDA BLKMSK 0416 4F MOV C,A ;MASK VALUE TO C 0417 3A9409 LDA VRECORD 041A A1 ANA C ;MASKED VALUE IN A 041B 47 MOV B,A 041C 328909 STA MSKVREC 041F 219609 LXI H,ARECORD ;ARECORD=HL OR (VRECORD AND BLKMSK) 0422 B6 ORA M 0423 77 MOV M,A 0424 C9 RET ; 0425 0C ATRAN0: INR C 0426 0D ATRAN1: DCR C 0427 C8 RZ 0428 29 DAD H 0429 8F ADC A 042A C32604 JMP ATRAN1 ; ; GET CURRENT EXTENT FIELD ADDRESS TO A ; 042D 2AAA09 GETEXTA:LHLD INFO 0430 110C00 LXI D,0000CH ;EXTNUM 0433 19 DAD D ;HL=.FCB(EXTNUM) 0434 C9 RET 0435 2AAA09 GETFCBB: LHLD INFO 0438 110F00 LXI D,0000FH 043B 19 DAD D 043C C9 RET ; ; COMPUTE RECCNT AND NXTREC ADDRESSES FOR GET/SETFCB ; 043D CD3504 GETFCBA:CALL GETFCBB 0440 EB XCHG ;DE=.FCB(NXTREC) 0441 211100 LXI H,00011H ;NXTREC-RECC 0444 19 DAD D ;HL=.FCB(NXTREC) 0445 C9 RET ; ; SET VARIABLES FROM CURRENTLY ADDRESSED FCB ; 0446 CD3D04 GETFCB: CALL GETFCBA ;ADDRESSES IN DE, HL 0449 7E MOV A,M 044A 329409 STA VRECORD ;VRECORD=FCB(NXTREC) 044D EB XCHG 044E 7E MOV A,M 044F 329209 STA RCOUNT ;RCOUNT=FCB(RECCNT) 0452 CD2D04 CALL GETEXTA ;HL=.FCB(EXTNUM) 0455 3A8009 LDA EXTMSK ;EXTENT MASK TO A 0458 A6 ANA M ;FCB(EXTNUM) AND EXTMASK 0459 329309 STA EXTVAL 045C C9 RET ; ; PLACE VALUES BACK IN CURRENT FCB ; 045D CD3D04 SETFCB: CALL GETFCBA ;ADDRESSES TO DE, HL 0460 0E01 MVI C,001H 0462 3A9409 LDA VRECORD 0465 81 ADD C 0466 77 MOV M,A ;FCB(NXTREC)=VRECORD+SEQIO 0467 EB XCHG 0468 3A9209 LDA RCOUNT 046B 77 MOV M,A ;FCB(RECCNT)=RCOUNT 046C C9 RET ; ; HL ROTATE RIGHT BY AMOUNT C ; 046D 0C HLROTR: INR C ;IN CASE 0 046E 0D HLROTR0:DCR C 046F C8 RZ ;RETURN WHEN C=0 0470 7C MOV A,H 0471 B7 ORA A 0472 1F RAR 0473 67 MOV H,A ;HIGH BYTE 0474 7D MOV A,L 0475 1F RAR 0476 6F MOV L,A ;LOW BYTE 0477 C36E04 JMP HLROTR0 ; ; ROTATE THE MASK IN HL BY THE AMOUNT IN C ; 047A 0C HLROTL: INR C ;MAY BE ZERO 047B 0D HLROTL0:DCR C 047C C8 RZ ;RETURN WHEN C=0 047D 29 DAD H 047E C37B04 JMP HLROTL0 ; ; SET A "1" VALUE IN CURDSK POSITION OF BC ; SET$DISK: 0481 3AA909 LDA CURDSK 0484 C5 PUSH B ;SAVE INPUT PARAMETER 0485 4F MOV C,A ;READY PARAMETER FOR SHIFT 0486 210100 LXI H,00001H 0489 CD7A04 CALL HLROTL ;HL=MASK TO INTEGRATE 048C C1 POP B ;ORIGINAL MASK 048D 79 MOV A,C 048E B5 ORA L 048F 6F MOV L,A 0490 78 MOV A,B 0491 B4 ORA H 0492 67 MOV H,A ;HL=MASK OR ROL(1,CURDSK) 0493 C9 RET ; ; RETURN TRUE IF DIR CHECKSUM ; 0494 3AA909 NOWRITE:LDA CURDSK 0497 4F MOV C,A 0498 CD6D04 CALL HLROTR 049B 7D MOV A,L 049C E601 ANI 001H 049E C9 RET ;NOW 0 IF NOWRITE ; ; COMPUTE THE ADDRESS OF A DIRECTORY ELEMENT AT ; POSITION DPTR IN THE BUFFER ; GETDPTRA: 049F 2A6709 LHLD BUFFA 04A2 3A9C09 LDA DPTR 04A5 85 ADD L ;HL=HL+A 04A6 6F MOV L,A 04A7 D0 RNC ;OVERFLOW TO H 04A8 24 INR H 04A9 C9 RET ; 04AA D5 RDDIR2: PUSH D 04AB 110A00 LXI D,0000AH 04AE 19 DAD D 04AF 5E MOV E,M 04B0 23 INX H 04B1 56 MOV D,M 04B2 EB XCHG 04B3 D1 POP D 04B4 C9 RET ; 04B5 CD0403 READDIR3: CALL SEEKDIR 04B8 3A8809 LDA ZERO2 04BB B7 ORA A 04BC CAC704 JZ RD$DIR 04BF 3E03 MVI A,003H 04C1 CDCB07 CALL READDIR4 04C4 C3D304 JMP SETDATA ; ; READ A DIRECTORY ENTRY INTO THE DIRECTORY BUFFER ; 04C7 CDD904 RD$DIR: CALL RDDIR1 04CA 226709 SHLD BUFFA 04CD CD1803 CALL SEEK 04D0 CDF102 CALL RDBUFF ;DIRECTORY ENTRY LOADED ; ; SET DATA DMA ADDRESS ; 04D3 2AA709 SETDATA:LHLD DMAAD 04D6 C3DF04 JMP SETDMA ; 04D9 2A7509 RDDIR1: LHLD ALLOCA 04DC CDAA04 CALL RDDIR2 ; ; HL=ADDRESS TO SET (I.E., BUFFA OR DMAAD) ; 04DF 226509 SETDMA: SHLD DMAADDR 04E2 C9 RET ; ; RETURN ZERO FLAG IF AT END OF DIRECTORY, NON ZERO ; IF NOT AT END (END OF DIR IF DCNT=0FFFFH) ; 04E3 21AE09 END$OF$DIR: LXI H,DCNT 04E6 7E MOV A,M ;MAY BE 0FFH 04E7 23 INX H 04E8 BE CMP M ;LOW(DCNT)=HIGH(DCNT)? 04E9 C0 RNZ ;NOW ZERO RETURNED IF DIFFERENT ;HIGH AND LOW THE SAME,=0FFH? 04EA 3C INR A ;0FFH BECOMES 00 IF SO 04EB C9 RET ; ; SET DCNT TO THE END OF THE DIRECTORY ; SET$END$DIR: 04EC 21FFFF LXI H,0FFFFH ;(ENDDIR) 04EF 22AE09 SHLD DCNT 04F2 C9 RET ; READ$DIR: 04F3 2A8309 LHLD DIRMAX 04F6 EB XCHG 04F7 2AAE09 LHLD DCNT 04FA 23 INX H 04FB 22AE09 SHLD DCNT 04FE 7B MOV A,E 04FF 95 SUB L 0500 6F MOV L,A 0501 7A MOV A,D 0502 9C SBB H 0503 67 MOV H,A 0504 DAEC04 JC SET$END$DIR 0507 3AAE09 LDA DCNT 050A E603 ANI 003H 050C 0605 MVI B,005H READDIR2: 050E 87 ADD A 050F 05 DCR B 0510 C20E05 JNZ READDIR2 0513 329C09 STA DPTR 0516 B7 ORA A 0517 C0 RNZ 0518 C5 PUSH B 0519 CDB504 CALL READDIR3 051C C1 POP B 051D C9 RET ; ; COMPARE EXTENT# IN A TO THAT IN C, RETURN NONZERO ; IF NO MATCH ; COMPEXT: 051E C5 PUSH B ;SAVE C'S ORIGINAL VALUE 051F F5 PUSH PSW 0520 3A8009 LDA EXTMSK 0523 2F CMA 0524 47 MOV B,A ;B HAS NEGATED FORM OF EXTENT MASK 0525 79 MOV A,C 0526 A0 ANA B 0527 4F MOV C,A ;LOW BITS REMOVED FROM C 0528 F1 POP PSW 0529 A0 ANA B ;LOW BITS REMOVED FROM A 052A 91 SUB C 052B E61F ANI 01FH ;(MAXEXT) SET FLAGS 052D C1 POP B ;RESTORE ORIGINAL VALUES 052E C9 RET ; 052F CD3D04 OPENER: CALL GETFCBA 0532 0E10 MVI C,010H 0534 41 MOV B,C 0535 0C INR C 0536 C5 PUSH B OPENER1: 0537 C1 POP B 0538 0D DCR C 0539 AF XRA A OPENER2: 053A 2B DCX H 053B 05 DCR B 053C BE CMP M 053D C24405 JNZ OPENER3 0540 0D DCR C 0541 C23A05 JNZ OPENER2 OPENER3: 0544 79 MOV A,C 0545 328E09 STA DMPOS 0548 3A9009 LDA SINGLE 054B B7 ORA A 054C 78 MOV A,B 054D C25105 JNZ OPENER4 0550 1F RAR OPENER4: 0551 C5 PUSH B 0552 E5 PUSH H 0553 6F MOV L,A 0554 2600 MVI H,000H 0556 3A7E09 LDA BLKSHF 0559 57 MOV D,A 055A 3E07 MVI A,007H 055C 92 SUB D 055D 4F MOV C,A 055E CD6D04 CALL HLROTR 0561 45 MOV B,L 0562 3A8009 LDA EXTMSK 0565 B8 CMP B 0566 E1 POP H 0567 DA3705 JC OPENER1 056A CD2D04 CALL GETEXTA 056D 4E MOV C,M 056E 2F CMA 056F E61F ANI 01FH 0571 A1 ANA C 0572 B0 ORA B 0573 C1 POP B 0574 C9 RET ; ; SEARCH FOR DIRECTORY ELEMENT OF LENGTH C AT INFO ; 0575 2AAA09 SEARCH: LHLD INFO 0578 22B009 SHLD SEARCHA ;SEARCHA=INFO 057B 79 MOV A,C 057C 32B209 STA SEARCHL 057F CDEC04 CALL SET$END$DIR ;DCNT=ENDIR 0582 CDD502 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 0585 0E00 MVI C,000H ;(FALSE) 0587 CDF304 CALL READ$DIR ;READ NEXT DIRECTORY ELEMENT 058A CDE304 CALL END$OF$DIR 058D CAD605 JZ SEARCH$FIN ;SKIP TO END IF SO ;NOT END OF DIRECTORY, SCAN FOR MATCH 0590 2AB009 LHLD SEARCHA 0593 EB XCHG 0594 CD9F04 CALL GETDPTRA ;HL=BUFFA+DPTR 0597 3AB209 LDA SEARCHL 059A 4F MOV C,A ;LENGTH OF SEARCH TO C 059B 0600 MVI B,000H ;B COUNTS UP, C COUNTS DOWN 059D 7E MOV A,M 059E FEE5 CPI 0E5H ;(EMPTY) 05A0 CA8505 JZ SEARCHN SEARCHLOOP: 05A3 79 MOV A,C 05A4 B7 ORA A 05A5 CACF05 JZ ENDSEARCH 05A8 78 MOV A,B 05A9 FE0D CPI 00DH ;(UBYTES) 05AB CAC805 JZ SEARCHOK ; ;NOT THE UBYTES FIELD, EXTENT FIELD? 05AE FE0C CPI 00CH ;(EXTNUM) MAY BE EXTENT FIELD 05B0 CABD05 JZ SEARCHEXT ;SKIP TO SEARCH EXTENT 05B3 1A LDAX D ;FCB CHARACTER 05B4 96 SUB M 05B5 E67F ANI 07FH ;MASK-OUT FLAGS/EXTENT MODULE 05B7 C28505 JNZ SEARCHN ;SKIP IF NOT MATCHED 05BA C3C805 JMP SEARCHOK ;MATCHED CHARACTER SEARCHEXT: ;A HAS FCB CHARACTER ;ATTEMPT AN EXTENT # MATCH 05BD 1A LDAX D 05BE C5 PUSH B ;SAVE COUNTERS 05BF 4E MOV C,M ;DIRECTORY CHARACTER TO C 05C0 CD1E05 CALL COMPEXT ;COMPARE USER/DIR CHAR 05C3 C1 POP B ;RECALL COUNTERS 05C4 B7 ORA A 05C5 C28505 JNZ SEARCHN ;SKIP IF NO MATCH ; SEARCHOK: ;CURRENT CHARACTER MATCHES 05C8 13 INX D 05C9 23 INX H 05CA 04 INR B 05CB 0D DCR C 05CC C3A305 JMP SEARCHLOOP ; ENDSEARCH: 05CF AF XRA A 05D0 327D08 STA ARET 05D3 47 MOV B,A 05D4 04 INR B 05D5 C9 RET ; ; END OF DIRECTORY OR EMPTY NAME ; SEARCH$FIN: 05D6 3EFF MVI A,0FFH 05D8 47 MOV B,A 05D9 04 INR B 05DA C35602 JMP STA$RET ; ; SEARCH FOR THE DIRECTORY ENTRY, COPY TO FCB ; 05DD 0E0F OPEN: MVI C,00FH ;NAMLEN 05DF CD7505 CALL SEARCH 05E2 C8 RZ ;RETURN WITH ARET=255 IF END ;NOT END OF DIRECTORY. COPY FCB ;INFORMATION (REFERENCED BELOW ;TO COPY FCB INFO) OPEN$COPY: 05E3 CD2D04 CALL GETEXTA 05E6 7E MOV A,M 05E7 F5 PUSH PSW 05E8 CD9F04 CALL GETDPTRA 05EB EB XCHG ;DE=.BUFF(DPTR) 05EC 2AAA09 LHLD INFO ;HL=.FCB(0) 05EF 0E20 MVI C,020H ;(NXTREC) LENGTH OF MOVE OPERATION 05F1 CD8702 CALL MOVE ;FROM .BUFF(DPTR) TO .FCB(0) ;NOTE THAT ENTIRE FCB IS COPIED, ; INCLUDING INDICATORS 05F4 CD2F05 CALL OPENER 05F7 4F MOV C,A 05F8 F1 POP PSW 05F9 77 MOV M,A OPEN$COPY1: 05FA 0600 MVI B,000H 05FC EB XCHG 05FD 210300 LXI H,00003H 0600 19 DAD D 0601 1A LDAX D 0602 91 SUB C 0603 CA1306 JZ OPEN$COPY2 0606 78 MOV A,B 0607 D20D06 JNC OPEN$RCNT ;USER IS LARGER 060A 3E80 MVI A,080H ;DIRECTORY IS LARGER 060C 46 MOV B,M OPEN$RCNT: ;A HAS RECORD COUNT TO FILL 060D 77 MOV M,A 060E 78 MOV A,B 060F 328F09 STA RECCNT 0612 C9 RET OPEN$COPY2: 0613 328F09 STA RECCNT 0616 7E MOV A,M 0617 B7 ORA A 0618 C0 RNZ 0619 3A8E09 LDA DMPOS 061C B7 ORA A 061D C8 RZ 061E 3AAD09 LDA SAVEC 0621 FE0F CPI 00FH 0623 C8 RZ 0624 3680 MVI M,080H 0626 C9 RET ; OPEN$REEL3: 0627 E5 PUSH H 0628 3A8F09 LDA RECCNT 062B B7 ORA A 062C CA3806 JZ OPEN$REEL4 062F 110300 LXI D,00003H 0632 19 DAD D 0633 77 MOV M,A 0634 AF XRA A 0635 328F09 STA RECCNT OPEN$REEL4: 0638 E1 POP H 0639 C9 RET ; ; CLOSE THE CURRENT EXTENT, AND OPEN THE NEXT ONE ; IF POSSIBLE. RMF IS TRUE IF IN READ MODE ; OPEN$REEL: 063A CD2D04 CALL GETEXTA 063D 7E MOV A,M 063E 4F MOV C,A 063F 0C INR C 0640 CD1E05 CALL COMPEXT 0643 CA5C06 JZ OPEN$REEL1 0646 3E1F MVI A,01FH 0648 A1 ANA C 0649 77 MOV M,A 064A 0E0F MVI C,00FH 064C CD7505 CALL SEARCH 064F CDE305 CALL OPEN$COPY OPEN$REEL0: 0652 CD4604 CALL GETFCB 0655 AF XRA A 0656 329409 STA VRECORD 0659 C35602 JMP STA$RET OPEN$REEL1: 065C 34 INR M 065D CD2F05 CALL OPENER 0660 4F MOV C,A 0661 BE CMP M 0662 D26906 JNC OPEN$REEL2 0665 35 DCR M 0666 C35402 JMP DISKEOF ; OPEN$REEL2: 0669 CD2706 CALL OPEN$REEL3 066C CDFA05 CALL OPEN$COPY1 066F C35206 JMP OPEN$REEL0 ; ; SEQUENTIAL DISK READ OPERATION ; SEQDISKREAD: 0672 CD4604 CALL GETFCB ;SETS PARAMETERS FOR THE READ 0675 3A9409 LDA VRECORD 0678 219209 LXI H,RCOUNT 067B BE CMP M ;VRECORD-RCOUNT,SKIP IF RCOUNT>VRECORD 067C DA8E06 JC RECORDOK ;NOT ENOUGH RECORDS IN THE EXTENT, ; RECORD COUNT MUST BE 128 TO CONTINUE 067F FE80 CPI 080H ;VRECORD=128 0681 C25402 JNZ DISKEOF ;SKIP IF VRECORD<>128 0684 CD3A06 CALL OPEN$REEL ;GO TO NEXT EXTENT IF SO 0687 3A7D08 LDA ARET 068A B7 ORA A 068B C25402 JNZ DISKEOF ;STOP AT EOF ; ; ARRIVE WITH FCB ADDRESSING A RECORD TO READ ; RECORDOK: 068E CDED03 CALL INDEX ;ERROR 2 IF READING UNWRITTEN DATA ; (RETURNS 1 TO BE COMPATABLE WITH 1.4) 0691 CA5402 JZ DISKEOF ;RECORD HAS BEEN ALLOCATED, READ IT 0694 CDFF03 CALL ATRAN ;ARECORD NOW A DISK ADDRESS 0697 3A8809 LDA ZERO2 069A B7 ORA A 069B C2C307 JNZ RECORDOK1 069E CDD304 CALL SETDATA 06A1 CD1803 CALL SEEK ;TO PROPER TRACK, SECTOR 06A4 CDF102 CALL RDBUFF ;TO DMA ADDRESS 06A7 C35D04 JMP SETFCB ;REPLACE PARAMETER 06AA 3AA909 SELECT: LDA CURDSK 06AD 3C INR A 06AE CA5A02 JZ SEL$ERROR 06B1 3D DCR A 06B2 219509 LXI H,SELSTR 06B5 BE CMP M 06B6 C8 RZ ;SKIP IN LINFO=CURDSK 06B7 77 MOV M,A 06B8 57 MOV D,A 06B9 2A6309 LHLD DLOG 06BC CD9404 CALL NOWRITE 06BF 5F MOV E,A 06C0 D5 PUSH D 06C1 CD9102 CALL SELECTDISK 06C4 E1 POP H ;RECALL DLOG VECTOR 06C5 D25A02 JNC SEL$ERROR 06C8 2D DCR L 06C9 C8 RZ 06CA 2A6309 LHLD DLOG 06CD 4D MOV C,L 06CE 44 MOV B,H ;CALL READY 06CF CD8104 CALL SET$DISK 06D2 226309 SHLD DLOG 06D5 C9 RET ; CURSELECT: 06D6 3A8D09 LDA LINFO 06D9 32A909 STA CURDSK 06DC C9 RET ; CLRMODNUM: 06DD AF XRA A 06DE 329B09 STA MODNUM 06E1 C31107 JMP RSEL1 ; ; CHECK CURRENT FCB TO SEE IF RESELECTION NECESSARY ; RESELECT: 06E4 3E80 MVI A,080H 06E6 47 MOV B,A 06E7 3D DCR A 06E8 4F MOV C,A 06E9 2AAA09 LHLD INFO 06EC 110700 LXI D,00007H 06EF EB XCHG 06F0 19 DAD D 06F1 7E MOV A,M 06F2 A0 ANA B 06F3 7E MOV A,M 06F4 A1 ANA C 06F5 77 MOV M,A 06F6 23 INX H 06F7 7E MOV A,M 06F8 A0 ANA B 06F9 329B09 STA MODNUM 06FC 7E MOV A,M 06FD A1 ANA C 06FE 77 MOV M,A 06FF CD2D04 CALL GETEXTA 0702 7E MOV A,M 0703 E61F ANI 01FH 0705 77 MOV M,A 0706 CD3504 CALL GETFCBB 0709 7E MOV A,M 070A A0 ANA B 070B CA1107 JZ RSEL1 070E 7E MOV A,M 070F A1 ANA C 0710 70 MOV M,B 0711 328F09 RSEL1: STA RECCNT 0714 210000 LXI H,00000H 0717 229D09 SHLD OLDDSK 071A 3EFF MVI A,0FFH 071C 32AC09 STA FCBDSK 071F 2AAA09 LHLD INFO 0722 7E MOV A,M 0723 E61F ANI 01FH 0725 3D DCR A 0726 328D09 STA LINFO 0729 FEFF CPI 0FFH 072B CA3507 JZ RSEL2 072E 7E MOV A,M 072F 329D09 STA OLDDSK 0732 CDD606 CALL CURSELECT 0735 CDAA06 RSEL2: CALL SELECT 0738 3E00 MVI A,000H 073A 2AAA09 LHLD INFO 073D 77 MOV M,A 073E C9 RET ; ; RESET DISK SYSTEM TO DISK 0 SEVERAL PARAMETERS RETURNED ; 073F 210000 FUNCT01:LXI H,00000H 0742 226309 SHLD DLOG 0745 AF XRA A 0746 32A909 STA CURDSK ;NOTE THAT USER CODE IS UNCHANGED 0749 3D DCR A 074A 329509 STA SELSTR 074D 218000 LXI H,TBUFF 0750 22A709 SHLD DMAAD ;DMAAD=TBUFF 0753 C3D304 JMP SETDATA ;TO DATA DMA ADDR ; ; SELECT DISK E=DISK NUMBER ; 0756 CDD606 FUNCT02:CALL CURSELECT 0759 C3AA06 JMP SELECT ; ; OPEN FILE DE=FCB ADDRESS A=DIRECTORY CODE ; 075C CDDD06 FUNCT03:CALL CLRMODNUM 075F CDDD05 CALL OPEN 0762 CDE304 CALL END$OF$DIR 0765 C8 RZ 0766 CD3D04 CALL GETFCBA 0769 7E MOV A,M 076A 3C INR A 076B C27207 JNZ OPENX1 076E 1B DCX D 076F 1B DCX D 0770 1A LDAX D 0771 77 MOV M,A 0772 E1 OPENX1: POP H 0773 0E40 MVI C,040H 0775 C9 RET ; ; READ SEQUENTIAL DE=FCB A=ERROR CODE ; 0776 CDE406 FUNCT04:CALL RESELECT 0779 C37206 JMP SEQDISKREAD ; ; RETURN CURRENT DISK HL=CURRENT DISK NUMBER ; 077C 3AA909 FUNCT05:LDA CURDSK 077F C35602 JMP STA$RET ; ; SET DMA ADDRESS DE=DMA ADDRESS ; SET SUBSEQUENT DMA ADDRESS TO INFO ; 0782 EB FUNCT06:XCHG ;WAS LHLD INFO 0783 22A709 SHLD DMAAD ;DMAAD=INFO 0786 C3D304 JMP SETDATA ;TO DATA DMA ADDRESS ; ; ARRIVE HERE AT END OF PROCESSING TO RETURN TO USER ; 0789 3AAD09 GOBACK: LDA SAVEC 078C FE0F CPI 00FH 078E DAB907 JC RETMON ;RESELECTION MAY HAVE TAKEN PLACE 0791 3A9109 LDA ZERO4 0794 32A909 STA CURDSK 0797 3AAC09 LDA FCBDSK 079A B7 ORA A 079B CAB907 JZ RETMON ;RESTORE DISK NUMBER 079E 2AAA09 LHLD INFO 07A1 3600 MVI M,000H ;FCB(0)=0 07A3 3A9D09 LDA OLDDSK 07A6 B7 ORA A 07A7 CAAB07 JZ GOBACK1 07AA 77 MOV M,A ;FCB(0)=FCBDSK 07AB 23 GOBACK1:INX H 07AC 3A9B09 LDA MODNUM 07AF B6 ORA M 07B0 77 MOV M,A 07B1 CD3504 CALL GETFCBB 07B4 3A8F09 LDA RECCNT 07B7 B6 ORA M 07B8 77 MOV M,A ; ; RETURN FROM THE DISK MONITOR ; 07B9 2A6109 RETMON: LHLD ENTSP ;GET OLD STACK POINTER 07BC F9 SPHL ;RESTORE THE STACK 07BD 2A7D08 LHLD ARET 07C0 7D MOV A,L 07C1 44 MOV B,H ;BA=HL=ARET 07C2 C9 RET ; RECORDOK1: 07C3 3E01 MVI A,001H 07C5 CDD107 CALL RECORDOK2 07C8 C35D04 JMP SETFCB ; READDIR4: 07CB 2A7509 LHLD ALLOCA 07CE C3D407 JMP READDIR5 RECORDOK2: 07D1 2A7709 LHLD ZERO5 READDIR5: 07D4 F5 PUSH PSW 07D5 3A8809 LDA ZERO2 07D8 47 MOV B,A 07D9 2F CMA 07DA 4F MOV C,A 07DB 3A9609 LDA ARECORD 07DE 5F MOV E,A 07DF A0 ANA B 07E0 329E09 STA SOMREC 07E3 7B MOV A,E 07E4 A1 ANA C 07E5 329609 STA ARECORD 07E8 229F09 SHLD RECADR 07EB CDAA04 CALL RDDIR2 07EE 226509 SHLD DMAADDR 07F1 2A9F09 LHLD RECADR 07F4 119509 LXI D,SELSTR 07F7 0E04 MVI C,004H 07F9 F1 POP PSW 07FA F5 PUSH PSW 07FB FE04 CPI 004H 07FD D20708 JNC RECOK2 0800 CD7D02 CALL RECOK8 0803 CA2008 JZ RECOK3 0806 AF XRA A RECOK2: 0807 110400 LXI D,00004H 080A 2A9F09 LHLD RECADR 080D 19 DAD D 080E 3E02 MVI A,002H 0810 CD4808 CALL RECOK7 0813 2A9F09 LHLD RECADR 0816 119509 LXI D,SELSTR 0819 0E04 MVI C,004H 081B CD8702 CALL MOVE 081E 3600 MVI M,000H 0820 3A9E09 RECOK3: LDA SOMREC 0823 3C INR A 0824 118000 LXI D,TBUFF 0827 2180FF LXI H,0FF80H 082A 19 RECOK4: DAD D 082B 3D DCR A 082C C22A08 JNZ RECOK4 082F EB XCHG 0830 2A6509 LHLD DMAADDR 0833 19 DAD D 0834 F1 POP PSW 0835 FE03 CPI 003H 0837 C23E08 JNZ BNKMOV 083A 226709 SHLD BUFFA 083D C9 RET ; 083E EB BNKMOV: XCHG 083F 2AA709 LHLD DMAAD 0842 018000 LXI B,TBUFF 0845 C34B0B JMP @MOV ;MOVE BETWEEN BANKS ; 0848 F5 RECOK7: PUSH PSW 0849 CD1803 CALL SEEK 084C F1 POP PSW 084D 3D DCR A 084E F4F102 CP RDBUFF 0851 110400 LXI D,00004H 0854 2A9F09 LHLD RECADR 0857 19 DAD D 0858 23 INX H 0859 23 INX H 085A 11A109 LXI D,TRACK 085D 0E04 MVI C,004H 085F C38702 JMP MOVE ; ; STORAGE LOCATIONS AND MESSAGES ; 0862 00 COMPCOL:DB 000H 0863 0D0A MSBDOS: DB 00DH,00AH 0865 42444F5320 DB 'BDOS ERR: $' 0870 53656C6563MSSLCT: DB 'Select$' 0877 5065726D2EMSPERM: DB 'Perm.$' 087D 0000 ARET: DW 0000H ; 087F 00 FCBT: DB 000H 0880 43504D3320 DB 'CPM3 SYS' 088B 0000000000 DB 0,0,0,0,0,0,0,0 0893 0000000000 DB 0,0,0,0,0,0,0,0 089B 0000000000 DB 0,0,0,0,0,0,0,0 ; 08A3 0D0A MSOPEN: DB 00DH,00AH 08A5 43504D4C44 DB 'CPMLDR error: failed to open CPM3.SYS' 08CB 0D0A DB 00DH,00AH 08CD 24 DB '$' ; 08CE 0D0A MSREAD: DB 00DH,00AH 08D0 43504D4C44 DB 'CPMLDR error: failed to read CPM3.SYS' 08F6 0D0A DB 00DH,00AH 08F8 24 DB '$' ; 08F9 0D MSBANR: DB 00DH 08FA 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 0900 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 0906 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 090C 0A0A0A0A0A DB 00AH,00AH,00AH,00AH,00AH,00AH 0912 43502F4D20 DB 'CP/M V3.0 Loader' 0922 0D0A DB 00DH,00AH 0924 436F707972 DB 'Copyright (C) 1982, Digital Research' 0948 0D0A DB 00DH,00AH 094A 24 DB '$' 094B 3032313138 DB '021182' 0951 00000000 DB 0,0,0,0 STACK1: ;STACK WALKS OVER THE BANNER ; 0955 00 HEDR1: DB 000H 0956 00 HEDR2: DB 000H 0957 00 HEDR3: DB 000H 0958 00 HEDR4: DB 000H 0959 0000000000HEDR5: DB 0,0,0,0,0,0,0,0 0961 0000 ENTSP: DB 0,0 0963 0000 DLOG: DW 0000H 0965 0000 DMAADDR:DW 0000H 0967 0000 BUFFA: DW 0000H 0969 0000 DW 0000H 096B 0000 CURTRKA:DW 0000H 096D 0000 CURRECA:DW 0000H 096F 0000 BUFFB: DW 0000H 0971 0000 DW 0000H 0973 0000 DW 0000H 0975 0000 ALLOCA: DW 0000H 0977 0000000000ZERO5: DB 0,0,0,0,0 097C 0000 SECTPT: DW 0000H 097E 00 BLKSHF: DB 000H 097F 00 BLKMSK: DB 000H 0980 00 EXTMSK: DB 000H 0981 0000 MAXALL: DW 0000H 0983 0000 DIRMAX: DW 0000H 0985 0000 OFFSET: DW 0000H 0987 00 ZERO1: DB 000H 0988 00 ZERO2: DB 000H 0989 00 MSKVREC:DB 000H 098A 00 ZERO3: DB 000H 098B 0000 TRANV: DW 0000H 098D 00 LINFO: DB 000H 098E 00 DMPOS: DB 000H 098F 00 RECCNT: DB 000H 0990 00 SINGLE: DB 000H 0991 00 ZERO4: DB 000H 0992 00 RCOUNT: DB 000H 0993 00 EXTVAL: DB 000H 0994 00 VRECORD:DB 000H 0995 FF SELSTR: DB 0FFH 0996 0000 ARECORD:DW 0000H 0998 00 SHIFTED:DB 000H 0999 0000 SHAREC: DW 0000H 099B 00 MODNUM: DB 000H 099C 00 DPTR: DB 000H 099D 00 OLDDSK: DB 000H 099E 00 SOMREC: DB 000H 099F 0000 RECADR: DW 0000H 09A1 0000 TRACK: DW 0000H 09A3 0000 SAVSEC: DW 0000H 09A5 00 COLUMN: DB 000H ;COLUMN NUMBER 09A6 24 DOLLAR: DB 024H ;$ 09A7 8000 DMAAD: DB 080H,000H ;DMA ADDRESS 09A9 00 CURDSK: DB 000H ;CURRENT DISK 09AA 0000 INFO: DW 0000H ;MESSAGE LOCATION 09AC 00 FCBDSK: DB 000H 09AD 00 SAVEC: DB 000H 09AE 0000 DCNT: DW 0000H 09B0 0000 SEARCHA:DW 0000H 09B2 00 SEARCHL:DB 000H ; 09B3 DS 80 LSTACK: ; 0A03 DS 134D ;F1LL OUT TO THE END OF THE BLOCK ; 0A89 END