home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
enterprs
/
cpm
/
utils
/
f
/
pwaids.ark
/
PWDIR.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-27
|
6KB
|
327 lines
; PWDIR.ASM -- RON FRIEDRICH DEC. 1984
; See PWDIR.DOC for installation procedures.
;
;Set MHELP and MGOSPEL below to the proper function addresses
;for your version of Perfect Writer. See the PW.SYM file on the PW
;installation disk. Don't forget the 'H' for hex numbers. The values
;given here are for PW v.1.20.
;
MHELP EQU 45F1H
MGOSPEL EQU 5EC9H
;
BDOS EQU 0005H ;DOS ENTRY POINT (DE)
CONIN EQU 1 ;READ CONSOLE (C; BYTE RETURNED TO A)
CONOUT EQU 2 ;TYPE CHARACTER (C; BYTE IN E)
PRINTS EQU 9 ;PRINT STRING FUNCTION (C; ADR IN DE)
RSTDSK EQU 13 ;RESET DISK SYSTEM (C)
SELDSK EQU 14 ;SELECT DISK (C; DISK # IN E)
SRCH EQU 17 ;SEARCH DIRECTORY (C; FCB IN DE)
SRCHMOR EQU 18 ;SEARCH FOR NEXT IN DIRECTORY (C)
CURDSK EQU 25 ;CURRENT DISK (C; DISK # RETURNED IN A)
SETDMA EQU 26 ;(C; DMA adr in DE)
ALLOC EQU 27 ;Get ALLOCATION address (C; returned in HL)
PARAMS EQU 31 ;Get DISK PARAMETER address (C; returned in HL)
;
; NON GRAPHIC CHARACTERS
CR EQU 0DH ;CARRIAGE RETURN
LF EQU 0AH ;LINE FEED
SPACE EQU 32
CLINE EQU 24 ;CLEAR TO END OF LINE
CLEAR EQU 26 ;CLEAR SCREEN
ESC EQU 27
;
;****************************************************************
;AUTOMATIC DISK RESET WHEN PW.COM IS LOADED:
ORG 104H ;address of null bytes PW.COM v.1
CALL MGOSPEL
;
;****************************************************************
;DISPLAY DISK DIRECTORY ROUTINE:
;
ORG MHELP
PUSH B
MVI C,CURDSK
CALL BDOS ;Get current default disk.
STA OLDSEL
XRA A ;ZERO A; DEFAULT DISK 'A'
STA NEWSEL
INR A ; A = 1; IN 'FOUR' VAR
STA FOUR
MVI A,'A'
STA TITLE2
LXI D,DRSEL
CALL PSTRING ;PRINT SIGN ON MESSAGE
MVI C,CONIN
CALL BDOS ;GET DISK SELECTION (A OR B)
CPI 'B' ;IS IT B?
CZ DRIVEB ;IF YES, SWITCH IT 'B'
CPI 'b'
CZ DRIVEB
LXI D,TITLE1 ;PRINT TITLE
CALL PSTRING
MVI C,RSTDSK
CALL BDOS ;Reset disk system.
LDA NEWSEL
MOV E,A
MVI C,SELDSK
CALL BDOS ;Select disk to check.
;
;START DIRECTORY SEARCH
LXI H,0
SHLD FILECT
LXI D,DMA
MVI C,SETDMA
CALL BDOS
LXI D,FCB
MVI C,SRCH
;
NEXTNAME:
CALL BDOS
INR A
JZ CALCFREE
DCR A
PUSH PSW ;PUSH A
LHLD FILECT ;GET FILE COUNT
INX H ;INCREMENT FILE COUNT
SHLD FILECT ;SAVE IT
LDA FOUR
DCR A
JZ RST4
STA FOUR
LXI D,DIV
CALL PSTRING ; ' | '
POP PSW
MULTA: ;A * 32 + 1
RAL ;Rotate A five times.
RAL ; ADD A five times also works.
RAL
RAL
RAL
INR A
MVI B,0 ;CLEAR B
MOV C,A ;DMA BYTE COUNT IN BC
LXI H,DMA ;DMA ADDRESS IN HL
DAD B ;ADD BC+LH = FIRST BYTE OF FILENAME
MVI B,8 ;START BYTE COUNT 'FILENAME'
;
FILENAME:
CALL PRINTFN
JNZ FILENAME
;Print space
PUSH H
MVI A,SPACE
CALL PCHAR
POP H
MVI B,3 ;START BYTE COUNT 'EXT'
;
EXTENT:
CALL PRINTFN
JNZ EXTENT
;
MVI C,SRCHMOR
JMP NEXTNAME
;
CALCFREE: ;CALCULATE FREE SPACE
MVI C,PARAMS
CALL BDOS
INX H
INX H
MOV A,M
STA BYTE
INX H
INX H
INX H
MOV E,M
INX H
MOV D,M
PUSH D
MVI C,ALLOC
CALL BDOS
XCHG
POP H
INX H
LXI B,0
LOOP1:
PUSH D
LDAX D
MVI E,8
LOOP2:
RAL
JC JMP1
INX B
JMP1:
MOV D,A
DCX H
MOV A,L
ORA H
JZ JMP2
MOV A,D
DCR E
JNZ LOOP2
POP D
INX D
JMP LOOP1
JMP2:
POP D
MOV L,C
MOV H,B
LDA BYTE
SUI 3
JZ PSIZE
LOOP3:
DAD H
DCR A
JNZ LOOP3
;
PSIZE: PUSH H
CALL NEWLN
CALL NEWLN
LHLD FILECT
CALL PRNUM
LXI D,FLMSG
CALL PSTRING
POP H
CALL PRNUM
LXI D,FREE
CALL PSTRING
;
LDA OLDSEL
MOV E,A
MVI C,SELDSK
CALL BDOS ;Restore default disk.
POP B
RET ;EXIT
;
; SUBROUTINES
;
PCHAR: ;PRINT A CHARACTER
PUSH D
MVI C,CONOUT
MOV E,A
CALL BDOS
POP D
RET
;
PRNUM: ;BCD ADJUST (BINARY NUMBER IS IN HL) AND PRINT IT (NUM < 1000)
XRA A ;ZERO A
LXI D,0 ;ZERO DE (BCD count)
LXI B,0 ;ZERO BC (BINARY count)
LOOP4:
PUSH PSW ;save packed BCD number
MOV A,C
CMP L ;low binary byte match?
JNZ INCR ;no, skip high byte check
MOV A,B
CMP H ;high binary byte match?
JZ PRINT ;yes, BCD adjust done, print the number
INCR: POP PSW ;recover packed BCD number
INX B ;increment binary (BC)
ANA A ;clear carry bit
INR A ;increment BCD number
DAA ;decimal adjust
JNC LOOP4 ;no carry
INR D ;carry "100" byte
JMP LOOP4 ;check it
PRINT:
MOV A,D ;get '100' byte
CPI 0 ;is it zero?
JZ GET10 ;yes, skip it
ADI '0' ;otherwise print it
CALL PCHAR
GET10: POP PSW ;recover packed BCD number
PUSH PSW ;save it again
RRC ;shift high nibble down
RRC
RRC
RRC
ANI 0FH ;zero all other bits
CPI 0 ;is '10' byte = 0?
JNZ PR10 ;no, print it
SUB D ;is '100' byte also = 0?
JZ PR1 ;yes, skip '10' byte
XRA A ;no, zero A and print it
PR10: ADI '0'
CALL PCHAR
PR1: POP PSW ;recover packed BCD number
ANI 0FH ;zero high ('10') nibble
ADI '0' ;print units nibble
CALL PCHAR
RET
;
RST4: ; The 'FOUR' variable counts # of file names / printed line.
CALL NEWLN
MVI A,4
STA FOUR
POP PSW
JMP MULTA
;
DRIVEB: ;SWITCH DRIVE SELECTION TO B:
MVI A,1
STA NEWSEL
MVI A,'B'
STA TITLE2
RET
;
NEWLN:
LXI D,CRLF
CALL PSTRING
RET
;
PSTRING: ;PRINT STRING
; D,E ADDRESSES MESSAGE ENDING WITH "$"
MVI C,PRINTS ;PRINT BUFFER FUNCTION
CALL BDOS
RET
;
PRINTFN:
MOV A,M ;GET FILENAME BYTE
PUSH H ;STASH DMA ADDRESS
PUSH B ;STASH LINE BYTE COUNT
CALL PCHAR ;PRINT IT
POP B
POP H
INX H ;INCREMENT DMA ADDRESS
DCR B ;DECREMENT LINE BYTE COUNT
RET
;
;
; VARIABLE & STRING AREA
FOUR: DB 1
CRLF: DB CR,LF,'$'
DIV: DB ' | $'
DRSEL: DB ESC,'=7 ',CLINE,'DIRECTORY: Drive A or B? $'
TITLE1: DB CLEAR,'Directory of disk in Drive '
TITLE2: DB 'A: $'
FCB: DB 0,'???????????',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
FLMSG: DB ' files, $'
FREE: DB 'K free disk space',ESC,'=6 '
REDRW: DB 'Hit ESC --> or ESC CTRL-L to redraw screen.$'
;
OLDSEL: DS 1 ;CURRENT DEFAULT DISK
NEWSEL: DS 1 ;DISK TO CHECK
FILECT: DS 2 ;FILE COUNT
BYTE: DS 1
DMA: NOP ;START DISK INPUT BUFFER
;
;*********************************************************************
;RESET DISK SYSTEM ROUTINE:
;
ORG MGOSPEL
PUSH B
MVI C,CURDSK
CALL BDOS ;Get current default disk.
MOV E,A
PUSH D ;Save it.
MVI C,RSTDSK
CALL BDOS ;Reset disk system.
POP D
MVI C,SELDSK
CALL BDOS ;Restore default disk.
POP B
RET
END
B ;STASH LINE BYTE COUNT
CALL PCHAR ;PRINT IT
POP B
POP H
INX H ;INCREMENT