home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol090 / szfname.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  14.7 KB  |  689 lines

  1. ;
  2. ; SYSLIB Module Name:  SZFNAM
  3. ; Author:  Richard Conn
  4. ; SYSLIB Version Number:  2.1
  5. ; Module Version Number:  1.1
  6. ; Module Entry Points:
  7. ;    ZFNINIT        ZFNAME        ZDNAME        ZDNFIND
  8. ; Module External References:
  9. ;    CAPS        FI3$CLOSE    FI3$OPEN    F3$GET
  10. ;    INITFCB        MOVEB        ZPFIND        BDOS
  11. ;
  12. ;*
  13. ;*  ZFNAME is a file name scanner.  Pointing to the first character
  14. ;*    of a file name specification of the form 'dir:filename.typ', where
  15. ;*    any part of this specification is optional, this routine fills in
  16. ;*    an FCB with zeros, properly initializes the FN and FT (File Name and
  17. ;*    File Type) fields if 'filename.typ' or any part thereof is present,
  18. ;*    and returns the value of disk and user if they are specified
  19. ;*    (or FFH if they are not).
  20. ;*  The directory indicator 'dir:', if specified, may be of one of two forms:
  21. ;*        DIRECT -- A named directory, of up to 8 chars in length
  22. ;*        d      -- A disk drive letter
  23. ;*        u      -- A user number
  24. ;*        du     -- A disk drive letter and a user number
  25. ;*    The named directory form is checked first, so if a directory named
  26. ;*        A or A10 exists, it matches, as opposed to Drive A or
  27. ;*        drive/user A/10.
  28. ;*    Examples:
  29. ;*        HELP:*.HLP
  30. ;*        A5:TEST.TXT
  31. ;*        C?:ABC.*
  32. ;*        PASCAL:*.COM
  33. ;*    NOTE:  It is the programmer's responsibility to have called and
  34. ;*        properly initialized the buffers in the ZCPRINIT routine
  35. ;*        in the SZCPR module
  36. ;*
  37.  
  38. ;*
  39. ;*  EXTERNALS
  40. ;*
  41.     EXT    BDOS    ; BDOS UTILITY
  42.     EXT    MOVEB    ; COPY UTILITY
  43.     EXT    INITFCB    ; INIT FCB UTILITY
  44.     EXT    CAPS    ; CAPITALIZE ROUTINE
  45.     EXT    ZPFIND    ; FIND FILE ALONG PATH
  46.     EXT    FI3$OPEN    ; BYTE-ORIENTED FILE I/O
  47.     EXT    FI3$CLOSE
  48.     EXT    F3$GET
  49.  
  50. ;*
  51. ;*  BASIC EQUATES
  52. ;*
  53. MAXDISK    EQU    16    ; MAX NUMBER OF DISKS
  54. MAXUSER    EQU    31    ; MAX USER NUMBER
  55. MAXNAME    EQU    64    ; MAX NUMBER OF NAMES IN DIR FILE
  56. CPM    EQU    0    ; CP/M ENTRY
  57. BENTRY    EQU    CPM+5    ; BDOS ENTRY
  58. CR    EQU    0DH
  59. LF    EQU    0AH
  60.  
  61. ;*
  62. ;*  INIT MODULE
  63. ;*    IF THE USER WISHES TO CHANGE THE NAME OF THE DIRECTORY FILE TO LOOK
  64. ;*    FOR, HE CALLS THIS ROUTINE, WITH THE FCB PTR IN DE
  65. ;*
  66. ;*    IF THE USER WISHES TO CHANGE THE NUMBER OF DIRECTORY NAMES PERMITTED
  67. ;*    IN THE DIRECTORY FILE, HE CALLS THIS ROUTINE, WITH THE NEW NAME
  68. ;*    COUNT IN C
  69. ;*
  70. ;*    THE SPECIFIC BUFFERED VALUES TO CHANGE ARE INDICATED BY THE A
  71. ;*    REGISTER AS FOLLOWS:
  72. ;*        BIT 7 -- SET NAME OF DIR FILE TO FCB PTED TO BY DE
  73. ;*        BIT 6 -- SET MAX NUMBER OF DIRECTORY NAMES PERMITTED
  74. ;*
  75. ;*    IF THIS MODULE IS NOT CALLED, THE FOLLOWING DEFAULT VALUES ARE
  76. ;*    ASSUMED:
  77. ;*        NAME OF DIRECTORY NAMES FILE -- NAMES.DIR
  78. ;*        MAX NUMBER OF DIRECTORY NAMES -- 64
  79. ;*
  80. ;*    NO REGS ARE AFFECTED
  81. ;*    ON INPUT, DE PTS TO NEW FCB
  82. ;*          C IS THE MAX NUMBER OF DIRECTORY NAMES
  83. ;*          A IS FLAG --
  84. ;*            BIT 7 SET (1) - LOAD DEFAULT FCB FROM DE
  85. ;*            BIT 6 SET (1) - LOAD NAME COUNT FROM C
  86. ;*
  87. ZFNINIT::
  88.     PUSH    H    ; SAVE REGS
  89.     PUSH    D
  90.     PUSH    B
  91.     PUSH    PSW
  92.     MOV    B,A    ; SAVE FLAG IN B
  93.     ANI    80H    ; LOOK AT BIT 7
  94.     JZ    ZFNIN1    ; SKIP FCB LOAD IF BIT 7 = 0
  95.     PUSH    B    ; SAVE FLAG IN B
  96.     XCHG        ; HL PTS TO FCB
  97.     LXI    D,FNFCB    ; PT TO MY FCB
  98.     MVI    B,12    ; COPY 12 BYTES
  99.     CALL    MOVEB    ; COPY
  100.     POP    B    ; GET FLAG IN B
  101. ZFNIN1:
  102.     MOV    A,B    ; GET FLAG
  103.     ANI    40H    ; LOOK AT BIT 6
  104.     JZ    ZFNIN2    ; SKIP NAMES LOAD IF BIT 6 = 0
  105.     MOV    A,C    ; GET COUNT
  106.     STA    MAXN    ; STORE IN BUFFER
  107. ZFNIN2:
  108.     POP    PSW    ; RESTORE REGS
  109.     POP    B
  110.     POP    D
  111.     POP    H
  112.     RET
  113.  
  114. ;
  115. ;  FCB USED BY ZFNAME
  116. ;
  117. MAXN:
  118.     DB    MAXNAME                ; INIT TO MAXNAME
  119. FNFCB:
  120.     DB    0,'NAMES   DIR',0,0,0,0        ; INIT TO NAMES.DIR
  121.     DS    16
  122.     DS    4
  123.  
  124. ;*
  125. ;*  MAIN MODULE
  126. ;*    ON ENTRY, DE PTS TO FCB TO BE FILLED AND HL PTS TO FIRST BYTE OF
  127. ;*        TARGET STRING; FCB IS 36 BYTES LONG
  128. ;*    ON EXIT, B=DISK NUMBER (1 FOR A, ETC) AND C=USER NUMBER
  129. ;*        HL PTS TO TERMINATING CHAR
  130. ;*        A=0 AND Z SET IF ERROR IN DISK OR USER NUMBERS, A=0FFH AND NZ
  131. ;*            IF OK
  132. ;*
  133. ZFNAME::
  134.     PUSH    D    ; SAVE DE
  135.     PUSH    H    ; SAVE HL
  136.     XCHG        ; SAVE PTR TO FCB
  137.     SHLD    FCBPTR
  138.     XCHG        ; DE PTS TO FCB
  139.     POP    H    ; GET HL
  140.     MVI    A,0FFH    ; SET DEFAULT DISK AND USER
  141.     STA    DISK
  142.     STA    USER
  143. ;  FILL TARGET FCB WITH ZEROES
  144.     MVI    B,36    ; INIT FCB
  145.     XRA    A    ; A=0
  146. FNINI:
  147.     STAX    D    ; STORE ZERO
  148.     INX    D    ; PT TO NEXT
  149.     DCR    B    ; COUNT DOWN
  150.     JNZ    FNINI
  151. ;  SCAN FOR COLON IN STRING
  152.     PUSH    H    ; SAVE PTR TO TARGET STRING
  153. COLON:
  154.     MOV    A,M    ; SCAN FOR COLON OR SPACE
  155.     CPI    ':'    ; COLON FOUND?
  156.     JZ    COLON1
  157.     CALL    DELCK    ; DELIMITER FOUND?
  158.     JZ    GETF1
  159.     INX    H    ; PT TO NEXT
  160.     JMP    COLON    ; CONTINUE IF NOT END OF LINE
  161. ;  WE HAVE FOUND A COLON, SO THERE IS A DIR: PREFIX
  162. COLON1:
  163.     POP    H    ; GET PTR TO FIRST CHAR
  164.     MVI    A,0FFH    ; ALLOW DU: FORM
  165.     CALL    ZDNFIND    ; SCAN FOR DIRECTORY NAME; RETURN DISK IN DISK,
  166.     JNZ    GETFILE        ;   USER IN USER, NZ IF OK, HL PTS TO COLON
  167.     XRA    A    ; ERROR INDICATOR
  168.     POP    D    ; RESTORE DE
  169.     RET
  170.  
  171. ;  EXTRACT FILE NAME
  172. GETF1:
  173.     POP    H    ; GET PTR TO BYTE
  174. GETFILE:
  175.     XCHG        ; GET PTR TO FCB
  176.     LHLD    FCBPTR
  177.     XCHG        ; HL PTS TO TARGET STRING, DE PTS TO FCB
  178.     MOV    A,M    ; PTING TO COLON?
  179.     CPI    ':'
  180.     JNZ    GFILE1
  181.     INX    H    ; SKIP OVER COLON
  182. GFILE1:
  183.     CALL    DELCK    ; GET NEXT CHAR AND CHECK FOR A DELIMITER
  184.     JNZ    GFILE2    ; PROCESS SINCE NOT A DELIMITER
  185.     CPI    '.'    ; WAS DELIMITER A '.'?
  186.     JZ    GFILE2    ; PROCESS SINCE FN MISSING
  187. ;  NO NAME SPECIFIED, SO MAKE IT WILD
  188. GFQUES:
  189.     INX    D    ; FILL WITH '?'
  190.     MVI    B,11    ; 11 BYTES
  191.     MVI    A,'?'
  192. GFFILL:
  193.     STAX    D    ; PUT ?
  194.     INX    D    ; PT TO NEXT
  195.     DCR    B    ; COUNT DOWN
  196.     JNZ    GFFILL
  197. ;  EXIT ZFNAME
  198. FNDONE:
  199.     LDA    DISK    ; GET DISK NUMBER
  200.     CPI    0FFH    ; CURRENT DISK?
  201.     JZ    FNDN1
  202.     INR    A    ; ADD 1 SO IN THE RANGE FROM 1 TO 16
  203. FNDN1:
  204.     MOV    B,A    ; ... IN B
  205.     LDA    USER    ; GET USER NUMBER
  206.     MOV    C,A    ; ... IN C
  207.     POP    D    ; RESTORE REGS
  208.     MVI    A,0FFH    ; NO ERROR
  209.     ORA    A    ; SET FLAGS
  210.     RET
  211. ;  GET FILE NAME FIELDS
  212. GFILE2:
  213.     MVI    B,8    ; AT MOST 8 BYTES FOR FN
  214.     CALL    SCANF    ; SCAN AND FILL
  215.     MVI    B,3    ; AT MOST 3 BYTES FOR FT
  216.     MOV    A,M    ; GET DELIMITER
  217.     CPI    '.'    ; FN ENDING IN '.'?
  218.     JNZ    GFILE3
  219.     INX    H    ; PT TO CHAR AFTER '.'
  220.     CALL    SCANF    ; SCAN AND FILL
  221.     JMP    FNDONE    ; DONE ... RETURN ARGS
  222. ;  FT FIELD NOT GIVEN, SO <SP> FILL FT FIELD IN FCB
  223. GFILE3:
  224.     CALL    SCANF4    ; FILL WITH <SP>
  225.     JMP    FNDONE
  226. ;
  227. ;  SCANNER ROUTINE
  228. ;
  229. SCANF:
  230.     CALL    DELCK    ; CHECK FOR DELIMITER
  231.     JZ    SCANF4    ; <SP> FILL IF FOUND
  232.     INX    D    ; PT TO NEXT BYTE IN FN
  233.     CPI    '*'    ; ? FILL?
  234.     JNZ    SCANF1
  235.     MVI    A,'?'    ; PLACE '?'
  236.     STAX    D
  237.     JMP    SCANF2
  238. SCANF1:
  239.     STAX    D    ; PLACE CHAR
  240.     INX    H    ; PT TO NEXT POSITION
  241. SCANF2:
  242.     DCR    B    ; COUNT DOWN
  243.     JNZ    SCANF    ; CONTINUE LOOP
  244. SCANF3:
  245.     CALL    DELCK    ; "B" CHARS OR MORE - SKIP TO DELIMITER
  246.     RZ
  247.     INX    H    ; PT TO NEXT
  248.     JMP    SCANF3
  249. SCANF4:
  250.     INX    D    ; PT TO NEXT FN OR FT
  251.     MVI    A,' '    ; <SP> FILL
  252.     STAX    D
  253.     DCR    B    ; COUNT DOWN
  254.     JNZ    SCANF4
  255.     RET
  256.  
  257. ;*
  258. ;*  ZDNAME -- LOAD THE CONTENTS OF THE NAMES.DIR FILE INTO THE MEMORY
  259. ;*    BUFFER PTED TO BY HL
  260. ;*    ON ENTRY, HL PTS TO THE MEMORY BUFFER EXTENDING TO THE BASE OF
  261. ;*        THE BDOS
  262. ;*    ON EXIT, HL PTS TO THE FIRST ENTRY IN THE NAMES.DIR FILE, BC IS
  263. ;*        THE NUMBER OF VALID ENTRIES, A IS THE ERROR FLAG (A=0FFH
  264. ;*        AND NZ IF NO ERROR, A=0 AND Z IF ERROR)
  265. ;*            ERRORS MAY BE EITHER MEMORY OVERFLOW OR NAMES.DIR
  266. ;*            NOT FOUND
  267. ;*    EACH NAMES.DIR ENTRY IS 10 BYTES LONG, STRUCTURED AS FOLLOWS:
  268. ;*        BYTE 0: DISK NUMBER (A=0)
  269. ;*        BYTE 1: USER NUMBER
  270. ;*        BYTES 2-9: DIRECTORY NAME, 8 CHARS MAX, <SP> FILL AT END
  271. ;*
  272. ZDNAME::
  273.     PUSH    D    ; SAVE UNCHANGED REG
  274.     SHLD    DIRNAME    ; SAVE PTR TO BUFFER
  275.     SHLD    CURNAME    ; SAVE PTR TO FIRST ENTRY
  276.     LXI    D,FNFCB    ; PT TO FCB WHICH CONTAINS DIR FILE NAME
  277.     CALL    INITFCB    ; INIT FCB
  278.     MVI    B,0FFH    ; SEARCH CURRENT USER
  279.     CALL    ZPFIND    ; LOOK FOR NAMES.DIR FILE
  280.     JZ    DIRNERR    ; FILE NOT FOUND ERROR
  281. ;
  282. ;  FOUND NAMES.DIR, SO LOAD IT
  283. ;
  284.     CALL    PUTUD    ; SAVE CURRENT USER/DISK
  285.     CALL    LOGUD    ; LOG IN NEW USER/DISK
  286.     LXI    D,FNFCB    ; PT TO FCB
  287.     CALL    FI3$OPEN    ; OPEN FOR INPUT
  288. ;
  289. ;  LOAD NAMES.DIR FILE
  290. ;
  291.     MVI    C,0    ; SET ENTRY COUNT
  292.     LDA    MAXN    ; GET MAX NUMBER OF NAMES
  293.     MOV    B,A    ; ... IN B
  294. ZDNA1:
  295.     LXI    H,ENTRY    ; PT TO ENTRY BUFFER
  296.     CALL    GETNAME    ; GET NAME FROM DISK
  297.     JNZ    ZDNA3    ; DONE?
  298.     LDA    ENTRY+2    ; LOOK AT FIRST LETTER OF DIR NAME
  299.     ORA    A    ; NO ENTRY?
  300.     JZ    ZDNA2
  301.     LHLD    DIRNAME    ; PT TO BUFFER ENTRY
  302.     LXI    D,ENTRY    ; PT TO NEW ENTRY
  303.     INR    C    ; INCREMENT ENTRY COUNTER
  304.     PUSH    B    ; SAVE COUNTERS
  305.     XCHG        ; HL PTS TO NEW ENTRY, DE PTS TO DEST
  306.     MOV    A,M    ; GET DISK NUMBER
  307.     STAX    D    ; STORE DISK NUMBER
  308.     INX    H    ; PT TO USER NUMBER
  309.     INX    D
  310.     MOV    A,M    ; GET USER
  311.     STAX    D    ; PUT USER
  312.     MVI    B,8    ; AT MOST 8 MORE BYTES
  313. ZDNA1A:
  314.     INX    H    ; PT TO NEXT BYTE
  315.     INX    D
  316.     MOV    A,M    ; GET NEXT BYTE
  317.     ORA    A    ; END OF NAME?
  318.     JZ    ZDNA1B    ; <SP> FILL
  319.     STAX    D    ; PUT BYTE
  320.     DCR    B    ; COUNT DOWN
  321.     JNZ    ZDNA1A
  322.     INX    D    ; PT TO FIRST BYTE OF NEXT ENTRY
  323.     JMP    ZDNA1C
  324. ZDNA1B:
  325.     MVI    A,' '    ; <SP> FILL
  326.     STAX    D    ; PLACE <SP>
  327.     INX    D    ; PT TO NEXT
  328.     DCR    B    ; COUNT DOWN
  329.     JNZ    ZDNA1B
  330. ZDNA1C:
  331.     POP    B    ; RESTORE COUNTERS
  332.     LHLD    BENTRY+1    ; PT TO BDOS ADDRESS
  333.     MOV    A,H    ; CHECK FOR PAGE BEFORE BDOS
  334.     DCR    A    ; PAGE BEFORE
  335.     CMP    D    ; ARE WE THERE?
  336.     JZ    DNSC2    ; ERROR IF SO, BUT RESTORE UD
  337.     JC    DNSC2
  338.     XCHG        ; HL PTS TO NEXT BUFFER POSITION
  339.     SHLD    DIRNAME    ; SAVE PTR
  340. ;
  341. ;  CONTINUE LOOPING
  342. ;
  343. ZDNA2:
  344.     DCR    B    ; COUNT DOWN
  345.     JNZ    ZDNA1
  346. ;
  347. ;  COMPLETION EXIT
  348. ;
  349. ZDNA3:
  350.     CALL    GETUD    ; RESTORE USER/DISK
  351.     MVI    B,0    ; SET HIGH-ORDER BYTE
  352.     LHLD    CURNAME    ; GET PTR TO FIRST ENTRY
  353.     MVI    A,0FFH    ; SET NO ERROR
  354.     ORA    A    ; SET FLAGS
  355.     POP    D    ; RESTORE DE
  356.     RET
  357.  
  358. ;*
  359. ;*  ZDNFIND -- SCAN FOR POSSIBLE DISK DIRECTORY NAME
  360. ;*    THIS ROUTINE EXAMINES THE DIR: PREFIX FOR EITHER A DIRECTORY NAME
  361. ;*        OR THE DU FORM
  362. ;*    ON ENTRY, HL PTS TO DIRECTORY NAME ENDING IN ANY VALID DELIMITER
  363. ;*        AND A=0 IF DU: FORM NOT ALLOWED (JUST DIR: FORM ALLOWED)
  364. ;*    RETURN DISK IN B, USER IN C, NZ IF OK, HL PTS TO COLON
  365. ;*    DE IS NOT AFFECTED
  366. ;*
  367. ZDNFIND::
  368.     PUSH    D    ; SAVE DE
  369.     SHLD    DIRNAME    ; SAVE DIRECTORY NAME AWAY
  370.     ORA    A    ; DU: FORM ALLOWED?
  371.     JNZ    SVDISK    ; SCAN FOR DU: FORM FIRST
  372. ;
  373. ;  LOOK FOR DIR: FORM
  374. ;
  375. NAME:
  376.     LXI    D,FNFCB    ; PT TO FCB WHICH CONTAINS DIR FILE NAME
  377.     CALL    INITFCB    ; INIT FCB
  378. ;
  379. ;  LOOK FOR DIR NAME FILE
  380. ;
  381.     LHLD    DIRNAME    ; PT TO DIRECTORY NAME
  382.     MVI    B,0FFH    ; SEARCH CURRENT USER
  383.     CALL    ZPFIND    ; LOOK FOR NAME FILE
  384.     JZ    DIRNERR    ; ERROR IF NOT FOUND
  385. ;
  386. ;  FOUND DIR NAME FILE, SO LOAD IT AND SCAN IT FOR TARGET NAME
  387. ;
  388.     CALL    PUTUD    ; SAVE CURRENT USER/DISK
  389.     CALL    LOGUD    ; LOG IN NEW USER/DISK
  390.     LXI    D,FNFCB    ; PT TO FCB
  391.     CALL    FI3$OPEN    ; OPEN FOR INPUT
  392. ;
  393. ;  LOAD DIR NAME FILE ENTRIES
  394. ;
  395.     LDA    MAXN    ; GET MAXIMUM NUMBER OF NAMES
  396.     MOV    B,A    ; ... IN B
  397. DNSC1:
  398.     LXI    H,ENTRY    ; PT TO ENTRY BUFFER
  399.     CALL    GETNAME    ; GET NAME FROM DISK
  400.     JNZ    DNSC2    ; ERROR EXIT?
  401.     CALL    SCANAME    ; SCAN FOR DIR NAME
  402.     JZ    DNSC3    ; FOUND ENTRY, SO GET VALUES
  403.     DCR    B    ; COUNT DOWN
  404.     JNZ    DNSC1
  405. DNSC2:
  406.     CALL    GETUD    ; RESTORE CURRENT USER/DISK
  407.     JMP    DIRNERR    ; ERROR SINCE NO ENTRY FOUND
  408. ;
  409. ;  DIR NAME FOUND, SO GET DISK AND USER INFORMATION
  410. ;
  411. DNSC3:
  412.     CALL    GETUD    ; RESTORE CURRENT USER/DISK
  413.     MOV    A,M    ; GET DISK (HL PTS TO CURRENT ENTRY)
  414.     STA    DISK    ; SAVE DISK
  415.     INX    H    ; PT TO USER
  416.     MOV    A,M    ; GET USER
  417.     STA    USER    ; SAVE USER
  418. ;
  419. ;  SKIP TO COLON AFTER DIR NAME
  420. ;
  421.     LHLD    DIRNAME    ; PT TO DIR NAME
  422. DNSC4:
  423.     CALL    DELCK    ; SKIP TO DELIMITER
  424.     JZ    DIRNX    ; EXIT IF SO
  425.     INX    H    ; PT TO NEXT
  426.     JMP    DNSC4
  427. ;
  428. ;  LOOK AT START OF DU: FORM
  429. ;    ON ENTRY, HL PTS TO FIRST CHAR OF DIRECTORY NAME
  430. ;
  431. SVDISK:
  432.     MOV    A,M    ; GET DISK LETTER
  433.     CALL    CAPS    ; CAPITALIZE LETTER
  434.     CPI    'A'    ; DIGIT?
  435.     JC    USERCK    ; IF NO DIGIT, MUST BE USER OR COLON
  436.     SUI    'A'    ; CONVERT TO NUMBER
  437.     CPI    MAXDISK    ; LIMIT?
  438.     JNC    NAME    ; NAME IF OUT OF LIMIT
  439.     STA    DISK    ; SAVE FLAG
  440.     INX    H    ; PT TO NEXT CHAR
  441. ;
  442. ;  CHECK FOR USER
  443. ;
  444. USERCK:
  445.     MOV    A,M    ; GET POSSIBLE USER NUMBER
  446.     CPI    ':'    ; NO USER NUMBER
  447.     JZ    DIRNX    ; EXIT IF SO
  448.     CPI    '?'    ; ALL USER NUMBERS?
  449.     JNZ    USERC1
  450.     STA    USER    ; SET VALUE
  451.     INX    H    ; PT TO AFTER
  452.     MOV    A,M    ; MUST BE COLON
  453.     CPI    ':'
  454.     JZ    DIRNX    ; EXIT
  455.     JMP    DIRNERR    ; FATAL ERROR IF NOT COLON AFTER ?
  456. USERC1:
  457.     XRA    A    ; ZERO USER NUMBER
  458.     MOV    B,A    ; B=ACCUMULATOR FOR USER NUMBER
  459. USRLOOP:
  460.     MOV    A,M    ; GET DIGIT
  461.     INX    H    ; PT TO NEXT
  462.     CPI    ':'    ; DONE?
  463.     JZ    USRDN
  464.     SUI    '0'    ; CONVERT TO BINARY
  465.     JC    NAME    ; NAME IF USER NUMBER ERROR
  466.     CPI    10
  467.     JNC    NAME
  468.     MOV    C,A    ; NEXT DIGIT IN C
  469.     MOV    A,B    ; OLD NUMBER IN A
  470.     ADD    A    ; *2
  471.     ADD    A    ; *4
  472.     ADD    B    ; *5
  473.     ADD    A    ; *10
  474.     ADD    C    ; *10+NEW DIGIT
  475.     MOV    B,A    ; RESULT IN B
  476.     JMP    USRLOOP
  477. USRDN:
  478.     MOV    A,B    ; GET NEW USER NUMBER
  479.     CPI    MAXUSER    ; WITHIN RANGE?
  480.     JNC    NAME    ; NAME IF OUT OF RANGE
  481.     STA    USER    ; SAVE IN FLAG
  482. ;
  483. ;  VALID EXIT -- FOUND IT, SO LOAD BC AND EXIT FLAG; ON ENTRY, HL PTS TO :
  484. ;
  485. DIRNX:
  486.     LDA    USER    ; RETURN USER IN C, DISK IN B
  487.     MOV    C,A
  488.     LDA    DISK
  489.     MOV    B,A
  490.     INR    B    ; DISK A = 1
  491.     MVI    A,0FFH    ; SET NO ERROR
  492.     ORA    A    ; SET FLAGS
  493.     POP    D    ; RESTORE DE
  494.     RET
  495. ;
  496. ;  INVALID EXIT -- NOT FOUND OR ERROR
  497. ;    NO VALID RETURN PARAMETERS (BC, HL)
  498. ;
  499. DIRNERR:
  500.     XRA    A    ; ERROR CODE
  501.     POP    D    ; RESTORE DE
  502.     RET
  503.  
  504. ;*
  505. ;*  BUFFERS
  506. ;*
  507. FCBPTR:    DS    2    ; PTR TO FCB
  508. DISK:    DS    1    ; DISK NUMBER
  509. USER:    DS    1    ; USER NUMBER
  510. ENTRY:
  511.     DS    11    ; ENTRY FROM DISK FILE (DISK, USER, DIR NAME)
  512. DIRNAME:
  513.     DS    2    ; PTR TO DIRECTORY NAME
  514. CURNAME:
  515.     DS    2    ; PTR TO CURRENT LOCATED NAME
  516.  
  517. ;
  518. ;  SCAN DIRECTORY ENTRY PTED TO BY HL FOR DIRECTORY NAME STARTING AT DIRNAME
  519. ;    RETURN WITH Z IF FOUND; DO NOT AFFECT BC
  520. ;
  521. SCANAME:
  522.     PUSH    B    ; SAVE BC
  523.     SHLD    CURNAME    ; SET CURRENT NAME PTR
  524.     INX    H    ; SKIP DISK
  525.     INX    H    ; SKIP USER
  526.     MVI    B,9    ; UP TO 9 CHARS
  527.     XCHG        ; CURRENT PTR IN DE
  528.     LHLD    DIRNAME    ; PT TO TARGET NAME
  529. SCANL:
  530.     LDAX    D    ; GET CHAR
  531.     ORA    A    ; END OF STRING?
  532.     JZ    SCANL2
  533.     MOV    C,A    ; SAVE IN C
  534.     MOV    A,M    ; GET TARGET NAME CHAR
  535.     CALL    CAPS    ; CAPITALIZE IT
  536.     CMP    C    ; COMPARE
  537.     JNZ    SCANL1    ; ABORT IF NO MATCH
  538.     CALL    DELCK    ; END OF TARGET NAME?
  539.     JZ    SCANL1    ; ABORT IF SO
  540.     INX    H    ; PT TO NEXT
  541.     INX    D
  542.     DCR    B    ; COUNT DOWN
  543.     JNZ    SCANL
  544. ;  NOT FOUND RETURN
  545. SCANL1:
  546.     LHLD    CURNAME    ; PT TO CURRENT ENTRY
  547.     LXI    B,11    ; SKIP 11 BYTES
  548.     DAD    B    ; PT TO NEXT ENTRY
  549.     POP    B    ; RESTORE BC
  550.     MVI    A,0FFH    ; NOT FOUND FLAG
  551.     ORA    A    ; SET FLAGS
  552.     RET
  553. ;  FOUND RETURN
  554. SCANL2:
  555.     CALL    DELCK    ; MUST PT TO DELIMITER IF MATCH
  556.     JNZ    SCANL1    ; ABORT IF NOT
  557.     LHLD    CURNAME    ; PT TO FOUND ENTRY
  558.     POP    B    ; RESTORE BC
  559.     XRA    A    ; FOUND
  560.     RET    
  561.  
  562. ;
  563. ;  GET NAME FROM FILE 3 INTO BUFFER PTED TO BY HL
  564. ;    DO NOT AFFECT BC OR HL; RET W/NZ IF ERROR
  565. ;
  566. GETNAME:
  567.     PUSH    B    ; SAVE BC
  568.     PUSH    H    ; SAVE HL
  569.     CALL    F3$GET    ; GET DISK LETTER
  570.     JNZ    GNERR    ; ERROR?
  571.     SUI    'A'    ; CONVERT TO NUMBER
  572.     MOV    M,A    ; STORE IT
  573.     INX    H    ; PT TO NEXT
  574.     MVI    B,10    ; GET USER AND DIRECTORY NAME
  575. GETN1:
  576.     CALL    F3$GET    ; GET BYTE
  577.     JNZ    GNERR    ; ERROR?
  578.     MOV    M,A    ; STORE IT
  579.     INX    H    ; PT TO NEXT
  580.     DCR    B    ; COUNT DOWN
  581.     JNZ    GETN1
  582.     XRA    A    ; OK
  583. GNERR:
  584.     POP    H    ; RESTORE HL
  585.     POP    B    ; RESTORE BC
  586.     RET
  587.  
  588. ;
  589. ;  CHECK CHAR PTED TO BY HL FOR A DELIMITER
  590. ;    RET WITH Z FLAG SET IF DELIMITER
  591. ;
  592. DELCK:
  593.     MOV    A,M    ; GET CHAR
  594.     CALL    CAPS    ; CAPITALIZE
  595.     ORA    A    ; 0=DELIM
  596.     RZ
  597.     CPI    ' '+1    ; <SP>+1
  598.     JC    DELCK1    ; <SP> OR LESS
  599.     CPI    '='
  600.     RZ
  601.     CPI    5FH    ; UNDERSCORE
  602.     RZ
  603.     CPI    '.'
  604.     RZ
  605.     CPI    ':'
  606.     RZ
  607.     CPI    ';'
  608.     RZ
  609.     CPI    ','
  610.     RZ
  611.     CPI    '<'
  612.     RZ
  613.     CPI    '>'
  614.     RET
  615. DELCK1:
  616.     CMP    M    ; COMPARE WITH SELF FOR OK
  617.     RET
  618.  
  619. ;
  620. ;  PUTUD -- SAVE CURRENT USER/DISK FOR LATER RESTORE
  621. ;    NO REGS AFFECTED
  622. ;
  623. PUTUD:
  624.     PUSH    B    ; SAVE REGS
  625.     PUSH    PSW
  626.     PUSH    D
  627.     PUSH    H
  628.     MVI    C,25    ; GET CURRENT DISK
  629.     CALL    BDOS
  630.     STA    CDISK    ; SET CURRENT DISK
  631.     MVI    E,0FFH    ; GET USER
  632.     MVI    C,32    ; GET CURRENT USER
  633.     CALL    BDOS
  634.     STA    CUSER    ; SET CURRENT USER
  635.     POP    H    ; RESTORE REGS
  636.     POP    D
  637.     POP    PSW
  638.     POP    B
  639.     RET
  640.  
  641. ;
  642. ;  BUFFERS
  643. ;
  644. CDISK:
  645.     DS    1    ; CURRENT DISK
  646. CUSER:
  647.     DS    1    ; CURRENT USER
  648.  
  649. ;
  650. ;  GETUD -- RESTORE USER/DISK FROM PREVIOUS PUTUD
  651. ;
  652. GETUD:
  653.     PUSH    H    ; SAVE REGS
  654.     PUSH    D
  655.     PUSH    B
  656.     PUSH    PSW
  657.     LDA    CDISK    ; SELECT DISK
  658.     MOV    E,A
  659.     MVI    C,14    ; SELECT
  660.     CALL    BDOS
  661.     LDA    CUSER    ; SELECT USER
  662.     MOV    E,A
  663.     MVI    C,32    ; SELECT
  664.     CALL    BDOS
  665. DONE:
  666.     POP    PSW    ; GET REGS
  667.     POP    B
  668.     POP    D
  669.     POP    H
  670.     RET
  671.  
  672. ;
  673. ;  LOGUD -- LOG IN USER/DISK, WHICH C=USER AND B=DISK
  674. ;
  675. LOGUD:
  676.     PUSH    H    ; SAVE REGS
  677.     PUSH    D
  678.     PUSH    B
  679.     PUSH    PSW
  680.     MOV    E,C    ; SELECT USER
  681.     MVI    C,32
  682.     CALL    BDOS
  683.     MOV    E,B    ; SELECT DISK
  684.     MVI    C,14
  685.     CALL    BDOS
  686.     JMP    DONE
  687.  
  688.     END
  689.