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.
230 lines
11 KiB
230 lines
11 KiB
NOTES on your CP/M 3.0 BIOS and ZPM3
|
|
====================================
|
|
Last updated 19/4/92
|
|
|
|
ZPM3 will work fine with your current CP/M 3.0 BIOS. This
|
|
document is not meant to tell you how to change your BIOS for
|
|
ZPM3, but rather to point out some interesting and useful facts
|
|
about the way ZPM3 uses the BIOS, and how you should configure
|
|
your BIOS.
|
|
|
|
|
|
|
|
XMOVE routine.
|
|
~~~~~~~~~~~~~~
|
|
If you have 128 byte physical sectors, or your BIOS does all the
|
|
deblocking so that it appears to the BDOS that you have 128 byte
|
|
physical sectors, XMOVE does not get used at all by ZPM3. Such
|
|
was not the case with CP/M 3.0 which would make redundant calls
|
|
to XMOVE. Make sure XMOVE is implemented and working anyhow as
|
|
applications may attempt to use it.
|
|
|
|
When the BDOS is operating in the system bank (bank 0) and it
|
|
needs to move data in the TPA bank, it switches to the TPA bank
|
|
and does an ordinary LDIR. As such, XMOVE will never get called
|
|
by the BDOS with B=C (source bank and destination bank the same).
|
|
|
|
In the CP/M 3.0 manuals, there are two differing opinions about
|
|
XMOVE as far as whether B is the source or the destination. The
|
|
truth is that C is the source and B is the destination. Anything
|
|
you see to the contrary is a misprint.
|
|
|
|
MOVE routine.
|
|
~~~~~~~~~~~~~
|
|
When CP/M 3.0 was released, it was made 8080 compatible simply
|
|
because CP/M 2.2 was 8080 compatible. I have never heard of an
|
|
8080 machine running CP/M 3.0, and it is likely that there has
|
|
never been one. Digital Research knew that the Z80 was the CPU of
|
|
choice for modern PC's, and while they wrote their code for the
|
|
8080, they recognised the Z80 with the MOVE routine (which a Z80
|
|
BIOS could implement in just three instructions).
|
|
|
|
ZPM3 uses the MOVE routine much less than CP/M 3.0 does. In fact,
|
|
the only time ZPM3 uses MOVE is with an XMOVE call directly
|
|
preceding it. If you have 128 byte physical sectors (or the BIOS
|
|
does the sector deblocking), MOVE will never get called.
|
|
|
|
Always remember that MOVE must return with HL and DE pointing to
|
|
the end of the moved data. If they don't, you will have trouble.
|
|
|
|
|
|
TIME routine.
|
|
~~~~~~~~~~~~~
|
|
Be aware that the DATE program supplied with CP/M 3.0 will not
|
|
work properly if your BIOS does not update the SCB with
|
|
interrupts. There have been replacements since then that are
|
|
available in the public domain.
|
|
|
|
One common trap for BIOS writers is forgetting that HL and DE
|
|
must be saved by the TIME routine. There is no obvious reason for
|
|
it, and really they should be saved in the BDOS.
|
|
|
|
ZPM3 does not expect HL to be saved. If you have had trouble with
|
|
your CP/M 3.0 clock things might work now. It was decided that
|
|
seeing as TIME was the only routine (apart from MOVE) which
|
|
required HL to be saved, it was too easy to overlook, and a real
|
|
pain to implement (some systems use HL to switch banks on entry
|
|
to the BIOS. MOVE is always accounted for, but TIME sometimes
|
|
isn't (Morrow MD11 owners take note!)).
|
|
|
|
Ideally, there should be no reason to save HL in your BIOS,
|
|
unless you intend to run CP/M 3.0 sometimes (although I can't
|
|
imagine why). Any applications which attempt to use TIME through
|
|
the function 50 are not guaranteed that HL will be saved anyhow.
|
|
|
|
Buffers.
|
|
~~~~~~~~
|
|
CP/M 3.0 (and therefore ZPM3) keeps special disk buffers. The
|
|
system is rather complex. The directory is buffered separately
|
|
from the rest of the disk (and in the case of 128 byte sectors
|
|
the rest of the disk isn't buffered anyhow).
|
|
|
|
You decide how many buffers to give to each disk's directory and
|
|
data, and you may choose to have buffers shared by different
|
|
drives. All these choices can make for lots of fun for the
|
|
hacker, but without knowing much about the internal workings of
|
|
the BDOS how do you best set the buffer up?
|
|
|
|
There are many cases to consider depending on how much RAM you
|
|
have available to allocate to buffers. If you have virtually
|
|
unlimited RAM, you might as well allocate as many buffers as
|
|
GENCPM will allow. The only catch to this is that more buffers
|
|
implies the BDOS will take more time to look through them all
|
|
before coming to the decision that a disk read is required. The
|
|
good news is that the ZPM3 searching algorithm is particularly
|
|
fast. Empty buffers are discovered even faster than buffers
|
|
which are valid but don't match, so large numbers of empty
|
|
buffers pose very little problem. In general, even with the
|
|
maximum number of buffers, the advantages they give outweigh the
|
|
disadvantages.
|
|
|
|
Of course, few people have unlimited RAM. If you have very little
|
|
room available, spend most of it on the directory buffers. These
|
|
buffers act like a cache of the directory, and can save the disk
|
|
heads from moving back to the directory tracks to find out where
|
|
the next block is stored. Even on very fast hard disks, the
|
|
advantages that decent directory buffers give are great.
|
|
|
|
When dividing up directory buffers between a number of drives,
|
|
consider which drive holds the most files and which drive does
|
|
the most work. A drive which holds a lot of files but is rarely
|
|
accessed is not worth wasting buffers on. If you have a system
|
|
with one hard drive and one floppy drive, and you don't intend to
|
|
use the floppy drive very much, give only one buffer to the
|
|
floppy and all the rest to your hard drive. This will penalise
|
|
the floppy's performance somewhat, but the improvement it gives
|
|
to the hard drive will make it worthwhile.
|
|
|
|
Data buffers, like directory buffers, perform two tasks:
|
|
deblocking of physical sectors, and cacheing. For data buffers
|
|
however the cacheing is the less important job, unless you have a
|
|
lot of data buffers available. The reason for this is that the
|
|
buffer algorithms work by taking the least recently used buffer
|
|
and using it for deblocking. If you are working on a file which
|
|
is 8k long, but you only have 4k of buffers, the BDOS will run
|
|
out of buffers before it has read the whole file and will grab
|
|
the least recently used one even though it contains valid data
|
|
from the file which could be required later on. The result is
|
|
that the BDOS does much searching through its 4k of buffers, but
|
|
rarely finds anything which matches and must read from the disk
|
|
anyhow.
|
|
|
|
In practice the system works a little better than that because of
|
|
the way files are used by most programs, so data buffers are
|
|
still worthwhile, but to take real advantage of their cacheing
|
|
ability you must have more room in the data buffers than the size
|
|
of the file you are working with. With word processors such as
|
|
Wordstar and NewWord creating extra files as they work, you
|
|
really need more than twice as much room in the buffers than the
|
|
size of the file.
|
|
|
|
So you can see why data buffers are less important than directory
|
|
buffers. Something else you should be aware of concerns multi-
|
|
sector i/o and the data buffers. When the BDOS is told to read a
|
|
file it searches its buffers and if it can't find the data there
|
|
it reads it from the disk. Normally it deblocks the data one
|
|
record at a time through its data buffers, leaving the data in
|
|
the buffers in case it is required again. However multi-sector
|
|
i/o does not usually need to deblock its data, so the data is
|
|
sent straight to the TPA without going through the data buffers.
|
|
If any of that data is required again, it will not be in the data
|
|
buffers and must be read from the disk. So two reads of the same
|
|
data using multi-sector i/o might actually be slower than reads
|
|
that are done a sector at a time!
|
|
|
|
And the really important thing about all this is that the CCP
|
|
uses multi-sector i/o to load programs. So if you thought that
|
|
implementing large numbers of data buffers would give you faster
|
|
loading of programs, you were wrong. The data buffers won't help
|
|
program loading unless the data can be put into the buffers
|
|
first.
|
|
|
|
If you use ZCCP, you will find there is a facility to prevent the
|
|
data buffers from being bypassed on program loads. It involves
|
|
simply setting the f1' bit of the file. The idea is that you set
|
|
f1' on all the files which are small enough not to clog up your
|
|
buffers, and then they run as if they are on a ram disk, but one
|
|
in which you can never lose data. The system is quite wonderful
|
|
in that the RAM used to hold the files is available to buffer
|
|
other data if required. Unlike a ram disk, the RAM is dynamically
|
|
allocated and the data is completely safe. But you must be using
|
|
ZCCP, and you must have at least 6k of data buffers before it
|
|
does anything useful. If you currently have a ram disk but few
|
|
data buffers, consider taking a chunk of your ram disk for data
|
|
buffers and switching to ZCCP.
|
|
|
|
CPMLDR bug.
|
|
~~~~~~~~~~~
|
|
This is closely related to the subject of buffers because you
|
|
will find that if you increase your buffers past a certain point,
|
|
the system will not boot. Almost certainly you will suspect a
|
|
problem with your BIOS code (you normally should), however the
|
|
CPMLDR.REL code supplied by DRI has a bug in it.
|
|
|
|
You may be wondering if everything DRI did with CP/M 3.0 was
|
|
buggy! I must say that what they achieved was terrific, but it
|
|
had its faults as well. Hopefully ZPM3 has addressed them all.
|
|
|
|
The CPMLDR problem occurs when your CPM3.SYS grows from being 16k
|
|
or less, to over 16k (and therefore two logical extents). You may
|
|
not have this problem under certain drive configurations, but if
|
|
you do, the symptom is that described above.
|
|
|
|
There really is no way of patching around this, but if you have
|
|
your loader BIOS, you can certainly use the (somewhat superior)
|
|
ZPM3LDR.REL code instead. This works very similarly to the DRI
|
|
code, except that it works properly. Unlike the DRI code, you
|
|
will find that ZPM3LDR has all its messages at the head of the
|
|
file so that you can patch them and change them if you wish.
|
|
|
|
ZPM3LDR does not clear the screen on boot up (CPMLDR does by
|
|
sending multiple linefeeds), but you could patch this if you
|
|
like. ZPM3LDR.REL will directly replace CPMLDR.REL. ZPM3LDR
|
|
however does not use the MOVE routine that CPMLDR requires
|
|
(although there is nothing much to be gained by removing it from
|
|
your loader bios code).
|
|
|
|
|
|
GENCPM bugs.
|
|
~~~~~~~~~~~~
|
|
GENCPM has bugs in it. If you can, try and set up all your
|
|
buffers manually. That way you'll know where they are and you are
|
|
in complete control.
|
|
|
|
The biggest fault I have found with GENCPM is that it will
|
|
allocate allocation vectors incorrectly. CP/M 3.0 can use double
|
|
bit allocation vectors, but doesn't necessarily. Sometimes (and I
|
|
think it is mainly with big disks), GENCPM will only allocate
|
|
enough room for single bit allocation vectors when double bit
|
|
vectors had been specified. The symptoms of this are varied, but
|
|
often, you can use your A: drive for a while, but as soon as you
|
|
use your B: drive funny things happen. If you only use A: and C:
|
|
drives, things appear to work OK.
|
|
|
|
The first thing to try if you suspect a GENCPM induced problem is
|
|
setting up with only one drive and a single buffer. If that fixes
|
|
it, the problem could well be with GENCPM.
|
|
|
|
Naturally, your BIOS code could still be the problem, so look out
|
|
for that too!
|
|
|