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
/
D-42A.LBR
/
D-42A.AQM
/
D-42A.ASM
Wrap
Assembly Source File
|
2000-06-30
|
32KB
|
1,442 lines
; D.ASM v4.2a - 10/27/84
;
; RESTRICTED DIRECTORY LIST PROGRAM
;
; D.COM is a directory list program, which writes 4 or 5 entries on a
; line, separated by colons.
;
; (THIS IS THE 'WHATSNEW' PROGRAM SEEN ON MANY RCPM SYSTEMS)
;
; The command contains an internal table of file names, which are not to
; be shown when just "D" is typed. (NOTE typing "D *.*" always shows
; all files)
;
; Why is this useful: A typical CP/M disk contains many utility files,
; such as ED.COM, ASM,COM, PIP.COM, STAT.COM, etc. When you do a direc-
; tory listing, you typically are not interested in seeing all those
; files, but rather just the "current" or "active" files. This is what
; "D.COM" can do.
;
; NOTE: Direct CBIOS calls are used for input and output in order to
; avoid echoing of inputted characters. This keeps a noisy phone
; line from causing garbage characters in the display.
;-----------------------------------------------------------------------
;
; WARNING: NZCPR 1.6 has a bug in the "path" logic that causes it not to
; search current drive, user 0 (sometimes) when you are not logged
; into user zero. The result is that WHATSNEW from drive A0: will
; get executed when you were expecting another drive to be displayed.
;
; 10/27/84 More gold for sysops. If you have directory names beginning
; v4.2a with a '-' they will no longer be set into the internal table.
; If you don't want them displayed use the ADD command. Note:
; the DEL command only deletes the first occurrence of a prog.
; name. When the program re-writes itself to disk the $SYS
; attribute is automatically set.
; - Russ Pencin [changes marked (RP)]
;
; 10/24/84 Now stores the user area and name of file in the internal
; v 4.2 table and checks the MAXUSR value to determine if the file
; name is within bounds before printing. Also checks the wheel
; byte before allowing any dangerous command to be used if the
; ZCPR equate is true. One caveat: ADD works the same as before;
; if you want to ADD a file to the list you must first go to the
; user area that you want assigned to the new file, then perform
; your ADD command. If you don't, the file will be assigned the
; current user area and appear as a +NOT FOUND+ in future searches.
; Any bugs or suggestions may be forwarded to The Dallas Connection
; RCP/M (214) 783-7684 (Ring back).
; - Russ Pencin [Changes marked (RP)]
;
; 10/12/84 Now displays two-digit user areas and has an assembly option
; v 4.1 for MAXUSR either hard-coded or ZCPR/NZCPR-controlled.
; - DCC, Dallas RCP/M.
;
; 10/10/84 A major change to the original 3.1 version of D.COM. This allows
; v 4.0 for only one copy of D.COM to reside on the root directory of each
; disk PROVIDED some version of NZCPR or ZCPR is used in place of the ; standard CP/M CCP. The program now steps thru all the user areas
; specified by MAXUSR on the current disk and catalogs new files by
; user area. Deleted files are called out by name (user area not
; necessary) and instructions given on how to search the system to
; find those that may have been moved. All original commands still
; function. I recommend LOKing the program to each disk in USER zero.
; The program will also function with the standard CCP but one copy
; will be required in each user area (as before).
; - Russ Pencin, Dallas Connection RCP/M.
;
;
; 05/05/84 Line with the "use FILE xxx*.*" now only appears on the line
; v3.1 with the message about moved or deleted files.
; - Irv Hoff
;
; 05/01/84 Changed the "Deleted files since --- " to "Files moved else-
; v3.0 where or deleted", then added a line "use FILE xxx*.* to see
; if available." With 20-40 megabyte disk systems now common,
; this is a convenient way to locate files which are no longer
; in the "Whatsnew" user area. It was misleading when reading
; the files had been deleted when most have merely been moved.
; (Every SYSOP needs FILE.COM on his system.) SD xxx*.* $U0AD
; may also be used, but gives information that is superfluous.
; Standardized the format. - Irv Hoff
;
; 08/12/82 Added SUB file option to allow writing each new filename
; v2.9 that appears in the "New Files" display to a .SUB file of
; the form:
; XSUB
; PIP
; $1=$2 Fn.Ft$3
; $1=$2 Fn.Ft$3
;
; etc., to allow a simple archive of new files to be performed
; by: SUBMIT D A:=B: [G1]. Also repaired bug in EXIT routine
; and removed character 'gobbler' routine so that the program
; will work better with 'type-ahead' BIOSes.
; - Dave Hardy
;
; 11/23/78 Originally written by Ward Christensen.
;
;=======================================================================
;
; Use: D *.* prints all names, 5 across.
;
; D *.ASM prints selected files just like DIR.
;
; D SET builds a table (in D.COM) of all names currently on the
; disk. (see *NOTE).
;
; D SET <DATE> adds the date for printing whenever is called by
; 'A>D<CR>' with no options. If the date field is left
; blank, it will be ignored. Note that the date must be
; 8 characters or less (see *NOTE).
;
; D TIT <TITLE FOR DISK> sets an internal disk title which prints
; out each time the program is run (if a title has been
; set). (maximum of about 70 characters, please, although
; it will handle a full CP/M input line.
;
; NOTE: To get rid of title (and accompanying
; print put type 'D TIT' and the title is
; set to null.
;
; D ADD FN.FT adds a name to the table in D.COM, so FN.FT will not
; be listed by the 'D' command (see *NOTE).
;
; D DEL FN.FT deletes a name from the table in D.COM, so if FN.FT
; is in the directory, it will be listed by 'D' (see NOTE)
;
; D SUB causes a file named 'D.SUB' to be generated on the current-
; ly logged-in drive. The file contains all of the 'New
; Files' names, and is of the form:
;
; XSUB
; PIP
; $1<fn1.ft>$2
; $1<fn2.ft>$2
; $1<fn3.ft>$2
;
; etc. D.SUB can be used to archive 'New Files' with a
; simple command line like: SUBMIT D B:=A: [G5] which
; would PIP all of the new files from B5: to A:
;
; D lists the directory, showing only those files NOT in D.COM
; as put there by 'D SET' or 'D ADD FN.FT'
;
; *NOTE: the program must write itself
; back to disk, modified, so your
; disk must not be write protected.
;
;-----------------------------------------------------------------------
;
; Examples: Suppose your disk has:
;
; D.COM \
; ASM.COM \
; ED.COM on it initially.
; LOAD.COM /
; DDT.COM /
;
; You would type: D SET to set these names into the
; D.COM program.
;
; Typing "D" would then list:
;
; -->New files
; A: ++ NONE ++
;
; -->Deleted files
; A: ++ NONE ++
;
; Suppose you: A>ED TEST.ASM, A>ASM TEST and LOAD TEST.
; Typing D would then list:
;
; -->New files
; A: TEST ASM : TEST BAK : TEST HEX : TEST COM
;
; -->Deleted files
; A: ++ NONE ++
;
; i.e., it tells you of the "current" files on the disk.
; Now, supposing you wanted to add TEST.COM as a "regular"
; file on your disk. Type:
;
; D ADD TEST.COM
;
; Now, typing D will show:
;
; -->New files
; A: TEST ASM : TEST BAK : TEST HEX
;
; -->Deleted files
; A: ++NONE++
;
; i.e., TEST.COM is now considered a "permanent" file.
;
; Now, suppose you accidentally erased ASM.COM from your
; disk. Typing D gives:
;
; -->New files
; A: TEST ASM : TEST BAK : TEST HEX
;
; -->Deleted files
; A: ASM COM
;
; showing you are missing one of the "regular" files. If,
; in fact, you didn't want ASM.COM to be on the disk, type:
;
; D DEL ASM.COM
;
; which will delete the name from the D.COM table, so
; ASM.COM will not up as "deleted".
;
;=======================================================================
;
; SPECIAL NOTES FOR REMOTE SYSTEM USE:
;
; If you keep a dedicated copy of this program on each drive of your re-
; mote system, you can 'dedicate' each copy of this program to a drive
; by filling in the byte at 103H with the drive number. This prevents
; such things as:
;
; A>D B:
; or
; B>A:D
;
; Do this by using the command:
;
; A>D LOK A: to lock to a drive
; or
; A>D LOK to unlock
;
; If the conditional 'NOSYS' is set YES, $SYS files in CP/M 2.x will be
; ignored in both directory listings and when the "ADD" option is in-
; voked, unless the override char is specified. This allows D.COM to be
; used as a "WHAT'S NEW" program for remote CP/M systems, where the $SYS
; files must not be listed.
;
; Examples:
;
; A>D *.* S displays everything
; A>D SET S puts ALL files in table
; A>D SET 12/23/80 sets date for reference
;
; (if you use 'D SET S', you lose the date option..
;
; If you use this program on a remote system, you will likely want to
; change the commands (ADD, DEL, and SET) for security. You will also
; want to change the $SYS suppress override character. You may also
; want to change the name of the program to make the name itself more
; informative, e.g. "WHATSNEW.COM".
;
;
; -->IMPORTANT: If you want the program to be 'TAG'ed after every D SET
; (so it cannot be taken by XMODEM), see the note at label
; "WRBACK" for setting the F1 bit in the filename itself.
;
;
; Note that this program defines its own name for write-back purposes
; under the label "WRBACK".
;
;=======================================================================
;
; Define some stuff
;
YES: EQU 0FFH
NO: EQU 0
;
;
BIAS: EQU 0 ;for std cp/m or 4200h for altcpm
BDOS: EQU 5+BIAS ;cp/m's BDOS access jump
CPMBUFF:EQU 80H+BIAS ;cp/m command line buffer
CR: EQU 0DH ;carriage return
FCB: EQU 5CH+BIAS ;cp/m's file control block
FCBRNO: EQU FCB+32 ;rec # in fcb
LF: EQU 0AH ;line feed
;
;
; Set the following for your system:
;
NOSYS EQU YES ;yes=ignore $sys files
FENCE EQU ' ' ;file name separator
NPL EQU 4 ;file names per line
zcpr equ YES ; if ZCPR or NZCPR handle MAXUSR
;
; The leader string for the SUB file (XSUB, PIP) is located at label
; SUBF4.
;
ORG 100H+BIAS
;
DENTRY: JMP AROUND
;
DRIVE: DB 0 ;<---drv # is put here if dedicated
;(this can be done with the lok command)
if zcpr
MAXUSR: equ 3Fh ;location of # of user areas to search
WHEEL: EQU 3EH ;LOCATION OF ZCPR WHEEL BYTE (RP)
endif
if not zcpr
MAXUSR: db 15+1 ;maximum user area (+1) to be searched
endif
;
;Initialize the local stack
;
AROUND: LXI H,0 ;hl=0
DAD SP ;hl=stack
SHLD STACK ;save stack pointer
LXI SP,STACK ;init local stack
;
;
;Initialize direct CBIOS calls
;
LHLD 1+BIAS
LXI D,3
DAD D ;hl=constat
SHLD TYPES+1
DAD D ;hl=conin
SHLD CIC+1
DAD D ;hl=conout
SHLD TYPEC+1
;
;
;Save the old user number and set user 0 (BH)
;
MVI C,32 ;get/set user
MVI E,0FFH ;to get
CALL BDOS
STA OLDUSR ;save it
MVI C,32
MVI E,0 ;to set
CALL BDOS
;
;
; Print ID message
;
CALL ILPRT ;print:
DB 'WhatsNew v4.2a',CR,LF
DB 'CTL-S pauses, CTL-C aborts',CR,LF,0
;
;
; Print Disk Title
;
PTITL: LXI H,DTITLE ;get title address
MOV A,M ;load it
ORA A ;end of string
JZ CONT ;don't print title
CALL ILPRT ;print heading
DB 'Title: ',0
LXI H,DTITLE ;load it again
;
LOOP1: MOV A,M
ORA A ;zero?
JZ ENDPRT ;all done
CALL TYPE ;type this char
INX H ;next char
JMP LOOP1 ;repeat ...
DTITLE: DB 0 ;storage for
DS 7FH ;title
;
ENDPRT: CALL CRLF
;
;
; Set file control block
;
CONT: LDA DRIVE
ORA A ;non-dedicated?
JZ NOND ;jump if so
STA FCB
;
NOND: LHLD FCB+17 ;get $sys override characters
SHLD SYSTOO ;and save for later
LDA FCB+19
STA SYSTOO+2
;
IF ZCPR
LDA WHEEL ;GET WHEEL BYTE VALUE (RP)
ORA A ;CHECK FOR NON-ZERO
JZ NOSET ;JUMP AROUND DANGEROUS COMMANDS
ENDIF ;ZCPR
;
;
; See if request to add name to list
;
LXI H,FCB+1
CALL ADDCM2
;
ADDCM: DB 'ADD ' ;11 characters (padded with spaces)
;
ADDCM2: POP D ;make de point to add command
LXI B,ADDCM2-ADDCM ;bc gets length of string
CALL COMPR
JNZ NOADD
;
;
; Got request to add name to table
;
CALL DELNAM ;first, delete the name
CALL FINDFF ;find end of table
XCHG ;addr to de
;
;
; Move name to table
;
LXI H,FCB+16 ;BACK UP FCB TO ALLOW USER AREA NUMBER (RP)
LDA OLDUSR ;GET CURRENT USER NUMBER
MOV M,A ;STUFF IT IN FIRST BYTE OF FILE NAME
LXI B,12 ;GET READY TO MOVE USER+FILENAME TO TABLE
CALL MOVER ;GO DO IT
MVI A,0FFH
STAX D ;set new end
JMP WRBACK ;write program back
;
;
; See if request to add title to disk
;
NOADD: LXI H,FCB+1
CALL NOADD1A
NOADD1B:
DB 'TITLE' ;total of this and the next line must..
TITLEN: DB ' ' ;be 11, change for a longer title name
;
NOADD1A:
POP D ;get to
LXI B,NOADD1A-NOADD1B
CALL COMPR
JNZ NOADD2A
;
;
; Process the title or erase it, if none given
;
LXI H,CPMBUFF ;get length
MOV A,M ;move it to a
SUI TITLEN-NOADD1B+1;but don't include the title command
JZ TITNO ;no title?
LXI H,CPMBUFF+TITLEN-NOADD1B+2
LXI B,0000
MOV C,A ;put length in bc
LXI D,DTITLE ;place to store
CALL MOVER ;move title in storage
MVI A,00 ;and mark end
STAX D ;of string
JMP WRBACK ;and write back to disk
;...
;
;
; No title - Clear title
;
TITNO: LXI H,DTITLE ;load in space
MVI M,00 ;store end of string
JMP WRBACK ;and write back to disk
;.....
;
;
; See if request to lock D.COM to a drive
;
NOADD2A:
LXI H,FCB+1
CALL NOADD3
;
NOADD2: DB 'LOK '
;
NOADD3: POP D ;get to
LXI B,NOADD3-NOADD2
CALL COMPR
JNZ NOLOK
;
;
; Got request to lock
;
LDA FCB+16
STA DRIVE
STA FCB
JMP WRBACK
;.....
;
;
; See if request to DEL name from list
;
NOLOK: LXI H,FCB+1
CALL NOLOK3
NOLOK2: DB 'DEL ' ;must be 11 total
;
NOLOK3: POP D ;get to
LXI B,NOLOK3-NOLOK2
CALL COMPR
JNZ NODEL
;
;
; Got request to delete a name from the file
;
CALL DELNAM ;delete the name
JNC WRBACK ;write back if ok
CALL MSGXIT
DB '++ NAME NOT IN TABLE ++$'
;.....
;
;
; See if request is to make SUB file
;
NODEL: LXI H,FCB+1
CALL SUBF3
SUBF2: DB 'SUB ' ;must be 11 total
;
SUBF3: POP D
LXI B,SUBF3-SUBF2
CALL COMPR
JNZ NOSUB
;
;
; Got request to make SUB file, so say so, and set flag to force it
;
CALL SAYSUB ;tell console that sub file will be made
DB 'Writing SUBMIT file...',CR,LF,'$'
;
SAYSUB: POP D
MVI C,9
CALL BDOS
MVI A,0FFH ;tell prgm to make sub file
STA SUBFLG
LXI H,SUBBUF ;write sub file start into file buffer
CALL SUBF5 ;(xsub, pip, etc.)
;
SUBF4: DB 'XSUB',CR,LF,'PIP',CR,LF
;
SUBF5: POP D ;use mover routine to copy to sub buffer
XCHG
LXI B,SUBF5-SUBF4
CALL MOVER
XCHG
SHLD SUBPTR ;save sub file buffer pointer
LXI H,FCB+1 ;then fill tail in with spaces to make
MVI C,11 ; program think that no options chosen
;
NXSPC: MVI M,' '
DCR C
INX H
JNZ NXSPC
MVI C,36H ;initialize local fcb
LXI H,LFCB ;(no default, because commands there)
;
NXFCB: MVI M,0
DCR C
INX H
JNZ NXFCB
LXI D,LFCB+1 ;set up local fcb to write d.sub file
CALL UWR2
;
UWR1: DB 'D SUB',0
;
UWR2: POP H
LXI B,UWR2-UWR1
CALL MOVER
MVI C,ERASE ;erase old file, if it exists
LXI D,LFCB
CALL BDOS
XRA A
STA LFCB ;set up to write to default drive
STA FCBRNO ;initialize record number
MVI C,MAKE ;create the file
LXI D,LFCB
CALL BDOS
JMP NOSET ;then jump off to display names as usual
;.....
;
;
; See if request to set up table from directory
;
NOSUB: LXI H,FCB+1
CALL NODEL3
NODEL2: DB 'SET ' ;must total 11
;
NODEL3: POP D ;get to
LXI B,NODEL3-NODEL2
CALL COMPR
JNZ NOSET
;
;
; Got request to setup table. Move the date (may be blank).
;
LXI H,FCB+17
LXI D,DATE
LXI B,8
CALL MOVER
;
LXI H,FCB+17
LXI D,DATE1
LXI B,8
CALL MOVER
;
MVI A,1 ;turn on..
STA SETFLG ;..set flag
MVI A,0FFH ;clear..
STA NAMES ;..names table
CALL FILLQ ;make fcb '????????.???'
;
NOSET: LDA FCB+1 ;get prtflg
SUI ' '
STA PRTFLG
PUSH PSW
CZ HEAD1
POP PSW
JNZ GOTNAM
CALL FILLQ ;make name ????????.???
;
GOTNAM: LDA FCB
ORA A
JZ NODISK
DCR A
MOV E,A
MVI C,SELDSK
CALL BDOS
;
NODISK: MVI B,NPL ;names per line
CALL LINMRK
MVI C,SRCHF
JMP CALLIT
;
LINE: MVI B,NPL ;names per line
CALL LINMRK
;
NEXT: MVI C,SRCHN
;
CALLIT: PUSH B
LXI D,FCB
CALL BDOS
INR A
JZ CKNONE
DCR A
ANI 3
MOV L,A
MVI H,0
DAD H
DAD H
DAD H
DAD H
DAD H
LXI D,80H+BIAS ;INCLUDE THE USER NUMBER
DAD D
;
;
; Check for $SYS attribute, then clear all attributes
;
PUSH H
LXI D,10 ;sys att offset
DAD D
MOV A,M
ANI 80H
STA SYSFLG
POP H ;retrieve filename ptr
PUSH H
INX H ;SKIP USER NUMBER (RP)
MVI E,11 ;11 chars in filename
;
ATTLP: MOV A,M ;pick up char
ANI 7FH ;kill attribute
MOV M,A ;put back down
INX H
DCR E
JNZ ATTLP
POP H
;
;
; See if name is to be printed
;
XCHG ;name pointer to de
LDA SETFLG ;request to setup table?
ORA A
JNZ SETUP ;go set entry into table
LDA PRTFLG
ORA A
JNZ GOPRNT ;explicit request for all
PUSH D
LXI H,NAMES
;
CKNEXT: POP D ;get name pointer
POP B
PUSH B
MOV A,M ;end of table?
INR A ;was it 0ffh?
JZ GOPRNT
MVI B,0
MVI C,12 ;name length including user area (RP)
PUSH D
;
CKLP: LDAX D
CMP M
JNZ NOMACH
INX D
INX H
DCR C
JNZ CKLP ;loop for 12 chars
;
;
; Got match, mark it found but do not print it
;
LXI D,-12 ;point back to user number
DAD D
MVI M,32 ;mark it found highest ure area is 31 so
;32 can never occur normally (RP)
POP D ;pop pointer
POP B
JMP NEXT ;skip the name
;
;
; Name didn't match, try next
;
NOMACH: DAD B ;point to next name
JMP CKNEXT
;
;
; Print the name
;
GOPRNT:
IF NOSYS
CALL SYSCK
JZ DONAME
LDA SYSFLG
RAL
POP B
JC NEXT
PUSH B
ENDIF ;NOSYS
;
;
DONAME: LDA SUBFLG ;see if sub file is to be made
ORA A
CNZ NAMSUB ;write the name into the sub buffer
MVI A,1 ;say we got one
STA GOTFLG
MVI C,8
XCHG ;name back to hl
INX H
CALL TYPMEM
MVI A,'.'
CALL TYPE
MVI C,3
CALL TYPMEM
POP B
CALL SPACE
MVI A,FENCE
DCR B
PUSH PSW
CNZ TYPE
CALL SPACE
POP PSW
JNZ NEXT
CALL CRLF
JMP LINE
;.....
;
;
; Write the filename pointed to by DE into the SUB file buffer in the
; format: $1<fn.ft>$2<cr><lf>
;
NAMSUB: PUSH H ;save hl (whatever's in it)
PUSH D ;save filename pointer
PUSH B ;save bc (whatever's in it)
LHLD SUBPTR ;hl to sub buffer (de to filename)
MVI C,8 ;8 characters in filename
MVI M,'$' ;first write '$1'
CALL INCPTR ;increment file buffer pointer and..
MVI M,'1' ;..write if full
CALL INCPTR
;
SNAM: LDAX D ;get a character of the name
CPI ' ' ;do not transfer spaces to sub buffer
JZ SNAM2
ANI 7FH ;trim off any nasty attributes
MOV M,A ;put the character into the sub buffer
CALL INCPTR ;point to next sub location
;
SNAM2: INX D ;point to next character of filename
DCR C ;decrement filename counter
JNZ SNAM ;continue until all 8 characters read
MVI M,'.' ;put a '.' separator into the sub buffer
CALL INCPTR ;point to next location in sub buffer
MVI C,3 ;now do the 3 character long filetype
;
SNAM3: LDAX D
CPI ' '
JZ SNAM4
ANI 7FH
MOV M,A
CALL INCPTR
;
SNAM4: INX D
DCR C
JNZ SNAM3
MVI M,'$' ;then write '$2<cr><lf>' on the end..
CALL INCPTR ;.. of the name
MVI M,'2'
CALL INCPTR
MVI M,CR
CALL INCPTR
MVI M,LF
CALL INCPTR
SHLD SUBPTR ;save the new sub buffer pointer
POP B ;restore all the registers
POP D
POP H
RET ;then return back to doname
;.....
;
;
; Increment the HL file buffer pointer, and write the buffer if full
;
INCPTR: INX H ;see if buffer is full
MVI A,(SUBBUF+80H) AND 0FFH
CMP L ;(see if lsh of hl = lsh of subbuf+80h)
RNZ ;return if buffer not full
WRTSBF: LXI H,SUBBUF ;reset pointer to start of buffer
;
WRTSB2: PUSH H
PUSH D
PUSH B
LXI D,SUBBUF ;set dma address to sub buffer
MVI C,SETDMA
CALL BDOS
LXI D,LFCB ;write the buffer to disk
MVI C,WRITE
CALL BDOS
LXI D,CPMBUFF ;now set dma address back to default so
MVI C,SETDMA ;..other routines can read directory
CALL BDOS
POP B
POP D
POP H
ORA A ;notify console and abort if write error
JNZ WRERR
RET
;
CKNONE: LDA GOTFLG ;GOT NEW FILES (not necessary RP)
ORA A
JNZ STEPDU ;Step to next user area (RP)
LDA SETFLG ;ARE WE DOING A SET?
ORA A
JNZ STEPDU ;Then step to next user area
CALL ILPRT
DB '++ NONE ++',0 ;otherwise say none
JMP STEPDU
;
;
; Print the files not found
;
NOTFND: LDA SETFLG ;is this 'D SET'?
ORA A
JNZ FINI ;done if so
LDA PRTFLG ;are we printing?
ORA A
JNZ CKNON2 ;done if not
;
; If this D.COM is dedicated ("DRIVE" is non-zero), then be sure to
; print the "FILES NOT FOUND".
;
; LDA DRIVE
; ORA A
; JNZ NOCHK
; LDA FCB ;drive specified?
; ORA A
; JNZ FINI ;skip not found if so
;
NOCHK: CALL HEAD3 ;print not fnd header
LXI H,NAMES ;start of table
LXI D,12
;
LINE2: MVI B,NPL
; CALL LINMRK ;removed to eliminate drive designator (RP)
;
NEXT2: MOV A,M ;first char of name
cpi 32 ;marked found?
JZ NOPRNT ;jump if so
INR A ;check for table end
JZ CKNON2 ;jump if end
LDA MAXUSR ;LOAD THE MAX USER NUMBER (RP)
CMP M ;HAVE WE GONE TOO FAR?
JC NOPRNT ;IF SO GET OUT
MVI A,1
STA GOTNF
inx H ;step past user area (RP)
MVI C,8
CALL TYPMEM
MVI A,'.'
CALL TYPE
MVI C,3
CALL TYPMEM
CALL SPACE
MVI A,FENCE
DCR B
PUSH PSW
CNZ TYPE
CALL SPACE
POP PSW
JNZ NEXT2
CALL CRLF
JMP LINE2
;
NOPRNT: DAD D
JMP NEXT2
;
STEPDU: PUSH B ;save anything important (RP)
PUSH D ; ditto
MVI A,0
STA GOTFLG
MVI C,32 ;set up for current user area check
MVI E,0FFH ;to get an answer back
CALL BDOS ;do it
LXI H,MAXUSR
inr a ;MAXUSR is excess one
CMP M ;have we gone far enough?
JNC DSKSET ;Yes, go reset disk
;do not INR A again (user number already bumped)
STA CURUSR ;No, save it for printout
MOV E,A ;get ready for user reset
MVI C,32 ;ditto
CALL BDOS ;do it
POP B ;put everything back
POP D ;ditto
CALL CRLF ;start a new line for new user area
JMP LINE ;go scan again
;
DSKSET: MVI C,32 ;get ready to reset didk to user 0
MVI E,0 ;ditto
CALL BDOS ;doit
STA CURUSR ;reset counter
POP B ;put everything back
POP D ;ditto
JMP NOTFND ;go do what ever was requested
;.....
;
;
; Print header
;
HEAD1: CALL ILPRT ;print:
DB CR,LF,'-->New files',0
LDA DATE
CPI ' '
JZ HEAD2
CALL SYSCK
JZ HEAD2
CALL ILPRT ;print:
DB ' since '
;
DATE: DB ' ' ;eight spaces
DB 0 ;string terminator
JMP CRLF
;
HEAD2: MVI A,':'
CALL TYPE
JMP CRLF
;.....
;
;
HEAD3: CALL ILPRT ;print:
DB CR,LF,CR,LF,'-->Files moved elsewhere or deleted',0
LDA DATE
CPI ' '
JZ HEAD5
CALL SYSCK
JZ HEAD5
CALL ILPRT ;print:
DB ' since '
;
DATE1: DB ' ' ;eight spaces
DB 0 ;string terminator
;
HEAD4: CALL ILPRT
DB CR,LF,' (use FILEFIND or SD filename.ext $AD to see if available)'
DB CR,LF,LF,0 ;extra line feed for beauty.(RP)
RET
;
HEAD5: MVI A,':'
CALL TYPE
JMP HEAD4
;.....
;
;
CKNON2: LDA GOTNF
ORA A
JNZ FINI ;jmp if got no 'NOT FOUND's
LDA PRTFLG
ORA A
JNZ FINI
CALL ILPRT ;print: (then fall into 'FINI')
DB '++ NONE ++',CR,LF,0
;
;
; Finished. If building table, write back. If making a SUB file, then
; flush the file buffer and close it.
;
FINI: LDA SUBFLG ;see if sub file is to be written
ORA A
JNZ WRTSUB ;jump if so,
LDA SETFLG ;else see if set was performed
ORA A
JZ EXIT ;jump out if not,
JMP WRBACK ;else write the program back to disk
;
;
; Write the SUB file to the currently logged in disk as 'D.SUB'
;
WRTSUB: LHLD SUBPTR ;fill rest of last sector with eof's
XCHG
LXI H,SUBBUF+7FH
;
WNXTS: MVI M,1AH
MOV A,L
DCX H
CMP E
JNZ WNXTS
CALL WRTSB2 ;write the last sector to disk
MVI C,CLOSE ;close the file
LXI D,LFCB
CALL BDOS
INR A ;if close error, then notify console..
JZ BADWCL ;..and abort
JMP EXIT ;exit back to cp/m
;
BADWCL: CALL MSGXIT
DB 'BAD CLOSE, SUB file incomplete$'
;
;
; Set up the name in the table
;
SETUP:
IF NOSYS
CALL SYSCK
JZ SETU1 ;GO CHECK FOR NAMED DIRECTORY (RP)
LDA SYSFLG
RAL
JC SETSKP
ENDIF ;NOSYS
;
SETU1: INX D ;SKIP THE USER AREA (RP)
LDAX D ;GET FIRSAT CHAR IN TO 'ACCUM'
DCX D ;GET USER AREA BACK
CPI '-' ;IS IT A '-'
JZ SETSKP ;YES; DON'T ADD IT TO TABLE.
;
SETU2: CALL FINDFF ;find end of table
XCHG ;setup for move
;
;
; (HL = name, DE = end of table)
;
LXI B,12 ;include the user area
CALL MOVER
MVI A,0FFH ;get table end flag
STAX D ;store it
;
SETSKP: POP B ;delete stack garbage
JMP NEXT ;get next entry
;
;
; Routine to type 'C' characters from memory (HL)
;
TYPMEM: MOV A,M
CALL TYPE
INX H
DCR C
JNZ TYPMEM
RET
;.....
;
;
; Inline print routine - prints string pointed to by stack until a zero
; is found. Returns to caller at next address after the zero terminator.
;
ILPRT: XTHL ;save hl, get msg adrs
;
ILPLP: MOV A,M ;get char
CALL TYPE ;output it
INX H ;point to next
MOV A,M ;test
ORA A ;..for end
JNZ ILPLP
XTHL ;restore hl, ret addr
RET ;ret past msg
;.....
;
;
CRLF: CALL ILPRT ;print:
DB CR,LF,0
RET
;.....
;
;
SPACE: MVI A,' '
;
;
; Print character in A to console
;
TYPE: PUSH B
PUSH D
PUSH H
MOV C,A ;char to c for cbios
;
TYPEC: CALL $-$ ;supplied at start
;
;
; See if console key pressed
;
TYPES: CALL $-$ ;supplied at start
ORA A ;key pressed?
CNZ CKKB ;yes, see which one
POP H
POP D
POP B
RET
;.....
;
;
CKKB: CALL CI ;get char
CPI 'S'-40H ;pause?
CZ CI ;yes, get next char
CPI 'C'-40H ;abort?
RNZ ;no, return
CALL MSGXIT
DB CR,LF,'++ ABORTED ++$'
;.....
;
;
; Move (BC) bytes from (HL) to (DE)
;
MOVER: MOV A,M
STAX D
INX D
INX H
DCX B
MOV A,B
ORA C
JNZ MOVER
RET
;.....
;
;
; Compare routine
;
COMPR: LDAX D
CMP M
RNZ
INX D
INX H
DCX B
MOV A,B
ORA C
JNZ COMPR
RET ;equal means z=1
;.....
;
;
; Routine to find 0FFH at end of table
;
FINDFF: LXI H,NAMES
;
FINDLP: MOV A,M
INX H
INR A ;0ffh?
JNZ FINDLP
DCX H ;back up to table end
RET
;.....
;
;
; Delete the name from the table
;
DELNAM: LXI H,NAMES
;
DELLP: MOV A,M
CPI YES
STC
RZ ;not found
LXI D,FCB+17
inx h ;step past user number
LXI B,11
CALL COMPR
JZ DELETE
DAD B ;calc next
JMP DELLP
;.....
;
;
; Delete the name
;
DELETE: XCHG ;next name to de
LXI H,-12 ;to back up..
DAD D ;..to name to del
;
DELCH: LDAX D
MOV M,A
INX H
INX D
INR A ;moved the 0ffh?
JNZ DELCH
ORA A ;show found
RET
;.....
;
;
; Fill FCB with all '?'
;
FILLQ: LXI H,FCB+1
MVI B,8+3
MVI A,'?'
;
QMLOOP: MOV M,A
INX H
DCR B
JNZ QMLOOP
RET
;.....
;
;
; Write back the program - note that you may set any of the CP/M 2.x
; attribute bits in the file name (be sure to define all 11 characters
; of the name).
;
WRBACK: LXI D,FCB+1
CALL WRBK2
;
WRBK1: DB 'WHATSNEWC' ;SET THE WRITE BACK TO A $SYS FILE (RP)
DB 'O'+80H ;<--put 'O'+80h here to set tag
DB 'M' ;see comment above
DB 0 ;extent number
;
WRBK2: POP H
LXI B,WRBK2-WRBK1
CALL MOVER
MVI C,ERASE
LXI D,FCB
CALL BDOS
XRA A ;get 0
STA SETFLG ;clear the flags..
STA GOTFLG
STA GOTNF
STA SYSTOO
STA FCBRNO ;zero record number
MVI C,MAKE
LXI D,FCB
CALL BDOS
;
;
; Before writing back, find end of table
;
CALL FINDFF
MOV B,H ;b=end page
INR B ;for compare
LXI D,100H+BIAS ;starting addr
;
WRLP: PUSH B
PUSH D
PUSH H
MVI C,SETDMA
CALL BDOS
MVI C,WRITE
LXI D,FCB
CALL BDOS
POP H
POP D
POP B
ORA A ;successful write?
JNZ WRERR ;..no
LXI H,80H ;point to..
DAD D ;..next block
XCHG ;addr to de
MOV A,D ;get page
CMP B ;past table end?
JC WRLP ;loop until done
MVI C,CLOSE
LXI D,FCB
CALL BDOS
INR A ;successful close?
JZ BADCLS ;..no, print err msg
CALL MSGXIT ;ok, exit w/msg
DB '++ DONE ++$'
;.....
;
;
WRERR: CALL MSGXIT
DB '++ WRITE ERROR ++$'
;.....
;
;
BADCLS: CALL MSGXIT
DB '++ BAD CLOSE, D.COM CLOBBERED ++$'
;.....
;
;
; Get console input via direct CBIOS call
;
CI: PUSH B ;console input
PUSH D
PUSH H
;
CIC: CALL $-$ ;supplied at start
POP H
POP D
POP B
RET
;.....
;
;
; Exit with message (error or informational)
;
MSGXIT: POP D ;get msg
MVI C,PRINT
CALL BDOS
;
;
; Exit, restoring DMA and stack, then return to CCP
;
EXIT: CALL CRLF ;give some room for beauty
LXI D,CPMBUFF ;reset dma adr to normal
MVI C,SETDMA
CALL BDOS
LDA OLDUSR ;set the user # back where it belongs (BH)
MOV E,A
MVI C,32 ;set user
CALL BDOS
LHLD STACK ;get old stack
SPHL ;restore it
RET ;return to ccp
;.....
;
LINMRK: PUSH B
PUSH D
PUSH H
LDA FCB ;get drive name from fcb
ORA A ;any there?
JNZ GOTDRV ;yes, go print it
MVI C,CURDSK ;else get current disk
CALL BDOS
INR A ;make 'A'=1
;
GOTDRV: ADI 40H ;make ascii
CALL TYPE ;print drive name
lda curusr ;user number to A
ani 1fH ;31 is max that USER can be
call decprt ;print user number in decimal
CALL ILPRT ;print separator
DB ': ',0
POP H
POP D
POP B
ret
;
; print user number in decimal (from A) w/leading zero suppressed
decprt:
mov c,a ;save A
sub a
l10: mov b,a ;save tens count
mov a,c ;restore A
sui 10 ;subtract 10
jc a10 ;if carry, end is past
mov c,a ;else save in c
mov a,b ;bump b
adi 1 ; by 1
jmp l10 ;and go again
a10: adi 10 ;make positive again
mov c,a ;save units in binary
mov a,b ;get tens count (in binary)
ori 30h ;convert to ascii digit
cpi 30h ;is it null?
cnz type ;type if not
mov a,c ;get units
adi 30h
call type ;print no matter what
ret
;.....
;
; Test for system file override
;
SYSCK: PUSH H
PUSH D
PUSH B
LXI H,SYSTOO
LXI D,SYSOK
MVI B,3
;
RSYSCK: LDAX D
CMP M
INX H
INX D
JNZ SYSOUT
DCR B
JNZ RSYSCK
;
SYSOUT: POP B
POP D
POP H
RET
;.....
;
;
DS 64 ;room for stack
STACK: DS 2 ;old stack stored here
SUBFLG DB 00H ;flag to order sub file built
SUBPTR DW 0000H ;pointer to end of sub file
GOTFLG: DB 0
OLDUSR: DB 0 ;old user area
CURUSR: DB 0 ;current user area (RP)
GOTNF: DB 0
SYSTOO: DB 0,0,0
SYSOK: DB '! ' ;sys suppression override chars
SETFLG: DB 0 ;1 => setup table
PRTFLG: DB 0 ;print only some
SYSFLG: DB 0 ;$sys attrib indicator
LFCB DS 36H ;local fcb used by sub file
SUBBUF DS 128 ;buffer used by sub file write routines
NAMES EQU $ ;names not to print are stored here..
;..(i.e., the current dir)
;
; Note the names are initially built by the "D SET" command
;
DB 0FFH ;end of table
;
;
; Miscellaneous BDOS equates
;
RDCON EQU 1
DIO EQU 6
PRINT EQU 9
CONST EQU 11
SELDSK EQU 14
CLOSE EQU 16
SRCHF EQU 17
SRCHN EQU 18
ERASE EQU 19
READ EQU 20
WRITE EQU 21
MAKE EQU 22
CURDSK EQU 25
SETDMA EQU 26
;
END
U 16
SRCHF EQU 17
SRCHN EQU 18
ERASE EQU 19
READ EQU 20
WRITE EQU 21
MAKE EQU 22
CURDSK EQU 25
SETDMA EQU 26