aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/iodev/vga.h
blob: cafb60cd6bde17b48fcc56952028b3cf6864aaff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/////////////////////////////////////////////////////////////////////////
// $Id: vga.h,v 1.36 2003/12/31 10:33:27 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2002  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

#if BX_SUPPORT_VBE
  #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4

  #define VBE_DISPI_BANK_ADDRESS          0xA0000
  #define VBE_DISPI_BANK_SIZE_KB          64

  #define VBE_DISPI_MAX_XRES              1024
  #define VBE_DISPI_MAX_YRES              768

  #define VBE_DISPI_IOPORT_INDEX          0x01CE
  #define VBE_DISPI_IOPORT_DATA           0x01CF

  #define VBE_DISPI_IOPORT_INDEX_OLD      0xFF80
  #define VBE_DISPI_IOPORT_DATA_OLD       0xFF81

  #define VBE_DISPI_INDEX_ID              0x0
  #define VBE_DISPI_INDEX_XRES            0x1
  #define VBE_DISPI_INDEX_YRES            0x2
  #define VBE_DISPI_INDEX_BPP             0x3
  #define VBE_DISPI_INDEX_ENABLE          0x4
  #define VBE_DISPI_INDEX_BANK            0x5
  #define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
  #define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
  #define VBE_DISPI_INDEX_X_OFFSET        0x8
  #define VBE_DISPI_INDEX_Y_OFFSET        0x9

  #define VBE_DISPI_ID0                   0xB0C0
  #define VBE_DISPI_ID1                   0xB0C1
  #define VBE_DISPI_ID2                   0xB0C2

  #define VBE_DISPI_BPP_4                 0x04
  #define VBE_DISPI_BPP_8                 0x08
  #define VBE_DISPI_BPP_15                0x0F
  #define VBE_DISPI_BPP_16                0x10
  #define VBE_DISPI_BPP_24                0x18
  #define VBE_DISPI_BPP_32                0x20

  #define VBE_DISPI_DISABLED              0x00
  #define VBE_DISPI_ENABLED               0x01
  #define VBE_DISPI_NOCLEARMEM            0x80
  #define VBE_DISPI_LFB_ENABLED           0x40

  #define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000

  
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_KB		(VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024)  
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES 	(VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)  

#define BX_MAX_XRES VBE_DISPI_MAX_XRES
#define BX_MAX_YRES VBE_DISPI_MAX_YRES

#else

#define BX_MAX_XRES 800
#define BX_MAX_YRES 600

#endif //BX_SUPPORT_VBE

#define X_TILESIZE 16
#define Y_TILESIZE 24
#define BX_NUM_X_TILES (BX_MAX_XRES /X_TILESIZE)
#define BX_NUM_Y_TILES (BX_MAX_YRES /Y_TILESIZE)

// Support varying number of rows of text.  This used to
// be limited to only 25 lines.
#define BX_MAX_TEXT_LINES 100

#if BX_USE_VGA_SMF
#  define BX_VGA_SMF  static
#  define BX_VGA_THIS theVga->
#else
#  define BX_VGA_SMF
#  define BX_VGA_THIS this->
#endif


class bx_vga_c : public bx_vga_stub_c {
public:

  bx_vga_c(void);
  ~bx_vga_c(void);
  virtual void   init(void);
  virtual void	 bios_init(void);
  virtual void   reset(unsigned type);
  virtual Bit8u  mem_read(Bit32u addr);
  // Note: either leave value of type Bit8u, or mask it when
  //       used to 8 bits, in memory.cc
  virtual void   mem_write(Bit32u addr, Bit8u value);
  virtual void   trigger_timer(void *this_ptr);

#if BX_SUPPORT_VBE
  BX_VGA_SMF Bit8u  vbe_mem_read(Bit32u addr) BX_CPP_AttrRegparmN(1);
  BX_VGA_SMF void   vbe_mem_write(Bit32u addr, Bit8u value) BX_CPP_AttrRegparmN(2);
#endif

  virtual void   redraw_area(unsigned x0, unsigned y0,
                             unsigned width, unsigned height);

  virtual void   set_update_interval (unsigned interval);
  virtual void   get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
                                   unsigned *txWidth);
  virtual Bit8u  get_actl_palette_idx(Bit8u index);

private:

  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
  static void   write_handler_no_log(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);

#if BX_SUPPORT_VBE
  static Bit32u vbe_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
  static void   vbe_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
