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
Assembly Source File  |  2000-06-30  |  32KB  |  1,442 lines

  1. ; D.ASM v4.2a -  10/27/84
  2. ;
  3. ;        RESTRICTED DIRECTORY LIST PROGRAM
  4. ;
  5. ; D.COM is a directory list program, which writes 4 or 5 entries on a
  6. ; line, separated by colons.
  7. ;
  8. ;   (THIS IS THE 'WHATSNEW' PROGRAM SEEN ON MANY RCPM SYSTEMS)
  9. ;
  10. ; The command contains an internal table of file names, which are not to
  11. ; be shown when just "D" is typed.  (NOTE typing "D *.*" always shows
  12. ; all files)
  13. ;
  14. ; Why is this useful:  A typical CP/M disk contains many utility files,
  15. ; such as ED.COM, ASM,COM, PIP.COM, STAT.COM, etc.  When you do a direc-
  16. ; tory listing, you typically are not interested in seeing all those
  17. ; files, but rather just the "current" or "active" files.  This is what
  18. ; "D.COM" can do.
  19. ;
  20. ; NOTE: Direct CBIOS calls are used for input and output in order to
  21. ;    avoid echoing of inputted characters.  This keeps a noisy phone
  22. ;    line from causing garbage characters in the display.
  23. ;-----------------------------------------------------------------------
  24. ;
  25. ; WARNING:  NZCPR 1.6 has a bug in the "path" logic that causes it not to
  26. ;        search current drive, user 0 (sometimes) when you are not logged
  27. ;        into user zero. The result is that WHATSNEW from drive A0: will
  28. ;        get executed when you were expecting another drive to be displayed.
  29. ;
  30. ; 10/27/84  More gold for sysops. If you have directory names beginning
  31. ;   v4.2a   with a '-' they will no longer be set into the internal table.
  32. ;        If you don't want them displayed use the ADD command. Note:
  33. ;        the DEL command only deletes the first occurrence of a prog.
  34. ;        name. When the program re-writes itself to disk the $SYS
  35. ;        attribute is automatically set.
  36. ;                - Russ Pencin [changes marked (RP)] 
  37. ;
  38. ; 10/24/84  Now stores the user area and name of file in the internal
  39. ;   v 4.2   table and checks the MAXUSR value to determine if the file
  40. ;        name is within bounds before printing. Also checks the wheel
  41. ;        byte before allowing any dangerous command to be used if the
  42. ;        ZCPR equate is true. One caveat: ADD works the same as before;
  43. ;        if you want to ADD a file to the list you must first go to the
  44. ;        user area that you want assigned to the new file, then perform
  45. ;        your ADD command. If you don't, the file will be assigned the
  46. ;        current user area and appear as a +NOT FOUND+ in future searches.
  47. ;        Any bugs or suggestions may be forwarded to The Dallas Connection
  48. ;        RCP/M (214) 783-7684 (Ring back).
  49. ;                 - Russ Pencin [Changes marked (RP)]
  50. ;
  51. ; 10/12/84  Now displays two-digit user areas and has an assembly option
  52. ;   v 4.1   for MAXUSR either hard-coded or ZCPR/NZCPR-controlled.
  53. ;        - DCC, Dallas RCP/M.
  54. ;
  55. ; 10/10/84  A major change to the original 3.1 version of D.COM. This allows
  56. ;   v 4.0   for only one copy of D.COM to reside on the root directory of each
  57. ;        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
  58. ;        specified by MAXUSR on the current disk and catalogs new files by
  59. ;        user area. Deleted files are called out by name (user area not
  60. ;        necessary) and instructions given on how to search the system to
  61. ;        find those that may have been moved. All original commands still
  62. ;        function. I recommend LOKing the program to each disk in USER zero.
  63. ;        The program will also function with the standard CCP but one copy
  64. ;        will be required in each user area (as before).
  65. ;        - Russ Pencin, Dallas Connection RCP/M.
  66. ;
  67. ;
  68. ; 05/05/84  Line with the "use FILE xxx*.*" now only appears on the line
  69. ;   v3.1    with the message about moved or deleted files.
  70. ;                    - Irv Hoff
  71. ;    
  72. ; 05/01/84  Changed the "Deleted files since --- " to "Files moved else-
  73. ;   v3.0    where or deleted", then added a line "use FILE xxx*.* to see
  74. ;        if available."  With 20-40 megabyte disk systems now common,
  75. ;        this is a convenient way to locate files which are no longer
  76. ;        in the "Whatsnew" user area.  It was misleading when reading
  77. ;        the files had been deleted when most have merely been moved.
  78. ;        (Every SYSOP needs FILE.COM on his system.)  SD xxx*.* $U0AD
  79. ;        may also be used, but gives information that is superfluous.
  80. ;        Standardized the format.    - Irv Hoff
  81. ;
  82. ; 08/12/82  Added SUB file option to allow writing each new filename
  83. ;   v2.9    that appears in the "New Files" display to a .SUB file of
  84. ;        the form:
  85. ;            XSUB
  86. ;            PIP
  87. ;            $1=$2 Fn.Ft$3
  88. ;            $1=$2 Fn.Ft$3
  89. ;
  90. ;        etc., to allow a simple archive of new files to be performed
  91. ;        by: SUBMIT D A:=B: [G1].  Also repaired bug in EXIT routine
  92. ;        and removed character 'gobbler' routine so that the program
  93. ;        will work better with 'type-ahead' BIOSes.
  94. ;                    - Dave Hardy
  95. ;
  96. ; 11/23/78  Originally written by Ward Christensen.
  97. ;
  98. ;=======================================================================
  99. ;
  100. ; Use:    D *.*    prints all names, 5 across.
  101. ;
  102. ;    D *.ASM prints selected files just like DIR.
  103. ;
  104. ;    D SET builds a table (in D.COM) of all names currently on the
  105. ;        disk. (see *NOTE).
  106. ;
  107. ;    D SET <DATE>  adds the date for printing whenever is called by
  108. ;        'A>D<CR>' with no options.  If the date field is left
  109. ;        blank, it will be ignored.  Note that the date must be
  110. ;        8 characters or less (see *NOTE).
  111. ;
  112. ;    D TIT <TITLE FOR DISK> sets an internal disk title which prints
  113. ;        out each time the program is run (if a title has been
  114. ;        set).  (maximum of about 70 characters, please, although
  115. ;        it will handle a full CP/M input line.
  116. ;
  117. ;        NOTE: To get rid of title (and accompanying
  118. ;        print put type 'D TIT' and the title is
  119. ;        set to null.
  120. ;
  121. ;    D ADD FN.FT adds a name to the table in D.COM, so FN.FT will not
  122. ;        be listed by the 'D' command (see *NOTE).
  123. ;
  124. ;    D DEL FN.FT deletes a name from the table in D.COM, so if FN.FT
  125. ;        is in the directory, it will be listed by 'D' (see NOTE)
  126. ;
  127. ;    D SUB causes a file named 'D.SUB' to be generated on the current-
  128. ;        ly logged-in drive.  The file contains all of the 'New
  129. ;        Files' names, and is of the form:
  130. ;
  131. ;            XSUB
  132. ;            PIP
  133. ;            $1<fn1.ft>$2
  134. ;            $1<fn2.ft>$2
  135. ;            $1<fn3.ft>$2
  136. ;
  137. ;        etc.  D.SUB can be used to archive 'New Files' with a
  138. ;        simple command line like:  SUBMIT D B:=A: [G5] which
  139. ;        would PIP all of the new files from B5: to A:
  140. ;
  141. ;    D     lists the directory, showing only those files NOT in D.COM
  142. ;        as put there by 'D SET' or 'D ADD FN.FT'
  143. ;
  144. ;            *NOTE:    the program must write itself
  145. ;                back to disk, modified, so your
  146. ;                disk must not be write protected.
  147. ;
  148. ;-----------------------------------------------------------------------
  149. ;
  150. ;        Examples:  Suppose your disk has:
  151. ;
  152. ;    D.COM      \
  153. ;    ASM.COM    \
  154. ;    ED.COM        on it initially.
  155. ;    LOAD.COM   /
  156. ;    DDT.COM   /
  157. ;
  158. ;        You would type:  D SET to set these names into the
  159. ;        D.COM program.
  160. ;
  161. ;        Typing "D" would then list:
  162. ;
  163. ;    -->New files
  164. ;    A: ++ NONE ++
  165. ;
  166. ;    -->Deleted files
  167. ;    A: ++ NONE ++
  168. ;
  169. ;        Suppose you:  A>ED TEST.ASM, A>ASM TEST and LOAD TEST.
  170. ;        Typing D would then list:
  171. ;
  172. ;    -->New files
  173. ;    A: TEST    ASM : TEST     BAK : TEST    HEX : TEST    COM
  174. ;
  175. ;    -->Deleted files
  176. ;    A: ++ NONE ++
  177. ;
  178. ;        i.e., it tells you of the "current" files on the disk.
  179. ;        Now, supposing you wanted to add TEST.COM as a "regular"
  180. ;        file on your disk.  Type:
  181. ;
  182. ;    D ADD TEST.COM
  183. ;
  184. ;        Now, typing D will show:
  185. ;
  186. ;    -->New files
  187. ;    A: TEST    ASM : TEST     BAK : TEST    HEX
  188. ;
  189. ;    -->Deleted files
  190. ;    A: ++NONE++
  191. ;
  192. ;        i.e., TEST.COM is now considered a "permanent" file.
  193. ;
  194. ;        Now, suppose you accidentally erased ASM.COM from your
  195. ;        disk.  Typing D gives:
  196. ;
  197. ;    -->New files
  198. ;    A: TEST    ASM : TEST     BAK : TEST    HEX
  199. ;
  200. ;    -->Deleted files
  201. ;    A: ASM       COM
  202. ;
  203. ;        showing you are missing one of the "regular" files.  If,
  204. ;        in fact, you didn't want ASM.COM to be on the disk, type:
  205. ;
  206. ;    D DEL ASM.COM
  207. ;
  208. ;        which will delete the name from the D.COM table, so
  209. ;        ASM.COM will not up as "deleted".
  210. ;
  211. ;=======================================================================
  212. ;
  213. ;           SPECIAL NOTES FOR REMOTE SYSTEM USE:
  214. ;
  215. ; If you keep a dedicated copy of this program on each drive of your re-
  216. ; mote system, you can 'dedicate' each copy of this program to a drive
  217. ; by filling in the byte at 103H with the drive number.  This prevents
  218. ; such things as:
  219. ;
  220. ;    A>D B:
  221. ;        or
  222. ;    B>A:D
  223. ;
  224. ; Do this by using the command:
  225. ;
  226. ;    A>D LOK A:    to lock to a drive
  227. ;        or
  228. ;    A>D LOK     to unlock
  229. ;
  230. ; If the conditional 'NOSYS' is set YES, $SYS files in CP/M 2.x will be
  231. ; ignored in both directory listings and when the "ADD" option is in-
  232. ; voked, unless the override char is specified.  This allows D.COM to be
  233. ; used as a "WHAT'S NEW" program for remote CP/M systems, where the $SYS
  234. ; files must not be listed.
  235. ;
  236. ; Examples:
  237. ;
  238. ;    A>D *.* S     displays everything
  239. ;    A>D SET S     puts ALL files in table
  240. ;    A>D SET 12/23/80 sets date for reference
  241. ;
  242. ;        (if you use 'D SET S', you lose the date option..
  243. ;
  244. ; If you use this program on a remote system, you will likely want to
  245. ; change the commands (ADD, DEL, and SET) for security.  You will also
  246. ; want to change the $SYS suppress override character.    You may also
  247. ; want to change the name of the program to make the name itself more
  248. ; informative, e.g. "WHATSNEW.COM".
  249. ;
  250. ;
  251. ; -->IMPORTANT: If you want the program to be 'TAG'ed after every D SET
  252. ;        (so it cannot be taken by XMODEM), see the note at label
  253. ;        "WRBACK" for setting the F1 bit in the filename itself.
  254. ;
  255. ;
  256. ; Note that this program defines its own name for write-back purposes
  257. ; under the label "WRBACK".
  258. ;
  259. ;=======================================================================
  260. ;
  261. ; Define some stuff
  262. ;
  263. YES:    EQU    0FFH
  264. NO:    EQU    0
  265. ;
  266. ;
  267. BIAS:    EQU    0        ;for std cp/m or 4200h for altcpm
  268. BDOS:    EQU    5+BIAS        ;cp/m's BDOS access jump
  269. CPMBUFF:EQU    80H+BIAS    ;cp/m command line buffer
  270. CR:    EQU    0DH        ;carriage return
  271. FCB:    EQU    5CH+BIAS    ;cp/m's file control block
  272. FCBRNO: EQU    FCB+32        ;rec # in fcb
  273. LF:    EQU    0AH        ;line feed
  274. ;
  275. ;
  276. ; Set the following for your system:
  277. ;
  278. NOSYS    EQU    YES        ;yes=ignore $sys files
  279. FENCE    EQU    ' '        ;file name separator
  280. NPL    EQU    4        ;file names per line
  281. zcpr    equ    YES        ; if ZCPR or NZCPR handle MAXUSR
  282. ;
  283. ; The leader string for the SUB file (XSUB, PIP) is located at label
  284. ; SUBF4.
  285. ;
  286.     ORG    100H+BIAS
  287. ;
  288. DENTRY: JMP    AROUND
  289. ;
  290. DRIVE:    DB    0        ;<---drv # is put here if dedicated
  291.                 ;(this can be done with the lok command)
  292.     if    zcpr
  293. MAXUSR: equ    3Fh        ;location of # of user areas to search
  294. WHEEL:    EQU    3EH        ;LOCATION OF ZCPR WHEEL BYTE    (RP)
  295.     endif
  296.     if    not zcpr
  297. MAXUSR: db    15+1        ;maximum user area (+1) to be searched
  298.     endif
  299. ;
  300. ;Initialize the local stack
  301. ;
  302. AROUND: LXI    H,0        ;hl=0
  303.     DAD    SP        ;hl=stack
  304.     SHLD    STACK        ;save stack pointer
  305.     LXI    SP,STACK    ;init local stack
  306. ;
  307. ;
  308. ;Initialize direct CBIOS calls
  309. ;
  310.     LHLD    1+BIAS
  311.     LXI    D,3
  312.     DAD    D        ;hl=constat
  313.     SHLD    TYPES+1
  314.     DAD    D        ;hl=conin
  315.     SHLD    CIC+1
  316.     DAD    D        ;hl=conout
  317.     SHLD    TYPEC+1
  318. ;
  319. ;
  320. ;Save the old user number and set user 0  (BH)
  321. ;
  322.     MVI    C,32        ;get/set user
  323.     MVI    E,0FFH        ;to get
  324.     CALL    BDOS
  325.     STA    OLDUSR        ;save it
  326.     MVI    C,32
  327.     MVI    E,0        ;to set
  328.     CALL    BDOS
  329. ;
  330. ;
  331. ; Print ID message
  332. ;
  333.     CALL    ILPRT        ;print:
  334.     DB    'WhatsNew v4.2a',CR,LF
  335.     DB    'CTL-S pauses, CTL-C aborts',CR,LF,0
  336. ;
  337. ;
  338. ; Print Disk Title
  339. ;
  340. PTITL:    LXI    H,DTITLE    ;get title address
  341.     MOV    A,M        ;load it
  342.     ORA    A        ;end of string
  343.     JZ    CONT        ;don't print title
  344.     CALL    ILPRT        ;print heading
  345.     DB    'Title: ',0
  346.     LXI    H,DTITLE    ;load it again
  347. ;
  348. LOOP1:    MOV    A,M
  349.     ORA    A        ;zero?
  350.     JZ    ENDPRT        ;all done
  351.     CALL    TYPE        ;type this char
  352.     INX    H        ;next char
  353.     JMP    LOOP1        ;repeat ...
  354.  
  355. DTITLE: DB    0        ;storage for
  356.     DS    7FH        ;title
  357. ;
  358. ENDPRT: CALL    CRLF
  359. ;
  360. ;
  361. ; Set file control block
  362. ;
  363. CONT:    LDA    DRIVE
  364.     ORA    A        ;non-dedicated?
  365.     JZ    NOND        ;jump if so
  366.     STA    FCB
  367. ;
  368. NOND:    LHLD    FCB+17        ;get $sys override characters
  369.     SHLD    SYSTOO        ;and save for later
  370.     LDA    FCB+19
  371.     STA    SYSTOO+2
  372. ;
  373.      IF    ZCPR
  374.     LDA    WHEEL        ;GET WHEEL BYTE VALUE        (RP)
  375.     ORA    A        ;CHECK FOR NON-ZERO
  376.     JZ    NOSET        ;JUMP AROUND DANGEROUS COMMANDS
  377.      ENDIF            ;ZCPR
  378. ;
  379. ;
  380. ; See if request to add name to list
  381. ;
  382.     LXI    H,FCB+1
  383.     CALL    ADDCM2
  384. ;
  385. ADDCM:    DB    'ADD        '    ;11 characters (padded with spaces)
  386. ;
  387. ADDCM2: POP    D        ;make de point to add command
  388.     LXI    B,ADDCM2-ADDCM    ;bc gets length of string
  389.     CALL    COMPR
  390.     JNZ    NOADD
  391. ;
  392. ;
  393. ; Got request to add name to table
  394. ;
  395.     CALL    DELNAM        ;first, delete the name
  396.     CALL    FINDFF        ;find end of table
  397.     XCHG            ;addr to de
  398. ;
  399. ;
  400. ; Move name to table
  401. ;
  402.     LXI    H,FCB+16    ;BACK UP FCB TO ALLOW USER AREA NUMBER (RP)
  403.     LDA    OLDUSR        ;GET CURRENT USER NUMBER
  404.     MOV    M,A        ;STUFF IT IN FIRST BYTE OF FILE NAME
  405.     LXI    B,12        ;GET READY TO MOVE USER+FILENAME TO TABLE
  406.     CALL    MOVER        ;GO DO IT
  407.     MVI    A,0FFH
  408.     STAX    D        ;set new end
  409.     JMP    WRBACK        ;write program back
  410. ;
  411. ;
  412. ; See if request to add title to disk
  413. ;
  414. NOADD:    LXI    H,FCB+1
  415.     CALL    NOADD1A
  416. NOADD1B:
  417.     DB    'TITLE'     ;total of this and the next line must..
  418. TITLEN: DB    '      '    ;be 11, change for a longer title name
  419. ;
  420. NOADD1A:
  421.     POP    D        ;get to
  422.     LXI    B,NOADD1A-NOADD1B
  423.     CALL    COMPR
  424.     JNZ    NOADD2A
  425. ;
  426. ;
  427. ; Process the title or erase it, if none given
  428. ;
  429.     LXI    H,CPMBUFF    ;get length
  430.     MOV    A,M        ;move it to a
  431.     SUI    TITLEN-NOADD1B+1;but don't include the title command
  432.     JZ    TITNO        ;no title?
  433.     LXI    H,CPMBUFF+TITLEN-NOADD1B+2
  434.     LXI    B,0000
  435.     MOV    C,A        ;put length in bc
  436.     LXI    D,DTITLE    ;place to store
  437.     CALL    MOVER        ;move title in storage
  438.     MVI    A,00        ;and mark end
  439.     STAX    D        ;of string
  440.     JMP    WRBACK        ;and write back to disk
  441. ;...
  442. ;
  443. ;    
  444. ; No title - Clear title
  445. ;
  446. TITNO:    LXI    H,DTITLE    ;load in space
  447.     MVI    M,00        ;store end of string
  448.     JMP    WRBACK        ;and write back to disk
  449. ;.....
  450. ;
  451. ;
  452. ; See if request to lock D.COM to a drive
  453. ;
  454. NOADD2A:
  455.     LXI    H,FCB+1
  456.     CALL    NOADD3
  457. ;
  458. NOADD2: DB    'LOK        '
  459. ;
  460. NOADD3: POP    D        ;get to
  461.     LXI    B,NOADD3-NOADD2
  462.     CALL    COMPR
  463.     JNZ    NOLOK
  464. ;
  465. ;
  466. ; Got request to lock
  467. ;
  468.     LDA    FCB+16
  469.     STA    DRIVE
  470.     STA    FCB
  471.     JMP    WRBACK
  472. ;.....
  473. ;
  474. ;
  475. ; See if request to DEL name from list
  476. ;
  477. NOLOK:    LXI    H,FCB+1
  478.     CALL    NOLOK3
  479. NOLOK2: DB    'DEL        '    ;must be 11 total
  480. ;
  481. NOLOK3: POP    D        ;get to
  482.     LXI    B,NOLOK3-NOLOK2
  483.     CALL    COMPR
  484.     JNZ    NODEL
  485. ;
  486. ;
  487. ; Got request to delete a name from the file
  488. ;
  489.     CALL    DELNAM        ;delete the name
  490.     JNC    WRBACK        ;write back if ok
  491.     CALL    MSGXIT
  492.     DB    '++ NAME NOT IN TABLE ++$'
  493. ;.....
  494. ;
  495. ;
  496. ; See if request is to make SUB file
  497. ;
  498. NODEL:    LXI    H,FCB+1
  499.     CALL    SUBF3
  500. SUBF2:    DB    'SUB        '    ;must be 11 total
  501. ;
  502. SUBF3:    POP    D
  503.     LXI    B,SUBF3-SUBF2
  504.     CALL    COMPR
  505.     JNZ    NOSUB
  506. ;
  507. ;
  508. ; Got request to make SUB file, so say so, and set flag to force it
  509. ;
  510.     CALL    SAYSUB        ;tell console that sub file will be made
  511.     DB    'Writing SUBMIT file...',CR,LF,'$'
  512. ;
  513. SAYSUB: POP    D
  514.     MVI    C,9
  515.     CALL    BDOS
  516.     MVI    A,0FFH        ;tell prgm to make sub file
  517.     STA    SUBFLG
  518.     LXI    H,SUBBUF    ;write sub file start into file buffer
  519.     CALL    SUBF5        ;(xsub, pip, etc.)
  520. ;
  521. SUBF4:    DB    'XSUB',CR,LF,'PIP',CR,LF
  522. ;
  523. SUBF5:    POP    D        ;use mover routine to copy to sub buffer
  524.     XCHG
  525.     LXI    B,SUBF5-SUBF4
  526.     CALL    MOVER
  527.     XCHG
  528.     SHLD    SUBPTR        ;save sub file buffer pointer
  529.     LXI    H,FCB+1     ;then fill tail in with spaces to make
  530.     MVI    C,11        ;  program think that no options chosen
  531. ;
  532. NXSPC:    MVI    M,' '
  533.     DCR    C
  534.     INX    H
  535.     JNZ    NXSPC
  536.     MVI    C,36H        ;initialize local fcb
  537.     LXI    H,LFCB        ;(no default, because commands there)
  538. ;
  539. NXFCB:    MVI    M,0
  540.     DCR    C
  541.     INX    H
  542.     JNZ    NXFCB
  543.     LXI    D,LFCB+1    ;set up local fcb to write d.sub file
  544.     CALL    UWR2
  545. ;
  546. UWR1:    DB    'D       SUB',0
  547. ;
  548. UWR2:    POP    H
  549.     LXI    B,UWR2-UWR1
  550.     CALL    MOVER
  551.     MVI    C,ERASE     ;erase old file, if it exists
  552.     LXI    D,LFCB
  553.     CALL    BDOS
  554.     XRA    A
  555.     STA    LFCB        ;set up to write to default drive
  556.     STA    FCBRNO        ;initialize record number
  557.     MVI    C,MAKE        ;create the file
  558.     LXI    D,LFCB
  559.     CALL    BDOS
  560.     JMP    NOSET        ;then jump off to display names as usual
  561. ;.....
  562. ;
  563. ;
  564. ; See if request to set up table from directory
  565. ;
  566. NOSUB:    LXI    H,FCB+1
  567.     CALL    NODEL3
  568. NODEL2: DB    'SET        '    ;must total 11
  569. ;
  570. NODEL3: POP    D        ;get to
  571.     LXI    B,NODEL3-NODEL2
  572.     CALL    COMPR
  573.     JNZ    NOSET
  574. ;
  575. ;
  576. ; Got request to setup table.  Move the date (may be blank).
  577. ;
  578.     LXI    H,FCB+17
  579.     LXI    D,DATE
  580.     LXI    B,8
  581.     CALL    MOVER
  582. ;
  583.     LXI    H,FCB+17
  584.     LXI    D,DATE1
  585.     LXI    B,8
  586.     CALL    MOVER
  587. ;
  588.     MVI    A,1        ;turn on..
  589.     STA    SETFLG        ;..set flag
  590.     MVI    A,0FFH        ;clear..
  591.     STA    NAMES        ;..names table
  592.     CALL    FILLQ        ;make fcb '????????.???'
  593. ;
  594. NOSET:    LDA    FCB+1        ;get prtflg
  595.     SUI    ' '
  596.     STA    PRTFLG
  597.     PUSH    PSW
  598.     CZ    HEAD1
  599.     POP    PSW
  600.     JNZ    GOTNAM
  601.     CALL    FILLQ        ;make name ????????.???
  602. ;
  603. GOTNAM: LDA    FCB
  604.     ORA    A
  605.     JZ    NODISK
  606.     DCR    A
  607.     MOV    E,A
  608.     MVI    C,SELDSK
  609.     CALL    BDOS
  610. ;
  611. NODISK: MVI    B,NPL        ;names per line
  612.     CALL    LINMRK
  613.     MVI    C,SRCHF
  614.     JMP    CALLIT
  615. ;
  616. LINE:    MVI    B,NPL        ;names per line
  617.     CALL    LINMRK
  618. ;
  619. NEXT:    MVI    C,SRCHN
  620. ;
  621. CALLIT: PUSH    B
  622.     LXI    D,FCB
  623.     CALL    BDOS
  624.     INR    A
  625.     JZ    CKNONE
  626.     DCR    A
  627.     ANI    3
  628.     MOV    L,A
  629.     MVI    H,0
  630.     DAD    H
  631.     DAD    H
  632.     DAD    H
  633.     DAD    H
  634.     DAD    H
  635.     LXI    D,80H+BIAS    ;INCLUDE THE USER NUMBER
  636.     DAD    D
  637. ;
  638. ;
  639. ; Check for $SYS attribute, then clear all attributes
  640. ;
  641.     PUSH    H
  642.     LXI    D,10        ;sys att offset
  643.     DAD    D
  644.     MOV    A,M
  645.     ANI    80H
  646.     STA    SYSFLG
  647.     POP    H        ;retrieve filename ptr
  648.     PUSH    H
  649.     INX    H        ;SKIP USER NUMBER    (RP)
  650.     MVI    E,11        ;11 chars in filename
  651. ;
  652. ATTLP:    MOV    A,M        ;pick up char
  653.     ANI    7FH        ;kill attribute
  654.     MOV    M,A        ;put back down
  655.     INX    H
  656.     DCR    E
  657.     JNZ    ATTLP
  658.     POP    H
  659. ;
  660. ;
  661. ; See if name is to be printed
  662. ;
  663.     XCHG            ;name pointer to de
  664.     LDA    SETFLG        ;request to setup table?
  665.     ORA    A
  666.     JNZ    SETUP        ;go set entry into table
  667.     LDA    PRTFLG
  668.     ORA    A
  669.     JNZ    GOPRNT        ;explicit request for all
  670.     PUSH    D
  671.     LXI    H,NAMES
  672. ;
  673. CKNEXT: POP    D        ;get name pointer
  674.     POP    B
  675.     PUSH    B
  676.     MOV    A,M        ;end of table?
  677.     INR    A        ;was it 0ffh?
  678.     JZ    GOPRNT
  679.     MVI    B,0
  680.     MVI    C,12        ;name length including user area (RP)
  681.     PUSH    D
  682. ;
  683. CKLP:    LDAX    D
  684.     CMP    M
  685.     JNZ    NOMACH
  686.     INX    D
  687.     INX    H
  688.     DCR    C
  689.     JNZ    CKLP        ;loop for 12 chars
  690. ;
  691. ;
  692. ; Got match, mark it found but do not print it
  693. ;
  694.     LXI    D,-12        ;point back to user number
  695.     DAD    D
  696.     MVI    M,32        ;mark it found highest ure area is 31 so
  697.                 ;32 can never occur normally    (RP)
  698.     POP    D        ;pop pointer
  699.     POP    B
  700.     JMP    NEXT        ;skip the name
  701. ;
  702. ;
  703. ; Name didn't match, try next
  704. ;
  705. NOMACH: DAD    B        ;point to next name
  706.     JMP    CKNEXT
  707. ;
  708. ;
  709. ; Print the name
  710. ;
  711. GOPRNT:
  712.      IF    NOSYS
  713.     CALL    SYSCK
  714.     JZ    DONAME
  715.     LDA    SYSFLG
  716.     RAL
  717.     POP    B
  718.     JC    NEXT
  719.     PUSH    B
  720.      ENDIF            ;NOSYS
  721. ;
  722. ;
  723. DONAME: LDA    SUBFLG        ;see if sub file is to be made
  724.     ORA    A
  725.     CNZ    NAMSUB        ;write the name into the sub buffer
  726.     MVI    A,1        ;say we got one
  727.     STA    GOTFLG
  728.     MVI    C,8
  729.     XCHG            ;name back to hl
  730.     INX    H
  731.     CALL    TYPMEM
  732.     MVI    A,'.'
  733.     CALL    TYPE
  734.     MVI    C,3
  735.     CALL    TYPMEM
  736.     POP    B
  737.     CALL    SPACE
  738.     MVI    A,FENCE
  739.     DCR    B
  740.     PUSH    PSW
  741.     CNZ    TYPE
  742.     CALL    SPACE
  743.     POP    PSW
  744.     JNZ    NEXT
  745.     CALL    CRLF
  746.     JMP    LINE
  747. ;.....
  748. ;
  749. ;
  750. ; Write the filename pointed to by DE into the SUB file buffer in the
  751. ; format: $1<fn.ft>$2<cr><lf>
  752. ;
  753. NAMSUB: PUSH    H        ;save hl (whatever's in it)
  754.     PUSH    D        ;save filename pointer
  755.     PUSH    B        ;save bc (whatever's in it)
  756.     LHLD    SUBPTR        ;hl to sub buffer (de to filename)
  757.     MVI    C,8        ;8 characters in filename
  758.     MVI    M,'$'        ;first write '$1'
  759.     CALL    INCPTR        ;increment file buffer pointer and..
  760.     MVI    M,'1'        ;..write if full
  761.     CALL    INCPTR
  762. ;
  763. SNAM:    LDAX    D        ;get a character of the name
  764.     CPI    ' '           ;do not transfer spaces to sub buffer
  765.     JZ    SNAM2
  766.     ANI    7FH        ;trim off any nasty attributes
  767.     MOV    M,A        ;put the character into the sub buffer
  768.     CALL    INCPTR        ;point to next sub location
  769. ;
  770. SNAM2:    INX    D        ;point to next character of filename
  771.     DCR    C        ;decrement filename counter
  772.     JNZ    SNAM        ;continue until all 8 characters read
  773.     MVI    M,'.'        ;put a '.' separator into the sub buffer
  774.     CALL    INCPTR        ;point to next location in sub buffer
  775.     MVI    C,3    ;now do the 3 character long filetype
  776. ;
  777. SNAM3:    LDAX    D
  778.     CPI    ' '
  779.     JZ    SNAM4
  780.     ANI    7FH
  781.     MOV    M,A
  782.     CALL    INCPTR
  783. ;
  784. SNAM4:    INX    D
  785.     DCR    C
  786.     JNZ    SNAM3
  787.     MVI    M,'$'        ;then write '$2<cr><lf>' on the end..
  788.     CALL    INCPTR        ;.. of the name
  789.     MVI    M,'2'
  790.     CALL    INCPTR
  791.     MVI    M,CR
  792.     CALL    INCPTR
  793.     MVI    M,LF
  794.     CALL    INCPTR
  795.     SHLD    SUBPTR        ;save the new sub buffer pointer
  796.     POP    B        ;restore all the registers
  797.     POP    D
  798.     POP    H
  799.     RET            ;then return back to doname
  800. ;.....
  801. ;
  802. ;
  803. ; Increment the HL file buffer pointer, and write the buffer if full
  804. ;
  805. INCPTR: INX    H        ;see if buffer is full
  806.     MVI    A,(SUBBUF+80H) AND 0FFH
  807.     CMP    L        ;(see if lsh of hl = lsh of subbuf+80h)
  808.     RNZ            ;return if buffer not full
  809. WRTSBF: LXI    H,SUBBUF    ;reset pointer to start of buffer
  810. ;
  811. WRTSB2: PUSH    H
  812.     PUSH    D
  813.     PUSH    B
  814.     LXI    D,SUBBUF    ;set dma address to sub buffer
  815.     MVI    C,SETDMA
  816.     CALL    BDOS
  817.     LXI    D,LFCB        ;write the buffer to disk
  818.     MVI    C,WRITE
  819.     CALL    BDOS
  820.     LXI    D,CPMBUFF    ;now set dma address back to default so
  821.     MVI    C,SETDMA    ;..other routines can read directory
  822.     CALL    BDOS
  823.     POP    B
  824.     POP    D
  825.     POP    H
  826.     ORA    A        ;notify console and abort if write error
  827.     JNZ    WRERR
  828.     RET
  829. ;
  830. CKNONE: LDA    GOTFLG        ;GOT NEW FILES (not necessary RP)
  831.     ORA    A
  832.     JNZ    STEPDU        ;Step to next user area (RP)
  833.     LDA    SETFLG        ;ARE WE DOING A SET?
  834.     ORA    A
  835.     JNZ    STEPDU        ;Then step to next user area
  836.     CALL    ILPRT
  837.     DB    '++ NONE ++',0    ;otherwise say none
  838.     JMP    STEPDU
  839. ;
  840. ;
  841. ; Print the files not found
  842. ;
  843. NOTFND: LDA    SETFLG        ;is this 'D SET'?
  844.     ORA    A
  845.     JNZ    FINI        ;done if so
  846.     LDA    PRTFLG        ;are we printing?
  847.     ORA    A
  848.     JNZ    CKNON2        ;done if not
  849. ;
  850. ; If this D.COM is dedicated ("DRIVE" is non-zero), then be sure to
  851. ; print the "FILES NOT FOUND".
  852. ;
  853. ;    LDA    DRIVE
  854. ;    ORA    A
  855. ;    JNZ    NOCHK
  856. ;    LDA    FCB        ;drive specified?
  857. ;    ORA    A
  858. ;    JNZ    FINI        ;skip not found if so
  859. ;
  860. NOCHK:    CALL    HEAD3        ;print not fnd header
  861.     LXI    H,NAMES     ;start of table
  862.     LXI    D,12
  863. ;
  864. LINE2:    MVI    B,NPL
  865. ;    CALL    LINMRK        ;removed to eliminate drive designator (RP)
  866. ;
  867. NEXT2:    MOV    A,M        ;first char of name
  868.     cpi    32        ;marked found?
  869.     JZ    NOPRNT        ;jump if so
  870.     INR    A        ;check for table end
  871.     JZ    CKNON2        ;jump if end
  872.     LDA    MAXUSR        ;LOAD THE MAX USER NUMBER    (RP)
  873.     CMP    M        ;HAVE WE GONE TOO FAR?
  874.     JC    NOPRNT        ;IF SO GET OUT
  875.     MVI    A,1
  876.     STA    GOTNF
  877.     inx    H        ;step past user area    (RP)
  878.     MVI    C,8
  879.     CALL    TYPMEM
  880.     MVI    A,'.'
  881.     CALL    TYPE
  882.     MVI    C,3
  883.     CALL    TYPMEM
  884.     CALL    SPACE
  885.     MVI    A,FENCE
  886.     DCR    B
  887.     PUSH    PSW
  888.     CNZ    TYPE
  889.     CALL    SPACE
  890.     POP    PSW
  891.     JNZ    NEXT2
  892.     CALL    CRLF
  893.     JMP    LINE2
  894. ;
  895. NOPRNT: DAD    D
  896.     JMP    NEXT2
  897. ;
  898. STEPDU: PUSH    B        ;save anything important (RP)
  899.     PUSH    D        ; ditto
  900.     MVI    A,0
  901.     STA    GOTFLG
  902.     MVI    C,32        ;set up for current user area check
  903.     MVI    E,0FFH        ;to get an answer back
  904.     CALL    BDOS        ;do it
  905.     LXI    H,MAXUSR
  906.     inr    a        ;MAXUSR is excess one
  907.     CMP    M        ;have we gone far enough?
  908.     JNC    DSKSET        ;Yes, go reset disk
  909. ;do not INR    A again      (user number already bumped)
  910.     STA    CURUSR        ;No, save it for printout
  911.     MOV    E,A        ;get ready for user reset
  912.     MVI    C,32        ;ditto
  913.     CALL    BDOS        ;do it
  914.     POP    B        ;put everything back
  915.     POP    D        ;ditto
  916.     CALL    CRLF        ;start a new line for new user area
  917.     JMP    LINE        ;go scan again
  918. ;
  919. DSKSET: MVI    C,32        ;get ready to reset didk to user 0
  920.     MVI    E,0        ;ditto
  921.     CALL    BDOS        ;doit
  922.     STA    CURUSR        ;reset counter
  923.     POP    B        ;put everything back
  924.     POP    D        ;ditto
  925.     JMP    NOTFND        ;go do what ever was requested
  926. ;.....
  927. ;
  928. ;
  929. ; Print header
  930. ;
  931. HEAD1:    CALL    ILPRT        ;print:
  932.     DB    CR,LF,'-->New files',0
  933.     LDA    DATE
  934.     CPI    ' '
  935.     JZ    HEAD2
  936.     CALL    SYSCK
  937.     JZ    HEAD2
  938.     CALL    ILPRT        ;print:
  939.     DB    ' since '
  940. ;
  941. DATE:    DB    '        '    ;eight spaces
  942.     DB    0        ;string terminator
  943.     JMP    CRLF
  944. ;
  945. HEAD2:    MVI    A,':'
  946.     CALL    TYPE
  947.     JMP    CRLF
  948. ;.....
  949. ;
  950. ;
  951. HEAD3:    CALL    ILPRT        ;print:
  952.     DB    CR,LF,CR,LF,'-->Files moved elsewhere or deleted',0
  953.     LDA    DATE
  954.     CPI    ' '
  955.     JZ    HEAD5
  956.     CALL    SYSCK
  957.     JZ    HEAD5
  958.     CALL    ILPRT        ;print:
  959.     DB    ' since '
  960. ;
  961. DATE1:    DB    '        '    ;eight spaces
  962.     DB    0        ;string terminator
  963. ;
  964. HEAD4:    CALL    ILPRT
  965.    DB       CR,LF,'  (use FILEFIND or SD filename.ext $AD to see if available)'
  966.     DB    CR,LF,LF,0    ;extra line feed for beauty.(RP)
  967.     RET
  968. ;
  969. HEAD5:    MVI    A,':'
  970.     CALL    TYPE
  971.     JMP    HEAD4
  972. ;.....
  973. ;
  974. ;
  975. CKNON2: LDA    GOTNF
  976.     ORA    A
  977.     JNZ    FINI        ;jmp if got no 'NOT FOUND's
  978.     LDA    PRTFLG
  979.     ORA    A
  980.     JNZ    FINI
  981.     CALL    ILPRT        ;print: (then fall into 'FINI')
  982.     DB    '++ NONE ++',CR,LF,0
  983. ;
  984. ;
  985. ; Finished.  If building table, write back.  If making a SUB file, then
  986. ; flush the file buffer and close it.
  987. ;
  988. FINI:    LDA    SUBFLG        ;see if sub file is to be written
  989.     ORA    A
  990.     JNZ    WRTSUB        ;jump if so,
  991.     LDA    SETFLG        ;else see if set was performed
  992.     ORA    A
  993.     JZ    EXIT        ;jump out if not,
  994.     JMP    WRBACK        ;else write the program back to disk
  995. ;
  996. ;
  997. ; Write the SUB file to the currently logged in disk as 'D.SUB'
  998. ;
  999. WRTSUB: LHLD    SUBPTR        ;fill rest of last sector with eof's
  1000.     XCHG
  1001.     LXI    H,SUBBUF+7FH
  1002. ;
  1003. WNXTS:    MVI    M,1AH
  1004.     MOV    A,L
  1005.     DCX    H
  1006.     CMP    E
  1007.     JNZ    WNXTS
  1008.     CALL    WRTSB2        ;write the last sector to disk
  1009.     MVI    C,CLOSE     ;close the file
  1010.     LXI    D,LFCB
  1011.     CALL    BDOS
  1012.     INR    A        ;if close error, then notify console..
  1013.     JZ    BADWCL        ;..and abort
  1014.     JMP    EXIT        ;exit back to cp/m
  1015. ;
  1016. BADWCL: CALL    MSGXIT
  1017.     DB    'BAD CLOSE, SUB file incomplete$'
  1018. ;
  1019. ;
  1020. ; Set up the name in the table
  1021. ;
  1022. SETUP:
  1023.      IF    NOSYS
  1024.     CALL    SYSCK
  1025.     JZ    SETU1        ;GO CHECK FOR NAMED DIRECTORY (RP)
  1026.     LDA    SYSFLG
  1027.     RAL
  1028.     JC    SETSKP
  1029.      ENDIF            ;NOSYS
  1030. ;
  1031. SETU1:    INX    D        ;SKIP THE USER AREA        (RP)
  1032.     LDAX    D        ;GET FIRSAT CHAR IN TO 'ACCUM'
  1033.     DCX    D        ;GET USER AREA BACK
  1034.     CPI    '-'        ;IS IT A '-'
  1035.     JZ    SETSKP        ;YES; DON'T ADD IT TO TABLE.
  1036.     
  1037. ;
  1038. SETU2:    CALL    FINDFF        ;find end of table
  1039.     XCHG            ;setup for move
  1040. ;
  1041. ;
  1042. ; (HL = name, DE = end of table)
  1043. ;
  1044.     LXI    B,12        ;include the user area
  1045.     CALL    MOVER
  1046.     MVI    A,0FFH        ;get table end flag
  1047.     STAX    D        ;store it
  1048. ;
  1049. SETSKP: POP    B        ;delete stack garbage
  1050.     JMP    NEXT        ;get next entry
  1051. ;
  1052. ;
  1053. ; Routine to type 'C' characters from memory (HL)
  1054. ;
  1055. TYPMEM: MOV    A,M
  1056.     CALL    TYPE
  1057.     INX    H
  1058.     DCR    C
  1059.     JNZ    TYPMEM
  1060.     RET
  1061. ;.....
  1062. ;
  1063. ;
  1064. ; Inline print routine - prints string pointed to by stack until a zero
  1065. ; is found.  Returns to caller at next address after the zero terminator.
  1066. ;
  1067. ILPRT:    XTHL            ;save hl, get msg adrs
  1068. ;
  1069. ILPLP:    MOV    A,M        ;get char
  1070.     CALL    TYPE        ;output it
  1071.     INX    H        ;point to next
  1072.     MOV    A,M        ;test
  1073.     ORA    A        ;..for end
  1074.     JNZ    ILPLP
  1075.     XTHL            ;restore hl, ret addr
  1076.     RET            ;ret past msg
  1077. ;.....
  1078. ;
  1079. ;
  1080. CRLF:    CALL    ILPRT    ;print:
  1081.     DB    CR,LF,0
  1082.     RET
  1083. ;.....
  1084. ;
  1085. ;
  1086. SPACE:    MVI    A,' '
  1087. ;
  1088. ;
  1089. ; Print character in A to console
  1090. ;
  1091. TYPE:    PUSH    B
  1092.     PUSH    D
  1093.     PUSH    H
  1094.     MOV    C,A        ;char to c for cbios
  1095. ;
  1096. TYPEC:    CALL    $-$        ;supplied at start
  1097. ;
  1098. ;
  1099. ; See if console key pressed
  1100. ;
  1101. TYPES:    CALL    $-$        ;supplied at start
  1102.     ORA    A        ;key pressed?
  1103.     CNZ    CKKB        ;yes, see which one
  1104.     POP    H
  1105.     POP    D
  1106.     POP    B
  1107.     RET
  1108. ;.....
  1109. ;
  1110. ;
  1111. CKKB:    CALL    CI        ;get char
  1112.     CPI    'S'-40H     ;pause?
  1113.     CZ    CI        ;yes, get next char
  1114.     CPI    'C'-40H     ;abort?
  1115.     RNZ            ;no, return
  1116.     CALL    MSGXIT
  1117.     DB    CR,LF,'++ ABORTED ++$'
  1118. ;.....
  1119. ;
  1120. ;
  1121. ; Move (BC) bytes from (HL) to (DE)
  1122. ;
  1123. MOVER:    MOV    A,M
  1124.     STAX    D
  1125.     INX    D
  1126.     INX    H
  1127.     DCX    B
  1128.     MOV    A,B
  1129.     ORA    C
  1130.     JNZ    MOVER
  1131.     RET
  1132. ;.....
  1133. ;
  1134. ;
  1135. ; Compare routine
  1136. ;
  1137. COMPR:    LDAX    D
  1138.     CMP    M
  1139.     RNZ
  1140.     INX    D
  1141.     INX    H
  1142.     DCX    B
  1143.     MOV    A,B
  1144.     ORA    C
  1145.     JNZ    COMPR
  1146.     RET            ;equal means z=1
  1147. ;.....
  1148. ;
  1149. ;
  1150. ; Routine to find 0FFH at end of table
  1151. ;
  1152. FINDFF: LXI    H,NAMES
  1153. ;
  1154. FINDLP: MOV    A,M
  1155.     INX    H
  1156.     INR    A        ;0ffh?
  1157.     JNZ    FINDLP
  1158.     DCX    H        ;back up to table end
  1159.     RET
  1160. ;.....
  1161. ;
  1162. ;
  1163. ; Delete the name from the table
  1164. ;
  1165. DELNAM: LXI    H,NAMES
  1166. ;
  1167. DELLP:    MOV    A,M
  1168.     CPI    YES
  1169.     STC
  1170.     RZ            ;not found
  1171.     LXI    D,FCB+17
  1172.     inx    h        ;step past user number
  1173.     LXI    B,11
  1174.     CALL    COMPR
  1175.     JZ    DELETE
  1176.     DAD    B        ;calc next
  1177.     JMP    DELLP
  1178. ;.....
  1179. ;
  1180. ;
  1181. ; Delete the name
  1182. ;
  1183. DELETE: XCHG            ;next name to de
  1184.     LXI    H,-12        ;to back up..
  1185.     DAD    D        ;..to name to del
  1186. ;
  1187. DELCH:    LDAX    D
  1188.     MOV    M,A
  1189.     INX    H
  1190.     INX    D
  1191.     INR    A        ;moved the 0ffh?
  1192.     JNZ    DELCH
  1193.     ORA    A        ;show found
  1194.     RET
  1195. ;.....
  1196. ;
  1197. ;
  1198. ; Fill FCB with all '?'
  1199. ;
  1200. FILLQ:    LXI    H,FCB+1
  1201.     MVI    B,8+3
  1202.     MVI    A,'?'
  1203. ;
  1204. QMLOOP: MOV    M,A
  1205.     INX    H
  1206.     DCR    B
  1207.     JNZ    QMLOOP
  1208.     RET
  1209. ;.....
  1210. ;
  1211. ;
  1212. ; Write back the program - note that you may set any of the CP/M 2.x
  1213. ; attribute bits in the file name (be sure to define all 11 characters
  1214. ; of the name).
  1215. ;
  1216. WRBACK: LXI    D,FCB+1
  1217.     CALL    WRBK2
  1218. ;
  1219. WRBK1:    DB    'WHATSNEWC'    ;SET THE WRITE BACK TO A $SYS FILE (RP)
  1220.     DB    'O'+80H     ;<--put 'O'+80h here to set tag
  1221.     DB    'M'         ;see comment above
  1222.     DB    0        ;extent number
  1223. ;
  1224. WRBK2:    POP    H
  1225.     LXI    B,WRBK2-WRBK1
  1226.     CALL    MOVER
  1227.     MVI    C,ERASE
  1228.     LXI    D,FCB
  1229.     CALL    BDOS
  1230.     XRA    A        ;get 0
  1231.     STA    SETFLG        ;clear the flags..
  1232.     STA    GOTFLG
  1233.     STA    GOTNF
  1234.     STA    SYSTOO
  1235.     STA    FCBRNO        ;zero record number
  1236.     MVI    C,MAKE
  1237.     LXI    D,FCB
  1238.     CALL    BDOS
  1239. ;
  1240. ;
  1241. ; Before writing back, find end of table
  1242. ;
  1243.     CALL    FINDFF
  1244.     MOV    B,H        ;b=end page
  1245.     INR    B        ;for compare
  1246.     LXI    D,100H+BIAS    ;starting addr
  1247. ;
  1248. WRLP:    PUSH    B
  1249.     PUSH    D
  1250.     PUSH    H
  1251.     MVI    C,SETDMA
  1252.     CALL    BDOS
  1253.     MVI    C,WRITE
  1254.     LXI    D,FCB
  1255.     CALL    BDOS
  1256.     POP    H
  1257.     POP    D
  1258.     POP    B
  1259.     ORA    A        ;successful write?
  1260.     JNZ    WRERR        ;..no
  1261.     LXI    H,80H        ;point to..
  1262.     DAD    D        ;..next block
  1263.     XCHG            ;addr to de
  1264.     MOV    A,D        ;get page
  1265.     CMP    B        ;past table end?
  1266.     JC    WRLP        ;loop until done
  1267.     MVI    C,CLOSE
  1268.     LXI    D,FCB
  1269.     CALL    BDOS
  1270.     INR    A        ;successful close?
  1271.     JZ    BADCLS        ;..no, print err msg
  1272.     CALL    MSGXIT        ;ok, exit w/msg
  1273.     DB    '++ DONE ++$'
  1274. ;.....
  1275. ;
  1276. ;
  1277. WRERR:    CALL    MSGXIT
  1278.     DB    '++ WRITE ERROR ++$'
  1279. ;.....
  1280. ;
  1281. ;
  1282. BADCLS: CALL    MSGXIT
  1283.     DB    '++ BAD CLOSE, D.COM CLOBBERED ++$'
  1284. ;.....
  1285. ;
  1286. ;
  1287. ; Get console input via direct CBIOS call
  1288. ;
  1289. CI:    PUSH    B        ;console input
  1290.     PUSH    D
  1291.     PUSH    H
  1292. ;
  1293. CIC:    CALL    $-$        ;supplied at start
  1294.     POP    H
  1295.     POP    D
  1296.     POP    B
  1297.     RET
  1298. ;.....
  1299. ;
  1300. ;
  1301. ; Exit with message (error or informational)
  1302. ;
  1303. MSGXIT: POP    D        ;get msg
  1304.     MVI    C,PRINT
  1305.     CALL    BDOS
  1306. ;
  1307. ;
  1308. ; Exit, restoring DMA and stack, then return to CCP
  1309. ;
  1310. EXIT:    CALL    CRLF        ;give some room for beauty
  1311.     LXI    D,CPMBUFF    ;reset dma adr to normal
  1312.     MVI    C,SETDMA
  1313.     CALL    BDOS
  1314.     LDA    OLDUSR        ;set the user # back where it belongs (BH)
  1315.     MOV    E,A
  1316.     MVI    C,32        ;set user
  1317.     CALL    BDOS
  1318.     LHLD    STACK        ;get old stack
  1319.     SPHL            ;restore it
  1320.     RET            ;return to ccp
  1321. ;.....
  1322. ;
  1323. LINMRK: PUSH    B
  1324.     PUSH    D
  1325.     PUSH    H
  1326.     LDA    FCB        ;get drive name from fcb
  1327.     ORA    A        ;any there?
  1328.     JNZ    GOTDRV        ;yes, go print it
  1329.     MVI    C,CURDSK    ;else get current disk
  1330.     CALL    BDOS
  1331.     INR    A        ;make 'A'=1
  1332. ;
  1333. GOTDRV: ADI    40H        ;make ascii
  1334.     CALL    TYPE        ;print drive name
  1335.     lda    curusr        ;user number to A
  1336.     ani    1fH        ;31 is max that USER can be
  1337.     call    decprt        ;print user number in decimal
  1338.     CALL    ILPRT        ;print separator
  1339.     DB    ': ',0
  1340.     POP    H
  1341.     POP    D
  1342.     POP    B
  1343.     ret
  1344. ;
  1345. ;    print user number in decimal (from A) w/leading zero suppressed
  1346. decprt: 
  1347.     mov    c,a        ;save A
  1348.     sub    a
  1349. l10:    mov    b,a        ;save tens count
  1350.     mov    a,c        ;restore A
  1351.     sui    10        ;subtract 10
  1352.     jc    a10        ;if carry, end is past
  1353.     mov    c,a        ;else save in c
  1354.     mov    a,b        ;bump b
  1355.     adi    1        ; by 1
  1356.     jmp    l10        ;and go again
  1357. a10:    adi    10        ;make positive again
  1358.     mov    c,a        ;save units in binary
  1359.     mov    a,b        ;get tens count (in binary)
  1360.     ori    30h        ;convert to ascii digit
  1361.     cpi    30h        ;is it null?
  1362.     cnz    type        ;type if not
  1363.     mov    a,c        ;get units
  1364.     adi    30h
  1365.     call    type        ;print no matter what
  1366.     ret
  1367. ;.....
  1368. ;
  1369. ; Test for system file override
  1370. ;
  1371. SYSCK:    PUSH    H
  1372.     PUSH    D
  1373.     PUSH    B
  1374.     LXI    H,SYSTOO
  1375.     LXI    D,SYSOK
  1376.     MVI    B,3
  1377. ;
  1378. RSYSCK: LDAX    D
  1379.     CMP    M
  1380.     INX    H
  1381.     INX    D
  1382.     JNZ    SYSOUT
  1383.     DCR    B
  1384.     JNZ    RSYSCK
  1385. ;
  1386. SYSOUT: POP    B
  1387.     POP    D
  1388.     POP    H
  1389.     RET
  1390. ;.....
  1391. ;
  1392. ;
  1393.     DS    64        ;room for stack
  1394. STACK:    DS    2        ;old stack stored here
  1395. SUBFLG    DB    00H        ;flag to order sub file built
  1396. SUBPTR    DW    0000H        ;pointer to end of sub file
  1397. GOTFLG: DB    0
  1398. OLDUSR: DB    0        ;old user area
  1399. CURUSR: DB    0        ;current user area (RP)
  1400. GOTNF:    DB    0
  1401. SYSTOO: DB    0,0,0
  1402. SYSOK:    DB    '!  '          ;sys suppression override chars
  1403. SETFLG: DB    0        ;1 => setup table
  1404. PRTFLG: DB    0        ;print only some
  1405. SYSFLG: DB    0        ;$sys attrib indicator
  1406. LFCB    DS    36H        ;local fcb used by sub file
  1407. SUBBUF    DS    128        ;buffer used by sub file write routines
  1408. NAMES    EQU    $        ;names not to print are stored here..
  1409.                 ;..(i.e., the current dir)
  1410. ;
  1411. ; Note the names are initially built by the "D SET" command
  1412. ;
  1413.     DB    0FFH    ;end of table
  1414. ;
  1415. ;
  1416. ; Miscellaneous BDOS equates
  1417. ;
  1418. RDCON    EQU    1
  1419. DIO    EQU    6
  1420. PRINT    EQU    9
  1421. CONST    EQU    11
  1422. SELDSK    EQU    14
  1423. CLOSE    EQU    16
  1424. SRCHF    EQU    17
  1425. SRCHN    EQU    18
  1426. ERASE    EQU    19
  1427. READ    EQU    20
  1428. WRITE    EQU    21
  1429. MAKE    EQU    22
  1430. CURDSK    EQU    25
  1431. SETDMA    EQU    26
  1432. ;
  1433.     END
  1434. U    16
  1435. SRCHF    EQU    17
  1436. SRCHN    EQU    18
  1437. ERASE    EQU    19
  1438. READ    EQU    20
  1439. WRITE    EQU    21
  1440. MAKE    EQU    22
  1441. CURDSK    EQU    25
  1442. SETDMA    EQU    26