1
0
Fork 0

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:
Sjoerd van der Berg 2002-12-22 15:11:29 +00:00
parent f1fd4ae696
commit d54ae0640b
10 changed files with 255 additions and 189 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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;
}
};

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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