home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
UTILS
/
DIRUTL
/
DIRF.AQM
/
DIRF.ASM
Wrap
Assembly Source File
|
2000-06-30
|
5KB
|
202 lines
; DIRF.ASM ver 1.3
; by Keith Petersen, W8SDZ
; (revised 12/19/80)
;
; DIRECTORY FUNCTION FOR CP/M 1.4 OR 2.x PROGRAMS
;
;This file contains routines which can be included in any
;CP/M program to allow listing the directory. No sorting
;is done because that would require use of more memory above
;the program. These routines use the 80h default buffer for
;all operations so if you have data there be sure to move it
;before running this directory function. Assume all registers
;destroyed when calling 'DIRF'.
;
;This module may be assembled as a stand-alone program for
;testing. Execute program from CP/M, not DDT or L80. It
;will return to the CCP after finishing.
;
;Remove the following ORG statement and the END statement
;when including this module in other programs
ORG 100H ;TEMPORARY ORG FOR TESTING
;
;--->DIRF.LIB STARTS HERE
;
NPL EQU 4 ;NUMBER OF NAMES PER LINE
TAB EQU 9 ;HORIZONTAL TAB
CR EQU 0DH ;CARRIAGE RETURN
LF EQU 0AH ;LINE FEED
;
;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
FSRCHF EQU 17 ;0FFH=NOT FOUND
FSRCHN EQU 18 ; " "
CURDSK EQU 25 ;GET CURRENT DISK NAME
BDOS EQU 5
FCB EQU 5CH
;
;First, we preserve old stack pointer and set a new one
;because some functions take more stack space than may
;be available in the calling program.
DIRF: LXI H,0
DAD SP ;GET OLD STACK POINTER
SHLD STACK ;SAVE FOR LATER
LXI SP,STACK ;SET NEW STACK POINTER
;
;Check FCB for drive request
LDA FCB ;GET DRIVE NAME FROM FCB
ORA A ;ANY REQUESTED? (0=NO)
JNZ GOTDRV ;NOT ZERO MEANS WE HAVE NAME
;
;Get drive name
MVI C,CURDSK ;GET CURRENT DRIVE NAME
CALL BDOS
INR A ;MAKE 'A' RELATIVE TO 1 NOT 0
;
;Print signon message and drive name
GOTDRV: ADI 40H ;MAKE IT ASCII
STA DNAME ;SAVE IT IN MESSAGE
LXI D,MSG ;POINT TO MESSAGE
MVI C,PRINT ;PRINT IT
CALL BDOS
;
;Make FCB all '?' to match any file
LXI H,FCB+1
MVI B,11 ;FN+FT COUNT
;
QLOOP: MVI M,'?' ;STORE '?' IN FCB
INX H
DCR B
JNZ QLOOP
;
;Initialize number of names per line counter
MVI A,NPL ;NR. NAMES PER LINE
STA NNAMS ;INIT COUNTER
;
;Look up the FCB in the directory
MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC
LXI D,FCB
CALL BDOS ;READ FIRST
INR A ;WERE THERE ANY?
JNZ SOME ;GOT SOME
CALL ERXIT
DB '++NOT FOUND$'
;
;Read more directory entries
MORDIR: MVI C,FSRCHN ;SEARCH NEXT
LXI D,FCB
CALL BDOS ;READ DIR ENTRY
INR A ;CHECK FOR END (0FFH)
JZ EXIT ;NO MORE - EXIT
;
;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)
;
;Check for console break
PUSH H ;SAVE NAME POINTER
MVI C,CONST ;CK STATUS OF KBD
CALL BDOS
POP H ;RESTORE NAME POINTER
ORA A ;ANY KEY PRESSED?
JNZ ABORT ;YES, ABORT
;
;Print an entry
MVI B,8 ;FILE NAME LENGTH
CALL TYPEIT ;TYPE FILENAME
MVI A,'.' ;PERIOD AFTER FN
CALL TYPE
MVI B,3 ;GET THE FILETYPE
CALL TYPEIT
LXI H,NNAMS ;POINT TO NAMES COUNTER
DCR M ;ONE LESS ON THIS LINE
PUSH PSW
CNZ FENCE ;NO CR-LF NEEDED, DO FENCE
POP PSW
CZ CRLF ;CR-LF NEEDED
JMP MORDIR
;
;Print two spaces, fence character, then two more spaces
FENCE: CALL TWOSPC
MVI A,':' ;FENCE CHARACTER
CALL TYPE
;
;Print two spaces
TWOSPC: CALL SPACE
;
;Print one space
SPACE: MVI A,' '
;
;Type char in A register
TYPE: PUSH B
PUSH D
PUSH H
MOV E,A ;CHAR TO E FOR CP/M
MVI C,WRCHR ;WRITE CHAR TO CONSOLE FUNC
CALL BDOS
POP H
POP D
POP B
RET
;
;Type (B) characters from memory (HL)
TYPEIT: MOV A,M
ANI 7FH ;REMOVE CP/M 2.x ATTRIBUTES
CALL TYPE
INX H
DCR B
JNZ TYPEIT
RET
;
;CR-LF routine. HL=NNAMS upon entry
CRLF: MVI A,CR ;CR
CALL TYPE
MVI A,LF ;LF
CALL TYPE
MVI M,NPL ;NUMBER OF NAMES PER LINE
RET
;
;Error exit
ERXIT: POP D ;GET MSG
MVI C,PRINT
JMP CALLB ;PRINT MSG, EXIT
;
;Abort - read char entered to clear it from CP/M buffer
ABORT: MVI C,RDCHR ;DELETE THE CHAR
;
;Fall into CALLB
CALLB: CALL BDOS
;
;Fall into EXIT
;
;Exit - All done, return to caller
EXIT: LHLD STACK ;GET OLD STACK
SPHL ;MOVE TO STACK
RET ;...AND RETURN
;
MSG: DB TAB,TAB,' Directory for drive '
DNAME: DB 'X:',CR,LF,'$'
;
;Temporary storage area
NNAMS: DS 1 ;NAMES PER LINE COUNTER
DS 40 ;ROOM FOR STACK
STACK: DS 2 ;OLD STACK STORED HERE
;
;Temporary end statement used only for testing DIRF module.
;Remove before including module in other programs.
END DIRF