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:
parent
8bc8960ab7
commit
c196fba725
10 changed files with 968 additions and 663 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
432
src/hardware/vga_s3.cpp
Normal 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;
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue