Video changes of the day (January 26th, 2025)
XGA: 1. Added a proper poll so to have its timings independent of the SVGA core and changes its renderer accordingly, mainly a blank render one. 2. Workaround the Ctrl-Alt-Del reset of Windows 2.x so that it switches back to VGA text mode correctly when using the 0xA000 64K aperture (in vid_svga.c). SVGA core: Re-organized the way the different timers are organized so that the XGA and 8514/A pollers can coexist with the SVGA timer without conflicts. ATI Mach32: Reworked the true color renderer and made it a Mach32 exclusive due to its differences from the standard one. Fixes wrong rendered colors in NT using the 32bpp renderer in RGB mode.
This commit is contained in:
@@ -83,26 +83,76 @@ svga_get_pri(void)
|
||||
return svga_pri;
|
||||
}
|
||||
|
||||
void
|
||||
svga_set_poll(svga_t *svga)
|
||||
{
|
||||
svga_log("SVGA Timer activated, enabled?=%x.\n", timer_is_enabled(&svga->timer));
|
||||
timer_set_callback(&svga->timer, svga_poll);
|
||||
if (!timer_is_enabled(&svga->timer))
|
||||
timer_enable(&svga->timer);
|
||||
}
|
||||
|
||||
void
|
||||
svga_set_override(svga_t *svga, int val)
|
||||
{
|
||||
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint8_t ret_poll = 0;
|
||||
|
||||
if (svga->override && !val)
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
|
||||
svga->override = val;
|
||||
|
||||
svga_log("Override=%x.\n", val);
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on) {
|
||||
if (svga->override)
|
||||
timer_set_callback(&svga->timer, svga_poll);
|
||||
else
|
||||
timer_set_callback(&svga->timer, ibm8514_poll);
|
||||
} else
|
||||
timer_set_callback(&svga->timer, svga_poll);
|
||||
} else
|
||||
timer_set_callback(&svga->timer, svga_poll);
|
||||
if (ibm8514_active && (svga->dev8514 != NULL))
|
||||
ret_poll |= 1;
|
||||
|
||||
if (xga_active && (svga->xga != NULL))
|
||||
ret_poll |= 2;
|
||||
|
||||
if (svga->override)
|
||||
svga_set_poll(svga);
|
||||
else {
|
||||
switch (ret_poll) {
|
||||
case 0:
|
||||
default:
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on)
|
||||
ibm8514_set_poll(svga);
|
||||
else
|
||||
svga_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (xga_active && (svga->xga != NULL)) {
|
||||
if (xga->on)
|
||||
xga_set_poll(svga);
|
||||
else
|
||||
svga_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (ibm8514_active && (svga->dev8514 != NULL) && xga_active && (svga->xga != NULL)) {
|
||||
if (dev->on)
|
||||
ibm8514_set_poll(svga);
|
||||
else if (xga->on)
|
||||
xga_set_poll(svga);
|
||||
else
|
||||
svga_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OVERRIDE_OVERSCAN
|
||||
if (!val) {
|
||||
@@ -241,7 +291,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (ibm8514_active && dev)
|
||||
dev->on = (val & 0x01) ? 0 : 1;
|
||||
|
||||
svga_log("Write Port 3C3.\n");
|
||||
svga_log("Write Port 3C3=%x.\n", val & 0x01);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x3c4:
|
||||
@@ -612,6 +662,8 @@ void
|
||||
svga_recalctimings(svga_t *svga)
|
||||
{
|
||||
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint8_t set_timer = 0;
|
||||
double crtcconst;
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
@@ -620,6 +672,10 @@ svga_recalctimings(svga_t *svga)
|
||||
double _dispontime8514 = 0.0;
|
||||
double _dispofftime8514 = 0.0;
|
||||
double disptime8514 = 0.0;
|
||||
double crtcconst_xga = 0.0;
|
||||
double _dispontime_xga = 0.0;
|
||||
double _dispofftime_xga = 0.0;
|
||||
double disptime_xga = 0.0;
|
||||
#ifdef ENABLE_SVGA_LOG
|
||||
int vsyncend;
|
||||
int vblankend;
|
||||
@@ -709,6 +765,12 @@ svga_recalctimings(svga_t *svga)
|
||||
} else
|
||||
svga->render = svga_render_text_80;
|
||||
|
||||
if (xga_active && (svga->xga != NULL)) {
|
||||
if (xga->on) {
|
||||
if ((svga->mapping.base == 0xb8000) && (xga->aperture_cntl == 1)) /*Some operating systems reset themselves with ctrl-alt-del by going into text mode.*/
|
||||
xga->on = 0;
|
||||
}
|
||||
}
|
||||
svga->hdisp_old = svga->hdisp;
|
||||
} else {
|
||||
svga->hdisp_old = svga->hdisp;
|
||||
@@ -904,6 +966,10 @@ svga_recalctimings(svga_t *svga)
|
||||
if (dev->on)
|
||||
crtcconst8514 = svga->clock8514;
|
||||
}
|
||||
if (xga_active && (svga->xga != NULL)) {
|
||||
if (xga->on)
|
||||
crtcconst_xga = svga->clock_xga;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SVGA_LOG
|
||||
vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f);
|
||||
@@ -952,6 +1018,13 @@ svga_recalctimings(svga_t *svga)
|
||||
}
|
||||
}
|
||||
|
||||
if (xga_active && (svga->xga != NULL)) {
|
||||
if (xga->on) {
|
||||
disptime_xga = xga->h_total ? xga->h_total : TIMER_USEC;
|
||||
_dispontime_xga = xga->h_disp;
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->seqregs[1] & 8) {
|
||||
disptime *= 2;
|
||||
_dispontime *= 2;
|
||||
@@ -968,25 +1041,84 @@ svga_recalctimings(svga_t *svga)
|
||||
if (svga->dispofftime < TIMER_USEC)
|
||||
svga->dispofftime = TIMER_USEC;
|
||||
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on) {
|
||||
_dispofftime8514 = disptime8514 - _dispontime8514;
|
||||
_dispontime8514 *= crtcconst8514;
|
||||
_dispofftime8514 *= crtcconst8514;
|
||||
if (ibm8514_active && (svga->dev8514 != NULL))
|
||||
set_timer |= 1;
|
||||
|
||||
dev->dispontime = (uint64_t) (_dispontime8514);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime8514);
|
||||
if (dev->dispontime < TIMER_USEC)
|
||||
dev->dispontime = TIMER_USEC;
|
||||
if (dev->dispofftime < TIMER_USEC)
|
||||
dev->dispofftime = TIMER_USEC;
|
||||
if (xga_active && (svga->xga != NULL))
|
||||
set_timer |= 2;
|
||||
|
||||
svga_log("IBM 8514/A poll.\n");
|
||||
timer_set_callback(&svga->timer, ibm8514_poll);
|
||||
} else {
|
||||
svga_log("SVGA poll enabled.\n");
|
||||
timer_set_callback(&svga->timer, svga_poll);
|
||||
}
|
||||
switch (set_timer) {
|
||||
default:
|
||||
case 0: /*VGA only*/
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 1: /*Plus 8514/A*/
|
||||
if (dev->on) {
|
||||
_dispofftime8514 = disptime8514 - _dispontime8514;
|
||||
_dispontime8514 *= crtcconst8514;
|
||||
_dispofftime8514 *= crtcconst8514;
|
||||
|
||||
dev->dispontime = (uint64_t) (_dispontime8514);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime8514);
|
||||
if (dev->dispontime < TIMER_USEC)
|
||||
dev->dispontime = TIMER_USEC;
|
||||
if (dev->dispofftime < TIMER_USEC)
|
||||
dev->dispofftime = TIMER_USEC;
|
||||
|
||||
ibm8514_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 2: /*Plus XGA*/
|
||||
if (xga->on) {
|
||||
_dispofftime_xga = disptime_xga - _dispontime_xga;
|
||||
_dispontime_xga *= crtcconst_xga;
|
||||
_dispofftime_xga *= crtcconst_xga;
|
||||
|
||||
xga->dispontime = (uint64_t) (_dispontime_xga);
|
||||
xga->dispofftime = (uint64_t) (_dispofftime_xga);
|
||||
if (xga->dispontime < TIMER_USEC)
|
||||
xga->dispontime = TIMER_USEC;
|
||||
if (xga->dispofftime < TIMER_USEC)
|
||||
xga->dispofftime = TIMER_USEC;
|
||||
|
||||
xga_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
|
||||
case 3: /*Plus 8514/A and XGA*/
|
||||
if (dev->on) {
|
||||
_dispofftime8514 = disptime8514 - _dispontime8514;
|
||||
_dispontime8514 *= crtcconst8514;
|
||||
_dispofftime8514 *= crtcconst8514;
|
||||
|
||||
dev->dispontime = (uint64_t) (_dispontime8514);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime8514);
|
||||
if (dev->dispontime < TIMER_USEC)
|
||||
dev->dispontime = TIMER_USEC;
|
||||
if (dev->dispofftime < TIMER_USEC)
|
||||
dev->dispofftime = TIMER_USEC;
|
||||
|
||||
ibm8514_set_poll(svga);
|
||||
} else if (xga->on) {
|
||||
_dispofftime_xga = disptime_xga - _dispontime_xga;
|
||||
_dispontime_xga *= crtcconst_xga;
|
||||
_dispofftime_xga *= crtcconst_xga;
|
||||
|
||||
xga->dispontime = (uint64_t) (_dispontime_xga);
|
||||
xga->dispofftime = (uint64_t) (_dispofftime_xga);
|
||||
if (xga->dispontime < TIMER_USEC)
|
||||
xga->dispontime = TIMER_USEC;
|
||||
if (xga->dispofftime < TIMER_USEC)
|
||||
xga->dispofftime = TIMER_USEC;
|
||||
|
||||
xga_set_poll(svga);
|
||||
} else
|
||||
svga_set_poll(svga);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!svga->force_old_addr)
|
||||
@@ -1064,7 +1196,6 @@ void
|
||||
svga_poll(void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint32_t x;
|
||||
uint32_t blink_delay;
|
||||
int wx;
|
||||
@@ -1072,15 +1203,6 @@ svga_poll(void *priv)
|
||||
int ret;
|
||||
int old_ma;
|
||||
|
||||
if (!svga->override) {
|
||||
if (xga_active && xga && xga->on) {
|
||||
if ((xga->disp_cntl_2 & 7) >= 2) {
|
||||
xga_poll(svga);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
svga_log("SVGA Poll.\n");
|
||||
if (!svga->linepos) {
|
||||
if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) {
|
||||
@@ -2070,6 +2192,8 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *priv)
|
||||
cycles -= svga->monitor->mon_video_timing_read_w;
|
||||
|
||||
if (!linear) {
|
||||
(void) xga_read_test(addr, svga);
|
||||
(void) xga_read_test(addr + 1, svga);
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
if (addr == 0xffffffff)
|
||||
return 0xffff;
|
||||
@@ -2116,6 +2240,10 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv)
|
||||
cycles -= svga->monitor->mon_video_timing_read_l;
|
||||
|
||||
if (!linear) {
|
||||
(void) xga_read_test(addr, svga);
|
||||
(void) xga_read_test(addr + 1, svga);
|
||||
(void) xga_read_test(addr + 2, svga);
|
||||
(void) xga_read_test(addr + 3, svga);
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
if (addr == 0xffffffff)
|
||||
return 0xffffffff;
|
||||
|
||||
Reference in New Issue
Block a user