• Please review our updated Terms and Rules here

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

OK, well I tried the LINK command, as I expect it to be, on my virtual H89. The resulting BNKBIOS3.SPR is not corrupt. Unsure how this happened, so maybe we need to review your link procedure. What command did you use to create BNKBIOS3.SPR? Was it only made from BIOS3.rel and SCB.rel? I used:

Code:
link bnkbios3=bios3,scb[b,os,nr]

Or else the SPR file got corrupted afterwards.
 
OK, well I tried the LINK command, as I expect it to be, on my virtual H89. The resulting BNKBIOS3.SPR is not corrupt. Unsure how this happened, so maybe we need to review your link procedure. What command did you use to create BNKBIOS3.SPR? Was it only made from BIOS3.rel and SCB.rel? I used:

Code:
link bnkbios3=bios3,scb[b,os,nr]

Yes, seems to be identical to what I'm using:

Code:
A>LINK BNKBIOS3=BIOS3,SCB[B,OS,NR]

EDIT: The jump table looks intact in BNKBIOS3 though?
 
Last edited:
I'm not sure where to go next. I use the same files you posted here, and I get a valid jump table for the BIOS in the SPR file.

Code:
O>
O>a:link bnkbios3=bios3-2,scb[b,os,nr]
LINK 1.31

@SEC     FE5C   @MIN     FE5B   @DATE    FE58   @HOUR    FE5A    
@BNKBF   FE35   @AIVEC   FE26   @CIVEC   FE22   @ERMDE   FE4B    
@AOVEC   FE28   @COVEC   FE24   @LOVEC   FE2A   @MXTPA   FE62    
@FX      FE43   @MEDIA   FE54   @CRDMA   FE3C   @BFLGS   FE57    
@CRDSK   FE3E   @ERDSK   FE51   @RESEL   FE41   @USRCD   FE44    
@VINFO   FE3F   @MLTIO   FE4A    

ABSOLUTE     0000    
CODE SIZE    0B12 (0000-0B11)
DATA SIZE    0C59 (0C00-1858)
COMMON SIZE  0000
USE FACTOR     16

O>a:dump bnkbios3.spr


CP/M 3 DUMP - Version 3.0
0000: 00 59 18 00 00 00 00 00 00 00 12 0B 00 00 00 00  .Y..............
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0100: C3 F0 01 C3 1A 03 C3 59 05 C3 2C 05 C3 10 05 C3  .......Y..,.....
0110: 6B 00 C3 6B 00 C3 6A 00 C3 8F 05 C3 74 05 C3 92  k..k..j.....t...
0120: 05 C3 97 05 C3 9C 05 C3 EB 05 C3 18 06 C3 67 00  ..............g.
0130: C3 A7 05 C3 25 05 C3 6A 00 C3 67 00 C3 63 00 C3  ....%..j..g..c..
0140: 66 00 C3 E9 01 C3 ED 01 C3 EE 01 C3 C5 01 C3 EF  f...............
0150: 01 C3 CA 01 C3 A3 05 C3 C9 01 C3 00 00 C3 00 00  ................
Press RETURN to continue 
O>
 
What files does GENCPM require to create CPM3.SYS? And yes, my LINK also produces a valid jump table in the BNKBIOS3.SPR file (see the one in the zip file in the earlier post for confirmation.)
 
I think just by a process of elimination the issue must be to do with GENCPM. The SPR files all seem normal (or at least the jump tables aren't corrupted in them). I wonder if it's worth trying to source another copy of it from elsewhere?
 
Looking at the pattern of corruption, it is as if those 9 bytes got zeroed sometime before GENCPM relocated them. The bitmap in the SPR tells GENCPM to add F4 (in this case) to certain bytes, turning C3 00 00 00 00 00... into C3 00 F4 00 00 F4... But, GENCPM probably does not have a bug (it works elsewhere). That being said, when I run GENCPM on these SPR files, I get the same corruption. It may take some reflection to figure out what might be going wrong.
 
Looking at the pattern of corruption, it is as if those 9 bytes got zeroed sometime before GENCPM relocated them. The bitmap in the SPR tells GENCPM to add F4 (in this case) to certain bytes, turning C3 00 00 00 00 00... into C3 00 F4 00 00 F4... But, GENCPM probably does not have a bug (it works elsewhere). That being said, when I run GENCPM on these SPR files, I get the same corruption. It may take some reflection to figure out what might be going wrong.

Yes, it's a real head-scratcher. I'm getting the same output from GENCPM in the SIMH Altair simulator too. I've got my fingers crossed that Dave's walk will have nudged a few ideas loose. ;)
 
