~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/cirrus_vga.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

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