ALIEN3.DOC
ALIEN3.DOC - Specification of ALIEN version 3
Update log
----------
24/08/91 Massive edit to combine several old files
into this one. L
31/08/91 Further elaboration of the O_ASYN and O_KILL
driver functions. L
22/07/92 Added some clarifications of the O_ASYN and O_KILL
driver functions. L
History
-------
As early as 1985, the Ordinator acquired the ability to
read and write foreign disks, at that time through the
ALIEN program, so named because with it you could access
alien disks. At that time, the BIOS contained translation
routines from CP/M logical disk adresses (consisting of
track and sector) to physical disk adresses (in registers)
which were simply patched by the ALIEN program. By also
updating the Disk Parameter Block given to the BDOS, any
CP/M disk format could be used, subject to the size
constraint that the allocation bit map and directory
checksum vector fitted in the space allocated for them
in the BIOS image. This was mostly the work of Luc Rooijakkers.
When the DiskServer came along, we created a BIOS for it by
modifying the Ordinator BIOS, thus automatically copying the
ALIEN support. Due to the more diverse nature of the disks
connected to it, this uncovered several problems with the
ALIEN support. Geert-Jan de Groot modified it somewhat,
producing what might be called ALIEN 1.5. This meant that
it could no longer be used with the standard ALIEN program,
in effect cutting off all ALIEN support for the DiskServer.
However, it did help structuring the more complicated disk
subsystem of the DiskServer BIOS.
Then the TimeSharing system came along. With it came a
disk caching system, thus using lots of disk adresses. At first
the disk cache could only handle 512-byte disk sectors, and
if I remember correctly, the translation from logical to
physical disk sectors was quite messy. During 1987 the
Ordinator got much more memory to play wit, and we enlarged
the disk cache to the point were it had to be exported from
the system address space, much like the buffer cache was
exported in V7 UNIX (in fact, that was my inspiration to
try it). We had thought about integrating ALIEN in TS
for quite some time, but during August 1987 I finally
started working on it. First and foremost, this meant
that the disk cache had to be able to handle non-512
sized sectors. After this was done, some kind of disk
kind descriptions had to be used, and I started implementing
what I called ALIEN version 3, because it again differed from
all earlier versions of ALIEN support. The TS way of using
disks (automatically recognizing them when placed on-line)
forced modifications to the DJOE bootstrap format, placing
the disk kind and parameters in it for the first time.
When I wanted to use the DiskServer for its intended purpose,
I first overhauled its BIOS to support ALIEN version 3,
to make it interoperable with TS. During this effort, other
modifications to the ALIEN support were made, generalizing
it very much. The DiskServer currently is the only BIOS
that allows several disk kinds and dynamically allocates
data structures for the disks, so it doesn't have size
limits on allocation bit map and directory checksum vector.
Additions to the bootstrap specification were made to allow
partitioning a disk, but this has not yet been implemented.
Additions were also made to the I/O calls, to finally allow
us to format an alien disk; something that for several years
already been called for. This has also not yet been completed.
Finally, addition of the EPROM programmer as a pseudo-disk
on the DiskServer forced addition of asynchronous I/O.
Until that time, all ALIEN3 disk I/O had always been
synchronous, with the exception of TS which used a convention
all of its own.
As of this writing, the above picture is accurate. I am not
sure how much of the specification will ever be implemented
everywhere, but the specification seems nice and complete,
even in the face of CHAOS.
L. Rooijakkers (0144), 24/08/91
Contents
--------
The ALIEN version 3 specification consists of many parts:
- A standard format for CP/M logical disk adresses.
- A standard format for physical disk adresses, for all kinds
of disks (8 inch, 5 1/4 inch and 3 1/2 inch floppy disks, as
well as winchester disks and CP/M logical disks). Such an
address has a kind which implies its format; there are
several possible formats (the format is a discrimitated
union).
- Standard text formats for the above.
- A standard calling sequence for disk address translation
routines (routines that translate logical disk adresses
to physical disk adresses).
- Standard identifiers for several kinds of file systems,
including DOS and CP/M.
- A standard calling sequence for disk recognition routines
(routines that recognize the kind of a disk from its
bootstrap sector).
- A standard format for a drive capability description (actually
a description of the physical disk adresses that are
acceptible to the disk device driver).
- A standard format for device kind descriptions. The
format includes a device class that indicated wether the
device is a disk, terminal etc. For disk class devices
(the only class currently used), the format includes
a file system identifier, a name, optional default
file system information, drive capabilities, a
translate routine and an optional recognition routine.
- A standard format for disk format descriptions. This
format is intended to be used by a disk formatting program;
part of it (the track description) must be passed to the
Format track function.
- A standard calling sequence for disk device drivers, with
several optional functions.
- Standard text formats for the parametes and results of the
above functions, in particular standard error texts.
This specification interacts with the DJOE bootsector format
because recognition routines must recognize bootsectors in that
format. It also interacts with the XBIOS specification because
that specification says how to make calls to disk device drivers
and how to install device kind descriptions. The format of the
drive control block that is passed to all disk device driver
calls is specified by the XBIOS specification.
Most of the constants from this document are given symbolic
named by the assembler include file ALIEN3.LIB, parts of which
are included below. The included parts are indented 4 spaces.
Not all of the constants from ALIEN3.LIB are described in this
document; some of them describe CP/M Disk Parameter Blocks
(DPBs) and Disk Parameter Headers (DPHs), which are explained
in the CP/M 2.2 Alteration Guide. Currently, ALIEN3.LIB also
includes constants from the DJOE bootsector specification.
The relevant constants are also, under other names, included
in the TS header files. They are also duplicated in the file
SRVCON.LIB, but should be removed there.
CP/M logical disk address
-------------------------
A CP/M logical disk address specifies a unique 128-byte logical
sector on the logical CP/M disk. Such an adress is passed from
the CP/M BDOS to the BIOS via the SETSEC and SETTRK calls. The
format described below is used only between the BIOS and the
translate routine.
The format of a CP/M logical disk address is
L_trk EQU 0 ;Track [0..TRK-1] (16-bit)
L_sec EQU 2 ;Sector [0..SPT-1] (16-bit)
L_SIZE EQU 4 ;Size of CP/M logical address
Here TRK (number of tracks) and SPT (sectors per track) are
derived from the CP/M Disk Parameter Block for the disk.
The L_trk field is directly set from the value passed to
the BIOS SETTRK routine, but the L_sec field is set from the
value passed to SETSEC minus one.
Physical disk address
---------------------
XXX
P_type EQU 0 ;Address type (8-bit)
P_addr EQU 1 ;Disk address, see below (5-byte)
P_leng EQU 6 ;Sector length (8-bit)
P_part EQU 7 ;Sector part (8-bit)
P_ADDR EQU 6 ;Size of phys. addr.
P_LENG EQU 7 ;Size of phys. addr. + length
P_SIZE EQU 8 ;Size of phys. addr. + length + part
XXX
P_flag EQU 1 ;Flags (8-bit)
XXX
;Format 0
P0_flag EQU 1 ;Flags (8-bit)
P0_trk EQU 2 ;Track (16-bit)
P0_sec EQU 4 ;Sector (16-bit)
;P0_flag:
;
;b0-b7 Unused
XXX
;Format 1
P1_flag EQU 1 ;Flags (8-bit)
P1_trk EQU 2 ;Track (8-bit)
P1_idt EQU 3 ;ID track (8-bit)
P1_sec EQU 4 ;Sector (8-bit)
P1_unu EQU 5 ;Unused (8-bit)
;P1_flag:
;
;b0 Head (H=0/1)
;b1 Density (M=D/S)
;b2 Address mark (A=N/D)
;b3-b7 Unused
XXX
;Format 2
P2_flag EQU 1 ;Flags (8-bit)
P2_lsn EQU 2 ;Logical Sector Number (24-bit)
P2_unu EQU 5 ;Unused (8-bit)
;P2_flag:
;
;b0-b7 Unused
XXX
;Unused bits and bytes must be zeroed !!
XXX
PT_CPM EQU 00H ;CP/M, format 0
PT_3 EQU 05H ;3.5 inch, format 1
PT_548 EQU 08H ;5.25 inch, 48 tpi, format 1
PT_596 EQU 09H ;5.25 inch, 96 tpi, format 1
PT_8 EQU 0CH ;8 inch, format 1
PT_WIN EQU 10H ;Winchester, format 2
Disk device drivers
-------------------
All of the drive I/O calls share the following basic calling
sequence:
;Generic driver function [AF,BC,DE,HL]
;
;Entry A= function code
; IX= drive control block
;
;Exit A= error code
What exactly is a drive control block and how to obtain one is
not specified here; see the XBIOS specification. In some cases,
other conventions may be used for drive control blocks.
The possible function codes are given below. The meaning of
an error code is also described below; a zero error code means
no error. An error code of E_UNK is returned if a driver does
not support a function. Note that the flags are not necessarily
set according to the value in A; callers have to do this
themselves when needed.
O_INIT EQU 0 ;Init driver
O_READ EQU 1 ;Read sector
O_WRIT EQU 2 ;Write sector
O_BOOT EQU 3 ;Read boot sector
O_OFF EQU 4 ;Put drive offline
O_ISRO EQU 5 ;Test read-only status
O_ISRM EQU 6 ;Test removable status
O_ISCH EQU 7 ;Test disk-changed status
O_RADR EQU 8 ;Read address
O_FTRK EQU 9 ;Format track
O_RTRK EQU 10 ;Read track
O_WTRK EQU 11 ;Write track
O_ASYN EQU 12 ;Set asynchronous mode
O_KILL EQU 13 ;Kill asynchronous functions
In general, driver functions are synchronous. If a driver
supports the O_ASYN function, functions can be done
asynchronously; see the description of O_ASYN below.
Asynchronous functions can be cancelled with the O_KILL
function if the driver supports it; see below.
For the purpose of this specification every drive is treated
independently. It may be the case that drives share resources
such that functions have to interleaved in some way, but this
does not mean that the behaviour of any individual drive
diverges from this specification. See the discussion of O_ASYN
for some ramifications of this constraint.
Many of the driver functions are optional; only O_INIT, O_READ,
O_WRITE and O_BOOT are required. The optional functions are
marked as such below. They are interrelated; presence of O_KILL,
for example, requires presence of O_ASYNC.
The individual driver functions have the following calling
sequence:
O_INIT - Init driver
;Init driver [AF,BC,DE,HL]
;
;Entry A= O_INIT (init driver)
; IX= drive control block
;
;Exit A= error code
XXX
O_READ - Read sector
;Read sector [AF,BC,DE,HL]
;
;Entry A= O_READ (read sector)
; IX= drive control block
; IY= physical address
; HL= buffer address
;
;Exit A= error code
This function is used to read a sector from the given physical
disk address into the given buffer. Only the first P_LENG bytes
of the address are examined; the P_leng field indicates the
length of the sector to be read. Effects are unpredicatable if
it does not match the physical length of the sector on disk;
ideally this should result in an E_LDA error, but some machines
cannot efficiently or reliably detect this. In any case, the
buffer will not be modified beyond the given length.
The physical address description will not be modified.
O_WRIT - Write sector
;Write sector [AF,BC,DE,HL]
;
;Entry A= O_WRITE (write sector)
; IX= drive control block
; IY= physical address
; HL= buffer address
;
;Exit A= error code
This function is used to write a sector from the given buffer to
the given physical disk address. Only the first P_LENG bytes
of the address are examined; the P_leng field indicates the
length of the sector to be written. Effects are unpredicatable
if it does not match the physical length of the sector on disk;
ideally this should result in an E_LDA error, but some machines
cannot efficiently or reliably detect this.
The physical address description will not be modified.
O_BOOT - Read boot sector
;Read boot sector [AF,BC,DE,HL]
;
;Entry A= O_BOOT (read boot sector)
; IX= drive control block
; IY= physical address pointer
; HL= buffer address
; DE= buffer length
;
;Exit A= error code
This function is used to read the boot sector. It is almost
like function O_READ, except that the physical address is
filled in by this function. This allows a machine dependent
algorithm to be used to find the boot sector. Typically the
driver will try track 0, sector 1 with varying densities.
If a boot sector was found, its physical address will be filled
in. Only the first P_LENG bytes of the address will be modified.
If possible, the P_leng field will indicate the length of the
boot sector. Some machines cannot reliably determine the length
of a sector read from disk; they will indicate this by setting
P_leng to zero. Before reading from disk, the buffer should be
filled with all E5 bytes.
The buffer length passed in DE should be at least 1024, since
this is the length of the longest sector currently accepted
by machines which cannot determine the boot sector length.
In any case, the buffer will not be modified beyond the given
length.
The E_ADDR bit will never be set for this function.
O_OFF - Put drive offline (optional)
;Put drive offline [AF,BC,DE,HL]
;
;Entry A= O_OFF (put drive offline)
; IX= drive control block
;
;Exit A= error code
This function is used to put a disk drive offline. If possible,
the disk should be ejected physically.
The E_ADDR bit will never be set for this function.
O_ISRO - Test read-only status (optional)
;Test read-only status [AF,BC,DE,HL]
;
;Entry A= O_ISRO (test read-only status)
; IX= drive control block
;
;Exit A= error code
This function is used to test if a disk is read-only, or,
more properly, if it is write-protected. The answer is
encoded in the returned error code as if this operation
was a disk write operation:
E_NUL - Disk is writable
E_WPT - Disk is write-protected
E_DSK - No disk
E_UNK - Function not implemented; unknown
Other disk-related error codes will not be returned.
The E_ADDR bit will never be set for this function.
O_ISRM - Test removable status (optional)
;Test removable status [AF,BC,DE,HL]
;
;Entry A= O_ISRM (test removable status)
; IX= drive control block
;
;Exit A= error code
This function is used to test if a disk is removable.
The answer is encoded in the returned error code as follows:
E_NUL - Disk is not removable
E_DSK - Disk is removable
E_UNK - Function not implemented; assume removable
Other disk-related error codes will not be returned.
The E_ADDR bit will never be set for this function.
O_ISCH - Test disk-changed status (optional)
;Test disk-changed status [AF,BC,DE,HL]
;
;Entry A= O_ISCH (test disk-changed status)
; IX= drive control block
;
;Exit A= error code
This function is used to test if a disk has changed
since the last driver call. The answer is encoded in
the returned error code as follows:
E_NUL - Disk has not changed
E_DSK - No disk or disk has changed
E_UNK - Function not implemented; assume changed
Other disk-related error codes will not be returned.
The E_ADDR bit will never be set for this function.
This function is most easily implemented with hardware support,
but it can also be implemented in software. The method is to
return E_NUL if the disk has been used some reasonably short
time ago and E_DSK otherwise. The key to this trick is
understanding that this function is mostly a performance trick
because it avoids having to look at the boot sector before
every disk operation. Consequently, a lazy driver can always
return E_DSK, which has the same effect as if the function
was not implemented at all.
O_RADR - Read address (optional)
;Read address [AF,BC,DE,HL]
;
;Entry A= O_RADR (read address)
; IX= drive control block
; IY= physical address
; HL= buffer address
;
;Exit A= error code
XXX
O_FTRK - Format track (optional)
;Format track [AF,BC,DE,HL]
;
;Entry A= O_FTRK (format track)
; IX= drive control block
; IY= physical address
; HL= buffer address
; DE= buffer length
;
;Exit A= error code
XXX
O_RTRK - Read track (optional)
;Read track [AF,BC,DE,HL]
;
;Entry A= O_RTRK (read track)
; IX= drive control block
; IY= physical address
; HL= buffer address
; DE= buffer length
;
;Exit A= error code
XXX
O_WTRK - Write track (optional)
;Write track [AF,BC,DE,HL]
;
;Entry A= O_WTRK (write track)
; IX= drive control block
; IY= physical address
; HL= buffer address
; DE= buffer length
;
;Exit A= error code
XXX
O_ASYN - Set asynchronous mode (optional)
;Set asynchronous mode [AF,BC,DE,HL]
;
;Entry A= O_ASYN (set asynchronous mode)
; IX= drive control block
; IY= completion routine parameter
; HL= completion routine
;
;Exit A= error code
; IY= old completion routine parameter
; HL= old completion routine
This function is used to set/reset asynchronous mode on drivers
that support it. If asynchronous mode is set, it applies only
to the next function. Asynchronous mode can be reset by invoking
O_ASYN with a zero completion routine address in HL.
If asynchronous mode has been set, the next function may return
E_ASYN. This indicates that the function has been started, but
is not yet finished. When it is finished, the completion
routine will be called with calling sequence
;Function complete [AF,BC,DE,HL,IX,IY]
;
;Entry A= function code
; IX= drive control block
; IY= completion routine parameter
; HL= completion routine
;
;Exit -
Because the completion routine may be called before the
original driver call has returned E_ASYN, the caller should
be prepared for completion routine calls when it does the
asynchronous function call.
When the completion routine is called the driver is idle;
a completion routine can therefore call the driver to start
the next function. It is the responsability of the driver not to
call the next completion routine until the previous one has returned,
however, in order to avoid stack overflow.
Completion routines may be called from interrupt routines and
with a different stack; they should not do much more then
start the next driver call in order to avoid system lockup.
Completion routines for different drives may be called in
arbitrary order and it is quite possible for one to be called
while another one is still active.
While the function is in progress, any address descriptors or
buffers passed to it should not be touched.
Every driver has an upper limit on the number of functions
that can be in progress simultaneously. If this limit has
been reached, all further calls to the driver (except O_KILL)
will return error code E_BUSY, even O_ASYN calls. For most
drivers, this limit will be 1, i.e., only one function can
be started asynchronously. The limit need not be constant.
In principe a driver could take advantage of multiple queued
requests to reorder them, but this is not expected to be
worthwile.
Note that a driver servicing multiple drives through a single
controller must be able to queue at least one request for
every drive, because it cannot return E_BUSY for functions on
idle drives. Instead, such functions must be queued, only to
be started when the controller becomes available. Such a
driver should take precautions not to starve a drive because
other drives are busy. A simple round-robin service discipline
is adequate for this.
O_KILL - Kill asynchronous function (optional)
;Kill asynchronous functions [AF,BC,DE,HL]
;
;Entry A= O_KILL (kill asynchronous function)
; IX= drive control block
;
;Exit A= error code
This function is used to kill asynchronous functions that have
been started via the O_ASYN function. The function currently in
progress will be aborted if it has not yet performed
irreversable actions on the disk, otherwise it will be completed
normally (that is, disk write operations will not be aborted
half-way through). The completion routines for such an aborted
function will be called with error code E_KILL.
Error codes
-----------
An error code consists of a 7-bit reason code and a one-bit
flag that indicates if an error is related to the entire
disk or only this address. Constants for masking these bits
are
E_ADDR EQU 80H ;Mask for address flag
E_CODE EQU 7FH ;Mask for reason code
The E_ADDR bit is set if the function passed an address and the
error is related to the adress, i.e., using a different addres
might result in no error or a different one.
Currently defined reason codes are
E_NUL EQU 00H ;No error
E_DSK EQU 01H ;No disk
E_WPT EQU 02H ;Write protect
E_WRF EQU 03H ;Write fault
E_RNF EQU 04H ;Record not found
E_CRC EQU 05H ;Crc error
E_LDA EQU 06H ;Lost data
E_ADR EQU 07H ;Bad address
E_FMT EQU 08H ;Unsupported format
E_ASYN EQU 40H ;Asynchronous function started
E_BUSY EQU 41H ;Driver is busy
E_KILL EQU 42H ;Asynchronous function killed
E_SYS EQU 7EH ;Wrong filesystem type
E_UNK EQU 7FH ;Unknown error
Programs should be prepared for unknown reason codes,
substituting E_UNK for them.
As indicated by the above division, reason codes can be split
in three classes.
The first class, E_NUL to E_FMT, is disk related and usually
indicates a real hardware or software error condition. Error
codes with these reason codes may have the E_ADDR bit set,
except for E_NUL.
The second class, E_ASYN to E_KILL, is related to the
asynchronous function support of the driver. Errors with
these reason codes will never have the E_ADDR bit set,
so it is safe to compare the entire error code agains the
reason codes.
Reason codes E_ASYN or E_BUSY will only be returned if the
O_ASYN function has been used. Reason code E_KILL will only
be passed to completion routines, and only if the O_KILL
function has been used.
Reason code E_ASYN means that the requested function has been
started; the completion routine set with the previous O_ASYN
function will be called when it finishes.
Reason code E_BUSY means that the requested function could
not be performed because the driver was already busy with
some other function.
Reason code E_KILL means that the requested function was
aborted with an O_KILL function; it is only passed to
completion routines. The driver will only abort a function
if it has not yet performed irreversable actions; otherwise
it will run to completion.
The third class, E_SYS and E_UNK, is miscellaneous. Error
codes with these reason codes may have the E_ADDR bit set.
Format description
-----------------
A format description describes the physical format of a disk
track. It is currently limited to floppy-like disks.
XXX
T_gap4 EQU 0 ;Pre-index gap length
T_gap1 EQU 1 ;Post-index gap length
T_gap2 EQU 2 ;Identification gap length
T_gap3 EQU 3 ;Data gap length
T_ssiz EQU 4 ;Sector size code (FS_*)
T_sdat EQU 5 ;Initial sector data
T_secs EQU 6 ;Number of sectors
T_res1 EQU 7 ;Reserved
T_SIZE EQU 8
XXX
T_UNSP EQU 255 ;Unspecified parameter
;Sector ID info
FI_cyl EQU 0 ;ID cylinder
FI_sid EQU 1 ;ID side
FI_rec EQU 2 ;ID record
FI_siz EQU 3 ;ID size
FI_SIZE EQU 4
;FI_siz codes
FS_128 EQU 00H
FS_256 EQU 01H
FS_512 EQU 02H
FS_1K EQU 03H
FS_2K EQU 04H
FS_4K EQU 05H
Track image
-----------
A track image starts with a one byte code that identifies the
encoding used for the image. The possible codes are
TI_RAW EQU 0 ;Raw disk bits
TI_WDS EQU 1 ;Western Digital 179X SD
TI_WDD EQU 2 ;Western Digital 179X DD
TI_NONE EQU 255 ;No image
After the encoding byte comes the actual image, or none
if the code is TI_NONE.
Device kind descriptors
-----------------------
A device kind description describes a device. It includes
the class of the device: disk, terminal, etc. The only
class described in this document is K_DISK; others may be
added and will be described in other documents. They should
still include the K_size, K_class, K_link and K_name fields,
at the same offsets.
A device kind description consists of a header block, which
contains pointers to the variable length parts of the
description. Kind descriptions are generally available in two
forms: a position-independent form with origin zero, so that
all the pointers in effect become offsets, and a relocatable
form suitable for linking to other object files. The second
form should still be position-independent except for
the pointers in the header.
Descriptions with class K_DISK are descriptions of disk formats,
containing all the information needed by a CP/M BIOS and BDOS
to access that disk, in addition to some other information.
The header block has the following format for K_DISK desc
K_size EQU 0 ;Size (16-bit)
K_clas EQU 2 ;Class (8-bit)
K_link EQU 3 ;Link count (8-bit)
K_fsys EQU 4 ;File system type (8-bit)
K_name EQU 5 ;Name (16-bit)
K_info EQU 7 ;File system information (16-bit)
K_dcap EQU 9 ;Drive capabilities (16-bit)
K_xlat EQU 11 ;Translation routine (16-bit)
K_boot EQU 13 ;Bootsector test routine (16-bit)
K_res1 EQU 15 ;Reserved (16-bit)
K_id EQU 17 ;Identity string (variable)
The meaning of the individual fields is as follows:
K_size - Size (16-bit)
This is the size of the total description; it is not a pointer.
When several descriptions are concatenated, the end of the
composite one is usually indicated by two zero bytes, indicating
a zero size.
K_clas - Class (8-bit)
This is the class of device. The only class described in this
document is K_DISK:
;K_clas values
K_DISK EQU 'd'
K_link - Link count (8-bit)
This is the number of links to this description. It should
always be zero as supplied; the field is used for internal
purposes by various operating systems.
K_fsys - File system type (8-bit)
This is the kind of file system on the disk. Possible kinds
include K_CPM and K_DOS; currently only K_CPM is supported.
;K_fsys values
K_CPM EQU 'c'
K_name - Name (16-bit)
This is a pointer to the name of the device description. The
name should satisfy the requirements of a volume name, i.e.,
at most 14 letters, digits or underscores, preferably upper
case only.
K_info - File system information (16-bit)
This is a pointer to file system specific information describing
the default disk format. For K_fsys equal to K_CPM, this is a
standard CP/M Disk Parameter Block (DPB). The pointer may be
null, if no default format is to be supplied.
K_dcap - Drive capabilities (16-bit)
This is a pointer to a drive capability description that
summarizes the kinds of addresses that can be produced by the
K_xlat routine described below. It consists of an address
type and flag bits.
K_xlat - Translation routine (16-bit)
;Translation routine [AF,BC,DE,HL]
;
;Entry: HL= translation routine
; IX= logical address
; IY= physical address
;
;Exit: A= error code
This routine is used to translate logical disk addresses
to to physical disk addresses. It should be position-
independent.
For K_fsys equal to CP/M, the logical address is a CP/M
logical disk address of L_SIZE bytes.
The physical address is P_SIZE bytes; the P_leng and P_part
fields must be filled in. Unused bits and bytes should be
zeroed.
If the error code is nonzero, it will usually have the E_ADDR
bit set.
K_boot - Bootsector test routine (16-bit)
;Bootsector test routine [AF,BC,DE,HL}
;
;Entry: HL= bootsector test routine
; DE= bootsector buffer pointer
; ( IX= kind descriptor ) UNDOCUMENTED FEATURE
; IY= physical address buffer (P_LENG bytes)
;
;Exit: A= error code
; HL= filesystem information (may be null)
; DE= disk name (may be null)
This optional routine is used to test if a boot sector is
for a disk of this kind. The physical address of the boot
sector is passed in IY; only the first P_LENG bytes are
valid. The P_leng field can be zero if the length of the
boot sector is not known. The buffer can be assumed to be
at least 1024 bytes.
The routine should determine if the boot sector is of this
kind. The error code should be E_NUL if it is, nonzero
otherwise. Standard DJOE boot sectors need not be recognized
by it; the routine will not be called for them anyway. This
routine exists to allow automatic recognition of exotic
disk formats whenever feasable.
The routine should try to determine file system information
and disk name and return the relevant pointers; these may
each be null, point into the sector buffer or to a static
area in the kind descriptor, since the objects they point
to will immediately be copied.
Note that file system information is required for any disk
kind; if no default is specified in K_fsys, it should be
returned by this routine, otherwise the disk will not be
accessible.
If no disk name is returned by this routine, the disk will
usually be named after the name of the drive it is in.
K_res1 - Reserved (16-bit)
Reserved for future use, should be set to zero.
K_id - Identity string (variable)
This is a nul-terminated identity string of the form
"@(#) KIND dd/mm/yy"
where KIND is the same as given by K_name. It is not currently
used by any software, but is very useful to allow extraction of
the names of contained kind descriptions from an image with the
WHAT program.