Callback symbols, VIP read/write

This commit is contained in:
Guy Perfect 2024-10-15 14:11:29 -05:00
parent 767675eb42
commit c91eb0785f
6 changed files with 538 additions and 49 deletions

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 */

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;
@ -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 ?

View File

@ -87,7 +87,55 @@ 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 control */
struct {
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 */
} dpctrl;
/* Drawing control */
struct {
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 */
uint8_t sbout; /* Drawing specified vertical output position */
uint8_t xpen; /* Drawing enabled */
} xpctrl;
/* 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 */
/* Other state */
uint8_t vram[0x40000]; /* Video memory */
} vip;
/* Other state */
uint8_t wram[0x10000]; /* System RAM */ uint8_t wram[0x10000]; /* System RAM */
/* Application data */ /* Application data */
@ -120,6 +168,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 +177,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;
} }
@ -259,38 +310,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;
} }

View File

@ -24,9 +24,10 @@ extern "C" {
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.
*/ */
/* /*

415
core/vip.c Normal file
View File

@ -0,0 +1,415 @@
/* This file is included into vb.c and cannot be compiled on its own. */
#ifdef VBAPI
/***************************** Module Functions ******************************/
/* Read a palette */
static int32_t vipReadPalette(uint8_t *entries) {
return entries[3] << 6 | entries[2] << 4 | entries[1] << 2;
}
/* Write a palette */
static void vipWritePalette(uint8_t *entries, int32_t mask, int32_t value) {
if (mask & 0x00FF)
return;
entries[3] = value >> 6 & 3;
entries[2] = value >> 4 & 3;
entries[1] = value >> 2 & 3;
}
/* Read a typed value from an I/O register */
static int32_t vipReadIO(VB *sim, uint32_t address, int type) {
int mask; /* Byte access mask */
int32_t value; /* Return value */
/* Adjustments by type */
switch (type) {
case VB_S32: /* Word */
return vipReadIO(sim, address, VB_U16) |
(uint32_t) vipReadIO(sim, address + 2, VB_U16) << 16;
case VB_S8: /* Byte */
case VB_U8:
mask = 0x00FF << ((address & 1) << 3);
break;
case VB_S16: /* Halfword */
case VB_U16:
mask = 0xFFFF;
}
/* Access by register */
switch (address >> 1) {
case 0x5F800>>1: /* INTPND */
value = sim->vip.intpnd;
break;
case 0x5F802>>1: /* INTENB */
value = sim->vip.intenb;
break;
case 0x5F820>>1: /* DPSTTS */
value =
(int32_t) sim->vip.dpctrl.lock << 10 |
(int32_t) sim->vip.dpctrl.synce << 9 |
(int32_t) sim->vip.dpctrl.re << 8 |
(int32_t) sim->vip.dpctrl.fclk << 7 |
(int32_t) sim->vip.dpctrl.scanrdy << 6 |
(int32_t) sim->vip.dpctrl.r1bsy << 5 |
(int32_t) sim->vip.dpctrl.l1bsy << 4 |
(int32_t) sim->vip.dpctrl.r0bsy << 3 |
(int32_t) sim->vip.dpctrl.l0bsy << 2 |
(int32_t) sim->vip.dpctrl.disp << 1
;
break;
case 0x5F824>>1: /* BRTA */
value = sim->vip.brtRest[0];
break;
case 0x5F826>>1: /* BRTB */
value = sim->vip.brtRest[1];
break;
case 0x5F828>>1: /* BRTC */
value = sim->vip.brtRest[2];
break;
case 0x5F82A>>1: /* REST */
value = sim->vip.brtRest[3];
break;
case 0x5F82E>>1: /* FRMCYC */
value = sim->vip.frmcyc;
break;
case 0x5F830>>1: /* CTA */
value = (int32_t) sim->vip.cta.cta_r << 8 | sim->vip.cta.cta_l;
break;
case 0x5F840>>1: /* XPSTTS */
value =
(int32_t) sim->vip.xpctrl.sbout << 15 |
(int32_t) sim->vip.xpctrl.sbcount << 8 |
(int32_t) sim->vip.xpctrl.overtime << 4 |
(int32_t) sim->vip.xpctrl.f1bsy << 3 |
(int32_t) sim->vip.xpctrl.f0bsy << 2 |
(int32_t) sim->vip.xpctrl.xpen << 1
;
break;
case 0x5F844>>1: /* VER */
value = 2;
break;
case 0x5F848>>1: /* SPT0 */
value = sim->vip.spt[0];
break;
case 0x5F84A>>1: /* SPT1 */
value = sim->vip.spt[1];
break;
case 0x5F84C>>1: /* SPT2 */
value = sim->vip.spt[2];
break;
case 0x5F84E>>1: /* SPT3 */
value = sim->vip.spt[3];
break;
case 0x5F860>>1: /* GPLT0 */
value = vipReadPalette(sim->vip.gplt[0]);
break;
case 0x5F862>>1: /* GPLT1 */
value = vipReadPalette(sim->vip.gplt[1]);
break;
case 0x5F864>>1: /* GPLT2 */
value = vipReadPalette(sim->vip.gplt[2]);
break;
case 0x5F866>>1: /* GPLT3 */
value = vipReadPalette(sim->vip.gplt[3]);
break;
case 0x5F868>>1: /* JPLT0 */
value = vipReadPalette(sim->vip.jplt[0]);
break;
case 0x5F86A>>1: /* JPLT1 */
value = vipReadPalette(sim->vip.jplt[1]);
break;
case 0x5F86C>>1: /* JPLT2 */
value = vipReadPalette(sim->vip.jplt[2]);
break;
case 0x5F86E>>1: /* JPLT3 */
value = vipReadPalette(sim->vip.jplt[3]);
break;
case 0x5F870>>1: /* BKCOL */
value = sim->vip.bkcol;
break;
/* Unmapped */
default: value = 0;
}
/* Select byte bits as necessary */
return
mask == 0x00FF ? value & 0x00FF :
mask == 0xFF00 ? value >> 8 :
value;
}
/* Write a typed value to an I/O register */
static void vipWriteIO(
VB *sim, uint32_t address, int type, int32_t value, int debug) {
int mask; /* Byte access mask */
/* Adjustments by type */
switch (type) {
case VB_S32: /* Word */
vipWriteIO(sim, address , VB_U16, value , debug);
vipWriteIO(sim, address + 2, VB_U16, value >> 16, debug);
return;
case VB_S8: /* Byte */
case VB_U8:
/* Select which half of the register to access */
if (debug) {
mask = (address & 1) << 3;
value = (value & 0x00FF) << mask;
mask = 0xFF00 >> mask;
break;
}
/* Convert to a halfword access */
if ((address & 1) != 0)
value = (value & 0x00FF) << 8;
/* Fallthrough */
default: /* Halfword */
mask = 0x0000;
}
/* Access by register */
switch (address >> 1) {
case 0x5F802>>1: /* INTENB */
sim->vip.intenb = (sim->vip.intenb & mask) | (value & 0xE01F);
break;
case 0x5F804>>1: /* INTCLR */
sim->vip.intpnd &= ~value;
if (sim->vip.intpnd == 0)
sim->cpu.irq &= ~0x0010;
break;
case 0x5F822>>1: /* DPCTRL */
if ((mask & 0xFF00) == 0) {
sim->vip.dpctrl.lock = value >> 10 & 1;
sim->vip.dpctrl.synce = value >> 9 & 1;
sim->vip.dpctrl.re = value >> 8 & 1;
}
if ((mask & 0x00FF) == 0) {
sim->vip.dpctrl.disp = value >> 1 & 1;
/* if (value & 1) {} TODO: DPRST */
}
break;
case 0x5F824>>1: /* BRTA */
sim->vip.brtRest[0] = (sim->vip.brtRest[0] & mask) | value;
break;
case 0x5F826>>1: /* BRTB */
sim->vip.brtRest[1] = (sim->vip.brtRest[1] & mask) | value;
break;
case 0x5F828>>1: /* BRTC */
sim->vip.brtRest[2] = (sim->vip.brtRest[2] & mask) | value;
break;
case 0x5F82A>>1: /* REST */
sim->vip.brtRest[3] = (sim->vip.brtRest[3] & mask) | value;
break;
case 0x5F82E>>1: /* FRMCYC */
sim->vip.frmcyc = (sim->vip.frmcyc & mask) | (value & 15);
break;
case 0x5F830>>1: /* CTA */
if ((mask & 0xFF00) == 0)
sim->vip.cta.cta_r = value >> 8;
if ((mask & 0x00FF) == 0)
sim->vip.cta.cta_l = value;
break;
case 0x5F842>>1: /* XPCTRL */
if ((mask & 0xFF00) == 0)
sim->vip.xpctrl.sbcmp = value >> 8 & 31;
if ((mask & 0x00FF) == 0) {
sim->vip.xpctrl.xpen = value >> 1 & 1;
/* if (value & 1) TODO: XPRST */
}
break;
case 0x5F848>>1: /* SPT0 */
sim->vip.spt[0] = (sim->vip.spt[0]&mask) | (value&0x03FF&~mask);
break;
case 0x5F84A>>1: /* SPT1 */
sim->vip.spt[1] = (sim->vip.spt[1]&mask) | (value&0x03FF&~mask);
break;
case 0x5F84C>>1: /* SPT2 */
sim->vip.spt[2] = (sim->vip.spt[2]&mask) | (value&0x03FF&~mask);
break;
case 0x5F84E>>1: /* SPT3 */
sim->vip.spt[3] = (sim->vip.spt[3]&mask) | (value&0x03FF&~mask);
break;
case 0x5F860>>1: /* GPLT0 */
vipWritePalette(sim->vip.gplt[0], mask, value);
break;
case 0x5F862>>1: /* GPLT1 */
vipWritePalette(sim->vip.gplt[1], mask, value);
break;
case 0x5F864>>1: /* GPLT2 */
vipWritePalette(sim->vip.gplt[2], mask, value);
break;
case 0x5F866>>1: /* GPLT3 */
vipWritePalette(sim->vip.gplt[3], mask, value);
break;
case 0x5F868>>1: /* JPLT0 */
vipWritePalette(sim->vip.jplt[0], mask, value);
break;
case 0x5F86A>>1: /* JPLT1 */
vipWritePalette(sim->vip.jplt[1], mask, value);
break;
case 0x5F86C>>1: /* JPLT2 */
vipWritePalette(sim->vip.jplt[2], mask, value);
break;
case 0x5F86E>>1: /* JPLT3 */
vipWritePalette(sim->vip.jplt[3], mask, value);
break;
case 0x5F870>>1: /* BKCOL */
sim->vip.bkcol = (sim->vip.bkcol & mask) | (value & 3 * ~mask);
break;
}
}
/***************************** Library Functions *****************************/
/* Process component */
static int vipEmulate(VB *sim, uint32_t clocks) {
(void) sim;
(void) clocks;
return 0;
}
/* Read a typed value from the VIP bus */
static void vipRead(VB *sim, uint32_t address, int type, int32_t *value) {
/* Working variables */
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x40000) {
*value = busReadBuffer(&sim->vip.vram[address], type);
}
/* Unmapped */
else if (address < 0x5E000)
*value = 0;
/* I/O register */
else if (address < 0x60000)
*value = vipReadIO(sim, address, type);
/* Unmapped */
if (address < 0x78000)
*value = 0;
/* Mirrors of character memory */
else {
address = 0x06000 | (address << 2 & 0x18000) | (address & 0x01FFF);
*value = busReadBuffer(&sim->vip.vram[address], type);
}
}
/* Simulate a hardware reset */
static void vipReset(VB *sim) {
int x, y; /* Iterators */
/* Normal */
sim->vip.dpctrl.disp = 0;
sim->vip.dpctrl.re = 0;
sim->vip.dpctrl.synce = 0;
sim->vip.intenb = 0x0000;
sim->vip.xpctrl.xpen = 0;
/* Extra (the hardware does not do this) */
sim->vip.bkcol = 0;
sim->vip.cta.cta_l = 0;
sim->vip.cta.cta_r = 0;
sim->vip.frmcyc = 0;
sim->vip.intpnd = 0x0000;
sim->vip.dpctrl.fclk = 0;
sim->vip.dpctrl.l0bsy = 0;
sim->vip.dpctrl.l1bsy = 0;
sim->vip.dpctrl.lock = 0;
sim->vip.dpctrl.r0bsy = 0;
sim->vip.dpctrl.r1bsy = 0;
sim->vip.dpctrl.scanrdy = 0;
sim->vip.xpctrl.f0bsy = 0;
sim->vip.xpctrl.f1bsy = 0;
sim->vip.xpctrl.overtime = 0;
sim->vip.xpctrl.sbcmp = 0;
sim->vip.xpctrl.sbcount = 0;
sim->vip.xpctrl.sbout = 0;
for (x = 0; x < 4; x++) {
sim->vip.brtRest[x] = 0;
sim->vip.spt [x] = 0;
for (y = 0; y < 4; y++) {
sim->vip.gplt[x][y] = 0;
sim->vip.jplt[x][y] = 0;
}
}
}
/* Determine how many clocks are guaranteed to process */
static uint32_t vipUntil(VB *sim, uint32_t clocks) {
(void) sim;
return clocks;
}
/* Write a typed value to the VIP bus */
static void vipWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
(void) debug;
/* Working variables */
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x40000)
busWriteBuffer(&sim->vip.vram[address], type, value);
/* Unmapped */
else if (address < 0x5E000)
;
/* I/O register */
else if (address < 0x60000)
vipWriteIO(sim, address, type, value, debug);
/* Unmapped */
else if (address < 0x78000)
;
/* Mirrors of character memory */
else {
address = 0x06000 | (address << 2 & 0x18000) | (address & 0x01FFF);
busWriteBuffer(&sim->vip.vram[address], type, value);
}
}
#endif /* VBAPI */

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"
@ -26,8 +26,9 @@ core:
@gcc core/vb.c -I core -c -o /dev/null \ @gcc core/vb.c -I core -c -o /dev/null \
-Werror -std=c90 -Wall -Wextra -Wpedantic \ -Werror -std=c90 -Wall -Wextra -Wpedantic \
-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_READ=testRead \
-D VB_DIRECT_WRITE=testWrite
# Clang generic # Clang generic
@emcc core/vb.c -I core -c -o /dev/null \ @emcc core/vb.c -I core -c -o /dev/null \
-Werror -std=c90 -Wall -Wextra -Wpedantic -Werror -std=c90 -Wall -Wextra -Wpedantic
@ -35,8 +36,9 @@ core:
@emcc core/vb.c -I core -c -o /dev/null \ @emcc core/vb.c -I core -c -o /dev/null \
-Werror -std=c90 -Wall -Wextra -Wpedantic \ -Werror -std=c90 -Wall -Wextra -Wpedantic \
-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_READ=testRead \
-D VB_DIRECT_WRITE=testWrite
.PHONY: wasm .PHONY: wasm
wasm: wasm: