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 "pic.h" 00023 #include "vga.h" 00024 #include <math.h> 00025 00026 void vsync_poll_debug_notify(); 00027 00028 void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen); 00029 Bitu vga_read_p3d4(Bitu port,Bitu iolen); 00030 void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); 00031 Bitu vga_read_p3d5(Bitu port,Bitu iolen); 00032 00033 /* allow the user to specify that undefined bits in 3DA/3BA be set to some nonzero value. 00034 * this is needed for "JOOP #2" by Europe demo, which has some weird retrace tracking code 00035 * like this: 00036 * 00037 * in al,dx ; <- dx = 3DAh 00038 * l1: shr al,1 ; AL >>= 1, CF = bit shifted out 00039 * jnc l1 00040 * 00041 * of course, if AL == 0, it becomes an infinite loop. this is why this option exists. */ 00042 unsigned char vga_p3da_undefined_bits = 0; 00043 00044 Bitu vga_read_p3da(Bitu port,Bitu iolen) { 00045 (void)port;//UNUSED 00046 (void)iolen;//UNUSED 00047 Bit8u retval = vga_p3da_undefined_bits; 00048 double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; 00049 00050 vga.internal.attrindex=false; 00051 vga.tandy.pcjr_flipflop=false; 00052 00053 // 3DAh (R): Status Register 00054 // bit 0 Horizontal or Vertical blanking 00055 // 3 Vertical sync 00056 00057 if (timeInFrame >= vga.draw.delay.vdend) { 00058 retval |= 1; // vertical blanking 00059 } else { 00060 double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); 00061 if (timeInLine >= vga.draw.delay.hblkstart && 00062 timeInLine <= vga.draw.delay.hblkend) { 00063 retval |= 1; // horizontal blanking 00064 } 00065 } 00066 00067 if (timeInFrame >= vga.draw.delay.vrstart && 00068 timeInFrame <= vga.draw.delay.vrend) { 00069 retval |= 8; // vertical retrace 00070 } 00071 00072 vsync_poll_debug_notify(); 00073 return retval; 00074 } 00075 00076 static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { 00077 (void)port;//UNUSED 00078 (void)iolen;//UNUSED 00079 if((machine==MCH_EGA) && ((vga.misc_output^val)&0xc)) VGA_StartResize(); 00080 vga.misc_output=(Bit8u)val; 00081 Bitu base=(val & 0x1) ? 0x3d0 : 0x3b0; 00082 Bitu free=(val & 0x1) ? 0x3b0 : 0x3d0; 00083 Bitu first=2, last=2; 00084 if (machine==MCH_EGA) {first=0; last=3;} 00085 00086 for (Bitu i=first; i<=last; i++) { 00087 IO_RegisterWriteHandler(base+i*2,vga_write_p3d4,IO_MB); 00088 IO_RegisterReadHandler(base+i*2,vga_read_p3d4,IO_MB); 00089 IO_RegisterWriteHandler(base+i*2+1,vga_write_p3d5,IO_MB); 00090 IO_RegisterReadHandler(base+i*2+1,vga_read_p3d5,IO_MB); 00091 IO_FreeWriteHandler(free+i*2,IO_MB); 00092 IO_FreeReadHandler(free+i*2,IO_MB); 00093 IO_FreeWriteHandler(free+i*2+1,IO_MB); 00094 IO_FreeReadHandler(free+i*2+1,IO_MB); 00095 } 00096 00097 IO_RegisterReadHandler(base+0xa,vga_read_p3da,IO_MB); 00098 IO_FreeReadHandler(free+0xa,IO_MB); 00099 00100 /* 00101 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. 00102 2-3 Clock Select. 0: 25MHz, 1: 28MHz 00103 5 When in Odd/Even modes Select High 64k bank if set 00104 6 Horizontal Sync Polarity. Negative if set 00105 7 Vertical Sync Polarity. Negative if set 00106 Bit 6-7 indicates the number of lines on the display: 00107 1: 400, 2: 350, 3: 480 00108 Note: Set to all zero on a hardware reset. 00109 Note: This register can be read from port 3CCh. 00110 */ 00111 } 00112 00113 00114 static Bitu read_p3cc(Bitu port,Bitu iolen) { 00115 (void)port;//UNUSED 00116 (void)iolen;//UNUSED 00117 return vga.misc_output; 00118 } 00119 00120 // VGA feature control register 00121 static Bitu read_p3ca(Bitu port,Bitu iolen) { 00122 (void)port;//UNUSED 00123 (void)iolen;//UNUSED 00124 return 0; 00125 } 00126 00127 static Bitu read_p3c8(Bitu port,Bitu iolen) { 00128 (void)port;//UNUSED 00129 (void)iolen;//UNUSED 00130 return 0x10; 00131 } 00132 00133 static Bitu read_p3c2(Bitu port,Bitu iolen) { 00134 (void)port;//UNUSED 00135 (void)iolen;//UNUSED 00136 Bit8u retval=0; 00137 00138 if (machine==MCH_EGA) retval = 0x0F; 00139 else if (IS_VGA_ARCH) retval = 0x60; 00140 00141 if(IS_EGAVGA_ARCH) { 00142 switch((vga.misc_output>>2)&3) { 00143 case 0: 00144 case 3: 00145 retval |= 0x10; // 0110 switch positions 00146 break; 00147 default: 00148 break; 00149 } 00150 } 00151 00152 if (vga.draw.vret_triggered) retval |= 0x80; 00153 return retval; 00154 /* 00155 0-3 0xF on EGA, 0x0 on VGA 00156 4 Status of the switch selected by the Miscellaneous Output 00157 Register 3C2h bit 2-3. Switch high if set. 00158 (apparently always 1 on VGA) 00159 5 (EGA) Pin 19 of the Feature Connector (FEAT0) is high if set 00160 6 (EGA) Pin 17 of the Feature Connector (FEAT1) is high if set 00161 (default differs by card, ET4000 sets them both) 00162 7 If set IRQ 2 has happened due to Vertical Retrace. 00163 Should be cleared by IRQ 2 interrupt routine by clearing port 3d4h 00164 index 11h bit 4. 00165 */ 00166 } 00167 00168 void VGA_SetupMisc(void) { 00169 if (IS_EGAVGA_ARCH) { 00170 vga.draw.vret_triggered=false; 00171 IO_RegisterReadHandler(0x3c2,read_p3c2,IO_MB); 00172 IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); 00173 if (IS_VGA_ARCH) { 00174 IO_RegisterReadHandler(0x3ca,read_p3ca,IO_MB); 00175 IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); 00176 } else { 00177 IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); 00178 } 00179 } else if (machine==MCH_CGA || machine==MCH_MCGA || machine==MCH_AMSTRAD || IS_TANDY_ARCH) { 00180 IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); 00181 } 00182 } 00183 00184 void VGA_UnsetupMisc(void) { 00185 IO_FreeWriteHandler(0x3b4,IO_MB); 00186 IO_FreeReadHandler(0x3b4,IO_MB); 00187 IO_FreeWriteHandler(0x3b5,IO_MB); 00188 IO_FreeReadHandler(0x3b5,IO_MB); 00189 IO_FreeWriteHandler(0x3c2,IO_MB); 00190 IO_FreeReadHandler(0x3c2,IO_MB); 00191 IO_FreeWriteHandler(0x3c8,IO_MB); 00192 IO_FreeReadHandler(0x3c8,IO_MB); 00193 IO_FreeWriteHandler(0x3ca,IO_MB); 00194 IO_FreeReadHandler(0x3ca,IO_MB); 00195 IO_FreeWriteHandler(0x3cc,IO_MB); 00196 IO_FreeReadHandler(0x3cc,IO_MB); 00197 IO_FreeWriteHandler(0x3d4,IO_MB); 00198 IO_FreeReadHandler(0x3d4,IO_MB); 00199 IO_FreeWriteHandler(0x3d5,IO_MB); 00200 IO_FreeReadHandler(0x3d5,IO_MB); 00201 IO_FreeWriteHandler(0x3da,IO_MB); 00202 IO_FreeReadHandler(0x3da,IO_MB); 00203 } 00204 00205 void pc98_clear_text(void) { 00206 for (unsigned int i = 0; i < 0x2000; i += 2) { 00207 *((uint16_t*)(vga.mem.linear + i)) = 0; 00208 *((uint16_t*)(vga.mem.linear + i + 0x2000)) = 0xE1; 00209 } 00210 } 00211 00212 void pc98_clear_graphics(void) { 00213 for (unsigned int i = 0; i < 0x8000; i += 2) { 00214 *((uint16_t*)(vga.mem.linear + i + 0x08000)) = 0; 00215 *((uint16_t*)(vga.mem.linear + i + 0x10000)) = 0; 00216 *((uint16_t*)(vga.mem.linear + i + 0x18000)) = 0; 00217 *((uint16_t*)(vga.mem.linear + i + 0x20000)) = 0; 00218 *((uint16_t*)(vga.mem.linear + i + 0x28000)) = 0; 00219 *((uint16_t*)(vga.mem.linear + i + 0x30000)) = 0; 00220 *((uint16_t*)(vga.mem.linear + i + 0x38000)) = 0; 00221 *((uint16_t*)(vga.mem.linear + i + 0x40000)) = 0; 00222 } 00223 }