157 lines
4.5 KiB
C
157 lines
4.5 KiB
C
|
/* 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 */
|