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 / ZCPR2 / MKDIR.MAC < prev    next >
Text File  |  2000-06-30  |  21KB  |  1,050 lines

  1. ;
  2. ;  PROGRAM:  MKDIR
  3. ;  VERSION:  1.2
  4. ;  AUTHOR:  RICHARD CONN
  5. ;  DATE:  17 Jan 83
  6. ;  PREVIOUS VERSIONS:  1.1 (15 Jan 83), 1.0 (14 Jan 83)
  7. ;
  8. VERS    EQU    12
  9.  
  10. ;
  11. ;    MKDIR is used to create named directory files.  It allows the user
  12. ; to read and edit them.  It is fully integrated into the ZCPR2 system.
  13. ;
  14. ;    Forms of the MKDIR command are:
  15. ;        MKDIR            <-- Enter System
  16. ;        MKDIR //        <-- Get Help
  17. ;        MKDIR filename.typ    <-- Enter System with selected file
  18. ;
  19.  
  20. ;
  21. ;  CP/M Constants
  22. ;
  23. cpm    equ    0    ; base
  24. bdose    equ    cpm+5
  25. fcb    equ    cpm+5ch
  26. tbuff    equ    cpm+80h
  27. cr    equ    0dh
  28. lf    equ    0ah
  29.  
  30. ;
  31. ;  SYSLIB Routines
  32. ;
  33.     ext    print,zgpins,putud,getud,logud,retud,zfname,moveb
  34.     ext    cin,cout,crlf,caps,compb
  35.     ext    fi0$open,f0$get,fi0$close
  36.     ext    fo0$open,f0$put,fo0$close
  37.     ext    bbline,padc,initfcb,cline,zpfind,codend
  38.     ext    sort
  39.  
  40. ;
  41. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  42. ;    All Rights Reserved
  43. ;
  44. ;    ZCPR2 and its utilities, including this one, are released
  45. ; to the public domain.  Anyone who wishes to USE them may do so with
  46. ; no strings attached.  The author assumes no responsibility or
  47. ; liability for the use of ZCPR2 and its utilities.
  48. ;
  49. ;    The author, Richard Conn, has sole rights to this program.
  50. ; ZCPR2 and its utilities may not be sold without the express,
  51. ; written permission of the author.
  52. ;
  53.  
  54. ;
  55. ;  Branch to Start of Program
  56. ;
  57.     jmp    start
  58.  
  59. ;
  60. ;******************************************************************
  61. ;
  62. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  63. ;
  64. ;    This data block precisely defines the data format for
  65. ; initial features of a ZCPR2 system which are required for proper
  66. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  67. ;
  68.  
  69. ;
  70. ;  EXTERNAL PATH DATA
  71. ;
  72. EPAVAIL:
  73.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  74. EPADR:
  75.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  76.  
  77. ;
  78. ;  INTERNAL PATH DATA
  79. ;
  80. INTPATH:
  81.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  82.             ; DISK = 1 FOR A, '$' FOR CURRENT
  83.             ; USER = NUMBER, '$' FOR CURRENT
  84.     DB    0,0
  85.     DB    0,0
  86.     DB    0,0
  87.     DB    0,0
  88.     DB    0,0
  89.     DB    0,0
  90.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  91.     DB    0    ; END OF PATH
  92.  
  93. ;
  94. ;  MULTIPLE COMMAND LINE BUFFER DATA
  95. ;
  96. MCAVAIL:
  97.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  98. MCADR:
  99.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  100.  
  101. ;
  102. ;  DISK/USER LIMITS
  103. ;
  104. MDISK:
  105.     DB    4    ; MAXIMUM NUMBER OF DISKS
  106. MUSER:
  107.     DB    31    ; MAXIMUM USER NUMBER
  108.  
  109. ;
  110. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  111. ;
  112. DOK:
  113.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  114. UOK:
  115.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  116.  
  117. ;
  118. ;  PRIVILEGED USER DATA
  119. ;
  120. PUSER:
  121.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  122. PPASS:
  123.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  124.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  125.  
  126. ;
  127. ;  CURRENT USER/DISK INDICATOR
  128. ;
  129. CINDIC:
  130.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  131.  
  132. ;
  133. ;  DMA ADDRESS FOR DISK TRANSFERS
  134. ;
  135. DMADR:
  136.     DW    80H    ; TBUFF AREA
  137.  
  138. ;
  139. ;  NAMED DIRECTORY INFORMATION
  140. ;
  141. NDRADR:
  142.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  143. NDNAMES:
  144.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  145. DNFILE:
  146.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  147.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  148.  
  149. ;
  150. ;  REQUIREMENTS FLAGS
  151. ;
  152. EPREQD:
  153.     DB    0FFH    ; EXTERNAL PATH?
  154. MCREQD:
  155.     DB    000H    ; MULTIPLE COMMAND LINE?
  156. MXREQD:
  157.     DB    0FFH    ; MAX USER/DISK?
  158. UDREQD:
  159.     DB    000H    ; ALLOW USER/DISK CHANGE?
  160. PUREQD:
  161.     DB    000H    ; PRIVILEGED USER?
  162. CDREQD:
  163.     DB    0FFH    ; CURRENT INDIC AND DMA?
  164. NDREQD:
  165.     DB    0FFH    ; NAMED DIRECTORIES?
  166. Z2CLASS:
  167.     DB    0    ; CLASS 0
  168.     DB    'ZCPR2'
  169.     DS    10    ; RESERVED
  170.  
  171. ;
  172. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  173. ;
  174. ;******************************************************************
  175. ;
  176.  
  177. ;
  178. ;  Start of Program
  179. ;
  180. start:
  181.     lxi    h,0    ; save stack
  182.     dad    sp
  183.     shld    stack
  184.     xra    a    ; A=0
  185.     sta    chflag    ; set no changes
  186.     sta    flflag    ; set no file loaded
  187.     sta    ecount    ; set no entries
  188.     call    zgpins    ; set up environ
  189.     call    print
  190.     db    'MKDIR  Version '
  191.     db    vers/10+'0','.',(vers mod 10)+'0',0
  192.     lda    fcb+1    ; check for help
  193.     cpi    '/'
  194.     jnz    start1
  195.     call    print    ; print help message
  196.     db    cr,lf,'    MKDIR is used to read and edit named directory files.'
  197.     db    cr,lf,'It is invoked by the following forms --'
  198.     db    cr,lf
  199.     db    cr,lf,'        MKDIR            <-- Enter System'
  200.     db    cr,lf,'        MKDIR dir:filename.typ    <-- Define File First'
  201.     db    cr,lf,'        MKDIR //        <-- Print this Help'
  202.     db    cr,lf,0
  203.     ret
  204.  
  205. start1:
  206.     call    putud    ; save current dir for quick return
  207.     call    retud    ; get current user and disk
  208.     mov    a,b    ; save disk
  209.     sta    cdisk
  210.     mov    a,c
  211.     sta    cuser
  212.     lxi    h,dnfile    ; set default file name
  213.     lxi    d,dfcb+1    ; copy into fcb
  214.     mvi    b,11    ; 11 chars
  215.     call    moveb
  216.     lxi    h,tbuff    ; save command line as string
  217.     call    cline
  218.     call    sblank    ; skip to non-blank
  219.     ora    a    ; no entry?
  220.     jz    mkdir    ; enter system
  221. ;
  222. ;  Main Entry Point for Loading a File
  223. ;
  224. loadfile:
  225.     lxi    sp,stack    ; set stack
  226.     lxi    d,dfcb    ; set up default file name
  227.     call    zfname    ; extract info
  228.     jnz    start2
  229.     call    print
  230.     db    cr,lf,'Error in Disk or User -- Ignoring',0
  231.     lda    cdisk    ; set current values
  232.     mov    b,a
  233.     lda    cuser
  234.     mov    c,a
  235.     jmp    start3
  236. start2:
  237.     mov    a,b    ; check for current disk
  238.     cpi    0ffh    ; current?
  239.     jnz    cutst
  240.     lda    cdisk    ; get current disk
  241.     mov    b,a
  242.     inr    b    ; add 1 for following decrement
  243. cutst:
  244.     dcr    b    ; adjust disk to 0 to n-1
  245.     mov    a,c    ; check for current user
  246.     cpi    0ffh    ; current?
  247.     jnz    start3
  248.     lda    cuser    ; get current user
  249.     mov    c,a
  250. start3:
  251.     call    logud    ; log into UD to begin search
  252. ;
  253. ;  Entry Point for Loading File in DFCB
  254. ;
  255. ffile:
  256.     lxi    sp,stack    ; reset stack
  257.     mvi    b,0ffh    ; search current first
  258.     lxi    d,dfcb    ; pt to FCB
  259.     call    initfcb    ; init it
  260.     call    zpfind    ; look for file
  261.     jnz    start4
  262.     call    print
  263.     db    cr,lf,'File ',0
  264.     lxi    h,dfcb+1    ; print name
  265.     call    prfn
  266.     call    print
  267.     db    ' Not Found',0
  268.     jmp    mkdir
  269. start4:
  270.     call    logud    ; log into dir of file
  271.     lxi    d,dfcb
  272.     call    initfcb
  273.     call    fi0$open    ; open file for input
  274.     call    codend    ; pt to scratch buffer
  275.     lda    ndnames    ; get max entry count
  276.     mov    b,a    ; ... in B
  277. readf:
  278.     call    getch    ; get disk letter from file
  279.     sui    'A'    ; convert to number from 0 to n-1
  280.     mov    m,a    ; store disk number
  281.     inx    h    ; pt to user number
  282.     call    getch    ; get user number
  283.     mov    m,a    ; store user number
  284.     inx    h    ; pt to next
  285.     mvi    c,8    ; store dir name
  286. readn:
  287.     call    getch    ; get char
  288.     ora    a    ; done?
  289.     jz    readn1
  290.     mov    m,a    ; store char if not done
  291.     inx    h    ; pt to next
  292.     dcr    c    ; count down
  293.     jnz    readn
  294.     jmp    readn2
  295. readn0:
  296.     call    getch    ; flush char
  297. readn1:
  298.     mvi    m,' '    ; store spaces now
  299.     inx    h    ; pt to next
  300.     dcr    c    ; count down
  301.     jnz    readn0
  302. readn2:
  303.     call    getch    ; flush 9th char
  304.     dcr    b    ; count down
  305.     jnz    readf    ; continue reading file entries
  306.     call    fi0$close    ; close input file
  307.     call    getud    ; return to current dir
  308.     call    dirpack    ; pack dir
  309.     mvi    a,0ffh    ; set file loaded flag
  310.     sta    flflag
  311.     jmp    mkdir1
  312. ;
  313. ;  Enter MKDIR System and Init Environ
  314. ;    Enter at MKDIR if no file loaded, enter at MKDIR1 if file loaded
  315. ;
  316. mkdir:
  317.     call    dinit0    ; init directory
  318.     xra    a    ; A=0
  319.     sta    ecount    ; set no entries present
  320.     sta    flflag    ; set no file loaded
  321.     sta    chflag    ; set no changes
  322. mkdir1:
  323.     lxi    sp,stack    ; set stack
  324.     call    print
  325.     db    cr,lf,'MKDIR Command (? for Help)? ',0
  326.     call    cin    ; get command
  327.     call    caps    ; capitalize
  328.     call    cout    ; echo
  329.     lxi    d,mkdir1    ; set ret address
  330.     push    d
  331.     lxi    h,ctable    ; scan command table for it
  332.     mov    c,a    ; command in C
  333. mkdir2:
  334.     mov    a,m    ; get command letter
  335.     ora    a    ; end of table?
  336.     jz    mkdirh
  337.     cmp    c    ; match?
  338.     jz    mkdir3
  339.     inx    h    ; skip over address
  340.     inx    h
  341.     inx    h
  342.     jmp    mkdir2
  343. mkdir3:
  344.     inx    h    ; get address in HL
  345.     mov    a,m    ; low
  346.     inx    h
  347.     mov    h,m
  348.     mov    l,a    ; HL is address of routine
  349.     pchl        ; "call" routine
  350. ;
  351. ;  Print MKDIR Command Help
  352. ;
  353. mkdirh:
  354.     call    print
  355.     db    cr,lf,'MKDIR Commands are --'
  356.     db    cr,lf,'    C -- Change Directory (Add/Rename/Delete Entries)'
  357.     db    cr,lf,'    I -- Initialize Directory'
  358.     db    cr,lf,'    P -- Print Directory'
  359.     db    cr,lf,'    R -- Read Directory File'
  360.     db    cr,lf,'    S -- Status of MKDIR Environment'
  361.     db    cr,lf,'    W -- Write Directory File'
  362.     db    cr,lf,'    X -- Exit Program'
  363.     db    cr,lf,0
  364.     ret
  365. ;
  366. ;  Command Table
  367. ;
  368. ctable:
  369.     db    'C'    ; change directory
  370.     dw    change
  371.     db    'I'    ; init directory
  372.     dw    dinit
  373.     db    'P'    ; print directory
  374.     dw    dprint
  375.     db    'R'    ; read file
  376.     dw    read
  377.     db    'S'    ; status
  378.     dw    status
  379.     db    'W'    ; write file
  380.     dw    write
  381.     db    'X'    ; exit
  382.     dw    exit
  383.     db    0    ; end of table
  384. ;
  385. ;  Status
  386. ;
  387. status:
  388.     call    print
  389.     db    cr,lf,'** MKDIR Status **',cr,lf,cr,lf,0
  390.     lda    ecount    ; print entry count
  391.     mov    b,a    ; ... count in B for later
  392.     call    padc
  393.     call    print
  394.     db    ' Entries in Directory',cr,lf,0
  395.     lda    ndnames    ; get limit
  396.     sub    b    ; subtract amount taken so far
  397.     call    padc
  398.     call    print
  399.     db    ' Empty Entries Remaining'
  400.     db    cr,lf
  401.     db    cr,lf,'Working File Name: ',0
  402.     lxi    h,dfcb+1
  403.     call    prfn
  404.     call    crlf    ; new line
  405.     call    crlf
  406.     lda    chflag    ; changes made?
  407.     ora    a
  408.     jnz    stat1
  409.     call    print
  410.     db    'No ',0
  411. stat1:
  412.     call    print
  413.     db    'Changes made to Directory since Startup'
  414.     db    cr,lf,0
  415.     lda    flflag    ; file loaded?
  416.     ora    a    ; 0=no
  417.     jnz    stat2
  418.     call    print
  419.     db    'No ',0
  420. stat2:
  421.     call    print
  422.     db    'File has been loaded',cr,lf,0
  423.     ret
  424.  
  425. ;
  426. ;  Init Directory
  427. ;
  428. dinit:
  429.     call    print
  430.     db    cr,lf,'    Are you sure you want to Initialize the Directory '
  431.     db    '(Y/N/<CR>=N)? ',0
  432.     call    cin    ; get response
  433.     call    caps
  434.     call    cout
  435.     call    crlf
  436.     cpi    'Y'    ; Yes is only valid reply
  437.     rnz
  438. dinit0:
  439.     xra    a    ; A=0
  440.     sta    ecount
  441.     mvi    a,0ffh
  442.     sta    chflag    ; set change flag
  443.     call    codend    ; pt to directory
  444.     lda    ndnames    ; get entry count
  445.     mov    b,a    ; ... in B
  446. dinit1:
  447.     mvi    m,0    ; set double zero
  448.     inx    h
  449.     mvi    m,0
  450.     inx    h    ; pt to name
  451.     mvi    c,8    ; 8 chars
  452. dinit2:
  453.     mvi    m,' '    ; store space
  454.     inx    h    ; pt to next
  455.     dcr    c    ; count down
  456.     jnz    dinit2
  457.     dcr    b    ; count down
  458.     jnz    dinit1
  459.     ret
  460. ;
  461. ;  Read File
  462. ;
  463. read:
  464.     call    getfname    ; get file name
  465.     ora    a        ; none?
  466.     jz    ffile        ; just find default file and load it
  467.     jmp    loadfile    ; parse entry and load file
  468. ;
  469. ;  Get File Name from User
  470. ;
  471. getfname:
  472.     call    print
  473.     db    cr,lf,'Name of File (<RETURN> = ',0
  474.     lxi    h,dfcb+1    ; print default name
  475.     call    prfn
  476.     call    print
  477.     db    ')? ',0
  478.     mvi    a,0ffh    ; capitalize
  479.     call    bbline    ; get user input
  480.     call    sblank    ; skip to non-blank
  481.     ora    a    ; default?
  482.     ret
  483. ;
  484. ;  Write File
  485. ;
  486. write:
  487.     call    getfname
  488.     jz    write1
  489.     lxi    d,dfcb    ; parse into DFCB
  490.     call    zfname    ; parse file name
  491.     jnz    write0
  492.     call    print
  493.     db    cr,lf,'Invalid Disk or User -- Using Current Directory',0
  494.     jmp    write1
  495. write0:
  496.     mov    a,b    ; current disk?
  497.     cpi    0ffh
  498.     jnz    wutst
  499.     lda    cdisk    ; select current disk
  500.     mov    b,a
  501.     inr    b    ; add 1 for following decrement
  502. wutst:
  503.     dcr    b    ; adjust disk to 0 to n-1
  504.     mov    a,c    ; current user?
  505.     cpi    0ffh
  506.     jnz    wlog
  507.     lda    cuser    ; select current user
  508.     mov    c,a
  509. wlog:
  510.     call    logud    ; log into new dir
  511. write1:
  512.     lxi    d,dfcb    ; open file for output
  513.     call    initfcb
  514.     call    fo0$open    ; open file
  515.     ora    a    ; OK?
  516.     jnz    werr    ; write error and abort
  517.     call    print
  518.     db    cr,lf,'Writing Directory to Disk ... ',0
  519.     lda    ndnames    ; save dir as loaded
  520.     mov    b,a    ; count in B
  521.     call    codend    ; pt to start of buffer
  522. writef:
  523.     mov    a,m    ; get disk
  524.     adi    'A'    ; convert to letter
  525.     call    putch    ; write char
  526.     inx    h    ; pt to user
  527.     mov    a,m    ; get user
  528.     call    putch    ; write char
  529.     inx    h    ; pt to next
  530.     mvi    c,8    ; write dir name to disk
  531. wf1:
  532.     mov    a,m    ; get char
  533.     cpi    ' '    ; done?
  534.     jz    wf2
  535.     inx    h    ; pt to next
  536.     call    putch    ; write char to disk
  537.     dcr    c    ; count down
  538.     jnz    wf1
  539.     jmp    wf3
  540. wf2:
  541.     xra    a    ; write zeroes
  542.     inx    h    ; skip next char
  543.     call    putch
  544.     dcr    c    ; count down
  545.     jnz    wf2
  546. wf3:
  547.     xra    a    ; write 9th zero
  548.     call    putch
  549.     dcr    b    ; count down
  550.     jnz    writef
  551.     call    fo0$close    ; close file
  552.     call    getud    ; go home
  553.     xra    a    ; A=0
  554.     sta    chflag    ; set no changes flag
  555.     call    print
  556.     db    'Done',0
  557.     ret
  558. ;
  559. ;  Exit from MKDIR
  560. ;
  561. exit:
  562.     lda    chflag    ; check for any changes
  563.     ora    a    ; 0=No
  564.     jz    exit1
  565.     call    print
  566.     db    cr,lf
  567.     db    cr,lf,'Directory has changed since last Write'
  568.     db    cr,lf,'Do you want to write Directory to Disk first '
  569.     db    '(Y/N/<CR>=Y)?',0
  570.     call    cin    ; get response
  571.     call    caps
  572.     call    cout
  573.     call    crlf    ; new line
  574.     cpi    'N'    ; no?
  575.     cnz    write    ; write if not No
  576. exit1:
  577.     lhld    stack    ; return to OS
  578.     sphl
  579.     ret
  580. ;
  581. ;  Print Directory to User
  582. ;
  583. dprint:
  584.     lda    ecount    ; any entries?
  585.     ora    a    ; 0=none
  586.     jnz    dpr1
  587.     call    print
  588.     db    cr,lf,'Empty Directory',0
  589.     ret
  590. dpr1:
  591.     call    codend    ; pt to first element
  592.     lda    ecount    ; get entry count
  593.     mov    b,a    ; ... in B
  594.     mvi    c,'A'-1    ; set disk type
  595. prloop:
  596.     inr    c    ; next disk
  597.     call    print
  598.     db    cr,lf,'Disk ',0
  599.     mov    a,c    ; print disk letter
  600.     call    cout
  601.     call    print
  602.     db    ' --',0
  603.     mvi    a,0ffh    ; set line count
  604.     sta    crcnt
  605. prl1:
  606.     mov    a,m    ; get next disk
  607.     adi    'A'    ; convert to alpha
  608.     cmp    c    ; same as current?
  609.     jnz    prloop    ; loop to next if not
  610.     lda    crcnt    ; increment entry count
  611.     inr    a
  612.     sta    crcnt
  613.     ani    3    ; new line?
  614.     cz    crlf
  615.     call    print
  616.     db    '   ',0    ; space over
  617.     inx    h    ; pt to user
  618.     mov    a,m    ; get user number
  619.     call    padc    ; print user number
  620.     call    print
  621.     db    ': ',0
  622.     inx    h    ; pt to name
  623.     mvi    d,8    ; 8 chars
  624. prl2:
  625.     mov    a,m    ; get char
  626.     inx    h    ; pt to next
  627.     call    cout    ; print char
  628.     dcr    d    ; count down
  629.     jnz    prl2
  630. prl3:
  631.     dcr    b    ; count down
  632.     jnz    prl1
  633.     call    crlf    ; new line
  634.     lda    ecount
  635.     call    padc
  636.     call    print
  637.     db    ' Entries in Directory',0
  638.     ret
  639. ;
  640. ;  Change Directory Contents
  641. ;
  642. change:
  643.     call    print
  644.     db    cr,lf,'** MKDIR Change Mode **',0
  645. ch0:
  646.     call    print
  647.     db    cr,lf,'Directory Entry (?<RETURN> for Help)? ',0
  648.     mvi    a,0ffh    ; caps
  649.     call    bbline    ; get user input
  650.     call    sblank    ; skip to non-blank
  651.     ora    a    ; no input?
  652.     jz    chprint    ; done, so print directory
  653.     mov    a,m    ; get first char
  654.     cpi    'X'    ; Exit?
  655.     jz    dsort    ; if so, sort and then exit
  656.     cpi    '?'    ; help?
  657.     jnz    ch1
  658.     call    print
  659.     db    cr,lf
  660.     db    cr,lf,'MKDIR Change Mode --'
  661.     db    cr,lf,'    You may issue the following commands at this point:'
  662.     db    cr,lf
  663.     db    cr,lf,'        DU:dirname    <-- Create/Rename Dir Entry'
  664.     db    cr,lf,'        DU:        <-- Delete Dir Entry'
  665.     db    cr,lf,'        <RETURN>    <-- Print Directory'
  666.     db    cr,lf,'        X        <-- Exit'
  667.     db    cr,lf,'        ?        <-- Print this Help'
  668.     db    cr,lf,0
  669.     jmp    ch0
  670. chprint:
  671.     call    dsort    ; use dsort routine
  672.     call    dprint    ; use dprint routine
  673.     jmp    ch0    ; continue
  674. ch1:
  675.     lxi    d,tfcb    ; extract user and disk info as well as name
  676.     call    zfname    ; get info
  677.     jnz    ch2
  678.     call    print
  679.     db    cr,lf,'Error in Disk or User',0
  680.     jmp    ch0
  681. ch2:
  682.     mov    a,b    ; current disk?
  683.     cpi    0ffh
  684.     jnz    ch3
  685.     lda    cdisk    ; set disk
  686.     mov    b,a
  687.     inr    b    ; add 1 for following decrement
  688. ch3:
  689.     dcr    b    ; adjust disk to 0 to n-1
  690.     mov    a,c    ; current user?
  691.     cpi    0ffh
  692.     jnz    ch4
  693.     lda    cuser    ; set user
  694.     mov    c,a
  695. ch4:
  696.     mov    a,b    ; save as temp disk and user
  697.     sta    tdisk
  698.     mov    a,c
  699.     sta    tuser
  700. ;
  701. ;  Scan Directory for Temp Disk and User
  702. ;
  703.     lda    ndnames    ; get entry count
  704.     mov    b,a    ; ... in B
  705.     call    codend    ; pt to first entry
  706. scanud:
  707.     inx    h    ; pt to name
  708.     inx    h
  709.     mov    a,m    ; get first char of name
  710.     dcx    h
  711.     dcx    h    ; pt to disk
  712.     cpi    ' '    ; deleted entry?
  713.     jz    scanud1
  714.     mov    d,m    ; get disk
  715.     lda    tdisk    ; compare it
  716.     cmp    d
  717.     jnz    scanud1
  718.     inx    h    ; pt to user
  719.     mov    a,m    ; get user
  720.     dcx    h    ; pt back
  721.     cmp    c    ; compare it
  722.     jz    udfound
  723. scanud1:
  724.     lxi    d,10    ; pt to next
  725.     dad    d
  726.     dcr    b    ; count down
  727.     jnz    scanud
  728.     lda    tfcb+1    ; delete?
  729.     cpi    '?'    ; ? if so
  730.     jnz    addname
  731.     call    print
  732.     db    cr,lf,'    -- DU not found for Delete -- No Change Made',0
  733.     jmp    ch0
  734. ;
  735. ;  Found Possible Directory Entry
  736. ;
  737. udfound:
  738.     inx    h    ; found existing entry
  739.     inx    h    ; pt to name
  740.     lda    tfcb+1    ; delete?
  741.     cpi    '?'    ; ? if so
  742.     jz    delname
  743. ;
  744. ;  Rename Function
  745. ;
  746.     xra    a    ; clear add flag
  747.     sta    addflg
  748.     call    print
  749.     db    cr,lf,'    Renaming ',0
  750.     mvi    b,8    ; 8 chars
  751.     push    h    ; save ptr
  752.     call    prfn1    ; print name
  753.     pop    h    ; get ptr
  754.     mvi    m,' '    ; space fill
  755.     jmp    putname
  756. ;
  757. ;  Add Function
  758. ;
  759. addname:
  760.     mvi    a,0ffh    ; set add flag
  761.     sta    addflg
  762.     call    print
  763.     db    cr,lf,'    Adding ',0
  764.     lxi    h,tfcb+1
  765.     mvi    b,8
  766.     call    prfn1
  767.     lda    ecount    ; increment entry count
  768.     inr    a
  769.     sta    ecount
  770. putname:
  771.     lda    ndnames    ; get entry count
  772.     mov    c,a    ; ... in C
  773.     call    codend    ; pt to first entry
  774.     inx    h    ; pt to name
  775.     inx    h
  776. etest:
  777.     lxi    d,tfcb+1    ; pt to new name
  778.     mvi    b,8    ; 8 chars
  779.     call    compb    ; compare
  780.     jnz    etest1
  781.     call    print
  782.     db    cr,lf,'    -- Error -- Duplicate Name Exists -- No Change Made',0
  783.     lda    addflg    ; add?
  784.     ora    a    ; 0=no
  785.     jz    ch0
  786.     lda    ecount    ; count down
  787.     dcr    a
  788.     sta    ecount
  789.     jmp    ch0
  790. etest1:
  791.     lxi    d,10    ; pt to next entry
  792.     dad    d
  793.     dcr    c    ; count down
  794.     jnz    etest
  795.     mvi    a,0ffh    ; change made
  796.     sta    chflag
  797.     lda    ndnames    ; get entry count
  798.     mov    b,a    ; ... in B
  799.     call    codend    ; pt to first
  800.     inx    h    ; pt to name
  801.     inx    h
  802. putn1:
  803.     mov    a,m    ; valid entry?
  804.     cpi    ' '    ; empty?
  805.     jnz    putn2
  806.     dcx    h    ; pt to disk
  807.     dcx    h
  808.     lda    tdisk
  809.     mov    m,a
  810.     inx    h
  811.     lda    tuser
  812.     mov    m,a
  813.     inx    h
  814.     lxi    d,tfcb+1    ; pt to new name
  815.     xchg
  816.     mvi    b,8    ; 8 chars
  817.     call    moveb
  818.     call    print
  819.     db    ' -- ',0
  820.     lda    ecount    ; print count
  821.     mov    b,a    ; ... in B
  822.     call    padc
  823.     call    print
  824.     db    ' Entries in Directory, Room for ',0
  825.     lda    ndnames
  826.     sub    b
  827.     call    padc
  828.     call    print
  829.     db    ' More',0
  830.     jmp    ch0    ; continue
  831. putn2:
  832.     lxi    d,10    ; skip to next entry
  833.     dad    d
  834.     dcr    b    ; count down
  835.     jnz    putn1
  836.     call    print
  837.     db    cr,lf,'** Directory Full **',0
  838.     lda    addflg    ; adding?
  839.     ora    a    ; 0=no
  840.     jz    ch0
  841.     lda    ecount    ; count down
  842.     dcr    a
  843.     sta    ecount
  844.     jmp    ch0
  845. ;
  846. ;  Delete Function
  847. ;
  848. delname:
  849.     mvi    a,0ffh    ; change made
  850.     sta    chflag
  851.     call    print
  852.     db    cr,lf,'    Deleting ',0
  853.     mvi    b,8    ; 8 chars
  854.     push    h    ; save ptr
  855.     call    prfn1
  856.     pop    h    ; get ptr
  857.     mvi    m,' '    ; space fill
  858.     call    dirpack    ; pack directory
  859.     call    print
  860.     db    ' -- ',0
  861.     lda    ecount    ; print remaining count
  862.     call    padc
  863.     call    print
  864.     db    ' Entries Remaining',0
  865.     jmp    ch0    ; continue
  866. ;
  867. ;  Sort Directory
  868. ;
  869. dsort:
  870.     call    dirpack    ; pack directory
  871.     lda    ecount    ; number of elements
  872.     ora    a    ; any?
  873.     rz        ; done if none
  874.     sta    ssbcnt    ; set count
  875.     call    codend    ; pt to first element
  876.     shld    ssbstrt    ; set starting address
  877.     lxi    d,ssb    ; pt to sort specifiction block
  878.     call    sort    ; sort
  879.     ret
  880. ;
  881. ;  Sort Compare Routine
  882. ;
  883. compare:
  884.     push    h    ; don't change regs
  885.     push    d
  886.     ldax    d    ; compare disk
  887.     cmp    m
  888.     jnz    comp1
  889.     inx    h    ; pt to user
  890.     inx    d
  891.     ldax    d    ; compare user
  892.     cmp    m
  893. comp1:
  894.     pop    d    ; restore regs
  895.     pop    h
  896.     ret
  897.  
  898. ;
  899. ;  Utilities
  900. ;
  901.  
  902. ;
  903. ;  Read and Write Chars to Disk
  904. ;
  905. getch:
  906.     call    f0$get    ; get char
  907.     rz        ; OK since no error
  908.     call    print
  909.     db    cr,lf,'File Read Error -- Aborting',0
  910.     jmp    mkdir1    ; goto command level
  911. putch:
  912.     call    f0$put    ; put char
  913.     rz        ; OK since no error
  914. werr:
  915.     call    print
  916.     db    cr,lf,'Disk Write Error -- Aborting',0
  917.     call    getud    ; return home
  918.     jmp    mkdir1
  919. ;
  920. ;  Pack Memory-Based Directory
  921. ;
  922. dirpack:
  923.     call    codend    ; get address of first entry
  924.     mov    d,h    ; DE pts to it also
  925.     mov    e,l
  926.     lda    ndnames    ; get max count
  927.     mov    b,a    ; ... in B
  928.     mvi    c,0    ; set entry count
  929. dirp0:
  930.     push    b    ; save counts
  931.     inx    h    ; pt to name
  932.     inx    h
  933.     mov    a,m    ; get char
  934.     dcx    h    ; pt back to disk
  935.     dcx    h
  936.     cpi    ' '    ; no entry if space
  937.     jz    dirp1
  938.     mvi    b,10    ; copy 10 bytes
  939. dirpm:
  940.     mov    a,m    ; copy HL to DE for B bytes
  941.     stax    d
  942.     inx    h    ; pt to next
  943.     inx    d
  944.     dcr    b    ; count down
  945.     jnz    dirpm
  946.     pop    b    ; get counts
  947.     inr    c    ; 1 more entry
  948.     jmp    dirp2
  949. dirp1:
  950.     push    d    ; save new entry ptr
  951.     lxi    d,10    ; pt to next entry
  952.     dad    d
  953.     pop    d
  954.     pop    b    ; get counts
  955. dirp2:
  956.     dcr    b    ; count down
  957.     jnz    dirp0
  958.     mov    a,c    ; save count
  959.     sta    ecount
  960.     lda    ndnames    ; make rest empty
  961.     sub    c    ; number of entries remaining
  962.     mov    b,a    ; ... in B
  963.     ora    a    ; none?
  964.     rz
  965.     xchg        ; HL pts to next entry
  966.     inx    h    ; pt to name
  967.     inx    h
  968.     lxi    d,10    ; prep to add 10
  969. dirp3:
  970.     mvi    m,' '    ; set space as first char
  971.     dad    d    ; pt to next
  972.     dcr    b    ; count down
  973.     jnz    dirp3
  974.     ret
  975. ;
  976. ;  Skip until non-blank encountered
  977. ;
  978. sblank:
  979.     mov    a,m    ; get char
  980.     inx    h    ; pt to next
  981.     cpi    ' '    ; skip space
  982.     jz    sblank
  983.     dcx    h    ; pt to char
  984.     ret
  985. ;
  986. ;  Print file name pted to by HL
  987. ;
  988. prfn:
  989.     push    b    ; save regs
  990.     push    h
  991.     mvi    b,8    ; 8 chars
  992.     call    prfn1
  993.     mvi    a,'.'
  994.     call    cout
  995.     mvi    b,3    ; 3 chars
  996.     call    prfn1
  997.     pop    h    ; get regs
  998.     pop    b
  999.     ret
  1000. prfn1:
  1001.     mov    a,m    ; print chars
  1002.     inx    h    ; pt to next
  1003.     call    cout
  1004.     dcr    b    ; count down
  1005.     jnz    prfn1
  1006.     ret
  1007.  
  1008. ;
  1009. ;  Sort Specification Block
  1010. ;
  1011. ssb:
  1012. ssbstrt:
  1013.     ds    2    ; start address of dir
  1014. ssbcnt:
  1015.     dw    0    ; number of records to sort
  1016.     dw    10    ; 10 bytes/record
  1017.     dw    compare    ; compare routine
  1018.     dw    0    ; no ptr table
  1019.     db    0,0    ; don't use ptrs
  1020. ;
  1021. ;  Buffers
  1022. ;
  1023. cdisk:
  1024.     ds    1    ; current disk
  1025. cuser:
  1026.     ds    1    ; current user
  1027. tdisk:
  1028.     ds    1    ; temp disk
  1029. tuser:
  1030.     ds    1    ; temp user
  1031. flflag:
  1032.     ds    1    ; file loaded flag
  1033. chflag:
  1034.     ds    1    ; dir changed flag
  1035. ecount:
  1036.     ds    1    ; entry count
  1037. addflg:
  1038.     ds    1    ; add/rename flag
  1039. crcnt:
  1040.     ds    1    ; new line count
  1041. tfcb:
  1042.     ds    36    ; temp FCB
  1043. dfcb:
  1044.     ds    36    ; Default FCB
  1045.     ds    50    ; 25-elt stack
  1046. stack:
  1047.     ds    2    ; original stack ptr
  1048.  
  1049.     end
  1050.