home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Assembly / LOCATE.ASM < prev    next >
Assembly Source File  |  1979-12-31  |  13KB  |  234 lines

  1.  
  2. CODE_SEG        SEGMENT
  3.         ASSUME  CS:CODE_SEG,DS:CODE_SEG,ES:CODE_SEG
  4.         ORG     100H                    ;Start off right for a .Com file
  5. ENTRY:  JMP     LOCATE                  ;Skip over Data area
  6.  
  7.         COPY_RIGHT DB '(C)1985 S.Holzner'       ;Author's Mark
  8.         FOUND_MSG DB 13,10,13,10,'FOUND IN $'   ;Like it says
  9.         LEN  DW 1                               ;The file length (low word)
  10.         PATH_LEN        DW 0                    ;Length of Path.Dat
  11.         NUMBER  DW 0                            ;Number of bytes read from file
  12.         EXTRA_PATHS     DB 0                    ;=1 if we open & use Path.Dat
  13.         OLD_BX  DW 0                            ;Save pointer to path at CS:DBH
  14.         OLD_SI  DW 0                            ;Save SI as pointer also
  15.         START_FLAG      DB 0                    ;For searches in Path.Dat
  16.         PATH_DAT        DB "\PATH.DAT",0        ;Asciiz string of Path.Dat
  17.  
  18. LOCATE   PROC    NEAR           ;Here we go
  19.                                 
  20.         MOV     DX,0B0H         ;Move Disk Transfer Area to CS:0B0H
  21.         MOV     AH,1AH          ; Matched file information goes there
  22.         INT     21H
  23.  
  24.         MOV     DI,5CH          ;Use CS:5CH to put '*.*'0 at for search
  25.         CALL    PUT             ; in current directory
  26.         MOV     DX,5CH          ;Point to '*.*'0 for search
  27.         MOV     AH,4EH          ; and find first matching file
  28.         INT     21H             ;Match now at DTA, 0B0H
  29. LOOP:                           ;Loop over matches now 
  30.         MOV     BX,0CAH         ;Get file length, came from match
  31.         MOV     DX,[BX]
  32.         MOV     LEN,DX          ;Store in Len
  33.         CMP     DX,60*1024      ;Don't write over stack, allow < 64K files
  34.         JB      NOT_BIG         ;Range extender (Find > 127 bytes ahead)
  35.         JMP     FIND            
  36. NOT_BIG:CMP     DX,0            ;Was this a 0 length file (disk dir or label)?
  37.         JA      FILE_OK         ;No, go on and read it
  38.         JMP     FIND            ;Yes, find next file and skip this one
  39. FILE_OK:CALL    READ_FILE       ;Get the file into memory
  40.         MOV     CX,NUMBER       ;Prepare to loop over all read bytes
  41.         MOV     DI,OFFSET PATHS+300     ;File starts at Offset Paths+300
  42. SEARCH:                                 ;Use Repne Scasb & DI to search for the
  43.         MOV     BX,82H          ;first letter of the string, which is at CS:82H
  44.         MOV     AL,BYTE PTR [BX]        ;Load into AL for Repne Scasb
  45. REPNE   SCASB                           ;Find first letter
  46.         JCXZ    FIND            ;If out of file to search, find next file
  47.         MOV     BX,80H          ;How many chars in string? Get from CS:80H
  48.         XOR     DX,DX           ;Set DX to zero
  49.         MOV     DL,[BX]         ;Get # of chars in string
  50.         DEC     DX              ;Get rid of space typed after 'Locate'
  51.         MOV     SI,83H          ;Search from second typed letter (1st matched)
  52. CPLOOP: DEC     DX              ;Loop counter
  53.         CMPS    BYTE PTR [DI],[SI]       ;See how far we get until no match
  54.         JZ      CPLOOP
  55.         DEC     DI              ;At end, reset DI (Scasb increments 1 too much)
  56.         CMP     DX,0            ;If DX is not zero, all letters did not match
  57.         JA      SEARCH          ;If not a match, go back and get next one
  58.         LEA     DX,FOUND_MSG    ;FILE HAS BEEN FOUND, say so.
  59.         MOV     AH,9            ;Request string search
  60.         INT     21H             
  61.         MOV     AH,2            ;Now to print filename. Without Path.Dat, at 
  62.         MOV     BX,0DBH         ; CS:CEH, with Path.Dat at CS:DBH
  63.         CMP     EXTRA_PATHS,1   ; Using Path.Dat yet?
  64.         JE      PRINT           ;Yes, print
  65.         MOV     BX,0CEH         ;No, reset BX to point to CS:CEH
  66. PRINT:  MOV     DL,[BX]         ;Print out the filename until 0 found
  67.         CMP     DL,0            ;Is it 0?
  68.         JE      MORE            ;If yes,print out sample at More:
  69.         INT     21H             ;Print filename character
  70.         INC     BX              ;Point to next character
  71.         JMP     PRINT           ;Go back relentlessly until done
  72. MORE:   PUSH    DI              ;Save DI,BX,CX
  73.         PUSH    BX
  74.         PUSH    CX 
  75.         MOV     CX,40           ;Prepare to type out total of 40 characters
  76.         MOV     AH,2            ;With Int 21H service 2
  77.         MOV     DL,':'          ;But first, add ':' to filename
  78.         INT     21H             ;And a carriage return linefeed
  79.         MOV     DL,13
  80.         INT     21H
  81.         MOV     DL,10
  82.         INT     21H
  83.         SUB     DI,20           ;DI points to end of found string, move back
  84.         MOV     BX,OFFSET PATHS+300     ;Beginning of file
  85.         CMP     DI,BX           ;If before beginning, start at beginning
  86.         JA      GO
  87.         MOV     DI,BX
  88. GO:     ADD     BX,LEN          ;Now BX=end of file (to check if we're past it)
  89. SHOW:   MOV     DL,[DI]         ;Get character from file
  90.         INC     DI              ;And point to next one
  91.         CMP     DI,BX           ;Past end?
  92.         JA      SHOWS_OVER      ;Yes, jump out, look for next match
  93.         CMP     DL,30           ;Unprintable character?
  94.         JA      POK             ;No, OK
  95.         MOV     DL,' '          ;Yes, make it a space
  96. POK:    INT     21H             ;Print Character
  97.         LOOP    SHOW            ;And return for the next one
  98. SHOWS_OVER:                     ;End of printout
  99.         POP     CX              ;Restore the registers used above
  100.         POP     BX
  101.         POP     DI
  102.         JMP     SEARCH          ;Return to search more of the file
  103. FIND:   CALL    FIND_FILE       ;This file done, find next match
  104.         CMP     AL,18           ;AL=18 --> no match
  105.         JE      OUT             ;And so we leave
  106.         JMP     LOOP            ;If match found, go back once again
  107. OUT:    INT     20H             ;End of Main Program
  108. LOCATE   ENDP
  109.         
  110. PUT     PROC    NEAR                    ;This little gem puts a '*.*'0
  111.         MOV     BYTE PTR [DI],'*'       ;Wherever you want it, just send
  112.         MOV     BYTE PTR [DI+1],'.'     ;It a value in DI. '*.*'0 used as
  113.         MOV     BYTE PTR [DI+2],'*'     ;Universal wilcard in searches
  114.         MOV     BYTE PTR [DI+3],0
  115.         RET
  116. PUT     ENDP
  117.  
  118. WS      PROC    NEAR                    ;Strip the bits for WordStar
  119.         CMP     CX,0                    ;If there is a length of 0, e.g.
  120.         JE      FIN                     ;Directory entries, etc. do nothing.
  121. WSLOOP: AND BYTE PTR [BX],127           ;Set top bit to zero
  122.         INC     BX                      ;Point to next unsuspecting byte
  123.         LOOP    WSLOOP                  ;And get it too.
  124. FIN:    RET                             ;To use, send this program BX and CX
  125. WS      ENDP
  126.  
  127. FIND_FILE       PROC    NEAR    ;The file finder
  128.         MOV     AH,4FH          ;Try service 4FH, find next match, first
  129.         INT     21H             
  130.         CMP     AL,18           ;AL = 18 --> no match
  131.         JE      CHECK           ;Range extender.
  132.         JMP     NEW
  133. CHECK:  CMP     EXTRA_PATHS,1   ;Have we used path.Dat?
  134.         JE      NEXT_PATH       ;Yes, get next path, this one used up
  135.         INC     EXTRA_PATHS     ;No, set it to 1
  136.         MOV     AX,3D00H        ;Request file opening for Path.Dat
  137.         LEA     DX,PATH_DAT     ;Point to '\PATH.DAT'0
  138.         INT     21H
  139.         JNC     READ            ;If there was a carry, Path.Dat not found
  140. DONE:   MOV     AL,18           ;And so we exit with AL=18
  141.         JMP     END
  142. READ:   MOV     CX,300          ;Assume the max length for Path.Dat, 300.
  143.         MOV     BX,AX           ;Move found file handle into BX for read
  144.         MOV     AH,3FH          ;Set up for file read
  145.         LEA     DX,PATHS        ;Put the file at location Paths (at end)
  146.         INT     21H             ;Read in the file
  147.         ADD     AX,OFFSET PATHS         ;Full offset of end of Path.Dat
  148.         MOV     PATH_LEN,AX     ;Get Path.Dat end point for loop
  149.         MOV     AH,3EH          ;Now close the file
  150.         INT     21H             ;Close file
  151.         MOV     OLD_SI,OFFSET PATHS     ;Save for future path-readings
  152.         MOV     CX,300                  ;Get ready to Un-WordStar
  153.         MOV     BX,OFFSET PATHS         ;300 bytes at location Paths
  154.         CALL    WS                      ;Strip high bit for WS
  155. NEXT_PATH:              ;Come here to find next path to search for files
  156.         MOV     SI,OLD_SI               ;Point to start of next path
  157.         MOV     DI,5CH  ;Move will be to CS:5CH for '\path\*.*0' file find
  158.         MOV     BX,0DBH ;Also to CS:DBH; will assemble full path & filename
  159.         MOV     START_FLAG,0    ;Start the path search
  160. CHAR:   CMP     SI,PATH_LEN     ;Past end of possible path names?
  161.         JGE     DONE            ;Yes, we're done. Leave with AL=18
  162.         CMP     BYTE PTR [SI],30        ;Carriage return or linefeed?
  163.         JB      NEXT                    ;Yes, get next char
  164.         MOV     START_FLAG,1            ;First char, stop skipping chars
  165.         MOV     AL,[SI]                 ;Get char from Path.Dat
  166.         MOV     [BX],AL                 ;Move char to DBH
  167.         INC     BX                      ;And increment to next location there
  168.         MOVSB                           ;Also move to 5CH area
  169.         JMP     CHAR                    ;And go back for more
  170. NEXT:   CMP     START_FLAG,1    ;Bad char, have we been reading a real pathname?
  171.         JE      PDONE           ;Yes, Have reached the end of it.
  172.         INC     SI              ;No, keep skipping chars to find pathname
  173.         JMP     CHAR            
  174. PDONE:  MOV     OLD_SI,SI       ;Save SI for the next path.
  175.         MOV     BYTE PTR [DI],'\'       ;Add '\' to both paths
  176.         MOV     BYTE PTR [BX],'\'
  177.         INC     BX                      ;Move BX on for next time
  178.         MOV     OLD_BX,BX               ;And save it.
  179.         INC     DI                      ;Move to next location at 5CH and
  180.         CALL    PUT                     ;Put '*.*'0 there to find all files.
  181.         MOV     DX,5CH                  ;Start the search for all files in 
  182.         MOV     AH,4EH                  ; the new path.
  183.         MOV     CX,0                    ;Set the file attribute to 0
  184.         INT     21H
  185.         CMP     AL,18                   ;Did we find any new files in new path?
  186.         JE      NEXT_PATH               ;No, get the next path.
  187. NEW:    CMP     EXTRA_PATHS,1           ;Yes,Move found filename to DBH area to
  188.         JNE     END                     ; read it in-only if DBH area is active
  189.         MOV     BX,OLD_BX               ; (i.e. Extra_Paths=1). Restore BX
  190.         MOV     SI,0CDH                 ;And point to found filename in DTA
  191. CLOOP:  INC     SI                      ;Next letter from found filename
  192.         MOV     AH,[SI]                 ;Move it to the DBH area so we can read
  193.         MOV     [BX],AH                 ; in the file (needs pathname\filename)
  194.         INC     BX                      ;Next character in 5CH area.
  195.         CMP     BYTE PTR [SI],0         ;Is this the last character?
  196.         JNE     CLOOP                   ;Nope, get next one
  197. END:    RET                             ;After path & filename assembled, return
  198. FIND_FILE       ENDP
  199.  
  200. READ_FILE       PROC    NEAR    ;Looks for filename at CEH or DBH & reads it 
  201.         PUSH    AX              ;Push everything to save it.
  202.         PUSH    BX
  203.         PUSH    CX
  204.         PUSH    DX
  205.         MOV     DX,0DBH         ;Try the DBH area
  206.         CMP     EXTRA_PATHS,1           ;Has it been used?
  207.         JE      OK              ;Yes
  208.         MOV     DX,0CEH  ;No, not using paths yet, use filename only, at CEH
  209. OK:     MOV     AX,3D00H        ;Prepare for file reading
  210.         INT     21H             ;And do so.
  211.         MOV     BX,AX           ;Move file handle into BX to read
  212.         MOV     DX,OFFSET PATHS+300     ;Read into data area at Paths+300 bytes
  213.         MOV     CX,LEN                  ;Read the full file's length in bytes
  214.         MOV     AH,3FH                  ;Read it in at last
  215.         INT     21H
  216.         MOV     NUMBER,AX               ;# bytes actually got.
  217.         MOV     AH,3EH                  ;Close file 
  218.         INT     21H
  219.         MOV     BX,OFFSET PATHS+300     ;Clean up the Word Star high bit.
  220.         MOV     CX,LEN                  ;For the full file
  221.         CALL    WS                      ;Strip high bit for ws
  222.         POP     DX                      ;Pop evrything and return
  223.         POP     CX
  224.         POP     BX
  225.         POP     AX  
  226.         RET                             ;Fin of Read_File
  227. READ_FILE       ENDP
  228. PATHS:                                  ;Here's the end of program marker
  229.  
  230. CODE_SEG        ENDS
  231.         END     ENTRY                   ;End 'Entry' so DOS starts at 'Entry'
  232.  
  233.  
  234.