pvbemu/core/bus.c

159 lines
5.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* This file is included into vb.c and cannot be compiled on its own. */
#ifdef VBAPI
/***************************** Utility Functions *****************************/
/* Read a data unit from a memory buffer */
static int32_t busReadBuffer(uint8_t *mem, int type) {
/* 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;
/* Generic implementation */
#else
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 */
static void busWriteBuffer(uint8_t *mem, int type, int32_t value) {
/* 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;
/* Generic implementation */
#else
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
}
/***************************** Module Functions ******************************/
/* Read a data unit from the bus */
static int32_t busRead(VB *sim, uint32_t address, int type, int debug) {
/* Force address alignment */
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
/* Process by address range */
switch (address >> 24 & 7) {
case 0 : return 0; /* VIP */
case 1 : return 0 * debug; /* VSU */
case 2 : return 0; /* Miscellaneous hardware */
case 3 : return 0; /* Unmapped */
case 4 : return 0; /* Game pak expansion */
case 5 : return /* WRAM */
busReadBuffer(&sim->wram[address & 0xFFFF], type);
case 6 : return sim->cart.sram == NULL ? 0 : /* Game pak RAM */
busReadBuffer(&sim->cart.sram
[address & (sim->cart.sramSize - 1)], type);
default: return sim->cart.rom == NULL ? 0 : /* Game pak ROM */
busReadBuffer(&sim->cart.rom
[address & (sim->cart.romSize - 1)], type);
}
}
/* Write a data unit to the bus */
static void busWrite(
VB *sim, uint32_t address, int type, uint32_t value, int debug) {
/* Force address alignment */
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
/* Process by address range */
switch (address >> 24 & 7) {
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 */
busWriteBuffer(&sim->wram[address & 0xFFFF], type, value);
return;
case 6 : /* Cartridge RAM */
if (sim->cart.sram != NULL)
busWriteBuffer(&sim->cart.sram
[address & (sim->cart.sramSize - 1)], type, value);
return;
default: /* Cartridge ROM */
if (debug && sim->cart.rom != NULL)
busWriteBuffer(&sim->cart.rom
[address & (sim->cart.romSize - 1)], type, value);
}
}
#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;
}
#endif /* VBAPI */