Statistics
| Branch: | Revision:

root / hw / cirrus_vga.c @ 78935c4a

History | View | Annotate | Download (93.3 kB)

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_FN(d, s) 0
284
#include "cirrus_vga_rop.h"
285

    
286
#define ROP_NAME src_and_dst
287
#define ROP_FN(d, s) (s) & (d)
288
#include "cirrus_vga_rop.h"
289

    
290
#define ROP_NAME src_and_notdst
291
#define ROP_FN(d, s) (s) & (~(d))
292
#include "cirrus_vga_rop.h"
293

    
294
#define ROP_NAME notdst
295
#define ROP_FN(d, s) ~(d)
296
#include "cirrus_vga_rop.h"
297

    
298
#define ROP_NAME src
299
#define ROP_FN(d, s) s
300
#include "cirrus_vga_rop.h"
301

    
302
#define ROP_NAME 1
303
#define ROP_FN(d, s) ~0
304
#include "cirrus_vga_rop.h"
305

    
306
#define ROP_NAME notsrc_and_dst
307
#define ROP_FN(d, s) (~(s)) & (d)
308
#include "cirrus_vga_rop.h"
309

    
310
#define ROP_NAME src_xor_dst
311
#define ROP_FN(d, s) (s) ^ (d)
312
#include "cirrus_vga_rop.h"
313

    
314
#define ROP_NAME src_or_dst
315
#define ROP_FN(d, s) (s) | (d)
316
#include "cirrus_vga_rop.h"
317

    
318
#define ROP_NAME notsrc_or_notdst
319
#define ROP_FN(d, s) (~(s)) | (~(d))
320
#include "cirrus_vga_rop.h"
321

    
322
#define ROP_NAME src_notxor_dst
323
#define ROP_FN(d, s) ~((s) ^ (d))
324
#include "cirrus_vga_rop.h"
325

    
326
#define ROP_NAME src_or_notdst
327
#define ROP_FN(d, s) (s) | (~(d))
328
#include "cirrus_vga_rop.h"
329

    
330
#define ROP_NAME notsrc
331
#define ROP_FN(d, s) (~(s))
332
#include "cirrus_vga_rop.h"
333

    
334
#define ROP_NAME notsrc_or_dst
335
#define ROP_FN(d, s) (~(s)) | (d)
336
#include "cirrus_vga_rop.h"
337

    
338
#define ROP_NAME notsrc_and_notdst
339
#define ROP_FN(d, s) (~(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 = 0, sy = 0;
677
    int dx = 0, dy = 0;
678
    int depth = 0;
679
    int notify = 0;
680

    
681
    /* make sure to only copy if it's a plain copy ROP */
682
    if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
683
        *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
684

    
685
        int width, height;
686

    
687
        depth = s->vga.get_bpp(&s->vga) / 8;
688
        s->vga.get_resolution(&s->vga, &width, &height);
689

    
690
        /* extra x, y */
691
        sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
692
        sy = (src / ABS(s->cirrus_blt_srcpitch));
693
        dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
694
        dy = (dst / ABS(s->cirrus_blt_dstpitch));
695

    
696
        /* normalize width */
697
        w /= depth;
698

    
699
        /* if we're doing a backward copy, we have to adjust
700
           our x/y to be the upper left corner (instead of the lower
701
           right corner) */
702
        if (s->cirrus_blt_dstpitch < 0) {
703
            sx -= (s->cirrus_blt_width / depth) - 1;
704
            dx -= (s->cirrus_blt_width / depth) - 1;
705
            sy -= s->cirrus_blt_height - 1;
706
            dy -= s->cirrus_blt_height - 1;
707
        }
708

    
709
        /* are we in the visible portion of memory? */
710
        if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
711
            (sx + w) <= width && (sy + h) <= height &&
712
            (dx + w) <= width && (dy + h) <= height) {
713
            notify = 1;
714
        }
715
    }
716

    
717
    /* we have to flush all pending changes so that the copy
718
       is generated at the appropriate moment in time */
719
    if (notify)
720
        vga_hw_update();
721

    
722
    (*s->cirrus_rop) (s, s->vga.vram_ptr +
723
                      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
724
                      s->vga.vram_ptr +
725
                      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
726
                      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
727
                      s->cirrus_blt_width, s->cirrus_blt_height);
728

    
729
    if (notify)
730
        qemu_console_copy(s->vga.ds,
731
                          sx, sy, dx, dy,
732
                          s->cirrus_blt_width / depth,
733
                          s->cirrus_blt_height);
734

    
735
    /* we don't have to notify the display that this portion has
736
       changed since qemu_console_copy implies this */
737

    
738
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
739
                                s->cirrus_blt_dstpitch, s->cirrus_blt_width,
740
                                s->cirrus_blt_height);
741
}
742

    
743
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
744
{
745
    if (BLTUNSAFE(s))
746
        return 0;
747

    
748
    cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
749
            s->cirrus_blt_srcaddr - s->vga.start_addr,
750
            s->cirrus_blt_width, s->cirrus_blt_height);
751

    
752
    return 1;
753
}
754

    
755
/***************************************
756
 *
757
 *  bitblt (cpu-to-video)
758
 *
759
 ***************************************/
760

    
761
static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
762
{
763
    int copy_count;
764
    uint8_t *end_ptr;
765

    
766
    if (s->cirrus_srccounter > 0) {
767
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
768
            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
769
        the_end:
770
            s->cirrus_srccounter = 0;
771
            cirrus_bitblt_reset(s);
772
        } else {
773
            /* at least one scan line */
774
            do {
775
                (*s->cirrus_rop)(s, s->vga.vram_ptr +
776
                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
777
                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
778
                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
779
                                         s->cirrus_blt_width, 1);
780
                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
781
                s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
782
                if (s->cirrus_srccounter <= 0)
783
                    goto the_end;
784
                /* more bytes than needed can be transfered because of
785
                   word alignment, so we keep them for the next line */
786
                /* XXX: keep alignment to speed up transfer */
787
                end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
788
                copy_count = s->cirrus_srcptr_end - end_ptr;
789
                memmove(s->cirrus_bltbuf, end_ptr, copy_count);
790
                s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
791
                s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
792
            } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
793
        }
794
    }
795
}
796

    
797
/***************************************
798
 *
799
 *  bitblt wrapper
800
 *
801
 ***************************************/
802

    
803
static void cirrus_bitblt_reset(CirrusVGAState * s)
804
{
805
    int need_update;
806

    
807
    s->vga.gr[0x31] &=
808
        ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
809
    need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
810
        || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
811
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
812
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
813
    s->cirrus_srccounter = 0;
814
    if (!need_update)
815
        return;
816
    cirrus_update_memory_access(s);
817
}
818

    
819
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
820
{
821
    int w;
822

    
823
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
824
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
825
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
826

    
827
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
828
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
829
            s->cirrus_blt_srcpitch = 8;
830
        } else {
831
            /* XXX: check for 24 bpp */
832
            s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
833
        }
834
        s->cirrus_srccounter = s->cirrus_blt_srcpitch;
835
    } else {
836
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
837
            w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
838
            if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
839
                s->cirrus_blt_srcpitch = ((w + 31) >> 5);
840
            else
841
                s->cirrus_blt_srcpitch = ((w + 7) >> 3);
842
        } else {
843
            /* always align input size to 32 bits */
844
            s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
845
        }
846
        s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
847
    }
848
    s->cirrus_srcptr = s->cirrus_bltbuf;
849
    s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
850
    cirrus_update_memory_access(s);
851
    return 1;
852
}
853

    
854
static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
855
{
856
    /* XXX */
857
#ifdef DEBUG_BITBLT
858
    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
859
#endif
860
    return 0;
861
}
862

    
863
static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
864
{
865
    int ret;
866

    
867
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
868
        ret = cirrus_bitblt_videotovideo_patterncopy(s);
869
    } else {
870
        ret = cirrus_bitblt_videotovideo_copy(s);
871
    }
872
    if (ret)
873
        cirrus_bitblt_reset(s);
874
    return ret;
875
}
876

    
877
static void cirrus_bitblt_start(CirrusVGAState * s)
878
{
879
    uint8_t blt_rop;
880

    
881
    s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
882

    
883
    s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
884
    s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
885
    s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
886
    s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
887
    s->cirrus_blt_dstaddr =
888
        (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
889
    s->cirrus_blt_srcaddr =
890
        (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
891
    s->cirrus_blt_mode = s->vga.gr[0x30];
892
    s->cirrus_blt_modeext = s->vga.gr[0x33];
893
    blt_rop = s->vga.gr[0x32];
894

    
895
#ifdef DEBUG_BITBLT
896
    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",
897
           blt_rop,
898
           s->cirrus_blt_mode,
899
           s->cirrus_blt_modeext,
900
           s->cirrus_blt_width,
901
           s->cirrus_blt_height,
902
           s->cirrus_blt_dstpitch,
903
           s->cirrus_blt_srcpitch,
904
           s->cirrus_blt_dstaddr,
905
           s->cirrus_blt_srcaddr,
906
           s->vga.gr[0x2f]);
907
#endif
908

    
909
    switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
910
    case CIRRUS_BLTMODE_PIXELWIDTH8:
911
        s->cirrus_blt_pixelwidth = 1;
912
        break;
913
    case CIRRUS_BLTMODE_PIXELWIDTH16:
914
        s->cirrus_blt_pixelwidth = 2;
915
        break;
916
    case CIRRUS_BLTMODE_PIXELWIDTH24:
917
        s->cirrus_blt_pixelwidth = 3;
918
        break;
919
    case CIRRUS_BLTMODE_PIXELWIDTH32:
920
        s->cirrus_blt_pixelwidth = 4;
921
        break;
922
    default:
923
#ifdef DEBUG_BITBLT
924
        printf("cirrus: bitblt - pixel width is unknown\n");
925
#endif
926
        goto bitblt_ignore;
927
    }
928
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
929

    
930
    if ((s->
931
         cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
932
                            CIRRUS_BLTMODE_MEMSYSDEST))
933
        == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
934
#ifdef DEBUG_BITBLT
935
        printf("cirrus: bitblt - memory-to-memory copy is requested\n");
936
#endif
937
        goto bitblt_ignore;
938
    }
939

    
940
    if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
941
        (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
942
                               CIRRUS_BLTMODE_TRANSPARENTCOMP |
943
                               CIRRUS_BLTMODE_PATTERNCOPY |
944
                               CIRRUS_BLTMODE_COLOREXPAND)) ==
945
         (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
946
        cirrus_bitblt_fgcol(s);
947
        cirrus_bitblt_solidfill(s, blt_rop);
948
    } else {
949
        if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
950
                                   CIRRUS_BLTMODE_PATTERNCOPY)) ==
