forked from MirrorRepos/RomWBW
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1311 lines
47 KiB
1311 lines
47 KiB
.bp 13
|
|
.tc 6.6 The BIOS Entry Points
|
|
.he CP/M Operating System Manual 6.6 BIOS Entry Points
|
|
.sh
|
|
6.6 The BIOS Entry Points
|
|
.qs
|
|
.pp 5
|
|
The entry points into the BIOS from the cold start loader and
|
|
BDOS are detailed below. Entry to the BIOS is through a jump
|
|
vector located at 4A00H+b, as shown below. See Appendixes A and
|
|
B. The jump vector is a sequence of 17 jump
|
|
instructions that send program control to the individual BIOS
|
|
subroutines. The BIOS subroutines might be empty for certain
|
|
functions (they might contain a single RET operation)
|
|
during reconfiguration of CP/M, but the entries must be present
|
|
in the jump vector.
|
|
.pp
|
|
The jump vector at 4A00H+b takes the form shown below, where the
|
|
individual jump addresses are given to the left:
|
|
.mb 4
|
|
.fm 1
|
|
.mt 4
|
|
.hm 1
|
|
.sp 2
|
|
.nf
|
|
.in 5
|
|
4A00H+b JMP BOOT ;ARRIVE HERE FROM COLD
|
|
START LOAD
|
|
.sp
|
|
4A03H+b JMP WBOOT ;ARRIVE HERE FOR WARM START
|
|
|
|
4A06H+b JMP CONST ;CHECK FOR CONSOLE CHAR
|
|
READY
|
|
|
|
4A09H+b JMP CONIN ;READ CONSOLE CHARACTER IN
|
|
|
|
4A0CH+b JMP CONOUT ;WRITE CONSOLE CHARACTER
|
|
OUT
|
|
|
|
4A0FH+b JMP LIST ;WRITE LISTING CHARACTER OUT
|
|
|
|
4A12H+b JMP PUNCH ;WRITE CHARACTER TO PUNCH
|
|
DEVICE
|
|
|
|
4A15H+b JMP READER ;READ READER DEVICE
|
|
|
|
4A18H+b JMP HOME ;MOVE TO TRACK 00 ON
|
|
SELECTED DISK
|
|
|
|
4A1BH+b JMP SELDSK ;SELECT DISK DRIVE
|
|
|
|
4A1EH+b JMP SETTRK ;SET TRACK NUMBER
|
|
|
|
4A21H+b JMP SETSEC ;SET SECTOR NUMBER
|
|
|
|
4A24H+b JMP SETDMA ;SET DMA ADDRESS
|
|
|
|
4A27H+b JMP READ ;READ SELECTED SECTOR
|
|
|
|
4A2AH+b JMP WRITE ;WRITE SELECTED SECTOR
|
|
|
|
4A2DH+b JMP LISTST ;RETURN LIST STATUS
|
|
|
|
4A30H+b JMP SECTRAN ;SECTOR TRANSLATE
|
|
SUBROUTINE
|
|
.fi
|
|
.in 0
|
|
.sp 2
|
|
.sh
|
|
Listing 6-2. BIOS Entry Points
|
|
.pp
|
|
Each jump address corresponds to a particular subroutine that performs the
|
|
specific function, as outlined below. There are three major
|
|
divisions in the jump table: the system reinitialization,
|
|
which results from calls on BOOT and WBOOT; simple character I/O,
|
|
performed by calls on CONST, CONIN, CONOUT, LIST, PUNCH, READER,
|
|
and LISTST; and disk I/O, performed by calls on HOME, SELDSK,
|
|
SETTRK, SETSEC, SETDMA, READ, WRITE, and SECTRAN.
|
|
.pp
|
|
All simple character I/O operations are assumed to be performed
|
|
in ASCII, upper- and lower-case, with high-order (parity bit) set
|
|
to zero. An end-of-file condition for an input device is given
|
|
by an ASCII CTRL-Z (1AH). Peripheral devices are seen by CP/M as
|
|
logical devices and are assigned to physical devices within the
|
|
BIOS.
|
|
.pp
|
|
To operate, the BDOS needs only the CONST, CONIN, and CONOUT
|
|
subroutines. LIST, PUNCH, and READER can be used by PIP, but not
|
|
the BDOS. Further, the LISTST entry is currently used only by
|
|
DESPOOL, the print spooling utility. Thus, the initial version
|
|
of CBIOS can have empty subroutines for the remaining ASCII
|
|
devices.
|
|
.pp
|
|
The following list describes the characteristics of each device.
|
|
.sp 2
|
|
.in 5
|
|
.ti -2
|
|
o CONSOLE is the principal interactive console that communicates with the
|
|
operator and it is accessed through CONST, CONIN, and CONOUT. Typically, the
|
|
CONSOLE is a device such as a CRT or teletype.
|
|
.sp
|
|
.ti -2
|
|
o LIST is the principal listing device. If it exists on the user's system,
|
|
it is usually a hard-copy device, such as a printer or teletype.
|
|
.sp
|
|
.ti -2
|
|
o PUNCH is the principal tape punching device. If it exists, it is normally a
|
|
high-speed paper tape punch or teletype.
|
|
.sp
|
|
.ti -2
|
|
o READER is the principal tape reading device, such as a simple optical
|
|
reader or teletype.
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
.pp
|
|
A single peripheral can be assigned as the LIST, PUNCH, and
|
|
READER device simultaneously. If no peripheral device is
|
|
assigned as the LIST, PUNCH, or READER device, the CBIOS
|
|
gives an appropriate error message so that the
|
|
system does not hang if the device is accessed by PIP or some
|
|
other user program. Alternately, the PUNCH and LIST routines can
|
|
just simply return, and the READER routine can return with a 1AH
|
|
(CTRL-Z) in register A to indicate immediate end-of-file.
|
|
.pp
|
|
For added flexibility, you can optionally implement the
|
|
IOBYTE function, which allows reassignment of physical devices.
|
|
The IOBYTE function creates a mapping of logical-to-physical
|
|
devices that can be altered during CP/M processing,
|
|
see the STAT command in Section 1.6.1.
|
|
.pp
|
|
The definition of the IOBYTE function corresponds to the Intel
|
|
standard as follows: a single location in memory, currently
|
|
location 0003H, is maintained, called IOBYTE, which defines the
|
|
logical-to-physical device mapping that is in effect at a
|
|
particular time. The mapping is performed by splitting the
|
|
IOBYTE into four distinct fields of two bits each, called the
|
|
CONSOLE, READER, PUNCH, and LIST fields, as shown in the
|
|
following figure.
|
|
.sp 2
|
|
.nf
|
|
most significant least significant
|
|
.sp
|
|
IOBYTE AT 003H LIST PUNCH READER CONSOLE
|
|
.sp
|
|
bits 6,7 bits 4,5 bits 2,3 bits 0,1
|
|
.fi
|
|
.sp 2
|
|
.sh
|
|
Figure 6-1. IOBYTE Fields
|
|
.sp 2
|
|
.pp
|
|
The value in each field can be in the range 0-3, defining the
|
|
assigned source or destination of each logical device. Table 6-4
|
|
gives the values that can be assigned to each field.
|
|
.sp 2
|
|
.sh
|
|
.nf
|
|
Table 6-4. IOBYTE Field Values
|
|
.sp
|
|
Value Meaning
|
|
.sp
|
|
CONSOLE field (bits 0,1)
|
|
.sp
|
|
0 console is assigned to the console printer
|
|
device (TTY:)
|
|
1 console is assigned to the CRT device (CRT:)
|
|
2 batch mode: use the READER as the CONSOLE input,
|
|
and the LIST device as the CONSOLE output (BAT:)
|
|
3 user-defined console device (UC1:)
|
|
.sp
|
|
.mb 4
|
|
.fm 1
|
|
.mt 4
|
|
.hm 1
|
|
READER field (bits 2,3)
|
|
.sp
|
|
0 READER is the teletype device (TTY:)
|
|
1 READER is the high speed reader device (PTR:)
|
|
2 user-defined reader #1 (UR1:)
|
|
3 user-defined reader #2 (UR2:)
|
|
.sp
|
|
PUNCH field (bits 4,5)
|
|
.sp
|
|
0 PUNCH is the teletype device (TTY:)
|
|
1 PUNCH is the high speed punch device (PTP:)
|
|
2 user-defined punch #1 (UP1:)
|
|
3 user-defined punch #2 (UP2:)
|
|
.sp
|
|
LIST field (bits 6,7)
|
|
.sp
|
|
0 LIST is the teletype device (TTY:)
|
|
1 LIST is the CRT device (CRT:)
|
|
2 LIST is the line printer device (LPT:)
|
|
3 user-defined list device (UL1:)
|
|
.fi
|
|
.bp
|
|
.pp
|
|
The implementation of the IOBYTE is optional and effects only the
|
|
organization of the CBIOS. No CP/M systems use the IOBYTE
|
|
(although they tolerate the existence of the IOBYTE at location
|
|
0003H) except for PIP, which allows access to the physical
|
|
devices, and STAT, which allows logical-physical assignments to
|
|
be make or displayed. For more information see Section 1. In
|
|
any case the IOBYTE implementation should be omitted until the
|
|
basic CBIOS is fully implemented and tested; then you should
|
|
add the IOBYTE to increase the facilities.
|
|
.mb 6
|
|
.fm 2
|
|
.mt 5
|
|
.hm 2
|
|
.pp
|
|
Disk I/O is always performed through a sequence of calls on the
|
|
various disk access subroutines that set up the disk number to
|
|
access, the track and sector on a particular disk, and the Direct
|
|
Memory Access (DMA) address involved in the I/O operation. After
|
|
all these parameters have been set up, a call is made to the READ
|
|
or WRITE function to perform the actual I/O operation.
|
|
.pp
|
|
There is often a single call to SELDSK to select a disk drive,
|
|
followed by a number of read or write operations to the selected
|
|
disk before selecting another drive for subsequent operations.
|
|
Similarly, there might be a single call to set the DMA address,
|
|
followed by several calls that read or write from the selected
|
|
DMA address before the DMA address is changed. The track and
|
|
sector subroutines are always called before the READ or WRITE
|
|
operations are performed.
|
|
.pp
|
|
The READ and WRITE routines should perform several retries (10 is
|
|
standard) before reporting the error condition to the BDOS. If
|
|
the error condition is returned to the BDOS, it reports the
|
|
error to the user. The HOME subroutine might or might not actually
|
|
perform the track 00 seek, depending upon controller
|
|
characteristics; the important point is that track 00 has been
|
|
selected for the next operation and is often treated in exactly
|
|
the same manner as SETTRK with a parameter of 00.
|
|
.pp
|
|
The following table describes the exact responsibilities of each
|
|
BIOS entry point subroutine.
|
|
.sp 2
|
|
.sh
|
|
Table 6-5. BIOS Entry Points
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.ll 60
|
|
.in 15
|
|
.ti -9
|
|
BOOT The BOOT entry point gets control from the cold start loader and is
|
|
responsible for basic system initialization, including sending a sign-on
|
|
message, which can be omitted in the first version. If the IOBYTE function
|
|
is implemented, it must be set at this point. The various system parameters
|
|
that are set by the WBOOT entry point must be initialized, and control is
|
|
transferred to the CCP at 3400+b for further processing. Note that register
|
|
C must be set to zero to select drive A.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-5. (continued)
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.in 15
|
|
.ti -9
|
|
WBOOT The WBOOT entry point gets control when a warm start occurs. A warm
|
|
start is performed whenever a user program branches to location 0000H, or
|
|
when the CPU is reset from the front panel. The CP/M system must be loaded
|
|
from the first two tracks of drive A up to, but not including, the BIOS, or
|
|
CBIOS, if the user has completed the patch. System parameters must be
|
|
initialized as follows:
|
|
.sp
|
|
.in 32
|
|
.ti -17
|
|
location 0,1,2 Set to JMP WBOOT for warm starts (000H: JMP 4A03H+b)
|
|
.sp
|
|
.ti -17
|
|
location 3 Set initial value of IOBYTE, if implemented in the CBIOS
|
|
.sp
|
|
.ti -17
|
|
location 4 High nibble = current user no; low nibble = current drive
|
|
.sp
|
|
.ti -17
|
|
location 5,6,7 Set to JMP BDOS, which is the primary entry point to CP/M for
|
|
transient programs. (0005H: JMP 3C06H+b)
|
|
.sp
|
|
.in 15
|
|
Refer to Section 6.9 for complete details of page zero use.
|
|
Upon completion of the initialization, the WBOOT program must branch to the
|
|
CCP at 3400H+b to restart the system. Upon entry to the CCP, register C is
|
|
set to the drive to select after system initialization. The WBOOT routine
|
|
should read location 4 in memory, verify that is a legal drive, and pass it
|
|
to the CCP in register C.
|
|
.sp
|
|
.ti -9
|
|
CONST You should sample the status of the currently assigned console
|
|
device and return 0FFH in register A if a character is ready to read and 00H
|
|
in register A if no console characters are ready.
|
|
.sp
|
|
.ti -9
|
|
CONIN The next console character is read into register A, and the parity
|
|
bit is set, high-order bit, to zero. If no console character is ready,
|
|
wait until a character is typed before returning.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-5. (continued)
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.in 15
|
|
.ti -9
|
|
CONOUT The character is sent from register C to the console
|
|
output device. The character is in ASCII, with high-order parity
|
|
bit set to zero. You might want to include a time-out on a
|
|
line-feed or carriage return, if the console device requires some
|
|
time interval at the end of the line (such as a TI Silent 700
|
|
terminal). You can filter out control characters that cause
|
|
the console device to react in a strange way (CTRL-Z causes the
|
|
Lear-Seigler terminal to clear the screen, for example).
|
|
.sp
|
|
.ti -9
|
|
LIST The character is sent from register C to the currently
|
|
assigned listing device. The character is in ASCII with zero
|
|
parity bit.
|
|
.sp
|
|
.ti -9
|
|
PUNCH The character is sent from register C to the currently
|
|
assigned punch device. The character is in ASCII with zero
|
|
parity.
|
|
.sp
|
|
.ti -9
|
|
READER The next character is read from the currently assigned reader
|
|
device into register A with zero parity (high-order bit must be
|
|
zero); an end-of-file condition is reported by returning an ASCII
|
|
CTRL-Z(1AH).
|
|
.sp
|
|
.ti -9
|
|
HOME The disk head of the currently selected disk
|
|
(initially disk A) is moved to the track 00 position. If the controller
|
|
allows access to the track 0 flag from the drive, the head is
|
|
stepped until the track 0 flag is detected. If the controller
|
|
does not support this feature, the HOME
|
|
call is translated into a call to SETTRK with a parameter of 0.
|
|
.sp
|
|
.ti -9
|
|
SELDSK The disk drive given by register C is selected for further
|
|
operations, where register C contains 0 for drive A, 1 for drive B, and so
|
|
on up to 15 for drive P (the standard CP/M distribution version supports four
|
|
drives). On each disk select, SELDSK must return in HL the base address of a
|
|
16-byte area, called the Disk Parameter Header, described in Section 6.10.
|
|
For standard floppy disk drives, the contents of the header and associated
|
|
tables do not change; thus, the program segment included in the sample CBIOS
|
|
performs this operation automatically.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-5. (continued)
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.in 15
|
|
If there is an attempt to select a
|
|
nonexistent drive, SELDSK returns HL=0000H as an error indicator.
|
|
Although SELDSK must return the header address on each call, it is advisable
|
|
to postpone the physical disk select operation until an I/O function (seek,
|
|
read, or write) is actually performed, because disk selects often occur
|
|
without utimately performing any disk I/O, and many controllers unload
|
|
the head of the current disk before selecting the new drive. This
|
|
causes an excessive amount of noise and disk wear. The least significant bit
|
|
of register E is zero if this is the first occurrence of the drive select
|
|
since the last cold or warm start.
|
|
.sp
|
|
.ti -9
|
|
SETTRK Register BC contains the track number for subsequent disk accesses
|
|
on the currently selected drive. The sector number in BC is the same as the
|
|
number returned from the SECTRAN entry point. You can choose to seek
|
|
the selected track at this time or delay the seek until the next read or
|
|
write actually occurs. Register BC can take on values in the range 0-76
|
|
corresponding to valid track numbers for standard floppy disk drives and
|
|
0-65535 for nonstandard disk subsystems.
|
|
.sp
|
|
.ti -9
|
|
SETSEC Register BC contains the sector number, 1 through 26, for subsequent
|
|
disk accesses on the currently selected drive. The sector number in BC is
|
|
the same as the number returned from the SECTRAN entry point. You can
|
|
choose to send this information to the controller at this point or delay
|
|
sector selection until a read or write operation occurs.
|
|
.mb 4
|
|
.fm 1
|
|
.sp
|
|
.ti -9
|
|
SETDMA Register BC contains the DMA (Disk Memory Access) address for
|
|
subsequent read or write operations. For example, if B = 00H and C = 80H
|
|
when SETDMA is called, all subsequent read operations read their data into
|
|
80H through 0FFH and all subsequent write operations get their
|
|
data from 80H through 0FFH, until the next call
|
|
to SETDMA occurs. The initial DMA address is
|
|
assumed to be 80H. The controller need not
|
|
actually support Direct Memory Access. If,
|
|
for example, all data transfers are through I/O
|
|
ports, the CBIOS that is constructed uses
|
|
the 128-byte area starting at the selected DMA
|
|
address for the memory buffer during the
|
|
subsequent read or write operations.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-5. (continued)
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.in 15
|
|
.ti -9
|
|
READ Assuming the drive has been selected, the track
|
|
has been set, and the DMA address has been
|
|
specified, the READ subroutine attempts to
|
|
read one sector based upon these parameters
|
|
and returns the following error codes in
|
|
register A:
|
|
.sp
|
|
0 no errors occurred
|
|
.sp
|
|
1 nonrecoverable error condition occurred
|
|
.sp
|
|
Currently, CP/M responds only to a zero or nonzero
|
|
value as the return code. That is, if the
|
|
value in register A is 0, CP/M assumes that the
|
|
disk operation was completed properly. IF an
|
|
error occurs the CBIOS should attempt
|
|
at least 10 retries to see if the error is
|
|
recoverable. When an error is reported the BDOS
|
|
prints the message BDOS ERR ONx: BAD
|
|
SECTOR. The operator then has the option of
|
|
pressing a carriage return to ignore the error, or
|
|
CTRL-C to abort.
|
|
.sp
|
|
.ti -9
|
|
WRITE Data is written from the currently
|
|
selected DMA address to the currently selected
|
|
drive, track, and sector. For floppy disks, the
|
|
data should be marked as nondeleted data to
|
|
maintain compatibility with other CP/M systems.
|
|
The error codes given in the READ command are
|
|
returned in register A, with error recovery
|
|
attempts as described above.
|
|
.mb 6
|
|
.fm 2
|
|
.sp
|
|
.ti -9
|
|
LISTST You return the ready status of the list
|
|
device used by the DESPOOL program to improve
|
|
console response during its operation. The
|
|
value 00 is returned in A if the list device is
|
|
not ready to accept a character and 0FFH if a
|
|
character can be sent to the printer. A 00
|
|
value should be returned if LIST status is not
|
|
implemented.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-5. (continued)
|
|
.sp
|
|
Entry Point Function
|
|
.sp
|
|
.in 15
|
|
.ti -9
|
|
SECTRAN Logical-to-physical sector
|
|
translation is performed to improve the overall response of
|
|
CP/M. Standard CP/M systems are shipped with a
|
|
skew factor of 6, where six physical sectors are
|
|
skipped between each logical read operation.
|
|
This skew factor allows enough time between
|
|
sectors for most programs to load their buffers
|
|
without missing the next sector. In particular
|
|
computer systems that use fast processors,
|
|
memory, and disk subsystems, the skew factor might
|
|
be changed to improve overall response.
|
|
However, the user should maintain a single-density
|
|
IBM-compatible version of CP/M for
|
|
information transfer into and out of the
|
|
computer system, using a skew factor of 6.
|
|
.sp
|
|
In general, SECTRAN receives a logical sector
|
|
number relative to zero in BC and a translate
|
|
table address in DE. The sector number is used
|
|
as an index into the translate table, with the
|
|
resulting physical sector number
|
|
in HL. For standard systems, the table and
|
|
indexing code is provided in the CBIOS and
|
|
need not be changed.
|
|
.in 0
|
|
.ll 65
|
|
.sp 2
|
|
.tc 6.7 A Sample BIOS
|
|
.he CP/M Operating System Manual 6.7 A Sample BIOS
|
|
.sh
|
|
6.7 A Sample BIOS
|
|
.qs
|
|
.pp
|
|
The program shown in Appendix B can serve as a basis for your
|
|
first BIOS. The simplest functions are assumed in this BIOS, so
|
|
that you can enter it through a front panel, if absolutely
|
|
necessary. You must alter and insert code into the
|
|
subroutines for CONST, CONIN, CONOUT, READ, WRITE, and WAITIO
|
|
subroutines. Storage is reserved for user-supplied code in these
|
|
regions. The scratch area reserved in page zero (see Section
|
|
6.9) for the BIOS is used in this program, so that it could be
|
|
implemented in ROM, if desired.
|
|
.pp
|
|
Once operational, this skeletal version can be enhanced to print
|
|
the initial sign-on message and perform better error recovery.
|
|
The subroutines for LIST, PUNCH, and READER can be filled out and
|
|
the IOBYTE function can be implemented.
|
|
.sp 2
|
|
.tc 6.8 A Sample Cold Start Loader
|
|
.he CP/M Operating System Manual 6.8 A Sample Cold Start Loader
|
|
.sh
|
|
6.8 A Sample Cold Start Loader
|
|
.qs
|
|
.pp
|
|
The program shown in Appendix E can serve as a basis for a cold
|
|
start loader. The disk read function must be supplied by the
|
|
user, and the program must be loaded somehow starting at location
|
|
0000. Space is reserved for the patch code so that the total
|
|
amount of storage required for the cold start loader is 128
|
|
bytes.
|
|
.pp
|
|
Eventually, you might want to get this
|
|
loader onto the first disk sector (track 0, sector 1) and cause
|
|
the controller to load it into memory automatically upon system
|
|
start up. Alternatively, the cold start loader can be placed
|
|
into ROM, and above the CP/M system. In this case, it is
|
|
necessary to originate the program at a higher address and key in
|
|
a jump instruction at system start up that branches to the
|
|
loader. Subsequent warm starts do not require this key-in
|
|
operation, because the entry point WBOOT gets control, thus bringing
|
|
the system in from disk automatically. The skeletal cold start
|
|
loader has minimal error recovery, which might be enhanced in later
|
|
versions.
|
|
.sp 2
|
|
.tc 6.9 Reserved Locations in Page Zero
|
|
.he CP/M Operating System Manual 6.9 Reserved Locations in Page Zero
|
|
.sh
|
|
6.9 Reserved Locations in Page Zero
|
|
.qs
|
|
.pp
|
|
Main memory page zero, between locations 00H and 0FFH, contains
|
|
several segments of code and data that are used during CP/M
|
|
processing. The code and data areas are given in the following table.
|
|
.sp 2
|
|
.sh
|
|
Table 6-6. Reserved Locations in Page Zero
|
|
.sp
|
|
.nf
|
|
Locations Contents
|
|
.fi
|
|
.sp
|
|
.ll 60
|
|
.in 22
|
|
.ti -17
|
|
000H-0002H Contains a jump instruction to the warm start entry location
|
|
4A03H+b. This allows a simple programmed restart (JMP 0000H) or manual
|
|
restart from the front panel.
|
|
.sp
|
|
.ti -17
|
|
0003H-0003H Contains the Intel standard IOBYTE is optionally
|
|
included in the user's CBIOS (refer to Section 6.6).
|
|
.sp
|
|
.ti -17
|
|
0004H-0004H Current default drive number (0=A,...,15=P).
|
|
.sp
|
|
.ti -17
|
|
0005H-0007H Contains a jump instruction to the BDOS and serves two
|
|
purposes: JMP 0005H provides the primary entry point to the BDOS, as
|
|
described in Chapter 5, and LHLD 0006H brings the address field of the
|
|
instruction to the HL register pair. This value is the lowest address in
|
|
memory used by CP/M, assuming the CCP is being overlaid. The DDT program
|
|
changes the address field to reflect the reduced memory size in debug mode.
|
|
.sp
|
|
.ti -17
|
|
0008H-0027H Interrupt locations 1 through 5 not used.
|
|
.sp
|
|
.ti -17
|
|
0030H-0037H Interrupt location 6 (not currently used) is reserved.
|
|
.in 0
|
|
.bp
|
|
.sh
|
|
Table 6-6. (continued)
|
|
.sp
|
|
.nf
|
|
Locations Contents
|
|
.fi
|
|
.sp
|
|
.in 22
|
|
.ti -17
|
|
0038H-003AH Restart 7; contains a jump instruction into the DDT or SID
|
|
program when running in debug mode for programmed breakpoints, but is not
|
|
otherwise used by CP/M.
|
|
.sp
|
|
.ti -17
|
|
003BH-003FH Not currently used; reserved.
|
|
.sp
|
|
.ti -17
|
|
0040H-004FH A 16-byte area reserved for scratch by CBIOS, but is not
|
|
used for any purpose in the distribution version of CP/M.
|
|
.sp
|
|
.ti -17
|
|
0050H-005BH Not currently used; reserved.
|
|
.sp
|
|
.ti -17
|
|
005CH-007CH Default File Control Block produced for a transient
|
|
program by the CCP.
|
|
.sp
|
|
.ti -17
|
|
007DH-007FH Optional default random record position.
|
|
.sp
|
|
.ti -17
|
|
0080H-00FFH Default 128-byte disk buffer, also filled with the
|
|
command line when a transient is loaded under the CCP.
|
|
.in 0
|
|
.ll 65
|
|
.mb 4
|
|
.fm 1
|
|
.sp
|
|
.pp
|
|
This information is set up for normal operation under the CP/M
|
|
system, but can be overwritten by a transient program if the BDOS
|
|
facilities are not required by the transient.
|
|
.pp
|
|
If, for example, a particular program performs only simple I/O
|
|
and must begin execution at location 0, it can first be loaded
|
|
into the TPA, using normal CP/M facilities, with a small memory
|
|
move program that gets control when loaded. The memory move
|
|
program must get control from location 0100H, which is the
|
|
assumed beginning of all transient programs. The move program can
|
|
then proceed to the entire memory image down to location 0 and
|
|
pass control to the starting address of the memory load.
|
|
.pp
|
|
If the BIOS is overwritten or if location 0, containing the warm
|
|
start entry point, is overwritten, the operator must bring the
|
|
CP/M system back into memory with a cold start sequence.
|
|
.sp 2
|
|
.tc 6.10 Disk Parameter Tables
|
|
.he CP/M Operating System Manual 6.10 Disk Parameter Tables
|
|
.sh
|
|
6.10 Disk Parameter Tables
|
|
.qs
|
|
.pp
|
|
Tables are included in the BIOS that describe the particular
|
|
characteristics of the disk subsystem used with CP/M. These
|
|
tables can be either hand-coded, as shown in the sample CBIOS in
|
|
Appendix B, or automatically generated using the DISKDEF macro
|
|
library, as shown in Appendix F. The purpose here is to describe
|
|
the elements of these tables.
|
|
.bp
|
|
.pp
|
|
In general, each disk drive has an associated (16-byte) disk
|
|
parameter header that contains information about the disk drive
|
|
and provides a scratch pad area for certain BDOS operations. The
|
|
format of the disk parameter header for each drive is shown
|
|
in Figure 6-2, where each element is a word (16-bit) value.
|
|
.mb 6
|
|
.fm 2
|
|
.sp 3
|
|
.nf
|
|
XLT 0000 0000 0000 DIRBUF DPB CSV ALV
|
|
16b 16b 16b 16b 16b 16b 16b 16b
|
|
.fi
|
|
.sp 2
|
|
.sh
|
|
Figure 6-2. Disk Parameter Header Format
|
|
.sp 2
|
|
.pp
|
|
The meaning of each Disk Parameter Header (DPH) element is detailed in Table
|
|
6-7.
|
|
.sp 2
|
|
.sh
|
|
Table 6-7. Disk Parameter Headers
|
|
.sp
|
|
.nf
|
|
Disk Parameter Meaning
|
|
Header
|
|
.fi
|
|
.ll 60
|
|
.sp
|
|
.in 20
|
|
.ti -14
|
|
XLT Address of the logical-to-physical translation vector, if used
|
|
for this particular drive, or the value 0000H if no sector translation
|
|
takes place (that is, the physical and logical sector numbers are the same).
|
|
Disk drives with identical sector skew factors share the same translate tables.
|
|
.sp
|
|
.ti -14
|
|
0000 Scratch pad values for use within the BDOS, initial value is
|
|
unimportant.
|
|
.sp
|
|
.ti -14
|
|
DIRBUF Address of a 128-byte scratch pad area for directory operations
|
|
within BDOS. All DPHs address the same scratch pad area.
|
|
.sp
|
|
.ti -14
|
|
DPB Address of a disk parameter block for this drive. Drives with
|
|
identical disk characteristics address the same disk parameter block.
|
|
.sp
|
|
.ti -14
|
|
CSV Address of a scratch pad area used for software check for
|
|
changed disks. This address is different for each DPH.
|
|
.sp
|
|
.ti -14
|
|
ALV Address of a scratch pad area used by the BDOS to keep disk
|
|
storage allocation information. This address is different for each DPH.
|
|
.fi
|
|
.in 0
|
|
.ll 65
|
|
.bp
|
|
.pp
|
|
Given n disk drives, the DPHs are arranged in a table whose first row of 16
|
|
bytes corresponds to drive 0, with the last row corresponding to drive n-1.
|
|
In the following figure the lable DPBASE defines the base address of the DPH
|
|
table.
|
|
.sp 3
|
|
.nf
|
|
DPBASE:
|
|
.sp
|
|
00 XLT 00 0000 0000 0000 DIRBUF DBP 00 CSV 00 ALV 00
|
|
.sp
|
|
01 XLT 01 0000 0000 0000 DIRBUF DBP 01 CSV 01 ALV 01
|
|
.
|
|
.
|
|
.
|
|
n-1 XLTn-1 0000 0000 0000 DIRBUF DBTn-1 CSVn-1 ALVn-1
|
|
.fi
|
|
.sp 2
|
|
.sh
|
|
Figure 6-3. Disk Parameter Header Table
|
|
.sp 2
|
|
.pp
|
|
A responsibility of the SELDSK subroutine is to return the base address of
|
|
the DPH for the selected drive. The following sequence of operations returns
|
|
the table address, with a 0000H returned if the selected drive does not exist.
|
|
.sp 2
|
|
.nf
|
|
.in 7
|
|
NDISKS EQU 4 ;NUMBER OF DISK DRIVES
|
|
.....
|
|
SELDSK: ;SELECT DISK GIVEN BY BC
|
|
LSI H,0000H ;ERROR CODE
|
|
MOV A,C ;DRIVE OK?
|
|
CPI NDISKS ;CY IF SO
|
|
RNC ;RET IF ERROR
|
|
;NO ERROR, CONTINUE
|
|
MOV L,C ;LOW(DISK)
|
|
MOV H,B ;HIGH(DISK)
|
|
DAD H ;*2
|
|
DAD H ;*4
|
|
DAD H ;*8
|
|
DAD H ;*16
|
|
LXI D,DPBASE;FIRST DPH
|
|
DAD D ;DPH(DISK)
|
|
RET
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
.pp
|
|
The translation vectors, XLT 00 through XLTn-1, are located elsewhere in
|
|
the BIOS, and simply correspond one-for-one with the logical sector numbers
|
|
zero through the sector count 1. The Disk Parameter Block (DPB) for each
|
|
drive is more complex. As shown in Figure 6-4, particular DPB, that is
|
|
addressed by one or more DPHs, takes the general form:
|
|
.sp 3
|
|
.nf
|
|
SPT BSH BLM EXM DSM DRM AL0 AL1 CKS 0FF
|
|
16b 8b 8b 8b 16b 16b 8b 8b 16b 16b
|
|
.fi
|
|
.sp 2
|
|
.sh
|
|
Figure 6-4. Disk Parameter Block Format
|
|
.sp 3
|
|
where each is a byte or word value, as shown by the 8b or 16b indicator below
|
|
the field.
|
|
.pp
|
|
The following field abbreviations are used in Figure 6-4:
|
|
.sp 2
|
|
.in 5
|
|
.ti -2
|
|
o SPT is the total number of sectors per track.
|
|
.sp
|
|
.ti -2
|
|
o BSH is the data allocation block shift factor, determined by the data
|
|
block allocation size.
|
|
.sp
|
|
.ti -2
|
|
o BLM is the data allocation block mask (2[BSH-1]).
|
|
.sp
|
|
.ti -2
|
|
o EXM is the extent mask, determined by the data block allocation
|
|
size and the number of disk blocks.
|
|
.sp
|
|
.ti -2
|
|
o DSM determines the total storage capacity of the disk drive.
|
|
.sp
|
|
.ti -2
|
|
o DRM determines the total number of directory entries that can be
|
|
stored on this drive. AL0, AL1 determine reserved directory blocks.
|
|
.sp
|
|
.ti -2
|
|
o CKS is the size of the directory check vector.
|
|
.sp
|
|
.ti -2
|
|
o 0FF is the number of reserved tracks at the beginning of the
|
|
(logical) disk.
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
The values of BSH and BLM determine the data allocation size BLS,
|
|
which is not an entry in the DPB. Given that the designer has selected a
|
|
value for BLS, the values of BSH and BLM are shown Table 6-8.
|
|
.sp 2
|
|
.sh
|
|
Table 6-8. BSH and BLM Values
|
|
.nf
|
|
.sp
|
|
.in 18
|
|
BLS BSH BLM
|
|
.sp
|
|
1024 3 7
|
|
2048 4 15
|
|
4096 5 31
|
|
8192 6 63
|
|
16,384 7 127
|
|
.fi
|
|
.in 0
|
|
.sp 2
|
|
where all values are in decimal. The value of EXM depends upon both the BLS
|
|
and whether the DSM value is less than 256 or greater than 255, as shown in
|
|
Table 6-9.
|
|
.bp
|
|
.sh
|
|
Table 6-9. EXM Values
|
|
.nf
|
|
.sp
|
|
BLS EXM values
|
|
.sp
|
|
.in 18
|
|
DSM<256 DSM>255
|
|
.sp
|
|
1024 0 N/A
|
|
2048 1 0
|
|
4096 3 1
|
|
8192 7 3
|
|
16,384 15 7
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
.pp
|
|
The value of DSM is the maximum data block number supported by this
|
|
particular drive, measured in BLS units. The product (DSM+1) is the
|
|
total number of bytes held by the drive and must be within the
|
|
capacity of the physical disk, not counting the reserved operating system
|
|
tracks.
|
|
.pp
|
|
The DRM entry is the one less than the total number of directory entries
|
|
that can take on a 16-bit value. The values of AL0 and AL1, however, are
|
|
determined by DRM. The values AL0 and AL1 can together be considered a
|
|
string of 16-bits, as shown in Figure 6-5.
|
|
.sp 3
|
|
.nf
|
|
AL0 AL1
|
|
|
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
|
|
.fi
|
|
.sp 2
|
|
.sh
|
|
Figure 6-5. AL0 and AL1
|
|
.sp 2
|
|
.pp
|
|
Position 00 corresponds to the high-order bit of the byte
|
|
labeled AL0 and 15 corresponds to the low-order bit of the byte
|
|
labeled AL1. Each bit position reserves a data block for number
|
|
of directory entries, thus allowing a total of 16 data blocks to
|
|
be assigned for directory entries (bits are assigned starting at
|
|
00 and filled to the right until position 15). Each directory
|
|
entry occupies 32 bytes, resulting in the following tabulation:
|
|
.sp 2
|
|
.sh
|
|
Table 6-10. BLS Tabulation
|
|
.sp
|
|
.nf
|
|
.in 18
|
|
BLS Directory Entries
|
|
.sp
|
|
1024 32 times # bits
|
|
2048 64 times # bits
|
|
4096 128 times # bits
|
|
8192 256 times # bits
|
|
16,384 512 times # bits
|
|
.fi
|
|
.in 0
|
|
.bp
|
|
.pp
|
|
Thus, if DRM = 127 (128 directory entries) and BLS = 1024, there
|
|
are 32 directory entries per block, requiring 4 reserved blocks.
|
|
In this case, the 4 high-order bits of AL0 are set, resulting in
|
|
the values AL0 = 0F0H and AL1 = 00H.
|
|
.pp
|
|
The CKS value is determined as follows: if the disk drive media is
|
|
removable, then CKS = (DRM+1)/4, where DRM is the last directory
|
|
entry number. If the media are fixed, then set CKS = 0 (no
|
|
directory records are checked in this case).
|
|
.pp
|
|
Finally, the 0FF field determines the number of tracks that are
|
|
skipped at the beginning of the physical disk. This value is
|
|
automatically added whenever SETTRK is called and can be used as
|
|
a mechanism for skipping reserved operating system tracks or for
|
|
partitioning a large disk into smaller segmented sections.
|
|
.pp
|
|
To complete the discussion of the DPB, several DPHs can address
|
|
the same DPB if their drive characteristics are identical.
|
|
Further, the DPB can be dynamically changed when a new drive is
|
|
addressed by simply changing the pointer in the DPH; because the
|
|
BDOS copies the DPB values to a local area whenever the SELDSK
|
|
function is invoked.
|
|
.pp
|
|
Returning back to DPH for a particular drive, the two address
|
|
values CSV and ALV remain. Both addresses reference an area of
|
|
uninitialized memory following the BIOS. The areas must be
|
|
unique for each drive, and the size of each area is determined by
|
|
the values in the DPB.
|
|
.pp
|
|
The size of the area addressed by CSV is CKS bytes, which is
|
|
sufficient to hold the directory check information for this
|
|
particular drive, If CKS = (DRM+1)/4, you must reserve (DRM+1)/4
|
|
bytes for directory check use. If CKS = 0, no storage is
|
|
reserved.
|
|
.pp
|
|
The size of the area addressed by ALV is determined by the
|
|
maximum number of data blocks allowed for this particular disk
|
|
and is computed as (DSM/8)+1.
|
|
.pp
|
|
The CBIOS shown in Appendix B demonstrates an instance of these
|
|
tables for standard 8-inch, single-density drives. It might be
|
|
useful to examine this program and compare the tabular values
|
|
with the definitions given above.
|
|
.sp 2
|
|
.tc 6.11 The DISKDEF Macro Library
|
|
.he CP/M Operating System Manual 6.11 The DISKDEF Macro Library
|
|
.sh
|
|
6.11 The DISKDEF Macro Library
|
|
.qs
|
|
.pp
|
|
A macro library called DISKDEF (shown in Appendix F), greatly
|
|
simplifies the table construction process. You must have access
|
|
to the MAC macro assembler, of course, to use the DISKDEF
|
|
facility, while the macro library is included with all CP.M 2
|
|
distribution disks.
|
|
.bp
|
|
.pp
|
|
A BIOS disk definition consists of the following sequence of
|
|
macro statements:
|
|
.sp
|
|
.nf
|
|
.in 7
|
|
MACLIB DISKDEF
|
|
.....
|
|
DISKS n
|
|
DISKDEF 0,...
|
|
DISKDEF 1,...
|
|
.....
|
|
DISKDEF n-1
|
|
.....
|
|
ENDEF
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
where the MACLIB statement loads the DISKDEF.LIB file, on the
|
|
same disk as the BIOS, into MAC's internal tables. The DISKS
|
|
macro call follows, which specifies the number of drives to be
|
|
configured with the user's system, where n is an integer in the
|
|
range 1 to 16. A series of DISKDEF macro calls then follow that
|
|
define the characteristics of each logical disk, 0 through n-1,
|
|
corresponding to logical drives A through P. The DISKS and
|
|
DISKDEF macros generate the in-line fixed data tables described
|
|
in the previous section and thus must be placed in a
|
|
nonexecutable portion of the BIOS, typically directly following
|
|
the BIOS jump vector.
|
|
.pp
|
|
The remaining portion of the BIOS is defined following the
|
|
DISKDEF macros, with the ENDEF macro call immediately preceding
|
|
the END statement. The ENDEF (End of Diskdef) macro generates
|
|
the necessary uninitialized RAM areas that are located in
|
|
memory above the BIOS.
|
|
.pp
|
|
The DISKDEF macro call takes the form:
|
|
.sp
|
|
.ti 8
|
|
DISKDEF dn,fsc,lsc,[skf],bls dks,dir,cks,ofs,[0]
|
|
.sp
|
|
where
|
|
.sp
|
|
.in 5
|
|
.ti -2
|
|
o dn is the logical disk number, 0 to n-1.
|
|
.ti -2
|
|
o fsc is the first physical sector number (0 or 1).
|
|
.ti -2
|
|
o lsc is the last sector number.
|
|
.ti -2
|
|
o skf is the optional sector skew factor.
|
|
.ti -2
|
|
o bls is the data allocation block size.
|
|
.ti -2
|
|
o dks is the number of blocks on the disk.
|
|
.ti -2
|
|
o dir is the number of directory entries.
|
|
.ti -2
|
|
o cks is the number of checked directory entries.
|
|
.ti -2
|
|
o ofs is the track offset to logical track 00.
|
|
.ti -2
|
|
o [0] is an optional 1.4 compatibility flag.
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
.pp
|
|
The value dn is the drive number being defined with this DISKDEF
|
|
macro invocation. The fsc parameter accounts for differing
|
|
sector numbering systems and is usually 0 to 1. The lsc is the
|
|
last numbered sector on a track. When present, the skf parameter
|
|
defines the sector skew factor, which is used to create a sector
|
|
translation table according to the skew.
|
|
.pp
|
|
If the number of sectors is less than 256, a single-byte table is
|
|
created, otherwise each translation table element occupies two
|
|
bytes. No translation table is created if the skf parameter is
|
|
omitted, or equal to 0.
|
|
.pp
|
|
The bls parameter specifies the number of bytes allocated to each
|
|
data block, and takes on the values 1024, 2048, 4096, 8192, or
|
|
16384. Generally, performance increases with larger data block
|
|
sizes because there are fewer directory references, and logically
|
|
connected data records are physically close on the disk.
|
|
Further, each directory entry addresses more data and the BIOS-resident
|
|
RAM space is reduced.
|
|
.pp
|
|
The dks parameter specifies the total disk size in bls units.
|
|
That is, if the bls = 2048 and dks = 1000, the total disk
|
|
capacity is 2,048,000 bytes. If dks is greater than 255, the
|
|
block size parameter bls must be greater than 1024. The value of
|
|
dir is the total number of directory entries that might exceed
|
|
255, if desired.
|
|
.pp
|
|
The cks parameter determines the number of directory items to
|
|
check on each directory scan and is used internally to detect
|
|
changed disks during system operation, where an intervening cold
|
|
or warm start has not occurred. When this situation is detected,
|
|
CP/M automatically marks the disk Read-Only so that data is not
|
|
subsequently destroyed.
|
|
.pp
|
|
As stated in the previous section, the value of cks = dir when
|
|
the medium is easily changed, as is the case with a floppy disk
|
|
subsystem. If the disk is permanently mounted, the value of cks
|
|
is typically 0, because the probability of changing disks without a
|
|
restart is low.
|
|
.pp
|
|
The ofs value determines the number of tracks to skip when this
|
|
particular drive is addressed, which can be used to reserve
|
|
additional operating system space or to simulate several logical
|
|
drives on a single large capacity physical drive.
|
|
Finally, the [0] parameter is included when file compatibility is
|
|
required with versions of 1.4 that have been modified for higher
|
|
density disks. This parameter ensures that only 16K is allocated
|
|
for each directory record, as was the case for previous versions.
|
|
Normally, this parameter is not included.
|
|
.pp
|
|
For convenience and economy of table space, the special form:
|
|
.sp
|
|
.ti 8
|
|
DISKDEF i,j
|
|
.sp
|
|
gives disk i the same characteristics as a previously defined
|
|
drive j. A standard four-drive, single-density system, which is
|
|
compatible with version 1.4, is defined using the following macro
|
|
invocations:
|
|
.sp
|
|
.nf
|
|
.in 7
|
|
DISKS 4
|
|
DISKDEF 0,1,26,6,1024,243,64,2
|
|
DISKDEF 1,0
|
|
DISKDEF 2,0
|
|
DISKDEF 3,0
|
|
....
|
|
ENDEF
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
with all disks having the same parameter values of 26 sectors per
|
|
track, numbered 1 through 26, with 6 sectors skipped between each
|
|
access, 1024 bytes per data block, 243 data blocks for a total of
|
|
243K-byte disk capacity, 64 checked directory entries, and two
|
|
operating system tracks.
|
|
.pp
|
|
The DISKS macro generates n DPHs, starting at the DPH table
|
|
address DPBASE generated by the macro. Each disk header block
|
|
contains sixteen bytes, as described above, and correspond
|
|
one-for-one to each of the defined drives. In the four-drive
|
|
standard system, for example, the DISKS macro generates a table
|
|
of the form:
|
|
.sp
|
|
.nf
|
|
.in 5
|
|
DPBASE EQU$
|
|
DPE0: DW XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV0,ALV0
|
|
DPE1: DW XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV1,ALV1
|
|
DPE2: DW XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV2,ALV2
|
|
DPE3: DW XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV3,ALV3
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
where the DPH labels are included for reference purposes to show
|
|
the beginning table addresses for each drive 0 through 3. The
|
|
values contained within the DPH are described in detail in the
|
|
previous section. The check and allocation vector addresses are
|
|
generated by the ENDEF macro in the ram area following the BIOS
|
|
code and tables.
|
|
.pp
|
|
Note that if the skf (skew factor) parameter is
|
|
omitted, or equal to 0, the translation table is omitted and a
|
|
0000H value is inserted in the XLT position of the DPH for the
|
|
disk. In a subsequent call to perform the logical-to-physical
|
|
translation, SECTRAN receives a translation table address of DE =
|
|
0000H and simply returns the original logical sector from BC in
|
|
the HL register pair.
|
|
.pp
|
|
A translate table is constructed when the skf parameter is
|
|
present, and the (nonzero) table address is placed into the
|
|
corresponding DPHs. The following for example, is constructed
|
|
when the standard skew factor skf = 6 is specified in the DISKDEF
|
|
macro call:
|
|
.sp
|
|
.nf
|
|
.in 8
|
|
XLT0: DB 1,7,13,19,25,5,11,17,23,3,9,15,21
|
|
DB 2,8,14,20,26,6,12,18,24,4,10,16,22
|
|
.fi
|
|
.in 0
|
|
.pp
|
|
Following the ENDEF macro call, a number of uninitialized data
|
|
areas are defined. These data areas need not be a part of the BIOS
|
|
that is loaded upon cold start, but must be available between the
|
|
BIOS and the end of memory. The size of the uninitialized RAM
|
|
area is determined by EQU statements generated by the ENDEF macro.
|
|
For a standard four-drive system, the ENDEF macro might produce
|
|
the following EQU statement:
|
|
.bp
|
|
.nf
|
|
.in 8
|
|
4C72 = BEGDAT EQU $
|
|
(data areas)
|
|
.sp
|
|
4DB0 = ENDDAT EQU $
|
|
.sp
|
|
013C = DATSIZ EQU $-BEGDAT
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
which indicates that uninitialized RAM begins at location 4C72H,
|
|
ends at 4DB0H-1, and occupies 013CH bytes. You must ensure
|
|
that these addresses are free for use after the system is loaded.
|
|
.pp
|
|
After modification, you can use the STAT program to
|
|
check drive characteristics, because STAT uses the disk parameter
|
|
block to decode the drive information. A STAT command of the form:
|
|
.sp
|
|
.ti 8
|
|
STAT d:DSK:
|
|
.sp
|
|
decodes the disk parameter block for drive d (d=A,...,P) and
|
|
displays the following values:
|
|
.sp 2
|
|
.nf
|
|
.in 8
|
|
r: 128-byte record capacity
|
|
k: kilobyte drive capacity
|
|
d: 32-byte directory entries
|
|
c: checked directory entries
|
|
e: records/extent
|
|
b: records/block
|
|
s: sectors/track
|
|
t: reserved tracks
|
|
.fi
|
|
.in 0
|
|
.sp
|
|
.pp
|
|
Three examples of DISKDEF macro invocations are shown below with
|
|
corresponding STAT parameter values. The last example produces a full
|
|
8-megabyte system.
|
|
.sp
|
|
.nf
|
|
.in 8
|
|
DISKDEF 0,1,58,,2048,256,128,128,2
|
|
r=4096, k=512, d=128, c=128, e=256, b=16, s=58, t=2
|
|
.sp
|
|
DISKDEF 0,1,58,,2048,1024,300,0,2
|
|
r=16348, k=2048, d=300, c=0, e=128, b=16, s=58, t=2
|
|
.sp
|
|
DISKDEF 0,1,58,,16348,512,128,128,2
|
|
r=65536, k=8192, d=128, c=128, e=1024, b=128, s=58, t=2
|
|
.fi
|
|
.in 0
|
|
.sp 2
|
|
.tc 6.12 Sector Blocking and Deblocking
|
|
.he CP/M Operating System Manual 6.12 Blocking and Deblocking
|
|
.sh
|
|
6.12 Sector Blocking and Deblocking
|
|
.qs
|
|
.pp
|
|
Upon each call to BIOS WRITE entry point, the CP/M BDOS includes
|
|
information that allows effective sector blocking and deblocking
|
|
where the host disk subsystem has a sector size that is a
|
|
multiple of the basic 128-byte unit. The purpose here is to
|
|
present a general-purpose algorithm that can be included within
|
|
the BIOS and that uses the BDOS information to perform the
|
|
operations automatically.
|
|
.pp
|
|
On each call to WRITE, the BDOS provides the following
|
|
information in register C:
|
|
.sp
|
|
.nf
|
|
.in 8
|
|
0 = (normal sector write)
|
|
1 = (write to directory sector)
|
|
2 = (write to the first sector
|
|
of a new data block)
|
|
.fi
|
|
.in 0
|
|
.pp
|
|
Condition 0 occurs whenever the next write operation is into a
|
|
previously written area, such as a random mode record update;
|
|
when the write is to other than the first sector of an
|
|
unallocated block; or when the write is not into the directory
|
|
area. Condition 1 occurs when a write into the directory area is
|
|
performed. Condition 2 occurs when the first record (only) of a
|
|
newly allocated data block is written. In most cases,
|
|
application programs read or write multiple 128-byte sectors in
|
|
sequence; thus, there is little overhead involved in either
|
|
operation when blocking and deblocking records, because preread
|
|
operations can be avoided when writing records.
|
|
.pp
|
|
Appendix G lists the blocking and deblocking algorithms in
|
|
skeletal form; this file is included on your CP/M disk.
|
|
Generally, the algorithms map all CP/M sector read operations
|
|
onto the host disk through an intermediate buffer that is the
|
|
size of the host disk sector. Throughout the program, values and
|
|
variables that relate to the CP/M sector involved in a seek
|
|
operation are prefixed by sek, while those related to the host
|
|
disk system are prefixed by hst. The equate statements beginning
|
|
on line 29 of Appendix G define the mapping between CP/M and the
|
|
host system, and must be changed if other than the sample host
|
|
system is involved.
|
|
.pp
|
|
The entry points BOOT and WBOOT must contain the initialization
|
|
code starting on line 57, while the SELDSK entry point must be
|
|
augmented by the code starting on line 65. Note that although
|
|
the SELDSK entry point computes and returns the Disk Parameter
|
|
Header address, it does not physically select the host disk at
|
|
this point (it is selected later at READHST or WRITEHST).
|
|
Further, SETTRK, SETTRK, and SETMA simply store the values, but
|
|
do not take any other action at this point. SECTRAN performs a
|
|
trivial function of returning the physical sector number.
|
|
.pp
|
|
The principal entry points are READ and WRITE, starting on lines
|
|
110 and 125, respectively. These subroutines take the place of
|
|
your previous READ and WRITE operations.
|
|
.pp
|
|
The actual physical read or write takes place at either WRITEHST
|
|
or READHST, where all values have been prepared: hstdsk is the
|
|
host disk number, hsttrk is the host track number, and
|
|
hstsec is the host sector number, which
|
|
may require translation to physical sector number. You must
|
|
insert code at this point that performs the full sector read or write
|
|
into or out of the buffer at hstbuf of length hstsiz. All other mapping
|
|
functions are performed by the algorithms.
|
|
.pp
|
|
This particular algorithm was tested using an 80-megabyte hard
|
|
disk unit that was originally configured for 128-byte sectors,
|
|
producing approximately 35 megabytes of formatted storage. When
|
|
configured for 512-byte host sectors, usable storage increased to
|
|
57 megabytes, with a corresponding 400% improvement in overall
|
|
response. In this situation, there is no apparent overhead
|
|
involved in deblocking sectors, with the advantage that user
|
|
programs still maintain 128-byte sectors. This is primarily
|
|
because of the information provided by the BDOS, which eliminates
|
|
the necessity for preread operations.
|
|
.sp 2
|
|
.ce
|
|
End of Section 6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|