VGA DetermineMode: Move out S3-specific mode determination into its own callback, leave only standard EGA/VGA there

This commit is contained in:
Jonathan Campbell 2025-01-20 17:01:23 -08:00
parent bb63119c7f
commit b26b851698
3 changed files with 76 additions and 46 deletions

View File

@ -808,6 +808,8 @@ void SetClock_S3(Bitu which,Bitu target);
// Amount of video memory required for a mode, implemented in int10_modes.cpp
Bitu VideoModeMemSize(Bitu mode);
bool VGA_DetermineMode_IsDCGA(void);
void VGA_DetermineMode_StandardVGA(void);
void VGA_DetermineMode_S3(void);
extern uint32_t ExpandTable[256];
extern uint32_t FillTable[16];

View File

@ -289,52 +289,40 @@ bool VGA_DetermineMode_IsDCGA(void) {
return (vga.gfx.miscellaneous & 0x0c) == 0x0c && J3_IsCga4Dcga();
}
void VGA_DetermineMode(void) {
if (svga.determine_mode) {
svga.determine_mode();
return;
}
/* Test for VGA output active or direct color modes */
switch (vga.s3.misc_control_2 >> 4) {
case 0:
if (vga.attr.mode_control & 1) { // graphics mode
if (IS_VGA_ARCH && ((vga.gfx.mode & 0x40)||(vga.s3.reg_3a&0x10))) {
// access above 256k?
if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN8);
else VGA_SetMode(M_VGA);
}
// NTS: Also handled by M_EGA case
// else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
void VGA_DetermineMode_StandardVGA(void) { /* and EGA, the extra regs are not used for machine=ega */
if (vga.attr.mode_control & 1) { // graphics mode
if (IS_VGA_ARCH && (vga.gfx.mode & 0x40)) {
VGA_SetMode(M_VGA);
}
// NTS: Also handled by M_EGA case
// else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
// NTS: Two things here. One is that CGA 2-color mode (and the MCGA 640x480 2-color mode)
// are just EGA planar modes with fewer bitplanes enabled. The planar render mode can
// display them just fine. The other is that checking for 2-color CGA mode entirely by
// whether video RAM is mapped to B8000h is a really lame way to go about it.
//
// The only catch here is that a contributor (Wengier, I think?) tied a DOS/V CGA rendering
// mode into M_CGA2 that we need to watch for.
//
else if (VGA_DetermineMode_IsDCGA()) {
VGA_SetMode(M_DCGA);
}
else {
// access above 256k?
if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN4);
else VGA_SetMode(M_EGA);
}
} else {
VGA_SetMode(M_TEXT);
}
break;
case 1:VGA_SetMode(M_LIN8);break;
case 3:VGA_SetMode(M_LIN15);break;
case 5:VGA_SetMode(M_LIN16);break;
case 7:VGA_SetMode(M_LIN24);break;
case 13:VGA_SetMode(M_LIN32);break;
case 15:VGA_SetMode(M_PACKED4);break;// hacked
// NTS: Two things here. One is that CGA 2-color mode (and the MCGA 640x480 2-color mode)
// are just EGA planar modes with fewer bitplanes enabled. The planar render mode can
// display them just fine. The other is that checking for 2-color CGA mode entirely by
// whether video RAM is mapped to B8000h is a really lame way to go about it.
//
// The only catch here is that a contributor (Wengier, I think?) tied a DOS/V CGA rendering
// mode into M_CGA2 that we need to watch for.
//
else if (VGA_DetermineMode_IsDCGA()) {
VGA_SetMode(M_DCGA);
}
else {
VGA_SetMode(M_EGA);
}
} else {
VGA_SetMode(M_TEXT);
}
}
void VGA_DetermineMode(void) {
if (svga.determine_mode)
svga.determine_mode();
else
VGA_DetermineMode_StandardVGA();
}
void VGA_StartResize(Bitu delay /*=50*/) {
if (!vga.draw.resizing) {
/* even if the user disables the delay, we can avoid a lot of window resizing by at least having 1ms of delay */
@ -349,10 +337,8 @@ void VGA_StartResize(Bitu delay /*=50*/) {
}
void VGA_SetClock(Bitu which,Bitu target) {
if (svga.set_clock) {
if (svga.set_clock)
svga.set_clock(which, target);
return;
}
}
void VGA_SetCGA2Table(uint8_t val0,uint8_t val1) {

View File

@ -696,7 +696,7 @@ void SVGA_Setup_S3Trio(void) {
svga.read_p3c1 = nullptr; /* no S3-specific functionality */
svga.set_video_mode = nullptr; /* implemented in core */
svga.determine_mode = nullptr; /* implemented in core */
svga.determine_mode = &VGA_DetermineMode_S3;
svga.set_clock = &SetClock_S3;
svga.get_clock = &SVGA_S3_GetClock;
svga.hardware_cursor_active = &SVGA_S3_HWCursorActive;
@ -748,6 +748,48 @@ void SVGA_Setup_S3Trio(void) {
PCI_AddSVGAS3_Device();
}
void VGA_DetermineMode_S3(void) {
/* Test for VGA output active or direct color modes */
switch (vga.s3.misc_control_2 >> 4) {
case 0:
if (vga.attr.mode_control & 1) { // graphics mode
if (IS_VGA_ARCH && ((vga.gfx.mode & 0x40)||(vga.s3.reg_3a&0x10))) {
// access above 256k?
if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN8);
else VGA_SetMode(M_VGA);
}
// NTS: Also handled by M_EGA case
// else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
// NTS: Two things here. One is that CGA 2-color mode (and the MCGA 640x480 2-color mode)
// are just EGA planar modes with fewer bitplanes enabled. The planar render mode can
// display them just fine. The other is that checking for 2-color CGA mode entirely by
// whether video RAM is mapped to B8000h is a really lame way to go about it.
//
// The only catch here is that a contributor (Wengier, I think?) tied a DOS/V CGA rendering
// mode into M_CGA2 that we need to watch for.
//
else if (VGA_DetermineMode_IsDCGA()) {
VGA_SetMode(M_DCGA);
}
else {
// access above 256k?
if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN4);
else VGA_SetMode(M_EGA);
}
} else {
VGA_SetMode(M_TEXT);
}
break;
case 1:VGA_SetMode(M_LIN8);break;
case 3:VGA_SetMode(M_LIN15);break;
case 5:VGA_SetMode(M_LIN16);break;
case 7:VGA_SetMode(M_LIN24);break;
case 13:VGA_SetMode(M_LIN32);break;
case 15:VGA_SetMode(M_PACKED4);break;// hacked
}
}
void SetClock_S3(Bitu which,Bitu target) {
struct{
Bitu n,m;