/* 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 */