DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/ints/int10_video_state.cpp
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 "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         Bit16u ct;
00040         if ((state&7)==0) return false;
00041 
00042         Bit16u base_seg=RealSeg(buffer);
00043         Bit16u 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,(Bit8u)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,(Bit8u)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,(Bit8u)(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,(Bit8u)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,(Bit8u)ct);
00119                         real_writeb(base_seg,base_dest+0x23u+ct,IO_ReadB(0x3c1));
00120                 }
00121         IO_ReadB(crt_reg+6u);
00122         IO_WriteB(0x3c0,0x20);
00123         IO_ReadB(crt_reg+6u);
00124 
00125                 base_dest+=0x46;
00126         }
00127 
00128         if (state&2)  {
00129                 real_writew(base_seg,RealOff(buffer)+2u,base_dest);
00130 
00131                 real_writeb(base_seg,base_dest+0x00,mem_readb(0x410)&0x30);
00132                 for (ct=0; ct<0x1e; ct++) {
00133                         real_writeb(base_seg,base_dest+0x01u+ct,mem_readb(0x449u+ct));
00134                 }
00135                 for (ct=0; ct<0x07; ct++) {
00136                         real_writeb(base_seg,base_dest+0x1fu+ct,mem_readb(0x484u+ct));
00137                 }
00138                 real_writed(base_seg,base_dest+0x26,mem_readd(0x48a));
00139                 real_writed(base_seg,base_dest+0x2a,mem_readd(0x14));   // int 5
00140                 real_writed(base_seg,base_dest+0x2e,mem_readd(0x74));   // int 1d
00141                 real_writed(base_seg,base_dest+0x32,mem_readd(0x7c));   // int 1f
00142                 real_writed(base_seg,base_dest+0x36,mem_readd(0x10c));  // int 43
00143 
00144                 base_dest+=0x3a;
00145         }
00146 
00147         if (state&4)  {
00148                 real_writew(base_seg,RealOff(buffer)+4u,base_dest);
00149 
00150                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00151 
00152                 IO_ReadB(crt_reg+6u);
00153                 IO_WriteB(0x3c0,0x14);
00154                 real_writeb(base_seg,base_dest+0x303,IO_ReadB(0x3c1));
00155 
00156                 Bit8u dac_state=IO_ReadB(0x3c7)&1u;
00157                 Bit8u dac_windex=IO_ReadB(0x3c8);
00158                 if (dac_state!=0) dac_windex--;
00159                 real_writeb(base_seg,base_dest+0x000,dac_state);
00160                 real_writeb(base_seg,base_dest+0x001,dac_windex);
00161                 real_writeb(base_seg,base_dest+0x002,IO_ReadB(0x3c6));
00162 
00163                 for (ct=0; ct<0x100; ct++) {
00164                         IO_WriteB(0x3c7,(Bit8u)ct);
00165                         real_writeb(base_seg,base_dest+0x003u+ct*3u+0,IO_ReadB(0x3c9));
00166                         real_writeb(base_seg,base_dest+0x003u+ct*3u+1,IO_ReadB(0x3c9));
00167                         real_writeb(base_seg,base_dest+0x003u+ct*3u+2,IO_ReadB(0x3c9));
00168                 }
00169 
00170                 IO_ReadB(crt_reg+6u);
00171                 IO_WriteB(0x3c0,0x20);
00172                 IO_ReadB(crt_reg+6u);
00173 
00174                 base_dest+=0x303u;
00175         }
00176 
00177         if ((svgaCard==SVGA_S3Trio) && (state&8u))  {
00178                 real_writew(base_seg,RealOff(buffer)+6u,base_dest);
00179 
00180                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00181 
00182                 IO_WriteB(0x3c4,0x08);
00183 //              Bitu seq_8=IO_ReadB(0x3c5);
00184                 IO_ReadB(0x3c5);
00185 //              real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5));
00186                 IO_WriteB(0x3c5,0x06);  // unlock s3-specific registers
00187 
00188                 // sequencer
00189                 for (ct=0; ct<0x13; ct++) {
00190                         IO_WriteB(0x3c4,(Bit8u)(0x09+ct));
00191                         real_writeb(base_seg,base_dest+0x00+ct,IO_ReadB(0x3c5));
00192                 }
00193 
00194                 // unlock s3-specific registers
00195                 IO_WriteW(crt_reg,0x4838);
00196                 IO_WriteW(crt_reg,0xa539);
00197 
00198                 // crt controller
00199                 Bit8u ct_dest=0x13;
00200                 for (ct=0; ct<0x40; ct++) {
00201                         if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) {
00202                                 IO_WriteB(crt_reg,0x45);
00203                                 IO_ReadB(crt_reg+1u);
00204                                 IO_WriteB(crt_reg,(Bit8u)(0x30+ct));
00205                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00206                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00207                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00208                         } else {
00209                                 IO_WriteB(crt_reg,0x30+ct);
00210                                 real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1u));
00211                         }
00212                 }
00213         }
00214         return true;
00215 }
00216 
00217 bool INT10_VideoState_Restore(Bitu state,RealPt buffer) {
00218         Bit16u ct;
00219         if ((state&7u)==0) return false;
00220 
00221         Bit16u base_seg=RealSeg(buffer);
00222         Bit16u base_dest;
00223 
00224         if (state&1u)  {
00225                 base_dest=real_readw(base_seg,RealOff(buffer));
00226                 Bit16u crt_reg=real_readw(base_seg,base_dest+0x40);
00227 
00228                 // reprogram for full access to plane latches
00229                 IO_WriteW(0x3c4,0x0704);
00230                 IO_WriteW(0x3ce,0x0406);
00231                 IO_WriteW(0x3ce,0x0005);
00232 
00233                 IO_WriteW(0x3c4,0x0002);
00234                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x42));
00235                 IO_WriteW(0x3c4,0x0102);
00236                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x43));
00237                 IO_WriteW(0x3c4,0x0202);
00238                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x44));
00239                 IO_WriteW(0x3c4,0x0402);
00240                 mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x45));
00241                 IO_WriteW(0x3c4,0x0f02);
00242                 mem_readb(0xaffff);
00243 
00244                 IO_WriteW(0x3c4,0x0100);
00245 
00246                 // sequencer
00247                 for (ct=1; ct<5; ct++) {
00248                         IO_WriteW(0x3c4,(Bit16u)((unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x04+ct)<<8u)));
00249                 }
00250 
00251                 IO_WriteB(0x3c2,real_readb(base_seg,base_dest+0x09));
00252                 IO_WriteW(0x3c4,0x0300);
00253                 IO_WriteW(crt_reg,0x0011);
00254 
00255                 // crt controller
00256                 for (ct=0; ct<0x19; ct++) {
00257                         IO_WriteW(crt_reg,(Bit16u)((unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x0a+ct)<<8u)));
00258                 }
00259 
00260                 IO_ReadB(crt_reg+6u);
00261                 // attr registers
00262                 for (ct=0; ct<4; ct++) {
00263                         IO_WriteB(0x3c0,0x10+(unsigned int)ct);
00264                         IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x33+(unsigned int)ct));
00265                 }
00266 
00267                 // graphics registers
00268                 for (ct=0; ct<9; ct++) {
00269                         IO_WriteW(0x3ce,(unsigned int)ct+(unsigned int)(real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x37+(unsigned int)ct)<<8u));
00270                 }
00271 
00272                 IO_WriteB(crt_reg+6u,real_readb(base_seg,base_dest+0x04));
00273                 IO_ReadB(crt_reg+6u);
00274 
00275                 // attr registers
00276                 for (ct=0; ct<0x10; ct++) {
00277                         IO_WriteB(0x3c0,(unsigned int)ct);
00278                         IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x23+(unsigned int)ct));
00279                 }
00280 
00281                 IO_WriteB(0x3c4,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00));
00282                 IO_WriteB(0x3d4,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x01));
00283                 IO_WriteB(0x3ce,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x02));
00284                 IO_ReadB(crt_reg+6u);
00285                 IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x03));
00286         }
00287 
00288         if (state&2)  {
00289                 base_dest=real_readw((unsigned int)base_seg,(unsigned int)RealOff(buffer)+2u);
00290 
00291                 mem_writeb(0x410,(mem_readb(0x410)&0xcf) | real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00));
00292                 for (ct=0; ct<0x1e; ct++) {
00293                         mem_writeb(0x449u+ct,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x01u+(unsigned int)ct));
00294                 }
00295                 for (ct=0; ct<0x07; ct++) {
00296                         mem_writeb(0x484u+ct,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x1fu+(unsigned int)ct));
00297                 }
00298                 mem_writed(0x48a,real_readd(base_seg,base_dest+0x26));
00299                 mem_writed(0x14,real_readd(base_seg,base_dest+0x2a));   // int 5
00300                 mem_writed(0x74,real_readd(base_seg,base_dest+0x2e));   // int 1d
00301                 mem_writed(0x7c,real_readd(base_seg,base_dest+0x32));   // int 1f
00302                 mem_writed(0x10c,real_readd(base_seg,base_dest+0x36));  // int 43
00303         }
00304 
00305         if (state&4)  {
00306                 base_dest=real_readw(base_seg,RealOff(buffer)+4u);
00307 
00308                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00309 
00310                 IO_WriteB(0x3c6,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x002));
00311 
00312                 for (ct=0; ct<0x100; ct++) {
00313                         IO_WriteB(0x3c8,(unsigned int)ct);
00314                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+0u));
00315                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+1u));
00316                         IO_WriteB(0x3c9,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x003+(unsigned int)ct*3u+2u));
00317                 }
00318 
00319                 IO_ReadB(crt_reg+6u);
00320                 IO_WriteB(0x3c0,0x14u);
00321                 IO_WriteB(0x3c0,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x303));
00322 
00323                 IO_ReadB(crt_reg+6u);
00324                 IO_WriteB(0x3c0,0x20u);
00325                 IO_ReadB(crt_reg+6u);
00326 
00327                 Bitu dac_state=real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x000);
00328                 if (dac_state==0) {
00329                         IO_WriteB(0x3c8,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x001));
00330                 } else {
00331                         IO_WriteB(0x3c7,real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x001));
00332                 }
00333         }
00334 
00335         if ((svgaCard==SVGA_S3Trio) && (state&8))  {
00336                 base_dest=real_readw((unsigned int)base_seg,(unsigned int)RealOff(buffer)+6u);
00337 
00338                 Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
00339 
00340                 Bit8u seq_idx=IO_ReadB(0x3c4);
00341                 IO_WriteB(0x3c4,0x08);
00342 //              Bitu seq_8=IO_ReadB(0x3c5);
00343                 IO_ReadB(0x3c5);
00344 //              real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5));
00345                 IO_WriteB(0x3c5,0x06);  // unlock s3-specific registers
00346 
00347                 // sequencer
00348                 for (ct=0; ct<0x13; ct++) {
00349                         IO_WriteW(0x3c4,(0x09+(unsigned int)ct)+((unsigned int)real_readb((unsigned int)base_seg,(unsigned int)base_dest+0x00+(unsigned int)ct)<<8u));
00350                 }
00351                 IO_WriteB(0x3c4,seq_idx);
00352 
00353 //              Bitu crtc_idx=IO_ReadB(0x3d4);
00354 
00355                 // unlock s3-specific registers
00356                 IO_WriteW(crt_reg,0x4838);
00357                 IO_WriteW(crt_reg,0xa539);
00358 
00359                 // crt controller
00360                 Bitu ct_dest=0x13;
00361                 for (ct=0; ct<0x40; ct++) {
00362                         if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) {
00363                                 IO_WriteB(crt_reg,0x45);
00364                                 IO_ReadB(crt_reg+1u);
00365                                 IO_WriteB(crt_reg,0x30+(unsigned int)ct);
00366                                 IO_WriteB(crt_reg,(unsigned int)real_readb((unsigned int)base_seg,(unsigned int)base_dest+(unsigned int)(ct_dest++)));
00367                         } else {
00368                                 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));
00369                         }
00370                 }
00371 
00372                 // mmio
00373 /*              IO_WriteB(crt_reg,0x40);
00374                 Bitu sysval1=IO_ReadB(crt_reg+1);
00375                 IO_WriteB(crt_reg+1,sysval|1);
00376                 IO_WriteB(crt_reg,0x53);
00377                 Bitu sysva2=IO_ReadB(crt_reg+1);
00378                 IO_WriteB(crt_reg+1,sysval2|0x10);
00379 
00380                 real_writew(0xa000,0x8128,0xffff);
00381 
00382                 IO_WriteB(crt_reg,0x40);
00383                 IO_WriteB(crt_reg,sysval1);
00384                 IO_WriteB(crt_reg,0x53);
00385                 IO_WriteB(crt_reg,sysval2);
00386                 IO_WriteB(crt_reg,crtc_idx); */
00387         }
00388 
00389         return true;
00390 }