8008guy
Veteran Member
This weekend I successfully booted CP/M on my bench system! It was quite a long journey.
It started almost exactly a year ago when I restored an Altair I acquired several decades ago. After restoring the Altair I got CP/M working on it using an FDC+. That wet my appetite, but using the FDC+ made it so easy it felt like cheating. No disrespect intended, just that all the heavy lifting was done by Mike who did an excellent job! Using his board and software made it impossible to fail.
After the Altair I restored my IMSAI that I bought about the same time I got my Altair. On the IMSAI I decided to take a more “authentic” path to CP/M. Being that the IMSAI would take up too much space in my office I opted to develop everything on a bench system. I bought one of Don Caprio’s Mini Front panels. Got one of the S100 groups nine slot back planes, and also one of Josh Bensadon’s 8080 CPU cards.
Having a working development system I first tackled the issue of an I/O card for the IMSAI. Not finding anything readily available I wire wrapped up an IMSAI SIO2. I completed the SIO2 card in January. I somewhat simplified the output side to only include RS232 drivers, as well as a single chip dual baud rate generator.
Next I bought a bare BYTE8080 MPU board and put it together. I could “un-option” Josh’s board, but wanted to work with a board and card configuration similar to the one in the IMSAI.
For RAM I used a 64K Compupro board which required me to work though the issues of having a RAM card that didn’t work with my front panel. It was designed to work with a standard S100 buss. To get it working required I cut the “inner” ground traces. I also had to pull the IC that does the > 64K bank selection and strap the desired bank select to ground.
To get everything going I needed a Monitor program. In my collection of cards I had a MicroDesign MR8. Not being able to find any documentation I ended up reverse engineering the schematic. Having bought one of Martin Eberhard’s dual seral cards for my Altair I had experience with his Memon/80 monitor and liked it very much. I burnt a copy and put it on the MR8. I also made one modification to the MR8 that would cause the MR8 to assert the phantom line so I didn’t have a conflict with my memory card.
Last I needed a floppy controller card. I chased a few on Ebay and finally ended up with a rather ratty California Computer Systems CCS2422 Rev A. If you are familiar with the Rev A you know there are a few challenges. In addition my controller was missing nearly half its chips. After placing an order for the missing IC’s and testing the existing IC’s I got my controller populated. I did some initial testing and things appeared that it would work. Using Martin’s MeMon I could manually send restore and seek commands.
Next I applied the published “problem” fixes to the board which solve the lock up and glitches of the Rev A version. I also applied some of Martin’s fixes to get the status registers to be the same as the Rev B and C boards. For my testing I am using a TEAC FD-55GFR drive. They can be strapped to run at 300RPM.
Nearly all of the CCS software was written to support Z80 op codes. I found the CCSINIT program which is used to format disks and disassembled it. I discovered that it only used a single unique Z80 instruction to create the error message. I NOP’d that out and then redirected the BDOS calls to use Memon/80’s character input and output routines, as the program was written to be run under CP/M. Once I had that completed I formatted a disk!
Next I set out to write some simple read/write sector commands. Through this process I discovered a bad 1793 controller chip and another IC. I’m really grateful to Martin who was gracious enough to answer a continuous flow of email fill with my novice type questions. I also heavily leveraged my Saleae logic analyzer which was continuously wired to the 2422 controller board.
After getting the basic sector read and write functionality working I started to modify an existing version of the CCBIOS. I ripped out the serial I/O routines substituting in routines to support the IMSAI SIO2. Since Martin’s MeMon supports the SIO2 I shamelessly liberated his functions. When I started doing the math on my system size, CPM/BDOS/CCBIOS, I saw that I would be over the three track limit. I could go double density but opted to go double sided for the system files.
When I played with the side select option everything broke. It took me several more days to understand what was happening and I got that fixed. The solution came after reading Martins format program and doing a few captures with the Saleae. Since Martin does a verify after format, unlike the CCSINIT SW, the problem showed up rather quickly.
Being over the two sided hurdle I could now modify the CCBIOS WBOOT routines to support my two sided system. Just like everything else before, this wasn’t going to be solved as quickly as I thought. At this point in time I could drop the hex files for CPM/BDOS and CCBIOS into memory. Using my boot strap routines, which were modified from my sector read/write code, I would get the disk param area set up and jump into the cold boot entry point of my CCBIOS. The CP/M A> prompt would magically appear and I could now do a dir command and see that I had an empty disk! Having a running system made it much easier to modify the CBIOS.
After studying the warm boot code I found where I needed to make my modifications. I first made a change to start reading at sector 3 being that my boot code was just under 256 bytes and it needed two sectors itself. Continuing though the function I would read to the end of the track and check for side and then swap over to side 1 or jump to the next track and reset to side 0. All this worked perfectly. I could see all the system data, minus the CCBIOS which I didn’t re-read, come back into the memory after a warm boot. The trouble came when I pulled out the code to halt after a load and jump to the CCP, the system would crash every time. I went back and forth for an entire day trying to trouble shoot where I had gone wrong. The load was perfect, I even did a memory dump and verified that the memory and hex code for CP/M and BDOS matched.
Later Saturday evening the answer came… Out of desperation, and a little intuition, I put in a single NOP between the warm boot code and the common boot code. I dropped in my CBIOS, did a control C, and the system reread the system from disk and I was back running. I tried the same exercise using two NOP’s and the system failed. For some reason there is a bug/alignment/assembler error that is causing this code to be position sensitive. Martin has encouraged me to go back and find the real error, which I may do one day when I feel slightly sadistic.
The only thing left to do at this point was to modify my boot loaders for their real and final destinations. Up to this point I was I was just loading them in as hex files and manually kicking them off. The primary loader needed to be burnt in EPROM. It would now reside above MeMon. The disk based loader gets pulled into memory and loaded just below CCP. That way I free up the space around 100H in lower memory so I can load the CP/M transient programs before booting CP/M and save them to disk.
Looking back it was a pretty intense way to pass five months’ worth of evenings and weekends. Before I started I had read many websites and documents about porting CP/M to a new system. I can’t even begin to count the thousands of lines of 8080 assembly code I read though. I really envied, and now greatly admire, those who have boot strapped their own custom systems. I had an amazing amount of help from Martin. Even using modern tools, emulators, a logic analyzer, and with the Internet this was a real challenge. It give me great appreciation for those who did it back in the 70’s and 80’s. For anyone wanting a real challenge I say go for it, you will never regret it.
Cheers and thank you to all those who unknowingly helped an old computer junkie get his fix.
len