View Full Version : CP/M ALV optimisation in a multi disk system

August 29th, 2017, 12:06 AM
This morning I had a bit of a random thought and I'd like to ask for your opinions on it.

First of all, an assumption: CP/M never needs to have more than three disk drives accessible at any one time (i.e., when copying from one to another with a logged-in drive; for example A:> PIP D:=C:*.*).

Having implemented an IDE driver for the TRS-80 Model II, I was thinking about its usage of ALV buffers. These are recording where on a particular disk the file extents are located, and - as far as I can tell - are initialised when you first access a particular disk. You need one per disk, and its size is relative to the disk's storage capacity (block count).

On a relatively fast drive such as a hard disk, ALV initialisation is fast. So I wondered, why do I need all these memory hogging ALV buffers lying around in memory when in practice I only ever need to access two or three at any one time? Maybe I could optimise the setup a little.

Here's the proposal:

Setup three ALVs big enough for the drives they are to manage.
ALV1 would normally be used by the logged in disk.
ALV2 and ALV3 would be used "on demand" as needed
When a disk is logged in, it initialises ALV1 and a pointer that points to ALV1 ("logged in ALV" pointer).
When a disk is accessed but not logged in, the next available ALV that is not the "logged in ALV" is used.
If an ALV is already in use at the time of access, the system chooses the oldest one (but never the logged in disk's ALV).
When the user changes the logged in disk, the system moves the "logged in ALV pointer" to its ALV (if it already has one) or reinitialises the ALV that the pointer is pointing to.

Given this scheme, we have the following situations:

Boot up: ALV1 contains the directory data from drive A, which is logged in. A "logged-in ALV" pointer is initialised (points to ALV1). ALV 2 / 3 are unused.
Copy from A: to B: (for example, with PIP): ALV2 is initialised with B's directory data, and the copy takes place as normal.
Copy from B: to C: (with A: as the logged in disk): ALV3 is initialised with C's directory data, and the copy takes place as normal.
Copy from C: to D: (with A: as the logged in disk): ALV2 is reinitialised with D's directory data (as it is the oldest) and the copy takes place as normal.
Copy from E: to F: (A: is still the logged in drive): ALV3 is used for E:, ALV2 for F: and the copy takes place.
User changes the logged in drive: If the drive already has an ALV allocated to it, the "logged-in ALV" pointer is altered to point to the ALV of the drive (2 or 3) and ALV1 is now available for non logged in disk use, otherwise ALV1 is initialised with the new drive's directory data.

You can see that ALV1 isn't always used for the logged in drive's ALV buffer and under these circumstances the selection of the next available ALV buffer would need to consider ALV1. So this means that, when accessing a disk that wasn't already covered by one of the ALV buffers, we would need to choose between those buffers not being pointed to by the "logged-in ALV" pointer (rather than ALV2/3 as suggested above).

Implementation would entail some BDOS hacking, of course, but I am interested in the validity of the concept. The only side effect I can think of for now is that STAT would only show the free space of three drives at the most.

The question is, would it work?

August 29th, 2017, 05:51 AM
I"d go a bit further and propose that a disk's ALV needs only to be built when a file is opened for writing. In theory, one could delay ALV creation until the first write of a file. Unless someone is checking for disk usage, there's no point in building an allocation vector.

August 29th, 2017, 11:12 AM
Hi Chuck

I'm encouraged that you haven't challenged the idea yet. :)

Is the ALV not used during reads, then? If not, what is the point of "logging in" a disk?


August 29th, 2017, 04:18 PM
None, really--ALV only tracks used clusters. Clearly, if you're only reading, you don't care what's allocated, because the list of allocated clusters is part of a file's directory entry. However, when you want to know how much space is used, or if you open a file for writing, then ALV matters.

September 1st, 2017, 07:34 AM
More than 3 disks could be in use at the same time. Even standard CP/M compilers and assemblers allow you to specify which drive to be used for various temporary and output files. That's in addition to the "current drive" and A:. Of course, CP/M plus is a different matter, but also takes care of a lot of that.

I believe the CP/M Systems Guide does not recommend that you share ALV between disks. If you are going to do that, you will need to carefully manage the login vector to make sure you don't accidentally use invalid ALV data. The risk is pretty big, you can destroy disks very easily this way.

September 1st, 2017, 07:50 AM
Another consequence of this in many CP/M systems is swapping disks during writing with nearly-identical initial allocation and directory entries. As CP/M has no way for the BIOS to notify the BDOS that a disk has been changed, you can clobber disks. CSV is supposed to avoid this, but it's not perfect.

Back in the day, when we were working on DX85M, we found that we could detect a floppy change by sampling the write-protect sensor (5.25" disks). So we kept track of the number of files open for write access on each drive. If the user attempted to swap floppies on a drive with a non-zero open-write count, we'd stop things, sound the alarm and flash a message that essentially said "Put that back!". Reports of data corruption dropped drastically. We found that sampling the write-protect sensor every 250 msec. was sufficient and didn't require that the drive motor be turned on.

Even MS-DOS had problems with this on 360K drives (no "disk changed" status) and you could corrupt disks if you weren't careful.

With the Apple Macs, floppy changing is pretty much under the control of software. "Door lock" features were available for many brands of 5.25" and 8" floppy drives as an option. I'm not aware of any vendor who tried to make that work with CP/M, however.