159 lines
5.0 KiB
C
159 lines
5.0 KiB
C
/* This file is included into vb.c and cannot be compiled on its own. */
|
||
#ifdef VBAPI
|
||
|
||
|
||
|
||
/***************************** Utility Functions *****************************/
|
||
|
||
/* Read a data unit from a memory buffer */
|
||
static int32_t busReadBuffer(uint8_t *mem, int type) {
|
||
|
||
/* 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;
|
||
|
||
/* Generic implementation */
|
||
#else
|
||
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 */
|
||
static void busWriteBuffer(uint8_t *mem, int type, int32_t value) {
|
||
|
||
/* 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;
|
||
|
||
/* Generic implementation */
|
||
#else
|
||
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
|
||
|
||
}
|
||
|
||
|
||
|
||
/***************************** Module Functions ******************************/
|
||
|
||
/* Read a data unit from the bus */
|
||
static int32_t busRead(VB *sim, uint32_t address, int type, int debug) {
|
||
|
||
/* Force address alignment */
|
||
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
|
||
|
||
/* Process by address range */
|
||
switch (address >> 24 & 7) {
|
||
case 0 : return 0; /* VIP */
|
||
case 1 : return 0 * debug; /* VSU */
|
||
case 2 : return 0; /* Miscellaneous hardware */
|
||
case 3 : return 0; /* Unmapped */
|
||
case 4 : return 0; /* Game pak expansion */
|
||
case 5 : return /* WRAM */
|
||
busReadBuffer(&sim->wram[address & 0xFFFF], type);
|
||
case 6 : return sim->cart.sram == NULL ? 0 : /* Game pak RAM */
|
||
busReadBuffer(&sim->cart.sram
|
||
[address & (sim->cart.sramSize - 1)], type);
|
||
default: return sim->cart.rom == NULL ? 0 : /* Game pak ROM */
|
||
busReadBuffer(&sim->cart.rom
|
||
[address & (sim->cart.romSize - 1)], type);
|
||
}
|
||
|
||
}
|
||
|
||
/* Write a data unit to the bus */
|
||
static void busWrite(
|
||
VB *sim, uint32_t address, int type, uint32_t value, int debug) {
|
||
|
||
/* Force address alignment */
|
||
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
|
||
|
||
/* Process by address range */
|
||
switch (address >> 24 & 7) {
|
||
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 */
|
||
busWriteBuffer(&sim->wram[address & 0xFFFF], type, value);
|
||
return;
|
||
case 6 : /* Cartridge RAM */
|
||
if (sim->cart.sram != NULL)
|
||
busWriteBuffer(&sim->cart.sram
|
||
[address & (sim->cart.sramSize - 1)], type, value);
|
||
return;
|
||
default: /* Cartridge ROM */
|
||
if (debug && sim->cart.rom != NULL)
|
||
busWriteBuffer(&sim->cart.rom
|
||
[address & (sim->cart.romSize - 1)], type, value);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
#endif /* VBAPI */
|
||
|