From f8fd035a3a2690490dc9c310477f6eef50e3677c Mon Sep 17 00:00:00 2001 From: ketmar Date: Thu, 22 Mar 2012 04:43:46 +0200 Subject: [PATCH] awasm: new code file format; fixes for (g|t)vars --- asm/goobers/main.awa | 8 +++-- asm/mapscripts/level01.awa | 3 ++ asm/roomscripts.awa | 4 +-- src/awasm.c | 76 +++++++++++++++++++++++++++++++++++++++++++--- src/awish.c | 4 +-- src/game.c | 2 +- src/gameglobals.c | 4 +-- src/gameglobals.h | 2 +- src/vm.c | 43 ++++++++++++++++++++++++-- src/vm.h | 6 ++-- 10 files changed, 133 insertions(+), 19 deletions(-) diff --git a/asm/goobers/main.awa b/asm/goobers/main.awa index c28edf5..b541101 100644 --- a/asm/goobers/main.awa +++ b/asm/goobers/main.awa @@ -13,18 +13,22 @@ * along with this program. If not, see . */ include: ../imports.awa -gvarbase: 77 -tvarbase: 77 +;gvarbase: 77 +;tvarbase: 77 + +defgvar: gg_global eproc: entry_goobers_init dbgprintstrnl "entry_goobers_init" + set [gg_global], 1 ret endp: entry_goobers_init eproc: entry_goobers_game_init dbgprintstrnl "entry_goobers_game_init" + set [gg_global], 0 ret endp: entry_goobers_game_init diff --git a/asm/mapscripts/level01.awa b/asm/mapscripts/level01.awa index cd03ca2..62d4892 100644 --- a/asm/mapscripts/level01.awa +++ b/asm/mapscripts/level01.awa @@ -22,6 +22,9 @@ eproc: entry_local_room_onload rst FRST_DEBUG_PRINT_NUM, [rst_result] rst FRST_DEBUG_PRINT_STR, -10 ; + dbgprintstr "level: " + dbgprintnumnl [cur_level] + ; bsr first_to_me ret endp: entry_local_room_onload diff --git a/asm/roomscripts.awa b/asm/roomscripts.awa index 47f38f9..faf2a60 100644 --- a/asm/roomscripts.awa +++ b/asm/roomscripts.awa @@ -12,5 +12,5 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -gvarbase: 66 -tvarbase: 66 +;gvarbase: 66 +;tvarbase: 66 diff --git a/src/awasm.c b/src/awasm.c index d859882..974f1a6 100644 --- a/src/awasm.c +++ b/src/awasm.c @@ -562,6 +562,36 @@ static int vtlast = 0; static int vtloc = VM_VARS_SIZE-1; // local thread (var 126 is used for internal thing) +typedef struct VarFixup { + struct VarFixup *next; + int pc; +} VarFixup; + + +static VarFixup *gvfixes = NULL; +static VarFixup *tvfixes = NULL; + + +static VarFixup *addVarFixup (VarFixup *list, int pc) { + VarFixup *res = calloc(1, sizeof(VarFixup)); + // + if (res == NULL) fatal("out of memory"); + res->next = list; + res->pc = pc; + return res; +} + + +static void addGVarFixup (int pc) { + gvfixes = addVarFixup(gvfixes, pc); +} + + +static void addTVarFixup (int pc) { + tvfixes = addVarFixup(tvfixes, pc); +} + + static LabelRefInfo *lrefRemoveDups (LabelRefInfo *list) { LabelRefInfo *p = NULL, *c = list; // @@ -899,8 +929,16 @@ static void emitOperand (OperandInfo *op) { // from label op->l->used = 1; switch (op->l->type) { - case LB_GVAR: emitByte(op->l->value|0x80); addLabelRef(op->l, pc-1); break; - case LB_TVAR: emitByte(op->l->value); addLabelRef(op->l, pc-1); break; + case LB_GVAR: + emitByte(op->l->value|0x80); + addLabelRef(op->l, pc-1); + if (op->l->ext >= 0 && op->l->name[0] != '.') addGVarFixup(pc-1); + break; + case LB_TVAR: + emitByte(op->l->value); + addLabelRef(op->l, pc-1); + if (op->l->ext >= 0 && op->l->name[0] != '.') addTVarFixup(pc-1); + break; case LB_SVAR: emitByte(127); // special emitByte(op->l->value&0xff); @@ -1580,6 +1618,12 @@ static void parseDW (void) { if (l != NULL) { addLabelRef(l, pc-2); addExternRef(l, pc-2, 2); + if (l->ext >= 0 && l->name[0] != '.') { + switch (l->type) { + case LB_GVAR: addGVarFixup(pc-2); break; + case LB_TVAR: addTVarFixup(pc-2); break; + } + } } if (nextToken() != ',') break; } @@ -1661,6 +1705,12 @@ static void parseDAscii (int zeroend) { if (l->type == LB_CODE) fatal("bad label type: '%s'", l->name); l->used = 1; addExternRef(l, pc, 1); + if (l->ext >= 0 && l->name[0] != '.') { + switch (l->type) { + case LB_GVAR: addGVarFixup(pc); break; + case LB_TVAR: addTVarFixup(pc); break; + } + } tint = l->value; // fallthru case TK_NUM: @@ -2256,8 +2306,20 @@ static int cfWriteExtLabels (FILE *fl) { } +static int cfWriteVarFixups (FILE *fl, const VarFixup *list) { + int cnt = 0; + // + for (const VarFixup *f = list; f != NULL; f = f->next) ++cnt; + if (cfWriteWord(fl, cnt) != 0) return -1; + for (const VarFixup *f = list; f != NULL; f = f->next) { + if (cfWriteWord(fl, f->pc) != 0) return -1; + } + return 0; +} + + static int writeCodeFile (FILE *fl) { - static const char *sign = "AVM1"; + static const char *sign = "AVM2"; int lcnt = 0, elcnt = 0; int rcnt = 0; // @@ -2272,7 +2334,7 @@ static int writeCodeFile (FILE *fl) { } } } - fprintf(stderr, "%d bytes of code, %d public labels, %d fixups, %d externs\n", pc, lcnt, rcnt, elcnt); + fprintf(stderr, "%d bytes of code, %d public labels, %d fixups, %d externs; maxgvar: %d, maxtvar: %d\n", pc, lcnt, rcnt, elcnt, vglast, vtlast); // if (fwrite(sign, 4, 1, fl) != 1) return -1; // code size @@ -2283,11 +2345,17 @@ static int writeCodeFile (FILE *fl) { if (cfWriteWord(fl, elcnt) != 0) return -1; // number of labels if (cfWriteWord(fl, lcnt) != 0) return -1; + // last used global + if (cfWriteWord(fl, vglast) != 0) return -1; + // last used thread local + if (cfWriteWord(fl, vtlast) != 0) return -1; // if (cfWriteCode(fl) != 0) return -1; if (cfWriteRels(fl) != 0) return -1; if (cfWriteExtLabels(fl) != 0) return -1; if (cfWritePublicLabels(fl) != 0) return -1; + if (cfWriteVarFixups(fl, gvfixes) != 0) return -1; + if (cfWriteVarFixups(fl, tvfixes) != 0) return -1; // return 0; } diff --git a/src/awish.c b/src/awish.c index 8c2192a..e5f29ef 100644 --- a/src/awish.c +++ b/src/awish.c @@ -470,7 +470,7 @@ int main (int argc, char *argv[]) { vmGVars[120] = 0; // vmCodeSize = 0; - if ((csz = loadCodeFile(&resfile, vmCodeSize, 93)) < 1) { + if ((csz = loadCodeFile(&resfile, vmCodeSize, 93, 0)) < 1) { fprintf(stderr, "FATAL: can't load VM code!\n"); exit(1); } @@ -483,7 +483,7 @@ int main (int argc, char *argv[]) { // if ((buf = loadDiskFileEx("goobers.vmd", &rsz)) != NULL) { if (buf != NULL) { - csz = vmLoadCodeFileFromDump(buf, rsz, vmCodeSize); + csz = vmLoadCodeFileFromDump(buf, rsz, vmCodeSize, vmMaxGVar, vmMaxTVar, &vmMaxGVar, &vmMaxTVar); free(buf); if (csz > 0) vmCodeSize += csz; } diff --git a/src/game.c b/src/game.c index 22508b8..838fc27 100644 --- a/src/game.c +++ b/src/game.c @@ -1022,7 +1022,7 @@ static void loadMapScript (ResFile *resfile) { // l = vmLabelAddMark(ROOM_SCRIPTS_MARK); l->value = vmCodeSize; - if ((csz = loadCodeFile(resfile, vmCodeSize, 94+curLevel)) > 1) { + if ((csz = loadCodeFile(resfile, vmCodeSize, 94+curLevel, 1)) > 1) { vmCodeSize += csz; } } diff --git a/src/gameglobals.c b/src/gameglobals.c index 5fb13b8..fe9b56c 100644 --- a/src/gameglobals.c +++ b/src/gameglobals.c @@ -115,13 +115,13 @@ Uint32 randUInt32 (void) { //////////////////////////////////////////////////////////////////////////////// // return vm code size -int loadCodeFile (ResFile *resfile, int pc, int idx) { +int loadCodeFile (ResFile *resfile, int pc, int idx, int asmodule) { int rsz = 0, res = 0; uint8_t *buf = loadResFile(resfile, idx, &rsz); // if (buf == NULL) return -1; // - res = vmLoadCodeFileFromDump(buf, rsz, pc); + res = vmLoadCodeFileFromDump(buf, rsz, pc, vmMaxGVar, vmMaxTVar, asmodule?NULL:&vmMaxGVar, asmodule?NULL:&vmMaxTVar); free(buf); return res; } diff --git a/src/gameglobals.h b/src/gameglobals.h index 759583f..7129fec 100644 --- a/src/gameglobals.h +++ b/src/gameglobals.h @@ -58,7 +58,7 @@ extern void setSeed (Uint32 u); extern Uint32 randUInt32 (void); -extern int loadCodeFile (ResFile *resfile, int pc, int idx); +extern int loadCodeFile (ResFile *resfile, int pc, int idx, int asmodule); extern int loadSound (int idx); // !0: error diff --git a/src/vm.c b/src/vm.c index 22dfa7d..0f212de 100644 --- a/src/vm.c +++ b/src/vm.c @@ -142,6 +142,9 @@ unsigned char vmCode[65536]; int vmCodeSize = 0; int vmGVars[VM_VARS_SIZE]; +int vmMaxGVar = 0; +int vmMaxTVar = 0; + static void fixLastThreadId (void) { for (; vmLastThreadId > 0; --vmLastThreadId) if (vmThreads[vmLastThreadId].stack) break; @@ -1221,14 +1224,14 @@ VMLabelInfo *vmFindMark (const char *name) { -extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc) { +extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc, int gvfirst, int tvfirst, int *gvmax, int *tvmax) { int rsz = datasize, pos = 4; const uint8_t *dta = (const uint8_t *)data; uint8_t *buf; - int csize, lcnt, rcnt, elcnt; + int csize, lcnt, rcnt, elcnt, tlast, glast; // if (rsz < 4) return -1; - if (memcmp(data, "AVM1", 4) != 0) goto quitbufonly; + if (memcmp(data, "AVM2", 4) != 0) goto quitbufonly; buf = malloc(rsz); if (buf == NULL) return 1; // @@ -1238,6 +1241,8 @@ extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc) { XREADW(rcnt, quitbufonly); // fixups XREADW(elcnt, quitbufonly); // extern labels XREADW(lcnt, quitbufonly); // labels + XREADW(glast, quitbufonly); // last used global + XREADW(tlast, quitbufonly); // last used thread local if (pc < 0 || pc+csize > 65535) goto quitbufonly; // /*if (goobers)*/ fprintf(stderr, "code: %d bytes, %d public labels, %d relocations, %d externs\n", csize, lcnt, rcnt, elcnt); @@ -1341,6 +1346,34 @@ extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc) { //if (l->type == LB_CODE) printf("%d/%d: [%s] %d : %d\n", f, lcnt, l->name, l->value-pc, l->value); } // + { + int cnt; + // + XREADW(cnt, quit); + while (cnt-- > 0) { + int fpc; + // + XREADW(fpc, quit); + if (gvfirst > 0) { + //fprintf(stderr, "GVFIX at 0x%04x: %d --> %d\n", fpc, vmCode[pc+fpc], vmCode[pc+fpc]+gvfirst); + vmCode[pc+fpc] += gvfirst; + } + } + // + XREADW(cnt, quit); + while (cnt-- > 0) { + int fpc; + // + XREADW(fpc, quit); + if (tvfirst > 0) { + //fprintf(stderr, "TVFIX at 0x%04x: %d --> %d\n", fpc, vmCode[pc+fpc], vmCode[pc+fpc]+tvfirst); + vmCode[pc+fpc] += tvfirst; + } + } + // + if (gvmax) *gvmax = glast+gvfirst+1; + if (tvmax) *tvmax = tlast+tvfirst+1; + } free(buf); return csize; quit: @@ -1359,6 +1392,8 @@ int vmSaveState (FILE *fl) { // if (writeDW(fl, VM_VARS_SIZE) != 0) return -1; //if (writeDW(fl, VM_STACK_SIZE) != 0) return -1; + if (writeDW(fl, vmMaxGVar) != 0) return -1; + if (writeDW(fl, vmMaxTVar) != 0) return -1; if (writeDW(fl, vmLastThreadId) != 0) return -1; if (writeDW(fl, vmCodeSize) != 0) return -1; if (writeBuf(fl, vmCode, vmCodeSize) != 0) return -1; @@ -1402,6 +1437,8 @@ int vmLoadState (FILE *fl) { // if (readDW(fl, &v) != 0 || v != VM_VARS_SIZE) goto fail; //if (readDW(fl, &ssz) != 0) goto fail; + if (readDW(fl, &vmMaxGVar) != 0 || vmMaxGVar < 0 || vmMaxGVar > VM_VARS_SIZE) goto fail; + if (readDW(fl, &vmMaxTVar) != 0 || vmMaxTVar < 0 || vmMaxTVar > VM_VARS_SIZE) goto fail; if (readDW(fl, &vmLastThreadId) != 0 || vmLastThreadId < 0 || vmLastThreadId > VM_MAX_THREADS) goto fail; if (readDW(fl, &vmCodeSize) != 0 || vmCodeSize < 1 || vmCodeSize > 65536) goto fail; if (readBuf(fl, vmCode, vmCodeSize) != 0) goto fail; diff --git a/src/vm.h b/src/vm.h index 0db0cd9..867d050 100644 --- a/src/vm.h +++ b/src/vm.h @@ -109,6 +109,9 @@ extern unsigned char vmCode[65536]; extern int vmCodeSize; extern int vmGVars[VM_VARS_SIZE]; +extern int vmMaxGVar; +extern int vmMaxTVar; + // <0: BRK; >0: END; 0: continue typedef int (*VMRSTCB) (int tid, int opcode, int argc, int argv[], int *argp[]); @@ -171,8 +174,7 @@ extern int vmLoadState (FILE *fl); // return code size -//extern int vmLoadCodeFile (ResFile *resfile, int pc, int idx); -extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc); +extern int vmLoadCodeFileFromDump (const void *data, int datasize, int pc, int gvfirst, int tvfirst, int *gvmax, int *tvmax); extern void vmFreeLabels (void); -- 2.11.4.GIT