• Please review our updated Terms and Rules here

CP/M 2.2 Source Code

I think I ruled out the stack as a problem. Used the pattern in memory and then looked at how far down the pattern changed to see the depth of the stack. I checked my CBIOS stack, which I had set in high memory, away from everything, the CCPSTACK, which doesn't go very deep at all and the STKAREA, the BDOS stack, this one goes deeper but has more space. The stacks don't seem to be the problem. My monitor program which I wrote before I did my assembler, has a little routine that prints out the flags and is very handy.
I have the idea that my problem lays with the interrupts, or more specifically, the routine that interprets them. So, I'm working on that line right now. In particular the Sense Interrupt after a Seek. So, I'm trying some ideas and different code. Thanks Mike.
 
Well.... it pays to do a thorough review of the software. Not only did I find that there was nothing wrong with my code, but I learned a bit about how CP/M works. Yesterday I found the problem! Turns out it was hardware, wiring actually. For some reason, which I now understand, the cold start loader would work just fine. Load CP/M flawlessly, yet CP/M would bomb every time. I could smell the trouble, but could not see it. Then going over everything I spotted it last night. I had configured the interrupts to use IR1 and had a jump at 000 010 to the ISR routine. Well, IR1 uses 000 004 not 000 010. Reason that the CSL worked was that my memory chip in that area always starts with zero's in it, or NOP's. The PIC would do a call to 000 004 when the CSL was running and the NOP's would just run up to 000 010 where my jump to ISR was. CP/M, when it was loaded would put a jump to BDOS in 000 005 to 000 007, which screwed up the interrupts. So, I just rewired the FDC and PIC to use IR2 and changed the PIC mask to IR2 and the 'A>' showed up. I could type in stuff and the console would respond 'stuff?' I typed in DIR and it responded 'NO FILE'. My 8" disk doesn't have any thing other than the system on it. So there isn't to much testing that I can do. But, before I add stuff to the disk, I want to change the interweave on the CP/M disk. Right now the system has an interweave of 1:1. This slows things down quite a bit, it takes about 10 seconds to load CP/M. But, that actually helped out on trouble shooting, I could kinda see what the drive was doing. So my next step, after a little breather, will be to redo the CP/M system on my 8" disk to an interweave of 6:1 and get that to work. Thanks for the support and help. Happy Day, Mike
 
If you have 26 sectors per track the an interleave of 6 should speed you up about 4.3 times, i.e. you can read 4.3 sectors per revolution if it keeps up with an interleave of 6, as opposed to reading one sector per revolution.

With a interleave of 6, you could get 4.3 sectors per revolution.
With a interleave of 5, you could get 5.2 sectors per revolution.
With a interleave of 4, you could get 6.5 sectors per revolution.
With a interleave of 3, you could get 8.6 sectors per revolution.

There is a chance you can get 3 with your DMA, but 4 would be safe. A lot of people use 5-7 sector interleave, but that's both conservative and typically for port transfers by the micro and on early systems with slow clocked micros.

Now I understand choosing an interleave of 6 because its more common for that format... but if you did a physical interleave instead of a table interleave, it wouldn't matter. I'd suggest that before you go with 6, at least play with it to find out what is the first interleave that does miss the next sector read.

Another argument for a larger than minimal interleave is to still catch the interleave when the micro is running a program that pulls in sectors, scans before requesting the next sector. That processing time imposes an additional delay which may or may not allow the next sector to spin past the R/W head before it is requested and cause a 1 revolution delay until the sector comes around again.

Running DB-II or compiling/assembling code on floppy files could also run faster if the interleave is just right. Its not usually as ideal as the argument suggests because complications like ouputing a listing file at the same time negates that interleave advantage in some part.
 
Last edited:
If you've got a lot of memory, you can read whole tracks at 1:1 with the 765. The downside is that you'll need a track buffer of 26*128 bytes. You can either track-buffer writes or just do single-sector writes in that case.