951
            CIRRUS_BLTMODE_COLOREXPAND) {
952

    
953
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
954
                if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
955
                    cirrus_bitblt_bgcol(s);
956
                else
957
                    cirrus_bitblt_fgcol(s);
958
                s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
959
            } else {
960
                cirrus_bitblt_fgcol(s);
961
                cirrus_bitblt_bgcol(s);
962
                s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
963
            }
964
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
965
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
966
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
967
                    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
968
                        cirrus_bitblt_bgcol(s);
969
                    else
970
                        cirrus_bitblt_fgcol(s);
971
                    s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
972
                } else {
973
                    cirrus_bitblt_fgcol(s);
974
                    cirrus_bitblt_bgcol(s);
975
                    s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
976
                }
977
            } else {
978
                s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
979
            }
980
        } else {
981
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
982
                if (s->cirrus_blt_pixelwidth > 2) {
983
                    printf("src transparent without colorexpand must be 8bpp or 16bpp\n");
984
                    goto bitblt_ignore;
985
                }
986
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
987
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
988
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
989
                    s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
990
                } else {
991
                    s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
992
                }
993
            } else {
994
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
995
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
996
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
997
                    s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
998
                } else {
999
                    s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
1000
                }
1001
            }
1002
        }
1003
        // setup bitblt engine.
1004
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
1005
            if (!cirrus_bitblt_cputovideo(s))
1006
                goto bitblt_ignore;
1007
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
1008
            if (!cirrus_bitblt_videotocpu(s))
1009
                goto bitblt_ignore;
1010
        } else {
1011
            if (!cirrus_bitblt_videotovideo(s))
1012
                goto bitblt_ignore;
1013
        }
1014
    }
1015
    return;
1016
  bitblt_ignore:;
1017
    cirrus_bitblt_reset(s);
1018
}
1019

    
1020
static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1021
{
1022
    unsigned old_value;
1023

    
1024
    old_value = s->vga.gr[0x31];
1025
    s->vga.gr[0x31] = reg_value;
1026

    
1027
    if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1028
        ((reg_value & CIRRUS_BLT_RESET) == 0)) {
1029
        cirrus_bitblt_reset(s);
1030
    } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1031
               ((reg_value & CIRRUS_BLT_START) != 0)) {
1032
        cirrus_bitblt_start(s);
1033
    }
1034
}
1035

    
1036

    
1037
/***************************************
1038
 *
1039
 *  basic parameters
1040
 *
1041
 ***************************************/
1042

    
1043
static void cirrus_get_offsets(VGACommonState *s1,
1044
                               uint32_t *pline_offset,
1045
                               uint32_t *pstart_addr,
1046
                               uint32_t *pline_compare)
1047
{
1048
    CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1049
    uint32_t start_addr, line_offset, line_compare;
1050

    
1051
    line_offset = s->vga.cr[0x13]
1052
        | ((s->vga.cr[0x1b] & 0x10) << 4);
1053
    line_offset <<= 3;
1054
    *pline_offset = line_offset;
1055

    
1056
    start_addr = (s->vga.cr[0x0c] << 8)
1057
        | s->vga.cr[0x0d]
1058
        | ((s->vga.cr[0x1b] & 0x01) << 16)
1059
        | ((s->vga.cr[0x1b] & 0x0c) << 15)
1060
        | ((s->vga.cr[0x1d] & 0x80) << 12);
1061
    *pstart_addr = start_addr;
1062

    
1063
    line_compare = s->vga.cr[0x18] |
1064
        ((s->vga.cr[0x07] & 0x10) << 4) |
1065
        ((s->vga.cr[0x09] & 0x40) << 3);
1066
    *pline_compare = line_compare;
1067
}
1068

    
1069
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1070
{
1071
    uint32_t ret = 16;
1072

    
1073
    switch (s->cirrus_hidden_dac_data & 0xf) {
1074
    case 0:
1075
        ret = 15;
1076
        break;                        /* Sierra HiColor */
1077
    case 1:
1078
        ret = 16;
1079
        break;                        /* XGA HiColor */
1080
    default:
1081
#ifdef DEBUG_CIRRUS
1082
        printf("cirrus: invalid DAC value %x in 16bpp\n",
1083
               (s->cirrus_hidden_dac_data & 0xf));
1084
#endif
1085
        ret = 15;                /* XXX */
1086
        break;
1087
    }
1088
    return ret;
1089
}
1090

    
1091
static int cirrus_get_bpp(VGACommonState *s1)
1092
{
1093
    CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1094
    uint32_t ret = 8;
1095

    
1096
    if ((s->vga.sr[0x07] & 0x01) != 0) {
1097
        /* Cirrus SVGA */
1098
        switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1099
        case CIRRUS_SR7_BPP_8:
1100
            ret = 8;
1101
            break;
1102
        case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1103
            ret = cirrus_get_bpp16_depth(s);
1104
            break;
1105
        case CIRRUS_SR7_BPP_24:
1106
            ret = 24;
1107
            break;
1108
        case CIRRUS_SR7_BPP_16:
1109
            ret = cirrus_get_bpp16_depth(s);
1110
            break;
1111
        case CIRRUS_SR7_BPP_32:
1112
            ret = 32;
1113
            break;
1114
        default:
1115
#ifdef DEBUG_CIRRUS
1116
            printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
1117
#endif
1118
            ret = 8;
1119
            break;
1120
        }
1121
    } else {
1122
        /* VGA */
1123
        ret = 0;
1124
    }
1125

    
1126
    return ret;
1127
}
1128

    
1129
static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1130
{
1131
    int width, height;
1132

    
1133
    width = (s->cr[0x01] + 1) * 8;
1134
    height = s->cr[0x12] |
1135
        ((s->cr[0x07] & 0x02) << 7) |
1136
        ((s->cr[0x07] & 0x40) << 3);
1137
    height = (height + 1);
1138
    /* interlace support */
1139
    if (s->cr[0x1a] & 0x01)
1140
        height = height * 2;
1141
    *pwidth = width;
1142
    *pheight = height;
1143
}
1144

    
1145
/***************************************
1146
 *
1147
 * bank memory
1148
 *
1149
 ***************************************/
1150

    
1151
static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1152
{
1153
    unsigned offset;
1154
    unsigned limit;
1155

    
1156
    if ((s->vga.gr[0x0b] & 0x01) != 0)        /* dual bank */
1157
        offset = s->vga.gr[0x09 + bank_index];
1158
    else                        /* single bank */
1159
        offset = s->vga.gr[0x09];
1160

    
1161
    if ((s->vga.gr[0x0b] & 0x20) != 0)
1162
        offset <<= 14;
1163
    else
1164
        offset <<= 12;
1165

    
1166
    if (s->real_vram_size <= offset)
1167
        limit = 0;
1168
    else
1169
        limit = s->real_vram_size - offset;
1170

    
1171
    if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1172
        if (limit > 0x8000) {
1173
            offset += 0x8000;
1174
            limit -= 0x8000;
1175
        } else {
1176
            limit = 0;
1177
        }
1178
    }
1179

    
1180
    if (limit > 0) {
1181
        /* Thinking about changing bank base? First, drop the dirty bitmap information
1182
         * on the current location, otherwise we lose this pointer forever */
1183
        if (s->vga.lfb_vram_mapped) {
1184
            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
1185
            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
1186
        }
1187
        s->cirrus_bank_base[bank_index] = offset;
1188
        s->cirrus_bank_limit[bank_index] = limit;
1189
    } else {
1190
        s->cirrus_bank_base[bank_index] = 0;
1191
        s->cirrus_bank_limit[bank_index] = 0;
1192
    }
1193
}
1194

    
1195
/***************************************
1196
 *
1197
 *  I/O access between 0x3c4-0x3c5
1198
 *
1199
 ***************************************/
