#include #include #include #include #include #include /////////////////////////////// Module Commands /////////////////////////////// // Allocate and initialize multiple simulations EMSCRIPTEN_KEEPALIVE VB** Create(int count) { VB **sims = malloc(count * sizeof (void *)); for (int x = 0; x < count; x++) vbReset(sims[x] = malloc(sizeof (VB))); return sims; } // Delete a simulation EMSCRIPTEN_KEEPALIVE void Destroy(VB *sim) { free(&sim->cart.rom); free(&sim->cart.sram); 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); } // Determine the size in bytes of a pointer EMSCRIPTEN_KEEPALIVE int PointerSize() { return sizeof (void *); } // Read multiple bytes from the bus EMSCRIPTEN_KEEPALIVE void ReadBuffer( VB* sim, uint8_t *dest, uint32_t address, uint32_t size) { for (; size > 0; address++, size--, dest++) *dest = vbRead(sim, address, VB_U8, 1); } // Supply a ROM buffer EMSCRIPTEN_KEEPALIVE int SetROM(VB *sim, uint8_t *rom, uint32_t size) { uint8_t *prev = vbGetROM(sim, NULL); int ret = vbSetROM(sim, rom, size); if (ret) { free(prev); vbReset(sim); } return ret; } // Write multiple bytes to the bus EMSCRIPTEN_KEEPALIVE void WriteBuffer( VB* sim, uint8_t *src, uint32_t address, uint32_t size) { for (; size > 0; address++, size--, src++) vbWrite(sim, address, VB_U8, *src, 1); } ////////////////////////////// Debugger Commands ////////////////////////////// // Attempt to execute until the following instruction static uint32_t RunNextPC; static int RunNextProcB(VB *sim, int fetch, VB_ACCESS *acc) { if (fetch == 0 && vbGetProgramCounter(sim) == RunNextPC) return 1; acc->value = vbRead(sim, acc->address, acc->type, 0); return 0; } static int RunNextProcA(VB *sim, VB_INSTRUCTION *inst) { RunNextPC = vbGetProgramCounter(sim) + inst->size; vbSetCallback(sim, VB_ONEXECUTE, NULL); vbSetCallback(sim, VB_ONFETCH, &RunNextProcB); return 0; } EMSCRIPTEN_KEEPALIVE void RunNext(VB *sim0, VB *sim1) { uint32_t clocks = 400000; // 1/50s VB *sims[2]; vbSetCallback(sim0, VB_ONEXECUTE, &RunNextProcA); if (sim1 != NULL) { sims[0] = sim0; sims[1] = sim1; vbEmulateMulti(sims, 2, &clocks); } else vbEmulate(sim0, &clocks); vbSetCallback(sim0, VB_ONFETCH, NULL); } // Execute one instruction static uint32_t SingleStepPC; static int SingleStepProc(VB *sim, int fetch, VB_ACCESS *acc) { if (fetch == 0 && vbGetProgramCounter(sim) != SingleStepPC) return 1; acc->value = vbRead(sim, acc->address, acc->type, 0); return 0; } EMSCRIPTEN_KEEPALIVE void SingleStep(VB *sim0, VB *sim1) { uint32_t clocks = 400000; // 1/50s VB *sims[2]; SingleStepPC = vbGetProgramCounter(sim0); vbSetCallback(sim0, VB_ONFETCH, &SingleStepProc); if (sim1 != NULL) { sims[0] = sim0; sims[1] = sim1; vbEmulateMulti(sims, 2, &clocks); } else vbEmulate(sim0, &clocks); vbSetCallback(sim0, VB_ONFETCH, NULL); } EMSCRIPTEN_KEEPALIVE uint32_t Clocks(VB *sim) { return sim->cpu.clocks; }