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 "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 }