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!