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