home *** CD-ROM | disk | FTP | other *** search
- ; Super File Find Version 1.2
- ; 06/20/84
- ;
- ; by
- ; G.B. Shaffstall SYSOP
- ; Lakewood RCP/M System
- ;
- ; To write Super File Find I started with SD-81 so let me give some
- ; credit that is due to the many people that worked on it in the past.
- ;
- ; This utility only works with CP/M 2.0 and upwards.
- ;
- ; Super File Find allows full wildcard searches of the DIRECTORYS and
- ; ALL LIBRARY files on your system for a requested file, starting at A:
- ; User 0 working it's way up and across all users and drives until
- ; a trapped I/O error causes exit just as SD does.
- ;
- ; If you prefer you can specify a single drive to be searched by
- ; including the drive name as a prefix to the search file.
- ;
- ; Entering SFF<cr> will display a brief help message.
- ;
- ; The USER AREA PATCH TABLE is the same as in SD with one exception,
- ; If you put a 0FFH in a user location that drive will be skipped.
- ;
- ; If you have a large system with many .LBR files on it you can patch
- ; lable QUIET to a 0 to provide the message "Searching <dn>: User <num>"
- ; so the user will know that the program is still running. With any
- ; other value in this location the message "+++ NO FILE ON <dn>:" will
- ; be printed as the program switches drives and no files were found.
- ;
- ; At the current time there is no PAGE PAUSE in it but unless something
- ; like SFF *.* is used this should be no problem..
- ;
- ; If you are running BYELOW enter the address of your BDOS into BDOLOC.
- ;
- CR: EQU 0DH
- LF: EQU 0AH
- ESC: EQU 1BH
- ;
- ; BDOS EQUATES
- ;
- RDCHR: EQU 1 ;READ CHAR FROM CONSOLE
- WRCHR: EQU 2 ;WRITE CHAR TO CONSOLE
- PRINTS: EQU 9 ;PRINT STRING
- CONST: EQU 11 ;CHECK CONS STAT
- RESET: EQU 13 ;RESET DISK SYSTEM
- SELDSK: EQU 14 ;SELECT DISK
- OPEN: EQU 15 ;0FFH=NOT FOUND
- CLOSE: EQU 16 ; " "
- SEARCH: EQU 17 ; " "
- NEXT: EQU 18 ; " "
- READ: EQU 20 ;NOT 0 = EOF
- WRITE: EQU 21 ;NOT 0 = DISK FULL
- MAKE: EQU 22 ;0FFH = DIRECTORY FULL
- CURDSK: EQU 25 ;GET CURRENTLY LOGGED DISK NAME
- SETDMA: EQU 26 ;SET CURRENT DMA
- GALLOC: EQU 27 ;GET ADDRESS OF ALLOCATION VECTOR
- CURDPB: EQU 31 ;GET CURRENT DISK PARAMETERS
- CURUSR: EQU 32 ;GET CURRENTLY LOGGED USER NUMBER (2.X ONLY)
- ;
- ;
- BASE EQU 0 ;DEFAULT TO 0
- TPA EQU 100H
- FCB EQU BASE+5CH
- BDOS EQU BASE+5
- ;
- ORG TPA
- ;
- ;
- ;
- ;***********************************************************************
- ;
- ; BEGIN EXECUTABLE PROGRAM CODE *
- ;
- ;***********************************************************************
- ;
- ;
- JMP START
- ;
- ;
- ; DRIVE CODE/USER AREA LOOKUP TABLE
- ;
- ; NOTE THAT THE LODRV-HIDRV TABLE IS INCLUDED HERE FULLY CONFIGURED.
- ; FOR YOUR OWN USE, YOU SHOULD CHANGE THE MAXIMUM USER AREAS AS APPRO-
- ; PRIATE FOR EACH DRIVE ON YOUR SYSTEM. NOTE THAT THERE ARE ONLY 16
- ; USER AREAS AVAILABLE UNDER CP/M 2, SO THE HIGHEST LEGAL USER AREA YOU
- ; CAN SPECIFY IS 15 (RANGE 0-15 = 16 AREAS). THE PROGRAM WILL CONVERT
- ; ANYTHING OVER 15 INTO MOD 15. ENTER AN 0FFH TO CAUSE A DRIVE TO BE
- ; SKIPPED ON SEARCH.
- ;
- LODRV: EQU $ ;MARK BEGINNING OF DRIVE/USER TABLE
- ;
- DB 15 ;MAXIMUM USER AREA FOR DRIVE A
- DB 15 ; " " " " " B
- DB 0FFH ; " " " " " C
- DB 0FFH ; " " " " " D
- DB 0FFH ; " " " " " E
- DB 0FFH ; " " " " " F
- DB 0FFH ; " " " " " G
- DB 0FFH ; " " " " " H
- DB 0FFH ; " " " " " I
- DB 0FFH ; " " " " " J
- DB 0FFH ; " " " " " K
- DB 0FFH ; " " " " " L
- DB 0FFH ; " " " " " M
- DB 0FFH ; " " " " " N
- DB 0FFH ; " " " " " O
- DB 0FFH ; " " " " " P
- ;
- HIDRV: EQU $ ;MARK END OF DRIVE/USER TABLE
- QUIET DB 0FFH ;PATCH TO NON ZERO FOR QUIET MODE
- ;
- ; IF RUNNING BYELOW ENTER ADDRESS THE OF YOUR BDOS INTO BDOLOC.
- ; (NOTE THE SWAP SUBROUTINE WILL CURRENTLY SET THE L REG TO 9.)
- ;
- BDOLOC DW 0
- ;
- VERNAME DB CR,LF,'Super File Find v1.2 - 06/20/84'
- db cr,lf,'A Total Wild-Card FILEFIND including Libraries.'
- db cr,lf,'Syntax to search all Drives and User Areas'
- db cr,lf,'is SFF <Filename.type>'
- db cr,lf,'Examples:'
- db cr,lf,'A0>SFF *.AQ6 or A0>SFF MBOOT*.*',cr,lf
- db cr,lf,'To search a single drive and all User Areas'
- db cr,lf,'Use SFF <Driveneme:Filename.type>'
- db cr,lf,'Examples:'
- db cr,lf,'A0>SFF B:MDM???.* or A0>SFF D:KP*.*',cr,lf+80h
- PROCES db cr,lf,'Searching '
- PROC1 db ' : User',' '+80H
- SIGNON db 'Use Ctrl/C to Abor','t'+80H
- ;
- START: LXI H,0
- DAD SP ;HL=OLD STACK
- SHLD STACK ;SAVE IT
- LXI SP,STACK ;GET NEW STACK
- XRA A
- STA FNDFLG ;CLEAR file found flag
- STA NEWUSR ;MAKE NEW USER = 0
- STA BASUSR ;DUPLICATE IT IF MULTI-DISK MODE
- MVI C,12 ;GET AND SAVE THE CP/M VERSION #
- CALL BDOS
- MOV A,L
- STA VERFLG
- STA DOPFLG ;DO NOT ALLOW MULTI-DRIVE YET
- CPI 20H ;SET CARRY IF CP/M 1.4
- JC VERERR ;EXIT ON EARLIER THAN 2.0
- LXI H,FCB+1 ;POINT TO NAME
- MOV A,M ;ANY SPECIFIED?
- CPI ' '
- JZ NONERR ;so print help info
- PUSH H ;SAVE FCB ADDRESS
- LXI D,SEARN ;POINT TO SEARCH NAME HOLDING AREA
- MVI B,11 ;SIZE OF FILE NAME, TYPE
- CALL MOVE ;MOVE IT
- POP H ;RESTORE FCB ADDRESS
- MVI E,0FFH ;GET CURRENT USER NUMBER
- MVI C,CURUSR
- CALL CPM
- STA OLDUSR ;INITIALIZE STARTUP USER NUMBER
- CLNON: MVI C,CURDSK
- CALL CPM ;GET CURRENT DISK NR
- STA OLDDSK ;SAVE FOR RESET IF NEEDED
- LXI H,FCB
- MOV A,M ;GET DRIVE NAME FOR DIRECTORY SEARCH
- ORA A ;ANY SPECIFIED?
- JNZ START2 ;YES SKIP NEXT ROUTINE
- XRA A
- STA DOPFLG ;OK LET MULTI-DRIVE IN
- MVI A,1 ;OTHERWISE, GET DISK "A"
- START2: MOV M,A ;PUT THE ABSOLUTE DRIVE CODE IN
- ;..DIRECTORY FCB
- CKREST: LXI D,SIGNON
- CALL PRINT
- LDA DOPFLG
- ORA A
- CZ SWAPEM ;SWAP BDOS ERROR VECTOR TABLES
- ;
- ;
- ; VALIDATE DRIVE CODE AND USER AREA NUMBERS FROM THE DRIVE TABLE.
- ;
- NOOPT: LXI D,DREMSG ;GET THE DRIVE/USER ERROR MESSAGE
- PUSH D
- LDA FCB ;GET DIRECTORY DRIVE CODE
- DCR A ;NORMALIZE TO RANGE OF 0-15
- CPI HIDRV-LODRV ;COMPARE WITH MAXIMUM DRIVES ON-LINE
- JNC ERXIT ;TAKE DRIVE ERROR EXIT IF OUT OF RANGE
- LXI H,USRMSG ;SWITCH TO USER # ERROR MESSAGE
- XTHL
- MOV E,A ;USE DRIVE CODE AS INDEX INTO TABLE
- MVI D,0
- USRCK: LXI H,LODRV ;POINT TO BASE OF DRIVE/USER TABLE
- DAD D
- MOV A,M ;GET THE MAXIMUM USER # FOR THIS DRIVE
- CPI 0FFH ;CHECK FOR SKIP DRIVE
- JZ ERXIT ;EXIT IF NOT WANTED
- USRCK2: ANI 0FH ;MAKE SURE ITS IN RANGE 0 - 15
- STA MAXUSR ;SAVE IT FOR LATER
- LXI H,NEWUSR ;POINT TO THE DIRECTORY USER AREA
- CMP M ;COMPARE IT WITH THE MAXIMUM
- JC ERXIT ;TAKE ERROR EXIT IF USER NUMBER ILLEGAL
- POP D ;DESTROY ERROR MESSAGE POINTER
- LXI H,FCB+1 ;POINT TO NAME
- ;
- ; MAKE FCB ALL '?' TO SEARCH FOR EVERY FILE
- ;
- WCD: MVI B,11 ;FN+FT COUNT
- QLOOP: MVI M,'?' ;STORE '?' IN FCB
- INX H
- DCR B
- JNZ QLOOP
- ;
- GOTFCB: MVI A,'?' ;FORCE WILD EXTENT
- STA FCB+12
- CALL SETSRC ;SET DMA FOR BDOS MEDIA CHANGE CHECK
- LXI H,FCB ;POINT TO FCB DRIVE CODE FOR DIRECTORY
- MOV E,M ;GET THE DRIVE CODE OUT OF THE FCB
- DCR E ;NORMALIZE DRIVE CODE FOR SELECT
- MVI C,SELDSK ;SELECT THE DIRECTORY DRIVE TO RETRIEVE
- CALL CPM ;..THE PROPER ALLOCATION VECTOR
- MVI C,CURDPB ;IT IS 2.X OR MP/M...REQUEST DPB
- CALL BDOS
- INX H
- INX H
- MOV A,M ;GET BLOCK SHIFT
- STA BLKSHF
- INX H ;BUMP TO BLOCK MASK
- MOV A,M
- STA BLKMSK ;GET IT
- INX H
- INX H
- MOV E,M ;GET MAX BLOCK #
- INX H
- MOV D,M
- XCHG
- SHLD BLKMAX ;SAVE IT
- XCHG
- INX H
- MOV E,M ;GET DIRECTORY SIZE
- INX H
- MOV D,M
- XCHG
- SHLD DIRMAX ;SAVE MAX # OF ENTRIES IN DIRECTORY
- ;
- ; REENTER HERE ON SUBSEQUENT PASSES WHILE IN THE ALL-USERS MODE
- ;
- SETTBL: LDA QUIET ;check if in quiet mode
- ORA A
- JNZ SETTB1 ;yes so skip printout
- LDA FCB
- ADI 'A'-1
- STA PROC1
- LXI D,PROCES ;show the user what area is being
- CALL PRINT ;worked on.
- CALL TYPUSR
- SETTB1: LHLD DIRMAX ;GET DIRECTORY MAXIMUM AGAIN
- INX H ;DIRECTORY SIZE IS DIRMAX+1
- DAD H ;DOUBLE DIRECTORY SIZE
- LXI D,ORDER ;TO GET SIZE OF ORDER TABLE
- DAD D ;ALLOCATE ORDER TABLE
- SHLD TBLOC ;NAME TBL BEGINS WHERE ORDER TBL ENDS
- SHLD NEXTT
- XCHG
- LHLD BDOS+1 ;MAKE SURE WE HAVE ROOM TO CONTINUE
- MOV A,E
- SUB L
- MOV A,D
- SBB H
- JNC OUTMEM
- LDA NEWUSR ;GET USER AREA FOR DIRECTORY
- MOV E,A
- MVI C,CURUSR ;GET THE USER FUNCTION
- CALL CPM ;..AND SET NEW USER NUMBER
- ;
- ;
- ; LOOK UP THE FCB IN THE DIRECTORY
- ;
- MVI A,'?'
- LXI H,FCB+12
- MOV M,A ;MATCH ALL EXTENTS
- INX H
- MOV M,A ;MATCH ALL S1 BYTES
- INX H
- MOV M,A ;MATCH ALL S2 BYTES
- LXI H,0
- SHLD COUNT ;INITIALIZE MATCH COUNTER
- CALL SETSRC ;SET DMA FOR DIRECTORY SEARCH
- MVI C,SEARCH ;GET 'SEARCH FIRST' FUNCTION
- JMP LOOK ;..AND GO SEARCH FOR 1ST MATCH
- ;
- ; READ MORE DIRECTORY ENTRIES
- ;
- MORDIR: MVI C,NEXT ;SEARCH NEXT
- ;
- LOOK: LXI D,FCB
- CALL CPM ;READ DIRECTORY ENTRY
- INR A ;CHECK FOR END (0FFH)
- JZ SPRINT ;IF NO MORE, SORT & PRINT WHAT WE HAVE
- ;
- ; POINT TO DIRECTORY ENTRY
- ;
- SOME: DCR A ;UNDO PREV 'INR A'
- ANI 3 ;MAKE MODULUS 4
- ADD A ;MULTIPLY...
- ADD A ;..BY 32 BECAUSE
- ADD A ;..EACH DIRECTORY
- ADD A ;..ENTRY IS 32
- ADD A ;..BYTES LONG
- LXI H,BASE+81H ;POINT TO BUFFER (SKIP TO FN/FT)
- ADD L ;POINT TO ENTRY
- ADI 9 ;POINT TO SYS BYTE
- MOV L,A ;SAVE (CAN'T CARRY TO H)
- MOV A,M ;GET SYS BYTE
- ORA A ;CHECK BIT 7
- JM MORDIR ;SKIP THAT FILE
- ;
- SYSFOK: MOV A,L ;GO BACK NOW
- SUI 10 ;BACK TO USER NUMBER (ALLOC FLAG)
- MOV L,A ;HL POINTS TO ENTRY NOW
- LDA NEWUSR ;GET CURRENT USER
- CMP M
- JNZ MORDIR ;IGNORE IF DIFFERENT
- INX H
- ;
- ; MOVE ENTRY TO TABLE
- ;
- XCHG ;ENTRY TO DE
- LHLD NEXTT ;NEXT TABLE ENTRY TO HL
- MVI B,11 ;ENTRY LENGTH (NAME, TYPE, EXTENT)
- ;
- TMOVE: LDAX D ;GET ENTRY CHAR
- ANI 7FH ;REMOVE ATTRIBUTES
- MOV M,A ;STORE IN TABLE
- INX D
- INX H
- DCR B ;MORE?
- JNZ TMOVE
- INX D ;DE->> S1
- INX D ;DE->> S2
- LDAX D ;GET S2 BYTE, OVERFLOW=INT(EXTENTS/32)
- PUSH H ;SAVE HL
- MOV L,A ;SET UP 16-BIT MULTIPLY
- MVI H,0
- MVI B,5
- CALL SHLL ;HL IS NOW # OF OVERFLOW EXTENTS
- DCX D ;DE->> S1
- DCX D ;DE->> EXTENT
- LDAX D ;GET EXTENT
- ADD L
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A ;HL NOW HAS TOTAL EXTENTS
- MVI B,7
- CALL SHLL ;HL NOW HAS TOTAL SECTORS LESS LAST EXT
- INX D ;DE->> S1
- INX D ;DE->> S2
- INX D ;POINT TO SECTOR COUNT
- LDAX D ;GET IT
- ADD L
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A ;HL NOW HAS TOTAL SECTORS
- XTHL ;DO SOME FANCY SHUFFLING
- XCHG
- XTHL
- XCHG
- MOV M,D
- INX H
- MOV M,E
- POP D ;ALL BACK TO NORMAL...
- INX H
- SHLD NEXTT ;SAVE UPDATED TABLE ADDRESS
- XCHG
- LHLD COUNT ;BUMP THE # OF MATCHES MADE
- INX H
- SHLD COUNT
- LXI H,13 ;SIZE OF NEXT ENTRY
- DAD D
- XCHG ;FUTURE NEXTT IS IN DE
- LHLD BDOS+1 ;PICK UP TPA END
- MOV A,E
- SUB L ;COMPARE NEXTT-TPA END
- MOV A,D
- SBB H
- JC MORDIR ;IF TPA END > NEXTT, LOOP BACK FOR MORE
- ;
- OUTMEM: CALL ERXIT ;EXIT IF DIRECTORY TOO LARGE
- DB 'Memor','y' OR 80H
- ;
- ; SHIFT HL LEFT BY B BITS
- ;
- SHLL: DAD H
- DCR B
- RZ
- JMP SHLL
- ;
- ; SORT
- ;
- SPRINT: CALL SETFOP ;RETURN TO FILE OUTPUT DMA & USER #
- LHLD COUNT ;GET FILE NAME COUNT
- MOV A,L
- ORA H ;ANY FOUND?
- JZ PRTOTL ;EXIT IF NO FILES FOUND
- PUSH H ;SAVE FILE COUNT
- STA SUPSPC ;ENABLE LEADING ZERO SUPPRESSION
- ;
- ; INITIALIZE THE ORDER TABLE
- ;
- LHLD TBLOC ;GET START OF NAME TABLE
- XCHG ;INTO DE
- LXI H,ORDER ;POINT TO ORDER TABLE
- LXI B,13 ;ENTRY LENGTH
- BLDORD: MOV M,E ;SAVE LOW ORDER ADDRESS
- INX H
- MOV M,D ;SAVE HIGH ORDER ADDRESS
- INX H
- XCHG ;TABLE ADDR TO HL
- DAD B ;POINT TO NEXT ENTRY
- XCHG
- XTHL ;SAVE TBL ADDR, FETCH LOOP COUNTER
- DCX H ;COUNT DOWN LOOP
- MOV A,L
- ORA H ;MORE?
- XTHL ;(RESTORE TBL ADDR, SAVE COUNTER)
- JNZ BLDORD ;YES, GO DO ANOTHER ONE
- POP H ;CLEAN LOOP COUNTER OFF STACK
- LHLD COUNT ;GET COUNT
- SHLD SCOUNT ;SAVE AS # TO SORT
- DCX H ;ONLY 1 ENTRY?
- MOV A,L
- ORA H
- JZ NOOUT ;YES, SO SKIP SORT
- ;
- ; THIS SORT ROUTINE IS ADAPTED FROM SOFTWARE TOOLS BY KERNIGAN AND
- ; PLAUGHER.
- ;
- SORT: LHLD SCOUNT ;NUMBER OF ENTRIES
- L0: ORA A ;CLEAR CARRY
- MOV A,H ;GAP=GAP/2
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
- ORA H ;IS IT ZERO?
- JZ NOOUT ;THEN NONE LEFT
- MOV A,L ;MAKE GAP ODD
- ORI 1
- MOV L,A
- SHLD GAP
- INX H ;I=GAP+1
- ;
- L2: SHLD I
- XCHG
- LHLD GAP
- MOV A,E ;J=I-GAP
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- ;
- L3: SHLD J
- XCHG
- LHLD GAP ;JG=J+GAP
- DAD D
- SHLD JG
- MVI A,13 ;COMPARE 13 CHARS {SFK}
- CALL COMPARE ;COMPARE (J) AND (JG)
- JP L5 ;IF A(J)<=A(JG)
- LHLD J
- XCHG
- LHLD JG
- CALL SWAP ;EXCHANGE A(J) AND A(JG)
- LHLD J ;J=J-GAP
- XCHG
- LHLD GAP
- MOV A,E
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- JM L5 ;IF J>0 GOTO L3
- ORA L ;CHECK FOR ZERO
- JZ L5
- JMP L3
- ;
- L5: LHLD SCOUNT ;FOR LATER
- XCHG
- LHLD I ;I=I+1
- INX H
- MOV A,E ;IF I<=N GOTO L2
- SUB L
- MOV A,D
- SBB H
- JP L2
- LHLD GAP
- JMP L0
- ;
- ; SORT IS ALL DONE - PRINT ENTRIES THAT COMPARE
- ;
- NOOUT: LHLD COUNT
- SHLD LCOUNT
- LXI H,ORDER ;INITIALIZE ORDER TABLE POINTER
- SHLD NEXTL
- SHLD NEXTT
- ;
- ; OUTPUT THE DIRECTORY FILES WE'VE MATCHED.
- ;
- ENTRY: LHLD COUNT
- DCX H ;DOCK FILE COUNT
- SHLD COUNT
- MOV A,H ;IS THIS THE LAST FILE?
- ORA L
- JZ OKPRNT ;IF COUNT=0, LAST FILE SO SKIP COMPARE
- ;
- ;
- ; COMPARE EACH ENTRY TO MAKE SURE THAT IT ISN'T PART OF A MULTIPLE EX-
- ; TENT FILE. GO ONLY WHEN WE HAVE THE LAST EXTENT OF THE FILE.
- ;
- CALL CKABRT ;CHECK FOR ABORT CODE FROM KEYBOARD
- LHLD NEXTT
- MVI A,11
- CALL COMPR ;DOES THIS ENTRY MATCH NEXT ONE?
- JNZ OKPRNT ;NO, PRINT IT
- INX H
- INX H ;SKIP SINCE HIGHEST EXTENT LAST IN LIST
- SHLD NEXTT
- JMP ENTRY ;LOOP BACK FOR NEXT LOWEST EXTENT
- ;
- OKPRNT: LHLD NEXTT ;GET ORDER TABLE POINTER
- MOV E,M ;GET LOW ORDER ADDRESS
- INX H
- MOV D,M ;GET HIGH ORDER ADDRESS
- INX H
- SHLD NEXTT ;SAVE UPDATED TABLE POINTER
- XCHG ;TABLE ENTRY TO HL
- ;
- ; PUT IN USER & DRIVE PRINTOUT HERE
- ;
- PUSH H
- LHLD TFILES
- INX H
- SHLD TFILES
- POP H
- CALL COMPS ;MATCH WHAT WE ARE LOOKING FOR ?
- JNZ OKEXIT ;NO SO DON'T PRINT IT
- PUSH H
- LHLD TMATCH
- INX H
- SHLD TMATCH
- POP H
- CALL CRLF
- LDA FCB ;..precede new line with drive name
- ADI 'A'-1
- CALL TYPE
- CALL TYPUSR
- MVI A,':' ;tag header with a colon and a space
- CALL TYPE ;..and exit back to ENTRY
- MVI A,' '
- CALL TYPE
- MVI B,8 ;FILE NAME LENGTH
- CALL TYPEIT ;TYPE FILENAME
- MVI A,'.' ;PERIOD AFTER FN
- CALL TYPE
- MVI B,3 ;DISPLAY 3 CHARACTERS OF FILETYPE
- CALL TYPEIT
- MOV D,M
- INX H
- MOV E,M ;SIZE IN DE (SECTORS)
- LDA BLKMSK
- PUSH PSW
- ADD E
- MOV E,A
- MOV A,D
- ACI 0
- MOV D,A
- POP PSW
- CMA
- ANA E
- MOV E,A ;SIZE IN DE (SECTORS ROUNDED TO BLOCKSIZE)
- MVI B,3
- SHRR: MOV A,D
- ORA A
- RAR
- MOV D,A
- MOV A,E
- RAR
- MOV E,A
- DCR B
- JNZ SHRR
- XCHG ;GET FILE SIZE
- ;
- ; OUTPUT THE SIZE OF THE INDIVIDUAL FILE.
- ;
- CALL DECPRT ;..GO PRINT IT
- MVI A,'k' ;..AND FOLLOW WITH K SIZE
- CALL TYPE
- MVI A,0FFH
- STA FNDFLG ;Set file found flag
- ;
- ; ONE FILE OUTPUT - TEST TO SEE IF WE HAVE TO OUTPUT ANOTHER ONE.
- ;
- OKEXIT LHLD COUNT ;GET CURRENT FILE COUNTER AND TEST IT
- MOV A,H
- ORA L
- JZ PRTOTL ;IF NO MORE FILES EXIT TO SUMMARY OUTPUT
- JMP ENTRY
- ;
- ; COMPUTE THE SIZE OF THE FILE/LIBRARY AND UPDATE OUR SUMMARY DATUM.
- ; THIS HAS BEEN CHANGED INTO A SUBROUTINE SO THAT BOTH THE FILE SIZE
- ; COMPUTATION AND A LIBRARY SIZE (WHEN PRINTING OUT LIBRARY MEMBERS)
- ; CAN BE COMPUTED IN K.
- ;
- DOIT: MOV E,M ;GET EXTENT #
- MVI D,0
- INX H
- MOV A,M ;GET SECTOR COUNT OF LAST EXTENT
- XCHG
- DAD H ;# OF EXTENTS TIMES 16K
- DAD H
- DAD H
- DAD H
- XCHG ;SAVE IN DE
- LXI H,BLKMSK
- ADD M ;ROUND LAST EXTENT TO BLOCK SIZE
- RRC
- RRC ;CONVERT FROM SECTORS TO K
- RRC
- ANI 1FH
- MOV L,A ;ADD TO TOTAL K
- MVI H,0
- DAD D
- LDA BLKMSK ;GET SECTORS/BLK-1
- RRC
- RRC ;CONVERT TO K/BLK
- RRC
- ANI 1FH
- CMA ;USE TO FINISH ROUNDING
- ANA L
- MOV L,A
- RET
- ;.....
- ;
- ; PRINT HL IN DECIMAL WITH LEADING ZERO SUPPRESSION
- ;
- DECPRT: XRA A ;CLEAR LEADING ZERO FLAG
- STA LZFLG
- LXI D,-1000 ;PRINT 1000'S DIGIT
- CALL DIGIT
- LXI D,-100 ;ETC.
- CALL DIGIT
- LXI D,-10
- CALL DIGIT
- MVI A,'0' ;GET 1'S DIGIT
- ADD L
- JMP TYPE
- ;
- DIGIT: MVI B,'0' ;START OFF WITH ASCII 0
- ;
- DIGLP: PUSH H ;SAVE CURRENT REMAINDER
- DAD D ;SUBTRACT
- JNC DIGEX ;QUIT ON OVERFLOW
- POP PSW ;THROW AWAY REMAINDER
- INR B ;BUMP DIGIT
- JMP DIGLP ;LOOP BACK
- ;
- DIGEX: POP H ;RESTORE POINTER
- MOV A,B
- CPI '0' ;ZERO DIGIT?
- JNZ DIGNZ ;NO, TYPE IT
- LDA LZFLG ;LEADING ZERO?
- ORA A
- MVI A,'0'
- JNZ TYPE ;PRINT DIGIT
- LDA SUPSPC ;GET SPACE SUPPRESSION FLAG
- ORA A ;SEE IF PRINTING FILE TOTALS
- RZ ;YES, DON'T GIVE LEADING SPACES
- MVI A,' '
- JMP TYPE ;LEADING ZERO...PRINT SPACE
- ;
- DIGNZ: STA LZFLG ;LEADING ZERO FLAG SO NEXT ZERO PRINTS
- JMP TYPE ;AND PRINT DIGIT
- ;
- ; NOW CHECK FOR LIBRARIES
- ;
- PRTOTL: LHLD LCOUNT ;HOW MANY FILES DID WE SEE?
- MOV A,H
- ORA L
- CNZ PRTLMEM ;SKIP THE .LBR CHECK IF NONE FOUND
- XRA A ;GET A ZERO TO...
- STA SUPSPC ;SUPPRESS LEADING SPACES IN TOTALS
- ;
- ; DIRECTORY FOR ONE USER AREA COMPLETED. IF 'ALL USERS' OPTION IS SE-
- ; LECTED, THEN GO DO ANOTHER DIRECTORY ON THE NEXT USER NUMBER UNTIL WE
- ; EXCEED THE MAXIMUM USER # FOR THE SELECTED DRIVE.
- ;
- NXTUSR: CALL CKABRT ;CHECK FOR USER ABORT FIRST
- LDA MAXUSR ;NO ABORT - GET MAXIMUM USER NUMBER
- LXI H,NEWUSR ;BUMP DIRECTORY USER NUMBER
- INR M
- CMP M ;DOES NEXT USER # EXCEED MAXIMUM?
- JNC SETTBL ;CONTINUE IF MORE USER AREAS TO GO
- LDA BASUSR ;RESET BASE USER NUMBER FOR THE
- MOV M,A ;..NEXT DIRECTORY SEARCH
- ;
- ; DIRECTORY FOR ALL USER AREAS COMPLETED. IF THE MULTI-DISK OPTION IS
- ; ENABLED AND SELECTED, RESET TO THE BASE USER AREA AND REPEAT THE DI-
- ; RECTORY FOR NEXT DRIVE ON-LINE UNTIL WE EITHER EXCEED THE DRIVES IN
- ; OUR LODRV-HIDRV TABLE, OR THE BDOS SHUTS US DOWN WITH A SELECT OR BAD
- ; SECTOR ERROR, WHICH WILL BE INTERCEPTED BACK TO THE EXIT MODULE.
- ;
- NXTDSK: LXI H,FNDFLG ;get file found flag
- MOV A,M
- MVI M,0 ;clear file found flag for next drive
- ORA A
- JNZ NDSK ;continue if at least 1 file found
- LDA QUIET ;CHECK OUTPUT MODE
- ORA A
- JZ NDSK
- CALL CRLF
- LDA FCB ;stash ASCII dir. drive in NO FILE msg
- ADI 'A'-1
- STA NOFMS2
- LXI D,NOFMS1 ;print "No file on ? - "
- CALL PRINT
- NDSK: LDA DOPFLG
- ORA A
- JNZ EXIT
- CALL CKABRT ;CHECK FOR USER ABORT FIRST
- MVI A,HIDRV-LODRV ;GET MAXIMUM DRIVE CODE TO SEARCH
- LXI H,FCB ;BUMP DIRECTORY FCB DRIVE CODE
- INR M
- CMP M ;DOES NEXT DISK EXCEED MAXIMUM?
- JC EXIT
- MOV E,M
- MVI D,0
- DCR E
- LXI H,LODRV
- DAD D
- MOV A,M
- CPI 0FFH
- JZ NDSK ;SEARCH NEXT DISK IF MAXDR NOT TRUE
- JMP NOOPT
- ;
- ; Print the user number of the directory in decimal
- ;
- TYPUSR: LDA NEWUSR
- CPI 10 ;if user no. > 9 print leading 1
- JC DUX
- MVI A,'1'
- CALL TYPE
- LDA NEWUSR ;print low digit of user #
- SUI 10
- ;
- DUX: ADI '0'
- JMP TYPE
- ;
- CRLF: MVI A,CR ;SEND CR
- CALL TYPE
- MVI A,LF ;SEND LF
- JMP TYPE
- ;..... ;EXIT TO CALLER FROM TYPE
- ;
- ; OUTPUT CHARACTER IN A TO CONSOLE, AND OPTIONALLY TO PRINTER AND/OR THE
- ; OUTPUT FILE.
- ;
- TYPE: PUSH B
- PUSH D
- PUSH H
- PUSH PSW ;SAVE THE CHARACTER TO OUTPUT
- CALL TYPE1 ;SEND IT TO CONSOLE
- POP PSW ;RESTORE THE OUTPUT CHARACTER
- TYPRET: POP H ;EXIT FROM TYPE
- POP D
- POP B
- RET
- ;.....
- ;
- ;
- ; OUTPUT CHARACTER
- ;
- TYPE1 MOV E,A ;GET CHARACTER INTO BDOS ENTRY REGISTER
- MVI C,WRCHR
- JMP BDOS ;CALL CONOUT VIA THE BDOS
- ;.....
- ;
- ;
- ; PRINT A STRING AT HL OF LENGTH B
- ;
- TYPEIT: MOV A,M
- CALL TYPE
- INX H
- DCR B
- JNZ TYPEIT
- RET
- ;.....
- ;
- ;
- ; PRINT STRING TERMINATED WITH LAST BYTE HIGH ON CONSOLE
- ;
- PRINT: LDAX D
- PUSH PSW
- ANI 7FH
- CALL TYPE
- POP PSW
- ORA A
- RM
- INX D
- JMP PRINT
- ;.....
- ;
- ;
- ; FETCH CHARACTER FROM CONSOLE (WITHOUT ECHO)
- ;
- CINPUT: LHLD BASE+1
- MVI L,9
- CALL GOHL
- ANI 7FH
- RET
- ;.....
- ;
- ; CHECK FOR A CTRL-C OR CTRL-S ENTERED FROM THE KEYBOARD. JUMP TO EXIT
- ; IF CTRL-C, PAUSE ON CTRL-S.
- ;
- CKABRT: LHLD BASE+1
- MVI L,6 ;CHECK STATUS OF KEYBOARD
- CALL GOHL ;ANY KEY PRESSED?
- ORA A
- RZ ;NO, RETURN TO CALLER
- CALL CINPUT ;GET CHARACTER
- CPI 'C'-40H ;CTL-C?
- JZ EX0 ;IF CTL-C THEN QUIT
- CPI 'S'-40H ;CTL-S?
- RNZ ;NO, RETURN TO CALLER
- CALL CINPUT ;YES, WAIT FOR ANOTHER CHAR.
- CPI 'C'-40H ;MIGHT BE CTL-C
- JZ EX0 ;IF CTL-C, ELSE FALL THRU AND CONTINUE
- RET
- ;.....
- ;
- ; KLUDGE TO ALLOW CALL TO ADDRESS IN HL
- ;
- GOHL: PCHL
- ;
- ; ENTRY TO BDOS SAVING ALL EXTENDED REGISTERS
- ;
- CPM: PUSH B
- PUSH D
- PUSH H
- CALL BDOS
- MOV B,A ;SAVE RETURN CODE
- LDA VERFLG ;IS THIS 3.0?
- CPI 30H
- MOV A,B
- JC CPM20 ;NO, EXIT NORMALLY
- CPI 0FFH ;IT IS 3.0 - WAS RETURN CODE FF?
- JNZ CPM20 ;NO, EXIT NORMALLY
- MOV A,H ;3.0 AND A=FF - CHECK FOR ERROR CODE
- ORA A
- JNZ DSKERR ;TRAP OUT IF WE GOT A PHYSICAL ERROR
- MOV A,B ; ELSE CONTINUE NORMALLY
- ;
- CPM20: POP H
- POP D
- POP B
- RET
- ;.....
- ;
- ;
- ; FOR FILE OUTPUT MODE, RETURN TO OLD USER AREA AND SET DMA FOR THE FILE
- ; OUTPUT BUFFER.
- ;
- SETFOP: LDA OLDUSR ;GET USER NUMBER AT STARTUP
- MOV E,A
- MVI C,CURUSR
- CALL CPM ;RESET THE OLD USER NUMBER
- RET
- ;.....
- ;
- ;
- ; MOVE DISK BUFFER DMA TO DEFAULT BUFFER FOR DIRECTORY SEARCH OPERATIONS
- ; AND BDOS MEDIA CHANGE ROUTINES (NECESSARY FOR PRE-CP/M 2 SYSTEMS WHILE
- ; IN FILE OUTPUT MODE WITH AN ACTIVE BUFFER).
- ;
- SETSRC: LXI D,BASE+80H
- ;
- SET2: MVI C,SETDMA
- JMP CPM
- ;.....
- ;
- ; COMPARE ROUTINE FOR SORT
- ;
- COMPR: PUSH H ;SAVE TABLE ADDR
- MOV E,M ;LOAD LOW ORDER
- INX H
- MOV D,M ;LOAD HIGH ORDER
- INX H
- MOV C,M
- INX H
- MOV B,M
- ;
- ;
- ; BC, DE NOW POINT TO ENTRIES TO BE COMPARED
- ;
- XCHG
- MOV E,A ;GET COUNT
- ;
- CMPLP: MOV A,M
- ANI 7FH
- MOV D,A
- LDAX B
- ANI 7FH
- CMP D
- INX H
- INX B
- JNZ NOTEQL ;QUIT ON MISMATCH
- DCR E ;OR END OF COUNT
- JNZ CMPLP
- ;
- NOTEQL: POP H
- RET ;COND CODE TELLS ALL
- ;.....
- ;
- ;
- ; SWAP ENTRIES IN THE ORDER TABLE
- ;
- SWAP: LXI B,ORDER-2 ;TABLE BASE
- DAD H ;*2
- DAD B ;+ BASE
- XCHG
- DAD H ;*2
- DAD B ;+ BASE
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- INX H
- INX D
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- RET
- ;.....
- ;
- ; NEW COMPARE ROUTINE
- ;
- COMPARE:LXI B,ORDER-2
- DAD H
- DAD B
- XCHG
- DAD H
- DAD B
- XCHG
- MOV C,M
- INX H
- MOV B,M
- XCHG
- MOV E,M
- INX H
- MOV D,M
- XCHG
- MOV E,A ;COUNT
- ;
- CMPLPE: MOV A,M
- ANI 7FH
- MOV D,A
- LDAX B
- ANI 7FH
- CMP D
- INX B
- INX H
- RNZ
- DCR E
- JNZ CMPLPE
- RET
- ;.....
- ;
- ; ERROR EXIT
- ;
- ERXIT: CALL CRLF ;SPACE DOWN
- POP D ;GET POINTER TO MESSAGE STRING
- CALL PRINT ;PRINT IT
- LXI D,ERRMS1 ;PRINT " ERROR"
- CALL PRINT
- CALL CRLF ;SPACE DOWN
- ;
- ; EXIT - ALL DONE RESTORE STACK
- ;
- EXIT: LDA DOPFLG ;CHECK MULTI DISK MODE
- ORA A
- JNZ EX0
- CALL CKABRT ;CHECK FOR USER ABORT FIRST
- MVI A,HIDRV-LODRV ;GET MAXIMUM DRIVE CODE TO SEARCH
- LXI H,FCB ;BUMP DIRECTORY FCB DRIVE CODE
- INR M
- CMP M ;DOES NEXT DISK EXCEED MAXIMUM?
- JC EX0
- JMP NOOPT ;SEARCH NEXT DISK IF MAXDR NOT TRUE
- TMMSG DB CR,LF,LF,'Files Matched -',' '+80H
- TCMSG: DB CR,LF,'Files Checked -',' '+80H
- TLMSG: DB CR,LF,'Libraries Searched -',' '+80H
- TFILES DW 0
- TLIBRA DW 0
- TMATCH DW 0
- ;
- EX0: LXI D,TMMSG
- CALL PRINT
- LHLD TMATCH
- CALL DECPRT
- LXI D,TCMSG
- CALL PRINT
- LHLD TFILES
- CALL DECPRT
- LXI D,TLMSG
- CALL PRINT
- LHLD TLIBRA
- CALL DECPRT
- MVI C,CONST ;CHECK CONSOLE STATUS
- CALL CPM
- ORA A ;CHAR WAITING?
- MVI C,RDCHR
- CNZ CPM ;GOBBLE UP CHAR
- LDA VERFLG ;OR ERROR MODE, DEPENDING ON VERSION
- CPI 30H
- JC EXIT0
- MVI C,45
- MVI E,0 ;SET ERROR MODE BACK TO DEFAULT
- CALL CPM
- JMP EXIT1
- ;
- EXIT0: LDA DOPFLG ;..if they were swapped
- ORA A
- CZ SWAPEM
- ;
- EXIT1: LHLD STACK ;GET OLD STACK POINTER
- SPHL ;MOVE BACK TO OLD STACK
- RET ;..AND RETURN TO CCP
- ;
- VERERR LXI D,VERBAD ;ABORT CP/M IS VERSION 1.?
- VERER1 CALL PRINT
- JMP EXIT1
- ;
- NONERR LXI D,VERNAME ;PRINT HELP INFO
- JMP VERER1
- ;.....
- ;
- ; TRAP BDOS SELECT AND SECTOR ERROR VECTORS TO OUR OWN INTERCEPT ROUTINE
- ; SO WE CAN CATCH A REFERENCE TO AN ILLEGAL DRIVE.
-
- SWAPEM: LDA VERFLG ;CHECK VERSION
- CPI 30H ;SEE IF ERROR MODE CALL IS AVAILABLE
- JC SWAP20 ;IF NOT, USE BDOS ERROR VECTORS
- MVI C,45
- MVI E,0FFH ;USE SET ERROR MODE CALL
- CALL CPM ;SET "RETURN CODE ONLY" MODE
- RET
- ;.....
- ;
- SWAP20: LHLD BDOLOC ;GET POINTER TO BASE OF BIOS
- MOV A,L
- ORA H
- JNZ SWAPO0
- LXI H,BASE+6 ;GET BDOS ADDRESS
- SWAPO0: MVI L,9 ;SET POINTER TO ERROR VECTORS
- ;
- SWAPOK: LXI D,VECTBL ;EXCHANGING WITH OUR OWN VECTOR TABLE
- MVI A,4 ;4 BYTES TO SWAP
- ;
- SWAPLP: MOV B,M ;GET BYTE FROM HL
- XCHG
- MOV C,M ;GET BYTE FROM DE
- MOV M,B ;PUT BYTE FROM HL
- XCHG
- MOV M,C ;PUT BYTE FROM DE
- INX H ;BUMP EXCHANGE POINTERS
- INX D
- DCR A ;DOCK COUNTER
- JNZ SWAPLP ;CONTINUE SWAPPING TIL DONE
- RET
- ;.....
- ;
- ; RECOVERY POINT FROM INTERCEPTED BDOS SELECT AND BAD SECTOR ERRORS.
- ;
- DSKERR: LXI SP,STACK ;GET OUT OF BDOS' STACK
- JMP EXIT ;..AND EXIT BACK TO CCP
- ;
- ;=======================================================================
- ;
- ; SUBROUTINES TO READ LIBRARY FILE DIRECTORY
- ;
- ;=======================================================================
- ;
- PRTLMEM LXI H,SEARN+8
- CALL CKLBR
- RZ
- LXI H,ORDER ;INITIALIZE ORDER TABLE POINTER
- SHLD NEXTL
- ;
- ENTRYL: LHLD LCOUNT ;GET FCB COUNT
- DCX H ;DECREMENT IT
- SHLD LCOUNT
- MOV A,H ;IS THIS THE LAST FILE?
- ORA L
- JZ LBRTST ;IF COUNT=0, LAST FILE SKIP COMPARE
- PUSH B
- CALL CKABRT ;CHECK FOR ABORT CODE FROM KEYBOARD
- LHLD NEXTL
- MVI A,11
- CALL COMPR ;DOES THIS ENTRY MATCH NEXT ONE?
- POP B
- JNZ LBRTST ;NO, PRINT IT
- INX H
- INX H ;SKIP, HIGHEST EXTENT COMES LAST IN LIST
- SHLD NEXTL
- JMP ENTRYL ;LOOP BACK FOR NEXT LOWEST EXTENT
- ;
- ; EXIT LIBRARY MEMBER PRINTING
- ;
- LBEXIT: XRA A ;GET A ZERO TO...
- STA SUPSPC ;SUPPRESS LEADING SPACES IN TOTALS
- RET
- ;.....
- ;
- ; VALID ENTRY OBTAINED - SPIT IT OUT.
- ;
- LBRTST: LHLD NEXTL ;GET ORDER TABLE POINTER
- MOV E,M ;GET LOW ORDER ADDRESS
- INX H
- MOV D,M ;GET HIGH ORDER ADDRESS
- INX H
- SHLD NEXTL ;SAVE UPDATED TABLE POINTER
- LXI H,8
- DAD D
- CALL CKLBR
- JNZ LBRNEX
- PUSH D
- POP H
- ;
- ; SAVES THE LIBRARY FILE NAME INTO LBRFCB
- ;
- LDA FCB
- LXI D,LBRFCB ;TO
- STAX D
- INX D
- MVI B,11 ;LEN
- CALL MOVE ;DO THE MOVE
- XCHG
- MVI B,25
- ;
- CLMFCB: MVI M,0
- INX H
- DCR B
- JNZ CLMFCB
- CALL SETLDMA
- LXI D,LBRFCB ;POINT TO FILE
- MVI C,OPEN ;GET FUNCTION
- CALL CPM ;OPEN IT
- MVI C,READ
- LXI D,LBRFCB
- CALL CPM
- CALL SETFOP
- LXI H,LBBUF
- MOV A,M
- ORA A
- JZ CKLDIR ;CHECK DIRECTORY PRESENT?
- ;
- LMLEXI: CALL LBCLOSE
- ;
- ; DO NEXT LIBRARY FILE
- ;
- LBRNEX: LHLD LCOUNT ;CHECK COUNT
- MOV A,H
- ORA L
- JZ LBEXIT ;NO MORE, ALL DONE
- JMP ENTRYL ;ELSE, GET NEXT .LBR FILE
- ;
- ; CLOSE THE LIBRARY FILE
- ;
- LBCLOSE:LXI D,LBRFCB
- MVI C,CLOSE
- CALL CPM
- RET
- ;.....
- ;
- ;
- ; SET THE LIBRARY FILE DMA ADDERSS
- ;
- SETLDMA LDA NEWUSR ;GET USER AREA FOR DIRECTORY
- MOV E,A
- MVI C,CURUSR ;GET THE USER FUNCTION
- CALL CPM ;..AND SET NEW USER NUMBER
- LXI D,LBBUF
- MVI C,SETDMA
- CALL CPM
- RET
- ;.....
- ;
- ; CHECK TO SEE IF THERE INDEED IS A LBR FILE DIRECTORY AND BARF IF NOT!
- ;
- CKLDIR: MVI B,11 ;LENGTH OF FILE NAME
- MVI A,' ' ;SPACE
- INX H
- CKDLP: CMP M
- JNZ LMLEXI
- DCR B
- INX H
- JNZ CKDLP
- ;
- ; THE FIRST ENTRY IN THE LBR DIRECTORY IS INDEED BLANK. NOW SEE IF THE
- ; DIRECTORY SIZE IS >0
- ;
- MOV E,M ;FILE STARTING LOCATION LOW
- INX H ;MUST BE ZERO HERE
- MOV A,M ;FILE STARTING LOCATION HIGH
- ORA E ;MUST BE ZERO HERE ALSO
- JNZ LMLEXI
- INX H
- MOV E,M ;GET LIBRARY SIZE LOW
- INX H ;POINT TO LIBRARY SIZE HIGH
- MOV D,M ;GET LIBRARY SIZE HIGH
- MOV A,D
- ORA E ;LIBRARY MUST HAVE SOME SIZE
- JZ LMLEXI
- DCX D
- XCHG
- SHLD SLFILE
- MVI B,3
- LXI H,17
- DAD D
- PUSH H
- LHLD TLIBRA
- INX H
- SHLD TLIBRA
- POP H
- JMP LMTEST
- ;
- LFMLOP: LHLD SLFILE ;GET
- MOV A,L
- ORA H
- JZ LMLEXI
- DCX H
- SHLD SLFILE
- CALL SETLDMA
- MVI C,READ
- LXI D,LBRFCB
- CALL CPM
- CALL SETFOP
- MVI B,4 ;GET FILE COUNT PER SECTOR
- LXI H,LBBUF ;GET BUFFER STARTING ADDRESS
- ;
- LMTEST: MOV A,M ;GET MEMBER OPEN FLAG
- ORA A ;TEST FOR OPEN
- JZ PRMNAM
- ;
- LMTESA: LXI D,32 ;MEMBER NOT OPEN GET OFFSET
- DAD D ;TO NEXT AND ADD IT IN.
- DCR B ;IS BUFFER EMPTY ?
- JNZ LMTEST ;NO SO TEST NEXT ENTRY
- JMP LFMLOP ;YES GET NEXT BUFFER...
- ;
- PRMNAM: PUSH H ;PRINT MEMBER NAME AND SIZE
- PUSH B
- CALL CKABRT ;CHECK FOR ABORT CODE FROM KEYBOARD
- PRMNA1: POP B
- POP H
- PUSH H
- PUSH B
- INX H
- PUSH H
- LHLD TFILES
- INX H
- SHLD TFILES
- POP H
- CALL COMPS ;MATCH WHAT WE ARE LOOKING FOR ?
- JNZ LBGNXT
- PUSH H
- LHLD TMATCH
- INX H
- SHLD TMATCH
- POP H
- CALL CRLF
- LDA FCB ;..precede new line with drive name
- ADI 'A'-1
- CALL TYPE
- CALL TYPUSR
- MVI A,':' ;tag header with a colon and a space
- CALL TYPE ;..and exit back to ENTRY
- MVI A,' '
- CALL TYPE
- MVI B,8 ;FILE NAME LENGTH
- CALL TYPEIT
- MVI A,'.' ;PERIOD AFTER FN
- CALL TYPE
- MVI B,3 ;DISPLAY 3 CHARACTERS OF FILETYPE
- CALL TYPEIT
- INX H
- INX H
- MOV E,M
- INX H
- MOV D,M
- XCHG
- ;
- ;
- ; OUTPUT THE SIZE OF THE INDIVIDUAL FILE.
- ;
- PUSH D
- PUSH H
- PUSH H
- LHLD LLENLOC
- PUSH H
- POP D
- POP H
- DAD D
- SHLD LLENLOC
- POP H
- ;
- ; NEW CODE ADDED TO CONVERT LIB MEMBERS FROM SECTORS TO 'K'
- ;
- ; UPON ENTRY MEMBER'S SIZE IN SECTORS IS IN HL
- ;
- XCHG ;PUT IT IN DE
- LXI H,0 ;ZERO OUT HL
- MOV A,E ;PUT LOW BYTE OF SECTOR COUNT IN A
- ADI 7 ;ADD SEVEN TO ALWAYS ROUND UP 1K
- RRC ;CONVERT IT TO K
- RRC
- RRC
- ANI 1FH
- MOV E,A ;AND PUT IT BACK
- MOV L,D ;GET THE HIGH BYTE IF ANY
- MVI D,0 ;CLEAN OUT THE OLD RESTING PLACE
- DAD H ;MULTIPLY IT BY 32 TO CONVERT TO
- DAD H ;NUMBER
- DAD H ;OF
- DAD H ;K
- DAD H ;BYTES
- DAD D ;AND ADD IN THE LOW BYTE
- POP D
- CALL DECPRT ;..GO PRINT IT
- MVI A,'k' ;..AND FOLLOW WITH SIZE
- CALL TYPE
- LXI H,INLBF
- MVI B,4
- CALL TYPEIT
- LXI H,LBRFCB+1
- MVI B,8 ;FILE NAME LENGTH
- CALL TYPEIT
- MVI A,'.' ;PERIOD AFTER FN
- CALL TYPE
- MVI B,3 ;DISPLAY 3 CHARACTERS OF FILETYPE
- CALL TYPEIT
- MVI A,0FFH
- STA FNDFLG ;Set file found flag
- ;
- ;
- ; AT LEAST ONE MORE FILE TO OUTPUT - CAN WE PUT IT ON THE CURRENT LINE?
- ;
- LBGNXT: POP B
- POP H
- JMP LMTESA ;.. AND GO OUTPUT ANOTHER FILE
- ;
- COMPS PUSH H
- PUSH D
- PUSH B
- LXI B,SEARN
- MVI E,11
- COMPS1 MOV A,M
- ANI 7FH
- MOV D,A
- LDAX B
- INX B
- INX H
- ANI 7FH
- CPI '?'
- JZ COMPS2
- CMP D
- JNZ COMPS3
- COMPS2 DCR E
- JNZ COMPS1
- COMPS3 POP B
- POP D
- POP H
- RET
- ;
- INLBF DB ' IN '
- ;.....
- ;
- ;
- ; MOVE CHARACTERS FROM 'HL' TO 'DE' LENGTH IN 'B'
- ;
- MOVE: MOV A,M ;GET A CHARACTER
- STAX D ;STORE IT
- INX H ;TO NEXT 'FROM'
- INX D ;TO NEXT 'TO'
- DCR B ;MORE?
- JNZ MOVE ;YES, LOOP
- RET ;NO, RETURN
- ;.....
- ;
- ; TEST FILE EXTENT FOR LBR
- ;
- CKLBR: PUSH H
- PUSH D
- PUSH B
- XCHG
- LXI H,LBRTYP
- MVI C,3
- ;
- CKLBL: LDAX D
- ANI 7FH
- CMP M
- JNZ CKLBX
- INX H
- INX D
- DCR C
- JNZ CKLBL
- CKLBX: POP B
- POP D
- POP H
- RET
- ;.....
- ;
- LBRTYP: DB 'LBR'
- ;
- ;
- ;-----------------------------------------------------------------------
- ;
- ; END OF PROGRAM CODE
- ;
- ;-----------------------------------------------------------------------
- ;
- ; INITIALIZED DATA AREA
- ;
- VERBAD: DB '+++ Needs CP/M 2.0 or Newer to RU','N'+80H
- DREMSG: DB '+++ Driv','e' OR 80H
- ERRMS1: DB ' '
- ERRMS2: DB 'Erro','r' OR 80H
- USRMSG: DB 'User ','#' OR 80H
- NOFMS1: DB '+++ NO FILE ON '
- NOFMS2: DB ' ',':' OR 80H
- ;
- VECTBL: DW DSKERR ;BDOS SECTOR ERROR INTERCEPT VECTOR
- DW DSKERR ;BDOS SELECT ERROR INTERCEPT VECTOR
- DOPFLG DB 0
- ;
- ;=======================================================================
- ;
- ; UNINITIALIZED DATA AREA
- ;
- ;=======================================================================
- ;
- BASUSR: DB 0 ;DUPE OF ORIGINAL DIR. USER # TO SEARCH
- BLKMAX: DW 0 ;HIGHEST BLOCK # ON DRIVE
- BLKMSK: DB 0 ;SEC/BLK - 1
- BLKSHF: DB 0 ;# SHIFTS TO MULT BY SEC/BLK
- COUNT: DW 0 ;ENTRY COUNT
- DIRMAX: DW 0 ;HIGHEST FILE # IN DIRECTORY
- GAP: DW 0 ;SORT ROUTINE STORAGE
- HITRAP: DB 0 ;HIGHLIT TRAP (PREVIOUSLY TYPED CHAR)
- I: DW 0 ;SORT ROUTINE STORAGE
- J: DW 0 ;SORT ROUTINE STORAGE
- JG: DW 0 ;SORT ROUTINE STORAGE
- LZFLG: DB 0 ;0 WHEN PRINTING LEADING ZEROS
- MAXUSR: DB 0 ;MAX USER # FOR DRIVE FROM LOOKUP TABLE
- NEWUSR: DB 0 ;CONTAINS USER # SELECTED BY "$U" OPTION
- NEXTT: DW 0 ;NEXT TABLE ENTRY
- OLDDSK: DB 0 ;HOLDER FOR CURRENTLY LOGGED-IN DRIVE
- OLDUSR: DB 0 ;CONTAINS USER NUMBER UPON INVOCATION
- SCOUNT: DW 0 ;# TO SORT
- SUPSPC: DB 0 ;LEADING SPACE FLAG FOR DECIMAL ROUTINE
- TBLOC: DW 0 ;POINTER TO START OF NAME TABLE
- TEMP: DW 0 ;SAVE DIR ENTRY
- VERFLG: DB 0 ;CX/M VERSION NUMBER (0=PRE-CP/M 2)
- FNDFLG DB 0 ;File found flag
- LLENLOC:DW 0 ;RUNNING TOTAL OF .LBR LENGTH
- LCOUNT: DW 0
- NEXTL: DW 0
- SLFILE: DW 0
- SEARN DS 11 ;HOLDING AREA FOR SEARCH NAME
- LBRFCB: DS 36
- LBBUF: DS 80H
- ;
- DS 80H ;STACK AREA
- STACK: DS 2 ;SAVE OLD STACK POINTER HERE
- ;
- ORDER: EQU $ ;ORDER TABLE STARTS HERE
- ;
- ;
- END