1200

    
1201
static int cirrus_vga_read_sr(CirrusVGAState * s)
1202
{
1203
    switch (s->vga.sr_index) {
1204
    case 0x00:                        // Standard VGA
1205
    case 0x01:                        // Standard VGA
1206
    case 0x02:                        // Standard VGA
1207
    case 0x03:                        // Standard VGA
1208
    case 0x04:                        // Standard VGA
1209
        return s->vga.sr[s->vga.sr_index];
1210
    case 0x06:                        // Unlock Cirrus extensions
1211
        return s->vga.sr[s->vga.sr_index];
1212
    case 0x10:
1213
    case 0x30:
1214
    case 0x50:
1215
    case 0x70:                        // Graphics Cursor X
1216
    case 0x90:
1217
    case 0xb0:
1218
    case 0xd0:
1219
    case 0xf0:                        // Graphics Cursor X
1220
        return s->vga.sr[0x10];
1221
    case 0x11:
1222
    case 0x31:
1223
    case 0x51:
1224
    case 0x71:                        // Graphics Cursor Y
1225
    case 0x91:
1226
    case 0xb1:
1227
    case 0xd1:
1228
    case 0xf1:                        // Graphics Cursor Y
1229
        return s->vga.sr[0x11];
1230
    case 0x05:                        // ???
1231
    case 0x07:                        // Extended Sequencer Mode
1232
    case 0x08:                        // EEPROM Control
1233
    case 0x09:                        // Scratch Register 0
1234
    case 0x0a:                        // Scratch Register 1
1235
    case 0x0b:                        // VCLK 0
1236
    case 0x0c:                        // VCLK 1
1237
    case 0x0d:                        // VCLK 2
1238
    case 0x0e:                        // VCLK 3
1239
    case 0x0f:                        // DRAM Control
1240
    case 0x12:                        // Graphics Cursor Attribute
1241
    case 0x13:                        // Graphics Cursor Pattern Address
1242
    case 0x14:                        // Scratch Register 2
1243
    case 0x15:                        // Scratch Register 3
1244
    case 0x16:                        // Performance Tuning Register
1245
    case 0x17:                        // Configuration Readback and Extended Control
1246
    case 0x18:                        // Signature Generator Control
1247
    case 0x19:                        // Signal Generator Result
1248
    case 0x1a:                        // Signal Generator Result
1249
    case 0x1b:                        // VCLK 0 Denominator & Post
1250
    case 0x1c:                        // VCLK 1 Denominator & Post
1251
    case 0x1d:                        // VCLK 2 Denominator & Post
1252
    case 0x1e:                        // VCLK 3 Denominator & Post
1253
    case 0x1f:                        // BIOS Write Enable and MCLK select
1254
#ifdef DEBUG_CIRRUS
1255
        printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
1256
#endif
1257
        return s->vga.sr[s->vga.sr_index];
1258
    default:
1259
#ifdef DEBUG_CIRRUS
1260
        printf("cirrus: inport sr_index %02x\n", s->vga.sr_index);
1261
#endif
1262
        return 0xff;
1263
        break;
1264
    }
1265
}
1266

    
1267
static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
1268
{
1269
    switch (s->vga.sr_index) {
1270
    case 0x00:                        // Standard VGA
1271
    case 0x01:                        // Standard VGA
1272
    case 0x02:                        // Standard VGA
1273
    case 0x03:                        // Standard VGA
1274
    case 0x04:                        // Standard VGA
1275
        s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
1276
        if (s->vga.sr_index == 1)
1277
            s->vga.update_retrace_info(&s->vga);
1278
        break;
1279
    case 0x06:                        // Unlock Cirrus extensions
1280
        val &= 0x17;
1281
        if (val == 0x12) {
1282
            s->vga.sr[s->vga.sr_index] = 0x12;
1283
        } else {
1284
            s->vga.sr[s->vga.sr_index] = 0x0f;
1285
        }
1286
        break;
1287
    case 0x10:
1288
    case 0x30:
1289
    case 0x50:
1290
    case 0x70:                        // Graphics Cursor X
1291
    case 0x90:
1292
    case 0xb0:
1293
    case 0xd0:
1294
    case 0xf0:                        // Graphics Cursor X
1295
        s->vga.sr[0x10] = val;
1296
        s->hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
1297
        break;
1298
    case 0x11:
1299
    case 0x31:
1300
    case 0x51:
1301
    case 0x71:                        // Graphics Cursor Y
1302
    case 0x91:
1303
    case 0xb1:
1304
    case 0xd1:
1305
    case 0xf1:                        // Graphics Cursor Y
1306
        s->vga.sr[0x11] = val;
1307
        s->hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
1308
        break;
1309
    case 0x07:                        // Extended Sequencer Mode
1310
    cirrus_update_memory_access(s);
1311
    case 0x08:                        // EEPROM Control
1312
    case 0x09:                        // Scratch Register 0
1313
    case 0x0a:                        // Scratch Register 1
1314
    case 0x0b:                        // VCLK 0
1315
    case 0x0c:                        // VCLK 1
1316
    case 0x0d:                        // VCLK 2
1317
    case 0x0e:                        // VCLK 3
1318
    case 0x0f:                        // DRAM Control
1319
    case 0x12:                        // Graphics Cursor Attribute
1320
    case 0x13:                        // Graphics Cursor Pattern Address
1321
    case 0x14:                        // Scratch Register 2
1322
    case 0x15:                        // Scratch Register 3
1323
    case 0x16:                        // Performance Tuning Register
1324
    case 0x18:                        // Signature Generator Control
1325
    case 0x19:                        // Signature Generator Result
1326
    case 0x1a:                        // Signature Generator Result
1327
    case 0x1b:                        // VCLK 0 Denominator & Post
1328
    case 0x1c:                        // VCLK 1 Denominator & Post
1329
    case 0x1d:                        // VCLK 2 Denominator & Post
1330
    case 0x1e:                        // VCLK 3 Denominator & Post
1331
    case 0x1f:                        // BIOS Write Enable and MCLK select
1332
        s->vga.sr[s->vga.sr_index] = val;
1333
#ifdef DEBUG_CIRRUS
1334
        printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
1335
               s->vga.sr_index, val);
1336
#endif
1337
        break;
1338
    case 0x17:                        // Configuration Readback and Extended Control
1339
        s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
1340
                                   | (val & 0xc7);
1341
        cirrus_update_memory_access(s);
1342
        break;
1343
    default:
1344
#ifdef DEBUG_CIRRUS
1345
        printf("cirrus: outport sr_index %02x, sr_value %02x\n",
1346
               s->vga.sr_index, val);
1347
#endif
1348
        break;
1349
    }
1350
}
1351

    
1352
/***************************************
1353
 *
1354
 *  I/O access at 0x3c6
1355
 *
1356
 ***************************************/
1357

    
1358
static int cirrus_read_hidden_dac(CirrusVGAState * s)
1359
{
1360
    if (++s->cirrus_hidden_dac_lockindex == 5) {
1361
        s->cirrus_hidden_dac_lockindex = 0;
1362
        return s->cirrus_hidden_dac_data;
1363
    }
1364
    return 0xff;
1365
}
1366

    
1367
static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1368
{
1369
    if (s->cirrus_hidden_dac_lockindex == 4) {
1370
        s->cirrus_hidden_dac_data = reg_value;
1371
#if defined(DEBUG_CIRRUS)
1372
        printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1373
#endif
1374
    }
1375
    s->cirrus_hidden_dac_lockindex = 0;
1376
}
1377

    
1378
/***************************************
1379
 *
1380
 *  I/O access at 0x3c9
1381
 *
1382
 ***************************************/
1383

    
1384
static int cirrus_vga_read_palette(CirrusVGAState * s)
1385
{
1386
    int val;
1387

    
1388
    if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1389
        val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
1390
                                       s->vga.dac_sub_index];
1391
    } else {
1392
        val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
1393
    }
1394
    if (++s->vga.dac_sub_index == 3) {
1395
        s->vga.dac_sub_index = 0;
1396
        s->vga.dac_read_index++;
1397
    }
1398
    return val;
1399
}
1400

    
1401
static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
1402
{
1403
    s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
1404
    if (++s->vga.dac_sub_index == 3) {
1405
        if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1406
            memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
1407
                   s->vga.dac_cache, 3);
1408
        } else {
1409
            memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
1410
        }
1411
        /* XXX update cursor */
1412
        s->vga.dac_sub_index = 0;
1413
        s->vga.dac_write_index++;
1414
    }
1415
}
1416

    
1417
/***************************************
1418
 *
1419
 *  I/O access between 0x3ce-0x3cf
1420
 *
1421
 ***************************************/
1422

    
1423
static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
1424
{
1425
    switch (reg_index) {
1426
    case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1427
        return s->cirrus_shadow_gr0;
1428
    case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1429
        return s->cirrus_shadow_gr1;
1430
    case 0x02:                        // Standard VGA
1431
    case 0x03:                        // Standard VGA
1432
    case 0x04:                        // Standard VGA
1433
    case 0x06:                        // Standard VGA
1434
    case 0x07:                        // Standard VGA
1435
    case 0x08:                        // Standard VGA
1436
        return s->vga.gr[s->vga.gr_index];
1437
    case 0x05:                        // Standard VGA, Cirrus extended mode
1438
    default:
1439
        break;
1440
    }
1441

    
1442
    if (reg_index < 0x3a) {
1443
        return s->vga.gr[reg_index];
1444
    } else {
1445
#ifdef DEBUG_CIRRUS
1446
        printf("cirrus: inport gr_index %02x\n", reg_index);
1447
#endif
1448
        return 0xff;
1449
    }
1450
}
1451

    
1452
static void
1453
cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1454
{
1455
#if defined(DEBUG_BITBLT) && 0
1456
    printf("gr%02x: %02x\n", reg_index, reg_value);
1457
#endif
1458
    switch (reg_index) {
1459
    case 0x00:                        // Standard VGA, BGCOLOR 0x000000ff
1460
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1461
        s->cirrus_shadow_gr0 = reg_value;
1462
        break;
1463
    case 0x01:                        // Standard VGA, FGCOLOR 0x000000ff
1464
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1465
        s->cirrus_shadow_gr1 = reg_value;
1466
        break;
1467
    case 0x02:                        // Standard VGA
1468
    case 0x03:                        // Standard VGA
1469
    case 0x04:                        // Standard VGA
1470
    case 0x06:                        // Standard VGA
1471
    case 0x07:                        // Standard VGA
1472
    case 0x08:                        // Standard VGA
1473
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1474
        break;
1475
    case 0x05:                        // Standard VGA, Cirrus extended mode
1476
        s->vga.gr[reg_index] = reg_value & 0x7f;
1477
        cirrus_update_memory_access(s);
1478
        break;
1479
    case 0x09:                        // bank offset #0
1480
    case 0x0A:                        // bank offset #1
1481
        s->vga.gr[reg_index] = reg_value;
1482
        cirrus_update_bank_ptr(s, 0);
1483
        cirrus_update_bank_ptr(s, 1);
1484
        cirrus_update_memory_access(s);
1485
        break;
1486
    case 0x0B:
1487
        s->vga.gr[reg_index] = reg_value;
1488
        cirrus_update_bank_ptr(s, 0);
1489
        cirrus_update_bank_ptr(s, 1);
1490
        cirrus_update_memory_access(s);
1491
        break;
1492
    case 0x10:                        // BGCOLOR 0x0000ff00
1493
    case 0x11:                        // FGCOLOR 0x0000ff00
1494
    case 0x12:                        // BGCOLOR 0x00ff0000
1495
    case 0x13:                        // FGCOLOR 0x00ff0000
1496
    case 0x14:                        // BGCOLOR 0xff000000
1497
    case 0x15:                        // FGCOLOR 0xff000000
1498
    case 0x20:                        // BLT WIDTH 0x0000ff
1499
    case 0x22:                        // BLT HEIGHT 0x0000ff
1500
    case 0x24:                        // BLT DEST PITCH 0x0000ff
1501
    case 0x26:                        // BLT SRC PITCH 0x0000ff
1502
    case 0x28:                        // BLT DEST ADDR 0x0000ff
1503
    case 0x29:                        // BLT DEST ADDR 0x00ff00
1504
    case 0x2c:                        // BLT SRC ADDR 0x0000ff
1505
    case 0x2d:                        // BLT SRC ADDR 0x00ff00
1506
    case 0x2f:                  // BLT WRITEMASK
1507
    case 0x30:                        // BLT MODE
1508
    case 0x32:                        // RASTER OP
1509
    case 0x33:                        // BLT MODEEXT
1510
    case 0x34:                        // BLT TRANSPARENT COLOR 0x00ff
1511
    case 0x35:                        // BLT TRANSPARENT COLOR 0xff00
1512
    case 0x38:                        // BLT TRANSPARENT COLOR MASK 0x00ff
1513
    case 0x39:                        // BLT TRANSPARENT COLOR MASK 0xff00
1514
        s->vga.gr[reg_index] = reg_value;
1515
        break;
1516
    case 0x21:                        // BLT WIDTH 0x001f00
1517
    case 0x23:                        // BLT HEIGHT 0x001f00
1518
    case 0x25:                        // BLT DEST PITCH 0x001f00
1519
    case 0x27:                        // BLT SRC PITCH 0x001f00
1520
        s->vga.gr[reg_index] = reg_value & 0x1f;
1521
        break;
1522
    case 0x2a:                        // BLT DEST ADDR 0x3f0000
1523
        s->vga.gr[reg_index] = reg_value & 0x3f;
1524
        /* if auto start mode, starts bit blt now */
1525
        if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
1526
            cirrus_bitblt_start(s);
1527
        }
1528
        break;
1529
    case 0x2e:                        // BLT SRC ADDR 0x3f0000
1530
        s->vga.gr[reg_index] = reg_value & 0x3f;
1531
        break;
1532
    case 0x31:                        // BLT STATUS/START
1533
        cirrus_write_bitblt(s, reg_value);
1534
        break;
1535
    default:
1536
#ifdef DEBUG_CIRRUS
1537
        printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
1538
               reg_value);
1539
#endif
1540
        break;
1541
    }
1542
}
1543

    
1544
/***************************************
1545
 *
1546
 *  I/O access between 0x3d4-0x3d5
1547
 *
1548
 ***************************************/
1549

    
1550
static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
1551
{
1552
    switch (reg_index) {
1553
    case 0x00:                        // Standard VGA
1554
    case 0x01:                        // Standard VGA
1555
    case 0x02:                        // Standard VGA
1556
    case 0x03:                        // Standard VGA
1557
    case 0x04:                        // Standard VGA
1558
    case 0x05:                        // Standard VGA
1559
    case 0x06:                        // Standard VGA
1560
    case 0x07:                        // Standard VGA
1561
    case 0x08:                        // Standard VGA
1562
    case 0x09:                        // Standard VGA
1563
    case 0x0a:                        // Standard VGA
1564
    case 0x0b:                        // Standard VGA
1565
    case 0x0c:                        // Standard VGA
1566
    case 0x0d:                        // Standard VGA
1567
    case 0x0e:                        // Standard VGA
1568
    case 0x0f:                        // Standard VGA
1569
    case 0x10:                        // Standard VGA
1570
    case 0x11:                        // Standard VGA
1571
    case 0x12:                        // Standard VGA
1572
    case 0x13:                        // Standard VGA
1573
    case 0x14:                        // Standard VGA
1574
    case 0x15:                        // Standard VGA
1575
    case 0x16:                        // Standard VGA
1576
    case 0x17:                        // Standard VGA
1577
    case 0x18:                        // Standard VGA
1578
        return s->vga.cr[s->vga.cr_index];
1579
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1580
        return (s->vga.ar_flip_flop << 7);
1581
    case 0x19:                        // Interlace End
1582
    case 0x1a:                        // Miscellaneous Control
1583
    case 0x1b:                        // Extended Display Control
1584
    case 0x1c:                        // Sync Adjust and Genlock
1585
    case 0x1d:                        // Overlay Extended Control
1586
    case 0x22:                        // Graphics Data Latches Readback (R)
1587
    case 0x25:                        // Part Status
1588
    case 0x27:                        // Part ID (R)
1589
        return s->vga.cr[s->vga.cr_index];
1590
    case 0x26:                        // Attribute Controller Index Readback (R)
1591
        return s->vga.ar_index & 0x3f;
1592
        break;
1593
    default:
1594
#ifdef DEBUG_CIRRUS
1595
        printf("cirrus: inport cr_index %02x\n", reg_index);
1596
#endif
1597
        return 0xff;
1598
    }
1599
}
1600

    
1601
static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
1602
{
1603
    switch (s->vga.cr_index) {
1604
    case 0x00:                        // Standard VGA
1605
    case 0x01:                        // Standard VGA
1606
    case 0x02:                        // Standard VGA
1607
    case 0x03:                        // Standard VGA
1608
    case 0x04:                        // Standard VGA
1609
    case 0x05:                        // Standard VGA
1610
    case 0x06:                        // Standard VGA
1611
    case 0x07:                        // Standard VGA
1612
    case 0x08:                        // Standard VGA
1613
    case 0x09:                        // Standard VGA
1614
    case 0x0a:                        // Standard VGA
1615
    case 0x0b:                        // Standard VGA
1616
    case 0x0c:                        // Standard VGA
1617
    case 0x0d:                        // Standard VGA
1618
    case 0x0e:                        // Standard VGA
1619
    case 0x0f:                        // Standard VGA
1620
    case 0x10:                        // Standard VGA
1621
    case 0x11:                        // Standard VGA
1622
    case 0x12:                        // Standard VGA
1623
    case 0x13:                        // Standard VGA
1624
    case 0x14:                        // Standard VGA
1625
    case 0x15:                        // Standard VGA
1626
    case 0x16:                        // Standard VGA
1627
    case 0x17:                        // Standard VGA
1628
    case 0x18:                        // Standard VGA
1629
        /* handle CR0-7 protection */
1630
        if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
1631
            /* can always write bit 4 of CR7 */
1632
            if (s->vga.cr_index == 7)
1633
                s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
1634
            return;
1635
        }
1636
        s->vga.cr[s->vga.cr_index] = reg_value;
1637
        switch(s->vga.cr_index) {
1638
        case 0x00:
1639
        case 0x04:
1640
        case 0x05:
1641
        case 0x06:
1642
        case 0x07:
1643
        case 0x11:
1644
        case 0x17:
1645
            s->vga.update_retrace_info(&s->vga);
1646
            break;
1647
        }
1648
        break;
1649
    case 0x19:                        // Interlace End
1650
    case 0x1a:                        // Miscellaneous Control
1651
    case 0x1b:                        // Extended Display Control
1652
    case 0x1c:                        // Sync Adjust and Genlock
1653
    case 0x1d:                        // Overlay Extended Control
1654
        s->vga.cr[s->vga.cr_index] = reg_value;
1655
#ifdef DEBUG_CIRRUS
1656
        printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
1657
               s->vga.cr_index, reg_value);
1658
#endif
1659
        break;
1660
    case 0x22:                        // Graphics Data Latches Readback (R)
1661
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1662
    case 0x26:                        // Attribute Controller Index Readback (R)
1663
    case 0x27:                        // Part ID (R)
1664
        break;
1665
    case 0x25:                        // Part Status
1666
    default:
1667
#ifdef DEBUG_CIRRUS
1668
        printf("cirrus: outport cr_index %02x, cr_value %02x\n",
1669
               s->vga.cr_index, reg_value);
1670
#endif
1671
        break;
1672
    }
1673
}
1674

    
1675
/***************************************
1676
 *
1677
 *  memory-mapped I/O (bitblt)
1678
 *
1679
 ***************************************/
1680

    
1681
static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1682
{
1683
    int value = 0xff;
1684

    
1685
    switch (address) {
1686
    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1687
        value = cirrus_vga_read_gr(s, 0x00);
1688
        break;
1689
    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1690
        value = cirrus_vga_read_gr(s, 0x10);
1691
        break;
1692
    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1693
        value = cirrus_vga_read_gr(s, 0x12);
1694
        break;
1695
    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1696
        value = cirrus_vga_read_gr(s, 0x14);
1697
        break;
1698
    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1699
        value = cirrus_vga_read_gr(s, 0x01);
1700
        break;
1701
    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1702
        value = cirrus_vga_read_gr(s, 0x11);
1703
        break;
1704
    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1705
        value = cirrus_vga_read_gr(s, 0x13);
1706
        break;
1707
    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1708
        value = cirrus_vga_read_gr(s, 0x15);
1709
        break;
1710
    case (CIRRUS_MMIO_BLTWIDTH + 0):
1711
        value = cirrus_vga_read_gr(s, 0x20);
1712
        break;
1713
    case (CIRRUS_MMIO_BLTWIDTH + 1):
1714
        value = cirrus_vga_read_gr(s, 0x21);
1715
        break;
1716
    case (CIRRUS_MMIO_BLTHEIGHT + 0):
1717
        value = cirrus_vga_read_gr(s, 0x22);
1718
        break;
1719
    case (CIRRUS_MMIO_BLTHEIGHT + 1):
1720
        value = cirrus_vga_read_gr(s, 0x23);
1721
        break;
1722
    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1723
        value = cirrus_vga_read_gr(s, 0x24);
1724
        break;
1725
    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1726
        value = cirrus_vga_read_gr(s, 0x25);
1727
        break;
1728
    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1729
        value = cirrus_vga_read_gr(s, 0x26);
1730
        break;
1731
    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1732
        value = cirrus_vga_read_gr(s, 0x27);
1733
        break;
1734
    case (CIRRUS_MMIO_BLTDESTADDR + 0):
1735
        value = cirrus_vga_read_gr(s, 0x28);
1736
        break;
1737
    case (CIRRUS_MMIO_BLTDESTADDR + 1):
1738
        value = cirrus_vga_read_gr(s, 0x29);
1739
        break;
1740
    case (CIRRUS_MMIO_BLTDESTADDR + 2):
1741
        value = cirrus_vga_read_gr(s, 0x2a);
1742
        break;
1743
    case (CIRRUS_MMIO_BLTSRCADDR + 0):
1744
        value = cirrus_vga_read_gr(s, 0x2c);
1745
        break;
1746
    case (CIRRUS_MMIO_BLTSRCADDR + 1):
1747
        value = cirrus_vga_read_gr(s, 0x2d);
1748
        break;
1749
    case (CIRRUS_MMIO_BLTSRCADDR + 2):
1750
        value = cirrus_vga_read_gr(s, 0x2e);
1751
        break;
1752
    case CIRRUS_MMIO_BLTWRITEMASK:
1753
        value = cirrus_vga_read_gr(s, 0x2f);
1754
        break;
1755
    case CIRRUS_MMIO_BLTMODE:
1756
        value = cirrus_vga_read_gr(s, 0x30);
1757
        break;
1758
    case CIRRUS_MMIO_BLTROP:
1759
        value = cirrus_vga_read_gr(s, 0x32);
1760
        break;
1761
    case CIRRUS_MMIO_BLTMODEEXT:
1762
        value = cirrus_vga_read_gr(s, 0x33);
1763
        break;
1764
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1765
        value = cirrus_vga_read_gr(s, 0x34);
1766
        break;
1767
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1768
        value = cirrus_vga_read_gr(s, 0x35);
1769
        break;
1770
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1771
        value = cirrus_vga_read_gr(s, 0x38);
1772
        break;
1773
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1774
        value = cirrus_vga_read_gr(s, 0x39);
1775
        break;
1776
    case CIRRUS_MMIO_BLTSTATUS:
1777
        value = cirrus_vga_read_gr(s, 0x31);
1778
        break;
1779
    default:
1780
#ifdef DEBUG_CIRRUS
1781
        printf("cirrus: mmio read - address 0x%04x\n", address);
1782
#endif
1783
        break;
1784
    }
1785

    
1786
    return (uint8_t) value;
1787
}
1788

    
1789
static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
1790
                                  uint8_t value)
