]> Git Repo - qemu.git/blob - hw/cirrus_vga.c
Merge remote-tracking branch 'stefanha/trivial-patches' into staging
[qemu.git] / hw / cirrus_vga.c
1 /*
2  * QEMU Cirrus CLGD 54xx VGA Emulator.
3  *
4  * Copyright (c) 2004 Fabrice Bellard
5  * Copyright (c) 2004 Makoto Suzuki (suzu)
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 /*
26  * Reference: Finn Thogersons' VGADOC4b
27  *   available at http://home.worldonline.dk/~finth/
28  */
29 #include "hw.h"
30 #include "pc.h"
31 #include "pci.h"
32 #include "console.h"
33 #include "vga_int.h"
34 #include "loader.h"
35
36 /*
37  * TODO:
38  *    - destination write mask support not complete (bits 5..7)
39  *    - optimize linear mappings
40  *    - optimize bitblt functions
41  */
42
43 //#define DEBUG_CIRRUS
44 //#define DEBUG_BITBLT
45
46 /***************************************
47  *
48  *  definitions
49  *
50  ***************************************/
51
52 // ID
53 #define CIRRUS_ID_CLGD5422  (0x23<<2)
54 #define CIRRUS_ID_CLGD5426  (0x24<<2)
55 #define CIRRUS_ID_CLGD5424  (0x25<<2)
56 #define CIRRUS_ID_CLGD5428  (0x26<<2)
57 #define CIRRUS_ID_CLGD5430  (0x28<<2)
58 #define CIRRUS_ID_CLGD5434  (0x2A<<2)
59 #define CIRRUS_ID_CLGD5436  (0x2B<<2)
60 #define CIRRUS_ID_CLGD5446  (0x2E<<2)
61
62 // sequencer 0x07
63 #define CIRRUS_SR7_BPP_VGA            0x00
64 #define CIRRUS_SR7_BPP_SVGA           0x01
65 #define CIRRUS_SR7_BPP_MASK           0x0e
66 #define CIRRUS_SR7_BPP_8              0x00
67 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK  0x02
68 #define CIRRUS_SR7_BPP_24             0x04
69 #define CIRRUS_SR7_BPP_16             0x06
70 #define CIRRUS_SR7_BPP_32             0x08
71 #define CIRRUS_SR7_ISAADDR_MASK       0xe0
72
73 // sequencer 0x0f
74 #define CIRRUS_MEMSIZE_512k        0x08
75 #define CIRRUS_MEMSIZE_1M          0x10
76 #define CIRRUS_MEMSIZE_2M          0x18
77 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
78
79 // sequencer 0x12
80 #define CIRRUS_CURSOR_SHOW         0x01
81 #define CIRRUS_CURSOR_HIDDENPEL    0x02
82 #define CIRRUS_CURSOR_LARGE        0x04 // 64x64 if set, 32x32 if clear
83
84 // sequencer 0x17
85 #define CIRRUS_BUSTYPE_VLBFAST   0x10
86 #define CIRRUS_BUSTYPE_PCI       0x20
87 #define CIRRUS_BUSTYPE_VLBSLOW   0x30
88 #define CIRRUS_BUSTYPE_ISA       0x38
89 #define CIRRUS_MMIO_ENABLE       0x04
90 #define CIRRUS_MMIO_USE_PCIADDR  0x40   // 0xb8000 if cleared.
91 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
92
93 // control 0x0b
94 #define CIRRUS_BANKING_DUAL             0x01
95 #define CIRRUS_BANKING_GRANULARITY_16K  0x20    // set:16k, clear:4k
96
97 // control 0x30
98 #define CIRRUS_BLTMODE_BACKWARDS        0x01
99 #define CIRRUS_BLTMODE_MEMSYSDEST       0x02
100 #define CIRRUS_BLTMODE_MEMSYSSRC        0x04
101 #define CIRRUS_BLTMODE_TRANSPARENTCOMP  0x08
102 #define CIRRUS_BLTMODE_PATTERNCOPY      0x40
103 #define CIRRUS_BLTMODE_COLOREXPAND      0x80
104 #define CIRRUS_BLTMODE_PIXELWIDTHMASK   0x30
105 #define CIRRUS_BLTMODE_PIXELWIDTH8      0x00
106 #define CIRRUS_BLTMODE_PIXELWIDTH16     0x10
107 #define CIRRUS_BLTMODE_PIXELWIDTH24     0x20
108 #define CIRRUS_BLTMODE_PIXELWIDTH32     0x30
109
110 // control 0x31
111 #define CIRRUS_BLT_BUSY                 0x01
112 #define CIRRUS_BLT_START                0x02
113 #define CIRRUS_BLT_RESET                0x04
114 #define CIRRUS_BLT_FIFOUSED             0x10
115 #define CIRRUS_BLT_AUTOSTART            0x80
116
117 // control 0x32
118 #define CIRRUS_ROP_0                    0x00
119 #define CIRRUS_ROP_SRC_AND_DST          0x05
120 #define CIRRUS_ROP_NOP                  0x06
121 #define CIRRUS_ROP_SRC_AND_NOTDST       0x09
122 #define CIRRUS_ROP_NOTDST               0x0b
123 #define CIRRUS_ROP_SRC                  0x0d
124 #define CIRRUS_ROP_1                    0x0e
125 #define CIRRUS_ROP_NOTSRC_AND_DST       0x50
126 #define CIRRUS_ROP_SRC_XOR_DST          0x59
127 #define CIRRUS_ROP_SRC_OR_DST           0x6d
128 #define CIRRUS_ROP_NOTSRC_OR_NOTDST     0x90
129 #define CIRRUS_ROP_SRC_NOTXOR_DST       0x95
130 #define CIRRUS_ROP_SRC_OR_NOTDST        0xad
131 #define CIRRUS_ROP_NOTSRC               0xd0
132 #define CIRRUS_ROP_NOTSRC_OR_DST        0xd6
133 #define CIRRUS_ROP_NOTSRC_AND_NOTDST    0xda
134
135 #define CIRRUS_ROP_NOP_INDEX 2
136 #define CIRRUS_ROP_SRC_INDEX 5
137
138 // control 0x33
139 #define CIRRUS_BLTMODEEXT_SOLIDFILL        0x04
140 #define CIRRUS_BLTMODEEXT_COLOREXPINV      0x02
141 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
142
143 // memory-mapped IO
144 #define CIRRUS_MMIO_BLTBGCOLOR        0x00      // dword
145 #define CIRRUS_MMIO_BLTFGCOLOR        0x04      // dword
146 #define CIRRUS_MMIO_BLTWIDTH          0x08      // word
147 #define CIRRUS_MMIO_BLTHEIGHT         0x0a      // word
148 #define CIRRUS_MMIO_BLTDESTPITCH      0x0c      // word
149 #define CIRRUS_MMIO_BLTSRCPITCH       0x0e      // word
150 #define CIRRUS_MMIO_BLTDESTADDR       0x10      // dword
151 #define CIRRUS_MMIO_BLTSRCADDR        0x14      // dword
152 #define CIRRUS_MMIO_BLTWRITEMASK      0x17      // byte
153 #define CIRRUS_MMIO_BLTMODE           0x18      // byte
154 #define CIRRUS_MMIO_BLTROP            0x1a      // byte
155 #define CIRRUS_MMIO_BLTMODEEXT        0x1b      // byte
156 #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c    // word?
157 #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20        // word?
158 #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24     // word
159 #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26     // word
160 #define CIRRUS_MMIO_LINEARDRAW_END_X  0x28      // word
161 #define CIRRUS_MMIO_LINEARDRAW_END_Y  0x2a      // word
162 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c       // byte
163 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d  // byte
164 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e      // byte
165 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f     // byte
166 #define CIRRUS_MMIO_BRESENHAM_K1      0x30      // word
167 #define CIRRUS_MMIO_BRESENHAM_K3      0x32      // word
168 #define CIRRUS_MMIO_BRESENHAM_ERROR   0x34      // word
169 #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36  // word
170 #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38    // byte
171 #define CIRRUS_MMIO_LINEDRAW_MODE     0x39      // byte
172 #define CIRRUS_MMIO_BLTSTATUS         0x40      // byte
173
174 #define CIRRUS_PNPMMIO_SIZE         0x1000
175
176 #define BLTUNSAFE(s) \
177     ( \
178         ( /* check dst is within bounds */ \
179             (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
180                 + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
181                     (s)->vga.vram_size \
182         ) || \
183         ( /* check src is within bounds */ \
184             (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
185                 + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
186                     (s)->vga.vram_size \
187         ) \
188     )
189
190 struct CirrusVGAState;
191 typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
192                                      uint8_t * dst, const uint8_t * src,
193                                      int dstpitch, int srcpitch,
194                                      int bltwidth, int bltheight);
195 typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
196                               uint8_t *dst, int dst_pitch, int width, int height);
197
198 typedef struct CirrusVGAState {
199     VGACommonState vga;
200
201     MemoryRegion cirrus_linear_io;
202     MemoryRegion cirrus_linear_bitblt_io;
203     MemoryRegion cirrus_mmio_io;
204     MemoryRegion pci_bar;
205     bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
206     MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
207     MemoryRegion low_mem;           /* always mapped, overridden by: */
208     MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
209     uint32_t cirrus_addr_mask;
210     uint32_t linear_mmio_mask;
211     uint8_t cirrus_shadow_gr0;
212     uint8_t cirrus_shadow_gr1;
213     uint8_t cirrus_hidden_dac_lockindex;
214     uint8_t cirrus_hidden_dac_data;
215     uint32_t cirrus_bank_base[2];
216     uint32_t cirrus_bank_limit[2];
217     uint8_t cirrus_hidden_palette[48];
218     uint32_t hw_cursor_x;
219     uint32_t hw_cursor_y;
220     int cirrus_blt_pixelwidth;
221     int cirrus_blt_width;
222     int cirrus_blt_height;
223     int cirrus_blt_dstpitch;
224     int cirrus_blt_srcpitch;
225     uint32_t cirrus_blt_fgcol;
226     uint32_t cirrus_blt_bgcol;
227     uint32_t cirrus_blt_dstaddr;
228     uint32_t cirrus_blt_srcaddr;
229     uint8_t cirrus_blt_mode;
230     uint8_t cirrus_blt_modeext;
231     cirrus_bitblt_rop_t cirrus_rop;
232 #define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
233     uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
234     uint8_t *cirrus_srcptr;
235     uint8_t *cirrus_srcptr_end;
236     uint32_t cirrus_srccounter;
237     /* hwcursor display state */
238     int last_hw_cursor_size;
239     int last_hw_cursor_x;
240     int last_hw_cursor_y;
241     int last_hw_cursor_y_start;
242     int last_hw_cursor_y_end;
243     int real_vram_size; /* XXX: suppress that */
244     int device_id;
245     int bustype;
246 } CirrusVGAState;
247
248 typedef struct PCICirrusVGAState {
249     PCIDevice dev;
250     CirrusVGAState cirrus_vga;
251 } PCICirrusVGAState;
252
253 static uint8_t rop_to_index[256];
254
255 /***************************************
256  *
257  *  prototypes.
258  *
259  ***************************************/
260
261
262 static void cirrus_bitblt_reset(CirrusVGAState *s);
263 static void cirrus_update_memory_access(CirrusVGAState *s);
264
265 /***************************************
266  *
267  *  raster operations
268  *
269  ***************************************/
270
271 static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
272                                   uint8_t *dst,const uint8_t *src,
273                                   int dstpitch,int srcpitch,
274                                   int bltwidth,int bltheight)
275 {
276 }
277
278 static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
279                                    uint8_t *dst,
280                                    int dstpitch, int bltwidth,int bltheight)
281 {
282 }
283
284 #define ROP_NAME 0
285 #define ROP_FN(d, s) 0
286 #include "cirrus_vga_rop.h"
287
288 #define ROP_NAME src_and_dst
289 #define ROP_FN(d, s) (s) & (d)
290 #include "cirrus_vga_rop.h"
291
292 #define ROP_NAME src_and_notdst
293 #define ROP_FN(d, s) (s) & (~(d))
294 #include "cirrus_vga_rop.h"
295
296 #define ROP_NAME notdst
297 #define ROP_FN(d, s) ~(d)
298 #include "cirrus_vga_rop.h"
299
300 #define ROP_NAME src
301 #define ROP_FN(d, s) s
302 #include "cirrus_vga_rop.h"
303
304 #define ROP_NAME 1
305 #define ROP_FN(d, s) ~0
306 #include "cirrus_vga_rop.h"
307
308 #define ROP_NAME notsrc_and_dst
309 #define ROP_FN(d, s) (~(s)) & (d)
310 #include "cirrus_vga_rop.h"
311
312 #define ROP_NAME src_xor_dst
313 #define ROP_FN(d, s) (s) ^ (d)
314 #include "cirrus_vga_rop.h"
315
316 #define ROP_NAME src_or_dst
317 #define ROP_FN(d, s) (s) | (d)
318 #include "cirrus_vga_rop.h"
319
320 #define ROP_NAME notsrc_or_notdst
321 #define ROP_FN(d, s) (~(s)) | (~(d))
322 #include "cirrus_vga_rop.h"
323
324 #define ROP_NAME src_notxor_dst
325 #define ROP_FN(d, s) ~((s) ^ (d))
326 #include "cirrus_vga_rop.h"
327
328 #define ROP_NAME src_or_notdst
329 #define ROP_FN(d, s) (s) | (~(d))
330 #include "cirrus_vga_rop.h"
331
332 #define ROP_NAME notsrc
333 #define ROP_FN(d, s) (~(s))
334 #include "cirrus_vga_rop.h"
335
336 #define ROP_NAME notsrc_or_dst
337 #define ROP_FN(d, s) (~(s)) | (d)
338 #include "cirrus_vga_rop.h"
339
340 #define ROP_NAME notsrc_and_notdst
341 #define ROP_FN(d, s) (~(s)) & (~(d))
342 #include "cirrus_vga_rop.h"
343
344 static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
345     cirrus_bitblt_rop_fwd_0,
346     cirrus_bitblt_rop_fwd_src_and_dst,
347     cirrus_bitblt_rop_nop,
348     cirrus_bitblt_rop_fwd_src_and_notdst,
349     cirrus_bitblt_rop_fwd_notdst,
350     cirrus_bitblt_rop_fwd_src,
351     cirrus_bitblt_rop_fwd_1,
352     cirrus_bitblt_rop_fwd_notsrc_and_dst,
353     cirrus_bitblt_rop_fwd_src_xor_dst,
354     cirrus_bitblt_rop_fwd_src_or_dst,
355     cirrus_bitblt_rop_fwd_notsrc_or_notdst,
356     cirrus_bitblt_rop_fwd_src_notxor_dst,
357     cirrus_bitblt_rop_fwd_src_or_notdst,
358     cirrus_bitblt_rop_fwd_notsrc,
359     cirrus_bitblt_rop_fwd_notsrc_or_dst,
360     cirrus_bitblt_rop_fwd_notsrc_and_notdst,
361 };
362
363 static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
364     cirrus_bitblt_rop_bkwd_0,
365     cirrus_bitblt_rop_bkwd_src_and_dst,
366     cirrus_bitblt_rop_nop,
367     cirrus_bitblt_rop_bkwd_src_and_notdst,
368     cirrus_bitblt_rop_bkwd_notdst,
369     cirrus_bitblt_rop_bkwd_src,
370     cirrus_bitblt_rop_bkwd_1,
371     cirrus_bitblt_rop_bkwd_notsrc_and_dst,
372     cirrus_bitblt_rop_bkwd_src_xor_dst,
373     cirrus_bitblt_rop_bkwd_src_or_dst,
374     cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
375     cirrus_bitblt_rop_bkwd_src_notxor_dst,
376     cirrus_bitblt_rop_bkwd_src_or_notdst,
377     cirrus_bitblt_rop_bkwd_notsrc,
378     cirrus_bitblt_rop_bkwd_notsrc_or_dst,
379     cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
380 };
381
382 #define TRANSP_ROP(name) {\
383     name ## _8,\
384     name ## _16,\
385         }
386 #define TRANSP_NOP(func) {\
387     func,\
388     func,\
389         }
390
391 static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
392     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
393     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
394     TRANSP_NOP(cirrus_bitblt_rop_nop),
395     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
396     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
397     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
398     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
399     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
400     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
401     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
402     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
403     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
404     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
405     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
406     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
407     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
408 };
409
410 static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
411     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
412     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
413     TRANSP_NOP(cirrus_bitblt_rop_nop),
414     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
415     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
416     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
417     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
418     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
419     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
420     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
421     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
422     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
423     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
424     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
425     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
426     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
427 };
428
429 #define ROP2(name) {\
430     name ## _8,\
431     name ## _16,\
432     name ## _24,\
433     name ## _32,\
434         }
435
436 #define ROP_NOP2(func) {\
437     func,\
438     func,\
439     func,\
440     func,\
441         }
442
443 static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
444     ROP2(cirrus_patternfill_0),
445     ROP2(cirrus_patternfill_src_and_dst),
446     ROP_NOP2(cirrus_bitblt_rop_nop),
447     ROP2(cirrus_patternfill_src_and_notdst),
448     ROP2(cirrus_patternfill_notdst),
449     ROP2(cirrus_patternfill_src),
450     ROP2(cirrus_patternfill_1),
451     ROP2(cirrus_patternfill_notsrc_and_dst),
452     ROP2(cirrus_patternfill_src_xor_dst),
453     ROP2(cirrus_patternfill_src_or_dst),
454     ROP2(cirrus_patternfill_notsrc_or_notdst),
455     ROP2(cirrus_patternfill_src_notxor_dst),
456     ROP2(cirrus_patternfill_src_or_notdst),
457     ROP2(cirrus_patternfill_notsrc),
458     ROP2(cirrus_patternfill_notsrc_or_dst),
459     ROP2(cirrus_patternfill_notsrc_and_notdst),
460 };
461
462 static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
463     ROP2(cirrus_colorexpand_transp_0),
464     ROP2(cirrus_colorexpand_transp_src_and_dst),
465     ROP_NOP2(cirrus_bitblt_rop_nop),
466     ROP2(cirrus_colorexpand_transp_src_and_notdst),
467     ROP2(cirrus_colorexpand_transp_notdst),
468     ROP2(cirrus_colorexpand_transp_src),
469     ROP2(cirrus_colorexpand_transp_1),
470     ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
471     ROP2(cirrus_colorexpand_transp_src_xor_dst),
472     ROP2(cirrus_colorexpand_transp_src_or_dst),
473     ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
474     ROP2(cirrus_colorexpand_transp_src_notxor_dst),
475     ROP2(cirrus_colorexpand_transp_src_or_notdst),
476     ROP2(cirrus_colorexpand_transp_notsrc),
477     ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
478     ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
479 };
480
481 static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
482     ROP2(cirrus_colorexpand_0),
483     ROP2(cirrus_colorexpand_src_and_dst),
484     ROP_NOP2(cirrus_bitblt_rop_nop),
485     ROP2(cirrus_colorexpand_src_and_notdst),
486     ROP2(cirrus_colorexpand_notdst),
487     ROP2(cirrus_colorexpand_src),
488     ROP2(cirrus_colorexpand_1),
489     ROP2(cirrus_colorexpand_notsrc_and_dst),
490     ROP2(cirrus_colorexpand_src_xor_dst),
491     ROP2(cirrus_colorexpand_src_or_dst),
492     ROP2(cirrus_colorexpand_notsrc_or_notdst),
493     ROP2(cirrus_colorexpand_src_notxor_dst),
494     ROP2(cirrus_colorexpand_src_or_notdst),
495     ROP2(cirrus_colorexpand_notsrc),
496     ROP2(cirrus_colorexpand_notsrc_or_dst),
497     ROP2(cirrus_colorexpand_notsrc_and_notdst),
498 };
499
500 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
501     ROP2(cirrus_colorexpand_pattern_transp_0),
502     ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
503     ROP_NOP2(cirrus_bitblt_rop_nop),
504     ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
505     ROP2(cirrus_colorexpand_pattern_transp_notdst),
506     ROP2(cirrus_colorexpand_pattern_transp_src),
507     ROP2(cirrus_colorexpand_pattern_transp_1),
508     ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
509     ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
510     ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
511     ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
512     ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
513     ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
514     ROP2(cirrus_colorexpand_pattern_transp_notsrc),
515     ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
516     ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
517 };
518
519 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
520     ROP2(cirrus_colorexpand_pattern_0),
521     ROP2(cirrus_colorexpand_pattern_src_and_dst),
522     ROP_NOP2(cirrus_bitblt_rop_nop),
523     ROP2(cirrus_colorexpand_pattern_src_and_notdst),
524     ROP2(cirrus_colorexpand_pattern_notdst),
525     ROP2(cirrus_colorexpand_pattern_src),
526     ROP2(cirrus_colorexpand_pattern_1),
527     ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
528     ROP2(cirrus_colorexpand_pattern_src_xor_dst),
529     ROP2(cirrus_colorexpand_pattern_src_or_dst),
530     ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
531     ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
532     ROP2(cirrus_colorexpand_pattern_src_or_notdst),
533     ROP2(cirrus_colorexpand_pattern_notsrc),
534     ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
535     ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
536 };
537
538 static const cirrus_fill_t cirrus_fill[16][4] = {
539     ROP2(cirrus_fill_0),
540     ROP2(cirrus_fill_src_and_dst),
541     ROP_NOP2(cirrus_bitblt_fill_nop),
542     ROP2(cirrus_fill_src_and_notdst),
543     ROP2(cirrus_fill_notdst),
544     ROP2(cirrus_fill_src),
545     ROP2(cirrus_fill_1),
546     ROP2(cirrus_fill_notsrc_and_dst),
547     ROP2(cirrus_fill_src_xor_dst),
548     ROP2(cirrus_fill_src_or_dst),
549     ROP2(cirrus_fill_notsrc_or_notdst),
550     ROP2(cirrus_fill_src_notxor_dst),
551     ROP2(cirrus_fill_src_or_notdst),
552     ROP2(cirrus_fill_notsrc),
553     ROP2(cirrus_fill_notsrc_or_dst),
554     ROP2(cirrus_fill_notsrc_and_notdst),
555 };
556
557 static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
558 {
559     unsigned int color;
560     switch (s->cirrus_blt_pixelwidth) {
561     case 1:
562         s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
563         break;
564     case 2:
565         color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
566         s->cirrus_blt_fgcol = le16_to_cpu(color);
567         break;
568     case 3:
569         s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
570             (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
571         break;
572     default:
573     case 4:
574         color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
575             (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
576         s->cirrus_blt_fgcol = le32_to_cpu(color);
577         break;
578     }
579 }
580
581 static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
582 {
583     unsigned int color;
584     switch (s->cirrus_blt_pixelwidth) {
585     case 1:
586         s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
587         break;
588     case 2:
589         color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
590         s->cirrus_blt_bgcol = le16_to_cpu(color);
591         break;
592     case 3:
593         s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
594             (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
595         break;
596     default:
597     case 4:
598         color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
599             (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
600         s->cirrus_blt_bgcol = le32_to_cpu(color);
601         break;
602     }
603 }
604
605 static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
606                                      int off_pitch, int bytesperline,
607                                      int lines)
608 {
609     int y;
610     int off_cur;
611     int off_cur_end;
612
613     for (y = 0; y < lines; y++) {
614         off_cur = off_begin;
615         off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
616         off_cur &= TARGET_PAGE_MASK;
617         while (off_cur < off_cur_end) {
618             memory_region_set_dirty(&s->vga.vram, off_cur);
619             off_cur += TARGET_PAGE_SIZE;
620         }
621         off_begin += off_pitch;
622     }
623 }
624
625 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
626                                             const uint8_t * src)
627 {
628     uint8_t *dst;
629
630     dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
631
632     if (BLTUNSAFE(s))
633         return 0;
634
635     (*s->cirrus_rop) (s, dst, src,
636                       s->cirrus_blt_dstpitch, 0,
637                       s->cirrus_blt_width, s->cirrus_blt_height);
638     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
639                              s->cirrus_blt_dstpitch, s->cirrus_blt_width,
640                              s->cirrus_blt_height);
641     return 1;
642 }
643
644 /* fill */
645
646 static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
647 {
648     cirrus_fill_t rop_func;
649
650     if (BLTUNSAFE(s))
651         return 0;
652     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
653     rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
654              s->cirrus_blt_dstpitch,
655              s->cirrus_blt_width, s->cirrus_blt_height);
656     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
657                              s->cirrus_blt_dstpitch, s->cirrus_blt_width,
658                              s->cirrus_blt_height);
659     cirrus_bitblt_reset(s);
660     return 1;
661 }
662
663 /***************************************
664  *
665  *  bitblt (video-to-video)
666  *
667  ***************************************/
668
669 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
670 {
671     return cirrus_bitblt_common_patterncopy(s,
672                                             s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
673                                             s->cirrus_addr_mask));
674 }
675
676 static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
677 {
678     int sx = 0, sy = 0;
679     int dx = 0, dy = 0;
680     int depth = 0;
681     int notify = 0;
682
683     /* make sure to only copy if it's a plain copy ROP */
684     if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
685         *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
686
687         int width, height;
688
689         depth = s->vga.get_bpp(&s->vga) / 8;
690         s->vga.get_resolution(&s->vga, &width, &height);
691
692         /* extra x, y */
693         sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
694         sy = (src / ABS(s->cirrus_blt_srcpitch));
695         dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
696         dy = (dst / ABS(s->cirrus_blt_dstpitch));
697
698         /* normalize width */
699         w /= depth;
700
701         /* if we're doing a backward copy, we have to adjust
702            our x/y to be the upper left corner (instead of the lower
703            right corner) */
704         if (s->cirrus_blt_dstpitch < 0) {
705             sx -= (s->cirrus_blt_width / depth) - 1;
706             dx -= (s->cirrus_blt_width / depth) - 1;
707             sy -= s->cirrus_blt_height - 1;
708             dy -= s->cirrus_blt_height - 1;
709         }
710
711         /* are we in the visible portion of memory? */
712         if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
713             (sx + w) <= width && (sy + h) <= height &&
714             (dx + w) <= width && (dy + h) <= height) {
715             notify = 1;
716         }
717     }
718
719     /* we have to flush all pending changes so that the copy
720        is generated at the appropriate moment in time */
721     if (notify)
722         vga_hw_update();
723
724     (*s->cirrus_rop) (s, s->vga.vram_ptr +
725                       (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
726                       s->vga.vram_ptr +
727                       (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
728                       s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
729                       s->cirrus_blt_width, s->cirrus_blt_height);
730
731     if (notify)
732         qemu_console_copy(s->vga.ds,
733                           sx, sy, dx, dy,
734                           s->cirrus_blt_width / depth,
735                           s->cirrus_blt_height);
736
737     /* we don't have to notify the display that this portion has
738        changed since qemu_console_copy implies this */
739
740     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
741                                 s->cirrus_blt_dstpitch, s->cirrus_blt_width,
742                                 s->cirrus_blt_height);
743 }
744
745 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
746 {
747     if (BLTUNSAFE(s))
748         return 0;
749
750     cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
751             s->cirrus_blt_srcaddr - s->vga.start_addr,
752             s->cirrus_blt_width, s->cirrus_blt_height);
753
754     return 1;
755 }
756
757 /***************************************
758  *
759  *  bitblt (cpu-to-video)
760  *
761  ***************************************/
762
763 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
764 {
765     int copy_count;
766     uint8_t *end_ptr;
767
768     if (s->cirrus_srccounter > 0) {
769         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
770             cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
771         the_end:
772             s->cirrus_srccounter = 0;
773             cirrus_bitblt_reset(s);
774         } else {
775             /* at least one scan line */
776             do {
777                 (*s->cirrus_rop)(s, s->vga.vram_ptr +
778                                  (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
779                                   s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
780                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
781                                          s->cirrus_blt_width, 1);
782                 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
783                 s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
784                 if (s->cirrus_srccounter <= 0)
785                     goto the_end;
786                 /* more bytes than needed can be transfered because of
787                    word alignment, so we keep them for the next line */
788                 /* XXX: keep alignment to speed up transfer */
789                 end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
790                 copy_count = s->cirrus_srcptr_end - end_ptr;
791                 memmove(s->cirrus_bltbuf, end_ptr, copy_count);
792                 s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
793                 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
794             } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
795         }
796     }
797 }
798
799 /***************************************
800  *
801  *  bitblt wrapper
802  *
803  ***************************************/
804
805 static void cirrus_bitblt_reset(CirrusVGAState * s)
806 {
807     int need_update;
808
809     s->vga.gr[0x31] &=
810         ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
811     need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
812         || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
813     s->cirrus_srcptr = &s->cirrus_bltbuf[0];
814     s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
815     s->cirrus_srccounter = 0;
816     if (!need_update)
817         return;
818     cirrus_update_memory_access(s);
819 }
820
821 static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
822 {
823     int w;
824
825     s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
826     s->cirrus_srcptr = &s->cirrus_bltbuf[0];
827     s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
828
829     if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
830         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
831             s->cirrus_blt_srcpitch = 8;
832         } else {
833             /* XXX: check for 24 bpp */
834             s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
835         }
836         s->cirrus_srccounter = s->cirrus_blt_srcpitch;
837     } else {
838         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
839             w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
840             if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
841                 s->cirrus_blt_srcpitch = ((w + 31) >> 5);
842             else
843                 s->cirrus_blt_srcpitch = ((w + 7) >> 3);
844         } else {
845             /* always align input size to 32 bits */
846             s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
847         }
848         s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
849     }
850     s->cirrus_srcptr = s->cirrus_bltbuf;
851     s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
852     cirrus_update_memory_access(s);
853     return 1;
854 }
855
856 static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
857 {
858     /* XXX */
859 #ifdef DEBUG_BITBLT
860     printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
861 #endif
862     return 0;
863 }
864
865 static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
866 {
867     int ret;
868
869     if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
870         ret = cirrus_bitblt_videotovideo_patterncopy(s);
871     } else {
872         ret = cirrus_bitblt_videotovideo_copy(s);
873     }
874     if (ret)
875         cirrus_bitblt_reset(s);
876     return ret;
877 }
878
879 static void cirrus_bitblt_start(CirrusVGAState * s)
880 {
881     uint8_t blt_rop;
882
883     s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
884
885     s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
886     s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
887     s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
888     s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
889     s->cirrus_blt_dstaddr =
890         (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
891     s->cirrus_blt_srcaddr =
892         (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
893     s->cirrus_blt_mode = s->vga.gr[0x30];
894     s->cirrus_blt_modeext = s->vga.gr[0x33];
895     blt_rop = s->vga.gr[0x32];
896
897 #ifdef DEBUG_BITBLT
898     printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
899            blt_rop,
900            s->cirrus_blt_mode,
901            s->cirrus_blt_modeext,
902            s->cirrus_blt_width,
903            s->cirrus_blt_height,
904            s->cirrus_blt_dstpitch,
905            s->cirrus_blt_srcpitch,
906            s->cirrus_blt_dstaddr,
907            s->cirrus_blt_srcaddr,
908            s->vga.gr[0x2f]);
909 #endif
910
911     switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
912     case CIRRUS_BLTMODE_PIXELWIDTH8:
913         s->cirrus_blt_pixelwidth = 1;
914         break;
915     case CIRRUS_BLTMODE_PIXELWIDTH16:
916         s->cirrus_blt_pixelwidth = 2;
917         break;
918     case CIRRUS_BLTMODE_PIXELWIDTH24:
919         s->cirrus_blt_pixelwidth = 3;
920         break;
921     case CIRRUS_BLTMODE_PIXELWIDTH32:
922         s->cirrus_blt_pixelwidth = 4;
923         break;
924     default:
925 #ifdef DEBUG_BITBLT
926         printf("cirrus: bitblt - pixel width is unknown\n");
927 #endif
928         goto bitblt_ignore;
929     }
930     s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
931
932     if ((s->
933          cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
934                             CIRRUS_BLTMODE_MEMSYSDEST))
935         == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
936 #ifdef DEBUG_BITBLT
937         printf("cirrus: bitblt - memory-to-memory copy is requested\n");
938 #endif
939         goto bitblt_ignore;
940     }
941
942     if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
943         (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
944                                CIRRUS_BLTMODE_TRANSPARENTCOMP |
945                                CIRRUS_BLTMODE_PATTERNCOPY |
946                                CIRRUS_BLTMODE_COLOREXPAND)) ==
947          (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
948         cirrus_bitblt_fgcol(s);
949         cirrus_bitblt_solidfill(s, blt_rop);
950     } else {
951         if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
952                                    CIRRUS_BLTMODE_PATTERNCOPY)) ==
953             CIRRUS_BLTMODE_COLOREXPAND) {
954
955             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
956                 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
957                     cirrus_bitblt_bgcol(s);
958                 else
959                     cirrus_bitblt_fgcol(s);
960                 s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
961             } else {
962                 cirrus_bitblt_fgcol(s);
963                 cirrus_bitblt_bgcol(s);
964                 s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
965             }
966         } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
967             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
968                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
969                     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
970                         cirrus_bitblt_bgcol(s);
971                     else
972                         cirrus_bitblt_fgcol(s);
973                     s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
974                 } else {
975                     cirrus_bitblt_fgcol(s);
976                     cirrus_bitblt_bgcol(s);
977                     s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
978                 }
979             } else {
980                 s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
981             }
982         } else {
983             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
984                 if (s->cirrus_blt_pixelwidth > 2) {
985                     printf("src transparent without colorexpand must be 8bpp or 16bpp\n");
986                     goto bitblt_ignore;
987                 }
988                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
989                     s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
990                     s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
991                     s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
992                 } else {
993                     s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
994                 }
995             } else {
996                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
997                     s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
998                     s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
999                     s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
1000                 } else {
1001                     s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
1002                 }
1003             }
1004         }
1005         // setup bitblt engine.
1006         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
1007             if (!cirrus_bitblt_cputovideo(s))
1008                 goto bitblt_ignore;
1009         } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
1010             if (!cirrus_bitblt_videotocpu(s))
1011                 goto bitblt_ignore;
1012         } else {
1013             if (!cirrus_bitblt_videotovideo(s))
1014                 goto bitblt_ignore;
1015         }
1016     }
1017     return;
1018   bitblt_ignore:;
1019     cirrus_bitblt_reset(s);
1020 }
1021
1022 static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1023 {
1024     unsigned old_value;
1025
1026     old_value = s->vga.gr[0x31];
1027     s->vga.gr[0x31] = reg_value;
1028
1029     if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1030         ((reg_value & CIRRUS_BLT_RESET) == 0)) {
1031         cirrus_bitblt_reset(s);
1032     } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1033                ((reg_value & CIRRUS_BLT_START) != 0)) {
1034         cirrus_bitblt_start(s);
1035     }
1036 }
1037
1038
1039 /***************************************
1040  *
1041  *  basic parameters
1042  *
1043  ***************************************/
1044
1045 static void cirrus_get_offsets(VGACommonState *s1,
1046                                uint32_t *pline_offset,
1047                                uint32_t *pstart_addr,
1048                                uint32_t *pline_compare)
1049 {
1050     CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1051     uint32_t start_addr, line_offset, line_compare;
1052
1053     line_offset = s->vga.cr[0x13]
1054         | ((s->vga.cr[0x1b] & 0x10) << 4);
1055     line_offset <<= 3;
1056     *pline_offset = line_offset;
1057
1058     start_addr = (s->vga.cr[0x0c] << 8)
1059         | s->vga.cr[0x0d]
1060         | ((s->vga.cr[0x1b] & 0x01) << 16)
1061         | ((s->vga.cr[0x1b] & 0x0c) << 15)
1062         | ((s->vga.cr[0x1d] & 0x80) << 12);
1063     *pstart_addr = start_addr;
1064
1065     line_compare = s->vga.cr[0x18] |
1066         ((s->vga.cr[0x07] & 0x10) << 4) |
1067         ((s->vga.cr[0x09] & 0x40) << 3);
1068     *pline_compare = line_compare;
1069 }
1070
1071 static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1072 {
1073     uint32_t ret = 16;
1074
1075     switch (s->cirrus_hidden_dac_data & 0xf) {
1076     case 0:
1077         ret = 15;
1078         break;                  /* Sierra HiColor */
1079     case 1:
1080         ret = 16;
1081         break;                  /* XGA HiColor */
1082     default:
1083 #ifdef DEBUG_CIRRUS
1084         printf("cirrus: invalid DAC value %x in 16bpp\n",
1085                (s->cirrus_hidden_dac_data & 0xf));
1086 #endif
1087         ret = 15;               /* XXX */
1088         break;
1089     }
1090     return ret;
1091 }
1092
1093 static int cirrus_get_bpp(VGACommonState *s1)
1094 {
1095     CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1096     uint32_t ret = 8;
1097
1098     if ((s->vga.sr[0x07] & 0x01) != 0) {
1099         /* Cirrus SVGA */
1100         switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1101         case CIRRUS_SR7_BPP_8:
1102             ret = 8;
1103             break;
1104         case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1105             ret = cirrus_get_bpp16_depth(s);
1106             break;
1107         case CIRRUS_SR7_BPP_24:
1108             ret = 24;
1109             break;
1110         case CIRRUS_SR7_BPP_16:
1111             ret = cirrus_get_bpp16_depth(s);
1112             break;
1113         case CIRRUS_SR7_BPP_32:
1114             ret = 32;
1115             break;
1116         default:
1117 #ifdef DEBUG_CIRRUS
1118             printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
1119 #endif
1120             ret = 8;
1121             break;
1122         }
1123     } else {
1124         /* VGA */
1125         ret = 0;
1126     }
1127
1128     return ret;
1129 }
1130
1131 static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1132 {
1133     int width, height;
1134
1135     width = (s->cr[0x01] + 1) * 8;
1136     height = s->cr[0x12] |
1137         ((s->cr[0x07] & 0x02) << 7) |
1138         ((s->cr[0x07] & 0x40) << 3);
1139     height = (height + 1);
1140     /* interlace support */
1141     if (s->cr[0x1a] & 0x01)
1142         height = height * 2;
1143     *pwidth = width;
1144     *pheight = height;
1145 }
1146
1147 /***************************************
1148  *
1149  * bank memory
1150  *
1151  ***************************************/
1152
1153 static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1154 {
1155     unsigned offset;
1156     unsigned limit;
1157
1158     if ((s->vga.gr[0x0b] & 0x01) != 0)  /* dual bank */
1159         offset = s->vga.gr[0x09 + bank_index];
1160     else                        /* single bank */
1161         offset = s->vga.gr[0x09];
1162
1163     if ((s->vga.gr[0x0b] & 0x20) != 0)
1164         offset <<= 14;
1165     else
1166         offset <<= 12;
1167
1168     if (s->real_vram_size <= offset)
1169         limit = 0;
1170     else
1171         limit = s->real_vram_size - offset;
1172
1173     if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1174         if (limit > 0x8000) {
1175             offset += 0x8000;
1176             limit -= 0x8000;
1177         } else {
1178             limit = 0;
1179         }
1180     }
1181
1182     if (limit > 0) {
1183         s->cirrus_bank_base[bank_index] = offset;
1184         s->cirrus_bank_limit[bank_index] = limit;
1185     } else {
1186         s->cirrus_bank_base[bank_index] = 0;
1187         s->cirrus_bank_limit[bank_index] = 0;
1188     }
1189 }
1190
1191 /***************************************
1192  *
1193  *  I/O access between 0x3c4-0x3c5
1194  *
1195  ***************************************/
1196
1197 static int cirrus_vga_read_sr(CirrusVGAState * s)
1198 {
1199     switch (s->vga.sr_index) {
1200     case 0x00:                  // Standard VGA
1201     case 0x01:                  // Standard VGA
1202     case 0x02:                  // Standard VGA
1203     case 0x03:                  // Standard VGA
1204     case 0x04:                  // Standard VGA
1205         return s->vga.sr[s->vga.sr_index];
1206     case 0x06:                  // Unlock Cirrus extensions
1207         return s->vga.sr[s->vga.sr_index];
1208     case 0x10:
1209     case 0x30:
1210     case 0x50:
1211     case 0x70:                  // Graphics Cursor X
1212     case 0x90:
1213     case 0xb0:
1214     case 0xd0:
1215     case 0xf0:                  // Graphics Cursor X
1216         return s->vga.sr[0x10];
1217     case 0x11:
1218     case 0x31:
1219     case 0x51:
1220     case 0x71:                  // Graphics Cursor Y
1221     case 0x91:
1222     case 0xb1:
1223     case 0xd1:
1224     case 0xf1:                  // Graphics Cursor Y
1225         return s->vga.sr[0x11];
1226     case 0x05:                  // ???
1227     case 0x07:                  // Extended Sequencer Mode
1228     case 0x08:                  // EEPROM Control
1229     case 0x09:                  // Scratch Register 0
1230     case 0x0a:                  // Scratch Register 1
1231     case 0x0b:                  // VCLK 0
1232     case 0x0c:                  // VCLK 1
1233     case 0x0d:                  // VCLK 2
1234     case 0x0e:                  // VCLK 3
1235     case 0x0f:                  // DRAM Control
1236     case 0x12:                  // Graphics Cursor Attribute
1237     case 0x13:                  // Graphics Cursor Pattern Address
1238     case 0x14:                  // Scratch Register 2
1239     case 0x15:                  // Scratch Register 3
1240     case 0x16:                  // Performance Tuning Register
1241     case 0x17:                  // Configuration Readback and Extended Control
1242     case 0x18:                  // Signature Generator Control
1243     case 0x19:                  // Signal Generator Result
1244     case 0x1a:                  // Signal Generator Result
1245     case 0x1b:                  // VCLK 0 Denominator & Post
1246     case 0x1c:                  // VCLK 1 Denominator & Post
1247     case 0x1d:                  // VCLK 2 Denominator & Post
1248     case 0x1e:                  // VCLK 3 Denominator & Post
1249     case 0x1f:                  // BIOS Write Enable and MCLK select
1250 #ifdef DEBUG_CIRRUS
1251         printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
1252 #endif
1253         return s->vga.sr[s->vga.sr_index];
1254     default:
1255 #ifdef DEBUG_CIRRUS
1256         printf("cirrus: inport sr_index %02x\n", s->vga.sr_index);
1257 #endif
1258         return 0xff;
1259         break;
1260     }
1261 }
1262
1263 static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
1264 {
1265     switch (s->vga.sr_index) {
1266     case 0x00:                  // Standard VGA
1267     case 0x01:                  // Standard VGA
1268     case 0x02:                  // Standard VGA
1269     case 0x03:                  // Standard VGA
1270     case 0x04:                  // Standard VGA
1271         s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
1272         if (s->vga.sr_index == 1)
1273             s->vga.update_retrace_info(&s->vga);
1274         break;
1275     case 0x06:                  // Unlock Cirrus extensions
1276         val &= 0x17;
1277         if (val == 0x12) {
1278             s->vga.sr[s->vga.sr_index] = 0x12;
1279         } else {
1280             s->vga.sr[s->vga.sr_index] = 0x0f;
1281         }
1282         break;
1283     case 0x10:
1284     case 0x30:
1285     case 0x50:
1286     case 0x70:                  // Graphics Cursor X
1287     case 0x90:
1288     case 0xb0:
1289     case 0xd0:
1290     case 0xf0:                  // Graphics Cursor X
1291         s->vga.sr[0x10] = val;
1292         s->hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
1293         break;
1294     case 0x11:
1295     case 0x31:
1296     case 0x51:
1297     case 0x71:                  // Graphics Cursor Y
1298     case 0x91:
1299     case 0xb1:
1300     case 0xd1:
1301     case 0xf1:                  // Graphics Cursor Y
1302         s->vga.sr[0x11] = val;
1303         s->hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
1304         break;
1305     case 0x07:                  // Extended Sequencer Mode
1306     cirrus_update_memory_access(s);
1307     case 0x08:                  // EEPROM Control
1308     case 0x09:                  // Scratch Register 0
1309     case 0x0a:                  // Scratch Register 1
1310     case 0x0b:                  // VCLK 0
1311     case 0x0c:                  // VCLK 1
1312     case 0x0d:                  // VCLK 2
1313     case 0x0e:                  // VCLK 3
1314     case 0x0f:                  // DRAM Control
1315     case 0x12:                  // Graphics Cursor Attribute
1316     case 0x13:                  // Graphics Cursor Pattern Address
1317     case 0x14:                  // Scratch Register 2
1318     case 0x15:                  // Scratch Register 3
1319     case 0x16:                  // Performance Tuning Register
1320     case 0x18:                  // Signature Generator Control
1321     case 0x19:                  // Signature Generator Result
1322     case 0x1a:                  // Signature Generator Result
1323     case 0x1b:                  // VCLK 0 Denominator & Post
1324     case 0x1c:                  // VCLK 1 Denominator & Post
1325     case 0x1d:                  // VCLK 2 Denominator & Post
1326     case 0x1e:                  // VCLK 3 Denominator & Post
1327     case 0x1f:                  // BIOS Write Enable and MCLK select
1328         s->vga.sr[s->vga.sr_index] = val;
1329 #ifdef DEBUG_CIRRUS
1330         printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
1331                s->vga.sr_index, val);
1332 #endif
1333         break;
1334     case 0x17:                  // Configuration Readback and Extended Control
1335         s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
1336                                    | (val & 0xc7);
1337         cirrus_update_memory_access(s);
1338         break;
1339     default:
1340 #ifdef DEBUG_CIRRUS
1341         printf("cirrus: outport sr_index %02x, sr_value %02x\n",
1342                s->vga.sr_index, val);
1343 #endif
1344         break;
1345     }
1346 }
1347
1348 /***************************************
1349  *
1350  *  I/O access at 0x3c6
1351  *
1352  ***************************************/
1353
1354 static int cirrus_read_hidden_dac(CirrusVGAState * s)
1355 {
1356     if (++s->cirrus_hidden_dac_lockindex == 5) {
1357         s->cirrus_hidden_dac_lockindex = 0;
1358         return s->cirrus_hidden_dac_data;
1359     }
1360     return 0xff;
1361 }
1362
1363 static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1364 {
1365     if (s->cirrus_hidden_dac_lockindex == 4) {
1366         s->cirrus_hidden_dac_data = reg_value;
1367 #if defined(DEBUG_CIRRUS)
1368         printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1369 #endif
1370     }
1371     s->cirrus_hidden_dac_lockindex = 0;
1372 }
1373
1374 /***************************************
1375  *
1376  *  I/O access at 0x3c9
1377  *
1378  ***************************************/
1379
1380 static int cirrus_vga_read_palette(CirrusVGAState * s)
1381 {
1382     int val;
1383
1384     if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1385         val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
1386                                        s->vga.dac_sub_index];
1387     } else {
1388         val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
1389     }
1390     if (++s->vga.dac_sub_index == 3) {
1391         s->vga.dac_sub_index = 0;
1392         s->vga.dac_read_index++;
1393     }
1394     return val;
1395 }
1396
1397 static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
1398 {
1399     s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
1400     if (++s->vga.dac_sub_index == 3) {
1401         if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1402             memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
1403                    s->vga.dac_cache, 3);
1404         } else {
1405             memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
1406         }
1407         /* XXX update cursor */
1408         s->vga.dac_sub_index = 0;
1409         s->vga.dac_write_index++;
1410     }
1411 }
1412
1413 /***************************************
1414  *
1415  *  I/O access between 0x3ce-0x3cf
1416  *
1417  ***************************************/
1418
1419 static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
1420 {
1421     switch (reg_index) {
1422     case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1423         return s->cirrus_shadow_gr0;
1424     case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1425         return s->cirrus_shadow_gr1;
1426     case 0x02:                  // Standard VGA
1427     case 0x03:                  // Standard VGA
1428     case 0x04:                  // Standard VGA
1429     case 0x06:                  // Standard VGA
1430     case 0x07:                  // Standard VGA
1431     case 0x08:                  // Standard VGA
1432         return s->vga.gr[s->vga.gr_index];
1433     case 0x05:                  // Standard VGA, Cirrus extended mode
1434     default:
1435         break;
1436     }
1437
1438     if (reg_index < 0x3a) {
1439         return s->vga.gr[reg_index];
1440     } else {
1441 #ifdef DEBUG_CIRRUS
1442         printf("cirrus: inport gr_index %02x\n", reg_index);
1443 #endif
1444         return 0xff;
1445     }
1446 }
1447
1448 static void
1449 cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1450 {
1451 #if defined(DEBUG_BITBLT) && 0
1452     printf("gr%02x: %02x\n", reg_index, reg_value);
1453 #endif
1454     switch (reg_index) {
1455     case 0x00:                  // Standard VGA, BGCOLOR 0x000000ff
1456         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1457         s->cirrus_shadow_gr0 = reg_value;
1458         break;
1459     case 0x01:                  // Standard VGA, FGCOLOR 0x000000ff
1460         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1461         s->cirrus_shadow_gr1 = reg_value;
1462         break;
1463     case 0x02:                  // Standard VGA
1464     case 0x03:                  // Standard VGA
1465     case 0x04:                  // Standard VGA
1466     case 0x06:                  // Standard VGA
1467     case 0x07:                  // Standard VGA
1468     case 0x08:                  // Standard VGA
1469         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1470         break;
1471     case 0x05:                  // Standard VGA, Cirrus extended mode
1472         s->vga.gr[reg_index] = reg_value & 0x7f;
1473         cirrus_update_memory_access(s);
1474         break;
1475     case 0x09:                  // bank offset #0
1476     case 0x0A:                  // bank offset #1
1477         s->vga.gr[reg_index] = reg_value;
1478         cirrus_update_bank_ptr(s, 0);
1479         cirrus_update_bank_ptr(s, 1);
1480         cirrus_update_memory_access(s);
1481         break;
1482     case 0x0B:
1483         s->vga.gr[reg_index] = reg_value;
1484         cirrus_update_bank_ptr(s, 0);
1485         cirrus_update_bank_ptr(s, 1);
1486         cirrus_update_memory_access(s);
1487         break;
1488     case 0x10:                  // BGCOLOR 0x0000ff00
1489     case 0x11:                  // FGCOLOR 0x0000ff00
1490     case 0x12:                  // BGCOLOR 0x00ff0000
1491     case 0x13:                  // FGCOLOR 0x00ff0000
1492     case 0x14:                  // BGCOLOR 0xff000000
1493     case 0x15:                  // FGCOLOR 0xff000000
1494     case 0x20:                  // BLT WIDTH 0x0000ff
1495     case 0x22:                  // BLT HEIGHT 0x0000ff
1496     case 0x24:                  // BLT DEST PITCH 0x0000ff
1497     case 0x26:                  // BLT SRC PITCH 0x0000ff
1498     case 0x28:                  // BLT DEST ADDR 0x0000ff
1499     case 0x29:                  // BLT DEST ADDR 0x00ff00
1500     case 0x2c:                  // BLT SRC ADDR 0x0000ff
1501     case 0x2d:                  // BLT SRC ADDR 0x00ff00
1502     case 0x2f:                  // BLT WRITEMASK
1503     case 0x30:                  // BLT MODE
1504     case 0x32:                  // RASTER OP
1505     case 0x33:                  // BLT MODEEXT
1506     case 0x34:                  // BLT TRANSPARENT COLOR 0x00ff
1507     case 0x35:                  // BLT TRANSPARENT COLOR 0xff00
1508     case 0x38:                  // BLT TRANSPARENT COLOR MASK 0x00ff
1509     case 0x39:                  // BLT TRANSPARENT COLOR MASK 0xff00
1510         s->vga.gr[reg_index] = reg_value;
1511         break;
1512     case 0x21:                  // BLT WIDTH 0x001f00
1513     case 0x23:                  // BLT HEIGHT 0x001f00
1514     case 0x25:                  // BLT DEST PITCH 0x001f00
1515     case 0x27:                  // BLT SRC PITCH 0x001f00
1516         s->vga.gr[reg_index] = reg_value & 0x1f;
1517         break;
1518     case 0x2a:                  // BLT DEST ADDR 0x3f0000
1519         s->vga.gr[reg_index] = reg_value & 0x3f;
1520         /* if auto start mode, starts bit blt now */
1521         if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
1522             cirrus_bitblt_start(s);
1523         }
1524         break;
1525     case 0x2e:                  // BLT SRC ADDR 0x3f0000
1526         s->vga.gr[reg_index] = reg_value & 0x3f;
1527         break;
1528     case 0x31:                  // BLT STATUS/START
1529         cirrus_write_bitblt(s, reg_value);
1530         break;
1531     default:
1532 #ifdef DEBUG_CIRRUS
1533         printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
1534                reg_value);
1535 #endif
1536         break;
1537     }
1538 }
1539
1540 /***************************************
1541  *
1542  *  I/O access between 0x3d4-0x3d5
1543  *
1544  ***************************************/
1545
1546 static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
1547 {
1548     switch (reg_index) {
1549     case 0x00:                  // Standard VGA
1550     case 0x01:                  // Standard VGA
1551     case 0x02:                  // Standard VGA
1552     case 0x03:                  // Standard VGA
1553     case 0x04:                  // Standard VGA
1554     case 0x05:                  // Standard VGA
1555     case 0x06:                  // Standard VGA
1556     case 0x07:                  // Standard VGA
1557     case 0x08:                  // Standard VGA
1558     case 0x09:                  // Standard VGA
1559     case 0x0a:                  // Standard VGA
1560     case 0x0b:                  // Standard VGA
1561     case 0x0c:                  // Standard VGA
1562     case 0x0d:                  // Standard VGA
1563     case 0x0e:                  // Standard VGA
1564     case 0x0f:                  // Standard VGA
1565     case 0x10:                  // Standard VGA
1566     case 0x11:                  // Standard VGA
1567     case 0x12:                  // Standard VGA
1568     case 0x13:                  // Standard VGA
1569     case 0x14:                  // Standard VGA
1570     case 0x15:                  // Standard VGA
1571     case 0x16:                  // Standard VGA
1572     case 0x17:                  // Standard VGA
1573     case 0x18:                  // Standard VGA
1574         return s->vga.cr[s->vga.cr_index];
1575     case 0x24:                  // Attribute Controller Toggle Readback (R)
1576         return (s->vga.ar_flip_flop << 7);
1577     case 0x19:                  // Interlace End
1578     case 0x1a:                  // Miscellaneous Control
1579     case 0x1b:                  // Extended Display Control
1580     case 0x1c:                  // Sync Adjust and Genlock
1581     case 0x1d:                  // Overlay Extended Control
1582     case 0x22:                  // Graphics Data Latches Readback (R)
1583     case 0x25:                  // Part Status
1584     case 0x27:                  // Part ID (R)
1585         return s->vga.cr[s->vga.cr_index];
1586     case 0x26:                  // Attribute Controller Index Readback (R)
1587         return s->vga.ar_index & 0x3f;
1588         break;
1589     default:
1590 #ifdef DEBUG_CIRRUS
1591         printf("cirrus: inport cr_index %02x\n", reg_index);
1592 #endif
1593         return 0xff;
1594     }
1595 }
1596
1597 static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
1598 {
1599     switch (s->vga.cr_index) {
1600     case 0x00:                  // Standard VGA
1601     case 0x01:                  // Standard VGA
1602     case 0x02:                  // Standard VGA
1603     case 0x03:                  // Standard VGA
1604     case 0x04:                  // Standard VGA
1605     case 0x05:                  // Standard VGA
1606     case 0x06:                  // Standard VGA
1607     case 0x07:                  // Standard VGA
1608     case 0x08:                  // Standard VGA
1609     case 0x09:                  // Standard VGA
1610     case 0x0a:                  // Standard VGA
1611     case 0x0b:                  // Standard VGA
1612     case 0x0c:                  // Standard VGA
1613     case 0x0d:                  // Standard VGA
1614     case 0x0e:                  // Standard VGA
1615     case 0x0f:                  // Standard VGA
1616     case 0x10:                  // Standard VGA
1617     case 0x11:                  // Standard VGA
1618     case 0x12:                  // Standard VGA
1619     case 0x13:                  // Standard VGA
1620     case 0x14:                  // Standard VGA
1621     case 0x15:                  // Standard VGA
1622     case 0x16:                  // Standard VGA
1623     case 0x17:                  // Standard VGA
1624     case 0x18:                  // Standard VGA
1625         /* handle CR0-7 protection */
1626         if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
1627             /* can always write bit 4 of CR7 */
1628             if (s->vga.cr_index == 7)
1629                 s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
1630             return;
1631         }
1632         s->vga.cr[s->vga.cr_index] = reg_value;
1633         switch(s->vga.cr_index) {
1634         case 0x00:
1635         case 0x04:
1636         case 0x05:
1637         case 0x06:
1638         case 0x07:
1639         case 0x11:
1640         case 0x17:
1641             s->vga.update_retrace_info(&s->vga);
1642             break;
1643         }
1644         break;
1645     case 0x19:                  // Interlace End
1646     case 0x1a:                  // Miscellaneous Control
1647     case 0x1b:                  // Extended Display Control
1648     case 0x1c:                  // Sync Adjust and Genlock
1649     case 0x1d:                  // Overlay Extended Control
1650         s->vga.cr[s->vga.cr_index] = reg_value;
1651 #ifdef DEBUG_CIRRUS
1652         printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
1653                s->vga.cr_index, reg_value);
1654 #endif
1655         break;
1656     case 0x22:                  // Graphics Data Latches Readback (R)
1657     case 0x24:                  // Attribute Controller Toggle Readback (R)
1658     case 0x26:                  // Attribute Controller Index Readback (R)
1659     case 0x27:                  // Part ID (R)
1660         break;
1661     case 0x25:                  // Part Status
1662     default:
1663 #ifdef DEBUG_CIRRUS
1664         printf("cirrus: outport cr_index %02x, cr_value %02x\n",
1665                s->vga.cr_index, reg_value);
1666 #endif
1667         break;
1668     }
1669 }
1670
1671 /***************************************
1672  *
1673  *  memory-mapped I/O (bitblt)
1674  *
1675  ***************************************/
1676
1677 static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1678 {
1679     int value = 0xff;
1680
1681     switch (address) {
1682     case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1683         value = cirrus_vga_read_gr(s, 0x00);
1684         break;
1685     case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1686         value = cirrus_vga_read_gr(s, 0x10);
1687         break;
1688     case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1689         value = cirrus_vga_read_gr(s, 0x12);
1690         break;
1691     case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1692         value = cirrus_vga_read_gr(s, 0x14);
1693         break;
1694     case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1695         value = cirrus_vga_read_gr(s, 0x01);
1696         break;
1697     case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1698         value = cirrus_vga_read_gr(s, 0x11);
1699         break;
1700     case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1701         value = cirrus_vga_read_gr(s, 0x13);
1702         break;
1703     case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1704         value = cirrus_vga_read_gr(s, 0x15);
1705         break;
1706     case (CIRRUS_MMIO_BLTWIDTH + 0):
1707         value = cirrus_vga_read_gr(s, 0x20);
1708         break;
1709     case (CIRRUS_MMIO_BLTWIDTH + 1):
1710         value = cirrus_vga_read_gr(s, 0x21);
1711         break;
1712     case (CIRRUS_MMIO_BLTHEIGHT + 0):
1713         value = cirrus_vga_read_gr(s, 0x22);
1714         break;
1715     case (CIRRUS_MMIO_BLTHEIGHT + 1):
1716         value = cirrus_vga_read_gr(s, 0x23);
1717         break;
1718     case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1719         value = cirrus_vga_read_gr(s, 0x24);
1720         break;
1721     case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1722         value = cirrus_vga_read_gr(s, 0x25);
1723         break;
1724     case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1725         value = cirrus_vga_read_gr(s, 0x26);
1726         break;
1727     case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1728         value = cirrus_vga_read_gr(s, 0x27);
1729         break;
1730     case (CIRRUS_MMIO_BLTDESTADDR + 0):
1731         value = cirrus_vga_read_gr(s, 0x28);
1732         break;
1733     case (CIRRUS_MMIO_BLTDESTADDR + 1):
1734         value = cirrus_vga_read_gr(s, 0x29);
1735         break;
1736     case (CIRRUS_MMIO_BLTDESTADDR + 2):
1737         value = cirrus_vga_read_gr(s, 0x2a);
1738         break;
1739     case (CIRRUS_MMIO_BLTSRCADDR + 0):
1740         value = cirrus_vga_read_gr(s, 0x2c);
1741         break;
1742     case (CIRRUS_MMIO_BLTSRCADDR + 1):
1743         value = cirrus_vga_read_gr(s, 0x2d);
1744         break;
1745     case (CIRRUS_MMIO_BLTSRCADDR + 2):
1746         value = cirrus_vga_read_gr(s, 0x2e);
1747         break;
1748     case CIRRUS_MMIO_BLTWRITEMASK:
1749         value = cirrus_vga_read_gr(s, 0x2f);
1750         break;
1751     case CIRRUS_MMIO_BLTMODE:
1752         value = cirrus_vga_read_gr(s, 0x30);
1753         break;
1754     case CIRRUS_MMIO_BLTROP:
1755         value = cirrus_vga_read_gr(s, 0x32);
1756         break;
1757     case CIRRUS_MMIO_BLTMODEEXT:
1758         value = cirrus_vga_read_gr(s, 0x33);
1759         break;
1760     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1761         value = cirrus_vga_read_gr(s, 0x34);
1762         break;
1763     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1764         value = cirrus_vga_read_gr(s, 0x35);
1765         break;
1766     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1767         value = cirrus_vga_read_gr(s, 0x38);
1768         break;
1769     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1770         value = cirrus_vga_read_gr(s, 0x39);
1771         break;
1772     case CIRRUS_MMIO_BLTSTATUS:
1773         value = cirrus_vga_read_gr(s, 0x31);
1774         break;
1775     default:
1776 #ifdef DEBUG_CIRRUS
1777         printf("cirrus: mmio read - address 0x%04x\n", address);
1778 #endif
1779         break;
1780     }
1781
1782     return (uint8_t) value;
1783 }
1784
1785 static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
1786                                   uint8_t value)
1787 {
1788     switch (address) {
1789     case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1790         cirrus_vga_write_gr(s, 0x00, value);
1791         break;
1792     case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1793         cirrus_vga_write_gr(s, 0x10, value);
1794         break;
1795     case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1796         cirrus_vga_write_gr(s, 0x12, value);
1797         break;
1798     case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1799         cirrus_vga_write_gr(s, 0x14, value);
1800         break;
1801     case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1802         cirrus_vga_write_gr(s, 0x01, value);
1803         break;
1804     case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1805         cirrus_vga_write_gr(s, 0x11, value);
1806         break;
1807     case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1808         cirrus_vga_write_gr(s, 0x13, value);
1809         break;
1810     case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1811         cirrus_vga_write_gr(s, 0x15, value);
1812         break;
1813     case (CIRRUS_MMIO_BLTWIDTH + 0):
1814         cirrus_vga_write_gr(s, 0x20, value);
1815         break;
1816     case (CIRRUS_MMIO_BLTWIDTH + 1):
1817         cirrus_vga_write_gr(s, 0x21, value);
1818         break;
1819     case (CIRRUS_MMIO_BLTHEIGHT + 0):
1820         cirrus_vga_write_gr(s, 0x22, value);
1821         break;
1822     case (CIRRUS_MMIO_BLTHEIGHT + 1):
1823         cirrus_vga_write_gr(s, 0x23, value);
1824         break;
1825     case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1826         cirrus_vga_write_gr(s, 0x24, value);
1827         break;
1828     case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1829         cirrus_vga_write_gr(s, 0x25, value);
1830         break;
1831     case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1832         cirrus_vga_write_gr(s, 0x26, value);
1833         break;
1834     case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1835         cirrus_vga_write_gr(s, 0x27, value);
1836         break;
1837     case (CIRRUS_MMIO_BLTDESTADDR + 0):
1838         cirrus_vga_write_gr(s, 0x28, value);
1839         break;
1840     case (CIRRUS_MMIO_BLTDESTADDR + 1):
1841         cirrus_vga_write_gr(s, 0x29, value);
1842         break;
1843     case (CIRRUS_MMIO_BLTDESTADDR + 2):
1844         cirrus_vga_write_gr(s, 0x2a, value);
1845         break;
1846     case (CIRRUS_MMIO_BLTDESTADDR + 3):
1847         /* ignored */
1848         break;
1849     case (CIRRUS_MMIO_BLTSRCADDR + 0):
1850         cirrus_vga_write_gr(s, 0x2c, value);
1851         break;
1852     case (CIRRUS_MMIO_BLTSRCADDR + 1):
1853         cirrus_vga_write_gr(s, 0x2d, value);
1854         break;
1855     case (CIRRUS_MMIO_BLTSRCADDR + 2):
1856         cirrus_vga_write_gr(s, 0x2e, value);
1857         break;
1858     case CIRRUS_MMIO_BLTWRITEMASK:
1859         cirrus_vga_write_gr(s, 0x2f, value);
1860         break;
1861     case CIRRUS_MMIO_BLTMODE:
1862         cirrus_vga_write_gr(s, 0x30, value);
1863         break;
1864     case CIRRUS_MMIO_BLTROP:
1865         cirrus_vga_write_gr(s, 0x32, value);
1866         break;
1867     case CIRRUS_MMIO_BLTMODEEXT:
1868         cirrus_vga_write_gr(s, 0x33, value);
1869         break;
1870     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1871         cirrus_vga_write_gr(s, 0x34, value);
1872         break;
1873     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1874         cirrus_vga_write_gr(s, 0x35, value);
1875         break;
1876     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1877         cirrus_vga_write_gr(s, 0x38, value);
1878         break;
1879     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1880         cirrus_vga_write_gr(s, 0x39, value);
1881         break;
1882     case CIRRUS_MMIO_BLTSTATUS:
1883         cirrus_vga_write_gr(s, 0x31, value);
1884         break;
1885     default:
1886 #ifdef DEBUG_CIRRUS
1887         printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
1888                address, value);
1889 #endif
1890         break;
1891     }
1892 }
1893
1894 /***************************************
1895  *
1896  *  write mode 4/5
1897  *
1898  * assume TARGET_PAGE_SIZE >= 16
1899  *
1900  ***************************************/
1901
1902 static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1903                                              unsigned mode,
1904                                              unsigned offset,
1905                                              uint32_t mem_value)
1906 {
1907     int x;
1908     unsigned val = mem_value;
1909     uint8_t *dst;
1910
1911     dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1912     for (x = 0; x < 8; x++) {
1913         if (val & 0x80) {
1914             *dst = s->cirrus_shadow_gr1;
1915         } else if (mode == 5) {
1916             *dst = s->cirrus_shadow_gr0;
1917         }
1918         val <<= 1;
1919         dst++;
1920     }
1921     memory_region_set_dirty(&s->vga.vram, offset);
1922     memory_region_set_dirty(&s->vga.vram, offset + 7);
1923 }
1924
1925 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1926                                               unsigned mode,
1927                                               unsigned offset,
1928                                               uint32_t mem_value)
1929 {
1930     int x;
1931     unsigned val = mem_value;
1932     uint8_t *dst;
1933
1934     dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1935     for (x = 0; x < 8; x++) {
1936         if (val & 0x80) {
1937             *dst = s->cirrus_shadow_gr1;
1938             *(dst + 1) = s->vga.gr[0x11];
1939         } else if (mode == 5) {
1940             *dst = s->cirrus_shadow_gr0;
1941             *(dst + 1) = s->vga.gr[0x10];
1942         }
1943         val <<= 1;
1944         dst += 2;
1945     }
1946     memory_region_set_dirty(&s->vga.vram, offset);
1947     memory_region_set_dirty(&s->vga.vram, offset + 15);
1948 }
1949
1950 /***************************************
1951  *
1952  *  memory access between 0xa0000-0xbffff
1953  *
1954  ***************************************/
1955
1956 static uint64_t cirrus_vga_mem_read(void *opaque,
1957                                     target_phys_addr_t addr,
1958                                     uint32_t size)
1959 {
1960     CirrusVGAState *s = opaque;
1961     unsigned bank_index;
1962     unsigned bank_offset;
1963     uint32_t val;
1964
1965     if ((s->vga.sr[0x07] & 0x01) == 0) {
1966         return vga_mem_readb(&s->vga, addr);
1967     }
1968
1969     if (addr < 0x10000) {
1970         /* XXX handle bitblt */
1971         /* video memory */
1972         bank_index = addr >> 15;
1973         bank_offset = addr & 0x7fff;
1974         if (bank_offset < s->cirrus_bank_limit[bank_index]) {
1975             bank_offset += s->cirrus_bank_base[bank_index];
1976             if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
1977                 bank_offset <<= 4;
1978             } else if (s->vga.gr[0x0B] & 0x02) {
1979                 bank_offset <<= 3;
1980             }
1981             bank_offset &= s->cirrus_addr_mask;
1982             val = *(s->vga.vram_ptr + bank_offset);
1983         } else
1984             val = 0xff;
1985     } else if (addr >= 0x18000 && addr < 0x18100) {
1986         /* memory-mapped I/O */
1987         val = 0xff;
1988         if ((s->vga.sr[0x17] & 0x44) == 0x04) {
1989             val = cirrus_mmio_blt_read(s, addr & 0xff);
1990         }
1991     } else {
1992         val = 0xff;
1993 #ifdef DEBUG_CIRRUS
1994         printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
1995 #endif
1996     }
1997     return val;
1998 }
1999
2000 static void cirrus_vga_mem_write(void *opaque,
2001                                  target_phys_addr_t addr,
2002                                  uint64_t mem_value,
2003                                  uint32_t size)
2004 {
2005     CirrusVGAState *s = opaque;
2006     unsigned bank_index;
2007     unsigned bank_offset;
2008     unsigned mode;
2009
2010     if ((s->vga.sr[0x07] & 0x01) == 0) {
2011         vga_mem_writeb(&s->vga, addr, mem_value);
2012         return;
2013     }
2014
2015     if (addr < 0x10000) {
2016         if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2017             /* bitblt */
2018             *s->cirrus_srcptr++ = (uint8_t) mem_value;
2019             if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2020                 cirrus_bitblt_cputovideo_next(s);
2021             }
2022         } else {
2023             /* video memory */
2024             bank_index = addr >> 15;
2025             bank_offset = addr & 0x7fff;
2026             if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2027                 bank_offset += s->cirrus_bank_base[bank_index];
2028                 if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2029                     bank_offset <<= 4;
2030                 } else if (s->vga.gr[0x0B] & 0x02) {
2031                     bank_offset <<= 3;
2032                 }
2033                 bank_offset &= s->cirrus_addr_mask;
2034                 mode = s->vga.gr[0x05] & 0x7;
2035                 if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2036                     *(s->vga.vram_ptr + bank_offset) = mem_value;
2037                     memory_region_set_dirty(&s->vga.vram, bank_offset);
2038                 } else {
2039                     if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2040                         cirrus_mem_writeb_mode4and5_8bpp(s, mode,
2041                                                          bank_offset,
2042                                                          mem_value);
2043                     } else {
2044                         cirrus_mem_writeb_mode4and5_16bpp(s, mode,
2045                                                           bank_offset,
2046                                                           mem_value);
2047                     }
2048                 }
2049             }
2050         }
2051     } else if (addr >= 0x18000 && addr < 0x18100) {
2052         /* memory-mapped I/O */
2053         if ((s->vga.sr[0x17] & 0x44) == 0x04) {
2054             cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
2055         }
2056     } else {
2057 #ifdef DEBUG_CIRRUS
2058         printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr,
2059                mem_value);
2060 #endif
2061     }
2062 }
2063
2064 static const MemoryRegionOps cirrus_vga_mem_ops = {
2065     .read = cirrus_vga_mem_read,
2066     .write = cirrus_vga_mem_write,
2067     .endianness = DEVICE_LITTLE_ENDIAN,
2068     .impl = {
2069         .min_access_size = 1,
2070         .max_access_size = 1,
2071     },
2072 };
2073
2074 /***************************************
2075  *
2076  *  hardware cursor
2077  *
2078  ***************************************/
2079
2080 static inline void invalidate_cursor1(CirrusVGAState *s)
2081 {
2082     if (s->last_hw_cursor_size) {
2083         vga_invalidate_scanlines(&s->vga,
2084                                  s->last_hw_cursor_y + s->last_hw_cursor_y_start,
2085                                  s->last_hw_cursor_y + s->last_hw_cursor_y_end);
2086     }
2087 }
2088
2089 static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
2090 {
2091     const uint8_t *src;
2092     uint32_t content;
2093     int y, y_min, y_max;
2094
2095     src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2096     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2097         src += (s->vga.sr[0x13] & 0x3c) * 256;
2098         y_min = 64;
2099         y_max = -1;
2100         for(y = 0; y < 64; y++) {
2101             content = ((uint32_t *)src)[0] |
2102                 ((uint32_t *)src)[1] |
2103                 ((uint32_t *)src)[2] |
2104                 ((uint32_t *)src)[3];
2105             if (content) {
2106                 if (y < y_min)
2107                     y_min = y;
2108                 if (y > y_max)
2109                     y_max = y;
2110             }
2111             src += 16;
2112         }
2113     } else {
2114         src += (s->vga.sr[0x13] & 0x3f) * 256;
2115         y_min = 32;
2116         y_max = -1;
2117         for(y = 0; y < 32; y++) {
2118             content = ((uint32_t *)src)[0] |
2119                 ((uint32_t *)(src + 128))[0];
2120             if (content) {
2121                 if (y < y_min)
2122                     y_min = y;
2123                 if (y > y_max)
2124                     y_max = y;
2125             }
2126             src += 4;
2127         }
2128     }
2129     if (y_min > y_max) {
2130         s->last_hw_cursor_y_start = 0;
2131         s->last_hw_cursor_y_end = 0;
2132     } else {
2133         s->last_hw_cursor_y_start = y_min;
2134         s->last_hw_cursor_y_end = y_max + 1;
2135     }
2136 }
2137
2138 /* NOTE: we do not currently handle the cursor bitmap change, so we
2139    update the cursor only if it moves. */
2140 static void cirrus_cursor_invalidate(VGACommonState *s1)
2141 {
2142     CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2143     int size;
2144
2145     if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
2146         size = 0;
2147     } else {
2148         if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
2149             size = 64;
2150         else
2151             size = 32;
2152     }
2153     /* invalidate last cursor and new cursor if any change */
2154     if (s->last_hw_cursor_size != size ||
2155         s->last_hw_cursor_x != s->hw_cursor_x ||
2156         s->last_hw_cursor_y != s->hw_cursor_y) {
2157
2158         invalidate_cursor1(s);
2159
2160         s->last_hw_cursor_size = size;
2161         s->last_hw_cursor_x = s->hw_cursor_x;
2162         s->last_hw_cursor_y = s->hw_cursor_y;
2163         /* compute the real cursor min and max y */
2164         cirrus_cursor_compute_yrange(s);
2165         invalidate_cursor1(s);
2166     }
2167 }
2168
2169 static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
2170 {
2171     CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2172     int w, h, bpp, x1, x2, poffset;
2173     unsigned int color0, color1;
2174     const uint8_t *palette, *src;
2175     uint32_t content;
2176
2177     if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
2178         return;
2179     /* fast test to see if the cursor intersects with the scan line */
2180     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2181         h = 64;
2182     } else {
2183         h = 32;
2184     }
2185     if (scr_y < s->hw_cursor_y ||
2186         scr_y >= (s->hw_cursor_y + h))
2187         return;
2188
2189     src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2190     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2191         src += (s->vga.sr[0x13] & 0x3c) * 256;
2192         src += (scr_y - s->hw_cursor_y) * 16;
2193         poffset = 8;
2194         content = ((uint32_t *)src)[0] |
2195             ((uint32_t *)src)[1] |
2196             ((uint32_t *)src)[2] |
2197             ((uint32_t *)src)[3];
2198     } else {
2199         src += (s->vga.sr[0x13] & 0x3f) * 256;
2200         src += (scr_y - s->hw_cursor_y) * 4;
2201         poffset = 128;
2202         content = ((uint32_t *)src)[0] |
2203             ((uint32_t *)(src + 128))[0];
2204     }
2205     /* if nothing to draw, no need to continue */
2206     if (!content)
2207         return;
2208     w = h;
2209
2210     x1 = s->hw_cursor_x;
2211     if (x1 >= s->vga.last_scr_width)
2212         return;
2213     x2 = s->hw_cursor_x + w;
2214     if (x2 > s->vga.last_scr_width)
2215         x2 = s->vga.last_scr_width;
2216     w = x2 - x1;
2217     palette = s->cirrus_hidden_palette;
2218     color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
2219                                  c6_to_8(palette[0x0 * 3 + 1]),
2220                                  c6_to_8(palette[0x0 * 3 + 2]));
2221     color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
2222                                  c6_to_8(palette[0xf * 3 + 1]),
2223                                  c6_to_8(palette[0xf * 3 + 2]));
2224     bpp = ((ds_get_bits_per_pixel(s->vga.ds) + 7) >> 3);
2225     d1 += x1 * bpp;
2226     switch(ds_get_bits_per_pixel(s->vga.ds)) {
2227     default:
2228         break;
2229     case 8:
2230         vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
2231         break;
2232     case 15:
2233         vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
2234         break;
2235     case 16:
2236         vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
2237         break;
2238     case 32:
2239         vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
2240         break;
2241     }
2242 }
2243
2244 /***************************************
2245  *
2246  *  LFB memory access
2247  *
2248  ***************************************/
2249
2250 static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
2251                                    unsigned size)
2252 {
2253     CirrusVGAState *s = opaque;
2254     uint32_t ret;
2255
2256     addr &= s->cirrus_addr_mask;
2257
2258     if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2259         ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2260         /* memory-mapped I/O */
2261         ret = cirrus_mmio_blt_read(s, addr & 0xff);
2262     } else if (0) {
2263         /* XXX handle bitblt */
2264         ret = 0xff;
2265     } else {
2266         /* video memory */
2267         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2268             addr <<= 4;
2269         } else if (s->vga.gr[0x0B] & 0x02) {
2270             addr <<= 3;
2271         }
2272         addr &= s->cirrus_addr_mask;
2273         ret = *(s->vga.vram_ptr + addr);
2274     }
2275
2276     return ret;
2277 }
2278
2279 static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
2280                                 uint64_t val, unsigned size)
2281 {
2282     CirrusVGAState *s = opaque;
2283     unsigned mode;
2284
2285     addr &= s->cirrus_addr_mask;
2286
2287     if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2288         ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
2289         /* memory-mapped I/O */
2290         cirrus_mmio_blt_write(s, addr & 0xff, val);
2291     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2292         /* bitblt */
2293         *s->cirrus_srcptr++ = (uint8_t) val;
2294         if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2295             cirrus_bitblt_cputovideo_next(s);
2296         }
2297     } else {
2298         /* video memory */
2299         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2300             addr <<= 4;
2301         } else if (s->vga.gr[0x0B] & 0x02) {
2302             addr <<= 3;
2303         }
2304         addr &= s->cirrus_addr_mask;
2305
2306         mode = s->vga.gr[0x05] & 0x7;
2307         if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2308             *(s->vga.vram_ptr + addr) = (uint8_t) val;
2309             memory_region_set_dirty(&s->vga.vram, addr);
2310         } else {
2311             if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2312                 cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2313             } else {
2314                 cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2315             }
2316         }
2317     }
2318 }
2319
2320 /***************************************
2321  *
2322  *  system to screen memory access
2323  *
2324  ***************************************/
2325
2326
2327 static uint64_t cirrus_linear_bitblt_read(void *opaque,
2328                                           target_phys_addr_t addr,
2329                                           unsigned size)
2330 {
2331     CirrusVGAState *s = opaque;
2332     uint32_t ret;
2333
2334     /* XXX handle bitblt */
2335     (void)s;
2336     ret = 0xff;
2337     return ret;
2338 }
2339
2340 static void cirrus_linear_bitblt_write(void *opaque,
2341                                        target_phys_addr_t addr,
2342                                        uint64_t val,
2343                                        unsigned size)
2344 {
2345     CirrusVGAState *s = opaque;
2346
2347     if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2348         /* bitblt */
2349         *s->cirrus_srcptr++ = (uint8_t) val;
2350         if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2351             cirrus_bitblt_cputovideo_next(s);
2352         }
2353     }
2354 }
2355
2356 static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
2357     .read = cirrus_linear_bitblt_read,
2358     .write = cirrus_linear_bitblt_write,
2359     .endianness = DEVICE_LITTLE_ENDIAN,
2360     .impl = {
2361         .min_access_size = 1,
2362         .max_access_size = 1,
2363     },
2364 };
2365
2366 static void unmap_bank(CirrusVGAState *s, unsigned bank)
2367 {
2368     if (s->cirrus_bank[bank]) {
2369         memory_region_del_subregion(&s->low_mem_container,
2370                                     s->cirrus_bank[bank]);
2371         memory_region_destroy(s->cirrus_bank[bank]);
2372         g_free(s->cirrus_bank[bank]);
2373         s->cirrus_bank[bank] = NULL;
2374     }
2375 }
2376
2377 static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
2378 {
2379     MemoryRegion *mr;
2380     static const char *names[] = { "vga.bank0", "vga.bank1" };
2381
2382     if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
2383         && !((s->vga.sr[0x07] & 0x01) == 0)
2384         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
2385         && !(s->vga.gr[0x0B] & 0x02)) {
2386
2387         mr = g_malloc(sizeof(*mr));
2388         memory_region_init_alias(mr, names[bank], &s->vga.vram,
2389                                  s->cirrus_bank_base[bank], 0x8000);
2390         memory_region_add_subregion_overlap(
2391             &s->low_mem_container,
2392             0x8000 * bank,
2393             mr,
2394             1);
2395         unmap_bank(s, bank);
2396         s->cirrus_bank[bank] = mr;
2397     } else {
2398         unmap_bank(s, bank);
2399     }
2400 }
2401
2402 static void map_linear_vram(CirrusVGAState *s)
2403 {
2404     if (!s->linear_vram) {
2405         s->linear_vram = true;
2406         memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
2407     }
2408     map_linear_vram_bank(s, 0);
2409     map_linear_vram_bank(s, 1);
2410 }
2411
2412 static void unmap_linear_vram(CirrusVGAState *s)
2413 {
2414     if (s->linear_vram) {
2415         s->linear_vram = false;
2416         memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
2417     }
2418     unmap_bank(s, 0);
2419     unmap_bank(s, 1);
2420 }
2421
2422 /* Compute the memory access functions */
2423 static void cirrus_update_memory_access(CirrusVGAState *s)
2424 {
2425     unsigned mode;
2426
2427     memory_region_transaction_begin();
2428     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
2429         goto generic_io;
2430     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2431         goto generic_io;
2432     } else {
2433         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2434             goto generic_io;
2435         } else if (s->vga.gr[0x0B] & 0x02) {
2436             goto generic_io;
2437         }
2438
2439         mode = s->vga.gr[0x05] & 0x7;
2440         if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2441             map_linear_vram(s);
2442         } else {
2443         generic_io:
2444             unmap_linear_vram(s);
2445         }
2446     }
2447     memory_region_transaction_commit();
2448 }
2449
2450
2451 /* I/O ports */
2452
2453 static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
2454 {
2455     CirrusVGAState *c = opaque;
2456     VGACommonState *s = &c->vga;
2457     int val, index;
2458
2459     if (vga_ioport_invalid(s, addr)) {
2460         val = 0xff;
2461     } else {
2462         switch (addr) {
2463         case 0x3c0:
2464             if (s->ar_flip_flop == 0) {
2465                 val = s->ar_index;
2466             } else {
2467                 val = 0;
2468             }
2469             break;
2470         case 0x3c1:
2471             index = s->ar_index & 0x1f;
2472             if (index < 21)
2473                 val = s->ar[index];
2474             else
2475                 val = 0;
2476             break;
2477         case 0x3c2:
2478             val = s->st00;
2479             break;
2480         case 0x3c4:
2481             val = s->sr_index;
2482             break;
2483         case 0x3c5:
2484             val = cirrus_vga_read_sr(c);
2485             break;
2486 #ifdef DEBUG_VGA_REG
2487             printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2488 #endif
2489             break;
2490         case 0x3c6:
2491             val = cirrus_read_hidden_dac(c);
2492             break;
2493         case 0x3c7:
2494             val = s->dac_state;
2495             break;
2496         case 0x3c8:
2497             val = s->dac_write_index;
2498             c->cirrus_hidden_dac_lockindex = 0;
2499             break;
2500         case 0x3c9:
2501             val = cirrus_vga_read_palette(c);
2502             break;
2503         case 0x3ca:
2504             val = s->fcr;
2505             break;
2506         case 0x3cc:
2507             val = s->msr;
2508             break;
2509         case 0x3ce:
2510             val = s->gr_index;
2511             break;
2512         case 0x3cf:
2513             val = cirrus_vga_read_gr(c, s->gr_index);
2514 #ifdef DEBUG_VGA_REG
2515             printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2516 #endif
2517             break;
2518         case 0x3b4:
2519         case 0x3d4:
2520             val = s->cr_index;
2521             break;
2522         case 0x3b5:
2523         case 0x3d5:
2524             val = cirrus_vga_read_cr(c, s->cr_index);
2525 #ifdef DEBUG_VGA_REG
2526             printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2527 #endif
2528             break;
2529         case 0x3ba:
2530         case 0x3da:
2531             /* just toggle to fool polling */
2532             val = s->st01 = s->retrace(s);
2533             s->ar_flip_flop = 0;
2534             break;
2535         default:
2536             val = 0x00;
2537             break;
2538         }
2539     }
2540 #if defined(DEBUG_VGA)
2541     printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2542 #endif
2543     return val;
2544 }
2545
2546 static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2547 {
2548     CirrusVGAState *c = opaque;
2549     VGACommonState *s = &c->vga;
2550     int index;
2551
2552     /* check port range access depending on color/monochrome mode */
2553     if (vga_ioport_invalid(s, addr)) {
2554         return;
2555     }
2556 #ifdef DEBUG_VGA
2557     printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2558 #endif
2559
2560     switch (addr) {
2561     case 0x3c0:
2562         if (s->ar_flip_flop == 0) {
2563             val &= 0x3f;
2564             s->ar_index = val;
2565         } else {
2566             index = s->ar_index & 0x1f;
2567             switch (index) {
2568             case 0x00 ... 0x0f:
2569                 s->ar[index] = val & 0x3f;
2570                 break;
2571             case 0x10:
2572                 s->ar[index] = val & ~0x10;
2573                 break;
2574             case 0x11:
2575                 s->ar[index] = val;
2576                 break;
2577             case 0x12:
2578                 s->ar[index] = val & ~0xc0;
2579                 break;
2580             case 0x13:
2581                 s->ar[index] = val & ~0xf0;
2582                 break;
2583             case 0x14:
2584                 s->ar[index] = val & ~0xf0;
2585                 break;
2586             default:
2587                 break;
2588             }
2589         }
2590         s->ar_flip_flop ^= 1;
2591         break;
2592     case 0x3c2:
2593         s->msr = val & ~0x10;
2594         s->update_retrace_info(s);
2595         break;
2596     case 0x3c4:
2597         s->sr_index = val;
2598         break;
2599     case 0x3c5:
2600 #ifdef DEBUG_VGA_REG
2601         printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2602 #endif
2603         cirrus_vga_write_sr(c, val);
2604         break;
2605         break;
2606     case 0x3c6:
2607         cirrus_write_hidden_dac(c, val);
2608         break;
2609     case 0x3c7:
2610         s->dac_read_index = val;
2611         s->dac_sub_index = 0;
2612         s->dac_state = 3;
2613         break;
2614     case 0x3c8:
2615         s->dac_write_index = val;
2616         s->dac_sub_index = 0;
2617         s->dac_state = 0;
2618         break;
2619     case 0x3c9:
2620         cirrus_vga_write_palette(c, val);
2621         break;
2622     case 0x3ce:
2623         s->gr_index = val;
2624         break;
2625     case 0x3cf:
2626 #ifdef DEBUG_VGA_REG
2627         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2628 #endif
2629         cirrus_vga_write_gr(c, s->gr_index, val);
2630         break;
2631     case 0x3b4:
2632     case 0x3d4:
2633         s->cr_index = val;
2634         break;
2635     case 0x3b5:
2636     case 0x3d5:
2637 #ifdef DEBUG_VGA_REG
2638         printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2639 #endif
2640         cirrus_vga_write_cr(c, val);
2641         break;
2642     case 0x3ba:
2643     case 0x3da:
2644         s->fcr = val & 0x10;
2645         break;
2646     }
2647 }
2648
2649 /***************************************
2650  *
2651  *  memory-mapped I/O access
2652  *
2653  ***************************************/
2654
2655 static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
2656                                  unsigned size)
2657 {
2658     CirrusVGAState *s = opaque;
2659
2660     if (addr >= 0x100) {
2661         return cirrus_mmio_blt_read(s, addr - 0x100);
2662     } else {
2663         return cirrus_vga_ioport_read(s, addr + 0x3c0);
2664     }
2665 }
2666
2667 static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
2668                               uint64_t val, unsigned size)
2669 {
2670     CirrusVGAState *s = opaque;
2671
2672     if (addr >= 0x100) {
2673         cirrus_mmio_blt_write(s, addr - 0x100, val);
2674     } else {
2675         cirrus_vga_ioport_write(s, addr + 0x3c0, val);
2676     }
2677 }
2678
2679 static const MemoryRegionOps cirrus_mmio_io_ops = {
2680     .read = cirrus_mmio_read,
2681     .write = cirrus_mmio_write,
2682     .endianness = DEVICE_LITTLE_ENDIAN,
2683     .impl = {
2684         .min_access_size = 1,
2685         .max_access_size = 1,
2686     },
2687 };
2688
2689 /* load/save state */
2690
2691 static int cirrus_post_load(void *opaque, int version_id)
2692 {
2693     CirrusVGAState *s = opaque;
2694
2695     s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
2696     s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
2697
2698     cirrus_update_memory_access(s);
2699     /* force refresh */
2700     s->vga.graphic_mode = -1;
2701     cirrus_update_bank_ptr(s, 0);
2702     cirrus_update_bank_ptr(s, 1);
2703     return 0;
2704 }
2705
2706 static const VMStateDescription vmstate_cirrus_vga = {
2707     .name = "cirrus_vga",
2708     .version_id = 2,
2709     .minimum_version_id = 1,
2710     .minimum_version_id_old = 1,
2711     .post_load = cirrus_post_load,
2712     .fields      = (VMStateField []) {
2713         VMSTATE_UINT32(vga.latch, CirrusVGAState),
2714         VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
2715         VMSTATE_BUFFER(vga.sr, CirrusVGAState),
2716         VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
2717         VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
2718         VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
2719         VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
2720         VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
2721         VMSTATE_BUFFER(vga.ar, CirrusVGAState),
2722         VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
2723         VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
2724         VMSTATE_BUFFER(vga.cr, CirrusVGAState),
2725         VMSTATE_UINT8(vga.msr, CirrusVGAState),
2726         VMSTATE_UINT8(vga.fcr, CirrusVGAState),
2727         VMSTATE_UINT8(vga.st00, CirrusVGAState),
2728         VMSTATE_UINT8(vga.st01, CirrusVGAState),
2729         VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
2730         VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
2731         VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
2732         VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
2733         VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
2734         VMSTATE_BUFFER(vga.palette, CirrusVGAState),
2735         VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
2736         VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
2737         VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
2738         VMSTATE_UINT32(hw_cursor_x, CirrusVGAState),
2739         VMSTATE_UINT32(hw_cursor_y, CirrusVGAState),
2740         /* XXX: we do not save the bitblt state - we assume we do not save
2741            the state when the blitter is active */
2742         VMSTATE_END_OF_LIST()
2743     }
2744 };
2745
2746 static const VMStateDescription vmstate_pci_cirrus_vga = {
2747     .name = "cirrus_vga",
2748     .version_id = 2,
2749     .minimum_version_id = 2,
2750     .minimum_version_id_old = 2,
2751     .fields      = (VMStateField []) {
2752         VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
2753         VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
2754                        vmstate_cirrus_vga, CirrusVGAState),
2755         VMSTATE_END_OF_LIST()
2756     }
2757 };
2758
2759 /***************************************
2760  *
2761  *  initialize
2762  *
2763  ***************************************/
2764
2765 static void cirrus_reset(void *opaque)
2766 {
2767     CirrusVGAState *s = opaque;
2768
2769     vga_common_reset(&s->vga);
2770     unmap_linear_vram(s);
2771     s->vga.sr[0x06] = 0x0f;
2772     if (s->device_id == CIRRUS_ID_CLGD5446) {
2773         /* 4MB 64 bit memory config, always PCI */
2774         s->vga.sr[0x1F] = 0x2d;         // MemClock
2775         s->vga.gr[0x18] = 0x0f;             // fastest memory configuration
2776         s->vga.sr[0x0f] = 0x98;
2777         s->vga.sr[0x17] = 0x20;
2778         s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
2779     } else {
2780         s->vga.sr[0x1F] = 0x22;         // MemClock
2781         s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
2782         s->vga.sr[0x17] = s->bustype;
2783         s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
2784     }
2785     s->vga.cr[0x27] = s->device_id;
2786
2787     /* Win2K seems to assume that the pattern buffer is at 0xff
2788        initially ! */
2789     memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
2790
2791     s->cirrus_hidden_dac_lockindex = 5;
2792     s->cirrus_hidden_dac_data = 0;
2793 }
2794
2795 static const MemoryRegionOps cirrus_linear_io_ops = {
2796     .read = cirrus_linear_read,
2797     .write = cirrus_linear_write,
2798     .endianness = DEVICE_LITTLE_ENDIAN,
2799     .impl = {
2800         .min_access_size = 1,
2801         .max_access_size = 1,
2802     },
2803 };
2804
2805 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
2806                                MemoryRegion *system_memory)
2807 {
2808     int i;
2809     static int inited;
2810
2811     if (!inited) {
2812         inited = 1;
2813         for(i = 0;i < 256; i++)
2814             rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
2815         rop_to_index[CIRRUS_ROP_0] = 0;
2816         rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
2817         rop_to_index[CIRRUS_ROP_NOP] = 2;
2818         rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
2819         rop_to_index[CIRRUS_ROP_NOTDST] = 4;
2820         rop_to_index[CIRRUS_ROP_SRC] = 5;
2821         rop_to_index[CIRRUS_ROP_1] = 6;
2822         rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
2823         rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
2824         rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
2825         rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
2826         rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
2827         rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
2828         rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
2829         rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
2830         rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
2831         s->device_id = device_id;
2832         if (is_pci)
2833             s->bustype = CIRRUS_BUSTYPE_PCI;
2834         else
2835             s->bustype = CIRRUS_BUSTYPE_ISA;
2836     }
2837
2838     register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
2839
2840     register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
2841     register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
2842     register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
2843     register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
2844
2845     register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
2846
2847     register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
2848     register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
2849     register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
2850     register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
2851
2852     memory_region_init(&s->low_mem_container,
2853                        "cirrus-lowmem-container",
2854                        0x20000);
2855
2856     memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
2857                           "cirrus-low-memory", 0x20000);
2858     memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
2859     memory_region_add_subregion_overlap(system_memory,
2860                                         isa_mem_base + 0x000a0000,
2861                                         &s->low_mem_container,
2862                                         1);
2863     memory_region_set_coalescing(&s->low_mem);
2864
2865     /* I/O handler for LFB */
2866     memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
2867                           "cirrus-linear-io", VGA_RAM_SIZE);
2868
2869     /* I/O handler for LFB */
2870     memory_region_init_io(&s->cirrus_linear_bitblt_io,
2871                           &cirrus_linear_bitblt_io_ops,
2872                           s,
2873                           "cirrus-bitblt-mmio",
2874                           0x400000);
2875
2876     /* I/O handler for memory-mapped I/O */
2877     memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
2878                           "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
2879
2880     s->real_vram_size =
2881         (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
2882
2883     /* XXX: s->vga.vram_size must be a power of two */
2884     s->cirrus_addr_mask = s->real_vram_size - 1;
2885     s->linear_mmio_mask = s->real_vram_size - 256;
2886
2887     s->vga.get_bpp = cirrus_get_bpp;
2888     s->vga.get_offsets = cirrus_get_offsets;
2889     s->vga.get_resolution = cirrus_get_resolution;
2890     s->vga.cursor_invalidate = cirrus_cursor_invalidate;
2891     s->vga.cursor_draw_line = cirrus_cursor_draw_line;
2892
2893     qemu_register_reset(cirrus_reset, s);
2894 }
2895
2896 /***************************************
2897  *
2898  *  ISA bus support
2899  *
2900  ***************************************/
2901
2902 void isa_cirrus_vga_init(MemoryRegion *system_memory)
2903 {
2904     CirrusVGAState *s;
2905
2906     s = g_malloc0(sizeof(CirrusVGAState));
2907
2908     vga_common_init(&s->vga, VGA_RAM_SIZE);
2909     cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory);
2910     s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
2911                                      s->vga.screen_dump, s->vga.text_update,
2912                                      &s->vga);
2913     vmstate_register(NULL, 0, &vmstate_cirrus_vga, s);
2914     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
2915     /* XXX ISA-LFB support */
2916 }
2917
2918 /***************************************
2919  *
2920  *  PCI bus support
2921  *
2922  ***************************************/
2923
2924 static int pci_cirrus_vga_initfn(PCIDevice *dev)
2925 {
2926      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
2927      CirrusVGAState *s = &d->cirrus_vga;
2928      PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info);
2929      int16_t device_id = info->device_id;
2930
2931      /* setup VGA */
2932      vga_common_init(&s->vga, VGA_RAM_SIZE);
2933      cirrus_init_common(s, device_id, 1, pci_address_space(dev));
2934      s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
2935                                       s->vga.screen_dump, s->vga.text_update,
2936                                       &s->vga);
2937
2938      /* setup PCI */
2939
2940     memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
2941
2942     /* XXX: add byte swapping apertures */
2943     memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
2944     memory_region_add_subregion(&s->pci_bar, 0x1000000,
2945                                 &s->cirrus_linear_bitblt_io);
2946
2947      /* setup memory space */
2948      /* memory #0 LFB */
2949      /* memory #1 memory-mapped I/O */
2950      /* XXX: s->vga.vram_size must be a power of two */
2951      pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
2952      if (device_id == CIRRUS_ID_CLGD5446) {
2953          pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
2954      }
2955      return 0;
2956 }
2957
2958 void pci_cirrus_vga_init(PCIBus *bus)
2959 {
2960     pci_create_simple(bus, -1, "cirrus-vga");
2961 }
2962
2963 static PCIDeviceInfo cirrus_vga_info = {
2964     .qdev.name    = "cirrus-vga",
2965     .qdev.desc    = "Cirrus CLGD 54xx VGA",
2966     .qdev.size    = sizeof(PCICirrusVGAState),
2967     .qdev.vmsd    = &vmstate_pci_cirrus_vga,
2968     .no_hotplug   = 1,
2969     .init         = pci_cirrus_vga_initfn,
2970     .romfile      = VGABIOS_CIRRUS_FILENAME,
2971     .vendor_id    = PCI_VENDOR_ID_CIRRUS,
2972     .device_id    = CIRRUS_ID_CLGD5446,
2973     .class_id     = PCI_CLASS_DISPLAY_VGA,
2974 };
2975
2976 static void cirrus_vga_register(void)
2977 {
2978     pci_qdev_register(&cirrus_vga_info);
2979 }
2980 device_init(cirrus_vga_register);
This page took 0.190979 seconds and 4 git commands to generate.