; WARD CHRISTENSON'S FMAP FROM CP/M UG VOL 8 ; MODIFIED BY TREVOR MARSHALL ; UNI W A ; DEPT ELEC ENG ; TO REFLECT HIS MODIFICATIONS ON THE ; CACHE T7 DISK ; AND TO ALLOW COMPATIBILITY WITH CDOS ; (UP TO 512 ENTRIES) ; 0100 ORG 100H ; JMP START ;SKIP PROGRAM ID 0100 CD1C01 CALL START 0103 43444F5320ID: DB 'CDOS 2.35 FMAP Sept 80',0DH,0AH,'$' ;SORTED DIRECTORY MAP PROGRAM ;WITH OPTION OF WRITING FILE OF NAMES ; ;FMAP FN.FT OR JUST MAP ;FMAP FN.FT F TO WRITE A FILE ;ALLOWS '*' OR '?' TYPE SPECIFICATIONS 005C = FCB EQU 5CH ;SYSTEM FCB ;SAVE THE STACK 011C D1 START POP D 011D 0E09 MVI C,9 011F CD0500 CALL BDOS 0122 210000 LXI H,0 0125 39 DAD SP ;H=STACK 0126 227204 SHLD STACK ;SAVE IT 0129 317204 LXI SP,STACK ;GET NEW STACK ;SAVE FILE WRITE REQUEST CHAR 012C 3A6D00 LDA FCB+17 012F 327B04 STA FILESW ;NO FCB SPECIFIED? 0132 215D00 LXI H,FCB+1 0135 7E MOV A,M 0136 FE20 CPI ' ' 0138 C24401 JNZ GOTFCB ;NO FCB - MAKE FCB ALL '?' 013B 060B MVI B,11 ;FN+FT COUNT 013D 363F QLOOP MVI M,'?' ;STORE '?' IN FCB 013F 23 INX H 0140 05 DCR B 0141 C23D01 JNZ QLOOP ;MOD #2 0144 3E3F GOTFCB MVI A,'?' 0146 326800 STA 68H ;LOOK UP THE FCB IN THE DIRECTORY 0149 0E11 MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC 014B 115C00 LXI D,FCB 014E CD0500 CALL BDOS ;READ FIRST 0151 3C INR A ;WERE THERE ANY? 0152 32BA03 STA TEMP ;SAVE 0155 C27A01 JNZ PRTTL1 ;GOT SOME - PRT TITLE, CONT 0158 116101 LXI D,NONMSG 015B CD7003 CALL WRCON 015E C3C603 JMP EXIT 0161 2A2A2A204ENONMSG DB '*** No Entries Found ***$' ; MOD #3 017A 3A7B04 PRTTL1 LDA FILESW 017D FE51 CPI 'Q' 017F CA9501 JZ JMP1 0182 FE44 CPI 'D' 0184 CA9501 JZ JMP1 0187 FE4D CPI 'M' 0189 CA9501 JZ JMP1 ;PRINT TITLE 018C 119B01 PRTTL LXI D,TTL 018F CD7003 CALL WRCON 0192 CDAF03 CALL CR 0195 3ABA03 JMP1: LDA TEMP ;RELOAD EXTENT 0198 C3CB01 JMP SOME 019B 46494C454ETTL DB 'FILENAME TYP EX RC -----EXTENT-----$' ;READ MORE DIRECTORY ENTRIES 01BF 0E12 MOREDIR MVI C,FSRCHN ;SEARCH NEXT 01C1 115C00 LXI D,FCB 01C4 CD0500 CALL BDOS ;READ DIR ENTRY 01C7 3C INR A ;CHECK FOR END (0FFH) 01C8 CAF301 JZ SPRINT ;NO MORE - SORT & PRINT ;POINT TO DIRECTORY ENTRY 01CB 3D SOME DCR A ;UNDO PREV 'INR A' 01CC E603 ANI 3 ;MAKE MODULUS 4 01CE 87 ADD A ;MULTIPLY... 01CF 87 ADD A ;..BY 32 BECAUSE 01D0 87 ADD A ;..EACH DIRECTORY 01D1 87 ADD A ;..ENTRY IS 32 01D2 87 ADD A ;..BYTES LONG 01D3 218100 LXI H,81H ;POINT TO BUFFER ;(SKIP TO FN/FT) 01D6 85 ADD L ;POINT TO ENTRY 01D7 6F MOV L,A ;SAVE (CAN'T CARRY TO H) ;MOVE ENTRY TO TABLE 01D8 EB XCHG ;ENTRY TO DE 01D9 2A7504 LHLD NEXTT ;NEXT TABLE ENTRY TO HL 01DC 061F MVI B,31 ;ENTRY LENGTH 01DE 1A TMOVE LDAX D ;GET ENTRY CHAR 01DF 77 MOV M,A ;STORE IN TABLE 01E0 13 INX D 01E1 23 INX H 01E2 05 DCR B ;MORE? 01E3 C2DE01 JNZ TMOVE 01E6 227504 SHLD NEXTT ;SAVE UPDATED TABLE ADDR 01E9 3A7804 LDA COUNT ;GET PREV COUNT 01EC 3C INR A 01ED 327804 STA COUNT 01F0 C3BF01 JMP MOREDIR ;SORT AND PRINT 01F3 3A7804 SPRINT LDA COUNT ;INIT THE ORDER TABLE 01F6 219F04 LXI H,ORDER 01F9 119F08 LXI D,TABLE 01FC 011F00 LXI B,31 ;ENTRY LENGTH 01FF 73 BLDORD MOV M,E ;SAVE LO ORD ADDR 0200 23 INX H 0201 72 MOV M,D ;SAVE HI ORD ADDR 0202 23 INX H 0203 EB XCHG ;TABLE ADDR TO HL 0204 09 DAD B ;POINT TO NEXT ENTRY 0205 EB XCHG 0206 3D DCR A ;MORE? 0207 C2FF01 JNZ BLDORD ;..YES 020A 3A7804 LDA COUNT ;GET COUNT 020D 327904 STA SCOUNT ;SAVE AS # TO SORT 0210 3D DCR A ;ONLY 1 ENTRY? 0211 CA4102 JZ DONE ;..YES, SO SKIP SORT 0214 AF SORT XRA A ;GET A ZERO 0215 327A04 STA SWITCH ;SHOW NONE SWITCHED 0218 3A7904 LDA SCOUNT ;GET COUNT 021B 3D DCR A ;USE 1 LESS 021C 32BA03 STA TEMP ;SAVE # TO COMPARE 021F 327904 STA SCOUNT ;SAVE HIGHEST ENTRY 0222 CA4102 JZ DONE ;EXIT IF NO MORE 0225 219F04 LXI H,ORDER ;POINT TO ORDER TABLE 0228 CD2E04 SORTLP CALL COMPR ;COMPARE 2 ENTRIES 022B FC4004 CM SWAP ;SWAP IF NOT IN ORDER 022E 23 INX H ;BUMP ORDER 022F 23 INX H ;..TABLE POINTER 0230 3ABA03 LDA TEMP ;GET COUNT 0233 3D DCR A 0234 32BA03 STA TEMP 0237 C22802 JNZ SORTLP ;CONTINUE ;ONE PASS OF SORT DONE 023A 3A7A04 LDA SWITCH ;ANY SWAPS DONE? 023D B7 ORA A 023E C21402 JNZ SORT ;SORT IS ALL DONE - PRINT ENTRIES 0241 219F04 DONE LXI H,ORDER 0244 227504 SHLD NEXTT ; MOD #4 0247 3A7B04 LDA FILESW 024A FE20 CPI ' ' 024C CA7802 JZ ENTRY ;IF WRITING A FILE, OPEN THE FILE ; LDA FILESW ; CPI 'F' ; JNZ ENTRY 024F 117E04 LXI D,MYFCB 0252 0E13 MVI C,ERASE 0254 CD0500 CALL BDOS 0257 117E04 LXI D,MYFCB 025A 0E16 MVI C,FMAKE ;MAKE THE FILE 025C CD0500 CALL BDOS 025F 3C INR A 0260 C27802 JNZ ENTRY ;MAKE ERROR 0263 CDBB03 CALL ERXIT 0266 2B2B46494C DB '++FILE MAKE ERROR$' ;PRINT AN ENTRY 0278 0E0B ENTRY MVI C,CONST ;CK STATUS OF KB 027A CD0500 CALL BDOS ;ANY KEY PRESSED? 027D 3D DCR A 027E CAC103 JZ ABORT ;YES, ABORT 0281 2A7504 LHLD NEXTT ;GET ORDER TABLE POINTER 0284 5E MOV E,M ;GET LO ADDR 0285 23 INX H 0286 56 MOV D,M ;GET HI ADDR 0287 23 INX H 0288 227504 SHLD NEXTT ;SAVE UPDATED TABLE POINTER ; MOD #5 028B 210B00 LXI H,0BH 028E 19 DAD D 028F 7E MOV A,M 0290 327704 STA NEWONE 0293 EB XCHG ;TABLE ENTRY TO HL 0294 3A7B04 LDA FILESW 0297 FE44 CPI 'D' 0299 CC7503 CZ ADDSUB 029C 3A7B04 LDA FILESW 029F FE4D CPI 'M' 02A1 F5 PUSH PSW 02A2 CC7503 CZ ADDSUB 02A5 F1 POP PSW 02A6 CC8E03 CZ ADDSUB2 02A9 0608 MVI B,8 ;FILE NAME LENGTH 02AB CD9D03 CALL TYPEIT ;TYPE FILENAME 02AE CD1904 CALL PERIOD ;SPACE AFTER FN 02B1 0603 MVI B,3 ;GET THE FILETYPE 02B3 CD9D03 CALL TYPEIT ;MOD #6 02B6 3A7B04 LDA FILESW 02B9 FE44 CPI 'D' 02BB CC8E03 CZ ADDSUB2 02BE CD2104 CALL FILECR 02C1 7E MOV A,M 02C2 CD3F03 CALL XOB 02C5 23 INX H ;SKIP EXTENT 02C6 23 INX H ;SKIP 02C7 23 INX H ;UNUSED 02C8 7E MOV A,M ;GET REC COUNT 02C9 3D DCR A ;FUDGE 02CA 1F RAR ;DIVIDE 02CB 1F RAR ;..BY 8 02CC 1F RAR 02CD E61F ANI 1FH ;DELETE GARBAGE 02CF 3C INR A ;MAKE RELATIVE TO 1, NOT 0 02D0 47 MOV B,A ;SAVE AS # EXTENTS 02D1 7E MOV A,M ;RELOAD RECORD COUNT 02D2 CD3F03 CALL XOB ;PRINT RECORD COUNT 02D5 23 INX H ;SKIP RECORD COUNT 02D6 0E00 MVI C,0 ;FOR EXTENT SKIP CTL 02D8 7E EXTLP MOV A,M ;GET EXTENT BYTE 02D9 B7 ORA A ;EMPTY? 02DA CAEC02 JZ ENDEXT ;..YES 02DD CD4503 CALL XO ;..NO, PRINT IT 02E0 0C INR C ;INCR COUNT 02E1 79 MOV A,C ;TIME TO SPACE? 02E2 E603 ANI 3 02E4 CCAA03 CZ SPACE 02E7 23 INX H ;POINT TO NEXT CHR 02E8 05 DCR B ;MORE IN EXTENT? 02E9 C2D802 JNZ EXTLP ;YES ;BUMP TOTAL FILE COUNT 02EC 3A7404 ENDEXT LDA NFILE ;GET # FILES 02EF 3C INR A ;BUMP 02F0 27 DAA ;MAKE DECIMAL 02F1 327404 STA NFILE ;SAVE IT BACK 02F4 CDAF03 CALL CR ;END, TYPE C/R ;SEE IF MORE ENTRIES 02F7 3A7804 LDA COUNT 02FA 3D DCR A 02FB 327804 STA COUNT 02FE C27802 JNZ ENTRY ;YES, MORE ; MOD #7 0301 3A7B04 LDA FILESW 0304 FE20 CPI ' ' 0306 CA0E03 JZ NXT1 0309 3E46 MVI A,'F' 030B 327B04 STA FILESW ;ALL DONE - PRINT # FILES 030E 3A7404 NXT1: LDA NFILE 0311 CD3F03 CALL XOB 0314 113903 LXI D,NMSG 0317 CD7003 CALL WRCON ;CLOSE FILE IF NECESSARY 031A 3A7B04 LDA FILESW ; MOD #8 ; CPI 'F' ; JNZ EXIT 031D FE20 CPI ' ' 031F CAC603 JZ EXIT 0322 AF XRA A 0323 327704 STA NEWONE ; 0326 3E1A MVI A,'Z'-40H ;EOF CHAR 0328 CDCB03 CALL FILCHR ;WRITE IT 032B CDF103 CALL WRSEC ;WRITE FINAL SECTOR 032E 117E04 LXI D,MYFCB 0331 0E10 MVI C,FCLOSE 0333 CD0500 CALL BDOS 0336 C3C603 JMP EXIT 0339 46494C4553NMSG DB 'FILES$' ;HEX OUTPUT W/BLANK 033F CD4503 XOB CALL XO 0342 C3AA03 JMP SPACE ;HEX OUTPUT 0345 F5 XO PUSH PSW ;SAVE CHAR 0346 1F RAR 0347 1F RAR 0348 1F RAR 0349 1F RAR 034A CD4E03 CALL NIBBL ;PRINT LEFT NIBBLE 034D F1 POP PSW ;GET VALUE BACK 034E E60F NIBBL ANI 0FH ;ISOLATE NIBBLE 0350 FE0A CPI 10 ;NUMBER? 0352 DA5703 JC XNUM ;YES 0355 C607 ADI 7 ;FUDGE ALPHA HEX 0357 C630 XNUM ADI '0' ;MAKE PRINTABLE ;TYPE CHAR IN A 0359 C5 TYPE PUSH B 035A D5 PUSH D 035B E5 PUSH H 035C 5F MOV E,A ;MOD #9 035D 0E02 MVI C,WRCHR 035F 3A7B04 LDA FILESW 0362 FE46 CPI 'F' 0364 CA6903 JZ NXT2 0367 FE20 CPI ' ' 0369 CC0500 NXT2 CZ BDOS 036C E1 POP H 036D D1 POP D 036E C1 POP B 036F C9 RET 0370 0E09 WRCON MVI C,PRINT 0372 C30500 JMP BDOS ; MOD #10 0375 3E24 ADDSUB MVI A,'$' 0377 CDCB03 CALL L03B7 037A 3E31 MVI A,'1' 037C CDCB03 CALL L03B7 037F 3E20 MVI A,' ' 0381 CDCE03 CALL L03BA 0384 3E24 MVI A,'$' 0386 CDCB03 CALL L03B7 0389 3E32 MVI A,'2' 038B C3CB03 JMP L03B7 038E 3E20 ADDSUB2 MVI A,' ' 0390 CDCE03 CALL L03BA 0393 3E24 MVI A,'$' 0395 CDCB03 CALL L03B7 0398 3E33 MVI A,'3' 039A C3CB03 JMP L03B7 ; 039D 7E TYPEIT MOV A,M 039E CDCB03 CALL FILCHR ;TO DISK IF REQ'D 03A1 CD5903 CALL TYPE 03A4 23 INX H 03A5 05 DCR B 03A6 C29D03 JNZ TYPEIT 03A9 C9 RET 03AA 3E20 SPACE MVI A,' ' 03AC C35903 JMP TYPE 03AF 3E0D CR MVI A,0DH 03B1 CD5903 CALL TYPE 03B4 3E0A MVI A,0AH 03B6 CD5903 CALL TYPE 03B9 C9 RET ;CR MVI E,13 ;PRINT ; MVI C,2 ;C/R ; CALL BDOS ; MVI E,10 ;LF ; MVI C,2 ; JMP BDOS 03BA TEMP DS 1 ;SAVE DIR ENTRY ;ERROR EXIT 03BB D1 ERXIT POP D ;GET MSG 03BC 0E09 MVI C,PRINT 03BE C3C303 JMP CALLB ;PRINT MSG, EXIT ;ABORT - READ CHAR ENTERED 03C1 0E01 ABORT MVI C,RDCHR 03C3 CD0500 CALLB CALL BDOS ;DELETE THE CHAR ;FALL INTO EXIT ;EXIT - ALL DONE , RESTORE STACK 03C6 2A7204 EXIT LHLD STACK ;GET OLD STACK 03C9 F9 SPHL ;MOVE TO STACK 03CA C9 RET ;..AND RETURN ;ROUTINES FOR CREATING FILE ; ; MOD #11 ;WRITE CHAR IN A TO FILE ;(SAVES ALL REGS INCLUDING A) L03B7: ; 03CB FE20 FILCHR CPI ' ' 03CD C8 RZ ;DON'T WRITE BLANKS 03CE F5 L03BA: PUSH PSW 03CF 3A7B04 LDA FILESW ;WRITING A FILE? ; CPI 'F' ; JNZ NOFILE 03D2 FE20 CPI ' ' 03D4 CAEF03 JZ NOFILE 03D7 3A7704 LDA NEWONE 03DA B7 ORA A 03DB C2EF03 JNZ NOFILE ; 03DE F1 POP PSW ;GET CHAR 03DF F5 PUSH PSW ;SAVE IT BACK 03E0 E5 PUSH H 03E1 2A7C04 LHLD BUFAD ;CURRENT BUFFER ADDR 03E4 77 MOV M,A 03E5 23 INX H 03E6 227C04 SHLD BUFAD 03E9 7C MOV A,H ;SEE IF FULL BUFF 03EA 3D DCR A 03EB CCF103 CZ WRSEC ;YES, WRITE SECTOR 03EE E1 POP H 03EF F1 NOFILE POP PSW ;RESTORE CHAR 03F0 C9 RET ;WRITE A SECTOR 03F1 C5 WRSEC PUSH B 03F2 D5 PUSH D 03F3 117E04 LXI D,MYFCB 03F6 0E15 MVI C,FWRTE 03F8 CD0500 CALL BDOS 03FB B7 ORA A 03FC CA1004 JZ WROK 03FF CDBB03 CALL ERXIT 0402 2B2B575249 DB '++WRITE ERROR$' 0410 218000 WROK LXI H,80H ;START OF BUFF 0413 227C04 SHLD BUFAD 0416 D1 POP D 0417 C1 POP B 0418 C9 RET ;TYPE A PERIOD INTO THE FILE 0419 3E2E PERIOD MVI A,'.' ;GET PERIOD 041B CDCB03 CALL FILCHR ;WRITE TO FILE 041E C3AA03 JMP SPACE ;WRITE CR/LF INTO FILE 0421 3E0D FILECR MVI A,13 0423 CDCB03 CALL FILCHR 0426 3E0A MVI A,10 0428 CDCB03 CALL FILCHR 042B C3AA03 JMP SPACE ;COMPARE ROUTINE FOR SORT 042E E5 COMPR PUSH H ;SAVE TABLE ADDR 042F 5E MOV E,M ;LOAD LO 0430 23 INX H 0431 56 MOV D,M ;LOAD HI 0432 23 INX H 0433 4E MOV C,M 0434 23 INX H 0435 46 MOV B,M ;BC, DE NOW POINT TO ENTRIES TO BE COMPARED 0436 EB XCHG 0437 0A CMPLP LDAX B 0438 BE CMP M 0439 23 INX H 043A 03 INX B 043B CA3704 JZ CMPLP 043E E1 POP H 043F C9 RET ;COND CODE TELLS ALL ;SWAP ENTRIES IN THE ORDER TABLE 0440 3E01 SWAP MVI A,1 0442 327A04 STA SWITCH ;SHOW A SWAP WAS MADE 0445 4E MOV C,M 0446 23 INX H 0447 E5 PUSH H ;SAVE TABLE ADDR+1 0448 46 MOV B,M 0449 23 INX H 044A 5E MOV E,M 044B 71 MOV M,C 044C 23 INX H 044D 56 MOV D,M 044E 70 MOV M,B 044F E1 POP H 0450 72 MOV M,D 0451 2B DCX H ;BACK POINTER TO CORRECT LOC'N 0452 73 MOV M,E 0453 C9 RET 0454 DS 30 ;STACK AREA 0472 STACK DS 2 ;SAVE OLD STACK HERE 0474 00 NFILE DB 0 ;NUMBER OF FILES PRINTED ; ; BDOS EQUATES ; 0001 = RDCHR EQU 1 ;READ CHAR FROM CONSOLE 0002 = WRCHR EQU 2 ;WRITE CHR TO CONSOLE 0009 = PRINT EQU 9 ;PRINT CONSOLE BUFF 000B = CONST EQU 11 ;CHECK CONS STAT 000F = FOPEN EQU 15 ;0FFH=NOT FOUND 0010 = FCLOSE EQU 16 ; " " 0011 = FSRCHF EQU 17 ; " " 0012 = FSRCHN EQU 18 ; " " 0013 = ERASE EQU 19 ;NO RET CODE 0014 = FREAD EQU 20 ;0=OK, 1=EOF 0015 = FWRTE EQU 21 ;0=OK, 1=ERR, 2=?, 255=NO DIR SPC 0016 = FMAKE EQU 22 ;255=BAD 0017 = FREN EQU 23 ;255=BAD 001A = FDMA EQU 26 0005 = BDOS EQU 5 0000 = REBOOT EQU 0 0475 9F08 NEXTT DW TABLE ;NEXT TABLE ENTRY 0477 NEWONE DS 1 ;******I THINK 0478 00 COUNT DB 0 ;ENTRY COUNT 0479 00 SCOUNT DB 0 ;# TO SORT 047A 00 SWITCH DB 0 ;SWAP SWITCH FOR SORT 047B FILESW DS 1 ;'F' IF WRITING FILE 047C 8000 BUFAD DW 80H ;OUTPUT ADDR 047E 004E414D45MYFCB DB 0,'NAMES SUB',0 048B DS 19 049E 00 DB 0 ;MODIFIED TABLE SIZE FOR 512 DIRECTORY ENTRIES 049F ORDER DS 1024 ;ORDER TABLE 089F = TABLE EQU $ ;READ ENTRIES IN HERE 089F END 100H