Hiya, I've been implementing a fake block device driver in Pyromaniac and found that I was unable to access the hard disc files used by RPCEmu. All I was doing was the (I thought) most obvious solution of treating the disc file as a raw sequence of bytes. That's not how the HDF works, and from reading the ide.c source in loadhd and a clue from David Thomas, I see that it does some jumping around to decide whether it should skip 512 bytes at the start of the file.
There's no justification given in the comments, so I tried to work out a reason for it. Other than 'leaving space for a potential header in the future, but still working with raw disc dumps', I couldn't come up with one. It would be handy if such things were described, so in my implementation I've left some commentary of this to explain it in the future. I offer that code and commentary in case it helps someone to improve the existing RPCEmu (ie someone could explain why this juggling is done), or someone can explain where it's wrong and I can update my code. This is python code, and it's based an an existing BlockData class which provides the guarded access to the disc image between a given offset and size: ---- class HDFBlockData(BlockData): """ Handle a block file for a HDF file, as used by RPCEmu. These files are based around the storage of a harddisc image as written by the controller in RPCEmu using the parameters stored in the FileCore disc record at the start of the disc (disc address &C00). However, there is the potential for all the disc data to be offset by 512 bytes. The algorithm basically allows the HDF reader to read a raw FileCore image if one has been given, but defaults to the image being at offset 512. The result is that newly created discs will have the 512 byte header. Existing discs which skip a 512 byte header will be just fine. Existing, and newly ripped, discs that are just a dump of the disc contents will be fine. There's a risk that another format might have data in these low sectors but then the chance of those discs being supplied to RPCEmu is low, so this is probably reasonable. The probable reason for this offset was that some header containing metadata could be included in the future. However, no such metadata is used or present at the current time. """ def __init__(self, *args, **kwargs): super(HDFBlockData, self).__init__(*args, **kwargs) # First read some data from the start of the file. sector_c00 = bytearray(self.read(DiscTransfer(address=0xc00, size=0x200), 0x200)) sector_e00 = bytearray(self.read(DiscTransfer(address=0xe00, size=0x200), 0x200)) if len(sector_c00) < 0x200 or len(sector_e00) < 0x200: # This disc is short, so we'll do no manipulation at all. return secspertrack_c00 = sector_c00[0x1c1] heads_c00 = sector_c00[0x1c2] secspertrack_e00 = sector_e00[0x1c1] heads_e00 = sector_e00[0x1c2] offset = 0 if secspertrack_e00 != 0 and heads_e00 != 0: # The two fields we're using as our basis are valid at offset 512. So # we use that. So there is a disc record here, we'll use it. print("HDF disc record lives at offset 512 + 0xc00") offset = 512 elif secspertrack_c00 == 0 and heads_c00 == 0: # The two fields aren't valid without any offset. We will apply the # offset of 512. print("HDF disc record not present so assumingdisc offset at offset 512") offset = 512 else: # There was a disc record at offset 0, so we use that. print("HDF disc record lives at offset 0 + 0xc00") offset = 0 if offset: # We need to change the data access offsets for this data so that we only # access the actual data which RISC OS expects to see. self.close() if self._initial_limit: self._initial_limit -= offset self.data_offset += offset ---- It's not at all complex, but it matches the results of what loadhd does, and allows me to mount existing .hdf files and raw dumps of a disc. -- Charles Justin Ferguson [ All information, speculation, opinion or data within, or attached to, this email is private and confidential. Such content may not be disclosed to third parties, or a public forum, without explicit permission being granted. ] _______________________________________________ RPCEmu mailing list RPCEmu@riscos.info http://www.riscos.info/cgi-bin/mailman/listinfo/rpcemu