+3 DOS
Notes on the Disk Operating System for the Plus 3
Table of Contents
+3DOS is the Disk Operating System of the Spectrum +3.
It is contained in ROM 2 on those machines and provides support for:
- Support for one or two floppy disk drives and a RAMdisk.
- CP/M Plus and CP/M 2.2 file compatibility.
- AMSTRAD CPC range and PCW range file and media compatibility.
- Up to 16 files open at the same time.
- Reading and writing files to or from any page in memory.
- Byte level random access.
- Deleting disk files; renaming disk files; changing disk files' attributes.
- Selecting the default drive and user.
- Booting a game or operating system.
- Low level access to floppy disk driver.
- Optional mapping of two logical drives (A: or B:) onto one physical drive (unit 0).
Spectrum +2A
The +2A (not the +2) has the exact same ROM's as the +3, it just has a Cassette tape instead of a 3" floppy drive.
As such, +3DOS is available but only provides:
- Only drive M: is available (the RAMdisk)
- The default drive for filenames is initialised to M: rather than A:
- Any attempt to use drives A: or B: will fail with error '22 - Drive not found'
-
As the sector cache is not required for use with the RAM disk,
it is increased to 64K (the whole of pages 1, 3, 4, 6).
This will give 62K of data and 2K of directory (64 entries).
-
The presence of the floppy disk interface can be determined by calling DD_INTERFACE.
If the interface were not present, then none of the other low level floppy disk routines (DD... etc.)
could be called; the effect of doing so is undefined.
Another method to determine if a machine is a +3 or a +2A is to inspect bit 4 of FLAGS3 (0x5B66).
If the bit is set then a disk interface is present, hence a +3.
If the bit is reset then no disk is present, hence a +2A or a +3 with no disk interface or the interface disabled.
CP/M File compatibility
+3DOS uses the CP/M file structure, subject to the following restrictions:
-
Maximum file size of 8 megabytes (CP/M Plus supports a maximum of 32 megabytes).
-
Maximum drive size of 8 megabytes (CP/M Plus supports a maximum of 128 megabytes).
-
Directory labels are ignored.
-
No passwords. XFCBs will be erased, renamed, etc., along with their file(s) but are otherwise ignored.
-
No date and time stamps. SFCBs are initialised to zero when a file is created, but are otherwise ignored.
-
The archive file attribute is ignored, i.e. it is unaffected by all routines except DOS SET ATTRIBUTES.
1 - Essential API
+3DOS Essential API
1.1 - DOS_INITIALISE
Initialise +3DOS
Function |
Address | Description |
DOS_INITIALISE |
0100 | Initialise +3DOS |
Synopsys
- Initialise +3DOS.
- Initialise disk drivers.
- Initialise cache and the RAMdisk.
- All files closed.
- All drives logged out.
- Default drive A: (if disk interface present), else M:
- Default user 0.
- Retry count 15.
- Error messages disabled.
Entry Parameters
None
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.2 - DOS_VERSION
Get the DOS issue and version numbers
Function |
Address | Description |
DOS_VERSION |
0103 | Return DOS issue and version numbers |
Synopsys
Get the DOS issue and version numbers.
Entry Parameters
None
Exit Parameters
- If OK:
- D = Issue
- E = Version (within issue)
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.3 - DOS_OPEN
Open and/or Create a file
Function |
Address | Description |
DOS_OPEN |
0106 | Open and/or Create a file |
Synopsys
Create and/or open a file
Entry Parameters
Register |
Content |
B |
File number 0…15 |
C |
Access mode required |
D |
Create action |
E |
Open action |
HL |
Address of filename, no wildcards. Terminated with 0xFF |
Exit Parameters
- If file newly created:
- Carry true
- Zero true
- A corrupt
- If existing file opened:
- Carry true
- Zero false
- A corrupt
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
Open |
Action |
0 | Error - File already exists. |
1 |
Open the file, read the header (if any).
Position file pointer after header.
|
2 |
Open the file, ignore any header.
Position file pointer at 000000h (0).
|
3 |
Assume given filename is 'filename.type'.
- Erase 'filename.BAK' (if it exists).
- Rename 'filename.type' to 'filename.BAK'.
- Follow create action.
|
4 |
Erase existing version.
Follow create action.
|
Create |
Action |
0 | Error - File does not exists. |
1 |
Create and open new file with a header.
Position file pointer after header.
|
2 |
Create and open new file without a header.
Position file pointer at 000000h (0).
|
Note: The original +3 Manual doesn't mention that the filename needs to be terminated with a 0xFF byte.
This was only discovered during testing by looking at the ROM 2 disassembly.
1.4 - DOS_CLOSE
Close a file
Function |
Address | Description |
DOS_CLOSE |
0109 | Close a file |
Synopsys
Close a file
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.5 - DOS_ABANDON
Abandon a file
Function |
Address | Description |
DOS_ABANDON |
010C | Abandon a file |
Synopsys
Abandon a file
Similar to DOS CLOSE, except that any header, or data, or directory data yet to be written to disk is discarded.
This routine should only be used to force a file closed in the event that DOS CLOSE is unable to close the file
(for example, if the media is damaged or permanently changed or removed).
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.6 - DOS_REF_HEAD
Point to header data for this file
Function |
Address | Description |
DOS_REF_HEAD |
010F | Point to header data for this file |
Synopsys
Point at the header data for this file.
The header data area is 8 bytes long and may be used by the caller for any purpose whatsoever.
It is available even if the file does not have a header;
however, only files with a header and opened with write access will have the header data recorded on disk.
Note that +3 BASIC uses these 8 bytes (see the note under DOS OPEN which gives the details).
If creating a file that will subsequently be LOADed within BASIC, then those bytes should be filled with the relevant values.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- IX = Address of header data
- Otherwise:
- Carry false
- A = Error code
- IX corrupt
- Always:
- BC DE HL corrupt, all other registers preserved.
The original manual doesn't mention exactly what IX points to after this call.
The address in IX is the +3 BASIC Header structure which is 8 bytes long.
(IX+0) is the file type, (IX+1) the file length and (IX+3) param 1.
1.7 - DOS_READ
Read bytes from a file into memory
Function |
Address | Description |
DOS_READ |
0112 | Read bytes from a file into memory |
Synopsys
Read bytes from a file into memory, advancing the file pointer in the process.
This routine does not consider any soft-EOF in the file.
Attempting to read past the EOF will produce an error.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
C |
Page number for addresses 0xC000…0xFFFF |
DE |
Number of bytes to read. 0 means 64K |
HL |
Address of where to write the bytes to |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- DE corrupt
- Otherwise:
- Carry false
- A = Error code
- DE = Number of bytes remaining unread
- Always:
- BC HL IX corrupt, all other registers preserved.
The value of C is only used when HL is within the upper 16K of memory (0xC000…0xFFFF).
If HL is in this range then C is the RAM bank to use.
For most purposes C should be set to 0 which is the default RAM bank mapped to that region.
1.8 - DOS_Write
Read bytes from a file into memory
Function |
Address | Description |
DOS_WRITE |
0115 | Write bytes from memory into a file |
Synopsys
Write bytes from memory into a file, advancing the file pointer in the process.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
C |
Page number for addresses 0xC000…0xFFFF |
DE |
Number of bytes to write. 0 means 64K |
HL |
Address of where to read the bytes from |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- DE corrupt
- Otherwise:
- Carry false
- A = Error code
- DE = Number of bytes remaining unwritten
- Always:
- BC HL IX corrupt, all other registers preserved.
The value of C is only used when HL is within the upper 16K of memory (0xC000…0xFFFF).
If HL is in this range then C is the RAM bank to use.
For most purposes C should be set to 0 which is the default RAM bank mapped to that region.
1.9 - DOS_READ_BYTE
Read byte from a file, check for soft-EOF
Function |
Address | Description |
DOS_READ_BYTE |
0118 | Read byte from a file, check for soft-EOF |
Synopsys
Read a byte from a file, advancing the file pointer in the process.
It tests for a soft EOF (0x1A) but it is possible to read past this.
Reading to the hard EOF will return an error.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK - not soft-EOF (0x1A)
- Carry true
- Zero false
- A corrupt
- C Byte read
- If OK - soft-EOF (0x1A)
- Carry true
- Zero true
- A corrupt
- C Byte read
- Otherwise:
- Carry false
- A = Error code
- C corrupt
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.10 - DOS_WRITE_BYTE
Write byte to a file
Function |
Address | Description |
DOS_WRITE_BYTE |
011B | Write byte to a file |
Synopsys
Write a byte to a file, advancing the file pointer in the process.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
C |
Byte to write |
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.11 - DOS_CATALOG
Get the disk catalog
Function |
Address | Description |
DOS_CATALOG |
011E | Get the disk catalog |
Synopsys
Fills a buffer with part of the directory (sorted).
The filename specifies the drive, user and a (possibly ambiguous) filename.
Since the size of a directory is variable (and may be quite large), this routine permits the directory to be
catalogued in a number of small sections.
The caller passes a buffer pre-loaded with the first required filename, or zeroes for the start of the directory.
The buffer is loaded with part (or all, if it fits) of the directory sorted in ASCII order.
If more of the directory is required, this routine is re-called with the buffer re-initialised with the last file
previously returned.
This procedure is followed repeatedly until all of the directory has been catalogued.
Note that +3DOS format disks (which are the same as single-sided, single track AMSTRAD PCW range format disks) may
have a maximum of 64 directory entries.
Entry Parameters
Register |
Content |
B |
n+1 size of buffer in entries, must be >= 2 |
C |
Filter:
Bit 0 = include system files if set
Bits 1…7 reserved
|
DE |
Address of buffer, first entry initialised |
HL |
Address of filename, wildcards permitted |
Exit Parameters
- If OK:
- Carry true
- A corrupt
-
B number of completed entries in buffer, 0…n.
If B=n then there may be more entries for subsequent calls
- Otherwise:
- Carry false
- A=Error code
- B corrupt
- Always:
- C DE HL IX corrupt, all other registers preserved.
Buffer format
The buffer passed to this routine consists of 2 or more entries, with the first one initialised
with the first filename required.
It is valid for the first entry to be all zero's.
If the buffer is too small for the directory then it can be called again with entry 0 being a
copy of entry n from the previous call.
Directory Entry Format
Bytes |
Length |
Content |
0 | 7 | 8 |
Filename in ASCII, left justified, space padding |
8 | 10 | 3 |
Type in ASCII, left justified, space padding |
11 | 12 | 2 |
File size in KB |
The file size is the disk space allocated, not the actual file size.
1.12 - DOS_FREE_SPACE
Get free space on drive
Function |
Address | Description |
DOS_FREE_SPACE |
0121 | Get free space on drive |
Synopsys
Return the amount of free space on a drive.
Entry Parameters
Register |
Content |
A |
Drive letter A…P |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- HL = Free space in KB
- Otherwise:
- Carry false
- A=Error code
- HL corrupt
- Always:
- BC DE IX corrupt, all other registers preserved.
1.13 - DOS_DELETE
Delete a file
Function |
Address | Description |
DOS_DELETE |
0124 | Delete a file |
Synopsys
Delete an existing file.
The file must not be open on any file number.
Entry Parameters
Register |
Content |
HL |
Address of filename, wildcards are permitted. |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.14 - DOS_RENAME
Rename a file
Function |
Address | Description |
DOS_RENAME |
0127 | Get free space on drive |
Synopsys
Return the amount of free space on a drive.
Entry Parameters
Register |
Content |
A |
Drive letter A…P |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- HL = Free space in KB
- Otherwise:
- Carry false
- A=Error code
- HL corrupt
- Always:
- BC DE IX corrupt, all other registers preserved.
1.15 - DOS_BOOT
Boot from disk
Function |
Address | Description |
DOS_BOOT |
012A | Boot from disk |
Synopsys
Boot from Disk
This routine loads a single bootstrap sector from the disk in drive A: into memory and enters it.
This is for loading games or other operating systems.
Entry Parameters
None
Exit Parameters
- If OK:
- No exit as the bootstrap has taken over
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
Bootstrap environment
When the bootstrap runs with the following memory configuration:
The bootstrap sector is on side 0, track 0, sector 1 of the disk.
It is loaded into memory at 0xFE00 and entered at 0xFE10.
Interrupts are disabled, and SP = 0xFE00.
The sum of all bytes in the sector must equal 3 MOD 256.
Byte 15 in the sector can be used to adjust the sum to achive this.
Bytes 0…15 of the sector hold the disk specification.
Memory Range |
RAM Bank |
0x0000 | 0x3FFF | Bank 4 |
0x4000 | 0x7FFF | Bank 7 |
0x8000 | 0xBFFF | Bank 6 |
0xC000 | 0xFFFF | Bank 3 |
1.16 - DOS_SET_DRIVE
Set the default drive
Function |
Address | Description |
DOS_SET_DRIVE |
012D | Set the default drive |
Synopsys
Set the default drive (i.e. the drive implied by all filenames that do not specify a drive).
The default drive is initially A:
Does not access the drive, but merely checks that there is a driver for it (which does not imply that the drive exists).
This only affects routines that take filename parameters.
Entry Parameters
Register |
Content |
A |
Drive letter A…P, 0xFF to get the default drive |
Exit Parameters
- If OK:
- Carry true
- A = default drive
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
1.17 - DOS_SET_USER
Set the default user
Function |
Address | Description |
DOS_SET_USER |
0130 | Set the default user |
Synopsys
Set the default user area, i.e. the user area implied by all filenames that do not specify a user number.
The default user number is initially 0.
This only affects routines that take filename parameters.
Entry Parameters
Register |
Content |
A |
User 0…15, 0xFF to get the default user |
Exit Parameters
- If OK:
- Carry true
- A = default user
- Otherwise:
- Carry false
- A=Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
2 - Additional API
+3DOS Additional API
2.1 - DOS_GET_POSITION
Get the file pointer
Function |
Address | Description |
DOS_GET_POSITION |
0133 | Get the file pointer |
Synopsys
Returns the current position in the file
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK
- Carry true
- A corrupt
-
E HL = File pointer 0x000000…0xFFFFFF (16Mb)
E is most significant byte, L least
- Otherwise:
- Carry false
- A = Error code
- E HL = Corrupt
- Always:
- BC D IX corrupt, all other registers preserved.
2.2 - DOS_SET_POSITION
Set the file pointer
Function |
Address | Description |
DOS_SET_POSITION |
0136 | Set the file pointer |
Synopsys
Sets the file pointer.
This does not access the disk, nor does it check if the file pointer is >= 8 megabytes.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
E HL |
File pointer 0x000000…0xFFFFFF (16Mb)
E is most significant byte, L least
|
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
2.3 - DOS_GET_EOF
Get the end of file (EOF) position
Function |
Address | Description |
DOS_GET_EOF |
0139 | Get the end of file (EOF) position |
Synopsys
Get the end of file (EOF) file position greater than all written byte positions.
Does not affect the file pointer.
Does not consider soft-EOF.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
Exit Parameters
- If OK
- Carry true
- A corrupt
-
E HL = File pointer 0x000000…0xFFFFFF (16Mb)
E is most significant byte, L least
- Otherwise:
- Carry false
- A = Error code
- E HL = Corrupt
- Always:
- BC D IX corrupt, all other registers preserved.
2.4 - DOS_GET_1346
Get current cache/ramdisk location
Function |
Address | Description |
DOS_GET_1346 |
013C | Set current cache/ramdisk location |
Synopsys
Get the current location of the cache and RAMdisk.
Pages 1, 3, 4, 6 are considered as an array of 128 sector buffers
(numbered 0...127), each of 512 bytes. The cache and RAMdisk occupy
two separate (contiguous) areas of this array.
Any unused sector buffers may be used by the caller.
Note that the sizes may be smaller than those specified in DOS_SET_1346,
as there is an (unpublished) maximum size of cache and a minimum
size of RAMdisk (4 sectors).
Entry Parameters
None
Exit Parameters
- D = First buffer of cache
- E = Number of cache sector buffers
- H = First buffer of RAM disk
- L = Number of RAM disk sector buffers
- Always:
- AF BC IX corrupt, all other registers preserved.
2.5 - DOS_SET_1346
Rebuild the sector cache and RAM disk
Function |
Address | Description |
DOS_SET_1346 |
013F | Rebuild the sector cache and RAM disk |
Synopsys
Rebuild the sector cache and RAM disk.
This routine is used to make some store available to the user, or to return store to DOS.
Note that if the RAM disk is moved, or its size is changed, then all files thereon are erased.
Pages 1, 3, 4, 6 are considered as an array of 128 sector buffers (numbered 0...127), each of 512 bytes.
The cache and RAMdisk occupy two separate (contiguous) areas of this array.
The location and size of the cache and RAMdisk can be specified separately;
any remaining buffers are unused by DOS and are available to the caller.
Note that the sizes actually used may be smaller than those specified as in practice, there is a maximum cache size and a minimum size of RAMdisk (4 sectors).
A cache size of 0 will still work but will seriously impair the floppy disk performance.
This routine will fail if there are any files open on drive M:
Entry Parameters
Register |
Content |
D |
First buffer for cache |
E |
Number of cache sector buffers |
H |
First buffer for RAM disk |
L |
Number of RAM disk sector buffers |
Note: E + L <= 128
|
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
2.6 - DOS_FLUSH
Write any pending data to this drive
Function |
Address | Description |
DOS_FLUSH |
0142 | Write any pending data to this drive |
Synopsys
Write any pending headers, data, directory entries for this drive.
This routine ensures that the disk is up-to-date.
It can be called at any time, even when files are open.
Entry Parameters
Register |
Content |
A |
Drive A…P |
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
2.7 - DOS_SET_ACCESS
Change access mode of an open file
Function |
Address | Description |
DOS_SET_ACCESS |
0145 | Change access mode of an open file |
Synopsys
Try to change the access mode of an open file.
This routine will fail if the file is already open, in an incompatible access mode,
or if write access is required for a read-only file or disk.
Entry Parameters
Register |
Content |
B |
File number 0…15 |
C |
Access mode required:
Bits 0…2:
1 = exclusive read
2 = exclusive write
3 = exclusive read/write
5 = shared read
Bits 3…7 =0 as reserved
|
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
2.8 - DOS_SET_ATTRIBUTES
Set a files attributes
Function |
Address | Description |
DOS_SET_ATTRIBUTES |
0148 | Set a files attributes |
Synopsys
Set a file's attributes.
Only the file attributes f1'...f4', t1'...t3' can be set or cleared.
The interface attributes f5'...f8' are always 0.
This routine first sets the attributes specified in D, then clears those attributes specified in E,
i.e. E has priority.
Entry Parameters
Register |
Content |
D |
Attributes to set |
E |
Attributes to clear |
HL |
Address of filename, wildcards permitted |
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
Bit definitions for Attributes
Bit |
Attribute |
Bit |
Attribute |
0 | t3 | Archive |
3 | f4 |
1 | t2 | System |
4 | f3 |
2 | t1 | Read Only |
5 | f2 |
|
6 | f1 |
2.9 - DOS_OPEN_DRIVE
Open drive as a single file
Function |
Address | Description |
DOS_OPEN_DRIVE |
014B | Open drive as a single file |
Synopsys
Open the disk in this drive as a single file.
The whole disk is presented as a single file regardless of any real files on the disk.
This routine can be used to examine/poke directories, files, etc.
It should not be used by the uninitiated, the faint-hearted, or by anyone who values their files!
Sets file pointer to 0x000000 (0).
If there are any files open on this drive from other file numbers with shared-read access, then the disk can only be
opened with shared-read access from this file number.
If there are any file open on this drive from other file numbers with exclusive access, then the disk cannot be opened
from this file number.
Entry Parameters
Register |
Content |
A |
Drive A…P |
B |
File number 0…15 |
C |
Access mode required: Bits 0…2:
1 = exclusive read
2 = exclusive write
3 = exclusive read/write
5 = shared read
All other bits are reserved
|
Exit Parameters
- If OK
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL corrupt, all other registers preserved.
2.10 - DOS_SET_MESSAGE
Enable/disable disk error messages
Function |
Address | Description |
DOS_SET_MESSAGE |
014E | Enable/disable disk error messages |
Synopsys
Enable/disable disk error messages.
This should be used to make +3DOS aware of your own ALERT subroutine.
When +3DOS detects an error, it will call your ALERT subroutine, passing to it the values documented below.
The ALERT subroutine should print the text of the message that +3DOS passes it, then should wait for the user to
press a key.
If the key is in the reply string (that +3DOS also passes - version V1.0 only), then a 'ret' should be made with A =
0, 1 or 2, or containing the character (depending on the version of +3DOS).
Entry Parameters
Register |
Content |
A |
Enable 0xff or disable 0x00 |
HL |
Address of ALERT routine if enabled |
Exit Parameters
- HL = address of previous ALERT routine, 0 if none
- Always:
- AF BC DE IX corrupt, all other registers preserved.
ALERT implementations
Note that if you are substituting your own ALERT subroutine, the 'entry conditions' are the conditions passed to
your subroutine and the 'exit conditions' are the values that your subroutine must produce and the registers you are
allowed to corrupt.
There are two routine interfaces for ALERT, depending on which version of +3DOS is installed.
If you provide an ALERT function, you should have two subroutines,
or one with switchable entry and exit conditions,
and check the +3DOS version number before deciding which one to use.
+3DOS V1.0
Entry Parameters
Register |
Content |
DE |
Address of reply string in page 7 terminated by 0xFF |
HL |
Address of error message in page 7 terminated by 0xFF |
Exit Parameters
- A = Reply character
- Always:
- F BC DE HL IX corrupt, all other registers preserved.
+3DOS V1.1 and above
The second version allows the user to provide non-UK error messages and is generally more flexible, is present in
+3DOS versions V1.1 and upwards.
Entry Parameters
Register |
Content |
B |
Error number |
C |
Drive A…P |
D |
Logical track if required by message |
E |
Logical sector if required by message |
HL |
Address of UK error message in page 7 terminated by 0xFF |
Exit Parameters
-
A = Reply
0 = cancel
1 = retry
2 = ignore
- Always:
- F BC DE HL IX corrupt, all other registers preserved.
2.11 - DOS_REF_XDPB
Point at XDPB for this drive
Function |
Address | Description |
DOS_REF_XDPB |
0151 | Point at XDPB for this drive |
Synopsys
Point at the XDPB for this drive. (The XDPB is required by the floppy
disk driver routines.)
Entry Parameters
Register |
Content |
A |
Drive letter A…P |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- IX = Address of XDPB
- Otherwise:
- Carry false
- A=Error code
- IX corrupt
- Always:
- BC DE HL corrupt, all other registers preserved.
2.12 - DOS_MAP_B
Map drive B to unit 0 or 1
Function |
Address | Description |
DOS_MAP_A |
0154 | Map drive B to unit 0 or 1 |
Synopsys
Map drive B: to unit 0 or unit 1.
This routine will fail if drive B: has files open.
If mapping B: to unit 0, then each time unit 0 is accessed, a check is made that the drive mapping is correct.
If it isn't, then a reverse call to CHANGE DISK is made, to ask the user to change the disk in unit 0.
If mapping B: to unit 1, then if unit 1 does not exist, drive B: is disabled.
Entry Parameters
Register |
Content |
C |
Unit 0 or 1 |
HL |
Address of change disk routine if unit = 0 |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- HL = Address of previous change disk routine, 0 if none
- Otherwise:
- Carry false
- A corrupt
- HL corrupt
- Always:
- BC DE IX corrupt, all other registers preserved.
Change Disk routine
If you are substituting your own CHANGE DISK subroutine,
the 'entry conditions' are the conditions passed to your subroutine,
and the 'exit conditions' are registers you are allowed to corrupt.
Entry Parameters
Register |
Content |
A |
Logical drive A…P |
HL |
Address of message in page 7 terminated by 0xFF |
Exit Parameters
- Always:
- AF BC DE IX corrupt, all other registers preserved.
3 - Low Level API
+3DOS Low Level API
The following are the floppy disk driver routines.
The unit number is 0…3 for the uPD765A.
On the +3, unit 0 is drive A: and unit 1 is drive B:, or optionally, both A: and B: may be mapped onto unit 0.
Units 2 and 3 are not used.
With the exception of DD_INTERFACE, none of these routines may be called if the floppy disk interface is not present.
All routines assume that interrupts are enabled on entry, and will still be enabled on exit.
3.1 - DD_INTERFACE
Check for the disk drive interface
Function |
Address | Description |
DD_INTERFACE |
0157 | Check for the disk drive interface |
Synopsys
Is the floppy disk drive interface present?
This information is also held by BASIC in bit 4 of the FLAGS3 system variable.
Entry Parameters
None
Exit Parameters
- If present
-
- Carry true
- Otherwise:
- Carry false
- Always:
- A BC DE HL IX corrupt, all other registers preserved.
3.2 - DD_INIT
Initialise the disk driver
Function |
Address | Description |
DD_INIT |
015A | Initialise the disk driver |
Synopsys
Initialise the disk driver
Entry Parameters
None
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
3.3 - DD_SETUP
Setup disk parameters
Function |
Address | Description |
DD_SETUP |
015D | Setup disk parameters |
Synopsys
Set up disk parameters.
Send a specify command.
Entry Parameters
Register |
Content |
HL |
Address of parameter block |
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
Parameter Block
Byte |
Content |
0 | Motor on time, unit=100ms |
1 | Motor off time, unit=100ms |
2 | Write off time, unit=10ms |
3 | Head settle time, unit=ms |
4 | Step rate, unit=ms |
5 | Head unload time, unit=32ms, 32…480 |
6 | (Head load time *2)+1, unit=4ms, 4…508 |
3.4 - DD_SET_RETRY
Set try/retry count
Function |
Address | Description |
DD_SET_RETRY |
0160 | Set try/retry count |
Synopsys
Set the try and retry count.
A value of 1 will try the operation once with no retries.
Entry Parameters
Register |
Content |
A |
Try/Retry count >= 1 |
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
3.5 - DD_READ_SECTOR
Read a sector
Function |
Address | Description |
DD_READ_SECTOR |
0163 | Read a sector |
Synopsys
Read a sector
Entry Parameters
Register |
Content |
B |
Page for 0xC000…0xFFFF |
C |
Unit 0 or 1 |
D |
Logical track, 0 base |
E |
logical sector, 0 base |
HL |
Address of buffer |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
3.6 - DD_WRITE_SECTOR
Write a sector
Function |
Address | Description |
DD_WRITE_SECTOR |
0166 | Write a sector |
Synopsys
Write a sector
Entry Parameters
Register |
Content |
B |
Page for 0xC000…0xFFFF |
C |
Unit 0 or 1 |
D |
Logical track, 0 base |
E |
logical sector, 0 base |
HL |
Address of buffer |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
3.7 - DD_CHECK_SECTOR
Check a sector
Function |
Address | Description |
DD_CHECK_SECTOR |
0169 | Check a sector |
Synopsys
Check a sector. (Uses the uPD765A scan equal command.)
Checks that the sector on disk is the same as the copy in memory.
Note that FFh (255) on disk or in memory always matches anything (see
uPD765A specification for further details).
Entry Parameters
Register |
Content |
B |
Page for 0xC000…0xFFFF |
C |
Unit 0 or 1 |
D |
Logical track, 0 base |
E |
logical sector, 0 base |
HL |
Address of buffer |
IX |
Address of XDPB |
Exit Parameters
- If OK & Equal:
- Carry true
- Zero true
- A corrupt
- If OK & Not Equal:
- Carry true
- Zero false
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
3.8 - DD_FORMAT
Format a track
Function |
Address | Description |
DD_FORMAT |
016C | Format a track |
Synopsys
Format a track. (Uses the uPD765A format track command.)
Entry Parameters
Register |
Content |
B |
Page for 0xC000…0xFFFF |
C |
Unit 0 or 1 |
D |
Logical track, 0 base |
E |
Filler byte, usually 0xE5 |
HL |
Address of format buffer |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
Format buffer
The format buffer contains 4 bytes for each sector:
Byte |
Content |
Range |
C | Track Number | 0…39 |
H | Head Number | Always 0 on a standard +3 single sided drive |
R | Sector Number | 0…255 |
N | Log2(sectorSize)-7 | 2 for 512 byte sectors |
3.9 - DD_READ_ID
Read a sector identifier
Function |
Address | Description |
DD_READ_ID |
016F | Read a sector identifier |
Synopsys
Read a sector identifier
Entry Parameters
Register |
Content |
C |
Unit 0 or 1 |
D |
Logical track, 0 base |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A = sector number from identifier
- Otherwise:
- Carry false
- A = Error code
- Always:
- HL = Address of result buffer in page 7
- BC DE IX corrupt, all other registers preserved.
3.10 - DD_TEST_UNSUITABLE
Check disk is suitable to write to
Function |
Address | Description |
DD_TEST_UNSUITABLE |
0172 | Check disk is suitable to write to |
Synopsys
Check that disk is suitable to write to.
A single track disk will not work in a double track drive, and vice versa.
Entry Parameters
Register |
Content |
C |
Unit 0 or 1 |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
3.11 - DD_LOGIN
Log in a new disk
Function |
Address | Description |
DD_LOGIN |
0175 | Login a new disk |
Synopsys
Log in a new disk.
Initialise the XDPB.
This routine does not affect or consider the freeze flag.
Entry Parameters
Register |
Content |
C |
Unit 0 or 1 |
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A = Disk type
- DE = Size of allocation vector
- HL = Size of hash table
- Otherwise:
- Carry false
- A = Error code
- DE HL corrupt
- Always:
- BC IX corrupt, all other registers preserved.
3.12 - DD_SEL_FORMAT
Select a standard format
Function |
Address | Description |
DD_SEL_FORMAT |
0178 | Select a standard format |
Synopsys
Initialise an XDPB for a standard format.
This routine does not affect or consider the freeze flag.
Entry Parameters
Register |
Content |
A |
Disk type:
0 = Spectrum +3 (Amstrad PCW DD, SS, ST)
1 = Amstrad CPC range system format
2 = Amstrad CPC range data-only format
3 = Amstrad PCW range DD, SS, DT
Any other value returns an error
|
IX |
Address of XDPB |
Exit Parameters
- If OK:
- Carry true
- A = Disk type
- DE = Size of 2 bit allocation vector
- HL = Size of hash table
- Otherwise:
- Carry false
- A = Error code
- DE HL corrupt
- Always:
- BC IX corrupt, all other registers preserved.
3.13 - DD_ASK_1
Check to see if unit 1 is present
Function |
Address | Description |
DD_ASK_1 |
017B | Check to see if unit 1 is present |
Synopsys
Check to see if unit 1 is present.
BASIC holds this information in bit 5 of the FLAGS3 system variable.
Turn motor on.
Fetch drive status.
If unit 1 is not-ready and write-protected, then unit 1 is missing.
Start motor off timeout.
Note that this routine can be fooled by disks which are almost, but not quite, inserted in the drive.
This routine assumes that when a disk is not in the drive, then write-protect is true.
This is indeed the case for 3 inch and 8 inch disk drives, but is not the case for 5 1/4 inch disk drives.
Entry Parameters
None
Exit Parameters
- If unit 1 present:
- Carry true
- Otherwise:
- Carry false
- Always:
- A BC DE HL IX corrupt, all other registers preserved.
3.14 - DD_DRIVE_STATUS
Check drive status
Function |
Address | Description |
DD_DRIVE_STATUS |
017E | Check drive status |
Synopsys
Issue a sense drive status command.
Entry Parameters
Register |
Content |
C |
Unit/head
Bits 0…1 Unit 0…3
Bit 2 Head
Bits 3…7 = 0
|
Exit Parameters
- A = ST3 status register 3 of uPD765A
- Always:
- F BC DE HL IX corrupt, all other registers preserved.
3.15 - DD_EQUIPMENT
Ask what type of drive
Function |
Address | Description |
DD_EQUIPMENT |
0181 | Ask what type of drive |
Synopsys
Ask what type of drive this is (i.e. single/double track, single/double sided).
Track information can only be determined once a disk has been seen and had its type identified during logging in.
Side information can only be detected after a double sided disk has been seen and has its type identified during
logging in.
Entry Parameters
Register |
Content |
C |
Unit 0 or 1 |
IX |
Address of XDPB |
Exit Parameters
- Carry true
-
A = Side/track information
bits 0…1 side information: 0 = unknown, 1 = single sided, 2 = double sided
bits 2…3 track information: 0 = unknown, 1 = single track, 2 = double track
- Always:
- F BC DE HL IX corrupt, all other registers preserved.
3.16 - DD_ENCODE
Set copy protection encode routine
Function |
Address | Description |
DD_ENCODE |
0184 | Set copy protection encode routine |
Synopsys
Set the copy protection ENCODE subroutine.
Copy protected disks have some of their track and sector numbers encoded on disk.
Before each disk access, the ENCODE subroutine is called to encode the physical track and sector numbers.
These encoded track and sector numbers must match those in the sector identifier.
Note that tracks 0…2 on either side of a disk should not be encoded.
Entry Parameters
Register |
Content |
A |
Enable 0xFF or disable 0x00 |
HL |
If enabled address of ENCODE routine |
Exit Parameters
- HL = Address of previous encode routine, 0 if none
- Always:
- AF BC DE IX corrupt, all other registers preserved.
ENCODE routine
If you are substituting your own ENCODE subroutine,
the 'entry conditions' are the conditions passed to your subroutine,
and the 'exit conditions' are the values that your subroutine must produce and the registers you are allowed to
corrupt.
Entry Parameters
Register |
Content |
C |
Unit/Side
Bits 0…1 = unit, Bit 2 = side
|
D |
Physical track |
E |
Physical sector |
IX |
Address of DPB |
Exit Parameters
- D = Encoded physical track
- E = Encoded physical sector
- Always:
- AF corrupt, all other registers preserved.
3.17 - DD_L_XDPB
Initialise XDPB for a given format
Function |
Address | Description |
DD_L_XDPB |
0187 | Initialise XDPB for a given format |
Synopsys
Initialise an XDPB for a given format.
This routine does not affect or consider the freeze flag.
Entry Parameters
Register |
Content |
DE |
Address of source disk specification |
IX |
Address of destination XDPB |
Exit Parameters
- If OK:
- Carry true
- A = Disk type recorded on disk
- DE = Size of allocation vector
- HL = Size of hash table
- Otherwise:
- Carry false
- A = Error code
- DE HL corrupt
- Always:
- BC IX corrupt, all other registers preserved.
3.18 - DD_L_DPB
Initialise DPB for a given format
Function |
Address | Description |
DD_L_DPB |
018A | Initialise DPB for a given format |
Synopsys
Initialise an DPB for a given format.
This routine does not affect or consider the freeze flag.
Entry Parameters
Register |
Content |
DE |
Address of source disk specification |
IX |
Address of destination DPB |
Exit Parameters
- If OK:
- Carry true
- A = Disk type recorded on disk
- DE = Size of allocation vector
- HL = Size of hash table
- Otherwise:
- Carry false
- A = Error code
- DE HL corrupt
- Always:
- BC IX corrupt, all other registers preserved.
3.19 - DD_L_SEEK
Seek to required track
Function |
Address | Description |
DD_L_SEEK |
018D | Seek to required track |
Synopsys
Seek to required track.
Retry if failure.
Entry Parameters
Register |
Content |
C |
Unit/head: Bits 0…1 unit, Bit 2 head |
D |
Track |
IX |
Address of destination XDPB |
Exit Parameters
- If OK:
- Carry true
- A corrupt
- Otherwise:
- Carry false
- A = Error code
- Always:
- BC DE HL IX corrupt, all other registers preserved.
3.20 - DD_L_READ
Low level uPD765A read command
Function |
Address | Description |
DD_L_READ |
0190 | Low level uPD765A read command |
Synopsys
Low level uPD765A read command.
- Read data.
- Read deleted data.
- Read a track.
- Writes commands.
- Reads data.
- Reads results.
- Motor must be running.
Entry Parameters
Register |
Content |
HL |
Address of parameter block |
Exit Parameters
- HL = Address of result buffer in page 7
- Always:
- AF BC DE IX corrupt, all other registers preserved.
Parameter Block Format
Bytes |
Length |
Content |
0 | 0 | 1 |
Page for 0xC000…0xFFFF |
1 | 2 | 2 |
Address of buffer |
3 | 4 | 2 |
Number of bytes to transfer |
5 | 5 | 1 |
Number of command bytes n |
6 | 5+n | n |
Command bytes |
3.21 - DD_L_WRITE
Low level uPD765A write command
Function |
Address | Description |
DD_L_WRITE |
0193 | Low level uPD765A write command |
Synopsys
Low level uPD765A write command.
- Write data.
- Write deleted data.
- Format a track.
- Scan equal.
- Scan low or Equal.
- Writes commands.
- Writes data.
- Reads results.
- Motor must be running.
Entry Parameters
Register |
Content |
HL |
Address of parameter block |
Exit Parameters
- HL = Address of result buffer in page 7
- Always:
- AF BC DE IX corrupt, all other registers preserved.
Parameter Block Format
Bytes |
Length |
Content |
0 | 0 | 1 |
Page for 0xC000…0xFFFF |
1 | 2 | 2 |
Address of buffer |
3 | 4 | 2 |
Number of bytes to transfer |
5 | 5 | 1 |
Number of command bytes n |
6 | 5+n | n |
Command bytes |
3.22 - DD_L_ON_MOTOR
Turn on motor
Function |
Address | Description |
DD_L_ON_MOTOR |
0196 | Turn on motor |
Synopsys
Turn on the motor.
Wait for the motor on time as set by DD SETUP.
Entry Parameters
None
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
3.23 - DD_L_T_OFF_MOTOR
Start motor off timeout
Function |
Address | Description |
DD_L_T_OFF_MOTOR |
0199 | Start motor off timeout |
Synopsys
Start motor off timeout.
Entry Parameters
None
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
3.24 - DD_L_OFF_MOTOR
Turn off motor
Function |
Address | Description |
DD_L_OFF_MOTOR |
019C | Turn off motor |
Synopsys
Turn off the motor.
Entry Parameters
None
Exit Parameters
- Always:
- AF BC DE HL IX corrupt, all other registers preserved.
4 - +3DOS File Header
The +3DOS File Header
Tape files have headers which contain some system information.
+3DOS files may, or may not, have headers.
All files created by BASIC's SAVE command will have headers.
The +3DOS header mechanism provides a dedicated 8 byte area in each headed file reserved for BASIC's use.
The remainder of the header is reserved for +3DOS.
This 8 byte header is utilised in files created by BASIC commands (see DOS OPEN description).
+3DOS files may have a single header in the first 128 bytes of the file - the header record.
These headers are detected by a 'signature' and checksum.
If the signature and checksum are as expected, then a header is present; if not, there is no header.
Thus, it is possible, but unlikely, that a file without a header could be mistaken for one with a header.
+3DOS File Header
Bytes |
Length |
Content |
0 | 7 | 8 | +3DOS Signature | "PLUS3DOS" |
8 | 1 | Soft-EOF | 0x1A |
9 | 1 | Issue | 0x01 |
10 | 1 | Version | 0x00 |
11 | 14 | 4 | Length of file including header |
15 | 22 | 8 | +3 BASIC Header |
23 | 126 | 104 | Reserved | 0x00 |
127 | 1 | Checksum | Sum bytes 0…126 AND 0xFF |
+3 BASIC Header
Bytes |
Length |
Content |
0 | 1 | File Type |
1 | 2 | 2 | File Length |
3 | 4 | 2 | Param 1 |
5 | 6 | 2 | Param 2 |
7 | 1 | Unused = 0x00 |
BASIC File Type
Type |
File Description |
Param 1 |
Param 2 |
0 |
BASIC Program |
Line number to start |
Start of variable area relative to program start |
1 |
Number Array |
Variable name, e.g. if DIM a() then this is 0x80 a=0x81, y=0x99
|
|
2 |
Character Array |
Variable name, e.g. if DIM a$() then this is 0x80 a=0xC1, y=0xD9
|
|
3 |
CODE |
Start when saved |
32768 |
Notes
-
The file header is the first 128 bytes of the file on disk.
-
The Length at bytes 11 is a 32-bit number, the max file size is 8Mb. This includes the 128 byte header.
-
The BASIC header at byte 15 is what IX points to after a call to DOS_READ_HEAD so (IX+0) is the File Type.
-
The length in the BASIC header is the actual length of the file, without the 128 byte header.
-
For File Type 0 - BASIC, Param 1 is either the line number to start execution or 0x8000 for none.
Param 2 is the offset of variables. For most purposes this can be the length of the program so no variables.
-
For File Type 3 - CODE, Param 1 is the load address. Param 2 is unused
-
The checksum byte 127 in the header is the sum of the rest of the header, not XOR like tape files.
5 - Error Codes
The +3DOS Error Codes
When a call to a +3DOS API fails then the carry flag will be false and the Accumulator will contain the error code.
The errors are in two categories, Recoverable (Green) and Non-recoverable (Red):
Code |
Error |
0 | 0x00 | Drive not ready |
1 | 0x01 | Disk is write protected |
2 | 0x02 | Seek fail |
3 | 0x03 | CRC data error |
4 | 0x04 | No data |
5 | 0x05 | Missing address mark |
6 | 0x06 | Unrecognised disk format |
7 | 0x07 | Unknown disk error |
8 | 0x08 | Disk changed whilst +3DOS was using it |
9 | 0x09 | Unsuitable media for drive |
20 | 0x14 | Bad filename |
21 | 0x15 | Bad parameter |
22 | 0x16 | Drive not found |
23 | 0x17 | File not found |
24 | 0x18 | File already exists |
25 | 0x19 | End of file |
26 | 0x1A | Disk full |
27 | 0x1B | Directory full |
28 | 0x1C | Read-only file |
29 | 0x1D | File number not open (or open with wrong access) |
30 | 0x1E | Access denied (file is in use already) |
31 | 0x1F | Cannot rename between drives |
32 | 0x20 | Extent missing (which should be there) |
33 | 0x21 | Uncached (software error) |
34 | 0x22 | File too big (trying to read or write past 8 megabytes) |
35 | 0x23 | Disk not bootable (boot sector is not acceptable to DOS BOOT) |
36 | 0x24 | Drive in use (trying to re-map or remove a drive with files open) |