1791
{
1792
    switch (address) {
1793
    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1794
        cirrus_vga_write_gr(s, 0x00, value);
1795
        break;
1796
    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1797
        cirrus_vga_write_gr(s, 0x10, value);
1798
        break;
1799
    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1800
        cirrus_vga_write_gr(s, 0x12, value);
1801
        break;
1802
    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1803
        cirrus_vga_write_gr(s, 0x14, value);
1804
        break;
1805
    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1806
        cirrus_vga_write_gr(s, 0x01, value);
1807
        break;
1808
    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1809
        cirrus_vga_write_gr(s, 0x11, value);
1810
        break;
1811
    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1812
        cirrus_vga_write_gr(s, 0x13, value);
1813
        break;
1814
    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1815
        cirrus_vga_write_gr(s, 0x15, value);
1816
        break;
1817
    case (CIRRUS_MMIO_BLTWIDTH + 0):
1818
        cirrus_vga_write_gr(s, 0x20, value);
1819
        break;
1820
    case (CIRRUS_MMIO_BLTWIDTH + 1):
1821
        cirrus_vga_write_gr(s, 0x21, value);
1822
        break;
1823
    case (CIRRUS_MMIO_BLTHEIGHT + 0):
1824
        cirrus_vga_write_gr(s, 0x22, value);
1825
        break;
1826
    case (CIRRUS_MMIO_BLTHEIGHT + 1):
1827
        cirrus_vga_write_gr(s, 0x23, value);
1828
        break;
1829
    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1830
        cirrus_vga_write_gr(s, 0x24, value);
1831
        break;
1832
    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1833
        cirrus_vga_write_gr(s, 0x25, value);
1834
        break;
1835
    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1836
        cirrus_vga_write_gr(s, 0x26, value);
1837
        break;
1838
    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1839
        cirrus_vga_write_gr(s, 0x27, value);
1840
        break;
1841
    case (CIRRUS_MMIO_BLTDESTADDR + 0):
1842
        cirrus_vga_write_gr(s, 0x28, value);
1843
        break;
1844
    case (CIRRUS_MMIO_BLTDESTADDR + 1):
1845
        cirrus_vga_write_gr(s, 0x29, value);
1846
        break;
1847
    case (CIRRUS_MMIO_BLTDESTADDR + 2):
1848
        cirrus_vga_write_gr(s, 0x2a, value);
1849
        break;
1850
    case (CIRRUS_MMIO_BLTDESTADDR + 3):
1851
        /* ignored */
1852
        break;
1853
    case (CIRRUS_MMIO_BLTSRCADDR + 0):
1854
        cirrus_vga_write_gr(s, 0x2c, value);
1855
        break;
1856
    case (CIRRUS_MMIO_BLTSRCADDR + 1):
1857
        cirrus_vga_write_gr(s, 0x2d, value);
1858
        break;
1859
    case (CIRRUS_MMIO_BLTSRCADDR + 2):
1860
        cirrus_vga_write_gr(s, 0x2e, value);
1861
        break;
1862
    case CIRRUS_MMIO_BLTWRITEMASK:
1863
        cirrus_vga_write_gr(s, 0x2f, value);
1864
        break;
1865
    case CIRRUS_MMIO_BLTMODE:
1866
        cirrus_vga_write_gr(s, 0x30, value);
1867
        break;
1868
    case CIRRUS_MMIO_BLTROP:
1869
        cirrus_vga_write_gr(s, 0x32, value);
1870
        break;
1871
    case CIRRUS_MMIO_BLTMODEEXT:
1872
        cirrus_vga_write_gr(s, 0x33, value);
1873
        break;
1874
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1875
        cirrus_vga_write_gr(s, 0x34, value);
1876
        break;
1877
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1878
        cirrus_vga_write_gr(s, 0x35, value);
1879
        break;
1880
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1881
        cirrus_vga_write_gr(s, 0x38, value);
1882
        break;
1883
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1884
        cirrus_vga_write_gr(s, 0x39, value);
1885
        break;
1886
    case CIRRUS_MMIO_BLTSTATUS:
1887
        cirrus_vga_write_gr(s, 0x31, value);
1888
        break;
1889
    default:
1890
#ifdef DEBUG_CIRRUS
1891
        printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
1892
               address, value);
1893
#endif
1894
        break;
1895
    }
1896
}
1897

    
1898
/***************************************
1899
 *
1900
 *  write mode 4/5
1901
 *
1902
 * assume TARGET_PAGE_SIZE >= 16
1903
 *
1904
 ***************************************/
1905

    
1906
static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1907
                                             unsigned mode,
1908
                                             unsigned offset,
1909
                                             uint32_t mem_value)
1910
{
1911
    int x;
1912
    unsigned val = mem_value;
1913
    uint8_t *dst;
1914

    
1915
    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1916
    for (x = 0; x < 8; x++) {
1917
        if (val & 0x80) {
1918
            *dst = s->cirrus_shadow_gr1;
1919
        } else if (mode == 5) {
1920
            *dst = s->cirrus_shadow_gr0;
1921
        }
1922
        val <<= 1;
1923
        dst++;
1924
    }
1925
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
1926
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
1927
}
1928

    
1929
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1930
                                              unsigned mode,
1931
                                              unsigned offset,
1932
                                              uint32_t mem_value)
1933
{
1934
    int x;
1935
    unsigned val = mem_value;
1936
    uint8_t *dst;
1937

    
1938
    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1939
    for (x = 0; x < 8; x++) {
1940
        if (val & 0x80) {
1941
            *dst = s->cirrus_shadow_gr1;
1942
            *(dst + 1) = s->vga.gr[0x11];
1943
        } else if (mode == 5) {
1944
            *dst = s->cirrus_shadow_gr0;
1945
            *(dst + 1) = s->vga.gr[0x10];
1946
        }
1947
        val <<= 1;
1948
        dst += 2;
1949
    }
1950
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
1951
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
1952
}
1953

    
1954
/***************************************
1955
 *
1956
 *  memory access between 0xa0000-0xbffff
1957
 *
1958
 ***************************************/
1959

    
1960
static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
1961
{
1962
    CirrusVGAState *s = opaque;
1963
    unsigned bank_index;
1964
    unsigned bank_offset;
1965
    uint32_t val;
1966

    
1967
    if ((s->vga.sr[0x07] & 0x01) == 0) {
1968
        return vga_mem_readb(s, addr);
1969
    }
1970

    
1971
    addr &= 0x1ffff;
1972

    
1973
    if (addr < 0x10000) {
1974
        /* XXX handle bitblt */
1975
        /* video memory */
1976
        bank_index = addr >> 15;
1977
        bank_offset = addr & 0x7fff;
1978
        if (bank_offset < s->cirrus_bank_limit[bank_index]) {
1979
            bank_offset += s->cirrus_bank_base[bank_index];
1980
            if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
1981
                bank_offset <<= 4;
1982
            } else if (s->vga.gr[0x0B] & 0x02) {
1983
                bank_offset <<= 3;
1984
            }
1985
            bank_offset &= s->cirrus_addr_mask;
1986
            val = *(s->vga.vram_ptr + bank_offset);
1987
        } else
1988
            val = 0xff;
1989
    } else if (addr >= 0x18000 && addr < 0x18100) {
1990
        /* memory-mapped I/O */
1991
        val = 0xff;
1992
        if ((s->vga.sr[0x17] & 0x44) == 0x04) {
1993
            val = cirrus_mmio_blt_read(s, addr & 0xff);
1994
        }
1995
    } else {
1996
        val = 0xff;
1997
#ifdef DEBUG_CIRRUS
1998
        printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
1999
#endif
2000
    }
2001
    return val;
2002
}
2003

    
2004
static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
2005
{
2006
    uint32_t v;
2007

    
2008
    v = cirrus_vga_mem_readb(opaque, addr);
2009
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2010
    return v;
2011
}
2012

    
2013
static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
2014
{
2015
    uint32_t v;
2016

    
2017
    v = cirrus_vga_mem_readb(opaque, addr);
2018
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2019
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
2020
    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
2021
    return v;
2022
}
2023

    
2024
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
2025
                                  uint32_t mem_value)
2026
{
2027
    CirrusVGAState *s = opaque;
2028
    unsigned bank_index;
2029
    unsigned bank_offset;
2030
    unsigned mode;
2031

    
2032
    if ((s->vga.sr[0x07] & 0x01) == 0) {
2033
        vga_mem_writeb(s, addr, mem_value);
2034
        return;
2035
    }
2036

    
2037
    addr &= 0x1ffff;
2038

    
2039
    if (addr < 0x10000) {
2040
        if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2041
            /* bitblt */
2042
            *s->cirrus_srcptr++ = (uint8_t) mem_value;
2043
            if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2044
                cirrus_bitblt_cputovideo_next(s);
2045
            }
2046
        } else {
2047
            /* video memory */
2048
            bank_index = addr >> 15;
2049
            bank_offset = addr & 0x7fff;
2050
            if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2051
                bank_offset += s->cirrus_bank_base[bank_index];
2052
                if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2053
                    bank_offset <<= 4;
2054
                } else if (s->vga.gr[0x0B] & 0x02) {
2055
                    bank_offset <<= 3;
2056
                }
2057
                bank_offset &= s->cirrus_addr_mask;
2058
                mode = s->vga.gr[0x05] & 0x7;
2059
                if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2060
                    *(s->vga.vram_ptr + bank_offset) = mem_value;
2061
                    cpu_physical_memory_set_dirty(s->vga.vram_offset +
2062
                                                  bank_offset);
2063
                } else {
2064
                    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2065
                        cirrus_mem_writeb_mode4and5_8bpp(s, mode,
2066
                                                         bank_offset,
2067
                                                         mem_value);
2068
                    } else {
2069
                        cirrus_mem_writeb_mode4and5_16bpp(s, mode,
2070
                                                          bank_offset,
2071
                                                          mem_value);
2072
                    }
2073
                }
2074
            }
2075
        }
2076
    } else if (addr >= 0x18000 && addr < 0x18100) {
2077
        /* memory-mapped I/O */
2078
        if ((s->vga.sr[0x17] & 0x44) == 0x04) {
2079
            cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
2080
        }
2081
    } else {
2082
#ifdef DEBUG_CIRRUS
2083
        printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr,
2084
               mem_value);
2085
#endif
2086
    }
2087
}
2088

    
2089
static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2090
{
2091
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2092
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2093
}
2094

    
2095
static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2096
{
2097
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2098
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2099
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2100
    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2101
}
2102

    
2103
static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
2104
    cirrus_vga_mem_readb,
2105
    cirrus_vga_mem_readw,
2106
    cirrus_vga_mem_readl,
2107
};
2108

    
2109
static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
2110
    cirrus_vga_mem_writeb,
2111
    cirrus_vga_mem_writew,
2112
    cirrus_vga_mem_writel,
