PDA

View Full Version : Writing a driver for CP/M 3



JonB
March 2nd, 2017, 10:15 AM
Hi

I need to write an IDE device driver for CP/M 3 ("plus"). I'm quite new to this, so what are my options?

Patch the BIOS like I did for CP/M 2.2?
Write a runtime loadable driver? RSX or some such..
Some other way?



A little background.

It's for the Amstrad CPC6128 CP/M implementation. The newer versions support FID files ("field installable driver") and I successfully wrote one for the Amstrad PCW machine. However it doesn't seem to work on the CPC6128's CP/M Plus, and that is after changing the code to be CPC compatible. The FID is just not being loaded at startup.

Any pointers would be great!

Thanks
JonB

Yes, I'm off to read the CP/M 3 alteration guide next, before someone says "RTFM". :)

geoffm3
March 2nd, 2017, 10:37 AM
Interesting. Did any other implementations of CP/M BIOS have this scheme? I have been toying with the idea of writing my own CP/M 3.0+ BIOS for the Coleco ADAM and that would likely solve several problems as there's a variety of different add-on hardware for serial/parallel ports and whatnot.

JonB
March 2nd, 2017, 11:02 AM
What scheme, the FID files? No, they were Amstrad only. CP/M 3 has relocatable system extensions loaded at boot time called RSX files. Similar but not the same as FIDS.

Pepinno
March 2nd, 2017, 12:47 PM
Hi

I need to write an IDE device driver for CP/M 3 ("plus").
(...)
It's for the Amstrad CPC6128 CP/M implementation.

How are you attaching the IDE disk to the CPC6128 computer?

JonB
March 2nd, 2017, 10:18 PM
Using uIDE-16:

http://www.cpcwiki.eu/index.php/UIDE_Universal_IDE_adapter_cards_for_Z-80_computers

For example: http://www.cpcwiki.eu/forum/amstrad-cpc-hardware/cpc-ide-adapter-anyone/?action=dlattach;attach=21967;image

But you can fit it internally using a Z80 shim card, like this:

http://www.cpcwiki.eu/forum/nc100-nc200-pcw-pda600/who-wants-ide-drives-on-the-pcw/?action=dlattach;attach=21819;image

So, looks like RSXes don't apply to BIOS extensions (they extend the BDOS). Hmmm...

JohnElliott
March 3rd, 2017, 10:55 AM
While RSXs are loaded and hooked into the BDOS function chain, there's nothing to stop them making modifications to the BIOS jumpblock or other parts of the system if that's what they want to do; the 'GET' and 'PUT' RSXs that are part of CP/M 3 hook into the BIOS character I/O functions.

If you download XLOGIN from http://www.seasip.info/Cpm/software/amstrad.html you'll see an example of a FID (xloginpw.z80) and an RSX (xloginrx.z80) that both do the same thing -- in this case, it's rewiring the Amstrad-specific DD LOGIN function, but the RSX should be a useful guide to how you load an RSX, check it's loaded into common memory and so on.

JonB
March 3rd, 2017, 09:48 PM
Thanks John, I'll check it out. Funnily enough a similar thought occurred to me in the shower this morning. Load an RSX then patch the BIOS to call the code within it. Maybe not such a lost cause after all...

durgadas311
March 10th, 2017, 04:59 PM
Sounds like you are making progress, but just in case... I have recently resurrected CP/M Plus on virtual H89 and Kaypro machines. Part of that was to port CP/NET to CP/M Plus for which I made it into an RSX (a "stay resident" (until told to remove) RSX). If an RSX is going to hook itself into the BIOS, there is a risk that it may get removed and make the OS unusable.

The implementation of CP/M Plus I am working with uses linkable device drivers (actually, the entire BIOS is modular). But that depends on how the BIOS source code is structured. I use RMAC to produce .REL modules, then LINK them into a working BNKBIOS3.SPR to use in GENCPM. I can then produce custom BIOS images based on desired hardware configuration.