You could, however, interleave the first 2 tracks at 1:1 (since CP/M doesn't fool with them) and even "skew" one track so that the track-to-track seek time puts the first sector of the second track right under the read head (allowing for settling) at exactly the right time. You can then boot in exactly 2 revolutions, plus however long it took you to seek to the first sector on the first track. (2 revs is about 330 msec.)

All sorts of fun and games can be (and have been) played with CP/M disk access.
 
Well, changing the interleave was easier than I had thought. I first formatted a disk to have an interweave of 6:1. Then copied the 1:1 system from my first disk into the 8080 machine, followed by writing the system back to the 6:1 disk. You were right, it loads a lot faster, probably about 2 seconds. Just for grins I tried 4:1 and it also works faster yet, but hard to tell. Seemed to be reliable read and write, I'll keep things at 6:1.

I also toke some time to look into the 22DISK program. It is rather easy to use. I copied the utility programs from my original CP/M disk to a DOS directory and then copied them back onto my new 6:1 system disk. I loaded up CPM on the 8080 (I'm impressed with the speed) and the DIR command listed the new files just copied. I was surprised to hear that the disk head loaded and unloaded three times, but after thinking about it, CP/M will read one directory sector at a time, which can hold 4 files. There were 12 extra programs, so three times makes sense.

What concerns me now, is that the extra programs are not the ones that I had expected. Here are the programs that were on my original disk
DPATCH.COM DPATCH.DOC DU.COM DU.DOC SWEEP.COM FIND.COM
UNERA.COM UNERA.DOC DPINS.COM REFM-IBM.COM SGLCPY.COM XD.COM

The programs in the CPM manual such as ED, STAT, LOAD, DDT, PIP, SYSGEN, SUBMIT or MOVCPM are not there. The other listed files are not even mentioned in the CPM Manual. What programs should have come with an original CPM 2.2 disk? Mike
 
The "orignal" set of programs varied, as some extras could be gotten from DRI, but basically PIP.COM, ED.COM, ASM.COM, LOAD.COM, SUBMIT.COM, XSUB.COM, MOVCPM.COM, STAT.COM, DDT.COM, DUMP.COM (as an ASM example) and the CBIOS.ASM samples. I don't think I forgot any. Individual OEMs expanded on that quite a bit.
 
I went back and looked again, and I found them. There is something different thou, on my 8080 machine I get a prompt 'A>', where as on the 22DISK I get 'A0' or 'A1'. I found the programs you mentioned with the A0 prompt and the first ones I found with the prompt A1. I'm guessing that the number is the User Number? I tried to use the USER command on my copy of CPM. It accepted the command but didn't change the prompt. Maybe that is an enhancement to CBIOS? I tried to use the editor ED, but it failed. I think I'm running into the bad spots on my OLD disks. Maybe it is time to make a purchase of some new ones. Thanks, Mike
 
A0: A1: are the user numbers - a quick and easy way to do file collections without directories.

NSWP is a utility that makes it easy to see all files on the floppy. I think I've used NSWP207 at home.

Regarding bad spots on the diskette... when you get your CP/M loaded with its assembler, you can write a diskette test routine and have it test and de-allocate bad sectors/blocks from the directory. Maybe that would be better to do later?
 
Last edited:
If you want DOS copies of any of the CP/M programs, just ask. Also note that 22DISK changes file extensions .CPM on DOS to .COM on CP/M and vice-versa during transfer. This keeps 8080 files safe from being executed as x86 files under DOS.

If you don't specify a user area, 22DISK assumes user 0 on copy-to-CP/M. On copy-from CP/M it assumes all files, regardless of user number.
 
Dallas, When I become more accustomed to using the new assembler maybe I can write something to de-allocate sectors etal. Sounds like a good idea.
Chuck, I've been puttzing around with it and I think I stumbled across the items you mentioned. It really is a nice program.

In the mean time, I want to improve the error handling of my program. I don't have any code that handles a drive ready change (door open or power off). The 8272 polls the drives and if the ready line changes (goes high) the FDC generates an async interrupt. I'm at a loss of what to do when this occurs. I can detect it by looking at ST0, but how should the code notify CP/M of the ready change?

The rest of my error handling is rather crude and also needs improvement, but I want to start with READY, Thanks Mike.
 
Could this be as simple as, when a not ready interrupt occurs, set a flag for that drive. Then when a command to read, write or seek on that drive occurs, check that drive ready flag, proceed if ready or print a message to the operator that the drive is not ready? Sounds like it would work, Mike
 
I have added a couple of flags, DRV0RDY and DRV1RDY, (I'm setting up my CP/M for only two drives). I'm using the Sense Drive command to see if a drive is ready or not and setting these flags accordingly. I've tested this and it works. Power on/off and door open/closed.

When a call is made to SEEK, READ or WRITE and the selected drive is not ready, the CBIOS will print a not ready message, it will give the user a chance to correct the ready problem. Once the user says the drive has been corrected, another Sense Drive will occur to be sure the drive is really ready and if it is, the routine will return to the calling routine and continue. But if for some reason the user can not correct the drive ready, an abort, what should be done here? The SEEK, READ or WRITE can not be done and the CBIOS needs to return to CP/M with an error, but how? I think that all I have to do is set A=000 and return, at least for READ and WRITE. But what about the SEEK, the CBIOS SETTRK, doesn't require a return error, probably because it doesn't SEEK at that time. My SETTRK will SEEK right away. Or, is this a don't care, because if the seek didn't work the next READ or WRITE will also not work, because the track will not be correct, but this doesn't seem to be a clean method. Any ideas? Thanks Mike
 
Unfortunately, there's no way to tell CP/M about disk status changes; one can only return a single "error" or "no error" status. In fact, this is a problem with all floppy-based systems, including, say, MS-DOS. In CP/M, the problem is worse than MS-DOS, because CP/M does not track open files; in fact, it's not even necessary to open a file before reading or writing--you just fill in an FCB with the right stuff and you're off and running.

Suppose you're in the middle of a program with files open and the user changes a floppy. What do you do? Maybe the floppy is just being removed and re-inserted so that its label can be read--in effect, no change has occurred. What if a disk with a file open for writing is changed?

Since CP/M can't tell you if any files are open on the disk, it's not at all clear if a disk change means anything. A program may request that the user change the disk, in which case the program will properly issue a "reset disk system" BDOS call, before looking at the new disk.

In an operating system developed for a different machine, I kept track of files open--and if there were any and a disk was changed, I stalled with the message "Re-insert Disk".

MS-DOS with it's "Fail, Abort, Retry, Ignore" prompt wasn't terribly useful in this respect.
 
Heath's HDOS actually handled changed disks well. Each disk had a volume number (0-255), and which is encoded before each sector (at least for the hard-sectored format, not sure how it was handled on the soft-sectored disks). So on every sector read/write it would be verified before doing the operation.
 
That's an interesting idea. There's nothing to prevent soft-sectored formats from doing the same. After all you have essentially 7 free bits in the head field of the ID address header of each sector. But I'm not aware of anyone actually doing that.

The bigger problem is "What do you do when you discover the wrong disk has been inserted?" Even the Shugart 801 could be configured to report a disk change. I've found it interesting that during a format that the 8272 writes an IAM (that might be used for such data), but has no way to read it--it's essentially "blind" during a short period after index.
 
Here's a ZIP with the CPM20.COM file and the MOVCPM.COM file that goes with it as described on page 6 of the "CPM 2.2 Alteration Guide". In other words, the MOVCPM 20 * and SAVE 34 CPM20.COM has been done. You'll need the MOVCPM.COM (patched so that it works with any CP/M 2.2 copy). You should be able to take things off from there. Note that the CCP entry point isn't until offset 880h in the CPM20.COM file.

Sorry for the necro bump. Is it me or has the ZIP file with the patched/unprotected MOVCPM.COM been removed? I can't see an attachment to your post...
 
Back
Top