DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/ints/int10_video_state.cpp
00001 /*
00002  *  Copyright (C) 2002-2013  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 "mem.h"
00022 #include "inout.h"
00023 #include "int10.h"
00024 
00025 Bitu INT10_VideoState_GetSize(Bitu state) {
00026         // state: bit0=hardware, bit1=bios data, bit2=color regs/dac state
00027         if ((state&7)==0) return 0;
00028 
00029         Bitu size=0x20;
00030         if (state&1) size+=0x46;
00031         if (state&2) size+=0x3a;
00032         if (state&4) size+=0x303;
00033         if ((svgaCard==SVGA_S3Trio) && (state&8)) size+=0x43;
00034         if (size!=0) size=(size-1)/64+1;
00035         return size;
00036 }
00037 
00038 bool INT10_VideoState_Save(Bitu state,RealPt buffer) {
00039         Bitu ct;
00040         if ((state&7)==0) return false;
00041 
00042         Bitu base_seg=RealSeg(buffer);
00043         Bitu base_dest=RealOff(buffer)+0x20u;
00044 
00045         if (state&1)  {
00046                 real_writew(base_seg,RealOff(buffer),base_dest);
00047 
00048                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00049                 real_writew(base_seg,base_dest+0x40,crt_reg);
00050 
00051                 real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c4));
00052                 real_writeb(base_seg,base_dest+0x01,IO_ReadB(0x3d4));
00053                 real_writeb(base_seg,base_dest+0x02,IO_ReadB(0x3ce));
00054                 IO_ReadB(crt_reg+6u);
00055                 real_writeb(base_seg,base_dest+0x03,IO_ReadB(0x3c0));
00056                 real_writeb(base_seg,base_dest+0x04,IO_ReadB(0x3ca));
00057 
00058                 // sequencer
00059                 for (ct=1; ct<5; ct++) {
00060                         IO_WriteB(0x3c4,ct);
00061                         real_writeb(base_seg,base_dest+0x04+ct,IO_ReadB(0x3c5));
00062                 }
00063 
00064                 real_writeb(base_seg,base_dest+0x09,IO_ReadB(0x3cc));
00065 
00066                 // crt controller
00067                 for (ct=0; ct<0x19; ct++) {
00068                         IO_WriteB(crt_reg,ct);
00069                         real_writeb(base_seg,base_dest+0x0a+ct,IO_ReadB(crt_reg+1u));
00070                 }
00071 
00072                 // attr registers
00073                 for (ct=0; ct<4; ct++) {
00074                         IO_ReadB(crt_reg+6u);
00075                         IO_WriteB(0x3c0,0x10+ct);
00076                         real_writeb(base_seg,base_dest+0x33+ct,IO_ReadB(0x3c1));
00077                 }
00078 
00079                 // graphics registers
00080                 for (ct=0; ct<9; ct++) {
00081                         IO_WriteB(0x3ce,ct);
00082                         real_writeb(base_seg,base_dest+0x37+ct,IO_ReadB(0x3cf));
00083                 }
00084 
00085                 // save some registers
00086                 IO_WriteB(0x3c4,2);
00087                 Bit8u crtc_2=IO_ReadB(0x3c5);
00088                 IO_WriteB(0x3c4,4);
00089                 Bit8u crtc_4=IO_ReadB(0x3c5);
00090                 IO_WriteB(0x3ce,6);
00091                 Bit8u gfx_6=IO_ReadB(0x3cf);
00092                 IO_WriteB(0x3ce,5);
00093                 Bit8u gfx_5=IO_ReadB(0x3cf);
00094                 IO_WriteB(0x3ce,4);
00095                 Bit8u gfx_4=IO_ReadB(0x3cf);
00096 
00097                 // reprogram for full access to plane latches
00098                 IO_WriteW(0x3c4,0x0f02);
00099                 IO_WriteW(0x3c4,0x0704);
00100                 IO_WriteW(0x3ce,0x0406);
00101                 IO_WriteW(0x3ce,0x0105);
00102                 mem_writeb(0xaffff,0);
00103 
00104                 for (ct=0; ct<4; ct++) {
00105                         IO_WriteW(0x3ce,0x0004+ct*0x100);
00106                         real_writeb(base_seg,base_dest+0x42u+ct,mem_readb(0xaffff));
00107                 }
00108 
00109                 // restore registers
00110                 IO_WriteW(0x3ce,0x0004u|((unsigned int)gfx_4<<8u));
00111                 IO_WriteW(0x3ce,0x0005u|((unsigned int)gfx_5<<8u));
00112                 IO_WriteW(0x3ce,0x0006u|((unsigned int)gfx_6<<8u));
00113                 IO_WriteW(0x3c4,0x0004u|((unsigned int)crtc_4<<8u));
00114                 IO_WriteW(0x3c4,0x0002u|((unsigned int)crtc_2<<8u));
00115 
00116                 for (ct=0; ct<0x10; ct++) {
00117                         IO_ReadB(crt_reg+6u);
00118                         IO_WriteB(0x3c0,ct);
00119                         real_writeb(base_seg,base_dest+0x23u+ct,IO_ReadB(0x3c1));
00120                 }
00121                 IO_WriteB(0x3c0,0x20);
00122 
00123                 base_dest+=0x46;
00124         }
00125 
00126         if (state&2)  {
00127                 real_writew(base_seg,RealOff(buffer)+2u,base_dest);
00128 
00129                 real_writeb(base_seg,base_dest+0x00,mem_readb(0x410)&0x30);
00130                 for (ct=0; ct<0x1e; ct++) {
00131                         real_writeb(base_seg,base_dest+0x01+ct,mem_readb(0x449+ct));
00132                 }
00133                 for (ct=0; ct<0x07; ct++) {
00134                         real_writeb(base_seg,base_dest+0x1f+ct,mem_readb(0x484+ct));
00135                 }
00136                 real_writed(base_seg,base_dest+0x26,mem_readd(0x48a));
00137                 real_writed(base_seg,base_dest+0x2a,mem_readd(0x14));   // int 5
00138                 real_writed(base_seg,base_dest+0x2e,mem_readd(0x74));   // int 1d
00139                 real_writed(base_seg,base_dest+0x32,mem_readd(0x7c));   // int 1f
00140                 real_writed(base_seg,base_dest+0x36,mem_readd(0x10c));  // int 43
00141 
00142                 base_dest+=0x3a;
00143         }
00144 
00145         if (state&4)  {
00146                 real_writew(base_seg,RealOff(buffer)+4u,base_dest);
00147 
00148                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00149 
00150                 IO_ReadB(crt_reg+6u);
00151                 IO_WriteB(0x3c0,0x14);
00152                 real_writeb(base_seg,base_dest+0x303,IO_ReadB(0x3c1));
00153 
00154                 Bitu dac_state=IO_ReadB(0x3c7)&1u;
00155                 Bitu dac_windex=IO_ReadB(0x3c8);
00156                 if (dac_state!=0) dac_windex--;
00157                 real_writeb(base_seg,base_dest+0x000,dac_state);
00158                 real_writeb(base_seg,base_dest+0x001,dac_windex);
00159                 real_writeb(base_seg,base_dest+0x002,IO_ReadB(0x3c6));
00160 
00161                 for (ct=0; ct<0x100; ct++) {
00162                         IO_WriteB(0x3c7,ct);
00163                         real_writeb(base_seg,base_dest+0x003+ct*3u+0,IO_ReadB(0x3c9));
00164                         real_writeb(base_seg,base_dest+0x003+ct*3u+1,IO_ReadB(0x3c9));
00165                         real_writeb(base_seg,base_dest+0x003+ct*3u+2,IO_ReadB(0x3c9));
00166                 }
00167 
00168                 IO_ReadB(crt_reg+6u);
00169                 IO_WriteB(0x3c0,0x20);
00170                 IO_ReadB(crt_reg+6u);
00171 
00172                 base_dest+=0x303u;
00173         }
00174 
00175         if ((svgaCard==SVGA_S3Trio) && (state&8u))  {
00176                 real_writew(base_seg,RealOff(buffer)+6u,base_dest);
00177 
00178                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00179 
00180                 IO_WriteB(0x3c4,0x08);
00181 //              Bitu seq_8=IO_ReadB(0x3c5);
00182                 IO_ReadB(0x3c5);
00183 //              real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5));
00184                 IO_WriteB(0x3c5,0x06);  // unlock s3-specific registers
00185 
00186                 // sequencer
00187                 for (ct=0; ct<0x13; ct++) {
00188                         IO_WriteB(0x3c4,0x09+ct);
00189                         real_writeb(base_seg,base_dest+0x00+ct,IO_ReadB(0x3c5));
00190                 }
00191 
00192                 // unlock s3-specific registers
00193                 IO_WriteW(crt_reg,0x4838);
00194                 IO_WriteW(crt_reg,0xa539);
00195 
00196                 // crt controller
00197                 Bitu ct_dest=0x13;
00198                 for (ct=0; ct<0x40; ct++) {
00199                         if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) {
00200                                 IO_WriteB(crt_reg,0x45);
00201                                 IO_ReadB(crt_reg+1u);
00202                                 IO_WriteB(crt_reg,0x30+ct);
00203                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00204                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00205                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00206                         } else {
00207                                 IO_WriteB(crt_reg,0x30+ct);
00208                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00209                         }
00210                 }
00211         }
00212         return true;
00213 }
00214 
00215 bool INT10_VideoState_Restore(Bitu state,RealPt buffer) {
00216         Bitu ct;
00217         if ((state&7u)==0) return false;
00218 
00219         Bit16u base_seg=RealSeg(buffer);
00220         Bit16u base_dest;
00221 
00222         if (state&1u)  {
00223                 base_dest=real_readw(base_seg,RealOff(buffer));
00224                 Bit16u crt_reg=real_readw(base_seg,base_dest+0x40);
00225 
00226                 // reprogram for full access to plane latches
00227                 IO_WriteW(0x3c4,0x0704);
00228                 IO_WriteW(0x3ce,0x0406);
00229                 IO_WriteW(0x3ce,0x0005);
00230 
00231                 IO_WriteW(0x3c4,0x0002);
00232                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x42));
00233                 IO_WriteW(0x3c4,0x0102);
00234                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x43));
00235                 IO_WriteW(0x3c4,0x0202);
00236                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x44));
00237                 IO_WriteW(0x3c4,0x0402);
00238                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x45));
00239                 IO_WriteW(0x3c4,0x0f02);
00240                 mem_readb(0xaffff);
00241 
00242                 IO_WriteW(0x3c4,0x0100);
00243 
00244                 // sequencer
00245                 for (ct=1; ct<5; ct++) {
00246                         IO_WriteW(0x3c4,(unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x04+ct)<<8u));
00247                 }
00248 
00249                 IO_WriteB(0x3c2,real_readb(base_seg,base_dest+0x09));
00250                 IO_WriteW(0x3c4,0x0300);
00251                 IO_WriteW(crt_reg,0x0011);
00252 
00253                 // crt controller
00254                 for (ct=0; ct<0x19; ct++) {
00255                         IO_WriteW(crt_reg,(unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x0a+ct)<<8u));
00256                 }
00257 
00258                 IO_ReadB(crt_reg+6u);
00259                 // attr registers
00260                 for (ct=0; ct<4; ct++) {
00261                         IO_WriteB(0x3c0,0x10+(unsigned int)ct);
00262                         IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x33+(unsigned int)ct));
00263                 }
00264 
00265                 // graphics registers
00266                 for (ct=0; ct<9; ct++) {
00267                         IO_WriteW(0x3ce,(unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x37+(unsigned int)ct)<<8u));
00268                 }
00269 
00270                 IO_WriteB(crt_reg+6u,real_readb(base_seg,base_dest+0x04));
00271                 IO_ReadB(crt_reg+6u);
00272 
00273                 // attr registers
00274                 for (ct=0; ct<0x10; ct++) {
00275                         IO_WriteB(0x3c0,(unsigned int)ct);
00276                         IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x23+(unsigned int)ct));
00277                 }
00278 
00279                 IO_WriteB(0x3c4,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00));
00280                 IO_WriteB(0x3d4,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x01));
00281                 IO_WriteB(0x3ce,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x02));
00282                 IO_ReadB(crt_reg+6u);
00283                 IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x03));
00284         }
00285 
00286         if (state&2)  {
00287                 base_dest=real_readw((unsigned int)base_seg,(unsigned int)RealOff(buffer)+2u);
00288 
00289                 mem_writeb(0x410,(mem_readb(0x410)&0xcf) | real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00));
00290                 for (ct=0; ct<0x1e; ct++) {
00291                         mem_writeb(0x449+ct,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x01+(unsigned int)ct));
00292                 }
00293                 for (ct=0; ct<0x07; ct++) {
00294                         mem_writeb(0x484+ct,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x1f+(unsigned int)ct));
00295                 }
00296                 mem_writed(0x48a,real_readd(base_seg,base_dest+0x26));
00297                 mem_writed(0x14,real_readd(base_seg,base_dest+0x2a));   // int 5
00298                 mem_writed(0x74,real_readd(base_seg,base_dest+0x2e));   // int 1d
00299                 mem_writed(0x7c,real_readd(base_seg,base_dest+0x32));   // int 1f
00300                 mem_writed(0x10c,real_readd(base_seg,base_dest+0x36));  // int 43
00301         }
00302 
00303         if (state&4)  {
00304                 base_dest=real_readw(base_seg,RealOff(buffer)+4u);
00305 
00306                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00307 
00308                 IO_WriteB(0x3c6,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x002));
00309 
00310                 for (ct=0; ct<0x100; ct++) {
00311                         IO_WriteB(0x3c8,(unsigned int)ct);
00312                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+0u));
00313                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+1u));
00314                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+2u));
00315                 }
00316 
00317                 IO_ReadB(crt_reg+6u);
00318                 IO_WriteB(0x3c0,0x14u);
00319                 IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x303));
00320 
00321                 IO_ReadB(crt_reg+6u);
00322                 IO_WriteB(0x3c0,0x20u);
00323                 IO_ReadB(crt_reg+6u);
00324 
00325                 Bitu dac_state=real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x000);
00326                 if (dac_state==0) {
00327                         IO_WriteB(0x3c8,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x001));
00328                 } else {
00329                         IO_WriteB(0x3c7,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x001));
00330                 }
00331         }
00332 
00333         if ((svgaCard==SVGA_S3Trio) && (state&8))  {
00334                 base_dest=real_readw((unsigned int)base_seg,(unsigned int)RealOff(buffer)+6u);
00335 
00336                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00337 
00338                 Bitu seq_idx=IO_ReadB(0x3c4);
00339                 IO_WriteB(0x3c4,0x08);
00340 //              Bitu seq_8=IO_ReadB(0x3c5);
00341                 IO_ReadB(0x3c5);
00342 //              real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5));
00343                 IO_WriteB(0x3c5,0x06);  // unlock s3-specific registers
00344 
00345                 // sequencer
00346                 for (ct=0; ct<0x13; ct++) {
00347                         IO_WriteW(0x3c4,(0x09+(unsigned int)ct)+((unsigned int)real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00+(unsigned int)ct)<<8u));
00348                 }
00349                 IO_WriteB(0x3c4,seq_idx);
00350 
00351 //              Bitu crtc_idx=IO_ReadB(0x3d4);
00352 
00353                 // unlock s3-specific registers
00354                 IO_WriteW(crt_reg,0x4838);
00355                 IO_WriteW(crt_reg,0xa539);
00356 
00357                 // crt controller
00358                 Bitu ct_dest=0x13;
00359                 for (ct=0; ct<0x40; ct++) {
00360                         if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) {
00361                                 IO_WriteB(crt_reg,0x45);
00362                                 IO_ReadB(crt_reg+1u);
00363                                 IO_WriteB(crt_reg,0x30+(unsigned int)ct);
00364                                 IO_WriteB(crt_reg,(unsigned int)real_readb((unsigned int)base_seg,(unsigned int)base_dest+(unsigned int)(ct_dest++)));
00365                         } else {
00366                                 IO_WriteW(crt_reg,(0x30+(unsigned int)ct)+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+(unsigned int)(ct_dest++))<<8u));
00367                         }
00368                 }
00369 
00370                 // mmio
00371 /*              IO_WriteB(crt_reg,0x40);
00372                 Bitu sysval1=IO_ReadB(crt_reg+1);
00373                 IO_WriteB(crt_reg+1,sysval|1);
00374                 IO_WriteB(crt_reg,0x53);
00375                 Bitu sysva2=IO_ReadB(crt_reg+1);
00376                 IO_WriteB(crt_reg+1,sysval2|0x10);
00377 
00378                 real_writew(0xa000,0x8128,0xffff);
00379 
00380                 IO_WriteB(crt_reg,0x40);
00381                 IO_WriteB(crt_reg,sysval1);
00382                 IO_WriteB(crt_reg,0x53);
00383                 IO_WriteB(crt_reg,sysval2);
00384                 IO_WriteB(crt_reg,crtc_idx); */
00385         }
00386 
00387         return true;
00388 }