From 4443d0c5c838c33a4c5968636dde8e05ecc9dcce Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Tue, 5 Mar 2024 18:15:52 -0800 Subject: [PATCH] The Windows 95 S3 driver 16-color modes are not planar, but packed. Update VESA modelist. This fixes garbled display in Windows 95 for 800x600, 1024x768, and 1280x1024 16-color display modes. Noted: Windows 98 and higher refuse to support 16-color modes other than stock VGA 640x480 16-color planar. --- CHANGELOG | 9 +++++++++ src/ints/int10_modes.cpp | 21 ++++++++++++++++----- src/ints/int10_vesa.cpp | 5 +++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 253b0c7ca87..36fa8a446b4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,13 @@ Next: + - Windows 95 S3 driver behavior suggests that S3 16-color VESA modes + 0x202 to 0x208 are NOT planar modes, but packed modes. Change modes to + M_PACKED4 and update modelist building to allow that range even if the + dosbox.conf is configured not to list 4bpp packed VESA modes. This fixes + Windows 95 S3 driver 16-color modes 800x600, 1024x768, 1280x1024. + Noted: Windows 95 is the last version of Windows to support 4bpp packed. + Windows 98 and higher refuses to support it and the Display settings + will not allow you to select any 16-color mode other than the stock + VGA 640x480 16-color planar mode. (joncampbell123) - Add --load-seg option to BOOT in case any PC-98 game boot floppy expects to be loaded somewhere other than the default. PC-98 game "Private School Adventure" will crash if loaded to segment 0x1FC0 but runs fine if booted diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0f4835b3644..d84b04b06b4 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -209,14 +209,25 @@ VideoModeBlock ModeList_VGA[]={ { 0x192 ,M_LIN32 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000, 50 ,525 ,40 ,480 ,_UNUSUAL_MODE }, // S3 specific modes (OEM modes). See also [http://www.ctyme.com/intr/rb-0275.htm] +// NTS: The 4bpp modes are PACKED not PLANAR. The Windows 95 S3 driver expects the 4bpp modes to provide +// a PACKED structure and M_LIN4 will result in an incorrect display. It is impossible to test these +// with Windows 98 and higher because the Display settings in Windows 98 REFUSES to let you select +// any 16-color mode other than 640x480 even if the driver allows it (this was also when Microsoft +// made it impossible to select monochrome display modes that Windows 95 once allowed i.e. 640x400 +// monochrome 2-color mode). +// +// These modes are needed for the Windows 95 driver and are provided regardless of the dosbox.conf +// "allow 4bpp packed vesa modes" option. +// +// FIXME: These don't work with the S3 Windows 3.1 drivers though. { 0x201 ,M_LIN8 ,640 ,480, 80,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, -{ 0x202 ,M_LIN4 ,800 ,600,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, +{ 0x202 ,M_PACKED4 ,800 ,600,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, { 0x203 ,M_LIN8 ,800 ,600,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, // Line Wars II, S3 accelerated 800x600 -{ 0x204 ,M_LIN4 ,1024,768,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, +{ 0x204 ,M_PACKED4 ,1024,768,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, { 0x205 ,M_LIN8 ,1024,768,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, -{ 0x206 ,M_LIN4 ,1280,960,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1024,160,960 ,0 }, // TODO VERIFY THIS +{ 0x206 ,M_PACKED4 ,1280,960,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1024,160,960 ,0 }, // TODO VERIFY THIS { 0x207 ,M_LIN8 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,182 ,948 ,144,864 ,0 }, -{ 0x208 ,M_LIN4 ,1280,1024,160,64,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, +{ 0x208 ,M_PACKED4 ,1280,1024,160,64,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, { 0x209 ,M_LIN15 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,364 ,948 ,288,864 ,0 }, { 0x20A ,M_LIN16 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,364 ,948 ,288,864 ,0 }, { 0x20B ,M_LIN32 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,182 ,948 ,144,864 ,0 }, @@ -2292,7 +2303,7 @@ Bitu VideoModeMemSize(Bitu mode) { switch(vmodeBlock->type) { case M_PACKED4: - if (mode >= 0x100 && !allow_vesa_4bpp_packed) return ~0ul; + if (mode >= 0x100 && !(mode >= 0x202 && mode <= 0x208)/*S3 Windows 95 driver needs these*/ && !allow_vesa_4bpp_packed) return ~0ul; return vmodeBlock->swidth*vmodeBlock->sheight/2; case M_LIN4: if (mode >= 0x100 && !allow_vesa_4bpp) return ~0ul; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 209ff103abd..6cfd82f7e43 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -294,7 +294,7 @@ uint8_t VESA_GetSVGAModeInformation(uint16_t mode,uint16_t seg,uint16_t off) { switch (mblock->type) { case M_PACKED4: - if (!allow_vesa_4bpp_packed) return VESA_FAIL;//TODO: New option to disable + if (!allow_vesa_4bpp_packed && !(ModeList_VGA[i].mode >= 0x202 && ModeList_VGA[i].mode <= 0x208)) return VESA_FAIL;//TODO: New option to disable pageSize = mblock->sheight * mblock->swidth/2; var_write(&minfo.BytesPerScanLine,(uint16_t)((((mblock->swidth+15U)/8U)&(~1U))*4)); /* NTS: 4bpp requires even value due to VGA registers, round up */ if (!int10.vesa_oldvbe10) { /* optional in VBE 1.0 */ @@ -904,6 +904,7 @@ Bitu INT10_WriteVESAModeList(Bitu max_modes) { (ModeList_VGA[i].special & _USER_MODIFIED) || (ModeList_VGA[i].swidth <= SCALER_MAXWIDTH && ModeList_VGA[i].sheight <= SCALER_MAXHEIGHT); bool allow_res = allow1 && allow2 && allow3 && allow4 && allow5; + bool allow_s3_packed4 = (ModeList_VGA[i].mode >= 0x202 && ModeList_VGA[i].mode <= 0x208); switch (ModeList_VGA[i].type) { case M_LIN32: canuse_mode=allow_vesa_32bpp && allow_res; break; @@ -912,7 +913,7 @@ Bitu INT10_WriteVESAModeList(Bitu max_modes) { case M_LIN15: canuse_mode=allow_vesa_15bpp && allow_res; break; case M_LIN8: canuse_mode=allow_vesa_8bpp && allow_res; break; case M_LIN4: canuse_mode=allow_vesa_4bpp && allow_res; break; - case M_PACKED4: canuse_mode=allow_vesa_4bpp_packed && allow_res; break; + case M_PACKED4: canuse_mode=(allow_vesa_4bpp_packed || allow_s3_packed4) && allow_res; break; case M_TEXT: canuse_mode=allow_vesa_tty && allow_res; break; default: break; }