Updated vga screen updates routines.
correct frame per second, corrected dac read/write index added support for split screen. Some more fixes i forgot Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@591
This commit is contained in:
parent
f1fd4ae696
commit
d54ae0640b
10 changed files with 255 additions and 189 deletions
|
@ -40,13 +40,72 @@ Bit32u FillTable[16]={
|
|||
};
|
||||
|
||||
|
||||
static void VGA_BlankTimer(void) {
|
||||
PIC_AddEvent(&VGA_BlankTimer,vga.draw.blank);
|
||||
Bit8u * buf,* bufsplit;
|
||||
/* Draw the current frame */
|
||||
if (!vga.draw.resizing && RENDER_StartUpdate()) {
|
||||
if (vga.config.line_compare<vga.draw.lines) {
|
||||
Bitu stop=vga.config.line_compare;
|
||||
if (vga.draw.double_height) stop/=2;
|
||||
if (stop>=vga.draw.height){
|
||||
LOG_VGA("Split at %d",stop);
|
||||
goto drawnormal;
|
||||
}
|
||||
switch (vga.mode) {
|
||||
case GFX_16:
|
||||
buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning];
|
||||
bufsplit=vga.buffer;
|
||||
break;
|
||||
case GFX_256U:
|
||||
buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2];
|
||||
bufsplit=vga.mem.linear;
|
||||
break;
|
||||
case GFX_256C:
|
||||
buf=memory+0xa0000;
|
||||
bufsplit=memory+0xa0000;
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("VGA:Unhandled split screen mode %d",vga.mode);
|
||||
goto norender;
|
||||
}
|
||||
RENDER_Part(buf,0,0,vga.draw.width,stop);
|
||||
RENDER_Part(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop);
|
||||
} else {
|
||||
drawnormal:
|
||||
switch (vga.mode) {
|
||||
case GFX_2:
|
||||
VGA_DrawGFX2_Fast(vga.buffer,vga.draw.width);
|
||||
buf=vga.buffer;
|
||||
break;
|
||||
case GFX_4:
|
||||
VGA_DrawGFX4_Fast(vga.buffer,vga.draw.width);
|
||||
buf=vga.buffer;
|
||||
break;
|
||||
case TEXT_16:
|
||||
VGA_DrawTEXT(vga.buffer,vga.draw.width);
|
||||
buf=vga.buffer;
|
||||
break;
|
||||
case GFX_16:
|
||||
buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning];
|
||||
break;
|
||||
case GFX_256C:
|
||||
buf=memory+0xa0000;
|
||||
break;
|
||||
case GFX_256U:
|
||||
buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2];
|
||||
break;
|
||||
}
|
||||
RENDER_Part(buf,0,0,vga.draw.width,vga.draw.height);
|
||||
|
||||
void VGA_Render_GFX_2(Bit8u * * data);
|
||||
void VGA_Render_GFX_4(Bit8u * * data);
|
||||
void VGA_Render_GFX_16(Bit8u * * data);
|
||||
void VGA_Render_GFX_256C(Bit8u * * data);
|
||||
void VGA_Render_GFX_256U(Bit8u * * data);
|
||||
void VGA_Render_TEXT_16(Bit8u * * data);
|
||||
|
||||
}
|
||||
norender:
|
||||
RENDER_EndUpdate();
|
||||
|
||||
}
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_FindSettings(void) {
|
||||
/* Sets up the correct memory handler from the vga.mode setting */
|
||||
|
@ -67,8 +126,10 @@ void VGA_FindSettings(void) {
|
|||
} else if (vga.config.cga_enabled) {
|
||||
/* 4 color cga */
|
||||
//TODO Detect hercules modes, probably set them up in bios too
|
||||
if (vga.config.pixel_double) vga.mode=GFX_4;
|
||||
else vga.mode=GFX_2;
|
||||
if (vga.seq.clocking_mode & 0x8) {
|
||||
vga.mode=GFX_4;
|
||||
// MEM_SetupPageHandlers(PAGE_COUNT(0x0b8000),PAGE_COUNT(0x10000),&VGA_GFX_4_ReadHandler,&VGA_GFX_4_WriteHandler);
|
||||
} else vga.mode=GFX_2;
|
||||
//TODO Maybe also use a page handler for cga mode
|
||||
} else {
|
||||
/* 16 color ega */
|
||||
|
@ -83,70 +144,96 @@ void VGA_FindSettings(void) {
|
|||
}
|
||||
|
||||
static void VGA_DoResize(void) {
|
||||
vga.draw.resizing=false;
|
||||
Bitu width,height,pitch;
|
||||
RENDER_Handler * renderer;
|
||||
/* Calculate the FPS for this screen */
|
||||
double fps;
|
||||
Bitu vtotal=2 + (vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) );
|
||||
Bitu htotal=5 + vga.crtc.horizontal_total;
|
||||
Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) );
|
||||
Bitu hdispend = 1 + (vga.crtc.horizontal_display_end);
|
||||
//TODO Maybe check if blanking comes before display_end
|
||||
|
||||
height=vga.config.vdisplayend+1;
|
||||
if (vga.config.vline_height>0) {
|
||||
height/=(vga.config.vline_height+1);
|
||||
}
|
||||
if (vga.config.vline_double) height>>=1;
|
||||
width=vga.config.hdisplayend;
|
||||
double clock=(double)vga.config.clock;
|
||||
/* Check for 8 for 9 character clock mode */
|
||||
if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9;
|
||||
/* Check for pixel doubling, master clock/2 */
|
||||
if (vga.seq.clocking_mode & 0x8) clock/=2;
|
||||
|
||||
LOG_VGA("H total %d, V Total %d",htotal,vtotal);
|
||||
LOG_VGA("H D End %d, V D End %d",hdispend,vdispend);
|
||||
fps=clock/(vtotal*htotal);
|
||||
|
||||
vga.draw.resizing=false;
|
||||
Bitu width,height,pitch,flags;
|
||||
|
||||
flags=0;
|
||||
vga.draw.lines=height=vdispend;
|
||||
width=hdispend;
|
||||
vga.draw.double_height=vga.config.vline_double;
|
||||
vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0;
|
||||
vga.draw.font_height=vga.config.vline_height+1;
|
||||
switch (vga.mode) {
|
||||
case GFX_256C:
|
||||
renderer=&VGA_Render_GFX_256C;
|
||||
width<<=2;
|
||||
pitch=vga.config.scan_len*8;
|
||||
break;
|
||||
case GFX_256U:
|
||||
vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel
|
||||
/* Don't know might do this different sometime, will have to do for now */
|
||||
if (!vga.draw.double_height) {
|
||||
if (vga.config.vline_height&1) {
|
||||
vga.draw.double_height=true;
|
||||
vga.draw.font_height/=2;
|
||||
}
|
||||
}
|
||||
width<<=2;
|
||||
pitch=vga.config.scan_len*8;
|
||||
renderer=&VGA_Render_GFX_256U;
|
||||
break;
|
||||
case GFX_16:
|
||||
width<<=3;
|
||||
pitch=vga.config.scan_len*16;
|
||||
renderer=&VGA_Render_GFX_16;
|
||||
break;
|
||||
case GFX_4:
|
||||
width<<=3;
|
||||
height<<=1;
|
||||
pitch=width;
|
||||
renderer=&VGA_Render_GFX_4;
|
||||
break;
|
||||
case GFX_2:
|
||||
width<<=3;
|
||||
height<<=1;
|
||||
pitch=width;
|
||||
renderer=&VGA_Render_GFX_2;
|
||||
break;
|
||||
case TEXT_16:
|
||||
/* probably a 16-color text mode, got to detect mono mode somehow */
|
||||
width<<=3; /* 8 bit wide text font */
|
||||
vga.draw.font_height=vga.config.vline_height+1;
|
||||
height<<=4;
|
||||
width<<=3; /* 8 bit wide text font */
|
||||
if (width>640) width=640;
|
||||
if (height>480) height=480;
|
||||
pitch=width;
|
||||
renderer=&VGA_Render_TEXT_16;
|
||||
};
|
||||
if (vga.draw.double_height) {
|
||||
flags|=DoubleHeight;
|
||||
height/=2;
|
||||
}
|
||||
if (vga.draw.double_width) {
|
||||
flags|=DoubleWidth;
|
||||
/* Double width is dividing main clock, the width should be correct already for this */
|
||||
}
|
||||
if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) {
|
||||
PIC_RemoveEvents(VGA_BlankTimer);
|
||||
vga.draw.width=width;
|
||||
vga.draw.height=height;
|
||||
vga.draw.pitch=pitch;
|
||||
|
||||
vga.draw.width=width;
|
||||
vga.draw.height=height;
|
||||
RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),0,renderer);
|
||||
|
||||
LOG_VGA("Width %d, Height %d",width,height);
|
||||
LOG_VGA("Flags %X, fps %f",flags,fps);
|
||||
RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags);
|
||||
vga.draw.blank=(Bitu)(1000000/fps);
|
||||
PIC_AddEvent(VGA_BlankTimer,vga.draw.blank);
|
||||
}
|
||||
};
|
||||
|
||||
void VGA_StartResize(void) {
|
||||
if (!vga.draw.resizing) {
|
||||
vga.draw.resizing=true;
|
||||
/* Start a resize after 50 ms */
|
||||
PIC_AddEvent(VGA_DoResize,500);
|
||||
PIC_AddEvent(VGA_DoResize,50000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VGA_Init(Section* sec) {
|
||||
vga.draw.resizing=false;
|
||||
VGA_SetupMemory();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -42,9 +42,11 @@ typedef struct {
|
|||
bool retrace; /* A retrace has started */
|
||||
Bitu scan_len;
|
||||
|
||||
/* Screen resolution and memory mode */
|
||||
Bitu vdisplayend;
|
||||
Bitu hdisplayend;
|
||||
/* Some other screen related variables */
|
||||
Bitu line_compare;
|
||||
|
||||
Bitu clock;
|
||||
bool clock_half;
|
||||
|
||||
bool chained; /* Enable or Disabled Chain 4 Mode */
|
||||
bool gfxmode; /* Yes or No Easy no */
|
||||
|
@ -56,7 +58,6 @@ typedef struct {
|
|||
bool vline_double;
|
||||
Bit8u vline_height;
|
||||
|
||||
bool pixel_double;
|
||||
/* Pixel Scrolling */
|
||||
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
|
||||
Bit8u hlines_skip;
|
||||
|
@ -85,12 +86,16 @@ typedef struct {
|
|||
bool resizing;
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu pitch;
|
||||
Bitu blank;
|
||||
bool double_width;
|
||||
bool double_height;
|
||||
Bitu lines;
|
||||
Bit8u * font;
|
||||
Bit8u font_height;
|
||||
Bit8u cursor_enable;
|
||||
Bit8u cursor_row;
|
||||
Bit8u cursor_col;
|
||||
Bit8u cursor_count;
|
||||
struct {
|
||||
Bitu row,col,sline,eline,count;
|
||||
} cursor;
|
||||
} VGA_Draw;
|
||||
|
||||
|
||||
|
@ -170,7 +175,8 @@ typedef struct {
|
|||
Bit8u pel_mask;
|
||||
Bit8u pel_index;
|
||||
Bit8u state;
|
||||
Bit8u index;
|
||||
Bit8u write_index;
|
||||
Bit8u read_index;
|
||||
Bitu first_changed;
|
||||
RGBEntry rgb[0x100];
|
||||
Bit8u attr[16];
|
||||
|
@ -202,8 +208,8 @@ typedef struct {
|
|||
VGA_Dac dac;
|
||||
VGA_Latch latch;
|
||||
VGA_Memory mem;
|
||||
//Special little hack to let the memory run over into the buffer
|
||||
Bit8u buffer[1024*1024];
|
||||
/* Extra buffer following main video ram with double data for overflowing of addresses */
|
||||
Bit8u buffer[1024*1024]; /* 256 kb vid ram with 16 colors and double addresses */
|
||||
} VGA_Type;
|
||||
|
||||
|
||||
|
@ -217,11 +223,10 @@ void VGA_StartResize(void);
|
|||
|
||||
/* The Different Drawing functions */
|
||||
void VGA_DrawTEXT(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX256U_Full(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu next_line);
|
||||
void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu next_line);
|
||||
/* The Different Memory Read/Write Handlers */
|
||||
Bit8u VGA_NormalReadHandler(Bit32u start);
|
||||
|
||||
|
|
|
@ -49,10 +49,12 @@ void write_p3c0(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x10: /* Mode Control Register */
|
||||
attr(mode_control)=val;
|
||||
vga.config.gfxmode=val&1;
|
||||
vga.config.vga_enabled=(val & 64)>0;
|
||||
VGA_FindSettings();
|
||||
if (val != attr(mode_control)) {
|
||||
attr(mode_control)=val;
|
||||
vga.config.gfxmode=val&1;
|
||||
vga.config.vga_enabled=(val & 0x40)>0;
|
||||
VGA_FindSettings();
|
||||
}
|
||||
//TODO Monochrome mode
|
||||
//TODO 9 bit characters
|
||||
//TODO line wrapping split screen shit see bit 5
|
||||
|
|
|
@ -40,9 +40,10 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
/* 0-7 Horizontal Total Character Clocks-5 */
|
||||
break;
|
||||
case 0x01: /* Horizontal Display End Register */
|
||||
crtc(horizontal_display_end)=val;
|
||||
vga.config.hdisplayend=val+1;
|
||||
VGA_StartResize();
|
||||
if (val != crtc(horizontal_display_end)) {
|
||||
crtc(horizontal_display_end)=val;
|
||||
VGA_StartResize();
|
||||
}
|
||||
/* 0-7 Number of Character Clocks Displayed -1 */
|
||||
break;
|
||||
case 0x02: /* Start Horizontal Blanking Register */
|
||||
|
@ -75,7 +76,10 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x06: /* Vertical Total Register */
|
||||
crtc(vertical_total)=val;
|
||||
if (val != crtc(vertical_total)) {
|
||||
crtc(vertical_total)=val;
|
||||
VGA_StartResize();
|
||||
}
|
||||
/* 0-7 Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7
|
||||
bit 0. Bit 9 is found in 3d4h index 7 bit 5.
|
||||
Note: For the VGA this value is the number of scan lines in the display -2.
|
||||
|
@ -83,8 +87,11 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
break;
|
||||
case 0x07: /* Overflow Register */
|
||||
crtc(overflow)=val;
|
||||
vga.config.vdisplayend=(vga.config.vdisplayend&0xFF)|(((val>>1) & 1)<<8)|(((val>>6) & 1)<<9);
|
||||
VGA_StartResize();
|
||||
vga.config.line_compare=(vga.config.line_compare & 0x2ff) | (val & 0x10) << 4;
|
||||
if ((vga.crtc.overflow ^ val) & 0xef) {
|
||||
crtc(overflow)=val;
|
||||
VGA_StartResize();
|
||||
} else crtc(overflow)=val;
|
||||
/*
|
||||
0 Bit 8 of Vertical Total (3d4h index 6)
|
||||
1 Bit 8 of Vertical Display End (3d4h index 12h)
|
||||
|
@ -110,10 +117,13 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x09: /* Maximum Scan Line Register */
|
||||
crtc(maximum_scan_line)=val;
|
||||
vga.config.vline_double=(val & 128)>1;
|
||||
vga.config.vline_height=(val & 0xf);
|
||||
VGA_StartResize();
|
||||
vga.config.line_compare=(vga.config.line_compare & 0x1ff)|(val&0x40)<<3;
|
||||
if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) {
|
||||
crtc(maximum_scan_line)=val;
|
||||
VGA_StartResize();
|
||||
} else crtc(maximum_scan_line)=val;
|
||||
/*
|
||||
0-4 Number of scan lines in a character row -1. In graphics modes this is
|
||||
the number of times (-1) the line is displayed before passing on to
|
||||
|
@ -152,16 +162,16 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
case 0x0E: /*Cursor Location High Register */
|
||||
crtc(cursor_location_high)=val;
|
||||
if (vga.config.scan_len<2) break;
|
||||
vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2);
|
||||
vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2);
|
||||
vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2);
|
||||
vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2);
|
||||
/* 0-7 Upper 8 bits of the address of the cursor */
|
||||
break;
|
||||
case 0x0F: /* Cursor Location Low Register */
|
||||
//TODO update cursor on screen
|
||||
crtc(cursor_location_low)=val;
|
||||
if (vga.config.scan_len<2) break;
|
||||
vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2);
|
||||
vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2);
|
||||
vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2);
|
||||
vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2);
|
||||
/* 0-7 Lower 8 bits of the address of the cursor */
|
||||
break;
|
||||
case 0x10: /* Vertical Retrace Start Register */
|
||||
|
@ -186,9 +196,10 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x12: /* Vertical Display End Register */
|
||||
crtc(vertical_display_end)=val;
|
||||
vga.config.vdisplayend=(vga.config.vdisplayend & 0x300)|val;
|
||||
VGA_StartResize();
|
||||
if (val!=crtc(vertical_display_end)) {
|
||||
crtc(vertical_display_end)=val;
|
||||
VGA_StartResize();
|
||||
}
|
||||
/*
|
||||
0-7 Lower 8 bits of Vertical Display End. The display ends when the line
|
||||
counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1.
|
||||
|
@ -196,9 +207,11 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x13: /* Offset register */
|
||||
crtc(offset)=val;
|
||||
vga.config.scan_len=val;
|
||||
VGA_StartResize();
|
||||
if (val!=crtc(offset)) {
|
||||
crtc(offset)=val;
|
||||
vga.config.scan_len=val;
|
||||
VGA_StartResize();
|
||||
}
|
||||
/*
|
||||
0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for
|
||||
word mode and 8 for Double Word mode.
|
||||
|
@ -228,9 +241,11 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x17: /* Mode Control Register */
|
||||
crtc(mode_control)=val;
|
||||
vga.config.cga_enabled=!((val&1)>0);
|
||||
VGA_FindSettings();
|
||||
if (val!=crtc(mode_control)) {
|
||||
crtc(mode_control)=val;
|
||||
vga.config.cga_enabled=!((val&1)>0);
|
||||
VGA_FindSettings();
|
||||
}
|
||||
/*
|
||||
0 If clear use CGA compatible memory addressing system
|
||||
by substituting character row scan counter bit 0 for address bit 13,
|
||||
|
@ -249,6 +264,7 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
break;
|
||||
case 0x18: /* Line Compare Register */
|
||||
crtc(line_compare)=val;
|
||||
vga.config.line_compare=(vga.config.line_compare & 0x300) | val;
|
||||
/*
|
||||
0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this
|
||||
value, the display address wraps to 0. Provides Split Screen
|
||||
|
|
|
@ -65,13 +65,13 @@ static Bit8u read_p3c6(Bit32u port) {
|
|||
|
||||
|
||||
static void write_p3c7(Bit32u port,Bit8u val) {
|
||||
vga.dac.index=val;
|
||||
vga.dac.read_index=val;
|
||||
vga.dac.pel_index=0;
|
||||
vga.dac.state=DAC_READ;
|
||||
}
|
||||
|
||||
static void write_p3c8(Bit32u port,Bit8u val) {
|
||||
vga.dac.index=val;
|
||||
vga.dac.write_index=val;
|
||||
vga.dac.pel_index=0;
|
||||
vga.dac.state=DAC_WRITE;
|
||||
}
|
||||
|
@ -79,36 +79,36 @@ static void write_p3c8(Bit32u port,Bit8u val) {
|
|||
static void write_p3c9(Bit32u port,Bit8u val) {
|
||||
switch (vga.dac.pel_index) {
|
||||
case 0:
|
||||
vga.dac.rgb[vga.dac.index].red=val;
|
||||
vga.dac.rgb[vga.dac.write_index].red=val;
|
||||
vga.dac.pel_index=1;
|
||||
break;
|
||||
case 1:
|
||||
vga.dac.rgb[vga.dac.index].green=val;
|
||||
vga.dac.rgb[vga.dac.write_index].green=val;
|
||||
vga.dac.pel_index=2;
|
||||
break;
|
||||
case 2:
|
||||
vga.dac.rgb[vga.dac.index].blue=val;
|
||||
vga.dac.rgb[vga.dac.write_index].blue=val;
|
||||
switch (vga.mode) {
|
||||
case GFX_256C:
|
||||
case GFX_256U:
|
||||
RENDER_SetPal(vga.dac.index,
|
||||
vga.dac.rgb[vga.dac.index].red << 2,
|
||||
vga.dac.rgb[vga.dac.index].green << 2,
|
||||
vga.dac.rgb[vga.dac.index].blue << 2
|
||||
RENDER_SetPal(vga.dac.write_index,
|
||||
vga.dac.rgb[vga.dac.write_index].red << 2,
|
||||
vga.dac.rgb[vga.dac.write_index].green << 2,
|
||||
vga.dac.rgb[vga.dac.write_index].blue << 2
|
||||
);
|
||||
break;
|
||||
default:
|
||||
/* Check for attributes and DAC entry link */
|
||||
for (Bitu i=0;i<16;i++) {
|
||||
if (vga.dac.attr[i]==vga.dac.index) {
|
||||
if (vga.dac.attr[i]==vga.dac.write_index) {
|
||||
RENDER_SetPal(i,
|
||||
vga.dac.rgb[vga.dac.index].red << 2,
|
||||
vga.dac.rgb[vga.dac.index].green << 2,
|
||||
vga.dac.rgb[vga.dac.index].blue << 2);
|
||||
vga.dac.rgb[vga.dac.write_index].red << 2,
|
||||
vga.dac.rgb[vga.dac.write_index].green << 2,
|
||||
vga.dac.rgb[vga.dac.write_index].blue << 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
vga.dac.index++;
|
||||
vga.dac.write_index++;
|
||||
vga.dac.pel_index=0;
|
||||
break;
|
||||
default:
|
||||
|
@ -120,16 +120,16 @@ static Bit8u read_p3c9(Bit32u port) {
|
|||
Bit8u ret;
|
||||
switch (vga.dac.pel_index) {
|
||||
case 0:
|
||||
ret=vga.dac.rgb[vga.dac.index].red;
|
||||
ret=vga.dac.rgb[vga.dac.read_index].red;
|
||||
vga.dac.pel_index=1;
|
||||
break;
|
||||
case 1:
|
||||
ret=vga.dac.rgb[vga.dac.index].green;
|
||||
ret=vga.dac.rgb[vga.dac.read_index].green;
|
||||
vga.dac.pel_index=2;
|
||||
break;
|
||||
case 2:
|
||||
ret=vga.dac.rgb[vga.dac.index].blue;
|
||||
vga.dac.index++;
|
||||
ret=vga.dac.rgb[vga.dac.read_index].blue;
|
||||
vga.dac.read_index++;
|
||||
vga.dac.pel_index=0;
|
||||
break;
|
||||
default:
|
||||
|
@ -155,6 +155,8 @@ void VGA_SetupDAC(void) {
|
|||
vga.dac.pel_mask=0xff;
|
||||
vga.dac.pel_index=0;
|
||||
vga.dac.state=DAC_READ;
|
||||
vga.dac.read_index=0;
|
||||
vga.dac.write_index=0;
|
||||
|
||||
/* Setup the DAC IO port Handlers */
|
||||
IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask");
|
||||
|
|
|
@ -21,45 +21,11 @@
|
|||
#include "video.h"
|
||||
#include "vga.h"
|
||||
|
||||
//TODO Make the full draw like the vga really does from video memory.
|
||||
|
||||
/* This Should draw a complete 16 colour screen */
|
||||
void VGA_Render_GFX_2(Bit8u * * data) {
|
||||
*data=vga.buffer;
|
||||
VGA_DrawGFX2_Full(vga.buffer,vga.draw.width);
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_Render_GFX_4(Bit8u * * data) {
|
||||
*data=vga.buffer;
|
||||
VGA_DrawGFX4_Full(vga.buffer,vga.draw.width);
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_Render_GFX_16(Bit8u * * data) {
|
||||
// *data=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning];
|
||||
*data=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning];
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_Render_GFX_256U(Bit8u * * data) {
|
||||
// *data=&vga.mem.linear[vga.config.display_start*4+vga.config.pel_panning];
|
||||
*data=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning];
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_Render_GFX_256C(Bit8u * * data) {
|
||||
*data=memory+0xa0000;
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_Render_TEXT_16(Bit8u * * data) {
|
||||
*data=vga.buffer;
|
||||
if (data && !vga.draw.resizing) VGA_DrawTEXT(vga.buffer,vga.draw.width);
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
|
||||
void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) {
|
||||
void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=HostMake(0xB800,0);
|
||||
Bit8u * flip=HostMake(0xB800,8*1024);
|
||||
Bit8u * draw;
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread;
|
||||
|
@ -70,7 +36,7 @@ void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) {
|
|||
};
|
||||
draw=bitdata;
|
||||
//TODO Look up table like in 4color mode
|
||||
for (Bit32u x=0;x<vga.draw.width>>3;x++) {
|
||||
for (Bit32u x=vga.draw.width>>3;x>0;x--) {
|
||||
Bit8u val=*(tempread++);
|
||||
*(draw+0)=(val>>7)&1;
|
||||
*(draw+1)=(val>>6)&1;
|
||||
|
@ -83,14 +49,12 @@ void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) {
|
|||
draw+=8;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
};
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=HostMake(0xB800,0);
|
||||
void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=HostMake(0xB800,vga.config.display_start*2);
|
||||
Bit8u * flip=HostMake(0xB800,8*1024);
|
||||
Bit8u * draw;
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread;
|
||||
|
@ -98,7 +62,8 @@ void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) {
|
|||
if (y&1) {
|
||||
tempread+=8*1024;
|
||||
reader+=80;
|
||||
};
|
||||
if (reader>=flip) reader-=8*1024;
|
||||
}
|
||||
draw=bitdata;
|
||||
for (Bit32u x=0;x<vga.draw.width>>2;x++) {
|
||||
Bit8u val=*(tempread++);
|
||||
|
@ -106,12 +71,10 @@ void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) {
|
|||
draw+=4;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
};
|
||||
VGA_StartRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the screen using the lookup buffer */
|
||||
//TODO include split screen or something
|
||||
void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) {
|
||||
Bit8u * reader=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning];
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
|
@ -119,12 +82,9 @@ void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) {
|
|||
bitdata+=vga.draw.width+next_line;
|
||||
reader+=vga.config.scan_len*16;
|
||||
}
|
||||
VGA_StartRetrace();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line) {
|
||||
void VGA_DrawGFX256U_Fast(Bit8u * bitdata,Bitu next_line) {
|
||||
Bit16u yreader=vga.config.display_start*1;
|
||||
/* TODO add pel panning */
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
|
@ -137,21 +97,8 @@ void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line) {
|
|||
}
|
||||
yreader+=vga.config.scan_len*2;
|
||||
bitdata+=next_line;
|
||||
};
|
||||
VGA_StartRetrace();
|
||||
};
|
||||
|
||||
void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu pitch) {
|
||||
/* For now just copy 64 kb of memory with pitch support */
|
||||
Bit8u * reader=memory+0xa0000;
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
memcpy((void *)bitdata,(void *)reader,vga.draw.width);
|
||||
bitdata+=pitch;
|
||||
reader+=vga.draw.width;
|
||||
}
|
||||
VGA_StartRetrace();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=HostMake(0xB800,0);
|
||||
|
@ -175,18 +122,16 @@ void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) {
|
|||
};
|
||||
draw_start+=16*pitch;
|
||||
};
|
||||
VGA_StartRetrace();
|
||||
|
||||
if(!(vga.internal.cursor & 0x2000)){
|
||||
/* Draw a cursor */
|
||||
if (((Bitu)vga.draw.cursor_col*8)>=vga.draw.width) return;
|
||||
if (((Bitu)vga.draw.cursor_row*16)>=vga.draw.height) return;
|
||||
Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*pitch+vga.draw.cursor_col*8;
|
||||
if (vga.draw.cursor_count>8) {
|
||||
for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15;
|
||||
}
|
||||
vga.draw.cursor_count++;
|
||||
if (vga.draw.cursor_count>16) vga.draw.cursor_count=0;
|
||||
if(!(vga.internal.cursor & 0x2000)) {
|
||||
/* Draw a cursor */
|
||||
if (((Bitu)vga.draw.cursor.col*8)>=vga.draw.width) return;
|
||||
if (((Bitu)vga.draw.cursor.row*16)>=vga.draw.height) return;
|
||||
Bit8u * cursor_draw=bitdata+(vga.draw.cursor.row*16+15)*pitch+vga.draw.cursor.col*8;
|
||||
if (vga.draw.cursor.count>8) {
|
||||
for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15;
|
||||
}
|
||||
vga.draw.cursor.count++;
|
||||
if (vga.draw.cursor.count>16) vga.draw.cursor.count=0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ void write_p3cf(Bit32u port,Bit8u val) {
|
|||
case 3: /* Data Rotate */
|
||||
gfx(data_rotate)=val;
|
||||
vga.config.data_rotate=val & 7;
|
||||
if (vga.config.data_rotate) LOG_WARN("VGA:Data Rotate used %d",val &7);
|
||||
vga.config.raster_op=(val>>3) & 3;
|
||||
/*
|
||||
0-2 Number of positions to rotate data right before it is written to
|
||||
|
|
|
@ -92,20 +92,21 @@ INLINE static Bit32u ModeOperation(Bit8u val) {
|
|||
}
|
||||
|
||||
Bit8u VGA_GFX_4_ReadHandler(Bit32u start) {
|
||||
return vga.mem.linear[start];
|
||||
return vga.mem.linear[start-0xb8000];
|
||||
}
|
||||
|
||||
void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) {
|
||||
start-=0xa0000;
|
||||
start-=0xb8000;
|
||||
vga.mem.linear[start]=val;
|
||||
Bitu line=start / 320;
|
||||
Bitu x=start % 320;
|
||||
Bit8u * draw=&vga.buffer[start<<2];
|
||||
Bitu off;
|
||||
if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4;
|
||||
else off=320*(((start)/80)*2)+(start % 80)*4;
|
||||
Bit32u * draw=(Bit32u *)&vga.buffer[off];
|
||||
/* TODO Could also use a Bit32u lookup table for this */
|
||||
*(draw+0)=(val>>6)&3;
|
||||
*(draw+1)=(val>>4)&3;
|
||||
*(draw+2)=(val>>2)&3;
|
||||
*(draw+3)=(val)&3;
|
||||
*draw=CGAWriteTable[val];
|
||||
draw=(Bit32u *)&vga.buffer[off+0x4000*4];
|
||||
*draw=CGAWriteTable[val];
|
||||
|
||||
}
|
||||
|
||||
void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) {
|
||||
|
|
|
@ -58,7 +58,8 @@ static void write_p3d8(Bit32u port,Bit8u val) {
|
|||
|
||||
static void write_p3c2(Bit32u port,Bit8u val) {
|
||||
p3c2data=val;
|
||||
if (val & 1) {
|
||||
|
||||
if (val & 0x1) {
|
||||
IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select");
|
||||
IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select");
|
||||
IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register");
|
||||
|
@ -77,6 +78,11 @@ static void write_p3c2(Bit32u port,Bit8u val) {
|
|||
IO_FreeWriteHandler(0x3d5);
|
||||
IO_FreeReadHandler(0x3d5);
|
||||
}
|
||||
if (val & 0x4) vga.config.clock=28322000;
|
||||
else vga.config.clock=25175000;
|
||||
|
||||
VGA_StartResize();
|
||||
|
||||
/*
|
||||
0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh.
|
||||
2-3 Clock Select. 0: 25MHz, 1: 28MHz
|
||||
|
|
|
@ -36,9 +36,10 @@ void write_p3c5(Bit32u port,Bit8u val) {
|
|||
seq(reset)=val;
|
||||
break;
|
||||
case 1: /* Clocking Mode */
|
||||
seq(clocking_mode)=val;
|
||||
vga.config.pixel_double=(val & 8)>0;
|
||||
VGA_FindSettings();
|
||||
if (val!=seq(clocking_mode)) {
|
||||
seq(clocking_mode)=val;
|
||||
VGA_StartResize();
|
||||
}
|
||||
/* TODO Figure this out :)
|
||||
0 If set character clocks are 8 dots wide, else 9.
|
||||
2 If set loads video serializers every other character
|
||||
|
|
Loading…
Add table
Reference in a new issue