It is also just possible that one (or more) .SPR files contain something later on that ends up over the 'top of' the jump table when GENCPM relocates them? So, even though the .SPR file contains the 'correct' jump table (ready for relocation) something else is being loaded after the BIOS CSEG 'over the top of' it. Just a thought.

The other thing I did was to read the CP/M 3 System Guide manual (I know, last resort!) and searched for the text SPR. I came across something that I had not seen before about symbols assigned as FExxH being relocated to the SCB. I notice that the entire SCB.ASM file starts at 0xFE00 for its symbols. Does this ring any bells with you durgadas311?

Dave
 
It is also just possible that one (or more) .SPR files contain something later on that ends up over the 'top of' the jump table when GENCPM relocates them? So, even though the .SPR file contains the 'correct' jump table (ready for relocation) something else is being loaded after the BIOS CSEG 'over the top of' it. Just a thought.

Dave

Interesting possibility - what comes before the BIOS? BDOS? Surely GENCPM wouldn't allow modules to overwrite each other though?

Another though just occurred whilst looking at the CPM System Guide - when I use GENCPM, the last question I get is "Accept new system definition (Y) ?" But the manual lists a whole load of memory banking-related questions, like number of memory segments, hashing and drive questions... none of these come up when I use GENCPM... Is that a problem? (I'm just using the default GENCPM answers, which includes a positive reply to the banking question.)
 
A 'decent' tool shouldn't allow anything to be overwritten - or at least should generate a warning.

The way SPR files seem to work is that there is one bit for each byte that needs relocating - so this shouldn't really happen. I am just having a look at the SPR bitmap now to see if something has gone silly though.

Can you post the GENCPM.DAT file (this should be the default answer file that is being used).

Dave
 
Yeah, GENCPM will special-case addresses that match FExx and make those relative to the SCB. But the SPR file should not have any addresses that "naturally" look like FExx (before relocation).

I keep wanting to blame this on SPR content, as daver2 suggests, but I can't reason it out. The SPR files are binary images with an appended bitmap to indicate where relocatable addresses are. So, the SPR cannot back-up the location counter like a REL file could. I could not find any such anomaly in the REL file, plus we know the SPR file is correct. I'm looking at my virtual H89 memory right now, after the GENCPM. Can't find the BIOS, but it is trial and error mostly. My thought is to either try running it under SID or else use the simulation debug tools to try and figure it out. Unfortunately, GENCPM is written in PL/M so it is more difficult to debug on a binary level.
 
I've made some progress. Using SID to run GENCPM, I was able to determine that the corruption (zeroing of 9 bytes) occurs somewhere between loading BNKBIOS3.SPR and relocating the image (exclusive). So, after the load the jump table is OK, but before the call to relocate it is corrupt. I'll run a few more times and see if I can bisect to where it is happening.
 
A 'decent' tool shouldn't allow anything to be overwritten - or at least should generate a warning.

The way SPR files seem to work is that there is one bit for each byte that needs relocating - so this shouldn't really happen. I am just having a look at the SPR bitmap now to see if something has gone silly though.

Can you post the GENCPM.DAT file (this should be the default answer file that is being used).

Dave

Here's the GENCPM.DAT (although the default option is not to create one, so I don't think I tend to use it?):

