shrooms-vb-core/core/bus.c

169 lines
4.8 KiB
C
Raw Normal View History

2024-10-14 20:07:00 +00:00
/* This file is included into vb.c and cannot be compiled on its own. */
#ifdef VBAPI
/********************************* Constants *********************************/
/* Memory access address masks by data type */
static const uint32_t TYPE_MASKS[] = {
0x07FFFFFF, /* S8 */
0x07FFFFFF, /* U8 */
0x07FFFFFE, /* S16 */
0x07FFFFFE, /* U16 */
0x07FFFFFC /* S32 */
};
/*************************** Sub-Module Functions ****************************/
/* Read a typed value from a buffer in host memory */
static int32_t busReadBuffer(uint8_t *data, int type) {
/* Processing by data type */
switch (type) {
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
case VB_S8 : return ((int8_t *)data)[0];
case VB_U8 : return data [0];
case VB_S16: return (int32_t) ((int8_t *)data)[1] << 8 | data[0];
case VB_U16: return (int32_t) data [1] << 8 | data[0];
case VB_S32: return
(int32_t) data[3] << 24 | (int32_t) data[2] << 16 |
(int32_t) data[1] << 8 | data[0];
/* Little-endian host */
#else
case VB_S8 : return *(int8_t *) data;
case VB_U8 : return * data;
case VB_S16: return *(int16_t *) data;
case VB_U16: return *(uint16_t *) data;
case VB_S32: return *(int32_t *) data;
#endif
}
return 0; /* Unreachable */
}
/* Write a typed value to a buffer in host memory */
static void busWriteBuffer(uint8_t *data, int type, int32_t value) {
/* Processing by data type */
switch (type) {
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
case VB_S32: data[3] = value >> 24;
data[2] = value >> 16; /* Fallthrough */
case VB_S16: /* Fallthrough */
case VB_U16: data[1] = value >> 8; /* Fallthrough */
case VB_S8 : /* Fallthrough */
case VB_U8 : data[0] = value;
/* Little-endian host */
#else
case VB_S8 : /* Fallthrough */
case VB_U8 : * data = value; return;
case VB_S16: /* Fallthrough */
case VB_U16: *(uint16_t *) data = value; return;
case VB_S32: *(int32_t *) data = value; return;
#endif
}
}
/***************************** Library Functions *****************************/
2024-10-15 19:11:29 +00:00
/* Forward references */
static void vipRead (VB *, uint32_t, int, int32_t *);
static void vipWrite(VB *, uint32_t, int, int32_t, int);
2024-10-14 20:07:00 +00:00
/* Read a typed value from the simulation bus */
static void busRead(VB *sim, uint32_t address, int type, int32_t *value) {
/* Working variables */
address &= TYPE_MASKS[type];
*value = 0;
/* Process by address range */
switch (address >> 24) {
2024-10-15 19:11:29 +00:00
case 0: /* VIP */
vipRead(sim, address, type, value);
break;
2024-10-14 20:07:00 +00:00
case 1: break; /* VSU */
case 2: break; /* Misc. I/O */
case 3: break; /* Unmapped */
case 4: break; /* Game Pak expansion */
case 5: /* WRAM */
*value = busReadBuffer(&sim->wram[address & 0x0000FFFF], type);
break;
case 6: /* Game Pak RAM */
if (sim->cart.ram != NULL) {
*value = busReadBuffer(
&sim->cart.ram[address & sim->cart.ramMask], type);
}
break;
case 7: /* Game Pak ROM */
if (sim->cart.rom != NULL) {
*value = busReadBuffer(
&sim->cart.rom[address & sim->cart.romMask], type);
}
break;
}
}
/* Write a typed value to the simulation bus */
static void busWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
/* Working variables */
address &= TYPE_MASKS[type];
/* Process by address range */
switch (address >> 24) {
2024-10-15 19:11:29 +00:00
case 0: /* VIP */
vipWrite(sim, address, type, value, debug);
break;
2024-10-14 20:07:00 +00:00
case 1: break; /* VSU */
case 2: break; /* Misc. I/O */
case 3: break; /* Unmapped */
case 4: break; /* Game Pak expansion */
case 5: /* WRAM */
busWriteBuffer(&sim->wram[address & 0x0000FFFF], type, value);
break;
case 6: /* Game Pak RAM */
if (sim->cart.ram != NULL) {
busWriteBuffer(
&sim->cart.ram[address & sim->cart.ramMask], type, value);
}
break;
case 7: /* Game Pak ROM */
if (debug && sim->cart.rom != NULL) {
busWriteBuffer(
&sim->cart.rom[address & sim->cart.romMask], type, value);
}
break;
}
}
#endif /* VBAPI */