home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol044 / wash-14.asm < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  33.0 KB  |  1,307 lines

  1. ;    TITLE 'MICRO RESOURCES "WASH" Directory Maintence Utility Ver 1.4'
  2.  
  3. ;*************************************************************************
  4. ;    MICRO RESOURCES "WASH"; THE SUPER DIRECTORY MAINTENANCE UTILITY
  5. ;*************************************************************************
  6. ;
  7. ;
  8. ;    This program is a super-duper CP/M disk directory maintence
  9. ;    utility that is designed as an "almost" all inclusive routine
  10. ;    to make it easy to do disk directory house keeping. The
  11. ;    inspiration to produce this program came from use of an older
  12. ;    utility program called "CLEAN" that I came across at a meeting of
  13. ;    the Valley Computer Club about a year and a half ago. At that
  14. ;    time "CLEAN" seemed like a dream come true. Unfortunately it
  15. ;    had several major problems that limited its overall usefullness.
  16. ;    The disadvantages of CLEAN have all been overcome with the new
  17. ;    WASH program. Program features are listed below:
  18. ;
  19. ;        a) Alphabetical list oriented file operations
  20. ;
  21. ;        b) Any legal CP/M drive (A: to P:) may be selected
  22. ;
  23. ;        c) Operator interface to the file list is at the console
  24. ;           in sequential apha order in forward or backup mode.
  25. ;
  26. ;        d) The file list is treated as a circular buffer. Forward
  27. ;           or backward scanning of the list wraps around the list
  28. ;           back to the beginning or ending respectively.
  29. ;
  30. ;        e) The current list position file can be viewed at the
  31. ;           Console, printed on the CP/M List device, or sent
  32. ;           to the CP/M Punch device.
  33. ;
  34. ;        f) The current list position file may be deleted or renamed.
  35. ;           If renamed, only the new name must be entered.
  36. ;
  37. ;        g) The current list position file may be copied, with the
  38. ;           same name, to any other operator selected disk drive.
  39. ;           The copy utilizes all of available memory as the copy
  40. ;            buffer for the ultimate in copy speed.
  41. ;
  42. ;              h) The current list can be deleted and the "WASH" operation
  43. ;           may be begun upon another operator selected disk drive.
  44. ;
  45. ;        i) The program is fully implemented in 8080 assembly language
  46. ;           for speed, small size, and portability to any CP/M 2.2
  47. ;           or 1.4 system. No assumption is made upon the maximum
  48. ;           number of directory files other than available memory
  49. ;           space for the list. (A directory with 1024 directory
  50. ;           file names takes 12 K bytes of storage. Assuming the
  51. ;           copy buffer minimum size requirement of 128 bytes, then
  52. ;           WASH should easily run in the minimum CP/M 2.2 20K
  53. ;           System with no problems at all.) ALL directory and
  54. ;           disk I/O is handled through calls to the BDOS. This
  55. ;           will guarentee WASH compatibility with any CP/M system
  56. ;           implementation. This makes the program disk media
  57. ;           independent (all you have to do is get WASH.COM onto
  58. ;           your diskette or hard disk in the first place.
  59. ;
  60. ;    Complete documentation on the operation of WASH is given in the
  61. ;    accompaning documentation file "WASH.DOC". For the most part the
  62. ;    program is self documenting and contains extensive error message
  63. ;    reporting.
  64. ;
  65. ;
  66. ;        This Program was Written by:
  67. ;
  68. ;        Michael J. Karas
  69. ;        MICRO RESOURCES
  70. ;        2468 Hansen Court
  71. ;        Simi Valley, California 93065
  72. ;        (805) 527-7299
  73. ;        September 20, 1981
  74. ;
  75. ;    NOTE:  The WASH program, its source code, documentation file,
  76. ;           and object code, has been released to the PUBLIC DOMAIN
  77. ;           by Michael J. Karas. This program may be modified to suit
  78. ;           your personal requirements or those of your friends. In
  79. ;           any case no COMMERCIAL or MONEY MAKING ventures with
  80. ;           regard to SOFTWARE SALES or MODIFICATION and the subsequent
  81. ;           SALE of the WASH program in WHOLE or any PART is permitted
  82. ;           by the author. Further modification and public domain
  83. ;           distribution of the WASH program must include:
  84. ;            a) This NOTE,
  85. ;            b) The name "WASH" must be retained,
  86. ;            c) The original authorship notice
  87. ;               from above, and
  88. ;            d) The MICRO RESOURCES Name in the Sign-on
  89. ;               Menu.
  90. ;
  91. ;    MICRO RESOURCES reserves the right to modify this program at any
  92. ;    time for any purpose. The Intent of the above NOTE is intended
  93. ;    for the public domain distribution of the WASH program and
  94. ;    MICRO RESOURCES reserves the right to utilize the WASH program
  95. ;    for any application whatsoever including but not limited to
  96. ;    commercial distribution and modification for custom applications
  97. ;    with or without the "WASH" name.
  98. ;
  99. ;
  100. ;
  101. ;    Modification History:
  102. ;
  103. ;    If you modify, enhance, or correct bugs in this program, please
  104. ;    include a short statement of the modifications done and include
  105. ;    your name and the date. The modification history log should be
  106. ;    kept intact with this source code in "most recent first" order.
  107. ;    Changes to program structure will generally require a change in
  108. ;    the program version. The version number is documented in the
  109. ;    signon message and the distribution program name as "WASH-10.ASM"
  110. ;    in the specific case of the initial release 1.0.
  111. ;
  112. ;    Date: Oct 13, 1981  Version Number: 1.4  Bob Zimmerman
  113. ;    Changed Delete (D) command to ^D to make deleting files
  114. ;    a two-handed operation
  115. ;
  116. ;    9-26-81 V 1.2 Chuck Forsberg
  117. ;
  118. ;    Changed BDOS write record call to detect ANY non zero return as
  119. ;    error in accordance with CP/M 2.2 documentaion.  This fix should
  120. ;    minimize file diversion to the proverbial bit bucket.
  121. ;    Other BDOS calls checked for the same error.
  122. ;
  123. ;
  124. ;    Date: Sept. 25, 1981  Version Number: 1.3  Name: Ted Shapin
  125. ;
  126. ;    Added BASE for standard or modified CP/M systems.  Added BUFR
  127. ;    equate for same purpose and to make code clearer.  Shortened long
  128. ;    labels to be unique in first six chars.  Fixed code to compute
  129. ;    buffer address correctly for BUFR other than at 80H.  Reprint
  130. ;    help menu on any unknown command.  Changed abort to stay at same
  131. ;    position in list (good for abort while viewing file).
  132. ;    CP/M 1.4 always returns 0FFH when
  133. ;    deleting a file, therefore after a file was deleted always
  134. ;    printed "Not found".  I added a switch to bypass this code.
  135. ;
  136. ;    Date: Sept. 24, 1981   Version Number: 1.1  Name: Keith B. Petersen
  137. ;
  138. ;    Fixed problem with incorrect drive select when default disk used
  139. ;    and running in other than user 0.  Added code to turn up two new
  140. ;    lines to console when entering VIEW mode.
  141. ;
  142. ;    Date: Sept. 20, 1981   Version Number: 1.0  Name: Michael J. Karas
  143. ;
  144. ;    Initial release to the public domain via the CP/M NET remote
  145. ;    software access program operated by Kelly Smith, 3055 Waco Ave,
  146. ;    Simi Valley, CA 93063. (805) 527-9321/ PMMI modem.
  147. ;
  148. ;******************************************************************************
  149. ;
  150. ;
  151. ;
  152. ;
  153. ;DEFINE TRUE AND FALSE ASSEMBLY PARAMETERS
  154. ;
  155. FALSE    EQU    0           ;DEFINE FALSE
  156. TRUE    EQU    NOT FALSE    ;DEFINE TRUE
  157. ;
  158. BASE    EQU    0H        ; 0 FOR STD, 4200H FOR MODIFIED CP/M
  159. BUFR    EQU    80H+BASE    ; DEFAULT CP/M BUFFER
  160. CPM14    EQU    FALSE         ; TRUE IF RUNNING 1.4
  161. ;
  162. ;
  163. ;CP/M BDOS INTERFACE EQUATES
  164. ;
  165. WBOOT    EQU    0+BASE        ;WARM BOOT ENTRY ADRS
  166. KEYIN    EQU    1        ;CONSOLE INPUT FUNCTION
  167. WRCON    EQU    2        ;WRITE CHARACTER TO CONSOLE
  168. WRLST    EQU    5        ;WRITE CHARACTER TO LIST DEVICE
  169. WRPUN    EQU    4        ;WRITE CHARACTER TO PUNCH DEVICE
  170. LOGDRIV    EQU    0004H+BASE    ;LOCATION OF CURRENTLY LOGGED DRIVE
  171. BDOS    EQU    0005H+BASE    ;THE BDOS I/O VECTOR
  172. PRINT    EQU    9        ;PRINT STRING (DE) UNTIL '$'
  173. GETBUF    EQU    10        ;READ INPUT STRING
  174. GETST    EQU    11        ;GET CONSOLE STATUS
  175. OPEN    EQU    15        ;OPEN FILE
  176. CLOSE    EQU    16        ;CLOSE FILE
  177. SRCHF    EQU    17        ;SEARCH DIR FOR FIRST OCCUR.
  178. SRCHN    EQU    18        ;SEARCH DIR FOR NEXT OCCUR.
  179. DELETE    EQU    19        ;ERASE FILE
  180. READR    EQU    20        ;READ RECORD
  181. WRITER    EQU    21        ;WRITE RECORD
  182. MAKE    EQU    22        ;MAKE FILE
  183. RENAM    EQU    23        ;RENAME FILE
  184. STDMA    EQU    26        ;SET DMA ADDRESS
  185. FCB    EQU    5CH+BASE    ;DEFAULT FILE CONTROL BLOCK
  186. FCBEXT    EQU    FCB+12          ;EXTENT BYTE IN FCB
  187. FCBRNO    EQU    FCB+32        ;RECORD NUMBER IN FCB
  188. ;
  189. ;
  190. ;ASCII CHARACTER DEFINITIONS
  191. ;
  192. BS    EQU    008H        ;ASCII BACK SPACE CHARACTER
  193. LF    EQU    00AH        ;ASCII LINE FEED CHARACTER
  194. CR    EQU    00DH        ;ASCII CARRIAGE RETURN CHARACTER
  195. ESC    EQU    01BH        ;ASCII ESCAPE CHARACTER
  196. RUBOUT    EQU    07FH        ;ASCII RUBOUT CHARACTER
  197. EOT    EQU    004H        ;ASCII EOT CHARACTER (^D)
  198. ;
  199. ;*****************************************************************************
  200. ;
  201. ;
  202.     ORG    0100H+BASE
  203. ;
  204.     DI
  205.     LXI    SP,STCKK    ;SETUP LOCAL UTILITY STACK
  206. ;
  207. RESTART:
  208.     CALL    MENU
  209. ;
  210. ;
  211. ;START UP BY ASSEMBLING LIST OF FILE NAMES OF SPECIFIED DISK DRIVE
  212. ;
  213.     LDA    FCB+1        ;CHECK IF A COMMAND PARAMETER WAS ENTERED
  214.     CPI    ' '        ;..FILE NAME = SPACES?
  215.     JNZ    NAMEPRES    ;NAME NOT SPACE SO PARM WAS ENTERED
  216.     LDA    FCB+9        ;EXTENT NAME ALSO SPACES?
  217.     CPI    ' '        ;..IF SO THEN MUST TREAT AS *.*
  218.     JNZ    NAMEPRES
  219. ;
  220. ;
  221. ;NO COMMAND PARAMETER FOR A FILE NAME SO SET LIKE *.*
  222. ;
  223.     LXI    H,ALFN        ;POINT AT ALL FILE WILD CARD NAME
  224.     LXI    D,FCB+1        ;PLACE TO PUT IT
  225.     MVI    B,11        ;SIZE TO SET
  226.     CALL    MOVBYT        ;SET FIELD TO *.*
  227.     JMP    NAMEPRES
  228. ;
  229. ALFN:
  230.     DB    '???????????'    ;DUMMY ALL FILE SPECIFIED NAME
  231. ;
  232. ;
  233. ;HERE IF NAME PROPERLY POSITIONED IN THE DEFAULT FCB AREA FOR LIST BUILD
  234. ;
  235. NAMEPRES:
  236.     MVI    C,STDMA        ;INITIALIZE DMA ADDRESS TO DEFAULT BUFFER
  237.     LXI    D,BUFR
  238.     CALL    BDOS
  239. ;
  240.     XRA    A        ;CLEAR APPROPIATE FIELDS OF SEARCH FCB
  241.     STA    FCBEXT        ;EXTENT BYTE
  242.     STA    FCBRNO        ;AND RECORD NUMBER
  243. ;
  244.     LXI    D,FCB        ;USE DEFAULT FCB FOR SEARCH
  245.     MVI    C,SRCHF        ;SEARCH FOR FIRST OCCURRANCE
  246.     CALL    BDOS
  247.     CPI    0FFH        ;SEE IF FOUND
  248.     JNZ    LOADLIST    ;IF SOME FOUND THEN GO BUILE LIST
  249. ;
  250.     CALL    PRTMSG        ;TELL THEM THAT NONE FOUND
  251.     DB    CR,LF,' ++ Not Found ++',0
  252.     JMP    EXIT
  253. ;
  254. ;
  255. MENU:
  256.     CALL    PRTMSG        ;PRINT SIGNON MESSAGE
  257. ;
  258.     DB    CR,LF,'   MICRO RESOURCES DIRECTORY "WASH UTILITY" Ver 1.3'
  259.     DB    CR,LF
  260.     DB    CR,LF,'         Command        Function'
  261.     DB    CR,LF,'         -------    ----------------------------'
  262.     DB    CR,LF,'            V       View file at Console'
  263.     DB      CR,LF,'                     (any key aborts)'
  264.     DB      CR,LF,'            L       Print file to List Device'
  265.     DB    CR,LF,'            P       Send file to Punch Device'
  266.     DB    CR,LF,'            C       Copy file to another Disk'
  267.     DB    CR,LF,'            R       Rename file'
  268.     DB    CR,LF,'           ^D       Delete file'
  269.     DB    CR,LF,'            X       Exit to CP/M'
  270.     DB    CR,LF,'            B       Backup one file in List'
  271.     DB    CR,LF,'            S       Restart on another Drive'
  272.     DB    CR,LF,'         sp or cr   Forward to next file in List'
  273.     DB    CR,LF,'H or anything else  Display this help message'
  274.     DB    CR,LF,CR,LF,CR,LF,0
  275.     RET
  276. ;
  277. ;
  278. ;BUILD UP LIST WITH ALL FOUND ENTRIES
  279. ;
  280. LOADLIST:
  281.     LXI    H,LIST        ;INITIALIZE LIST POINTER PARAMETERS
  282.     SHLD    LISTPOS        ;START = CURRENT POS OF LIST
  283. ;
  284. ;
  285. ;PUT CURRENTLY FOUND NAME TO LIST
  286. ;(A) = OFFSET IN DEFAULT BUFFER OF NAME
  287. ;
  288. ;
  289. NM2LST:
  290.     ANI    3        ;ZERO BASED TWO BIT INDEX
  291.     ADD    A        ;TIMES 32 TO MAKE POSITION INDEX
  292.     ADD    A
  293.     ADD    A
  294.     ADD    A
  295.     ADD    A
  296.     MOV    C,A        ;PUT IN BC
  297.     XRA    B        ;CLEAR HIGH ORDER
  298.     LXI    H,BUFR        ;TO NAME POSITION IN DEFAULT BUFFER
  299.     DAD    B           ;(HL) = CURRENT FOUND NAME POINTER
  300.     LDA    FCB        ;PUT DISK DRIVE NUMBER INTO NAME PLACE
  301.     ORA    A        ;SEE IF DEFAULT DRIVE
  302.     JNZ    NOTDEF        ;SKIP SETTING IF NOT DEFAULT
  303.     LDA    LOGDRIV
  304.     ANI    0FH        ;GET RID OF USER NUMBER
  305.     INR    A        ;MAKE 1 = A:
  306. NOTDEF:
  307.     MOV    M,A        ;INTO BUFFER
  308.     XCHG
  309.     LHLD    LISTPOS        ;POINTER TO CURRENT LOAD POINT IN LIST
  310.     XCHG
  311.     MVI    B,12        ;MOVE DRIVE DESIGNATOR AND NAME TO LIST
  312.     CALL    MOVBYT
  313.     XCHG            ;(DE) WAS LEFT WITH LEXT LOAD POINT ADDRESS
  314.     SHLD    LISTPOS
  315. ;
  316. ;
  317. ;SEARCH FOR NEXT OCCURANCE OF SPECIFIED FILE NAME
  318. ;
  319.     MVI    C,SRCHN        ;SEARCH NEXT FUNCTION CODE
  320.     LXI    D,FCB        ;FILE NAME SPECIFICATION FIELD
  321.     CALL    BDOS
  322.     CPI    0FFH        ;SEE IF ALL THROUGH DIRECTORY YET
  323.     JNZ    NM2LST    ;IF NOT GO PUT NAME INTO LIST
  324. ;
  325. ;
  326. ;ALL FILE NAMES NOW IN LIST SO LETS SETUP PARAMETERS ASSOCIATED
  327. ;THE LIST SIZE AND COPY BUFFER START POINT.
  328. ;
  329.     LHLD    LISTPOS        ;NEXT LOAD POINT OF LIST IS START OF BUFFER
  330.     SHLD    LISTEND        ;SET LIST END MARKER
  331.     SHLD    BUFSTART
  332.     LXI    D,LIST+12    ;COMPARE LISTEND TAB BASE+12
  333.     CALL    CDEHL
  334.     JZ    CMDST        ;GO TO COMMAND LOOP IF NO SORT
  335. ;
  336. ;
  337. ;SORT LIST OF FILE NAMES IN ALPHA ORDER AS AN OPERATOR NICEITY
  338. ;THIS MAY TAKE A LITTLE WHILE AS THIS IS A VERY SIMPLE SORT ROUTINE
  339. ;
  340. SORT:
  341.     LXI    H,LIST        ;INITIALIZE I SORT VARIABLE
  342.     SHLD    LISTI
  343.     LXI    D,12        ;INITIALIZE ALSO THE J VARIABLE
  344.     DAD    D
  345.     SHLD    LISTJ
  346. ;
  347. SORT1:
  348.     LHLD    LISTJ        ;COMPARE NAMES I & J
  349.     XCHG
  350.     LHLD    LISTI
  351.     PUSH    H        ;SAVE POSITION POINTERS FOR MAYBE SWAP
  352.     PUSH    D
  353.     MVI    B,12        ;COMPARE SIZE
  354.     CALL    CMPSTR        ;GO COMPARE
  355.     POP    D
  356.     POP    H
  357.     MVI    B,12
  358.     CC    SWAP        ;GO SWAP IF J STRING LARGER THAN I
  359. ;
  360.     LHLD    LISTJ        ;INCREMENT J POINTER
  361.     LXI    D,12
  362.     DAD    D
  363.     SHLD    LISTJ
  364.     XCHG            ;SEE IF END OF J LOOP
  365.     LHLD    LISTEND
  366.     CALL    CDEHL
  367.     JNZ    SORT1        ;..NO SO MORE J LOOP
  368. ;
  369.     LHLD    LISTI        ;BUMP I POINTER
  370.     LXI    D,12
  371.     DAD    D
  372.     SHLD    LISTI
  373.     DAD    D        ;SET START OVER J POINTER
  374.     SHLD    LISTJ
  375.     XCHG            ;SEE IF END OF I LOOP
  376.     LHLD    LISTEND
  377.     CALL    CDEHL
  378.     JNZ    SORT1        ;MUST BE MORE I LOOP TO DO
  379. ;
  380. ;
  381. ;FILE PROCESSING AND DISPLAY LOOP
  382. ;
  383. CMDST:
  384.     LXI    H,LIST        ;SET START POINT OF LISTING
  385.     SHLD    LISTPOS
  386. ;
  387. ;
  388. ;DISPLAY CURRENT FILE POSITION
  389. ;
  390. LOOP:
  391.     LHLD    LISTPOS        ;MOVE FROM LOCATION
  392.     LXI    D,PNAME        ;START POINT OF LIST POINT
  393.     MVI    B,1        ;ONE CHARACTER OF DRIVE ID TO MOVE
  394.     CALL    MOVBYT
  395. ;
  396.     LXI    D,PNAME+3    ;PLACE TO PUT FILE NAME FOR PRINT
  397.     MVI    B,8        ;8 CHARS IN FILE NAME
  398.     CALL    MOVBYT        ;MOVE NAME FIELD
  399. ;
  400.     LXI    D,PNAME+12    ;PLACE TO PUT EXTENSION FOR PRINT
  401.     MVI    B,3        ;3 CHARS IN FILE TYPE
  402.     CALL    MOVBYT        ;MOVE TYPE NAME
  403. ;
  404.     SHLD    LISTPOS        ;SAVE NEXT POSITION OF LISTING
  405. ;
  406.     LDA    PNAME        ;MAKE DRIVE NAME PRINTABLE
  407.     ADI    'A'-1        ;THIS ONE O.K. SO MAKE DRIVE PRINTABLE
  408.     STA    PNAME
  409. ;
  410. SAMEPOS:
  411.     CALL    PRTMSG        ;PRINT CURRENT READY TO TRANSFER FILE NAME
  412. PNAME:
  413.     DB    'X: XXXXXXXX.XXX   : ' ;DUMMY FILE NAME PRINTING FIELD
  414.     DB    0
  415. ;
  416.     MVI    C,KEYIN        ;CONSOLE CHAR IN FUNCTION
  417.     CALL    BDOS        ;GET THE CHARACTER
  418.     CALL    UPCASE
  419.     CPI    ' '        ;IF SPACE THEN ON TO NEXT FILE
  420.     JZ    NEXTPOS
  421.     CPI    CR        ;IF CARRIAGE RETURN THEN ON TO NEXT FILE
  422.     JZ    NEXTPOS
  423.     CPI    'B'        ;IF BACKUP THEN ADJUST POSITION POINTER -1 FILE
  424.     JZ    BACKUP
  425.     CPI    'X'        ;IF EXIT THEN TO CP/M
  426.     JZ    EXIT
  427.     CPI    'R'        ;IF RENAME THEN GO DO IT
  428.     JZ    RENAME
  429.     CPI    EOT        ;TO DELETE A FILE IF "^D"
  430.     JZ    DELFLE
  431.     CPI    'V'        ;IF TO VIEW FILE AT CONSOLE
  432.     JZ    VIEW
  433.     CPI    'L'        ;IF TO PRINT FILE TO LIST DEVICE
  434.     JZ    PRTFIL
  435.     CPI    'P'        ;IF TO SEND FILE TO THE PUNCH DEVICE
  436.     JZ    PUNFIL
  437.     CPI    'C'        ;IF TO COPY FILE TO ANOTHER DISK
  438.     JZ    COPY
  439.     CPI    'S'        ;IF TO START OVER ON ANOTHER DRIVE
  440.     JZ    LOG
  441. CMDERR:
  442.     CALL    MENU          ;GIVE HELP MESSAGE
  443.     JMP    SAMEPOS        ;STAY IN THIS POSITION
  444. ;
  445. BACKUP:
  446.     LHLD    LISTPOS        ;SEE IF AT BEGINNING OF LIST
  447.     LXI    D,LIST+12
  448.     CALL    CDEHL
  449.     JNZ    BAKUP1        ;SKIP POSITION POINTER RESET IF NOT
  450.                 ;..AT BEGINNING
  451.     CALL    PRTMSG
  452.     DB    CR,LF,CR,LF,'      Beginning of List',CR,LF,0
  453.     LHLD    LISTEND        ;SET TO END +1 TO BACKUP TO END
  454.     LXI    D,12
  455.     DAD    D
  456.     SHLD    LISTPOS
  457. ;
  458. BAKUP1:
  459.     CALL    PRTMSG        ;PRINT BACKUP INDICATOR
  460.     DB    CR,LF,'<  ',0
  461.     LHLD    LISTPOS
  462.     LXI    D,12*2        ;ONE LIST POSITION BACKWARDS SIZE
  463.     CALL    SDEHL        ;SUBTRACT
  464.     SHLD    LISTPOS
  465.     JMP    LOOP        ;DISPLAY THAT GUY WITHOUT CRLF
  466. ;
  467. NEXTPOS:
  468.     CALL    PRTMSG        ;DO CARRIAGE RETURN LINE FEED
  469.     DB    CR,LF,0
  470.     LHLD    LISTPOS        ;SEE IF AT END OF LOOP YET
  471.     XCHG
  472.     LHLD    LISTEND
  473.     CALL    CDEHL        ;COMPARE
  474.     JNZ    LOOP        ;GO ON TO NEXT POSITION TO PRINT
  475. ;
  476. ;
  477. ;AT END OF DIRECTORY. PRINT MESSAGE AND GO BACK TO TOP
  478. ;
  479.     CALL    PRTMSG        ;PRINT END OF DIRECTORY MESSAGE
  480.     DB    CR,LF,'      End of List',CR,LF,CR,LF,0
  481.     LXI    H,LIST        ;SET POSITION POINTER TO BEGINNING
  482.     SHLD    LISTPOS
  483.     JMP    LOOP        ;TO REDISPLAY START ENTRY
  484. ;
  485. ;
  486. ;CLEAN COMMAND LOOP EXIT POINT TO CP/M
  487. ;
  488. EXIT:
  489.     JMP    WBOOT        ;BACK TO CP/M
  490. ;
  491. ;
  492. ;ROUTINE TO RENAME THE FILE CURRENTLY DISPLAYED
  493. ;
  494. RENAME:
  495.     LHLD    LISTPOS        ;MOVE NAME FROM LIST TO RENAME FCB
  496.     LXI    D,12
  497.     CALL    SDEHL        ;POINT TO NAME POSITION
  498.     LXI    D,DESTFCB    ;PLACE TO MOVE THE NAME
  499.     MVI    B,12        ;AMOUNT TO MOVE
  500.     CALL    MOVBYT
  501. ;
  502.     CALL    PRTMSG        ;NEW NAME PROMPT
  503.     DB    '  New Name ? ',0
  504.     MVI    C,GETBUF    ;GET COMMAND BUFFER FUNCTION
  505.     LXI    D,CBUFF        ;PLACE TO PUT COMMAND LINE
  506.     CALL    BDOS
  507. ;
  508. ;
  509. ;CONVERT TO UPPER CASE
  510. ;
  511.     LXI    H,CBUFFL    ;GET BUFFER LENGTH
  512.     MOV    B,M        ;..TO (B)
  513.     XRA    A
  514.     ORA    B        ;IF ZERO LENGTH SKIP RENAME
  515.     JZ    NEXTPOS
  516. ;
  517. CONV:
  518.     INX    H        ;POINT AT A CHAR TO CONVERT
  519.     MOV    A,M
  520.     CALL    UPCASE
  521.     MOV    M,A        ;PUT BACK INTO BUFFER
  522.     DCR    B
  523.     JNZ    CONV
  524. ;
  525. ;
  526. ;SCAN INPUT BUFFER TO MOVE A FILE NAME TO THE RENAME POSITION OF
  527. ;DESTINATION FCB
  528. ;
  529.     LXI    H,DESTFCB+16
  530.     MVI    M,0        ;BDOS EXPECTS ZERO HERE
  531.     INX    H
  532. ;
  533. ;
  534. ;PREBLANK THE NEW FILE NAME FIELD
  535. ;
  536.     PUSH    H        ;SAVE START POINTER
  537.     MVI    B,11        ;NUMBER OF SPACES TO BLANK
  538. PREFILL:
  539.     MVI    M,' '        ;PUT IN A SPACE CODE
  540.     INX    H
  541.     DCR    B        ;CHECK BYTE COUNT TO SEE IF DONE
  542.     JNZ    PREFILL
  543.     POP    H
  544. ;
  545.     XCHG
  546.     LXI    H,CBUFFL    ;GET LENGTH TO (C)
  547.     MOV    C,M
  548.     INX    H
  549.     XCHG            ;(DE) = BUFFER POINTER
  550.                 ;..& (HL) = FCB POINTER
  551. ;
  552. ;
  553. ;PURGE SPACES OFF THE BEGINNING OF BUFFER
  554. ;
  555. DEBLANK:
  556.     LDAX    D        ;GET A CHARACTER
  557.     CPI    ' '
  558.     JNZ    EXTND        ;NOT BLANK, WE HAVE SOMETHING
  559.     INX    D        ;TO NEXT CHAR
  560.     DCR    C
  561.     JZ    CMDERR        ;ALL SPACES SO ERROR
  562.     JMP    DEBLANK
  563. ;
  564. ;
  565. ;EXTEND BUFFER TO BLANKS BEYOND COMMAND LENGTH
  566. ;
  567. EXTND:
  568.     PUSH    H
  569.     MOV    L,C        ;DOUBLE BYTE REMAINING LENGTH
  570.     MVI    H,0
  571.     DAD    D        ;TO BUFFER END +1
  572.     MVI    M,' '        ;FORCE ILLEGAL CHAR END
  573.     POP    H
  574. ;
  575. ;
  576. ;START FILE NAME SCAN
  577. ;
  578. SCAN:
  579.     MVI    B,8        ;MAX OF 8 CHAR IN FILE NAME
  580. SCAN1:
  581.     CALL    CHKLEGL        ;GET AND SEE IF LEGAL CHARACTER
  582.     JC    CMDERR        ;CHECK IF ALL OF COMMAND LINE
  583.     CPI    ' '        ;SEE IF END OF PARAMETER FIELD
  584.     JZ    CPYBITS        ;GO TO RENAME THE FILE
  585.     CPI    '.'        ;AT END OF FILE NAME
  586.     JZ    SCAN2        ;GO TO PROCESS THE FILE TYPE FIELD
  587.     MOV    M,A        ;PUT CHAR INTO DESTINATION FCB
  588.     INX    H
  589.     DCR    B        ;CHECK NAME CHARACTER COUNT
  590.     JNZ    SCAN1
  591. ;
  592. ;
  593. ;GOT HERE IF EIGHT CHAR WITHOUT A "."
  594. ;
  595. SCAN1A:
  596.     CALL    CHKLEGL        ;SCAN BUFFER UP TO PERIOD
  597.                 ;OR END
  598.     JC    CPYBITS        ;NO EXTENT IF NOT LEGAL
  599.     CPI    ' '        ;END OF PARAMETER FIELD?
  600.     JZ    CPYBITS
  601.     CPI    '.'
  602.     JZ    SCAN2        ;NOW GO DO EXTENT FIELD
  603.     JMP    SCAN1A        ;DO TILL END OR PERIOD
  604. ;
  605. ;
  606. ;NOW BUILD THE EXTENT FIELD
  607. ;
  608. SCAN2:
  609.     MVI    B,3        ;MAX LENGTH OF EXTENT FIELD
  610.     LXI    H,DESTFCB+25    ;DESTINATION RENAME EXTENT START
  611. SCAN3:
  612.     CALL    CHKLEGL        ;GET AND CHECK CHARACTER
  613.     JC    SCAN4        ;NAME DONE IF ILLEGAL
  614.     CPI    ' '        ;END OF PARAMETER FIELD?
  615.     JZ    SCAN4
  616.     CPI    '.'        ;CHECK IF ANOTHER PERIOD
  617.     JZ    SCAN4
  618.     MOV    M,A
  619.     INX    H
  620.     DCR    B
  621.     JNZ    SCAN3        ;GET NEXT EXTENT CHARACTER
  622. ;
  623. SCAN4:
  624.     MVI    B,4        ;FILL EX,S1,S2,RC WITH ZEROS
  625.     LXI    H,DESTFCB+28    ;SET POINTER TO RENAME EXTENT FIELD
  626. SCAN5:
  627.     MVI    M,0
  628.     INX    H
  629.     DCR    B
  630.     JNZ    SCAN5
  631. ;
  632. ;
  633. ;COPY OLD FILES ATTRIBUTE BITS TO THE NEW FILE NAME TO HAVE THEN BE
  634. ;THE SAME AS OLD FILE NAME
  635. ;
  636. CPYBITS:
  637.     LXI    D,DESTFCB+1    ;FIRST CHAR OF OLD NAME
  638.     LXI    H,DESTFCB+17    ;FIRST CHAR OF NEW NAME
  639.     MVI    C,011        ;NUMBER OF BYTES WITH TAG BITS
  640. CBITS1:
  641.     LDAX    D        ;FETCH BIT OF OLD NAME CHAR
  642.     ANI    080H        ;STRIP ONLY UPPER BIT OUT
  643.     MOV    B,A        ;SAVE BIT INTO (B)
  644.     MVI    A,07FH        ;FETCH A MASK FOR CHAR ONLY
  645.     ANA    M        ;GET MASKED CHAR TO (A)
  646.     ORA    B        ;PUT OLD BIT IN
  647.     MOV    M,A        ;SAVE NEW BYTE BACK
  648.     INX    H        ;BUMP COPY POINTERS
  649.     INX    D
  650.     DCR    C        ;DEC BYTE COPY COUNT
  651.     JNZ    CBITS1
  652. ;
  653. ;
  654. ;SEE IF THE NEW FILE NAME ALREADY EXISTS. IF SO SAY SO AND THEN GO
  655. ;TO THE COMMAND LOOP AGAIN AT SAME POSITION
  656. ;
  657.     LDA    DESTFCB        ;COPY NEW NAME TO SOURCE FCB
  658.     STA    SORCFCB
  659.     MVI    B,11
  660.     LXI    H,DESTFCB+17    ;COPY NEW NAME TO
  661.     LXI    D,SORCFCB+1    ;..SOURCE FCB FOR EXISTENCE CHECK
  662.     CALL    MOVBYT
  663.     MVI    B,4        ;ZERO THE OPERATIONAL FIELDS
  664.     LXI    H,SORCFCB+12
  665. RNFILLP:
  666.     MVI    M,0        ;PUT A ZERO IN THERE
  667.     INX    H        ;TAKE CARE OF COUNTERS
  668.     DCR    B
  669.     JNZ    RNFILLP
  670. ;
  671.     LXI    D,SORCFCB    ;SEARCH TO SEE IF THIS FILE EXISTS
  672.     MVI    C,SRCHF        ;SEARCH FIRST FUNCTION
  673.     CALL    BDOS
  674.     CPI    0FFH        ;RETURN CODE IF NOT FOUND
  675.     JZ    RNFILE        ;TO RENAME COMMAND IF NOT A DUPLICATE NAME
  676. ;
  677.     CALL    PRTMSG        ;ASK IF TO REPLACE
  678.     DB    CR,LF,' ++ Name Already Exists ++',CR,LF,0
  679.     JMP    SAMEPOS        ;BACK TO LET HIM TRY ALL THAT AGAIN ON
  680.                 ;... THE SAME FILE NAME
  681. ;
  682. ;
  683. ;COPY NEW NAME INTO LIST POSITION IN CASE HE BACKS UP
  684. ;
  685. RNFILE:
  686.     LHLD    LISTPOS        ;GET LIST POSITION POINTER
  687.     LXI    D,11        ;BACK 11 TO LEAVE DRIVE ID THE SAME
  688.     CALL    SDEHL
  689.     XCHG
  690.     LXI    H,DESTFCB+17    ;POINT AT THE NEW NAME
  691.     MVI    B,11        ;AMOUNT TO MOVE
  692.     CALL    MOVBYT
  693. ;
  694. ;
  695. ;NOW DO THE RENAME BDOS FUNCTION
  696. ;
  697. RNFIL1:
  698.     LXI    D,DESTFCB    ;RENAME FCB LOCATION
  699.     MVI    C,RENAM        ;RENAME FUNCTION CODE
  700.     CALL    BDOS        ;GO DO IT
  701.     CPI    0FFH        ;SEE IF RENAME ERROR
  702.     JNZ    NEXTPOS        ;IF O.K. PROCEDE
  703.     CALL    PRTMSG        ;OR ELSE PRINT ERROR MESSAGE
  704.     DB    ' ++ Not Found ++',0
  705.     JMP    NEXTPOS        ;GO TO NEXT LIST POSITION
  706. ;
  707. ;
  708. ;DELETE A FILE NAME AS SPECIFIED IN CURRENT POSITION POINTER
  709. ;
  710. DELFLE:
  711.     LHLD    LISTPOS        ;MOVE NAME FROM LIST TO RENAME FCB
  712.     LXI    D,12
  713.     CALL    SDEHL        ;POINT TO NAME POSITION
  714.     LXI    D,DESTFCB    ;PLACE TO MOVE THE NAME
  715.     MVI    B,12        ;AMOUNT TO MOVE
  716.     CALL    MOVBYT
  717. ;
  718. ;
  719. ;DELETE THE FILE NOW
  720. ;
  721.     LXI    D,DESTFCB    ;POINT AT DELETE FCB
  722.     MVI    C,DELETE    ;DELETE FUNCTION CODE
  723.     CALL    BDOS
  724.     IF    NOT CPM14    ;AVOID 1.4 BUG
  725.     CPI    0FFH
  726.     JNZ    DELFL1        ;FILE DELETED O.K.
  727.     CALL    PRTMSG        ;TYPE ERROR MESSAGE
  728.     DB    ' ++ Not Found ++',0
  729.     JMP    NEXTPOS
  730.     ENDIF
  731. ;
  732. DELFL1:
  733.     CALL    PRTMSG        ;SAY IT HAS BEEN DELETED
  734.     DB    '  Deleted',0
  735. ;
  736. ;
  737. ;MOVE LIST UP ONE POSITION TO CLOSE UP THE ERASED POSITION
  738. ;
  739.     LHLD    LISTPOS        ;FIXUP MOVE UP POINTERS
  740.     PUSH    H
  741.     LXI    D,12
  742.     CALL    SDEHL
  743.     SHLD    LISTPOS        ;RESET CURRENT POSITION FOR MOVE
  744.     XCHG            ;(DE) = TO LOCATION
  745.     POP    H        ;(HL) = FROM LOCATION
  746. ;
  747. MOVUP:
  748.     XCHG
  749.     PUSH    H        ;CHECK IF AT END
  750.     LHLD    LISTEND        ;GET OLD END POINTER
  751.     CALL    CDEHL        ;CHECK AGAINST CURRENT END LOCATION
  752.     POP    H
  753.     XCHG
  754.     JZ    MOVDONE        ;MUST BE AT END OF LIST
  755.     MVI    B,12        ;ONE NAME SIZE
  756.     CALL    MOVBYT        ;MOVE ONE NAME UP
  757.     JMP    MOVUP        ;GO CHECK END PARAMETERS
  758. ;
  759. MOVDONE:
  760.     XCHG
  761.     SHLD    LISTEND        ;SET NEW LIST END IF ALL MOVED
  762.     LXI    D,LIST        ;SEE IF LIST IS EMPTY
  763.     CALL    CDEHL        ;..IE LISTEND=LISTPOS=LIST
  764.     JNZ    NEXTPOS
  765.     LHLD    LISTPOS
  766.     CALL    CDEHL
  767.     JNZ    NEXTPOS        ;NEITHER EQUAL SO NOT EMPTY
  768.     CALL    PRTMSG
  769.     DB    CR,LF,CR,LF,'      List Empty',0
  770.     JMP    EXIT        ;BALE OUT IF DONE
  771. ;
  772. ;
  773. ;ENTRY POINT TO SEND CURRENT FILE NAME CONTENTS TO THE CONSOLE
  774. ;
  775. VIEW:
  776.     CALL    PRTMSG
  777.     DB    CR,LF,CR,LF,0    ;TURN UP TWO NEW LINES
  778.     MVI    A,WRCON        ;WRITE CONSOLE OUT FUNCTION
  779.     JMP    OUTCM        ;TO COMMON I/O PROCESSING
  780. ;
  781. ;
  782. ;ENTRY POINT TO SEND CURRENT FILE NAME CONTENTS TO THE LIST DEVICE
  783. ;
  784. PRTFIL:
  785.     MVI    A,WRLST        ;WRITE LIST DEVICE OUT FUNCTION
  786.     JMP    OUTCM        ;TO COMMON I/O PROCESSING
  787. ;
  788. ;
  789. ;ENTRY POINT TO SEND CURRENT FILE NAME CONTENTS TO THE PUNCH DEVICE
  790. ;
  791. PUNFIL:
  792.     MVI    A,WRPUN        ;WRITE PUNCH DEVICE OUT FUNCTION
  793. ;
  794. ;
  795. ;COMMON OUTPUT CHARACTER I/O PROCESSING ENTRY
  796. ;
  797. OUTCM:
  798.     STA    OUTOP        ;SAVE BDOS FUNCTION
  799. ;
  800. ;
  801. ;FETCH THE FILE NAME TO SEND OUT
  802. ;
  803.     LHLD    LISTPOS        ;MOVE NAME FROM LIST TO SOURCE FCB
  804.     LXI    D,12
  805.     CALL    SDEHL        ;POINT TO NAME POSITION
  806.     LXI    D,SORCFCB    ;PLACE TO MOVE THE NAME
  807.     MVI    B,12        ;AMOUNT TO MOVE
  808.     CALL    MOVBYT
  809. ;
  810.     LXI    D,BUFR        ;SET TO USE DEFAULT DMA BUFFER
  811.     MVI    C,STDMA        ;ADDRESS SET FUNCTION
  812.     CALL    BDOS
  813. ;
  814.     MVI    B,4        ;FILL EX,S1,S2,RC WITH ZEROS
  815.     LXI    H,SORCFCB+12    ;SET POINTER TO SOURCE EXTENT FIELD
  816. OUTCM1:
  817.     MVI    M,0
  818.     INX    H
  819.     DCR    B
  820.     JNZ    OUTCM1
  821. ;
  822.     LXI    D,SORCFCB    ;OPEN THE FILE FOR READING
  823.     MVI    C,OPEN        ;FILE OPEN FUNCTION CODE
  824.     CALL    BDOS
  825.     CPI    0FFH
  826.     JNZ    OUTCM2        ;SKIP ERROR MESSAGE IF O.K.
  827.     CALL    PRTMSG
  828.     DB    ' ++ File Cannot Be Opened ++',0
  829.     JMP    NEXTPOS
  830. ;
  831. OUTCM2:
  832.     XRA    A        ;ZERO THE CURRENT RECORD FIELD
  833.     STA    SORCFCB+32
  834. ;
  835. OUTCM3:
  836.     LXI    D,SORCFCB    ;POINT AT FILE FCB FOR READING
  837.     MVI    C,READR        ;FUNCTION SET FOR RECORD READ
  838.     CALL    BDOS
  839.     ORA    A        ;CHECK IF READ WAS O.K.
  840.     JZ    OUTCM4        ;READ O.K. SO GO TO SEND OUT
  841.     JMP    NEXTPOS        ;EOF SO TO NEXT LIST NAME POSITION
  842. ;
  843. OUTCM4:
  844.     LXI    H,BUFR        ;POINT AT SECTOR JUST READ
  845.     MVI    B,080H        ;SET SECTOR CHARACTER COUNTER TO OUTPUT
  846. OUTCM5:
  847.     MOV    A,M        ;GET A CHARACTER
  848.     CPI    01AH        ;SEE IF LOGICAL END OF FILE
  849.     JZ    NEXTPOS        ;BACK TO LIST LOOP IF LOG EOF
  850.     MOV    E,A        ;POSITION CHARACTER FOR BDOS
  851.     PUSH    B
  852.     PUSH    H
  853.     LDA    OUTOP        ;GET DEVICE CODE FOR OUTPUT
  854.     MOV    C,A
  855.     CALL    BDOS        ;SEND THE CHARACTER
  856. ;
  857.     MVI    C,GETST        ;GET CONSOLE STATUS FUNCTION
  858.     CALL    BDOS        ;GO GET THE ABORT STATUS
  859.     POP    H
  860.     POP    B
  861. ;
  862.     ORA    A        ;IF CHAR THERE, THEN ABORT
  863.     JNZ    BACKUP         ;  TO SAME LIST POSITION
  864. ;
  865.     INX    H        ;INC BUFFER POINTER
  866.     DCR    B        ;ALL BYTES OF SECTOR SENT YET?
  867.     JNZ    OUTCM5        ;MORE TO DO
  868. ;
  869.     JMP    OUTCM3        ;GO GET THE NEXT SECTOR
  870. ;
  871. ;
  872. ;ROUTINE TO COPY A DISK FILE NAMED BY THE CURRENT LIST POSITON TO
  873. ;A DIFFERENT DISK DRIVE OF OPERATOR SELECTION.
  874. ;
  875. COPY:
  876.     LHLD    LISTPOS        ;MOVE NAME FROM LIST TO SOURCE FCB
  877.     LXI    D,12
  878.     CALL    SDEHL        ;POINT TO NAME POSITION
  879.     LXI    D,SORCFCB    ;PLACE TO MOVE THE NAME
  880.     MVI    B,12        ;AMOUNT TO MOVE
  881.     CALL    MOVBYT
  882. ;
  883.     MVI    B,4        ;FILL EX,S1,S2,RC WITH ZEROS
  884.     LXI    H,SORCFCB+12    ;SET POINTER TO SOURCE EXTENT FIELD
  885. COPY1:
  886.     MVI    M,0        ;PUT ZERO IN
  887.     INX    H
  888.     DCR    B
  889.     JNZ    COPY1
  890. ;
  891.     XRA    A        ;ZERO THE CURRENT RECORD FIELD
  892.     STA    SORCFCB+32
  893. ;
  894.     MVI    B,33        ;COPY SOURCE FCB TO DESTINATION FCB
  895.     LXI    H,SORCFCB    ;FROM COPY POINT
  896.     LXI    D,DESTFCB    ;TO COPY POINT
  897.     CALL    MOVBYT        ;MOVE IT ACROSS
  898. ;
  899.     LXI    D,SORCFCB    ;OPEN THE FILE FOR READING
  900.     MVI    C,OPEN        ;FILE OPEN FUNCTION CODE
  901.     CALL    BDOS
  902.     CPI    0FFH
  903.     JNZ    COPY2        ;SKIP ERROR MESSAGE IF O.K.
  904.     CALL    PRTMSG
  905.     DB    CR,LF,' ++ Source File Cannot Be Opened ++',0
  906.     JMP    NEXTPOS
  907. ;
  908. COPY2:
  909.     CALL    PRTMSG        ;PROMPT FOR DRIVE SELECT NAME
  910.     DB    '  Destination Drive ? ',0
  911.     MVI    C,KEYIN        ;GET SELECTION
  912.     CALL    BDOS
  913.     CALL    UPCASE        ;CONVERT TO UPPER CASE
  914.     SUI    'A'        ;ZERO BASE FOR RANGE CHECK
  915.     CPI    'P'-'A'+1
  916.     JNC    CMDERR        ;BACK TO COMMAND LOOP WITH "?"
  917. ;
  918.     INR    A        ;BASE DRIVE SELECT FOR 1=A:
  919.     STA    DESTFCB        ;SET INTO THE DESTINATION FCB
  920. ;
  921.     MOV    B,A        ;SEE IF HE PICKED SAME DISK AS CURRENT
  922.     LDA    SORCFCB        ;GET SOURCE DRIVE ID
  923.     CMP    B
  924.     JNZ    COPY2A        ;NO THEY ARE DIFFERENT?
  925.     CALL    PRTMSG
  926.     DB    CR,LF,' ++ Cannot Select Same Disk as Source ++',CR,LF,0
  927.     JMP    SAMEPOS        ;LET HIM TRY AGAIN
  928. ;
  929. COPY2A:
  930.     LXI    D,DESTFCB    ;SEARCH TO SEE IF THIS FILE EXISTED
  931.     MVI    C,SRCHF        ;SEARCH FIRST FUNCTION
  932.     CALL    BDOS
  933.     CPI    0FFH        ;RETURN CODE IF NOT FOUND
  934.     JZ    COPY3        ;GO TO MAKE FUNCTION FOR NEW FILE
  935. ;
  936.     CALL    PRTMSG        ;ASK IF TO REPLACE
  937.     DB    '  Replace ? ',0
  938.     MVI    C,KEYIN        ;GET HIS ANSWER
  939.     CALL    BDOS
  940.     CALL    UPCASE
  941.     CPI    'Y'        ;IF YES THEN DELETE IT AND COPY OVER
  942.     JNZ    NEXTPOS        ;IF COPY NOT WANTED THEN ON TO NEXT
  943. ;
  944.     LXI    D,DESTFCB    ;DELETE FILE THAT ALREADY EXISTS
  945.     MVI    C,DELETE    ;ERASE FILE FUNCTION CODE
  946.     CALL    BDOS
  947. ;
  948. COPY3:
  949.     LXI    D,DESTFCB    ;MAKE NEW FILE AND OPEN FOR WRITING
  950.     MVI    C,MAKE        ;MAKE FUNCTION CODE
  951.     CALL    BDOS        ;GO MAKE IT
  952.     CPI    0FFH        ;CHECK IF THE DIRECTORY WAS FULL
  953.     JNZ    COPY4
  954.     CALL    PRTMSG
  955.     DB    CR,LF,' ++ Destination Directory Full ++',0
  956.     JMP    NEXTPOS        ;BACK TO LIST PROCESSOR IF ERROR
  957. ;
  958. COPY4:
  959.     LXI    B,0        ;FIGURE OUT HOW MANY SECTORS
  960.     LHLD    BDOS+1        ;FIT INTO MEMORY BUFFER
  961.     DCX    H
  962.     XCHG            ;(DE) = MAX ADDRESS ALLOWABLE
  963.     LHLD    BUFSTART    ;START ADDRESS OF BUFFER
  964. COPY5:
  965.     INX    B        ;INCREASE SECTOR COUNT BY ONE
  966.     PUSH    D
  967.     LXI    D,080H        ;ONE SECTOR SIZE
  968.     DAD    D        ;BUFFER ADDRESS + SEC SIZE
  969.     POP    D
  970.     CALL    CDEHL        ;COMPARE VALUES TO SEE IF ALL DONE
  971.     JNC    COPY5        ;MORE WILL FIT?
  972. ;
  973.     DCX    B        ;SET MAX SECTOR COUNT LESS BY ONE
  974.     MOV    A,B        ;CHECK IF ANY MEMORY FOR COPY AT ALL
  975.     ORA    C
  976.     JNZ    COPY6        ;THERE IS MEMORY FOR BUFFER
  977.     CALL    PRTMSG
  978.     DB    CR,LF,' ++ No Memory Available for Copy Buffer ++',0
  979.     JMP    NEXTPOS
  980. ;
  981. COPY6:
  982.     MOV    L,C
  983.     MOV    H,B        ;PUT MAX SECTOR COUNT IN STORAGE
  984.     SHLD    BUFMAX
  985.     XRA    A        ;CLEAR EOF FLAG
  986.     STA    EOFLG
  987. ;
  988. COPY6A:
  989.     LXI    H,0        ;SET CURRENT BUFFER COUNTER TO ZERO
  990.     SHLD    BUFCNT
  991.     LHLD    BUFSTART    ;SET BUFFER START POINTER TO BEGIN
  992.     SHLD    BUFPNT
  993. ;
  994. ;
  995. ;FILE SOURCE READING LOOP TO READ ALL MEMORY FULL OR STOP ON EOF
  996. ;
  997. COPY7:
  998.     LHLD    BUFPNT        ;SET DMA ADDRESS TO BUFFER POINTER
  999.     XCHG
  1000.     MVI    C,STDMA
  1001.     CALL    BDOS
  1002. ;
  1003.     LXI    D,SORCFCB    ;POINT AT FILE FCB FOR READING
  1004.     MVI    C,READR        ;FUNCTION SET FOR RECORD READ
  1005.     CALL    BDOS
  1006.     ORA    A        ;CHECK IF READ WAS O.K. OF EOF
  1007.     JNZ    COPY8        ;END OF FILE SO SET EOF FLAG
  1008. ;
  1009.     LHLD    BUFPNT        ;SET BUFFER POINTER UP ONE SECTOR
  1010.     LXI    D,080H
  1011.     DAD    D
  1012.     SHLD    BUFPNT
  1013.     LHLD    BUFCNT        ;INCREASE BUFFER SECTOR COUNT
  1014.     INX    H
  1015.     SHLD    BUFCNT
  1016.     XCHG            ;CHECK TO SEE IF MEMORY IS FULL
  1017.     LHLD    BUFMAX        ;MAXIMUM SECTOR COUNT
  1018.     CALL    CDEHL        ;COMPARE
  1019.     JNZ    COPY7        ;IF NOT FULL GO GET NEXT SECTOR
  1020.     JMP    COPY9        ;GO HANDLE WRITE OPERATION
  1021. ;
  1022. ;
  1023. ;HERE IF READ OPERATION INDICATES THAT THE FILE IS AT ITS END ON READ
  1024. ;
  1025. COPY8:
  1026.     MVI    A,0FFH        ;SET EOF FLAG
  1027.     STA    EOFLG
  1028. ;
  1029. ;
  1030. ;WRITE OUTPUT FILE PROCESSING LOOP TO SEND MEMORY BUFFER TO
  1031. ;DESTINATION DISK FILE
  1032. ;
  1033. COPY9:
  1034.     LHLD    BUFSTART    ;SET BUFFER POINTER TO START
  1035.     SHLD    BUFPNT
  1036. ;
  1037. COPY10:
  1038.     LHLD    BUFCNT        ;SEE IF BUFFER IS EMPTY YET
  1039.     MOV    A,H
  1040.     ORA    L
  1041.     JZ    COPY11        ;BUFFER EMPTY SO CHECK EOF FLAG
  1042.     DCX    H        ;DEC BUFFER SECTOR COUNT FOR EACH WRITE
  1043.     SHLD    BUFCNT
  1044. ;
  1045.     LHLD    BUFPNT        ;SET UP DMA ADDRESS
  1046.     PUSH    H        ;SAVE FOR SIZE BUMP
  1047.     XCHG
  1048.     MVI    C,STDMA
  1049.     CALL    BDOS
  1050.     POP    H
  1051.     LXI    D,080H        ;INCREASE ADDRESS FOR SECTOR SIZE
  1052.     DAD    D
  1053.     SHLD    BUFPNT
  1054. ;
  1055.     LXI    D,DESTFCB    ;POINT TO OUTPUT FILE FCB
  1056.     MVI    C,WRITER    ;WRITE RECORD FUNCTION CODE
  1057.     CALL    BDOS        ;GO WRITE
  1058.     ORA    A           ;CHECK IF ANY ERROR-CAF
  1059.     JZ    COPY10        ;O.K. SO DO NEXT RECORD
  1060. ;
  1061.     CALL    PRTMSG        ;TELL OF DISK WRITE ERROR
  1062.     DB    CR,LF,' ++ Disk or Directory Full or error on Write ++',0 ;ts
  1063.     JMP    NEXTPOS        ;BACK TO LIST PROCESSING
  1064. ;
  1065. COPY11:
  1066.     LDA    EOFLG        ;BUFFER ALL WRITTEN SO GO CHECK EOF
  1067.     ORA    A
  1068.     JZ    COPY6A        ;GO TO READ NEXT BUFFER FULL
  1069. ;
  1070.     LXI    D,DESTFCB    ;POINT AT FCB FOR FILE CLOSE
  1071.     MVI    C,CLOSE        ;CLOSE FILE FUNCTION CODE
  1072.     CALL    BDOS
  1073.     CPI    0FFH        ;CHECK IF CLOSE ERROR
  1074.     JNZ    NEXTPOS
  1075.     CALL    PRTMSG
  1076.     DB    CR,LF,' ++ Destination Close Error ++',0
  1077.     JMP    NEXTPOS
  1078. ;
  1079. ;
  1080. ;ROUTINE TO INQUIRE ABOUT SELECTING OPERATION ON ANOTHER DRIVE
  1081. ;
  1082. LOG:
  1083.     CALL    PRTMSG        ;PROMPT FOR DRIVE SELECT NAME
  1084.     DB    '  New Drive ? ',0
  1085.     MVI    C,KEYIN        ;GET SELECTION
  1086.     CALL    BDOS
  1087.     CALL    UPCASE        ;CONVERT TO UPPER CASE
  1088.     CPI    CR        ;IF CARRIAGE RETURN SKIP RE-LOG
  1089.     JZ    NEXTPOS
  1090. ;
  1091.     SUI    'A'        ;ZERO BASE FOR RANGE CHECK
  1092.     CPI    'P'-'A'+1
  1093.     JNC    CMDERR        ;BACK TO COMMAND LOOP WITH "?"
  1094. ;
  1095.     INR    A        ;BASE DRIVE SELECT FOR 1=A:
  1096.     STA    FCB        ;SET INTO THE START DEFAULT FCB
  1097.     MVI    A,' '        ;SET DEFAULT FCB TO LOOK LIKE *.*
  1098.     STA    FCB+1
  1099.     STA    FCB+9
  1100.     JMP    RESTART        ;GO RESTART WITH MENU PRINT OVER
  1101. ;
  1102. ;
  1103. ;
  1104. ;***************************************************************************
  1105. ;
  1106. ;    UTILITY SUBROUTINES
  1107. ;
  1108. ;COMPARE DOUBLE REGISTERS (DE) TO (HL) SIMILAR TO CMP B INSTRUCTION AND SET
  1109. ;FLAGS ACCORDINGLY.
  1110. ;
  1111. CDEHL:
  1112.     MOV    A,D        ;SEE IF HIGH BYTES SET FLAGS
  1113.     CMP    H
  1114.     RNZ            ;RETURN IF NOT EQUAL
  1115.     MOV    A,E
  1116.     CMP    L        ;LOW BYTES SET THE FLAGS INSTEAD
  1117.     RET
  1118. ;
  1119. ;
  1120. ;SUBTRACT DOUBLE REGISTERS (DE) FROM (HL) LEAVING RESULT IN (HL)
  1121. ;
  1122. SDEHL:
  1123.     MOV    A,L        ;DO LOW BYTES FIRST
  1124.     SUB    E
  1125.     MOV    L,A        ;SET LOW BYTE OF RESULT BACK
  1126.     MOV    A,H        ;HIGH BYTES NOW
  1127.     SBB    D        ;SUBTRACT HIGH AND BORROW
  1128.     MOV    H,A        ;HIGH BYTE OF RESULT BCK TO (H)
  1129.     RET
  1130. ;
  1131. ;
  1132. ;MOVE SUBROUTINE  MOVE (B) BYTES FROM (HL) TO (DE)
  1133. ;
  1134. MOVBYT:
  1135.     MOV    A,M        ;GET (HL) REFERENCED SOURCE BYTE
  1136.     ANI    7FH        ;STRIP CP/M 2.x ATTRIBUTES
  1137.     STAX    D        ;PUT TO (DE) REFERENCED DESTINATION
  1138.     INX    H        ;FIX POINTERS FOR NEXT SEARCH
  1139.     INX    D
  1140.     DCR    B        ;DEC BYTE COUNT AND SEE IF DONE
  1141.     JNZ    MOVBYT
  1142.     RET
  1143. ;
  1144. ;
  1145. ;INLINE PRINT OF MESSAGE TILL A ZERO
  1146. ;
  1147. PRTMSG:
  1148.     XTHL            ;SAVE HL, GET MSG POINTER
  1149. ;
  1150. PRTMLP:
  1151.     MOV    A,M        ;GET CHARACTER
  1152.     ANI    07FH        ;STRIP USER TYPE BITS
  1153.     MOV    E,A
  1154.     INX    H        ;INCREMENT POINTER TO NEXT CHAR
  1155.                 ;..OR RETURN ADDRESS
  1156.     JZ    PMXIT        ;EXIT IF ZERO
  1157. ;
  1158.     PUSH    H        ;SAVE MESSAGE POINTER
  1159.     MVI    C,WRCON        ;CHARACTER OUTPUT FUNCTION CODE
  1160.     CALL    BDOS        ;OUTPUT IT
  1161.     POP    H
  1162.     JMP    PRTMLP        ;GO CHECK/DO NEXT CHAR
  1163. ;
  1164. PMXIT:
  1165.     XTHL            ;RESTORE HL, RET ADDR
  1166.     RET            ;RET PAST MSG
  1167. ;
  1168. ;
  1169. ;CONVERT CHARACTER IN (A) TO UPPER CASE
  1170. ;
  1171. UPCASE:
  1172.     ANI    07FH        ;STRIP UPPER BIT
  1173.     CPI    060H        ;IS CHAR ONE REQUIRING CONVERT
  1174.     RC            ;NO CONVERT NEEDED
  1175.     ANI    05FH        ;CONVERT
  1176.     RET
  1177. ;
  1178. ;
  1179. ;CHECK FOR LEGAL FILE NAME CHARACTER
  1180. ;
  1181. CHKLEGL:
  1182.     LDAX    D        ;GET CHARACTER FROM .(DE)
  1183.     INX    D        ;TO POINT AT NEXT CHARACTER
  1184.     CPI    ' '        ;IS IT LESS THAN SPACE
  1185.     RC            ;RETURN CARRY IF ERROR CHAR
  1186.     CPI    05FH        ;IF GREATER THAN UNDERSCORE ERROR
  1187.     JNC    CHKERR        ;CARRY SET EXIT
  1188.     CPI    '='
  1189.     JZ    CHKERR
  1190.     CPI    ':'
  1191.     JZ    CHKERR
  1192.     CPI    ';'
  1193.     JZ    CHKERR
  1194.     CPI    '<'
  1195.     JZ    CHKERR
  1196.     CPI    '>'
  1197.     JZ    CHKERR
  1198.     ORA    A        ;CLEAR CARRY FOR GOOD CHAR
  1199.     RET
  1200. ;
  1201. CHKERR:
  1202.     STC            ;ERROR EXIT
  1203.     RET
  1204. ;
  1205. ;
  1206. ;ROUTINE TO COMPARE TWO STRINGS LEFT TO RIGHT SIMILAR TO CMP B INSTRUCTION
  1207. ;
  1208. ;    (B)=STRING LENGTH
  1209. ;    (DE)=STRING A BASE POINTER
  1210. ;    (HL)=STRING B BASE POINTER
  1211. ;
  1212. CMPSTR:
  1213.     LDAX    D        ;GET AN A STRING CHARACTER
  1214.     CMP    M        ;CHECK AGAINST B STRING CHARACTER
  1215.     RNZ            ;NOT EQUAL SETS RETURN FLAGS
  1216.     DCR    B        ;DECREMENT COMPARE BYTE COUNT
  1217.     RZ            ;SET LIKE EQUAL IF ALL COMPARED EQUAL
  1218.     INX    H        ;BUMP COMPARE POINTERS
  1219.     INX    D
  1220.     JMP    CMPSTR        ;TO DO NEXT CHARACTER
  1221. ;
  1222. ;
  1223. ;ROUTINE TO INTERCHANGE TWO STRINGS FOR SORTING
  1224. ;
  1225. ;    (B)=STRING LENGTH
  1226. ;    (DE)=STRING A BASE POINTER
  1227. ;    (HL)=STRING B BASE POINTER
  1228. ;
  1229. SWAP:
  1230.     MOV    C,M        ;GET CHAR FROM ONE STRING
  1231.     LDAX    D        ;AND ONE FROM OTHER STRING
  1232.     MOV    M,A        ;SECOND INTO FIRST
  1233.     MOV    A,C        ;FIRST INTO SECOND
  1234.     STAX    D
  1235.     INX    H        ;BUMP SWAP POINTERS
  1236.     INX    D
  1237.     DCR    B        ;SEE IF ALL BYTES SWAPPED YET
  1238.     JNZ    SWAP
  1239.     RET
  1240. ;
  1241. ;
  1242. ;*************************************************************************
  1243. ;
  1244. ;
  1245. ;
  1246.     DS    080H        ;DEFINE STORAGE FOR AN EXECUTION STACK
  1247. STCKK:
  1248.     DS    2
  1249. ;
  1250. SORCFCB:
  1251.     DS    33        ;FCB FOR SOURCE FILE
  1252. ;
  1253. DESTFCB:
  1254.     DS    33        ;FCB FOR DESTINATION FILE IF COPY
  1255.                 ;AND NEW NAME IF RENAME FUNCTION
  1256. ;
  1257. MAXLEN    EQU    25        ;MAXIMUM BUFFER INPUT LENGTH
  1258. ;
  1259. CBUFF:
  1260.     DB    MAXLEN        ;COMMAND BUFFER LENGTH
  1261. CBUFFL:
  1262.     DB    0        ;CURRENT INPUT LENGTH
  1263. CSTRING:
  1264.     DS    MAXLEN+3    ;STORAGE FOR INPUT
  1265. ;
  1266. LISTPOS:
  1267.     DS    2        ;CURRENT LIST POSITION IN SCAN
  1268. ;
  1269. LISTI:
  1270.     DS    2        ;LIST SORT POINTER
  1271. ;
  1272. LISTJ:
  1273.     DS    2        ;ANOTHER LIST SORT POINTER
  1274. ;
  1275. LISTEND:
  1276.     DS    2        ;CURRENT LIST END POINTER
  1277. ;
  1278. BUFSTART:
  1279.     DS    2        ;START POINTER FOR COPY BUFFER
  1280. ;
  1281. BUFPNT:
  1282.     DS    2        ;CURRENT POINTER FOR COPY BUFFER
  1283. ;
  1284. BUFMAX:
  1285.     DS    2        ;MAXIMUM NUMBER OF BUFFER SECTORS
  1286. ;
  1287. BUFCNT:
  1288.     DS    2        ;NUMBER OF SECTORS CURRENTLY IN BUFFER
  1289. ;
  1290. OUTOP:
  1291.     DS    1        ;SIMPLE FILE OUTPUT DESTINATION FUNCTION
  1292.                 ;EQUAL TO BDOS FLAG
  1293. ;
  1294. EOFLG:
  1295.     DS    1        ;FILE COPY LOOP EOF FLAG
  1296. ;
  1297. LIST:
  1298.     DS    1        ;BASE OF FILE NAME LIST
  1299.  
  1300. ;
  1301. ;
  1302. ;
  1303.     END
  1304. ;
  1305. ;
  1306. ;+++...END OF FILE
  1307.