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
This commit is contained in:
parent
97e1c2dc42
commit
4e18ea92f4
7 changed files with 237 additions and 110 deletions
|
@ -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);
|
||||
|
|
|
@ -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;i<cheight/2;i++) {
|
||||
for (Bitu i=0;i<cheight/2U;i++) {
|
||||
MEM_BlockCopy(dest,src,copy);
|
||||
MEM_BlockCopy(dest+8*1024,src+8*1024,copy);
|
||||
dest+=nextline;src+=nextline;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void TANDY16_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/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;i<cheight/2U;i++) {
|
||||
MEM_BlockCopy(dest,src,copy);
|
||||
MEM_BlockCopy(dest+8*1024,src+8*1024,copy);
|
||||
MEM_BlockCopy(dest+16*1024,src+16*1024,copy);
|
||||
MEM_BlockCopy(dest+24*1024,src+24*1024,copy);
|
||||
dest+=nextline;src+=nextline;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) {
|
||||
PhysPt src,dest;Bitu copy;
|
||||
Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||
|
@ -66,11 +80,12 @@ static INLINE void TEXT_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,P
|
|||
MEM_BlockCopy(dest,src,(cright-cleft)*2);
|
||||
}
|
||||
|
||||
static INLINE void CGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) {
|
||||
static INLINE void CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) {
|
||||
Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||
PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft)*2;
|
||||
Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2;
|
||||
for (Bitu i=0;i<cheight/2;i++) {
|
||||
attr=(attr & 0x3) | ((attr & 0x3) << 2) | ((attr & 0x3) << 4) | ((attr & 0x3) << 6);
|
||||
for (Bitu i=0;i<cheight/2U;i++) {
|
||||
for (Bitu x=0;x<copy;x++) {
|
||||
mem_writeb(dest+x,attr);
|
||||
mem_writeb(dest+8*1024+x,attr);
|
||||
|
@ -79,6 +94,24 @@ static INLINE void CGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bi
|
|||
}
|
||||
}
|
||||
|
||||
static INLINE void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) {
|
||||
Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||
PhysPt dest=base+((CurMode->twidth*row)*cheight+cleft)*4;
|
||||
Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4;
|
||||
attr=(attr & 0xf) | (attr & 0xf) << 4;
|
||||
for (Bitu i=0;i<cheight/4U;i++) {
|
||||
for (Bitu x=0;x<copy;x++) {
|
||||
mem_writeb(dest+x,attr);
|
||||
mem_writeb(dest+8*1024+x,attr);
|
||||
mem_writeb(dest+16*1024+x,attr);
|
||||
mem_writeb(dest+24*1024+x,attr);
|
||||
}
|
||||
dest+=nextline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static INLINE void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) {
|
||||
/* Set Bitmask / Color / Full Set Reset */
|
||||
IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff);
|
||||
|
@ -112,7 +145,7 @@ static INLINE void TEXT_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B
|
|||
|
||||
void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) {
|
||||
/* Do some range checking */
|
||||
if (CurMode->type!=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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;i<ATT_REGS;i++) {
|
||||
IO_Write(0x3c0,i);
|
||||
IO_Write(0x3c0,att_data[i]);
|
||||
|
@ -406,12 +440,13 @@ skipatt:
|
|||
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]);
|
||||
for (i=0;i<16;i++) {
|
||||
IO_Write(0x3c9,cga_palette[i][0]);
|
||||
IO_Write(0x3c9,cga_palette[i][1]);
|
||||
IO_Write(0x3c9,cga_palette[i][2]);
|
||||
}
|
||||
break;
|
||||
case M_TEXT2:
|
||||
case M_TEXT16:
|
||||
dac_text16:
|
||||
for (i=0;i<64;i++) {
|
||||
|
@ -429,29 +464,53 @@ dac_text16:
|
|||
}
|
||||
break;
|
||||
}
|
||||
/* Setup registers for special video modes */
|
||||
/* Setup some special stuff for different modes */
|
||||
Bit8u feature=real_readb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE);
|
||||
switch (CurMode->type) {
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue