mirror of
https://github.com/iKarith/beneath-apple-dos.git
synced 2025-02-11 21:30:45 +00:00
Fix bitrot in CH6.2, append to ch06.txt
This commit is contained in:
parent
25bdb9698c
commit
be06e36760
@ -1,521 +0,0 @@
|
||||
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
|
509
ch06.txt
509
ch06.txt
@ -301,7 +301,7 @@ Output: Byte 0D - Return code (See previous definition)
|
||||
0E - Current Volume number
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
.bp
|
||||
|
||||
WRITE Write a sector from a specified buffer
|
||||
|
||||
Input: Byte 00 - Table type ($01)
|
||||
@ -341,4 +341,509 @@ Output: Byte 0D - Return code (See previous definition)
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
|
||||
.nx ch6.2
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
X = 0 - If file is not found, allocate it
|
||||
X # 0 - If file is not found, do not allocate one
|
||||
|
||||
Normally,
|
||||
X should be zero on an OPEN call for a
|
||||
new file and non-zero for all other
|
||||
call types.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
FILE MANAGER PARAMETER LIST - GENERAL FORMAT
|
||||
|
||||
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.
|
||||
|
||||
*** INSERT FIGURE 6.2 ***
|
||||
|
||||
FILE MANAGER PARAMETER LIST BY CALL TYPE
|
||||
|
||||
OPEN Locates or creates a file. A call to POSITION should
|
||||
follow every OPEN.
|
||||
|
||||
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
|
||||
|
||||
Output: Byte 07 - File type of file which was OPENed
|
||||
0A - Return code (see previous definitions)
|
||||
|
||||
CLOSE Write out final sectors, update the Catalog.
|
||||
A CLOSE call is required eventually for every OPEN.
|
||||
|
||||
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
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
DELETE Locate and delete a file, freeing its sectors.
|
||||
|
||||
Input: Byte 00 - 05
|
||||
(remainder are the same as with OPEN call type)
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
CATALOG Produce a catalog listing on the output device.
|
||||
|
||||
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
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
LOCK Lock a file.
|
||||
|
||||
Input: Byte 00 - 07
|
||||
(remainder are the same as with OPEN call type)
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
UNLOCK Unlock a file.
|
||||
|
||||
Input: Byte 00 - 08
|
||||
(remainder are the same as with OPEN call type)
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
RENAME Rename a file.
|
||||
|
||||
Input: Byte 00 - 09
|
||||
02/03 - Address of new file name (30 bytes)
|
||||
(remainder are the same as with OPEN call type)
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
VERIFY Verify that there are no bad sectors in a file by
|
||||
reading every sector.
|
||||
|
||||
Input: Byte 00 - 0C
|
||||
(remainder are the same as the OPEN call type)
|
||||
|
||||
Output: Byte 0A - Return code
|
||||
|
||||
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.
|
||||
|
||||
*** INSERT FIGURE 6.3 ***
|
||||
|
||||
DOS BUFFER FORMAT
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
FILE MANAGER WORKAREA FORMAT
|
||||
|
||||
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
|
||||
|
||||
COMMON ALGORITHMS
|
||||
|
||||
Given below are several pieces of code
|
||||
which are used when working with DOS:
|
||||
|
||||
LOCATE A FREE DOS BUFFER
|
||||
|
||||
The following subroutine may be used
|
||||
to locate an unallocated DOS buffer
|
||||
for use with the DOS file manager.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
LDA $3D0 GET VECTOR JMP
|
||||
CMP #$4C IS IT A JUMP?
|
||||
BNE NODOS NO, DOS NOT LOADED
|
||||
|
||||
WHICH VERSION OF DOS IS ACTIVE?
|
||||
|
||||
In case the program has version dependent code, a check of
|
||||
the DOS version may be required:
|
||||
|
||||
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)
|
||||
|
||||
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:
|
||||
|
||||
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 $C081 NO, TRY ROM CARD OUT
|
||||
CMP $EOOO GOT IT NOW?
|
||||
RTS RTS IN ANY CASE, EXIT TO CALLER
|
||||
|
||||
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:
|
||||
|
||||
..IF INTEGER BASIC IS ACTIVE...
|
||||
LDA $D9
|
||||
BMI EXEC PROGRAM EXECUTING
|
||||
BPL NOEXEC PROGRAM NOT EXECUTING
|
||||
|
||||
..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
|
||||
|
||||
.nx ch7
|
||||
|
Loading…
x
Reference in New Issue
Block a user