DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/vga.h
00001  /*
00002  *  Copyright (C) 2002-2015  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 #ifndef DOSBOX_VGA_H
00021 #define DOSBOX_VGA_H
00022 
00023 #ifndef DOSBOX_DOSBOX_H
00024 #include "dosbox.h"
00025 #endif
00026 #include <iostream>
00027 
00028 #define VGA_LFB_MAPPED
00029 
00030 #define S3_LFB_BASE_DEFAULT       0xE0000000u
00031 
00032 class PageHandler;
00033 
00034 enum VGAModes {
00035     M_CGA2,         // 0
00036     M_CGA4,
00037     M_EGA,
00038     M_VGA,
00039     M_LIN4,
00040     M_LIN8,         // 5
00041     M_LIN15,
00042     M_LIN16,
00043     M_LIN24,
00044     M_LIN32,
00045     M_TEXT,         // 10
00046     M_HERC_GFX,
00047     M_HERC_TEXT,
00048     M_CGA16,
00049     M_TANDY2,
00050     M_TANDY4,       // 15
00051     M_TANDY16,
00052     M_TANDY_TEXT,
00053     M_AMSTRAD,
00054     M_PC98,
00055     M_FM_TOWNS,     // 20 STUB
00056     M_PACKED4,
00057     M_ERROR,
00058 
00059     M_MAX
00060 };
00061 
00062 extern const char* const mode_texts[M_MAX];
00063 
00064 enum VGA_Vsync {
00065         VS_Off,
00066         VS_On,
00067         VS_Force,
00068         VS_Host,
00069 };
00070 
00071 struct vsync_state {
00072         double period;
00073         bool manual;            // use manual vsync timing
00074         bool persistent;        // use persistent timer (to keep in sync even after internal mode switches)
00075         bool faithful;          // use faithful framerate adjustment
00076 };
00077 
00078 extern struct vsync_state vsync;
00079 extern float uservsyncjolt;
00080 
00081 #define CLK_25 25175u
00082 #define CLK_28 28322u
00083 
00084 #define MIN_VCO 180000u
00085 #define MAX_VCO 360000u
00086 
00087 #define S3_CLOCK_REF    14318u  /* KHz */
00088 #define S3_CLOCK(_M,_N,_R)      ((S3_CLOCK_REF * (((Bitu)_M) + 2ul)) / ((((Bitu)_N) + 2ul) * (1ul << ((Bitu)_R))))
00089 #define S3_MAX_CLOCK    150000u /* KHz */
00090 
00091 #define S3_XGA_1024             0x00u
00092 #define S3_XGA_1152             0x01u
00093 #define S3_XGA_640              0x40u
00094 #define S3_XGA_800              0x80u
00095 #define S3_XGA_1280             0xc0u
00096 #define S3_XGA_1600             0x81u
00097 #define S3_XGA_WMASK    (S3_XGA_640|S3_XGA_800|S3_XGA_1024|S3_XGA_1152|S3_XGA_1280)
00098 
00099 #define S3_XGA_8BPP  0x00u
00100 #define S3_XGA_16BPP 0x10u
00101 #define S3_XGA_32BPP 0x30u
00102 #define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP)
00103 
00104 typedef struct {
00105         bool attrindex;
00106 } VGA_Internal;
00107 
00108 typedef struct {
00109 /* Memory handlers */
00110         Bitu mh_mask;
00111 
00112 /* Video drawing */
00113         Bitu display_start;
00114         Bitu real_start;
00115         bool retrace;                                   /* A retrace is active */
00116         Bitu scan_len;
00117         Bitu cursor_start;
00118 
00119 /* Some other screen related variables */
00120         Bitu line_compare;
00121         bool chained;                                   /* Enable or Disabled Chain 4 Mode */
00122         bool compatible_chain4;
00123 
00124         /* Pixel Scrolling */
00125         Bit8u pel_panning;                              /* Amount of pixels to skip when starting horizontal line */
00126         Bit8u hlines_skip;
00127         Bit8u bytes_skip;
00128         Bit8u addr_shift;
00129 
00130 /* Specific stuff memory write/read handling */
00131         
00132         Bit8u read_mode;
00133         Bit8u write_mode;
00134         Bit8u read_map_select;
00135         Bit8u color_dont_care;
00136         Bit8u color_compare;
00137         Bit8u data_rotate;
00138         Bit8u raster_op;
00139 
00140         Bit32u full_bit_mask;
00141         Bit32u full_map_mask;
00142         Bit32u full_not_map_mask;
00143         Bit32u full_set_reset;
00144         Bit32u full_not_enable_set_reset;
00145         Bit32u full_enable_set_reset;
00146         Bit32u full_enable_and_set_reset;
00147 } VGA_Config;
00148 
00149 typedef enum {
00150         LINE,
00151         EGALINE
00152 } Drawmode;
00153 
00154 typedef struct {
00155         bool resizing;
00156         Bitu width;
00157         Bitu height;
00158         Bitu blocks;
00159         Bitu address;
00160         Bitu panning;
00161         Bitu bytes_skip;
00162         Bit8u *linear_base;
00163         Bitu linear_mask;
00164     Bitu planar_mask;
00165         Bitu address_add;
00166         Bitu line_length;
00167         Bitu address_line_total;
00168         Bitu address_line;
00169         Bitu lines_total;
00170         Bitu vblank_skip;
00171         Bitu lines_done;
00172         Bitu split_line;
00173         Bitu byte_panning_shift;
00174     Bitu render_step,render_max;
00175         struct {
00176                 double framestart;
00177                 double vrstart, vrend;          // V-retrace
00178                 double hrstart, hrend;          // H-retrace
00179                 double hblkstart, hblkend;      // H-blanking
00180                 double vblkstart, vblkend;      // V-Blanking
00181                 double vdend, vtotal;
00182                 double hdend, htotal;
00183                 float singleline_delay;
00184         } delay;
00185         double screen_ratio;
00186         double refresh;
00187         Bit8u font[516*1024]; /* enlarged to 516KB for PC-98 character font data (256*16) + (128*2*128*16) */
00188         Bit8u * font_tables[2];
00189         Bitu blinking;
00190         bool blink;
00191         bool char9dot;
00192         struct {
00193                 Bitu address;
00194                 Bit8u sline,eline;
00195                 Bit8u count,delay;
00196                 Bit8u enabled;
00197         } cursor;
00198         Drawmode mode;
00199         bool has_split;
00200         bool vret_triggered;
00201         bool vga_override;
00202         bool doublescan_set;
00203         bool doublescan_effect;
00204         bool char9_set;
00205         Bitu bpp;
00206         double clock;
00207         Bit8u cga_snow[80];                     // one bit per horizontal column where snow should occur
00208 } VGA_Draw;
00209 
00210 typedef struct {
00211         Bit8u curmode;
00212         Bit16u originx, originy;
00213         Bit8u fstackpos, bstackpos;
00214         Bit8u forestack[4];
00215         Bit8u backstack[4];
00216         Bit16u startaddr;
00217         Bit8u posx, posy;
00218         Bit8u mc[64][64];
00219 } VGA_HWCURSOR;
00220 
00221 typedef struct {
00222         Bit8u reg_lock1;
00223         Bit8u reg_lock2;
00224         Bit8u reg_31;
00225         Bit8u reg_35;
00226         Bit8u reg_36; // RAM size
00227         Bit8u reg_3a; // 4/8/doublepixel bit in there
00228         Bit8u reg_40; // 8415/A functionality register
00229         Bit8u reg_41; // BIOS flags 
00230         Bit8u reg_42; // CR42 Mode Control
00231         Bit8u reg_43;
00232         Bit8u reg_45; // Hardware graphics cursor
00233         Bit8u reg_50;
00234         Bit8u reg_51;
00235         Bit8u reg_52;
00236         Bit8u reg_55;
00237         Bit8u reg_58;
00238         Bit8u reg_6b; // LFB BIOS scratchpad
00239         Bit8u ex_hor_overflow;
00240         Bit8u ex_ver_overflow;
00241         Bit16u la_window;
00242         Bit8u misc_control_2;
00243         Bit8u ext_mem_ctrl;
00244         Bitu xga_screen_width;
00245         VGAModes xga_color_mode;
00246         struct {
00247                 Bit8u r;
00248                 Bit8u n;
00249                 Bit8u m;
00250         } clk[4],mclk;
00251         struct {
00252                 Bit8u lock;
00253                 Bit8u cmd;
00254         } pll;
00255         VGA_HWCURSOR hgc;
00256 } VGA_S3;
00257 
00258 typedef struct {
00259         Bit8u mode_control;
00260         Bit8u enable_bits;
00261         bool blend;
00262 } VGA_HERC;
00263 
00264 typedef struct {
00265         Bit32u mask_plane;
00266         Bit8u write_plane;
00267         Bit8u read_plane;
00268         Bit8u border_color;
00269 } VGA_AMSTRAD;
00270 
00271 typedef struct {
00272         Bit8u index;
00273         Bit8u htotal;
00274         Bit8u hdend;
00275         Bit8u hsyncp;
00276         Bit8u hsyncw;
00277         Bit8u vtotal;
00278         Bit8u vdend;
00279         Bit8u vadjust;
00280         Bit8u vsyncp;
00281         Bit8u vsyncw;
00282         Bit8u max_scanline;
00283         Bit16u lightpen;
00284         bool lightpen_triggered;
00285         Bit8u cursor_start;
00286         Bit8u cursor_end;
00287     Bit8u mcga_mode_control;
00288 } VGA_OTHER;
00289 
00290 typedef struct {
00291         Bit8u pcjr_flipflop;
00292         Bit8u mode_control;
00293         Bit8u color_select;
00294         Bit8u disp_bank;
00295         Bit8u reg_index;
00296         Bit8u gfx_control;
00297         Bit8u palette_mask;
00298         Bit8u extended_ram;
00299         Bit8u border_color;
00300         Bit8u line_mask, line_shift;
00301         Bit8u draw_bank, mem_bank;
00302         Bit8u *draw_base, *mem_base;
00303         Bitu addr_mask;
00304 } VGA_TANDY;
00305 
00306 typedef struct {
00307         Bit8u index;
00308         Bit8u reset;
00309         Bit8u clocking_mode;
00310         Bit8u map_mask;
00311         Bit8u character_map_select;
00312         Bit8u memory_mode;
00313 } VGA_Seq;
00314 
00315 typedef struct {
00316         Bit8u palette[16];
00317         Bit8u mode_control;
00318         Bit8u horizontal_pel_panning;
00319         Bit8u overscan_color;
00320         Bit8u color_plane_enable;
00321         Bit8u color_select;
00322         Bit8u index;
00323         Bit8u disabled; // Used for disabling the screen.
00324                                         // Bit0: screen disabled by attribute controller index
00325                                         // Bit1: screen disabled by sequencer index 1 bit 5
00326                                         // These are put together in one variable for performance reasons:
00327                                         // the line drawing function is called maybe 60*480=28800 times/s,
00328                                         // and we only need to check one variable for zero this way.
00329 } VGA_Attr;
00330 
00331 typedef struct {
00332         Bit8u horizontal_total;
00333         Bit8u horizontal_display_end;
00334         Bit8u start_horizontal_blanking;
00335         Bit8u end_horizontal_blanking;
00336         Bit8u start_horizontal_retrace;
00337         Bit8u end_horizontal_retrace;
00338         Bit8u vertical_total;
00339         Bit8u overflow;
00340         Bit8u preset_row_scan;
00341         Bit8u maximum_scan_line;
00342         Bit8u cursor_start;
00343         Bit8u cursor_end;
00344         Bit8u start_address_high;
00345         Bit8u start_address_low;
00346         Bit8u cursor_location_high;
00347         Bit8u cursor_location_low;
00348         Bit8u vertical_retrace_start;
00349         Bit8u vertical_retrace_end;
00350         Bit8u vertical_display_end;
00351         Bit8u offset;
00352         Bit8u underline_location;
00353         Bit8u start_vertical_blanking;
00354         Bit8u end_vertical_blanking;
00355         Bit8u mode_control;
00356         Bit8u line_compare;
00357 
00358         Bit8u index;
00359         bool read_only;
00360 } VGA_Crtc;
00361 
00362 typedef struct {
00363         Bit8u index;
00364         Bit8u set_reset;
00365         Bit8u enable_set_reset;
00366         Bit8u color_compare;
00367         Bit8u data_rotate;
00368         Bit8u read_map_select;
00369         Bit8u mode;
00370         Bit8u miscellaneous;
00371         Bit8u color_dont_care;
00372         Bit8u bit_mask;
00373 } VGA_Gfx;
00374 
00375 typedef struct  {
00376         Bit8u red;
00377         Bit8u green;
00378         Bit8u blue;
00379 } RGBEntry;
00380 
00381 typedef struct {
00382         Bit8u bits;                                             /* DAC bits, usually 6 or 8 */
00383         Bit8u pel_mask;
00384         Bit8u pel_index;        
00385         Bit8u state;
00386         Bit8u write_index;
00387         Bit8u read_index;
00388         Bitu first_changed;
00389         Bit8u combine[16];
00390         RGBEntry rgb[0x100];
00391         Bit16u xlat16[256];
00392         Bit32u xlat32[256];
00393         Bit8u hidac_counter;
00394         Bit8u reg02;
00395 } VGA_Dac;
00396 
00397 typedef struct {
00398         Bitu    readStart, writeStart;
00399         Bitu    bankMask;
00400         Bitu    bank_read_full;
00401         Bitu    bank_write_full;
00402         Bit8u   bank_read;
00403         Bit8u   bank_write;
00404         Bitu    bank_size;
00405 } VGA_SVGA;
00406 
00407 typedef union {
00408         Bit32u d;
00409         Bit8u b[4];
00410 } VGA_Latch;
00411 
00412 typedef struct {
00413         Bit8u*      linear = NULL;
00414         Bit8u*      linear_orgptr = NULL;
00415 
00416     uint32_t    memsize = 0;
00417     uint32_t    memmask = 0;
00418     uint32_t    memmask_crtc = 0;       // in CRTC-visible units (depends on byte/word/dword mode)
00419 } VGA_Memory;
00420 
00421 typedef struct {
00422         //Add a few more just to be safe
00423         Bit8u*  map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */
00424         Bit8u   checkMask, frame, writeMask;
00425         bool    active;
00426         Bit32u  clearMask;
00427         Bit32u  start, last;
00428         Bit32u  lastAddress;
00429 } VGA_Changes;
00430 
00431 typedef struct {
00432         Bit32u page;
00433         Bit32u addr;
00434         Bit32u mask;
00435         PageHandler *handler;
00436 } VGA_LFB;
00437 
00438 typedef struct {
00439         VGAModes mode;                                                          /* The mode the vga system is in */
00440         VGAModes lastmode;
00441         Bit8u misc_output;
00442         VGA_Draw draw;
00443         VGA_Config config;
00444         VGA_Internal internal;
00445 /* Internal module groups */
00446         VGA_Seq seq;
00447         VGA_Attr attr;
00448         VGA_Crtc crtc;
00449         VGA_Gfx gfx;
00450         VGA_Dac dac;
00451         VGA_Latch latch;
00452         VGA_S3 s3;
00453         VGA_SVGA svga;
00454         VGA_HERC herc;
00455         VGA_TANDY tandy;
00456         VGA_AMSTRAD amstrad;
00457         VGA_OTHER other;
00458         VGA_Memory mem;
00459         VGA_LFB lfb;
00460 } VGA_Type;
00461 
00462 
00463 /* Hercules Palette function */
00464 void Herc_Palette(void);
00465 
00466 /* CGA Mono Palette function */
00467 void Mono_CGA_Palette(void);
00468 
00469 /* Functions for different resolutions */
00470 void VGA_SetMode(VGAModes mode);
00471 void VGA_DetermineMode(void);
00472 void VGA_SetupHandlers(void);
00473 void VGA_StartResize(Bitu delay=50);
00474 void VGA_SetupDrawing(Bitu val);
00475 void VGA_CheckScanLength(void);
00476 void VGA_ChangedBank(void);
00477 
00478 /* Some DAC/Attribute functions */
00479 void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
00480 void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue);
00481 void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
00482 
00483 typedef enum {CGA, EGA, MONO} EGAMonitorMode;
00484 
00485 typedef enum {AC_4x4, AC_low4/*4low*/} ACPalRemapMode;
00486 
00487 extern unsigned char VGA_AC_remap;
00488 
00489 void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m);
00490 
00491 /* The VGA Subfunction startups */
00492 void VGA_SetupAttr(void);
00493 void VGA_SetupMemory(void);
00494 void VGA_SetupDAC(void);
00495 void VGA_SetupCRTC(void);
00496 void VGA_SetupMisc(void);
00497 void VGA_SetupGFX(void);
00498 void VGA_SetupSEQ(void);
00499 void VGA_SetupOther(void);
00500 void VGA_SetupXGA(void);
00501 
00502 /* Some Support Functions */
00503 void VGA_SetClock(Bitu which,Bitu target);
00504 void VGA_DACSetEntirePalette(void);
00505 void VGA_StartRetrace(void);
00506 void VGA_StartUpdateLFB(void);
00507 void VGA_SetBlinking(Bitu enabled);
00508 void VGA_SetCGA2Table(Bit8u val0,Bit8u val1);
00509 void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
00510 void VGA_ActivateHardwareCursor(void);
00511 void VGA_KillDrawing(void);
00512 
00513 void VGA_SetOverride(bool vga_override);
00514 
00515 extern VGA_Type vga;
00516 
00517 /* Support for modular SVGA implementation */
00518 /* Video mode extra data to be passed to FinishSetMode_SVGA().
00519    This structure will be in flux until all drivers (including S3)
00520    are properly separated. Right now it contains only three overflow
00521    fields in S3 format and relies on drivers re-interpreting those.
00522    For reference:
00523    ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10
00524    hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8
00525    offset is not currently used by drivers (useful only for S3 itself)
00526    It also contains basic int10 mode data - number, vtotal, htotal
00527    */
00528 typedef struct {
00529         Bit8u ver_overflow;
00530         Bit8u hor_overflow;
00531         Bitu offset;
00532         Bitu modeNo;
00533         Bitu htotal;
00534         Bitu vtotal;
00535 } VGA_ModeExtraData;
00536 
00537 // Vector function prototypes
00538 typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen);
00539 typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen);
00540 typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData);
00541 typedef void (*tDetermineMode)();
00542 typedef void (*tSetClock)(Bitu which,Bitu target);
00543 typedef Bitu (*tGetClock)();
00544 typedef bool (*tHWCursorActive)();
00545 typedef bool (*tAcceptsMode)(Bitu modeNo);
00546 typedef void (*tSetupDAC)();
00547 typedef void (*tINT10Extensions)();
00548 
00549 struct SVGA_Driver {
00550         tWritePort write_p3d5;
00551         tReadPort read_p3d5;
00552         tWritePort write_p3c5;
00553         tReadPort read_p3c5;
00554         tWritePort write_p3c0;
00555         tReadPort read_p3c1;
00556         tWritePort write_p3cf;
00557         tReadPort read_p3cf;
00558 
00559         tFinishSetMode set_video_mode;
00560         tDetermineMode determine_mode;
00561         tSetClock set_clock;
00562         tGetClock get_clock;
00563         tHWCursorActive hardware_cursor_active;
00564         tAcceptsMode accepts_mode;
00565         tSetupDAC setup_dac;
00566         tINT10Extensions int10_extensions;
00567 };
00568 
00569 extern SVGA_Driver svga;
00570 extern int enableCGASnow;
00571 
00572 void SVGA_Setup_S3Trio(void);
00573 void SVGA_Setup_TsengET4K(void);
00574 void SVGA_Setup_TsengET3K(void);
00575 void SVGA_Setup_ParadisePVGA1A(void);
00576 void SVGA_Setup_Driver(void);
00577 
00578 // Amount of video memory required for a mode, implemented in int10_modes.cpp
00579 Bitu VideoModeMemSize(Bitu mode);
00580 
00581 extern Bit32u ExpandTable[256];
00582 extern Bit32u FillTable[16];
00583 extern Bit32u CGA_2_Table[16];
00584 extern Bit32u CGA_4_Table[256];
00585 extern Bit32u CGA_4_HiRes_Table[256];
00586 extern Bit32u CGA_16_Table[256];
00587 extern Bit32u TXT_Font_Table[16];
00588 extern Bit32u TXT_FG_Table[16];
00589 extern Bit32u TXT_BG_Table[16];
00590 extern Bit32u Expand16Table[4][16];
00591 extern Bit32u Expand16BigTable[0x10000];
00592 
00593 void VGA_DAC_UpdateColorPalette();
00594 
00595 extern uint32_t GFX_Rmask;
00596 extern unsigned char GFX_Rshift;
00597 
00598 extern uint32_t GFX_Gmask;
00599 extern unsigned char GFX_Gshift;
00600 
00601 extern uint32_t GFX_Bmask;
00602 extern unsigned char GFX_Bshift;
00603 
00604 extern uint32_t GFX_Amask;
00605 extern unsigned char GFX_Ashift;
00606 
00607 extern unsigned char GFX_bpp;
00608 
00609 #endif