Let me know if I can help.
Doug

JonB
March 17th, 2017, 11:24 AM
Oh yes, Doug! I'm sure you can help. :)

However... at the moment I am busy building uIDE-8 boards for the Amstrad PCW crowd (as John knows, I already wrote the driver for that, with his advice). So I will come back to this in the not too distant future!

In the meantime there is a question. How do I know a RSX is in the same memory space as the BIOS? Meaning by that, is there any guarantee that it won't be paged out on a banked system like the one on the Amstrad 6128?

durgadas311
March 18th, 2017, 07:33 AM
Forgive me if I'm repeating information you already know, but I figure a complete picture is better.

The original intent of RSXs was to intercept BDOS calls from a user program, thus the RSX design is to run in the user bank. So, using an RSX to intercept BIOS calls is a bit of a stretch. If the RSX is small enough (and/or the common memory size large enough) you could get around some of that. First off, you would have to intercept the BIOS calls in the common-memory jump table, as when the RSX first starts it won't have access to the system bank (it could, theoretically, switch banks but would have to make sure it managed that precisely). So, once the BIOS calls are intercepted, then the RSX would essentially pass-thru BDOS calls unaltered, I assume. The issue comes up when the BDOS makes BIOS calls that are intercepted by the RSX. I'm pretty sure those all happen when the system bank is enabled (at least when originating form the BNKBDOS), so the RSX would have be in common memory (at least the intercept routines). It's all a bit of a tap-dance as the banked parts of BDOS and BIOS interact with each other, the resident parts of BDOS and BIOS, and the user program - as well as with optional memory banks for various buffers.

So, using an RSX to extend the BIOS is going to be tricky and might not even work depending on how much common memory exists on the target system. Of course, extending the BIOS by using a linked-in module depends on whether the vendor implemented their BNKBIOS that way. It is the DRI recommendation that the BNKBIOS be modular, but they do not suggest much in the way of specifics. Also, without the vendor's BIOS source code, or at least the REL files and a description of the interfaces between modules, it becomes difficult.

All that being said, the BIOS is the "owner" of the banked memory implementation, so it usually keeps track of which bank is active (so if the RSX was banking other memory in/out it could know what bank to select before returning). Of course, interrupts also can be a problem, depending on how the BIOS manages memory banks there. The BDOS exposes the "SCB" (System Control Block) which are essentially a set of external symbols to key variables, some of which are related to memory banks. So, the RSX could gather enough information to keep from causing a banked-memory catastrophe. But, as your question points out, at the time a BIOS call is made you really can't expect that the whole RSX code is banked-in. In fact, most of the time it won't be banked-in.

I'm not familiar with the Amstrad 6128, but will see if some information is available to give me more information.

durgadas311
March 18th, 2017, 08:01 AM
I had another thought: It should be possible to write a BIOS-extension SPR and pre-pend it to the banked BIOS SPR. I'll have to check whether existing DRI tools can do that, but it's not terribly complicated. I'm been wanting to do the same thing on the BNKBDOS in order to incorporate CP/NET in a cleaner way (although CP/NET is much better suited to be an RSX than a BIOS driver would be). That way you just write a fake BIOS that passes through most calls but intercepts ones that pertain to the device you're adding. It would operate in the system bank of memory and might interface better to the BIOS facilities already being used by the BDOS.

RuudB
March 18th, 2017, 09:03 AM
Hallo allemaal,

I just happened to be confronted with the same question: how to write an IDE driver for CP/M?

I own a Bondwell 14 and I was able to give its life more meaning thanks to Larry Kraemer. I only had the few basic system disks for this system and Larry told me what programs to use so I could create some more disks with tools for it like Turbo Pascal. Working with TP I immediately got the same feeling as in 1986: I'm not a disk jockey and I need an hard disk drive. I remembered GIDE from the past but soon found out that it isn't available any more. To be sure, I wanted ask around here and bumped into this thread.

