home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / trs80model4 / m4wild.asm < prev    next >
Assembly Source File  |  1986-10-21  |  13KB  |  449 lines

  1. ;        m4wild/asm
  2. ;
  3. ;    Build a list of filenames given a list of arbitrary names
  4. ;    pointed to by HL.  Wild card processing is done here.
  5. ;
  6. ;    The resulting blank separated list is returned in HL.  The
  7. ;    number of names put into the buffer is indicated by the
  8. ;    count in FILECNT.  This is a byte valued count, so 255 is
  9. ;    the maximum number possible.
  10. ;
  11. BUILDF        EQU    $
  12.         LD    (SRCPTR),HL    ;Save the source input pointer
  13.         LD    HL,FILEBUFF    ;Set the pointer to the matches
  14.         LD    (FBPTR),HL    ;buffer where all matches go
  15.         XOR    A        ;Set number of files found to 0
  16.         LD    (FILECNT),A
  17. BF_0        EQU    $
  18.         LD    HL,(SRCPTR)    ;Get the input string
  19.         LD    BC,0        ;Get zero
  20.         LD    (SYSFLAG),BC    ;No system files
  21.         LD    (INVFLAG),BC    ;No invisible files
  22.         XOR    A        ;Reset response values
  23.         LD    (INVRESP),A
  24.         LD    (SYSRESP),A
  25.         LD    A,' '
  26. BF_A        IFANOT    (HL),BF_B
  27.         INC    HL
  28.         JR    BF_A
  29. ;
  30. BF_B        LD    DE,PARMS    ;Get the parse table
  31.         CALL    XPARAM        ;Do @PARAM SVC
  32.         JR    Z,BF_D        ;Jump if parse ok
  33. BF_C        STROUT    BADPARM        ;Print error message
  34.         JP    KERMIT        ;Abort!
  35. ;
  36. BF_D        LD    A,(SYSRESP)    ;Get the system response
  37.         AND    0A0H        ;Valid?
  38.         JR    NZ,BF_C        ;Jump if not
  39.         LD    A,(INVRESP)    ;Check invisble flag
  40.         AND    0A0H        ;Valid?
  41.         JR    NZ,BF_C        ;Jump if not
  42.         LD    A,' '        ;Get a space to compare with
  43. BF_E        IFANOT    (HL),BF_F    ;Jump if not space
  44.         INC    HL
  45.         JR    BF_E
  46. ;
  47. BF_F        LD    B,32        ;Move 32 characters, MAX
  48.         LD    DE,TFBUF    ;Get the temporary buffer
  49. BF_1        LD    A,(HL)        ;Get a character
  50.         IFALT    ' '+1,BF_2    ;Jump if at end of this filename
  51.         CALL    CPTAL        ;Capitalize it
  52.         LD    (DE),A        ;Save the new character
  53.         INC    DE        ;Increment the pointers
  54.         INC    HL
  55.         DJNZ    BF_1        ;Loop until done
  56. BF_2        XOR    A        ;Terminate the string with a zero
  57.         LD    (DE),A        ;Put in a terminator
  58. BF_3        LD    A,(HL)        ;Get the next character
  59.         IFAGE    ' '+1,BF_4    ;Jump if not separator
  60.         IFA    CR,BF_4        ;Jump if end of string
  61.         INC    HL        ;Skip the separator
  62.         JR    BF_3        ;Loop on
  63. ;
  64. BF_4        LD    (SRCPTR),HL    ;Save the next string pointer
  65.         LD    A,32        ;Get the max length
  66.         SUB    B        ;Compute length
  67.         LD    (FNLEN),A    ;Save it
  68.         JP    Z,BF_18        ;Exit if no more names
  69.         LD    A,1        ;Initially check all drives
  70.         LD    (MOREDRV),A    ;Set the flag
  71.         DEC    DE        ;Check if '/' last character
  72.         EX    DE,HL        ;Put it in HL
  73.         LD    A,(HL)        ;Get the character
  74.         IFANOT    '/',BF_5    ;Is it a '/'
  75.         LD    (HL),0        ;Remove the trailing slash
  76. BF_5        LD    HL,TFBUF    ;Look for a drive specification
  77.         LD    A,(FNLEN)    ;Get the length
  78.         LD    C,A        ;Make BC a 16 bit copy of A
  79.         LD    B,0
  80.         ADD    HL,BC        ;Compute end of name plus one
  81.         DEC    HL        ;Backup to possible drive number
  82.         DEC    C        ;Decrement the counter
  83.         JR    Z,BF_7        ;Jump if no characters left
  84.         DEC    HL        ;Backup to possible ':' separator
  85.         DEC    C        ;Decrement counter
  86.         JR    Z,BF_7        ;Jump no characters left
  87.         LD    A,(HL)        ;Get a possible ':'
  88.         IFANOT    ':',BF_7    ;Jump if not drive spec
  89.         LD    (HL),0        ;Terminate with no drive number
  90.         INC    HL        ;Point back at drive number
  91.         LD    A,(HL)        ;Get the drive number
  92.         LD    HL,FNLEN    ;Change the length
  93.         DEC    (HL)
  94.         DEC    (HL)
  95.         SUB    '0'        ;Make the drive number binary
  96.         LD    C,A        ;Save the drive to check
  97.         XOR    A
  98.         LD    (MOREDRV),A    ;No more drives to check
  99.         JR    BF_8
  100. ;
  101. BF_7        EQU    $
  102.         XOR    A        ;Zero A
  103.         LD    C,A        ;Set drive number to zero
  104. BF_8        EQU    $
  105.         PUSH    BC        ;Save the current drive number
  106.         CALL    XCHKDRV        ;Check this drive
  107.         JP    NZ,BF_17    ;Jump if drive not ready
  108.         LD    HL,DIRSPEC    ;Get the source of 'DIR/SYS'
  109.         LD    DE,DIRFCB    ;Put it here
  110.         LD    BC,DLEN        ;Move this many characters
  111.         LDIR            ;Copy the name
  112.         POP    BC        ;Get the drive number
  113.         PUSH    BC        ;Put it back
  114.         LD    A,C        ;Put it into A
  115.         ADD    A,'0'        ;Make it printable
  116.         LD    (DIRDRV),A    ;Set the drive number
  117.         LD    (SDIRDRV),A    ;Save the current drive
  118.         LD    A,CR        ;Get a EOL marker
  119.         LD    (DIRDRV+1),A    ;Put in a terminator
  120.         LD    HL,DIRBUFF    ;Get the buffer
  121.         LD    B,0        ;LRECL = 256
  122.         LD    DE,DIRFCB    ;Get the FCB
  123.         CALL    XOPEN        ;Try to open the directory
  124.         JP    NZ,BF_19    ;Jump on open error
  125.         LD    DE,DIRFCB    ;Get the FCB
  126.         CALL    XSKIP        ;Skip HIT and GAT
  127.         CALL    XSKIP
  128. BF_9        EQU    $
  129.         LD    HL,DIRBUFF    ;Get the data buffer
  130.         LD    DE,DIRFCB    ;Get the FCB
  131.         CALL    XREAD        ;Read a record
  132.         JP    NZ,BF_15    ;Jump if can't read anymore
  133.         LD    B,8        ;Number of dir entries
  134.         LD    HL,DIRBUFF    ;Get the starting data
  135. BF_10        PUSH    BC        ;Save the counter
  136.         BIT    4,(HL)        ;Check for used directory record
  137.         JR    Z,BF_12        ;Jump entry not in use
  138.         BIT    7,(HL)        ;Check if FPDE
  139.         JR    NZ,BF_12    ;Jump if extent or other
  140.         LD    A,(SYSFLAG)    ;Check is system file valid
  141.         IFNZ    BF_10A        ;Jump if system OK
  142.         BIT    6,(HL)        ;Is it a system file
  143.         JR    NZ,BF_12    ;Skip it if it is
  144. BF_10A        LD    A,(INVFLAG)    ;Is invisible file valid?
  145.         IFNZ    BF_10B        ;Jump if invisble ok (no check)
  146.         BIT    3,(HL)        ;Is the file invisible?
  147.         JR    NZ,BF_12    ;Skip it if it is
  148. BF_10B        LD    DE,TFBUF    ;Get the pattern to match
  149.         LD    A,1
  150.         LD    (HASWILD),A    ;Set wild cards present flag
  151.         CALL    ISWILD        ;Check if it really is
  152.         JR    Z,BF_11        ;Jump if there are wild cards
  153.         XOR    A
  154.         LD    (HASWILD),A    ;Reset has wild cards flag
  155. BF_11        EQU    $
  156.         CALL    MATCH        ;See if it matches
  157.         JR    NZ,BF_12
  158.         CALL    COPYFILE    ;Copy it if it matches
  159.         LD    A,(HASWILD)    ;Check if should check others
  160.         IFNZ    BF_12        ;Jump if wild, might be more
  161.         POP    BC        ;Otherwise, no wild, so keep only
  162.         POP    BC        ;the first match as in TRSDOS's
  163.         JP    BF_0        ;normal drive search algorithm
  164. ;
  165. BF_12        LD    BC,32        ;Get the length of a DIR record
  166.         ADD    HL,BC        ;Point to next
  167.         POP    BC        ;Restore the number of entries
  168.         DJNZ    BF_10        ;Decrement and loop if not end
  169.         JR    BF_9        ;Try next drive
  170. ;
  171. ;    Control comes to here on an error in the call to @READ.  Check
  172. ;    to make sure it is EOF, and print an error message if not.
  173. ;
  174. BF_15        EQU    $
  175.         CP    28        ;Check for end of file
  176.         JR    Z,BF_16        ;Jump if end of file
  177.         CALL    XERROR0        ;Print the error message
  178.         LD    DE,DIRFCB    ;Close the open file
  179.         CALL    XCLOSE
  180.         JP    KERMIT        ;Abort completely
  181. ;
  182. BF_16        EQU    $
  183.         LD    DE,DIRFCB    ;Close the directory
  184.         CALL    XCLOSE        ;Closed
  185.         JP    NZ,BFCLSERR    ;Jump if close error
  186. BF_17        EQU    $
  187.         POP    BC        ;Restore drive number
  188.         INC    C        ;Next drive
  189.         LD    A,8        ;Get max drive number (plus 1)
  190.         CP    C        ;Get next name if no more drvs
  191.         JP    Z,BF_0        ;Go get next name if end
  192.         LD    A,(MOREDRV)    ;See if should check other drvs
  193.         OR    A        ;Check for zero
  194.         JP    NZ,BF_8        ;If set, then no drive spec so go
  195.         JP    BF_0        ;Get the next filename in list
  196. ;
  197. ;    At the end of processing, we update the end of the list of names,
  198. ;    and return the pointer to the start of the list in HL.
  199. ;
  200. BF_18        EQU    $
  201.         LD    HL,(FBPTR)    ;Get the pointer
  202.         LD    (HL),CR        ;Terminate the string
  203.         LD    HL,FILEBUFF    ;Return the start of the list
  204.         RET
  205. ;
  206. ;    Control comes to here on a directory open error.  Print the error
  207. ;    message, and then go check next drive.
  208. ;
  209. BF_19        EQU    $
  210.         CALL    XERROR0
  211.         JR    BF_17
  212. ;
  213. ;    Control comes to here if CLOSE on DIR/SYS fails.
  214. ;
  215. BFCLSERR    EQU    $
  216.         CALL    XERROR0        ;Print the error message
  217.         JP    KERMIT        ;Return to command level
  218. ;
  219. ;    Do a wild card match on the 2 strings pointed to by
  220. ;    HL, and DE.  DE points at the pattern containing possible
  221. ;    wild card characters.  HL points at the start of a TRSDOS
  222. ;    complete directory record.  HL must be moved to the start
  223. ;    of the filename.  The filename HL points to has up to 11
  224. ;    characters in it.  The first 8 are the filename, the last
  225. ;    3 are the extension.  Both are left justified within their
  226. ;    respective fields, with blanks as fill.
  227. ;
  228. MATCH        EQU    $
  229.         PUSH    BC        ;Save BC
  230.         PUSH    HL        ;Save HL
  231.         PUSH    DE        ;Save DE
  232.         LD    BC,5        ;Move HL to filename field
  233.         ADD    HL,BC        ;Move the pointer
  234. ;
  235. ;    We must now convert the filename in the directory record
  236. ;    to have the '/' in it.  I.E. the entry may look like:
  237. ;
  238. ;        DIR+5                     DIR+15
  239. ;        +-+-+-+-+-+-+-+-+-+-+-+
  240. ;        |F|I|L|E| | | | |C| | |
  241. ;        +-+-+-+-+-+-+-+-+-+-+-+
  242. ;
  243. ;    So we must make the name be FILE/C
  244. ;
  245.         LD    DE,COMPNAME    ;Get the destination
  246.         LD    BC,0B30H    ;Number of characters to move
  247. ;
  248. ;    Note that C has a big enough value in it to keep the LDI
  249. ;    below from changing B which is the loop counter.
  250. ;
  251. MATCH_1        LD    A,(HL)        ;See if at the end of name
  252.         INC    HL        ;Point a head in case ' ' is next
  253.         IFA    ' ',MATCH_3    ;Skip spaces if at one
  254.         DEC    HL        ;Move back, valid character
  255.         LD    A,B        ;Check if time for '/'
  256.         IFANOT    3,MATCH_2    ;If B is 3, then put in a '/'
  257.         LD    A,'/'        ;Get the '/'
  258.         LD    (DE),A        ;Put it in the destination
  259.         INC    DE        ;Point to next position
  260. MATCH_2        LDI            ;Move the current character
  261. MATCH_3        DJNZ    MATCH_1        ;Loop until all moved
  262.         XOR    A        ;Put in a terminating NULL
  263.         LD    (DE),A
  264.         POP    DE        ;Get the wild card pattern back
  265.         PUSH    DE        ;Save it again
  266.         LD    HL,COMPNAME    ;Get the name to compare against
  267. ;
  268. ;    Now the matching process starts
  269. ;
  270. ;    From C-Kermit's wild carding, this is the function match()
  271. ;    HL is string, DE is pattern.  There are some things different
  272. ;    here, but this is mostly a line by line translation.
  273. ;
  274. ;
  275.         LD    A,(HL)        ;Check for null strings
  276.         IFZ    NOMATCH        ;Return if no match
  277.         LD    A,(DE)        ;Check for null pattern
  278.         IFZ    NOMATCH        ;Return if no match
  279. ;
  280.         LD    (SPAT),DE    ;Save current pattern spot
  281.         LD    (SSTR),HL    ;Save current string spot
  282.         LD    HL,0        ;Reset the 2 pointers
  283.         LD    (PSAVE),HL
  284.         LD    (SSAVE),HL
  285. ;
  286. MATCH_6        EQU    $
  287.         LD    HL,(SSTR)    ;Get the pointer
  288.         LD    A,(HL)        ;Check for end of str
  289.         IFZ    MATCH_9        ;Jump if at the end
  290. ;
  291.         LD    DE,(SPAT)    ;Ge&t the pattern pointer
  292.         LD    A,(DE)        ;Get the character
  293.         CP    (HL)        ;Do the characters match
  294.         JR    NZ,MATCH_9
  295.         INC    HL        ;Increment the pointers
  296.         INC    DE
  297.         LD    (SPAT),DE    ;Save the new values
  298.         LD    (SSTR),HL
  299.         JR    MATCH_6        ;Loop until done
  300. ;
  301. MATCH_9        EQU    $
  302.         LD    A,(HL)        ;Check if a match was found
  303.         IFNZ    MATCH_10    ;Jump if not at end
  304.         LD    DE,(SPAT)    ;Get the pattern pointer
  305.         LD    A,(DE)        ;Check if at end of pattern
  306.         IFNZ    MATCH_10    ;Jump if not at end
  307. MATCHED        CP    A        ;Set Z status
  308.         POP    DE        ;Restore the saved registers
  309.         POP    HL
  310.         POP    BC
  311.         RET            ;Return the matched status
  312. ;
  313. MATCH_10    EQU    $
  314.         LD    DE,(SPAT)    ;Get the pattern pointer
  315.         LD    A,(DE)        ;Get the pattern character
  316.         IFANOT    '$',MATCH_12    ;Jump if not '$'
  317.         INC    HL        ;++sstr
  318.         INC    DE        ;++spat
  319.         LD    (SSTR),HL
  320.         LD    (SPAT),DE
  321.         JR    MATCH_20    ;Skip else case
  322. ;
  323. MATCH_12    EQU    $
  324.         IFANOT    '*',MATCH_15    ;Jump if not '*'
  325.         INC    DE        ;Move pattern forward
  326.         LD    (SPAT),DE    ;Save the new value
  327.         LD    (PSAVE),DE
  328.         LD    (SSAVE),HL    ;Match Zero characters
  329.         JR    MATCH_20
  330. ;
  331. MATCH_15    EQU    $
  332.         LD    HL,(SSAVE)    ;Get the saved position
  333.         LD    A,H        ;Check if null pointer
  334.         OR    L
  335.         JR    Z,MATCH_17    ;Jump if pointer NULL
  336.         LD    A,(HL)        ;Check if end of string
  337.         IFZ    MATCH_17    ;Jump if at the end
  338.         INC    HL
  339.         LD    (SSTR),HL    ;sstr = ++ssave;
  340.         LD    (SSAVE),HL    ;Save new value
  341.         LD    HL,(PSAVE)
  342.         LD    (SPAT),HL    ;spat = psave;
  343.         JR    MATCH_20
  344. ;
  345. MATCH_17    EQU    $
  346. NOMATCH        LD    A,1        ;Set NZ status
  347.         CP    0
  348.         POP    DE        ;Restore the saved registers
  349.         POP    HL
  350.         POP    BC
  351.         RET            ;Return to caller
  352. ;
  353. MATCH_20    EQU    $
  354.         JP    MATCH_6        ;Loop
  355. ;
  356. ;    This function takes the string in the COMPNAME data area, and
  357. ;    appends it to the list of filenames already collected.
  358. ;
  359. COPYFILE    EQU    $
  360.         PUSH    DE        ;Save the regs
  361.         PUSH    HL
  362.         PUSH    BC
  363.         LD    HL,COMPNAME    ;Get name matched
  364.         LD    DE,(FBPTR)    ;Get the current position
  365.         PUSH    DE        ;Save address to print from
  366. COPYF_1        EQU    $
  367.         LD    A,(HL)        ;Check for end of string
  368.         IFZ    COPYF_3        ;Jump if at the end
  369.         LDI            ;Move a character
  370.         PUSH    HL        ;Save HL
  371.         PUSH    DE        ;Copy DE to HL
  372.         POP    HL
  373.         LD    BC,FILEBUFF+BUFFSIZE    ;Get the end of buffer
  374.         OR    A        ;Reset the carry
  375.         SBC    HL,BC        ;Check for too far
  376.         POP    HL        ;Restore HL back
  377.         JR    NZ,COPYF_1    ;Loop if not too far
  378.         STROUT    OUTOFSTR    ;Print a message
  379.         JP    KERMIT
  380. ;
  381. COPYF_3        EQU    $
  382.         PUSH    DE
  383.         POP    HL        ;Copy DE to HL
  384.         LD    BC,FILEBUFF+BUFFSIZE-4    ;Get max for following
  385.         OR    A
  386.         SBC    HL,BC        ;Compute remaining
  387.         JR    NZ,COPYF_5
  388. COPYF_4        STROUT    OUTOFSTR    ;Print message
  389.         JP    KERMIT        ;Abort
  390. ;
  391. COPYF_5        LD    A,':'        ;Put in the drive delimiter
  392.         LD    (DE),A        ;Store it
  393.         INC    DE        ;Point ahead one
  394.         LD    A,(SDIRDRV)    ;Get the drive number
  395.         LD    (DE),A        ;Store it
  396.         INC    DE        ;Point ahead one more
  397.         LD    A,' '        ;Add a space at the end
  398.         LD    (DE),A        ;Store it
  399.         INC    DE        ;Point ahead
  400.         LD    A,EOS        ;Get the end of string character
  401.         LD    (DE),A        ;Put in a terminator
  402.         LD    (FBPTR),DE    ;Save the new pointer
  403.         LD    HL,FILECNT    ;Increment the number of files
  404.         LD    A,(HL)        ;Get the current count
  405.         PUSH    AF        ;Save the count
  406.         INC    (HL)        ;Add one to counter
  407.         IFNZ    COPYF_6        ;Jump if not first
  408.         LD    A,(LOGNAMES)    ;Check if should print anything
  409.         IFZ    COPYF_6        ;Jump if not
  410.         STROUT    FILESFND    ;Print the message only once
  411. COPYF_6        EQU    $
  412.         POP    AF
  413.         IFA    255,COPYF_4    ;Jump if not too many names
  414.         POP    DE        ;Get the string
  415.         LD    A,(LOGNAMES)    ;Check if should print anything
  416.         IFZ    COPYF_7        ;Jump if not
  417.         CALL    PRTSTR        ;Print the string
  418.         CALL    NEWLIN        ;Get a new line
  419. COPYF_7        EQU    $
  420.         POP    BC        ;Restore the registers
  421.         POP    HL
  422.         POP    DE
  423.         RET            ;Return to caller
  424. ;
  425. ;    Check if any wild card characters are in the string pointed
  426. ;    to by HL.  Return Z status if there are, NZ if there are not
  427. ;
  428. ISWILD        EQU    $
  429.         PUSH    HL        ;Save the strings address
  430.         PUSH    DE
  431.         EX    DE,HL
  432. ISWILD_1    LD    A,(HL)        ;Get a character
  433.         IFZ    ISWILD_2    ;End of string?  Jump if so
  434.         IFA    '$',ISWILD_4    ;Jump if it is a wild card
  435.         IFA    '*',ISWILD_4    ;Jump if it is a wild card
  436.         INC    HL        ;Point to next character
  437.         JR    ISWILD_1    ;Loop until there
  438. ;
  439. ISWILD_2    EQU    $
  440.         INC    A        ;Set NZ
  441. ISWILD_3    POP    DE        ;Restore the registers
  442.         POP    HL
  443.         RET            ;Return to caller
  444. ;
  445. ISWILD_4    EQU    $
  446.         CP    A        ;Set Z status
  447.         JR    ISWILD_3    ;Return
  448. ; end of file
  449.