pvbemu/core/bus.c

163 lines
4.9 KiB
C

/* This file is included into vb.c and cannot be compiled on its own. */
#ifdef VBAPI
/***************************** Utility Functions *****************************/
/* Read a typed value from a buffer in host memory */
static int32_t busReadBuffer(
uint8_t *buffer, uint32_t size, uint32_t offset, int type) {
/* There is no data */
if (buffer == NULL)
return 0;
/* Mirror the buffer across its address range */
offset &= size - 1;
/* Processing by type */
switch (type) {
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
case VB_S8 :
return (int8_t) buffer[offset];
case VB_U8:
return buffer[offset];
case VB_S16:
return (int32_t) (int8_t)
buffer[offset + 1] << 8 | buffer[offset];
case VB_U16:
offset &= 0xFFFFFFFE;
return (int32_t) (int8_t)
buffer[offset + 1] << 8 | buffer[offset];
case VB_S32:
offset &= 0xFFFFFFFC;
return
(int32_t) buffer[offset + 3] << 24 |
(int32_t) buffer[offset + 2] << 16 |
(int32_t) buffer[offset + 1] << 8 |
buffer[offset ]
;
/* Little-endian implementation */
#else
case VB_S8 : return *(int8_t *)&buffer[offset ];
case VB_U8 : return buffer[offset ];
case VB_S16: return *(int16_t *)&buffer[offset & 0xFFFFFFFE];
case VB_U16: return *(uint16_t *)&buffer[offset & 0xFFFFFFFE];
case VB_S32: return *(int32_t *)&buffer[offset & 0xFFFFFFFC];
#endif
}
/* Invalid type */
return 0;
}
/* Write a typed value to a buffer in host memory */
static void busWriteBuffer(
uint8_t *buffer, uint32_t size, uint32_t offset, int type, int32_t value) {
/* There is no data */
if (buffer == NULL)
return;
/* Mirror the buffer across its address range */
offset &= size - 1;
/* Processing by type */
switch (type) {
/* Generic implementation */
#ifndef VB_LITTLE_ENDIAN
case VB_S32:
offset &= 0xFFFFFFFC;
buffer[offset ] = value;
buffer[offset + 1] = value >> 8;
buffer[offset + 2] = value >> 16;
buffer[offset + 3] = value >> 24;
break;
case VB_S16:
case VB_U16:
offset &= 0xFFFFFFFE;
buffer[offset ] = value;
buffer[offset + 1] = value >> 8;
break;
case VB_S8 :
case VB_U8 :
buffer[offset ] = value;
/* Little-endian implementation */
#else
case VB_S8 :
case VB_U8 :
buffer[offset ] = value;
break;
case VB_S16:
case VB_U16:
*(int16_t *)&buffer[offset & 0xFFFFFFFE] = value;
break;
case VB_S32:
*(int32_t *)&buffer[offset & 0xFFFFFFFC] = value;
#endif
}
}
/***************************** Module Functions ******************************/
/* Read a typed value from the simulation bus */
static int32_t busRead(VB *sim, uint32_t address, int type) {
/* Processing by address region */
switch (address >> 24 & 7) {
case 0: return 0; /* VIP */
case 1: return 0; /* VSU */
case 2: return 0; /* Misc. hardware */
case 3: return 0; /* Unmapped */
case 4: return 0; /* Game pak expansion */
case 5: return /* WRAM */
busReadBuffer(sim->wram , 0x10000 , address, type);
case 6: return /* Game pak RAM */
busReadBuffer(sim->cart.ram, sim->cart.ramSize, address, type);
case 7: return /* Game pak ROM */
busReadBuffer(sim->cart.rom, sim->cart.romSize, address, type);
}
/* Unreachable */
return 0;
}
/* Write a typed value to the simulation bus */
static void busWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
(void) 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(sim->wram ,0x10000 ,address,type,value);
break;
case 6: /* Game pak RAM */
busWriteBuffer(sim->cart.ram,sim->cart.ramSize,address,type,value);
break;
case 7: /* Game pak ROM */
busWriteBuffer(sim->cart.rom,sim->cart.romSize,address,type,value);
break;
}
}
#endif /* VBAPI */