diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index d56735d2..c924393c 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -50,20 +50,22 @@ void VGA_DetermineMode(void) { if (vga.s3.misc_control_2 & 0xf0) { switch (vga.s3.misc_control_2 >> 4) { case 1:VGA_SetMode(M_LIN8);break; + case 3:VGA_SetMode(M_LIN15);break; + case 5:VGA_SetMode(M_LIN16);break; + case 13:VGA_SetMode(M_LIN32);break; } /* Test for graphics or alphanumeric mode */ } else if (vga.attr.mode_control & 1) { if (vga.gfx.mode & 0x40) VGA_SetMode(M_VGA); else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); - else VGA_SetMode(M_EGA16); - /* old mode detection: - if (!(vga.crtc.mode_control & 0x1)) { - if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); - else VGA_SetMode(M_CGA2); - } else if (vga.attr.mode_control & 0x40) { - VGA_SetMode(M_VGA); - } else VGA_SetMode(M_EGA16); */ + else { + if (vga.s3.reg_31 & 0x8) + VGA_SetMode(M_LIN4); + else + VGA_SetMode(M_EGA); + + } } else { VGA_SetMode(M_TEXT); } diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index b2010589..1e7bc272 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -121,6 +121,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { case M_LIN8: vga.config.pel_panning=(val & 0x7)/2; break; + case M_LIN16: default: vga.config.pel_panning=(val & 0x7); } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 82daa008..d193f372 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -29,18 +29,18 @@ void VGA_MapMMIO(void); void VGA_UnmapMMIO(void); -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); Bitu DEBUG_EnableDebugger(void); -void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) { +void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; } -Bitu read_p3d4_vga(Bitu port,Bitu iolen) { +Bitu vga_read_p3d4(Bitu port,Bitu iolen) { return crtc(index); } -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { // if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -289,291 +289,19 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { Bit 9 is found in 3d4h index 9 bit 6. */ break; -/* S3 specific group */ - case 0x31: /* CR31 Memory Configuration */ -//TODO Base address - vga.s3.reg_31=val; - vga.config.compatible_chain4 = !(val&0x08); - VGA_SetupHandlers(); - break; - /* - 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if - set, disables if clear. - 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup - 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit - 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to - video memory above 256k. - 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index - 51h, for the 864/964 see index 69h. - 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode - for Alpha Mode Font Access. - 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area - C6800h-C7FFFh is mapped out, if set it is accessible. - */ - case 0x35: /* CR35 CRT Register Lock */ - if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection - vga.s3.reg_35=val & 0xf0; - if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { - vga.s3.bank&=0xf0; - vga.s3.bank|=val & 0xf; - VGA_SetupHandlers(); - } - break; - /* - 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h - index 51h bits 2-3. For the 864/964 see index 6Ah. - 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 - (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set - 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index - 0,1,2,3,4,5,17h bit 2 if set - 6 (911/924) Lock VSync Polarity. - 7 (911/924) Lock HSync Polarity. - */ - case 0x38: /* CR38 Register Lock 1 */ - vga.s3.reg_lock1=val; - break; - case 0x39: /* CR39 Register Lock 2 */ - vga.s3.reg_lock2=val; - break; - case 0x40: /* CR40 System Config */ - vga.s3.reg_40 = val; - break; - case 0x43: /* CR43 Extended Mode */ - vga.s3.reg_43=val & ~0x4; - if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { - vga.config.scan_len&=0x2ff; - vga.config.scan_len|=(val & 0x4) << 6; - VGA_CheckScanLength(); - } - break; - /* - 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ - (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 - are 0 - */ - case 0x45: /* Hardware cursor mode */ - vga.s3.hgc.curmode = val; - // Activate hardware cursor code if needed - VGA_ActivateHardwareCursor(); - break; - case 0x46: - vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); - break; - case 0x47: /* HGC orgX */ - vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; - break; - case 0x48: - vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); - break; - case 0x49: /* HGC orgY */ - vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; - break; - case 0x4A: /* HGC foreground stack */ - if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; - vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; - vga.s3.hgc.fstackpos++; - break; - case 0x4B: /* HGC background stack */ - if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; - vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; - vga.s3.hgc.bstackpos++; - break; - case 0x4c: /* HGC start address high byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); - break; - case 0x4d: /* HGC start address low byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); - break; - case 0x4e: /* HGC pattern start X */ - vga.s3.hgc.posx = val; - break; - case 0x4f: /* HGC pattern start X */ - vga.s3.hgc.posy = val; - break; - case 0x51: /* Extended System Control 2 */ - vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 - //TODO Display start - vga.config.display_start&=0xFCFFFF; - vga.config.display_start|=(val & 3) << 16; - if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { - vga.s3.bank&=0xcf; - vga.s3.bank|=(val&0xc)<<2; - VGA_SetupHandlers(); - } - if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { - vga.config.scan_len&=0xff; - vga.config.scan_len|=(val & 0x30) << 4; - VGA_CheckScanLength(); - } - break; - /* - 0 (80x) Display Start Address bit 18 - 0-1 (928 +) Display Start Address bit 18-19 - Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index - 0Ch,0Dh. For the 864/964 see 3d4h index 69h - 2 (80x) CPU BASE. CPU Base Address Bit 18. - 2-3 (928 +) Old CPU Base Address Bits 19-18. - 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. - For the 864/964 see 3d4h index 6Ah - 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register - (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active - 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers - allows transferring one half of the VRAM shift register data while - the other half is being output. For the 964 Split Transfers - must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They - probably can't time the VRAM load cycle closely enough while the - graphics engine is running. - 7 (not 864/964) Enable EPROM Write. If set enables flash memory write - control to the BIOS ROM address - */ - case 0x53: - if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { - /* Map or unmap MMIO */ - if ((val & 0x10) != 0) { - //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); - VGA_MapMMIO(); - } else { - VGA_UnmapMMIO(); - } - } - vga.s3.ext_mem_ctrl = val; - break; - case 0x55: /* Extended Video DAC Control */ - vga.s3.reg_55=val; - break; - /* - 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the - RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. - If this field is 0, 3d4h index 43h bit 1 is active. - 2 Enable General Input Port Read. If set DAC reads are disabled and the - STRD strobe for reading the General Input Port is enabled for reading - while DACRD is active, if clear DAC reads are enabled. - 3 (928) Enable External SID Operation if set. If set video data is - passed directly from the VRAMs to the DAC rather than through the - VGA chip - 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 - mode, if clear in MS-Windows mode - 5 (80x,928) Hardware Cursor External Operation Mode. If set the two - bits of cursor data ,is output on the HC[0-1] pins for the video DAC - The SENS pin becomes HC1 and the MID2 pin becomes HC0. - 6 ?? - 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. - (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri - -stated if set - */ - case 0x58: /* Linear Address Window Control */ - vga.s3.reg_58=val; - break; - /* - 0-1 Linear Address Window Size. Must be less than or equal to video - memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) - 2 (not 864/964) Enable Read Ahead Cache if set - 3 (80x,928) ISA Latch Address. If set latches address during every ISA - cycle, unlatches during every ISA cycle if clear. - (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set - address latching occours in the T1 cycle, if clear in the T2 cycle - (I.e. one clock cycle delayed). - 4 ENB LA. Enable Linear Addressing if set. - 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write - -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. - 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM - control is 256 words, if clear 512 words. - 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, - if clear 7MCLKs - */ - case 0x59: /* Linear Address Window Position High */ - if ((vga.s3.la_window&0xff00) ^ (val << 8)) { - vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); - VGA_StartUpdateLFB(); - } - break; - case 0x5a: /* Linear Address Window Position Low */ - if ((vga.s3.la_window&0x00ff) ^ val) { - vga.s3.la_window=(vga.s3.la_window&0xff00) | val; - VGA_StartUpdateLFB(); - } - break; - case 0x5D: /* Extended Horizontal Overflow */ - if ((val & vga.s3.ex_hor_overflow) ^ 3) { - vga.s3.ex_hor_overflow=val; - VGA_StartResize(); - } else vga.s3.ex_hor_overflow=val; - break; - /* - 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h - index 0) - 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End - register (3d4h index 1) - 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking - register (3d4h index 2). - 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse - is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or - does it really extend by 64 ? - 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start - Retrace register (3d4h index 4). - 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse - is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or - does it really extend by 32 ? - 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer - Position register (3d4h index 3Bh) - 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant - Termination register (3d4h index 5Fh). - */ - case 0x5e: /* Extended Vertical Overflow */ - vga.config.line_compare=(vga.config.line_compare & 0x3ff) | (val & 0x40) << 4; - if ((val ^ vga.s3.ex_ver_overflow) & 0x3) { - vga.s3.ex_ver_overflow=val; - VGA_StartResize(); - } else vga.s3.ex_ver_overflow=val; - break; - /* - 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h - index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. - 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End - register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 - and 6 - 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking - register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 - in 3d4h index 9 bit 5 - 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace - register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 - and 7. - 6 Line Compare Position bit 10. Bit 10 of the Line Compare register - (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h - index 9 bit 6. - */ - case 0x67: /* Extended Miscellaneous Control 2 */ - /* - 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted - DCLK, if set VCLK = DCLK. - 4-7 Pixel format. - 0 Mode 0: 8bit (1 pixel/VCLK) - 1 Mode 8: 8bit (2 pixels/VCLK) - 3 Mode 9: 15bit (1 pixel/VCLK) - 5 Mode 10: 16bit (1 pixel/VCLK) - 7 Mode 11: 24/32bit (2 VCLKs/pixel) - 13 (732/764) 32bit (1 pixel/VCLK) - */ - vga.s3.misc_control_2=val; - VGA_DetermineMode(); - break; - case 0x69: /* Extended System Control 3 */ - if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { - vga.config.display_start&=0xffff; - vga.config.display_start|=(val & 0x1f) << 16; - } - break; - case 0x6a: /* Extended System Control 4 */ - vga.s3.bank=val & 0x3f; - VGA_SetupHandlers(); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write %X to unknown index %2X",val,crtc(index)); + switch (svgaCard) { + case SVGA_S3Trio: + SVGA_S3_WriteCRTC( crtc(index), val, iolen); + break; + default: + break; + } + break; } } -Bitu read_p3d5_vga(Bitu port,Bitu iolen) { +Bitu vga_read_p3d5(Bitu port,Bitu iolen) { // LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -626,72 +354,15 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return crtc(mode_control); case 0x18: /* Line Compare Register */ return crtc(line_compare); - - -/* Additions for S3 SVGA Support */ - case 0x2d: /* Extended Chip ID. */ - return 0x88; - // Always 88h ? - case 0x2e: /* New Chip ID */ - return 0x11; - //Trio 64 id - case 0x2f: /* Revision */ - return 0x00; - case 0x30: /* CR30 Chip ID/REV register */ - return 0xe0; //Trio+ dual byte - // Trio32/64 has 0xe0. extended - case 0x31: /* CR31 Memory Configuration */ -//TODO mix in bits from baseaddress; - return vga.s3.reg_31; - case 0x35: /* CR35 CRT Register Lock */ - return vga.s3.reg_35|(vga.s3.bank & 0xf); - case 0x36: /* CR36 Reset State Read 1 */ - //return 0x8f; - return 0x8e; /* PCI version */ - //2 Mb PCI and some bios settings - case 0x37: /* Reset state read 2 */ - return 0x2b; - case 0x38: /* CR38 Register Lock 1 */ - return vga.s3.reg_lock1; - case 0x39: /* CR39 Register Lock 2 */ - return vga.s3.reg_lock2; - case 0x40: /* CR40 system config */ - return vga.s3.reg_40; - case 0x43: /* CR43 Extended Mode */ - return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); - case 0x45: /* Hardware cursor mode */ - vga.s3.hgc.bstackpos = 0; - vga.s3.hgc.fstackpos = 0; - return vga.s3.hgc.curmode; - case 0x51: /* Extended System Control 2 */ - return ((vga.config.display_start >> 16) & 3 ) | - ((vga.s3.bank & 0x30) >> 2) | - ((vga.config.scan_len & 0x300) >> 4) | - vga.s3.reg_51; - case 0x53: - return vga.s3.ext_mem_ctrl; - case 0x55: /* Extended Video DAC Control */ - return vga.s3.reg_55; - case 0x58: /* Linear Address Window Control */ - return vga.s3.reg_58; - case 0x59: /* Linear Address Window Position High */ - return (vga.s3.la_window >> 8); - case 0x5a: /* Linear Address Window Position Low */ - return (vga.s3.la_window & 0xff); - case 0x5D: /* Extended Horizontal Overflow */ - return vga.s3.ex_hor_overflow; - case 0x5e: /* Extended Vertical Overflow */ - return vga.s3.ex_ver_overflow; - case 0x67: /* Extended Miscellaneous Control 2 */ - return vga.s3.misc_control_2; - case 0x69: /* Extended System Control 3 */ - return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); - case 0x6a: /* Extended System Control 4 */ - return (Bit8u)(vga.s3.bank & 0x3f); default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); + switch (svgaCard) { + case SVGA_S3Trio: + return SVGA_S3_ReadCRTC( crtc(index), iolen ); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); + return 0x0; + } } - return 0x0; } diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 98865c76..c714c8c6 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -100,6 +100,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: RENDER_SetPal(vga.dac.write_index, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -155,6 +156,7 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: break; default: RENDER_SetPal(attr, @@ -172,6 +174,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: return; } for (Bitu i=0;i<16;i++) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 40b0582b..1d9b6e29 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -21,6 +21,7 @@ #include "dosbox.h" #include "video.h" #include "render.h" +#include "../gui/render_scalers.h" #include "vga.h" #include "pic.h" @@ -31,7 +32,7 @@ typedef void (* VGA_FrameStart_Handler)(); static VGA_Line_Handler VGA_DrawLine; static VGA_FrameStart_Handler VGA_FrameStart; -static Bit8u TempLine[1280]; +static Bit8u TempLine[SCALER_MAXWIDTH * 4]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; @@ -75,7 +76,7 @@ static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; + const Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; //Generate a temporary bitline to calculate the avarage //over bit-2 bit-1 bit bit+1. @@ -147,13 +148,21 @@ static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } - +static Bit8u * VGA_Draw_LIN4_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[512*1024+vidstart*8+panning]; +} static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+vidstart*8+panning]; } static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning]; } +static Bit8u * VGA_Draw_LIN16_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[vidstart*4+panning]; +} +static Bit8u * VGA_Draw_LIN32_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[vidstart*4+panning]; +} static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+((vidstart*4+panning)&0xffff)]; @@ -169,17 +178,16 @@ static void VGA_StartFrame_VGA() { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { Bitu lineat = vidstart / ((160 * vga.draw.height) / 480); - if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) { + if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { - memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line); if(moff<0) moff+=64; Bitu xat = vga.s3.hgc.originx; - Bitu m, mat, mapat; + Bitu m, mapat; Bits r, z; mapat = 0; @@ -242,8 +250,8 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { *draw++=fg&mask1 | bg&~mask1; *draw++=fg&mask2 | bg&~mask2; } - Bits font_addr=(vga.draw.cursor.address-vidstart)/2; if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + Bitu font_addr=(vga.draw.cursor.address-vidstart) >> 1; if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; @@ -257,7 +265,7 @@ skip_cursor: static void VGA_VerticalDisplayEnd(Bitu val) { vga.config.retrace=true; - vga.config.real_start=vga.config.display_start; + vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); } static void VGA_HorizontalTimer(void) { @@ -310,14 +318,16 @@ static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.delay.vend); - if (RENDER_StartUpdate()) { + bool bDoDraw = RENDER_StartUpdate(); + if (bDoDraw) { +// if (RENDER_StartUpdate()) { vga.draw.parts_left=vga.draw.parts_total; vga.draw.lines_done=0; vga.draw.address=vga.config.real_start; vga.draw.address_line=vga.config.hlines_skip; vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; - PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); +// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); } switch (vga.mode) { case M_TEXT: @@ -339,13 +349,19 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address+=vga.tandy.disp_bank << 14; vga.draw.cursor.address+=vga.tandy.disp_bank << 14; } + if (bDoDraw) + VGA_DrawPart(vga.draw.parts_lines); } void VGA_CheckScanLength(void) { switch (vga.mode) { - case M_EGA16: + case M_EGA: case M_VGA: + case M_LIN4: case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: vga.draw.address_add=vga.config.scan_len*2; break; case M_TEXT: @@ -412,13 +428,21 @@ void VGA_SetupDrawing(Bitu val) { if (hbstart> 2) & 3; - if (clock == 0) - clock = 25175000; - else if (clock == 1) - clock = 28322000; - else - clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + switch (svgaCard) { + case SVGA_S3Trio: + clock = SVGA_S3_GetClock(); + break; + default: + switch ((vga.misc_output >> 2) & 3) { + case 0: + clock = 25175000; + break; + case 1: + clock = 28322000; + break; + } + break; + } /* 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 */ @@ -469,6 +493,7 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.resizing=false; Bitu width=hdispend; Bitu height=vdispend; + Bitu bpp=8; bool doubleheight=false; bool doublewidth=false; VGA_FrameStart = NULL; @@ -482,11 +507,49 @@ void VGA_SetupDrawing(Bitu val) { break; case M_LIN8: width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } /* Use HW mouse cursor drawer if enabled */ VGA_ActivateHardwareCursor(); break; - case M_EGA16: + case M_LIN15: + bpp = 15; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN16_Line; + break; + case M_LIN16: + bpp = 16; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN16_Line; + break; + case M_LIN32: + bpp = 32; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN32_Line; + break; + case M_LIN4: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; + vga.draw.blocks = width; + width<<=3; + VGA_DrawLine=VGA_Draw_LIN4_Line; + break; + case M_EGA: + doublewidth=(vga.seq.clocking_mode & 0x8) > 0; + vga.draw.blocks = width; width<<=3; VGA_DrawLine=VGA_Draw_EGA_Line; break; @@ -579,7 +642,8 @@ void VGA_SetupDrawing(Bitu val) { } vga.draw.lines_total=height; vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; - if (( width != vga.draw.width) || (height != vga.draw.height)) { + if (( width != vga.draw.width) || (height != vga.draw.height) || (vga.mode != vga.lastmode)) { + vga.lastmode = vga.mode; PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); PIC_RemoveEvents(VGA_DrawPart); @@ -594,7 +658,7 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif - RENDER_SetSize(width,height,8,aspect_ratio,doublewidth,doubleheight); + RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); } }; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 391f66ae..6581b3eb 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -26,38 +26,7 @@ #include "inout.h" void VGA_MapMMIO(void); - -static Bitu VGA_NormalReadHandler(PhysPt start) { - vga.latch.d=vga.mem.latched[start].d; - switch (vga.config.read_mode) { - case 0: - return (vga.latch.b[vga.config.read_map_select]); - case 1: - VGA_Latch templatch; - templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; - return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); - } - return 0; -} - -static Bitu VGA_Chain4ReadHandler(PhysPt start) { - if(vga.mode == M_VGA) - return vga.mem.linear[((start&~3)<<2)|(start&3)]; - return vga.mem.linear[start]; -} - -static void VGA_Chain4WriteHandler(PhysPt start, Bit8u val) { - // No need to check for compatible chains here, this one is only enabled if that bit is set - vga.mem.linear[((start&~3)<<2)|(start&3)] = val; - // Linearized version for faster rendering - vga.mem.linear[512*1024+start] = val; - // And replicate the first line - if (start < 320) - vga.mem.linear[512*1024+start+64*1024] = val; -} - //Nice one from DosEmu - INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { switch (vga.config.raster_op) { case 0x00: /* None */ @@ -100,73 +69,6 @@ INLINE static Bit32u ModeOperation(Bit8u val) { return full; } -static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - /* Update video memory and the pixel buffer */ - VGA_Latch pixels; - pixels.d=vga.mem.latched[start].d; - pixels.d&=vga.config.full_not_map_mask; - pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[start].d=pixels.d; - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; - - Bit32u colors0_3, colors4_7; - VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; - colors0_3 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)write_pixels=colors0_3; - *(Bit32u *)(write_pixels+512*1024)=colors0_3; - temp.d=pixels.d & 0x0f0f0f0f; - colors4_7 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)(write_pixels+4)=colors4_7; - *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; - -} - -static void VGA_GFX_16Chain4_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - /* Update video memory and the pixel buffer */ - VGA_Latch pixels; - vga.mem.linear[start] = val; - start >>= 2; - pixels.d=vga.mem.latched[start].d; - - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; - - Bit32u colors0_3, colors4_7; - VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; - colors0_3 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)write_pixels=colors0_3; - temp.d=pixels.d & 0x0f0f0f0f; - colors4_7 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)(write_pixels+4)=colors4_7; -} - -static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - VGA_Latch pixels; - pixels.d=vga.mem.latched[start].d; - pixels.d&=vga.config.full_not_map_mask; - pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[start].d=pixels.d; - vga.mem.latched[start+64*1024].d=pixels.d; -} - /* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */ #define VGA_PAGES (128/4) @@ -175,142 +77,238 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { #define VGA_PAGE_B8 (0xB8000/4096) static struct { - Bitu base,mask; + Bitu base, mask; } vgapages; -class VGARead_PageHandler : public PageHandler { +class VGA_UnchainedRead_Handler : public PageHandler { +public: + Bitu readHandler(PhysPt start) { + vga.latch.d=vga.mem.latched[start].d; + switch (vga.config.read_mode) { + case 0: + return (vga.latch.b[vga.config.read_map_select]); + case 1: + VGA_Latch templatch; + templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; + return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); + } + return 0; + } public: Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - return VGA_NormalReadHandler(addr); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_NormalReadHandler(addr+0) << 0) | - (VGA_NormalReadHandler(addr+1) << 8); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_NormalReadHandler(addr+0) << 0) | - (VGA_NormalReadHandler(addr+1) << 8) | - (VGA_NormalReadHandler(addr+2) << 16) | - (VGA_NormalReadHandler(addr+3) << 24); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); } }; -class VGAReadChain4_PageHandler : public PageHandler { +class VGA_Chained_ReadHandler : public PageHandler { +public: + Bitu readHandler(PhysPt addr) { + if(vga.mode == M_VGA) + return vga.mem.linear[((addr&~3)<<2)|(addr&3)]; + return vga.mem.linear[addr]; + } public: Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - return VGA_Chain4ReadHandler(addr); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_Chain4ReadHandler(addr+0) << 0) | - (VGA_Chain4ReadHandler(addr+1) << 8); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_Chain4ReadHandler(addr+0) << 0) | - (VGA_Chain4ReadHandler(addr+1) << 8) | - (VGA_Chain4ReadHandler(addr+2) << 16) | - (VGA_Chain4ReadHandler(addr+3) << 24); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); } }; -class VGA_16_PageHandler : public VGARead_PageHandler { +class VGA_ChainedEGA_Handler : public VGA_Chained_ReadHandler { +public: + void writeHandler(PhysPt start, Bit8u val) { + Bit32u data=ModeOperation(val); + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + vga.mem.linear[start] = val; + start >>= 2; + pixels.d=vga.mem.latched[start].d; + + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; + } public: - VGA_16_PageHandler() { + VGA_ChainedEGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_16_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_16_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_16Chain4_PageHandler : public VGAReadChain4_PageHandler { +class VGA_UnchainedEGA_Handler : public VGA_UnchainedRead_Handler { +public: + void writeHandler(PhysPt start, Bit8u val) { + Bit32u data=ModeOperation(val); + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + pixels.d=vga.mem.latched[start].d; + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); + vga.mem.latched[start].d=pixels.d; + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + *(Bit32u *)(write_pixels+512*1024)=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; + *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; + } public: - VGA_16Chain4_PageHandler() { + VGA_UnchainedEGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_16Chain4_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_16Chain4_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_256_PageHandler : public VGARead_PageHandler { + +class VGA_ChainedVGA_Handler : public VGA_Chained_ReadHandler { +public: + void writeHandler(PhysPt addr, Bitu val) { + // No need to check for compatible chains here, this one is only enabled if that bit is set + vga.mem.linear[((addr&~3)<<2)|(addr&3)] = val; + // Linearized version for faster rendering + vga.mem.linear[512*1024+addr] = val; + // And replicate the first line + if (addr < 320) + vga.mem.linear[512*1024+addr+64*1024] = val; + } public: - VGA_256_PageHandler() { + VGA_ChainedVGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_256U_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_256U_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_256Chain4_PageHandler : public VGAReadChain4_PageHandler { -public: - VGA_256Chain4_PageHandler() { +class VGA_UnchainedVGA_Handler : public VGA_UnchainedRead_Handler { +public: + void writeHandler( PhysPt addr, Bit8u val ) { + Bit32u data=ModeOperation(val); + VGA_Latch pixels; + pixels.d=vga.mem.latched[addr].d; + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); + vga.mem.latched[addr].d=pixels.d; + vga.mem.latched[addr+64*1024].d=pixels.d; + } +public: + VGA_UnchainedVGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_Chain4WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_Chain4WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; @@ -320,11 +318,11 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & vgapages.mask; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; return vga.draw.font[addr]; } void writeb(PhysPt addr,Bitu val){ - addr = PAGING_GetLinearAddress(addr) & vgapages.mask; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; if (vga.seq.map_mask & 0x4) { vga.draw.font[addr]=(Bit8u)val; } @@ -336,22 +334,163 @@ public: VGA_MAP_PageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { + phys_page-=vgapages.base; + return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + } + HostPt GetHostWritePt(Bitu phys_page) { phys_page-=vgapages.base; return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; } }; -class VGA_MMIO_PageHandler : public PageHandler { + +class VGA_LIN4Linear_Handler : public VGA_UnchainedEGA_Handler { +public: + VGA_LIN4Linear_Handler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); + } + Bitu readb(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return readHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); + } +}; + +class VGA_LIN4Banked_Handler : public VGA_UnchainedEGA_Handler { +public: + VGA_LIN4Banked_Handler() { + flags=PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); + } + Bitu readb(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return readHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); + } +}; + + +class VGA_LFBChanges_Handler : public PageHandler { +public: + VGA_LFBChanges_Handler() { + flags=PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit8u*)(&vga.mem.linear[addr]); + } + Bitu readw(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit16u*)(&vga.mem.linear[addr]); + } + Bitu readd(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit32u*)(&vga.mem.linear[addr]); + } + void writeb(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit8u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } + void writew(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit16u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } + void writed(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit32u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } +}; + +class VGA_LFB_Handler : public PageHandler { +public: + VGA_LFB_Handler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostReadPt( Bitu phys_page ) { + phys_page -= vga.lfb.page; + return &vga.mem.linear[phys_page * 4096]; + } + HostPt GetHostWritePt( Bitu phys_page ) { + return GetHostReadPt( phys_page ); + } +}; + +class VGA_MMIO_Handler : public PageHandler { public: Bit16u regmem[16384]; - - VGA_MMIO_PageHandler() { + VGA_MMIO_Handler() { flags=PFLAG_NOCODE; //memset(®mem[0], 0, sizeof(regmem)); } void writeb(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteB(port, val); if(port <= 0x4000) { if(port == 0x0000) { @@ -363,7 +502,7 @@ public: //LOG_MSG("MMIO: Write byte to %x with %x", addr, val); } void writew(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteW(port, val); if(port == 0x8118) IO_WriteW(0x9ae8, val); if(port <= 0x4000) { @@ -376,7 +515,7 @@ public: //LOG_MSG("MMIO: Write word to %x with %x", addr, val); } void writed(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteD(port, val); if(port == 0x8100) { IO_WriteW(0x86e8, (val >> 16)); @@ -391,9 +530,9 @@ public: IO_WriteW(0xe2e0, (val & 0xffff)); IO_WriteW(0xe2e8, (val >> 16)); } else { - IO_WriteW(0xe2e8, (val & 0xffff)); - IO_WriteW(0xe2e8, (val >> 16)); - } + IO_WriteW(0xe2e8, (val & 0xffff)); + IO_WriteW(0xe2e8, (val >> 16)); + } } //LOG_MSG("MMIO: Write dword to %x with %x", addr, val); @@ -405,7 +544,7 @@ public: return 0x00; } Bitu readw(PhysPt addr) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) return IO_ReadW(port); //LOG_MSG("MMIO: Read word from %x", addr); return 0x00; @@ -423,7 +562,7 @@ public: flags=PFLAG_READABLE|PFLAG_WRITEABLE; // |PFLAG_NOCODE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { if (phys_page>=0xb8) { phys_page-=0xb8; return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; @@ -432,6 +571,9 @@ public: return &vga.mem.linear[phys_page * 4096]; } } + HostPt GetHostWritePt(Bitu phys_page) { + return GetHostReadPt( phys_page ); + } }; class VGA_PCJR_PageHandler : public PageHandler { @@ -439,24 +581,31 @@ public: VGA_PCJR_PageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { phys_page-=0xb8; if (!vga.tandy.is_32k_mode) phys_page&=0x03; return MemBase+(vga.tandy.mem_bank << 14)+(phys_page * 4096); } + HostPt GetHostWritePt(Bitu phys_page) { + return GetHostReadPt( phys_page ); + } }; static struct vg { - VGA_MAP_PageHandler hmap; - VGA_TEXT_PageHandler htext; - VGA_TANDY_PageHandler htandy; - VGA_PCJR_PageHandler hpcjr; - VGA_256_PageHandler h256; - VGA_256Chain4_PageHandler h256c4; - VGA_16_PageHandler h16; - VGA_16Chain4_PageHandler h16c4; - VGA_MMIO_PageHandler mmio; + VGA_MAP_PageHandler map; + VGA_TEXT_PageHandler text; + VGA_TANDY_PageHandler tandy; + VGA_ChainedEGA_Handler cega; + VGA_ChainedVGA_Handler cvga; + VGA_UnchainedEGA_Handler uega; + VGA_UnchainedVGA_Handler uvga; + VGA_PCJR_PageHandler hpcjr; + VGA_LIN4Banked_Handler l4banked; + VGA_LIN4Linear_Handler l4linear; + VGA_LFB_Handler lfb; + VGA_LFBChanges_Handler lfbchanges; + VGA_MMIO_Handler mmio; } vgaph; @@ -464,14 +613,14 @@ void VGA_SetupHandlers(void) { PageHandler * range_handler; switch (machine) { case MCH_CGA: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; goto range_b800; case MCH_HERC: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; if (vga.herc.mode_control&0x80) goto range_b800; else goto range_b000; case MCH_TANDY: - range_handler=&vgaph.htandy; + range_handler=&vgaph.tandy; MEM_SetPageHandler(0x80,32,range_handler); goto range_b800; case MCH_PCJR: @@ -482,31 +631,39 @@ void VGA_SetupHandlers(void) { switch (vga.mode) { case M_ERROR: return; + case M_LIN4: + range_handler=&vgaph.l4banked; + break; case M_LIN8: - range_handler=&vgaph.hmap; + case M_LIN15: + case M_LIN16: + case M_LIN32: + range_handler=&vgaph.map; break; case M_VGA: if (vga.config.chained) { if(vga.config.compatible_chain4) - range_handler = &vgaph.h256c4; + range_handler = &vgaph.cvga; else - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; } else { - range_handler=&vgaph.h256; + range_handler=&vgaph.uvga; } break; - case M_EGA16: - if (vga.config.chained) range_handler=&vgaph.h16c4; - else range_handler=&vgaph.h16; + case M_EGA: + if (vga.config.chained) + range_handler=&vgaph.cega; + else + range_handler=&vgaph.uega; break; case M_TEXT: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.hmap; - else range_handler=&vgaph.htext; + if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.map; + else range_handler=&vgaph.text; break; case M_CGA4: case M_CGA2: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; break; } switch ((vga.gfx.miscellaneous >> 2) & 3) { @@ -539,28 +696,28 @@ range_b800: break; } - if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) + MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); PAGING_ClearTLB(); } -static bool lfb_update; - -static void VGA_DoUpdateLFB(Bitu val) { - lfb_update=false; - MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); -} - void VGA_StartUpdateLFB(void) { - if (!lfb_update) { - lfb_update=true; - PIC_AddEvent(VGA_DoUpdateLFB,0.100f); //100 microseconds later + vga.lfb.page = vga.s3.la_window << 4; + vga.lfb.addr = vga.s3.la_window << 16; + switch (vga.mode) { + case M_LIN4: + vga.lfb.handler = &vgaph.l4linear; + break; + default: + vga.lfb.handler = &vgaph.lfbchanges; + break; } + MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096, vga.lfb.handler ); } void VGA_MapMMIO(void) { MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); - } void VGA_UnmapMMIO(void) { diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index c63c53b2..3cefa5aa 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -23,12 +23,12 @@ static Bit8u flip=0; -void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen); -Bitu read_p3d4_vga(Bitu port,Bitu iolen); -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); -Bitu read_p3d5_vga(Bitu port,Bitu iolen); +void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen); +Bitu vga_read_p3d4(Bitu port,Bitu iolen); +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); +Bitu vga_read_p3d5(Bitu port,Bitu iolen); -static Bitu read_p3da(Bitu port,Bitu iolen) { +static Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; if (vga.config.retrace) { @@ -53,23 +53,26 @@ static Bitu read_p3da(Bitu port,Bitu iolen) { static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { vga.misc_output=val; if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,IO_MB); - IO_RegisterReadHandler(0x3d4,read_p3d4_vga,IO_MB); - IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3d5,read_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); - + IO_RegisterWriteHandler(0x3d4,vga_write_p3d4,IO_MB); + IO_RegisterReadHandler(0x3d4,vga_read_p3d4,IO_MB); + IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); + + IO_RegisterWriteHandler(0x3d5,vga_write_p3d5,IO_MB); + IO_RegisterReadHandler(0x3d5,vga_read_p3d5,IO_MB); + IO_FreeWriteHandler(0x3b4,IO_MB); IO_FreeReadHandler(0x3b4,IO_MB); IO_FreeWriteHandler(0x3b5,IO_MB); IO_FreeReadHandler(0x3b5,IO_MB); IO_FreeReadHandler(0x3ba,IO_MB); } else { - IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,IO_MB); - IO_RegisterReadHandler(0x3b4,read_p3d4_vga,IO_MB); - IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3b5,read_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); + IO_RegisterWriteHandler(0x3b4,vga_write_p3d4,IO_MB); + IO_RegisterReadHandler(0x3b4,vga_read_p3d4,IO_MB); + IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); + + IO_RegisterWriteHandler(0x3b5,vga_write_p3d5,IO_MB); + IO_RegisterReadHandler(0x3b5,vga_read_p3d5,IO_MB); + IO_FreeWriteHandler(0x3d4,IO_MB); IO_FreeReadHandler(0x3d4,IO_MB); @@ -121,9 +124,9 @@ void VGA_SetupMisc(void) { IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); } else if (machine==MCH_CGA || IS_TANDY_ARCH) { - IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); + IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); } else if (machine==MCH_HERC) { - IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); + IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); } } diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp new file mode 100644 index 00000000..b54400a0 --- /dev/null +++ b/src/hardware/vga_s3.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2002-2005 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + +void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { + switch (reg) { + case 0x31: /* CR31 Memory Configuration */ +//TODO Base address + vga.s3.reg_31 = val; + VGA_DetermineMode(); + break; + /* + 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if + set, disables if clear. + 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup + 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit + 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to + video memory above 256k. + 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index + 51h, for the 864/964 see index 69h. + 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode + for Alpha Mode Font Access. + 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area + C6800h-C7FFFh is mapped out, if set it is accessible. + */ + case 0x35: /* CR35 CRT Register Lock */ + if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection + vga.s3.reg_35=val & 0xf0; + if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { + vga.s3.bank&=0xf0; + vga.s3.bank|=val & 0xf; + VGA_SetupHandlers(); + } + break; + /* + 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h + index 51h bits 2-3. For the 864/964 see index 6Ah. + 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 + (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set + 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index + 0,1,2,3,4,5,17h bit 2 if set + 6 (911/924) Lock VSync Polarity. + 7 (911/924) Lock HSync Polarity. + */ + case 0x38: /* CR38 Register Lock 1 */ + vga.s3.reg_lock1=val; + break; + case 0x39: /* CR39 Register Lock 2 */ + vga.s3.reg_lock2=val; + break; + case 0x40: /* CR40 System Config */ + vga.s3.reg_40 = val; + break; + case 0x43: /* CR43 Extended Mode */ + vga.s3.reg_43=val & ~0x4; + if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { + vga.config.scan_len&=0x2ff; + vga.config.scan_len|=(val & 0x4) << 6; + VGA_CheckScanLength(); + } + break; + /* + 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ + (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 + are 0 + */ + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.curmode = val; + // Activate hardware cursor code if needed + VGA_ActivateHardwareCursor(); + break; + case 0x46: + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); + break; + case 0x47: /* HGC orgX */ + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; + break; + case 0x48: + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); + break; + case 0x49: /* HGC orgY */ + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; + break; + case 0x4A: /* HGC foreground stack */ + if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; + vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; + vga.s3.hgc.fstackpos++; + break; + case 0x4B: /* HGC background stack */ + if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; + vga.s3.hgc.bstackpos++; + break; + case 0x4c: /* HGC start address high byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + break; + case 0x4d: /* HGC start address low byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + break; + case 0x4e: /* HGC pattern start X */ + vga.s3.hgc.posx = val; + break; + case 0x4f: /* HGC pattern start X */ + vga.s3.hgc.posy = val; + break; + case 0x51: /* Extended System Control 2 */ + vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 + //TODO Display start + vga.config.display_start&=0xFCFFFF; + vga.config.display_start|=(val & 3) << 16; + if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { + vga.s3.bank&=0xcf; + vga.s3.bank|=(val&0xc)<<2; + VGA_SetupHandlers(); + } + if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { + vga.config.scan_len&=0xff; + vga.config.scan_len|=(val & 0x30) << 4; + VGA_CheckScanLength(); + } + break; + /* + 0 (80x) Display Start Address bit 18 + 0-1 (928 +) Display Start Address bit 18-19 + Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index + 0Ch,0Dh. For the 864/964 see 3d4h index 69h + 2 (80x) CPU BASE. CPU Base Address Bit 18. + 2-3 (928 +) Old CPU Base Address Bits 19-18. + 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. + For the 864/964 see 3d4h index 6Ah + 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register + (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active + 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers + allows transferring one half of the VRAM shift register data while + the other half is being output. For the 964 Split Transfers + must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They + probably can't time the VRAM load cycle closely enough while the + graphics engine is running. + 7 (not 864/964) Enable EPROM Write. If set enables flash memory write + control to the BIOS ROM address + */ + case 0x53: + if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { + /* Map or unmap MMIO */ + if ((val & 0x10) != 0) { + //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); +// VGA_MapMMIO(); + } else { +// VGA_UnmapMMIO(); + } + } + vga.s3.ext_mem_ctrl = val; + break; + case 0x55: /* Extended Video DAC Control */ + vga.s3.reg_55=val; + break; + /* + 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the + RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. + If this field is 0, 3d4h index 43h bit 1 is active. + 2 Enable General Input Port Read. If set DAC reads are disabled and the + STRD strobe for reading the General Input Port is enabled for reading + while DACRD is active, if clear DAC reads are enabled. + 3 (928) Enable External SID Operation if set. If set video data is + passed directly from the VRAMs to the DAC rather than through the + VGA chip + 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 + mode, if clear in MS-Windows mode + 5 (80x,928) Hardware Cursor External Operation Mode. If set the two + bits of cursor data ,is output on the HC[0-1] pins for the video DAC + The SENS pin becomes HC1 and the MID2 pin becomes HC0. + 6 ?? + 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. + (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri + -stated if set + */ + case 0x58: /* Linear Address Window Control */ + vga.s3.reg_58=val; + break; + /* + 0-1 Linear Address Window Size. Must be less than or equal to video + memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) + 2 (not 864/964) Enable Read Ahead Cache if set + 3 (80x,928) ISA Latch Address. If set latches address during every ISA + cycle, unlatches during every ISA cycle if clear. + (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set + address latching occours in the T1 cycle, if clear in the T2 cycle + (I.e. one clock cycle delayed). + 4 ENB LA. Enable Linear Addressing if set. + 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write + -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. + 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM + control is 256 words, if clear 512 words. + 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, + if clear 7MCLKs + */ + case 0x59: /* Linear Address Window Position High */ + if ((vga.s3.la_window&0xff00) ^ (val << 8)) { + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + VGA_StartUpdateLFB(); + } + break; + case 0x5a: /* Linear Address Window Position Low */ + if ((vga.s3.la_window&0x00ff) ^ val) { + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + VGA_StartUpdateLFB(); + } + break; + case 0x5D: /* Extended Horizontal Overflow */ + if ((val & vga.s3.ex_hor_overflow) ^ 3) { + vga.s3.ex_hor_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_hor_overflow=val; + break; + /* + 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h + index 0) + 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End + register (3d4h index 1) + 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking + register (3d4h index 2). + 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse + is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or + does it really extend by 64 ? + 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start + Retrace register (3d4h index 4). + 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse + is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or + does it really extend by 32 ? + 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer + Position register (3d4h index 3Bh) + 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant + Termination register (3d4h index 5Fh). + */ + case 0x5e: /* Extended Vertical Overflow */ + vga.config.line_compare=(vga.config.line_compare & 0x3ff) | (val & 0x40) << 4; + if ((val ^ vga.s3.ex_ver_overflow) & 0x3) { + vga.s3.ex_ver_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_ver_overflow=val; + break; + /* + 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h + index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. + 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End + register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 + and 6 + 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking + register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 + in 3d4h index 9 bit 5 + 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace + register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 + and 7. + 6 Line Compare Position bit 10. Bit 10 of the Line Compare register + (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h + index 9 bit 6. + */ + case 0x67: /* Extended Miscellaneous Control 2 */ + /* + 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted + DCLK, if set VCLK = DCLK. + 4-7 Pixel format. + 0 Mode 0: 8bit (1 pixel/VCLK) + 1 Mode 8: 8bit (2 pixels/VCLK) + 3 Mode 9: 15bit (1 pixel/VCLK) + 5 Mode 10: 16bit (1 pixel/VCLK) + 7 Mode 11: 24/32bit (2 VCLKs/pixel) + 13 (732/764) 32bit (1 pixel/VCLK) + */ + vga.s3.misc_control_2=val; + VGA_DetermineMode(); + break; + case 0x69: /* Extended System Control 3 */ + if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { + vga.config.display_start&=0xffff; + vga.config.display_start|=(val & 0x1f) << 16; + } + break; + case 0x6a: /* Extended System Control 4 */ + vga.s3.bank=val & 0x3f; + VGA_SetupHandlers(); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X", reg ); + break; + } +} + +Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { + switch (reg) { + case 0x2d: /* Extended Chip ID. */ + return 0x88; + // Always 88h ? + case 0x2e: /* New Chip ID */ + return 0x11; + //Trio 64 id + case 0x2f: /* Revision */ + return 0x00; + case 0x30: /* CR30 Chip ID/REV register */ + return 0xe0; //Trio+ dual byte + // Trio32/64 has 0xe0. extended + case 0x31: /* CR31 Memory Configuration */ +//TODO mix in bits from baseaddress; + return vga.s3.reg_31; + case 0x35: /* CR35 CRT Register Lock */ + return vga.s3.reg_35|(vga.s3.bank & 0xf); + case 0x36: /* CR36 Reset State Read 1 */ + //return 0x8f; + return 0x8e; /* PCI version */ + //2 Mb PCI and some bios settings + case 0x37: /* Reset state read 2 */ + return 0x2b; + case 0x38: /* CR38 Register Lock 1 */ + return vga.s3.reg_lock1; + case 0x39: /* CR39 Register Lock 2 */ + return vga.s3.reg_lock2; + case 0x40: /* CR40 system config */ + return vga.s3.reg_40; + case 0x43: /* CR43 Extended Mode */ + return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.fstackpos = 0; + return vga.s3.hgc.curmode; + case 0x51: /* Extended System Control 2 */ + return ((vga.config.display_start >> 16) & 3 ) | + ((vga.s3.bank & 0x30) >> 2) | + ((vga.config.scan_len & 0x300) >> 4) | + vga.s3.reg_51; + case 0x53: + return vga.s3.ext_mem_ctrl; + case 0x55: /* Extended Video DAC Control */ + return vga.s3.reg_55; + case 0x58: /* Linear Address Window Control */ + return vga.s3.reg_58; + case 0x59: /* Linear Address Window Position High */ + return (vga.s3.la_window >> 8); + case 0x5a: /* Linear Address Window Position Low */ + return (vga.s3.la_window & 0xff); + case 0x5D: /* Extended Horizontal Overflow */ + return vga.s3.ex_hor_overflow; + case 0x5e: /* Extended Vertical Overflow */ + return vga.s3.ex_ver_overflow; + case 0x67: /* Extended Miscellaneous Control 2 */ + return vga.s3.misc_control_2; + case 0x69: /* Extended System Control 3 */ + return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); + case 0x6a: /* Extended System Control 4 */ + return (Bit8u)(vga.s3.bank & 0x3f); + default: + return 0x00; + } +} + +void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen) { + switch (reg) { + case 0x08: + vga.s3.pll.lock=val; + break; + case 0x10: /* Memory PLL Data Low */ + vga.s3.mclk.n=val & 0x1f; + vga.s3.mclk.r=val >> 5; + break; + case 0x11: /* Memory PLL Data High */ + vga.s3.mclk.m=val & 0x7f; + break; + case 0x12: /* Video PLL Data Low */ + vga.s3.clk[3].n=val & 0x1f; + vga.s3.clk[3].r=val >> 5; + break; + case 0x13: /* Video PLL Data High */ + vga.s3.clk[3].m=val & 0x7f; + break; + case 0x15: + vga.s3.pll.cmd=val; + VGA_StartResize(); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Write to illegal index %2X", reg ); + break; + } +} + +Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen) { + /* S3 specific group */ + switch (reg) { + case 0x08: /* PLL Unlock */ + return vga.s3.pll.lock; + case 0x10: /* Memory PLL Data Low */ + return vga.s3.mclk.n || (vga.s3.mclk.r << 5); + case 0x11: /* Memory PLL Data High */ + return vga.s3.mclk.m; + case 0x12: /* Video PLL Data Low */ + return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); + case 0x13: /* Video Data High */ + return vga.s3.clk[3].m; + case 0x15: + return vga.s3.pll.cmd; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Read from illegal index %2X", reg); + return 0; + } +} + +Bitu SVGA_S3_GetClock(void) { + Bitu clock = (vga.misc_output >> 2) & 3; + if (clock == 0) + clock = 25175000; + else if (clock == 1) + clock = 28322000; + else + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + return clock; +} \ No newline at end of file diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index e001ea9a..6015d0ef 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -98,33 +98,16 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { else vga.config.chained=false; VGA_SetupHandlers(); break; -/* S3 specific group */ - case 0x08: - vga.s3.pll.lock=val; - break; - case 0x10: /* Memory PLL Data Low */ - vga.s3.mclk.n=val & 0x1f; - vga.s3.mclk.r=val >> 5; - break; - case 0x11: /* Memory PLL Data High */ - vga.s3.mclk.m=val & 0x7f; - break; - case 0x12: /* Video PLL Data Low */ - vga.s3.clk[3].n=val & 0x1f; - vga.s3.clk[3].r=val >> 5; - break; - case 0x13: /* Video PLL Data High */ - vga.s3.clk[3].m=val & 0x7f; - break; - case 0x15: - vga.s3.pll.cmd=val; - VGA_StartResize(); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); - }; -}; + switch (svgaCard) { + case SVGA_S3Trio: + SVGA_S3_WriteSEQ( seq(index), val, iolen ); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); + } + } +} Bitu read_p3c5(Bitu port,Bitu iolen) { @@ -145,25 +128,14 @@ Bitu read_p3c5(Bitu port,Bitu iolen) { break; case 4: /* Memory Mode */ return seq(memory_mode); - /* S3 specific group */ - case 0x08: /* PLL Unlock */ - return vga.s3.pll.lock; - case 0x10: /* Memory PLL Data Low */ - return vga.s3.mclk.n || (vga.s3.mclk.r << 5); - case 0x11: /* Memory PLL Data High */ - return vga.s3.mclk.m; - case 0x12: /* Video PLL Data Low */ - return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); - case 0x13: /* Video Data High */ - return vga.s3.clk[3].m; - case 0x15: - return vga.s3.pll.cmd; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Read from illegal index %2X",seq(index)); - }; + switch (svgaCard) { + case SVGA_S3Trio: + return SVGA_S3_ReadSEQ( seq(index), iolen ); + } + } return 0; -}; +} void VGA_SetupSEQ(void) { diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index f600dda7..1fe0c121 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -35,8 +35,8 @@ struct XGAStatus { Bit32u readmask; Bit32u writemask; - Bit32u forecolor; - Bit32u backcolor; + Bit8u forecolor; + Bit8u backcolor; Bitu curcommand; @@ -189,7 +189,7 @@ void XGA_DrawLineVector(Bitu val) { Bit8u dstdata; Bits i; - Bits dx, sx, dy, sy, e; + Bits dx, sx, sy; dx = xga.MAPcount; xat = xga.curx; @@ -487,7 +487,7 @@ void XGA_DrawWait(Bitu val, Bitu len) { switch(mixmode) { case 0x00: /* FOREMIX always used */ mixmode = xga.foremix; - int t; + Bitu t; for(t=0;t> (8 * t)) & 0xff; switch((mixmode >> 5) & 0x03) { @@ -616,7 +616,7 @@ void XGA_DrawWait(Bitu val, Bitu len) { void XGA_BlitRect(Bitu val) { Bit32u xat, yat; - Bit32u xmass, xmod, xdist, memrec; +// Bit32u xmass, xmod, xdist, memrec; //Bit8u *srcptr; //Bit8u *destptr; //Bit8u *destline;