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 / KAYPRO / DIRF37KP.LBR / DIRF37KP.AQM / DIRF37.ASM
Assembly Source File  |  2000-06-30  |  34KB  |  1,225 lines

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