diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0554cf69..410fb176 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -27,31 +27,42 @@ #include "int10.h" #include "../hardware/vga.h" /* Maybe move this thing */ -#define TEXT_SEG 0xb800 - +Int10Data int10; static Bitu call_10; static bool warned_ff=false; -static bool warned_int10_0b=false; -Int10Data int10; - static Bitu INT10_Handler(void) { +#if 0 + switch (reg_ah) { + case 0x02: + case 0x03: + case 0x09: + case 0xc: + case 0xd: + case 0x0e: + case 0x10: + case 0x4f: + break; + default: + LOG(LOG_INT10,LOG_NORMAL)("Function AX:%04X , BX %04X",reg_ax,reg_bx); + break; + } +#endif switch (reg_ah) { case 0x00: /* Set VideoMode */ INT10_SetVideoMode(reg_al); break; case 0x01: /* Set TextMode Cursor Shape */ - vga.internal.cursor=reg_cx; // maybe write some memory somewhere - LOG(LOG_INT10,LOG_NORMAL)("INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); + INT10_SetCursorShape(reg_ch,reg_cl); break; case 0x02: /* Set Cursor Pos */ - //TODO Check some shit but not really usefull INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); break; case 0x03: /* get Cursor Pos and Cursor Shape*/ - //TODO the Cursor Shape Stuff + reg_ah=0; reg_dl=CURSOR_POS_COL(reg_bh); reg_dh=CURSOR_POS_ROW(reg_bh); + reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE); break; case 0x04: /* read light pen pos YEAH RIGHT */ /* Light pen is not supported */ @@ -62,15 +73,12 @@ static Bitu INT10_Handler(void) { else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ -//TODO Graphics mode scroll INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,-reg_al,reg_bh,0xFF); break; - case 0x07: - /* Scroll Down */ + case 0x07: /* Scroll Down */ INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); break; case 0x08: /* Read character & attribute at cursor */ -//TODO Check for GRAPH and then just return INT10_ReadCharAttr(®_ax,reg_bh); break; case 0x09: /* Write Character & Attribute at cursor CX times */ @@ -80,10 +88,14 @@ static Bitu INT10_Handler(void) { INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false); break; case 0x0B: /* Set Background/Border Colour & Set Palette*/ - if(!warned_int10_0b) { - LOG(LOG_INT10,LOG_ERROR)("Function 0B Unsupported: Set Background/border colour & Set Pallete"); - warned_int10_0b=true; - } + switch (reg_bh) { + case 0x00: //Background/Border color + INT10_SetBackgroundBorder(reg_bl); + break; + case 0x01: //Set color Select + INT10_SetColorSelect(reg_bl); + break; + } break; case 0x0C: /* Write Graphics Pixel */ INT10_PutPixel(reg_cx,reg_dx,reg_bh,reg_al); @@ -128,18 +140,68 @@ static Bitu INT10_Handler(void) { case 0x12: /* SET BLOCK OF DAC REGISTERS */ INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; + case 0x13: /* SELECT VIDEO DAC COLOR PAGE */ + INT10_SelectDACPage(reg_bl,reg_bh); + break; case 0x15: /* GET INDIVIDUAL DAC REGISTER */ INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); break; case 0x17: /* GET BLOCK OF DAC REGISTER */ INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; + case 0x18: /* undocumented - SET PEL MASK */ + INT10_SetPelMask(reg_bl); + break; + case 0x19: /* undocumented - GET PEL MASK */ + INT10_GetPelMask(reg_bl); + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } break; case 0x11: /* Character generator functions */ switch (reg_al) { +/* Textmode calls */ + case 0x00: /* Load user font */ + case 0x10: + INT10_LoadFont(SegPhys(es)+reg_bp,reg_al==0x10,reg_cx,reg_dx,reg_bl,reg_bh); + break; + case 0x01: /* Load 8x14 font */ + case 0x11: + INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + break; + case 0x02: /* Load 8x8 font */ + case 0x12: + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + break; +/* Graphics mode calls */ + case 0x20: /* Set User 8x8 Graphics characters */ + RealSetVec(0x1f,RealMake(SegValue(es),reg_bp)); + break; + case 0x21: /* Set user graphics characters */ + RealSetVec(0x43,RealMake(SegValue(es),reg_bp)); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,reg_cx); + goto graphics_chars; + case 0x22: /* Rom 8x14 set */ + RealSetVec(0x43,int10.rom.font_14); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,14); + goto graphics_chars; +// case 0x23: /* Rom 8x8 double dot set */ + //TODO + case 0x24: /* Rom 8x16 set */ + RealSetVec(0x43,int10.rom.font_16); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,16); + goto graphics_chars; +graphics_chars: + switch (reg_bl) { + case 0x00:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,reg_dl-1);break; + case 0x01:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,13);break; + case 0x03:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,42);break; + case 0x02: + default:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,24);break; + } + break; +/* General */ case 0x30:/* Get Font Information */ switch (reg_bh) { case 0x00: /* interupt 0x1f vector */ @@ -159,23 +221,23 @@ static Bitu INT10_Handler(void) { } break; case 0x02: /* font 8x14 */ - SegSet16(es,RealSeg(int10_romarea.font_14)); - reg_bp=RealOff(int10_romarea.font_14); + SegSet16(es,RealSeg(int10.rom.font_14)); + reg_bp=RealOff(int10.rom.font_14); reg_cx=14; break; case 0x03: /* font 8x8 first 128 */ - SegSet16(es,RealSeg(int10_romarea.font_8_first)); - reg_bp=RealOff(int10_romarea.font_8_first); + SegSet16(es,RealSeg(int10.rom.font_8_first)); + reg_bp=RealOff(int10.rom.font_8_first); reg_cx=8; break; case 0x04: /* font 8x8 second 128 */ - SegSet16(es,RealSeg(int10_romarea.font_8_second)); - reg_bp=RealOff(int10_romarea.font_8_second); + SegSet16(es,RealSeg(int10.rom.font_8_second)); + reg_bp=RealOff(int10.rom.font_8_second); reg_cx=8; break; case 0x06: /* font 8x16 */ - SegSet16(es,RealSeg(int10_romarea.font_16)); - reg_bp=RealOff(int10_romarea.font_16); + SegSet16(es,RealSeg(int10.rom.font_16)); + reg_bp=RealOff(int10.rom.font_16); reg_cx=16; break; default: @@ -197,8 +259,16 @@ static Bitu INT10_Handler(void) { reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; break; } + case 0x36: /* VGA Refresh control */ + /* + Call disables/enables the vga from outputting video, + don't support it, but fake a success return + */ + reg_al=0x12; + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); + reg_al=0x12; //Always fake a success call } break; case 0x13: /* Write String */ @@ -223,7 +293,76 @@ static Bitu INT10_Handler(void) { reg_al=0x1B; break; default: - LOG(LOG_INT10,LOG_ERROR)("Function 1B:Unhandled call BX %2X",reg_bx); + LOG(LOG_INT10,LOG_ERROR)("1B:Unhandled call BX %2X",reg_bx); + } + break; + case 0x4f: /* VESA Calls */ + switch (reg_al) { + case 0x00: /* Get SVGA Information */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAInformation(SegValue(es),reg_di); + break; + case 0x01: /* Get SVGA Mode Information */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAModeInformation(reg_cx,SegValue(es),reg_di); + break; + case 0x02: /* Set videomode */ + reg_al=0x4f; + reg_ah=VESA_SetSVGAMode(reg_bx); + break; + case 0x03: /* Get videomode */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAMode(reg_bx); + break; + case 0x05: + if (reg_bh==0) { /* Set CPU Window */ + reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); + reg_al=0x4f; + } else if (reg_bh == 1) { /* Get CPU Window */ + reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); + reg_al=0x4f; + } else { + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bh); + reg_ah=0x01; + } + break; + case 0x07: + switch (reg_bl) { + case 0x80: /* Set Display Start during retrace ?? */ + case 0x00: /* Set display Start */ + reg_al=0x4f; + reg_ah=VESA_SetDisplayStart(reg_cx,reg_dx); + break; + case 0x01: + reg_al=0x4f; + reg_bh=0x00; //Weird? + reg_ah=VESA_GetDisplayStart(reg_cx,reg_dx); + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); + reg_ah=0x1; + } + break; + case 0x09: + switch (reg_bl) { + case 0x80: /* Set Palette during retrace */ + //TODO + case 0x00: /* Set Palette */ + reg_ah=VESA_SetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx); + reg_al=0x4f; + break; + case 0x01: /* Get Palette */ + reg_ah=VESA_GetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx); + reg_al=0x4f; + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); + reg_ah=0x01; + } + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X",reg_al); + reg_al=0x0; } break; case 0xff: @@ -251,8 +390,6 @@ static void INT10_Seg40Init(void) { real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,0x51); // Set the default MSR real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x09); - - INT10_SetVideoMode(3); } @@ -275,6 +412,8 @@ void INT10_Init(Section* sec) { //Init the 0x40 segment and init the datastructures in the the video rom area INT10_SetupRomMemory(); INT10_Seg40Init(); + INT10_SetupVESA(); + INT10_SetVideoMode(3); }; diff --git a/src/ints/int10.h b/src/ints/int10.h index de9c92ce..05067f67 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "../hardware/vga.h" + #define BIOSMEM_SEG 0x40 #define BIOSMEM_INITIAL_MODE 0x10 @@ -83,99 +85,64 @@ #define VGAMEM_CTEXT 0xB800 #define VGAMEM_MTEXT 0xB000 - - -/* - * - * Tables of default values for each mode - * - */ -#define MODE_MAX 0x13 -#define TEXT 0x00 -#define GRAPH 0x01 - -#define CTEXT 0x00 -#define MTEXT 0x01 -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR2 0x04 -#define PLANAR4 0x05 -#define LINEAR8 0x06 -#define CGA2 0x07 -// for Tandy - -#define TANDY16 0x0A - - -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - - #define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) #define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) #define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) +#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); +#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; extern Bit8u int10_font_16[256 * 16]; +struct VideoModeBlock { + Bitu mode; + VGAModes type; + Bitu swidth, sheight; + Bitu twidth, theight; + Bitu cwidth, cheight; + Bitu ptotal,pstart,plength; - -typedef struct -{Bit8u svgamode; - Bit16u vesamode; - Bit8u type; /* TEXT, GRAPH */ - Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - Bit8u nbpages; - Bit8u pixbits; - Bit16u swidth, sheight; - Bit16u twidth, theight; - Bit16u cwidth, cheight; - Bit16u sstart; - Bit16u slength; - Bit8u miscreg; - Bit8u pelmask; - Bit8u crtcmodel; - Bit8u actlmodel; - Bit8u grdcmodel; - Bit8u sequmodel; - Bit8u dacmodel; /* 0 1 2 3 */ -} VGAMODES; - -extern VGAMODES vga_modes[MODE_MAX+1]; - + Bitu htotal,vtotal; + Bitu hdispend,vdispend; + Bitu special; + +}; +extern VideoModeBlock ModeList[]; +extern VideoModeBlock * CurMode; typedef struct { - RealPt font_8_first; - RealPt font_8_second; - RealPt font_14; - RealPt font_16; - RealPt static_state; -} VGAROMAREA; -extern VGAROMAREA int10_romarea; + struct { + RealPt font_8_first; + RealPt font_8_second; + RealPt font_14; + RealPt font_16; + RealPt static_state; + RealPt oemstring; + RealPt vesa_modes; + Bitu used; + } rom; +} Int10Data; -#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); -#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; +extern Int10Data int10; -inline Bit8u CURSOR_POS_COL(Bit8u page) { +INLINE Bit8u CURSOR_POS_COL(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2); } -inline Bit8u CURSOR_POS_ROW(Bit8u page) { +INLINE Bit8u CURSOR_POS_ROW(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); } - -void INT10_SetVideoMode(Bit8u mode); +bool INT10_SetVideoMode(Bitu mode); void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); void INT10_SetActivePage(Bit8u page); 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, Bit8u page); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); @@ -185,9 +152,13 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B /* Graphics Stuff */ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color); void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color); -VGAMODES * GetCurrentMode(void); + +/* Font Stuff */ +void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height); /* Palette Group */ +void INT10_SetBackgroundBorder(Bit8u val); +void INT10_SetColorSelect(Bit8u val); void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val); void INT10_SetOverscanBorderColor(Bit8u val); void INT10_SetAllPaletteRegisters(PhysPt data); @@ -199,17 +170,27 @@ void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue); void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue); void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); +void INT10_SelectDACPage(Bit8u function,Bit8u mode); +void INT10_SetPelMask(Bit8u mask); +void INT10_GetPelMask(Bit8u & mask); -/* Mouse pointer */ -void INT10_SetGfxControllerToDefault(void); + + +/* Vesa Group */ +Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off); +Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off); +Bit8u VESA_SetSVGAMode(Bit16u mode); +Bit8u VESA_GetSVGAMode(Bit16u & mode); +Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address); +Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address); +Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines); +Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y); +Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y); +Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count); +Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sup Groups */ void INT10_SetupRomMemory(void); +void INT10_SetupVESA(void); -struct Int10Data { - Bit8u mode; - VGAMODES * entry; -}; - -extern Int10Data int10; diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index eb8e8ac2..2865267e 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -24,28 +24,28 @@ #include "inout.h" #include "int10.h" -static INLINE void CGA_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { - PhysPt dest=base+((curmode->twidth*rnew)*(curmode->cheight/2)+cleft)*2; - PhysPt src=base+((curmode->twidth*rold)*(curmode->cheight/2)+cleft)*2; - Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; - for (Bits i=0;icheight/2;i++) { +static INLINE void CGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + PhysPt dest=base+((CurMode->twidth*rnew)*(CurMode->cheight/2)+cleft)*2; + PhysPt src=base+((CurMode->twidth*rold)*(CurMode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; + for (Bitu i=0;icheight/2;i++) { MEM_BlockCopy(dest,src,copy); MEM_BlockCopy(dest+8*1024,src+8*1024,copy); dest+=nextline;src+=nextline; } } -static INLINE void PLANAR4_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; - dest=base+(curmode->twidth*rnew)*curmode->cheight+cleft; - src=base+(curmode->twidth*rold)*curmode->cheight+cleft; - Bitu nextline=curmode->twidth; + dest=base+(CurMode->twidth*rnew)*CurMode->cheight+cleft; + src=base+(CurMode->twidth*rold)*CurMode->cheight+cleft; + Bitu nextline=CurMode->twidth; /* Setup registers correctly */ IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Enable all Write planes */ /* Do some copying */ Bitu rowsize=(cright-cleft); - copy=curmode->cheight; + copy=CurMode->cheight; for (;copy>0;copy--) { for (Bitu x=0;xtwidth+cleft)*2; - dest=base+(rnew*curmode->twidth+cleft)*2; + src=base+(rold*CurMode->twidth+cleft)*2; + dest=base+(rnew*CurMode->twidth+cleft)*2; MEM_BlockCopy(dest,src,(cright-cleft)*2); } -static INLINE void CGA_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { - PhysPt dest=base+((curmode->twidth*row)*(curmode->cheight/2)+cleft)*2; - Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; - for (Bits i=0;icheight/2;i++) { +static INLINE void CGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { + PhysPt dest=base+((CurMode->twidth*row)*(CurMode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; + for (Bitu i=0;icheight/2;i++) { for (Bitu x=0;xtwidth*row)*curmode->cheight+cleft; - Bitu nextline=curmode->twidth; - Bitu copy=curmode->cheight; Bitu rowsize=(cright-cleft); + dest=base+(CurMode->twidth*row)*CurMode->cheight+cleft; + Bitu nextline=CurMode->twidth; + Bitu copy=CurMode->cheight; Bitu rowsize=(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;xtwidth+cleft)*2; + dest=base+(row*CurMode->twidth+cleft)*2; Bit16u fill=(attr<<8)+' '; for (Bit8u x=0;x<(cright-cleft);x++) { mem_writew(dest,fill); @@ -107,8 +106,7 @@ static INLINE void TEXT_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8 void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) { /* Do some range checking */ - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + if (CurMode->type!=M_TEXT16) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -118,9 +116,9 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - PhysPt base=PhysMake(curmode->sstart,curmode->slength*page); + PhysPt base=CurMode->pstart+CurMode->plength*page; - /* See how much lines need to be copies */ + /* See how much lines need to be copied */ Bit8u start,end;Bits next; /* Copy some lines */ if (nlines>0) { @@ -137,15 +135,16 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit } while (start!=end) { start+=next; - switch (curmode->memmodel) { - case MTEXT: - case CTEXT: - TEXT_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - case CGA2: - case CGA: - CGA_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - case PLANAR4: - PLANAR4_CopyRow(curmode,cul,clr,start,start+nlines,base);break; + switch (CurMode->type) { + case M_TEXT16: + TEXT_CopyRow(cul,clr,start,start+nlines,base);break; + case M_CGA2: + case M_CGA4: + CGA_CopyRow(cul,clr,start,start+nlines,base);break; + case M_EGA16: + EGA16_CopyRow(cul,clr,start,start+nlines,base);break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } } /* Fill some lines */ @@ -157,14 +156,16 @@ filling: start=rlr-nlines+1; } for (;nlines>0;nlines--) { - switch (curmode->memmodel) { - case MTEXT: - case CTEXT: - TEXT_FillRow(curmode,cul,clr,start,base,attr);break; - case CGA: - CGA_FillRow(curmode,cul,clr,start,base,attr);break; - case PLANAR4: - PLANAR4_FillRow(curmode,cul,clr,start,base,attr);break; + switch (CurMode->type) { + case M_TEXT16: + TEXT_FillRow(cul,clr,start,base,attr);break; + case M_CGA2: + case M_CGA4: + CGA_FillRow(cul,clr,start,base,attr);break; + case M_EGA16: + EGA16_FillRow(cul,clr,start,base,attr);break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } start++; } @@ -175,14 +176,11 @@ void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; Bit8u cur_col=0 ,cur_row=0 ; - VGAMODES * curmode=GetCurrentMode(); - if (curmode==0) return; if (page>7) return; - mem_address=page*curmode->slength; + mem_address=page*CurMode->plength; /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (curmode->svgamode<8) mem_address>>=1; - + if (CurMode->mode<8) mem_address>>=1; /* Write the new start address in vgahardware */ IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); @@ -197,6 +195,53 @@ void INT10_SetActivePage(Bit8u page) { INT10_SetCursorPos(cur_row,cur_col,page); } +void INT10_SetCursorShape(Bit8u first,Bit8u last) { + real_writew(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,last|(first<<8)); + /* Skip CGA cursor emulation if EGA/VGA system is active */ + if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x8)) { + /* Check for CGA type 01, invisible */ + if ((first & 0x60) == 0x20) { + first=0x1e; + last=0x00; + goto dowrite; + } + /* Check if we need to convert CGA Bios cursor values */ + if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x1)) { + if (CurMode->mode>0x3) goto dowrite; //Only mode 0-3 are text modes on cga + if ((first & 0xe0) || (last & 0xe0)) goto dowrite; + Bit8u cheight=real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)-1; + /* Creative routine i based of the original ibmvga bios */ + if (last=cheight) || !(last==(cheight-1)) || !(first==cheight) ) { + if (last<=3) goto dowrite; + if (first+22) { + first=(cheight+1)/2; + last=cheight; + } else { + last=cheight; + } + } else { + first=(first-last)+cheight; + last=cheight; + if (cheight>0xc) { + first--; + last--; + } + } + } + + } + } +dowrite: + IO_Write(0x3d4,0xa);IO_Write(0x3d5,first); + IO_Write(0x3d4,0xb);IO_Write(0x3d5,last); +} + void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; @@ -217,12 +262,11 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(address&0xff00)>>8); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,address&0x00ff); - } + } } void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); @@ -233,66 +277,55 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { } - -INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->type) { - case TEXT: +static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { + Bit8u * fontdata; + Bitu x,y; + switch (CurMode->type) { + case M_TEXT16: { // Compute the address - Bit16u address=SCREEN_MEM_START(curmode->twidth,curmode->theight,page)+(col+row*curmode->twidth)*2; + Bit16u address=SCREEN_MEM_START(CurMode->twidth,CurMode->theight,page)+(col+row*CurMode->twidth)*2; // Write the char - Bit16u segment = curmode->sstart; - real_writeb(segment,address,chr); + PhysPt where = CurMode->pstart+address; + mem_writeb(where,chr); if (useattr) { - real_writeb(segment,address+1,attr); + mem_writeb(where+1,attr); } } + return; + case M_CGA4: + case M_CGA2: + if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; + else { + chr-=128; + fontdata=Real2Host(RealGetVec(0x1F))+(chr)*8; + } break; - case GRAPH: - { - /* Amount of lines */ - Bit8u * fontdata; - Bit16u x,y; - switch (curmode->cheight) { - case 8: -// fontdata=&int10_font_08[chr*8]; - if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; - else fontdata=Real2Host(RealGetVec(0x1F))+(chr-128)*8; - break; - case 14: - fontdata=&int10_font_14[chr*14]; - break; - case 16: - fontdata=&int10_font_16[chr*16]; - break; - default: - LOG(LOG_INT10,LOG_ERROR)("Teletype Illegal Font Height"); - return; - } - x=8*col; - y=curmode->cheight*row; - //TODO Check for out of bounds - for (Bit8u h=0;hcheight;h++) { - Bit8u bitsel=128; - Bit8u bitline=*fontdata++; - Bit16u tx=x; - while (bitsel) { - if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); - else INT10_PutPixel(tx,y,page,attr & 0x80); - tx++; - bitsel>>=1; - } - y++; - } - } + default: + fontdata=Real2Host(RealGetVec(0x43))+chr*real_readw(0x40,BIOSMEM_CHAR_HEIGHT); break; } + x=8*col; + y=CurMode->cheight*row; + //TODO Check for out of bounds + for (Bit8u h=0;hcheight;h++) { + Bit8u bitsel=128; + Bit8u bitline=*fontdata++; + Bit16u tx=x; + while (bitsel) { + if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); + else INT10_PutPixel(tx,y,page,attr & 0x80); + tx++; + bitsel>>=1; + } + y++; + } + } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + 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); @@ -310,8 +343,8 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + if (CurMode->type!=M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); @@ -357,8 +390,8 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + if (CurMode->type!=M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 84b21e05..1370fb0a 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,6 @@ #include "int10.h" -VGAROMAREA int10_romarea; static Bit8u static_functionality[0x10]= { /* 0 */ 0xff, // All modes supported #1 @@ -40,35 +39,67 @@ static Bit8u static_functionality[0x10]= /* f */ 0x00 // reserved }; +static Bit16u map_offset[8]={ + 0x0000,0x4000,0x8000,0xc000, + 0x2000,0x6000,0xa000,0xe000 +}; + +void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { + PhysPt where=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); + IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 + IO_Write(0x3ce,0x6);IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing + for (Bitu i=0;isheight/height)-1); + real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height); + //TODO Reprogram cursor size? + } +} + + + void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ - Bit32u i; - - Bit16u segoff=0; - int10_romarea.font_8_first=RealMake(0xC000,segoff); + Bitu i; + int10.rom.used=2; + real_writew(0xc000,0,0xaa55); + int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,segoff++,int10_font_08[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_08[i]); } - int10_romarea.font_8_second=RealMake(0xC000,segoff); + int10.rom.font_8_second=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,segoff++,int10_font_08[i+128*8]); + real_writeb(0xC000,int10.rom.used++,int10_font_08[i+128*8]); } - int10_romarea.font_14=RealMake(0xC000,segoff); + int10.rom.font_14=RealMake(0xC000,int10.rom.used); for (i=0;i<256*14;i++) { - real_writeb(0xC000,segoff++,int10_font_14[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_14[i]); } - int10_romarea.font_16=RealMake(0xC000,segoff); + int10.rom.font_16=RealMake(0xC000,int10.rom.used); for (i=0;i<256*16;i++) { - real_writeb(0xC000,segoff++,int10_font_16[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_16[i]); } - int10_romarea.static_state=RealMake(0xC000,segoff); + int10.rom.static_state=RealMake(0xC000,int10.rom.used); for (i=0;i<0x10;i++) { - real_writeb(0xC000,segoff++,static_functionality[i]); + real_writeb(0xC000,int10.rom.used++,static_functionality[i]); } MEM_BlockWrite(PhysMake(0xf000,0xfa6e),int10_font_08,128*8); - RealSetVec(0x1F,int10_romarea.font_8_second); + RealSetVec(0x1F,int10.rom.font_8_second); }; diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 2ec9f019..40a8a918 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -73,12 +73,12 @@ struct Dynamic_Functionality { void INT10_GetFuncStateInformation(PhysPt save) { /* set static state pointer */ - mem_writed(save,int10_romarea.static_state); + mem_writed(save,int10.rom.static_state); /* Copy BIOS Segment areas */ Bit16u i; /* First area in Bios Seg */ - for (i=0;i<30;i++) { + for (i=0;i<0x1e;i++) { mem_writeb(save+0x4+i,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE+i)); } /* Second area */ @@ -89,31 +89,27 @@ void INT10_GetFuncStateInformation(PhysPt save) { for (i=0x25;i<0x40;i++) mem_writeb(save+i,0); /* DCC Index */ mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); - VGAMODES * curmode=GetCurrentMode(); - if (!curmode) return; Bit16u col_count=0; - switch (curmode->memmodel) { - case CTEXT: - col_count=2;break; - case MTEXT: + switch (CurMode->type) { + case M_TEXT16: col_count=16;break; - case CGA: - col_count=4;break; - case PLANAR1: + case M_CGA2: col_count=2;break; - case PLANAR2: + case M_CGA4: col_count=4;break; - case PLANAR4: + case M_EGA16: col_count=16;break; - case LINEAR8: + case M_VGA: col_count=256;break; + default: + LOG(LOG_INT10,LOG_ERROR)("Get Func State illegal mode type %d",CurMode->type); } /* Colour count */ mem_writew(save+0x27,col_count); /* Page count */ - mem_writeb(save+0x29,curmode->nbpages); + mem_writeb(save+0x29,CurMode->ptotal); /* scan lines */ - switch (curmode->sheight) { + switch (CurMode->sheight) { case 200: mem_writeb(save+0x2a,0);break; case 350: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 36f0bc87..806ae16a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,20 +1,4 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ +#include #include "dosbox.h" #include "mem.h" @@ -22,113 +6,57 @@ #include "int10.h" #include "mouse.h" -//TODO Maybe also add PCJR Video Modes could be nice :) -//TODO include some credits to bochs/plex86 bios i used for info/tables +#define _HALF_CLOCK 0x0001 +#define _LINE_DOUBLE 0x0002 + +#define SEQ_REGS 0x05 +#define GFX_REGS 0x09 +#define ATT_REGS 0x15 + +VideoModeBlock ModeList[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,special flags */ +{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, +{ 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 }, +{ 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 ,0xB8000 ,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 }, + -VGAMODES vga_modes[MODE_MAX+1]= -{//mode vesa class model pg bits sw sh tw th cw ch sstart slength misc pelm crtc actl gdc sequ dac - {0x00, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x01, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x02, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, - {0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, - {0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, - {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, - {0x06, 0xFFFF, GRAPH, CGA2, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, - {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, - {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x2000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, - {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x4000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, - {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, - {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, - {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, - {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, - {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0xFA00, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03} +{ 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 }, +{ 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 }, +{ 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 ,0 }, + +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,20 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, + + +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, + }; -/* CRTC */ -#define CRTC_MAX_REG 0x18 -#define CRTC_MAX_MODEL 0x09 - -static Bit8u crtc_regs[CRTC_MAX_MODEL+1][CRTC_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */ - /* 00 */ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,0xff}, - /* 01 */ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff}, - /* 02 */ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,0xff}, - /* 03 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,0xff}, - /* 04 */ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,0xff}, - /* 05 */ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,0xff}, - /* 06 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,0xff}, - /* 07 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,0xff}, - /* 08 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,0xff}, - /* 09 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,0xff} -}; - -/* Attribute Controler 0x3c0 */ -#define ACTL_MAX_REG 0x14 -#define ACTL_MAX_MODEL 0x08 - -static Bit8u actl_regs[ACTL_MAX_MODEL+1][ACTL_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */ - /* 00 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00}, - /* 01 */ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x03,0x00,0x00}, - /* 02 */ {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x01,0x00,0x01,0x00,0x00}, - /* 03 */ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0e,0x00,0x0f,0x08,0x00}, - /* 04 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x0f,0x00,0x00}, - /* 05 */ {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x0b,0x00,0x05,0x00,0x00}, - /* 06 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x01,0x00,0x0f,0x00,0x00}, - /* 07 */ {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x01,0x00,0x01,0x00,0x00}, - /* 08 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x41,0x00,0x0f,0x00,0x00} -}; - -/* Sequencer 0x3c4 */ -#define SEQU_MAX_REG 0x04 -#define SEQU_MAX_MODEL 0x06 - -static Bit8u sequ_regs[SEQU_MAX_MODEL+1][SEQU_MAX_REG+1]= -{/* Model 00 01 02 03 04 */ - /* 00 */ {0x03,0x08,0x03,0x00,0x02}, - /* 01 */ {0x03,0x00,0x03,0x00,0x02}, - /* 02 */ {0x03,0x09,0x03,0x00,0x02}, - /* 03 */ {0x03,0x01,0x01,0x00,0x06}, - /* 04 */ {0x03,0x09,0x0f,0x00,0x06}, - /* 05 */ {0x03,0x01,0x0f,0x00,0x06}, - /* 06 */ {0x03,0x01,0x0f,0x00,0x0e} -}; - -/* Graphic ctl 0x3ce */ -#define GRDC_MAX_REG 0x08 -#define GRDC_MAX_MODEL 0x05 - -static Bit8u grdc_regs[GRDC_MAX_MODEL+1][GRDC_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 */ - /* 00 */ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x0f,0xff}, - /* 01 */ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x0f,0xff}, - /* 02 */ {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x0f,0xff}, - /* 03 */ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x0f,0xff}, - /* 04 */ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,0xff}, - /* 05 */ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,0xff} -}; - -/* Default Palette */ -#define DAC_MAX_MODEL 3 - -static Bit8u dac_regs[DAC_MAX_MODEL+1]= -{0x3f,0x3f,0x3f,0xff}; - -/* Mono */ -static Bit8u palette0[63+1][3]= +static Bit8u text_palette[64][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, - {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f} + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, + 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, + 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, + 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, + 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,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 }; -static Bit8u palette1[63+1][3]= +static Bit8u ega_palette[64][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}, {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, @@ -140,220 +68,415 @@ static Bit8u palette1[63+1][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} }; -static Bit8u palette2[63+1][3]= + +static Bit8u vga_palette[256][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x2a,0x00}, {0x2a,0x2a,0x2a}, - {0x00,0x00,0x15}, {0x00,0x00,0x3f}, {0x00,0x2a,0x15}, {0x00,0x2a,0x3f}, {0x2a,0x00,0x15}, {0x2a,0x00,0x3f}, {0x2a,0x2a,0x15}, {0x2a,0x2a,0x3f}, - {0x00,0x15,0x00}, {0x00,0x15,0x2a}, {0x00,0x3f,0x00}, {0x00,0x3f,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x15,0x2a}, {0x2a,0x3f,0x00}, {0x2a,0x3f,0x2a}, - {0x00,0x15,0x15}, {0x00,0x15,0x3f}, {0x00,0x3f,0x15}, {0x00,0x3f,0x3f}, {0x2a,0x15,0x15}, {0x2a,0x15,0x3f}, {0x2a,0x3f,0x15}, {0x2a,0x3f,0x3f}, - {0x15,0x00,0x00}, {0x15,0x00,0x2a}, {0x15,0x2a,0x00}, {0x15,0x2a,0x2a}, {0x3f,0x00,0x00}, {0x3f,0x00,0x2a}, {0x3f,0x2a,0x00}, {0x3f,0x2a,0x2a}, - {0x15,0x00,0x15}, {0x15,0x00,0x3f}, {0x15,0x2a,0x15}, {0x15,0x2a,0x3f}, {0x3f,0x00,0x15}, {0x3f,0x00,0x3f}, {0x3f,0x2a,0x15}, {0x3f,0x2a,0x3f}, - {0x15,0x15,0x00}, {0x15,0x15,0x2a}, {0x15,0x3f,0x00}, {0x15,0x3f,0x2a}, {0x3f,0x15,0x00}, {0x3f,0x15,0x2a}, {0x3f,0x3f,0x00}, {0x3f,0x3f,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} + 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, + 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, + 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, + 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, + 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, + 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, + 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + + 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, + 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, + 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, + 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, + 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, + 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, + 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, + 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + + 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, + 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, + 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, + 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, + 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, + 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, + 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, + 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + + 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, + 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, + 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, + 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, + 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, + 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, + 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 }; -static Bit8u palette3[256][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}, - {0x00,0x00,0x00}, {0x05,0x05,0x05}, {0x08,0x08,0x08}, {0x0b,0x0b,0x0b}, {0x0e,0x0e,0x0e}, {0x11,0x11,0x11}, {0x14,0x14,0x14}, {0x18,0x18,0x18}, - {0x1c,0x1c,0x1c}, {0x20,0x20,0x20}, {0x24,0x24,0x24}, {0x28,0x28,0x28}, {0x2d,0x2d,0x2d}, {0x32,0x32,0x32}, {0x38,0x38,0x38}, {0x3f,0x3f,0x3f}, - {0x00,0x00,0x3f}, {0x10,0x00,0x3f}, {0x1f,0x00,0x3f}, {0x2f,0x00,0x3f}, {0x3f,0x00,0x3f}, {0x3f,0x00,0x2f}, {0x3f,0x00,0x1f}, {0x3f,0x00,0x10}, - {0x3f,0x00,0x00}, {0x3f,0x10,0x00}, {0x3f,0x1f,0x00}, {0x3f,0x2f,0x00}, {0x3f,0x3f,0x00}, {0x2f,0x3f,0x00}, {0x1f,0x3f,0x00}, {0x10,0x3f,0x00}, - {0x00,0x3f,0x00}, {0x00,0x3f,0x10}, {0x00,0x3f,0x1f}, {0x00,0x3f,0x2f}, {0x00,0x3f,0x3f}, {0x00,0x2f,0x3f}, {0x00,0x1f,0x3f}, {0x00,0x10,0x3f}, - {0x1f,0x1f,0x3f}, {0x27,0x1f,0x3f}, {0x2f,0x1f,0x3f}, {0x37,0x1f,0x3f}, {0x3f,0x1f,0x3f}, {0x3f,0x1f,0x37}, {0x3f,0x1f,0x2f}, {0x3f,0x1f,0x27}, +VideoModeBlock * CurMode; - {0x3f,0x1f,0x1f}, {0x3f,0x27,0x1f}, {0x3f,0x2f,0x1f}, {0x3f,0x37,0x1f}, {0x3f,0x3f,0x1f}, {0x37,0x3f,0x1f}, {0x2f,0x3f,0x1f}, {0x27,0x3f,0x1f}, - {0x1f,0x3f,0x1f}, {0x1f,0x3f,0x27}, {0x1f,0x3f,0x2f}, {0x1f,0x3f,0x37}, {0x1f,0x3f,0x3f}, {0x1f,0x37,0x3f}, {0x1f,0x2f,0x3f}, {0x1f,0x27,0x3f}, - {0x2d,0x2d,0x3f}, {0x31,0x2d,0x3f}, {0x36,0x2d,0x3f}, {0x3a,0x2d,0x3f}, {0x3f,0x2d,0x3f}, {0x3f,0x2d,0x3a}, {0x3f,0x2d,0x36}, {0x3f,0x2d,0x31}, - {0x3f,0x2d,0x2d}, {0x3f,0x31,0x2d}, {0x3f,0x36,0x2d}, {0x3f,0x3a,0x2d}, {0x3f,0x3f,0x2d}, {0x3a,0x3f,0x2d}, {0x36,0x3f,0x2d}, {0x31,0x3f,0x2d}, - {0x2d,0x3f,0x2d}, {0x2d,0x3f,0x31}, {0x2d,0x3f,0x36}, {0x2d,0x3f,0x3a}, {0x2d,0x3f,0x3f}, {0x2d,0x3a,0x3f}, {0x2d,0x36,0x3f}, {0x2d,0x31,0x3f}, - {0x00,0x00,0x1c}, {0x07,0x00,0x1c}, {0x0e,0x00,0x1c}, {0x15,0x00,0x1c}, {0x1c,0x00,0x1c}, {0x1c,0x00,0x15}, {0x1c,0x00,0x0e}, {0x1c,0x00,0x07}, - {0x1c,0x00,0x00}, {0x1c,0x07,0x00}, {0x1c,0x0e,0x00}, {0x1c,0x15,0x00}, {0x1c,0x1c,0x00}, {0x15,0x1c,0x00}, {0x0e,0x1c,0x00}, {0x07,0x1c,0x00}, - {0x00,0x1c,0x00}, {0x00,0x1c,0x07}, {0x00,0x1c,0x0e}, {0x00,0x1c,0x15}, {0x00,0x1c,0x1c}, {0x00,0x15,0x1c}, {0x00,0x0e,0x1c}, {0x00,0x07,0x1c}, - - {0x0e,0x0e,0x1c}, {0x11,0x0e,0x1c}, {0x15,0x0e,0x1c}, {0x18,0x0e,0x1c}, {0x1c,0x0e,0x1c}, {0x1c,0x0e,0x18}, {0x1c,0x0e,0x15}, {0x1c,0x0e,0x11}, - {0x1c,0x0e,0x0e}, {0x1c,0x11,0x0e}, {0x1c,0x15,0x0e}, {0x1c,0x18,0x0e}, {0x1c,0x1c,0x0e}, {0x18,0x1c,0x0e}, {0x15,0x1c,0x0e}, {0x11,0x1c,0x0e}, - {0x0e,0x1c,0x0e}, {0x0e,0x1c,0x11}, {0x0e,0x1c,0x15}, {0x0e,0x1c,0x18}, {0x0e,0x1c,0x1c}, {0x0e,0x18,0x1c}, {0x0e,0x15,0x1c}, {0x0e,0x11,0x1c}, - {0x14,0x14,0x1c}, {0x16,0x14,0x1c}, {0x18,0x14,0x1c}, {0x1a,0x14,0x1c}, {0x1c,0x14,0x1c}, {0x1c,0x14,0x1a}, {0x1c,0x14,0x18}, {0x1c,0x14,0x16}, - {0x1c,0x14,0x14}, {0x1c,0x16,0x14}, {0x1c,0x18,0x14}, {0x1c,0x1a,0x14}, {0x1c,0x1c,0x14}, {0x1a,0x1c,0x14}, {0x18,0x1c,0x14}, {0x16,0x1c,0x14}, - {0x14,0x1c,0x14}, {0x14,0x1c,0x16}, {0x14,0x1c,0x18}, {0x14,0x1c,0x1a}, {0x14,0x1c,0x1c}, {0x14,0x1a,0x1c}, {0x14,0x18,0x1c}, {0x14,0x16,0x1c}, - {0x00,0x00,0x10}, {0x04,0x00,0x10}, {0x08,0x00,0x10}, {0x0c,0x00,0x10}, {0x10,0x00,0x10}, {0x10,0x00,0x0c}, {0x10,0x00,0x08}, {0x10,0x00,0x04}, - {0x10,0x00,0x00}, {0x10,0x04,0x00}, {0x10,0x08,0x00}, {0x10,0x0c,0x00}, {0x10,0x10,0x00}, {0x0c,0x10,0x00}, {0x08,0x10,0x00}, {0x04,0x10,0x00}, - - {0x00,0x10,0x00}, {0x00,0x10,0x04}, {0x00,0x10,0x08}, {0x00,0x10,0x0c}, {0x00,0x10,0x10}, {0x00,0x0c,0x10}, {0x00,0x08,0x10}, {0x00,0x04,0x10}, - {0x08,0x08,0x10}, {0x0a,0x08,0x10}, {0x0c,0x08,0x10}, {0x0e,0x08,0x10}, {0x10,0x08,0x10}, {0x10,0x08,0x0e}, {0x10,0x08,0x0c}, {0x10,0x08,0x0a}, - {0x10,0x08,0x08}, {0x10,0x0a,0x08}, {0x10,0x0c,0x08}, {0x10,0x0e,0x08}, {0x10,0x10,0x08}, {0x0e,0x10,0x08}, {0x0c,0x10,0x08}, {0x0a,0x10,0x08}, - {0x08,0x10,0x08}, {0x08,0x10,0x0a}, {0x08,0x10,0x0c}, {0x08,0x10,0x0e}, {0x08,0x10,0x10}, {0x08,0x0e,0x10}, {0x08,0x0c,0x10}, {0x08,0x0a,0x10}, - {0x0b,0x0b,0x10}, {0x0c,0x0b,0x10}, {0x0d,0x0b,0x10}, {0x0f,0x0b,0x10}, {0x10,0x0b,0x10}, {0x10,0x0b,0x0f}, {0x10,0x0b,0x0d}, {0x10,0x0b,0x0c}, - {0x10,0x0b,0x0b}, {0x10,0x0c,0x0b}, {0x10,0x0d,0x0b}, {0x10,0x0f,0x0b}, {0x10,0x10,0x0b}, {0x0f,0x10,0x0b}, {0x0d,0x10,0x0b}, {0x0c,0x10,0x0b}, - {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} -}; - -static Bit8u FindVideoMode(Bit8u mode) { - Bit8u line=0xff; - for(Bit8u i=0;i<=MODE_MAX;i++) { - if(vga_modes[i].svgamode==mode) { - line=i; - break; - } - } - return line; - -} - -VGAMODES * GetCurrentMode(void) { - Bit8u mode=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127; - if (mode==int10.mode) return int10.entry; - int10.mode=mode; - int10.entry=&vga_modes[FindVideoMode(mode)]; - return int10.entry; -} +bool INT10_SetVideoMode(Bitu mode) { -void INT10_SetVideoMode(Bit8u mode) { - - bool clearmem=(mode & 128)==0; - Bit8u *palette; - Bit16u i,twidth,theight,cheight; + bool clearmem=true; Bit8u modeset_ctl,video_ctl,vga_switches; Bit16u crtc_addr; - Bit8u line; - mode&=mode & 127; - line=FindVideoMode(mode); - if (line==0xff) { - LOG(LOG_INT10,LOG_ERROR)("INT10:Trying to set non supported video mode %X",mode); - return; + if (mode<256) { + if (mode & 128) { + clearmem=false; + mode-=128; + } + } else { + /* Check for special vesa mode bits */ + mode&=0xfff; } - - twidth=vga_modes[line].twidth; - theight=vga_modes[line].theight; - cheight=vga_modes[line].cheight; - - // Read the bios vga control + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + Bitu i=0; + while (ModeList[i].mode!=0xffff) { + if (ModeList[i].mode==mode) goto foundmode; + i++; + } + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; +foundmode: + CurMode=&ModeList[i]; + + /* First read mode setup settings from bios area */ video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); - - // Read the bios vga switches vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); - - // Read the bios mode set control modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + /* Setup the VGA to the correct mode */ + VGA_SetMode(CurMode->type); - - /* Reset Attribute ctl into address mode just to be safe */ - - IO_Read(VGAREG_ACTL_RESET); - // Set the High Attribute Ctl - for(i=0x10;i<=ACTL_MAX_REG;i++) { - IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + /* Setup MISC Output Register */ + Bit8u misc_output=0x3; //Color and cpu memory access + /* Program Sequencer */ + Bit8u seq_data[SEQ_REGS]; + memset(seq_data,0,SEQ_REGS); + seq_data[1]|=1; //8 dot fonts by default + seq_data[1]|= //Check for half clock + (CurMode->special & _HALF_CLOCK) ? 0x08 : 0x00; + seq_data[4]|=0x02; //More than 64kb + switch (CurMode->type) { + case M_TEXT16: + seq_data[2]|=0x3; //Enable plane 0 and 1 + seq_data[4]|=0x05; //Alpanumeric and odd/even enabled + break; + case M_EGA16: + seq_data[2]|=0xf; //Enable all planes for writing + break; + case M_LIN8: //Seems to have the same reg layout from testing + case M_VGA: + seq_data[2]|=0xf; //Enable all planes for writing + seq_data[4]|=0xc; //Graphics - odd/even - Chained + break; } - // Set Sequencer Ctl - for(i=0;i<=SEQU_MAX_REG;i++) { - IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]); + for (i=0;ihtotal-5); + hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8; + /* Horizontal Display End */ + IO_Write(0x3d4,0x01);IO_Write(0x3d5,CurMode->hdispend-1); + hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7; + /* Start horizontal Blanking */ + IO_Write(0x3d4,0x02);IO_Write(0x3d5,CurMode->hdispend); + hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; + /* End horizontal Blanking */ + Bitu blank_end; + if (CurMode->special & _HALF_CLOCK) { + blank_end = (CurMode->htotal-1) & 0x7f; + } else { + blank_end = (CurMode->htotal-2) & 0x7f; } + IO_Write(0x3d4,0x03);IO_Write(0x3d5,0x80|(blank_end & 0x1f)); +// hor_overflow|=(blank_end & 0x40) >> 3; - // Set the misc register - IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg); - - // Enable video - IO_Write(VGAREG_ACTL_ADDRESS,0x20); - IO_Read(VGAREG_ACTL_RESET); - - //Set the palette - if ((modeset_ctl&0x08)==0x8) LOG(LOG_INT10,LOG_NORMAL)("Mode set without palette"); - if((modeset_ctl&0x08)==0) { - // Set the PEL mask - IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); - // Set the whole dac always, from 0 - IO_Write(VGAREG_DAC_WRITE_ADDRESS,0x00); - // From which palette - switch(vga_modes[line].dacmodel) { - case 0: - palette=(Bit8u*)&palette0; - break; - case 1: - palette=(Bit8u*)&palette1; - break; - case 2: - palette=(Bit8u*)&palette2; - break; - case 3: - palette=(Bit8u*)&palette3; - break; - default: - palette=(Bit8u*)&palette0;/*for gcc*/ - E_Exit("INT10: palette error in setvidmode"); - break; - } - // Set the actual palette - for (i=0;i<256;i++) { - if (i<=dac_regs[vga_modes[line].dacmodel]) { - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+0]); - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+1]); - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+2]); - } else { - IO_Write(VGAREG_DAC_DATA,0); - IO_Write(VGAREG_DAC_DATA,0); - IO_Write(VGAREG_DAC_DATA,0); - } - } + /* Start Horizontal Retrace */ + Bitu ret_start; + if (CurMode->special & _HALF_CLOCK) { + ret_start = (CurMode->hdispend+2); + } else { + ret_start = (CurMode->hdispend+4); } - - IO_Read(VGAREG_ACTL_RESET); - // Set the Low Attribute Ctl - for(i=0;i<=0xf;i++) { - IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + IO_Write(0x3d4,0x04);IO_Write(0x3d5,ret_start); + hor_overflow|=(ret_start & 0x100) >> 4; + /* End Horizontal Retrace */ + Bitu ret_end; + if (CurMode->special & _HALF_CLOCK) { + ret_end = (CurMode->htotal-2) & 0x3f; + } else { + ret_end = (CurMode->htotal-4) & 0x3f; } + IO_Write(0x3d4,0x05);IO_Write(0x3d5,(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)); + overflow|=((CurMode->vtotal-2) & 0x100) >> 8; + overflow|=((CurMode->vtotal-2) & 0x200) >> 4; + ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; +/* + These aren't exactly accurate i think, + Should be more like a certain percentage based on vertical total + So you get same sized borders, but okay :) + */ + /* Vertical Retrace Start */ + IO_Write(0x3d4,0x10);IO_Write(0x3d5,(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); + + /* Vertical Display End */ + IO_Write(0x3d4,0x12);IO_Write(0x3d5,(CurMode->vdispend-1)); + overflow|=((CurMode->vdispend-1) & 0x100) >> 7; + overflow|=((CurMode->vdispend-1) & 0x200) >> 3; + ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; - Bit32u tel; - if(clearmem) { - if(vga_modes[line].type==TEXT) { - PhysPt dest=PhysMake(vga_modes[line].sstart,0); - for (tel=0;tel<0x4000;tel++) { - mem_writew(dest,0x0720); - dest+=2; + /* Vertical Blank Start */ + IO_Write(0x3d4,0x15);IO_Write(0x3d5,(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)); + /* Line Compare */ + Bitu line_compare=CurMode->vtotal+1; //Out of range + IO_Write(0x3d4,0x18);IO_Write(0x3d5,line_compare&0xff); + overflow|=(line_compare & 0x100) >> 4; + max_scanline|=(line_compare & 0x200) >> 3; + ver_overflow|=(line_compare & 0x400) >> 4; + Bit8u underline=0; + /* Maximum scanline / Underline Location */ + if (CurMode->special & _LINE_DOUBLE) max_scanline|=0x80; + switch (CurMode->type) { + case M_TEXT16: + max_scanline|=CurMode->theight-1; + underline=0x1f; + break; + case M_VGA: + underline=0x40; + max_scanline|=1; //Vga doesn't use double line but this + break; + case M_LIN8: + underline=0x60; //Seems to enable the every 4th clock on my s3 + break; + } + IO_Write(0x3d4,0x09);IO_Write(0x3d5,max_scanline); + IO_Write(0x3d4,0x14);IO_Write(0x3d5,underline); + + /* OverFlow */ + IO_Write(0x3d4,0x07);IO_Write(0x3d5,overflow); + /* Extended Horizontal Overflow */ + IO_Write(0x3d4,0x5d);IO_Write(0x3d5,hor_overflow); + /* Extended Vertical Overflow */ + IO_Write(0x3d4,0x5e);IO_Write(0x3d5,ver_overflow); + /* Offset Register */ + IO_Write(0x3d4,0x13); + switch (CurMode->type) { + case M_LIN8: + IO_Write(0x3d5,CurMode->swidth/8); + break; + default: + IO_Write(0x3d5,CurMode->hdispend/2); + } + /* Mode Control */ + Bit8u mode_control=0; + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + mode_control=0xa2; + break; + case M_EGA16: + mode_control=0xe3; + break; + case M_TEXT16: + case M_VGA: + mode_control=0xa3; + break; + case M_LIN8: + mode_control=0xab; + break; + + } + IO_Write(0x3d4,0x17);IO_Write(0x3d5,mode_control); + /* Renable write protection */ + IO_Write(0x3d4,0x11); + IO_Write(0x3d5,IO_Read(0x3d5)|0x80); + /* Setup the correct clock */ + if (CurMode->mode<0x100) { + //Stick to 25mhz clock for now + } else { + misc_output|=0xef; //Select clock 3 + Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; + VGA_SetClock(3,clock/1000); + } + /* Write Misc Output */ + IO_Write(0x3c2,misc_output); + + /* Program Graphics controller */ + Bit8u gfx_data[GFX_REGS]; + memset(gfx_data,0,GFX_REGS); + gfx_data[0x7]=0xf; /* Color don't care */ + gfx_data[0x8]=0xff; /* BitMask */ + switch (CurMode->type) { + case M_TEXT16: + gfx_data[0x5]|=0x10; //Odd-Even Mode + gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbffff + break; + case M_LIN8: + case M_VGA: + gfx_data[0x5]|=0x40; //256 color mode + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + case M_EGA16: + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + case M_CGA4: + gfx_data[0x5]|=0x20; //CGA mode + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + } + for (i=0;itype) { + case M_EGA16: + if (CurMode->mode>0xe) goto att_text16; + case M_TANDY16: + att_data[0x10]=0x01; //Color Graphics + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; + } + break; + 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 +att_text16: + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; + } + break; + case M_CGA2: + case M_CGA4: + IO_Write(0x3d9,0x20); //Setup using CGA color select register + goto skipatt; + case M_VGA: + case M_LIN8: + for (i=0;i<16;i++) { + att_data[i]=i; + } + att_data[0x10]=0x41; //Color Graphics 8-bit + break; + } + + IO_Read(0x3da); + for (i=0;itype) { + case M_EGA16: + if (CurMode->mode>0xe) goto dac_text16; + case M_CGA2: + case M_CGA4: + case M_TANDY16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,ega_palette[i][0]); + IO_Write(0x3c9,ega_palette[i][1]); + IO_Write(0x3c9,ega_palette[i][2]); + } + break; + case M_TEXT16: +dac_text16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,text_palette[i][0]); + IO_Write(0x3c9,text_palette[i][1]); + IO_Write(0x3c9,text_palette[i][2]); + } + break; + case M_VGA: + case M_LIN8: + for (i=0;i<256;i++) { + IO_Write(0x3c9,vga_palette[i][0]); + IO_Write(0x3c9,vga_palette[i][1]); + IO_Write(0x3c9,vga_palette[i][2]); + } + break; + } + /* Setup registers for special video modes */ + switch (CurMode->type) { + case M_TANDY16: + IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 + break; + } + /* 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 + + /* Load text mode font */ + if (CurMode->type==M_TEXT16) { + INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + } + /* Clear video memory if needs be */ + if (clearmem) { + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0000); } - } else { - PhysPt dest=PhysMake(0xb800,0); - for (tel=0;tel<0x4000;tel++) { - mem_writew(dest,0x0000); - dest+=2; + break; + case M_TEXT16: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0700); } - dest=PhysMake(0xa000,0); - for (tel=0;tel<0x8000;tel++) { - mem_writew(dest,0x0000); - dest+=2; + break; + case M_EGA16: + case M_VGA: + for (i=0;i<64*1024;i++) { + real_writeb(0xa000,i,0x00); } - // FIXME should handle gfx mode + break; } } - // Set the BIOS mem - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode|((!clearmem) << 7)); - real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); - real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,vga_modes[line].slength); + /* 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_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theight-1); - real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); + 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))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); @@ -368,27 +491,23 @@ void INT10_SetVideoMode(Bit8u mode) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... // Set cursor shape - if(vga_modes[line].type==TEXT) { -//TODO cursor shape biosfn_set_cursor_shape(0x06,0x07); + if(CurMode->type==M_TEXT16) { + INT10_SetCursorShape(0x06,07); } // Set cursor pos for page 0..7 for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); // Set active page 0 INT10_SetActivePage(0); /* Set some interrupt vectors */ - RealSetVec(0x43,int10_romarea.font_8_first); + switch (CurMode->cheight) { + case 8:RealSetVec(0x43,int10.rom.font_8_first);break; + case 14:RealSetVec(0x43,int10.rom.font_14);break; + case 16:RealSetVec(0x43,int10.rom.font_16);break; + } /* Tell mouse resolution change */ - Mouse_SetResolution(vga_modes[line].swidth,vga_modes[line].sheight); -}; + Mouse_NewVideoMode(); + return true; +} + + -void INT10_SetGfxControllerToDefault() -// reset gfx controller to default values -// needed for drawing mouse pointer -{ - Bit8u line=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127); - // Set Grafx Ctl - for(Bit8u i=0;i<=GRDC_MAX_REG;i++) { - IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); - } -}; \ No newline at end of file diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index c73553a4..2563e30b 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -29,6 +29,7 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { IO_Write(VGAREG_ACTL_ADDRESS,reg); IO_Write(VGAREG_ACTL_WRITE_DATA,val); } + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } @@ -36,6 +37,7 @@ void INT10_SetOverscanBorderColor(Bit8u val) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,val); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_SetAllPaletteRegisters(PhysPt data) { @@ -49,6 +51,7 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { // Then the border IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_ToggleBlinkingBit(Bit8u state) { @@ -64,19 +67,20 @@ void INT10_ToggleBlinkingBit(Bit8u state) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x10); IO_Write(VGAREG_ACTL_WRITE_DATA,value); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { if(reg<=ACTL_MAX_REG) { IO_Read(VGAREG_ACTL_RESET); - IO_Write(VGAREG_ACTL_ADDRESS,reg); + IO_Write(VGAREG_ACTL_ADDRESS,reg+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); } } void INT10_GetOverscanBorderColor(Bit8u * val) { IO_Read(VGAREG_ACTL_RESET); - IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); } @@ -89,7 +93,7 @@ void INT10_GetAllPaletteRegisters(PhysPt data) { data++; } // Then the border - IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); } @@ -123,4 +127,46 @@ void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) { mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); } -}; +} + +void INT10_SelectDACPage(Bit8u function,Bit8u mode) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + Bit8u old10=IO_Read(VGAREG_ACTL_READ_DATA); + if (!function) { //Select paging mode + if (mode) old10|=0x80; + else old10&=0x7f; + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + IO_Write(VGAREG_ACTL_WRITE_DATA,old10); + } else { //Select page + if (!(old10 & 0x80)) mode<<=2; + mode&=0xf; + IO_Write(VGAREG_ACTL_ADDRESS,0x14); + IO_Write(VGAREG_ACTL_WRITE_DATA,mode); + } + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette +} + +void INT10_SetPelMask(Bit8u mask) { + IO_Write(VGAREG_PEL_MASK,mask); +} + +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); +} + +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); +} + diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 22e40ac2..efa0a336 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -25,9 +25,8 @@ static Bit8u cga_masks[4]={~192,~48,~12,~3}; static Bit8u cga_masks2[8]={~128,~64,~32,~16,~8,~4,~2,~1}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { - case CGA: + switch (CurMode->type) { + case M_CGA4: { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; @@ -41,7 +40,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case CGA2: + case M_CGA2: { Bit16u off=(y>>1)*80+(x>>3); if (y&1) off+=8*1024; @@ -55,7 +54,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case PLANAR4: + case M_EGA16: { /* Set the correct bitmask for the pixel position */ IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask); @@ -67,7 +66,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x18); } //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); + PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); /* Bitmask and set/reset should do the rest */ mem_readb(off); mem_writeb(off,0xff); @@ -78,23 +77,18 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; } - case LINEAR8: + case M_VGA: mem_writeb(Real2Phys(RealMake(0xa000,y*320+x)),color); break; - case PLANAR1: - case PLANAR2: - case CTEXT: - case MTEXT: default: - LOG(LOG_INT10,LOG_ERROR)("PutPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); break; } } void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { - case CGA: + switch (CurMode->type) { + case M_CGA4: { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; @@ -102,7 +96,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((3-x&3))*2)) & 3 ; } break; - case CGA2: + case M_CGA2: { Bit16u off=(y>>1)*80+(x>>3); if (y&1) off+=8*1024; @@ -110,10 +104,10 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((7-x&7)))) & 1 ; } break; - case PLANAR4: + case M_EGA16: { /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); + PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); Bitu shift=7-(x & 7); /* Set the read map */ *color=0; @@ -127,15 +121,11 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color|=((mem_readb(off)>>shift) & 1) << 3; break; } - case LINEAR8: + case M_VGA: *color=mem_readb(PhysMake(0xa000,320*y+x)); break; - case PLANAR1: - case PLANAR2: - case CTEXT: - case MTEXT: default: - LOG(LOG_INT10,LOG_ERROR)("GetPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("GetPixel unhandled mode type %d",CurMode->type); break; } }