2113
};
2114

    
2115
/***************************************
2116
 *
2117
 *  hardware cursor
2118
 *
2119
 ***************************************/
2120

    
2121
static inline void invalidate_cursor1(CirrusVGAState *s)
2122
{
2123
    if (s->last_hw_cursor_size) {
2124
        vga_invalidate_scanlines(&s->vga,
2125
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_start,
2126
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_end);
2127
    }
2128
}
2129

    
2130
static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
2131
{
2132
    const uint8_t *src;
2133
    uint32_t content;
2134
    int y, y_min, y_max;
2135

    
2136
    src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2137
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2138
        src += (s->vga.sr[0x13] & 0x3c) * 256;
2139
        y_min = 64;
2140
        y_max = -1;
2141
        for(y = 0; y < 64; y++) {
2142
            content = ((uint32_t *)src)[0] |
2143
                ((uint32_t *)src)[1] |
2144
                ((uint32_t *)src)[2] |
2145
                ((uint32_t *)src)[3];
2146
            if (content) {
2147
                if (y < y_min)
2148
                    y_min = y;
2149
                if (y > y_max)
2150
                    y_max = y;
2151
            }
2152
            src += 16;
2153
        }
2154
    } else {
2155
        src += (s->vga.sr[0x13] & 0x3f) * 256;
2156
        y_min = 32;
2157
        y_max = -1;
2158
        for(y = 0; y < 32; y++) {
2159
            content = ((uint32_t *)src)[0] |
2160
                ((uint32_t *)(src + 128))[0];
2161
            if (content) {
2162
                if (y < y_min)
2163
                    y_min = y;
2164
                if (y > y_max)
2165
                    y_max = y;
2166
            }
2167
            src += 4;
2168
        }
2169
    }
2170
    if (y_min > y_max) {
2171
        s->last_hw_cursor_y_start = 0;
2172
        s->last_hw_cursor_y_end = 0;
2173
    } else {
2174
        s->last_hw_cursor_y_start = y_min;
2175
        s->last_hw_cursor_y_end = y_max + 1;
2176
    }
2177
}
2178

    
2179
/* NOTE: we do not currently handle the cursor bitmap change, so we
2180
   update the cursor only if it moves. */
2181
static void cirrus_cursor_invalidate(VGACommonState *s1)
2182
{
2183
    CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2184
    int size;
2185

    
2186
    if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
2187
        size = 0;
2188
    } else {
2189
        if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
2190
            size = 64;
2191
        else
2192
            size = 32;
2193
    }
2194
    /* invalidate last cursor and new cursor if any change */
2195
    if (s->last_hw_cursor_size != size ||
2196
        s->last_hw_cursor_x != s->hw_cursor_x ||
2197
        s->last_hw_cursor_y != s->hw_cursor_y) {
2198

    
2199
        invalidate_cursor1(s);
2200

    
2201
        s->last_hw_cursor_size = size;
2202
        s->last_hw_cursor_x = s->hw_cursor_x;
2203
        s->last_hw_cursor_y = s->hw_cursor_y;
2204
        /* compute the real cursor min and max y */
2205
        cirrus_cursor_compute_yrange(s);
2206
        invalidate_cursor1(s);
2207
    }
2208
}
2209

    
2210
static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
2211
{
2212
    CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2213
    int w, h, bpp, x1, x2, poffset;
2214
    unsigned int color0, color1;
2215
    const uint8_t *palette, *src;
2216
    uint32_t content;
2217

    
2218
    if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
2219
        return;
2220
    /* fast test to see if the cursor intersects with the scan line */
2221
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2222
        h = 64;
2223
    } else {
2224
        h = 32;
2225
    }
2226
    if (scr_y < s->hw_cursor_y ||
2227
        scr_y >= (s->hw_cursor_y + h))
2228
        return;
2229

    
2230
    src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2231
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2232
        src += (s->vga.sr[0x13] & 0x3c) * 256;
2233
        src += (scr_y - s->hw_cursor_y) * 16;
2234
        poffset = 8;
2235
        content = ((uint32_t *)src)[0] |
2236
            ((uint32_t *)src)[1] |
2237
            ((uint32_t *)src)[2] |
2238
            ((uint32_t *)src)[3];
2239
    } else {
2240
        src += (s->vga.sr[0x13] & 0x3f) * 256;
2241
        src += (scr_y - s->hw_cursor_y) * 4;
2242
        poffset = 128;
2243
        content = ((uint32_t *)src)[0] |
2244
            ((uint32_t *)(src + 128))[0];
2245
    }
2246
    /* if nothing to draw, no need to continue */
2247
    if (!content)
2248
        return;
2249
    w = h;
2250

    
2251
    x1 = s->hw_cursor_x;
2252
    if (x1 >= s->vga.last_scr_width)
2253
        return;
2254
    x2 = s->hw_cursor_x + w;
2255
    if (x2 > s->vga.last_scr_width)
2256
        x2 = s->vga.last_scr_width;
2257
    w = x2 - x1;
2258
    palette = s->cirrus_hidden_palette;
2259
    color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
2260
                                 c6_to_8(palette[0x0 * 3 + 1]),
2261
                                 c6_to_8(palette[0x0 * 3 + 2]));
2262
    color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
2263
                                 c6_to_8(palette[0xf * 3 + 1]),
2264
                                 c6_to_8(palette[0xf * 3 + 2]));
2265
    bpp = ((ds_get_bits_per_pixel(s->vga.ds) + 7) >> 3);
2266
    d1 += x1 * bpp;
2267
    switch(ds_get_bits_per_pixel(s->vga.ds)) {
2268
    default:
2269
        break;
2270
    case 8:
2271
        vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
2272
        break;
2273
    case 15:
2274
        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
2275
        break;
2276
    case 16:
2277
        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
2278
        break;
2279
    case 32:
2280
        vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
2281
        break;
2282
    }
2283
}
2284

    
2285
/***************************************
2286
 *
2287
 *  LFB memory access
2288
 *
2289
 ***************************************/
2290

    
2291
static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
2292
{
2293
    CirrusVGAState *s = opaque;
2294
    uint32_t ret;
2295

    
2296
    addr &= s->cirrus_addr_mask;
2297

    
2298
    if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2299
        ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2300
        /* memory-mapped I/O */
2301
        ret = cirrus_mmio_blt_read(s, addr & 0xff);
2302
    } else if (0) {
2303
        /* XXX handle bitblt */
2304
        ret = 0xff;
2305
    } else {
2306
        /* video memory */
2307
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2308
            addr <<= 4;
2309
        } else if (s->vga.gr[0x0B] & 0x02) {
2310
            addr <<= 3;
2311
        }
2312
        addr &= s->cirrus_addr_mask;
2313
        ret = *(s->vga.vram_ptr + addr);
2314
    }
2315

    
2316
    return ret;
2317
}
2318

    
2319
static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
2320
{
2321
    uint32_t v;
2322

    
2323
    v = cirrus_linear_readb(opaque, addr);
2324
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2325
    return v;
2326
}
2327

    
2328
static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
2329
{
2330
    uint32_t v;
2331

    
2332
    v = cirrus_linear_readb(opaque, addr);
2333
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2334
    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
2335
    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
2336
    return v;
2337
}
2338

    
2339
static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
2340
                                 uint32_t val)
2341
{
2342
    CirrusVGAState *s = opaque;
2343
    unsigned mode;
2344

    
2345
    addr &= s->cirrus_addr_mask;
2346

    
2347
    if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2348
        ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
2349
        /* memory-mapped I/O */
2350
        cirrus_mmio_blt_write(s, addr & 0xff, val);
2351
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2352
        /* bitblt */
2353
        *s->cirrus_srcptr++ = (uint8_t) val;
2354
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2355
            cirrus_bitblt_cputovideo_next(s);
2356
        }
2357
    } else {
2358
        /* video memory */
2359
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2360
            addr <<= 4;
2361
        } else if (s->vga.gr[0x0B] & 0x02) {
2362
            addr <<= 3;
2363
        }
2364
        addr &= s->cirrus_addr_mask;
2365

    
2366
        mode = s->vga.gr[0x05] & 0x7;
2367
        if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2368
            *(s->vga.vram_ptr + addr) = (uint8_t) val;
2369
            cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
2370
        } else {
2371
            if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2372
                cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2373
            } else {
2374
                cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2375
            }
2376
        }
2377
    }
2378
}
2379

    
2380
static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
2381
                                 uint32_t val)
2382
{
2383
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2384
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2385
}
2386

    
2387
static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
2388
                                 uint32_t val)
2389
{
2390
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2391
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2392
    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2393
    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2394
}
2395

    
2396

    
2397
static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
2398
    cirrus_linear_readb,
2399
    cirrus_linear_readw,
2400
    cirrus_linear_readl,
2401
};
2402

    
2403
static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
2404
    cirrus_linear_writeb,
2405
    cirrus_linear_writew,
2406
    cirrus_linear_writel,
2407
};
2408

    
2409
/***************************************
2410
 *
2411
 *  system to screen memory access
2412
 *
2413
 ***************************************/
2414

    
2415

    
2416
static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
2417
{
2418
    uint32_t ret;
2419

    
2420
    /* XXX handle bitblt */
2421
    ret = 0xff;
2422
    return ret;
2423
}
2424

    
2425
static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
2426
{
2427
    uint32_t v;
2428

    
2429
    v = cirrus_linear_bitblt_readb(opaque, addr);
2430
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2431
    return v;
2432
}
2433

    
2434
static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
2435
{
2436
    uint32_t v;
2437

    
2438
    v = cirrus_linear_bitblt_readb(opaque, addr);
2439
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2440
    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
2441
    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
2442
    return v;
2443
}
2444

    
2445
static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
2446
                                 uint32_t val)
2447
{
2448
    CirrusVGAState *s = opaque;
2449

    
2450
    if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2451
        /* bitblt */
2452
        *s->cirrus_srcptr++ = (uint8_t) val;
2453
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2454
            cirrus_bitblt_cputovideo_next(s);
2455
        }
2456
    }
2457
}
2458

    
2459
static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
2460
                                 uint32_t val)
2461
{
2462
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2463
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2464
}
2465

    
2466
static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
2467
                                 uint32_t val)
2468
{
2469
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2470
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2471
    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2472
    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2473
}
2474

    
2475

    
2476
static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
2477
    cirrus_linear_bitblt_readb,
2478
    cirrus_linear_bitblt_readw,
2479
    cirrus_linear_bitblt_readl,
2480
};
2481

    
2482
static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
2483
    cirrus_linear_bitblt_writeb,
2484
    cirrus_linear_bitblt_writew,
2485
    cirrus_linear_bitblt_writel,
