• Please review our updated Terms and Rules here

Installing CP/M 3 (Plus?) on a home-built Z80 computer

nockieboy

Experienced Member
Joined
May 12, 2017
Messages
261
Location
UK - Kent
Hi everyone,

I've got a Z80-based computer that I've built with 256KB of memory (made up of 128KB RAM and 128KB ROM), divided into 16 x 16KB banks that I can map in any combination to the 4 pages accessible by the Z80's 16-bit address bus. It currently runs CP/M 2.2.

As the MMU was a recent addition, I thought my next step should be to get CP/M 3 up and running as it supports banked memory. The plan is to fix the upper 16KB page and allow CP/M to swap the lower 48KB as one block, giving it Bank 0 and Bank 1 (the minimum requirement for CP/M 3.)

My knowledge of CP/M (and assembly - although not programming in general) is extremely limited and I'm learning as I go. From what I can gather from the documents, I need to write a new CPMLDR.COM file with a modified CBIOS in it to allow CP/M 3 to interface with the hardware in my computer (the CompactFlash drive specifically) so it can load CP/M 3 on boot. Makes sense. Then I need to write a more fleshed-out CBIOS for CP/M 3 itself and build a CPM3.COM file for CPMLDR to load into memory and execute. Also makes sense.

However, I'd appreciate a little guidance on how to complete these tasks if possible. I have CP/M 2.2 with a working CBIOS already. I've read in the CP/M 3 System Guide that you can convert the CBIOS from 2.2 to 3. This would obviously make sense as I'll likely be building the CPMLDR and CPM 3 .COM files in CP/M 2.2, and there's no point re-inventing the wheel.

Initially I had a look online to find examples of LDRBIOS assembly files but all I can find relating to the LDRBIOS I need to build CPMLDR are written in 8080. Yes, I know the Z80 can understand 8080 opcodes but I can't (I'm still learning Z80 opcodes!) :rolleyes:

The guide talks about extra jump points, which I've added, to the BIOS jump table - I'm about to start working my way through the functions and making sure they do what CP/M 3 expects (though I'm looking initially to create a non-banked version of CP/M 3 first.) But the LDRBIOS.ASM comments talk about 'boot' being null, then elsewhere that it should get its start value from @mxtpa and... :confused:

Anyone done this before and can remember what they did? I just need a few pointers really as I don't know enough about the subject to confidently make the edits I need to.

I've attached a zip file with the two .ASM files - CPM3_CBIOS64.ASM is the full CBIOS for CP/M 3 that I'm building based off of the CP/M 2.2 CBIOS, LDRBIOS.ASM is an example BIOS for CPMLDR (stripped down) that I'm trying to convert to work with my system and get CPM 3 running.

Any help would be greatly appreciated!

File Attachment: View attachment BIOS.zip
 
I haven't looked at your BIOS yet, but I do have CP/M 3 for the Z89/Z90 computers online at https://github.com/durgadas311/MmsCpm3 which might help. This example is a bit extreme, as the BIOS supports many different disk and hardware options, through linkable modules. The main BIOS (mbios3.asm) is tailored for the H89 platform, but might be a possible starting point. There's also a wiki there, where I try to describe more details. If you think it's useful, let me know and I can help you adapt it. Or at least explain parts of it. In this case, the loader is created by linking in a BIOS disk module and a bootstrap module for the specific disk to boot from.

I should note that all of that code uses "Intel mnemonics extended for the Z80", so you will have that hurdle to understand and/or utilize it. There is a Z80.LIB macro library for RMAC, though.
 
Last edited:
Thanks durgadas311, any examples are a great help to me as I find it much easier learning from a working example than from a sequence of instructions that often miss important steps out because of assumptions about the reader's prior knowledge.

I'm going to have some time hopefully tomorrow to take a good look at the BIOS. It makes most sense to me to use the CP/M 2.2 BIOS and 'upgrade' it to work with CP/M 3 - then I'll pare it down to the minimum required for CPMLDR and get that built too.
 
John Monahan has some write-ups on bringing up CPM/3 his S100Computers website:

Floppy - www.s100computers.com/Software Folder/CPM3 BIOS Installation/CPM3 FLOPPY BIOS Software.htm
IDE/CF card - http://www.s100computers.com/Software Folder/CPM3 BIOS Installation/CPM3 HDISK BIOS Software.htm

Note that John's IDE write-up uses a 'holes' version of the LBA translation routine out of simplicity, which does not work with cpmtools, if you scroll down to the 'A New Simplified CF-CARD CPM3 Image.' there is information on the LBA translation routines needed to avoid the holes.
 
I've never verified this, but I've long suspected that if one writes a BIOS/XIOS for MP/M II, then the job's pretty much done for CP/M 3. Truth or delusion? :) (i.e., I've done for former, but not the latter)
 
