2021-08-30 02:14:06 +00:00
|
|
|
|
/* This file is included into vb.c and cannot be compiled on its own. */
|
|
|
|
|
#ifdef VBAPI
|
|
|
|
|
|
2021-09-19 01:31:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************** Utility Functions *****************************/
|
|
|
|
|
|
2021-08-30 13:58:40 +00:00
|
|
|
|
/* Read a data unit from a memory buffer */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
static int32_t busReadBuffer(uint8_t *mem, int type) {
|
2021-08-30 02:14:06 +00:00
|
|
|
|
|
2021-09-02 00:16:22 +00:00
|
|
|
|
/* Little-endian implementation */
|
|
|
|
|
#ifdef VB_LITTLEENDIAN
|
|
|
|
|
switch (type) {
|
|
|
|
|
case VB_S8 : return *(int8_t *)mem;
|
|
|
|
|
case VB_U8 : return * mem;
|
|
|
|
|
case VB_S16: return *(int16_t *)mem;
|
|
|
|
|
case VB_U16: return *(uint16_t *)mem;
|
|
|
|
|
}
|
|
|
|
|
return *(int32_t *)mem;
|
|
|
|
|
|
2021-08-30 02:14:06 +00:00
|
|
|
|
/* Generic implementation */
|
2021-09-02 00:16:22 +00:00
|
|
|
|
#else
|
2021-08-30 02:14:06 +00:00
|
|
|
|
switch (type) {
|
|
|
|
|
case VB_S8 : return (int8_t) *mem;
|
|
|
|
|
case VB_U8 : return *mem;
|
|
|
|
|
case VB_S16: return (int16_t ) (int8_t) mem[1] << 8 | mem[0];
|
|
|
|
|
case VB_U16: return (uint16_t) mem[1] << 8 | mem[0];
|
|
|
|
|
}
|
|
|
|
|
return (int32_t ) mem[3] << 24 | (uint32_t) mem[2] << 16 |
|
|
|
|
|
(uint32_t) mem[1] << 8 | mem[0];
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write a data unit to a memory buffer */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
static void busWriteBuffer(uint8_t *mem, int type, int32_t value) {
|
2021-08-30 02:14:06 +00:00
|
|
|
|
|
2021-09-02 00:16:22 +00:00
|
|
|
|
/* Little-endian implementation */
|
|
|
|
|
#ifdef VB_LITTLEENDIAN
|
|
|
|
|
switch (type) {
|
|
|
|
|
case VB_S16: case VB_U16: *(uint16_t *)mem = value; return;
|
|
|
|
|
case VB_S8 : case VB_U8 : * mem = value; return;
|
|
|
|
|
}
|
|
|
|
|
*(int32_t *)mem = value;
|
|
|
|
|
|
2021-08-30 02:14:06 +00:00
|
|
|
|
/* Generic implementation */
|
2021-09-02 00:16:22 +00:00
|
|
|
|
#else
|
2021-08-30 02:14:06 +00:00
|
|
|
|
switch (type) {
|
|
|
|
|
case VB_S32:
|
|
|
|
|
mem[3] = value >> 24;
|
|
|
|
|
mem[2] = value >> 16;
|
|
|
|
|
/* Fallthrough */
|
|
|
|
|
case VB_S16:
|
|
|
|
|
case VB_U16:
|
|
|
|
|
mem[1] = value >> 8;
|
|
|
|
|
}
|
|
|
|
|
mem[0] = value;
|
|
|
|
|
#endif
|
2021-09-19 01:31:40 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************** Module Functions ******************************/
|
|
|
|
|
|
|
|
|
|
/* Read a data unit from the bus */
|
2022-04-15 01:51:09 +00:00
|
|
|
|
static int32_t busRead(VB *sim, uint32_t address, int type, int debug) {
|
2021-09-19 01:31:40 +00:00
|
|
|
|
|
|
|
|
|
/* Force address alignment */
|
|
|
|
|
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
|
|
|
|
|
|
|
|
|
|
/* Process by address range */
|
|
|
|
|
switch (address >> 24 & 7) {
|
|
|
|
|
case 0 : return 0; /* VIP */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
case 1 : return 0 * debug; /* VSU */
|
2021-09-19 01:31:40 +00:00
|
|
|
|
case 2 : return 0; /* Miscellaneous hardware */
|
|
|
|
|
case 3 : return 0; /* Unmapped */
|
|
|
|
|
case 4 : return 0; /* Game pak expansion */
|
|
|
|
|
case 5 : return /* WRAM */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busReadBuffer(&sim->wram[address & 0xFFFF], type);
|
2022-04-15 01:51:09 +00:00
|
|
|
|
case 6 : return sim->cart.sram == NULL ? 0 : /* Game pak RAM */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busReadBuffer(&sim->cart.sram
|
2022-04-15 01:51:09 +00:00
|
|
|
|
[address & (sim->cart.sramSize - 1)], type);
|
|
|
|
|
default: return sim->cart.rom == NULL ? 0 : /* Game pak ROM */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busReadBuffer(&sim->cart.rom
|
2022-04-15 01:51:09 +00:00
|
|
|
|
[address & (sim->cart.romSize - 1)], type);
|
2021-09-19 01:31:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-30 02:14:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-30 13:58:40 +00:00
|
|
|
|
/* Write a data unit to the bus */
|
2021-08-30 02:14:06 +00:00
|
|
|
|
static void busWrite(
|
2022-04-15 01:51:09 +00:00
|
|
|
|
VB *sim, uint32_t address, int type, uint32_t value, int debug) {
|
2021-08-30 02:14:06 +00:00
|
|
|
|
|
|
|
|
|
/* Force address alignment */
|
|
|
|
|
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
|
|
|
|
|
|
|
|
|
|
/* Process by address range */
|
2021-09-19 19:36:30 +00:00
|
|
|
|
switch (address >> 24 & 7) {
|
2021-08-30 02:14:06 +00:00
|
|
|
|
case 0 : return; /* VIP */
|
|
|
|
|
case 1 : return; /* VSU */
|
|
|
|
|
case 2 : return; /* Miscellaneous hardware */
|
|
|
|
|
case 3 : return; /* Unmapped */
|
|
|
|
|
case 4 : return; /* Game pak expansion */
|
|
|
|
|
case 5 : /* WRAM */
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busWriteBuffer(&sim->wram[address & 0xFFFF], type, value);
|
2021-08-30 02:14:06 +00:00
|
|
|
|
return;
|
|
|
|
|
case 6 : /* Cartridge RAM */
|
2022-04-15 01:51:09 +00:00
|
|
|
|
if (sim->cart.sram != NULL)
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busWriteBuffer(&sim->cart.sram
|
2022-04-15 01:51:09 +00:00
|
|
|
|
[address & (sim->cart.sramSize - 1)], type, value);
|
2021-08-30 02:14:06 +00:00
|
|
|
|
return;
|
|
|
|
|
default: /* Cartridge ROM */
|
2022-04-15 01:51:09 +00:00
|
|
|
|
if (debug && sim->cart.rom != NULL)
|
2022-04-21 03:37:05 +00:00
|
|
|
|
busWriteBuffer(&sim->cart.rom
|
2022-04-15 01:51:09 +00:00
|
|
|
|
[address & (sim->cart.romSize - 1)], type, value);
|
2021-08-30 02:14:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-19 01:31:40 +00:00
|
|
|
|
|
|
|
|
|
|
2023-03-08 16:42:27 +00:00
|
|
|
|
#endif /* VBAPI */
|
|
|
|
|
|