I'm not unfamiliar with HDDs: 1541IDE8 (http://www.baltissen.org/newhtm/1541ide8.htm). You will notice that I'm only using eight bits of the IDE-bus. And no, I'm not using the HDD or CF in 8-bits mode, I'm only using 8 bits. Instead of the normal 512 bytes sectors, I only have 256 bytes on a sector. Using only 8 bits has two advantages: 2) much less hardware needed (in fact I only need one single IC if I want to) and 2) it solved a Commodore related problem. The disadvantage: I can use only the half of the storage capacity of the HDD. Do I care? No. When connecting a 40 GB HDD it means I can "only" use 20 GB. Someone calculated that all Commodore software together is about 10 GB. So why worry about the lost 20 GB :)

Back to my question. I know two things: I have to change 1) the boot ROM to be able to boot from the HDD and 2) the BIOS to tell the system there is another drive present (that is, I assume it is done here). Regarding 2) I ran into an article that can help me a lot: a virtual disk for you Bondwell (http://www.eld.leidenuniv.nl/~moene/Home/museum/Bondwell12/bgg-vdisk/). Unfortunately for the most of you: it is in Dutch. Changing the boot ROM seems to be the problematic item. The reason: I have no knowledge of the file system at all so I have no idea where to look.

So any pointers, URLs or other help is highly appreciated :)

durgadas311
March 20th, 2017, 05:40 AM
My current thinking is to add a "BIOS intercept module" to BNKBIOS3.SPR. The banked-memory CP/M3 systems I've seen use a single BNKBIOS3.SPR file which contains both the CSEG (resident) and DSEG (banked) sections of the BIOS. One could write a BIOS extension that places a fake BIOS jump vector in CSEG and then adds code in DSEG. I think CP/M 3 has pretty much eliminated direct calling of the BIOS by user programs, although a given vendor was free to allow that. If the vendor used the "direct BIOS call" BDOS function, then the proper memory bank is switched-in before calling the BIOS. Otherwise, care must be taken to ensure the CSEG code switches banks before calling DSEG (and switches back before returning). Then, this BIOS extension is added to BNKBIOS3.SPR - which requires a program that I don't believe exists, although I need to write the same thing to install a BDOS extension for CP/NET. If your vendor's BIOS comes with .REL files (or, of course, source code), then you don't need to modify the SPR in order to extend the BIOS (you can link the extension with the vendor's REL files to make a new BNKBIOS3.SPR).

JonB
March 24th, 2017, 08:00 AM
OK... I think I can see a way, after reading some rather cryptic examples such as http://cirsovius.de/CPM/Projekte/Assembler/RSX/CPM2/CPM2RSX-MAC.txt. I'm writing an IDE driver, by the way.

I can't use the normal approach because I'm doing it for Amstrad CP/M Plus and it has none of the standard CP/M OS files.

Can I use a RSX? When loaded, it would patch the BIOS, pointing the BIOS disk vectors to routines within the RSX and setting a flag to prevent re-initialisation. Per a typical CP/M 2.2 driver, it would contain code to call the original disk I/O bios functions if the disk number (in C) isn't mapped to the new device (IDE), otherwise, call the IDE replacement vectors. It would also contain the IDE DPB, dirbuff, ALV buffers.

Other than that, as an RSX, it is a no op, it doesn't intercept any BDOS calls. Would this work? I'm thinking memory banks - what happens if the RSX switched out at the time of the BIOS call? When the BIOS is jump table patched, it needs to point to code in the RSX, and the RSX must point to the original vectors.

So far my reading suggests that the top of the TPA is common but this stuff is so badly explained (by DRI) that I cannot be sure.

JonB
March 24th, 2017, 08:11 AM
Hallo allemaal,

I just happened to be confronted with the same question: how to write an IDE driver for CP/M?

I own a Bondwell 14 and I was able to give its life more meaning thanks to Larry Kraemer. I only had the few basic system disks for this system and Larry told me what programs to use so I could create some more disks with tools for it like Turbo Pascal. Working with TP I immediately got the same feeling as in 1986: I'm not a disk jockey and I need an hard disk drive. I remembered GIDE from the past but soon found out that it isn't available any more. To be sure, I wanted ask around here and bumped into this thread.

I'm not unfamiliar with HDDs: 1541IDE8 (http://www.baltissen.org/newhtm/1541ide8.htm). You will notice that I'm only using eight bits of the IDE-bus. And no, I'm not using the HDD or CF in 8-bits mode, I'm only using 8 bits. Instead of the normal 512 bytes sectors, I only have 256 bytes on a sector. Using only 8 bits has two advantages: 2) much less hardware needed (in fact I only need one single IC if I want to) and 2) it solved a Commodore related problem. The disadvantage: I can use only the half of the storage capacity of the HDD. Do I care? No. When connecting a 40 GB HDD it means I can "only" use 20 GB. Someone calculated that all Commodore software together is about 10 GB. So why worry about the lost 20 GB :)

