2343 lines
93 KiB
Raw Permalink Normal View History

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).
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.
Call an RTS instruction in the monitor ROM and
extract the return address from the stack to find out
the address of this controller card ROM.
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.
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.
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
from location $8FE, add the length of Boot 2 in
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,
Get slot*16 again and go to Boot 2 ($3700 for a
master disk, $B700 in its final relocated location).
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.
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.
9D1E-9D55 Command handler entry point table. This table
contains the address of a command handler subroutine
for each DOS command in the following standard order:
MON A233
PR# A229
IN# A22E
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).
9D62-9D6B Image of the entry point vector for INTEGER BASIC.
This image is copied to 9D56 if INTEGER BASIC is made
9D6C-9D77 Image of the entry point vector for the ROM version
9D78-9D83 Image of the entry point vector for the RAM version
9D84-9DBE DOS coldstart entry routine.
Get the slot and drive numbers and store as default
values for command keywords.
vector into current BASIC entry point vector.
Remember which BASIC is active.
Go to 9DD1.
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
Set video intercept handler state to 0.
Coldstart or warmstart the current BASIC (exit DOS).
(DOS will next gain control when BASIC prints its
input prompt character)
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
Set the video intercept state to 0 and indicate
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
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.
9E51-9E7F An image of the DOS 3-page jump vector which the
above routine copies to $3D0-$3FF. See Chapter 5 for
a description of its contents.
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).
If in read state (reading a file) go to A626 to get
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.
9EBA-9EBC A jump to the true KSWL handler routine.
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.
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.
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
If read flag is on and output is prompt character
($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.
9F12-9F22 State 1 output handler. --collect DOS command--
Using line index, store character in input buffer at
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.
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
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
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.
9F61-9F70 State 5 output handler. --Start of WRITE data line--
If the character is a control-D, go to state 0 to
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.
9F71-9F77 State 6 output handler. --Skip prompt character--
Set state to 0.
Exit DOS via 9F9D (echo if MON I).
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.
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.
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.
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.
9FC5-9FC7 A jump to the true CSWL routine.
9FC8-9FCC Skip a line on the screen.
Load a carriage return into the A register and
call 9FC5 to print it.
9FCD-A179 DOS command parse routine.
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
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
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
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
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
Go parse the next keyword. go to A0E8.
A17A-A17F Call A180 to process the command, then exit via echo
at 9F83.
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.
A193-A1A3 Get next character on command line and check to see
if it is a carriage return or a comma.
A1A4-A1AD Flush command line characters until a non-blank is
A1AE-A1B8 Clear the file manager parameter list at B5BA to
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 ($).
A1D6-A202 Decimal convert subroutine.
A203-A228 Hexadecimal convert subroutine.
A229-A22D PR#n command handler.
Load the parsed numeric value and exit via FE95 in
the monitor ROM.
A22E-A232 IN#n command handler.
Load the parsed numeric value and exit via FE8B in
the monitor ROM.
A233-A23C MON command handler.
Add new MON flags to old in AA5E and exit.
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.
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.
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.
A271-A274 LOCK command handler.
Load the lock file manager opcode (07) and go to
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).
A27D-A280 VERIFY command handler.
Load the verify file manager opcode (0C) and go to
A277 to perform function.
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).
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.
A2A3-A2A7 OPEN command handler.
Set file type as TEXT.
Go to A3D5 to open file.
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)
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.
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
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.
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
Copy file buffer pointers to the file manager
Set file manager opcode to CLOSE.
Exit through the file manager driver routine.
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.
A331-A35C BSAVE command handler.
Insure that the A and L keywords were present on the
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.
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
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.
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
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).
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.
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
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.
A410-A412 Issue "FILE TYPE MISMATCH" message.
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
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.
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.
A4AB-A4B0 Close file and issue "PROGRAM TOO LARGE" message.
A4B1-A4D0 Select desired BASIC.
If desired BASIC is already active, exit to caller.
Save current command index in case we must RUN
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.
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.
A4E5-A4EF INTEGER BASIC RUN entry point intercept.
Delete all variables (CLR equivalent).
Go to the CHAIN entry point in INTEGER BASIC.
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.
A4FC-A505 APPLESOFT ROM RUN entry point intercept.
Call APPLESOFT to clear variables.
Reset ONERR.
Go to RUN entry point.
A506-A50D APPLESOFT RAM RUN entry point intercept.
Call APPLESOFT to clear variables.
Reset ONERR.
Go to RUN entry point.
A510-A51A WRITE command handler.
Call READ/WRITE common code (A526).
Set CSWL state to 5 (WRITE mode line start).
Exit DOS (9F83).
A51B-A525 READ command handler.
Call READ/WRITE common code (A526).
Set READ mode flag in status flags (AA51).
Exit DOS (9F83).
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.
A54F-A56D INIT command handler.
If V was given, use it. Otherwise, use 254.
Store first page number of DOS in file manager
Call file manager driver to INIT diskette.
Exit through SAVE to store greeting program on disk.
A56E-A579 CATALOG command handler.
Call file manager with CATALOG opcode.
Set new V value as default for future commands.
Exit to caller.
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.
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).
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.
A5C6-A5DC EXEC command handler.
Open the file (A2A3).
Copy file buffer address to EXEC's buffer pointer at
Set EXEC active flag (AAB3).
Jump into POSITION command handler to skip R lines.
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.
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.
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).
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.
A679-A681 Close current file and warmstart DOS.
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.
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.
A69D-A6A7 Set $40,$41 to point to EXEC file buffer.
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
A6C4-A6D4 Miscellaneous error messages.
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.
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.
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.
A743-A74D Copy primary filename to file buffer filename field.
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.