/* 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