I have code like this for computing a packed address:
if self.version < 4:
return 2 * address
elif self.version < 6:
return 4 * address
elif self.version < 8 and is_routine:
return 4 * address + (8 * self.routine_offset)
elif self.version < 8:
return 4 * address + (8 * self.string_offset)
else:
return 8 * address
That seems to match what the spec is telling me in section 1.2.3.
A decompilation of Zork 0 shows the following:
Routines offset: 0e930
Strings offset: 362e0
So those are the addresses I should get. I’ll focus on the routines offset here. I try to get those addresses via:
self.routine_offset = self.get_word(0x28)
self.string_offset = self.get_word(0x2A)
Here my get_word()
implementation is this:
def get_word(self, address: int) -> int:
return (self.memory[address] << 8) + self.memory[address + 1]
Here’s the problem. When I use the above calculation on Zork 0 v6, the following branch path is (correctly) executed:
return 4 * address + (8 * self.routine_offset)
However on that Zork 0 v6 file, it returns this:
Routines offset: 0x1d26
Static strings offset: 0x6c5c
Those are wrong compared to the decompilation. But if I just do this:
8 * self.routine_offset
Then the calculation is right and the correct address is returned.
So to bring it home:
4 * address + (8 * self.routine_offset) # incorrectly returns 0x1d26
8 * self.routine_offset # correctly returns 0e930
What am I misreading here or doing incorrectly?