home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol093
/
modem797.lib
< prev
next >
Wrap
Text File
|
1984-04-29
|
18KB
|
1,037 lines
; MACROS LIBRARY FOR CP/M ROUTINE SIMULATION 12/27/82
;
;
; CONTAINS:
;
; 1) INBUF - Duplicates 'read buffer' routine same as CP/M
; function 10, but does not use CTL-C (reason for
; for the routine). Does allow controls U, R, E
; and H (backspace). Outputs bell if the input is
; greater than the buffer.
; 2) CMDLINE - Parses a CPM/M buffer into format same as CP/M
; command line.
; 3) INLNCOMP - Compares a string following 'CALL ILCOMP' to a
; string addressed by the 'DE' registers.
; 4) MFACCESS - Multi-file access routine from the CP/M user's
; group.
; 5) SENDTIME - Shows the time needed to send a file for current
; baud rate. (For 110-9600 baud).
; 6) PRTBAUD - Shows baud rates set for 'time to send' file
; transfer.
; 7) DIRLIST - Lists directory and gives free space remaining
; on the requested drive.
;
;
INBUF MACRO ;NO PARAMETERS USED.
;
LOCAL START,INBUFO,INBUFA,DELETE,NODEL,ALERT,INBUFLT,CLEAR
LOCAL CLEARL,INBUFR,RETYPE,BKSPC,PCRLF,CONIN,COUNOUT,CONIN1
LOCAL CONOUT1,NOUCASE,CTLRLP,CONSTAT,CONST1,CONINLP
;
PUSH PSW
PUSH H
PUSH B
PUSH D ;'DE' REGISTERS MUST BE PUSHED LAST
START
CALL CLEAR ;CLEAR THE BUFFER AREA
POP D ;GET ADDRESS OF BUFFER ON RETRIES
PUSH D ;RESTORE STACK
XRA A
INX D ;ADDRESS COUNT FIELD
STAX D ;INITIALIZE WITH A ZERO IN COUNT BYTE
INX D
XCHG ;ADDRESS FIRST BUFFER BYTE WITH 'HL'
INBUFA
CALL CONIN
CPI 0DH ;IS IT A RETURN?
JZ INBUFR ;IF SO, THEN RETURN
CPI 7FH ;IS IT A DELETE?
JZ DELETE
CPI 8 ;CTL-H WILL BACKSPACE..
JZ DELETE ;..OVER DELETED CHAR.
CPI 'U'-40H ;IS IT A CTL-U
JZ INBUFO ;OUTPUT # CR-LF AND START OVER
CPI 'R'-40H ;CTL-R RETYPES LINE
JZ RETYPE
CPI 'E'-40H
JZ PCRLF
CPI 20H ;NO CONTROL CHARACTERS OTHER..
JC INBUFA ;..THAN ABOVE ALLOWED.
MOV B,A ;SAVE INPUTTED CHARACTER
XCHG ;SAVE 'HL' IN 'DE'
POP H ;GET ADDRESS OF BUFFER IN 'HL'
PUSH H ;RESTORE STACK
INX H ;ADDRESS COUNT BYTE
INR M ;INCREASE COUNT BYTE
DCX H ;ADDRESS MAXIMUM
MOV A,M ;PUT MAXIMUM IN 'A'
INX H ;ADDRESS COUNT
CMP M ;COMPARE COUNT TO MAXIMUM
JC ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR
XCHG ;RESTORE BUFFER POINTER TO 'HL'
MOV M,B ;PUT INPUTTED CHARACTER IN BUFFER
MOV A,B ;OUTPUT IT
CALL CONOUT
INX H ;BUMP POINTER
JMP INBUFA ;GET NEXT CHARACTER
;
DELETE
XCHG ;SAVE BUFFER POINTER IN 'DE'
POP H ;ADDRESS BEGINNING OF BUFFER
PUSH H ;RESTORE STACK
INX H ;ADDRESS COUNT FIELD
MOV B,A ;SAVE DELETE CHAR - 7FH OR 08H
MOV A,M
SUI 1 ;DECREASE COUNT
MOV M,A
JC NODEL ;DON'T DELETE PAST BEGINING OF BUFFER.
XCHG ;RESTORE BUFFER POINTER TO 'HL'
DCX H ;POINT TO LAST BYTE INPUTTED
MOV A,B ;GET BACK EITHER 7FH OR 08H
MOV B,M ;GET CHARACTER BEING DELETED
MVI M,20H ;RESTORE BLANK
CPI 8
JZ BKSPC
CPI 7FH
JZ BKSPC0
JMP INBUFA ;GET NEXT CHARACTER
;
NODEL
INR M ;DON'T LEAVE COUNT NEGATIVE
XCHG ;RESTORE POINTER TO 'HL'
JMP INBUFA
;
BKSPC0
MVI A,08H
BKSPC
CALL CONOUT ;TRUE ERASE IF 08H
MVI A,20H
CALL CONOUT
MVI A,8
CALL CONOUT
JMP INBUFA
;
INBUFO
MVI A,'#'
CALL CONOUT
MVI A,0DH
CALL CONOUT
MVI A,0AH
CALL CONOUT
JMP START
;
RETYPE
POP D
PUSH D
INX D ;POINT TO CURRENT NUMBER..
LDAX D ;..OF CHARACTERS.
MOV B,A
MVI A,'#'
CALL CONOUT
MVI A,0DH
CALL CONOUT
MVI A,0AH
CALL CONOUT
MOV A,B ;TEST IF ZERO INPUT
ORA A
JZ INBUFA
CTLRLP
INX D
LDAX D
CALL CONOUT
DCR B
JNZ CTLRLP
JMP INBUFA
;
ALERT
MVI A,7
CALL CONOUT
DCR M
XCHG
JMP INBUFA
;
PCRLF
MVI A,0DH
CALL CONOUT
MVI A,0AH
CALL CONOUT
JMP INBUFA
;
INBUFR
MVI A,0DH
CALL CONOUT
MVI A,0AH
CALL CONOUT
POP D
POP B
POP H
POP PSW
RET
;
CLEAR
POP D ;ACCOUNTS FOR CALL
POP H ;ADDRESS BUFFER IN 'HL'
PUSH H ;RESTORE..
PUSH D ;..STACK
MOV B,M ;SAVE MAXIMUM IN 'B'
INX H ;POINT TO FIRST..
INX H ;..BUFFER BYTE.
MVI A,20H
CLEARL
MOV M,A
INX H
DCR B
JNZ CLEARL
RET
;
CONIN
PUSH H
PUSH D
PUSH B
CONINLP
CALL CONSTAT
ORA A
JZ CONINLP
CALL CONIN1
CPI 61H ;CHANGE TO UPPER..
JC NOUCASE ;..CASE SINCE CP/M..
CPI 7BH ;..DOES THE SAME.
JNC NOUCASE
ANI 5FH
NOUCASE
POP B
POP D
POP H
RET
;
CONIN1
LHLD 1
LXI D,6
DAD D
PCHL
;
CONSTAT PUSH H
PUSH D
PUSH B
CALL CONST1
POP B
POP D
POP H
RET
;
CONST1
LHLD 1
LXI D,3
DAD D
PCHL
;
CONOUT PUSH H
PUSH D
PUSH B
PUSH PSW
CALL CONOUT1
POP PSW
POP B
POP D
POP H
RET
;
CONOUT1
LHLD 1
LXI D,9
DAD D
MOV C,A
PCHL
;
ENDM
;.....
;
;
CMDLINE MACRO ;NO PARAMETERS USED
; Loads a command line addressed by 'DE' registers (max # characters in
; line in 'DE', number of characters in the line in 'DE'+1, line starts
; in 'DE'+2) into FCB addressed by 'HL' registers. The FCB should be at
; least 33 bytes in length. The command line buffer must have a maximum
; length of at least one more than the greatest number of characters
; that will be needed.
;
LOCAL CMDLINE,DEFDR,DONE,DRIVE,FILL1,FILL,FILL2,INIT,INITL1
LOCAL INITL2,INITL3,INITL4,NAME1,NAME2,SCAN,TRANS,TSTNAM
LOCAL TSTTYP,TSTTYPL,TYPE1,TYPE2,NAME2C
;
PUSH PSW
PUSH B
PUSH D
PUSH H
;
CALL INIT ;FILLS FCBS WITH BLANKS AND NULLS
;
XCHG ;GET START OF COMMAND LINE IN 'HL'
INX H ;ADDRESS # BYTES IN CMD LINE
MOV E,M ;LOAD 'DE' PAIR WITH # BYTES
MVI D,0
INX H
DAD D ;POINT TO BYTE AFTER LAST CHAR..
MVI M,0DH ;..IN CMD LINE AND STORE DELIMITER
POP H ;RESTORE 'HL' AND 'DE'
POP D
PUSH D
PUSH H
INX D ;ADDRESS START OF COMMAND
INX D
;
CALL DRIVE
NAME1
MVI C,8 ;TRANSFER FIRST FILENAME TO FCB
CALL TRANS
CPI 0DH
JZ DONE
CPI 20H ;IF SPACE, THEN START OF..
JZ NAME2 ;..SECOND FILENAME.
TYPE1
POP H ;FILETYPE MUST BE AFTER..
PUSH H ;..EIGHTH BYTE OF NAME
LXI B,9
DAD B
MVI C,3 ;TRANSFER TYPE OF FIRST FILE
CALL TRANS
CPI 0DH
JZ DONE
NAME2
LDAX D ;EAT MULTIPLE SPACES..
CPI 20H ;..BETWEEN NAMES
JNZ NAME2C
INX D
JMP NAME2
LDAX D
CPI 0DH ;TEST IF FIRST NAME..
JZ DONE ;..ONLY AND THEN SPACE
NAME2C
POP H ;SECOND NAME STARTS IN 16TH BYTE
PUSH H ;POINT 'HL' TO THIS BYTE
LXI B,16
DAD B
CALL DRIVE
MVI C,8
CALL TRANS
CPI 0DH
JZ DONE
TYPE2
POP H ;SECOND TYPE STARTS IN 25TH BYTE.
PUSH H
LXI B,25
DAD B
MVI C,3
CALL TRANS
DONE
POP H
PUSH H
INX H ;POINT TO 1ST CHAR OF 1ST NAME IN FCB
CALL SCAN ;CHECK FOR * (AMBIGUOUS NAMES).
POP H
PUSH H
LXI B,17 ;POINT TO 1ST CHAR OF 2ND NAME IN FCB.
DAD B
CALL SCAN
POP H
POP D
POP B
POP PSW
RET
;
;
INIT PUSH H ;INITIALIZES FCB WITH 1 NULL (FOR 1ST DRIVE),..
PUSH B ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE),..
MVI M,0 ;..11 BLANKS, AND 4 NULLS
INX H
MVI B,11
MVI A,20H
CALL INITFILL
MVI B,5
MVI A,0
CALL INITFILL
MVI B,11
MVI A,20H
CALL INITFILL
MVI B,4
MVI A,0
CALL INITFILL
POP B
POP H
RET
;
INITFILL
MOV M,A
INX H
DCR B
JNZ INITFILL
RET
;
DRIVE INX D ;CHECK 2ND BYTE OF FILENAME. IF IT..
LDAX D ;..IS A ":", THEN DRIVE WAS SPECIFIED
DCX D
CPI ':'
JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO)
LDAX D
ANI 5FH
SUI 40H ;CALCULATE DRIVE (A=1, B=2,...)..
MOV M,A ;..AND PLACE IT IN FCB
INX D ;ADDRESS FIRST BYTE OF..
INX D ;..IN CMD LINE..
DEFDR
INX H ;..AND NAME FIELD IN FCB
RET
;
TRANS
LDAX D ;TRANSFER FROM CMD LINE TO FCB..
INX D ;..UP TO NUMBER OF CHARS SPECIFIED..
CPI 0DH ;..BY 'C' REG. KEEP SCANNING FIELD..
RZ ;..WITHOUT TRANSFER UNTIL A DELIMITING..
CPI '.' ;..FIELD CHAR SUCH AS '.', BLANK, OR..
RZ ;..C/R (FOR END OF CMD LINE)
CPI 20H
RZ
DCR C
JM TRANS ;ONCE 'C' REG IS LESS THAN '0' KEEP READING
MOV M,A ;..CMD LINE BUT DO NOT TRANSFER TO FCB
INX H
JMP TRANS
;
SCAN
MVI B,8 ;SCAN FILE NAME ADDRESSED BY 'HL'
TSTNAM
MOV A,M
CPI '*' ;IF '*' FOUND, FILL IN REST OF FIELD..
JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME
INX H
DCR B
JNZ TSTNAM
JMP TSTTYP
FILL1
CALL FILL
TSTTYP
MVI B,3 ;SCAN AND FILL TYPE FIELD FOR NAME..
TSTTYPL
MOV A,M ;..SPECIFIED ABOVE
CPI '*'
JZ FILL2
INX H
DCR B
RZ
JMP TSTTYPL
;
FILL2
;
FILL
MVI M,'?' ;ROUTINE TRANSFERS '?'
INX H
DCR B
JNZ FILL
RET
;
ENDM
;.....
;
;
INLNCOMP MACRO ;NO PARAMETERS USED
;
; In-line compare. Compares string addressed by 'DE' pair to string af-
; the call (ends with '0'). Return with carry set means strings not the
; same. All registers (except 'A') are unaffected.
; SAME. ALL REGISTERS EXCEPT A-REG ARE UNAFFECTED.
;
LOCAL ILCOMPL,SAME,NOTSAME,NSLP
;
XTHL ;POINT 'HL' TO 1ST CHARACTER
PUSH D
ILCOMPL
MOV A,M ;'HL' POINTS TO IN-LINE STRING
ORA A ;END OF STRING IF ZERO
JZ SAME
LDAX D
CMP M
JNZ NOTSAME
INX H
INX D
JMP ILCOMPL
;
NOTSAME
MVI A,0 ;IF NOT SAME, FINISH THRU..
NSLP
INX H ;..STRING SO RETURN WILL..
CMP M ;..GO TO INSTRUCTION AFTER..
JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING
STC
SAME
POP D
INX H ;AVOIDS A NOP INSTRUCTION..
XTHL ;..WHEN RETURNING
RET
;
ENDM
;.....
;
;
MFACCESS MACRO ;NO PARAMETERS USED
;
; Multi-file access subroutine. Allows processing of multiple files
; (i.e., *.ASM) from disk. This routine builds the proper name in the
; FCB each time it is called. This command would be used in such pro-
; grams such as modem transfer, tape save, etc. in which you want to
; process single or multiple files.
;
; The FCB will be set up with the next name, ready to do normal proces-
; sing (OPEN, READ, etc.) when routine is called.
;
; Carry is set if no more names can be found
;
; Define data move MACRO
;
LOCAL MOVE,CPM,MFNAME,MFN01,MFN02,MFFIX1,MFREQ,MFCUR,MOVER
LOCAL SRCHF,SRCHN,STDMA,BDOS,FCB,FCBEXT,FCBRNO
;
; ;MFFLG1 IS NOT SET LOCAL BECAUSE IT MUST
; ;BE RESET IN MAIN MODEM PROGRAM ON AN
; ;ABORT
;
MOVE MACRO ?F,?T,?L,?I
IF NOT NUL ?F
LXI H,?F
ENDIF
IF NOT NUL ?T
LXI D,?T
ENDIF
IF NOT NUL ?L
LXI B,?L
ENDIF
IF NOT NUL ?I
LOCAL ?B,?Z
CALL ?Z
?B DB ?I
?Z POP H ;GET TO
LXI B,?Z-?B
ENDIF
CALL MOVER
MF SET -1 ;SHOW EXPANSION
ENDM
;...
;
;
;DEFINE CP/M MACRO - CPM FNC,PARM
;
CPM MACRO ?F,?P
PUSH B
PUSH D
PUSH H
IF NOT NUL ?F
MVI C,?F
ENDIF
IF NOT NUL ?P
LXI D,?P
ENDIF
CALL BDOS
POP H
POP D
POP B
ENDM
;...
;
;
; MULTI-FILE ACCESS SUBROUTINE
;
; The routine is commented in pseudo code, each pseudo code statement is
; in <<...>>
;
MFNAME
;
;<<INIT DMA ADDR, FCB>>
;
CPM STDMA,80H
XRA A
STA FCBEXT
;
;<<IF FIRST TIME>>
;
LDA MFFLG1
ORA A
JNZ MFN01
;
; <<TURN OFF 1ST TIME SW>>
;
MVI A,1
STA MFFLG1
;
; <<SAVE THE REQUESTED NAME>>
;
MOVE FCB,MFREQ,12 ;SAVE ORIG REQ
LDA FCB
STA MFCUR ;SAVE DISK IN CURRENT FCB
;
; <<SRCHF REQ NAME>>
;
MOVE MFREQ,FCB,12
CPM SRCHF,FCB
;
;<<ELSE>>
;
JMP MFN02
MFN01
;
; <<SRCHF CURR NAME>>
;
MOVE MFCUR,FCB,12
CPM SRCHF,FCB
;
; <<SRCHN REQ NAME>>
;
MOVE MFREQ,FCB,12
CPM SRCHN,FCB
;
;<<ENDIF>>
;
MFN02
;
;<<RETURN CARRY IF NOT FOUND>>
;
INR A
STC
JNZ MFFIX1
STA MFFLG1
RET
;
;
MFFIX1
;
;<<MOVE NAME FOUND TO CURR>>
DCR A
ANI 3
ADD A
ADD A
ADD A
ADD A
ADD A
ADI 81H
MOV L,A
MVI H,0
PUSH H ;SAVE NAME POINTER
MOVE ,MFCUR+1,11
;
;<<MOVE NAME FOUND TO FCB>>
;
POP H
MOVE ,FCB+1,11
;
;<<SETUP FCB>>
;
XRA A
STA FCBEXT
STA FCBRNO
;
;<<RETURN>>
;
RET
;
;
; Multi-file access work area
MFFLG1 DB 0 ;1ST TIME SW
MFREQ DS 12 ;REQ NAME
MFCUR DS 12 ;CURR NAME
;
; Move subroutine
;
MOVER MOV A,M
STAX D
INX H
INX D
DCX B
MOV A,B
ORA C
JNZ MOVER
RET
;
;
; Equates used by multi-access subroutine
SRCHF EQU 17
SRCHN EQU 18
STDMA EQU 26
BDOS EQU 5
FCB EQU 5CH
FCBEXT EQU FCB+12
FCBRNO EQU FCB+32
ENDM
;.....
;
;
SENDTIME MACRO ;NO PARAMETERS USED
;
; Shows the time to transfer a file at various baud rates
;
LOCAL BTABLE,SECTBL,DVHLDE,DIVL1,MULHLA,MULLP,SHFTHL
CALL ILPRT ;PRINT:
DB 'File open: ',0
LHLD RCNT ;GET RECORD COUNT.
CALL DECOUT ;PRINT DECIMAL NUMBER OF RECORDS
CALL ILPRT
DB ' (',0
CALL DHXOUT ;NOW PRINT SIZE IN HEX.
CALL ILPRT
DB ' Hex) Records',CR,LF
DB 'Send time: ',0
LDA MSPEED ;GET THE SPEED INDICATOR
MVI D,0
MOV E,A ;SET UP FOR TABLE ACCESS
LXI H,BTABLE ;POINT TO BAUD FACTOR TABLE
DAD D ;INDEX TO PROPER FACTOR
DAD D ;FACTOR IN DE
MOV E,M
INX H
MOV D,M
LHLD RCNT ;GET # OF RECORDS
CALL DVHLDE ;DIVIDE 'HL' BY VALUE IN DE (RECORDS/MIN)
PUSH H
MOV L,C
MOV H,B
CALL DECOUT ;PRINT THE MINUTES PORTION
CALL ILPRT
DB ' mins, ',0
LXI H,SECTBL ;POINT TO DIVISORS FOR SECONDS
LXI D,0 ; CALCULATION
LDA MSPEED ;GET INDEX FOR BAUD RATE
MOV E,A
DAD D ;INDEX INTO TABLE
MOV A,M ;GET MULTIPLIER
POP H ;GET REMAINDER
CALL MULHLA ;MULTIPLY THE 'HL' x 'A'
CALL SHFTHL
CALL SHFTHL
CALL SHFTHL
CALL SHFTHL
MVI H,0
CALL DECOUT ;PRINT THE SECONDS PORTION
CALL ILPRT
DB ' secs at ',0
CALL BAUDPRT
CALL ILPRT
DB 'To cancel: ctrl-X',CR,LF,0
RET
;
;
BTABLE DW 5,13,19,25,29,49,96,192,384,0 ;RECORDS/MIN FOR 110-9600 BAUD
SECTBL DB 192,74,51,38,33,20,11,5,3,0
;
;
;----> DVHLDE: DIVIDES 'HL' BY VALUE IN 'DE',
; UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER
;
DVHLDE
PUSH D ; SAVE DIVISOR
MOV A,E
CMA ; NEGATE DIVISOR
MOV E,A
MOV A,D
CMA
MOV D,A
INX D ; DE IS NOW TWOS COMPLEMENTED
LXI B,0 ; INIT QUOTIENT
DIVL1:
DAD D ; SUBTRACT DIVISOR FROM DIVIDEND
INX B ; BUMP QUOTIENT
JC DIVL1 ; LOOP TILL SIGN CHANGES
DCX B ; ADJUST QUOTIENT
POP D ; RETRIEVE DIVISOR
DAD D ; ADJUST REMAINDER
RET
;
;
;----> MULHLA: MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A'
; RETURN WITH ANSWER IN 'HL'
MULHLA
XCHG ; MULTIPLICAND TO DE
LXI H,0 ; INIT PRODUCT
INR A ; ADJUST MULTIPLIER FOR ZERO TEST
MULLP
DCR A
RZ
DAD D
JMP MULLP
;
;
; SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT
;
SHFTHL
MOV A,L
RAR
MOV L,A
ORA A ;CLEAR THE CARRY
MOV A,H
RAR
MOV H,A
RNC
MVI A,80H
ORA L
MOV L,A
RET
;
ENDM
;.....
;
;
PRTBAUD MACRO ;NO PARAMETERS USED
;
LOCAL BAUDSPD
;
LXI H,BAUDSPD
MVI D,0
LDA MSPEED ;GET BAUD RATE CODE
MOV E,A ;X1
ADD A ;X2
ADD A ;X4
ADD E ;X5
MOV E,A
DAD D ;POINT TO CORRECT RATE
XCHG
MVI C,PRINT
CALL BDOS
CALL ILPRT
DB ' baud',CR,LF,0
RET
;
BAUDSPD DB '110$',0,'300$',0,'450$',0,'600$',0,'710$',0
DB '1200$','2400$','4800$','9600$'
;
ENDM
;.....
;
;
DIRLIST MACRO ;NO PARAMETERS USED
;
LOCAL DIRLP,PRTNAME,NOFILE,DIRDONE,QSTMARK,QSTLP,PRNTNAME
LOCAL NEXTSR,MOVENAME,GETADD,SRCHFCB,NAMECT,PRNTHD,DRNAME
LOCAL FENCE,GSPBYT,GSPLUP,NOTFRE,ENDALC,FREKLP,PRTFREE
LOCAL PRTHD,DRNAME
;
LXI D,CMDBUF ;PUT COMMAND LINE IN FCB
LXI H,5CH
CALL CPMLINE
LXI H,SRCHFCB
CALL INITFCBS
LDA 6CH ;GET DRIVE #
STA SRCHFCB
LDA 6DH
CPI 20H ;IF BLANK GET ALL NAMES
PUSH PSW
CZ QSTMARK
POP PSW
CNZ MOVENAME ;ELSE MOVE NAME INTO FCB
LXI D,80H
MVI C,STDMA
CALL BDOS
XRA A
STA NAMEGD
STA NAMECT ;CR AFTER 4 NAMES
LXI D,SRCHFCB
MVI C,SRCHF ;DO FIRST SEARCH
CALL BDOS
CPI 0FFH
JZ NOFILE
PUSH PSW
DIRLP
POP PSW
CALL GETADD
LXI D,15 ;OFFSET FOR RECORD COUNT
DAD D
MOV A,M
ORA A
JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH
LXI D,-5
DAD D ;POINT TO $SYS ATTRIB BYTE
MOV A,M
ANI 80H
JNZ NEXTSR ;NO LIST IF $SYS FILE
LXI D,-10
DAD D ;POINT TO BEGINNING OF NAME
INX H ;POINT TO FIRST LETTER
LXI D,PRNTNAME
MVI B,8
CALL MOVE
INX D
MVI B,3
CALL MOVE
CALL ILPRT
PRNTNAME
DB ' ','.',' ',' ', 0 ;8 SPACES, PERIOD, 3 SPACES, 1 SPACE
MVI A,0FFH
STA NAMEGD
NEXTSR
LXI D,SRCHFCB
MVI C,SRCHN ;DO NEXT SEARCH
CALL BDOS
CPI 0FFH
JZ DIRDONE
PUSH PSW
LDA NAMEGD
ORA A
JZ DIRLP
LDA NAMECT
INR A
STA NAMECT
ANI 03H
ORA A
CZ CRLF
CNZ FENCE
MVI A,0
STA NAMEGD
JMP DIRLP
;
NOFILE
CALL ILPRT
DB 'NO FILE',0
;
;
; Determines free space remaining
;
DIRDONE
LDA SRCHFCB
ORA A
JZ DEFLT
DCR A
MOV E,A
MVI C,SELDSK
CALL BDOS
DEFLT
MVI C,GETPARM ;CURRENT DISK PARAMETER BLOACK
CALL BDOS
INX H
INX H
MOV A,M ;GET BLOCK SHIFT FACTOR
STA BSHIFTF
INX H ;BUMP TO BLOCK MASK
MOV A,M ;GET IT
STA BMASK
INX H
INX H
MOV E,M ;GET MAX BLOCK NUMBER
INX H
MOV D,M
XCHG
SHLD BMAX ;PUT IT AWAY
MVI C,GETALC ;ADDRESS OF CP/M ALLOCATION VECTOR
CALL BDOS
XCHG ;GET ITS LENGTH
LHLD BMAX
INX H
LXI B,0 ;INITIALIZE BLOCK COUNT TO ZERO
GSPBYT
PUSH D ;SAVE ALLOCATION ADDRESS
LDAX D
MVI E,8 ;SET TO PROCESS 8 BLOCKS
GSPLUP
RAL ;TEST BIT
JC NOTFRE
INX B
NOTFRE
MOV D,A ;SAVE BITS
DCX H
MOV A,L
ORA H
JZ ENDALC ;QUIT IF OUT OF BLOCKS
MOV A,D ;RESTORE BITS
DCR E ;COUNT DOWN 8 BITS
JNZ GSPLUP ;DO ANOTHER BIT
POP D ;BUMP TO NEXT COUNT OF ALLOCATION VECTOR
INX D
JMP GSPBYT ;PROCESS IT
;
ENDALC
POP D ;CLEAR ALLOCATION VECTOR FROM STACK
MOV L,C ;COPY BLOCK TO 'HL'
MOV H,B
LDA BSHIFTF ;GET BLOCK SHIFT FACTOR
SUI 3 ;CONVERT FROM RECORDS TO THOUSANDS
JZ PRTFREE ;SKIP SHIFTS IF 1K BLOCKS
FREKLP
DAD H ;MULTIPLY BLOCKS BY 'K PER BLOCK'
DCR A
JNZ FREKLP
PRTFREE
PUSH H
CALL ILPRT
DB CR,LF,'Drive ',0
LDA SRCHFCB ;IF NO DRIVE, GET
ORA A ;LOGGED IN DRIVE
JNZ PRNTHD
MVI C,CURDSK
CALL BDOS
INR A
PRNTHD
ADI 'A'-1
STA DRNAME
CALL ILPRT
DRNAME
DB ' has ',0
POP H ;GET NUMBER OF BYTES AVAILABLE
CALL DECOUT
CALL ILPRT
DB 'K bytes free',CR,LF,0
RET
;
; Subroutines
;
FENCE
CALL ILPRT
DB '| ',0
RET
;
QSTMARK
MVI A,'?' ;IF BLANK IN FCB, PUT IN 11 ?'s
MVI B,11
LXI H,SRCHFCB+1
QSTLP
MOV M,A
INX H
DCR B
JNZ QSTLP
RET
;
MOVENAME
LXI H,6DH
LXI D,SRCHFCB+1
MVI B,11
JMP MOVE ;MOVE IN MAIN PROGRAM
;
GETADD
ANI 03H ;GET MOD4 FOR CP/M 1.4
ADD A ;ADD 32
ADD A
ADD A
ADD A
ADD A
MOV E,A
MVI D,0
LXI H,80H ;ADD DMA OFFSET
DAD D
RET
;
;
; Parameters used
;
GETALC EQU 27 ;CP/M ALLOCATION VECTOR ADDRESS
GETPARM EQU 31 ;CURRENT DISK PARAMETERS ADDRESS
;
;
; Unitialized storage
;
SRCHFCB DS 33
NAMEGD DS 1
NAMECT DS 1
BMAX DS 2 ;HIGHEST BLOCK NUMBER ON DRIVE
BMASK DS 1 ;(RECORDS/BLOCK)-1
BSHIFTF DS 1 ;NUMBER OF SHIFTS TO MULTIPLY BY REC/BLOCK
;
ENDM