mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-22 19:30:36 +00:00
have startup code ensure that code resource is locked.
This commit is contained in:
parent
334f06ed83
commit
f549ead8ac
@ -147,9 +147,9 @@ int main(int argc, char *argv[])
|
||||
longword(code1, 0x61000002); // bsr *+2
|
||||
|
||||
word(code1, 0x0697); // addi.l #_, (a7)
|
||||
longword(code1, entrypoint + 8);
|
||||
longword(code1, entrypoint + 12);
|
||||
word(code1, 0x4e75); // rts
|
||||
|
||||
longword(code1, code1.tellp() + 4);
|
||||
code1 << flt;
|
||||
|
||||
rsrc.addResource(Resource("CODE", 1, code1.str()));
|
||||
|
@ -1,13 +1,15 @@
|
||||
type 'INIT' (0) {
|
||||
type 'INIT' {
|
||||
hex string dontBreakAtEntry = $"", breakAtEntry = $"A9FF";
|
||||
longint = 0x61000002; // bsr *+2
|
||||
relativeTo:
|
||||
integer = 0x0697; // addi.l #_, (a7)
|
||||
longint = $$long(fltfile + 8*8) + 8;
|
||||
longint = $$long(fltfile + 8*8) + (fltfile-relativeTo)/8;
|
||||
integer = 0x4e75; // rts
|
||||
longint = fltfile/8;
|
||||
fltfile:
|
||||
hex string;
|
||||
};
|
||||
|
||||
resource 'INIT' (0) {
|
||||
resource 'INIT' (128) {
|
||||
dontBreakAtEntry, $$read("SystemExtension.flt");
|
||||
};
|
||||
|
@ -23,16 +23,22 @@
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define RETRO68_GET_DISPLACEMENT(DISPLACEMENT) \
|
||||
#define _RETRO68_GET_DISPLACEMENT(DISPLACEMENT, STRIP) \
|
||||
do { \
|
||||
long virtualstart, realstart; \
|
||||
char *virtualstart, *realstart; \
|
||||
__asm__( "1:\n" \
|
||||
"\tmove.l #1b, %0\n" \
|
||||
"\tlea (1b:w,%%pc), %1" \
|
||||
: "=r"(virtualstart) , "=a"(realstart) ); \
|
||||
DISPLACEMENT = realstart - virtualstart; \
|
||||
DISPLACEMENT = STRIP(realstart) - virtualstart; \
|
||||
} while(0)
|
||||
|
||||
#define RETRO68_GET_DISPLACEMENT(DISPLACEMENT) \
|
||||
_RETRO68_GET_DISPLACEMENT(DISPLACEMENT, )
|
||||
|
||||
#define RETRO68_GET_DISPLACEMENT_STRIP(DISPLACEMENT) \
|
||||
_RETRO68_GET_DISPLACEMENT(DISPLACEMENT, StripAddress)
|
||||
|
||||
#define RETRO68_CALL_UNRELOCATED(FUN,ARGS) \
|
||||
do { \
|
||||
long displacement; \
|
||||
|
@ -65,8 +65,9 @@ extern void __fini_section_end(void);
|
||||
|
||||
|
||||
|
||||
static long headerVirtualAddress = -0x40;
|
||||
static long headerVirtualAddress = -sizeof(struct flat_hdr);
|
||||
static Ptr bssPtr = (Ptr) -1;
|
||||
static Handle codeHandle = NULL;
|
||||
|
||||
#define ACCESS_DISPLACED(VAR) \
|
||||
( * (typeof(&VAR)) ((char*)(&VAR) + displacement) )
|
||||
@ -74,9 +75,35 @@ static Ptr bssPtr = (Ptr) -1;
|
||||
void Retro68Relocate()
|
||||
{
|
||||
long displacement;
|
||||
RETRO68_GET_DISPLACEMENT(displacement);
|
||||
RETRO68_GET_DISPLACEMENT_STRIP(displacement);
|
||||
|
||||
struct flat_hdr *header = (struct flat_hdr*) (ACCESS_DISPLACED(headerVirtualAddress) + displacement);
|
||||
if(displacement == 0)
|
||||
{
|
||||
if(bssPtr != (Ptr) -1)
|
||||
{
|
||||
// this is not the first time, no relocations needed.
|
||||
// should only happen for code resources.
|
||||
HLock(codeHandle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
long headerOldVirtualAddress = ACCESS_DISPLACED(headerVirtualAddress);
|
||||
struct flat_hdr *header = (struct flat_hdr*) (headerOldVirtualAddress + displacement);
|
||||
uint8_t *base = (uint8_t*) (header+1);
|
||||
|
||||
uint32_t headerOffsetInResource = ((uint32_t*)header)[-1];
|
||||
|
||||
if(headerOffsetInResource < 4096)
|
||||
// Arbitrary magic number. We expect the offset to be small, just a few header bytes before it.
|
||||
{
|
||||
Handle h = RecoverHandle((Ptr) header - headerOffsetInResource);
|
||||
if(MemError() == noErr && h)
|
||||
{
|
||||
HLock(h);
|
||||
ACCESS_DISPLACED(codeHandle) = h;
|
||||
}
|
||||
}
|
||||
|
||||
SysEnvRec env;
|
||||
long bss_size;
|
||||
@ -89,7 +116,8 @@ void Retro68Relocate()
|
||||
long n = header->reloc_count;
|
||||
long *relocs = (long*)( (char*)header + header->reloc_start );
|
||||
long i;
|
||||
long data_end = header->data_end - 0x40;
|
||||
long data_end = header->data_end + headerOldVirtualAddress;
|
||||
uint32_t flt_size = (uint32_t) header->data_end;
|
||||
long bss_displacement = 0;
|
||||
|
||||
Ptr bss = ACCESS_DISPLACED(bssPtr);
|
||||
@ -105,17 +133,19 @@ void Retro68Relocate()
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
uint8_t *addrPtr = (uint8_t*)(relocs[i] + displacement);
|
||||
long addr;
|
||||
uint8_t *addrPtr = base + relocs[i];
|
||||
uint32_t addr;
|
||||
|
||||
addr = (addrPtr[0] << 24) | (addrPtr[1] << 16) | (addrPtr[2] << 8) | addrPtr[3];
|
||||
//addr = *(uint32_t*)addrPtr;
|
||||
addr = (((((addrPtr[0] << 8) | addrPtr[1]) << 8) | addrPtr[2]) << 8) | addrPtr[3];
|
||||
|
||||
addr += addr >= data_end ? bss_displacement : displacement;
|
||||
addr += (uint32_t)(addr - headerOldVirtualAddress) >= flt_size ? bss_displacement : displacement;
|
||||
|
||||
addrPtr[0] = addr >> 24;
|
||||
addrPtr[1] = addr >> 16;
|
||||
addrPtr[2] = addr >> 8;
|
||||
addrPtr[3] = addr;
|
||||
addrPtr[2] = (addr >>= 8);
|
||||
addrPtr[1] = (addr >>= 8);
|
||||
addrPtr[0] = (addr >>= 8);
|
||||
//*(uint32_t*)addrPtr = addr;
|
||||
}
|
||||
|
||||
if(env.processor >= env68040)
|
||||
|
Loading…
Reference in New Issue
Block a user