pvbemu/core/bus.c

124 lines
3.8 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 busReadMemory(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 busWriteMemory(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 *emu, 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 : debug = debug; return 0; /* VSU */
case 2 : return 0; /* Miscellaneous hardware */
case 3 : return 0; /* Unmapped */
case 4 : return 0; /* Game pak expansion */
case 5 : return /* WRAM */
busReadMemory(&emu->wram[address & 0xFFFF], type);
case 6 : return emu->cart.sram == NULL ? 0 : /* Game pak RAM */
busReadMemory(&emu->cart.sram
[address & (emu->cart.sramSize - 1)], type);
default: return emu->cart.rom == NULL ? 0 : /* Game pak ROM */
busReadMemory(&emu->cart.rom
[address & (emu->cart.romSize - 1)], type);
}
}
/* Write a data unit to the bus */
static void busWrite(
VB *emu, 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 */
busWriteMemory(&emu->wram[address & 0xFFFF], type, value);
return;
case 6 : /* Cartridge RAM */
if (emu->cart.sram != NULL)
busWriteMemory(&emu->cart.sram
[address & (emu->cart.sramSize - 1)], type, value);
return;
default: /* Cartridge ROM */
if (debug && emu->cart.rom != NULL)
busWriteMemory(&emu->cart.rom
[address & (emu->cart.romSize - 1)], type, value);
}
}
#endif /* VBAPI */