From 75d7ee65e9871d3bdffd4617253f43038c9ecb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 6 Sep 2009 19:25:34 +0000 Subject: [PATCH] add special int10 scanline modifying function (hal, fixes some mz700 emulator and others) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3463 --- src/dos/dos_keyboard_layout.cpp | 5 +-- src/ints/int10.cpp | 43 +++++++++++++++++++--- src/ints/int10.h | 3 +- src/ints/int10_memory.cpp | 17 ++++++++- src/ints/int10_modes.cpp | 65 ++++++++++++++++++++++++--------- 5 files changed, 104 insertions(+), 29 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 1d828870..661ca88c 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.21 2009-04-01 18:30:41 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.22 2009-09-06 19:25:33 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -935,8 +935,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s // update font if necessary if (font_changed && (CurMode->type==M_TEXT) && (IS_EGAVGA_ARCH)) { - if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); - else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + INT10_ReloadFont(); } INT10_SetupRomMemoryChecksum(); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1e25c925..62b638ba 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.55 2009-04-11 07:58:39 qbix79 Exp $ */ +/* $Id: int10.cpp,v 1.56 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -329,11 +329,42 @@ graphics_chars: case 0x20: /* Set alternate printscreen */ break; case 0x30: /* Select vertical resolution */ - if (!IS_VGA_ARCH) break; - LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - if (reg_al>2) reg_al=0; //invalid subfunction - else reg_al=0x12; //fake a success call - break; + { + if (!IS_VGA_ARCH) break; + LOG(LOG_INT10,LOG_WARN)("Function 12:Call %2X (select vertical resolution)",reg_bl); + if (svgaCard != SVGA_None) { + if (reg_al > 2) { + reg_al=0; // invalid subfunction + break; + } + } + Bit8u modeset_ctl = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + Bit8u video_switches = real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES)&0xf0; + switch(reg_al) { + case 0: // 200 + modeset_ctl &= 0xef; + modeset_ctl |= 0x80; + video_switches |= 8; // ega normal/cga emulation + break; + case 1: // 350 + modeset_ctl &= 0x6f; + video_switches |= 9; // ega enhanced + break; + case 2: // 400 + modeset_ctl &= 0x6f; + modeset_ctl |= 0x10; // use 400-line mode at next mode set + video_switches |= 9; // ega enhanced + break; + default: + modeset_ctl &= 0xef; + video_switches |= 8; // ega normal/cga emulation + break; + } + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,modeset_ctl); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,video_switches); + reg_al=0x12; // success + break; + } case 0x31: /* Palette loading on modeset */ { if (!IS_VGA_ARCH) break; diff --git a/src/ints/int10.h b/src/ints/int10.h index 23338b31..4e0fd1ce 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.41 2009-07-31 15:36:00 c2woody Exp $ */ +/* $Id: int10.h,v 1.42 2009-09-06 19:25:34 c2woody Exp $ */ #include "vga.h" @@ -175,6 +175,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color); /* Font Stuff */ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height); +void INT10_ReloadFont(void); /* Palette Group */ void INT10_SetBackgroundBorder(Bit8u val); diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 49e93187..1c0ee0ab 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.29 2009-07-31 15:36:01 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.30 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -74,6 +74,21 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } } +void INT10_ReloadFont(void) { + switch(CurMode->cheight) { + case 8: + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + break; + case 14: + INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + break; + case 16: + default: + INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + break; + } +} + void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f1a424ff..4acd8f00 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.89 2009-08-01 13:39:48 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.90 2009-09-06 19:25:34 c2woody Exp $ */ #include @@ -124,6 +124,22 @@ VideoModeBlock ModeList_VGA[]={ {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; +VideoModeBlock ModeList_VGA_Text_200lines[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x001 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x002 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x003 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE } +}; + +VideoModeBlock ModeList_VGA_Text_350lines[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 } +}; + VideoModeBlock ModeList_VGA_Tseng[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ { 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, @@ -394,7 +410,6 @@ static void FinishSetMode(bool clearmem) { real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit16u)CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); - real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // this is an index into the dcc table: if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x0b); @@ -620,7 +635,11 @@ bool INT10_SetVideoMode(Bit16u mode) { int10.vesa_setmode=0xffff; LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem); - Bit8u modeset_ctl,video_ctl,vga_switches; + + /* First read mode setup settings from bios area */ +// Bit8u video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); +// Bit8u vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); + Bit8u modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); if (IS_VGA_ARCH) { if (svga.accepts_mode) { @@ -647,6 +666,18 @@ 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 ((modeset_ctl&0x90)==0x00) { // 350 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; + } + } + } } else { if (!SetCurMode(ModeList_EGA,mode)){ LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); @@ -654,11 +685,6 @@ bool INT10_SetVideoMode(Bit16u mode) { } } - /* First read mode setup settings from bios area */ - video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); - vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); - modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); - /* Setup the VGA to the correct mode */ Bit16u crtc_base; @@ -675,11 +701,14 @@ bool INT10_SetVideoMode(Bit16u mode) { /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); + if ((CurMode->type==M_TEXT) && (CurMode->cwidth==9)) { + // 28MHz (16MHz EGA) clock for 9-pixel wide chars + misc_output|=0x4; + } + switch (CurMode->vdispend) { case 400: misc_output|=0x60; - if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) - misc_output|=0x4; break; case 480: misc_output|=0xe0; @@ -695,12 +724,13 @@ bool INT10_SetVideoMode(Bit16u mode) { /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); - if (CurMode->cwidth==8) seq_data[1]|=1; //8 dot fonts by default + seq_data[1]|=0x01; //8 dot fonts by default if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock if ((machine==MCH_EGA) && (CurMode->special & _EGA_HALF_CLOCK)) seq_data[1]|=0x02; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { case M_TEXT: + if (CurMode->cwidth==9) seq_data[1] &= ~1; seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x01; //Alpanumeric if (IS_VGA_ARCH) seq_data[4]|=0x04; //odd/even enabled @@ -1067,12 +1097,12 @@ bool INT10_SetVideoMode(Bit16u mode) { for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct; break; case M_TEXT: - if (machine==MCH_EGA) { - att_data[0x13]=0x00; - att_data[0x10]=0x08; //8 Bit characters - } else { + if (CurMode->cwidth==9) { att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode - att_data[0x10]=0x0C; //Color Text with blinking + att_data[0x10]=0x0C; //Color Text with blinking, 9 Bit characters + } else { + att_data[0x13]=0x00; + att_data[0x10]=0x08; //Color Text with blinking, 8 Bit characters } real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: @@ -1340,8 +1370,7 @@ dac_text16: /* Load text mode font */ if (CurMode->type==M_TEXT) { - if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); - else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + INT10_ReloadFont(); } return true; }