#endif

  struct {
    struct {
      bx_bool color_emulation;  // 1=color emulation, base address = 3Dx
                                // 0=mono emulation,  base address = 3Bx
      bx_bool enable_ram;       // enable CPU access to video memory if set
      Bit8u   clock_select;     // 0=25Mhz 1=28Mhz
      bx_bool select_high_bank; // when in odd/even modes, select
                                // high 64k bank if set
      bx_bool horiz_sync_pol;   // bit6: negative if set
      bx_bool vert_sync_pol;    // bit7: negative if set
                                //   bit7,bit6 represent number of lines on display:
                                //   0 = reserved
                                //   1 = 400 lines
                                //   2 = 350 lines
                                //   3 - 480 lines
      } misc_output;

    struct {
      Bit8u   address;
      Bit8u   reg[0x19];
      } CRTC;

    struct {
      bx_bool  flip_flop; /* 0 = address, 1 = data-write */
      unsigned address;  /* register number */
      bx_bool  video_enabled;
      Bit8u    palette_reg[16];
      Bit8u    overscan_color;
      Bit8u    color_plane_enable;
      Bit8u    horiz_pel_panning;
      Bit8u    color_select;
      struct {
        bx_bool graphics_alpha;
        bx_bool display_type;
        bx_bool enable_line_graphics;
        bx_bool blink_intensity;
        bx_bool pixel_panning_compat;
        bx_bool pixel_clock_select;
        bx_bool internal_palette_size;
        } mode_ctrl;
      } attribute_ctrl;

    struct {
      Bit8u write_data_register;
      Bit8u write_data_cycle; /* 0, 1, 2 */
      Bit8u read_data_register;
      Bit8u read_data_cycle; /* 0, 1, 2 */
      Bit8u dac_state;
      struct {
        Bit8u red;
        Bit8u green;
        Bit8u blue;
        } data[256];
      Bit8u mask;
      } pel;


    struct {
      Bit8u   index;
      Bit8u   set_reset;
      Bit8u   enable_set_reset;
      Bit8u   color_compare;
      Bit8u   data_rotate;
      Bit8u   raster_op;
      Bit8u   read_map_select;
      Bit8u   write_mode;
      bx_bool read_mode;
      bx_bool odd_even;
      bx_bool chain_odd_even;
      Bit8u   shift_reg;
      bx_bool graphics_alpha;
      Bit8u   memory_mapping; /* 0 = use A0000-BFFFF
                               * 1 = use A0000-AFFFF EGA/VGA graphics modes
                               * 2 = use B0000-B7FFF Monochrome modes
                               * 3 = use B8000-BFFFF CGA modes
                               */
      Bit8u   color_dont_care;
      Bit8u   bitmask;
      Bit8u   latch[4];
      } graphics_ctrl;

    struct {
      Bit8u   index;
      Bit8u   map_mask;
      bx_bool map_mask_bit[4];
      bx_bool reset1;
      bx_bool reset2;
      Bit8u   reg1;
      Bit8u   char_map_select;
      bx_bool extended_mem;
      bx_bool odd_even;
      bx_bool chain_four;
      } sequencer;

    bx_bool  vga_mem_updated;
    unsigned x_tilesize;
    unsigned y_tilesize;
    unsigned line_offset;
    unsigned line_compare;
    unsigned vertical_display_end;
    bx_bool  vga_tile_updated[BX_NUM_X_TILES][BX_NUM_Y_TILES];
    Bit8u vga_memory[256 * 1024];
    Bit8u text_snapshot[32 * 1024]; // current text snapshot
    Bit8u rgb[3 * 256];
    Bit8u tile[X_TILESIZE * Y_TILESIZE * 4]; /**< Currently allocates the tile as large as needed. */
    Bit16u charmap_address;
    bx_bool x_dotclockdiv2;
    bx_bool y_doublescan;

#if BX_SUPPORT_VBE    
    Bit8u vbe_memory[VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES];
    Bit16u  vbe_cur_dispi;
    Bit16u  vbe_xres;
    Bit16u  vbe_yres;
    Bit16u  vbe_bpp;
    Bit16u  vbe_bank;
    bx_bool vbe_enabled;
    Bit16u  vbe_curindex;
    Bit32u  vbe_visable_screen_size; /**< in bytes */
    Bit16u  vbe_offset_x;		 /**< Virtual screen x start (in pixels) */ 
    Bit16u  vbe_offset_y;		 /**< Virtual screen y start (in pixels) */
    Bit16u  vbe_virtual_xres;
    Bit16u  vbe_virtual_yres;
    Bit16u  vbe_line_byte_width; /**< For dealing with bpp>8, this is they width of a line in bytes. */
    Bit32u  vbe_virtual_start;   /**< For dealing with bpp>8, this is where the virtual screen starts. */
    Bit8u   vbe_bpp_multiplier;  /**< We have to save this b/c sometimes we need to recalculate stuff with it. */
    bx_bool vbe_lfb_enabled;
#endif    
    } s;  // state information


#if !BX_USE_VGA_SMF
  Bit32u read(Bit32u address, unsigned io_len);
  void   write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
#else
  void write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
#endif

#if BX_SUPPORT_VBE

#if !BX_USE_VGA_SMF
  Bit32u vbe_read(Bit32u address, unsigned io_len);
  void   vbe_write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
#else
  void vbe_write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
#endif
#endif

  int timer_id;

  public:
  static void   timer_handler(void *);
  BX_VGA_SMF void   timer(void);

  private:
  BX_VGA_SMF void   update(void);
  BX_VGA_SMF void   dump_status(void);
  BX_VGA_SMF void determine_screen_dimensions(unsigned *piHeight,
                                              unsigned *piWidth);
  };