Working with real EDASM generated .REL files

This commit is contained in:
David Schmenk 2014-05-23 22:54:36 -07:00
parent 76d900a4ee
commit 178db35815
4 changed files with 94 additions and 82 deletions

View File

@ -634,7 +634,7 @@ end
;
;def modtosym(mod, dci)
; byte len, c
; (dci).0 = '#' | $80
; (dci).0 = '#'|$80
; len = 0
; repeat
; c = (mod).[len]
@ -679,7 +679,7 @@ end
; tbl = tbl + 1
; match = match + 1
; loop
; while ^tbl & $80
; while (^tbl & $80)
; tbl = tbl + 1
; loop
; tbl = tbl + 3
@ -1030,10 +1030,11 @@ def loadmod(mod)
dcitos(mod, @filename)
refnum = open(@filename, iobuffer)
if refnum > 0
init = 0
rdlen = read(refnum, @header, 128)
modsize = header:0
moddep = @header + 1
moddep = @header.1
defofst = modsize
init = 0
if rdlen > 4 and header:2 == $DA7E ; DAVE = magic number :-)
;
; This is an EXTended RELocatable (data+bytecode) module.
@ -1042,7 +1043,7 @@ def loadmod(mod)
defofst = header:6
defcnt = header:8
init = header:10
moddep = @header + 12
moddep = @header.12
;
; Load module dependencies.
;
@ -1074,9 +1075,9 @@ def loadmod(mod)
; Alloc heap space for relocated module (data + bytecode).
;
moddep = moddep + 1
modfix = moddep - @header ; Adjust to skip header
modfix = moddep - @header.2 ; Adjust to skip header
modsize = modsize - modfix
rdlen = rdlen - modfix
rdlen = rdlen - modfix - 2
modaddr = allocheap(modsize)
memcpy(modaddr, moddep, rdlen)
;
@ -1091,8 +1092,8 @@ def loadmod(mod)
;
; Apply all fixups and symbol import/export.
;
modfix = modaddr - modfix - MODADDR
bytecode = defofst + modfix
modfix = modaddr - modfix
bytecode = defofst + modfix - MODADDR
rld = modaddr + modsize ; Re-Locatable Directory
cdd = rld ; Code Definition Directory
esd = rld ; Extern+Entry Symbol Directory
@ -1118,33 +1119,32 @@ def loadmod(mod)
;
; This is a bytcode def entry - add it to the def directory.
;
;addr = (rld):1 + modfix
;(rld):1 = addr
adddef(defbank, (rld):1 - defofst + defaddr, @deflast)
else
addr = (rld):1 + modfix
if ^rld & $80 ; WORD sized fixup.
fixup = *addr
else ; BYTE sized fixup.
fixup = ^addr
fin
if ^rld & $10 ; EXTERN reference.
fixup = fixup + lookupextern(esd, (rld).3);
else ; INTERN fixup.
fixup = fixup + modfix
if uword_isge(fixup, bytecode)
;
; Bytecode address - replace with call def directory.
;
fixup = lookupdef(fixup - bytecode + defaddr, deftbl)
if addr >= modaddr ; Skip fixups to header
if ^rld & $80 ; WORD sized fixup.
fixup = *addr
else ; BYTE sized fixup.
fixup = ^addr
fin
if ^rld & $10 ; EXTERN reference.
fixup = fixup + lookupextern(esd, (rld).3)
else ; INTERN fixup.
fixup = fixup + modfix - MODADDR
if uword_isge(fixup, bytecode)
;
; Bytecode address - replace with call def directory.
;
fixup = lookupdef(fixup - bytecode + defaddr, deftbl)
fin
fin
if ^rld & $80 ; WORD sized fixup.
*addr = fixup
else ; BYTE sized fixup.
^addr = fixup
fin
fin
if ^rld & $80 ; WORD sized fixup.
*addr = fixup
else ; BYTE sized fixup.
^addr = fixup
fin
fin
rld = rld + 4
loop
@ -1163,7 +1163,7 @@ def loadmod(mod)
;
; Use the def directory address for bytecode.
;
addr = lookupdef(0, addr - bytecode + defaddr, deftbl)
addr = lookupdef(addr - bytecode + defaddr, deftbl)
fin
addsym(sym, addr)
fin
@ -1394,7 +1394,6 @@ while 1
volumes();
is '-'
execsys(cmdptr)
perr = $46
is '+'
execmod(cmdptr)
otherwise

View File

@ -309,8 +309,8 @@ void emit_header(void)
printf("; CA65 COMPATIBLE OUTPUT\n");
if (outflags & MODULE)
{
printf("_SEGBEGIN%c\n", LBL);
printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW);
printf("_SEGBEGIN%c\n", LBL);
printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW);
printf("\t%s\t_SYSFLAGS\t\t\t; SYSTEM FLAGS\n", DW);
printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW);
@ -345,13 +345,13 @@ void emit_rld(void)
if (fixup_type[i] & EXTERN_TYPE)
{
printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i] & 0xFF);
printf("\t%s\t_F%03d\t\t\n", DW, i);
printf("\t%s\t_F%03d-_SEGBEGIN\t\t\n", DW, i);
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]);
}
else
{
printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i] & 0xFF);
printf("\t%s\t_F%03d\t\t\n", DW, i);
printf("\t%s\t_F%03d-_SEGBEGIN\t\t\n", DW, i);
printf("\t%s\t$00\n", DB);
}
}
@ -374,7 +374,7 @@ void emit_esd(void)
{
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB);
printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i]));
printf("\t%s\t%s-_SEGBEGIN\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i]));
}
}
printf("\t%s\t$00\t\t\t; END OF ESD\n", DB);

View File

@ -45,38 +45,38 @@ $(CMD): cmd.pla cmdstub.s $(PLVM) $(PLASM)
TESTLIB: testlib.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < testlib.pla > testlib.a
acme --setpc 4096 -o TESTLIB testlib.a
acme --setpc 4094 -o TESTLIB testlib.a
test: test.pla TESTLIB $(PLVM) $(PLASM)
./$(PLASM) -AM < test.pla > test.a
acme --setpc 4096 -o TEST.REL test.a
acme --setpc 4094 -o TEST.REL test.a
./$(PLVM) TEST.REL
TESTCLS: testcls.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < testcls.pla > testcls.a
acme --setpc 4096 -o TESTCLS testcls.a
acme --setpc 4094 -o TESTCLS testcls.a
class: class.pla TESTCLS $(PLVM) $(PLASM)
./$(PLASM) -AM < class.pla > class.a
acme --setpc 4096 -o CLASS.REL class.a
acme --setpc 4094 -o CLASS.REL class.a
./$(PLVM) CLASS.REL
debug: test.pla TESTLIB $(PLVM) $(PLASM)
./$(PLASM) -AM < test.pla > test.a
acme --setpc 4096 -o TEST.REL test.a
acme --setpc 4094 -o TEST.REL test.a
./$(PLVM) -s TEST.REL MAIN
hello: hello.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < hello.pla > hello.a
acme --setpc 4096 -o HELLO.REL hello.a
acme --setpc 4094 -o HELLO.REL hello.a
./$(PLVM) HELLO.REL
ROD.REL: rod.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < rod.pla > rod.a
acme --setpc 4096 -o ROD.REL rod.a
acme --setpc 4094 -o ROD.REL rod.a
HGR1: hgr1.pla hgr1test.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < hgr1test.pla > hgr1test.a
acme --setpc 4096 -o HGR1TEST.REL hgr1test.a
acme --setpc 4094 -o HGR1TEST.REL hgr1test.a
./$(PLASM) -AM < hgr1.pla > hgr1.a
acme --setpc 4096 -o HGR1 hgr1.a
acme --setpc 4094 -o HGR1 hgr1.a

View File

