; D.ASM v3.1 - 05/05/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. ;----------------------------------------------------------------------- ; ; 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 adds the date for printing whenever is called by ; 'A>D' 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 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. "D.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 ; ; ; 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) ; ;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 ; ; ; Print ID message ; CALL ILPRT ;print: DB 'D v3.1',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 ; ; ; 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+17 LXI B,11 CALL MOVER 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 'TIT' ;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,81H+BIAS DAD D ; ; ; Check for $SYS attribute, then clear all attributes ; PUSH H LXI D,9 ;sys att offset DAD D MOV A,M ANI 80H STA SYSFLG POP H ;retrieve filename ptr PUSH H 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,11 ;name length PUSH D ; CKLP: LDAX D CMP M JNZ NOMACH INX D INX H DCR C JNZ CKLP ;loop for 11 chars ; ; ; Got match, mark it found but do not print it ; LXI D,-11 ;point back to name DAD D MVI M,0 ;mark it found 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 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 ;some new files found? ORA A JNZ NOTFND ;jump if yes LDA PRTFLG ;print names? ORA A JNZ NOTFND ;jump if yes CALL ILPRT DB '++ NONE ++',CR,LF,0 ; ; ; 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,11 ; LINE2: MVI B,NPL CALL LINMRK ; NEXT2: MOV A,M ;first char of name ORA A ;marked found? JZ NOPRNT ;jump if so INR A ;check for table end JZ CKNON2 ;jump if end MVI A,1 STA GOTNF 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 ;..... ; ; ; 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 FILE xxx*.* to see if available)' DB CR,LF,0 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 SETU2 LDA SYSFLG RAL JC SETSKP ENDIF ;NOSYS ; SETU2: CALL FINDFF ;find end of table XCHG ;setup for move ; ; ; (HL = name, DE = end of table) ; LXI B,11 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 LXI B,11 CALL COMPR JZ DELETE DAD B ;calc next JMP DELLP ;..... ; ; ; Delete the name ; DELETE: XCHG ;next name to de LXI H,-11 ;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 'D'+80H ;<--put 'D'+80h here to set tag DB ' COM' ;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: LXI D,CPMBUFF ;reset dma adr to normal MVI C,SETDMA 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 CALL ILPRT ;print DB ': ',0 POP H POP D POP B 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 GOTNF: DB 0 SYSTOO: DB 0,0,0 SYSOK: DB 'S ' ;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