diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c9f620f4d0..3acd86eff2 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -91,6 +91,9 @@ #include +bool int10_vp_use_always = false; +bool int10_vp_use_auto = true; + unsigned int preventcap = PREVCAP_NONE; #ifndef WDA_NONE @@ -967,6 +970,23 @@ void Init_VGABIOS() { VGA_BIOS_use_rom = false; } + { + const char *s = video_section->Get_string("int 10h use video parameter table"); + + if (!strcmp(s,"true") || !strcmp(s,"1")) { + int10_vp_use_always = true; + int10_vp_use_auto = false; + } + else if (!strcmp(s,"false") || !strcmp(s,"0")) { + int10_vp_use_always = false; + int10_vp_use_auto = false; + } + else { + int10_vp_use_always = false; + int10_vp_use_auto = true; + } + } + int size_override = video_section->Get_int("vga bios size override"); if (size_override > 0) VGA_BIOS_Size_override = ((Bitu)size_override+0x7FFU)&(~0xFFFU); @@ -1420,6 +1440,7 @@ void DOSBOX_SetupConfigSections(void) { const char *vga_ac_mapping_settings[] = { "", "auto", "4x4", "4low", "first16", nullptr }; const char* fpu_settings[] = { "true", "false", "1", "0", "auto", "8087", "287", "387", nullptr }; const char* sb_recording_sources[] = { "silence", "hiss", "1khz tone", nullptr }; + const char* int10usevp[] = { "auto", "true", "false", "1", "0", nullptr }; const char* hostkeys[] = { "ctrlalt", "ctrlshift", "altshift", "mapper", nullptr }; @@ -2449,6 +2470,13 @@ void DOSBOX_SetupConfigSections(void) { Pstring->Set_help("Specifies the text color in J-3100 mode. If not specified, the colors will be those of the display type corresponding to the model specified in j3100type."); secprop=control->AddSection_prop("video",&Null_Init); + + Pstring = secprop->Add_string("int 10h use video parameter table",Property::Changeable::OnlyAtStart,"auto"); + Pstring->Set_values(int10usevp); + Pstring->Set_help("If set, INT 10h will use the video parameter table for standard EGA/VGA modes.\n" + "If not set, internal modesetting will be used, same as DOSBox and most forks do.\n" + "If auto, the video parameter table will be used if any DOS program redirects the table (usually to override mode setting parameters)"); + Pint = secprop->Add_int("vmemdelay", Property::Changeable::WhenIdle,0); Pint->SetMinMax(-1,1000000); Pint->Set_help( "VGA Memory I/O delay in nanoseconds. Set to -1 to use default, 0 to disable.\n" diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index ff6420ea97..87670c5e63 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1237,6 +1237,26 @@ bool INT10_SetVideoMode_OTHER(uint16_t mode,bool clearmem) { return true; } +extern bool int10_vp_use_always; +extern bool int10_vp_use_auto; + +static bool ShouldUseVPT(void) { + if (int10_vp_use_always) + return true; + if (!int10_vp_use_auto) + return false; + + /* If the VPT points into ROM, no. + * Otherwise a DOS program wants to override it, yes. */ + RealPt r_vsopt = real_readd(BIOSMEM_SEG,0xA8); + if (r_vsopt != 0) { + RealPt r_vpt = real_readd(RealSeg(r_vsopt),RealOff(r_vsopt)); + if (RealSeg(r_vpt) < 0xC000) return true; + } + + return false; +} + bool unmask_irq0_on_int10_setmode = true; bool INT10_SetVideoMode(uint16_t mode) { if (CurMode&&CurMode->mode==7&&!IS_PC98_ARCH) { @@ -1291,7 +1311,7 @@ bool INT10_SetVideoMode(uint16_t mode) { * or auto, which means only use if the pointer in the Video Save/Override * Pointer Table is not pointing to ROM (because something in the guest intends * to override parameters) */ - if (IS_EGAVGA_ARCH && mode <= 0x13/*standard EGA/VGA modes only*/) { + if (IS_EGAVGA_ARCH && mode <= 0x13/*standard EGA/VGA modes only*/ && ShouldUseVPT()) { RealPt r_vpt = 0; RealPt r_vsopt = real_readd(BIOSMEM_SEG,0xA8); if (r_vsopt != 0) r_vpt = real_readd(RealSeg(r_vsopt),RealOff(r_vsopt));