299 lines
8.9 KiB
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
|