2486
};
2487

    
2488
static void map_linear_vram(CirrusVGAState *s)
2489
{
2490
    if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
2491
        s->vga.map_addr = s->vga.lfb_addr;
2492
        s->vga.map_end = s->vga.lfb_end;
2493
        cpu_register_physical_memory(s->vga.map_addr, s->vga.map_end - s->vga.map_addr, s->vga.vram_offset);
2494
    }
2495

    
2496
    if (!s->vga.map_addr)
2497
        return;
2498

    
2499
    s->vga.lfb_vram_mapped = 0;
2500

    
2501
    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
2502
        && !((s->vga.sr[0x07] & 0x01) == 0)
2503
        && !((s->vga.gr[0x0B] & 0x14) == 0x14)
2504
        && !(s->vga.gr[0x0B] & 0x02)) {
2505

    
2506
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
2507
                                    (s->vga.vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
2508
        cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
2509
                                    (s->vga.vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM);
2510

    
2511
        s->vga.lfb_vram_mapped = 1;
2512
    }
2513
    else {
2514
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2515
                                     s->vga.vga_io_memory);
2516
    }
2517

    
2518
    vga_dirty_log_start(&s->vga);
2519
}
2520

    
2521
static void unmap_linear_vram(CirrusVGAState *s)
2522
{
2523
    if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
2524
        s->vga.map_addr = s->vga.map_end = 0;
2525
         cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
2526
                                      s->cirrus_linear_io_addr);
2527
    }
2528
    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2529
                                 s->vga.vga_io_memory);
2530
}
2531

    
2532
/* Compute the memory access functions */
2533
static void cirrus_update_memory_access(CirrusVGAState *s)
2534
{
2535
    unsigned mode;
2536

    
2537
    if ((s->vga.sr[0x17] & 0x44) == 0x44) {
2538
        goto generic_io;
2539
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2540
        goto generic_io;
2541
    } else {
2542
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2543
            goto generic_io;
2544
        } else if (s->vga.gr[0x0B] & 0x02) {
2545
            goto generic_io;
2546
        }
2547

    
2548
        mode = s->vga.gr[0x05] & 0x7;
2549
        if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2550
            map_linear_vram(s);
2551
        } else {
2552
        generic_io:
2553
            unmap_linear_vram(s);
2554
        }
2555
    }
2556
}
2557

    
2558

    
2559
/* I/O ports */
2560

    
2561
static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
2562
{
2563
    CirrusVGAState *c = opaque;
2564
    VGACommonState *s = &c->vga;
2565
    int val, index;
2566

    
2567
    if (vga_ioport_invalid(s, addr)) {
2568
        val = 0xff;
2569
    } else {
2570
        switch (addr) {
2571
        case 0x3c0:
2572
            if (s->ar_flip_flop == 0) {
2573
                val = s->ar_index;
2574
            } else {
2575
                val = 0;
2576
            }
2577
            break;
2578
        case 0x3c1:
2579
            index = s->ar_index & 0x1f;
2580
            if (index < 21)
2581
                val = s->ar[index];
2582
            else
2583
                val = 0;
2584
            break;
2585
        case 0x3c2:
2586
            val = s->st00;
2587
            break;
2588
        case 0x3c4:
2589
            val = s->sr_index;
2590
            break;
2591
        case 0x3c5:
2592
            val = cirrus_vga_read_sr(c);
2593
            break;
2594
#ifdef DEBUG_VGA_REG
2595
            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2596
#endif
2597
            break;
2598
        case 0x3c6:
2599
            val = cirrus_read_hidden_dac(c);
2600
            break;
2601
        case 0x3c7:
2602
            val = s->dac_state;
2603
            break;
2604
        case 0x3c8:
2605
            val = s->dac_write_index;
2606
            c->cirrus_hidden_dac_lockindex = 0;
2607
            break;
2608
        case 0x3c9:
2609
            val = cirrus_vga_read_palette(c);
2610
            break;
2611
        case 0x3ca:
2612
            val = s->fcr;
2613
            break;
2614
        case 0x3cc:
2615
            val = s->msr;
2616
            break;
2617
        case 0x3ce:
2618
            val = s->gr_index;
2619
            break;
2620
        case 0x3cf:
2621
            val = cirrus_vga_read_gr(c, s->gr_index);
2622
#ifdef DEBUG_VGA_REG
2623
            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2624
#endif
2625
            break;
2626
        case 0x3b4:
2627
        case 0x3d4:
2628
            val = s->cr_index;
2629
            break;
2630
        case 0x3b5:
2631
        case 0x3d5:
2632
            val = cirrus_vga_read_cr(c, s->cr_index);
2633
#ifdef DEBUG_VGA_REG
2634
            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2635
#endif
2636
            break;
2637
        case 0x3ba:
2638
        case 0x3da:
2639
            /* just toggle to fool polling */
2640
            val = s->st01 = s->retrace(s);
2641
            s->ar_flip_flop = 0;
2642
            break;
2643
        default:
2644
            val = 0x00;
2645
            break;
2646
        }
2647
    }
2648
#if defined(DEBUG_VGA)
2649
    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2650
#endif
2651
    return val;
2652
}
2653

    
2654
static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2655
{
2656
    CirrusVGAState *c = opaque;
2657
    VGACommonState *s = &c->vga;
2658
    int index;
2659

    
2660
    /* check port range access depending on color/monochrome mode */
2661
    if (vga_ioport_invalid(s, addr)) {
2662
        return;
2663
    }
2664
#ifdef DEBUG_VGA
2665
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2666
#endif
2667

    
2668
    switch (addr) {
2669
    case 0x3c0:
2670
        if (s->ar_flip_flop == 0) {
2671
            val &= 0x3f;
2672
            s->ar_index = val;
2673
        } else {
2674
            index = s->ar_index & 0x1f;
2675
            switch (index) {
2676
            case 0x00 ... 0x0f:
2677
                s->ar[index] = val & 0x3f;
2678
                break;
2679
            case 0x10:
2680
                s->ar[index] = val & ~0x10;
2681
                break;
2682
            case 0x11:
2683
                s->ar[index] = val;
2684
                break;
2685
            case 0x12:
2686
                s->ar[index] = val & ~0xc0;
2687
                break;
2688
            case 0x13:
2689
                s->ar[index] = val & ~0xf0;
2690
                break;
2691
            case 0x14:
2692
                s->ar[index] = val & ~0xf0;
2693
                break;
2694
            default:
2695
                break;
2696
            }
2697
        }
2698
        s->ar_flip_flop ^= 1;
2699
        break;
2700
    case 0x3c2:
2701
        s->msr = val & ~0x10;
2702
        s->update_retrace_info(s);
2703
        break;
2704
    case 0x3c4:
2705
        s->sr_index = val;
2706
        break;
2707
    case 0x3c5:
2708
#ifdef DEBUG_VGA_REG
2709
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2710
#endif
2711
        cirrus_vga_write_sr(c, val);
2712
        break;
2713
        break;
2714
    case 0x3c6:
2715
        cirrus_write_hidden_dac(c, val);
2716
        break;
2717
    case 0x3c7:
2718
        s->dac_read_index = val;
2719
        s->dac_sub_index = 0;
2720
        s->dac_state = 3;
2721
        break;
2722
    case 0x3c8:
2723
        s->dac_write_index = val;
2724
        s->dac_sub_index = 0;
2725
        s->dac_state = 0;
2726
        break;
2727
    case 0x3c9:
2728
        cirrus_vga_write_palette(c, val);
2729
        break;
2730
    case 0x3ce:
2731
        s->gr_index = val;
2732
        break;
2733
    case 0x3cf:
2734
#ifdef DEBUG_VGA_REG
2735
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2736
#endif
2737
        cirrus_vga_write_gr(c, s->gr_index, val);
2738
        break;
2739
    case 0x3b4:
2740
    case 0x3d4:
2741
        s->cr_index = val;
2742
        break;
2743
    case 0x3b5:
2744
    case 0x3d5:
2745
#ifdef DEBUG_VGA_REG
2746
        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2747
#endif
2748
        cirrus_vga_write_cr(c, val);
2749
        break;
2750
    case 0x3ba:
2751
    case 0x3da:
2752
        s->fcr = val & 0x10;
2753
        break;
2754
    }
2755
}
2756

    
2757
/***************************************
2758
 *
2759
 *  memory-mapped I/O access
2760
 *
2761
 ***************************************/
2762

    
2763
static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
2764
{
2765
    CirrusVGAState *s = opaque;
2766

    
2767
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2768

    
2769
    if (addr >= 0x100) {
2770
        return cirrus_mmio_blt_read(s, addr - 0x100);
2771
    } else {
2772
        return cirrus_vga_ioport_read(s, addr + 0x3c0);
2773
    }
2774
}
2775

    
2776
static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
2777
{
2778
    uint32_t v;
2779

    
2780
    v = cirrus_mmio_readb(opaque, addr);
2781
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2782
    return v;
2783
}
2784

    
2785
static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
2786
{
2787
    uint32_t v;
2788

    
2789
    v = cirrus_mmio_readb(opaque, addr);
2790
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2791
    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
2792
    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
2793
    return v;
2794
}
2795

    
2796
static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
2797
                               uint32_t val)
2798
{
2799
    CirrusVGAState *s = opaque;
2800

    
2801
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2802

    
2803
    if (addr >= 0x100) {
2804
        cirrus_mmio_blt_write(s, addr - 0x100, val);
2805
    } else {
2806
        cirrus_vga_ioport_write(s, addr + 0x3c0, val);
2807
    }
2808
}
2809

    
2810
static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
2811
                               uint32_t val)
2812
{
2813
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2814
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2815
}
2816

    
2817
static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
2818
                               uint32_t val)
2819
{
2820
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2821
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2822
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2823
    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2824
}
2825

    
2826

    
2827
static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
2828
    cirrus_mmio_readb,
2829
    cirrus_mmio_readw,
2830
    cirrus_mmio_readl,
2831
};
2832

    
2833
static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
2834
    cirrus_mmio_writeb,
2835
    cirrus_mmio_writew,
2836
    cirrus_mmio_writel,
