Printed Amstrad Addict magazine announced, check it out here!

Main Menu

FID files and multiple drives

Started by JonB, 17:48, 20 January 17

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


One for the FID experts.

Most of my information comes from

I have got my IDE driver to a working state, and I would like to allocate multiple drives in its FID_EMS routine. This means calling the SVC_D_HOOK several times. Each time it is called, I pass the same DPT (which is right, as all drives have the same parameters) and the same ALV buffer size. I expect SVC_D_HOOK to allocate a new ALV buffer for each call, and (on successful return) I retrieve the drive ID and use it to build a map of drive ID to IDE partition number. This is then used in the FID read/write routines to choose the correct IDE partition for the corresponding drive ID.

So far, so good; only it doesn't quite work. So what I have done instead is to hard code the IDE partition ID into two copies of the FID. One uses IDE partition 0, the other partition 1, but they load separately (which takes time), and of course there is more memory usage. But this does work. Today I successfully copied all of the PCW CP/M files onto C: from B:, then from C: to D: (which was pretty fast!).

I guess my question is about other IDE driver implementations. Do any of them support multiple IDE drives from one FID? If so, I know that my mapping scheme will work, as it does on my CP/M 2.2 IDE driver.



Sounds like you're making great progress.

I don't know the answer to your question, but I suspect that back in those days, few people would have wondered about adding more than 1 HD to any computer.   Even having 1 HD to add was a major thing, whichever way you looked at it.

I don't remember any mention of any of the add-on HDs being any more than 'a' HD, as in singular.

Could the original PC(XT) cope with more than 1 HD?

I understand that reference to the Joyce emulator may be a total aside, but that will allow HDs of C: thru to P: (excl M: which is already assigned).   That used only the one FID file.   Did you get around to dis-assembling that file?

Best wishes,



No, Geoff not yet. It started working, and besides it's far better to work this out for myself. Therein lies the satisfaction, despite the questions I've asked to speed things up.

So. I think it's possible to implement up to 6 drives under CP/M and only one tiny little FID. They are really partitions on a single physical drive, although the TRS-80 driver supports 32 partitions across 2 separate devices (master/slave) under CP/M 2.2., You can only access 16 at any one time, but you can map any of the 32 partitions to any drive letter using a utility I wrote. But due to the limitations of the FID under CP/M 3, I think there's little point in implementing drive mapping on the PCW.

I'm definitely getting closer. Now, what about the hardware? That is next up.


I think this will do nicely...


Some notes:

  • It's yellow because my 9512 is plugged into a TV with an amber filter fixed over the screen.
  • B: is missing because I hadn't logged it in prior to doing SHOW.
  • Drives have different capacities because I've copied stuff onto them to test they work.
  • Drives with 8,144k have no files so are showing the full capacity.


If you have the time to read my other post:
I wonder how you figured out the multiple drive in one FID problem. So far I have managed to get two drives registered in my FID but as soon as I request a third I get the 'device not available' response.
My IDE drive/DOM is connected (in 16 bit mode) to a 8255 PPI and works really nice already but at the moment limited to only two extra drives.


John Elliot helped me to patch the BDOS.

In other words, I cheated!


Quote from: JonB on 21:17, 10 August 21
John Elliot helped me to patch the BDOS.

In other words, I cheated!
;D   Nicely done. I managed to get 4 drives without cheating and for now that is fine. I am now adding the second UART channel to the system, it is connected to an ESP8266.. WiFi on the PCW


The thing is, the FID itself is hacking the svc_d_hook call to trick it into allowing the additional drives. All credit to JohnElliot for that one. The patch code is smarter than just poking into memory; it searches for the data sequence to patch and if not found the driver will just allocate the limited drives with the unpatched svc_d_hook. In other words, if you run it on a different version of CP/M with a different svc_d_hook it won't crash the system and you can still access the first few partitions on IDE drive.

Here's how I implemented it.

; Now we need to find the code
; 11 11 00 CD xx xx D2 xx xx FD 75 10 FD 74 11
; and replace CD xx xx D2 xx xx with
;             21 (dpbaddr) 37 00 00
ld hl,svc_d_hook ; start at the hook function entry point

ploop: ld (f_ptr),hl ; store it
call find ; look for pattern
jr nz,nloop ; not found?

cp 0C9h ; end of SVC? (C9h = RET instruction)
jr z,dralloc ; yes, just do the normal allocation

cp 0FFh ; was it found?
jr z,dopatch ; issue patch

nloop: ld hl,(f_ptr) ; otherwise, restore SVC pointer
inc hl ; advance it
jr ploop ; restart the check

dopatch: ; at this point, hl points to the first XX
dec hl ; .. so step back a byte
ld d,h ; move into de for LDIR
ld e,l ;
ld hl,replpatch ; start of patch code
ld bc,RP_BYTES ; length of patch
ldir ; copy patch to SVC
jr next ; jump to allocation routine iteration

find: ld bc,findpatch ; start of patch
floop: ld a,(bc) ; get patch byte
cp 0FFh ; end of pattern?
ret z ; yes, match found

cp (hl) ; compare pattern byte with SVC byte
ret nz ; no match, exit

ld a,0C9h ; check for RET instruction (end of SVC)
cp (hl) ;
ret z ; drop out now

inc hl ; advance pointers
inc bc ;
jr floop ; loop back for next byte

dralloc:ld (drvcnt),a ; save index down
ld b,0FFh ; get next available drive
ld de,ddjump ; setup disk device jump block
ld hl,512 ; alv buffer size max
ld ix,0 ; no directory checksum needed
ld iy,0 ; no hash table needed
call svc_d_hook ; add drive
jr nc,check ; if error, skip allocation

call domap ; update drive map and string

next: ld a,(drvcnt) ; get loop counter
inc a ; increment it
cp CF_MAXDRIVES ; done?
jr z,done ; yes, end the loop
jr dralloc ; no, loopback for next drive

check: cp 2 ; check for drive in use
jr z,next ; loop back if so (out of memory drops out)



; pattern to search for (FF terminator)
findpatch: db 11h, 11h, 00h, 0CDh, 0FFh

; patch code
replpatch: db 21h
dpbaddr: dw 0 ; Points to first allocated DPB
db 37h, 0, 0

Powered by SMFPacks Menu Editor Mod