Full front-end rewrite
This commit is contained in:
+98
-107
@@ -1,21 +1,31 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <vb.h>
|
||||
|
||||
|
||||
|
||||
//////////////////////////////// Static Memory ////////////////////////////////
|
||||
|
||||
static VB sims[2]; // Hardware simulations
|
||||
|
||||
|
||||
|
||||
/////////////////////////////// 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) {
|
||||
EMSCRIPTEN_KEEPALIVE void Free(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
@@ -24,116 +34,97 @@ EMSCRIPTEN_KEEPALIVE void* Malloc(int size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
// Read multiple data units from the bus
|
||||
// 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(
|
||||
int sim, uint8_t *dest, uint32_t address, uint32_t size, int debug) {
|
||||
VB* sim, uint8_t *dest, uint32_t address, uint32_t size) {
|
||||
for (; size > 0; address++, size--, dest++)
|
||||
*dest = vbRead(&sims[sim], address, VB_U8, debug);
|
||||
*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 *emu, int fetch, VB_ACCESS *acc) {
|
||||
if (fetch == 0 && vbGetProgramCounter(emu, VB_PC) != SingleStepPC)
|
||||
static int SingleStepProc(VB *sim, int fetch, VB_ACCESS *acc) {
|
||||
if (fetch == 0 && vbGetProgramCounter(sim) != SingleStepPC)
|
||||
return 1;
|
||||
acc->value = vbRead(emu, acc->address, acc->type, 0);
|
||||
acc->value = vbRead(sim, acc->address, acc->type, 0);
|
||||
return 0;
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void SingleStep(int sim) {
|
||||
EMSCRIPTEN_KEEPALIVE void SingleStep(VB *sim0, VB *sim1) {
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
EMSCRIPTEN_KEEPALIVE uint32_t Clocks(VB *sim) {
|
||||
return sim->cpu.clocks;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user