home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol004
/
fmap6-12.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
8KB
|
441 lines
;
; FMAP.ASM
; (revised 6/12/80)
;
;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
;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
;
;10/30/79 MODIFIED TO ALLOW FOR 128 DIRECTORY ENTRIES
; (KEITH PETERSEN, W8SDZ).
;12/29/79 CORRECTED ERROR IN CONSTAT TEST
; FOR ABORTING PRINT. (KBP)
;06/12/80 ADD ANI 7FH TO REMOVE FILE ATTRIBUTES
; TO MAKE COMPATIBLE WITH CPM-2. (KBP)
;
FCB EQU 5CH ;SYSTEM FCB
;
ORG 100H
JMP START ;SKIP PROGRAM ID
DB '(FMAP 6/12/80)'
;SAVE THE STACK
START LXI H,0
DAD SP ;H=STACK
SHLD STACK ;SAVE IT
LXI SP,STACK ;GET NEW STACK
;SAVE FILE WRITE REQUEST CHAR
LDA FCB+17
STA FILESW
;NO FCB SPECIFIED?
LXI H,FCB+1
MOV A,M
CPI ' '
JNZ GOTFCB
;NO FCB - MAKE FCB ALL '?'
MVI B,11 ;FN+FT COUNT
QLOOP MVI M,'?' ;STORE '?' IN FCB
INX H
DCR B
JNZ QLOOP
;LOOK UP THE FCB IN THE DIRECTORY
GOTFCB MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC
LXI D,FCB
CALL BDOS ;READ FIRST
INR A ;WERE THERE ANY?
STA TEMP ;SAVE
JNZ PRTTL ;GOT SOME - PRT TITLE, CONT
LXI D,NONMSG
CALL WRCON
JMP EXIT
;
NONMSG DB '++NOT FOUND$'
;
;PRINT TITLE
PRTTL LXI D,TTL
CALL WRCON
CALL CR
LDA TEMP ;RELOAD EXTENT
JMP SOME
;
TTL DB 'FILENAME TYP RC -----GROUPS------$'
;
;READ MORE DIRECTORY ENTRIES
MOREDIR MVI C,FSRCHN ;SEARCH NEXT
LXI D,FCB
CALL BDOS ;READ DIR ENTRY
INR A ;CHECK FOR END (0FFH)
JZ SPRINT ;NO MORE - SORT & PRINT
;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,81H ;POINT TO BUFFER
;(SKIP TO FN/FT)
ADD L ;POINT TO ENTRY
MOV L,A ;SAVE (CAN'T CARRY TO H)
;MOVE ENTRY TO TABLE
XCHG ;ENTRY TO DE
LHLD NEXTT ;NEXT TABLE ENTRY TO HL
MVI B,11 ;NAME ENTRY LENGTH
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
MVI B,20 ;REST OF ENTRY LENGTH
;
TMOVE2 LDAX D ;GET ENTRY CHAR
MOV M,A ;STORE IN TABLE
INX D
INX H
DCR B ;MORE?
JNZ TMOVE2
SHLD NEXTT ;SAVE UPDATED TABLE ADDR
LDA COUNT ;GET PREV COUNT
INR A
STA COUNT
JMP MOREDIR
;
;SORT AND PRINT
SPRINT LDA COUNT ;INIT THE ORDER TABLE
LXI H,ORDER
LXI D,TABLE
LXI B,31 ;ENTRY LENGTH
;
BLDORD MOV M,E ;SAVE LO ORD ADDR
INX H
MOV M,D ;SAVE HI ORD ADDR
INX H
XCHG ;TABLE ADDR TO HL
DAD B ;POINT TO NEXT ENTRY
XCHG
DCR A ;MORE?
JNZ BLDORD ;..YES
LDA COUNT ;GET COUNT
STA SCOUNT ;SAVE AS # TO SORT
DCR A ;ONLY 1 ENTRY?
JZ DONE ;..YES, SO SKIP SORT
;
SORT XRA A ;GET A ZERO
STA SWITCH ;SHOW NONE SWITCHED
LDA SCOUNT ;GET COUNT
DCR A ;USE 1 LESS
STA TEMP ;SAVE # TO COMPARE
STA SCOUNT ;SAVE HIGHEST ENTRY
JZ DONE ;EXIT IF NO MORE
LXI H,ORDER ;POINT TO ORDER TABLE
;
SORTLP CALL COMPR ;COMPARE 2 ENTRIES
CM SWAP ;SWAP IF NOT IN ORDER
INX H ;BUMP ORDER
INX H ;..TABLE POINTER
LDA TEMP ;GET COUNT
DCR A
STA TEMP
JNZ SORTLP ;CONTINUE
;
;ONE PASS OF SORT DONE
LDA SWITCH ;ANY SWAPS DONE?
ORA A
JNZ SORT
;
;SORT IS ALL DONE - PRINT ENTRIES
DONE LXI H,ORDER
SHLD NEXTT
;IF WRITING A FILE, OPEN THE FILE
LDA FILESW
CPI 'F'
JNZ ENTRY
LXI D,MYFCB
MVI C,ERASE
CALL BDOS
LXI D,MYFCB
MVI C,FMAKE ;MAKE THE FILE
CALL BDOS
INR A
JNZ ENTRY
;MAKE ERROR
CALL ERXIT
DB '++FILE MAKE ERROR$'
;
;PRINT AN ENTRY
ENTRY MVI C,CONST ;CK STATUS OF KBD
CALL BDOS ;ANY KEY PRESSED?
ORA A
JNZ ABORT ;YES, ABORT
LHLD NEXTT ;GET ORDER TABLE POINTER
MOV E,M ;GET LO ADDR
INX H
MOV D,M ;GET HI ADDR
INX H
SHLD NEXTT ;SAVE UPDATED TABLE POINTER
XCHG ;TABLE ENTRY TO HL
MVI B,8 ;FILE NAME LENGTH
CALL TYPEIT ;TYPE FILENAME
CALL PERIOD ;SPACE AFTER FN
MVI B,3 ;GET THE FILETYPE
CALL TYPEIT
CALL FILECR
INX H ;SKIP EXTENT
INX H ;SKIP
INX H ;UNUSED
MOV A,M ;GET REC COUNT
DCR A ;FUDGE
RAR ;DIVIDE
RAR ;..BY 8
RAR
ANI 1FH ;DELETE GARBAGE
INR A ;MAKE RELATIVE TO 1, NOT 0
MOV B,A ;SAVE AS # EXTENTS
MOV A,M ;RELOAD RECORD COUNT
CALL XOB ;PRINT RECORD COUNT
INX H ;SKIP RECORD COUNT
MVI C,0 ;FOR EXTENT SKIP CTL
;
EXTLP MOV A,M ;GET EXTENT BYTE
ORA A ;EMPTY?
JZ ENDEXT ;..YES
CALL XO ;..NO, PRINT IT
INR C ;INCR COUNT
MOV A,C ;TIME TO SPACE?
ANI 3
CZ SPACE
INX H ;POINT TO NEXT CHR
DCR B ;MORE IN EXTENT?
JNZ EXTLP ;YES
;
;BUMP TOTAL FILE COUNT
ENDEXT LDA NFILE ;GET # FILES
INR A ;BUMP
DAA ;MAKE DECIMAL
STA NFILE ;SAVE IT BACK
CALL CR ;END, TYPE C/R
;SEE IF MORE ENTRIES
LDA COUNT
DCR A
STA COUNT
JNZ ENTRY ;YES, MORE
;ALL DONE - PRINT # FILES
LDA NFILE
CALL XOB
LXI D,NMSG
CALL WRCON
;CLOSE FILE IF NECESSARY
LDA FILESW
CPI 'F'
JNZ EXIT
MVI A,'Z'-40H ;EOF CHAR
CALL FILCHR ;WRITE IT
CALL WRSEC ;WRITE FINAL SECTOR
LXI D,MYFCB
MVI C,FCLOSE
CALL BDOS
JMP EXIT
;
NMSG DB 'FILES$'
;
;HEX OUTPUT W/BLANK
XOB CALL XO
JMP SPACE
;
;HEX OUTPUT
XO PUSH PSW ;SAVE CHAR
RAR
RAR
RAR
RAR
CALL NIBBL ;PRINT LEFT NIBBLE
POP PSW ;GET VALUE BACK
NIBBL ANI 0FH ;ISOLATE NIBBLE
CPI 10 ;NUMBER?
JC XNUM ;YES
ADI 7 ;FUDGE ALPHA HEX
XNUM ADI '0' ;MAKE PRINTABLE
;
;TYPE CHAR IN A
TYPE PUSH B
PUSH D
PUSH H
MOV E,A
MVI C,WRCHR
CALL BDOS
POP H
POP D
POP B
RET
;
WRCON MVI C,PRINT
JMP BDOS
;
TYPEIT MOV A,M
CALL FILCHR ;TO DISK IF REQ'D
CALL TYPE
INX H
DCR B
JNZ TYPEIT
RET
;
SPACE MVI A,' '
JMP TYPE
;
CR MVI E,13 ;PRINT
MVI C,2 ;C/R
CALL BDOS
MVI E,10 ;LF
MVI C,2
JMP BDOS
;
;ERROR EXIT
ERXIT POP D ;GET MSG
MVI C,PRINT
JMP CALLB ;PRINT MSG, EXIT
;
;ABORT - READ CHAR ENTERED
ABORT MVI C,RDCHR
CALLB CALL BDOS ;DELETE THE CHAR
;FALL INTO EXIT
;
;EXIT - ALL DONE , RESTORE STACK
EXIT LHLD STACK ;GET OLD STACK
SPHL ;MOVE TO STACK
RET ;..AND RETURN
;
;ROUTINES FOR CREATING FILE
;
;WRITE CHAR IN A TO FILE
;(SAVES ALL REGS INCLUDING A)
FILCHR CPI ' '
RZ ;DON'T WRITE BLANKS
PUSH PSW
LDA FILESW ;WRITING A FILE?
CPI 'F'
JNZ NOFILE
POP PSW ;GET CHAR
PUSH PSW ;SAVE IT BACK
PUSH H
LHLD BUFAD ;CURRENT BUFFER ADDR
MOV M,A
INX H
SHLD BUFAD
MOV A,H ;SEE IF FULL BUFF
DCR A
CZ WRSEC ;YES, WRITE SECTOR
POP H
NOFILE POP PSW ;RESTORE CHAR
RET
;
;WRITE A SECTOR
WRSEC PUSH B
PUSH D
LXI D,MYFCB
MVI C,FWRTE
CALL BDOS
ORA A
JZ WROK
CALL ERXIT
DB '++WRITE ERROR$'
;
WROK LXI H,80H ;START OF BUFF
SHLD BUFAD
POP D
POP B
RET
;
;TYPE A PERIOD INTO THE FILE
PERIOD MVI A,'.' ;GET PERIOD
CALL FILCHR ;WRITE TO FILE
JMP SPACE
;
;WRITE CR/LF INTO FILE
FILECR MVI A,13
CALL FILCHR
MVI A,10
CALL FILCHR
JMP SPACE
;
;COMPARE ROUTINE FOR SORT
COMPR PUSH H ;SAVE TABLE ADDR
MOV E,M ;LOAD LO
INX H
MOV D,M ;LOAD HI
INX H
MOV C,M
INX H
MOV B,M
;BC, DE NOW POINT TO ENTRIES TO BE COMPARED
XCHG
CMPLP LDAX B
CMP M
INX H
INX B
JZ CMPLP
POP H
RET ;COND CODE TELLS ALL
;
;SWAP ENTRIES IN THE ORDER TABLE
SWAP MVI A,1
STA SWITCH ;SHOW A SWAP WAS MADE
MOV C,M
INX H
PUSH H ;SAVE TABLE ADDR+1
MOV B,M
INX H
MOV E,M
MOV M,C
INX H
MOV D,M
MOV M,B
POP H
MOV M,D
DCX H ;BACK POINTER TO CORRECT LOC'N
MOV M,E
RET
;
NFILE DB 0 ;NUMBER OF FILES PRINTED
NEXTT DW TABLE ;NEXT TABLE ENTRY
COUNT DB 0 ;ENTRY COUNT
SCOUNT DB 0 ;# TO SORT
SWITCH DB 0 ;SWAP SWITCH FOR SORT
BUFAD DW 80H ;OUTPUT ADDR
MYFCB DB 0,'NAMES SUB',0
DS 19
DB 0
FILESW DS 1 ;'F' IF WRITING FILE
TEMP DS 1 ;SAVE DIR ENTRY
DS 60 ;STACK AREA
STACK DS 2 ;SAVE OLD STACK HERE
ORDER DS 256 ;ORDER TABLE (ROOM FOR 128 NAMES)
TABLE EQU $ ;READ ENTRIES IN HERE
;
; BDOS EQUATES
;
RDCHR EQU 1 ;READ CHAR FROM CONSOLE
WRCHR EQU 2 ;WRITE CHR TO CONSOLE
PRINT EQU 9 ;PRINT CONSOLE BUFF
CONST EQU 11 ;CHECK CONS STAT
FOPEN EQU 15 ;0FFH=NOT FOUND
FCLOSE EQU 16 ; " "
FSRCHF EQU 17 ; " "
FSRCHN EQU 18 ; " "
ERASE EQU 19 ;NO RET CODE
FREAD EQU 20 ;0=OK, 1=EOF
FWRTE EQU 21 ;0=OK, 1=ERR, 2=?, 255=NO DIR SPC
FMAKE EQU 22 ;255=BAD
FREN EQU 23 ;255=BAD
FDMA EQU 26
BDOS EQU 5
REBOOT EQU 0
;
END 100H