Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37b9a94338 | ||
|
|
3c2c9bb938 | ||
|
|
7a8cf8952a | ||
|
|
eecc55bbd7 | ||
|
|
448658430c | ||
|
|
c91eb0785f |
+14
-2
@@ -80,6 +80,10 @@ static void busWriteBuffer(uint8_t *data, int type, int32_t value) {
|
||||
|
||||
/***************************** 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 */
|
||||
static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||
|
||||
@@ -89,7 +93,11 @@ static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||
|
||||
/* Process by address range */
|
||||
switch (address >> 24) {
|
||||
case 0: break; /* VIP */
|
||||
|
||||
case 0: /* VIP */
|
||||
vipRead(sim, address, type, value);
|
||||
break;
|
||||
|
||||
case 1: break; /* VSU */
|
||||
case 2: break; /* Misc. I/O */
|
||||
case 3: break; /* Unmapped */
|
||||
@@ -125,7 +133,11 @@ static void busWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
|
||||
|
||||
/* Process by address range */
|
||||
switch (address >> 24) {
|
||||
case 0: break; /* VIP */
|
||||
|
||||
case 0: /* VIP */
|
||||
vipWrite(sim, address, type, value, debug);
|
||||
break;
|
||||
|
||||
case 1: break; /* VSU */
|
||||
case 2: break; /* Misc. I/O */
|
||||
case 3: break; /* Unmapped */
|
||||
|
||||
+48
-17
@@ -212,8 +212,8 @@ static const uint8_t OPDEFS_FLOATENDO[] = {
|
||||
#ifndef VB_DIRECT_EXCEPTION
|
||||
#define VB_ON_EXCEPTION sim->onException
|
||||
#else
|
||||
extern int vbxOnException(VB *, uint16_t *);
|
||||
#define VB_ON_EXCEPTION sim->onException
|
||||
extern int VB_DIRECT_EXCEPTION(VB *, uint16_t *);
|
||||
#define VB_ON_EXCEPTION VB_DIRECT_EXCEPTION
|
||||
#endif
|
||||
static int cpuOnException(VB *sim, uint16_t *cause) {
|
||||
return sim->onException != NULL && VB_ON_EXCEPTION(sim, cause);
|
||||
@@ -224,8 +224,8 @@ static int cpuOnException(VB *sim, uint16_t *cause) {
|
||||
#ifndef VB_DIRECT_EXECUTE
|
||||
#define VB_ON_EXECUTE sim->onExecute
|
||||
#else
|
||||
extern int vbxOnExecute(VB *, uint32_t, const uint16_t *, int);
|
||||
#define VB_ON_EXECUTE vbxOnExecute
|
||||
extern int VB_DIRECT_EXECUTE(VB *, uint32_t, const uint16_t *, int);
|
||||
#define VB_ON_EXECUTE VB_DIRECT_EXECUTE
|
||||
#endif
|
||||
static int cpuOnExecute(VB *sim) {
|
||||
return
|
||||
@@ -239,8 +239,8 @@ static int cpuOnExecute(VB *sim) {
|
||||
#ifndef VB_DIRECT_READ
|
||||
#define VB_ON_READ sim->onRead
|
||||
#else
|
||||
extern int vbxOnRead(VB *, uint32_t, int, int32_t *, uint32_t *);
|
||||
#define VB_ON_READ vbxOnRead
|
||||
extern int VB_DIRECT_READ(VB *, uint32_t, int, int32_t *, uint32_t *);
|
||||
#define VB_ON_READ VB_DIRECT_READ
|
||||
#endif
|
||||
static int cpuRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||
uint32_t cycles = 4; /* TODO: Research this */
|
||||
@@ -264,8 +264,8 @@ static int cpuRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
||||
#ifndef VB_DIRECT_FETCH
|
||||
#define VB_ON_FETCH sim->onFetch
|
||||
#else
|
||||
extern int vbxOnFetch(VB *, int, uint32_t, int32_t *, uint32_t *);
|
||||
#define VB_ON_FETCH vbxOnFetch
|
||||
extern int VB_DIRECT_FETCH(VB *, int, uint32_t, int32_t *, uint32_t *);
|
||||
#define VB_ON_FETCH VB_DIRECT_FETCH
|
||||
#endif
|
||||
static int cpuReadFetch(VB *sim, int fetch, uint32_t address, int32_t *value) {
|
||||
uint32_t cycles = 0;
|
||||
@@ -289,8 +289,8 @@ static int cpuReadFetch(VB *sim, int fetch, uint32_t address, int32_t *value) {
|
||||
#ifndef VB_DIRECT_WRITE
|
||||
#define VB_ON_WRITE sim->onWrite
|
||||
#else
|
||||
extern int vbxOnWrite(VB *, uint32_t, int, int32_t *, uint32_t *, int *);
|
||||
#define VB_ON_WRITE vbxOnWrite
|
||||
extern int VB_DIRECT_WRITE(VB *,uint32_t,int,int32_t *,uint32_t *,int *);
|
||||
#define VB_ON_WRITE VB_DIRECT_WRITE
|
||||
#endif
|
||||
static int cpuWrite(VB *sim, uint32_t address, int type, int32_t value) {
|
||||
int cancel = 0;
|
||||
@@ -376,7 +376,7 @@ static uint32_t cpuSetSystemRegister(VB*sim,
|
||||
case VB_FEPSW: return sim->cpu.fepsw = value & 0x000FF3FF;
|
||||
case VB_PIR : return 0x00005346;
|
||||
case VB_PSW :
|
||||
sim->cpu.psw.i = value >> 16 & 0xF;
|
||||
sim->cpu.psw.i = value >> 16 & 15;
|
||||
sim->cpu.psw.np = value >> 15 & 1;
|
||||
sim->cpu.psw.ep = value >> 14 & 1;
|
||||
sim->cpu.psw.ae = value >> 13 & 1;
|
||||
@@ -414,7 +414,7 @@ static int cpuIRQ(VB *sim) {
|
||||
if (sim->cpu.psw.id | sim->cpu.psw.ep | sim->cpu.psw.np)
|
||||
return 0;
|
||||
level = IRQ_LEVELS[sim->cpu.irq];
|
||||
if (level == -1 || level > sim->cpu.psw.i)
|
||||
if (level < sim->cpu.psw.i)
|
||||
return 0;
|
||||
cpuThrow(sim, 0xFE00 | level << 4);
|
||||
return 1;
|
||||
@@ -476,6 +476,9 @@ static int cpuException(VB *sim) {
|
||||
/* Regular exception */
|
||||
else {
|
||||
|
||||
/* All exceptions */
|
||||
sim->cpu.eipsw = cpuGetSystemRegister(sim, VB_PSW);
|
||||
|
||||
/* Interrupts only */
|
||||
if ((cause & 0xFF00) == 0xFE00) {
|
||||
sim->cpu.psw.i = (cause >> 4 & 7) + 1;
|
||||
@@ -487,7 +490,6 @@ static int cpuException(VB *sim) {
|
||||
|
||||
/* All exceptions */
|
||||
sim->cpu.ecr.eicc = cause;
|
||||
sim->cpu.eipsw = cpuGetSystemRegister(sim, VB_PSW);
|
||||
sim->cpu.eipc = sim->cpu.pc;
|
||||
sim->cpu.psw.ep = 1;
|
||||
sim->cpu.nextPC = 0xFFFF0000 |
|
||||
@@ -1692,10 +1694,8 @@ static int cpuEmulate(VB *sim, uint32_t clocks) {
|
||||
}
|
||||
|
||||
/* Advance forward the CPU's number of clocks */
|
||||
if (sim->cpu.clocks != 0) {
|
||||
clocks -= sim->cpu.clocks;
|
||||
sim->cpu.clocks = 0;
|
||||
}
|
||||
clocks -= sim->cpu.clocks;
|
||||
sim->cpu.clocks = 0;
|
||||
|
||||
/* Processing by operation ID */
|
||||
switch (sim->cpu.operation) {
|
||||
@@ -1792,6 +1792,37 @@ static int cpuEmulate(VB *sim, uint32_t clocks) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Simulate a hardware reset */
|
||||
static void cpuReset(VB *sim) {
|
||||
uint32_t x; /* Iterator */
|
||||
|
||||
/* Normal */
|
||||
sim->cpu.exception = 0;
|
||||
sim->cpu.halt = 0;
|
||||
sim->cpu.irq = 0;
|
||||
sim->cpu.pc = 0xFFFFFFF0;
|
||||
cpuSetSystemRegister(sim, VB_ECR, 0x0000FFF0, 1);
|
||||
cpuSetSystemRegister(sim, VB_PSW, 0x00008000, 1);
|
||||
|
||||
/* Extra (the hardware does not do this) */
|
||||
sim->cpu.adtre = 0x00000000;
|
||||
sim->cpu.eipc = 0x00000000;
|
||||
sim->cpu.eipsw = 0x00000000;
|
||||
sim->cpu.fepc = 0x00000000;
|
||||
sim->cpu.fepsw = 0x00000000;
|
||||
sim->cpu.sr29 = 0x00000000;
|
||||
sim->cpu.sr31 = 0x00000000;
|
||||
cpuSetSystemRegister(sim, VB_CHCW, 0x00000000, 1);
|
||||
for (x = 0; x < 32; x++)
|
||||
sim->cpu.program[x] = 0x00000000;
|
||||
|
||||
/* Other */
|
||||
sim->cpu.clocks = 0;
|
||||
sim->cpu.nextPC = 0xFFFFFFF0;
|
||||
sim->cpu.operation = CPU_FETCH;
|
||||
sim->cpu.step = 0;
|
||||
}
|
||||
|
||||
/* Determine how many clocks are guaranteed to process */
|
||||
static uint32_t cpuUntil(VB *sim, uint32_t clocks) {
|
||||
return sim->cpu.halt || sim->cpu.clocks > clocks ?
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
/*********************************** Types ***********************************/
|
||||
|
||||
/* Output image */
|
||||
typedef uint8_t Pixels[2][384*224];
|
||||
|
||||
/* Simulation state */
|
||||
struct VB {
|
||||
|
||||
@@ -87,13 +90,91 @@ struct VB {
|
||||
int step; /* Operation sub-task ID */
|
||||
} cpu;
|
||||
|
||||
/* Other system state */
|
||||
/* VIP */
|
||||
struct {
|
||||
|
||||
/* CTA */
|
||||
struct {
|
||||
uint8_t cta_l; /* Left column table index */
|
||||
uint8_t cta_r; /* Right column table index */
|
||||
} cta;
|
||||
|
||||
/* Display processor */
|
||||
struct {
|
||||
|
||||
/* Hardware state */
|
||||
uint8_t disp; /* Display enabled */
|
||||
uint8_t fclk; /* Frame clock signal high */
|
||||
uint8_t l0bsy; /* Displaying left frame buffer 0 */
|
||||
uint8_t l1bsy; /* Displaying left frame buffer 1 */
|
||||
uint8_t lock; /* Lock CTA */
|
||||
uint8_t r0bsy; /* Displaying right frame buffer 0 */
|
||||
uint8_t r1bsy; /* Displaying right frame buffer 1*/
|
||||
uint8_t re; /* Memory refresh enabled */
|
||||
uint8_t scanrdy; /* Mirrors are stable */
|
||||
uint8_t synce; /* Servo enabled */
|
||||
|
||||
/* Simulation state */
|
||||
uint8_t brt[4]; /* Precomputed brightness */
|
||||
int buffer; /* Index of frame buffer to display */
|
||||
uint32_t clocks; /* Master clocks to wait */
|
||||
int column; /* Index of column to display */
|
||||
uint32_t cta; /* Column table pointer in memory */
|
||||
uint32_t fbDest; /* Output frame pixel address */
|
||||
uint32_t fbSrc; /* Source frame buffer address */
|
||||
int32_t repeat; /* Current column table repeat value */
|
||||
int step; /* Processing phase */
|
||||
uint32_t until; /* Clocks until interrupt condition */
|
||||
} dp;
|
||||
|
||||
/* Pixel processor */
|
||||
struct {
|
||||
|
||||
/* Hardware state */
|
||||
uint8_t f0bsy; /* Drawing into frame buffer 0 */
|
||||
uint8_t f1bsy; /* Drawing into frame buffer 1 */
|
||||
uint8_t overtime; /* Drawing extends into display interval */
|
||||
uint8_t sbcmp; /* Vertical output position compare */
|
||||
uint8_t sbcount; /* Current vertical output position */
|
||||
uint32_t sbout; /* Drawing specified vertical output position */
|
||||
uint8_t xpen; /* Drawing enabled */
|
||||
|
||||
/* Simulation state */
|
||||
uint32_t clocks; /* Master clocks to wait */
|
||||
int column; /* Current horizontal output position */
|
||||
int frame; /* FRMCYC counter */
|
||||
int32_t halfword; /* Current output halfword offset */
|
||||
int step; /* Processing phase */
|
||||
uint32_t until; /* Clocks until interrupt condition */
|
||||
} xp;
|
||||
|
||||
/* Control state */
|
||||
uint8_t bkcol; /* Backdrop color */
|
||||
uint8_t brtRest[4]; /* Brightness and REST */
|
||||
uint8_t frmcyc; /* Game frame control */
|
||||
uint8_t gplt[4][4]; /* Background palettes */
|
||||
uint16_t intenb; /* Interrupts enabled */
|
||||
uint16_t intpnd; /* Interrupts pending */
|
||||
uint8_t jplt[4][4]; /* Object palettes */
|
||||
uint16_t spt[4]; /* Object control */
|
||||
|
||||
/* Rendering shadow memory */
|
||||
uint16_t halfwords[384*28]; /* Output timing by 1x8 halfword */
|
||||
Pixels output[2]; /* Output images, row-major */
|
||||
Pixels shadow; /* Drawing shadow image, column-major */
|
||||
|
||||
/* Other state */
|
||||
uint8_t ram[0x40000]; /* Video memory */
|
||||
} vip;
|
||||
|
||||
/* Other state */
|
||||
uint8_t wram[0x10000]; /* System RAM */
|
||||
|
||||
/* Application data */
|
||||
vbOnException onException; /* CPU exception */
|
||||
vbOnExecute onExecute; /* CPU instruction execute */
|
||||
vbOnFetch onFetch; /* CPU instruction fetch */
|
||||
vbOnFrame onFrame; /* VIP frame ready */
|
||||
vbOnRead onRead; /* CPU instruction read */
|
||||
vbOnWrite onWrite; /* CPU instruction write */
|
||||
void *tag; /* User data */
|
||||
@@ -120,6 +201,7 @@ static int32_t SignExtend(int32_t value, int32_t bits) {
|
||||
|
||||
#include "bus.c"
|
||||
#include "cpu.c"
|
||||
#include "vip.c"
|
||||
|
||||
|
||||
|
||||
@@ -128,13 +210,15 @@ static int32_t SignExtend(int32_t value, int32_t bits) {
|
||||
/* Process a simulation for a given number of clocks */
|
||||
static int sysEmulate(VB *sim, uint32_t clocks) {
|
||||
return
|
||||
cpuEmulate(sim, clocks)
|
||||
cpuEmulate(sim, clocks) |
|
||||
vipEmulate(sim, clocks)
|
||||
;
|
||||
}
|
||||
|
||||
/* Determine how many clocks are guaranteed to process */
|
||||
static uint32_t sysUntil(VB *sim, uint32_t clocks) {
|
||||
clocks = cpuUntil(sim, clocks);
|
||||
clocks = vipUntil(sim, clocks);
|
||||
return clocks;
|
||||
}
|
||||
|
||||
@@ -191,21 +275,66 @@ VBAPI void* vbGetCartROM(VB *sim, uint32_t *size) {
|
||||
return sim->cart.rom;
|
||||
}
|
||||
|
||||
/* Retrieve the exception callback handle */
|
||||
/* Retrieve the exception callback handler */
|
||||
VBAPI vbOnException vbGetExceptionCallback(VB *sim) {
|
||||
return sim->onException;
|
||||
}
|
||||
|
||||
/* Retrieve the execute callback handle */
|
||||
/* Retrieve the execute callback handler */
|
||||
VBAPI vbOnExecute vbGetExecuteCallback(VB *sim) {
|
||||
return sim->onExecute;
|
||||
}
|
||||
|
||||
/* Retrieve the fetch callback handle */
|
||||
/* Retrieve the fetch callback handler */
|
||||
VBAPI vbOnFetch vbGetFetchCallback(VB *sim) {
|
||||
return sim->onFetch;
|
||||
}
|
||||
|
||||
/* Retrieve the frame callback handler */
|
||||
VBAPI vbOnFrame vbGetFrameCallback(VB *sim) {
|
||||
return sim->onFrame;
|
||||
}
|
||||
|
||||
/* Retrieve the most recent frame image pixels */
|
||||
VBAPI void vbGetPixels(VB *sim, void *left, int leftStrideX, int leftStrideY,
|
||||
void *right, int rightStrideX, int rightStrideY) {
|
||||
uint8_t *dest; /* Output data */
|
||||
int offset; /* Horizontal offset of output pixel */
|
||||
uint8_t *src; /* Source data */
|
||||
int xStride; /* Bytes between output pixels */
|
||||
int yStride; /* Bytes between output lines */
|
||||
int i, x, y; /* Iterators */
|
||||
|
||||
/* Process both eyes */
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
/* Working variables for left image */
|
||||
if (i == 0) {
|
||||
dest = left;
|
||||
xStride = leftStrideX;
|
||||
yStride = leftStrideY;
|
||||
}
|
||||
|
||||
/* Working variables for right image */
|
||||
else {
|
||||
dest = right;
|
||||
xStride = rightStrideX;
|
||||
yStride = rightStrideY;
|
||||
}
|
||||
|
||||
/* Nothing to do */
|
||||
if (dest == NULL)
|
||||
continue;
|
||||
|
||||
/* Transfer pixels to the destination */
|
||||
src = sim->vip.output[sim->vip.dp.buffer ^ 1][i];
|
||||
for (y = 0; y < 224; y++, dest += yStride)
|
||||
for (x = offset = 0; x < 384; x++, offset += xStride)
|
||||
dest[offset] = *src++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Retrieve the value of the program counter */
|
||||
VBAPI uint32_t vbGetProgramCounter(VB *sim) {
|
||||
return sim->cpu.pc;
|
||||
@@ -216,7 +345,7 @@ VBAPI int32_t vbGetProgramRegister(VB *sim, int index) {
|
||||
return index < 1 || index > 31 ? 0 : sim->cpu.program[index];
|
||||
}
|
||||
|
||||
/* Retrieve the read callback handle */
|
||||
/* Retrieve the read callback handler */
|
||||
VBAPI vbOnRead vbGetReadCallback(VB *sim) {
|
||||
return sim->onRead;
|
||||
}
|
||||
@@ -231,19 +360,20 @@ VBAPI void* vbGetUserData(VB *sim) {
|
||||
return sim->tag;
|
||||
}
|
||||
|
||||
/* Retrieve the write callback handle */
|
||||
/* Retrieve the write callback handler */
|
||||
VBAPI vbOnWrite vbGetWriteCallback(VB *sim) {
|
||||
return sim->onWrite;
|
||||
}
|
||||
|
||||
/* Initialize a simulation instance */
|
||||
VBAPI VB* vbInit(VB *sim) {
|
||||
sim->cart.ram = NULL;
|
||||
sim->cart.rom = NULL;
|
||||
sim->onExecute = NULL;
|
||||
sim->onFetch = NULL;
|
||||
sim->onRead = NULL;
|
||||
sim->onWrite = NULL;
|
||||
sim->cart.ram = NULL;
|
||||
sim->cart.rom = NULL;
|
||||
sim->onExecute = NULL;
|
||||
sim->onFetch = NULL;
|
||||
sim->onFrame = NULL;
|
||||
sim->onRead = NULL;
|
||||
sim->onWrite = NULL;
|
||||
vbReset(sim);
|
||||
return sim;
|
||||
}
|
||||
@@ -259,38 +389,15 @@ VBAPI int32_t vbRead(VB *sim, uint32_t address, int type) {
|
||||
|
||||
/* Simulate a hardware reset */
|
||||
VBAPI VB* vbReset(VB *sim) {
|
||||
uint32_t x; /* Iterator */
|
||||
int x; /* Iterator */
|
||||
|
||||
/* WRAM (the hardware does not do this) */
|
||||
for (x = 0; x < 0x10000; x++)
|
||||
sim->wram[x] = 0x00;
|
||||
|
||||
/* CPU (normal) */
|
||||
sim->cpu.exception = 0;
|
||||
sim->cpu.halt = 0;
|
||||
sim->cpu.irq = 0;
|
||||
sim->cpu.pc = 0xFFFFFFF0;
|
||||
cpuSetSystemRegister(sim, VB_ECR, 0x0000FFF0, 1);
|
||||
cpuSetSystemRegister(sim, VB_PSW, 0x00008000, 1);
|
||||
|
||||
/* CPU (extra, hardware does not do this) */
|
||||
sim->cpu.adtre = 0x00000000;
|
||||
sim->cpu.eipc = 0x00000000;
|
||||
sim->cpu.eipsw = 0x00000000;
|
||||
sim->cpu.fepc = 0x00000000;
|
||||
sim->cpu.fepsw = 0x00000000;
|
||||
sim->cpu.sr29 = 0x00000000;
|
||||
sim->cpu.sr31 = 0x00000000;
|
||||
cpuSetSystemRegister(sim, VB_CHCW, 0x00000000, 1);
|
||||
for (x = 0; x < 32; x++)
|
||||
sim->cpu.program[x] = 0x00000000;
|
||||
|
||||
/* CPU (other) */
|
||||
sim->cpu.clocks = 0;
|
||||
sim->cpu.nextPC = 0xFFFFFFF0;
|
||||
sim->cpu.operation = CPU_FETCH;
|
||||
sim->cpu.step = 0;
|
||||
|
||||
/* Components */
|
||||
cpuReset(sim);
|
||||
vipReset(sim);
|
||||
return sim;
|
||||
}
|
||||
|
||||
@@ -316,27 +423,34 @@ VBAPI int vbSetCartROM(VB *sim, void *rom, uint32_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Specify a new exception callback handle */
|
||||
/* Specify a new exception callback handler */
|
||||
VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback) {
|
||||
vbOnException prev = sim->onException;
|
||||
sim->onException = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new execute callback handle */
|
||||
/* Specify a new execute callback handler */
|
||||
VBAPI vbOnExecute vbSetExecuteCallback(VB *sim, vbOnExecute callback) {
|
||||
vbOnExecute prev = sim->onExecute;
|
||||
sim->onExecute = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new fetch callback handle */
|
||||
/* Specify a new fetch callback handler */
|
||||
VBAPI vbOnFetch vbSetFetchCallback(VB *sim, vbOnFetch callback) {
|
||||
vbOnFetch prev = sim->onFetch;
|
||||
sim->onFetch = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new frame callback handler */
|
||||
VBAPI vbOnFrame vbSetFrameCallback(VB *sim, vbOnFrame callback) {
|
||||
vbOnFrame prev = sim->onFrame;
|
||||
sim->onFrame = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new value for the program counter */
|
||||
VBAPI uint32_t vbSetProgramCounter(VB *sim, uint32_t value) {
|
||||
sim->cpu.operation = CPU_FETCH;
|
||||
@@ -350,7 +464,7 @@ VBAPI int32_t vbSetProgramRegister(VB *sim, int index, int32_t value) {
|
||||
return index < 1 || index > 31 ? 0 : (sim->cpu.program[index] = value);
|
||||
}
|
||||
|
||||
/* Specify a new read callback handle */
|
||||
/* Specify a new read callback handler */
|
||||
VBAPI vbOnRead vbSetReadCallback(VB *sim, vbOnRead callback) {
|
||||
vbOnRead prev = sim->onRead;
|
||||
sim->onRead = callback;
|
||||
@@ -363,7 +477,7 @@ VBAPI uint32_t vbSetSystemRegister(VB *sim, int index, uint32_t value) {
|
||||
cpuSetSystemRegister(sim, index, value, 1);
|
||||
}
|
||||
|
||||
/* Specify a new write callback handle */
|
||||
/* Specify a new write callback handler */
|
||||
VBAPI vbOnWrite vbSetWriteCallback(VB *sim, vbOnWrite callback) {
|
||||
vbOnWrite prev = sim->onWrite;
|
||||
sim->onWrite = callback;
|
||||
|
||||
@@ -21,12 +21,14 @@ extern "C" {
|
||||
VB_DIRECT_EXCEPTION
|
||||
VB_DIRECT_EXECUTE
|
||||
VB_DIRECT_FETCH
|
||||
VB_DIRECT_FRAME
|
||||
VB_DIRECT_READ
|
||||
VB_DIRECT_WRITE
|
||||
|
||||
Implements callbacks as direct function calls with names in the form of
|
||||
vbxOn<callback>() with the same prototypes as the regular function pointer
|
||||
callbacks. If left undefined, the function pointers are used.
|
||||
Implements callbacks as direct function calls with names given by the above
|
||||
symbols in their respective situations. If left undefined, the function
|
||||
pointer in the simulation state is used. Whether or not to call the callback
|
||||
is still determined by whether the function pointer is NULL.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -57,14 +59,6 @@ extern "C" {
|
||||
|
||||
/********************************* Constants *********************************/
|
||||
|
||||
/* Callback IDs */
|
||||
#define VB_EXCEPTION 0
|
||||
#define VB_EXECUTE 1
|
||||
#define VB_FETCH 2
|
||||
#define VB_FRAME 3
|
||||
#define VB_READ 4
|
||||
#define VB_WRITE 5
|
||||
|
||||
/* System registers */
|
||||
#define VB_ADTRE 25
|
||||
#define VB_CHCW 24
|
||||
@@ -95,6 +89,7 @@ typedef struct VB VB;
|
||||
typedef int (*vbOnException)(VB *sim, uint16_t *cause);
|
||||
typedef int (*vbOnExecute )(VB *sim, uint32_t address, const uint16_t *code, int length);
|
||||
typedef int (*vbOnFetch )(VB *sim, int fetch, uint32_t address, int32_t *value, uint32_t *cycles);
|
||||
typedef int (*vbOnFrame )(VB *sim);
|
||||
typedef int (*vbOnRead )(VB *sim, uint32_t address, int type, int32_t *value, uint32_t *cycles);
|
||||
typedef int (*vbOnWrite )(VB *sim, uint32_t address, int type, int32_t *value, uint32_t *cycles, int *cancel);
|
||||
|
||||
@@ -111,6 +106,8 @@ VBAPI void* vbGetCartROM (VB *sim, uint32_t *size);
|
||||
VBAPI vbOnException vbGetExceptionCallback(VB *sim);
|
||||
VBAPI vbOnExecute vbGetExecuteCallback (VB *sim);
|
||||
VBAPI vbOnFetch vbGetFetchCallback (VB *sim);
|
||||
VBAPI vbOnFrame vbGetFrameCallback (VB *sim);
|
||||
VBAPI void vbGetPixels (VB *sim, void *left, int leftStrideX, int leftStrideY, void *right, int rightStrideX, int rightStrideY);
|
||||
VBAPI uint32_t vbGetProgramCounter (VB *sim);
|
||||
VBAPI int32_t vbGetProgramRegister (VB *sim, int index);
|
||||
VBAPI vbOnRead vbGetReadCallback (VB *sim);
|
||||
@@ -125,6 +122,7 @@ VBAPI int vbSetCartROM (VB *sim, void *rom, uint32_t size);
|
||||
VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback);
|
||||
VBAPI vbOnExecute vbSetExecuteCallback (VB *sim, vbOnExecute callback);
|
||||
VBAPI vbOnFetch vbSetFetchCallback (VB *sim, vbOnFetch callback);
|
||||
VBAPI vbOnFrame vbSetFrameCallback (VB *sim, vbOnFrame callback);
|
||||
VBAPI uint32_t vbSetProgramCounter (VB *sim, uint32_t value);
|
||||
VBAPI int32_t vbSetProgramRegister (VB *sim, int index, int32_t value);
|
||||
VBAPI vbOnRead vbSetReadCallback (VB *sim, vbOnRead callback);
|
||||
|
||||
+1167
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo
|
||||
@echo "Shrooms Virtual Boy core module - October 14, 2024"
|
||||
@echo "Shrooms Virtual Boy core module - October 15, 2024"
|
||||
@echo
|
||||
@echo "Target build environment is any Debian with the following packages:"
|
||||
@echo " emscripten"
|
||||
@@ -20,23 +20,25 @@ clean:
|
||||
.PHONY: core
|
||||
core:
|
||||
# GCC generic
|
||||
@gcc core/vb.c -I core -c -o /dev/null \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic
|
||||
@gcc core/vb.c -I core -c -o /dev/null -O3 \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing
|
||||
# GCC compilation control
|
||||
@gcc core/vb.c -I core -c -o /dev/null \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic \
|
||||
@gcc core/vb.c -I core -c -o /dev/null -O3 \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing \
|
||||
-D VB_LITTLE_ENDIAN -D VB_SIGNED_PROPAGATE -D VB_DIV_GENERIC \
|
||||
-D VB_DIRECT_EXCEPTION -D VB_DIRECT_EXECUTE -D VB_DIRECT_FETCH \
|
||||
-D VB_DIRECT_READ -D VB_DIRECT_WRITE -D VB_DIV_GENERIC
|
||||
-D VB_DIRECT_EXCEPTION=textException -D VB_DIRECT_EXECUTE=textExecute \
|
||||
-D VB_DIRECT_FETCH=testFetch -D VB_DIRECT_FRAME=testFrame \
|
||||
-D VB_DIRECT_WRITE=testWrite -D VB_DIRECT_READ=testRead
|
||||
# Clang generic
|
||||
@emcc core/vb.c -I core -c -o /dev/null \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic
|
||||
@emcc core/vb.c -I core -c -o /dev/null -O3 \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing
|
||||
# Clang compilation control
|
||||
@emcc core/vb.c -I core -c -o /dev/null \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic \
|
||||
@emcc core/vb.c -I core -c -o /dev/null -O3 \
|
||||
-Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing \
|
||||
-D VB_LITTLE_ENDIAN -D VB_SIGNED_PROPAGATE -D VB_DIV_GENERIC \
|
||||
-D VB_DIRECT_EXCEPTION -D VB_DIRECT_EXECUTE -D VB_DIRECT_FETCH \
|
||||
-D VB_DIRECT_READ -D VB_DIRECT_WRITE -D VB_DIV_GENERIC
|
||||
-D VB_DIRECT_EXCEPTION=textException -D VB_DIRECT_EXECUTE=textExecute \
|
||||
-D VB_DIRECT_FETCH=testFetch -D VB_DIRECT_FRAME=testFrame \
|
||||
-D VB_DIRECT_WRITE=testWrite -D VB_DIRECT_READ=testRead
|
||||
|
||||
.PHONY: wasm
|
||||
wasm:
|
||||
|
||||
Reference in New Issue
Block a user