Code:
A>type gencpm.dat
PRTMSG   = Y
PAGWID   = 4F
PAGLEN   = 17
BACKSPC  = N
RUBOUT   = Y
BOOTDRV  = A
MEMTOP   = FF
BNKSWT   = Y
COMBAS   = C0
LERROR   = Y
NUMSEGS  = 03
MEMSEG00 = 00,80,00
MEMSEG01 = 00,C0,02
MEMSEG02 = 00,C0,03
MEMSEG03 = 00,C0,04
MEMSEG04 = 00,C0,05
MEMSEG05 = 00,C0,06
MEMSEG06 = 00,C0,07
MEMSEG07 = 00,C0,08
MEMSEG08 = 00,C0,09
MEMSEG09 = 00,C0,0A
MEMSEG0A = 00,C0,0B
MEMSEG0B = 00,C0,0C
MEMSEG0C = 00,C0,0D
MEMSEG0D = 00,C0,0E
MEMSEG0E = 00,C0,0F
MEMSEG0F = 00,C0,10
HASHDRVA = Y
HASHDRVB = Y
HASHDRVC = Y
HASHDRVD = Y
HASHDRVE = Y
HASHDRVF = Y
HASHDRVG = Y
HASHDRVH = Y
HASHDRVI = Y
HASHDRVJ = Y
HASHDRVK = Y
HASHDRVL = Y
HASHDRVM = Y
HASHDRVN = Y
HASHDRVO = Y
HASHDRVP = Y
ALTBNKSA = N
ALTBNKSB = N
ALTBNKSC = N
ALTBNKSD = N
ALTBNKSE = N
ALTBNKSF = N
ALTBNKSG = N
ALTBNKSH = N
ALTBNKSI = N
ALTBNKSJ = N
ALTBNKSK = N
ALTBNKSL = N
ALTBNKSM = N
ALTBNKSN = N
ALTBNKSO = N
ALTBNKSP = N
NDIRRECA = 01
NDIRRECB = 01
NDIRRECC = 01
NDIRRECD = 01
NDIRRECE = 01
NDIRRECF = 01
NDIRRECG = 01
NDIRRECH = 01
NDIRRECI = 01
NDIRRECJ = 01
NDIRRECK = 01
NDIRRECL = 01
NDIRRECM = 01
NDIRRECN = 01
NDIRRECO = 01
NDIRRECP = 01
NDTARECA = 01
NDTARECB = 01
NDTARECC = 01
NDTARECD = 01
NDTARECE = 01
NDTARECF = 01
NDTARECG = 01
NDTARECH = 01
NDTARECI = 01
NDTARECJ = 01
NDTARECK = 01
NDTARECL = 01
NDTARECM = 01
NDTARECN = 01
NDTARECO = 01
NDTARECP = 01
ODIRDRVA = A
ODIRDRVB = A
ODIRDRVC = A
ODIRDRVD = A
ODIRDRVE = A
ODIRDRVF = A
ODIRDRVG = A
ODIRDRVH = A
ODIRDRVI = A
ODIRDRVJ = A
ODIRDRVK = A
ODIRDRVL = A
ODIRDRVM = A
ODIRDRVN = A
ODIRDRVO = A
ODIRDRVP = A
ODTADRVA = A
ODTADRVB = A
ODTADRVC = A
ODTADRVD = A
ODTADRVE = A
ODTADRVF = A
ODTADRVG = A
ODTADRVH = A
ODTADRVI = A
ODTADRVJ = A
ODTADRVK = A
ODTADRVL = A
ODTADRVM = A
ODTADRVN = A
ODTADRVO = A
ODTADRVP = A
OVLYDIRA = Y
OVLYDIRB = Y
OVLYDIRC = Y
OVLYDIRD = Y
OVLYDIRE = Y
OVLYDIRF = Y
OVLYDIRG = Y
OVLYDIRH = Y
OVLYDIRI = Y
OVLYDIRJ = Y
OVLYDIRK = Y
OVLYDIRL = Y
OVLYDIRM = Y
OVLYDIRN = Y
OVLYDIRO = Y
OVLYDIRP = Y
OVLYDTAA = Y
OVLYDTAB = Y
OVLYDTAC = Y
OVLYDTAD = Y
OVLYDTAE = Y
OVLYDTAF = Y
OVLYDTAG = Y
OVLYDTAH = Y
OVLYDTAI = Y
OVLYDTAJ = Y
OVLYDTAK = Y
OVLYDTAL = Y
OVLYDTAM = Y
OVLYDTAN = Y
OVLYDTAO = Y
OVLYDTAP = Y
CRDATAF  = N
DBLALV   = Y