2837
};
2838

    
2839
/* load/save state */
2840

    
2841
static int cirrus_post_load(void *opaque, int version_id)
2842
{
2843
    CirrusVGAState *s = opaque;
2844

    
2845
    s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
2846
    s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
2847

    
2848
    cirrus_update_memory_access(s);
2849
    /* force refresh */
2850
    s->vga.graphic_mode = -1;
2851
    cirrus_update_bank_ptr(s, 0);
2852
    cirrus_update_bank_ptr(s, 1);
2853
    return 0;
2854
}
2855

    
2856
static const VMStateDescription vmstate_cirrus_vga = {
2857
    .name = "cirrus_vga",
2858
    .version_id = 2,
2859
    .minimum_version_id = 1,
2860
    .minimum_version_id_old = 1,
2861
    .post_load = cirrus_post_load,
2862
    .fields      = (VMStateField []) {
2863
        VMSTATE_UINT32(vga.latch, CirrusVGAState),
2864
        VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
2865
        VMSTATE_BUFFER(vga.sr, CirrusVGAState),
2866
        VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
2867
        VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
2868
        VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
2869
        VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
2870
        VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
2871
        VMSTATE_BUFFER(vga.ar, CirrusVGAState),
2872
        VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
2873
        VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
2874
        VMSTATE_BUFFER(vga.cr, CirrusVGAState),
2875
        VMSTATE_UINT8(vga.msr, CirrusVGAState),
2876
        VMSTATE_UINT8(vga.fcr, CirrusVGAState),
2877
        VMSTATE_UINT8(vga.st00, CirrusVGAState),
2878
        VMSTATE_UINT8(vga.st01, CirrusVGAState),
2879
        VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
2880
        VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
2881
        VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
2882
        VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
2883
        VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
2884
        VMSTATE_BUFFER(vga.palette, CirrusVGAState),
2885
        VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
2886
        VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
2887
        VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
2888
        VMSTATE_UINT32(hw_cursor_x, CirrusVGAState),
2889
        VMSTATE_UINT32(hw_cursor_y, CirrusVGAState),
2890
        /* XXX: we do not save the bitblt state - we assume we do not save
2891
           the state when the blitter is active */
2892
        VMSTATE_END_OF_LIST()
2893
    }
2894
};
2895

    
2896
static const VMStateDescription vmstate_pci_cirrus_vga = {
2897
    .name = "cirrus_vga",
2898
    .version_id = 2,
2899
    .minimum_version_id = 2,
2900
    .minimum_version_id_old = 2,
2901
    .fields      = (VMStateField []) {
2902
        VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
2903
        VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
2904
                       vmstate_cirrus_vga, CirrusVGAState),
2905
        VMSTATE_END_OF_LIST()
2906
    }
2907
};
2908

    
2909
/***************************************
2910
 *
2911
 *  initialize
2912
 *
2913
 ***************************************/
2914

    
2915
static void cirrus_reset(void *opaque)
2916
{
2917
    CirrusVGAState *s = opaque;
2918

    
2919
    vga_common_reset(&s->vga);
2920
    unmap_linear_vram(s);
2921
    s->vga.sr[0x06] = 0x0f;
2922
    if (s->device_id == CIRRUS_ID_CLGD5446) {
2923
        /* 4MB 64 bit memory config, always PCI */
2924
        s->vga.sr[0x1F] = 0x2d;                // MemClock
2925
        s->vga.gr[0x18] = 0x0f;             // fastest memory configuration
2926
        s->vga.sr[0x0f] = 0x98;
2927
        s->vga.sr[0x17] = 0x20;
2928
        s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
2929
    } else {
2930
        s->vga.sr[0x1F] = 0x22;                // MemClock
2931
        s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
2932
        s->vga.sr[0x17] = s->bustype;
2933
        s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
2934
    }
2935
    s->vga.cr[0x27] = s->device_id;
2936

    
2937
    /* Win2K seems to assume that the pattern buffer is at 0xff
2938
       initially ! */
2939
    memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
2940

    
2941
    s->cirrus_hidden_dac_lockindex = 5;
2942
    s->cirrus_hidden_dac_data = 0;
2943
}
2944

    
2945
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
2946
{
2947
    int i;
2948
    static int inited;
2949

    
2950
    if (!inited) {
2951
        inited = 1;
2952
        for(i = 0;i < 256; i++)
2953
            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
2954
        rop_to_index[CIRRUS_ROP_0] = 0;
2955
        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
2956
        rop_to_index[CIRRUS_ROP_NOP] = 2;
2957
        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
2958
        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
2959
        rop_to_index[CIRRUS_ROP_SRC] = 5;
2960
        rop_to_index[CIRRUS_ROP_1] = 6;
2961
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
2962
        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
2963
        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
2964
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
2965
        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
2966
        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
2967
        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
2968
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
2969
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
2970
        s->device_id = device_id;
2971
        if (is_pci)
2972
            s->bustype = CIRRUS_BUSTYPE_PCI;
2973
        else
2974
            s->bustype = CIRRUS_BUSTYPE_ISA;
2975
    }
2976

    
2977
    register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
2978

    
2979
    register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
2980
    register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
2981
    register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
2982
    register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
2983

    
2984
    register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
2985

    
2986
    register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
2987
    register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
2988
    register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
2989
    register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
2990

    
2991
    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
2992
                                                  cirrus_vga_mem_write, s,
2993
                                                  DEVICE_LITTLE_ENDIAN);
2994
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
2995
                                 s->vga.vga_io_memory);
2996
    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
2997

    
2998
    /* I/O handler for LFB */
2999
    s->cirrus_linear_io_addr =
3000
        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
3001
                               DEVICE_LITTLE_ENDIAN);
3002

    
3003
    /* I/O handler for LFB */
3004
    s->cirrus_linear_bitblt_io_addr =
3005
        cpu_register_io_memory(cirrus_linear_bitblt_read,
3006
                               cirrus_linear_bitblt_write, s,
3007
                               DEVICE_LITTLE_ENDIAN);
3008

    
3009
    /* I/O handler for memory-mapped I/O */
3010
    s->cirrus_mmio_io_addr =
3011
        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
3012
                               DEVICE_LITTLE_ENDIAN);
3013

    
3014
    s->real_vram_size =
3015
        (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
3016

    
3017
    /* XXX: s->vga.vram_size must be a power of two */
3018
    s->cirrus_addr_mask = s->real_vram_size - 1;
3019
    s->linear_mmio_mask = s->real_vram_size - 256;
3020

    
3021
    s->vga.get_bpp = cirrus_get_bpp;
3022
    s->vga.get_offsets = cirrus_get_offsets;
3023
    s->vga.get_resolution = cirrus_get_resolution;
3024
    s->vga.cursor_invalidate = cirrus_cursor_invalidate;
3025
    s->vga.cursor_draw_line = cirrus_cursor_draw_line;
3026

    
3027
    qemu_register_reset(cirrus_reset, s);
3028
    cirrus_reset(s);
3029
}
3030

    
3031
/***************************************
3032
 *
3033
 *  ISA bus support
3034
 *
3035
 ***************************************/
3036

    
3037
void isa_cirrus_vga_init(void)
3038
{
3039
    CirrusVGAState *s;
3040

    
3041
    s = qemu_mallocz(sizeof(CirrusVGAState));
3042

    
3043
    vga_common_init(&s->vga, VGA_RAM_SIZE);
3044
    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
3045
    s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
3046
                                     s->vga.screen_dump, s->vga.text_update,
3047
                                     &s->vga);
3048
    vmstate_register(NULL, 0, &vmstate_cirrus_vga, s);
3049
    rom_add_vga(VGABIOS_CIRRUS_FILENAME);
3050
    /* XXX ISA-LFB support */
3051
}
3052

    
3053
/***************************************
3054
 *
3055
 *  PCI bus support
3056
 *
3057
 ***************************************/
3058

    
3059
static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
3060
                               pcibus_t addr, pcibus_t size, int type)
3061
{
3062
    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
3063

    
3064
    /* XXX: add byte swapping apertures */
3065
    cpu_register_physical_memory(addr, s->vga.vram_size,
3066
                                 s->cirrus_linear_io_addr);
3067
    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
3068
                                 s->cirrus_linear_bitblt_io_addr);
3069

    
3070
    s->vga.map_addr = s->vga.map_end = 0;
3071
    s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
3072
    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
3073
    /* account for overflow */
3074
    if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
3075
        s->vga.lfb_end = addr + VGA_RAM_SIZE;
3076

    
3077
    vga_dirty_log_start(&s->vga);
3078
}
3079

    
3080
static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
3081
                                pcibus_t addr, pcibus_t size, int type)
3082
{
3083
    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
3084

    
3085
    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
3086
                                 s->cirrus_mmio_io_addr);
3087
}
3088

    
3089
static void pci_cirrus_write_config(PCIDevice *d,
3090
                                    uint32_t address, uint32_t val, int len)
3091
{
3092
    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
3093
    CirrusVGAState *s = &pvs->cirrus_vga;
3094

    
3095
    pci_default_write_config(d, address, val, len);
3096
    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED)
3097
        s->vga.map_addr = 0;
3098
    cirrus_update_memory_access(s);
3099
}
3100

    
3101
static int pci_cirrus_vga_initfn(PCIDevice *dev)
3102
{
3103
     PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
3104
     CirrusVGAState *s = &d->cirrus_vga;
3105
     uint8_t *pci_conf = d->dev.config;
3106
     int device_id = CIRRUS_ID_CLGD5446;
3107

    
3108
     /* setup VGA */
3109
     vga_common_init(&s->vga, VGA_RAM_SIZE);
3110
     cirrus_init_common(s, device_id, 1);
3111
     s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
3112
                                      s->vga.screen_dump, s->vga.text_update,
3113
                                      &s->vga);
3114

    
3115
     /* setup PCI */
3116
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
3117
     pci_config_set_device_id(pci_conf, device_id);
3118
     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
3119

    
3120
     /* setup memory space */
3121
     /* memory #0 LFB */
3122
     /* memory #1 memory-mapped I/O */
3123
     /* XXX: s->vga.vram_size must be a power of two */
3124
     pci_register_bar(&d->dev, 0, 0x2000000,
3125
                      PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
3126
     if (device_id == CIRRUS_ID_CLGD5446) {
3127
         pci_register_bar(&d->dev, 1, CIRRUS_PNPMMIO_SIZE,
3128
                          PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map);
3129
     }
3130
     return 0;
3131
}
3132

    
3133
void pci_cirrus_vga_init(PCIBus *bus)
3134
{
3135
    pci_create_simple(bus, -1, "cirrus-vga");
3136
}
3137

    
3138
static PCIDeviceInfo cirrus_vga_info = {
3139
    .qdev.name    = "cirrus-vga",
3140
    .qdev.desc    = "Cirrus CLGD 54xx VGA",
3141
    .qdev.size    = sizeof(PCICirrusVGAState),
3142
    .qdev.vmsd    = &vmstate_pci_cirrus_vga,
3143
    .init         = pci_cirrus_vga_initfn,
3144
    .romfile      = VGABIOS_CIRRUS_FILENAME,
3145
    .config_write = pci_cirrus_write_config,
3146
};
3147

    
3148
static void cirrus_vga_register(void)
3149
{
3150
    pci_qdev_register(&cirrus_vga_info);
3151
}
3152
device_init(cirrus_vga_register);