John Monahan has some write-ups on bringing up CPM/3 his S100Computers website:

Floppy - www.s100computers.com/Software Folder/CPM3 BIOS Installation/CPM3 FLOPPY BIOS Software.htm
IDE/CF card - http://www.s100computers.com/Software Folder/CPM3 BIOS Installation/CPM3 HDISK BIOS Software.htm

Note that John's IDE write-up uses a 'holes' version of the LBA translation routine out of simplicity, which does not work with cpmtools, if you scroll down to the 'A New Simplified CF-CARD CPM3 Image.' there is information on the LBA translation routines needed to avoid the holes.

Wow that's a really detailed resource - thanks for that, MarsMan2020. :)

I've already got CPM 2.2 running on my system - so the BIOS is set up to work with the CompactFlash card and I'm hoping it won't take much to convert it for use with CPM 3. Now I know that CPM 3 has a few changes to the drive tables compared to 2.2, but aside from those and the jump table modifications (and coding the associated extra functions where necessary), I don't think there's much more I need to do to get a working CPM3 BIOS?
 
Okay, I've had a go at LDRBIOS.ASM and converted it to Z80 opcodes, with a couple of tweaks (a DJNZ and LDIR where the 8080 version had loops).

From what I can gather from the comments in the file, I don't need to do anything else as this BIOS will run alongside my CP/M 2.2 CBIOS and uses the functions in that to access the CompactFlash and other machine-specific IO features?

Anyone care to take a look at the file and give it a quick sanity check for me? If it's okay, I guess I just need to compile a CPMLDR.COM file using this assembly to run at 0100H and I'll be able to run it in CP/M 2.2? Do I need to compile a new CPM3.SYS with a full CBIOS first before I can run CP/M 3 from CP/M 2.2?

File attachment: View attachment LDRBIOS.zip

EDIT: Update as I've tried to create CPMLDR.COM with LINK and got the following error/s:

Code:
A>LINK CPMLDR[L100]=CPMLDR,LDRBIOS
LINK 1.31

UNDEFINED SYMBOLS:

@CIVEC  @COVEC  @AOVEC  @LOVEC  @BNKBF  @CRDMA  @CRDSK  @FX
@RESEL  @VINFO  @USRCD  @ERMDE  @DATE   @HOUR   @MIN    @SEC
@MXTPA

ABSOLUTE     0000
CODE SIZE    0AC7 (0100-0BC6)
DATA SIZE    0000
COMMON SIZE  0000
USE FACTOR     22

A>

I've obviously misunderstood the symbols in LDRBIOS.ASM - these need to be explicitly set in the assembly file?
 
Last edited:
If CPMLDR.COM is truly stand-alone (does not depend on the CP/M 2.2 used to start it) then you should be OK. This image is often placed on boot tracks of a disk so that you can boot directly into CP/M 3. For my Kaypro version, I used a modified CP/M 2.2 boot disk (to avoid critical memory areas) and then made that CCP "auto execute" the CPMLDR command (by patching the command buffer in the CCP). For test purposes, you can usually just invoke CPMLDR from CP/M 2.2 CCP, provided there are no memory conflicts (i.e. CPMLDR.COM is stand-alone). The first instruction in CPMLDR.COM should probably be a DI, or at least before the LDRBIOS cold boot entry is called.
 
