DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #include "dosbox.h" 00021 #include "inout.h" 00022 #include "vga.h" 00023 #include "mem.h" 00024 #include "pci_bus.h" 00025 00026 void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { 00027 (void)iolen;//UNUSED 00028 switch (reg) { 00029 case 0x31: /* CR31 Memory Configuration */ 00030 //TODO Base address 00031 vga.s3.reg_31 = (Bit8u)val; 00032 vga.config.compatible_chain4 = !(val&0x08); 00033 // if (vga.config.compatible_chain4) vga.vmemwrap = 256*1024; 00034 // else vga.vmemwrap = vga.mem.memsize; 00035 vga.config.display_start = (vga.config.display_start&~0x30000ul)|((val&0x30u)<<12ul); 00036 VGA_DetermineMode(); 00037 VGA_SetupHandlers(); 00038 break; 00039 /* 00040 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if 00041 set, disables if clear. 00042 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup 00043 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit 00044 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to 00045 video memory above 256k. 00046 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 00047 51h, for the 864/964 see index 69h. 00048 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode 00049 for Alpha Mode Font Access. 00050 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area 00051 C6800h-C7FFFh is mapped out, if set it is accessible. 00052 */ 00053 case 0x35: /* CR35 CRT Register Lock */ 00054 if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection 00055 vga.s3.reg_35=val & 0xf0; 00056 if ((vga.svga.bank_read & 0xf) ^ (val & 0xf)) { 00057 vga.svga.bank_read&=0xf0; 00058 vga.svga.bank_read|=val & 0xf; 00059 vga.svga.bank_write = vga.svga.bank_read; 00060 VGA_SetupHandlers(); 00061 } 00062 break; 00063 /* 00064 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h 00065 index 51h bits 2-3. For the 864/964 see index 6Ah. 00066 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 00067 (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set 00068 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index 00069 0,1,2,3,4,5,17h bit 2 if set 00070 6 (911/924) Lock VSync Polarity. 00071 7 (911/924) Lock HSync Polarity. 00072 */ 00073 case 0x38: /* CR38 Register Lock 1 */ 00074 vga.s3.reg_lock1=(Bit8u)val; 00075 break; 00076 case 0x39: /* CR39 Register Lock 2 */ 00077 vga.s3.reg_lock2=(Bit8u)val; 00078 break; 00079 case 0x3a: 00080 vga.s3.reg_3a = (Bit8u)val; 00081 break; 00082 case 0x40: /* CR40 System Config */ 00083 vga.s3.reg_40 = (Bit8u)val; 00084 break; 00085 case 0x41: /* CR41 BIOS flags */ 00086 vga.s3.reg_41 = (Bit8u)val; 00087 break; 00088 case 0x42: /* CR42 Mode Control */ 00089 if ((val ^ vga.s3.reg_42) & 0x20) { 00090 vga.s3.reg_42= (Bit8u)val; 00091 VGA_StartResize(); 00092 } else vga.s3.reg_42= (Bit8u)val; 00093 /* 00094 3d4h index 42h (R/W): CR42 Mode Control 00095 bit 0-3 DCLK Select. These bits are effective when the VGA Clock Select 00096 (3C2h/3CCh bit 2-3) is 3. 00097 5 Interlaced Mode if set. 00098 */ 00099 break; 00100 case 0x43: /* CR43 Extended Mode */ 00101 vga.s3.reg_43= (Bit8u)val & ~0x4u; 00102 if ((((Bit8u)val & 0x4u) ^ (vga.config.scan_len >> 6u)) & 0x4u) { 00103 vga.config.scan_len&=0x2ffu; 00104 vga.config.scan_len|=((Bit8u)val & 0x4u) << 6u; 00105 VGA_CheckScanLength(); 00106 } 00107 break; 00108 /* 00109 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ 00110 (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 00111 are 0 00112 */ 00113 case 0x45: /* Hardware cursor mode */ 00114 vga.s3.hgc.curmode = (Bit8u)val; 00115 // Activate hardware cursor code if needed 00116 VGA_ActivateHardwareCursor(); 00117 break; 00118 case 0x46: 00119 vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | ((Bit8u)val << 8u); 00120 break; 00121 case 0x47: /* HGC orgX */ 00122 vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | (Bit8u)val; 00123 break; 00124 case 0x48: 00125 vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | ((Bit8u)val << 8u); 00126 break; 00127 case 0x49: /* HGC orgY */ 00128 vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | (Bit8u)val; 00129 break; 00130 case 0x4A: /* HGC foreground stack */ 00131 if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; 00132 vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = (Bit8u)val; 00133 vga.s3.hgc.fstackpos++; 00134 break; 00135 case 0x4B: /* HGC background stack */ 00136 if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; 00137 vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = (Bit8u)val; 00138 vga.s3.hgc.bstackpos++; 00139 break; 00140 case 0x4c: /* HGC start address high byte*/ 00141 vga.s3.hgc.startaddr &=0xff; 00142 vga.s3.hgc.startaddr |= (((Bit8u)val & 0xf) << 8); 00143 if ((((Bitu)vga.s3.hgc.startaddr)<<10)+((64*64*2)/8) > vga.mem.memsize) { 00144 vga.s3.hgc.startaddr &= 0xff; // put it back to some sane area; 00145 // if read back of this address is ever implemented this needs to change 00146 LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:CRTC: HGC pattern address beyond video memory" ); 00147 } 00148 break; 00149 case 0x4d: /* HGC start address low byte*/ 00150 vga.s3.hgc.startaddr &=0xff00; 00151 vga.s3.hgc.startaddr |= ((Bit8u)val & 0xff); 00152 break; 00153 case 0x4e: /* HGC pattern start X */ 00154 vga.s3.hgc.posx = (Bit8u)val & 0x3f; // bits 0-5 00155 break; 00156 case 0x4f: /* HGC pattern start Y */ 00157 vga.s3.hgc.posy = (Bit8u)val & 0x3f; // bits 0-5 00158 break; 00159 case 0x50: // Extended System Control 1 00160 vga.s3.reg_50 = (Bit8u)val; 00161 switch (val & S3_XGA_CMASK) { 00162 case S3_XGA_32BPP: vga.s3.xga_color_mode = M_LIN32; break; 00163 case S3_XGA_16BPP: vga.s3.xga_color_mode = M_LIN16; break; 00164 case S3_XGA_8BPP: vga.s3.xga_color_mode = M_LIN8; break; 00165 } 00166 switch (val & S3_XGA_WMASK) { 00167 case S3_XGA_1024: vga.s3.xga_screen_width = 1024; break; 00168 case S3_XGA_1152: vga.s3.xga_screen_width = 1152; break; 00169 case S3_XGA_640: vga.s3.xga_screen_width = 640; break; 00170 case S3_XGA_800: vga.s3.xga_screen_width = 800; break; 00171 case S3_XGA_1280: vga.s3.xga_screen_width = 1280; break; 00172 case S3_XGA_1600: vga.s3.xga_screen_width = 1600; break; 00173 default: vga.s3.xga_screen_width = 1024; break; 00174 } 00175 break; 00176 case 0x51: /* Extended System Control 2 */ 00177 vga.s3.reg_51= (Bit8u)val & 0xc0; //Only store bits 6,7 00178 vga.config.display_start&=0xF3FFFF; 00179 vga.config.display_start|=((Bit8u)val & 3u) << 18u; 00180 if ((vga.svga.bank_read&0x30u) ^ (((Bit8u)val&0xcu)<<2u)) { 00181 vga.svga.bank_read&=0xcfu; 00182 vga.svga.bank_read|=((Bit8u)val&0xcu)<<2u; 00183 vga.svga.bank_write = vga.svga.bank_read; 00184 VGA_SetupHandlers(); 00185 } 00186 if (((val & 0x30u) ^ (vga.config.scan_len >> 4u)) & 0x30u) { 00187 vga.config.scan_len&=0xffu; 00188 vga.config.scan_len|=((Bit8u)val & 0x30u) << 4u; 00189 VGA_CheckScanLength(); 00190 } 00191 break; 00192 /* 00193 0 (80x) Display Start Address bit 18 00194 0-1 (928 +) Display Start Address bit 18-19 00195 Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index 00196 0Ch,0Dh. For the 864/964 see 3d4h index 69h 00197 2 (80x) CPU BASE. CPU Base Address Bit 18. 00198 2-3 (928 +) Old CPU Base Address Bits 19-18. 00199 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. 00200 For the 864/964 see 3d4h index 6Ah 00201 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register 00202 (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active 00203 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers 00204 allows transferring one half of the VRAM shift register data while 00205 the other half is being output. For the 964 Split Transfers 00206 must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They 00207 probably can't time the VRAM load cycle closely enough while the 00208 graphics engine is running. 00209 7 (not 864/964) Enable EPROM Write. If set enables flash memory write 00210 control to the BIOS ROM address 00211 */ 00212 case 0x52: // Extended System Control 1 00213 vga.s3.reg_52 = (Bit8u)val; 00214 break; 00215 case 0x53: 00216 // Map or unmap MMIO 00217 // bit 4 = MMIO at A0000 00218 // bit 3 = MMIO at LFB + 16M (should be fine if its always enabled for now) 00219 if(vga.s3.ext_mem_ctrl != (Bit8u)val) { 00220 vga.s3.ext_mem_ctrl = (Bit8u)val; 00221 VGA_SetupHandlers(); 00222 } 00223 break; 00224 case 0x55: /* Extended Video DAC Control */ 00225 vga.s3.reg_55=(Bit8u)val; 00226 break; 00227 /* 00228 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the 00229 RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. 00230 If this field is 0, 3d4h index 43h bit 1 is active. 00231 2 Enable General Input Port Read. If set DAC reads are disabled and the 00232 STRD strobe for reading the General Input Port is enabled for reading 00233 while DACRD is active, if clear DAC reads are enabled. 00234 3 (928) Enable External SID Operation if set. If set video data is 00235 passed directly from the VRAMs to the DAC rather than through the 00236 VGA chip 00237 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 00238 mode, if clear in MS-Windows mode 00239 5 (80x,928) Hardware Cursor External Operation Mode. If set the two 00240 bits of cursor data ,is output on the HC[0-1] pins for the video DAC 00241 The SENS pin becomes HC1 and the MID2 pin becomes HC0. 00242 6 ?? 00243 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. 00244 (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri 00245 -stated if set 00246 */ 00247 case 0x58: /* Linear Address Window Control */ 00248 vga.s3.reg_58=(Bit8u)val; 00249 VGA_StartUpdateLFB(); 00250 break; 00251 /* 00252 0-1 Linear Address Window Size. Must be less than or equal to video 00253 memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) 00254 2 (not 864/964) Enable Read Ahead Cache if set 00255 3 (80x,928) ISA Latch Address. If set latches address during every ISA 00256 cycle, unlatches during every ISA cycle if clear. 00257 (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set 00258 address latching occours in the T1 cycle, if clear in the T2 cycle 00259 (I.e. one clock cycle delayed). 00260 4 ENB LA. Enable Linear Addressing if set. 00261 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write 00262 -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. 00263 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM 00264 control is 256 words, if clear 512 words. 00265 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, 00266 if clear 7MCLKs 00267 */ 00268 case 0x59: /* Linear Address Window Position High */ 00269 if ((vga.s3.la_window&0xff00) ^ ((Bit8u)val << 8)) { 00270 vga.s3.la_window=(vga.s3.la_window&0x00ff) | ((Bit8u)val << 8); 00271 VGA_StartUpdateLFB(); 00272 } 00273 break; 00274 case 0x5a: /* Linear Address Window Position Low */ 00275 if ((vga.s3.la_window&0x00ff) ^ (Bit8u)val) { 00276 vga.s3.la_window=(vga.s3.la_window&0xff00) | (Bit8u)val; 00277 VGA_StartUpdateLFB(); 00278 } 00279 break; 00280 case 0x5D: /* Extended Horizontal Overflow */ 00281 if ((val ^ vga.s3.ex_hor_overflow) & 3) { 00282 vga.s3.ex_hor_overflow=(Bit8u)val; 00283 VGA_StartResize(); 00284 } else vga.s3.ex_hor_overflow=(Bit8u)val; 00285 break; 00286 /* 00287 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h 00288 index 0) 00289 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End 00290 register (3d4h index 1) 00291 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking 00292 register (3d4h index 2). 00293 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse 00294 is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or 00295 does it really extend by 64 ? 00296 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start 00297 Retrace register (3d4h index 4). 00298 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse 00299 is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or 00300 does it really extend by 32 ? 00301 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer 00302 Position register (3d4h index 3Bh) 00303 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant 00304 Termination register (3d4h index 5Fh). 00305 */ 00306 case 0x5e: /* Extended Vertical Overflow */ 00307 vga.config.line_compare=(vga.config.line_compare & 0x3ffu) | ((Bit8u)val & 0x40u) << 4u; 00308 if ((val ^ vga.s3.ex_ver_overflow) & 0x3u) { 00309 vga.s3.ex_ver_overflow=(Bit8u)val; 00310 VGA_StartResize(); 00311 } else vga.s3.ex_ver_overflow=(Bit8u)val; 00312 break; 00313 /* 00314 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h 00315 index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. 00316 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End 00317 register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 00318 and 6 00319 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking 00320 register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 00321 in 3d4h index 9 bit 5 00322 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace 00323 register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 00324 and 7. 00325 6 Line Compare Position bit 10. Bit 10 of the Line Compare register 00326 (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h 00327 index 9 bit 6. 00328 */ 00329 case 0x67: /* Extended Miscellaneous Control 2 */ 00330 /* 00331 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted 00332 DCLK, if set VCLK = DCLK. 00333 2-3 (Trio64V+) streams mode 00334 00 disable Streams Processor 00335 01 overlay secondary stream on VGA-mode background 00336 10 reserved 00337 11 full Streams Processor operation 00338 4-7 Pixel format. 00339 0 Mode 0: 8bit (1 pixel/VCLK) 00340 1 Mode 8: 8bit (2 pixels/VCLK) 00341 3 Mode 9: 15bit (1 pixel/VCLK) 00342 5 Mode 10: 16bit (1 pixel/VCLK) 00343 7 Mode 11: 24/32bit (2 VCLKs/pixel) 00344 13 (732/764) 32bit (1 pixel/VCLK) 00345 */ 00346 vga.s3.misc_control_2=(Bit8u)val; 00347 VGA_DetermineMode(); 00348 break; 00349 case 0x69: /* Extended System Control 3 */ 00350 if (((vga.config.display_start & 0x1f0000u)>>16u) ^ (val & 0x1fu)) { 00351 vga.config.display_start&=0xffffu; 00352 vga.config.display_start|=((Bit8u)val & 0x1fu) << 16u; 00353 } 00354 break; 00355 case 0x6a: /* Extended System Control 4 */ 00356 vga.svga.bank_read=(Bit8u)val & 0x7f; 00357 vga.svga.bank_write = vga.svga.bank_read; 00358 VGA_SetupHandlers(); 00359 break; 00360 case 0x6b: // BIOS scratchpad: LFB address 00361 vga.s3.reg_6b=(Bit8u)val; 00362 break; 00363 default: 00364 LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:CRTC:Write to illegal index %2X", (int)reg ); 00365 break; 00366 } 00367 } 00368 00369 Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { 00370 (void)iolen;//UNUSED 00371 switch (reg) { 00372 case 0x24: /* attribute controller index (read only) */ 00373 case 0x26: 00374 return ((vga.attr.disabled & 1u)?0x00u:0x20u) | (vga.attr.index & 0x1fu); 00375 case 0x2d: /* Extended Chip ID (high byte of PCI device ID) */ 00376 return 0x88; 00377 case 0x2e: /* New Chip ID (low byte of PCI device ID) */ 00378 return 0x11; // Trio64 00379 case 0x2f: /* Revision */ 00380 return 0x00; // Trio64 (exact value?) 00381 // return 0x44; // Trio64 V+ 00382 case 0x30: /* CR30 Chip ID/REV register */ 00383 return 0xe1; // Trio+ dual byte 00384 case 0x31: /* CR31 Memory Configuration */ 00385 //TODO mix in bits from baseaddress; 00386 return vga.s3.reg_31; 00387 case 0x35: /* CR35 CRT Register Lock */ 00388 return vga.s3.reg_35|(vga.svga.bank_read & 0xfu); 00389 case 0x36: /* CR36 Reset State Read 1 */ 00390 return vga.s3.reg_36; 00391 case 0x37: /* Reset state read 2 */ 00392 return 0x2b; 00393 case 0x38: /* CR38 Register Lock 1 */ 00394 return vga.s3.reg_lock1; 00395 case 0x39: /* CR39 Register Lock 2 */ 00396 return vga.s3.reg_lock2; 00397 case 0x3a: 00398 return vga.s3.reg_3a; 00399 case 0x40: /* CR40 system config */ 00400 return vga.s3.reg_40; 00401 case 0x41: /* CR40 system config */ 00402 return vga.s3.reg_41; 00403 case 0x42: // not interlaced 00404 return 0x0d; 00405 case 0x43: /* CR43 Extended Mode */ 00406 return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); 00407 case 0x45: /* Hardware cursor mode */ 00408 vga.s3.hgc.bstackpos = 0; 00409 vga.s3.hgc.fstackpos = 0; 00410 return vga.s3.hgc.curmode|0xa0u; 00411 case 0x46: 00412 return (unsigned int)vga.s3.hgc.originx>>8u; 00413 case 0x47: /* HGC orgX */ 00414 return vga.s3.hgc.originx&0xffu; 00415 case 0x48: 00416 return (unsigned int)vga.s3.hgc.originy>>8u; 00417 case 0x49: /* HGC orgY */ 00418 return vga.s3.hgc.originy&0xffu; 00419 case 0x4A: /* HGC foreground stack */ 00420 return vga.s3.hgc.forestack[vga.s3.hgc.fstackpos]; 00421 case 0x4B: /* HGC background stack */ 00422 return vga.s3.hgc.backstack[vga.s3.hgc.bstackpos]; 00423 case 0x50: // CR50 Extended System Control 1 00424 return vga.s3.reg_50; 00425 case 0x51: /* Extended System Control 2 */ 00426 return ((vga.config.display_start >> 16u) & 3u) | 00427 ((vga.svga.bank_read & 0x30u) >> 2u) | 00428 ((vga.config.scan_len & 0x300u) >> 4u) | 00429 vga.s3.reg_51; 00430 case 0x52: // CR52 Extended BIOS flags 1 00431 return vga.s3.reg_52; 00432 case 0x53: 00433 return vga.s3.ext_mem_ctrl; 00434 case 0x55: /* Extended Video DAC Control */ 00435 return vga.s3.reg_55; 00436 case 0x58: /* Linear Address Window Control */ 00437 return vga.s3.reg_58; 00438 case 0x59: /* Linear Address Window Position High */ 00439 return ((unsigned int)vga.s3.la_window >> 8u); 00440 case 0x5a: /* Linear Address Window Position Low */ 00441 return (vga.s3.la_window & 0xff); 00442 case 0x5D: /* Extended Horizontal Overflow */ 00443 return vga.s3.ex_hor_overflow; 00444 case 0x5e: /* Extended Vertical Overflow */ 00445 return vga.s3.ex_ver_overflow; 00446 case 0x67: /* Extended Miscellaneous Control 2 */ 00447 return vga.s3.misc_control_2; 00448 case 0x69: /* Extended System Control 3 */ 00449 return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); 00450 case 0x6a: /* Extended System Control 4 */ 00451 return (Bit8u)(vga.svga.bank_read & 0x7f); 00452 case 0x6b: // BIOS scatchpad: LFB address 00453 return vga.s3.reg_6b; 00454 default: 00455 return 0x00; 00456 } 00457 } 00458 00459 void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen) { 00460 (void)iolen;//UNUSED 00461 if (reg>0x8 && vga.s3.pll.lock!=0x6) return; 00462 switch (reg) { 00463 case 0x08: 00464 vga.s3.pll.lock=(Bit8u)val; 00465 break; 00466 case 0x10: /* Memory PLL Data Low */ 00467 vga.s3.mclk.n=(Bit8u)val & 0x1f; 00468 vga.s3.mclk.r=(Bit8u)val >> 5; 00469 break; 00470 case 0x11: /* Memory PLL Data High */ 00471 vga.s3.mclk.m=(Bit8u)val & 0x7f; 00472 break; 00473 case 0x12: /* Video PLL Data Low */ 00474 vga.s3.clk[3].n=(Bit8u)val & 0x1f; 00475 vga.s3.clk[3].r=(Bit8u)val >> 5; 00476 break; 00477 case 0x13: /* Video PLL Data High */ 00478 vga.s3.clk[3].m=(Bit8u)val & 0x7f; 00479 break; 00480 case 0x15: 00481 vga.s3.pll.cmd=(Bit8u)val; 00482 VGA_StartResize(); 00483 break; 00484 default: 00485 LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Write to illegal index %2X", (int)reg ); 00486 break; 00487 } 00488 } 00489 00490 // to make the S3 Trio64 BIOS work 00491 const Bit8u reg17ret[] ={0x7b, 0xc0, 0x0, 0xda}; 00492 Bit8u reg17index=0; 00493 00494 Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen) { 00495 (void)iolen;//UNUSED 00496 /* S3 specific group */ 00497 if (reg>0x8 && vga.s3.pll.lock!=0x6) { 00498 if (reg<0x1b) return 0; 00499 else return reg; 00500 } 00501 switch (reg) { 00502 case 0x08: /* PLL Unlock */ 00503 return vga.s3.pll.lock; 00504 case 0x10: /* Memory PLL Data Low */ 00505 return vga.s3.mclk.n || ((vga.s3.mclk.r << 5) != 0); /* FIXME: What is this testing exactly? */ 00506 case 0x11: /* Memory PLL Data High */ 00507 return vga.s3.mclk.m; 00508 case 0x12: /* Video PLL Data Low */ 00509 return vga.s3.clk[3].n || ((vga.s3.clk[3].r << 5) != 0); /* FIXME: What is this testing exactly? */ 00510 case 0x13: /* Video Data High */ 00511 return vga.s3.clk[3].m; 00512 case 0x15: 00513 return vga.s3.pll.cmd; 00514 case 0x17: { 00515 Bit8u retval = reg17ret[reg17index]; 00516 reg17index++; 00517 if(reg17index>3)reg17index=0; 00518 return retval; 00519 } 00520 default: 00521 LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Read from illegal index %2X", (int)reg); 00522 return 0; 00523 } 00524 } 00525 00526 Bitu SVGA_S3_GetClock(void) { 00527 Bitu clock = (vga.misc_output >> 2) & 3; 00528 if (clock == 0) 00529 clock = 25175000; 00530 else if (clock == 1) 00531 clock = 28322000; 00532 else 00533 clock=1000ul * S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); 00534 /* Check for dual transfer, master clock/2 */ 00535 if (vga.s3.pll.cmd & 0x10) clock/=2; 00536 return clock; 00537 } 00538 00539 bool SVGA_S3_HWCursorActive(void) { 00540 return (vga.s3.hgc.curmode & 0x1) != 0; 00541 } 00542 00543 bool SVGA_S3_AcceptsMode(Bitu mode) { 00544 return VideoModeMemSize(mode) < vga.mem.memsize; 00545 } 00546 00547 void SVGA_Setup_S3Trio(void) { 00548 svga.write_p3d5 = &SVGA_S3_WriteCRTC; 00549 svga.read_p3d5 = &SVGA_S3_ReadCRTC; 00550 svga.write_p3c5 = &SVGA_S3_WriteSEQ; 00551 svga.read_p3c5 = &SVGA_S3_ReadSEQ; 00552 svga.write_p3c0 = 0; /* no S3-specific functionality */ 00553 svga.read_p3c1 = 0; /* no S3-specific functionality */ 00554 00555 svga.set_video_mode = 0; /* implemented in core */ 00556 svga.determine_mode = 0; /* implemented in core */ 00557 svga.set_clock = 0; /* implemented in core */ 00558 svga.get_clock = &SVGA_S3_GetClock; 00559 svga.hardware_cursor_active = &SVGA_S3_HWCursorActive; 00560 svga.accepts_mode = &SVGA_S3_AcceptsMode; 00561 00562 if (vga.mem.memsize == 0) 00563 vga.mem.memsize = 2*1024*1024; // the most common S3 configuration 00564 00565 // Set CRTC 36 to specify amount of VRAM and PCI 00566 if (vga.mem.memsize < 1024*1024) { 00567 vga.mem.memsize = 512*1024; 00568 vga.s3.reg_36 = 0xfa; // less than 1mb fast page mode 00569 } else if (vga.mem.memsize < 2048*1024) { 00570 vga.mem.memsize = 1024*1024; 00571 vga.s3.reg_36 = 0xda; // 1mb fast page mode 00572 } else if (vga.mem.memsize < 3072*1024) { 00573 vga.mem.memsize = 2048*1024; 00574 vga.s3.reg_36 = 0x9a; // 2mb fast page mode 00575 } else if (vga.mem.memsize < 4096*1024) { 00576 vga.mem.memsize = 3072*1024; 00577 vga.s3.reg_36 = 0x5a; // 3mb fast page mode 00578 } else if (vga.mem.memsize < 8192*1024) { // Trio64 supported only up to 4M 00579 vga.mem.memsize = 4096*1024; 00580 vga.s3.reg_36 = 0x1a; // 4mb fast page mode 00581 } else if (vga.mem.memsize < 16384*1024) { // 8M 00582 vga.mem.memsize = 8192*1024; 00583 vga.s3.reg_36 = 0x7a; // 8mb fast page mode 00584 } else { // HACK: 16MB mode, with value not supported by actual hardware 00585 vga.mem.memsize = 16384*1024; // FIXME: This breaks the cursor in Windows 3.1, though Windows 95 has no problem with it 00586 vga.s3.reg_36 = 0x7a; // 8mb fast page mode 00587 } 00588 00589 // S3 ROM signature 00590 phys_writes(PhysMake(0xc000,0)+0x003f, "S3 86C764", 10); 00591 00592 PCI_AddSVGAS3_Device(); 00593 } 00594 00595 // save state support 00596 void POD_Save_VGA_S3( std::ostream& stream ) 00597 { 00598 // - pure struct data 00599 WRITE_POD( &vga.s3, vga.s3 ); 00600 00601 //***************************************** 00602 //***************************************** 00603 00604 // static globals 00605 } 00606 00607 void POD_Load_VGA_S3( std::istream& stream ) 00608 { 00609 // - pure struct data 00610 READ_POD( &vga.s3, vga.s3 ); 00611 00612 //***************************************** 00613 //***************************************** 00614 00615 // static globals 00616 }