I'm writing a CF adapter driver for a vanilla CP/M 2.2 implementation. The read and write routines are already written and working on a different CP/M device. They use a non standard interface because they're patched into an existing ram disk driver, but both need the (logical) sector and CP/M buffer address to function, so it should be straightforward to port across.
I have a DPB and DPH. The DPH is actually the one for Disk 3, with an alternative DPB vector patched in. This is a temporary measure (since there is no Disk 3 on my system). The CF card is going to be Disk 4 (E: in CP/M).
I've written a bunch of alternative BIOS routines to implement the CF driver. Each one jumps to the original routine if the current drive (stored in sdisk) is not 4 (E:). What follows is the functional description of the CF card part of them.
- HOMEDSK: Copy 0 to BC and jump to SETTRK.
- SELDSK: Copy selected drive number from C to local address (sdisk). Load address of CF card DPH into HL.
- SETTRK: Copy track (in BC) to local address (strack). strack is unused by the driver, it is just there for debug purposes.
- SETSEC: Copy sector (in BC) to local address (slsec).
- SETDMA: Copy DMA (in BC) to local address (sdma).
- SECTRAN: Copy logical sector (in BC) to HL (no translation for CF Card, as write and read routines do this themselves).
- READDSK: Read a sector from CF card. Compute head, cylinder, sector from value in local address (slsec). Copy data to local buffer (sdma).
- WRITEDSK: Write a sector from local buffer (sdma) to CF card. Compute head, cylinder, sector from value in local address (slsec).
The driver code sits at the top of memory from FC00. To make room for this, I used MOVCPM to relocate the BDOS and BIOS down by 1K. The CP/M sign-on message now says "63k CP/M" instead of "64k CP/M".
The driver loader comprises of a piece of code to copy the driver into high memory and then patch the BIOS jump table with my new vectors, as well as the DPB vector in Disk 4's DPH. The driver is assembled separately with ORG FC00 (top 1K of memory) and combined with the loader so that it can copy it to high memory. Several special addresses have to be hand patched into the loader code with reference to the driver's .LST (assembly output) file.
What's happening is the driver is getting loaded to the correct address and the BIOS jump table / DPB vectors are getting patched correctly. However, on warm boot after driver load it hangs, which is a bit odd because with drive A: the patched code should just be passing through to the original driver code. I have traced this in ZSID and found it to be so... so there must be a bug somewhere, which I am having difficulty locating.
I haven't even got to the bit where I try to access drive E: (the CF card).
Any comments on the approach so far?