From c91eb0785fea087dcf36f8471624a55506b130e0 Mon Sep 17 00:00:00 2001 From: Guy Perfect Date: Tue, 15 Oct 2024 14:11:29 -0500 Subject: [PATCH] Callback symbols, VIP read/write --- core/bus.c | 16 ++- core/cpu.c | 51 +++++-- core/vb.c | 86 +++++++---- core/vb.h | 7 +- core/vip.c | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 12 +- 6 files changed, 538 insertions(+), 49 deletions(-) create mode 100644 core/vip.c diff --git a/core/bus.c b/core/bus.c index 6ee9655..c9b85ac 100644 --- a/core/bus.c +++ b/core/bus.c @@ -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 */ diff --git a/core/cpu.c b/core/cpu.c index 261ac59..9395b4c 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -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; @@ -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 ? diff --git a/core/vb.c b/core/vb.c index 6934313..dba76cf 100644 --- a/core/vb.c +++ b/core/vb.c @@ -87,7 +87,55 @@ 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 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 */ /* Application data */ @@ -120,6 +168,7 @@ static int32_t SignExtend(int32_t value, int32_t bits) { #include "bus.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 */ 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; } @@ -259,38 +310,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; } diff --git a/core/vb.h b/core/vb.h index 39caf2b..fef2f08 100644 --- a/core/vb.h +++ b/core/vb.h @@ -24,9 +24,10 @@ extern "C" { VB_DIRECT_READ VB_DIRECT_WRITE - Implements callbacks as direct function calls with names in the form of - vbxOn() 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. */ /* diff --git a/core/vip.c b/core/vip.c new file mode 100644 index 0000000..6db9cbc --- /dev/null +++ b/core/vip.c @@ -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 */ diff --git a/makefile b/makefile index 3be4908..5f01476 100644 --- a/makefile +++ b/makefile @@ -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" @@ -26,8 +26,9 @@ core: @gcc core/vb.c -I core -c -o /dev/null \ -Werror -std=c90 -Wall -Wextra -Wpedantic \ -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_READ=testRead \ + -D VB_DIRECT_WRITE=testWrite # Clang generic @emcc core/vb.c -I core -c -o /dev/null \ -Werror -std=c90 -Wall -Wextra -Wpedantic @@ -35,8 +36,9 @@ core: @emcc core/vb.c -I core -c -o /dev/null \ -Werror -std=c90 -Wall -Wextra -Wpedantic \ -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_READ=testRead \ + -D VB_DIRECT_WRITE=testWrite .PHONY: wasm wasm: