Heya.

 BBS: Inland Empire Archive
Date: 01-22-93 (11:14)             Number: 369
From: CORIDON HENSHAW              Refer#: NONE
  To: MARK REJHON                   Recvd: NO  
Subj: Heya.                          Conf: (2) Quik_Bas
Hello Mark!

In a msg of <20 Jan 93>, Mark Rejhon writes to Coridon Henshaw:

 >> MR> The code needs a bit of optimization, though :)
 >> Where?

 MR> I'm an ASM programmer, and the conception of using strings to set the
 MR> file attributes is _darned_ inefficient! :)

I designed those SUBs to be easy to use, not fast.

 >> that the directory be opened as a file? You could use direct
 >> disk access via int 13h to read the directory directly.

 MR> I am capable of doing that, but where is the root directory,

Call int 21h with AH=1Fh to find it.  This is best done in
ASM, because BASIC can't read unsigned values without extra
help.  Here's code to do it:

GetDir  PROC FAR USES DS, BX
;
;This is BASIC callable.  It's also off the top of my head;
watch out for bugs ;
;
;Notes: Works ONLY in DOS 2 and 3.  You'll probably want to
add version ;checking code.  For this to work in DOS 4.0,
change "ADD BX,10h" to "ADD ;BX,11h"
;
;Works only on default drive.  If you want to force a disk
to use, you have to ;change the default drive.

        MOV AH,1Fh      ;DOS function 1fh, get default disk parameter block
        INT 21h         ;Call DOS
        TEST AL,FFh     ;Was there an error?
        JE Error        ;If yes, jump to ERROR
        ;DS = segment of Drive Parameter block
        ;BX = offset
        ADD BX,10h      ;BX now points to root directory starting sector
        MOV AX,[BX]     ;AX = the starting sector of the root directory
        RET
Error:  MOV AX, FFFFh   ;Return -1 to BASIC
        RET
GetDir  Endp

FUNCTION declaration for BASIC is:

DECLARE FUNCTION GetDir%

Now you have the sector of the root directory, next to
convert it into drive-head-track-sector notation for INT
13h.  I don't know how to do this, so your on your own here. ]:>

 MR> how do I read a whole subdirectory into a string (especially on a
 MR> fragmented disk, as directories are simply special files, they
 MR> can become fragmented too!)

Quite simply.  First, find the location of the FAT.  More ASM code:

GetFAT  PROC FAR USES DS, BX
;
;This is BASIC callable.  It's also off the top of my head;
watch out for bugs ;
;
;Works only on default drive.  If you want to force a disk to use, you have
to ;change the default drive.

        MOV AH,1Fh      ;DOS function 1fh, get default disk parameter block
        INT 21h         ;Call DOS
        TEST AL,FFh     ;Was there an error?
        JE Error        ;If yes, jump to ERROR
        ;DS = segment of Drive Parameter block
        ;BX = offset
        ADD BX,06h      ;BX now points to root directory starting sector
        MOV AX,[BX]     ;AX = the starting sector of the FAT
        RET
Error:  MOV AX, FFFFh   ;Return -1 to BASIC
        RET
GetFAT  Endp

BASIC calling syntax is:

DECLARE FUNTION GetFAT%

You've now got a disk pointer to the FAT.  Next step is to
find out what kind of FAT it is.  This is also something
that I don't know about.  You'll have to ask someone else.

Once you have located the FAT, you need to convert sectors
into clusters. Every value in the FAT is in clusters, and
is in a linked list.  Here's an example:

Directory entry points to cluster 00FCh, so you read the FAT entry for
cluster 00FCh, it points to the next cluster in the object,
read your data from that cluster, seek to the entry for
this cluster in the FAT, and so on.  You've reached the end
of the chain when you read a 0FF8h-0FFFh entry (For a _12_
bit fat) or FFF8h-FFFFh entry (For a 16 bit fat)

You know how many bytes are in a object by it's directory entry.

 MR> -After I read it and detect a directory in the data, where do I look
 MR> for to go to that next subdirectory?

Scan every entry in the directory, and check it's DIR
attribute bit.  Make sure to skip the "." entry, or you'll
have a endless loop.

Directory structure:

Offset          Size            Meaning
00h             8 Bytes         File name
08h             3 Bytes         File extiontion
0Bh             1 Byte          Attributes, bit based
*                               0 = Readonly
*                               1 = Hidden
*                               2 = System
*                               3 = Volume Label (Root dir ONLY)
*                               4 = Subdirectory
*                               5 = Archive
*                               6 = Reserved
*                               7 = Reserved
0Ch             10 Bytes        Reserved under MS-DOS, file
password under * DR-DOS
16h             Unsigned Word   Time of last update
18h             Unsigned Word   Date of last update
1Ah             Unsigned Word   Beginging disk cluster
1Ch             Unsigned Dword  Object size

 MR> How do I account for fragmentation?

Via FAT reading

 MR> -How do I know when I've reached the end of a directory?

When you hit a NULL filename.

I know this is quite a vage discription, but I'm getting
tired of typing now :))

\  Coridon Henshaw  \          ³
  \  Sirrus Software  \      \ ³ /
    \   Sysop,          \  ÄÄÄÄ*ÄÄÄÄ
      \  TCS Concordia    \  / ³ \
        \  34:3416/18       \  ³

...I used to be sane, but now I'm better!
Outer Court
Echo Basic Postings

Books at Amazon:

Back to BASIC: The History, Corruption, and Future of the Language

Hackers: Heroes of the Computer Revolution (including Tiny BASIC)

Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution

The Advent of the Algorithm: The Idea that Rules the World

Moths in the Machine: The Power and Perils of Programming

Mastering Visual Basic .NET