pvbemu/src/core/vip.c

299 lines
8.9 KiB
C

/* This file is included through vue.c and cannot be built directly. */
#ifdef VUEAPI
/*****************************************************************************
* Internal Functions *
******************************************************************************/
/* Process the simulation */
static void vipEmulate(Vue *vue, uint32_t cycles) {
vue = vue;
cycles = cycles;
}
/* Read an I/O register */
static int32_t vipReadRegister(Vue *vue, int32_t address) {
vue=vue;
/* Process by register */
switch (address & ~1) {
case 0x0005F800: break; /* INTPND */
case 0x0005F802: break; /* INTENB */
case 0x0005F804: break; /* INTCLR */
case 0x0005F820: break; /* DPSTTS */
case 0x0005F822: break; /* DPCTRL */
case 0x0005F824: break; /* BRTA */
case 0x0005F826: break; /* BRTB */
case 0x0005F828: break; /* BRTC */
case 0x0005F82A: break; /* REST */
case 0x0005F82E: break; /* FRMCYC */
case 0x0005F830: break; /* CTA */
case 0x0005F840: break; /* XPSTTS */
case 0x0005F842: break; /* XPCTRL */
case 0x0005F844: break; /* VER */
case 0x0005F848: break; /* SPT0 */
case 0x0005F84A: break; /* SPT1 */
case 0x0005F84C: break; /* SPT2 */
case 0x0005F84E: break; /* SPT3 */
case 0x0005F860: break; /* GPLT0 */
case 0x0005F862: break; /* GPLT1 */
case 0x0005F864: break; /* GPLT2 */
case 0x0005F866: break; /* GPLT3 */
case 0x0005F868: break; /* JPLT0 */
case 0x0005F86A: break; /* JPLT1 */
case 0x0005F86C: break; /* JPLT2 */
case 0x0005F86E: break; /* JPLT3 */
case 0x0005F870: break; /* BKCOL */
}
/* Unmapped */
return 0;
}
/* Read an I/O register */
static void vipWriteRegister(Vue *vue, int32_t address, int32_t value) {
vue=vue;
value=value;
/* Process by register */
switch (address & ~1) {
case 0x0005F800: break; /* INTPND */
case 0x0005F802: break; /* INTENB */
case 0x0005F804: break; /* INTCLR */
case 0x0005F820: break; /* DPSTTS */
case 0x0005F822: break; /* DPCTRL */
case 0x0005F824: break; /* BRTA */
case 0x0005F826: break; /* BRTB */
case 0x0005F828: break; /* BRTC */
case 0x0005F82A: break; /* REST */
case 0x0005F82E: break; /* FRMCYC */
case 0x0005F830: break; /* CTA */
case 0x0005F840: break; /* XPSTTS */
case 0x0005F842: break; /* XPCTRL */
case 0x0005F844: break; /* VER */
case 0x0005F848: break; /* SPT0 */
case 0x0005F84A: break; /* SPT1 */
case 0x0005F84C: break; /* SPT2 */
case 0x0005F84E: break; /* SPT3 */
case 0x0005F860: break; /* GPLT0 */
case 0x0005F862: break; /* GPLT1 */
case 0x0005F864: break; /* GPLT2 */
case 0x0005F866: break; /* GPLT3 */
case 0x0005F868: break; /* JPLT0 */
case 0x0005F86A: break; /* JPLT1 */
case 0x0005F86C: break; /* JPLT2 */
case 0x0005F86E: break; /* JPLT3 */
case 0x0005F870: break; /* BKCOL */
}
}
/* Read a value from the CPU bus */
static int32_t vipRead(Vue *vue, int32_t address, int32_t type) {
int32_t value; /* Register value */
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x00040000)
return readBuffer(vue->vip.vram, 0x40000, address, type);
/* Mirrors of character memory */
if (address >= 0x00078000)
return readBuffer(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
type);
/* I/O register or unmapped */
value = vipReadRegister(vue, address);
if (type < 2 && (address & 1) == 1)
value >>= 8;
switch (type) {
case VUE_S8 : return SIGN_EXTEND(value, 8);
case VUE_U8 : return value & 0x000000FF;
case VUE_S16: return SIGN_EXTEND(value, 16);
case VUE_S32: return value | vipReadRegister(vue, address + 2) << 16;
}
return value; /* U16 */
}
/* Read bytes from the CPU bus */
static void vipReadBytes(Vue *vue, int address, uint8_t *dest, int length) {
int32_t count, size, value; /* Working variables */
address &= 0x0007FFFF;
/* Perform the operation */
while (length > 0) {
/* VRAM */
if (address < 0x00040000) {
count = 0x00040000 - address;
if (length < count)
count = length;
readBytes(vue->vip.vram, 0x40000, address, dest, count);
}
/* Mirrors of character memory */
else if (address >= 0x00078000) {
count = 0x2000 - (address & 0x1FFF);
if (length < count)
count = length;
readBytes(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
dest, count);
}
/* I/O register or unmapped */
else {
count = 0x00078000 - address;
if (length < count)
count = length;
/* Read all registers in the range */
while (count > 0) {
value = vipReadRegister(vue, address);
/* Odd address */
if ((address & 1) == 1) {
*dest = value >> 8;
address++;
count --;
length --;
dest ++;
continue;
}
/* Even address */
size = count == 1 ? 1 : 2;
*dest = value;
if (size == 2)
dest[1] = value >> 8;
address += size;
count -= size;
length -= size;
dest += size;
}
continue;
}
/* Advance to the next region */
address += count;
length -= count;
dest += count;
}
}
/* System reset */
static void vipReset(Vue *vue) {
vue = vue;
}
/* Determine the number of CPU cycles until a breakpoint could trigger */
static uint32_t vipUntil(Vue *vue, uint32_t cycles) {
vue = vue;
return cycles;
}
/* Write a value to the CPU bus */
static void vipWrite(Vue *vue, int32_t address, int32_t type, int32_t value) {
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x00040000) {
writeBuffer(vue->vip.vram, 0x40000, address, type, value);
return;
}
/* Mirrors of character memory */
if (address >= 0x00078000) {
writeBuffer(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
type, value);
return;
}
/* I/O register or unmapped */
if (type < 2 && (address & 1) == 1)
value <<= 8;
vipWriteRegister(vue, address, value);
if (type == VUE_S32)
vipWriteRegister(vue, address + 2, value >> 16);
}
/* Write bytes to the CPU bus */
static void vipWriteBytes(Vue *vue, int address, uint8_t *src, int length) {
int32_t count, size, value; /* Working variables */
address &= 0x0007FFFF;
/* Perform the operation */
while (length > 0) {
/* VRAM */
if (address < 0x00040000) {
count = 0x00040000 - address;
if (length < count)
count = length;
writeBytes(vue->vip.vram, 0x40000, address, src, count);
}
/* Mirrors of character memory */
else if (address >= 0x00078000) {
count = 0x2000 - (address & 0x1FFF);
if (length < count)
count = length;
writeBytes(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
src, count);
}
/* I/O register or unmapped */
else {
count = 0x00078000 - address;
if (length < count)
count = length;
/* Read all registers in the range */
while (count > 0) {
value = *src;
/* Odd address */
if ((address & 1) == 1) {
vipWriteRegister(vue, address, value << 8);
address++;
count --;
length --;
src ++;
continue;
}
/* Even address */
size = count == 1 ? 1 : 2;
if (size == 2)
value |= src[1] << 8;
vipWriteRegister(vue, address, value);
address += size;
count -= size;
length -= size;
src += size;
}
continue;
}
/* Advance to the next region */
address += count;
length -= count;
src += count;
}
}
#endif