Closed tobiasvl closed 2 years ago
Good thought. It sure would be nice to have this kind of compatibility, but I don't think it is possible.
First, because of the size limits you mention. Especially ROMs for the older systems will easily and quickly go over the size limit. And I don't want to encourage people reducing their descriptions to a haiku to fit it in with the ROM 😄 Also, this would introduce new uncertainty for newcomers, since some CBF files run just fine while others are way too large to even fit in CHIP-8 memory. What's this new madness..?! 😉
Second, because the bytecode segment is basically just a CH8 file, to be loaded into memory at 0x200. If you load a CBF ROM at 0x200, all the jumps, index register loads and other offsets will be wrong, because the ROM would expect to have been loaded at 0x200, but is now at [header size]+0x200.
An alternative that we have explored in the discord channel is to have a fixed header size of 512 bytes. That way an interpreter could load a CBF file into memory starting from address 0x000, the ROM would nicely align to 0x200, and all would be well. However, that severely reduces the amount of information that can be present in the header, while simultaneously not really achieving the goal of proper "binary compatibility", because CBF ROMs would need to be loaded at 0x000 while CH8 ROMs would need to be loaded at 0x200.
So yeah, would love to have it, but I don't think it's even really possible. And if it is, it needs to modify the original CH8 ROM (either to fit in meta-data or to fix all the addresses) which I think is a shame (and adds a lot of complexity) and it will also severely limit the amount of meta-data that we can add, greatly reducing its usefulness IMO.
Which is why, in the end, this is the current proposal. You either support the format (and load the bytecode segment into 0x200 to run) or you don't, and your interpreter will not know what to do with this file format. Which is unfortunate, but at least it's predictable and allows for only a single interpretation.
Currently, CBF's magic number starts with
0x43 0x42
, which translates to the CHIP-8 instruction "skip the following instruction ifV3
does not contain0x42
.The next instruction is then
0x46 0x??
(the rest of the magic number followed by the platform signifier). It would be fair to assume that for most CHIP-8 interpreters, this instruction will be skipped sinceV3
probably doesn't contain0x42
.The following instruction is the pointer to the bytecode segment. As I read the spec, this is just the address where the bytecode starts.
This offset should IMO always start with a
0x1
(ie. the jump instruction,0x1NNN
), so that CHIP-8 interpreters that don't support CBF will encounter this offset after skipping the initial header, and then interpret the offset as a jump to the actual bytecode.In the current CBF version, the offset is probably likely to be
0x0FFF
, and so will be interpreted as a machine code routine call, which is unsupported by the vast majority of emulators (and even if it were supported, it would crash since the CHIP-8 bytecode isn't machine code). Offsets between0x1000
and0x2FFF
would be interpreted as jumps or calls; jumps would be fine, as I argue here, and probably subroutine calls too, although it would leave a stray entry in the call stack. After that, though, all bets would be off.)