Last edited:
The first instruction in CPMLDR.COM should probably be a DI, or at least before the LDRBIOS cold boot entry is called.

Ah, thanks. I'll add that in. Is there anywhere I can look up EXTRN assembly directives so I can work out what I need to do to fix them in my LDRBIOS source? They're throwing 'undefined symbol' errors when I try to link/compile CPMLDR with my BIOS, as shown in my previous post.
 
Your undefined symbols look like SCB. Since the loader is not exactly CP/M 3, I'm not sure what those resolve to. Perhaps the loader is pre-initializing the SCB for CP/M 3. I'll have to check the loader submit files, but there probably needs to be another module to link with it. Maybe see if there is a submit file on my github repository that might lend a clue. Probably looking for an SCB.ASM or SCB.REL.
 
Sorry, what's an SCB? Will SCB.MAC/ASM be a generic file, or another hardware specific one?

EDIT: Ah - System Control Block? Found a reference to SCB.Z80 online.. Just need to find one now. Not in front of a computer at the moment. How would I include that with the LINK command I was using to build the CPMLDR.COM file?
 
Last edited:
I would suggest reading the CP/M 3 system manual, and perhaps programmers manual, for more about SCB. Also, there may be different versions of SCB.ASM out there. I'm not sure that the one used for the BIOS is the same as what is needed for the LOADER. There is some good information in the DRI manual about bringing up CP/M 3. The SCB used for the BIOS has a "dummy" base address for the SCB, which GENCPM (or some other component) recognizes and translates into a real address. I'm not sure what the LOADER needs SCB for, so not sure what sort of base address it needs.

Basically, though, the SCB is a block of memory, mostly maintained by the BDOS, that exports various bits of information. In some cases, external entities like the BIOS and CCP may alter information in the SCB or pre-init values during boot.
 
Last edited:
Odd, I posted a reply and it seems to have disappeared.

There's a copy here:

http://v1050.classiccmp.org/src/index.html#SCB.ASM

It's part of the standard distribution.

I can't find the SUB file I used to build CPMLDR for my system so I can't say if I linked SCB.REL or not.

I'm still trying to recover my build environment.

Ah, thanks Alphasite - that's a handy resource. I managed to find an SCB.Z80 - funnily enough - in the CP/M 3 distribution files I have, as you've mentioned. :rolleyes: As far as linking it with LDRBIOS.ASM to create CPMLDR.COM, I've taken a shortcut and just copied the contents into LDRBIOS.ASM as it's just a group of equates. I've managed to successfully build a CPMLDR.COM file as a result but, no surprise, it crashes the emulator when I run it. I've got to go through the equates and make sure they're matching up to the correct addresses for the SCB in my computer and try it out on that, but I just feel there's probably a million other things I need to be matching up as well that could cause it all to fall over.
 
I'd still recommend going the through the instructions in the DRI manuals and make sure you didn't miss something. Again, the "base address" in SCB.ASM is actually a fake one, and what the loader needs depends on how it's used. BDOS3 does not exist when the loader starts, and once BDOS3 (and BIOS3) runs the loader never executes again, so anything the loader does with the SCB is limited. Unless these EXTRNs are actually for something else, in which case SCB.ASM is the wrong way to resolve them.
 
I'm taking a look now at the CPMLDR.ASM I got from www.cpm.z80.de and I don't see any references to the SCB. That file contains a strip-down CP/M 2.2 BDOS with a loader program front-end. I wonder now where those undefined symbols come from. Does your loader BIOS have CP/M 3 code in it (references to the SCB)? I'll go back and review your earlier posts to try and see what you are doing.
 
