pvbemu/core/bus.c

159 lines
5.0 KiB
C
Raw Normal View History

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 */
dBuffer(vb->cart.rom, vb->cart.romSize, address, type);
}
/* Unreachable */
return 0;
}
/* Write a typed value to the simulation bus */
static void busWrite(VB *vb,uint32_t address,int type,int32_t value,int debug){
/* Processing by address region */
switch (address >> 24 & 7) {
case 0: break; /* VIP */
case 1: break; /* VSU */
case 2: break; /* Misc. hardware */
case 3: break; /* Unmapped */
case 4: break; /* Game pak expansion */
case 5: /* WRAM */
busWriteBuffer(vb->wram ,0x10000 ,address,type,value);
break;
case 6: /* Game pak RAM */
busWriteBuffer(vb->cart.ram,vb->cart.ramSize,address,type,value);
break;
case 7: /* Game pak ROM */
busWriteBuffer(vb->cart.rom,vb->cart.romSize,address,type,value);
break;
}
return;
debug = debug ? debug : 0;
}
2021-08-30 02:14:06 +00:00
#endif /* VBAPI */