Back to my question. I know two things: I have to change 1) the boot ROM to be able to boot from the HDD and 2) the BIOS to tell the system there is another drive present (that is, I assume it is done here). Regarding 2) I ran into an article that can help me a lot: a virtual disk for you Bondwell (http://www.eld.leidenuniv.nl/~moene/Home/museum/Bondwell12/bgg-vdisk/). Unfortunately for the most of you: it is in Dutch. Changing the boot ROM seems to be the problematic item. The reason: I have no knowledge of the file system at all so I have no idea where to look.

So any pointers, URLs or other help is highly appreciated :)

Hi Ruud

Please don't hijack my thread. Start a new one. But I will say that what you could use (hardware wise) is one of these: http://www.cpcwiki.eu/index.php/UIDE_Universal_IDE_adapter_cards_for_Z-80_computers

uIDE-8 is my own design (albeit derivative - but then, there are only so many ways to connect an IDE device to a bus!) and I supply them. They are conceptually similar to GIDE but far simpler and easier to build (cheap too, if you build it yourself). Only 2 ICs and a transistor, even simpler than 1541ide8 (but then, it is unbuffered), yet it allows configuration of its I/O base address via a set of jumpers. For the Bondwell, I'd use a Z80 shim card and uIDE-8, plus a 128 Mb DOM.

If your Bondwell has CP/M 2.2 I have a driver suite already that we might be able to port to it. The suite is called xdriver and was originally written for Lifeboat CP/M 2.2 on the TRS-80 Model II. You can read about its capabilities here: http://www.vcfed.org/forum/showthread.php?55487-TRS-80-Model-II-Lifeboat-CP-M-LoTech-IDE-Adapter-Extended-Driver-v1-9 (http://www.vcfed.org/forum/showthread.php?55487-TRS-80-Model-II-Lifeboat-CP-M-LoTech-IDE-Adapter-Extended-Driver-v1-9&highlight=xdriver+1.9). Look at the readme file in the first post, and note in particular the installation instructions.

The xdriver's loader initialises the IDE device for 8-bit transfer, so no capacity is lost on the device. 128Mb is supposed to be the theroretical maximum that CP/M 2.2 can handle (16 drives of 8MB). Moreover, you can use cpmtools to directly access the data on the drive - I have a set of diskdefs for it - so mass file transfer is easy. No messing with floppies. Also, you can use a slave IDE device for a total of 32 x 8 MB drives and map them to the CP/M drives at will using the XMAP utility that is provided with the driver.

I only distribute the driver binaries though, so you would need to collaborate with me to produce a Bondwell version. It is a matter of locating the BIOS jump table and CP/M DIRBUFF vector. And you can do this with a few simple commands.

By the way, I have a Philips P2000C here (the doyenne of the Dutch 8 bit computer scene as was). It's got a built in SASI interface, to which is connected a SCSI2SD card. It boots from the SD device, but the in built driver doesn't allow for much drive space (4x5MB drives max).

Regards
JonB