From 77bb9df6a62e4ffd3ff9dcc5ea360cbdeb0898a5 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:29:05 +0000 Subject: [PATCH] Reset CurMode object when detecting that the video mode number in BIOS memory was modified directly instead of through the INT 10h mode set function. Fixes cases where BIOS behavior is influenced with the mode number, such as the status line in Bruce Lee. Set color modes (to the extent that they can be) on the Hercules machine type if the BIOS equipment list is not set to monochrome. Fixes missing text in Victory Road. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3975 --- src/dos/dev_con.h | 2 + src/ints/int10.cpp | 1 + src/ints/int10.h | 1 + src/ints/int10_modes.cpp | 85 +++++++++++++++++++++++++++++++--------- src/ints/mouse.cpp | 1 + 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 05af1d0a..9368c49c 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -53,6 +53,7 @@ private: bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; Bit16u count=0; + INT10_SetCurMode(); if ((readcache) && (*size)) { data[count++]=readcache; if(dos.echo) INT10_TeletypeOutput(readcache,7); @@ -117,6 +118,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit8u col,row; Bit16u ncols,nrows; Bit8u tempdata; + INT10_SetCurMode(); while (*size>count) { if (!ansi.esc){ if(data[count]=='\033') { diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 38bf5c00..1ec16b5c 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -48,6 +48,7 @@ static Bitu INT10_Handler(void) { break; } #endif + INT10_SetCurMode(); switch (reg_ah) { case 0x00: /* Set VideoMode */ diff --git a/src/ints/int10.h b/src/ints/int10.h index 4fdbdc0b..d53065da 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -156,6 +156,7 @@ static Bit8u CURSOR_POS_ROW(Bit8u page) { } bool INT10_SetVideoMode(Bit16u mode); +void INT10_SetCurMode(void); void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 65b80c48..f7f2735a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -380,6 +380,66 @@ static bool SetCurMode(VideoModeBlock modeblock[],Bit16u mode) { return false; } +static void SetTextLines(void) { + // check for scanline backwards compatibility (VESA text modes??) + switch (real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x90) { + case 0x80: // 200 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; + } + break; + case 0x00: // 350 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; + } + break; + } +} + +void INT10_SetCurMode(void) { + Bit16u bios_mode=(Bit16u)real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + if (GCC_UNLIKELY(CurMode->mode!=bios_mode)) { + bool mode_changed=false; + switch (machine) { + case MCH_CGA: + if (bios_mode<7) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + break; + case TANDY_ARCH_CASE: + if (bios_mode!=7 && bios_mode<=0xa) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + break; + case MCH_HERC: + if (bios_mode<7) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + else if (bios_mode==7) {mode_changed=true;CurMode=&Hercules_Mode;} + break; + case MCH_EGA: + mode_changed=SetCurMode(ModeList_EGA,bios_mode); + break; + case VGA_ARCH_CASE: + switch (svgaCard) { + case SVGA_TsengET4K: + case SVGA_TsengET3K: + mode_changed=SetCurMode(ModeList_VGA_Tseng,bios_mode); + break; + case SVGA_ParadisePVGA1A: + mode_changed=SetCurMode(ModeList_VGA_Paradise,bios_mode); + break; + case SVGA_S3Trio: + if (bios_mode>=0x68 && CurMode->mode==(bios_mode+0x98)) break; + // fall-through + default: + mode_changed=SetCurMode(ModeList_VGA,bios_mode); + break; + } + if (mode_changed && CurMode->type==M_TEXT) SetTextLines(); + break; + } + if (mode_changed) LOG(LOG_INT10,LOG_WARN)("BIOS video mode changed to %X",bios_mode); + } +} static void FinishSetMode(bool clearmem) { /* Clear video memory if needs be */ @@ -466,8 +526,12 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { } break; case MCH_HERC: - // Only init the adapter if the equipment word is set to monochrome (Testdrive) - if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30) return false; + // Allow standard color modes if equipment word is not set to mono (Victory Road) + if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30 && mode<7) { + SetCurMode(ModeList_OTHER,mode); + FinishSetMode(clearmem); + return true; + } CurMode=&Hercules_Mode; mode=7; // in case the video parameter table is modified break; @@ -682,22 +746,7 @@ bool INT10_SetVideoMode(Bit16u mode) { return false; } } - // check for scanline backwards compatibility (VESA text modes??) - if (CurMode->type==M_TEXT) { - if ((modeset_ctl&0x90)==0x80) { // 200 lines emulation - if (CurMode->mode <= 3) { - CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; - } else if (CurMode->mode == 7) { - CurMode = &ModeList_VGA_Text_350lines[4]; - } - } else if ((modeset_ctl&0x90)==0x00) { // 350 lines emulation - if (CurMode->mode <= 3) { - CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; - } else if (CurMode->mode == 7) { - CurMode = &ModeList_VGA_Text_350lines[4]; - } - } - } + if (CurMode->type==M_TEXT) SetTextLines(); } else { if (!SetCurMode(ModeList_EGA,mode)){ LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index b56be405..3b337e50 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -375,6 +375,7 @@ void RestoreCursorBackground() { void DrawCursor() { if (mouse.hidden || mouse.inhibit_draw) return; + INT10_SetCurMode(); // In Textmode ? if (CurMode->type==M_TEXT) { DrawCursorText();