From 4e18ea92f4444ca49eb8d519fdb2f8dc6955661a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:50:28 +0000 Subject: [PATCH] More tandy/cga/hercules support, determined by machine type. Changed teletype output function with attirbutes Mono text mode support somewhat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1360 --- src/ints/int10.h | 5 +- src/ints/int10_char.cpp | 104 ++++++++++++++----- src/ints/int10_memory.cpp | 5 +- src/ints/int10_misc.cpp | 2 + src/ints/int10_modes.cpp | 192 ++++++++++++++++++++++------------- src/ints/int10_pal.cpp | 17 ++-- src/ints/int10_put_pixel.cpp | 22 +++- 7 files changed, 237 insertions(+), 110 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index b6bfca58..da3cccd7 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. */ -#include "../hardware/vga.h" +#include "vga.h" #define S3_LFB_BASE 0xC0000000 @@ -144,7 +144,8 @@ void INT10_GetFuncStateInformation(PhysPt save); void INT10_SetCursorShape(Bit8u first,Bit8u last); void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr); +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr); +void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr); void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page); diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 26e755b0..e4b70950 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.19 2003-09-24 19:33:26 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.20 2003-10-22 14:50:28 harekiet Exp $ */ /* Character displaying moving functions */ @@ -26,18 +26,32 @@ #include "inout.h" #include "int10.h" -static INLINE void CGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static INLINE void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft)*2; PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;itwidth*rnew)*(cheight/4)+cleft)*4; + PhysPt src=base+((CurMode->twidth*rold)*(cheight/4)+cleft)*4; + Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; + for (Bitu i=0;itwidth*row)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;itwidth*row)*cheight+cleft)*4; + Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; + attr=(attr & 0xf) | (attr & 0xf) << 4; + for (Bitu i=0;itype!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -142,11 +175,14 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit while (start!=end) { start+=next; switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: TEXT_CopyRow(cul,clr,start,start+nlines,base);break; - case M_CGA2: +// case M_CGA2: case M_CGA4: - CGA_CopyRow(cul,clr,start,start+nlines,base);break; + CGA4_CopyRow(cul,clr,start,start+nlines,base);break; + case M_TANDY16: + TANDY16_CopyRow(cul,clr,start,start+nlines,base);break; case M_EGA16: EGA16_CopyRow(cul,clr,start,start+nlines,base);break; default: @@ -163,11 +199,14 @@ filling: } for (;nlines>0;nlines--) { switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: TEXT_FillRow(cul,clr,start,base,attr);break; - case M_CGA2: +// case M_CGA2: case M_CGA4: - CGA_FillRow(cul,clr,start,base,attr);break; + CGA4_FillRow(cul,clr,start,base,attr);break; + case M_TANDY16: + TANDY16_FillRow(cul,clr,start,base,attr);break; case M_EGA16: EGA16_FillRow(cul,clr,start,base,attr);break; default: @@ -187,10 +226,11 @@ void INT10_SetActivePage(Bit8u page) { real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); if (CurMode->mode<0x8) mem_address>>=1; /* Write the new start address in vgahardware */ - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(mem_address>>8)); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)mem_address); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x0c); + IO_Write(base+1,(Bit8u)(mem_address>>8)); + IO_Write(base,0x0d); + IO_Write(base+1,(Bit8u)mem_address); // And change the BIOS page real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); @@ -243,8 +283,9 @@ void INT10_SetCursorShape(Bit8u first,Bit8u last) { } } dowrite: - IO_Write(0x3d4,0xa);IO_Write(0x3d5,first); - IO_Write(0x3d4,0xb);IO_Write(0x3d5,last); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0xa);IO_Write(base+1,first); + IO_Write(base,0xb);IO_Write(base+1,last); } @@ -263,10 +304,11 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { // Calculate the address knowing nbcols nbrows and page num address=(ncols*row)+col+real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START); // CRTC regs 0x0e and 0x0f - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0e); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(address>>8)); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)address); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x0e); + IO_Write(base+1,(Bit8u)(address>>8)); + IO_Write(base,0x0f); + IO_Write(base+1,(Bit8u)address); } } @@ -290,6 +332,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: { // Compute the address @@ -305,6 +348,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool return; case M_CGA4: case M_CGA2: + case M_TANDY16: if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; //was plain 8 else { chr-=128; @@ -335,7 +379,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -351,8 +395,7 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) } } - -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { +void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { //TODO Check if this page thing is correct Bit8u page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; @@ -375,14 +418,14 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { break; case '\t': do { - INT10_TeletypeOutput(' ',attr,showattr); + INT10_TeletypeOutputAttr(' ',attr,useattr); cur_row=CURSOR_POS_ROW(page); cur_col=CURSOR_POS_COL(page); } while(cur_col%8); break; default: /* Draw the actual Character */ - WriteChar(cur_col,cur_row,page,chr,attr,showattr); + WriteChar(cur_col,cur_row,page,chr,attr,useattr); cur_col++; } if(cur_col==ncols) { @@ -398,9 +441,14 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { INT10_SetCursorPos(cur_row,cur_col,page); } + +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { + INT10_TeletypeOutputAttr(chr,attr,CurMode->type>M_TEXT16); +} + void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; @@ -420,8 +468,8 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B if (flag&2) { attr=mem_readb(string); string++; - } - INT10_TeletypeOutput(chr,attr,true); + } else attr=7; + INT10_TeletypeOutputAttr(chr,attr,flag & 2); count--; } if (flag & 1) { diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index af827cec..7d42c366 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -59,8 +59,9 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu /* Reload tables and registers with new values based on this height */ if (reload) { //Max scanline - IO_Write(0x3d4,0x9); - IO_Write(0x3d5,(IO_Read(0x3d5) & 0xe0)|(height-1)); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x9); + IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1)); //Vertical display end bios says, but should stay the same? //Rows setting in bios segment real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 40a8a918..2f5987f0 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -93,6 +93,8 @@ void INT10_GetFuncStateInformation(PhysPt save) { switch (CurMode->type) { case M_TEXT16: col_count=16;break; + case M_TEXT2: + col_count=2;break; // ?? case M_CGA2: col_count=2;break; case M_CGA4: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 9cf4e1fc..e26e739e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -21,12 +21,12 @@ VideoModeBlock ModeList[]={ { 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, { 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x007 ,M_TEXT16 ,720 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, /* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, @@ -34,11 +34,16 @@ VideoModeBlock ModeList[]={ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 }, { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_LINE_DOUBLE }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, { 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 }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _VGA_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 }, + {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -67,6 +72,18 @@ static Bit8u ega_palette[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; +#if 0 +static Bit8u cga_palette[64][3]= { + {0x00,0x00,0x00}, {0x00,0x00,0x1f}, {0x00,0x1f,0x00}, {0x00,0x1f,0x1f}, {0x1f,0x00,0x00}, {0x1f,0x00,0x1f}, {0x1f,0x1f,0x00}, {0x1f,0x1f,0x1f}, + {0x0f,0x0f,0x0f}, {0x00,0x00,0x3f}, {0x00,0x3f,0x00}, {0x00,0x3f,0x3f}, {0x3f,0x00,0x00}, {0x3f,0x00,0x3f}, {0x3f,0x3f,0x00}, {0x3f,0x3f,0x3f}, +}; +#else +static Bit8u cga_palette[16][3]= { + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, +}; +#endif + static Bit8u vga_palette[256][3]= { @@ -114,7 +131,6 @@ bool INT10_SetVideoMode(Bitu mode) { bool clearmem=true; Bit8u modeset_ctl,video_ctl,vga_switches; - Bit16u crtc_addr; if (mode<256) { if (mode & 128) { @@ -143,9 +159,17 @@ foundmode: /* Setup the VGA to the correct mode */ VGA_SetMode(CurMode->type); - + + Bit16u crtc_base; + bool mono_mode=CurMode->type == M_TEXT2; + if (mono_mode) { + crtc_base=0x3b4; + } else { + crtc_base=0x3d4; + } /* Setup MISC Output Register */ - Bit8u misc_output=0x3; //Color and cpu memory access + Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); + IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); @@ -154,6 +178,7 @@ foundmode: (CurMode->special & _HALF_CLOCK) ? 0x08 : 0x00; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled @@ -173,22 +198,22 @@ foundmode: } /* Program CRTC */ /* First disable write protection */ - IO_Write(0x3d4,0x11); - IO_Write(0x3d5,IO_Read(0x3d5)&0x7f); + IO_Write(crtc_base,0x11); + IO_Write(crtc_base+1,IO_Read(crtc_base+1)&0x7f); /* Clear all the regs */ for (i=0x0;i<=0x18;i++) { - IO_Write(0x3d4,i);IO_Write(0x3d5,0); + IO_Write(crtc_base,i);IO_Write(crtc_base+1,0); } Bit8u overflow=0;Bit8u max_scanline=0; Bit8u ver_overflow=0;Bit8u hor_overflow=0; /* Horizontal Total */ - IO_Write(0x3d4,0x00);IO_Write(0x3d5,CurMode->htotal-5); + IO_Write(crtc_base,0x00);IO_Write(crtc_base+1,CurMode->htotal-5); hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8; /* Horizontal Display End */ - IO_Write(0x3d4,0x01);IO_Write(0x3d5,CurMode->hdispend-1); + IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,CurMode->hdispend-1); hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7; /* Start horizontal Blanking */ - IO_Write(0x3d4,0x02);IO_Write(0x3d5,CurMode->hdispend); + IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,CurMode->hdispend); hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; /* End horizontal Blanking */ Bitu blank_end; @@ -197,7 +222,7 @@ foundmode: } else { blank_end = (CurMode->htotal-2) & 0x7f; } - IO_Write(0x3d4,0x03);IO_Write(0x3d5,0x80|(blank_end & 0x1f)); + IO_Write(crtc_base,0x03);IO_Write(crtc_base+1,0x80|(blank_end & 0x1f)); // hor_overflow|=(blank_end & 0x40) >> 3; /* Start Horizontal Retrace */ @@ -207,7 +232,7 @@ foundmode: } else { ret_start = (CurMode->hdispend+4); } - IO_Write(0x3d4,0x04);IO_Write(0x3d5,ret_start); + IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ Bitu ret_end; @@ -216,12 +241,12 @@ foundmode: } else { ret_end = (CurMode->htotal-4) & 0x3f; } - IO_Write(0x3d4,0x05);IO_Write(0x3d5,(ret_end & 0x1f) | (blank_end & 0x20) << 2); + IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(ret_end & 0x1f) | (blank_end & 0x20) << 2); // hor_overflow|=(ret_end & 0x20); //TODO Be sure about these ending values in extended overflow of s3 /* Vertical Total */ - IO_Write(0x3d4,0x06);IO_Write(0x3d5,(CurMode->vtotal-2)); + IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; overflow|=((CurMode->vtotal-2) & 0x200) >> 4; ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; @@ -231,29 +256,29 @@ foundmode: So you get same sized borders, but okay :) */ /* Vertical Retrace Start */ - IO_Write(0x3d4,0x10);IO_Write(0x3d5,(CurMode->vdispend+12)); + IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,(CurMode->vdispend+12)); overflow|=((CurMode->vdispend+12) & 0x100) >> 6; overflow|=((CurMode->vdispend+12) & 0x200) >> 2; ver_overflow|=((CurMode->vdispend+12) & 0x400) >> 6; /* Vertical Retrace End */ - IO_Write(0x3d4,0x11);IO_Write(0x3d5,(CurMode->vdispend+14) & 0xF); + IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(CurMode->vdispend+14) & 0xF); /* Vertical Display End */ - IO_Write(0x3d4,0x12);IO_Write(0x3d5,(CurMode->vdispend-1)); + IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(CurMode->vdispend-1)); overflow|=((CurMode->vdispend-1) & 0x100) >> 7; overflow|=((CurMode->vdispend-1) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; /* Vertical Blank Start */ - IO_Write(0x3d4,0x15);IO_Write(0x3d5,(CurMode->vdispend+8)); + IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+8)); overflow|=((CurMode->vdispend+8) & 0x100) >> 5; max_scanline|=((CurMode->vdispend+8) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend+8) & 0x400) >> 8; /* Vertical Retrace End */ - IO_Write(0x3d4,0x16);IO_Write(0x3d5,(CurMode->vtotal-8)); + IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); /* Line Compare */ Bitu line_compare=CurMode->vtotal+1; //Out of range - IO_Write(0x3d4,0x18);IO_Write(0x3d5,line_compare&0xff); + IO_Write(crtc_base,0x18);IO_Write(crtc_base+1,line_compare&0xff); overflow|=(line_compare & 0x100) >> 4; max_scanline|=(line_compare & 0x200) >> 3; ver_overflow|=(line_compare & 0x400) >> 4; @@ -261,8 +286,9 @@ foundmode: /* Maximum scanline / Underline Location */ if (CurMode->special & _LINE_DOUBLE) max_scanline|=0x80; switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: - max_scanline|=CurMode->theight-1; + max_scanline|=CurMode->cheight-1; underline=0x1f; break; case M_VGA: @@ -275,23 +301,23 @@ foundmode: if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } - IO_Write(0x3d4,0x09);IO_Write(0x3d5,max_scanline); - IO_Write(0x3d4,0x14);IO_Write(0x3d5,underline); + IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); + IO_Write(crtc_base,0x14);IO_Write(crtc_base+1,underline); /* OverFlow */ - IO_Write(0x3d4,0x07);IO_Write(0x3d5,overflow); + IO_Write(crtc_base,0x07);IO_Write(crtc_base+1,overflow); /* Extended Horizontal Overflow */ - IO_Write(0x3d4,0x5d);IO_Write(0x3d5,hor_overflow); + IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow); /* Extended Vertical Overflow */ - IO_Write(0x3d4,0x5e);IO_Write(0x3d5,ver_overflow); + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); /* Offset Register */ - IO_Write(0x3d4,0x13); + IO_Write(crtc_base,0x13); switch (CurMode->type) { case M_LIN8: - IO_Write(0x3d5,CurMode->swidth/8); + IO_Write(crtc_base+1,CurMode->swidth/8); break; default: - IO_Write(0x3d5,CurMode->hdispend/2); + IO_Write(crtc_base+1,CurMode->hdispend/2); } /* Mode Control */ Bit8u mode_control=0; @@ -303,6 +329,7 @@ foundmode: case M_EGA16: mode_control=0xe3; break; + case M_TEXT2: case M_TEXT16: case M_VGA: mode_control=0xa3; @@ -310,12 +337,11 @@ foundmode: case M_LIN8: mode_control=0xab; break; - } - IO_Write(0x3d4,0x17);IO_Write(0x3d5,mode_control); + IO_Write(crtc_base,0x17);IO_Write(crtc_base+1,mode_control); /* Renable write protection */ - IO_Write(0x3d4,0x11); - IO_Write(0x3d5,IO_Read(0x3d5)|0x80); + IO_Write(crtc_base,0x11); + IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); /* Setup the correct clock */ if (CurMode->mode<0x100) { //Stick to 25mhz clock for now @@ -333,6 +359,10 @@ foundmode: gfx_data[0x7]=0xf; /* Color don't care */ gfx_data[0x8]=0xff; /* BitMask */ switch (CurMode->type) { + case M_TEXT2: + gfx_data[0x5]|=0x10; //Odd-Even Mode + gfx_data[0x6]|=0x0a; //alphanumeric mode at 0xb000=0x7fff + break; case M_TEXT16: gfx_data[0x5]|=0x10; //Odd-Even Mode gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbfff @@ -365,11 +395,11 @@ foundmode: if (CurMode->mode>0xe) goto att_text16; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics - for (i=0;i<8;i++) { + for (i=0;i<16;i++) { att_data[i]=i; - att_data[i+8]=i+0x10; } break; + case M_TEXT2: case M_TEXT16: 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 @@ -380,8 +410,12 @@ att_text16: } break; case M_CGA2: + IO_Write(0x3d9,0x7); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x7); + goto skipatt; case M_CGA4: - IO_Write(0x3d9,0x20); //Setup using CGA color select register + IO_Write(0x3d9,0x30); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); goto skipatt; case M_VGA: case M_LIN8: @@ -392,7 +426,7 @@ att_text16: break; } - IO_Read(0x3da); + IO_Read(mono_mode ? 0x3ba : 0x3da); for (i=0;itype) { + case M_CGA2: + feature=(feature&~0x30)|0x20; + IO_Write(0x3d8,0x12); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x12); + break; + case M_CGA4: + feature=(feature&~0x30)|0x20; + IO_Write(0x3d8,0x2); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); + break; case M_TANDY16: + feature=(feature&~0x30)|0x20; IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 break; + case M_TEXT2: + feature=(feature&~0x30)|0x30; + break; + case M_TEXT16: + feature=(feature&~0x30)|0x20; + break; + case M_EGA16: + case M_VGA: + feature=(feature&~0x30); + break; + } + real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); /* Setup the CPU Window */ - IO_Write(0x3d4,0x6a); - IO_Write(0x3d5,0); + IO_Write(crtc_base,0x6a); + IO_Write(crtc_base+1,0); /* Setup the linear frame buffer */ - IO_Write(0x3d4,0x59); - IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 24)); - IO_Write(0x3d4,0x5a); - IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 16)); + IO_Write(crtc_base,0x59); + 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(0x3d4,0x31);IO_Write(0x3d5,0x9); //Enable banked memory and 256k+ access - IO_Write(0x3d4,0x58);IO_Write(0x3d5,0x3); //Enable 8 mb of linear addressing - IO_Write(0x3d4,0x38);IO_Write(0x3d5,0x48); //Register lock 1 - IO_Write(0x3d4,0x39);IO_Write(0x3d5,0xa5); //Register lock 2 + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //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,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 + IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 /* Load text mode font */ - if (CurMode->type==M_TEXT16) { + if (CurMode->type<=M_TEXT16) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } /* Clear video memory if needs be */ @@ -463,9 +522,14 @@ dac_text16: real_writew(0xb800,i*2,0x0000); } break; + case M_TEXT2: + for (i=0;i<16*1024;i++) { + real_writew(0xb000,i*2,0x0120); + } + break; case M_TEXT16: for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0700); + real_writew(0xb800,i*2,0x0720); } break; case M_EGA16: @@ -477,16 +541,12 @@ dac_text16: } } } - /* Setup the CRTC Address */ - - crtc_addr=0x3d4; - /* Setup the BIOS */ if (mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode-0x98); //Looks like the s3 bios real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); - real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_base); real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); @@ -498,12 +558,8 @@ dac_text16: real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); - // FIXME - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... - // Set cursor shape - if(CurMode->type==M_TEXT16) { + if(CurMode->type<=M_TEXT16) { INT10_SetCursorShape(0x06,07); } // Set cursor pos for page 0..7 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 2563e30b..3c7a0840 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -155,18 +155,17 @@ void INT10_GetPelMask(Bit8u & mask) { mask=IO_Read(VGAREG_PEL_MASK); } - void INT10_SetBackgroundBorder(Bit8u val) { -//TODO Detect if we're CGA? - Bit8u old=IO_Read(0x3d9) & 0xf0; - old|=val & 0xf; - IO_Write(0x3d9,old); + Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + temp=(temp & 0xe0) | (val & 0x1f); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); + IO_Write(0x3d9,temp); } void INT10_SetColorSelect(Bit8u val) { -//TODO Detect if we're CGA? - Bit8u old=IO_Read(0x3d9) & ~0x20; - old|=(val & 1) << 5; - IO_Write(0x3d9,old); + Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); + IO_Write(0x3d9,temp); } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index efa0a336..dd07b596 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -54,6 +54,25 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; + case M_TANDY16: + { + Bit16u off=(y>>2)*160+(x>>1); + off+=(8*1024) * (y & 3); + Bit8u old=real_readb(0xb800,off); + Bit8u p[2]; + p[1] = (old >> 4) & 0xf; + p[0] = old & 0xf; + Bitu ind = 1-(x & 0x1); + + if (color & 0x80) { + p[ind]^=color; + } else { + p[ind]=color; + } + old = (p[1] << 4) | p[0]; + real_writeb(0xb800,off,old); + } + break; case M_EGA16: { /* Set the correct bitmask for the pixel position */ @@ -77,8 +96,9 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; } + case M_VGA: - mem_writeb(Real2Phys(RealMake(0xa000,y*320+x)),color); + mem_writeb(PhysMake(0xa000,y*320+x),color); break; default: LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type);