/* 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 *****************************/ /* 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) { case 0: break; /* VIP */ 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) { case 0: break; /* VIP */ 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 */