Implement game pad and timer
This commit is contained in:
parent
37b9a94338
commit
e9f5437c1f
75
core/bus.c
75
core/bus.c
|
@ -16,6 +16,13 @@ static const uint32_t TYPE_MASKS[] = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** Forward references *****************************/
|
||||||
|
|
||||||
|
static void vipRead (VB *, uint32_t, int, int32_t *);
|
||||||
|
static void vipWrite(VB *, uint32_t, int, int32_t, int);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************** Sub-Module Functions ****************************/
|
/*************************** Sub-Module Functions ****************************/
|
||||||
|
|
||||||
/* Read a typed value from a buffer in host memory */
|
/* Read a typed value from a buffer in host memory */
|
||||||
|
@ -76,14 +83,62 @@ static void busWriteBuffer(uint8_t *data, int type, int32_t value) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a value from miscellaneous hardware I/O */
|
||||||
|
static int32_t busReadMisc(VB *sim, uint8_t address, int type) {
|
||||||
|
|
||||||
|
/* Unmapped */
|
||||||
|
switch (type) {
|
||||||
|
case VB_S8 : case VB_U8 : if (address & 3) return 0; break;
|
||||||
|
case VB_S16: case VB_U16: if (address & 1) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access by register */
|
||||||
|
switch (address >> 2 & 15) {
|
||||||
|
case 0x00>>2: break; /* CCR */
|
||||||
|
case 0x04>>2: break; /* CCSR */
|
||||||
|
case 0x08>>2: break; /* CDTR */
|
||||||
|
case 0x0C>>2: break; /* CDRR */
|
||||||
|
case 0x10>>2: return sim->pad.sdlr; /* SDLR */
|
||||||
|
case 0x14>>2: return sim->pad.sdhr; /* SDHR */
|
||||||
|
case 0x18>>2: return sim->tmr.counter & 0xFF; /* TLR */
|
||||||
|
case 0x1C>>2: return sim->tmr.counter >> 8 & 0xFF; /* THR */
|
||||||
|
case 0x20>>2: return tmrReadControl(sim); /* TCR */
|
||||||
|
case 0x24>>2: return sim->wcr; /* WCR */
|
||||||
|
case 0x28>>2: return padReadControl(sim); /* SCR */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unmapped */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a value to miscellaneous hardware I/O */
|
||||||
|
static void busWriteMisc(VB *sim, uint8_t address, int type, int32_t value) {
|
||||||
|
|
||||||
|
/* Unmapped */
|
||||||
|
switch (type) {
|
||||||
|
case VB_S8 : case VB_U8 : if (address & 3) return; break;
|
||||||
|
case VB_S16: case VB_U16: if (address & 1) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access by register */
|
||||||
|
switch (address >> 2 & 15) {
|
||||||
|
case 0x00>>2: break; /* CCR */
|
||||||
|
case 0x04>>2: break; /* CCSR */
|
||||||
|
case 0x08>>2: break; /* CDTR */
|
||||||
|
case 0x0C>>2: break; /* CDRR */
|
||||||
|
case 0x18>>2: tmrWriteLow (sim, value); break; /* TLR */
|
||||||
|
case 0x1C>>2: tmrWriteHigh (sim, value); break; /* THR */
|
||||||
|
case 0x20>>2: tmrWriteControl(sim, value); break; /* TCR */
|
||||||
|
case 0x24>>2: sim->wcr = value & 3; break; /* WCR */
|
||||||
|
case 0x28>>2: padWriteControl(sim, value); break; /* SCR */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************** Library Functions *****************************/
|
/***************************** Library Functions *****************************/
|
||||||
|
|
||||||
/* Forward references */
|
|
||||||
static void vipRead (VB *, uint32_t, int, int32_t *);
|
|
||||||
static void vipWrite(VB *, uint32_t, int, int32_t, int);
|
|
||||||
|
|
||||||
/* Read a typed value from the simulation bus */
|
/* Read a typed value from the simulation bus */
|
||||||
static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||||
|
|
||||||
|
@ -99,7 +154,11 @@ static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: break; /* VSU */
|
case 1: break; /* VSU */
|
||||||
case 2: break; /* Misc. I/O */
|
|
||||||
|
case 2: /* Misc. I/O */
|
||||||
|
*value = busReadMisc(sim, address, type);
|
||||||
|
break;
|
||||||
|
|
||||||
case 3: break; /* Unmapped */
|
case 3: break; /* Unmapped */
|
||||||
case 4: break; /* Game Pak expansion */
|
case 4: break; /* Game Pak expansion */
|
||||||
|
|
||||||
|
@ -139,7 +198,11 @@ static void busWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: break; /* VSU */
|
case 1: break; /* VSU */
|
||||||
case 2: break; /* Misc. I/O */
|
|
||||||
|
case 2: /* Misc. I/O */
|
||||||
|
busWriteMisc(sim, address, type, value);
|
||||||
|
break;
|
||||||
|
|
||||||
case 3: break; /* Unmapped */
|
case 3: break; /* Unmapped */
|
||||||
case 4: break; /* Game Pak expansion */
|
case 4: break; /* Game Pak expansion */
|
||||||
|
|
||||||
|
|
14
core/cpu.c
14
core/cpu.c
|
@ -1825,8 +1825,18 @@ static void cpuReset(VB *sim) {
|
||||||
|
|
||||||
/* Determine how many clocks are guaranteed to process */
|
/* Determine how many clocks are guaranteed to process */
|
||||||
static uint32_t cpuUntil(VB *sim, uint32_t clocks) {
|
static uint32_t cpuUntil(VB *sim, uint32_t clocks) {
|
||||||
return sim->cpu.halt || sim->cpu.clocks > clocks ?
|
|
||||||
clocks : sim->cpu.clocks;
|
/* Halting */
|
||||||
|
if (sim->cpu.halt) {
|
||||||
|
return
|
||||||
|
sim->cpu.operation == CPU_HALTING &&
|
||||||
|
!(sim->cpu.psw.id | sim->cpu.psw.ep | sim->cpu.psw.np) &&
|
||||||
|
IRQ_LEVELS[sim->cpu.irq] < sim->cpu.psw.i
|
||||||
|
? 0 : clocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not halting */
|
||||||
|
return sim->cpu.clocks > clocks ? clocks : sim->cpu.clocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* VBAPI */
|
#endif /* VBAPI */
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
/* This file is included into vb.c and cannot be compiled on its own. */
|
||||||
|
#ifdef VBAPI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************** Library Functions *****************************/
|
||||||
|
|
||||||
|
/* Process component */
|
||||||
|
static int padEmulate(VB *sim, uint32_t clocks) {
|
||||||
|
|
||||||
|
/* No hardware read in progress */
|
||||||
|
if (sim->pad.si_stat == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Hardware read completes after time to process */
|
||||||
|
if (sim->pad.si_stat > clocks) {
|
||||||
|
sim->pad.si_stat -= clocks;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complete hardware read */
|
||||||
|
sim->pad.si_stat = 0;
|
||||||
|
sim->pad.sdlr = sim->pad.keys;
|
||||||
|
sim->pad.sdhr = sim->pad.keys >> 8;
|
||||||
|
|
||||||
|
/* Raise game pad interrupt */
|
||||||
|
if (
|
||||||
|
!sim->pad.k_int_inh &&
|
||||||
|
(sim->pad.keys & 0xFFF0) != 0 &&
|
||||||
|
(sim->pad.keys & 0x000E) == 0
|
||||||
|
) sim->cpu.irq |= 0x0001;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a value from SCR */
|
||||||
|
static int32_t padReadControl(VB *sim) {
|
||||||
|
return 0x4C |
|
||||||
|
sim->pad.k_int_inh << 7 |
|
||||||
|
sim->pad.para_si << 5 |
|
||||||
|
sim->pad.soft_ck << 4 |
|
||||||
|
!!sim->pad.si_stat << 1 |
|
||||||
|
sim->pad.s_abt_dis
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate a hardware reset */
|
||||||
|
static void padReset(VB *sim) {
|
||||||
|
|
||||||
|
/* Normal */
|
||||||
|
sim->pad.k_int_inh = 0;
|
||||||
|
sim->pad.para_si = 0;
|
||||||
|
sim->pad.s_abt_dis = 0;
|
||||||
|
sim->pad.sdhr = 0x00;
|
||||||
|
sim->pad.sdlr = 0x00;
|
||||||
|
sim->pad.si_stat = 0;
|
||||||
|
sim->pad.soft_ck = 0;
|
||||||
|
|
||||||
|
/* Other */
|
||||||
|
sim->pad.step = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a value to SCR */
|
||||||
|
static void padWriteControl(VB *sim, uint8_t value) {
|
||||||
|
|
||||||
|
/* Acknowledge and disable interrupt */
|
||||||
|
sim->pad.k_int_inh = value >> 7 & 1;
|
||||||
|
if (sim->pad.k_int_inh)
|
||||||
|
sim->cpu.irq &= ~0x0001;
|
||||||
|
|
||||||
|
/* Enable or disable hardware reads */
|
||||||
|
sim->pad.s_abt_dis = value & 1;
|
||||||
|
if (sim->pad.s_abt_dis)
|
||||||
|
sim->pad.si_stat = 0; /* Abort hardware read */
|
||||||
|
|
||||||
|
/* Initiate a hardware read */
|
||||||
|
if (
|
||||||
|
(value & 0x04) && /* HW-SI */
|
||||||
|
sim->pad.si_stat == 0 && /* No hardware read underway */
|
||||||
|
!sim->pad.s_abt_dis /* Hardware reads enabled */
|
||||||
|
) {
|
||||||
|
sim->pad.si_stat = 10240; /* 512us */
|
||||||
|
sim->pad.step = 0; /* Abort software read */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the read operation */
|
||||||
|
sim->pad.para_si = value >> 5 & 1;
|
||||||
|
if (
|
||||||
|
sim->pad.para_si &&
|
||||||
|
sim->pad.si_stat == 0 /* No hardware read underway */
|
||||||
|
) sim->pad.step = 32;
|
||||||
|
|
||||||
|
/* Signal a bit for a software read */
|
||||||
|
sim->pad.soft_ck = value >> 4 & 1;
|
||||||
|
if (
|
||||||
|
sim->pad.step != 0 && /* Software read is underway */
|
||||||
|
!sim->pad.para_si && /* Not resetting software read */
|
||||||
|
((sim->pad.soft_ck ^ sim->pad.step) & 1) == 1 /* Advance */
|
||||||
|
) {
|
||||||
|
sim->pad.step--;
|
||||||
|
if (sim->pad.step == 0) {
|
||||||
|
sim->pad.sdlr = sim->pad.keys;
|
||||||
|
sim->pad.sdhr = sim->pad.keys >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine how many clocks are guaranteed to process */
|
||||||
|
static uint32_t padUntil(VB *sim, uint32_t clocks) {
|
||||||
|
return sim->pad.si_stat != 0 && sim->pad.si_stat < clocks ?
|
||||||
|
sim->pad.si_stat : clocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VBAPI */
|
|
@ -0,0 +1,130 @@
|
||||||
|
/* This file is included into vb.c and cannot be compiled on its own. */
|
||||||
|
#ifdef VBAPI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************** Module Functions ******************************/
|
||||||
|
|
||||||
|
/* Update the counter to a new value */
|
||||||
|
static void tmrUpdate(VB *sim, uint16_t value) {
|
||||||
|
if (value == 0 && sim->tmr.counter != 0) {
|
||||||
|
if (sim->tmr.t_enb)
|
||||||
|
sim->tmr.z_stat = 1;
|
||||||
|
if (sim->tmr.tim_z_int)
|
||||||
|
sim->cpu.irq |= 0x0002;
|
||||||
|
}
|
||||||
|
sim->tmr.counter = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************** Library Functions *****************************/
|
||||||
|
|
||||||
|
/* Process component */
|
||||||
|
static int tmrEmulate(VB *sim, uint32_t clocks) {
|
||||||
|
|
||||||
|
/* Timer is disabled */
|
||||||
|
if (!sim->tmr.t_enb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Process all clocks */
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
/* Next tick is after time to process */
|
||||||
|
if (sim->tmr.clocks > clocks) {
|
||||||
|
sim->tmr.clocks -= clocks;
|
||||||
|
sim->tmr.until -= clocks;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance forward the component's number of clocks */
|
||||||
|
clocks -= sim->tmr.clocks;
|
||||||
|
sim->tmr.until -= sim->tmr.clocks;
|
||||||
|
sim->tmr.clocks = sim->tmr.t_clk_sel ? 400 : 2000;
|
||||||
|
|
||||||
|
/* Advance to the next counter value */
|
||||||
|
tmrUpdate(sim, sim->tmr.counter == 0 ?
|
||||||
|
sim->tmr.reload : sim->tmr.counter - 1);
|
||||||
|
if (sim->tmr.counter == 0)
|
||||||
|
sim->tmr.until = sim->tmr.clocks * ((uint32_t)sim->tmr.reload + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a value from TCR */
|
||||||
|
static int32_t tmrReadControl(VB *sim) {
|
||||||
|
return 0xE4 |
|
||||||
|
sim->tmr.t_clk_sel << 4 |
|
||||||
|
sim->tmr.tim_z_int << 3 |
|
||||||
|
sim->tmr.z_stat << 1 |
|
||||||
|
sim->tmr.t_enb
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate a hardware reset */
|
||||||
|
static void tmrReset(VB *sim) {
|
||||||
|
|
||||||
|
/* Normal */
|
||||||
|
sim->tmr.t_enb = 0;
|
||||||
|
sim->tmr.t_clk_sel = 0;
|
||||||
|
sim->tmr.tim_z_int = 0;
|
||||||
|
sim->tmr.z_stat = 0;
|
||||||
|
|
||||||
|
/* Other */
|
||||||
|
sim->tmr.counter = 0xFFFF;
|
||||||
|
sim->tmr.reload = 0x0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine how many clocks are guaranteed to process */
|
||||||
|
static uint32_t tmrUntil(VB *sim, uint32_t clocks) {
|
||||||
|
return sim->tmr.t_enb && sim->tmr.until < clocks ?
|
||||||
|
sim->tmr.until : clocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a value to TCR */
|
||||||
|
static void tmrWriteControl(VB *sim, uint8_t value) {
|
||||||
|
|
||||||
|
/* Clear interrupt status */
|
||||||
|
if (
|
||||||
|
(value & 0x04) && /* Z-Stat-Clr */
|
||||||
|
(
|
||||||
|
sim->tmr.counter != 0 ||
|
||||||
|
!sim->tmr.t_enb
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
sim->tmr.z_stat = sim->tmr.counter != 0;
|
||||||
|
sim->cpu.irq &= ~0x0002;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse fields */
|
||||||
|
sim->tmr.t_clk_sel = value >> 4 & 1;
|
||||||
|
sim->tmr.tim_z_int = value >> 3 & 1;
|
||||||
|
sim->tmr.t_enb = value & 1;
|
||||||
|
|
||||||
|
/* The interrupt is disabled */
|
||||||
|
if (!sim->tmr.tim_z_int)
|
||||||
|
sim->cpu.irq &= ~0x0002;
|
||||||
|
|
||||||
|
/* Configure countdowns */
|
||||||
|
sim->tmr.clocks = sim->tmr.t_clk_sel ? 400 : 2000;
|
||||||
|
sim->tmr.until = sim->tmr.clocks * (sim->tmr.counter == 0 ?
|
||||||
|
(uint32_t) sim->tmr.reload + 1 : sim->tmr.counter);
|
||||||
|
|
||||||
|
/* TODO: Will Z-Stat raise an interrupt when Tim-Z-Int is set? */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write to the high data register */
|
||||||
|
static void tmrWriteHigh(VB *sim, uint8_t value) {
|
||||||
|
sim->tmr.reload = (uint16_t) value << 8 | (sim->tmr.reload & 0x00FF);
|
||||||
|
tmrUpdate(sim, sim->tmr.reload);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write to the low data register */
|
||||||
|
static void tmrWriteLow(VB *sim, uint8_t value) {
|
||||||
|
sim->tmr.reload = (sim->tmr.reload & 0xFF00) | value;
|
||||||
|
tmrUpdate(sim, sim->tmr.reload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VBAPI */
|
57
core/vb.c
57
core/vb.c
|
@ -90,6 +90,39 @@ struct VB {
|
||||||
int step; /* Operation sub-task ID */
|
int step; /* Operation sub-task ID */
|
||||||
} cpu;
|
} cpu;
|
||||||
|
|
||||||
|
/* Game pad */
|
||||||
|
struct {
|
||||||
|
|
||||||
|
/* Hardware state */
|
||||||
|
uint8_t k_int_inh; /* Interrupt acknowledge/disable */
|
||||||
|
uint8_t para_si; /* Read reset signal */
|
||||||
|
uint8_t s_abt_dis; /* Abort hardware read */
|
||||||
|
uint8_t sdhr; /* High key bits */
|
||||||
|
uint8_t sdlr; /* Low key bits */
|
||||||
|
uint32_t si_stat; /* Hardware read in progress */
|
||||||
|
uint8_t soft_ck; /* Controller communication signal */
|
||||||
|
|
||||||
|
/* Simulation state */
|
||||||
|
uint8_t keys; /* Next input bits */
|
||||||
|
int step; /* Software read processing phase */
|
||||||
|
} pad;
|
||||||
|
|
||||||
|
/* Timer */
|
||||||
|
struct {
|
||||||
|
|
||||||
|
/* Hardware state */
|
||||||
|
uint8_t t_clk_sel; /* Counter tick duration */
|
||||||
|
uint8_t t_enb; /* Enable timer */
|
||||||
|
uint8_t tim_z_int; /* Enable interrupt */
|
||||||
|
uint8_t z_stat; /* Zero status */
|
||||||
|
|
||||||
|
/* Simulation state */
|
||||||
|
uint32_t clocks; /* Master clocks to wait */
|
||||||
|
uint16_t counter; /* Current counter value */
|
||||||
|
uint16_t reload; /* Reload counter value */
|
||||||
|
uint32_t until; /* Clocks until interrupt condition */
|
||||||
|
} tmr;
|
||||||
|
|
||||||
/* VIP */
|
/* VIP */
|
||||||
struct {
|
struct {
|
||||||
|
|
||||||
|
@ -168,6 +201,7 @@ struct VB {
|
||||||
} vip;
|
} vip;
|
||||||
|
|
||||||
/* Other state */
|
/* Other state */
|
||||||
|
uint8_t wcr; /* Wait controller state */
|
||||||
uint8_t wram[0x10000]; /* System RAM */
|
uint8_t wram[0x10000]; /* System RAM */
|
||||||
|
|
||||||
/* Application data */
|
/* Application data */
|
||||||
|
@ -199,6 +233,8 @@ static int32_t SignExtend(int32_t value, int32_t bits) {
|
||||||
|
|
||||||
/******************************** Sub-Modules ********************************/
|
/******************************** Sub-Modules ********************************/
|
||||||
|
|
||||||
|
#include "game-pad.c"
|
||||||
|
#include "timer.c"
|
||||||
#include "bus.c"
|
#include "bus.c"
|
||||||
#include "cpu.c"
|
#include "cpu.c"
|
||||||
#include "vip.c"
|
#include "vip.c"
|
||||||
|
@ -211,7 +247,9 @@ static int32_t SignExtend(int32_t value, int32_t bits) {
|
||||||
static int sysEmulate(VB *sim, uint32_t clocks) {
|
static int sysEmulate(VB *sim, uint32_t clocks) {
|
||||||
return
|
return
|
||||||
cpuEmulate(sim, clocks) |
|
cpuEmulate(sim, clocks) |
|
||||||
vipEmulate(sim, clocks)
|
vipEmulate(sim, clocks) |
|
||||||
|
padEmulate(sim, clocks) |
|
||||||
|
tmrEmulate(sim, clocks)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +257,8 @@ static int sysEmulate(VB *sim, uint32_t clocks) {
|
||||||
static uint32_t sysUntil(VB *sim, uint32_t clocks) {
|
static uint32_t sysUntil(VB *sim, uint32_t clocks) {
|
||||||
clocks = cpuUntil(sim, clocks);
|
clocks = cpuUntil(sim, clocks);
|
||||||
clocks = vipUntil(sim, clocks);
|
clocks = vipUntil(sim, clocks);
|
||||||
|
clocks = padUntil(sim, clocks);
|
||||||
|
clocks = tmrUntil(sim, clocks);
|
||||||
return clocks;
|
return clocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +335,11 @@ VBAPI vbOnFrame vbGetFrameCallback(VB *sim) {
|
||||||
return sim->onFrame;
|
return sim->onFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retrieve the current game pad key state */
|
||||||
|
VBAPI uint16_t vbGetKeys(VB *sim) {
|
||||||
|
return sim->pad.keys;
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve the most recent frame image pixels */
|
/* Retrieve the most recent frame image pixels */
|
||||||
VBAPI void vbGetPixels(VB *sim, void *left, int leftStrideX, int leftStrideY,
|
VBAPI void vbGetPixels(VB *sim, void *left, int leftStrideX, int leftStrideY,
|
||||||
void *right, int rightStrideX, int rightStrideY) {
|
void *right, int rightStrideX, int rightStrideY) {
|
||||||
|
@ -391,6 +436,9 @@ VBAPI int32_t vbRead(VB *sim, uint32_t address, int type) {
|
||||||
VBAPI VB* vbReset(VB *sim) {
|
VBAPI VB* vbReset(VB *sim) {
|
||||||
int x; /* Iterator */
|
int x; /* Iterator */
|
||||||
|
|
||||||
|
/* Wait controller */
|
||||||
|
sim->wcr = 0x00;
|
||||||
|
|
||||||
/* WRAM (the hardware does not do this) */
|
/* WRAM (the hardware does not do this) */
|
||||||
for (x = 0; x < 0x10000; x++)
|
for (x = 0; x < 0x10000; x++)
|
||||||
sim->wram[x] = 0x00;
|
sim->wram[x] = 0x00;
|
||||||
|
@ -398,6 +446,8 @@ VBAPI VB* vbReset(VB *sim) {
|
||||||
/* Components */
|
/* Components */
|
||||||
cpuReset(sim);
|
cpuReset(sim);
|
||||||
vipReset(sim);
|
vipReset(sim);
|
||||||
|
padReset(sim);
|
||||||
|
tmrReset(sim);
|
||||||
return sim;
|
return sim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +501,11 @@ VBAPI vbOnFrame vbSetFrameCallback(VB *sim, vbOnFrame callback) {
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Specify new game pad keys */
|
||||||
|
VBAPI uint16_t vbSetKeys(VB *sim, uint16_t keys) {
|
||||||
|
return sim->pad.keys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
/* Specify a new value for the program counter */
|
/* Specify a new value for the program counter */
|
||||||
VBAPI uint32_t vbSetProgramCounter(VB *sim, uint32_t value) {
|
VBAPI uint32_t vbSetProgramCounter(VB *sim, uint32_t value) {
|
||||||
sim->cpu.operation = CPU_FETCH;
|
sim->cpu.operation = CPU_FETCH;
|
||||||
|
|
|
@ -107,6 +107,7 @@ VBAPI vbOnException vbGetExceptionCallback(VB *sim);
|
||||||
VBAPI vbOnExecute vbGetExecuteCallback (VB *sim);
|
VBAPI vbOnExecute vbGetExecuteCallback (VB *sim);
|
||||||
VBAPI vbOnFetch vbGetFetchCallback (VB *sim);
|
VBAPI vbOnFetch vbGetFetchCallback (VB *sim);
|
||||||
VBAPI vbOnFrame vbGetFrameCallback (VB *sim);
|
VBAPI vbOnFrame vbGetFrameCallback (VB *sim);
|
||||||
|
VBAPI uint16_t vbGetKeys (VB *sim);
|
||||||
VBAPI void vbGetPixels (VB *sim, void *left, int leftStrideX, int leftStrideY, void *right, int rightStrideX, int rightStrideY);
|
VBAPI void vbGetPixels (VB *sim, void *left, int leftStrideX, int leftStrideY, void *right, int rightStrideX, int rightStrideY);
|
||||||
VBAPI uint32_t vbGetProgramCounter (VB *sim);
|
VBAPI uint32_t vbGetProgramCounter (VB *sim);
|
||||||
VBAPI int32_t vbGetProgramRegister (VB *sim, int index);
|
VBAPI int32_t vbGetProgramRegister (VB *sim, int index);
|
||||||
|
@ -123,6 +124,7 @@ VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback);
|
||||||
VBAPI vbOnExecute vbSetExecuteCallback (VB *sim, vbOnExecute callback);
|
VBAPI vbOnExecute vbSetExecuteCallback (VB *sim, vbOnExecute callback);
|
||||||
VBAPI vbOnFetch vbSetFetchCallback (VB *sim, vbOnFetch callback);
|
VBAPI vbOnFetch vbSetFetchCallback (VB *sim, vbOnFetch callback);
|
||||||
VBAPI vbOnFrame vbSetFrameCallback (VB *sim, vbOnFrame callback);
|
VBAPI vbOnFrame vbSetFrameCallback (VB *sim, vbOnFrame callback);
|
||||||
|
VBAPI uint16_t vbSetKeys (VB *sim, uint16_t keys);
|
||||||
VBAPI uint32_t vbSetProgramCounter (VB *sim, uint32_t value);
|
VBAPI uint32_t vbSetProgramCounter (VB *sim, uint32_t value);
|
||||||
VBAPI int32_t vbSetProgramRegister (VB *sim, int index, int32_t value);
|
VBAPI int32_t vbSetProgramRegister (VB *sim, int index, int32_t value);
|
||||||
VBAPI vbOnRead vbSetReadCallback (VB *sim, vbOnRead callback);
|
VBAPI vbOnRead vbSetReadCallback (VB *sim, vbOnRead callback);
|
||||||
|
|
Loading…
Reference in New Issue