static void VirgeWaitIdleEmpty() { // Wait until GP is idle and queue is empty. if(gInfo.sharedInfo->chipType == S3_TRIO_3D) while ((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000); else while ((IN_SUBSYS_STAT() & 0x3f00) != 0x3000); }
static void Virge_NopAllCmdSets() { // This function should be called only for the Trio 3D chip. for (int i = 0; i < 1000; i++) { if ( (IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) == 0x20002000) { break; } } gInfo.WaitQueue(7); WriteReg32(CMD_SET, CMD_NOP); }
static void Virge_GEReset(const DisplayModeEx& mode) { SharedInfo& si = *gInfo.sharedInfo; if (si.chipType == S3_TRIO_3D) Virge_NopAllCmdSets(); gInfo.WaitIdleEmpty(); if (si.chipType == S3_TRIO_3D) { bool ge_was_on = false; snooze(10000); for (int r = 1; r < 10; r++) { uint8 resetidx = 0x66; VerticalRetraceWait(); uint8 tmp = ReadCrtcReg(resetidx); VerticalRetraceWait(); IN_SUBSYS_STAT(); // turn off the GE if (tmp & 0x01) { WriteCrtcReg(resetidx, tmp); ge_was_on = true; snooze(10000); } IN_SUBSYS_STAT(); WriteCrtcReg(resetidx, tmp | 0x02); snooze(10000); VerticalRetraceWait(); WriteCrtcReg(resetidx, tmp & ~0x02); snooze(10000); if (ge_was_on) { tmp |= 0x01; WriteCrtcReg(resetidx, tmp); snooze(10000); } VerticalRetraceWait(); Virge_NopAllCmdSets(); gInfo.WaitIdleEmpty(); WriteReg32(DEST_SRC_STR, mode.bytesPerRow << 16 | mode.bytesPerRow); snooze(10000); if ((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000) { TRACE("Restarting S3 graphics engine reset %2d ...%lx\n", r, IN_SUBSYS_STAT() ); } else break; } } else { uint8 regIndex = (si.chipType == S3_VIRGE_VX ? 0x63 : 0x66); uint8 tmp = ReadCrtcReg(regIndex); snooze(10000); // try multiple times to avoid lockup of VIRGE/MX for (int r = 1; r < 10; r++) { WriteCrtcReg(regIndex, tmp | 0x02); snooze(10000); WriteCrtcReg(regIndex, tmp & ~0x02); snooze(10000); gInfo.WaitIdleEmpty(); WriteReg32(DEST_SRC_STR, mode.bytesPerRow << 16 | mode.bytesPerRow); snooze(10000); if (((IN_SUBSYS_STAT() & 0x3f00) != 0x3000)) { TRACE("Restarting S3 graphics engine reset %2d ...\n", r); } else break; } } gInfo.WaitQueue(2); WriteReg32(SRC_BASE, 0); WriteReg32(DEST_BASE, 0); gInfo.WaitQueue(4); WriteReg32(CLIP_L_R, ((0) << 16) | mode.timing.h_display); WriteReg32(CLIP_T_B, ((0) << 16) | mode.timing.v_display); WriteReg32(MONO_PAT_0, ~0); WriteReg32(MONO_PAT_1, ~0); if (si.chipType == S3_TRIO_3D) Virge_NopAllCmdSets(); }
static inline void WaitForSync() { while ((IN_SUBSYS_STAT() & 0x2000) == 0) ; }