beneath-apple-dos/D1S1/CH6.2#064000.txt
2017-07-20 15:45:47 -07:00

522 lines
18 KiB
Plaintext

CALLING THE DOS FILE MANAGER
The DOS file manager exists in every
version of DOS as a collection of
subroutines occupying approximately
the central third of the DOS program.
The interface to these routines is
generalized in such a way that they
may be called by a program running
outside of DOS. The definition of
this interface has
never been published by APPLE (or
anyone else, for that manner) but
since the calls can be made through
fixed vectors, and, the format of the
parameter lists passed have not
changed in all the versions of DOS,
these routines may be relied upon as
"safe". Indeed, the new FID utility
program
uses these routines to process files
on the diskette.
There are
two subroutines which must be called
in order to access the file manager.
.sp1
JSR $3DC - When this subroutine is
called, the Y and A registers are
loaded with the address of the file
manager parameter list. The low order
part of the address is in Y and the
high order part in A. This subroutine
must be called at least once to
locate this parameter list and the
results may be stored in two zero page
locations to allow the programmer to
set input values in the parameter
list and to locate output values
there after file manager calls.
.sp1
JSR $3D6 - This is the main entry to
the file manager. Prior to making
this call the parameter list, located
using the call described
above, must be completed
appropriately, depending upon the
type of call, and the X register must
be set to either zero or non-zero as
follows:
.sp1
X = 0 - If file is not found, allocate it
X # 0 - If file is not found, do not allocate one
.sp1
Normally,
X should be zero on an OPEN call for a
new file and non-zero for all other
call types.
.bp
Three buffers must be provided to the
file manager by the programmer,
allocated by him in his memory. These
buffers, together, occupy 557 bytes
of RAM, and must be passed to the
file manager each time their
associated file is used. A separate
set of these buffers must be
maintained for each open file.
DOS maintains buffers for this
purpose, as described in earlier
chapters, in high RAM. These buffers
may be "borrowed" from DOS if care is
taken to let DOS know about it. A
method for doing this will be
outlined later.
.sp1
A chart giving the required inputs
for each call type to the file
manager is given in Figure 6.2.
The general format of the file
manager parameter list is as follows:
.bp
FILE MANAGER PARAMETER LIST - GENERAL FORMAT
.np
BYTE DESCRIPTION
00 Call type: 01=OPEN 05=DELETE 09=RENAME
02=CLOSE 06=CATALOG 0A=POSITION
03=READ 07=LOCK 0B=INIT
04=WRITE 08=UNLOCK 0C=VERIFY
01 Sub-call type for READ or WRITE:
00=No operation (ignore call entirely)
01=READ or WRITE one byte
02=READ or WRITE a range of bytes
03=POSITION then READ or WRITE one byte
04=POSITION then READ/WRITE a range
02-09 Parameters specific to the call type used. See
FILE MANAGER PARAMETER LIST BY CALL TYPE below.
0A Return code (note: not all return codes can occur
for any call type). The processor CARRY
flag is set upon return from the file
manager if there is a non-zero return code:
00=No errors
01=Not used ("LANGUAGE NOT AVAILABLE")
02=Bad call type
03=Bad sub-call type (greater than four)
04=WRITE PROTECTED
05=END OF DATA
06=FILE NOT FOUND (was allocated if X=0)
07=VOLUME MISMATCH
08=DISK I/O ERROR
09=DISK FULL
0A=FILE LOCKED
0B Not used
0C-0D Address of a 45 byte buffer which will be used by the
file manager to save its status between calls. This
area is called the file manager workarea and need not
be initialized by the caller but the space must be
provided and this two byte address field initialized.
(addresses are in low/high order format)
0E-0F Address of a 256 byte buffer which will be used by the
file manager to maintain the current Track/Sector List
sector for the open file. Buffer itself need not be
initialized by the caller.
10-11 Address of a 256 byte buffer which will be used by the
file manager to maintain the data sector buffer.
Buffer need not be initialized by the caller.
.sp1
*** INSERT FIGURE 6.2 ***
.bp
FILE MANAGER PARAMETER LIST BY CALL TYPE
.np
OPEN Locates or creates a file. A call to POSITION should
follow every OPEN.
.sp1
Input: Byte 00 - 01
02/03 - Fixed record length or 0000 if variable
04 - Volume number or 00 for any volume
05 - Drive number to be used (01 or 02)
06 - Slot number to be used (01-07)
07 - File type (used only for new files)
$00 = TEXT
$01 = INTEGER BASIC
$02 = APPLESOFT BASIC
$04 = BINARY
$08 = RELOCATABLE
$10 = S TYPE FILE
$20 = A TYPE FILE
$40 = B TYPE FILE
08/09 - Address of file name (30 characters)
(Low/high format)
0C/0D - Address of file manager workarea buffer
0E/0F - Address of T/S List sector buffer
10/11 - Address of data sector buffer
.sp1
Output: Byte 07 - File type of file which was OPENed
0A - Return code (see previous definitions)
.sp2
.ne5
CLOSE Write out final sectors, update the Catalog.
A CLOSE call is required eventually for every OPEN.
.sp1
Input: Byte 00 - 02
0C/0D - Address of file manager workarea buffer
0E/0F - Address of T/S List sector buffer
10/11 - Address of data sector buffer
.sp1
Output: Byte 0A - Return code
.bp
READ Read one or a range of bytes from the file to memory.
WRITE Write one or a range of bytes from memory to the file.
Input: Byte 00 - 03 (READ) 04 (WRITE)
01 - Subcode:
00 = No operation
01 = READ or WRITE one byte only
02 = READ or WRITE a range of bytes
03 = POSITION then READ/WRITE one byte
04 = POSITION then READ/WRITE range
02/03 - (Subcodes 03 or 04) Record number
04/05 - (Subcodes 03 or 04) Byte offset
06/07 - (Subcodes 02 or 04) Number of bytes in
range to be read or written. (Note: for
WRITE, this length must be one less
than the actual length to be written)
08/09 - (Subcodes 02 or 04) Address of range of
bytes to be written or address of
buffer to which bytes are to be read.
08 - (WRITE, Subcodes 01 or 03) Single byte
to be written.
0C/0D - Address of file manager workarea buffer
0E/0F - Address of T/S List sector buffer
10/11 - Address of data sector buffer
.sp1
Output: Byte 02/03 - Record number of current file position
04/05 - Byte offset of current position in file
08 - (READ, Subcodes 01 or 03) Byte read
0A - Return code
.sp2
.ne5
DELETE Locate and delete a file, freeing its sectors.
.sp1
Input: Byte 00 - 05
(remainder are the same as with OPEN call type)
.sp1
Output: Byte 0A - Return code
.bp
CATALOG Produce a catalog listing on the output device.
.sp1
Input: Byte 00 - 06
05 - Drive
06 - Slot
0C/0D - Address of file manager workarea buffer
0E/0F - Address of T/S List sector buffer
10/11 - Address of data sector buffer
.sp1
Output: Byte 0A - Return code
.sp2
.ne5
LOCK Lock a file.
.sp1
Input: Byte 00 - 07
(remainder are the same as with OPEN call type)
.sp1
Output: Byte 0A - Return code
.sp2
.ne5
UNLOCK Unlock a file.
.sp1
Input: Byte 00 - 08
(remainder are the same as with OPEN call type)
.sp1
Output: Byte 0A - Return code
.sp2
.ne5
RENAME Rename a file.
.sp1
Input: Byte 00 - 09
02/03 - Address of new file name (30 bytes)
(remainder are the same as with OPEN call type)
.sp1
Output: Byte 0A - Return code
.bp
POSITION Calculate the location of a record and/or byte
offset in the file. Position such that next READ or
WRITE will be at that location in the file. A call
to POSITION (either explicitly or implictly using
subcodes of READ or WRITE) is required prior to the
first READ or WRITE. Bytes 02 through 05 should be
set to zeros for a normal position to the beginning
of the file.
.sp1
Input: Byte 00 - 0A
02/03 - Relative record number for files with a
fixed length record size or zero. First
record of file is record 0000.
04/05 - Relative byte offset into record or of
entire file if record number is zero.
0C/0D - Address of file manager workarea buffer.
0E/0F - Address of T/S List sector buffer.
10/11 - Address of data sector buffer.
.sp1
Output: Byte 0A - Return code
.sp2
.ne5
INIT Initialize a slave diskette. This function formats a
diskette and writes a copy of DOS onto tracks 0-2.
A VTOC and Catalog are also created. A HELLO program
is not stored, however.
.sp1
Input: Byte 00 - 0B
01 - First page of DOS image to be copied to
the diskette. Normally $9D for a 48K
machine.
04 - Volume number of new diskette.
05 - Drive number (01 or 02)
06 - Slot number (01-07)
0C/0D - Address of file manager workarea buffer.
0E/0F - Address of T/S List sector buffer.
10/11 - Address of data sector buffer.
.sp1
Output: Byte 0A - Return code
.sp2
VERIFY Verify that there are no bad sectors in a file by
reading every sector.
.sp1
Input: Byte 00 - 0C
(remainder are the same as the OPEN call type)
.sp1
Output: Byte 0A - Return code
.bp
DOS BUFFERS
Usually it is desirable to use one of DOS's buffers when
calling the file manager to save memory. DOS buffers consist of
each of the three buffers used by the file manager (file
manager workarea, T/S List sector, and data sector) as well as
a 30 byte file name buffer and some link pointers. All together
a DOS buffer occupies 595 bytes of memory. The address of the
first DOS buffer is stored in the first two bytes of DOS ($9D00
on a 48K APPLE II). The address of the next buffer is stored in
the first and so on in a chain of linked elements. The link
address to the next buffer in the last buffer is zeros. If the
buffer is not being used by DOS, the first byte of the file
name field is a hex 00. Otherwise, it contains the first
character of the name of the open file. The assembly language
programmer should follow these conventions to avoid having DOS
reuse the buffer while he is using it. This means that the
name of the file should be stored in the buffer to reserve it
for exclusive use (or at least a non-zero byte stored on the
first character) and later, when the user is through with the
buffer, a 00 should be stored on the file name to return it
to DOS's use. If the later is not done, DOS will eventually
run out of available buffers and will refuse even to do a
CATALOG command. A diagram of the DOS
buffers for MAXFILES 3 is given in
Figure 6.3 and
the format of a DOS buffer is given below.
.sp1
*** INSERT FIGURE 6.3 ***
.sp1
.ne10
DOS BUFFER FORMAT
.np
BYTE DESCRIPTION
000/0FF Data sector buffer (256 bytes in length)
100/1FF T/S List sector buffer (256 bytes in length)
200/22C File manager workarea buffer (45 bytes in length)
22D/24A File name buffer (30 bytes in length)
First byte indicates whether this DOS buffer is
being used. If hex 00, buffer is free for use.
24B/24C Address (Lo/High) of file manager workarea buffer
24D/24E Address of T/S List sector buffer
24F/250 Address of data sector buffer
251/252 Address of the file name field of the next buffer on
the chain of buffers. If this is the last buffer on
the chain then this field contains zeros.
.bp
THE FILE MANAGER WORKAREA
The file manager workarea contains
the variables which, taken together,
constitute all of the information the
file manager needs to deal with an
open file. Each time the file manager
finishes processing a call, it copies
all of its important variables into
the file manager workarea buffer
provided by the caller. Each
subsequent time the file manager is
called, the first thing it does is to
copy the contents of the file manager
workarea buffer back into its
variables so that it may resume
processing for the file where it left
off on the previous call.
Ordinarily, the programmer will have
no need to worry about the contents
of this workarea, since most of the
useful information is present in the
parameter list anyway. Occasionally,
it is handy to know more about the
open file. For these cases, the
format of the file manager workarea
is given below:
.sp1
FILE MANAGER WORKAREA FORMAT
.np
BYTE DESCRIPTION
00/01 Track/Sector of first T/S List for file
02/03 Track/Sector of current T/S List for file
04 Flags:
80=T/S List buffer changed and needs writing
40=Data buffer has been changed and needs writing
02=Volume freespace map changed and needs writing
05/06 Track/Sector of current data sector
07 Sector offset into catalog to entry for this file
08 Byte offset into catalog sector to entry for file
09/0A Maximum data sectors represented by one T/S List
0B/0C Offset of first sector in current T/S List
0D/0E Offset of last sector in current T/S List
0F/10 Relative sector number last read
11/12 Sector size in bytes (256)
13/14 Current position in sectors (relative)
15 Current byte offset in this sector
16 Not used
17/18 Fixed record length
19/1A Current record number
1B/1C Byte offset into current record
1D/1E Length of file in sectors
1F Next sector to allocate on this track
20 Current track being allocated
21/24 Bit map of available sectors on this track (rotated)
25 File type (80=locked) 0,1,2,4=T,I,A,B
26 Slot number times 16 (example: $60=slot 6)
27 Drive number (01 or 02)
28 Volume number (complemented)
29 Track
2A/2C Not used
.bp
COMMON ALGORITHMS
Given below are several pieces of code
which are used when working with DOS:
.sp1
.ne5
LOCATE A FREE DOS BUFFER
The following subroutine may be used
to locate an unallocated DOS buffer
for use with the DOS file manager.
.sp1
.np
FBUFF LDA $3D2 LOCATE DOS LOAD POINT
STA $1
LDY #0
STY $0
*
GBUF0 LDA ($0),Y LOCATE NEXT DOS BUFFER
PHA
INY
LDA ($0),Y
STA $1
PLA
STA $0
BNE GBUF GOT ONE
LDA $1
BEQ NBUF NO BUFFERS FREE
*
GBUF LDY #0 GET FILENAME
LDA ($0),Y
BEQ GOTBUF ITS FREE
LDY #36 ITS NOT FREE
BNE GBUF0 GO GET NEXT BUFFER
*
GOTBUF CLC INDICATE-GOT A FREE BUFFER
RTS RETURN TO CALLER
NBUF SEC INDICATE-NO FREE BUFFERS
RTS RETURN TO CALLER
.bp
IS DOS IN THE MACHINE?
The following series of instructions
should be used prior to attempting to
call RWTS or the file manager to
insure that DOS is present on this
machine.
.sp1
.np
LDA $3D0 GET VECTOR JMP
CMP #$4C IS IT A JUMP?
BNE NODOS NO, DOS NOT LOADED
.sp2
.ne5
WHICH VERSION OF DOS IS ACTIVE?
In case the program has version dependent code, a check of
the DOS version may be required:
.sp1
.np
CLC
LDA #0 ADD $16BE TO DOS LOAD POINT
ADC #$BE
STA $0
LDA $3D2
ADC #$16
STA $1
LDY #0
LDA ($0),Y GET DOS VERSION NUMBER (2 OR 3)
.sp2
.ne5
WHICH BASIC IS SELECTED?
Some programs depend upon either the
INTEGER BASIC ROM or the APPLESOFT
ROM. To find out which is active and
select the one desired, the following
subroutine can be called. First the A
register is loaded with a code to
indicate which BASIC is desired. $20
is used for INTEGER BASIC and $4C is
used for APPLESOFT. To set up for
APPLESOFT, for example:
.sp1
.np
LDA #$4C CODE FOR APPLESOFT
JSR SETBSC CALL SUBROUTINE
BNE ERROR LANGUAGE NOT AVAILABLE
.
.
.
SETBSC CMP $E000 CORRECT BASIC ALREADY THERE?
BEQ RTS YES
STA $C080 NO, SELECT ROM CARD
CMP $E000 NOW DO WE HAVE IT?
BEQ RTS YES
STA $C\x3f\x4f\x47\x57\x57\x57\x3b\x3b\x5b\x57\x23\x27Y ROM CARD OUT
\x8cL\x8cL\x8cL\x88/\x19g_\x20_\x20_[\x8b\x8b\x8b\x9b\x9b\x9b\xffwo\x9bs
\x2c\x40\x42\x5b\x33\x03\x61\x9fTS RTS IN ANY CASE, EXIT TO CALLER
.bp
SEE IF A BASIC PROGRAM IS IN EXECUTION
To determine if there is a BASIC program running or
if BASIC is in immediate command mode, use the following
statements:
.np
.sp1
..IF INTEGER BASIC IS ACTIVE...
LDA $D9
BMI EXEC PROGRAM EXECUTING
BPL NOEXEC PROGRAM NOT EXECUTING
.sp1
..IF APPLESOFT BASIC IS ACTIVE...
LDX $76 GET LINE NUMBER
INX
BEQ NOEXEC PROGRAM NOT EXECUTING
LDX $33 GET PROMPT CHARACTER
CPX #$DD PROMPT IS A "]"?
BEQ NOEXEC YES, NOT EXECUTING
BNE EXEC ELSE, PROGRAM IS EXECUTING
.br
.nx ch7