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 / HEATH / DIRF38HZ.LBR / DIRF38HZ.AZM / DIRF38HZ.ASM
Assembly Source File  |  2000-06-30  |  34KB  |  1,245 lines

  1. ;        DIRFILES: Version 3.8 (Heath video only)
  2. ;
  3. ; Note: this code is riddled with Heath-specific video equates, if
  4. ;
  5. ;            Joe Smith - Heath Users Group
  6. ;
  7. ;
  8. ;               Steve Sanders - Tampa Bay Kaypro UG
  9. ;               (813) 791-1454 or 791-1455  300/1200/2400
  10. ;
  11. ; Modification History
  12. ;
  13. ; 09/18/87  Made a Heath-only version from version 3.7
  14. ;    v3.8   for local use only - not for remotes.
  15. ;        Changed number of files to 256 for larger
  16. ;        directory disks, such as hard disk.
  17. ;
  18. ;
  19. ; 01/28/86  Made a Kaypro-only version to show all files, no restrictions,
  20. ;    v3.7   for local use only - not for remote systems. - S. Sanders
  21. ;
  22. ; 02/23/85  Corrected bug in MATCH routine that caused failure to
  23. ;    v3.6   compare if any flag is set.  Removed  embedded tabs in
  24. ;        space strings.  Thanks to Steve Sanders for secure mode
  25. ;        improvements.  Named Version 3.6 because of existence of
  26. ;        spurious versions that were created without coordination
  27. ;        between authors. - C. Horn
  28. ;
  29. ; 10/24/84  Modified to use C/R to continue instead of "any key"
  30. ;    v3.1   which caused a lot of problems on-line with 1200 baud
  31. ;        noise present (infinite loop).  Added a CTRL-C option
  32. ;        to abort listing if desired, entry of CTRL-C while
  33. ;        printing will abort to options menu.  -  Steve Sanders
  34. ;
  35. ; 09/04/84  Modified to write the data file back to disk only if it
  36. ;    v3.0   was edited while we were here.  -  C. Horn.
  37. ;
  38. ; A utility that maintains a data file on any default disk or user area
  39. ; containing directory file names for all current files.  The data file
  40. ; is called in and updated each time DIRFILES is run.  The data file
  41. ; contains a description of each listed file that is entered by the user
  42. ; via the EDIT function within DIRFILES.  When the program exits it writes
  43. ; the updated data file back to disk.  No disk space is needed in this
  44. ; process other than the space occupied by the data file when first created.
  45. ; When first called, if the data file DIRFILES.DAT does not exist, the
  46. ; program provides by menu the option to create it.  The maximum number of
  47. ; directory entries at the EQUate NUMFILES determines the size of the data
  48. ; file.  128 is the correct entry for a standard SSSD CP/M disk, and is
  49. ; probably appropriate for SSDD and DSSD disks.  This setting creates a
  50. ; 10K DIRFILES.DAT file.
  51. ;
  52. ; This program is a product of Horn Engineering Associates.  It is placed
  53. ; into the public domain for free use by anybody except that it may not
  54. ; be sold, either in itself or as any part of a collection of software,
  55. ; without the express permission of Horn Engineering Associates.  It is
  56. ; requested that any user retain our SIGNON logo.
  57. ;
  58. ; Copyright (c) 1985 by Charles E. Horn,PE
  59. ; for Horn Engineering Associates
  60. ;
  61. TRUE        EQU    0FFH
  62. FALSE        EQU    NOT TRUE
  63. ;
  64. SECURE        EQU    FALSE        ;TRUE, for RCP/M, uses WHEEL status
  65. NOSYS        EQU    FALSE        ;set TRUE to exclude SYS files
  66. WHEEL        EQU    003EH        ;address of the WHEEL byte
  67. ;
  68. ;    CP/M Equates
  69. ;
  70. BOOT        EQU    0        ;org zero CP/M
  71. BDOS        EQU    BOOT+5        ;bdos entry
  72. DEFDMA        EQU    80H        ;normal default DMA address
  73. TPA        EQU    BOOT+100H    ;ORG address
  74. CONIN        EQU    1        ;BDOS console input function
  75. CONOUT        EQU    2        ;console output function
  76. PBUF        EQU    9        ;print buffer function
  77. RDCON        EQU    10        ;read console buffer function
  78. CONSTAT     EQU    11        ;console status function
  79. RESDISK     EQU    13        ;reset disk system function
  80. SELDISK     EQU    14        ;select default disk function
  81. OPENF        EQU    15        ;open file function
  82. CLOSEF        EQU    16        ;close file function
  83. SRCHF        EQU    17        ;search for first dir file function
  84. SRCHN        EQU    18        ;search for next file function
  85. DELF        EQU    19        ;delete file function
  86. READF        EQU    20        ;read file function
  87. WRITEF        EQU    21        ;write file function
  88. MAKEF        EQU    22        ;make file function
  89. GETDISK     EQU    25        ;get default disk function
  90. SETDMA        EQU    26        ;set DMA address function
  91. SETATTR     EQU    30        ;set file attributes
  92. ;
  93. ;    Misc Equates
  94. ;
  95. BELL        EQU    07H        ;bell character
  96. BS        EQU    08H        ;backspace character
  97. LF        EQU    0AH        ;line feed
  98. CR        EQU    0DH        ;carriage return
  99. BLANK        EQU    20H        ;space character
  100. CLRSCR        EQU    69
  101. ESC        EQU    27
  102. CAD        EQU    59
  103. ROW        EQU    31
  104. COL        EQU    31
  105. ;
  106. ;    Program Equates
  107. ;
  108. NUMFILES    EQU    255        ;maximum number of directory entries
  109. DATLEN        EQU    NUMFILES * 80    ;size of DIRFILES.DAT data file
  110.                     ;(80 columns per directory entry)
  111. NUMRECORDS    EQU    DATLEN / 128    ;number of records in data file
  112. SCREEN        EQU    24        ;number of lines per screen
  113. COLUMNS     EQU    80        ;80 column screen
  114. ;
  115.     ORG    TPA            ;program runs here
  116. ;
  117. ;    Main program
  118. ;
  119. START:    JMP    START1            ;jump over fixed data
  120. DATFNAME:
  121.     DB    'DIRFILESDAT'        ;name of data file (here for easy patch
  122. ;       ---- >-----------< ----    ;filenames must be exactly this long
  123.                     ;..space fill - type must be last 3
  124. DIRFNAME:
  125.     DB    '???????????'        ;wild card directory name
  126. START1: LXI    H,0            ;find CP/M stack pointer
  127.     DAD    SP
  128.     LXI    SP,STACK        ;set up our local stack
  129.     PUSH    H            ;store CP/Ms SP on ours
  130. ;
  131.     CALL    CLR            ;clear screen
  132. ;
  133.     LXI    D,SIGNON        ;point to signon message
  134.     MVI    C,PBUF            ;and show it
  135.     CALL    BDOS
  136. ;
  137. ;    We will only work on the current default drive which by now we know
  138. ;    has a mounted disk which might not be logged on.  We reset the disk
  139. ;    system here.  If the disk is write protected we find out later.
  140. ;
  141.     MVI    C,GETDISK        ;get the default drive
  142.     CALL    BDOS
  143.     PUSH    PSW            ;save it
  144.     MVI    C,RESDISK        ;reset the disk system
  145.     CALL    BDOS
  146.     POP    PSW            ;recover the default drive
  147.     MOV    E,A            ;move to E
  148.     MVI    C,SELDISK        ;set default to original
  149.     CALL    BDOS
  150. ;
  151. ;    Now try to open the directory data file.  First we need to move
  152. ;    in the data file name - case it has been changed or patched.
  153. ;
  154.     LXI    B,11            ;11 char to move in
  155.     LXI    H,DATFNAME        ;point to data file name
  156.     LXI    D,FCB+1         ;point past the drive number
  157.     CALL    MOVE            ;move it in
  158. ;
  159.     LXI    D,FCB            ;point to file control block
  160.     MVI    C,OPENF         ;open the file
  161.     CALL    BDOS
  162.     INR    A            ;was 0FFH if error
  163.     JNZ    READIN            ;if no error, go read it in
  164. ;
  165. ;    If no data file - create it per menu
  166. ;
  167.     IF SECURE
  168.     LDA    WHEEL            ;get wheel byte
  169.     ORA    A            ;secure?
  170.     JZ    EXIT0            ;exit with no support message
  171.     ENDIF    ;SECURE
  172. ;
  173.     LXI    D,NFDMSG        ;file not found and query message
  174.     MVI    C,PBUF
  175.     CALL    BDOS            ;print it
  176.     MVI    C,CONIN         ;get keyboard response
  177.     CALL    BDOS
  178.     ANI    5FH            ;make response UC
  179.     CPI    'Y'            ;if not yes
  180.     JNZ    EXITA            ;abort program
  181. ;
  182. ;    We must create the data file.  Fill data buffer with blanks.
  183. ;
  184.     LXI    H,FILEBUF        ;point to data file buffer
  185.     LXI    B,DATLEN        ;length of data file
  186. FILLOOP:
  187.     MVI    M,BLANK         ;insert a space
  188.     INX    H            ;bump pointer
  189.     DCX    B            ;bump count down
  190.     MOV    A,C            ;get count LS
  191.     ORA    B            ;'z' set if done
  192.     JNZ    FILLOOP         ;loop til done
  193. ;
  194. ;    Create, write, and close the new data file
  195. ;
  196.     LXI    D,FCB            ;point to FCB
  197.     MVI    C,MAKEF         ;create the file in directory
  198.     CALL    BDOS
  199.     INR    A            ;was 0FFH if no directory space
  200.     JZ    EXITB
  201. ;
  202.     CALL    WRITEFILE
  203.     JC    EXITC            ;cy set if disk full
  204.     LXI    D,FCB            ;point to FCB
  205.     MVI    C,CLOSEF        ;close the file
  206.     CALL    BDOS
  207. ;
  208. ;    Clean up the FCB here to get ready to read in the data file
  209. ;
  210. READIN: CALL    ZFCB            ;zero the FCB
  211. ;
  212. ;    Move in the data file name
  213. ;
  214.     LXI    B,11            ;11 char to move
  215.     LXI    H,DATFNAME        ;point to the data file name
  216.     LXI    D,FCB+1         ;point past drive in FCB
  217.     CALL    MOVE            ;move it in
  218. ;
  219. ;    If not to show SYS files we set the file attribute
  220. ;
  221.     IF NOSYS
  222.     LXI    H,FCB+10        ;point to second type byte
  223.     MOV    A,M            ;get it
  224.     ORI    80H            ;set the high byte
  225.     MOV    M,A            ;put it back
  226.     ENDIF    ;NOSYS
  227. ;
  228. ;    At least - set the R/W attribute - case it has been set R/O
  229. ;
  230.     LXI    D,FCB            ;point to FCB
  231.     MVI    C,SETATTR        ;set attributes
  232.     CALL    BDOS
  233. ;
  234. ;    Open the data file
  235. ;
  236.     LXI    D,FCB
  237.     MVI    C,OPENF
  238.     CALL    BDOS            ;no error expected - we know it's there
  239. ;
  240. ;    Read it into memory and close it
  241. ;
  242.     CALL    READFILE        ;read it
  243.     LXI    D,FCB
  244.     MVI    C,CLOSEF        ;if it is ever to work with MP/M
  245.     CALL    BDOS
  246. ;
  247. ;    Here we set up the FCB to read the directory, read it, and one by
  248. ;    one either match an existing entry in the data file or enter the
  249. ;    new file if not present.
  250. ;
  251.     CALL    ZFCB            ;zero the FCB
  252.     LXI    B,11            ;11 char in file name
  253.     LXI    H,DIRFNAME        ;the wild card file name
  254.     LXI    D,FCB+1         ;point to FCB file name space
  255.     CALL    MOVE            ;move the file name in
  256. ;
  257.     LXI    D,DEFDMA        ;set the CP/M DMA address
  258.     MVI    C,SETDMA
  259.     CALL    BDOS
  260. ;
  261. ;    Now start the directory search.  We set the maximum number of files
  262. ;    we will enter into the data file buffer to prevent any attempt to
  263. ;    write past the buffer if there are more files in the directory than
  264. ;    we have designated as NUMFILES.
  265. ;
  266.     MVI    B,NUMFILES-1        ;the maximum number to the buffer
  267.     PUSH    B            ;save it
  268.     LXI    D,FCB            ;find first match
  269.     MVI    C,SRCHF
  270.     CALL    BDOS
  271.     LXI    H,DEFDMA        ;point to DMA buffer
  272.     CALL    FINDFN            ;find the file name in the DMA space
  273.     IF NOSYS
  274.     PUSH    H            ;save DMA filename pointer
  275.     LXI    D,10            ;index to SYS attribute byte
  276.     DAD    D            ;point to it
  277.     MOV    A,M            ;get it
  278.     ANI    80H            ;will be zero if not SYS
  279.     POP    H            ;restore pointer
  280.     JNZ    MOREFILES        ;skip it if SYS
  281.     ENDIF    ;NOSYS
  282. ;
  283.     INX    H            ;point past drive number
  284.     CALL    ADDOT            ;put name into FNBUF with dot
  285. ;
  286. ;    SEARCH looks for the file name in the data file.  Returns with HL
  287. ;    pointing to data file entry or CY set if not found.  If not found,
  288. ;    HL points to first available blank line.
  289. ;
  290.     CALL    SEARCH
  291.     CC    ADDNAME         ;add name to file if not found
  292.     MVI    M,0FFH            ;flag the entry good
  293.     POP    B            ;recover maximum files number
  294.     DCR    B            ;bump down - we wrote one
  295.     PUSH    B            ;resave it
  296. MOREFILES:
  297.     LXI    D,FCB            ;look for matches for all files
  298.     MVI    C,SRCHN         ;look for next
  299.     CALL    BDOS
  300.     INR    A            ;was 0FFH if no more files
  301.     JZ    PURGE            ;if done - go purge erased files
  302.     DCR    A            ;set directory code back to what is was
  303.     LXI    H,DEFDMA        ;point to DMA buffer
  304.     CALL    FINDFN            ;find the name in the DMA space
  305.     IF NOSYS
  306.     PUSH    H            ;save pointer
  307.     LXI    D,10            ;index to SYS byte
  308.     DAD    D            ;point to it
  309.     MOV    A,M            ;get it
  310.     ANI    80H            ;zero if not set
  311.     POP    H            ;restore pointer
  312.     JNZ    MOREFILES        ;skip it
  313.     ENDIF    ;NOSYS
  314. ;
  315.     INX    H            ;point past drive number in DMA
  316.     CALL    ADDOT            ;file name to FNBUF with dot
  317.     CALL    SEARCH
  318.     CC    ADDNAME         ;add name to file if not found there
  319.     MVI    M,0FFH            ;flag entry good
  320.     POP    B            ;recover maximum files count
  321.     DCR    B            ;bump down - we wrote one
  322.     PUSH    B            ;save max file count
  323.     JNZ    MOREFILES        ;find all directory entries
  324. ;
  325. ;    At this point all directory entries are matched.  Found files are
  326. ;    flagged 0FFH.  Erased files are still flagged 0.  Blank lines are
  327. ;    flagged blank.    We go through and blank all lines containing erased
  328. ;    files, then go through again and flag all current files 0 for next time
  329. ;
  330. PURGE:    POP    B            ;clear stack
  331.     LXI    H,FILEBUF        ;point to data file buffer
  332.     MVI    C,NUMFILES        ;maximum entry counter
  333. PURGE1: MOV    A,M            ;get an entry flag
  334.     ORA    A            ;flag 0 (erased)?
  335.     JNZ    PURGE2            ;if not
  336.     PUSH    H            ;save buffer pointer
  337.     MVI    B,COLUMNS        ;number of bytes per entry
  338. PURLOOP:
  339.     MVI    M,BLANK         ;enter a space
  340.     INX    H            ;bump pointer
  341.     DCR    B            ;bump column counter down
  342.     JNZ    PURLOOP         ;fill line with blanks
  343.     POP    H            ;recover buffer pointer
  344. PURGE2: LXI    D,COLUMNS        ;index to next entry
  345.     DAD    D            ;set pointer to next
  346.     DCR    C            ;bump down max files counter
  347.     JNZ    PURGE1            ;continue for all possible entries
  348. ;
  349. ;    Flag all current files zero
  350. ;
  351.     LXI    H,FILEBUF        ;point to data buffer
  352.     MVI    C,NUMFILES        ;max number of entries
  353. FLAGLOOP:
  354.     MOV    A,M            ;get entry flag
  355.     CPI    0FFH            ;good entry?
  356.     JNZ    NXTFLAG         ;if blank line space
  357.     XRA    A            ;else - get a zero
  358.     MOV    M,A            ;and flag entry good
  359. NXTFLAG:
  360.     LXI    D,COLUMNS        ;index to next entry
  361.     DAD    D
  362.     DCR    C            ;bump down remaining entries to do
  363.     JNZ    FLAGLOOP        ;fix all entries
  364. ;
  365. ;    We now have a clean updated buffer that is suitable for display.
  366. ;    First we will sort all entries aphabetically.  This sort
  367. ;    moves all entries to the beginning of the buffer, with all
  368. ;    blanked entries following.
  369. ;
  370.     CALL    SORT            ;sort it
  371. ;
  372. ;    The data file is now sorted and ready for display and edit.
  373. ;    We enter here with a clean stack and no passed parameters.  We
  374. ;    return here after editing.  The only exit from here is via the
  375. ;    display menu.
  376. ;
  377. DISPLAY:
  378.     CALL    CLR            ;clear screen
  379.     LXI    H,FILEBUF        ;point to data buffer
  380.     MVI    B,NUMFILES        ;max entry counter
  381.     MVI    C,SCREEN-1        ;no of display lines less one for menu
  382. ;
  383. ;    The main display loop
  384. ;
  385. DISPLAY1:
  386.     MOV    A,M            ;get status flag
  387.     ORA    A            ;zero if valid entry
  388.     JNZ    DISPLAY3        ;if not valid
  389.     XRA    A            ;entry is valid - flag at least 1 found
  390.     STA    NONEFLAG
  391.     PUSH    H            ;save registers
  392.     PUSH    B
  393.     MVI    A,CR            ;get cursor to left margin
  394.     CALL    PCHAR            ;print CR
  395.     POP    B            ;restore registers
  396.     POP    H
  397.     PUSH    H            ;resave registers
  398.     PUSH    B
  399.     MVI    C,15            ;length of file name entry
  400.     CALL    PSTRING         ;print the entry
  401.     MVI    C,COLUMNS-15        ;remainder of string space
  402.     CALL    MINSTRG         ;go print minimum text (skip blanks)
  403.     CALL    CRLF            ;set up for next
  404. ;
  405. ; added following routine to check console for CTRL-C abort request
  406. ;           - Steve Sanders 10/24/84
  407. ;
  408.     MVI    C,CONSTAT        ;any chr waiting at console?
  409.     CALL    BDOS            ;let's see
  410.     CPI    0            ;if none waiting
  411.     JZ    DISPL1B         ;then continue displaying
  412. ;
  413.     MVI    C,CONIN         ;else check console for
  414.     CALL    BDOS            ;char waiting at keyboard
  415.     CPI    'C'-40H         ;CTRL-C ?
  416.     JZ    DISPL1A         ;if yes, then abort to menu
  417.     JMP    DISPL1B         ;or jump over DISPL1A routine
  418. ;
  419. DISPL1A:
  420.     POP    B            ;restore registers
  421.     POP    H            ;      ditto
  422.     JMP    DISPLAY2        ;before going back to menu
  423. ;
  424. DISPL1B:
  425.     POP    B            ;restore registers
  426.     POP    H
  427.     DCR    C            ;screen full?
  428.     JNZ    DISPLAY3        ;continue if not
  429. DISPLAY2:
  430.     PUSH    H            ;save registers
  431.     PUSH    B
  432.     LXI    D,DISMENU        ;point to normal display menu
  433.     IF SECURE
  434.     LDA    WHEEL            ;get wheel byte
  435.     ORA    A            ;zero if secure
  436.     JNZ    DISPLAY6        ;if not secure
  437.     LXI    D,SECMENU        ;else change pointer to secure menu
  438.     ENDIF    ;SECURE
  439. ;
  440. DISPLAY6:
  441.     MVI    C,PBUF            ;print it
  442.     CALL    BDOS
  443.     MVI    C,CONIN         ;get the console reply
  444.     CALL    BDOS
  445.     POP    B            ;restore registers
  446.     POP    H
  447.     ANI    5FH            ;make assumed ascii UC
  448.     CPI    'Q'            ;quit?
  449.     JZ    DISPLAY4        ;check for secure?
  450.     CPI    'E'            ;edit?
  451.     JZ    DISPLAY5        ;check for secure?
  452. ;
  453. ; changed the following routine to wait for CR to continue instead
  454. ; of "any key".  Remote callers would be hung in an endless loop if
  455. ; extreme line noise was present.  - Steve Sanders 10/24/84
  456. ;
  457.     CPI    CR            ;C/R to continue
  458.     JZ    DISP6A            ;yes,then continue
  459.     JMP    DISPLAY2        ;not 'Q', 'E', or C/R, ask again...
  460. ;
  461. DISP6A:
  462.     MVI    C,SCREEN-1        ;reset screen line counter
  463.     PUSH    H            ;save pointer
  464.     PUSH    B            ;save counters
  465.     MVI    A,CR            ;to left of current line
  466.     CALL    PCHAR
  467.     MVI    A,BLANK         ;blank the menu
  468.     MVI    C,COLUMNS        ;number of blanks per line
  469.     CALL    PCHARS
  470.     POP    B            ;restore counters
  471.     POP    H            ;restore pointer
  472.     JMP    DISPLAY3        ;continue display
  473. ;
  474. DISPLAY4:                ;process Quit
  475.     IF SECURE
  476.     LDA    WHEEL            ;get wheel byte
  477.     ORA    A            ;zero is secure
  478.     JZ    EXIT            ;without rewriting the file
  479.     ENDIF    ;SECURE
  480.     JMP    WRITEBACK        ;not secure - write the file back
  481. ;
  482. DISPLAY5:                ;process Edit
  483.     IF SECURE
  484.     LDA    WHEEL            ;wheel byte
  485.     ORA    A            ;zero is secure
  486.     JZ    DISPLAY3        ;ignore edit - continue display
  487.     ENDIF    ;SECURE
  488.     JMP    EDIT            ;else not secure - go edit
  489. ;
  490. NONEFLAG:
  491.     DB    0FFH            ;default is files present
  492. ;
  493. ;    Pointer and end of buffer processor
  494. ;
  495. DISPLAY3:
  496.     LDA    CRLFLAG         ;are we at end of buffer?
  497.     ORA    A            ;not zero if so
  498.     JNZ    DISPLAY7        ;reset CRLFLAG and go to top of buffer
  499.     LXI    D,COLUMNS        ;index to next data entry
  500.     DAD    D            ;set the pointer in HL
  501.     DCR    B            ;end of buffer?
  502.     JNZ    DISPLAY1        ;display more if not
  503.     LDA    NONEFLAG        ;get files present flag
  504.     ORA    A            ;zero if present
  505.     JNZ    EXITD            ;if none to display
  506.     LXI    H,FILEBUF        ;else - reset pointer to top
  507.     MVI    B,NUMFILES        ;and reset entry counter
  508.     PUSH    H            ;save buffer pointer
  509.     PUSH    B            ;save counters
  510.     CALL    CRLF            ;put in a blank line
  511.     MVI    A,1            ;set the CRLFLAG
  512.     STA    CRLFLAG
  513.     POP    B            ;restore registers
  514.     POP    H
  515.     JMP    DISPLAY2        ;show the menu
  516. ;
  517. DISPLAY7:
  518.     XRA    A            ;reset the CRLFLAG
  519.     STA    CRLFLAG
  520.     JMP    DISPLAY1
  521. ;
  522. CRLFLAG:
  523.     DB    0            ;default not flagged
  524.  
  525. ;
  526. DISMENU:    ;full access menu
  527.        DB    CR,'     ',1bh,'p'
  528.        DB    ' [ Options: ',1bh,'p','<Q>',1bh,'q','uit, '
  529.        DB    1bh,'p','<E>',1bh,'q','dit, or ',1bh,'p'
  530.        DB    '<RETURN>',1bh,'q',' shows more ] '
  531.        DB    1bh,'y4',' ','$'
  532. ;
  533. SECMENU:    ;secure menu
  534.        DB    CR,'     [ Options:  <Q>=Quit, <C/R>=Continue,'
  535.     DB    ' or ^C aborts while printing ] $'
  536. ;
  537. ;    The file EDIT code
  538. ;
  539. ;    We first set a flag here to note that we have been here.  Flag
  540. ;    is checked at exit.  If there has been no edit, we do not write
  541. ;    the data file back to disk.
  542. ;
  543. EDIT:    MVI    A,1            ;set flag to 1
  544.     STA    EDITFLG
  545.     MVI    A,CR            ;move to left margin
  546.     CALL    PCHAR            ;..of current console line
  547.     MVI    A,BLANK         ;fill line with spaces
  548.     MVI    C,COLUMNS        ;number of spaces to print
  549.     CALL    PCHARS            ;print them
  550.     LXI    D,EDTMENU1        ;show the primary editor menu
  551.     MVI    C,PBUF
  552.     CALL    BDOS
  553. EDIT1:    LXI    D,EDTMENU2        ;show the secondary editor menu
  554.     MVI    C,PBUF
  555.     CALL    BDOS
  556. ;
  557. ;    Call for the file name to edit
  558. ;
  559.     CALL    SCIN$NE         ;read console buffer - no CRLF echo
  560.     LDA    CLEFT            ;get number of characters entered
  561.     ORA    A            ;zero if none entered
  562.     JZ    DISPLAY         ;so go back to main menu
  563. ;
  564. ;    This code gets the entered file name into FNBUF in a directory
  565. ;    format that can be matched to the data file name entry.  This code
  566. ;    is a kludge but it allows for entry of the file name in lower case
  567. ;    in any reasonable way.
  568. ;
  569.     CALL    MAKEUC            ;make the buffer alphas upper case
  570.     LXI    H,CLIN            ;point to console buffer text
  571.     LXI    D,FNBUF         ;point to the processed file name buf
  572.     MVI    B,8            ;8 char spaces for main filename
  573. GETENTRY:
  574.     MOV    A,M            ;get char from buf
  575.     ORA    A            ;end of entry?
  576.     JZ    FNBLANK         ;fill out name field with blanks
  577.     CPI    '.'            ;dot?
  578.     JZ    FNBLANK
  579.     STAX    D            ;else put char in FNBUF
  580.     INX    H            ;bump pointers
  581.     INX    D
  582.     DCR    B            ;more?
  583.     JZ    PUTDOT            ;if not
  584.     JMP    GETENTRY        ;else - loop
  585. ;
  586. FNBLANK:
  587.     MVI    A,BLANK         ;get a space
  588.     STAX    D            ;put in FNBUF
  589.     INX    D            ;bump pointer
  590.     DCR    B            ;downcount
  591.     JZ    PUTDOT            ;install the dot
  592.     JMP    FNBLANK         ;fill out til 8
  593. ;
  594. PUTDOT: MVI    A,'.'            ;get a dot
  595.     STAX    D            ;install it
  596.     INX    H            ;bump pointers
  597.     INX    D
  598.     MVI    B,3            ;3 char in file type field
  599. PUTDOT1:
  600.     MOV    A,M            ;get a type char
  601.     ORA    A            ;zero if past entry
  602.     JZ    TYPBLANK        ;fill field with blanks
  603.     CPI    '.'            ;dot?
  604.     JZ    TYPBLANK
  605.     STAX    D            ;good char - install it
  606.     INX    H            ;bump pointers
  607.     INX    D
  608.     DCR    B            ;downcount
  609.     JZ    FINDMAT         ;done - go find a match in data buffer
  610.     JMP    PUTDOT1         ;else - finish it
  611. ;
  612. TYPBLANK:
  613.     MVI    A,BLANK         ;fill unused type field with blanks
  614.     STAX    D
  615.     INX    D
  616.     DCR    B
  617.     JNZ    TYPBLANK
  618. ;
  619. ;    FNBUF now filled.  This code finds the file entry in the data buffer
  620. ;    and returns with HL point to the head of the entry line.  If CY
  621. ;    returned the search failed.
  622. ;
  623. FINDMAT:
  624.     CALL    SEARCH
  625.     JC    FNF            ;if file not found
  626.     PUSH    H            ;save line pointer
  627.     MVI    C,COLUMNS
  628.     CALL    PSTRING         ;show the line on the console
  629.     MVI    A,BS            ;backspace to head of text
  630.     MVI    C,COLUMNS-15        ;number to do
  631.     CALL    PCHARS            ;do it
  632.     POP    H            ;restore line pointer
  633.     LXI    D,15            ;index to start of text
  634.     DAD    D            ;set text pointer in HL
  635.     PUSH    H            ;save it
  636. ;
  637. ;    We are now ready for editing the text.    Existing text will be
  638. ;    overwritten.  Trailing garbage will not be retained.
  639. ;
  640.     CALL    SCIN$NE         ;read the console buffer
  641.     POP    D            ;the text pointer
  642.     LDA    CLEFT            ;get number of char entered
  643.     ORA    A            ;zero if none entered
  644.     JZ    DISPLAY         ;back to main menu
  645.     LXI    H,CLIN            ;point to buffer text
  646.     MVI    B,COLUMNS-15        ;we will accept only this many char
  647. BUFLOOP:
  648.     MOV    A,M            ;get char from con buffer
  649.     ORA    A            ;zero if at end
  650.     JZ    FILLOUT         ;go fill out the line with blanks
  651.     STAX    D            ;else enter the character
  652.     INX    H            ;bump pointers
  653.     INX    D
  654.     DCR    B            ;countdown
  655.     JNZ    BUFLOOP         ;if not done
  656.     JMP    EDIT1            ;max characters in text line
  657. ;
  658. FILLOUT:
  659.     MVI    A,BLANK         ;get a space
  660.     STAX    D            ;put in text line
  661.     INX    D            ;move to next
  662.     DCR    B            ;countdown
  663.     JNZ    FILLOUT
  664.     JMP    EDIT1            ;back to top of EDIT
  665. ;
  666. FNF:    LXI    D,FNFMSG        ;file not found prompt
  667.     MVI    C,PBUF
  668.     CALL    BDOS
  669.     JMP    EDIT            ;back to top of editor
  670. ;
  671. FNFMSG: DB    CR,LF,'File not found, check your spelling.',7,CR,LF,'$'
  672. ;
  673. EDTMENU1:
  674.     DB    CR,LF,'Just a RETURN while in EDIT will go to the main '
  675.     DB    'menu with no changes...',CR,LF,'$'
  676. EDTMENU2:
  677.     DB    CR,1bh,'p',' File to ',1bh,'q',' edit ',1bh,'p'
  678.     DB    ' (RETURN alone exits): ',1bh,'q',' ',17h,'$'
  679. ;
  680. ;    This is where we write the data file back to disk before we exit.
  681. ;    Here we will set the existing data file to R/W just be be safe,
  682. ;    erase it, recreate it, open it, write it, and close it.  This way,
  683. ;    we do not need more disk space than we already use.
  684. ;
  685. WRITEBACK:
  686.     LDA    EDITFLG         ;did we edit while here?
  687.     ORA    A            ;zero if we did not
  688.     JZ    RESDMA            ;..so don't write a new data file
  689.     CALL    ZFCB            ;clean up the FCB
  690.     LXI    B,11            ;11 characters in file name
  691.     LXI    H,DATFNAME        ;point to data file name
  692.     LXI    D,FCB+1         ;place to put it
  693.     CALL    MOVE            ;move it in
  694. ;
  695. ;    Erase the old data file
  696. ;
  697.     LXI    D,FCB
  698.     MVI    C,DELF            ;delete file
  699.     CALL    BDOS
  700. ;
  701. ;    Create a new one
  702. ;
  703.     LXI    D,FCB
  704.     MVI    C,MAKEF
  705.     CALL    BDOS
  706. ;
  707. ;    Open it
  708. ;
  709.     LXI    D,FCB
  710.     MVI    C,OPENF
  711.     CALL    BDOS
  712. ;
  713. ;    Write it
  714. ;
  715.     CALL    WRITEFILE
  716. ;
  717. ;    Close it
  718. ;
  719.     LXI    D,FCB
  720.     MVI    C,CLOSEF
  721.     CALL    BDOS
  722. ;
  723.     IF NOSYS        ;set it to SYS
  724.     LXI    H,FCB+10        ;point to SYS attribute byte
  725.     MOV    A,M            ;get it
  726.     ORI    80H            ;set the high bit
  727.     MOV    M,A            ;put it back
  728.     LXI    D,FCB
  729.     MVI    C,SETATTR        ;set it to SYS
  730.     CALL    BDOS
  731.     ENDIF    ;NOSYS
  732. ;
  733. ;    Reset CP/M DMA
  734. ;
  735. RESDMA: LXI    D,DEFDMA
  736.     MVI    C,SETDMA
  737.     CALL    BDOS
  738. ;
  739. ;    All done
  740. ;
  741.     JMP    EXIT
  742. ;
  743. ;***********************
  744. ;*** EXIT PROCESSORS ***
  745. ;***********************
  746. ;
  747. EXIT0:    LXI    D,NSPMSG        ;the no support message
  748.     MVI    C,PBUF            ;print it
  749.     CALL    BDOS
  750.     JMP    EXIT
  751. ;
  752. EXITA:    LXI    D,ABTMSG        ;abort message
  753.     MVI    C,PBUF            ;print it
  754.     CALL    BDOS
  755.     JMP    EXIT            ;and quit
  756. ;
  757. EXITB:    LXI    D,NDSMSG        ;no disk space message
  758.     MVI    C,PBUF            ;print it
  759.     CALL    BDOS
  760.     JMP    EXITA            ;and do abort report
  761. ;
  762. EXITC:    LXI    D,FULMSG        ;disk full message
  763.     MVI    C,PBUF            ;print it
  764.     CALL    BDOS
  765.     JMP    EXITA            ;and report abort
  766. ;
  767. EXITD:    LXI    D,NONMSG        ;no files message
  768.     MVI    C,PBUF            ;print it
  769.     CALL    BDOS            ;fall through to EXIT
  770. ;
  771. EXIT:    LXI    D,CLS
  772.     MVI    C,PBUF
  773.     CALL    BDOS
  774.     POP    H            ;recover CP/M SP from stack
  775.     SPHL                ;set it
  776.     RET                ;and exit quietly to CP/M
  777. ;
  778. ;************************
  779. ;*** CONSOLE MESSAGES ***
  780. ;************************
  781. ;
  782. SIGNON: DB    CR,LF,1bh,'p'
  783.     DB    ' DIRFiles v3.8hz  (c)1985 Horn Engineering Associates '
  784.     DB    1bh,'q',CR,LF,LF
  785.     DB    ' Heath screen and video by Joe Smith  09/18/87) '
  786.     DB    CR,LF,LF,LF,'>> Loading data file...','$'
  787. ;
  788. NFDMSG: DB    CR,'DIRFILES.DAT not found... Create new file? '
  789.     DB    1bh,'x4','<Y/N> ',1bh,'y4',7,'$'
  790. ;
  791. ABTMSG: DB    CR,LF,LF,'DIRFILES Aborted...',7,'$'
  792. ;
  793. NDSMSG: DB    CR,LF,LF,'No Disk Space...',7,'$'
  794. ;
  795. FULMSG: DB    CR,LF,LF,'Disk Full...',7,'$'
  796. ;
  797. NONMSG: DB    CR,LF,LF,'++ NO FILES ++',7,'$'
  798. ;
  799. NSPMSG: DB    CR,LF,LF,'DIRFILES not supported in this area...',7,'$'
  800. ;
  801. ;**************************************
  802. ;*** THE PRIVATE FILE CONTROL BLOCK ***
  803. ;**************************************
  804. ;
  805. FCB:
  806. FCB$DISK:    DB    0        ;preset default drive
  807. FCB$NAME:    DB    'DIRFILES'    ;preset default data file name
  808. FCB$TYP     DB    'DAT'        ;file type
  809. FCB$EXTENT:    DB    0        ;preset extent
  810. FCB$RESV:    DB    0,0        ;reserved by CP/M
  811. FCB$RECUSED:    DB    0        ;records used
  812. FCB$ABUSED:    DB    0,0,0,0,0,0,0,0 ;assigned blocks
  813.         DB    0,0,0,0,0,0,0,0
  814. FCB$SEQREC:    DB    0        ;sequential record number
  815. FCB$RANREC:    DW    0        ;random record number
  816. FCB$RANRECO:    DB    0        ;record overflow
  817. ;
  818. ;*******************
  819. ;*** SUBROUTINES ***
  820. ;*******************
  821. ;
  822. ;    WRITEFILE - Writes the records at FILEBUF to default disk
  823. ;
  824. WRITEFILE:
  825.     MVI    C,NUMRECORDS        ;number of records to write
  826.     LXI    D,FILEBUF        ;set DMA to data file buffer
  827. WRLOOP: PUSH    B            ;save number of records
  828.     PUSH    D            ;save DMA pointer
  829.     MVI    C,SETDMA        ;set the DMA address
  830.     CALL    BDOS
  831.     LXI    D,FCB            ;point to the FCB
  832.     MVI    C,WRITEF        ;write a record
  833.     CALL    BDOS
  834.     POP    D            ;clear stack for possible error
  835.     POP    B
  836.     ORA    A            ;zero if no error
  837.     JNZ    RETERR            ;if error set cy and return
  838.     LXI    H,128            ;add 128 to DMA pointer
  839.     DAD    D            ;original pointer in DE
  840.     XCHG                ;new pointer to DE
  841.     DCR    C            ;bump down record count
  842.     JNZ    WRLOOP            ;do more if not done
  843.     XRA    A            ;clear possible cy flag
  844.     RET                ;with no error
  845. RETERR: STC                ;set cy for error
  846.     RET                ;with error flag set
  847. ;
  848. ;    READFILE - Read the file specified by the FCB into FILEBUF
  849. ;
  850. READFILE:
  851.     LXI    D,FILEBUF        ;point to file buffer
  852. RDLOOP: PUSH    D            ;save DMA pointer
  853.     MVI    C,SETDMA        ;set the DMA
  854.     CALL    BDOS
  855.     LXI    D,FCB            ;point to FCB
  856.     MVI    C,READF         ;read a record
  857.     CALL    BDOS
  858.     POP    D            ;recover DMA pointer
  859.     ORA    A            ;non-zero is EOF
  860.     RNZ                ;if done
  861.     LXI    H,128            ;index DMA to next record space
  862.     DAD    D
  863.     XCHG                ;pointer to DE
  864.     JMP    RDLOOP            ;loop til done
  865. ;
  866. ;    ZFCB - Zero the 36 bytes in the designated FCB
  867. ;
  868. ZFCB:    MVI    C,36
  869.     LXI    H,FCB            ;point to FCB
  870. ZLOOP:    MVI    M,0            ;enter a zero
  871.     INX    H            ;bump pointer
  872.     DCR    C            ;bump down counter
  873.     JNZ    ZLOOP            ;loop for more
  874.     RET
  875. ;
  876. ;    ADDOT - Moves the file name in the DMA area to FNBUF.  Adds the
  877. ;    dot before file type on the way.
  878. ;
  879. ADDOT:    MVI    C,8            ;8 char in filename
  880.     LXI    D,FNBUF         ;point to name buffer
  881. ADDOT1: MOV    A,M            ;get a character
  882.     ani    7fh            ;strip hi bits
  883.     STAX    D            ;put into buffer
  884.     INX    H            ;bump pointer
  885.     INX    D            ;bump pointer
  886.     DCR    C            ;bump down counter
  887.     JNZ    ADDOT1            ;move all 8
  888.     MVI    A,'.'            ;get a dot
  889.     STAX    D            ;put into buffer
  890.     INX    D            ;bump buffer pointer
  891.     MVI    C,3            ;3 char in file type
  892. ADDOT2: MOV    A,M            ;get type char
  893.     ani    7fh
  894.     STAX    D            ;to buffer
  895.     INX    H
  896.     INX    D
  897.     DCR    C
  898.     JNZ    ADDOT2
  899.     RET
  900. ;
  901. FNBUF:    DS    12            ;the 12 char name buffer
  902. ;
  903. ;    SEARCH - Searches for a match between directory file name in FNBUF
  904. ;    and entries in the data file.
  905. ;    If found:    Returns with HL pointing to data file entry line.
  906. ;    If not found:    Returns with HL pointing to the first available
  907. ;            blank line. CY flag is set.
  908. ;
  909. SEARCH: LXI    H,FILEBUF        ;point to data file buffer
  910.     MVI    C,NUMFILES        ;max number of tries
  911. SRCHLOOP:
  912.     PUSH    H            ;save buffer pointer
  913.     PUSH    B            ;save try counter
  914.     INX    H            ;point past status flag
  915.     LXI    D,FNBUF         ;point to file name buffer
  916.     CALL    MATCH            ;look for match - CY set if none
  917.     POP    B            ;recover count
  918.     POP    H            ;recover pointer
  919.     RNC                ;if no CY we found match
  920.     LXI    D,COLUMNS        ;index to next data line + 1
  921.     DAD    D            ;set it
  922.     DCR    C            ;bump down try counter
  923.     JNZ    SRCHLOOP        ;if not done
  924. ;
  925. ;    No match found - find first available blank line - RET to caller
  926. ;
  927.     LXI    H,FILEBUF        ;buffer pointer
  928. BLNKLOOP:
  929.     MOV    A,M            ;get flag byte
  930.     CPI    BLANK            ;is it a space?
  931.     JZ    NOTFND            ;return with CY set
  932.     LXI    D,COLUMNS        ;index to next flag
  933.     DAD    D            ;set it
  934.     JMP    BLNKLOOP        ;we'll find one somewhere
  935. NOTFND: STC
  936.     RET
  937. ;
  938. ;    MATCH - Checks for 12 char match between (HL) and (DE).  Returns
  939. ;        with CY set if no match.
  940. ;
  941. MATCH:
  942.     MVI    C,12            ;12 char to check
  943. MATLOOP:
  944.     LDAX    D            ;get char from (DE)
  945.     ANI    7FH            ;strip possible flag (v3.2)
  946.     MOV    B,A            ;char to B
  947.     MOV    A,M            ;(HL) to A
  948.     ANI    7FH            ;strip possible flag (v3.2)
  949.     CMP    B            ;compare chars
  950.     JNZ    NOMATCH         ;any failure will cause exit with CY
  951.     INX    H
  952.     INX    D
  953.     DCR    C
  954.     JNZ    MATLOOP         ;go for all 12
  955.     XRA    A            ;reset CY flag (if set)
  956.     RET                ;got a match
  957. NOMATCH:
  958.     STC                ;set no match flag
  959.     RET
  960. ;
  961. ;    ADDNAME - Entry with HL pointing to head of a blank line.  Adds
  962. ;          the file name in FNBUF to the data buffer, adds a trailing
  963. ;          colon, and returns with HL pointing to head of line.
  964. ;
  965. ADDNAME:
  966.     PUSH    H            ;save line pointer
  967.     INX    H            ;point past status flag
  968.     XCHG                ;put pointer in DE
  969.     LXI    B,12            ;12 char to move
  970.     LXI    H,FNBUF         ;point to new file name
  971.     CALL    MOVE            ;move it in
  972.     MVI    A,':'            ;get a colon
  973.     STAX    D            ;add at end of filename
  974.     POP    H            ;restore line pointer
  975.     RET
  976. ;
  977. ;    FINDFN - Locates directory file name in DMA after directory
  978. ;    search.  Returns pointer in HL.  Entry with directory code in A.
  979. ;
  980. FINDFN: ADD    A        ;*2
  981.     ADD    A        ;*4
  982.     ADD    A        ;*8
  983.     ADD    A        ;*16
  984.     ADD    A        ;*32
  985.     MOV    E,A        ;offset to DE
  986.     MVI    D,0
  987.     DAD    D        ;add to HL
  988.     RET
  989. ;
  990. ;    MOVE - Moves the number of characters in BC from (HL) to (DE)
  991. ;
  992. MOVE:    MOV    A,M        ;get char from (HL)
  993.     STAX    D        ;put in (DE)
  994.     INX    H
  995.     INX    D
  996.     DCX    B
  997.     MOV    A,C        ;get LS count byte
  998.     ORA    B        ;both B & C zero?
  999.     JNZ    MOVE        ;loop til done
  1000.     RET
  1001. ;
  1002. ;    PSTRING - Prints string pointed to by HL.
  1003. ;    Number of characters to print in C
  1004. ;
  1005. PSTRING:
  1006.     PUSH    H        ;save string pointer
  1007.     PUSH    B        ;save count
  1008.     MOV    E,M        ;get a character
  1009.     MVI    C,CONOUT    ;print it
  1010.     CALL    BDOS
  1011.     POP    B        ;restore count
  1012.     POP    H        ;restore pointer
  1013.     INX    H        ;bump it
  1014.     DCR    C        ;done?
  1015.     JNZ    PSTRING     ;if not
  1016.     RET
  1017. ;
  1018. ;    MINSTRG - Types a string until either 3 blanks in a row or
  1019. ;    the maximum number of characters is reached.
  1020. ;    HL = string pointer
  1021. ;    C = max number of characters in string
  1022. ;
  1023. MINSTRG:
  1024.     MVI    E,3        ;set blank counter
  1025. MINSTRG1:
  1026.     MOV    A,M        ;get a character
  1027.     CPI    BLANK        ;space?
  1028.     JNZ    MINSTRG2    ;no space
  1029.     DCR    E        ;bump down counter
  1030.     RZ            ;exit if 3 spaces in row
  1031. ;
  1032. MINSTRG2:
  1033.     PUSH    H        ;save registers
  1034.     PUSH    D
  1035.     PUSH    B
  1036.     PUSH    PSW
  1037.     MOV    E,A        ;char to E
  1038.     ani    7fh
  1039.     MVI    C,CONOUT    ;out to console
  1040.     CALL    BDOS
  1041.     POP    PSW
  1042.     POP    B        ;restore registers
  1043.     POP    D
  1044.     POP    H
  1045.     INX    H        ;bump pointer
  1046.     DCR    C        ;downcount characters
  1047.     RZ            ;if maximum
  1048.     CPI    BLANK        ;was it a blank?
  1049.     JZ    MINSTRG1    ;yes - don't reset blank counter
  1050.     JMP    MINSTRG     ;else - loop back to top
  1051. ;
  1052. ;
  1053. ;    CLR - Clear local screen
  1054. ;
  1055. CLR:    LXI    D,CLS
  1056.     MVI    C,PBUF
  1057.     CALL    BDOS
  1058.     RET
  1059. ;
  1060. CLS    DB    ESC,CLRSCR,'$'
  1061. ;
  1062. ;
  1063. ;    CRLF - Puts a CR and LF out to console
  1064. ;
  1065. CRLF:    MVI    E,CR
  1066.     MVI    C,CONOUT
  1067.     CALL    BDOS
  1068.     MVI    E,LF
  1069.     MVI    C,CONOUT
  1070.     CALL    BDOS
  1071.     RET
  1072. ;
  1073. ;    PCHAR - Prints the character in A
  1074. ;
  1075. PCHAR:    MOV    E,A
  1076.     ani    7fh        ;strip hi bits
  1077.     MVI    C,CONOUT
  1078.     CALL    BDOS
  1079.     RET
  1080. ;
  1081. ;    PCHARS - Prints the character in A the number of times in C
  1082. ;
  1083. PCHARS: PUSH    PSW            ;save character
  1084.     PUSH    B            ;save count
  1085.     MOV    E,A            ;char to E
  1086.     ani    7fh            ;strip hi bits
  1087.     MVI    C,CONOUT        ;print one
  1088.     CALL    BDOS
  1089.     POP    B            ;restore count
  1090.     POP    PSW            ;restore character
  1091.     DCR    C            ;bump down count
  1092.     JNZ    PCHARS            ;do some more
  1093.     RET
  1094. ;
  1095. ;    MAKEUC - Makes the alpha characters in the console buffer upper case
  1096. ;
  1097. MAKEUC: LXI    H,CLIN            ;point to the buffer
  1098. MAKEUC1:
  1099.     MOV    A,M            ;get a char
  1100.     ORA    A            ;zero if past end
  1101.     RZ
  1102.     CPI    'A'            ;< 'A'?
  1103.     JC    MAKEUC2         ;if not alpha
  1104.     CPI    'z'+1            ;> 'z'?
  1105.     JNC    MAKEUC2         ;if not alpha
  1106.     ANI    5FH            ;is alpha - make UC
  1107.     MOV    M,A            ;and put it back
  1108.     INX    H            ;point to next
  1109.     JMP    MAKEUC1         ;and loop
  1110. ;
  1111. MAKEUC2:
  1112.     INX    H            ;not alpha - skip it
  1113.     JMP    MAKEUC1
  1114. ;
  1115. ;    SCIN$NE - Reads the console buffer without a CRLF echo to console
  1116. ;
  1117. SCIN$NE:
  1118.     LXI    H,CLIN            ;point to buffer string space
  1119.     LDA    CBUF            ;get buffer length
  1120.     MOV    B,A            ;put into B
  1121.     XRA    A            ;get a zero
  1122. SCIN$NE1:
  1123.     MOV    M,A            ;move in a zero
  1124.     DCR    B            ;countdown
  1125.     INX    H            ;bump pointer
  1126.     JNZ    SCIN$NE1        ;fill whole buffer with zeros
  1127. ;
  1128.     LXI    D,CBUF            ;point to buffer
  1129.     MVI    C,RDCON         ;read console function
  1130.     CALL    BDOS
  1131.     RET
  1132. ;
  1133. ;    The console buffer
  1134. ;
  1135. CBUF:    DB    CLEN            ;buffer length
  1136. CLEFT:    DB    0            ;number of char in buffer
  1137. CLIN:    DS    128            ;number of buffer spaces
  1138. CLEN:    EQU    $-CLIN            ;buffer length
  1139. ;
  1140. ;    SORT - Main sort routine - sorts directory entries alphabetically
  1141. ;           Records handled in pairs.
  1142. ;           String1 = first position pointer
  1143. ;           String2 = second position pointer
  1144. ;           Entry: none
  1145. ;           Exit: entries sorted
  1146. ;
  1147. SORT:    LXI    H,FILEBUF        ;point to data buffer first entry
  1148.     LXI    B,NUMFILES-1        ;max number of entry pairs
  1149. SORT1:    PUSH    B            ;save counter
  1150.     PUSH    H            ;save string1
  1151.     LXI    D,COLUMNS        ;offset to string2
  1152.     DAD    D            ;string2 to HL
  1153.     XCHG                ;string2 to DE
  1154.     POP    H            ;string1 to HL
  1155.     PUSH    H            ;save string1
  1156.     PUSH    D            ;save string2
  1157.     MVI    C,13            ;length of search string
  1158.     CALL    COMP            ;CY set if (string2) < (string1)
  1159.     POP    D            ;restore string2
  1160.     POP    H            ;restore string1
  1161.     PUSH    D            ;resave string2
  1162.     CC    SWAP            ;swap string if CY
  1163.     POP    H            ;new string1 pointer
  1164.     POP    B            ;get counter
  1165.     DCX    B            ;bump it down
  1166.     MOV    A,C
  1167.     ORA    B            ;zero if at bottom
  1168.     JZ    BOTTOM
  1169.     JMP    SORT1            ;go do next pair
  1170. ;
  1171. BOTTOM: LDA    SWAPFLG         ;is 1 if anything was swapped
  1172.     DCR    A
  1173.     STA    SWAPFLG         ;assume was 1 - reset to zero
  1174.     JZ    SORT            ;was 1? - sort entire buffer again
  1175.     RET                ;was 0 - sort done
  1176. ;
  1177. ;    SWAP - Swaps record string pair.
  1178. ;           Entry: HL points to string1
  1179. ;              DE points to string2
  1180. ;           Process:
  1181. ;           (1) buffer <--- string2
  1182. ;           (2) string2 <--- string1
  1183. ;           (3) string1 <--- buffer
  1184. ;
  1185. SWAP:    PUSH    H            ;save string1 ptr
  1186.     PUSH    D            ;save string2 ptr
  1187.     XCHG                ;string2 to HL
  1188.     LXI    D,SWAPBUF        ;point to buffer
  1189.     LXI    B,COLUMNS        ;size of record
  1190.     CALL    MOVE            ;move string2 to buffer
  1191.     POP    D            ;restore string2
  1192.     POP    H            ;restore string1
  1193.     PUSH    H            ;save string1
  1194.     LXI    B,COLUMNS        ;size of record
  1195.     CALL    MOVE            ;move string1 to string2 position
  1196.     POP    D            ;string1 to DE
  1197.     LXI    H,SWAPBUF        ;point HL to buffer
  1198.     LXI    B,COLUMNS        ;size of record
  1199.     CALL    MOVE            ;buffer to string1 position
  1200.     MVI    A,1            ;flag that a swap was done
  1201.     STA    SWAPFLG
  1202.     RET
  1203. ;
  1204. SWAPFLG:
  1205.     DB    0            ;default no swap
  1206. ;
  1207. ;    COMP - Compares two strings.
  1208. ;           Entry: HL points to string1
  1209. ;              DE points to string2
  1210. ;              C = maximum length of search
  1211. ;           Exit: Z set if strings match
  1212. ;             CY set if string2 < string1 (flags swap)
  1213. ;             No CY if (1) string1 < string2
  1214. ;               or (2) string1 = string2 (all blanks - no swap)
  1215. ;
  1216. COMP:    LDAX    D            ;get byte from string2
  1217.     CMP    M            ;CY if string2 byte < string1 byte
  1218.     RNZ                ;if no match
  1219.     INX    H            ;bump pointers
  1220.     INX    D
  1221.     DCR    C            ;downcount
  1222.     JNZ    COMP            ;check next
  1223.     RET                ;strings match - no CY
  1224. ;
  1225. EDITFLG:
  1226.     DB    0            ;default edit never used
  1227. ;
  1228. ;************************
  1229. ;*** UNITIALIZED AREA ***
  1230. ;************************
  1231. ;
  1232. SWAPBUF:
  1233.     DS    COLUMNS         ;string swap buffer
  1234.     DS    64            ;our private stack area
  1235. STACK:    EQU    $
  1236. ;
  1237. FILEBUF:
  1238.     DS    DATLEN            ;the data file buffer
  1239. ;
  1240.     END
  1241. L    BDOS
  1242.     RET
  1243. ;
  1244. ;    PCHARS - Prints the character in A the number of times in C
  1245. ;