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