Compare commits

...
6 Commits
Author SHA1 Message Date
GuyPerfect 37b9a94338 Implement VIP, fix interrupts 2024-10-19 17:01:36 -05:00
GuyPerfect 3c2c9bb938 Establish drawing procedure 2024-10-16 20:14:38 -05:00
GuyPerfect 7a8cf8952a Implement vipUntil() 2024-10-16 18:19:31 -05:00
GuyPerfect eecc55bbd7 Display tweaks, add vbGetPixels() 2024-10-16 16:53:33 -05:00
GuyPerfect 448658430c Establish display processing 2024-10-16 16:15:39 -05:00
GuyPerfect c91eb0785f Callback symbols, VIP read/write 2024-10-15 14:11:29 -05:00
6 changed files with 1412 additions and 88 deletions
+14 -2
View File
@@ -80,6 +80,10 @@ static void busWriteBuffer(uint8_t *data, int type, int32_t value) {
/***************************** 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) {
@@ -89,7 +93,11 @@ static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
/* Process by address range */ /* Process by address range */
switch (address >> 24) { switch (address >> 24) {
case 0: break; /* VIP */
case 0: /* VIP */
vipRead(sim, address, type, value);
break;
case 1: break; /* VSU */ case 1: break; /* VSU */
case 2: break; /* Misc. I/O */ case 2: break; /* Misc. I/O */
case 3: break; /* Unmapped */ 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 */ /* Process by address range */
switch (address >> 24) { switch (address >> 24) {
case 0: break; /* VIP */
case 0: /* VIP */
vipWrite(sim, address, type, value, debug);
break;
case 1: break; /* VSU */ case 1: break; /* VSU */
case 2: break; /* Misc. I/O */ case 2: break; /* Misc. I/O */
case 3: break; /* Unmapped */ case 3: break; /* Unmapped */
+46 -15
View File
@@ -212,8 +212,8 @@ static const uint8_t OPDEFS_FLOATENDO[] = {
#ifndef VB_DIRECT_EXCEPTION #ifndef VB_DIRECT_EXCEPTION
#define VB_ON_EXCEPTION sim->onException #define VB_ON_EXCEPTION sim->onException
#else #else
extern int vbxOnException(VB *, uint16_t *); extern int VB_DIRECT_EXCEPTION(VB *, uint16_t *);
#define VB_ON_EXCEPTION sim->onException #define VB_ON_EXCEPTION VB_DIRECT_EXCEPTION
#endif #endif
static int cpuOnException(VB *sim, uint16_t *cause) { static int cpuOnException(VB *sim, uint16_t *cause) {
return sim->onException != NULL && VB_ON_EXCEPTION(sim, 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 #ifndef VB_DIRECT_EXECUTE
#define VB_ON_EXECUTE sim->onExecute #define VB_ON_EXECUTE sim->onExecute
#else #else
extern int vbxOnExecute(VB *, uint32_t, const uint16_t *, int); extern int VB_DIRECT_EXECUTE(VB *, uint32_t, const uint16_t *, int);
#define VB_ON_EXECUTE vbxOnExecute #define VB_ON_EXECUTE VB_DIRECT_EXECUTE
#endif #endif
static int cpuOnExecute(VB *sim) { static int cpuOnExecute(VB *sim) {
return return
@@ -239,8 +239,8 @@ static int cpuOnExecute(VB *sim) {
#ifndef VB_DIRECT_READ #ifndef VB_DIRECT_READ
#define VB_ON_READ sim->onRead #define VB_ON_READ sim->onRead
#else #else
extern int vbxOnRead(VB *, uint32_t, int, int32_t *, uint32_t *); extern int VB_DIRECT_READ(VB *, uint32_t, int, int32_t *, uint32_t *);
#define VB_ON_READ vbxOnRead #define VB_ON_READ VB_DIRECT_READ
#endif #endif
static int cpuRead(VB *sim, uint32_t address, int type, int32_t *value) { static int cpuRead(VB *sim, uint32_t address, int type, int32_t *value) {
uint32_t cycles = 4; /* TODO: Research this */ 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 #ifndef VB_DIRECT_FETCH
#define VB_ON_FETCH sim->onFetch #define VB_ON_FETCH sim->onFetch
#else #else
extern int vbxOnFetch(VB *, int, uint32_t, int32_t *, uint32_t *); extern int VB_DIRECT_FETCH(VB *, int, uint32_t, int32_t *, uint32_t *);
#define VB_ON_FETCH vbxOnFetch #define VB_ON_FETCH VB_DIRECT_FETCH
#endif #endif
static int cpuReadFetch(VB *sim, int fetch, uint32_t address, int32_t *value) { static int cpuReadFetch(VB *sim, int fetch, uint32_t address, int32_t *value) {
uint32_t cycles = 0; 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 #ifndef VB_DIRECT_WRITE
#define VB_ON_WRITE sim->onWrite #define VB_ON_WRITE sim->onWrite
#else #else
extern int vbxOnWrite(VB *, uint32_t, int, int32_t *, uint32_t *, int *); extern int VB_DIRECT_WRITE(VB *,uint32_t,int,int32_t *,uint32_t *,int *);
#define VB_ON_WRITE vbxOnWrite #define VB_ON_WRITE VB_DIRECT_WRITE
#endif #endif
static int cpuWrite(VB *sim, uint32_t address, int type, int32_t value) { static int cpuWrite(VB *sim, uint32_t address, int type, int32_t value) {
int cancel = 0; int cancel = 0;
@@ -376,7 +376,7 @@ static uint32_t cpuSetSystemRegister(VB*sim,
case VB_FEPSW: return sim->cpu.fepsw = value & 0x000FF3FF; case VB_FEPSW: return sim->cpu.fepsw = value & 0x000FF3FF;
case VB_PIR : return 0x00005346; case VB_PIR : return 0x00005346;
case VB_PSW : 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.np = value >> 15 & 1;
sim->cpu.psw.ep = value >> 14 & 1; sim->cpu.psw.ep = value >> 14 & 1;
sim->cpu.psw.ae = value >> 13 & 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) if (sim->cpu.psw.id | sim->cpu.psw.ep | sim->cpu.psw.np)
return 0; return 0;
level = IRQ_LEVELS[sim->cpu.irq]; level = IRQ_LEVELS[sim->cpu.irq];
if (level == -1 || level > sim->cpu.psw.i) if (level < sim->cpu.psw.i)
return 0; return 0;
cpuThrow(sim, 0xFE00 | level << 4); cpuThrow(sim, 0xFE00 | level << 4);
return 1; return 1;
@@ -476,6 +476,9 @@ static int cpuException(VB *sim) {
/* Regular exception */ /* Regular exception */
else { else {
/* All exceptions */
sim->cpu.eipsw = cpuGetSystemRegister(sim, VB_PSW);
/* Interrupts only */ /* Interrupts only */
if ((cause & 0xFF00) == 0xFE00) { if ((cause & 0xFF00) == 0xFE00) {
sim->cpu.psw.i = (cause >> 4 & 7) + 1; sim->cpu.psw.i = (cause >> 4 & 7) + 1;
@@ -487,7 +490,6 @@ static int cpuException(VB *sim) {
/* All exceptions */ /* All exceptions */
sim->cpu.ecr.eicc = cause; sim->cpu.ecr.eicc = cause;
sim->cpu.eipsw = cpuGetSystemRegister(sim, VB_PSW);
sim->cpu.eipc = sim->cpu.pc; sim->cpu.eipc = sim->cpu.pc;
sim->cpu.psw.ep = 1; sim->cpu.psw.ep = 1;
sim->cpu.nextPC = 0xFFFF0000 | sim->cpu.nextPC = 0xFFFF0000 |
@@ -1692,10 +1694,8 @@ static int cpuEmulate(VB *sim, uint32_t clocks) {
} }
/* Advance forward the CPU's number of clocks */ /* Advance forward the CPU's number of clocks */
if (sim->cpu.clocks != 0) {
clocks -= sim->cpu.clocks; clocks -= sim->cpu.clocks;
sim->cpu.clocks = 0; sim->cpu.clocks = 0;
}
/* Processing by operation ID */ /* Processing by operation ID */
switch (sim->cpu.operation) { switch (sim->cpu.operation) {
@@ -1792,6 +1792,37 @@ static int cpuEmulate(VB *sim, uint32_t clocks) {
return 0; 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 */ /* 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 ? return sim->cpu.halt || sim->cpu.clocks > clocks ?
+153 -39
View File
@@ -8,6 +8,9 @@
/*********************************** Types ***********************************/ /*********************************** Types ***********************************/
/* Output image */
typedef uint8_t Pixels[2][384*224];
/* Simulation state */ /* Simulation state */
struct VB { struct VB {
@@ -87,13 +90,91 @@ struct VB {
int step; /* Operation sub-task ID */ int step; /* Operation sub-task ID */
} cpu; } 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 */ uint8_t wram[0x10000]; /* System RAM */
/* Application data */ /* Application data */
vbOnException onException; /* CPU exception */ vbOnException onException; /* CPU exception */
vbOnExecute onExecute; /* CPU instruction execute */ vbOnExecute onExecute; /* CPU instruction execute */
vbOnFetch onFetch; /* CPU instruction fetch */ vbOnFetch onFetch; /* CPU instruction fetch */
vbOnFrame onFrame; /* VIP frame ready */
vbOnRead onRead; /* CPU instruction read */ vbOnRead onRead; /* CPU instruction read */
vbOnWrite onWrite; /* CPU instruction write */ vbOnWrite onWrite; /* CPU instruction write */
void *tag; /* User data */ void *tag; /* User data */
@@ -120,6 +201,7 @@ static int32_t SignExtend(int32_t value, int32_t bits) {
#include "bus.c" #include "bus.c"
#include "cpu.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 */ /* Process a simulation for a given number of clocks */
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)
; ;
} }
/* Determine how many clocks are guaranteed to process */ /* Determine how many clocks are guaranteed to process */
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);
return clocks; return clocks;
} }
@@ -191,21 +275,66 @@ VBAPI void* vbGetCartROM(VB *sim, uint32_t *size) {
return sim->cart.rom; return sim->cart.rom;
} }
/* Retrieve the exception callback handle */ /* Retrieve the exception callback handler */
VBAPI vbOnException vbGetExceptionCallback(VB *sim) { VBAPI vbOnException vbGetExceptionCallback(VB *sim) {
return sim->onException; return sim->onException;
} }
/* Retrieve the execute callback handle */ /* Retrieve the execute callback handler */
VBAPI vbOnExecute vbGetExecuteCallback(VB *sim) { VBAPI vbOnExecute vbGetExecuteCallback(VB *sim) {
return sim->onExecute; return sim->onExecute;
} }
/* Retrieve the fetch callback handle */ /* Retrieve the fetch callback handler */
VBAPI vbOnFetch vbGetFetchCallback(VB *sim) { VBAPI vbOnFetch vbGetFetchCallback(VB *sim) {
return sim->onFetch; 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 */ /* Retrieve the value of the program counter */
VBAPI uint32_t vbGetProgramCounter(VB *sim) { VBAPI uint32_t vbGetProgramCounter(VB *sim) {
return sim->cpu.pc; 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]; 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) { VBAPI vbOnRead vbGetReadCallback(VB *sim) {
return sim->onRead; return sim->onRead;
} }
@@ -231,7 +360,7 @@ VBAPI void* vbGetUserData(VB *sim) {
return sim->tag; return sim->tag;
} }
/* Retrieve the write callback handle */ /* Retrieve the write callback handler */
VBAPI vbOnWrite vbGetWriteCallback(VB *sim) { VBAPI vbOnWrite vbGetWriteCallback(VB *sim) {
return sim->onWrite; return sim->onWrite;
} }
@@ -242,6 +371,7 @@ VBAPI VB* vbInit(VB *sim) {
sim->cart.rom = NULL; sim->cart.rom = NULL;
sim->onExecute = NULL; sim->onExecute = NULL;
sim->onFetch = NULL; sim->onFetch = NULL;
sim->onFrame = NULL;
sim->onRead = NULL; sim->onRead = NULL;
sim->onWrite = NULL; sim->onWrite = NULL;
vbReset(sim); vbReset(sim);
@@ -259,38 +389,15 @@ VBAPI int32_t vbRead(VB *sim, uint32_t address, int type) {
/* Simulate a hardware reset */ /* Simulate a hardware reset */
VBAPI VB* vbReset(VB *sim) { VBAPI VB* vbReset(VB *sim) {
uint32_t x; /* Iterator */ int x; /* Iterator */
/* 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;
/* CPU (normal) */ /* Components */
sim->cpu.exception = 0; cpuReset(sim);
sim->cpu.halt = 0; vipReset(sim);
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;
return sim; return sim;
} }
@@ -316,27 +423,34 @@ VBAPI int vbSetCartROM(VB *sim, void *rom, uint32_t size) {
return 0; return 0;
} }
/* Specify a new exception callback handle */ /* Specify a new exception callback handler */
VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback) { VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback) {
vbOnException prev = sim->onException; vbOnException prev = sim->onException;
sim->onException = callback; sim->onException = callback;
return prev; return prev;
} }
/* Specify a new execute callback handle */ /* Specify a new execute callback handler */
VBAPI vbOnExecute vbSetExecuteCallback(VB *sim, vbOnExecute callback) { VBAPI vbOnExecute vbSetExecuteCallback(VB *sim, vbOnExecute callback) {
vbOnExecute prev = sim->onExecute; vbOnExecute prev = sim->onExecute;
sim->onExecute = callback; sim->onExecute = callback;
return prev; return prev;
} }
/* Specify a new fetch callback handle */ /* Specify a new fetch callback handler */
VBAPI vbOnFetch vbSetFetchCallback(VB *sim, vbOnFetch callback) { VBAPI vbOnFetch vbSetFetchCallback(VB *sim, vbOnFetch callback) {
vbOnFetch prev = sim->onFetch; vbOnFetch prev = sim->onFetch;
sim->onFetch = callback; sim->onFetch = callback;
return prev; 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 */ /* 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;
@@ -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); 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) { VBAPI vbOnRead vbSetReadCallback(VB *sim, vbOnRead callback) {
vbOnRead prev = sim->onRead; vbOnRead prev = sim->onRead;
sim->onRead = callback; sim->onRead = callback;
@@ -363,7 +477,7 @@ VBAPI uint32_t vbSetSystemRegister(VB *sim, int index, uint32_t value) {
cpuSetSystemRegister(sim, index, value, 1); cpuSetSystemRegister(sim, index, value, 1);
} }
/* Specify a new write callback handle */ /* Specify a new write callback handler */
VBAPI vbOnWrite vbSetWriteCallback(VB *sim, vbOnWrite callback) { VBAPI vbOnWrite vbSetWriteCallback(VB *sim, vbOnWrite callback) {
vbOnWrite prev = sim->onWrite; vbOnWrite prev = sim->onWrite;
sim->onWrite = callback; sim->onWrite = callback;
+9 -11
View File
@@ -21,12 +21,14 @@ extern "C" {
VB_DIRECT_EXCEPTION VB_DIRECT_EXCEPTION
VB_DIRECT_EXECUTE VB_DIRECT_EXECUTE
VB_DIRECT_FETCH VB_DIRECT_FETCH
VB_DIRECT_FRAME
VB_DIRECT_READ VB_DIRECT_READ
VB_DIRECT_WRITE VB_DIRECT_WRITE
Implements callbacks as direct function calls with names in the form of Implements callbacks as direct function calls with names given by the above
vbxOn<callback>() with the same prototypes as the regular function pointer symbols in their respective situations. If left undefined, the function
callbacks. If left undefined, the function pointers are used. 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 *********************************/ /********************************* 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 */ /* System registers */
#define VB_ADTRE 25 #define VB_ADTRE 25
#define VB_CHCW 24 #define VB_CHCW 24
@@ -95,6 +89,7 @@ typedef struct VB VB;
typedef int (*vbOnException)(VB *sim, uint16_t *cause); typedef int (*vbOnException)(VB *sim, uint16_t *cause);
typedef int (*vbOnExecute )(VB *sim, uint32_t address, const uint16_t *code, int length); 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 (*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 (*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); 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 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 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);
VBAPI vbOnRead vbGetReadCallback (VB *sim); 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 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 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);
+1167
View File
File diff suppressed because it is too large Load Diff
+15 -13
View File
@@ -1,7 +1,7 @@
.PHONY: help .PHONY: help
help: help:
@echo @echo
@echo "Shrooms Virtual Boy core module - October 14, 2024" @echo "Shrooms Virtual Boy core module - October 15, 2024"
@echo @echo
@echo "Target build environment is any Debian with the following packages:" @echo "Target build environment is any Debian with the following packages:"
@echo " emscripten" @echo " emscripten"
@@ -20,23 +20,25 @@ clean:
.PHONY: core .PHONY: core
core: core:
# GCC generic # GCC generic
@gcc core/vb.c -I core -c -o /dev/null \ @gcc core/vb.c -I core -c -o /dev/null -O3 \
-Werror -std=c90 -Wall -Wextra -Wpedantic -Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing
# GCC compilation control # GCC compilation control
@gcc core/vb.c -I core -c -o /dev/null \ @gcc core/vb.c -I core -c -o /dev/null -O3 \
-Werror -std=c90 -Wall -Wextra -Wpedantic \ -Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing \
-D VB_LITTLE_ENDIAN -D VB_SIGNED_PROPAGATE -D VB_DIV_GENERIC \ -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_EXCEPTION=textException -D VB_DIRECT_EXECUTE=textExecute \
-D VB_DIRECT_READ -D VB_DIRECT_WRITE -D VB_DIV_GENERIC -D VB_DIRECT_FETCH=testFetch -D VB_DIRECT_FRAME=testFrame \
-D VB_DIRECT_WRITE=testWrite -D VB_DIRECT_READ=testRead
# Clang generic # Clang generic
@emcc core/vb.c -I core -c -o /dev/null \ @emcc core/vb.c -I core -c -o /dev/null -O3 \
-Werror -std=c90 -Wall -Wextra -Wpedantic -Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing
# Clang compilation control # Clang compilation control
@emcc core/vb.c -I core -c -o /dev/null \ @emcc core/vb.c -I core -c -o /dev/null -O3 \
-Werror -std=c90 -Wall -Wextra -Wpedantic \ -Werror -std=c90 -Wall -Wextra -Wpedantic -fno-strict-aliasing \
-D VB_LITTLE_ENDIAN -D VB_SIGNED_PROPAGATE -D VB_DIV_GENERIC \ -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_EXCEPTION=textException -D VB_DIRECT_EXECUTE=textExecute \
-D VB_DIRECT_READ -D VB_DIRECT_WRITE -D VB_DIV_GENERIC -D VB_DIRECT_FETCH=testFetch -D VB_DIRECT_FRAME=testFrame \
-D VB_DIRECT_WRITE=testWrite -D VB_DIRECT_READ=testRead
.PHONY: wasm .PHONY: wasm
wasm: wasm: