1 /* 2 * Copyright (C) 2002-2021 The DOSBox Team 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef DOSBOX_VGA_H 20 #define DOSBOX_VGA_H 21 22 #include "dosbox.h" 23 24 #include <utility> 25 26 #include "inout.h" 27 #include "control.h" 28 29 //Don't enable keeping changes and mapping lfb probably... 30 #define VGA_LFB_MAPPED 31 //#define VGA_KEEP_CHANGES 32 #define VGA_CHANGE_SHIFT 9 33 34 class PageHandler; 35 36 enum VGAModes { 37 M_CGA2 = 1 << 0, 38 M_CGA4 = 1 << 1, 39 M_EGA = 1 << 2, 40 M_VGA = 1 << 3, 41 M_LIN4 = 1 << 4, 42 M_LIN8 = 1 << 5, 43 M_LIN15 = 1 << 6, 44 M_LIN16 = 1 << 7, 45 M_LIN24 = 1 << 8, 46 M_LIN32 = 1 << 9, 47 M_TEXT = 1 << 10, 48 M_HERC_GFX = 1 << 11, 49 M_HERC_TEXT = 1 << 12, 50 M_TANDY2 = 1 << 13, 51 M_TANDY4 = 1 << 14, 52 M_TANDY16 = 1 << 15, 53 M_TANDY_TEXT = 1 << 16, 54 M_CGA16 = 1 << 17, 55 M_CGA2_COMPOSITE = 1 << 18, 56 M_CGA4_COMPOSITE = 1 << 19, 57 M_CGA_TEXT_COMPOSITE = 1 << 20, 58 // bits 20 through 30 for more modes 59 M_ERROR = 1 << 31, 60 }; 61 62 constexpr uint16_t EGA_HALF_CLOCK = 1 << 0; 63 constexpr uint16_t EGA_LINE_DOUBLE = 1 << 1; 64 constexpr uint16_t VGA_PIXEL_DOUBLE = 1 << 2; 65 66 #define CLK_25 25175 67 #define CLK_28 28322 68 69 #define MIN_VCO 180000 70 #define MAX_VCO 360000 71 72 #define S3_CLOCK_REF 14318 /* KHz */ 73 #define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R)))) 74 #define S3_MAX_CLOCK 150000 /* KHz */ 75 76 #define S3_XGA_1024 0x00 77 #define S3_XGA_1152 0x01 78 #define S3_XGA_640 0x40 79 #define S3_XGA_800 0x80 80 #define S3_XGA_1280 0xc0 81 #define S3_XGA_1600 0x81 82 #define S3_XGA_WMASK \ 83 (S3_XGA_640 | S3_XGA_800 | S3_XGA_1024 | S3_XGA_1152 | S3_XGA_1280 | S3_XGA_1600) 84 85 #define S3_XGA_8BPP 0x00 86 #define S3_XGA_16BPP 0x10 87 #define S3_XGA_32BPP 0x30 88 #define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP) 89 90 struct VGA_Internal { 91 bool attrindex = false; 92 }; 93 94 struct VGA_Config { 95 /* Memory handlers */ 96 Bitu mh_mask = 0; 97 98 /* Video drawing */ 99 uint32_t display_start = 0; 100 Bitu real_start = 0; 101 bool retrace = false; /* A retrace is active */ 102 Bitu scan_len = 0; 103 Bitu cursor_start = 0; 104 105 /* Some other screen related variables */ 106 Bitu line_compare = 0; 107 bool chained = false; /* Enable or Disabled Chain 4 Mode */ 108 bool compatible_chain4 = false; 109 110 /* Pixel Scrolling */ 111 Bit8u pel_panning = 0; /* Amount of pixels to skip when starting 112 horizontal line */ 113 Bit8u hlines_skip = 0; 114 Bit8u bytes_skip = 0; 115 Bit8u addr_shift = 0; 116 117 /* Specific stuff memory write/read handling */ 118 119 Bit8u read_mode = 0; 120 Bit8u write_mode = 0; 121 Bit8u read_map_select = 0; 122 Bit8u color_dont_care = 0; 123 Bit8u color_compare = 0; 124 Bit8u data_rotate = 0; 125 Bit8u raster_op = 0; 126 127 Bit32u full_bit_mask = 0; 128 Bit32u full_map_mask = 0; 129 Bit32u full_not_map_mask = 0; 130 Bit32u full_set_reset = 0; 131 Bit32u full_not_enable_set_reset = 0; 132 Bit32u full_enable_set_reset = 0; 133 Bit32u full_enable_and_set_reset = 0; 134 }; 135 136 enum Drawmode { PART, DRAWLINE, EGALINE }; 137 138 struct VGA_Draw { 139 bool resizing = false; 140 Bitu width = 0; 141 Bitu height = 0; 142 uint32_t blocks = 0; 143 Bitu address = 0; 144 uint16_t panning = 0; 145 Bitu bytes_skip = 0; 146 Bit8u *linear_base = nullptr; 147 Bitu linear_mask = 0; 148 Bitu address_add = 0; 149 uint32_t line_length = 0; 150 uint32_t address_line_total = 0; 151 Bitu address_line = 0; 152 uint32_t lines_total = 0; 153 Bitu vblank_skip = 0; 154 uint32_t lines_done = 0; 155 Bitu lines_scaled = 0; 156 Bitu split_line = 0; 157 uint32_t parts_total = 0; 158 uint32_t parts_lines = 0; 159 uint32_t parts_left = 0; 160 Bitu byte_panning_shift = 0; 161 struct { 162 double framestart = 0; 163 double vrstart = 0, vrend = 0; // V-retrace 164 double hrstart = 0, hrend = 0; // H-retrace 165 double hblkstart = 0, hblkend = 0; // H-blanking 166 double vblkstart = 0, vblkend = 0; // V-Blanking 167 double vdend = 0, vtotal = 0; 168 double hdend = 0, htotal = 0; 169 double parts = 0; 170 } delay; 171 Bitu bpp = 0; 172 double aspect_ratio = 0; 173 bool double_scan = false; 174 bool doublewidth = false; 175 bool doubleheight = false; 176 Bit8u font[64 * 1024] = {}; 177 Bit8u *font_tables[2] = {nullptr, nullptr}; 178 Bitu blinking = 0; 179 bool blink = false; 180 bool char9dot = false; 181 struct { 182 Bitu address = 0; 183 Bit8u sline = 0; 184 uint8_t eline = 0; 185 Bit8u count = 0; 186 uint8_t delay = 0; 187 Bit8u enabled = 0; 188 } cursor; 189 Drawmode mode; 190 bool vret_triggered = false; 191 }; 192 193 struct VGA_HWCURSOR { 194 Bit8u curmode = 0; 195 Bit16u originx = 0; 196 uint16_t originy = 0; 197 Bit8u fstackpos = 0; 198 uint8_t bstackpos = 0; 199 Bit8u forestack[4] = {}; 200 Bit8u backstack[4] = {}; 201 Bit16u startaddr = 0; 202 Bit8u posx = 0; 203 uint8_t posy = 0; 204 Bit8u mc[64][64] = {}; 205 }; 206 207 struct VGA_S3 { 208 uint8_t reg_lock1 = 0; 209 uint8_t reg_lock2 = 0; 210 uint8_t reg_31 = 0; 211 uint8_t reg_35 = 0; 212 uint8_t reg_36 = 0; // RAM size 213 uint8_t reg_3a = 0; // 4/8/doublepixel bit in there 214 uint8_t reg_40 = 0; // 8415/A functionality register 215 uint8_t reg_41 = 0; // BIOS flags 216 uint8_t reg_42 = 0; 217 uint8_t reg_43 = 0; 218 uint8_t reg_45 = 0; // Hardware graphics cursor 219 uint8_t reg_50 = 0; 220 uint8_t reg_51 = 0; 221 uint8_t reg_52 = 0; 222 uint8_t reg_55 = 0; 223 uint8_t reg_58 = 0; 224 uint8_t reg_6b = 0; // LFB BIOS scratchpad 225 uint8_t ex_hor_overflow = 0; 226 uint8_t ex_ver_overflow = 0; 227 uint16_t la_window = 0; 228 uint8_t misc_control_2 = 0; 229 uint8_t ext_mem_ctrl = 0; 230 uint16_t xga_screen_width = 0; // from 640 to 1600 231 VGAModes xga_color_mode = {}; 232 struct clk_t { 233 uint8_t r = 0; 234 uint8_t n = 1; 235 uint8_t m = 1; 236 }; 237 clk_t clk[4] = {}; 238 clk_t mclk = {}; 239 struct pll_t { 240 uint8_t lock = 0; // Extended Sequencer Access Rgister SR8 (pp. 124) 241 uint8_t control_2 = 0; // CLKSYN Control 2 Register SR15 (pp. 130) 242 uint8_t control = 0; // RAMDAC/CLKSYN Control Register SRI8 (pp. 132) 243 }; 244 pll_t pll = {}; 245 VGA_HWCURSOR hgc = {}; 246 }; 247 248 struct VGA_HERC { 249 Bit8u mode_control = 0; 250 Bit8u enable_bits = 0; 251 }; 252 253 struct VGA_OTHER { 254 Bit8u index = 0; 255 Bit8u htotal = 0; 256 Bit8u hdend = 0; 257 Bit8u hsyncp = 0; 258 Bit8u hsyncw = 0; 259 Bit8u vtotal = 0; 260 Bit8u vdend = 0; 261 Bit8u vadjust = 0; 262 Bit8u vsyncp = 0; 263 Bit8u vsyncw = 0; 264 Bit8u max_scanline = 0; 265 Bit16u lightpen = 0; 266 bool lightpen_triggered = false; 267 Bit8u cursor_start = 0; 268 Bit8u cursor_end = 0; 269 }; 270 271 struct VGA_TANDY { 272 Bit8u pcjr_flipflop = 0; 273 Bit8u mode_control = 0; 274 Bit8u color_select = 0; 275 Bit8u disp_bank = 0; 276 Bit8u reg_index = 0; 277 Bit8u gfx_control = 0; 278 Bit8u palette_mask = 0; 279 Bit8u extended_ram = 0; 280 Bit8u border_color = 0; 281 Bit8u line_mask = 0; 282 uint8_t line_shift = 0; 283 Bit8u draw_bank = 0; 284 uint8_t mem_bank = 0; 285 Bit8u *draw_base = nullptr; 286 uint8_t *mem_base = nullptr; 287 Bitu addr_mask = 0; 288 }; 289 290 struct VGA_Seq { 291 Bit8u index = 0; 292 Bit8u reset = 0; 293 Bit8u clocking_mode = 0; 294 Bit8u map_mask = 0; 295 Bit8u character_map_select = 0; 296 Bit8u memory_mode = 0; 297 }; 298 299 struct VGA_Attr { 300 Bit8u palette[16] = {}; 301 Bit8u mode_control = 0; 302 Bit8u horizontal_pel_panning = 0; 303 Bit8u overscan_color = 0; 304 Bit8u color_plane_enable = 0; 305 Bit8u color_select = 0; 306 Bit8u index = 0; 307 Bit8u disabled = 0; // Used for disabling the screen. 308 // Bit0: screen disabled by attribute controller 309 // index Bit1: screen disabled by sequencer index 1 310 // bit 5 These are put together in one variable for 311 // performance reasons: the line drawing function is 312 // called maybe 60*480=28800 times/s, and we only 313 // need to check one variable for zero this way. 314 }; 315 316 struct VGA_Crtc { 317 Bit8u horizontal_total = 0; 318 Bit8u horizontal_display_end = 0; 319 Bit8u start_horizontal_blanking = 0; 320 Bit8u end_horizontal_blanking = 0; 321 Bit8u start_horizontal_retrace = 0; 322 Bit8u end_horizontal_retrace = 0; 323 Bit8u vertical_total = 0; 324 Bit8u overflow = 0; 325 Bit8u preset_row_scan = 0; 326 Bit8u maximum_scan_line = 0; 327 Bit8u cursor_start = 0; 328 Bit8u cursor_end = 0; 329 Bit8u start_address_high = 0; 330 Bit8u start_address_low = 0; 331 Bit8u cursor_location_high = 0; 332 Bit8u cursor_location_low = 0; 333 Bit8u vertical_retrace_start = 0; 334 Bit8u vertical_retrace_end = 0; 335 Bit8u vertical_display_end = 0; 336 Bit8u offset = 0; 337 Bit8u underline_location = 0; 338 Bit8u start_vertical_blanking = 0; 339 Bit8u end_vertical_blanking = 0; 340 Bit8u mode_control = 0; 341 Bit8u line_compare = 0; 342 343 Bit8u index = 0; 344 bool read_only = false; 345 }; 346 347 struct VGA_Gfx { 348 Bit8u index = 0; 349 Bit8u set_reset = 0; 350 Bit8u enable_set_reset = 0; 351 Bit8u color_compare = 0; 352 Bit8u data_rotate = 0; 353 Bit8u read_map_select = 0; 354 Bit8u mode = 0; 355 Bit8u miscellaneous = 0; 356 Bit8u color_dont_care = 0; 357 Bit8u bit_mask = 0; 358 }; 359 360 struct RGBEntry { 361 Bit8u red = 0; 362 Bit8u green = 0; 363 Bit8u blue = 0; 364 }; 365 366 struct VGA_Dac { 367 Bit8u bits = 0; /* DAC bits, usually 6 or 8 */ 368 Bit8u pel_mask = 0; 369 Bit8u pel_index = 0; 370 Bit8u state = 0; 371 Bit8u write_index = 0; 372 Bit8u read_index = 0; 373 Bitu first_changed = 0; 374 Bit8u combine[16] = {}; 375 RGBEntry rgb[0x100] = {}; 376 Bit16u xlat16[256] = {}; 377 }; 378 379 struct VGA_SVGA { 380 Bitu readStart = 0, writeStart = 0; 381 Bitu bankMask = 0; 382 Bitu bank_read_full = 0; 383 Bitu bank_write_full = 0; 384 Bit8u bank_read = 0; 385 Bit8u bank_write = 0; 386 Bitu bank_size = 0; 387 }; 388 389 union VGA_Latch { 390 Bit32u d = 0; 391 Bit8u b[4]; 392 }; 393 394 struct VGA_Memory { 395 Bit8u *linear = nullptr; 396 Bit8u *linear_orgptr = nullptr; 397 }; 398 399 struct VGA_Changes { 400 //Add a few more just to be safe 401 Bit8u *map = nullptr; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */ 402 Bit8u checkMask = 0; 403 uint8_t frame = 0; 404 uint8_t writeMask = 0; 405 bool active = 0; 406 Bit32u clearMask = 0; 407 Bit32u start = 0, last = 0; 408 Bit32u lastAddress = 0; 409 }; 410 411 struct VGA_LFB { 412 Bit32u page = 0; 413 Bit32u addr = 0; 414 Bit32u mask = 0; 415 PageHandler *handler = nullptr; 416 }; 417 418 struct VGA_Type { 419 VGAModes mode = {}; /* The mode the vga system is in */ 420 Bit8u misc_output = 0; 421 VGA_Draw draw = {}; 422 VGA_Config config = {}; 423 VGA_Internal internal = {}; 424 /* Internal module groups */ 425 VGA_Seq seq = {}; 426 VGA_Attr attr = {}; 427 VGA_Crtc crtc = {}; 428 VGA_Gfx gfx = {}; 429 VGA_Dac dac = {}; 430 VGA_Latch latch = {}; 431 VGA_S3 s3 = {}; 432 VGA_SVGA svga = {}; 433 VGA_HERC herc = {}; 434 VGA_TANDY tandy = {}; 435 VGA_OTHER other = {}; 436 VGA_Memory mem = {}; 437 Bit32u vmemwrap = 0; /* this is assumed to be power of 2 */ 438 Bit8u *fastmem = nullptr; /* memory for fast (usually 16-color) 439 rendering, always twice as big as vmemsize */ 440 Bit8u *fastmem_orgptr = nullptr; 441 Bit32u vmemsize = 0; 442 #ifdef VGA_KEEP_CHANGES 443 VGA_Changes changes = {}; 444 #endif 445 VGA_LFB lfb = {}; 446 // Composite video mode parameters 447 int ri = 0, rq = 0, gi = 0, gq = 0, bi = 0, bq = 0; 448 int sharpness = 0; 449 }; 450 451 /* Hercules Palette function */ 452 void Herc_Palette(void); 453 454 /* CGA Mono Palette function */ 455 void Mono_CGA_Palette(void); 456 457 void VGA_SetMonoPalette(const char *colour); 458 459 /* Functions for different resolutions */ 460 void VGA_SetMode(VGAModes mode); 461 void VGA_DetermineMode(void); 462 void VGA_SetupHandlers(void); 463 void VGA_StartResize(Bitu delay=50); 464 void VGA_SetupDrawing(uint32_t val); 465 void VGA_CheckScanLength(void); 466 void VGA_ChangedBank(void); 467 468 /* Some DAC/Attribute functions */ 469 void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); 470 void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue); 471 void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); 472 473 enum EGAMonitorMode { CGA, EGA, MONO }; 474 475 void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m); 476 477 /* The VGA Subfunction startups */ 478 void VGA_SetupAttr(void); 479 void VGA_SetupMemory(Section* sec); 480 void VGA_SetupDAC(void); 481 void VGA_SetupCRTC(void); 482 void VGA_SetupMisc(void); 483 void VGA_SetupGFX(void); 484 void VGA_SetupSEQ(void); 485 void VGA_SetupOther(void); 486 void VGA_SetupXGA(void); 487 void VGA_AddCompositeSettings(Config &conf); 488 489 /* Some Support Functions */ 490 std::pair<const char *, const char *> VGA_DescribeType(VGAModes type); 491 void VGA_SetClock(Bitu which, uint32_t target); 492 void VGA_DACSetEntirePalette(void); 493 void VGA_StartRetrace(void); 494 void VGA_StartUpdateLFB(void); 495 void VGA_SetBlinking(uint8_t enabled); 496 void VGA_SetCGA2Table(Bit8u val0,Bit8u val1); 497 void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); 498 void VGA_ActivateHardwareCursor(void); 499 void VGA_KillDrawing(void); 500 501 void VGA_LogInitialization(const char *adapter_name, 502 const char *ram_type, 503 const size_t num_modes); 504 505 extern VGA_Type vga; 506 507 /* Support for modular SVGA implementation */ 508 /* Video mode extra data to be passed to FinishSetMode_SVGA(). 509 This structure will be in flux until all drivers (including S3) 510 are properly separated. Right now it contains only three overflow 511 fields in S3 format and relies on drivers re-interpreting those. 512 For reference: 513 ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10 514 hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8 515 offset is not currently used by drivers (useful only for S3 itself) 516 It also contains basic int10 mode data - number, vtotal, htotal 517 */ 518 struct VGA_ModeExtraData { 519 Bit8u ver_overflow = 0; 520 Bit8u hor_overflow = 0; 521 Bitu offset = 0; 522 Bitu modeNo = 0; 523 uint32_t htotal = 0; 524 uint32_t vtotal = 0; 525 }; 526 527 // Vector function prototypes 528 typedef void (*tWritePort)(io_port_t reg, io_val_t value, io_width_t width); 529 typedef uint8_t (*tReadPort)(io_port_t reg, io_width_t width); 530 typedef void (*tFinishSetMode)(io_port_t crtc_base, VGA_ModeExtraData *modeData); 531 typedef void (*tDetermineMode)(); 532 typedef void (*tSetClock)(Bitu which, uint32_t target); 533 typedef uint32_t (*tGetClock)(); 534 typedef bool (*tHWCursorActive)(); 535 typedef bool (*tAcceptsMode)(Bitu modeNo); 536 537 struct SVGA_Driver { 538 tWritePort write_p3d5; 539 tReadPort read_p3d5; 540 tWritePort write_p3c5; 541 tReadPort read_p3c5; 542 tWritePort write_p3c0; 543 tReadPort read_p3c1; 544 tWritePort write_p3cf; 545 tReadPort read_p3cf; 546 547 tFinishSetMode set_video_mode; 548 tDetermineMode determine_mode; 549 tSetClock set_clock; 550 tGetClock get_clock; 551 tHWCursorActive hardware_cursor_active; 552 tAcceptsMode accepts_mode; 553 }; 554 555 extern SVGA_Driver svga; 556 557 void SVGA_Setup_S3Trio(void); 558 void SVGA_Setup_TsengET4K(void); 559 void SVGA_Setup_TsengET3K(void); 560 void SVGA_Setup_ParadisePVGA1A(void); 561 void SVGA_Setup_Driver(void); 562 563 // Amount of video memory required for a mode, implemented in int10_modes.cpp 564 uint32_t VideoModeMemSize(uint16_t mode); 565 566 extern Bit32u ExpandTable[256]; 567 extern Bit32u FillTable[16]; 568 extern Bit32u CGA_2_Table[16]; 569 extern Bit32u CGA_4_Table[256]; 570 extern Bit32u CGA_4_HiRes_Table[256]; 571 extern Bit32u CGA_16_Table[256]; 572 extern int CGA_Composite_Table[1024]; 573 extern Bit32u TXT_Font_Table[16]; 574 extern Bit32u TXT_FG_Table[16]; 575 extern Bit32u TXT_BG_Table[16]; 576 extern Bit32u Expand16Table[4][16]; 577 extern Bit32u Expand16BigTable[0x10000]; 578 579 #endif 580