I think you'll need to work on LDRBIOS.ASM more. I see the EXTRN declarations there for SCB symbols, but those are never used - except @MXTPA. Also, it looks like your cold boot routine does nothing but return immediately. That probably won't work, you'll need to be sure to reclaim all your hardware away from the previous CP/M instance. That might only be critical if interrupts are setup and enabled (on device hardware), but probably you'll need to some amount of hardware reconditioning - in case any of the hardware is in an undefined state. You really want to minimize this as well, especially to ensure any crash is unlikely to write to disk. Also, use of "ORG" may be contradictory to use of RMAC/LINK. You need to let LINK resolve the first address in your BIOS so that it is placed immediately after the last byte of CPMLDR.REL. Typically, a relocatable program segment will simply start with CSEG (and no ORG). It appears that the loader uses only CSEG, which makes it simpler. I think the only place you'd use absolute addresses in LDRBIOS.ASM is if there were some memory-mapped spaces or a ROM BIOS memory region you needed to access. If such things exist, you'll also need to make sure your CP/M 3 image avoids placing anything there.

update: I see you did comment-out the ORG statement, so that is not the problem. So maybe just work on the cold boot code. Also, I see some calls to BDOS although I'm not sure if they are getting executed. The loader does not setup 0005H, as far as I can tell, so you might end up calling the wrong BDOS. Especially if you're using @MXTPA to do that, when that symbol will not have been initialized. I'm not sure how one is supposed to call the loader BDOS from the loader BIOS, if that is even possible.
 
Last edited:
update: I see you did comment-out the ORG statement, so that is not the problem. So maybe just work on the cold boot code. Also, I see some calls to BDOS although I'm not sure if they are getting executed. The loader does not setup 0005H, as far as I can tell, so you might end up calling the wrong BDOS. Especially if you're using @MXTPA to do that, when that symbol will not have been initialized. I'm not sure how one is supposed to call the loader BDOS from the loader BIOS, if that is even possible.

Well, I'm trying to 'upgrade' my existing CP/M 2.2 installation to CP/M 3 - there's an archive here from cpm.z80.de that is set up to allow CP/M 3 to run from CP/M 2.2, that's what I've been using and where LDRBIOS.ASM comes from.

I'm trying to learn assembly and CP/M at the same time as trying to get CP/M 3 running on my SBC - I'm starting to feel I've bitten off more than I can chew. Unfortunately, the CP/M System Guide doesn't give a step-by-step tutorial on how to upgrade 2.2 to 3 (well, the instructions given are too high-level for me) and that's what I need. I don't have the assembly knowledge or familiarity with the CP/M tools/system/code to do much more than copy and paste blocks of code from the 2.2 CBIOS to the 3 BIOS and hope it works.

I'm going to take a break and go work on some more features for the monitor ROM - then hopefully I can come back and take a fresh look at this. As I understand it though, this is what I have to do:

1. Create a CPMLDR.COM file, by:
a) Creating a working LDRBIOS.ASM
b) Compile in RMAC and link to create CPMLDR.COM file

2. Create a full BIOS for CP/M 3, by:
a) Taking the CP/M 2.2 CBIOS and modifying it with the extra CP/M 3 jumps
b) Modify the extra routines to return null etc
c) Tweak a couple of existing routines to return expected values for CP/M 3
d) Compile in RMAC and link to create CPM3.SYS file

3. At this point, I should be able to run CP/M 3 in CP/M 2.2 by running CPMLDR.COM.

4. Modify boot sector of CF card to run CPMLDR.COM using COPYSYS?
 
I understand the frustration, this sort of thing is not really easy - despite what the instructions might imply. And to do this while learning (about Z80 ASM and CP/M) is even harder. If I had a virtual machine to match your hardware, I could probably be of more help. I'm strapped for spare time right now, though.

another area to pay attention to, when creating the BIOS3 code, is the DPH and associated structures. There are some subtle differences and new structures which need to be carefully handled.

I'l try to find some time this weekend to take a closer look at your BIOS code and see if I can help by inspection. If you've got something to document your hardware, that might be nice. either "programmer notes" or a schematic.
 
Back
Top