pvbemu/core/bus.c

157 lines
4.5 KiB
C
Raw Permalink 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
2024-10-10 23:35:16 +00:00
/********************************* Constants *********************************/
/* Memory access address masks by data type */
static const uint32_t TYPE_MASKS[] = {
0x07FFFFFF, /* S8 */
0x07FFFFFF, /* U8 */
0x07FFFFFE, /* S16 */
0x07FFFFFE, /* U16 */
0x07FFFFFC /* S32 */
};
2021-09-19 01:31:40 +00:00
2023-03-11 00:44:57 +00:00
2024-10-10 23:35:16 +00:00
/*************************** Sub-Module Functions ****************************/
/* Read a typed value from a buffer in host memory */
static int32_t busReadBuffer(uint8_t *data, int type) {
2023-03-11 00:44:57 +00:00
2024-10-10 23:35:16 +00:00
/* Processing by data type */
2023-03-11 00:44:57 +00:00
switch (type) {
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
2024-10-10 23:35:16 +00:00
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 */
2023-03-11 00:44:57 +00:00
#else
2024-10-10 23:35:16 +00:00
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;
2023-03-11 00:44:57 +00:00
#endif
2021-09-19 01:31:40 +00:00
2023-03-11 00:44:57 +00:00
}
2024-10-10 23:35:16 +00:00
return 0; /* Unreachable */
2021-09-19 01:31:40 +00:00
}
2023-03-11 00:44:57 +00:00
/* Write a typed value to a buffer in host memory */
2024-10-10 23:35:16 +00:00
static void busWriteBuffer(uint8_t *data, int type, int32_t value) {
2021-09-19 01:31:40 +00:00
2024-10-10 23:35:16 +00:00
/* Processing by data type */
2023-03-11 00:44:57 +00:00
switch (type) {
2021-09-19 01:31:40 +00:00
2023-03-11 00:44:57 +00:00
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
2024-10-10 23:35:16 +00:00
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 */
2023-03-11 00:44:57 +00:00
#else
2024-10-10 23:35:16 +00:00
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;
2023-03-11 00:44:57 +00:00
#endif
2021-09-19 01:31:40 +00:00
}
2021-08-30 02:14:06 +00:00
}
2024-10-10 23:35:16 +00:00
/***************************** Library Functions *****************************/
2021-09-19 01:31:40 +00:00
2023-03-11 00:44:57 +00:00
/* Read a typed value from the simulation bus */
2024-10-10 23:35:16 +00:00
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;
2023-03-08 17:10:33 +00:00
}
}
/* Write a typed value to the simulation bus */
2023-03-11 01:00:45 +00:00
static void busWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
2023-03-08 17:10:33 +00:00
2024-10-10 23:35:16 +00:00
/* Working variables */
address &= TYPE_MASKS[type];
/* Process by address range */
switch (address >> 24) {
2023-03-08 17:10:33 +00:00
case 0: break; /* VIP */
case 1: break; /* VSU */
2024-10-10 23:35:16 +00:00
case 2: break; /* Misc. I/O */
2023-03-08 17:10:33 +00:00
case 3: break; /* Unmapped */
2024-10-10 23:35:16 +00:00
case 4: break; /* Game Pak expansion */
case 5: /* WRAM */
busWriteBuffer(&sim->wram[address & 0x0000FFFF], type, value);
2023-03-08 17:10:33 +00:00
break;
2024-10-10 23:35:16 +00:00
case 6: /* Game Pak RAM */
if (sim->cart.ram != NULL) {
busWriteBuffer(
&sim->cart.ram[address & sim->cart.ramMask], type, value);
}
2023-03-08 17:10:33 +00:00
break;
2024-10-10 23:35:16 +00:00
case 7: /* Game Pak ROM */
if (debug && sim->cart.rom != NULL) {
busWriteBuffer(
&sim->cart.rom[address & sim->cart.romMask], type, value);
}
2023-03-08 17:10:33 +00:00
break;
2024-10-10 23:35:16 +00:00
2023-03-08 17:10:33 +00:00
}
}
2021-08-30 02:14:06 +00:00
#endif /* VBAPI */