DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/vga_s3.cpp
00001 /*
00002  *  Copyright (C) 2002-2015  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
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 = 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=val;
00075         break;
00076     case 0x39:  /* CR39 Register Lock 2 */
00077         vga.s3.reg_lock2=val;
00078         break;
00079     case 0x3a:
00080         vga.s3.reg_3a = val;
00081         break;
00082     case 0x40:  /* CR40 System Config */
00083         vga.s3.reg_40 = val;
00084         break;
00085     case 0x41:  /* CR41 BIOS flags */
00086         vga.s3.reg_41 = val;
00087         break;
00088     case 0x42:  /* CR42 Mode Control */
00089         if ((val ^ vga.s3.reg_42) & 0x20) {
00090             vga.s3.reg_42=val;
00091             VGA_StartResize();
00092         } else vga.s3.reg_42=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=val & ~0x4u;
00102         if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) {
00103             vga.config.scan_len&=0x2ff;
00104             vga.config.scan_len|=(val & 0x4) << 6;
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 = 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) | (val << 8);
00120         break;
00121     case 0x47:  /*  HGC orgX */
00122         vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val;
00123         break;
00124     case 0x48:
00125         vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8);
00126         break;
00127     case 0x49:  /*  HGC orgY */
00128         vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | 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] = 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] = 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 |= ((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 |= (val & 0xff);
00152         break;
00153     case 0x4e:  /* HGC pattern start X */
00154         vga.s3.hgc.posx = val & 0x3f;   // bits 0-5
00155         break;
00156     case 0x4f:  /* HGC pattern start Y */
00157         vga.s3.hgc.posy = val & 0x3f;   // bits 0-5
00158         break;
00159     case 0x50:  // Extended System Control 1
00160         vga.s3.reg_50 = 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=val & 0xc0;       //Only store bits 6,7
00178         vga.config.display_start&=0xF3FFFF;
00179         vga.config.display_start|=(val & 3) << 18;
00180         if ((vga.svga.bank_read&0x30) ^ ((val&0xc)<<2)) {
00181             vga.svga.bank_read&=0xcf; 
00182             vga.svga.bank_read|=(val&0xc)<<2;
00183             vga.svga.bank_write = vga.svga.bank_read;
00184             VGA_SetupHandlers();
00185         }
00186         if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) {
00187             vga.config.scan_len&=0xff;
00188             vga.config.scan_len|=(val & 0x30) << 4;
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 = 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!=val) {
00220             vga.s3.ext_mem_ctrl = val;
00221             VGA_SetupHandlers();
00222         }
00223         break;
00224     case 0x55:  /* Extended Video DAC Control */
00225         vga.s3.reg_55=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=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) ^ (val << 8)) {
00270             vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8);
00271             VGA_StartUpdateLFB();
00272         }
00273         break;
00274     case 0x5a:  /* Linear Address Window Position Low */
00275         if ((vga.s3.la_window&0x00ff) ^ val) {
00276             vga.s3.la_window=(vga.s3.la_window&0xff00) | 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=val;
00283             VGA_StartResize();
00284         } else vga.s3.ex_hor_overflow=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 & 0x3ff) | (val & 0x40) << 4;
00308         if ((val ^ vga.s3.ex_ver_overflow) & 0x3) {
00309             vga.s3.ex_ver_overflow=val;
00310             VGA_StartResize();
00311         } else vga.s3.ex_ver_overflow=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=val;
00347         VGA_DetermineMode();
00348         break;
00349     case 0x69:  /* Extended System Control 3 */
00350         if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) {
00351             vga.config.display_start&=0xffff;
00352             vga.config.display_start|=(val & 0x1f) << 16;
00353         }
00354         break;
00355     case 0x6a:  /* Extended System Control 4 */
00356         vga.svga.bank_read=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=val;
00465         break;
00466     case 0x10:      /* Memory PLL Data Low */
00467         vga.s3.mclk.n=val & 0x1f;
00468         vga.s3.mclk.r=val >> 5;
00469         break;
00470     case 0x11:      /* Memory PLL Data High */
00471         vga.s3.mclk.m=val & 0x7f;
00472         break;
00473     case 0x12:      /* Video PLL Data Low */
00474         vga.s3.clk[3].n=val & 0x1f;
00475         vga.s3.clk[3].r=val >> 5;
00476         break;
00477     case 0x13:      /* Video PLL Data High */
00478         vga.s3.clk[3].m=val & 0x7f;
00479         break;
00480     case 0x15:
00481         vga.s3.pll.cmd=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=1000*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 {    // 8M
00582         vga.mem.memsize = 8192*1024;
00583         vga.s3.reg_36 = 0x7a;       // 8mb fast page mode
00584     }
00585 
00586     // S3 ROM signature
00587     phys_writes(PhysMake(0xc000,0)+0x003f, "S3 86C764", 10);
00588 
00589     PCI_AddSVGAS3_Device();
00590 }
00591