@ -61,7 +61,7 @@ int dcitos(byte *dci, char *str)
int len = 0;
do
str[len] = *dci & 0x7F;
while ((len++ < 15) && (*dci++ & 0x80));
while ((len++ < 16) && (*dci++ & 0x80));
str[len] = 0;
return len;
}
@ -70,7 +70,7 @@ int stodci(char *str, byte *dci)
int len = 0;
do
dci[len] = toupper(*str) | 0x80;
while (*str++ && (len++ < 15));
while (*str++ && (len++ < 16));
dci[len - 1] &= 0x7F;
return len;
}
@ -138,7 +138,7 @@ uword lookup_tbl(byte *dci, byte *tbl)
match = dci;
while (*entry == *match)
{
if ((*entry & 0x80) == 0)
if (!(*entry & 0x80))
return entry[1] | (entry[2] << 8);
entry++;
match++;
@ -293,9 +293,9 @@ int load_mod(byte *mod)
/*
* Apply all fixups and symbol import/export.
*/
modfix = modaddr - hdrlen - MOD_ADDR;
bytecode += modfix;
end = modaddr - hdrlen + modsize;
modfix = modaddr - hdrlen + 2; // - MOD_ADDR;
bytecode += modfix - MOD_ADDR;
end = modaddr - hdrlen + modsize + 2;
rld = mem_data + end; // Re-Locatable Directory
esd = rld; // Extern+Entry Symbol Directory
while (*esd != 0x00) // Scan to end of RLD
@ -307,13 +307,14 @@ int load_mod(byte *mod)
/*
* Dump different parts of module.
*/
printf("Module load addr: $%04X\n", modaddr);
printf("Module size: %d\n", end - modaddr + hdrlen);
printf("Module code+data size: %d\n", modsize);
printf("Module magic: $%04X\n", magic);
printf("Module sysflags: $%04X\n", sysflags);
printf("Module bytecode: $%04X\n", bytecode);
printf("Module def count: $%04X\n", defcnt);
printf("Module init: $%04X\n", init);
printf("Module init: $%04X\n", init ? init + modfix - MOD_ADDR : 0);
}
/*
* Print out the Re-Location Dictionary.
@ -324,9 +325,9 @@ int load_mod(byte *mod)
{
if (rld[0] == 0x02)
{
if (show_state) printf("\tDEF CODE");
if (show_state) printf("\tDEF CODE");
addr = rld[1] | (rld[2] << 8);
addr += modfix;
addr += modfix - MOD_ADDR;
rld[1] = addr;
rld[2] = addr >> 8;
end = rld - mem_data + 4;
@ -334,37 +335,49 @@ int load_mod(byte *mod)
else
{
addr = rld[1] | (rld[2] << 8);
addr += modfix;
if (rld[0] & 0x80)
fixup = mem_data[addr] | (mem_data[addr + 1] << 8);
else
fixup = mem_data[addr];
if (rld[0] & 0x10)
if (addr > 12)
{
if (show_state) printf("\tEXTERN[$%02X] ", rld[3]);
fixup += extern_lookup(esd, rld[3]);
addr += modfix;
if (rld[0] & 0x80)
fixup = (mem_data[addr] | (mem_data[addr + 1] << 8));
else
fixup = mem_data[addr];
if (rld[0] & 0x10)
{
if (show_state) printf("\tEXTERN[$%02X] ", rld[3]);
fixup += extern_lookup(esd, rld[3]);
}
else
{
fixup += modfix - MOD_ADDR;
if (fixup >= bytecode)
{
/*
* Replace with call def dictionary.
*/
if (show_state) printf("\tDEF[$%04X->", fixup);
fixup = def_lookup(cdd, fixup);
if (show_state) printf("$%04X] ", fixup);
}
else
if (show_state) printf("\tINTERN ");
}
if (rld[0] & 0x80)
{
if (show_state) printf("WORD");
mem_data[addr] = fixup;
mem_data[addr + 1] = fixup >> 8;
}
else
{
if (show_state) printf("BYTE");
mem_data[addr] = fixup;
}
}
else
{
if (show_state) printf("\tINTERN ");
fixup += modfix;
if (fixup >= bytecode)
/*
* Replace with call def dictionary.
*/
fixup = def_lookup(cdd, fixup);
if (show_state) printf("\tIGNORE (HDR) ");
}
if (rld[0] & 0x80)
{
if (show_state) printf("WORD");
mem_data[addr] = fixup;
mem_data[addr + 1] = fixup >> 8;
}
else
{
if (show_state) printf("BYTE");
mem_data[addr] = fixup;
}
}
if (show_state) printf("@$%04X\n", addr);
rld += 4;
@ -404,7 +417,7 @@ int load_mod(byte *mod)
*/
if (init)
{
interp(mem_data + init + modfix);
interp(mem_data + init + modfix - MOD_ADDR);
return POP;
}
return 0;