Thank you, @zarf – even a straw at which to grasp is helpful at the moment.
I did the exercise of taking a copy of Ruins from working through DM4 (which has plenty of objects [67], routines and strings) and adding the following to its Initialise() routine:
print "<header word $28 (routine offset) = ", 0-->$28, ">^";
print "<header word $2A (strings offset) = ", 0-->$2A, ">^";
print "<#code_offset = ", #code_offset, ">^";
print "<#strings_offset = ", #strings_offset, ">^";
print "<location of Main() = ", Main, ">^";
print "<location of Main__() = ", Main__, ">^";
[EDIT: The above includes an addressing error, so the wrong offset values for the header block addresses $28 and $2A are reported. See zarf’s reply and revised output values below.]
Then I compiled it as Z5, Z6 and Z8 (using Inform 6.31) and looked at the produced output.
compiled as Z5:
<header word $28 (routine offset) = 32>
<header word $2A (strings offset) = 32>
<#code_offset = 3325> ! $0CFD
<#strings_offset = 18858> ! $49AA
<location of Main() = 3327>
<location of Main__() = 0>
! per -z output, Z-code begins $33F4 and strings begin $126A8, #*_offset values exhibit scale_factor 4
compiled as Z6:
<header word $28 (routine offset) = 32>
<header word $2A (strings offset) = 32>
<#code_offset = 256> ! $0100
<#strings_offset = 15872> ! $3E00
<location of Main() = 258>
<location of Main__() = 0>
! per -z output, Z-code begins $33F8 and strings begin $127F8, no apparent correlation to reported #*_offset values
compiled as Z8:
<header word $28 (routine offset) = 32>
<header word $2A (strings offset) = 32>
<#code_offset = 1663> ! $067F
<#strings_offset = 9545> ! $2549
<location of Main() = 1664>
<location of Main__() = 0>
! per -z output, Z-code begins $33F8 and strings begin $12A48, #*_offset values exhibit scale_factor 8
[Note that output when compiled with Inform 6.34 (but StdLib 6/11) is essentially identical, although values for #strings_offset
are very slightly (<= 10 bytes difference) lower.]
From this, it seems that R
and S
(at least as stored in the header block) are always identical (and always 32?), regardless of Z-machine version. Main()
always seems to be just after #code_offset
. (I don’t know what’s going on with the reported location of Main___
, which is the lowest-address routine cited in ITM 8.8. The reported address seems incorrect.)
In the Z6 case, the $28
routine offset value times 8 does match up with the value of #code_offset
, and the reported location of Main()
is in accordance with this value. However, the starting address for the Z-code block ($33F8
as reported in the memory map at compilation) doesn’t correlate. Also, the $2A
strings offset value times 8 clearly does NOT match up with the value of #strings_offset
. So… it does not seem possible that R == S
, as described.
In the Z5 and Z8 cases, there is a clear correlation (at different scale factors, per the version-specific formulae in ITM 8.8) between the reported #*_offset
values and the reported-at-compilation starting addresses for the memory blocks for Z-code and strings. However, there is no correlation between reported #*_offset
values and what’s stored in the header block at $28
and $2A
.
So I’m back to square one now in making sense of this section. (Though some of the details underlying packed addressing are becoming clearer.)