I keep wanting to blame this on SPR content, as daver2 suggests, but I can't reason it out. The SPR files are binary images with an appended bitmap to indicate where relocatable addresses are. So, the SPR cannot back-up the location counter like a REL file could. I could not find any such anomaly in the REL file, plus we know the SPR file is correct. I'm looking at my virtual H89 memory right now, after the GENCPM. Can't find the BIOS, but it is trial and error mostly. My thought is to either try running it under SID or else use the simulation debug tools to try and figure it out. Unfortunately, GENCPM is written in PL/M so it is more difficult to debug on a binary level.

Let me know if you've got the same results if you've tried building CPM3.SYS with GENCPM. I'm just dumping the output CPM3.SYS file and the corrupt jump table is at 0C80.
 
I've made some progress. Using SID to run GENCPM, I was able to determine that the corruption (zeroing of 9 bytes) occurs somewhere between loading BNKBIOS3.SPR and relocating the image (exclusive). So, after the load the jump table is OK, but before the call to relocate it is corrupt. I'll run a few more times and see if I can bisect to where it is happening.

Just missed this with my last post - excellent news! But it's sounding like a bug with GENCPM then rather than a (more fixable) issue with the ZMAC/LINK outputs?
 
I am looking through the PL/M source for GENCPM at the moment.

So, what you are saying is that "call load(.bios$fcb,.bios$atts);" seems to be OK whereas when we get as far as "call reloc$module(.bios$fcb);" it has gone south?

Between those two points are "call page$chop;" and 'some other stuff'.

EDIT: It is not necessarily a bug in GENCPM if it is being fed something 'duff' in the SPR file still. There seems to be a lot of 'maths' going on with the file attributes in GENCPM...

Dave
 
I figured out the problem. Basically, the template BIOS I gave you had a bogus implementation for the "drvtbl" function and thus it sent GENCPM off into the weeds and corrupted the BIOS image in memory. I should have reviewed the docs more, and compared better to my old BIOSes. Anyway, here is a modified BIOS3 that fixes the drvtbl function and produces a non-corrupted CPM3.SYS.

View attachment BIOS3.ASM.txt

Basically, GENCPM (the only user of the "drvtbl" entry?) expects the returned address to be a pointer to a table of 16 pointers to DPHs, not a table of DPHs. Garbage in, garbage out.
 
And I think I have found it in GENCPM.PLM in the need$tbl procedure:

call movef(9,.(0,0,0,0,0,0,0,0,0),dph$adr+2);

Dave
 
Awesome stuff - that's sorted the issue with the jump table!! Well spotted, durgadas311 and thanks for the corrected bios. :bigups:

I'm still not out of the woods yet, though :( - I'm getting a CCP.COM error now (looks like the filename isn't being constructed properly?)

Code:
CP/M V3.0 Loader
Copyright (C) 1982, Digital Research

 BNKBIOS3 SPR  F400  0C00
 BNKBIOS3 SPR  B300  0D00
 RESBDOS3 SPR  EE00  0600
 BNKBDOS3 SPR  8500  2E00

 59K TPA
BIOS3: Preparing MMU...
BIOS3: Initialising SIO...
Z80 MINICOM II CP/M Plus BIOS 1.0.0 by J.Nock 2017

CP/M Plus Copyright 1982 (c) by Digital Research

CP/M Error On /: Invalid Drive
BDOS Function = 15  File = CCP    C.OM

It's looking for an invalid drive and a file called CCP C.OM? Is there a missing space in one of the ccp$fcb definitions somewhere? I've added a space into the filename here:

Code:
ccp$fcb:			.DB	0,'CCP     COM',0,0,0,0

There were only 3 chars (CCP) + 4 chars (spaces) before the COM - I'm guessing that the string should make up the 8+3 format for CPM? So I added an extra space after CCP to make 8 chars before COM, but it doesn't seem to have made any difference to the CCP C.OM issue... I'm guessing here, admittedly.

EDIT: Actually, perhaps it does make a difference. I've just tried launching CPMLDR again and this time there was no invalid drive or filename error - the system just seems to hang after the BIOS3 signon message with no prompt.
 
Last edited:
Back
Top