X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=sect.c;h=b076ca6a313dddaa9db58087ab1aac65f34b63fb;hp=2269403e2b68e3426e843a9cb0569d5aa3b58637;hb=30a208654896284b50e7b362e97d3e63ec717b96;hpb=4ca3c2db2690ab998707415f8555ecd2fabc6ef2 diff --git a/sect.c b/sect.c index 2269403..b076ca6 100644 --- a/sect.c +++ b/sect.c @@ -91,12 +91,12 @@ void InitSection(void) // void MakeSection(int sno, uint16_t attr) { - SECT * p = §[sno]; - p->scattr = attr; - p->sloc = 0; - p->orgaddr = 0; - p->scode = p->sfcode = NULL; - p->sfix = p->sffix = NULL; + SECT * sp = §[sno]; + sp->scattr = attr; + sp->sloc = 0; + sp->orgaddr = 0; + sp->scode = sp->sfcode = NULL; + sp->sfix = sp->sffix = NULL; } @@ -108,15 +108,15 @@ void SwitchSection(int sno) { CHUNK * cp; cursect = sno; - SECT * p = §[sno]; + SECT * sp = §[sno]; m6502 = (sno == M6502); // Set 6502-mode flag // Copy section vars - scattr = p->scattr; - sloc = p->sloc; - scode = p->scode; - orgaddr = p->orgaddr; + scattr = sp->scattr; + sloc = sp->sloc; + scode = sp->scode; + orgaddr = sp->orgaddr; // Copy code chunk vars if ((cp = scode) != NULL) @@ -126,6 +126,12 @@ void SwitchSection(int sno) chptr = cp->chptr + ch_size; // For 6502 mode, add the last org'd address +// Why? +/* +Because the way this is set up it treats the 6502 assembly space as a single 64K space (+ 16 bytes, for some reason) and just bobbles around inside that space and uses a stack of org "pointers" to show where the data ended up. + +This is a piss poor way to handle things, and for fucks sake, we can do better than this! +*/ if (m6502) chptr = cp->chptr + orgaddr; } @@ -139,11 +145,11 @@ void SwitchSection(int sno) // void SaveSection(void) { - SECT * p = §[cursect]; + SECT * sp = §[cursect]; - p->scattr = scattr; // Bailout section vars - p->sloc = sloc; - p->orgaddr = orgaddr; + sp->scattr = scattr; // Bailout section vars + sp->sloc = sloc; + sp->orgaddr = orgaddr; if (scode != NULL) // Bailout code chunk scode->ch_size = ch_size; @@ -290,7 +296,7 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr) DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr); if (symbol != NULL) - printf(" name: %s, value: $lX\n", symbol->sname, symbol->svalue); + printf(" name: %s, value: $%lX\n", symbol->sname, symbol->svalue); } return 0; @@ -679,9 +685,8 @@ int ResolveFixups(int sno) break; - // Fixup LONG forward references; - // the long could be unaligned in the section buffer, so be careful - // (again). + // Fixup LONG forward references; the long could be unaligned in the + // section buffer, so be careful (again). case FU_LONG: flags = MLONG; @@ -702,6 +707,37 @@ int ResolveFixups(int sno) SETBE32(locp, 0, eval); break; + // Fixup QUAD forward references (mainly used by the OP assembler) + case FU_QUAD: + if (w & FU_OBJLINK) + { + uint64_t quad = GETBE64(locp, 0); + uint64_t addr = eval; + + if (fup->orgaddr) + addr = fup->orgaddr; + + eval = (quad & 0xFFFFFC0000FFFFFFLL) | ((addr & 0x3FFFF8) << 21); + } + else if (w & FU_OBJDATA) + { + // If it's in a TEXT or DATA section, be sure to mark for a + // fixup later + if (tdb) + MarkRelocatable(sno, loc, tdb, MQUAD, NULL); + + uint64_t quad = GETBE64(locp, 0); + uint64_t addr = eval; + + if (fup->orgaddr) + addr = fup->orgaddr; + + eval = (quad & 0x000007FFFFFFFFFFLL) | ((addr & 0xFFFFF8) << 40); + } + + SETBE64(locp, 0, eval); + break; + // Fixup a 3-bit "QUICK" reference in bits 9..1 // (range of 1..8) in a word. [Really bits 1..3 in a byte.] case FU_QUICK: