mirror of
https://github.com/ksherlock/mpw.git
synced 2024-12-22 15:29:45 +00:00
far model relocation
This commit is contained in:
parent
88423bc690
commit
4041b14b36
@ -130,7 +130,67 @@ void WriteLong(void *data, uint32_t offset, uint32_t value)
|
||||
((uint8_t *)data)[offset++] = value;
|
||||
}
|
||||
|
||||
void reloc1(const uint8_t *r, uint32_t address, uint32_t offset)
|
||||
{
|
||||
// %00000000 00000000 -> break
|
||||
// %0xxxxxxx -> 7-bit value
|
||||
// %1xxxxxxx xxxxxxxx -> 15-bit value
|
||||
// %00000000 1xxxxxxx x{8} x{8} x{8} -> 31 bit value
|
||||
// ^ that's what the documentation says..
|
||||
// that's how the 32-bit bootstrap works
|
||||
// DumpCode ignores the high 2 bytes.
|
||||
for(;;)
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t value;
|
||||
|
||||
x = *r++;
|
||||
|
||||
if (x == 0x00)
|
||||
{
|
||||
x = *r++;
|
||||
if (x == 0x00) break;
|
||||
|
||||
x = (x << 8) | *r++;
|
||||
x = (x << 8) | *r++;
|
||||
x = (x << 8) | *r++;
|
||||
}
|
||||
else if (x & 0x80)
|
||||
{
|
||||
x &= 0x7f;
|
||||
x = (x << 8) | *r++;
|
||||
}
|
||||
|
||||
x <<= 1; // * 2
|
||||
|
||||
address += x;
|
||||
|
||||
value = memoryReadLong(address);
|
||||
memoryWriteLong(value + offset, address);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// relocate a far model segment.
|
||||
void relocate(uint32_t address, uint32_t size, uint32_t a5)
|
||||
{
|
||||
// see MacOS RT Architecture, 10-23 .. 10-26
|
||||
uint32_t offset;
|
||||
|
||||
offset = memoryReadLong(address + 0x14);
|
||||
if (memoryReadLong(address + 0x18) != a5 && offset != 0)
|
||||
{
|
||||
memoryWriteLong(a5, address + 0x18); // current value of A5
|
||||
reloc1(memoryPointer(address + offset), address, a5);
|
||||
}
|
||||
|
||||
offset = memoryReadLong(address + 0x1c);
|
||||
if (memoryReadLong(address + 0x20) != address && offset != 0)
|
||||
{
|
||||
memoryWriteLong(address, address + 0x20); // segment load address.
|
||||
reloc1(memoryPointer(address + offset), address, address + 0x28);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t load(const char *file)
|
||||
{
|
||||
@ -302,7 +362,7 @@ uint32_t load(const char *file)
|
||||
assert(offset < p.size);
|
||||
|
||||
// +$4/$28 for the jump table info header.
|
||||
uint32_t address = p.address + offset + (p.farModel ? 0x28 : 0x04);
|
||||
uint32_t address = p.address + offset + (p.farModel ? 0x00 : 0x04); // was 0x28
|
||||
|
||||
// JMP absolute long
|
||||
memoryWriteWord(0x4EF9, jtStart + 2);
|
||||
@ -316,6 +376,16 @@ uint32_t load(const char *file)
|
||||
}
|
||||
}
|
||||
|
||||
// far-model relocation. This happens here, after a5 is loaded.
|
||||
|
||||
for (const auto &seg : segments)
|
||||
{
|
||||
if (seg.farModel)
|
||||
{
|
||||
relocate(seg.address, seg.size, a5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set pc to jump table entry 0.
|
||||
return returnAddress;
|
||||
|
Loading…
Reference in New Issue
Block a user