1
0
Fork 0

Rewrtites of most memory and drawing handlers

Some splitting of the s3 hardware into a seperate module
Support for 15/16/32bpp modes
Support for a highres 4bpp mode


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2446
This commit is contained in:
Sjoerd van der Berg 2006-01-30 10:04:03 +00:00
parent 8bc8960ab7
commit c196fba725
10 changed files with 968 additions and 663 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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_addr<vga.draw.blocks) {
if (line<vga.draw.cursor.sline) goto skip_cursor;
if (line>vga.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<hdispend) hdispend=hbstart;
if (vbstart<vdispend) vdispend=vbstart;
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);
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);
}
};

View file

@ -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(&regmem[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) {

View file

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

432
src/hardware/vga_s3.cpp Normal file
View file

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

View file

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

View file

@ -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<len;t++) {
tmpval = (val >> (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;