#include #include #include #include #include //////////////////////////////// Static Memory //////////////////////////////// static VB sims[2]; // Hardware simulations /////////////////////////////// Module Commands /////////////////////////////// // Proxy for free() EMSCRIPTEN_KEEPALIVE void Free(void* ptr) { free(ptr); } // Proxy for malloc() EMSCRIPTEN_KEEPALIVE void* Malloc(int size) { return malloc(size); } // Read multiple data units from the bus EMSCRIPTEN_KEEPALIVE void ReadBuffer( int sim, uint8_t *dest, uint32_t address, uint32_t size, int debug) { for (; size > 0; address++, size--, dest++) *dest = vbRead(&sims[sim], address, VB_U8, debug); } // Execute one instruction static uint32_t SingleStepPC; static int SingleStepProc(VB *emu, int fetch, VB_ACCESS *acc) { if (fetch == 0 && vbGetProgramCounter(emu, VB_PC) != SingleStepPC) return 1; acc->value = vbRead(emu, acc->address, acc->type, 0); return 0; } EMSCRIPTEN_KEEPALIVE void SingleStep(int sim) { uint32_t clocks = 400000; // 1/50s VB *emu = &sims[sim]; SingleStepPC = vbGetProgramCounter(emu, VB_PC); emu->onFetch = &SingleStepProc; vbEmulate(emu, NULL, &clocks); emu->onFetch = NULL; } // Attempt to execute until the following instruction static uint32_t RunNextPC; static int RunNextProcB(VB *emu, int fetch, VB_ACCESS *acc) { if (fetch == 0 && vbGetProgramCounter(emu, VB_PC) == RunNextPC) return 1; acc->value = vbRead(emu, acc->address, acc->type, 0); return 0; } static int RunNextProcA(VB *emu, VB_INSTRUCTION *inst) { RunNextPC = vbGetProgramCounter(emu, VB_PC) + inst->size; emu->onExecute = NULL; emu->onFetch = &RunNextProcB; return 0; } EMSCRIPTEN_KEEPALIVE void RunNext(int sim) { uint32_t clocks = 400000; // 1/50s VB *emu = &sims[sim]; emu->onExecute = &RunNextProcA; vbEmulate(emu, NULL, &clocks); emu->onFetch = NULL; } //////////////////////////////// Core Commands //////////////////////////////// // Retrieve the value of PC EMSCRIPTEN_KEEPALIVE uint32_t GetProgramCounter(int sim, int type) { return vbGetProgramCounter(&sims[sim], type); } // Retrieve the value of a program register EMSCRIPTEN_KEEPALIVE int32_t GetProgramRegister(int sim, int id) { return vbGetProgramRegister(&sims[sim], id); } // Retrieve the value of a system register EMSCRIPTEN_KEEPALIVE uint32_t GetSystemRegister(int sim, int id) { return vbGetSystemRegister(&sims[sim], id); } // Prepare simulation state instances for use EMSCRIPTEN_KEEPALIVE void Init() { vbInit(&sims[0]); vbInit(&sims[1]); } // Read a data unit from the bus EMSCRIPTEN_KEEPALIVE int32_t Read(int sim,uint32_t address,int type,int debug){ return vbRead(&sims[sim], address, type, debug); } // Simulate a hardware reset EMSCRIPTEN_KEEPALIVE void Reset(int sim) { vbReset(&sims[sim]); } // Specify a new value for PC EMSCRIPTEN_KEEPALIVE uint32_t SetProgramCounter(int sim, uint32_t value) { return vbSetProgramCounter(&sims[sim], value); } // Specify a new value for a program register EMSCRIPTEN_KEEPALIVE int32_t SetProgramRegister(int sim,int id,int32_t value) { return vbSetProgramRegister(&sims[sim], id, value); } // Supply a ROM buffer EMSCRIPTEN_KEEPALIVE int SetROM(int sim, void *rom, uint32_t size) { free(vbGetROM(&sims[sim], NULL)); return vbSetROM(&sims[sim], rom, size); } // Supply an SRAM buffer EMSCRIPTEN_KEEPALIVE int SetSRAM(int sim, void *sram, uint32_t size) { free(vbGetSRAM(&sims[sim], NULL)); return vbSetSRAM(&sims[sim], sram, size); } // Specify a new value for a system register EMSCRIPTEN_KEEPALIVE uint32_t SetSystemRegister(int sim,int id,uint32_t value){ return vbSetSystemRegister(&sims[sim], id, value); } // Write a data unit to the bus EMSCRIPTEN_KEEPALIVE void Write( int sim, uint32_t address, int type, int32_t value, int debug) { vbWrite(&sims[sim], address, type, value, debug); }