I've been working all week to try and get CP/M Plus (aka CP/M 3) to boot on the Z80 system. Compared to CP/M 2.2, it's much more complicated due to the large number of features that were added. I could stick to just running CP/M 2.2, but then there would be 64kB of RAM (of the 128kB total) that would go to waste on the basic system because 2.2 doesn't implement bank switching. I'd also like to make an expansion board with the necessary hardware to run MP/M-II - the multitasking CP/M - which CP/M Plus is based on.
CP/M 2.2 was quite straight forward to bring up because the system components are very linear in the memory map. There are three modules in CP/M - the CCP (Console Command Processor), the BDOS (Basic Disk Operating System) and the BIOS (Basic Input/Output System). In CP/M 2.2, the three modules are loaded as one sequential block from the first track of the storage medium and dumped to the top of RAM. This makes the system less flexible but very easy to implement.
Say if you change the amount of RAM in your system, you would have to relocate the whole of CP/M to a new memory location and update all of your boot disks with the new version. Chances are you would also have to change the boot sector to load everything to the correct address too. The same goes if you change your system configuration, i.e. higher capacity storage, new peripherals, etc. You need to add the changes to your BIOS, reassemble, relink and update any boot disks.
CP/M 3, being quite advanced for the time, solves these problems to some degree by having a four stage boot process before you get to the command prompt. First the system ROM loads the first sector of the first track of the disk storage and executes it. This loads in a small program called CPMLDR.COM from the first track and executes it. CPMLDR.COM contains a minimal implementation of CP/M Plus and a BIOS. This loads the file CPM3.SYS off the file system to the correct location in memory and executes it. The system is then initialized by CPM3.SYS, vectors set and so on, then CCP.COM is loaded into the program area and executed, giving you the command prompt. It is done this way so the operating system code is in a file, not on the boot track, which makes the task of updating or patching it a little easier.
Given the system is so complicated, if there is anything even resembling a bug in the boot procedure or CPM3.SYS, the system will crash. This is the problem I've been having as I'm not exactly the best coder out there.
My first problem was trying to read the existing CP/M 2.2 file system at all. That was down to CP/M Plus using slightly different parameters to 2.2 for defining the disk storage. Then when booting, the system would try to switch to memory bank 2, which doesn't exist, and load CCP.COM to it. Only banks 0 and 1 exist, that is two banks of 48kB plus 16kB of 'common' RAM that doesn't get switched. The bug was in the default boot code. It explicitly switched to bank 2 to load CCP.COM, and copied it to bank 1 to warm boot the system without having to access the disk. No problem, the system doesn't touch most of bank 0 so I'll use that instead. I eventually got it to say "BIOS Err on A: No CCP.COM file" so I transferred CCP.COM to the file system. It still wouldn't boot.
After more stuffing around and some amount of luck I got it to display an A> prompt, but it doesn't respond to interrupts from the ATmega. I'm stuck here. For some reason interrupts don't work. I'm using Interrupt Mode 1 on the Z80, which uses vector 38h to jump to the interrupt routine. CP/M should in theory leave that vector alone unless you're running a debugger. Something is either disabling interrupts or is changing the the vector. I'll keep at it though.
A final note, CP/M was the ubiquitous 8-bit operating system for 8080, 8085 and Z80 business machines of the late 70's and early 80's. MS-DOS might be considered a clone of it. We all know who won out of the two...