No bitrot in chapter 8, cat files together!
This commit is contained in:
parent
07c72034a0
commit
73fe69173a
165
ch08-1.txt
165
ch08-1.txt
|
@ -1,165 +0,0 @@
|
|||
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.
|
||||
.np
|
||||
A17A-A17F Call A180 to process the command, then exit via echo
|
||||
at 9F83.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A193-A1A3 Get next character on command line and check to see
|
||||
if it is a carriage return or a comma.
|
||||
.np
|
||||
A1A4-A1AD Flush command line characters until a non-blank is
|
||||
found.
|
||||
.np
|
||||
A1AE-A1B8 Clear the file manager parameter list at B5BA to
|
||||
zeros.
|
||||
.np
|
||||
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 ($).
|
||||
.np
|
||||
A1D6-A202 Decimal convert subroutine.
|
||||
.np
|
||||
A203-A228 Hexadecimal convert subroutine.
|
||||
.np
|
||||
A229-A22D PR#n command handler.
|
||||
Load the parsed numeric value and exit via FE95 in
|
||||
the monitor ROM.
|
||||
.np
|
||||
A22E-A232 IN#n command handler.
|
||||
Load the parsed numeric value and exit via FE8B in
|
||||
the monitor ROM.
|
||||
.np
|
||||
A233-A23C MON command handler.
|
||||
Add new MON flags to old in AA5E and exit.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A271-A274 LOCK command handler.
|
||||
Load the lock file manager opcode (07) and go to
|
||||
A277.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
A27D-A280 VERIFY command handler.
|
||||
Load the verify file manager opcode (0C) and go to
|
||||
A277 to perform function.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.nx ch8.2
|
220
ch08-2.txt
220
ch08-2.txt
|
@ -1,220 +0,0 @@
|
|||
.np
|
||||
A2A3-A2A7 OPEN command handler.
|
||||
Set file type as TEXT.
|
||||
Go to A3D5 to open file.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A410-A412 Issue "FILE TYPE MISMATCH" message.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A4AB-A4B0 Close file and issue "PROGRAM TOO LARGE" message.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A4E5-A4EF INTEGER BASIC RUN entry point intercept.
|
||||
Delete all variables (CLR equivalent).
|
||||
Go to the CHAIN entry point in INTEGER BASIC.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A4FC-A505 APPLESOFT ROM RUN entry point intercept.
|
||||
Call APPLESOFT to clear variables.
|
||||
Reset ONERR.
|
||||
Go to RUN entry point.
|
||||
.np
|
||||
A506-A50D APPLESOFT RAM RUN entry point intercept.
|
||||
Call APPLESOFT to clear variables.
|
||||
Reset ONERR.
|
||||
Go to RUN entry point.
|
||||
.np
|
||||
A510-A51A WRITE command handler.
|
||||
Call READ/WRITE common code (A526).
|
||||
Set CSWL state to 5 (WRITE mode line start).
|
||||
Exit DOS (9F83).
|
||||
.np
|
||||
A51B-A525 READ command handler.
|
||||
Call READ/WRITE common code (A526).
|
||||
Set READ mode flag in status flags (AA51).
|
||||
Exit DOS (9F83).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A56E-A579 CATALOG command handler.
|
||||
.nx ch8.3
|
221
ch08-3.txt
221
ch08-3.txt
|
@ -1,221 +0,0 @@
|
|||
Call file manager with CATALOG opcode.
|
||||
Set new V value as default for future commands.
|
||||
Exit to caller.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A679-A681 Close current file and warmstart DOS.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A69D-A6A7 Set $40,$41 to point to EXEC file buffer.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A6C4-A6D4 Miscellaneous error messages.
|
||||
A6C4 "COMMAND SYNTAX ERROR"
|
||||
A6C8 "NO FILE BUFFERS AVAILABLE"
|
||||
A6CC "PROGRAM TOO LARGE"
|
||||
A6D0 "FILE TYPE MISMATCH"
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A743-A74D Copy primary filename to file buffer filename field.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A75B-A763 Reset state to 0 and set warmstart flag.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
A792-A799 Point $40,$41 at first file buffer on chain.
|
||||
.np
|
||||
A79A-A7A9 Point $40,$41 at next file buffer on chain.
|
||||
.np
|
||||
A7AA-A7AE Get first byte of file name in file buffer.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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".
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.nx ch8.4
|
255
ch08-4.txt
255
ch08-4.txt
|
@ -1,255 +0,0 @@
|
|||
.np
|
||||
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)
|
||||
.np
|
||||
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:
|
||||
.ul
|
||||
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
|
||||
.np
|
||||
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
|
||||
.np
|
||||
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 ...
|
||||
.np
|
||||
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:
|
||||
.ul
|
||||
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.
|
||||
.np
|
||||
A971-AA3E Error message text table.
|
||||
This table contains the text for each error code in
|
||||
order of error code number:
|
||||
.ul
|
||||
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"
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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)
|
||||
.np
|
||||
AA75-AA92 Primary file name buffer
|
||||
.np
|
||||
AA93-AAB0 Secondary (RENAME) file name buffer
|
||||
.np
|
||||
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)
|
||||
.np
|
||||
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)
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AB1F-AB21 Return with return code=2 (bad opcode).
|
||||
.np
|
||||
AB22-AB27 OPEN function handler.
|
||||
Call common open code (AB28).
|
||||
Exit file manager.
|
||||
.np
|
||||
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").
|
||||
.nx ch8.5
|
280
ch08-5.txt
280
ch08-5.txt
|
@ -1,280 +0,0 @@
|
|||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AC6A-AC6C Return code = 3, subcode bad
|
||||
.np
|
||||
AC6D-AC6F "FILE LOCKED" error return
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AC87-AC89 POSITION AND READ ONE BYTE subcode handler
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
AC8A-AC92 READ ONE BYTE subcode handler.
|
||||
Read next file byte (ACA8).
|
||||
Store in parmlist for pass back to caller.
|
||||
Exit the file manager.
|
||||
.np
|
||||
AC93-AC95 POSITION AND READ A RANGE OF BYTES subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
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.)
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
ACBB-ACBD POSITION AND WRITE ONE BYTE subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
ACBE-ACC6 WRITE ONE BYTE subcode handler.
|
||||
Find data byte to be written.
|
||||
Write it to file (ACDA).
|
||||
Exit file manager.
|
||||
.np
|
||||
ACC7-ACC9 POSITION AND WRITE A RANGE OF BYTES subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
ACEF-ACF5 LOCK function handler.
|
||||
Set mask byte to $80 (lock).
|
||||
Go to common code (ACFB).
|
||||
.np
|
||||
ACF6-ACFA UNLOCK function handler.
|
||||
Set mask byte to $00 (unlock).
|
||||
Fall through to common code.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AD12-AD17 POSITION function handler.
|
||||
Call position routine.
|
||||
Exit file manager.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AE42-AE69 Convert the number stored at $44 to a three character
|
||||
printable number and print it.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AE7E-AE8D Save file manager workarea in file buffer.
|
||||
Select file manager workarea buffer.
|
||||
Copy 45 byte workarea to file buffer.
|
||||
Exit to caller.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.nx ch8.6
|
408
ch08-6.txt
408
ch08-6.txt
|
@ -1,408 +0,0 @@
|
|||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
AFDC-AFE3 Read a data sector.
|
||||
Set up for RWTS (AFE4).
|
||||
Set RWTS READ opcode and go to RWTS driver to do it.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B037-B044 Write directory sector.
|
||||
Set buffer pointers.
|
||||
Find its track/sector in workarea.
|
||||
Exit through RWTS to write it.
|
||||
.np
|
||||
B045-B051 Prepare for RWTS for directory buffer.
|
||||
Copy directory buffer address to RWTS parmlist.
|
||||
Exit to caller.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B1B5-B1C8 Decrement range length.
|
||||
Decrement range length in file manager parmlist by
|
||||
one.
|
||||
If zero, exit file manager.
|
||||
Otherwise, exit to caller.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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"
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B3A4-B3A6 Decimal conversion table (1,10,100).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B3AF-B3BA ASCII text "DISK VOLUME " backwards. Used by CATALOG.
|
||||
.np
|
||||
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
|
||||
.np
|
||||
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)).
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B5FE-B5FF Not used.
|
||||
.np
|
||||
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.
|
||||
.br
|
||||
.nx ch8.7
|
404
ch08-7.txt
404
ch08-7.txt
|
@ -1,404 +0,0 @@
|
|||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B78D-B792 Unused.
|
||||
.np
|
||||
B793-B7B4 Read/Write a group of pages.
|
||||
call RWTS through external entry point ($B7B5).
|
||||
Exit to caller.
|
||||
.np
|
||||
B7B5-B7C1 Disable interrupts and call RWTS.
|
||||
.np
|
||||
B7C2-B7D5 Set RWTS parameters for writing DOS.
|
||||
.np
|
||||
B7D6-B7DE Zero current buffer.
|
||||
Zero 256 bytes pointed to by $42,$43.
|
||||
Exit to caller.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B7F9-B7FA Unused.
|
||||
.np
|
||||
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).
|
||||
.np
|
||||
B7FF Unused.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
B8B8-B8C1 Write a byte subroutine.
|
||||
Timing critical code used to write bytes at 32 cycle
|
||||
intervals.
|
||||
Exit to caller.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BA11-BA28 Arm move delay table.
|
||||
Contains values of 100 Usec intervals used during
|
||||
Phase-on and Phase-off of stepper motor.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BA69-BA95 Unused.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BB00-BBFF Primary Buffer.
|
||||
BC00-BC55 Secondary Buffer.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BCDF-BCFF Unused.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BFB8-BFC7 Sector Translate Table
|
||||
Sector interleaving done with software.
|
||||
.np
|
||||
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.
|
||||
.np
|
||||
BFD9-BFDB Unused.
|
||||
.np
|
||||
BFDC-BFE5 Patch called from $A0E2.
|
||||
Set three additional defaults (Byte offset=0).
|
||||
Return to caller.
|
||||
.np
|
||||
BFE6-BFEC Patch called from $A6D5.
|
||||
Call $A75B to reset state and set warmstart flag.
|
||||
Mark RUN not interrupted.
|
||||
Return to caller.
|
||||
.np
|
||||
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").
|
||||
.br
|
||||
.nx ch8 zpage use
|
52
ch08-8.txt
52
ch08-8.txt
|
@ -1,52 +0,0 @@
|
|||
.bp
|
||||
.nf
|
||||
.na
|
||||
DOS ZERO PAGE USAGE
|
||||
.sp1
|
||||
.un
|
||||
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)
|
||||
.br
|
Loading…
Reference in New Issue