2017-07-21 12:29:21 +00:00
|
|
|
# CHAPTER 8 - DOS PROGRAM LOGIC
|
|
|
|
|
|
|
|
This chapter will take a detailed look at the operation of the DOS program
|
|
|
|
itself to aid the APPLE user in understanding it and to help him to make
|
|
|
|
intelligent use of its facilities. Each subroutine and group of variables or
|
|
|
|
constants will be covered separately by storage address. The enterprising
|
|
|
|
programmer may wish to create a disassembly of DOS on his printer and transfer
|
|
|
|
the annotations given here directly to such a listing. Addresses used will be
|
|
|
|
for DOS 3.3 and for a 48K master diskette version of DOS. Slot 6 is assumed.
|
|
|
|
Unless specifically indicated by a $ character, lengths are given in decimal,
|
|
|
|
addresses in hexadecimal (base 16).
|
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
DISK II CONTROLLER CARD ROM - BOOT 0
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
ADDRESS
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
C600-C65B This routine is the first code executed when a disk
|
|
|
|
is to be booted. It receives control via PR#6 or
|
|
|
|
C600G or 6 control-P.
|
|
|
|
Dynamically build a translate table for converting
|
|
|
|
disk codes to six bit hex at location $356-$3FF.
|
2017-07-20 22:45:47 +00:00
|
|
|
Call an RTS instruction in the monitor ROM and
|
2017-07-20 21:50:14 +00:00
|
|
|
extract the return address from the stack to find out
|
2017-07-20 22:45:47 +00:00
|
|
|
the address of this controller card ROM.
|
2017-07-20 21:50:14 +00:00
|
|
|
Use this address to determine the slot number of this
|
|
|
|
drive by shifting $Csxx.
|
|
|
|
Save the slot number times 16 ($s0)
|
|
|
|
Clear disk I/O latches, set read mode, select drive
|
|
|
|
1, turn disk drive on.
|
|
|
|
Pull disk arm back over 80 tracks to recalibrate the
|
|
|
|
arm to track zero.
|
|
|
|
Set up parms to read sector zero on track zero to
|
|
|
|
location $800.
|
|
|
|
Execution falls through into a general sector read
|
|
|
|
subroutine at C65C.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
C65C-C6FA This subroutine reads the sector number stored at
|
|
|
|
$3D on the track indicated by $41 to the address
|
|
|
|
stored at $26,$27.
|
|
|
|
Look for D5/AA/96 sector address header on the disk.
|
|
|
|
If D5/AA/AD is found and sector data was wanted, go
|
|
|
|
to C6A6.
|
|
|
|
C683 Handle a sector address block.
|
|
|
|
Read three double bytes from the disk and combine
|
|
|
|
them to obtain the volume, track, and sector number
|
|
|
|
of the sector being read from the disk at this time.
|
|
|
|
Store the track at $40.
|
|
|
|
Compare the sector found to the sector wanted and the
|
|
|
|
track found to the track wanted.
|
|
|
|
If no match, go back to C65C.
|
|
|
|
Otherwise, if sector is correct, go to C65D to find
|
|
|
|
the sector data itself.
|
|
|
|
C6A6 Handle sector data block.
|
|
|
|
Read the 85 bytes of secondary data to $300-$355.
|
|
|
|
Read 256 bytes of primary data to the address stored
|
|
|
|
at $26,$27.
|
|
|
|
Verify that the data checksum is valid.
|
|
|
|
If not, start over at C65C.
|
|
|
|
"Nibbilize" the primary and secondary data together
|
|
|
|
into the primary data buffer ($26,$27).
|
|
|
|
Increment $27 (address page of read data) and $3D
|
|
|
|
(sector number to be read) and check against $800
|
|
|
|
to see if additional sectors need to be read.
|
|
|
|
If so, reload slot*16 and go back to C65C to read
|
|
|
|
next sector. (This feature is not used when loading
|
|
|
|
DOS but is used when loading from a BASICS diskette.)
|
|
|
|
Otherwise, go to $801 to begin executing the second
|
|
|
|
stage of the bootstrap.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 22:45:47 +00:00
|
|
|
FIRST RAM BOOTSTRAP LOADER - BOOT 1
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
ADDRESS
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
0801-084C This routine loads the second RAM loader, Boot 2,
|
|
|
|
including RWTS, into memory and jumps to it.
|
|
|
|
If this is not the first entry to Boot 1, go to $81F.
|
|
|
|
Get slot*16 and shift down to slot number.
|
|
|
|
Create the address of the ROM sector read subroutine
|
|
|
|
(C65C in our case) and store it at $3E,$3F.
|
|
|
|
Pick up the first memory page in which to read Boot 2
|
2017-07-20 22:45:47 +00:00
|
|
|
from location $8FE, add the length of Boot 2 in
|
2017-07-20 21:50:14 +00:00
|
|
|
sectors from $8FF, and set that value as the first
|
|
|
|
address to which to read (read last page first).
|
|
|
|
081F Get sector to read, if zero, go to $839.
|
|
|
|
Translate theoretical sector number into physical
|
|
|
|
sector number by indexing into skewing table at $84D.
|
|
|
|
Decrement theoretical sector number (8FF) for next
|
|
|
|
iteration through.
|
|
|
|
Set up parameters for ROM subroutine (C65C) and
|
|
|
|
jump to it. It will return to $801 when the sector
|
|
|
|
has been read.
|
|
|
|
0839 Adjust page number at 8FE to locate entry point of
|
|
|
|
Boot 2.
|
|
|
|
Perform a PR#0 and IN#0 by calling the monitor.
|
|
|
|
Initialize the monitor (TEXT mode, standard window,
|
|
|
|
etc.)
|
|
|
|
Get slot*16 again and go to Boot 2 ($3700 for a
|
|
|
|
master disk, $B700 in its final relocated location).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
DOS 3.3 MAIN ROUTINES
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
ADDRESS
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D00-9D0F Relocatable address constants
|
|
|
|
9D00 Address of first DOS buffer at its file name field.
|
|
|
|
9D02 Address of the DOS keyboard intercept routine.
|
|
|
|
9D04 Address of the DOS video intercept routine.
|
|
|
|
9D06 Address of the primary file name buffer.
|
|
|
|
9D08 Address of the secondary (RENAME) file name buffer.
|
|
|
|
9D0A Address of the range length parameter used for LOAD.
|
|
|
|
9D0C Address of the DOS load address ($9D00).
|
|
|
|
9D0E Address of the file manager parameter list.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D10-9D1C DOS video (CSWL) intercept's state handler address
|
|
|
|
table. States are used to drive the handling of DOS
|
|
|
|
commands as they appear as output of PRINT statements
|
|
|
|
and this table contains the address of the routine
|
|
|
|
which handles each state from state 0 to state 6.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 22:45:47 +00:00
|
|
|
9D1E-9D55 Command handler entry point table. This table
|
2017-07-20 21:50:14 +00:00
|
|
|
contains the address of a command handler subroutine
|
|
|
|
for each DOS command in the following standard order:
|
|
|
|
INIT A54F
|
|
|
|
LOAD A413
|
|
|
|
SAVE A397
|
|
|
|
RUN A4D1
|
|
|
|
CHAIN A4F0
|
|
|
|
DELETE A263
|
|
|
|
LOCK A271
|
|
|
|
UNLOCK A275
|
|
|
|
CLOSE A2EA
|
|
|
|
READ A51B
|
|
|
|
EXEC A5C6
|
|
|
|
WRITE A510
|
|
|
|
POSITION A5DD
|
|
|
|
OPEN A2A3
|
|
|
|
APPEND A298
|
|
|
|
RENAME A281
|
|
|
|
CATALOG A56E
|
|
|
|
MON A233
|
|
|
|
NOMON A23D
|
|
|
|
PR# A229
|
|
|
|
IN# A22E
|
|
|
|
MAXFILES A251
|
|
|
|
FP A57A
|
|
|
|
INT A59E
|
|
|
|
BSAVE A331
|
|
|
|
BLOAD A35D
|
|
|
|
BRUN A38E
|
|
|
|
VERIFY A27D
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D56-9D61 Active BASIC entry point vector table. The addresses
|
|
|
|
stored here are maintained by DOS such that they
|
|
|
|
apply to the current version of BASIC running.
|
|
|
|
9D56 Address of CHAIN entry point to BASIC.
|
|
|
|
9D58 Address of RUN.
|
|
|
|
9D5A Address of error handler.
|
|
|
|
9D5C Address of BASIC coldstart.
|
|
|
|
9D5E Address of BASIC warmstart.
|
|
|
|
9D60 Address of BASIC relocate (APPLESOFT only).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 22:45:47 +00:00
|
|
|
9D62-9D6B Image of the entry point vector for INTEGER BASIC.
|
2017-07-20 21:50:14 +00:00
|
|
|
This image is copied to 9D56 if INTEGER BASIC is made
|
|
|
|
active.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D6C-9D77 Image of the entry point vector for the ROM version
|
|
|
|
of APPLESOFT.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D78-9D83 Image of the entry point vector for the RAM version
|
|
|
|
of APPLESOFT.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9D84-9DBE DOS coldstart entry routine.
|
|
|
|
Get the slot and drive numbers and store as default
|
|
|
|
values for command keywords.
|
|
|
|
Copy APPLESOFT ROM or INTEGER BASIC entry point
|
|
|
|
vector into current BASIC entry point vector.
|
|
|
|
Remember which BASIC is active.
|
|
|
|
Go to 9DD1.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9DBF-9DE9 DOS warmstart entry routine.
|
|
|
|
Get the remembered BASIC type and set the ROM card
|
|
|
|
as necessary (calls A5B2).
|
|
|
|
9DD1 Remember whether entry is coldstart or warmstart
|
|
|
|
Call A851 to replace DOS keyboard and video
|
|
|
|
intercepts.
|
|
|
|
Set NOMON C,I,O.
|
|
|
|
Set video intercept handler state to 0.
|
|
|
|
Coldstart or warmstart the current BASIC (exit DOS).
|
2017-07-20 22:45:47 +00:00
|
|
|
(DOS will next gain control when BASIC prints its
|
2017-07-20 21:50:14 +00:00
|
|
|
input prompt character)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9DEA-9E50 First entry processing for DOS. This routine is
|
|
|
|
called by the keyboard intercept handler when the
|
|
|
|
first keyboard input request is made by BASIC after
|
|
|
|
a DOS coldstart.
|
|
|
|
If RAM APPLESOFT is active, copy its entry point
|
|
|
|
vector to the active BASIC entry point vector and
|
|
|
|
blank out the primary file name buffer so that no
|
|
|
|
HELLO file will be run.
|
|
|
|
Set MAXFILES to 3 by default.
|
|
|
|
Call A7D4 to build the DOS file buffers.
|
|
|
|
If an EXEC was active, close the EXEC file
|
2017-07-20 22:45:47 +00:00
|
|
|
Set the video intercept state to 0 and indicate
|
2017-07-20 21:50:14 +00:00
|
|
|
warmstart status by calling A75B.
|
|
|
|
If the last command executed was not INIT (this DOS
|
|
|
|
was not just booted), go to 9E45.
|
|
|
|
Otherwise, copy an image of the DOS jump vector to
|
|
|
|
$3D0-$3FF.
|
|
|
|
Point $3F2,$3F3 to DOS warmstart routine.
|
|
|
|
Set the AUTOSTART ROM power-up byte since the RESET
|
|
|
|
handler address was changed.
|
|
|
|
Set the command index for RUN (to run the HELLO file)
|
|
|
|
and go to A180 to execute it.
|
|
|
|
9E45 See if there is a pending command.
|
|
|
|
If so, go to A180 to execute it. Otherwise, return
|
|
|
|
to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 22:45:47 +00:00
|
|
|
9E51-9E7F An image of the DOS 3-page jump vector which the
|
2017-07-20 21:50:14 +00:00
|
|
|
above routine copies to $3D0-$3FF. See Chapter 5 for
|
|
|
|
a description of its contents.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9E81-9EB9 DOS keyboard intercept routine.
|
|
|
|
Call 9ED1 to save the registers at entry to DOS.
|
|
|
|
If not coldstarting or reading a disk file,
|
|
|
|
go to 9E9E.
|
|
|
|
Get value in A register at entry and echo it on the
|
|
|
|
screen (erases flashing cursor).
|
2017-07-20 22:45:47 +00:00
|
|
|
If in read state (reading a file) go to A626 to get
|
2017-07-20 21:50:14 +00:00
|
|
|
next byte from disk file.
|
|
|
|
Otherwise, call 9DEA to do first entry processing.
|
|
|
|
Put cursor on screen in next position.
|
|
|
|
If EXECing, call A682 to get the next byte from the
|
|
|
|
EXEC file.
|
|
|
|
Set the video intercept state to 3 (input echo).
|
|
|
|
Call 9FBA to restore the registers at entry to DOS.
|
|
|
|
Call the true keyboard input routine.
|
|
|
|
Save the input character so that it will be restored
|
|
|
|
with the registers in the A register.
|
|
|
|
Do the same with the new X register value.
|
|
|
|
Exit DOS via 9FB3.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9EBA-9EBC A jump to the true KSWL handler routine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9EBD-9ED0 DOS video intercept routine.
|
|
|
|
Call 9ED1 to save the registers at entry to DOS.
|
|
|
|
Get the video intercept state and, using it as an
|
|
|
|
index into the state handler table (9D11), go to
|
|
|
|
the proper handler routine, passing it the character
|
|
|
|
being printed.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9ED1-9EEA Common intercept save registers routine.
|
|
|
|
Save the A, X, Y, and S registers at AA59-AA5C.
|
|
|
|
While in DOS, restore the true I/O handlers (KSWL and
|
|
|
|
CSWL) to $36-$39.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9EEB-9F11 State 0 output handler. --start of line--
|
|
|
|
If a RUN command was interrupted (by loading RAM
|
|
|
|
APPLESOFT) go to 9F78 to complete it.
|
|
|
|
If read flag is on (file being read) and output is a
|
|
|
|
"?" character (BASIC INPUT), go to state 6 to skip
|
|
|
|
it.
|
2017-07-20 22:45:47 +00:00
|
|
|
If read flag is on and output is prompt character
|
2017-07-20 21:50:14 +00:00
|
|
|
($33) go to state 2 to ignore the line.
|
|
|
|
Set state to 2 (ignore non-DOS command) just in case.
|
|
|
|
If output character is not a control-D, go to
|
|
|
|
state 2.
|
|
|
|
Otherwise, set state to 1 (collect possible DOS
|
|
|
|
command), set line index to zero, and fall through
|
|
|
|
to state 1.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F12-9F22 State 1 output handler. --collect DOS command--
|
|
|
|
Using line index, store character in input buffer at
|
|
|
|
$200.
|
|
|
|
Increment line index.
|
|
|
|
If character is not a carriage return, exit DOS
|
|
|
|
via 9F95 (echo character on screen if MON I).
|
|
|
|
Otherwise, go to command scanner at 9FCD.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F23-9F2E State 2 output handler. --non-DOS command ignore--
|
|
|
|
If the character is not a carriage return, exit DOS
|
|
|
|
via 9FA4 (echo character on screen).
|
|
|
|
Otherwise, set state back to 0 and exit DOS via
|
|
|
|
9FA4.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F2F-9F51 State 3 output handler. --INPUT statement handler--
|
|
|
|
Set state to 0 in case INPUT ends.
|
|
|
|
If character is not a carriage return, echo it on
|
|
|
|
screen as long as EXEC is not in effect with NOMON I
|
|
|
|
but exit DOS in any case. (KSWL will set state=3)
|
|
|
|
Otherwise, call A65E to see if BASIC is executing a
|
|
|
|
program or is in immediate mode. If EXEC is running
|
|
|
|
or if BASIC is in immediate mode, go to state 1 to
|
|
|
|
collect the possible DOS command.
|
|
|
|
Otherwise, exit DOS, echoing the character as
|
|
|
|
appropriate.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F52-9F60 State 4 output handler. --WRITE data to a file--
|
|
|
|
If the character is a carriage return, set state to
|
|
|
|
5 (start of write data line).
|
|
|
|
Call A60E to write the byte to the disk file.
|
|
|
|
Exit DOS with echo on screen if MON O.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F61-9F70 State 5 output handler. --Start of WRITE data line--
|
2017-07-20 22:45:47 +00:00
|
|
|
If the character is a control-D, go to state 0 to
|
2017-07-20 21:50:14 +00:00
|
|
|
immediately exit write mode.
|
|
|
|
If the character is a line feed, write it and exit,
|
|
|
|
staying in state 5.
|
|
|
|
Otherwise, set the state to 4 and go to state 4.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F71-9F77 State 6 output handler. --Skip prompt character--
|
|
|
|
Set state to 0.
|
|
|
|
Exit DOS via 9F9D (echo if MON I).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F78-9F82 Finish RUN command, interrupted by APPLESOFT RAM LOAD
|
|
|
|
Reset the "RUN interrupted" flag.
|
|
|
|
Call A851 to replace the DOS CSWL/KSWL intercepts.
|
|
|
|
Go to A4DC to complete the RUN command.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F83-9F94 DOS command scanner exit to BASIC routine.
|
|
|
|
If first character of command line is control-D,
|
|
|
|
go to echo exit (9F95).
|
|
|
|
Otherwise, set things up so BASIC won't see the DOS
|
|
|
|
command by passing a zero length line (only a
|
|
|
|
carriage return). Fall through to echo exit.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9F95-9FB0 Echo character on screen (conditionally) and exit DOS
|
|
|
|
9F95 Echo only if MON C set, otherwise, go to 9FB3.
|
|
|
|
9F99 Echo only if MON O set, otherwise, go to 9FB3.
|
|
|
|
9F9D Echo only if MON I set, otherwise, go to 9FB3.
|
|
|
|
9FA4 Always echo character.
|
|
|
|
Call 9FBA to restore registers at entry to DOS.
|
|
|
|
Call 9FC5 to echo character on screen.
|
|
|
|
Save contents of the registers after echoing.
|
|
|
|
Fall through to DOS exit routine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9FB3-9FC4 DOS exit routine and register restore.
|
|
|
|
Call A851 to put back DOS KSWL/CSWL intercepts.
|
|
|
|
Restore S (stack) register from entry to DOS.
|
|
|
|
9FBA DOS register restore subroutine.
|
|
|
|
Restore registers from first entry to DOS and return
|
|
|
|
to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9FC5-9FC7 A jump to the true CSWL routine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9FC8-9FCC Skip a line on the screen.
|
|
|
|
Load a carriage return into the A register and
|
|
|
|
call 9FC5 to print it.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-20 21:50:14 +00:00
|
|
|
9FCD-A179 DOS command parse routine.
|
2017-07-21 12:26:27 +00:00
|
|
|
Set the command index to -1 (none).
|
|
|
|
Reset the pending command flag (none pending).
|
|
|
|
9FD6 Add one to command index.
|
|
|
|
If first charcater is a control-D, skip it.
|
|
|
|
Flush to a non-blank (call A1A4).
|
|
|
|
Compare command to command name in command name table
|
|
|
|
at A884 for the current command index.
|
|
|
|
If it doesn't match and if there are more entries
|
|
|
|
left to check, go back to 9FD6.
|
|
|
|
If it does match, go to A01B.
|
|
|
|
Otherwise, if command was not found in the table,
|
|
|
|
check to see if the first character was a control-D.
|
|
|
|
If so, go to A6C4 to print "SYNTAX ERROR".
|
|
|
|
Otherwise, call A75B to reset the state and warmstart
|
|
|
|
flag and go to 9F95 to echo the command and exit.
|
|
|
|
(the command must be for BASIC, not DOS)
|
|
|
|
A01B Compute an index into the operand table for the
|
|
|
|
command which was entered.
|
|
|
|
Call A65E to see if a BASIC program is executing.
|
|
|
|
If not, and the command is not a direct type command,
|
|
|
|
(according to the operand table) go to A6D2 to print
|
|
|
|
"NOT DIRECT COMMAND".
|
|
|
|
Otherwise, if the command is RUN, make the prompt
|
|
|
|
character ($33) non-printing.
|
|
|
|
Check the operand table to see if a first filename
|
|
|
|
is a legal operand for this command.
|
|
|
|
If not, go to A0A0.
|
|
|
|
Otherwise, clear the filename buffer (call A095).
|
|
|
|
Flush to the next non-blank (call A1A4) and copy
|
|
|
|
the filename operand to the first filename buffer.
|
|
|
|
Skip forward to a comma if one was not found yet.
|
|
|
|
If a second filename is legal for this command, use
|
|
|
|
the code above to copy it into the second filename
|
|
|
|
buffer.
|
|
|
|
Check both filenames to see if they are blank.
|
|
|
|
If one was required by the command but not given,
|
|
|
|
give a syntax error or pass it through to BASIC.
|
|
|
|
(As in the case of LOAD with no operands)
|
|
|
|
If all is well, go to A0D1 to continue.
|
|
|
|
A095 A subroutine to blank both filename buffers.
|
|
|
|
A0A0 Indicate no filename parsed.
|
|
|
|
Check operand table to see if a positional operand
|
|
|
|
is expected.
|
|
|
|
If not, go to A0D1 to continue.
|
|
|
|
Otherwise, call A1B9 to convert the numeric operand.
|
|
|
|
If omitted, give syntax error.
|
|
|
|
If number converted exceeds 16, give "RANGE ERROR"
|
|
|
|
If number is supposed to be a slot number, give
|
|
|
|
"RANGE ERROR" if it exceeds 7.
|
|
|
|
If number is not a slot number, give "RANGE ERROR" if
|
|
|
|
it is zero. (MAXFILES 0 is a no-no)
|
|
|
|
A0D1 Set defaults for the keyword operands (V=0,L=0,B=0)
|
|
|
|
A0E8 Get the line offset index and flush to the next
|
|
|
|
non-blank, skipping any commas found.
|
|
|
|
If we are not yet to the end of the line, go to A10C.
|
|
|
|
Check to see if any keywords were given which were
|
|
|
|
not allowed for this command.
|
|
|
|
If not, go to A17A to process the command.
|
|
|
|
A10C Lookup the keyword found on the command line in the
|
|
|
|
table of valid keywords (A940)
|
|
|
|
If not in table, give "SYNTAX ERROR" message.
|
|
|
|
Get its bit position in the keywords-given flag.
|
|
|
|
If the keyword does not have an operand value, go to
|
|
|
|
A164.
|
|
|
|
Otherwise, indicate keyword found in flag.
|
|
|
|
Convert the numeric value associated with keyword.
|
|
|
|
Give "SYNTAX ERROR" message if invalid.
|
|
|
|
Check to see if the number is within the acceptable
|
|
|
|
range as given in the keyword valid range table at
|
|
|
|
A955.
|
|
|
|
Save the value of the keyword in the keyword values
|
|
|
|
table starting at AA66.
|
|
|
|
Go parse the next keyword. go to A0E8.
|
|
|
|
A164 Indicate C, I, or O keywords were parsed.
|
|
|
|
Update the MON value in the keyword value table
|
|
|
|
appropriately.
|
|
|
|
Go parse the next keyword. go to A0E8.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A17A-A17F Call A180 to process the command, then exit via echo
|
|
|
|
at 9F83.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A180-A192 Do command.
|
|
|
|
Reset the video intercept state to zero.
|
|
|
|
Clear the file manager parameter list.
|
|
|
|
Using the command index, get the address of the
|
|
|
|
command handling routine from the command handler
|
|
|
|
routine table at 9D1E and go to it.
|
|
|
|
Command handler will exit to caller of this routine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A193-A1A3 Get next character on command line and check to see
|
|
|
|
if it is a carriage return or a comma.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A1A4-A1AD Flush command line characters until a non-blank is
|
|
|
|
found.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A1AE-A1B8 Clear the file manager parameter list at B5BA to
|
|
|
|
zeros.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A1B9-A1D5 Convert numeric operand from command line. Call
|
|
|
|
either A1D6 (decimal convert) or A203 (hex convert)
|
|
|
|
depending upon the presence or lack thereof of a
|
|
|
|
dollar sign ($).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A1D6-A202 Decimal convert subroutine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A203-A228 Hexadecimal convert subroutine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A229-A22D PR#n command handler.
|
|
|
|
Load the parsed numeric value and exit via FE95 in
|
|
|
|
the monitor ROM.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A22E-A232 IN#n command handler.
|
|
|
|
Load the parsed numeric value and exit via FE8B in
|
|
|
|
the monitor ROM.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A233-A23C MON command handler.
|
|
|
|
Add new MON flags to old in AA5E and exit.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A23D-A250 NOMON command handler.
|
|
|
|
If C was given, put out a carriage return since this
|
|
|
|
line was echoed but its CR was not.
|
|
|
|
Turn off the proper bits in AA5E and exit.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A251-A262 MAXFILES command handler.
|
|
|
|
Turn off any EXEC file which is active.
|
|
|
|
Close all open files (call A316).
|
|
|
|
Set the new MAXFILES number at AA57.
|
|
|
|
Go to A7D4 to rebuild the DOS file buffers and exit.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A263-A270 DELETE command handler.
|
|
|
|
Load the delete file manager opcode (05).
|
|
|
|
Call the file manager open driver (A2AA) to perform
|
|
|
|
the delete.
|
|
|
|
Find the file buffer used to do the delete and free
|
|
|
|
it (call A764).
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A271-A274 LOCK command handler.
|
|
|
|
Load the lock file manager opcode (07) and go to
|
|
|
|
A277.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A275-A27C UNLOCK command handler.
|
|
|
|
Load the unlock file manager opcode (08).
|
|
|
|
A277 Call the file manager open driver (A2AA) to perform
|
|
|
|
the desired function.
|
|
|
|
Exit to the caller via close (A2EA).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A27D-A280 VERIFY command handler.
|
|
|
|
Load the verify file manager opcode (0C) and go to
|
|
|
|
A277 to perform function.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A281-A297 RENAME command handler.
|
|
|
|
Store address of second file name in file manager
|
|
|
|
parameter list.
|
|
|
|
Load the rename file manager opcode (09).
|
|
|
|
Call the file manager driver at A2C8.
|
|
|
|
Exit via close (A2EA).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A298-A2A2 APPEND command handler.
|
|
|
|
Call A2A3 to OPEN the file.
|
|
|
|
Read the file byte by byte until a zero is found.
|
|
|
|
If append flag is on, add one to record number
|
|
|
|
and turn flag off.
|
|
|
|
Exit via a call to POSITION.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A2A3-A2A7 OPEN command handler.
|
|
|
|
Set file type as TEXT.
|
|
|
|
Go to A3D5 to open file.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A2A8-A2E9 Command handler common file management code.
|
|
|
|
Set opcode to OPEN.
|
|
|
|
A2AA If no L value was given on the command, use 0001 and
|
|
|
|
store record length value in file manager parmlist.
|
|
|
|
A2C8 Close file if already open.
|
|
|
|
Is there an available file buffer?
|
|
|
|
If not, issue "NO FILE BUFFERS AVAILABLE" message.
|
|
|
|
Point $40,$41 at the free file buffer.
|
|
|
|
Copy filename to file buffer (allocates the buffer)
|
|
|
|
(A743).
|
|
|
|
Copy buffer pointers to file manager parmlist (A74E).
|
|
|
|
Finish filling in the file manager parmlist (A71A).
|
|
|
|
Set operation code in parmlist.
|
|
|
|
Exit through the file manager driver.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A2EA-A2FB CLOSE command handler.
|
|
|
|
If no filename was given as part of command,
|
|
|
|
go to A316 to close all files.
|
|
|
|
Otherwise, find the open file buffer for filename
|
|
|
|
(A764).
|
|
|
|
If no such file open, exit to caller.
|
|
|
|
Otherwise, close file and free buffer (A2FC).
|
|
|
|
Go back through CLOSE command handler to make sure
|
|
|
|
there are not more open buffers for the same file.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A2FC-A315 Close a file and free its file buffer.
|
|
|
|
Find out if this buffer is EXEC's (A7AF).
|
|
|
|
If so, turn EXEC flag off.
|
|
|
|
Release the buffer by storing a $00 on its filename
|
|
|
|
field.
|
|
|
|
Copy file buffer pointers to the file manager
|
|
|
|
parmlist.
|
|
|
|
Set file manager opcode to CLOSE.
|
|
|
|
Exit through the file manager driver routine.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A316-A330 Close all open files.
|
|
|
|
Point to first file buffer (A792).
|
|
|
|
Go to A320.
|
|
|
|
A31B Point to next file buffer on chain (A79A).
|
|
|
|
If at end of chain, exit to caller.
|
|
|
|
A320 Is this file buffer EXEC's?
|
|
|
|
If so, skip it and go to A31B.
|
|
|
|
Is it not in use (open)?
|
|
|
|
If so, skip it and go to A31B.
|
|
|
|
Otherwise, close it and free it (A2FC).
|
|
|
|
Go to A316 to start all over.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A331-A35C BSAVE command handler.
|
|
|
|
Insure that the A and L keywords were present on the
|
|
|
|
command.
|
|
|
|
If not, issue "SYNTAX ERROR" message.
|
|
|
|
Open and verify a B type file (A3D5).
|
|
|
|
Write the A keyword value as the first two bytes of
|
|
|
|
the file.
|
|
|
|
Write the L keyword value as the next two bytes of
|
|
|
|
the file.
|
|
|
|
Use the A value to exit by writing a range of bytes
|
|
|
|
from memory to the file.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A35D-A38D BLOAD command handler.
|
|
|
|
Open the file, ignoring its type.
|
|
|
|
Insure the type is B.
|
|
|
|
If not, issue "FILE TYPE MISMATCH" message.
|
|
|
|
Otherwise, open B type file and test file type (A3D5)
|
|
|
|
Read the A value from the first two bytes of file.
|
|
|
|
If A keyword was not given, use the value just read.
|
|
|
|
Read L value as next two bytes in file.
|
|
|
|
Go to A471 to read range of bytes to memory from file
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A38E-A396 BRUN command handler.
|
|
|
|
Call BLOAD command handler to load file into memory.
|
|
|
|
Replace DOS intercepts.
|
|
|
|
Exit DOS by jumping to the A address value to begin
|
|
|
|
execution of the binary program.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A397-A3D4 SAVE command handler.
|
|
|
|
Get the active BASIC type (AAB6).
|
|
|
|
If INTEGER, go to A3BC.
|
|
|
|
If APPLESOFT, test $D6 flag to see if program is
|
|
|
|
protected.
|
|
|
|
If so, issue "PROGRAM TOO LARGE" message.
|
|
|
|
Otherwise, open and test for A type file (A3D5).
|
|
|
|
Compute program length (PGMEND-LOMEM).
|
|
|
|
Write this two byte length to file.
|
|
|
|
Exit by writing program image from LOMEM as a range
|
|
|
|
of bytes (A3FF).
|
|
|
|
A3BC Open and test for I type file (A3D5).
|
|
|
|
Compute program length (HIMEM-PGMSTART).
|
|
|
|
Write this two byte length to file.
|
|
|
|
Exit by writing program image from PGMSTART as a
|
|
|
|
range of bytes (A3FF).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A3D5-A3DF Open and test file type.
|
|
|
|
Set file type wanted in file manager parmlist.
|
|
|
|
Call A2A8 to open file.
|
|
|
|
Go to A7C4 to check file type.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A3E0-A3FE Write a 2 byte value to the open file.
|
|
|
|
Store value to be written in file manager parmlist.
|
|
|
|
Set write one byte opcodes.
|
|
|
|
Call file manager driver.
|
|
|
|
Call it again to write second byte and exit to caller
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A3FF-A40F Read/write a range of bytes.
|
|
|
|
Set the address of the range in file manager parmlist
|
|
|
|
Set subcode to read or write a range of bytes.
|
|
|
|
Call the file manager driver.
|
|
|
|
Close the file.
|
|
|
|
Exit through the VERIFY command handler to insure
|
|
|
|
data was written ok.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A410-A412 Issue "FILE TYPE MISMATCH" message.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A413-A479 LOAD command handler.
|
|
|
|
Close all files (A316).
|
|
|
|
Open the file in question.
|
|
|
|
Is it an A or I type file?
|
|
|
|
If not, issue "FILE TYPE MISMATCH" message.
|
|
|
|
Which BASIC is active?
|
|
|
|
If INTEGER, go to A450.
|
|
|
|
Select APPLESOFT BASIC (A4B1). This call could result
|
|
|
|
in DOS losing control if the RAM version must be
|
|
|
|
run.
|
|
|
|
Read first two bytes of file as length of program.
|
|
|
|
Add length to LOMEM (program start) to compute
|
|
|
|
program end.
|
|
|
|
Is program end beyond HIMEM?
|
|
|
|
If so, close file and issue "PROGRAM TOO LARGE".
|
|
|
|
Set program end and start of variables pointers.
|
|
|
|
Read program as range of bytes to program start.
|
|
|
|
Replace DOS intercepts (A851).
|
|
|
|
Go to BASIC's relocation routine to convert a RAM
|
|
|
|
APPLESOFT program to ROM and vice versa as needed.
|
|
|
|
A450 Select INTEGER BASIC (A4B1).
|
|
|
|
Read length of program (first two bytes in file).
|
|
|
|
Compute program start (HIMEM-LENGTH).
|
|
|
|
If zero or less than LOMEM, issue "PROGRAM TOO LARGE"
|
|
|
|
message and close file.
|
|
|
|
Set program start pointers.
|
|
|
|
Read program into memory as a range of bytes.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A47A-A4AA Read two bytes from file (Address or Length).
|
|
|
|
Set up parmlist to read two bytes to range length
|
|
|
|
field (AA60).
|
|
|
|
Call file manager driver.
|
|
|
|
Store value read as range length in file manager
|
|
|
|
parmlist just in case it was a length.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4AB-A4B0 Close file and issue "PROGRAM TOO LARGE" message.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4B1-A4D0 Select desired BASIC.
|
|
|
|
If desired BASIC is already active, exit to caller.
|
|
|
|
Save current command index in case we must RUN
|
|
|
|
APPLESOFT.
|
|
|
|
If INTEGER, go to A59E to select it.
|
|
|
|
Otherwise, copy primary file name to secondary
|
|
|
|
buffer to save it in case RAM APPLESOFT is needed.
|
|
|
|
Go to A57A to set APPLESOFT.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4D1-A4E4 RUN command handler.
|
|
|
|
If APPLESOFT is active, set RUN intercepted flag so
|
|
|
|
that RUN can complete after APPLESOFT is loaded.
|
|
|
|
Call LOAD command handler to load the program.
|
|
|
|
Skip a line on the screen.
|
|
|
|
Put DOS intercepts back.
|
|
|
|
Go to the RUN entry point in the current BASIC.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4E5-A4EF INTEGER BASIC RUN entry point intercept.
|
|
|
|
Delete all variables (CLR equivalent).
|
|
|
|
Go to the CHAIN entry point in INTEGER BASIC.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4F0-A4FB CHAIN command handler.
|
|
|
|
Call the LOAD command handler to load the program.
|
|
|
|
Skip a line.
|
|
|
|
Replace DOS intercepts.
|
|
|
|
Go to current BASIC's CHAIN entry point.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A4FC-A505 APPLESOFT ROM RUN entry point intercept.
|
|
|
|
Call APPLESOFT to clear variables.
|
|
|
|
Reset ONERR.
|
|
|
|
Go to RUN entry point.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A506-A50D APPLESOFT RAM RUN entry point intercept.
|
|
|
|
Call APPLESOFT to clear variables.
|
|
|
|
Reset ONERR.
|
|
|
|
Go to RUN entry point.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A510-A51A WRITE command handler.
|
|
|
|
Call READ/WRITE common code (A526).
|
|
|
|
Set CSWL state to 5 (WRITE mode line start).
|
|
|
|
Exit DOS (9F83).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A51B-A525 READ command handler.
|
|
|
|
Call READ/WRITE common code (A526).
|
|
|
|
Set READ mode flag in status flags (AA51).
|
|
|
|
Exit DOS (9F83).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A526-A54E READ/WRITE common code.
|
|
|
|
Locate the open file buffer for this file (A764).
|
|
|
|
If not open, open it.
|
|
|
|
Copy file buffer addresses to file manager parmlist.
|
|
|
|
If R or B were given on command, copy to parmlist
|
|
|
|
and issue a POSITION call to file manager.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A54F-A56D INIT command handler.
|
|
|
|
If V was given, use it. Otherwise, use 254.
|
|
|
|
Store first page number of DOS in file manager
|
|
|
|
parmlist.
|
|
|
|
Call file manager driver to INIT diskette.
|
|
|
|
Exit through SAVE to store greeting program on disk.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A56E-A579 CATALOG command handler.
|
|
|
|
Call file manager with CATALOG opcode.
|
|
|
|
Set new V value as default for future commands.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A57A-A59D FP command handler.
|
|
|
|
Set ROM card, if any, for APPLESOFT (A5B2).
|
|
|
|
If successful, coldstart DOS (9D84).
|
|
|
|
Otherwise, set status flag to indicate INTEGER BASIC
|
|
|
|
is active.
|
|
|
|
Set primary filename buffer to "APPLESOFT".
|
|
|
|
Set flags to indicate RAM APPLESOFT and coldstart.
|
|
|
|
Go to RUN command handler.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A59E-A5B1 INT command handler.
|
|
|
|
Set ROM card, if any, for INTEGER BASIC (A5B2).
|
|
|
|
If not successful, issue "LANGUAGE NOT AVAILABLE".
|
|
|
|
Otherwise, clear RUN intercepted flag.
|
|
|
|
Coldstart DOS (9D84).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A5B2-A5C5 Set ROM to desired BASIC.
|
|
|
|
(This routine is passed a $4C for APPLESOFT or a $20
|
|
|
|
for INTEGER, since these bytes appear at $E000 in
|
|
|
|
these BASICs. It will work regardless of which
|
|
|
|
BASIC is onboard)
|
|
|
|
If desired BASIC is already available, exit.
|
|
|
|
Try selecting ROM card.
|
|
|
|
If desired BASIC is now available, exit.
|
|
|
|
Try selecting onboard ROM.
|
|
|
|
If desired BASIC is now available, exit.
|
|
|
|
Otherwise, exit with error return code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A5C6-A5DC EXEC command handler.
|
|
|
|
Open the file (A2A3).
|
|
|
|
Copy file buffer address to EXEC's buffer pointer at
|
|
|
|
AAB4,AAB5.
|
|
|
|
Set EXEC active flag (AAB3).
|
|
|
|
Jump into POSITION command handler to skip R lines.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A5DD-A60D POSITION command handler.
|
|
|
|
Locate the open file buffer (A764).
|
|
|
|
If not found, open one as a TEXT file.
|
|
|
|
Copy buffer pointers to file manager parmlist.
|
|
|
|
If R was not given on command, exit.
|
|
|
|
A5F2 Otherwise, test R value for zero and exit if so.
|
|
|
|
Decrement R value by one.
|
|
|
|
Read file byte by byte until a carriage return (end
|
|
|
|
of line - $8D) is reached.
|
|
|
|
If at end of file, issue "END OF FILE" message.
|
|
|
|
Otherwise, go to A5F2 to skip next record.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A60E-A625 Write one data byte to file.
|
|
|
|
Insure that BASIC is running a program (A65E).
|
|
|
|
If not, close file and warmstart DOS.
|
|
|
|
Set up file manager parmlist to write the data byte
|
|
|
|
to the open file.
|
|
|
|
Call file manager and exit.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A626-A65B Read one data byte from file.
|
|
|
|
Insure that BASIC is running a program (A65E).
|
|
|
|
If not, close file and warmstart DOS.
|
|
|
|
Set CSWL intercept state to 6 (skip prompt character)
|
|
|
|
A630 Read next file byte (A68C).
|
|
|
|
If not at end of file, go to A644.
|
|
|
|
Otherwise, close file.
|
|
|
|
If state is not 3 (EXEC) issue "END OF DATA" message.
|
|
|
|
Exit to caller.
|
|
|
|
A644 If data byte is lower case character, turn its most
|
|
|
|
significant bit off to fool GETIN routine in monitor.
|
|
|
|
Store data byte in A register saved at entry to DOS.
|
|
|
|
Using line index, turn high bit back on in previous
|
|
|
|
data byte stored at $200 (input line buffer) to make
|
|
|
|
it lower case if necessary.
|
|
|
|
Exit DOS (9FB3).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A65E-A678 Test to see if BASIC is running a program or is in
|
|
|
|
immediate command mode.
|
|
|
|
If active BASIC is INTEGER, go to A672.
|
|
|
|
If line number is greater than 65280 and prompt is
|
|
|
|
"]" then APPLESOFT is in immediate mode.
|
|
|
|
Otherwise, it is executing a program.
|
|
|
|
Exit to caller with appropriate return code.
|
|
|
|
A672 Check $D9 to determine whether BASIC is executing a
|
|
|
|
program and exit with proper return code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A679-A681 Close current file and warmstart DOS.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A682-A68B EXEC read one byte from file.
|
|
|
|
Select EXEC file buffer.
|
|
|
|
Copy file buffer addresses to file manager parmlist.
|
|
|
|
Set state to 3 (input echo).
|
|
|
|
Go to A62D to read a file byte.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A68C-A69C Read next text file byte.
|
|
|
|
Set up file manager parmlist to read one byte.
|
|
|
|
Call file manager driver.
|
|
|
|
Return to caller with the data byte.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A69D-A6A7 Set $40,$41 to point to EXEC file buffer.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A6A8-A6C3 File manager driver routine.
|
|
|
|
Call the file manager itself (AB06).
|
|
|
|
If no errors, exit to caller.
|
|
|
|
Otherwise, point $40,$41 at file buffer.
|
|
|
|
If found, release it by storing a zero on the file
|
|
|
|
name field.
|
|
|
|
If error was not "END OF DATA", print error message.
|
|
|
|
Otherwise, pretend a $00 was read and return to
|
|
|
|
caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A6C4-A6D4 Miscellaneous error messages.
|
|
|
|
A6C4 "COMMAND SYNTAX ERROR"
|
|
|
|
A6C8 "NO FILE BUFFERS AVAILABLE"
|
|
|
|
A6CC "PROGRAM TOO LARGE"
|
|
|
|
A6D0 "FILE TYPE MISMATCH"
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A6D5-A701 Error handler.
|
|
|
|
Set warmstart flag and clear status (BFE6).
|
|
|
|
If APPLESOFT ONERR is active, go to A6EF.
|
|
|
|
Otherwise, print RETURN BELL RETURN.
|
|
|
|
Print text of error message (A702).
|
|
|
|
Print another RETURN.
|
|
|
|
A6EF Replace DOS intercepts.
|
|
|
|
If a BASIC program is in execution, pass error code
|
|
|
|
to BASIC's error handler.
|
|
|
|
Otherwise, warmstart BASIC.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A702-A719 Print text of error message.
|
|
|
|
Using the error number as an index, print the message
|
|
|
|
text from the message table (A971) byte by byte.
|
|
|
|
Last character has most significant bit on.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A71A-A742 Complete file manager parameter list.
|
|
|
|
Copy Volume value to parmlist.
|
|
|
|
Copy Drive value to parmlist.
|
|
|
|
Copy Slot value to parmlist.
|
|
|
|
Copy address of primary filename buffer to parmlist.
|
|
|
|
Save file buffer address in $40,$41.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A743-A74D Copy primary filename to file buffer filename field.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A74E-A75A Copy current buffer pointers to file manager parmlist
|
|
|
|
Copy file manager workarea buffer pointer.
|
|
|
|
Copy T/S List sector buffer pointer.
|
|
|
|
Copy data sector buffer address.
|
|
|
|
Copy next file buffer link address.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A75B-A763 Reset state to 0 and set warmstart flag.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A764-A791 Locate an open or free file buffer.
|
|
|
|
Assume there are no free file buffers by zeroing $45.
|
|
|
|
Point $40,$41 at first buffer on chain.
|
|
|
|
Go to A773.
|
|
|
|
A76E Point $40,$41 at next buffer on chain.
|
|
|
|
If at end of chain, exit with file not open code.
|
|
|
|
A773 Get first byte of filename field.
|
|
|
|
If zero (file buffer free), save file buffer address
|
|
|
|
at $44,$45 as an available buffer and go to A76E.
|
|
|
|
Otherwise, see if name in primary filename buffer
|
|
|
|
matches the name in this file buffer.
|
|
|
|
If not, go to A76E to get next buffer.
|
|
|
|
If so, return to caller with open file found code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A792-A799 Point $40,$41 at first file buffer on chain.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A79A-A7A9 Point $40,$41 at next file buffer on chain.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A7AA-A7AE Get first byte of file name in file buffer.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A7AF-A7C3 See if current buffer belongs to EXEC.
|
|
|
|
Is EXEC active?
|
|
|
|
If not, exit.
|
|
|
|
If so, does current buffer address match EXEC's?
|
|
|
|
Return to caller with appropriate code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A7C4-A7D3 Check file type.
|
|
|
|
Does file type of open file match desired file type?
|
|
|
|
If so, exit.
|
|
|
|
Otherwise, turn lock bit off and test again.
|
|
|
|
If ok, exit.
|
|
|
|
Otherwise, close file and issue "FILE TYPE MISMATCH".
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A7D4-A850 Initialize (build) DOS file buffer chain.
|
|
|
|
Set $40,$41 to point to first buffer.
|
|
|
|
Set counter to MAXFILES value.
|
|
|
|
A7E5 Store zero on filename field to mark as free.
|
|
|
|
Set up link pointers in buffer to point to file
|
|
|
|
manager workarea (45 bytes prior to filename field).
|
|
|
|
Set up link pointer to T/S List sector buffer (-256
|
|
|
|
bytes from file manager workarea buffer).
|
|
|
|
Set up link pointer to data sector buffer 256 bytes
|
|
|
|
before that.
|
|
|
|
Decrement counter.
|
|
|
|
If zero, go to A82D to set HIMEM.
|
|
|
|
Otherwise, set link to next file buffer as 38 bytes
|
|
|
|
prior to data sector buffer.
|
|
|
|
Go to A7E5 to set up next buffer.
|
|
|
|
A82D Set link of last buffer to $0000.
|
|
|
|
If INTEGER BASIC is active, go to A846.
|
|
|
|
Otherwise, set APPLESOFT's HIMEM and STRING START
|
|
|
|
pointers in zeropage to point just below the last
|
|
|
|
buffer.
|
|
|
|
Exit to caller.
|
|
|
|
A846 Set INTEGER BASIC's HIMEM and PROGRAM START pointers
|
|
|
|
to point just below the last buffer.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A851-A883 Replace DOS keyboard/video intercept vectors.
|
|
|
|
Is DOS keyboard (KSWL) vector still set?
|
|
|
|
If so, go to A86A.
|
|
|
|
Otherwise, save current KSWL vector ($38,$39) at
|
|
|
|
AA55,AA56 and replace with DOS intercept routine's
|
|
|
|
address.
|
|
|
|
A86A Is DOS video (CSWL) vector still set?
|
|
|
|
If so, exit to caller.
|
|
|
|
Otherwise, save current CSWL vector ($36,$37) at
|
|
|
|
AA53,AA54 and replace with DOS intercept routine's
|
|
|
|
address.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A884-A908 DOS command name text table.
|
|
|
|
This table consists of the ASCII name for each DOS
|
|
|
|
command in order of command index values, with the
|
|
|
|
last character of each indicated by the MSB being
|
|
|
|
on. Commands in order are:
|
|
|
|
INIT,LOAD,SAVE,RUN,CHAIN,DELETE,LOCK,UNLOCK,CLOSE,
|
|
|
|
READ,EXEC,WRITE,POSITION,OPEN,APPEND,RENAME,
|
|
|
|
CATALOG,MON,NOMON,PR#,IN#,MAXFILES,FP,INT,BSAVE,
|
|
|
|
BLOAD,BRUN,VERIFY.
|
|
|
|
Example: INIT is $49 $4E $49 $D4 (I N I T)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A909-A940 Command valid keywords table.
|
|
|
|
This table is used to determine which keywords are
|
|
|
|
required or may be given for any DOS command.
|
|
|
|
Each command has a two byte entry with 16 flags,
|
|
|
|
indicating which keywords may be given. The flag
|
|
|
|
bit settings are as follows:
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BIT MEANING
|
|
|
|
0 Filename legal but optional
|
|
|
|
1 Command has no positional operand
|
|
|
|
2 Filename #1 expected
|
|
|
|
3 Filename #2 expected
|
|
|
|
4 Slot number positional operand expected
|
|
|
|
5 MAXFILES value expected as positional operand
|
|
|
|
6 Command may only be issued from within a program
|
|
|
|
7 Command may create a new file if file not found
|
|
|
|
8 C, I, O keywords legal
|
|
|
|
9 V keyword legal
|
|
|
|
10 D keyword legal
|
|
|
|
11 S keyword legal
|
|
|
|
12 L keyword legal
|
|
|
|
13 R keyword legal
|
|
|
|
14 B keyword legal
|
|
|
|
15 A keyword legal
|
|
|
|
Thus, for a typical command, OPEN, where the value
|
|
|
|
is $2378, bits 2, 6, 7, 9, 10, 11, and 12 are set so
|
|
|
|
the command has one filename operand, may only be
|
|
|
|
issued from within a program, may create a new file,
|
|
|
|
and the V, D, S, and L keywords are legal.
|
|
|
|
The command entries are:
|
|
|
|
INIT 2170
|
|
|
|
LOAD A070
|
|
|
|
SAVE A170
|
|
|
|
RUN A070
|
|
|
|
CHAIN 2070
|
|
|
|
DELETE 2070
|
|
|
|
LOCK 2070
|
|
|
|
UNLOCK 2070
|
|
|
|
CLOSE 6000
|
|
|
|
READ 2206
|
|
|
|
EXEC 2074
|
|
|
|
WRITE 2206
|
|
|
|
POSITION 2204
|
|
|
|
OPEN 2378
|
|
|
|
APPEND 2270
|
|
|
|
RENAME 3070
|
|
|
|
CATALOG 4070
|
|
|
|
MON 4080
|
|
|
|
NOMON 4080
|
|
|
|
PR# 0800
|
|
|
|
IN# 0800
|
|
|
|
MAXFILES 0400
|
|
|
|
FP 4070
|
|
|
|
INT 4000
|
|
|
|
BSAVE 2179
|
|
|
|
BLOAD 2071
|
|
|
|
BRUN 2071
|
|
|
|
VERIFY 2070
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A941-A94A Keyword name table.
|
|
|
|
This table contains all the ASCII names of the DOS
|
|
|
|
keywords in standard order. Each keyword name
|
|
|
|
occupies one byte:
|
|
|
|
V,D,S,L,R,B,A,C,I,O
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A94B-A954 Keyword flag bit positions table.
|
|
|
|
This table gives the bit positions for each keyword
|
|
|
|
into the second byte of the command valid keyword
|
|
|
|
table above and in the flag (AA65) which indicates
|
|
|
|
which keywords were present on the command line.
|
|
|
|
The bit positions are:
|
|
|
|
V - 40
|
|
|
|
D - 20
|
|
|
|
S - 10
|
|
|
|
L - 08
|
|
|
|
R - 04
|
|
|
|
B - 02
|
|
|
|
A - 01
|
|
|
|
C - C0 ...
|
|
|
|
I - A0 ... not used in valid keyword table
|
|
|
|
O - 90 ...
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A955-A970 Keyword value valid range table.
|
|
|
|
This table indicates the range any keyword value
|
|
|
|
may legally have. Each keyword has a four byte entry,
|
|
|
|
two bytes of minimum value, and two bytes of maximum
|
|
|
|
value. Values are:
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
KEYWORD MIN MAX
|
|
|
|
V 0 254
|
|
|
|
D 1 2
|
|
|
|
S 1 7
|
|
|
|
L 1 32767
|
|
|
|
R 0 32767
|
|
|
|
B 0 32767
|
|
|
|
A 0 65535
|
|
|
|
C, I, and O do not appear in this table since they
|
|
|
|
do not have numeric values.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
A971-AA3E Error message text table.
|
|
|
|
This table contains the text for each error code in
|
|
|
|
order of error code number:
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
NUMBER TEXT
|
|
|
|
0 RETURN BELL RETURN
|
|
|
|
1 "LANGUAGE NOT AVAILABLE"
|
|
|
|
2 "RANGE ERROR" (Bad file manager opcode)
|
|
|
|
3 "RANGE ERROR" (Bad file manager subcode)
|
|
|
|
4 "WRITE PROTECTED
|
|
|
|
5 "END OF DATA"
|
|
|
|
6 "FILE NOT FOUND"
|
|
|
|
7 "VOLUME MISMATCH"
|
|
|
|
8 "I/O ERROR"
|
|
|
|
9 "DISK FULL"
|
|
|
|
10 "FILE LOCKED"
|
|
|
|
11 "SYNTAX ERROR"
|
|
|
|
12 "NO BUFFERS AVAILABLE"
|
|
|
|
13 "FILE TYPE MISMATCH"
|
|
|
|
14 "PROGRAM TOO LARGE"
|
|
|
|
15 "NOT DIRECT COMMAND"
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AA3F-AA4F Error message text offset index table.
|
|
|
|
This table contains the offset in bytes to the text
|
|
|
|
of any given error message in the table above.
|
|
|
|
Entries are one byte each for each error code number.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AA4F-AA65 DOS main routines variables.
|
|
|
|
AA4F Current file buffer address (2 bytes).
|
|
|
|
AA51 Status flags: $01=READ state, $00=Warmstart,
|
|
|
|
$80=Coldstart, $40=APPLESOFT RAM
|
|
|
|
AA52 DOS CSWL intercept state number.
|
|
|
|
AA53 Address of true CSWL handler (2 bytes).
|
|
|
|
AA55 Address of true KSWL handler (2 bytes).
|
|
|
|
AA57 MAXFILES value.
|
|
|
|
AA59 Save area for S, X, Y, and A registers when DOS is
|
|
|
|
entered (4 bytes).
|
|
|
|
AA5D Command line index value (offset into line).
|
|
|
|
AA5E MON flags: (C=$40, I=$20, O=$10)
|
|
|
|
AA5F Index of last command times 2.
|
|
|
|
AA60 Range length for LOAD and BLOAD (2 bytes).
|
|
|
|
AA62 Index of pending command, if any.
|
|
|
|
AA63 Scratch variable (counter, message index, etc.)
|
|
|
|
AA64 Index of current keyword.
|
|
|
|
AA65 Keywords present on command line flags.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AA66-AA74 Keyword values parsed from command and defaulted.
|
|
|
|
AA66 Volume (2 bytes)
|
|
|
|
AA68 Drive (2 bytes)
|
|
|
|
AA6A Slot (2 bytes)
|
|
|
|
AA6C Length (2 bytes)
|
|
|
|
AA6E Record (2 bytes)
|
|
|
|
AA70 Byte (2 bytes)
|
|
|
|
AA72 Address (2 bytes)
|
|
|
|
AA74 MON value (one byte)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AA75-AA92 Primary file name buffer
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AA93-AAB0 Secondary (RENAME) file name buffer
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAB1-AAC0 DOS main routines constants and variables.
|
|
|
|
AAB1 MAXFILES default ($03).
|
|
|
|
AAB2 Control-D ($84).
|
|
|
|
AAB3 EXEC file active flag ($00=not active).
|
|
|
|
AAB4 EXEC file buffer address (2 bytes).
|
|
|
|
AAB6 Active BASIC flag: $00=INTEGER, $40=APPLESOFT ROM,
|
|
|
|
$80=APPLESOFT RAM
|
|
|
|
AAB7 RUN intercepted flag.
|
|
|
|
AAB8 "APPLESOFT" characters in ASCII (9 bytes)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAC1-AAC8 File manager constants.
|
|
|
|
AAC1 Address of RWTS paramter list (B7E8).
|
|
|
|
AAC3 Address of VTOC sector buffer (B3BB).
|
|
|
|
AAC5 Address of directory sector buffer (B4BB).
|
|
|
|
AAC7 Address of last byte of DOS plus one. (C000)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAC9-AAE4 File manager function routine entry point table.
|
|
|
|
This table contains a two byte function handler
|
|
|
|
routine address for each of the 14 file manager
|
|
|
|
opcodes in opcode order.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAE5-AAF0 File manager read subcode handler entry point table.
|
|
|
|
This table contains a two byte function handler
|
|
|
|
routine address for each of the 6 read subcodes.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAF1-AAFC File manager write subcode handler entry point table.
|
|
|
|
This table contains a two byte function handler
|
|
|
|
routine address for each of the 6 write subcodes.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AAFD-AB05 File manager external entry point (from $3D6).
|
|
|
|
Is X register zero?
|
|
|
|
If so, allow new files by simulating an INIT command
|
|
|
|
index.
|
|
|
|
Otherwise, require old file by simulating a LOAD
|
|
|
|
command index.
|
|
|
|
Fall through to main file manager entry point.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AB06-AB1E File manager main entry.
|
|
|
|
Save S register at B39B.
|
|
|
|
Restore file manager workarea from file buffer (AE6A)
|
|
|
|
Make sure opcode does not exceed 13.
|
|
|
|
If it does, return with code=2 (invalid opcode).
|
|
|
|
Use opcode as index into file manager function
|
|
|
|
routine entry point table and go to proper handler
|
|
|
|
via RTS.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AB1F-AB21 Return with return code=2 (bad opcode).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AB22-AB27 OPEN function handler.
|
|
|
|
Call common open code (AB28).
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AB28-ABDB Common open routine.
|
|
|
|
Initialize file manager workarea by resetting
|
|
|
|
variables to their defaults (ABDC).
|
|
|
|
Set sector length to 256.
|
|
|
|
Insure record length is non-zero. If zero, use 1.
|
|
|
|
Store record length in file manager workarea.
|
|
|
|
Locate or allocate a directory entry for the file
|
|
|
|
(B1C9).
|
|
|
|
If file already exists, go to ABA6.
|
|
|
|
Otherwise, save directory index for free entry.
|
|
|
|
Using last command index and valid keywords table,
|
|
|
|
determine whether current command may create a new
|
|
|
|
file.
|
|
|
|
If so, go to AB64.
|
|
|
|
Otherwise, if running "APPLESOFT", set return code
|
|
|
|
to "LANGUAGE NOT AVAILABLE" and exit.
|
|
|
|
If not running "APPLESOFT" set return code to "FILE
|
|
|
|
NOT FOUND" and exit.
|
|
|
|
AB64 Set sector count in directory entry to 1 (there will
|
|
|
|
only be a T/S List sector initially).
|
|
|
|
Allocate a sector for a T/S List (B244).
|
|
|
|
Store sector number of this sector in directory
|
|
|
|
entry and in first and current T/S List sector number
|
|
|
|
in file manager workarea.
|
|
|
|
Store track number in both places also.
|
|
|
|
Move file type desired to directory entry.
|
|
|
|
Write directory sector back to catalog (B037).
|
|
|
|
Select T/S List buffer (AF0C).
|
|
|
|
Zero it (B7D6).
|
|
|
|
And write it back (AF3A).
|
|
|
|
Set return code to 6 ("FILE NOT FOUND").
|
|
|
|
ABA6 Place track/sector of T/S List in directory entry in
|
|
|
|
first T/S List variable in file manager workarea.
|
|
|
|
Copy file type from directory to parmlist to pass it
|
|
|
|
back to caller and to file manager workarea.
|
|
|
|
Copy number of sectors in file to workarea.
|
|
|
|
Save directory offset to entry in workarea.
|
|
|
|
Set end of data pointer to "infinity".
|
|
|
|
Set number of data bytes represented by one T/S List
|
|
|
|
sector to 122*256 (30.5K) in workarea.
|
|
|
|
Go read first T/S List sector (AF5E).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ABDC-AC05 Initialize file manager workarea.
|
|
|
|
Zero entire 45 bytes of workarea.
|
|
|
|
Save complemented volume number in workarea.
|
|
|
|
Save drive number in workarea.
|
|
|
|
Save slot*16 in workarea.
|
|
|
|
Set track number to $11 (catalog track).
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC06-AC39 CLOSE function handler.
|
|
|
|
Checkpoint data buffer to disk if needed (AF1D).
|
|
|
|
Checkpoint T/S List buffer if needed (AF34).
|
|
|
|
Release any sectors which were preallocated but not
|
|
|
|
used (B2C3).
|
|
|
|
If VTOC does not need to be re-read, exit.
|
|
|
|
Otherwise, re-read VTOC sector (AFF7).
|
|
|
|
Flush through directory sectors in the catalog until
|
|
|
|
we reach the one which contains the entry for this
|
|
|
|
file.
|
|
|
|
Get the index to the entry.
|
|
|
|
Update the sector count in the entry to reflect the
|
|
|
|
new file's length.
|
|
|
|
Checkpoint the directory sector back to the disk.
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC3A-AC57 RENAME function handler.
|
|
|
|
Call common code to locate/open the file.
|
|
|
|
If file is locked, exit with "FILE LOCKED" return
|
|
|
|
code.
|
|
|
|
Set $42,$43 to point to new name.
|
|
|
|
Copy new name to directory entry.
|
|
|
|
Write back directory sector to disk.
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC58-AC69 READ function handler.
|
|
|
|
Insure subcode does not exceed 5. If so, exit with
|
|
|
|
return code=3.
|
|
|
|
Use subcode as index into READ subcode handler entry
|
|
|
|
point table.
|
|
|
|
Go to proper handler of subcode.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC6A-AC6C Return code = 3, subcode bad
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC6D-AC6F "FILE LOCKED" error return
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC70-AC86 WRITE function handler.
|
|
|
|
If file is locked, exit with "FILE LOCKED" error.
|
|
|
|
Insure subcode does not exceed 5. If so, exit with
|
|
|
|
return code=3.
|
|
|
|
Use subcode as index into WRITE subcode handler entry
|
|
|
|
point table.
|
|
|
|
Go to proper handler of subcode.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC87-AC89 POSITION AND READ ONE BYTE subcode handler
|
|
|
|
Call position routine.
|
|
|
|
Fall through to next subcode handler.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC8A-AC92 READ ONE BYTE subcode handler.
|
|
|
|
Read next file byte (ACA8).
|
|
|
|
Store in parmlist for pass back to caller.
|
|
|
|
Exit the file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC93-AC95 POSITION AND READ A RANGE OF BYTES subcode handler.
|
|
|
|
Call position routine.
|
|
|
|
Fall through to next subcode handler.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AC96-ACA7 READ A RANGE OF BYTES subcode handler.
|
|
|
|
Decrement and check length (B1B5).
|
|
|
|
Read a byte (ACA8).
|
|
|
|
Point $42,$43 at range address and add one to address
|
|
|
|
Store byte read at address.
|
|
|
|
Loop back to AC96. (length check will exit file
|
|
|
|
manager when length is zero.)
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACA8-ACB8 Read a data byte.
|
|
|
|
Read next data sector if necessary (B0B6).
|
|
|
|
If at end of file, exit with "END OF DATA" error.
|
|
|
|
Otherwise, load data byte from data sector buffer.
|
|
|
|
Increment record number/byte offset into file (B15B).
|
|
|
|
Increment file position offset (B194).
|
|
|
|
Return with data byte read.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACBB-ACBD POSITION AND WRITE ONE BYTE subcode handler.
|
|
|
|
Call position routine.
|
|
|
|
Fall through to next subcode handler.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACBE-ACC6 WRITE ONE BYTE subcode handler.
|
|
|
|
Find data byte to be written.
|
|
|
|
Write it to file (ACDA).
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACC7-ACC9 POSITION AND WRITE A RANGE OF BYTES subcode handler.
|
|
|
|
Call position routine.
|
|
|
|
Fall through to next subcode handler.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AACA-ACD7 WRITE A RANGE OF BYTES subcode handler.
|
|
|
|
Copy and advance range address pointer.
|
|
|
|
Get next byte to write.
|
|
|
|
Write it to file (ACDA).
|
|
|
|
Test and decrement length (B1B5).
|
|
|
|
Loop back to AACA.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACDA-ACEC Write a data byte.
|
|
|
|
Read the proper data sector (if necessary) (B0B6).
|
|
|
|
Store data byte to be written in sector buffer.
|
|
|
|
Flag data sector buffer as requiring rewrite.
|
|
|
|
Increment record number/byte offset into file (B15B).
|
|
|
|
Exit via file position offset increment routine
|
|
|
|
(B194).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACEF-ACF5 LOCK function handler.
|
|
|
|
Set mask byte to $80 (lock).
|
|
|
|
Go to common code (ACFB).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACF6-ACFA UNLOCK function handler.
|
|
|
|
Set mask byte to $00 (unlock).
|
|
|
|
Fall through to common code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
ACFB-AD11 LOCK/UNLOCK common code.
|
|
|
|
Locate/open file (AB28).
|
|
|
|
Get index into directory to entry.
|
|
|
|
Update file type byte to lock ($8X) or unlock ($0X).
|
|
|
|
Write directory sector back to disk.
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AD12-AD17 POSITION function handler.
|
|
|
|
Call position routine.
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AD18-AD2A VERIFY function handler.
|
|
|
|
Locate/open file (AB28).
|
|
|
|
AD1B Read next data sector.
|
|
|
|
If at end of file, exit file manager.
|
|
|
|
Otherwise, increment sector position.
|
|
|
|
And loop back to AD1B.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AD2B-AD88 DELETE function handler.
|
|
|
|
Locate/open file (AB28).
|
|
|
|
Using directory index, determine if file is locked.
|
|
|
|
If so, exit with "FILE LOCKED" error code.
|
|
|
|
Copy T/S List sector's track number from directory to
|
|
|
|
workarea and to last character of file name in the
|
|
|
|
directory entry itself.
|
|
|
|
Store a $FF over T/S List sector's track number in
|
|
|
|
directory entry to mark file deleted.
|
|
|
|
Copy T/S List sector's sector number to workarea.
|
|
|
|
Write directory sector back to disk.
|
|
|
|
AD54 Read next T/S List sector (AF5E).
|
|
|
|
If no more exist, write VTOC and exit file manager.
|
|
|
|
Otherwise, select T/S List buffer (AF0C).
|
|
|
|
Index to first T/S pair.
|
|
|
|
AD5E If track number is zero or minus, skip it.
|
|
|
|
Otherwise, free the data sector by updating the VTOC
|
|
|
|
bit map (AD89).
|
|
|
|
Index to next T/S pair.
|
|
|
|
If more, go to AD5E.
|
|
|
|
Get T/S of next T/S List sector from this one.
|
|
|
|
Free this T/S List sector (AD89).
|
|
|
|
Go process next one, if any (go to AD54).
|
|
|
|
Otherwise, write VTOC and exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AD89-AD97 Free a sector.
|
|
|
|
Call B2DD to deallocate sector in VTOC bit map.
|
|
|
|
Zero the sector allocation area of the workarea.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AD98-AE2E CATALOG function handler.
|
|
|
|
Initialize file manager workarea (ABDC).
|
|
|
|
Set V value to zero (complimented=$FF).
|
|
|
|
Read the VTOC sector (AFF7).
|
|
|
|
Set up a counter for 22 lines before waiting for
|
|
|
|
the keyboard.
|
|
|
|
Skip 2 lines on the screen.
|
|
|
|
Print "DISK VOLUME ".
|
|
|
|
Convert Volume number and print it (AE42).
|
|
|
|
Skip 2 more lines.
|
|
|
|
ADCA Read next directory sector.
|
|
|
|
If no more exist, exit file manager.
|
|
|
|
Set index to first entry.
|
|
|
|
ADD1 Get track number.
|
|
|
|
If zero, exit file manager.
|
|
|
|
If minus, skip entry (deleted file).
|
|
|
|
Print "*" if file is locked (check file type byte).
|
|
|
|
Use file type as index into file type name table at
|
|
|
|
B3A7 and print single character found there.
|
|
|
|
Print a blank.
|
|
|
|
Convert and print the number of sectors in the file.
|
|
|
|
Print a blank.
|
|
|
|
Index to filename.
|
|
|
|
Print file name.
|
|
|
|
Skip to next line.
|
|
|
|
Advance index to next directory entry.
|
|
|
|
If there are more, go to ADD1.
|
|
|
|
If not, go to ADCA to read next directory sector.
|
|
|
|
Exit when finished.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AE2F-AE41 Skip a line on CATALOG printout.
|
|
|
|
Output a carriage return.
|
|
|
|
Decrement line counter.
|
|
|
|
If still nonzero, exit.
|
|
|
|
Otherwise, wait for keyboard keypush.
|
|
|
|
Then reset counter to 21 lines.
|
|
|
|
And return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AE42-AE69 Convert the number stored at $44 to a three character
|
|
|
|
printable number and print it.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AE6A-AE7D Restore file manager workarea from file buffer.
|
|
|
|
Select file manager workarea buffer.
|
|
|
|
Set return code in parmlist to zero initially.
|
|
|
|
Copy 45 byte saved image of file manager workarea in
|
|
|
|
file buffer to real file manager workarea.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AE7E-AE8D Save file manager workarea in file buffer.
|
|
|
|
Select file manager workarea buffer.
|
|
|
|
Copy 45 byte workarea to file buffer.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AE8E-AF07 INIT function handler.
|
|
|
|
Initialize the file manager workarea (ABDC).
|
|
|
|
Call RWTS to format the diskette (B058).
|
|
|
|
Copy V value to VTOC buffer.
|
|
|
|
Start track to allocate next value at $11.
|
|
|
|
And direction of allocation as $01 (forward).
|
|
|
|
Zero VTOC bit map (all sectors in use).
|
|
|
|
Skipping the first three tracks and track $11, copy
|
|
|
|
the 4 byte bit mask (B3A0) to each track entry in
|
|
|
|
the VTOC bit map to free the sectors. This leaves the
|
|
|
|
first three tracks and the catalog track marked in
|
|
|
|
use.
|
|
|
|
Zero the directory sector buffer.
|
|
|
|
Point to directory sector buffer.
|
|
|
|
Set track $11 in RWTS parmlist.
|
|
|
|
Set up link from this directory sector to next (track
|
|
|
|
$11, sector-1).
|
|
|
|
Call RWTS to write directory sector.
|
|
|
|
Write each sector on track in this way except for
|
|
|
|
sector zero.
|
|
|
|
On last sector (sector 1) zero link pointer.
|
|
|
|
Point RWTS parms at DOS load point (B7C2).
|
|
|
|
Write DOS image onto tracks 0-2 (B74A).
|
|
|
|
Exit file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AF08-AF1C Select a buffer by setting $42,$43 to point to it.
|
|
|
|
AF08 Select file manager workarea buffer in file buffer.
|
|
|
|
AF0C Select T/S List sector buffer in file buffer.
|
|
|
|
AF10 Select data sector buffer in file buffer.
|
|
|
|
Exit to caller when $42,$43 are set.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AF1D-AF33 Checkpoint write data sector buffer to disk.
|
|
|
|
Test flag to see if buffer was changed since last
|
|
|
|
read/write.
|
|
|
|
If not, exit to caller.
|
|
|
|
Otherwise, set up RWTS pointer (AFE4).
|
|
|
|
Call RWTS to write sector.
|
|
|
|
Reset flag to indicate data sector no longer in need
|
|
|
|
of a checkpoint.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AF34-AF4A Checkpoint write T/S List sector buffer to disk.
|
|
|
|
Test flag to see if buffer was changed since last
|
|
|
|
read/write.
|
|
|
|
If not, exit to caller.
|
|
|
|
Otherwise, set up RWTS pointer (AF4B).
|
|
|
|
Call RWTS to write sector.
|
|
|
|
Reset flag to indicate T/S List sector no longer in
|
|
|
|
need of checkpoint.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AF4B-AF5D Prepare for RWTS call with a T/S List sector.
|
|
|
|
Copy address of T/S List buffer to RWTS parmlist.
|
|
|
|
Get track/sector of sector.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AF5E-AFDB Read a T/S List sector to file buffer.
|
|
|
|
(CARRY flag is set at entry to indicate whether the
|
|
|
|
first T/S List for the file is wanted (C=0) or the
|
|
|
|
next (C=1).
|
|
|
|
Memorize carry flag entry code.
|
|
|
|
Checkpoint current T/S List sector if necessary.
|
|
|
|
Set up for RWTS (AF4B).
|
|
|
|
Select T/S List buffer (AF0C).
|
|
|
|
Is first or next wanted?
|
|
|
|
If first, go to AFB5 to continue.
|
|
|
|
Otherwise, get link to next T/S List from this one.
|
|
|
|
If link is non-zero, use it to find next one and go
|
|
|
|
to AFB5.
|
|
|
|
Otherwise, we are out of T/S Lists for this file.
|
|
|
|
If we are reading file, exit with error code.
|
|
|
|
Otherwise, allocate a new sector (B244).
|
|
|
|
Point old T/S List sector to new one's track/sector.
|
|
|
|
Write old T/S List sector back to disk.
|
|
|
|
Zero the buffer to form new T/S List sector.
|
|
|
|
Compute and store the relative sector number of the
|
|
|
|
first sector listed in this sector at +5,+6 into the
|
|
|
|
buffer.
|
|
|
|
Set RWTS opcode to write new T/S List sector to disk.
|
|
|
|
AFB5 Set RWTS opcode to read old T/S List (unless we just
|
|
|
|
allocated it above).
|
|
|
|
Set track and sector and call RWTS to read old list
|
|
|
|
or write new list.
|
|
|
|
Compute relative sector number of last sector (plus
|
|
|
|
one) in this list and store in workarea.
|
|
|
|
Exit to caller with normal return code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AFDC-AFE3 Read a data sector.
|
|
|
|
Set up for RWTS (AFE4).
|
|
|
|
Set RWTS READ opcode and go to RWTS driver to do it.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AFE4-AFF6 Prepare for RWTS with data sector.
|
|
|
|
Copy address of data sector buffer to RWTS parmlist.
|
|
|
|
Get its track/sector.
|
|
|
|
And exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
AFF7-B010 Read/write the VTOC buffer.
|
|
|
|
AFF7 Read VTOC entry, go to AFFD.
|
|
|
|
AFFB Write VTOC entry, fall through.
|
|
|
|
AFFD Common code.
|
|
|
|
Copy VTOC sector buffer address to RWTS parmlist.
|
|
|
|
Get its track number and use sector $00.
|
|
|
|
Exit through RWTS driver.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B011-B036 Read a directory sector.
|
|
|
|
(If CARRY flag is zero on entry, read first directory
|
|
|
|
sector. If CARRY is one, read next)
|
|
|
|
Memorize entry code.
|
|
|
|
Set buffer pointers (B045).
|
|
|
|
First or next?
|
|
|
|
If first, get track/sector of directory sector from
|
|
|
|
VTOC at offset +1,+2.
|
|
|
|
Otherwise, get track/sector from directory sector at
|
|
|
|
offset +1,+2. If track is zero, exit with error code
|
|
|
|
(end of directory).
|
|
|
|
Call RWTS to read sector.
|
|
|
|
Exit with normal return code.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B037-B044 Write directory sector.
|
|
|
|
Set buffer pointers.
|
|
|
|
Find its track/sector in workarea.
|
|
|
|
Exit through RWTS to write it.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B045-B051 Prepare for RWTS for directory buffer.
|
|
|
|
Copy directory buffer address to RWTS parmlist.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B052-B0B3 Read/Write Track/Sector (RWTS) driver.
|
|
|
|
Set track/sector in RWTS parmlist.
|
|
|
|
B058 Set command code (read,write,etc.)
|
|
|
|
If writing, set flag (B5D5).
|
|
|
|
Set volume number expected in parmlist.
|
|
|
|
Set slot*16 in parmlist.
|
|
|
|
Set drive in parmlist.
|
|
|
|
Set sector size in parmlist.
|
|
|
|
Set IOB type in parmlist ($01).
|
|
|
|
Call RWTS, passing parmlist pointer.
|
|
|
|
Copy true volume found to file manager parmlist.
|
|
|
|
Reset volume expected field in RWTS parmlist.
|
|
|
|
If an error did not occur, exit to caller.
|
|
|
|
Otherwise, get return code.
|
|
|
|
Translate vol mismatch to rc=7, write protected to
|
|
|
|
rc=4 and all other errors to rc=8 (I/O error).
|
|
|
|
Exit file manager now.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B0B6-B133 Read next data sector (if necessary).
|
|
|
|
Is the current file position in the current data
|
|
|
|
sector now in memory?
|
|
|
|
If so, go to B12C.
|
|
|
|
Otherwise, checkpoint data sector buffer.
|
|
|
|
Is the current file position prior to or after this
|
|
|
|
T/S List's domain?
|
|
|
|
If not, go to B0F3.
|
|
|
|
Otherwise, read each T/S List for the file, starting
|
|
|
|
with the first, until the proper one is found.
|
|
|
|
If it is never found, exit with error (ran off end of
|
|
|
|
file reading).
|
|
|
|
B0F3 Data is in this T/S List sector.
|
|
|
|
Compute the displacement to the proper entry in this
|
|
|
|
T/S List sector.
|
|
|
|
Select the T/S List buffer.
|
|
|
|
Get the track of the data sector wanted.
|
|
|
|
If non-zero, go to B114.
|
|
|
|
Otherwise, if not writing, exit with error (no data
|
|
|
|
to read there).
|
|
|
|
If writing, allocate a new sector and store its
|
|
|
|
track/sector location in the list at this point
|
|
|
|
(B134).
|
|
|
|
Go to B120.
|
|
|
|
B114 Read old data sector, using the track/sector found
|
|
|
|
in the T/S List entry.
|
|
|
|
B120 Save number of sector last read in workarea.
|
|
|
|
B12C Select data buffer.
|
|
|
|
Get byte offset and exit normally to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B134-B15A Add a new data sector to file.
|
|
|
|
Allocate a sector (B244).
|
|
|
|
Put track/sector numbers in T/S List entry.
|
|
|
|
Select data buffer and zero it.
|
|
|
|
Set flags to indicate that the T/S List sector and
|
|
|
|
the data sector buffer require checkpoints.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B15B-B193 Increment record number and byte offset into file.
|
|
|
|
Copy current record number and byte offset to file
|
|
|
|
manager parameter list to pass back to caller.
|
|
|
|
Increment byte offset in workarea.
|
|
|
|
If byte offset equals record length, set byte offset
|
|
|
|
back to zero and increment record number.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B194-B1A1 Increment file position offset.
|
|
|
|
Increment byte offset into current sector by one.
|
|
|
|
If at end of sector, increment sector number by one.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B1A2-B1B4 Copy and advance range address.
|
|
|
|
Copy range address from file manager parmlist to $42.
|
|
|
|
Increment range address in parmlist for next time
|
|
|
|
through.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B1B5-B1C8 Decrement range length.
|
|
|
|
Decrement range length in file manager parmlist by
|
|
|
|
one.
|
|
|
|
If zero, exit file manager.
|
|
|
|
Otherwise, exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B1C9-B21B Locate or allocate a directory entry in the catalog.
|
|
|
|
Read the VTOC sector (AFF7).
|
|
|
|
Set $42,$43 to point to file name we are looking for.
|
|
|
|
Set pass number to one (locate file).
|
|
|
|
B1D8 Initialize directory sector offset (first sector).
|
|
|
|
B1E1 Increment sector offset.
|
|
|
|
Read directory sector.
|
|
|
|
If at end of directory, go to B23A.
|
|
|
|
Set entry index to first file entry.
|
|
|
|
B1EB Get track.
|
|
|
|
If deleted, skip entry, go to B217.
|
|
|
|
If empty, end of directory, go to B212.
|
|
|
|
Advance index to filename in directory.
|
|
|
|
Compare against filename wanted.
|
|
|
|
If they match, return entry index and exit.
|
|
|
|
If not, advance index to next entry in sector and
|
|
|
|
loop back to B1EB.
|
|
|
|
If at end of sector, go to B1E1 to get next sector.
|
|
|
|
B212 If pass number is one, go to B1D8 to start second
|
|
|
|
pass.
|
|
|
|
B217 If pass number is one, go to B20B to skip entry.
|
|
|
|
If second pass, fall through to allocate entry.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B21C-B22F Copy file name to directory entry.
|
|
|
|
Advance index to file name field in directory entry.
|
|
|
|
Copy 30 byte filename to directory entry.
|
|
|
|
Reload directory index and return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B230-B239 Advance index to next directory entry in sector.
|
|
|
|
Add 35 (length of entry) to index.
|
|
|
|
Test for end of sector and return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B23A-B243 Switch to second pass in directory scan.
|
|
|
|
If on pass one, switch to pass 2 and go to B1D8.
|
|
|
|
If on pass two, exit file manager with "DISK FULL"
|
|
|
|
error.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B244-B2C2 Allocate a disk sector.
|
|
|
|
Is there a track currently allocated to this file?
|
|
|
|
If not, go to B26A to find a track with free sectors.
|
|
|
|
B249 Otherwise, decrement sector number to get next
|
|
|
|
possible free sector number.
|
|
|
|
If there are no more sectors on this track, go to
|
|
|
|
B265 to find a new track.
|
|
|
|
Otherwise, rotate the track bit mask by one position
|
|
|
|
and get the bit for this sector.
|
|
|
|
If the sector is in use, loop back to B249.
|
|
|
|
Otherwise, add one to file's sector count.
|
|
|
|
Pass back sector number (track number is at B5F1).
|
|
|
|
And return to caller.
|
|
|
|
B265 Indicate no track is being used at present.
|
|
|
|
B26A Reset allocation flag to allow at least one complete
|
|
|
|
search of all tracks for some space.
|
|
|
|
Read VTOC sector.
|
|
|
|
B272 Get last track allocated from and add direction value
|
|
|
|
to get next track to examine (+1 or -1).
|
|
|
|
Are we back to track 0?
|
|
|
|
If so, go to B284.
|
|
|
|
Otherwise, are we past track 34?
|
|
|
|
If so, reverse direction and go to B28E.
|
|
|
|
B284 Is this the second time we have come to track 0 ?
|
|
|
|
(check allocation flag).
|
|
|
|
If so, exit with "DISK FULL" error.
|
|
|
|
Otherwise, set allocation flag to remember this.
|
|
|
|
Set direction to forward (+1).
|
|
|
|
B28E Begin at directory track (17 + or - 1).
|
|
|
|
Compute bit map index (tracknumber*4).
|
|
|
|
Copy track bit map from VTOC to workarea, watching
|
|
|
|
to see if all four bytes are zero (track is full).
|
|
|
|
In any case, set all four bytes in VTOC to zero
|
|
|
|
(allocate all sectors).
|
|
|
|
If no free sectors in the track, go to B272 to try
|
|
|
|
next track.
|
|
|
|
Otherwise, write VTOC to disk to insure file's
|
|
|
|
integrity.
|
|
|
|
Set sector number to last sector in track.
|
|
|
|
Go to B249 to allocate one of its free sectors to
|
|
|
|
the file.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B2C3-B2DC Release pre-allocated sectors in current track and
|
|
|
|
checkpoint the VTOC.
|
|
|
|
Has a track been allocated to the file?
|
|
|
|
If not, exit to caller.
|
|
|
|
Otherwise, read VTOC.
|
|
|
|
Get next sector which could have been used (number
|
|
|
|
of times track map was shifted during allocation).
|
|
|
|
Call B2DD to shift track bit map back and merge it
|
|
|
|
back into the VTOC bit map.
|
|
|
|
Indicate no track has been allocated.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B2DD-B2FF Free one or more sectors by shifting mask in file
|
|
|
|
manager's allocation area back into VTOC bit map.
|
|
|
|
(If CARRY is set, current sector is freed also)
|
|
|
|
Rotate entire 4 byte track bit mask once.
|
|
|
|
Repeat for as many sectors as were allocated.
|
|
|
|
Compute index into VTOC for this track's map.
|
|
|
|
If zero, exit.
|
|
|
|
Merge ("OR") file manager's bits with those already
|
|
|
|
in VTOC, freeing sectors which were never used by
|
|
|
|
the file.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B300-B35E Calculate file position.
|
|
|
|
Set record number passed in file manager parmlist
|
|
|
|
in workarea and in sector offsets.
|
|
|
|
Clear sector offset high part.
|
|
|
|
Perform a 16 bit multiply as follows:
|
|
|
|
3 byte file position = record number times record
|
|
|
|
length.
|
|
|
|
Add the byte offset from the parmlist into the three
|
|
|
|
byte file position value (B5E4,B5E5,B5E6).
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B35F-B37D Error exits.
|
|
|
|
B35F RC=1 "LANGUAGE NOT AVAILABLE"
|
|
|
|
B363 RC=2 "RANGE ERROR" (bad opcode)
|
|
|
|
B367 RC=3 "RANGE ERROR" (bad subcode)
|
|
|
|
B36B RC=4 "WRITE PROTECTED"
|
|
|
|
B36F RC=5 "END OF DATA"
|
|
|
|
B373 RC=6 "FILE NOT FOUND"
|
|
|
|
B377 RC=9 "DISK FULL" (all files closed)
|
|
|
|
B37B RC=A "FILE LOCKED"
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B37F-B396 Exit file manager.
|
|
|
|
B37F Exit with no errors.
|
|
|
|
Get return code of zero.
|
|
|
|
Clear carry flag and go to B386.
|
|
|
|
B385 Set carry flag to indicate error.
|
|
|
|
B386 Save return code in parmlist.
|
|
|
|
Clear monitor status register ($48) after RWTS has
|
|
|
|
probably tromped on it.
|
|
|
|
Save file manager workarea to file buffer (AE7E).
|
|
|
|
Restore processor status and stack register.
|
|
|
|
Exit to original caller of file manager.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B397-B3A3 File manager scratch space.
|
|
|
|
B397 Track/sector of current directory sector (2 bytes).
|
|
|
|
B39B S register save area.
|
|
|
|
B39C Directory index.
|
|
|
|
B39D Catalog line counter/Directory lookup flag/Etc.
|
|
|
|
B39E LOCK/UNLOCK mask/Allocation flag/Etc.
|
|
|
|
B3A0 Four byte mask used by INIT to free an entire track
|
|
|
|
in the VTOC bit map.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B3A4-B3A6 Decimal conversion table (1,10,100).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B3A7-B3AE File type name table used by CATALOG.
|
|
|
|
File types are: T,I,A,B,S,R,A,B, corresponding to
|
|
|
|
hex values: $00, $01, $02, $04, $08, $10, $20, and
|
|
|
|
$40 respectively.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B3AF-B3BA ASCII text "DISK VOLUME " backwards. Used by CATALOG.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B3BB-B4BA VTOC sector buffer.
|
|
|
|
B3BC Track/sector of first directory sector.
|
|
|
|
B3BE DOS release number (1, 2, or 3).
|
|
|
|
B3C1 Volume number of diskette.
|
|
|
|
B3E2 Number of entries in each T/S List sector.
|
|
|
|
B3EB Track to allocate next.
|
|
|
|
B3EC Direction of track allocation (+1 or -1)
|
|
|
|
B3EF Number of tracks on a disk.
|
|
|
|
B3F0 Number of sectors on a disk.
|
|
|
|
B3F1 Sector size in bytes (2 bytes)
|
|
|
|
B3F3 Track 0 bit map
|
|
|
|
B3F7 Track 1 bit map
|
|
|
|
etc.
|
|
|
|
B47B Track 34 bit map
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B4BB-B5BA DIRECTORY sector buffer.
|
|
|
|
B4BC Track/sector of next directory sector.
|
|
|
|
B4C6 First directory entry and
|
|
|
|
Track of T/S List
|
|
|
|
B4C7 Sector of T/S List
|
|
|
|
B4C8 File type and lock bit
|
|
|
|
B4C9 Filename field (30 bytes)
|
|
|
|
B4E7 Size of file in sectors (including T/S List(s)).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B5BB-B5D0 File manager parameter list.
|
|
|
|
B5BB Opcode
|
|
|
|
B5BC Subcode
|
|
|
|
B5BD Eight bytes of variable parameters depending on
|
|
|
|
opcode.
|
|
|
|
B5C5 Return code.
|
|
|
|
B5C7 Address of file manager workarea buffer.
|
|
|
|
B5C9 Address of T/S List sector buffer.
|
|
|
|
B5CB Address of data sector buffer.
|
|
|
|
B5CD Address of next DOS buffer on chain (not used).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B5D1-B5FD File manager workarea.
|
|
|
|
B5D1 1st T/S List sector's track/sector.
|
|
|
|
B5D3 Current T/S List sector's track/sector.
|
|
|
|
B5D5 Flags: 80=T/S List needs checkpoint
|
|
|
|
40=Data sector needs checkpoint
|
|
|
|
20=VTOC sector needs checkpoint
|
|
|
|
02=Last operation was write
|
|
|
|
B5D6 Current data sector's track/sector.
|
|
|
|
B5D8 Directory sector index for file entry.
|
|
|
|
B5D9 Index into directory sector to directory entry for
|
|
|
|
file.
|
|
|
|
B5DA Number of sectors described by one T/S List.
|
|
|
|
B5DC Relative sector number of first sector in list.
|
|
|
|
B5DE Relative sector number +1 of last sector in list.
|
|
|
|
B5E0 Relative sector number of last sector read.
|
|
|
|
B5E2 Sector length in bytes.
|
|
|
|
B5E4 File position (3 bytes) sector offset, byte offset
|
|
|
|
into that sector.
|
|
|
|
B5E8 Record length from OPEN.
|
|
|
|
B5EA Record number.
|
|
|
|
B5EC Byte offset into record.
|
|
|
|
B5EE Number of sectors in file.
|
|
|
|
B5F0 Sector allocation area (6 bytes).
|
|
|
|
Next sector to allocate (shift count)
|
|
|
|
Track being allocated
|
|
|
|
Four byte bit map of track being allocated, rotated
|
|
|
|
to next sector to allocate.
|
|
|
|
B5F6 File type.
|
|
|
|
B5F7 Slot number times 16.
|
|
|
|
B5F8 Drive number.
|
|
|
|
B5F9 Volume number (complemented).
|
|
|
|
B5FA Track number.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B5FE-B5FF Not used.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B600-B6FF Start of Boot 2/RWTS image.
|
|
|
|
B600 Boot 1 image which can be written to INITed disks
|
|
|
|
on track 0, sector 0.
|
|
|
|
B65D DOS 3.3 patch area.
|
|
|
|
B65D APPEND patch flag.
|
|
|
|
B65E APPEND patch. Come here when file manager driver
|
|
|
|
gets an error other than end of data.
|
|
|
|
Locate and free the file buffer.
|
|
|
|
Clear the APPEND flag.
|
|
|
|
Get the error number and go print error (A6D2).
|
|
|
|
B671 APPEND patch. Come here from APPEND command handler
|
|
|
|
to increment record number if APPEND flag is set and
|
|
|
|
to clear the flag. Exit through POSITION.
|
|
|
|
B686 VERIFY patch. Come here from I/O a range of bytes
|
|
|
|
routine to exit through VERIFY after SAVE or BSAVE.
|
|
|
|
B692 APPEND patch. Come here from file manager driver if
|
|
|
|
return code was END OF DATA.
|
|
|
|
Test the file position for zero.
|
|
|
|
If non-zero, set APPEND flag on and return to caller.
|
|
|
|
If zero (at start of file), copy record number and
|
|
|
|
byte offset to file manager parmlist and return a
|
|
|
|
zero data byte to caller.
|
|
|
|
B6FE Page address of first page in Boot 2.
|
|
|
|
B6FF Number of sectors (pages) in Boot 2.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B700-B749 DOS 2nd stage boot loader.
|
|
|
|
Set RWTS parmlist to read DOS from disk.
|
|
|
|
Call Read/Write group of pages ($B793).
|
|
|
|
Create new stack.
|
|
|
|
Call SETVIC ($FE93) and SETKBD ($FE89).
|
|
|
|
Exit to DOS coldstart ($9D84).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B74A-B78C Put DOS on tracks 0-2.
|
|
|
|
Set RWTS parmlist to write DOS to disk.
|
|
|
|
Call Read/Write group of pages ($B793).
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B78D-B792 Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B793-B7B4 Read/Write a group of pages.
|
|
|
|
call RWTS through external entry point ($B7B5).
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7B5-B7C1 Disable interrupts and call RWTS.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7C2-B7D5 Set RWTS parameters for writing DOS.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7D6-B7DE Zero current buffer.
|
|
|
|
Zero 256 bytes pointed to by $42,$43.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7DF-B7E7 DOS 2nd stage boot loader parmlist.
|
|
|
|
B7DF Unused.
|
|
|
|
B7E0 Number of pages in 2nd DOS load.
|
|
|
|
B7E1 Number of sectors to read/write.
|
|
|
|
B7E2 Number of pages in 1st DOS load.
|
|
|
|
B7E3 INIT DOS page counter.
|
|
|
|
B7E4 Pointer to RWTS parmlist (2 bytes).
|
|
|
|
B7E6 Pointer to 1st stage boot location (2 bytes).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7E8-B7F8 RWTS parmlist.
|
|
|
|
B7E8 Table type. Must be $01.
|
|
|
|
B7E9 Slot number times 16.
|
|
|
|
B7EA Drive number ($01 or $02).
|
|
|
|
B7EB Volume number expected (0 matches any volume).
|
|
|
|
B7EC Track number ($00 to $22).
|
|
|
|
B7ED Sector number ($00 to $0F).
|
|
|
|
B7EE Pointer to Device Characteristics Table (2 bytes).
|
|
|
|
B7F0 Pointer to user data buffer for READ/WRITE (2 bytes).
|
|
|
|
B7F2 Unused.
|
|
|
|
B7F3 Byte count for partial sector (use $00 for 256).
|
|
|
|
B7F4 Command code: 0=SEEK, 1=READ, 2=WRITE, 4=FORMAT.
|
|
|
|
B7F5 Error code:(valid if carry set) $10=Write protect,
|
|
|
|
$20=Volume mismatch, $40=Drive error, $80=Read error.
|
|
|
|
B7F6 Volume number found.
|
|
|
|
B7F7 Slot number found.
|
|
|
|
B7F8 Drive number found.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7F9-B7FA Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7FB-B7FE Device Characteristics Table (DCT).
|
|
|
|
B7FB Device type (should be $00).
|
|
|
|
B7FC Phases per track (should be $01).
|
|
|
|
B7FD Motor on time count (2 bytes - should be $EF, $D8).
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B7FF Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B800-B829 PRENIBBLE routine.
|
|
|
|
Converts 256 (8 bit) bytes to 342 (6 bit) "nibbles"
|
|
|
|
of the form 00XXXXXX.
|
|
|
|
Pointer to page to convert stored at $3E,$3F.
|
|
|
|
Data stored at primary and secondary buffers.
|
|
|
|
On entry: $3E,$3F contain pointer to user data.
|
|
|
|
On exit: A-reg:unknown
|
|
|
|
X-reg:$FF
|
|
|
|
Y-reg:$FF
|
|
|
|
Carry set
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B82A-B8B7 WRITE routine.
|
|
|
|
Writes prenibbilized data from primary and secondary
|
|
|
|
buffers to disk.
|
|
|
|
Calls Write a byte subroutine.
|
|
|
|
Writes 5 bytes autosync, starting data marks
|
|
|
|
($D5/$AA/$AD), 342 bytes data, one byte checksum, and
|
|
|
|
closing data marks ($DE/$AA/$EB).
|
|
|
|
Uses Write Translate Table ($ba29).
|
|
|
|
On entry: X-reg:Slot number times 16
|
|
|
|
On exit: Carry set if error
|
|
|
|
If no error:
|
|
|
|
A-reg:unknown
|
|
|
|
X-reg:unchanged
|
|
|
|
Y-reg:$00
|
|
|
|
Carry clear
|
|
|
|
Uses $26,$27,$678
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B8B8-B8C1 Write a byte subroutine.
|
|
|
|
Timing critical code used to write bytes at 32 cycle
|
|
|
|
intervals.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B8C2-B8DB POSTNIBBLE routine.
|
|
|
|
Converts 342 (6 bit) "nibbles" of the form 00XXXXXX
|
|
|
|
to 256 (8 bit) bytes.
|
|
|
|
Nibbles stored at primary and secondary buffers.
|
|
|
|
Pointer to data page stored at $3E,$3F.
|
|
|
|
On entry: X-reg:Slot number times 16
|
|
|
|
$36,$37:pointer to user data
|
|
|
|
$26:byte count in secondary buffer ($00)
|
|
|
|
On exit: A-reg:unknown
|
|
|
|
X-reg:unknown
|
|
|
|
Y-reg:byte count in secondary buffer
|
|
|
|
Carry set
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B8DC-B943 READ routine.
|
|
|
|
Read a sector of data from disk and store it at
|
|
|
|
primary and secondary buffers. (First uses secondary
|
|
|
|
buffer high to low, then primary low to high)
|
|
|
|
On entry: X-reg:Slot times 16
|
|
|
|
Read mode (Q6L,Q7L)
|
|
|
|
On exit: Carry set if error.
|
|
|
|
If no error:
|
|
|
|
A-reg:$AA
|
|
|
|
X-reg:unchanged
|
|
|
|
Y-reg:$00
|
|
|
|
Carry clear
|
|
|
|
Uses $26
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B944-B99F RDADR routine.
|
|
|
|
Read an Address Field.
|
|
|
|
Reads starting address marks ($D5/$AA/$96), address
|
|
|
|
information (volume/track/sector/checksum), and
|
|
|
|
closing address marks ($DE/$AA).
|
|
|
|
On entry: X-reg:Slot number times 16
|
|
|
|
Read mode (Q6L,Q7L)
|
|
|
|
On exit: Carry set if error.
|
|
|
|
If no error:
|
|
|
|
A-reg:$AA
|
|
|
|
X-reg:unchanged
|
|
|
|
Y-reg:$00
|
|
|
|
Carry clear
|
|
|
|
$2F: Volume number found
|
|
|
|
$2E: Track number found
|
|
|
|
$2D: Sector number found
|
|
|
|
$2C: Checksum found
|
|
|
|
Uses $26,$27
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B9A0-B9FC SEEKABS routine.
|
|
|
|
Move disk arm to desired track.
|
|
|
|
Calls arm move delay subroutine ($B9FD).
|
|
|
|
On entry: X-reg:Slot number times 16
|
|
|
|
A-reg:Desired track (halftrack for single
|
|
|
|
phase disk).
|
|
|
|
$478:Current track.
|
|
|
|
On exit: A-reg:unknown
|
|
|
|
X-reg:unchanged
|
|
|
|
Y-reg:unknown
|
|
|
|
$2A and $478:Final track
|
|
|
|
$27:Prior track (if seek needed)
|
|
|
|
Uses: $26,$27,$2A,$2B
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
B9FD-BA10 Arm move delay subroutine.
|
|
|
|
Delays a specified number of 100 Usec intervals.
|
|
|
|
On entry: A-reg:number of 100 Usec intervals.
|
|
|
|
$46,$47:Should contain motor on time count
|
|
|
|
($EF,$D8) from Device Characteristics Table
|
|
|
|
$478:Current track.
|
|
|
|
On exit: A-reg:$00
|
|
|
|
X-reg:$00
|
|
|
|
Y-reg:unchanged
|
|
|
|
Carry set
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BA11-BA28 Arm move delay table.
|
|
|
|
Contains values of 100 Usec intervals used during
|
|
|
|
Phase-on and Phase-off of stepper motor.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BA29-BA68 Write Translate Table.
|
|
|
|
Contains 6 bit "nibbles" used to convert 8 bit bytes.
|
|
|
|
Values range from $96 to $FF.
|
|
|
|
Codes with more than one pair of adjacent zeros or
|
|
|
|
with no adjacent ones are excluded.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BA69-BA95 Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BA96-BAFF Read Translate Table.
|
|
|
|
Contains 8 bit bytes used to convert 6 bit "nibbles".
|
|
|
|
Values range from $96 to $FF.
|
|
|
|
Codes with more than one pair of adjacent zeros or
|
|
|
|
with no adjacent ones are excluded.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BB00-BBFF Primary Buffer.
|
|
|
|
BC00-BC55 Secondary Buffer.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BC56-BCC3 Write Address Field during initialization.
|
|
|
|
Calls Write double byte subroutine.
|
|
|
|
Writes number of autosync bytes contained in Y-reg,
|
|
|
|
starting address marks ($D5/$AA/$96), address
|
|
|
|
information (volume/track/sector/checksum), closing
|
|
|
|
address marks ($DE/$AA/$EB).
|
|
|
|
On entry: X-reg:Slot number times 16
|
|
|
|
Y-reg:number of autosync to write
|
|
|
|
$3E: $AA
|
|
|
|
$3F: sector number
|
|
|
|
$41: volume number
|
|
|
|
$44: track number
|
|
|
|
On exit: A-reg:unknown
|
|
|
|
X-reg:unchanged
|
|
|
|
Y-reg:$00
|
|
|
|
Carry set
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BCC4-BCDE Write double byte subroutine.
|
|
|
|
Timing critical code that encodes address information
|
|
|
|
into even and odd bits and writes it at 32 cycle
|
|
|
|
intervals.
|
|
|
|
Exit to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BCDF-BCFF Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BD00-BD18 Main entry to RWTS.
|
|
|
|
Upon entry, store Y-reg and A-reg at $48,$49 as
|
|
|
|
pointers to the IOB.
|
|
|
|
Initialize maximum number of recals at 1 and seeks
|
|
|
|
at 4.
|
|
|
|
Check if the slot number has changed. If not,
|
|
|
|
branch to SAMESLOT at $BD34.
|
|
|
|
BD19-BD33 Update slot number in IOB and wait for old drive
|
|
|
|
to turn off.
|
|
|
|
BD34-BD53 SAMESLOT
|
|
|
|
Enter read mode and read with delays to see if disk
|
|
|
|
is spinning.
|
|
|
|
Save result of test and turn on motor just in case.
|
|
|
|
BD54-BD73 Move pointers in IOB to zero page for future use.
|
|
|
|
Device Characteristics Table pointer at $3C,$3D
|
|
|
|
and data buffer pointer at $3E,$3F.
|
|
|
|
Set up $47 (motor on time) with $D8 from DCT.
|
|
|
|
Check if the drive number has changed. If not,
|
|
|
|
branch to $BD74.
|
|
|
|
If so, change test results to show drive off.
|
|
|
|
BD74-BD8F Select appropriate drive and save drive being used
|
|
|
|
as high bit of $35. 1=drive 1, 0=drive 2.
|
|
|
|
Get test results. If drive was on, branch to $BD90.
|
|
|
|
Wait for capacitor to discharge using MSWAIT
|
|
|
|
subroutine at $BA00.
|
|
|
|
BD90-BDAA Get destination track and go to it using MYSEEK
|
|
|
|
subroutine at $BE5A.
|
|
|
|
Check test result again and if drive was on,
|
|
|
|
branch to TRYTRK at $BDAB.
|
|
|
|
Delay for motor to come up to speed.
|
|
|
|
BDAB-BDBB TRYTRK
|
|
|
|
Get command code.
|
|
|
|
If null, exit through ALLDONE at $BE46, turning drive
|
|
|
|
off and returning to caller.
|
|
|
|
If =4, branch to FORMDSK at $BE0D.
|
|
|
|
Otherwise, move low bit into carry (set=read,
|
|
|
|
clear=write) and save value on status reg.
|
|
|
|
If write operation, data is prenibbilized via a call
|
|
|
|
to PRENIB16 at $B800.
|
|
|
|
BDBC-BDEC Initialize maximum retries at 48 and read an
|
|
|
|
Address Field via RDADR16 at $B944.
|
|
|
|
If read was good, branch to RDRIGHT at $BDED.
|
|
|
|
If bad read, decrement retries, and, if still some
|
|
|
|
left try again. Else, prepare to recalibrate.
|
|
|
|
Decrement recal count. If no more, then indicate
|
|
|
|
drive error via DRVERR at $BE04.
|
|
|
|
Otherwise, reinitialize reseeks at 4 and recalibrate
|
|
|
|
arm. Move to desired track and try again.
|
|
|
|
BDED-BE03 RDRIGHT
|
|
|
|
Verify on correct track. If so branch to RTTRK
|
|
|
|
at $BE10.
|
|
|
|
If not, set correct track via SETTRK subroutine at
|
|
|
|
$BE95 and decrement reseek count.
|
|
|
|
If not zero then reseek track. If zero, then recal.
|
|
|
|
BE04-BE0A DRVERR
|
|
|
|
Clean up stack and status reg.
|
|
|
|
Load A-reg with $40 (drive error)
|
|
|
|
Goto HNDLERR at $BE48.
|
|
|
|
BE0B-BE0C Used to branch to ALLDONE at $BE46.
|
|
|
|
BE0D-BF0F FORMDSK
|
|
|
|
Jump to DSKFORM at $BEAF.
|
|
|
|
BE10-BE25 RTTRK
|
|
|
|
Check volume number found against volume number
|
|
|
|
wanted.
|
|
|
|
If no volume was specified, then no error.
|
|
|
|
If specified volume doesn't match, load A-reg with
|
|
|
|
$20 (volume mismatch error) and exit via HNDLERR
|
|
|
|
at $BE48.
|
|
|
|
BE26-BE45 CRCTVOL
|
|
|
|
Check to see if sector is correct.
|
|
|
|
Use ILFAV table at $BFB8 for software sector
|
|
|
|
interleaving.
|
|
|
|
If wrong sector, try again by branching back to
|
|
|
|
TRYADR at $BDC1.
|
|
|
|
If sector correct, find out what operation to do.
|
|
|
|
If write, branch to WRIT at $BE51.
|
|
|
|
Otherwise, read data via READ16 ($B8DC).
|
|
|
|
If read is good, then postnibble data via POSTNB16
|
|
|
|
($B8C2) and return to caller with no error.
|
|
|
|
BE46-BE47 ALLDONE
|
|
|
|
Skip over set carry instruction in HNDLERR.
|
|
|
|
BE48-BE50 HNDLERR
|
|
|
|
Set carry.
|
|
|
|
Store A-reg in IOB as return code.
|
|
|
|
Turn off motor.
|
|
|
|
Return to caller.
|
|
|
|
BE51-BE59 WRITE
|
|
|
|
Write a sector using WRITE16 ($B82A).
|
|
|
|
If the write was good, exit via ALLDONE ($BE46).
|
|
|
|
If bad write, load A-reg with $10 (write protect
|
|
|
|
error) and exit via HNDLERR ($BE48).
|
|
|
|
BE5A-BE8D MYSEEK
|
|
|
|
Provides necessary housekeeping before going to
|
|
|
|
SEEKABS routine.
|
|
|
|
Determines number of phases per track and stores
|
|
|
|
track information in appropriate slot dependent
|
|
|
|
location.
|
|
|
|
BE8E-BE94 XTOY routine.
|
|
|
|
Put slot in Y-reg by transferring X-reg divided
|
|
|
|
by 16 into Y-reg.
|
|
|
|
BE95-BEAE Set track number.
|
|
|
|
BEAF-BF0C INIT command handler
|
|
|
|
Provides setup for initializing a disk.
|
|
|
|
Get the desired volume number from the IOB.
|
|
|
|
Zero both the primary and secondary buffers.
|
|
|
|
Recalibrate the disk arm to track 0.
|
|
|
|
Set the number of sync bytes to be written between
|
|
|
|
sectors to $28 (40.).
|
|
|
|
Call TRACK WRITE routine for the actual formatting.
|
|
|
|
Allow 48 retries during initialization.
|
|
|
|
Double check that the first sector found is zero
|
|
|
|
after calling TRACK WRITE.
|
|
|
|
Increment the track number after successfully
|
|
|
|
formatting a track.
|
|
|
|
Loop back until 35 tracks are done.
|
|
|
|
BF0D-BF61 TRACK WRITE routine.
|
|
|
|
Start with sector zero.
|
|
|
|
Preceed it with 128 self-sync bytes.
|
|
|
|
Follow them with sectors 0 through 15 in sequence.
|
|
|
|
Set retry count for verifying the track at 48.
|
|
|
|
Fill the sector initilization map with positive
|
|
|
|
numbers.
|
|
|
|
Loop through a delay period to bypass most of the
|
|
|
|
initial self-sync bytes.
|
|
|
|
Read the first Address Field found.
|
|
|
|
If the read is good and sector zero was found,
|
|
|
|
enter the VERIFY TRACK routine.
|
|
|
|
Decrement the sync count by 2 (until it reaches 16
|
|
|
|
at which time it is decremented by 1).
|
|
|
|
If sync count is greater than or equal to 5, exit
|
|
|
|
via $BF71.
|
|
|
|
If not, set carry and return to caller.
|
|
|
|
BF62-BF87 VERIFY TRACK routine.
|
|
|
|
This routine reads all 16 sectors from the track that
|
|
|
|
was just formatted.
|
|
|
|
If an error occurs during the read of either the
|
|
|
|
Address Field or the Data Field, the number of
|
|
|
|
retries is decremented.
|
|
|
|
The routine continues reading until retries is zero.
|
|
|
|
Calls Sector Map routine ($BF88).
|
|
|
|
BF88-BFA7 Sector Map routine.
|
|
|
|
This routine marks the sector initialization map as
|
|
|
|
each sector is verified.
|
|
|
|
If an error occurs, the routine exits through $BF6C,
|
|
|
|
which decrements the number of retries and continues
|
|
|
|
if that value is greater than zero.
|
|
|
|
Upon completion of track zero, the sync count is
|
|
|
|
decremented by two if it is at least 16.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFA8-BFB7 Sector Initialization Map used to mark sectors as
|
|
|
|
they are initialized.
|
|
|
|
Contains a $30 prior to initialization of a track.
|
|
|
|
Value changed to $FF as each sector is completed.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFB8-BFC7 Sector Translate Table
|
|
|
|
Sector interleaving done with software.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFC8-BFD6 Patch area starts here.
|
|
|
|
Patch from $B741 to zero language card during boot.
|
|
|
|
Call SETVID ($FE93).
|
|
|
|
Unprotect Language Card (if present).
|
|
|
|
Store $00 at $E000.
|
|
|
|
Exit through SETKBD ($FE89) and DOS coldstart.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFD9-BFDB Unused.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFDC-BFE5 Patch called from $A0E2.
|
|
|
|
Set three additional defaults (Byte offset=0).
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFE6-BFEC Patch called from $A6D5.
|
|
|
|
Call $A75B to reset state and set warmstart flag.
|
|
|
|
Mark RUN not interrupted.
|
|
|
|
Return to caller.
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BFED-BFFF Patch called from $B377.
|
|
|
|
Call $AE7E to save file manager workarea.
|
|
|
|
Restore stack.
|
|
|
|
Close all open files ($A316).
|
|
|
|
Save stack again.
|
|
|
|
Exit through $B385 ("DISK FULL ERROR").
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
DOS ZERO PAGE USAGE
|
2017-07-21 12:29:21 +00:00
|
|
|
|
2017-07-21 12:26:27 +00:00
|
|
|
BYTE USE
|
|
|
|
24 Cursor horizontal (DOS)
|
|
|
|
26,27 Sector read buffer address (ROM)
|
|
|
|
Scratch space (RWTS)
|
|
|
|
28,29 BASL/BASH (DOS)
|
|
|
|
2A Segment merge counter (ROM,BOOT)
|
|
|
|
Scratch space (RWTS)
|
|
|
|
2B BOOT slot*16 (ROM)
|
|
|
|
Scratch space (RWTS)
|
|
|
|
2C Checksum from sector header (RWTS)
|
|
|
|
2D Sector number from sector header (RWTS)
|
|
|
|
2E Track number from sector header (RWTS)
|
|
|
|
2F Volume number from sector header (RWTS)
|
|
|
|
33 Prompt character (DOS)
|
|
|
|
35 Drive number in high bit (RWTS)
|
|
|
|
36,37 CSWL,CSWH (DOS)
|
|
|
|
38,39 KSWL,KSWH (DOS)
|
|
|
|
3C Workbyte (ROM)
|
|
|
|
Merge workbyte (BOOT)
|
|
|
|
Device characteristics table address (RWTS)
|
|
|
|
3D Sector number (ROM)
|
|
|
|
Device characteristics table address (RWTS)
|
|
|
|
3E,3F Address of ROM sector-read subroutine (BOOT)
|
|
|
|
Buffer address (RWTS)
|
|
|
|
40,41 DOS image address (BOOT)
|
|
|
|
File buffer address (DOS)
|
|
|
|
41 Format track counter (RWTS)
|
|
|
|
42,43 Buffer address (DOS)
|
|
|
|
44,45 Numeric operand (DOS)
|
|
|
|
46,47 Scratch space (RWTS)
|
|
|
|
48,49 IOB address (RWTS)
|
|
|
|
4A,4B INTEGER BASIC LOMEM address (DOS)
|
|
|
|
Format diskette workspace (RWTS)
|
|
|
|
4C,4D INTEGER BASIC HIMEM address (DOS)
|
|
|
|
67,68 APPLESOFT BASIC PROGRAM START (DOS)
|
|
|
|
69,6A APPLESOFT BASIC VARIABLES START (DOS)
|
|
|
|
6F,70 APPLESOFT BASIC STRING START (DOS)
|
|
|
|
73,74 APPLESOFT BASIC HIMEM address (DOS)
|
|
|
|
76 APPLESOFT BASIC line number high (DOS)
|
|
|
|
AF,B0 APPLESOFT BASIC PROGRAM END (DOS)
|
|
|
|
CA,CB INTEGER BASIC PROGRAM START (DOS)
|
|
|
|
CC,CD INTEGER BASIC VARIABLES END (DOS)
|
|
|
|
D6 APPLESOFT BASIC PROGRAM protection flag (DOS)
|
|
|
|
D8,D9 INTEGER BASIC line number (DOS)
|
|
|
|
APPLESOFT BASIC ONERR (DOS)
|