#undef VBAPI #include #include #include /////////////////////////////// Module Commands /////////////////////////////// // Create and initialize a new simulation EMSCRIPTEN_KEEPALIVE VB* Create() { VB *sim = malloc(sizeof (VB)); vbInit(sim); return sim; } // Delete all memory used by a simulation EMSCRIPTEN_KEEPALIVE void Delete(VB *sim) { free(sim->cart.ram); free(sim->cart.rom); free(sim); } // Proxy for free() EMSCRIPTEN_KEEPALIVE void Free(void *ptr) { free(ptr); } // Proxy for malloc() EMSCRIPTEN_KEEPALIVE void* Malloc(int size) { return malloc(size); } // Size in bytes of a pointer EMSCRIPTEN_KEEPALIVE int PointerSize() { return sizeof (void *); } ////////////////////////////// Debugger Commands ////////////////////////////// // Execute until the following instruction static uint32_t RunToNextAddress; static int RunToNextFetch(VB *sim, int fetch, VBAccess *access) { return access->address == RunToNextAddress; } static int RunToNextExecute(VB *sim, VBInstruction *inst) { RunToNextAddress = inst->address + inst->size; vbSetCallback(sim, VB_ONEXECUTE, NULL); vbSetCallback(sim, VB_ONFETCH, &RunToNextFetch); return 0; } EMSCRIPTEN_KEEPALIVE void RunToNext(VB **sims, int count) { uint32_t clocks = 20000000; // 1s vbSetCallback(sims[0], VB_ONEXECUTE, &RunToNextExecute); vbEmulateEx (sims, count, &clocks); vbSetCallback(sims[0], VB_ONEXECUTE, NULL); vbSetCallback(sims[0], VB_ONFETCH , NULL); } // Execute the current instruction static int SingleStepBreak; static int SingleStepFetch(VB *sim, int fetch, VBAccess *access) { if (fetch != 0) return 0; if (SingleStepBreak == 1) return 1; SingleStepBreak = 1; return 0; } EMSCRIPTEN_KEEPALIVE void SingleStep(VB **sims, int count) { uint32_t clocks = 20000000; // 1s SingleStepBreak = sims[0]->cpu.stage == 0 ? 0 : 1; vbSetCallback(sims[0], VB_ONFETCH, &SingleStepFetch); vbEmulateEx (sims, count, &clocks); vbSetCallback(sims[0], VB_ONEXECUTE, NULL); vbSetCallback(sims[0], VB_ONFETCH , NULL); }