<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Fri, 11 Oct 1985 09:56:24 mdt
From   : Richard Thomsen <rgt%a@LANL.ARPA>
Subject: Request for CP/M help on Find Next

       I need some help on using the CP/M Find First/Find Next commands.
I use the following routine to find the first file on the disk by using
the Find First CP/M command, then open the file and print the file name.
Then I close the file and use the same routine to find the next file.
On calling this routine, the ambigious file name is pointed to by reg HL,
and the last file found is pointed to by reg DE.  Reg A contains the value
zero on the first call, and 7 on successive calls.  I stepped through this
code with DDT, and everything seems proper, but the Find Next call always
returns with Reg A = 0FFH to indicate no files found.  But files exist!

       I got this code from _The CP/M Programmer's Handbook_ by Andy
Johnson-Laird, but it never finds the second or later files.  Another
version of code using this routine finds some, but not all, of the files
on the disk.  What am I doing wrong???

       I looked through the INSIDCPM.LBR, but they are not really doing
anything similar.  When I modify the program to not open the files that
were found, but just print the names, and also to not do the Find First
again, then it finds all the files.  But I need to open the files and
copy them, and this seems to screw up the Find Next!  Can anyone help?????


;++
;
;   TITLE:             GETNEXTF
;
;   TYPE:              Subroutine
;
;   ABSTRACT:
;
;      This subroutine gets the next file FCB from a possibly ambiguous file
;      name.  The actual FCB is stored in the destination FCB.
;
;
;   INPUTS:
;
;      Reg HL  --  Address of the possibly ambiguious file name FCB.
;      Reg DE  --  Address of FCB to contain the file name found
;      Reg A   --  File control byte.
;                      Zero to return the first file name that matches
;                      Non-zero to return the next file name that matches
;
;   OUTPUTS:
;
;      Carry   --  Exit status
;                      Set     --  File not found
;                      Clear   --  File name found and FCB set up
;
;   SIDE EFFECTS:
;
;      Address pointed to by reg DE is set to file name found.
;      DMA address is changed.
;
;   REGISTERS CHANGED: A, B, C
;
;--
;
;   Define the data areas and values used by this subroutine
;
GNFFCBMOVSIZE  EQU     13              ;Define size of FCB to be moved
GNFDIRBUF      DS      128             ;Define buffer area for directory
;
;   Start of code  --  save the FCB addresses
;
GETNEXTF:
       PUSH    D               ;Save destination FCB on stack
       PUSH    H               ;Save source FCB on stack
       PUSH    PSW             ;Save First/Next flag on stack
;
;   Set the DMA address to the directory buffer
;
       LXI     D,GNFDIRBUF     ;Get address of directory buffer
       MVI     C,SETDMA        ;Get code for set DMA
       CALL    BDOS            ;Call BDOS to set the DMA address
;
;   DMA address set  --  see if first or next
;
       POP     PSW             ;Restore First/Next flag
       ORA     A               ;Check First/Next flag
       JNZ     GNFNEXT         ;If next, use that call
;
;   Request is to get the first file name
;
       POP     D               ;Get address of source file FCB for search
       PUSH    D               ;And save it again
       MVI     C,SEARCHF       ;Get code to search for first filename
       CALL    BDOS            ;Call BDOS to perform search
       POP     H               ;Restore address of source FCB
       POP     D               ;Restore address of destination FCB
       CPI     0FFH            ;See if file was found
       JZ      GNFFILENOTFND   ;If not, then just exit with error
       JMP     GNFGETFCB       ;Otherwise, get the FCB
;
;   Request is to get the next file name  --  search for next
;      First, the context of the file name must be restored by again
;      searching for the last one found.
;
GNFNEXT:
;
;   Request is to get the next file name  --  search for next
;      First, the context of the file name must be restored by again
;      searching for the last one found.
;
GNFNEXT:
       POP     H               ;Recover address of source file name FCB
       POP     D               ;Recover address of destination FCB
       PUSH    H               ;Save them again, but in opposite order
       PUSH    D
       CALL    GNFZEROFILE     ;Clear all but the name from the FCB
       POP     D               ;Recover the destination FCB address
       PUSH    D               ;And save it again
       MVI     C,SEARCHF       ;Get code to search for the last file found
       CALL    BDOS            ;And re-find that file

***   At this point, it finds the file again, as it should   ***

;
;   Now the FCB is set to what it was at the end of the last search.
;      Move the source FCB into the destination FCB and search for the next.
;
       POP     D               ;Get the address of the destination FCB
       POP     H               ;Get the address of the source FCB
       PUSH    D               ;Save them again in the opposite order
       PUSH    H
       PUSH    D               ;Save address of destination FCB again
       MVI     C,FCBSIZE       ;Get the size of the FCB's
       CALL    MOVE            ;Set the destination FCB to the source FCB
;
;   Now call the BDOS to search for the next occurance of the FCB
;
       POP     D               ;Get address of destination FCB
       CALL    GNFZEROFILE     ;And clear all but the name
       MVI     C,SEARCHN       ;Get code to search for next file name
       CALL    BDOS            ;Call the BDOS to do the search

***   At this point, it returns with Reg A = 0FFH, indicating no more files

       POP     H               ;Restore the address of the source FCB
       POP     D               ;Restore the address of the destination FCB
       CPI     0FFH            ;See if file was found
       JZ      GNFFILENOTFND   ;If not, then just exit with error
;
;
;   File was found  --  save the filename found in the save area for
;      next search
;
GNFGETFCB:
       PUSH    H               ;Save the address of the source FCB
       PUSH    D               ;Save the address of the destination FCB
       ADD     A               ;Multiply return code by 32 to get offset
       ADD     A               ;4
       ADD     A               ;8
       ADD     A               ;16
       ADD     A               ;32
       LXI     H,GNFDIRBUF     ;Get address of directory buffer
       MOV     E,A             ;Put offset into reg E
       MVI     D,0             ;Clear reg D to get 16-bit offset
       DAD     D               ;Add to directory buffer
       POP     D               ;Get address of destination FCB
       PUSH    D               ;And save it again
       MVI     C,FCBSIZE       ;Get size of entry to save
       CALL    MOVE            ;Move name into save area
       POP     D               ;Get the address of the destination FCB
       POP     H               ;Get the address of the source FCB
       MOV     A,M             ;Get the disk/user number from source
       STAX    D               ;Store disk/user number in destination FCB
;
;   FCB now set to next disk  --  zero fill it for any disk commands
;
       PUSH    D               ;Save the address of the destination FCB
       PUSH    H               ;Save the address of the source FCB
       CALL    ZEROFCB         ;Zero fill the FCB
       POP     H               ;Restore the address of the source FCB
       POP     D               ;Restore the address of the destination FCB
       XRA     A               ;Clear carry to indicate success
       RET                     ;And return to caller
;
;   File not found  --  return error code to user
;
GNFFILENOTFND:
       STC                     ;Set carry to indicate error
       RET                     ;And return to caller
;
;   Clear the FCB except for the disk, file name, file type, and extent
;      Address of FCB is in reg DE.
;
GNFZEROFILE:
       LXI     H,13            ;Bypass the file name and extent stored
       DAD     D               ;Get the address of the part to clear
       MVI     C,36-13         ;Get number of bytes to clear
GNFZEROFILELP:
       MVI     M,0             ;Clear the byte
       INX     H               ;Increment to next byte
       DCR     C               ;Decrement count
       JNZ     GNFZEROFILELP   ;Continue for all bytes
       RET                     ;Otherwise, return to caller
;

       Version 2.2 (I believe) of CP/M on a DEC Rainbow 100+.

                                               Richard Thomsen
                                               rgt@lanl
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>