This chapter is about the ProDOS Machine Language Interface (MLI), which provides a simple way to use disk files from machine-language programs. This chapter describes
The ProDOS MLI is a complete, consistent, and interruptible interface between the machine-language programmer and files on disks. It is entirely independent of the ProDOS BASIC system program; thus, it serves as a base upon which other system programs can be written. Its filename is PRODOS. It consists of:
A program sends a call to the Machine Language Interface by executing a JSR (jump to subroutine) to address $BF00 (referred to below as MLI). The call number and a two-byte pointer (low byte first) to the call's parameter list must immediately follow the call. Here is an example of a call to the MLI:
Upon completion of the call, the MLI returns to the address of the JSR plus 3 (in the above example, the BNE statement); the call number and parameter list pointer are skipped. If the call is successful, the C-flag is cleared and the Accumulator is set to zero. If the call is unsuccessful, the C-flag is set and the Accumulator is set to the error code. The register status upon call completion is summarized below. Note that the value of the N-flag is determined by the Accumulator and that the value of the V-flag is undefined.
N Z C D V Acc PC X Y SP Successful call: 0 1 0 0 x 0 JSR+3 unchanged Unsuccessful call: x 0 1 0 x error JSR+3 unchanged code
Here is an example of a small program that issues calls to the MLI. It tries to create a text file named NEWFILE on a volume named TESTMLI. If an error occurs, the Apple II beeps and prints the error code on the screen. Both the source and the object are given so you can enter it from the Monitor if you wish (remember to use a formatted disk named /TESTMLI).
The parameters used in TESTCMD are explained in the following sections. The MLI error codes are summarized in Section 4.7.
As defined above, each MLI call has a two-byte pointer to a parameter list. A parameter list contains information to be used by the call and space for information to be returned by the call. There are three types of elements used in parameter lists: values, results, and pointers.
A value is a one or more byte quantity that is passed to the Block File Manager (BFM). Values help determine the action taken by the BFM.
A result is a one or more byte space in the parameter list into which the Block File Manager will place a value. From results, programs can get information about the status of a volume, file, or interrupt, or about the success of the call just completed.
A pointer is a two-byte memory address that indicates the location of data, code, or a space in which the Block File Manager can place or receive data. All pointers are arranged low byte first, high byte second.
The first element in every parameter list is the parameter count, a one-byte value that indicates the number of parameters used by the call (not including the parameter count). This byte is used to verify that the call was not accidental.
To help you learn to use the ProDOS Machine Language Interface, there is a useful little program called the ProDOS Machine Language Exerciser. It allows you to execute MLI calls from a menu; it has a hexadecimal memory editor for reviewing and altering the contents of buffers; and it has a catalog command.
Instructions for using the Machine Language Exerciser program are in Appendix D.
When you use it to make an MLI call, you request the call by its call number, then you specify its parameter list, just as if you were coding the call in a program. When you press [RETURN], the call is executed. Using the Exerciser, you can try out sequences of MLI calls before actually coding them.
The MLI calls can be divided into three groups: housekeeping calls, filing calls, and system calls.
The housekeeping calls perform operations such as creating, deleting, and renaming, which cannot be used on open files. They are used to change a file's status, but not the information that is in the file. They refer to files by their pathnames, and each requires a temporary buffer, which is used during execution of the call. The housekeeping calls are:
The filing calls cause the transfer of data to or from files. The first filing call, OPEN, must be used before any of the others can be used. The OPEN call specifies a file by its pathname; the other filing calls refer to files by the reference number returned by the OPEN call. In addition, an input/output buffer (io_buffer), is allocated to the open file; subsequent data transfers go through this buffer. The reference number remains assigned and the buffer remains allocated until the file is closed. The filing calls are:
System calls are those calls that are neither housekeeping nor filing calls. They are used for getting the current date and time, for installing and removing interrupt routines, and for reading and writing specific blocks of a disk. The system calls are:
Each of the following sections contains a description of a housekeeping call, including its parameters and the possible errors that may be returned.
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 7 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 3 | access (1-byte value) | +---+---+---+---+---+---+---+---+ 4 | file_type (1-byte value) | +---+---+---+---+---+---+---+---+ 5 | aux_type (low) | 6 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+ 7 | storage_type (1-byte value) | +---+---+---+---+---+---+---+---+ 8 | create_date (byte 0) | 9 | (2-byte value) (byte 1) | +---+---+---+---+---+---+---+---+ A | create_time (byte 0) | B | (2-byte value) (byte 1) | +---+---+---+---+---+---+---+---+
Every disk file except the volume directory file must be created using this call. There are two organizationally distinct types of file storage: tree structure (storage_type = $1), used for standard files; and linked list (storage_type = $D), used for directory files.
Pathname specifies the name of the file to be created and the directory in which to insert an entry for the new file. One block (512 bytes) of disk space is allocated, and the entry's key_pointer field is set to indicate that block. Access, in most cases, should be set to $E3 (full access permitted). File_type and aux_type may be anything, but it is strongly recommended that conventions be followed (see below).
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |D |RN|B |Reserved|W |R | +--+--+--+--+--+--+--+--+ D: Destroy enable bit RN: Rename enable bit B: Backup needed bit W: Write enable bit R: Read enable bitFor all bits, 1 = enabled, 0 = disabled. Bits 2 through 4 are reserved for future definition and must always be disabled. Usually access should be set to $C3. If the file is destroy, rename, and write enabled, it is unlocked. If all three are disabled, it is locked. Any other combination of access bits is called restricted access. The backup bit (B) is always set by this call.
File Type Preferred Use $00 Typeless file (SOS and ProDOS) $01 Bad block file $02 * Pascal code file $03 * Pascal text file $04 ASCII text file (SOS and ProDOS) $05 * Pascal data file $06 General binary file (SOS and ProDOS) $07 * Font file $08 Graphics screen file $09 * Business BASIC program file $0A * Business BASIC data file $0B * Word Processor file $0C * SOS system file $0D,$0E * SOS reserved $0F Directory file (SOS and ProDOS) $10 * RPS data file $11 * RPS index file $12 * AppleFile discard file $13 * AppleFile model file $14 * AppleFile report format file $15 * Screen library file $16-$18 * SOS reserved $19 AppleWorks Data Base file $1A AppleWorks Word Processor file $1B AppleWorks Spreadsheet file $1C-$EE Reserved $EF Pascal area $F0 ProDOS added command file $F1-$F8 ProDOS user defined files 1-8 $F9 ProDOS reserved $FA Integer BASIC program file $FB Integer BASIC variable file $FC Applesoft program file $FD Applesoft variables file $FE Relocatable code file (EDASM) $FF ProDOS system file
Note: The file types marked with a * in the above list apply to Apple III SOS only; they are not used by ProDOS. For the file_types used by Apple III SOS only, refer to the SOS Reference Manual.
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | Year | Month | Day | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |0 0 0| Hour | |0 0| Minute | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
See Chapter 6 for information about the use of ProDOS with a clock/calendar card.
Possible Errors
$27 - I/O error $2B - Disk write protected $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found $47 - Duplicate filename $48 - Overrun error: not enough disk space $49 - Directory full -- ProDOS can have no more than 51 files in a volume directory. $4B - Unsupported storage_type $53 - Invalid parameter $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
Deletes the file specified by pathname by removing its entry from the directory that owns it, and by returning its blocks to the volume bit map. Volume directory files and open files cannot be destroyed. Subdirectory files must be empty before they can be destroyed.
Parameters
Possible Errors
$27 - I/O error $2B - Disk write protected $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found $4A - Incompatible file format $4B - Unsupported storage_type $4E - Access error: destroy not enabled $50 - File is open: request denied $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 3 | new_pathname (low) | 4 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
Changes the name of the file specified by pathname to that specified by new_pathname. Both pathname and new_pathname must be identical except for the rightmost filename (they must indicate files in the same directory). For example, the path /EGG/ROLL can be renamed /EGG/PLANT, but not /JELLY/ROLL or /EGG/DRUM/ROLL.
Parameters
Possible Errors
$27 - I/O error $2B - Disk write protected $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found
$47 - Duplicate filename $4A - Incompatible file format $4B - Unsupported storage_type $4E - Access error: rename not enabled $50 - File is open: request denied $57 - Duplicate volume
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 7 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 3 | access (1-byte value) | +---+---+---+---+---+---+---+---+ 4 | file_type (1-byte value) | +---+---+---+---+---+---+---+---+ 5 | aux_type (low) | 6 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+ 7 | | 8 | null_field (3 bytes) | 9 | | +---+---+---+---+---+---+---+---+ A | mod_date (byte 0) | B | (2-byte value) (byte 1) | +---+---+---+---+---+---+---+---+ C | mod_time (byte 0) | D | (2-byte value) (byte 1) | +---+---+---+---+---+---+---+---+
Modifies information in the specified file's entry field. This call can be performed when the file is either open or closed. However, new access attributes are not used by an open file until the next time the file is opened (that is, this call doesn't modify existing file control blocks).
You should use the GET_FILE_INFO call to read a file's attributes into a parameter list, modify them as needed, and then use the same parameter list for the SET_FILE_INFO call.
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |D |RN|B |Reserved|W |R | +--+--+--+--+--+--+--+--+ D: Destroy enable bit RN: Rename enable bit B: Backup needed bit W: Write enable bit R: Read enable bit
For all bits, 1 = enabled, 0 = disabled. Bits 2 through 4 are used internally and should be set to 0. Usually access should be set to $C3. If the file is destroy, rename, and write enabled it is unlocked. If all three are disabled, it is locked. Any other combination of access bits is called restricted access. The backup bit (B) is set by this call. </dl>
File Type Preferred Use $00 Typeless file (SOS and ProDOS) $01 Bad block file $02 * Pascal code file $03 * Pascal text file $04 ASCII text file (SOS and ProDOS) $05 * Pascal data file $06 General binary file (SOS and ProDOS) $07 * Font file $08 Graphics screen file $09 * Business BASIC program file $0A * Business BASIC data file $0B * Word Processor file $0C * SOS system file $0D,$0E * SOS reserved $0F Directory file (SOS and ProDOS) $10 * RPS data file $11 * RPS index file $12 * AppleFile discard file $13 * AppleFile model file $14 * AppleFile report format file $15 * Screen library file $16-$18 * SOS reserved $19 AppleWorks Data Base file $1A AppleWorks Word Processor file $1B AppleWorks Spreadsheet file $1C-$EE Reserved $EF Pascal area $F0 ProDOS added command file $F1-$F8 ProDOS user defined files 1-8 $F9 ProDOS reserved $FA Integer BASIC program file $FB Integer BASIC variable file $FC Applesoft program file $FD Applesoft variables file $FE Relocatable code file (EDASM) $FF ProDOS system file
Note: The file types marked with a * in the above list apply to Apple III SOS only; they are not used by ProDOS. For the file_types used by Apple III SOS only, refer to the SOS Reference Manual.
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | Year | Month | Day | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |0 0 0| Hour | |0 0| Minute | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
See Chapter 6 for information about the use or ProDOS with a clock/calendar card.
Possible Errors
$27 - I/O error $2B - Disk write protected $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found $4A - Incompatible file format $4B - Unsupported storage_type $4E - Access error: file not write enabled $53 - Invalid value in parameter list $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = $A | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 3 | access (1-byte result) | +---+---+---+---+---+---+---+---+ 4 | file_type (1-byte result) | +---+---+---+---+---+---+---+---+ 5 | aux_type (low) | * 6 | (2-byte result) (high) | +---+---+---+---+---+---+---+---+ 7 | storage_type (1-byte result) | +---+---+---+---+---+---+---+---+ 8 | blocks used (low) | * 9 | (2-byte result) (high) | +---+---+---+---+---+---+---+---+ A | mod_date (byte 0) | B | (2-byte result) (byte 1) | +---+---+---+---+---+---+---+---+ C | mod_time (byte 0) | D | (2-byte result) (byte 1) | +---+---+---+---+---+---+---+---+ E | create_date (byte 0) | F | (2-byte result) (byte 1) | +---+---+---+---+---+---+---+---+ 10 | create_time (byte 0) | 11 | (2-byte result) (byte 1) | +---+---+---+---+---+---+---+---+
* When file information about a volume directory is requested, the total number of blocks on the volume is returned in the aux_type field and the total blocks for all files is returned in blocks_used.
GET_FILE_INFO returns the information that is stored in the specified file's entry field. This call can be performed whether the file is open or closed. If the SET_FILE_INFO call is used to change the access while the file is open, the change does not take effect until the file has been closed and reopened.
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |D |RN|B |Reserved|W |R | +--+--+--+--+--+--+--+--+ D: Destroy enable bit RN: Rename enable bit B: Backup needed bit W: Write enable bit R: Read enable bit
For all bits, 1 = enabled, 0 = disabled. Bits 2 through 4 are not used. Usually access should be set to $C3. If the file is destroy, rename, and write enabled it is unlocked. If all three are disabled, it is locked. Any other combination of access bits is called restricted access.
File Type Preferred Use $00 Typeless file (SOS and ProDOS) $01 Bad block file $02 * Pascal code file $03 * Pascal text file $04 ASCII text file (SOS and ProDOS) $05 * Pascal data file $06 General binary file (SOS and ProDOS) $07 * Font file $08 Graphics screen file $09 * Business BASIC program file $0A * Business BASIC data file $0B * Word Processor file $0C * SOS system file $0D,$0E * SOS reserved $0F Directory file (SOS and ProDOS) $10 * RPS data file $11 * RPS index file $12 * AppleFile discard file $13 * AppleFile model file $14 * AppleFile report format file $15 * Screen library file $16-$18 * SOS reserved $19 AppleWorks Data Base file $1A AppleWorks Word Processor file $1B AppleWorks Spreadsheet file $1C-$EE Reserved $EF Pascal area $F0 ProDOS added command file $F1-$F8 ProDOS user defined files 1-8 $F9 ProDOS reserved $FA Integer BASIC program file $FB Integer BASIC variable file $FC Applesoft program file $FD Applesoft variables file $FE Relocatable code file (EDASM) $FF ProDOS system file
Note: The file types marked with a * in the above list apply to Apple III SOS only; they are not used by ProDOS. For the file_types used by Apple III SOS only, refer to the SOS Reference Manual.
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | Year | Month | Day | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |0 0 0| Hour | |0 0| Minute | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | Year | Month | Day | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
byte 1 byte 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |0 0 0| Hour | |0 0| Minute | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
See Chapter 6 for information about the use of ProDOS with a clock/calendar card.
Possible Errors
$27 - I/O error $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found $4A - Incompatible file format $4B - Unsupported storage_type $53 - Invalid value in parameter list $5A - Bit map address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | unit_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | data_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
This command can be used to determine the names of all ProDOS (or SOS) volumes that are currently mounted (such as disks in disk drives), or it can be used to determine the name of a disk in a specified slot and drive.
When unit_num is 0, this command places a list of the volume names, slot numbers, and drive numbers of all mounted disks into the 256 byte buffer pointed to by data_buffer. When a specific unit_num is requested, only 16 bytes need be set aside for the buffer. The format of the returned information is described below.
The volume names are placed in the list in volume search order, as described in section 3.2.
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |Dr| Slot | Unused | +--+--+--+--+--+--+--+--+
For drive 1, Dr = 0; for drive 2, Dr = 1. Slot specifies the device's slot number (1-7). If unit_num is 0, all mounted disks are scanned. Here are possible values for unit_num:
Slot: 7 6 5 4 3 2 1 Drive 1: 70 60 50 40 30 20 10 Drive 2: F0 E0 D0 C0 B0 A0 90
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |dr| slot | name_len | +--+--+--+--+--+--+--+--+Bit 7 specifies drive 1 (Dr = 0) or drive 2 (Dr = 1). Bits 6-4 specify the slot number (1 through 7). Bits 3-0 specify a valid name_length if nonzero. The next 15 bytes of the record are for a volume name. If name_length = 0, then an error was detected in the specified slot and drive. The error code is present in the second byte of the record. If error $57 (duplicate volume) is encountered, the third byte contains the unit number of the duplicate. When multiple records are returned, the last valid record is followed by one that has unit_num and name_length set to 0.
Remember: ON_LINE returns volume names that are not preceded by slashes. Remember to put a slash in front of the name before you use it in a pathname.
Possible Errors
$27 - I/O error $28 - Device not connected $2E - Disk switched: File still open on other disk $45 - Volume directory not found $52 - Not a ProDOS disk $55 - Volume Control Block full $56 - Bad buffer address $57 - Duplicate volume
When an error pertains to a specific drive, the error code is returned in the second byte of the record corresponding to that drive, as described above. In such cases, the call completes with the accumulator set to 0, and the carry flag clear. Only errors $55 and $56 are not drive specific.
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
Sets the system prefix to the indicated directory. The pathname may be a full pathname or a partial pathname. The system prefix can be set to null by indicating a pathname with a count of zero. The prefix must be no longer than 64 characters. When ProDOS is started up, the system prefix is set to the name of the volume in the startup drive.
The MLI verifies that the requested prefix directory is on an on-line volume before accepting it.
Parameters
Possible Errors
$27 - I/O error $40 - Invalid pathname syntax $44 - Path not found $45 - Volume directory not found $46 - File not found $4A - Incompatible file format $4B - Unsupported storage_type $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | data_buffer (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
Returns the current system prefix. If the system prefix is set to null (no prefix), then a count of 0 is returned. Otherwise the returned prefix is preceded by a length byte and bracketed by slashes. Examples are $7/APPLE/ and $D/APPLE/BYTES/. Each character in the prefix is returned with its high bit cleared.
The buffer pointed to by data_buffer is assumed to be 64 bytes long.
Parameters
Possible Error
$56 - Bad buffer address</pre>
Each of the following sections contains a description of a filing command, including its parameters and the possible errors that may be returned.
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 3 | +---+---+---+---+---+---+---+---+ 1 | pathname (low) | 2 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 3 | io_buffer (low) | 4 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 5 | ref_num (1-byte result) | +---+---+---+---+---+---+---+---+
OPEN prepares a file to be read or written. It creates a file control block that keeps track of the current (open) characteristics of the file specified by pathname, it sets the current position in the file to zero, and it returns a reference number by which the other commands in this section must refer to the file.
The I/O buffer is used by the system for the entire time the file is open. It contains information about the file's structure on the disk, and it contains the current 512-byte block being read or written. It is used until the file is closed, and therefore should not be modified directly by the user. A maximum of eight files can be open at a time.
When a file is opened it is assigned a level, from 0 to $F, depending on the current value of the LEVEL location ($BF94) in the system global page. When the CLOSE command is issued with a ref_num of 0, all files at or above the current level are closed. Thus, a CLOSE with a ref_num of 0 and a level of 0 will close all open files.
Refer to Section 2.1.7, "File Levels," for an example of the use of level.
Warning Once a file has been opened, that file's disk must not be removed from its drive and replaced by another. The system does not check the identity of a volume before writing on it. A system program should check a volume's identity before writing to it.
Parameters
Refer to Appendix B for more information on directory file blocks, index blocks, and data blocks.
Possible Errors
$27 - I/O error $40 - Invalid pathname syntax $42 - File Control Block table full $44 - Path not found $45 - Volume directory not found $46 - File not found $4B - Unsupported storage_type $50 - File is open $53 - Invalid value in parameter list $56 - Bad buffer address $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 3 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | enable_mask (1-byte value) | +---+---+---+---+---+---+---+---+ 3 | newline_char (1-byte value) | +---+---+---+---+---+---+---+---+
This call allows you to enable or disable newline read mode for any open file. When newline is disabled, a read request terminates when the requested number of characters has been read, or when the end of file is encountered. When newline is enabled, a read request will also terminate if the newline character (newline_char) is read.
Each character read is first transferred to the user's data buffer. Next it is ANDed with the enable_mask and compared to the newline_char. If there is a match, the read is terminated. For example, if enable_mask is $7F and newline_char is $0D (ASCII CR), either a $0D or $8D matches and terminates input. This process does not change the character.
Parameters
Possible Error
$43 - Invalid reference number
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 4 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | data_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 4 | request_count (low) | 5 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+ 6 | trans_count (low) | 7 | (2-byte result) (high) | +---+---+---+---+---+---+---+---+
Tries to transfer the requested number of bytes (request_count), starting at the current position (MARK) of the file specified by ref_num to the buffer pointed to by data_buffer. The number of bytes actually transferred is returned in trans_count.
If newline read mode is enabled and a newline character is encountered before request_count bytes have been read, then the trans_count parameter is set to the number of bytes transferred, including the newline byte.
If the end of file is encountered before request_count bytes have been read, then trans_count is set to the number of bytes transferred. The end of file error ($4C) is returned if and only if zero bytes were transferred (trans_count = 0).
Parameters
Possible Errors
$27 - I/O error $43 - Invalid reference number $4C - End of file has been encountered $4E - Access error: file not read enabled $56 - Bad buffer address $5A - Bit map address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 4 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | data_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 4 | request_count (low) | 5 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+ 6 | trans_count (low) | 7 | (2-byte result) (high) | +---+---+---+---+---+---+---+---+
Tries to transfer a specified number of bytes (request_count) from the buffer pointed to by data_buffer to the file specified by ref_num starting at the current position (MARK) in the file. The actual number of bytes transferred is returned in trans_count.
The file position is updated to position + trans_count. If necessary, additional data and index blocks are allocated to the file, and EOF is extended.
See Appendix B for an explanation of data and index blocks.
Parameters
Possible Errors
$27 - I/O error $2B - Disk write protected $43 - Invalid reference number $48 - Overrun error: not enough disk space $4E - Access error: file not write enabled $56 - Bad buffer address $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+
This call is used to release all resources used by an open file. The file control block is released. If necessary, the file's buffer (io_buffer) is emptied to the file and the directory entry for the file is updated. Until that ref_num is assigned to another open file, subsequent filing calls using that ref_num will fail.
If ref_num equals zero ($0), all open files at or above the current level are closed. For example, if you open files at levels 0, 1, and 2, set the level to 1, and then use CLOSE with ref_num set to 0, the files at level 1 and 2 are closed, but the ones at level 0 are not.
The level is a value from 0 to $F that is stored in the LEVEL location ($BFD8) of the system global page. It is only changed by system programs, and it is used by OPEN and CLOSE.
This call causes the backup bit to be set.
Parameters
Possible Errors
$27 - I/O error $2B - Disk write protected $43 - Invalid reference number $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+
The file's write buffer (io_buffer) is emptied to the file, and the file's directory is updated. If ref_num equals zero ($0), then all open files at or above the current level are flushed.
The backup bit is set by this call.
FLUSH is further explained in Chapter 2, section "Closing and Flushing Files."
Parameters
Possible Errors
$27 - I/O error $2B - Disk write protected $43 - Invalid reference number $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | (low) | 3 | position (3-byte value) | 4 | (high) | +---+---+---+---+---+---+---+---+
Changes the current position (MARK) in the file to that specified by the position parameter. Position may not exceed the end of file (EOF) value.
See the example of SET_MARK in Chapter 2, section "The EOF and MARK."
Parameters
Possible Errors
$27 - I/O error $43 - Invalid reference number $4D - Position out of range $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | (low) | 3 | position (3-byte result) | 4 | (high) | +---+---+---+---+---+---+---+---+
Returns the current position (MARK) in an open file.
Parameters
Possible Error
$43 - Invalid reference number
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | (low) | 3 | EOF (3-byte value) | 4 | (high) | +---+---+---+---+---+---+---+---+
Sets the logical size of the file specified by ref_num to EOF. If the new EOF is less than the current EOF, then blocks past the new EOF are released to the system. If the new EOF is greater than or equal to the current EOF, no blocks are allocated. If the new EOF is less than the current position, the value of the position is set to the EOF. The EOF cannot be changed unless the file is write enabled.
The logical size of a file is the number of bytes that can be read from it.
Parameters
Possible Errors
$27 - I/O error $43 - Invalid reference number $4D - Position out of range $4E - Access error: File not write enabled $5A - Bit map disk address is impossible
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | (low) | 3 | EOF (3-byte result) | 4 | (high) | +---+---+---+---+---+---+---+---+
Returns the number of bytes that can be read from the open file.
Parameters
Possible Error
$43 - Invalid reference number
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | io_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
This call allows you to reassign the address of the input/output buffer that is used by the file specified by ref_num (assigned when the file was opened). The MLI checks to see that the specified buffer is not already used by the system, then it moves the contents of the old buffer into the new buffer.
Parameters
Possible Errors
$43 - Invalid reference number $56 - Bad buffer address
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | ref_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | io_buffer (low) | 3 | (2-byte result) (high) | +---+---+---+---+---+---+---+---+
Returns the address of the input/output buffer currently being used by the file specified by ref_num.
Parameters
Possible Error
$43 - Invalid reference number
Each of the following sections describes a system command, including any parameters and possible errors.
This call has no parameter list, and it cannot generate an error. It calls a clock/calendar routine, if there is one, which returns the current date and time to the system date and time locations ($BF90-BF93). If there is no clock/calendar routine, the system date and time locations are left unchanged.
Here is the layout of the four bytes that make up the system date and time.
49041 ($BF91) 49040 ($BF90) 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ DATE: | year | month | day | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ TIME: | hour | | minute | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 49043 ($BF93) 49042 ($BF92)
When ProDOS starts up, it looks for a clock/calendar card in one of the Apple II's slots. If it recognizes one, ProDOS installs a routine that can read the date and time from the card and place them in the system date and time locations. Otherwise, no routine is installed.
Note that the GET_TIME call number for ProDOS is different from the GET_TIME call number for SOS.
Chapter 5 explains the use of the date and time locations by the system.
Chapter 6 explains the installation of clock/calendar routines.
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 2 | +---+---+---+---+---+---+---+---+ 1 | int_num (1-byte result) | +---+---+---+---+---+---+---+---+ 2 | int_code (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+
This call places the address of an interrupt receiving routine int_code into the interrupt vector table. It should be made before you enable the hardware that could cause this interrupt. It is your responsibility to make sure that the routine is installed at the proper location and that it follows interrupt conventions.
The int_num that is returned gives an indication of what priority the interrupt is given (1, 2, 3, or 4). Routines that are installed first are given the highest priority. You must use this number when you remove the routine from the system.
Interrupt receiving routines are described in Chapter 6.
Parameters
Possible Errors
$25 - Interrupt vector table full $53 - Invalid parameter
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 1 | +---+---+---+---+---+---+---+---+ 1 | int_num (1-byte value) | +---+---+---+---+---+---+---+---+
This call clears the entry for int_num from the interrupt vector table. You must disable interrupt hardware before you make this call. If you don't, and the hardware interrupts after the vector table has been updated, a SYSTEM FAILURE will occur (see Section 4.8.1).
Interrupt receiving routines are described in Chapter 6.
Parameters
Possible Error
$53 - Invalid parameter
The direct disk access commands READ_BLOCK and WRITE_BLOCK, allow you to read from or write to any logical block on a disk. They are intended to be used by utility (such as copying) and diagnostic programs.
Warning Application programs should not use these commands: they can very easily damage the data integrity of the ProDOS file structure. All necessary functions can be performed without these calls.
These calls will also read and write blocks (not tracks and sectors) from DOS 3.3 disks. A mapping of tracks and sectors on a DOS 3.3 disk to blocks read or written by ProDOS is given in Section B.5.
ProDOS BLOCK_READ and BL0CK_WRITE calls can access DOS 3.3 disks: see Appendix B, Section "DOS 3.3 Disk Organization."
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 3 | +---+---+---+---+---+---+---+---+ 1 | unit_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | data_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 4 | block_num (low) | 5 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+
This call reads one block from the disk device specified by unit_num into memory starting at the address indicated by data_buffer. The buffer must be 512 or more bytes in length.
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |Dr| Slot | Unused | +--+--+--+--+--+--+--+--+
Possible Errors
$27 - I/O error $28 - No device connected
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ 0 | param_count = 3 | +---+---+---+---+---+---+---+---+ 1 | unit_num (1-byte value) | +---+---+---+---+---+---+---+---+ 2 | data_buffer (low) | 3 | (2-byte pointer) (high) | +---+---+---+---+---+---+---+---+ 4 | block_num (low) | 5 | (2-byte value) (high) | +---+---+---+---+---+---+---+---+
This call transfers one block of data from the memory buffer indicated by data_buffer to the disk device specified by unit_num. The block of data is placed in the logical block specified by block_num. It is assumed that the data buffer is at least 512 bytes long.
Parameters
7 6 5 4 3 2 1 0 +--+--+--+--+--+--+--+--+ |Dr| Slot | Unused | +--+--+--+--+--+--+--+--+
Possible Errors
$27 - I/O error $28 - No device connected $2B - Disk write protected
This is a summary of the ProDOS error codes. If there is no error, the C-flag is clear, and the Accumulator contains $00. If there is an error, the C-flag is set, and the Accumulator contains the error code.
$00 - No error.
$01 - Bad system call number. A non-existent command was issued.
$04 - Bad system call parameter count. This error will occur only if the call parameter list is not properly constructed.
$25 - Interrupt vector table full. Only four routines can be activated for interrupt processing at a time. One must be deactivated before another one may be enabled.
$27 - I/O error. This catch-all error is reported when some hardware failure prevents proper transfer of data to/from the disk device.
$28 - No device detected/connected. Will occur if, for example, drive 2 is specified for Disk II when only one drive is connected.
$2B - Disk write protected. Hardware write-inhibit is enabled, write request cannot be processed.
$2E - Disk switched: A WRITE, FLUSH, or CLOSE operation cannot be accomplished because a disk containing an open file has been removed from its drive.
$40 - Invalid pathname syntax. The pathname contains illegal characters.
$42 - File Control Block table full. The FCB can contain a maximum of eight entries. Thus, a maximum of eight files can be open concurrently.
$43 - Invalid reference number. The value parameter given as a reference number does not match the reference number of any currently open file.
$44 - Path not found. A filename in the specified pathname (which refers to a subdirectory) does not exist. The pathname's syntax is legal.
$45 - Volume directory not found. The volume name in the specified pathname does not exist. The pathname's syntax is otherwise legal.
$46 - File not found. The last filename of the pathname does not exist. The syntax of the pathname is legal.
$47 - Duplicate filename. An attempt was made to create a file that already exists or to rename a file with an already used name.
$48 - Overrun error. An attempt to allocate blocks on a block device during a CREATE or WRITE operation failed due to lack of space on the device. This error also is returned on an invalid EOF parameter. Data is written until the disk is full, but you will always be able to close the file.
$49 - Volume directory full. No more entries are left in the volume directory. In ProDOS 1.0, a volume directory can hold no more than 51 entries. No more files can be added (using CREATE) in this directory until others are destroyed.
$4A - Incompatible file format. The file is not backward compatible with this version of ProDOS. Storage_type is recognized, but the File Manager may not support that storage_type in a fully compatible fashion. This error is likely to occur when data written by a future version of the BFM is read back using an earlier version of the BFM.
$4B - Unsupported storage_type. File is of an organization unknown to the executing File Manager. This error may be reported if the directory is tampered with by the user. This error is also returned if you attempt to set the prefix to a nondirectory file.
$4C - End of file has been encountered. This error is returned after a READ call when the file position is equal to EOF and no data can be read.
$4D - Position out of range. Returned when the position parameter is greater than current EOF.
$4E - Access error. The file's access attribute forbids the RENAME, DESTROY, READ or WRITE operation that was attempted.
$50 - File is open. An attempt was made to OPEN, RENAME or DESTROY an open file.
$51 - Directory count error: The number of entries indicated in the directory header does not match the number of entries actually found in the file.
$52 - Not a ProDOS disk. The specified disk does not contain a ProDOS (or SOS) directory format.
$53 - Invalid parameter. The value of one or more parameters in the parameter list is out of range.
$55 - Volume Control Block table full. More than eight volumes on line. The VCB table can contain a maximum of eight entries. This error occurs only if eight files, on eight volumes, are open and the ON_LINE command is requested for a device having no open files.
$56 - Bad buffer address. The data_buffer or io_buffer specified conflicts with memory currently in use by the MLI.
$57 - Duplicate volume. This is a warning that two or more volume directory names are the same.
$5A - Bit map disk address is impossible. The volume bit map indicates that the volume contains blocks beyond the block count for that volume.
Note: System failure errors should never occur. They indicate that the system has encountered a situation that should not have happened, and it has no available means of recovery.
Possible causes include
- bad RAM
- disk failure
- operating system bug
- unclaimed interrupt.