From b032209b752bf1651c21ea3d08457c4198afe1fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:07:19 +0000 Subject: [PATCH] Support for 15/16/32 bpp and highres 4bpp Added some lowres resolutions to the vesa modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2450 --- src/ints/int10_char.cpp | 10 +- src/ints/int10_misc.cpp | 8 +- src/ints/int10_modes.cpp | 197 +++++++++++++++++++++++++++-------- src/ints/int10_put_pixel.cpp | 14 ++- src/ints/int10_vesa.cpp | 111 ++++++++++++++++---- 5 files changed, 267 insertions(+), 73 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 09ae940f..90ebe5de 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.42 2005-12-02 13:10:18 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.43 2006-01-30 10:07:19 harekiet Exp $ */ /* Character displaying moving functions */ @@ -235,7 +235,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit CGA4_CopyRow(cul,clr,start,start+nlines,base);break; case M_TANDY16: TANDY16_CopyRow(cul,clr,start,start+nlines,base);break; - case M_EGA16: + case M_EGA: EGA16_CopyRow(cul,clr,start,start+nlines,base);break; case M_VGA: VGA_CopyRow(cul,clr,start,start+nlines,base);break; @@ -261,7 +261,7 @@ filling: CGA4_FillRow(cul,clr,start,base,attr);break; case M_TANDY16: TANDY16_FillRow(cul,clr,start,base,attr);break; - case M_EGA16: + case M_EGA: EGA16_FillRow(cul,clr,start,base,attr);break; case M_VGA: VGA_FillRow(cul,clr,start,base,attr);break; @@ -483,7 +483,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt attr = 0x1; break; case M_TANDY16: - case M_EGA16: + case M_EGA: default: attr = 0xf; break; @@ -493,7 +493,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds - if (CurMode->type==M_EGA16) { + if (CurMode->type==M_EGA) { /* enable all planes for EGA modes (Ultima 1 colour bug) */ /* might be put into INT10_PutPixel but different vga bios implementations have different opinions about this */ diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 5c680ffc..de1db8fb 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -98,8 +98,12 @@ void INT10_GetFuncStateInformation(PhysPt save) { col_count=2;break; case M_CGA4: col_count=4;break; - case M_EGA16: - if (CurMode->mode==0x11 || CurMode->mode==0x0f) col_count=2; else col_count=16;break; + case M_EGA: + if (CurMode->mode==0x11 || CurMode->mode==0x0f) + col_count=2; + else + col_count=16; + break; case M_VGA: col_count=256;break; default: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2996f014..0120c6d3 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -27,6 +27,7 @@ #define _EGA_HALF_CLOCK 0x0001 #define _EGA_LINE_DOUBLE 0x0002 +#define _VGA_PIXEL_DOUBLE 0x0004 #define SEQ_REGS 0x05 #define GFX_REGS 0x09 @@ -43,24 +44,60 @@ VideoModeBlock ModeList_VGA[]={ { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, -{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, + +/* Follow vesa 1.2 for first 0x20 */ { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x102 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x104 ,M_LIN4 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x105 ,M_LIN8 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, + +{ 0x10D ,M_LIN15 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x10E ,M_LIN16 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x10F ,M_LIN32 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x110 ,M_LIN15 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x111 ,M_LIN16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x112 ,M_LIN32 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x113 ,M_LIN15 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x114 ,M_LIN16 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x115 ,M_LIN32 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, + +{ 0x116 ,M_LIN15 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x117 ,M_LIN16 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x118 ,M_LIN32 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, + + +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, + +{ 0x160 ,M_LIN15 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x161 ,M_LIN15 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x162 ,M_LIN15 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x165 ,M_LIN15 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, + +{ 0x170 ,M_LIN16 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x171 ,M_LIN16 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x172 ,M_LIN16 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x175 ,M_LIN16 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, + +{ 0x190 ,M_LIN32 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x191 ,M_LIN32 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x192 ,M_LIN32 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x195 ,M_LIN32 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _EGA_LINE_DOUBLE }, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _EGA_LINE_DOUBLE }, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -175,7 +212,6 @@ static Bit8u vga_palette[256][3]= {0x0b,0x10,0x0b},{0x0b,0x10,0x0c},{0x0b,0x10,0x0d},{0x0b,0x10,0x0f},{0x0b,0x10,0x10},{0x0b,0x0f,0x10},{0x0b,0x0d,0x10},{0x0b,0x0c,0x10}, {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00} }; - VideoModeBlock * CurMode; static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { @@ -210,9 +246,13 @@ static void FinishSetMode(bool clearmem) { real_writew(0xb800,i*2,0x0720); } break; - case M_EGA16: + case M_EGA: case M_VGA: case M_LIN8: + case M_LIN4: + case M_LIN15: + case M_LIN16: + case M_LIN32: /* Hack we just acess the memory directly */ memset(&vga.mem,0,sizeof(vga.mem)); } @@ -318,7 +358,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { //Setup the special registers for each machine type Bit8u mode_control_list[0xa+1]={ 0x2c,0x28,0x2d,0x29, //0-3 - 0x2a,0x2e,0x1e,0x29, //4-7 + 0x2a,0x2e,0x16,0x29, //4-7 0x2a,0x2b,0x3b //8-a }; Bit8u mode_control_list_pcjr[0xa+1]={ @@ -436,15 +476,19 @@ bool INT10_SetVideoMode(Bitu mode) { Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); 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; - break; - case 350: misc_output|=0xa0; - break; - default: misc_output|=0x60; + case 400: + misc_output|=0x60; + if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) + misc_output|=0x4; + break; + case 480: + misc_output|=0xe0; + break; + case 350: + misc_output|=0xa0; + break; + default: + misc_output|=0x60; } IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 @@ -459,10 +503,17 @@ bool INT10_SetVideoMode(Bitu mode) { seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled break; - case M_EGA16: + case M_CGA2: + seq_data[2]|=0xf; //Enable plane 0 + break; + case M_LIN4: + case M_EGA: seq_data[2]|=0xf; //Enable all planes for writing break; case M_LIN8: //Seems to have the same reg layout from testing + case M_LIN15: + case M_LIN16: + case M_LIN32: case M_VGA: seq_data[2]|=0xf; //Enable all planes for writing seq_data[4]|=0xc; //Graphics - odd/even - Chained @@ -587,6 +638,9 @@ bool INT10_SetVideoMode(Bitu mode) { max_scanline|=1; //Vga doesn't use double line but this break; case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: underline=0x60; //Seems to enable the every 4th clock on my s3 break; case M_CGA2: @@ -606,14 +660,30 @@ bool INT10_SetVideoMode(Bitu mode) { /* Extended Vertical Overflow */ IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); /* Offset Register */ - IO_Write(crtc_base,0x13); + Bitu offset; switch (CurMode->type) { case M_LIN8: - IO_Write(crtc_base+1,CurMode->swidth/8); + offset = CurMode->swidth/8; + break; + case M_LIN15: + case M_LIN16: + offset = 2 * CurMode->swidth/8; + break; + case M_LIN32: + offset = 4 * CurMode->swidth/8; break; default: - IO_Write(crtc_base+1,CurMode->hdispend/2); + offset = CurMode->hdispend/2; } + IO_Write(crtc_base,0x13); + IO_Write(crtc_base + 1,offset & 0xff); + /* Extended System Control 2 Register */ + /* This register actually has more bits but only use the extended offset ones */ + IO_Write(crtc_base,0x61); + IO_Write(crtc_base + 1,(offset & 0x300) >> 4); + /* Extended Vertical Overflow */ + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + /* Mode Control */ Bit8u mode_control=0; @@ -624,7 +694,8 @@ bool INT10_SetVideoMode(Bitu mode) { case M_CGA4: mode_control=0xa2; break; - case M_EGA16: + case M_LIN4: + case M_EGA: if (CurMode->mode==0x11) // 0x11 also sets address wrap. thought maybe all 2 color modes did but 0x0f doesn't. mode_control=0xc3; // so.. 0x11 or 0x0f a one off? else @@ -632,10 +703,13 @@ bool INT10_SetVideoMode(Bitu mode) { break; case M_TEXT: case M_VGA: - mode_control=0xa3; - break; case M_LIN8: - mode_control=0xab; + case M_LIN15: + case M_LIN16: + case M_LIN32: + mode_control=0xa3; + if (CurMode->special & _VGA_PIXEL_DOUBLE) + mode_control |= 0x08; break; } @@ -653,8 +727,18 @@ bool INT10_SetVideoMode(Bitu mode) { /* Setup Pixel format */ switch (CurMode->type) { case M_LIN8: - if (CurMode->swidth < 640) misc_control_2=0x0; //Use single pixel mode,M_VGA then - else misc_control_2=0x10; + /* This should be 0x0 according to the specs but makes it easier to detect + compared to normal vga modes now */ + misc_control_2=0x10; + break; + case M_LIN15: + misc_control_2=0x30; + break; + case M_LIN16: + misc_control_2=0x50; + break; + case M_LIN32: + misc_control_2=0xd0; break; default: misc_control_2=0x0; @@ -674,15 +758,18 @@ bool INT10_SetVideoMode(Bitu mode) { gfx_data[0x6]|=mono_mode ? 0x0a : 0x0e; //Either b800 or b000 break; case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: case M_VGA: gfx_data[0x5]|=0x40; //256 color mode gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; - case M_EGA16: + case M_LIN4: + case M_EGA: gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; case M_CGA4: - case M_TANDY16: gfx_data[0x5]|=0x20; //CGA mode case M_CGA2: gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff @@ -697,7 +784,8 @@ bool INT10_SetVideoMode(Bitu mode) { att_data[0x12]=0xf; //Always have all color planes enabled /* Program Attribute Controller */ switch (CurMode->type) { - case M_EGA16: + case M_LIN4: + case M_EGA: att_data[0x10]=0x01; //Color Graphics switch (CurMode->mode) { case 0x0f: @@ -749,15 +837,17 @@ att_text16: att_data[1]=0x13; att_data[2]=0x15; att_data[3]=0x17; - att_data[4]=0x2; - att_data[5]=0x4; - att_data[6]=0x6; - att_data[7]=0x7; - for (i=8;i<16;i++) att_data[i]=i+8; + att_data[4]=0x02; + att_data[5]=0x04; + att_data[6]=0x06; + att_data[7]=0x07; + for (i=0x8;i<0x10;i++) + att_data[i] = i + 0x8; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); break; case M_VGA: case M_LIN8: + case M_LIN16: for (i=0;i<16;i++) att_data[i]=i; att_data[0x10]=0x41; //Color Graphics 8-bit break; @@ -767,10 +857,11 @@ att_text16: IO_Write(0x3c0,i); IO_Write(0x3c0,att_data[i]); } + IO_Write(0x3c0,0x20); //Disable palette access /* Setup the DAC */ IO_Write(0x3c8,0); switch (CurMode->type) { - case M_EGA16: + case M_EGA: if (CurMode->mode>0xf) goto dac_text16; else if (CurMode->mode==0xf) goto dac_mtext16; for (i=0;i<64;i++) { @@ -807,6 +898,7 @@ dac_text16: break; case M_VGA: case M_LIN8: + case M_LIN16: for (i=0;i<256;i++) { IO_Write(0x3c9,vga_palette[i][0]); IO_Write(0x3c9,vga_palette[i][1]); @@ -845,11 +937,11 @@ dac_text16: case 3:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29);break; } break; - case M_EGA16: + case M_LIN4: + case M_EGA: case M_VGA: feature=(feature&~0x30); break; - } // disabled, has to be set in bios.cpp exclusively // real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); @@ -861,11 +953,24 @@ dac_text16: IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); IO_Write(crtc_base,0x5a); IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); - /* Setup some remaining S3 registers */ -// IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //Enable banked memory and 256k+ access - IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,CurMode->mode<=0x13?0x1:0x9); //Enable banked memory and 256k+ access for SVGA modes only + Bitu reg_31; + switch (CurMode->type) { + case M_LIN4: + case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: + reg_31 = 9; + break; + default: + reg_31 = 0; + break; + } + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access + IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing + IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index d20ac51d..17d10eae 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -90,7 +90,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case M_EGA16: + case M_EGA: { /* Set the correct bitmask for the pixel position */ IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask); @@ -117,6 +117,11 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { case M_VGA: mem_writeb(PhysMake(0xa000,y*320+x),color); break; + case M_LIN8: { + PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + mem_writeb(off,color); + break; + } default: LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); break; @@ -141,7 +146,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((7-x&7)))) & 1 ; } break; - case M_EGA16: + case M_EGA: { /* Calculate where the pixel is in video memory */ PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); @@ -161,6 +166,11 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { case M_VGA: *color=mem_readb(PhysMake(0xa000,320*y+x)); break; + case M_LIN8: { + PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + *color = mem_readb(off); + break; + } default: LOG(LOG_INT10,LOG_ERROR)("GetPixel unhandled mode type %d",CurMode->type); break; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 6a4388c1..b9453b60 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.18 2005-10-29 09:32:52 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.19 2006-01-30 10:07:19 harekiet Exp $ */ #include #include @@ -87,7 +87,8 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { PhysPt buffer=PhysMake(seg,off); Bitu i; bool vbe2=false;Bit16u vbe2_pos=256+off; - if (mem_readd(buffer)==0x32454256) vbe2=true; + Bitu id=mem_readd(buffer); + if ((id==0x56424532)||(id==0x32454256)) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); } else { @@ -119,8 +120,9 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { MODE_INFO minfo; memset(&minfo,0,sizeof(minfo)); PhysPt buf=PhysMake(seg,off); - + Bitu pageSize; Bitu i=0; + if (mode<0x100) return 0x01; while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; @@ -129,23 +131,77 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { foundit: VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { - case M_LIN8: //Linear 8-bit - var_write(&minfo.ModeAttributes,0x9b); - var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable - var_write(&minfo.WinGranularity,64); - var_write(&minfo.WinSize,64); - var_write(&minfo.WinASegment,0xa000); -// var_write(&minfo.WinBSegment,0xa000); - var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); - var_write(&minfo.BytesPerScanLine,mblock->swidth); - var_write(&minfo.NumberOfPlanes,0x1); - var_write(&minfo.BitsPerPixel,0x08); - var_write(&minfo.NumberOfBanks,0x1); - var_write(&minfo.MemoryModel,0x04); //packed pixel - var_write(&minfo.NumberOfImagePages,0x05); - var_write(&minfo.Reserved_page,0x1); + case M_LIN4: + pageSize = mblock->sheight * mblock->swidth/2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(512*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth/8); + var_write(&minfo.BitsPerPixel,4); + var_write(&minfo.MemoryModel,3); //ega planar mode break; + case M_LIN8: + pageSize = mblock->sheight * mblock->swidth; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth); + var_write(&minfo.BitsPerPixel,8); + var_write(&minfo.MemoryModel,4); //packed pixel + break; + case M_LIN15: + pageSize = mblock->sheight * mblock->swidth*2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,15); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,10); + var_write(&minfo.GreenMaskSize,5); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + case M_LIN16: + pageSize = mblock->sheight * mblock->swidth*2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,16); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,11); + var_write(&minfo.GreenMaskSize,6); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + case M_LIN32: + pageSize = mblock->sheight * mblock->swidth*4; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,32); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,11); + var_write(&minfo.GreenMaskSize,6); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + default: + return 0x1; } + + var_write(&minfo.ModeAttributes,0x9b); + var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable + var_write(&minfo.WinGranularity,64); + var_write(&minfo.WinSize,64); + var_write(&minfo.WinASegment,0xa000); + var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + var_write(&minfo.NumberOfPlanes,0x1); + var_write(&minfo.NumberOfBanks,0x1); + var_write(&minfo.Reserved_page,0x1); var_write(&minfo.XResolution,mblock->swidth); var_write(&minfo.YResolution,mblock->sheight); var_write(&minfo.XCharSize,mblock->cwidth); @@ -275,6 +331,13 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { //TODO Maybe do things differently with lowres double line modes? Bitu start; switch (CurMode->type) { + case M_LIN4: + start=vga.config.scan_len*8*y+x; + vga.config.display_start=start/8; + IO_Read(0x3da); + IO_Write(0x3c0,0x13+32); + IO_Write(0x3c0,start % 8); + break; case M_LIN8: start=vga.config.scan_len*8*y+x; vga.config.display_start=start/4; @@ -282,6 +345,15 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { IO_Write(0x3c0,0x13+32); IO_Write(0x3c0,(start % 4)*2); break; + case M_LIN16: + case M_LIN15: + start=vga.config.scan_len*4*y+x; + vga.config.display_start=start/4; + break; + case M_LIN32: + start=vga.config.scan_len*4*y+x; + vga.config.display_start=start/4; + break; default: return 0x1; } @@ -333,6 +405,9 @@ void INT10_SetupVESA(void) { /* Copy the pmode interface block */ int10.rom.pmode_interface=RealMake(0xc000,int10.rom.used); int10.rom.pmode_interface_size=sizeof(PmodeInterface); + switch (svgaCard) { + + } for (i=0;i