diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index dac94628..b62dd7e3 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -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.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(); diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 4d3427d5..24537a4d 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -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); diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 953b4521..4bd43051 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 020866c9..588f900b 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index d8e0ae2a..a4b400c5 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -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"); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1a120999..006b1e13 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -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>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=flip) reader-=8*1024; + } draw=bitdata; for (Bit32u x=0;x>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.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; } }; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index ff7b6a1c..a6e00d23 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index c0ed8229..32af55b0 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -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) { diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index f8ed0c79..9202e913 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 9a7aa0c8..15f0aa46 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -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