diff --git a/contrib/windows/installer/dosbox-x.reference.setup.conf b/contrib/windows/installer/dosbox-x.reference.setup.conf index 5b5ca0f88..6d960e479 100644 --- a/contrib/windows/installer/dosbox-x.reference.setup.conf +++ b/contrib/windows/installer/dosbox-x.reference.setup.conf @@ -605,7 +605,7 @@ convertdrivefat = true # To fit a scaler in the resolution used at full screen may require a border or side bars. # To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work. # Scalers should work with most output options, but they are ignored for openglpp and TrueType font outputs. -# If you are using OpenGL/Direct3D shaders that need the exact pixels of the video output without scaling, set to hardware_none or hardware2x. +# If you are using OpenGL/Direct3D output and a shader that requires it, set to hardware_none or hardware2x. # Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, gray, gray2x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x, xbrz, xbrz_bilinear. # glshader: Path to GLSL shader source to use with OpenGL output ("none" to disable, or "default" for default shader). # Can be either an absolute path, a file in the "glshaders" subdirectory of the DOSBox-X configuration directory, or one of the built-in shaders (e.g. "sharp" for the pixel-perfect scaling mode): @@ -2338,6 +2338,9 @@ timeout = 0 #DOSBOX-X-ADV:# Possible values: true, false, 1, 0, auto. #DOSBOX-X-ADV:# private area in umb: If set, keep private DOS segment in upper memory block, usually segment 0xC800 (Mainline DOSBox behavior) #DOSBOX-X-ADV:# If clear, place private DOS segment at the base of system memory (just below the MCB) +#DOSBOX-X-ADV:# private area write protect: If set, prevent the guest from writing to the DOSBox private area. The emulator itself can still write to it, of course. +#DOSBOX-X-ADV:# Some DOS games have sloppy video routines that can spill over and corrupt the private area and cause problems. +#DOSBOX-X-ADV:# This option when set can prevent that errant game from causing crashes. # quick reboot: If set, the DOS restart call will reboot the emulated DOS (integrated DOS or guest DOS) instead of the virtual machine. # # ver: Set DOS version. Specify as major.minor format. A single number is treated as the major version (compatible with LFN support). Common settings are: @@ -2444,7 +2447,7 @@ timeout = 0 # dos idle api: If set, DOSBox-X can lower the host system's CPU load when a supported guest program is idle. #DOSBOX-X-ADV-SEE:# #DOSBOX-X-ADV-SEE:# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details): -#DOSBOX-X-ADV-SEE:# -> xms memmove causes flat real mode; xms init causes flat real mode; resized free memory block becomes allocated; badcommandhandler; mscdex device name; hma allow reservation; command shell flush keyboard buffer; special operation file prefix; drive z is remote; drive z convert fat; drive z expand path; drive z hide files; automount drive directories; hidenonrepresentable; hma minimum allocation; dos sda size; hma free space; cpm compatibility mode; minimum dos initial private segment; minimum mcb segment; enable dummy device mcb; maximum environment block size on exec; additional environment block size on exec; enable a20 on windows init; zero memory on xms memory allocation; vcpi; unmask timer on disk io; zero int 67h if no ems; zero unused int 68h; emm386 startup active; zero memory on ems memory allocation; ems system handle memory size; ems system handle on even megabyte; ems frame; umb start; umb end; kernel allocation in umb; keep umb on boot; keep private area on boot; private area in umb; autoa20fix; autoloadfix; startincon; int33 max x; int33 max y; int33 xy adjust; int33 mickey threshold; int33 hide host cursor if interrupt subroutine; int33 hide host cursor when polling; int33 disable cell granularity; int 13 disk change detect; int 13 extensions; biosps2; int15 wait force unmask irq; int15 mouse callback does not preserve registers; filenamechar; collating and uppercase; con device use int 16h to detect keyboard input; zero memory on int 21h memory allocation; pipe temporary device +#DOSBOX-X-ADV-SEE:# -> xms memmove causes flat real mode; xms init causes flat real mode; resized free memory block becomes allocated; badcommandhandler; mscdex device name; hma allow reservation; command shell flush keyboard buffer; special operation file prefix; drive z is remote; drive z convert fat; drive z expand path; drive z hide files; automount drive directories; hidenonrepresentable; hma minimum allocation; dos sda size; hma free space; cpm compatibility mode; minimum dos initial private segment; minimum mcb segment; enable dummy device mcb; maximum environment block size on exec; additional environment block size on exec; enable a20 on windows init; zero memory on xms memory allocation; vcpi; unmask timer on disk io; zero int 67h if no ems; zero unused int 68h; emm386 startup active; zero memory on ems memory allocation; ems system handle memory size; ems system handle on even megabyte; ems frame; umb start; umb end; kernel allocation in umb; keep umb on boot; keep private area on boot; private area in umb; private area write protect; autoa20fix; autoloadfix; startincon; int33 max x; int33 max y; int33 xy adjust; int33 mickey threshold; int33 hide host cursor if interrupt subroutine; int33 hide host cursor when polling; int33 disable cell granularity; int 13 disk change detect; int 13 extensions; biosps2; int15 wait force unmask irq; int15 mouse callback does not preserve registers; filenamechar; collating and uppercase; con device use int 16h to detect keyboard input; zero memory on int 21h memory allocation; pipe temporary device #DOSBOX-X-ADV-SEE:# xms = true #DOSBOX-X-ADV:xms memmove causes flat real mode = true @@ -2500,6 +2503,7 @@ umb = true #DOSBOX-X-ADV:keep umb on boot = false #DOSBOX-X-ADV:keep private area on boot = auto #DOSBOX-X-ADV:private area in umb = true +#DOSBOX-X-ADV:private area write protect = false quick reboot = false ver = lfn = auto diff --git a/dosbox-x.reference.conf b/dosbox-x.reference.conf index 5526261cf..085a6762b 100644 --- a/dosbox-x.reference.conf +++ b/dosbox-x.reference.conf @@ -295,7 +295,7 @@ convertdrivefat = true # To fit a scaler in the resolution used at full screen may require a border or side bars. # To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work. # Scalers should work with most output options, but they are ignored for openglpp and TrueType font outputs. -# If you are using OpenGL/Direct3D shaders that need the exact pixels of the video output without scaling, set to hardware_none or hardware2x. +# If you are using OpenGL/Direct3D output and a shader that requires it, set to hardware_none or hardware2x. # Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, gray, gray2x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x, xbrz, xbrz_bilinear. # glshader: Path to GLSL shader source to use with OpenGL output ("none" to disable, or "default" for default shader). # Can be either an absolute path, a file in the "glshaders" subdirectory of the DOSBox-X configuration directory, or one of the built-in shaders (e.g. "sharp" for the pixel-perfect scaling mode): @@ -1164,7 +1164,7 @@ timeout = 0 # dos idle api: If set, DOSBox-X can lower the host system's CPU load when a supported guest program is idle. # # Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details): -# -> xms memmove causes flat real mode; xms init causes flat real mode; resized free memory block becomes allocated; badcommandhandler; mscdex device name; hma allow reservation; command shell flush keyboard buffer; special operation file prefix; drive z is remote; drive z convert fat; drive z expand path; drive z hide files; automount drive directories; hidenonrepresentable; hma minimum allocation; dos sda size; hma free space; cpm compatibility mode; minimum dos initial private segment; minimum mcb segment; enable dummy device mcb; maximum environment block size on exec; additional environment block size on exec; enable a20 on windows init; zero memory on xms memory allocation; vcpi; unmask timer on disk io; zero int 67h if no ems; zero unused int 68h; emm386 startup active; zero memory on ems memory allocation; ems system handle memory size; ems system handle on even megabyte; ems frame; umb start; umb end; kernel allocation in umb; keep umb on boot; keep private area on boot; private area in umb; autoa20fix; autoloadfix; startincon; int33 max x; int33 max y; int33 xy adjust; int33 mickey threshold; int33 hide host cursor if interrupt subroutine; int33 hide host cursor when polling; int33 disable cell granularity; int 13 disk change detect; int 13 extensions; biosps2; int15 wait force unmask irq; int15 mouse callback does not preserve registers; filenamechar; collating and uppercase; con device use int 16h to detect keyboard input; zero memory on int 21h memory allocation; pipe temporary device +# -> xms memmove causes flat real mode; xms init causes flat real mode; resized free memory block becomes allocated; badcommandhandler; mscdex device name; hma allow reservation; command shell flush keyboard buffer; special operation file prefix; drive z is remote; drive z convert fat; drive z expand path; drive z hide files; automount drive directories; hidenonrepresentable; hma minimum allocation; dos sda size; hma free space; cpm compatibility mode; minimum dos initial private segment; minimum mcb segment; enable dummy device mcb; maximum environment block size on exec; additional environment block size on exec; enable a20 on windows init; zero memory on xms memory allocation; vcpi; unmask timer on disk io; zero int 67h if no ems; zero unused int 68h; emm386 startup active; zero memory on ems memory allocation; ems system handle memory size; ems system handle on even megabyte; ems frame; umb start; umb end; kernel allocation in umb; keep umb on boot; keep private area on boot; private area in umb; private area write protect; autoa20fix; autoloadfix; startincon; int33 max x; int33 max y; int33 xy adjust; int33 mickey threshold; int33 hide host cursor if interrupt subroutine; int33 hide host cursor when polling; int33 disable cell granularity; int 13 disk change detect; int 13 extensions; biosps2; int15 wait force unmask irq; int15 mouse callback does not preserve registers; filenamechar; collating and uppercase; con device use int 16h to detect keyboard input; zero memory on int 21h memory allocation; pipe temporary device # xms = true xms handles = 0 diff --git a/dosbox-x.reference.full.conf b/dosbox-x.reference.full.conf index 80590578b..2b1a67bc9 100644 --- a/dosbox-x.reference.full.conf +++ b/dosbox-x.reference.full.conf @@ -593,7 +593,7 @@ enable pci bus = true # To fit a scaler in the resolution used at full screen may require a border or side bars. # To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work. # Scalers should work with most output options, but they are ignored for openglpp and TrueType font outputs. -# If you are using OpenGL/Direct3D shaders that need the exact pixels of the video output without scaling, set to hardware_none or hardware2x. +# If you are using OpenGL/Direct3D output and a shader that requires it, set to hardware_none or hardware2x. # Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, gray, gray2x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x, xbrz, xbrz_bilinear. # glshader: Path to GLSL shader source to use with OpenGL output ("none" to disable, or "default" for default shader). # Can be either an absolute path, a file in the "glshaders" subdirectory of the DOSBox-X configuration directory, or one of the built-in shaders (e.g. "sharp" for the pixel-perfect scaling mode): @@ -2278,6 +2278,9 @@ timeout = 0 # Possible values: true, false, 1, 0, auto. # private area in umb: If set, keep private DOS segment in upper memory block, usually segment 0xC800 (Mainline DOSBox behavior) # If clear, place private DOS segment at the base of system memory (just below the MCB) +# private area write protect: If set, prevent the guest from writing to the DOSBox private area. The emulator itself can still write to it, of course. +# Some DOS games have sloppy video routines that can spill over and corrupt the private area and cause problems. +# This option when set can prevent that errant game from causing crashes. # quick reboot: If set, the DOS restart call will reboot the emulated DOS (integrated DOS or guest DOS) instead of the virtual machine. # # ver: Set DOS version. Specify as major.minor format. A single number is treated as the major version (compatible with LFN support). Common settings are: @@ -2436,6 +2439,7 @@ kernel allocation in umb = false keep umb on boot = false keep private area on boot = auto private area in umb = true +private area write protect = false quick reboot = false ver = lfn = auto diff --git a/include/dos_inc.h b/include/dos_inc.h index 4bd1b6f56..d97e07b7b 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -324,6 +324,7 @@ bool DOS_ResizeMemory(uint16_t segment,uint16_t * blocks); bool DOS_FreeMemory(uint16_t segment); void DOS_FreeProcessMemory(uint16_t pspseg); uint16_t DOS_GetMemory(uint16_t pages,const char *who=NULL); +void DOS_Private_UMB_Lock(const bool lock); void DOS_FreeTableMemory(); bool DOS_SetMemAllocStrategy(uint16_t strat); uint16_t DOS_GetMemAllocStrategy(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index da94e9108..93a740fba 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -3480,6 +3480,7 @@ static Bitu DOS_26Handler(void) { return DOS_26Handler_Actual(false); } +bool private_segment_write_protect = false; bool enable_collating_uppercase = true; bool keep_private_area_on_boot = false; bool private_always_from_umb = false; @@ -4148,6 +4149,7 @@ public: minimum_mcb_free = section->Get_hex("minimum mcb free"); minimum_mcb_segment = section->Get_hex("minimum mcb segment"); private_segment_in_umb = section->Get_bool("private area in umb"); + private_segment_write_protect = section->Get_bool("private area write protect"); enable_collating_uppercase = section->Get_bool("collating and uppercase"); private_always_from_umb = section->Get_bool("kernel allocation in umb"); minimum_dos_initial_private_segment = section->Get_hex("minimum dos initial private segment"); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 7186c1b7c..0e958f942 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -31,6 +31,7 @@ extern int maxfcb; extern bool gbk, chinasea; extern Bitu DOS_PRIVATE_SEGMENT_Size; extern uint16_t desired_ems_segment; +extern bool private_segment_write_protect; #if defined(USE_TTF) extern bool ttf_dosv; #endif @@ -103,6 +104,20 @@ bool DOS_User_Wants_UMBs() { bool EMS_Active(void); void Update_Get_Desired_Segment(void); +/* Some DOS games and demoscene stuff has fast and loose VRAM rendering code that can spill + * past video RAM into whatever follows in C0000h. If the DOSBox private area is there, then + * that sloppiness will corrupt whatever data structures and interrupts we put there and + * cause crashes. To prevent that, we allow write-protecting the area (DOSBox-X can still + * write to it using phys_writeb). */ +void DOS_Private_UMB_Lock(const bool lock) { + if (DOS_PRIVATE_SEGMENT >= 0xA000) { + if (lock) + MEM_map_ROM_physmem((Bitu)DOS_PRIVATE_SEGMENT<<4u,((Bitu)DOS_PRIVATE_SEGMENT_END<<4u)-1u); + else + MEM_map_RAM_physmem((Bitu)DOS_PRIVATE_SEGMENT<<4u,((Bitu)DOS_PRIVATE_SEGMENT_END<<4u)-1u); + } +} + void DOS_GetMemory_Choose() { if (DOS_PRIVATE_SEGMENT == 0) { /* DOSBox-X non-compatible: Position ourself just past the VGA BIOS */ @@ -145,7 +160,11 @@ void DOS_GetMemory_Choose() { if (DOS_PRIVATE_SEGMENT >= 0xA000) { memset(GetMemBase()+((Bitu)DOS_PRIVATE_SEGMENT<<4u),0x00,(Bitu)(DOS_PRIVATE_SEGMENT_END-DOS_PRIVATE_SEGMENT)<<4u); - MEM_map_RAM_physmem((Bitu)DOS_PRIVATE_SEGMENT<<4u,((Bitu)DOS_PRIVATE_SEGMENT_END<<4u)-1u); + + if (private_segment_write_protect) + MEM_map_ROM_physmem((Bitu)DOS_PRIVATE_SEGMENT<<4u,((Bitu)DOS_PRIVATE_SEGMENT_END<<4u)-1u); + else + MEM_map_RAM_physmem((Bitu)DOS_PRIVATE_SEGMENT<<4u,((Bitu)DOS_PRIVATE_SEGMENT_END<<4u)-1u); } LOG(LOG_DOSMISC,LOG_DEBUG)("DOS private segment set to 0x%04x-0x%04x",DOS_PRIVATE_SEGMENT,DOS_PRIVATE_SEGMENT_END-1); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7cc37ee62..56059e644 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -4700,6 +4700,11 @@ void DOSBOX_SetupConfigSections(void) { Pbool->Set_help("If set, keep private DOS segment in upper memory block, usually segment 0xC800 (Mainline DOSBox behavior)\n" "If clear, place private DOS segment at the base of system memory (just below the MCB)"); + Pbool = secprop->Add_bool("private area write protect",Property::Changeable::WhenIdle,false); + Pbool->Set_help("If set, prevent the guest from writing to the DOSBox private area. The emulator itself can still write to it, of course.\n" + "Some DOS games have sloppy video routines that can spill over and corrupt the private area and cause problems.\n" + "This option when set can prevent that errant game from causing crashes."); + Pbool = secprop->Add_bool("quick reboot",Property::Changeable::WhenIdle,false); Pbool->Set_help("If set, the DOS restart call will reboot the emulated DOS (integrated DOS or guest DOS) instead of the virtual machine.\n"); Pbool->SetBasic(true);