Statistics
| Branch: | Revision:

root / hw / cirrus_vga.c @ 5245d57a

History | View | Annotate | Download (97.8 kB)

1
/*
2
 * QEMU Cirrus CLGD 54xx VGA Emulator.
3
 *
4
 * Copyright (c) 2004 Fabrice Bellard
5
 * Copyright (c) 2004 Makoto Suzuki (suzu)
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
/*
26
 * Reference: Finn Thogersons' VGADOC4b
27
 *   available at http://home.worldonline.dk/~finth/
28
 */
29
#include "hw.h"
30
#include "pc.h"
31
#include "pci.h"
32
#include "console.h"
33
#include "vga_int.h"
34
#include "kvm.h"
35
#include "loader.h"
36

    
37
/*
38
 * TODO:
39
 *    - destination write mask support not complete (bits 5..7)
40
 *    - optimize linear mappings
41
 *    - optimize bitblt functions
42
 */
43

    
44
//#define DEBUG_CIRRUS
45
//#define DEBUG_BITBLT
46

    
47
/***************************************
48
 *
49
 *  definitions
50
 *
51
 ***************************************/
52

    
53
// ID
54
#define CIRRUS_ID_CLGD5422  (0x23<<2)
55
#define CIRRUS_ID_CLGD5426  (0x24<<2)
56
#define CIRRUS_ID_CLGD5424  (0x25<<2)
57
#define CIRRUS_ID_CLGD5428  (0x26<<2)
58
#define CIRRUS_ID_CLGD5430  (0x28<<2)
59
#define CIRRUS_ID_CLGD5434  (0x2A<<2)
60
#define CIRRUS_ID_CLGD5436  (0x2B<<2)
61
#define CIRRUS_ID_CLGD5446  (0x2E<<2)
62

    
63
// sequencer 0x07
64
#define CIRRUS_SR7_BPP_VGA            0x00
65
#define CIRRUS_SR7_BPP_SVGA           0x01
66
#define CIRRUS_SR7_BPP_MASK           0x0e
67
#define CIRRUS_SR7_BPP_8              0x00
68
#define CIRRUS_SR7_BPP_16_DOUBLEVCLK  0x02
69
#define CIRRUS_SR7_BPP_24             0x04
70
#define CIRRUS_SR7_BPP_16             0x06
71
#define CIRRUS_SR7_BPP_32             0x08
72
#define CIRRUS_SR7_ISAADDR_MASK       0xe0
73

    
74
// sequencer 0x0f
75
#define CIRRUS_MEMSIZE_512k        0x08
76
#define CIRRUS_MEMSIZE_1M          0x10
77
#define CIRRUS_MEMSIZE_2M          0x18
78
#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80        // bank switching is enabled.
79

    
80
// sequencer 0x12
81
#define CIRRUS_CURSOR_SHOW         0x01
82
#define CIRRUS_CURSOR_HIDDENPEL    0x02
83
#define CIRRUS_CURSOR_LARGE        0x04        // 64x64 if set, 32x32 if clear
84

    
85
// sequencer 0x17
86
#define CIRRUS_BUSTYPE_VLBFAST   0x10
87
#define CIRRUS_BUSTYPE_PCI       0x20
88
#define CIRRUS_BUSTYPE_VLBSLOW   0x30
89
#define CIRRUS_BUSTYPE_ISA       0x38
90
#define CIRRUS_MMIO_ENABLE       0x04
91
#define CIRRUS_MMIO_USE_PCIADDR  0x40        // 0xb8000 if cleared.
92
#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
93

    
94
// control 0x0b
95
#define CIRRUS_BANKING_DUAL             0x01
96
#define CIRRUS_BANKING_GRANULARITY_16K  0x20        // set:16k, clear:4k
97

    
98
// control 0x30
99
#define CIRRUS_BLTMODE_BACKWARDS        0x01
100
#define CIRRUS_BLTMODE_MEMSYSDEST       0x02
101
#define CIRRUS_BLTMODE_MEMSYSSRC        0x04
102
#define CIRRUS_BLTMODE_TRANSPARENTCOMP  0x08
103
#define CIRRUS_BLTMODE_PATTERNCOPY      0x40
104
#define CIRRUS_BLTMODE_COLOREXPAND      0x80
105
#define CIRRUS_BLTMODE_PIXELWIDTHMASK   0x30
106
#define CIRRUS_BLTMODE_PIXELWIDTH8      0x00
107
#define CIRRUS_BLTMODE_PIXELWIDTH16     0x10
108
#define CIRRUS_BLTMODE_PIXELWIDTH24     0x20
109
#define CIRRUS_BLTMODE_PIXELWIDTH32     0x30
110

    
111
// control 0x31
112
#define CIRRUS_BLT_BUSY                 0x01
113
#define CIRRUS_BLT_START                0x02
114
#define CIRRUS_BLT_RESET                0x04
115
#define CIRRUS_BLT_FIFOUSED             0x10
116
#define CIRRUS_BLT_AUTOSTART            0x80
117

    
118
// control 0x32
119
#define CIRRUS_ROP_0                    0x00
120
#define CIRRUS_ROP_SRC_AND_DST          0x05
121
#define CIRRUS_ROP_NOP                  0x06
122
#define CIRRUS_ROP_SRC_AND_NOTDST       0x09
123
#define CIRRUS_ROP_NOTDST               0x0b
124
#define CIRRUS_ROP_SRC                  0x0d
125
#define CIRRUS_ROP_1                    0x0e
126
#define CIRRUS_ROP_NOTSRC_AND_DST       0x50
127
#define CIRRUS_ROP_SRC_XOR_DST          0x59
128
#define CIRRUS_ROP_SRC_OR_DST           0x6d
129
#define CIRRUS_ROP_NOTSRC_OR_NOTDST     0x90
130
#define CIRRUS_ROP_SRC_NOTXOR_DST       0x95
131
#define CIRRUS_ROP_SRC_OR_NOTDST        0xad
132
#define CIRRUS_ROP_NOTSRC               0xd0
133
#define CIRRUS_ROP_NOTSRC_OR_DST        0xd6
134
#define CIRRUS_ROP_NOTSRC_AND_NOTDST    0xda
135

    
136
#define CIRRUS_ROP_NOP_INDEX 2
137
#define CIRRUS_ROP_SRC_INDEX 5
138

    
139
// control 0x33
140
#define CIRRUS_BLTMODEEXT_SOLIDFILL        0x04
141
#define CIRRUS_BLTMODEEXT_COLOREXPINV      0x02
142
#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
143

    
144
// memory-mapped IO
145
#define CIRRUS_MMIO_BLTBGCOLOR        0x00        // dword
146
#define CIRRUS_MMIO_BLTFGCOLOR        0x04        // dword
147
#define CIRRUS_MMIO_BLTWIDTH          0x08        // word
148
#define CIRRUS_MMIO_BLTHEIGHT         0x0a        // word
149
#define CIRRUS_MMIO_BLTDESTPITCH      0x0c        // word
150
#define CIRRUS_MMIO_BLTSRCPITCH       0x0e        // word
151
#define CIRRUS_MMIO_BLTDESTADDR       0x10        // dword
152
#define CIRRUS_MMIO_BLTSRCADDR        0x14        // dword
153
#define CIRRUS_MMIO_BLTWRITEMASK      0x17        // byte
154
#define CIRRUS_MMIO_BLTMODE           0x18        // byte
155
#define CIRRUS_MMIO_BLTROP            0x1a        // byte
156
#define CIRRUS_MMIO_BLTMODEEXT        0x1b        // byte
157
#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c        // word?
158
#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20        // word?
159
#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24        // word
160
#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26        // word
161
#define CIRRUS_MMIO_LINEARDRAW_END_X  0x28        // word
162
#define CIRRUS_MMIO_LINEARDRAW_END_Y  0x2a        // word
163
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c        // byte
164
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d        // byte
165
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e        // byte
166
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f        // byte
167
#define CIRRUS_MMIO_BRESENHAM_K1      0x30        // word
168
#define CIRRUS_MMIO_BRESENHAM_K3      0x32        // word
169
#define CIRRUS_MMIO_BRESENHAM_ERROR   0x34        // word
170
#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36        // word
171
#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38        // byte
172
#define CIRRUS_MMIO_LINEDRAW_MODE     0x39        // byte
173
#define CIRRUS_MMIO_BLTSTATUS         0x40        // byte
174

    
175
// PCI 0x04: command(word), 0x06(word): status
176
#define PCI_COMMAND_IOACCESS                0x0001
177
#define PCI_COMMAND_MEMACCESS               0x0002
178
#define PCI_COMMAND_BUSMASTER               0x0004
179
#define PCI_COMMAND_SPECIALCYCLE            0x0008
180
#define PCI_COMMAND_MEMWRITEINVALID         0x0010
181
#define PCI_COMMAND_PALETTESNOOPING         0x0020
182
#define PCI_COMMAND_PARITYDETECTION         0x0040
183
#define PCI_COMMAND_ADDRESSDATASTEPPING     0x0080
184
#define PCI_COMMAND_SERR                    0x0100
185
#define PCI_COMMAND_BACKTOBACKTRANS         0x0200
186
// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
187
#define PCI_CLASS_BASE_DISPLAY        0x03
188
// PCI 0x08, 0x00ff0000
189
#define PCI_CLASS_SUB_VGA             0x00
190
// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
191
// 0x10-0x3f (headertype 00h)
192
// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
193
//   0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
194
#define PCI_MAP_MEM                 0x0
195
#define PCI_MAP_IO                  0x1
196
#define PCI_MAP_MEM_ADDR_MASK       (~0xf)
197
#define PCI_MAP_IO_ADDR_MASK        (~0x3)
198
#define PCI_MAP_MEMFLAGS_32BIT      0x0
199
#define PCI_MAP_MEMFLAGS_32BIT_1M   0x1
200
#define PCI_MAP_MEMFLAGS_64BIT      0x4
201
#define PCI_MAP_MEMFLAGS_CACHEABLE  0x8
202
// PCI 0x28: cardbus CIS pointer
203
// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
204
// PCI 0x30: expansion ROM base address
205
#define PCI_ROMBIOS_ENABLED         0x1
206
// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
207
// PCI 0x38: reserved
208
// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
209

    
210
#define CIRRUS_PNPMMIO_SIZE         0x1000
211

    
212
#define ABS(a) ((signed)(a) > 0 ? a : -a)
213

    
214
#define BLTUNSAFE(s) \
215
    ( \
216
        ( /* check dst is within bounds */ \
217
            (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
218
                + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
219
                    (s)->vga.vram_size \
220
        ) || \
221
        ( /* check src is within bounds */ \
222
            (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
223
                + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
224
                    (s)->vga.vram_size \
225
        ) \
226
    )
227

    
228
struct CirrusVGAState;
229
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
230
                                     uint8_t * dst, const uint8_t * src,
231
                                     int dstpitch, int srcpitch,
232
                                     int bltwidth, int bltheight);
233
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
234
                              uint8_t *dst, int dst_pitch, int width, int height);
235

    
236
typedef struct CirrusVGAState {
237
    VGACommonState vga;
238

    
239
    int cirrus_linear_io_addr;
240
    int cirrus_linear_bitblt_io_addr;
241
    int cirrus_mmio_io_addr;
242
    uint32_t cirrus_addr_mask;
243
    uint32_t linear_mmio_mask;
244
    uint8_t cirrus_shadow_gr0;
245
    uint8_t cirrus_shadow_gr1;
246
    uint8_t cirrus_hidden_dac_lockindex;
247
    uint8_t cirrus_hidden_dac_data;
248
    uint32_t cirrus_bank_base[2];
249
    uint32_t cirrus_bank_limit[2];
250
    uint8_t cirrus_hidden_palette[48];
251
    uint32_t hw_cursor_x;
252
    uint32_t hw_cursor_y;
253
    int cirrus_blt_pixelwidth;
254
    int cirrus_blt_width;
255
    int cirrus_blt_height;
256
    int cirrus_blt_dstpitch;
257
    int cirrus_blt_srcpitch;
258
    uint32_t cirrus_blt_fgcol;
259
    uint32_t cirrus_blt_bgcol;
260
    uint32_t cirrus_blt_dstaddr;
261
    uint32_t cirrus_blt_srcaddr;
262
    uint8_t cirrus_blt_mode;
263
    uint8_t cirrus_blt_modeext;
264
    cirrus_bitblt_rop_t cirrus_rop;
265
#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
266
    uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
267
    uint8_t *cirrus_srcptr;
268
    uint8_t *cirrus_srcptr_end;
269
    uint32_t cirrus_srccounter;
270
    /* hwcursor display state */
271
    int last_hw_cursor_size;
272
    int last_hw_cursor_x;
273
    int last_hw_cursor_y;
274
    int last_hw_cursor_y_start;
275
    int last_hw_cursor_y_end;
276
    int real_vram_size; /* XXX: suppress that */
277
    int device_id;
278
    int bustype;
279
} CirrusVGAState;
280

    
281
typedef struct PCICirrusVGAState {
282
    PCIDevice dev;
283
    CirrusVGAState cirrus_vga;
284
} PCICirrusVGAState;
285

    
286
static uint8_t rop_to_index[256];
287

    
288
/***************************************
289
 *
290
 *  prototypes.
291
 *
292
 ***************************************/
293

    
294

    
295
static void cirrus_bitblt_reset(CirrusVGAState *s);
296
static void cirrus_update_memory_access(CirrusVGAState *s);
297

    
298
/***************************************
299
 *
300
 *  raster operations
301
 *
302
 ***************************************/
303

    
304
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
305
                                  uint8_t *dst,const uint8_t *src,
306
                                  int dstpitch,int srcpitch,
307
                                  int bltwidth,int bltheight)
308
{
309
}
310

    
311
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
312
                                   uint8_t *dst,
313
                                   int dstpitch, int bltwidth,int bltheight)
314
{
315
}
316

    
317
#define ROP_NAME 0
318
#define ROP_OP(d, s) d = 0
319
#include "cirrus_vga_rop.h"
320

    
321
#define ROP_NAME src_and_dst
322
#define ROP_OP(d, s) d = (s) & (d)
323
#include "cirrus_vga_rop.h"
324

    
325
#define ROP_NAME src_and_notdst
326
#define ROP_OP(d, s) d = (s) & (~(d))
327
#include "cirrus_vga_rop.h"
328

    
329
#define ROP_NAME notdst
330
#define ROP_OP(d, s) d = ~(d)
331
#include "cirrus_vga_rop.h"
332

    
333
#define ROP_NAME src
334
#define ROP_OP(d, s) d = s
335
#include "cirrus_vga_rop.h"
336

    
337
#define ROP_NAME 1
338
#define ROP_OP(d, s) d = ~0
339
#include "cirrus_vga_rop.h"
340

    
341
#define ROP_NAME notsrc_and_dst
342
#define ROP_OP(d, s) d = (~(s)) & (d)
343
#include "cirrus_vga_rop.h"
344

    
345
#define ROP_NAME src_xor_dst
346
#define ROP_OP(d, s) d = (s) ^ (d)
347
#include "cirrus_vga_rop.h"
348

    
349
#define ROP_NAME src_or_dst
350
#define ROP_OP(d, s) d = (s) | (d)
351
#include "cirrus_vga_rop.h"
352

    
353
#define ROP_NAME notsrc_or_notdst
354
#define ROP_OP(d, s) d = (~(s)) | (~(d))
355
#include "cirrus_vga_rop.h"
356

    
357
#define ROP_NAME src_notxor_dst
358
#define ROP_OP(d, s) d = ~((s) ^ (d))
359
#include "cirrus_vga_rop.h"
360

    
361
#define ROP_NAME src_or_notdst
362
#define ROP_OP(d, s) d = (s) | (~(d))
363
#include "cirrus_vga_rop.h"
364

    
365
#define ROP_NAME notsrc
366
#define ROP_OP(d, s) d = (~(s))
367
#include "cirrus_vga_rop.h"
368

    
369
#define ROP_NAME notsrc_or_dst
370
#define ROP_OP(d, s) d = (~(s)) | (d)
371
#include "cirrus_vga_rop.h"
372

    
373
#define ROP_NAME notsrc_and_notdst
374
#define ROP_OP(d, s) d = (~(s)) & (~(d))
375
#include "cirrus_vga_rop.h"
376

    
377
static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
378
    cirrus_bitblt_rop_fwd_0,
379
    cirrus_bitblt_rop_fwd_src_and_dst,
380
    cirrus_bitblt_rop_nop,
381
    cirrus_bitblt_rop_fwd_src_and_notdst,
382
    cirrus_bitblt_rop_fwd_notdst,
383
    cirrus_bitblt_rop_fwd_src,
384
    cirrus_bitblt_rop_fwd_1,
385
    cirrus_bitblt_rop_fwd_notsrc_and_dst,
386
    cirrus_bitblt_rop_fwd_src_xor_dst,
387
    cirrus_bitblt_rop_fwd_src_or_dst,
388
    cirrus_bitblt_rop_fwd_notsrc_or_notdst,
389
    cirrus_bitblt_rop_fwd_src_notxor_dst,
390
    cirrus_bitblt_rop_fwd_src_or_notdst,
391
    cirrus_bitblt_rop_fwd_notsrc,
392
    cirrus_bitblt_rop_fwd_notsrc_or_dst,
393
    cirrus_bitblt_rop_fwd_notsrc_and_notdst,
394
};
395

    
396
static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
397
    cirrus_bitblt_rop_bkwd_0,
398
    cirrus_bitblt_rop_bkwd_src_and_dst,
399
    cirrus_bitblt_rop_nop,
400
    cirrus_bitblt_rop_bkwd_src_and_notdst,
401
    cirrus_bitblt_rop_bkwd_notdst,
402
    cirrus_bitblt_rop_bkwd_src,
403
    cirrus_bitblt_rop_bkwd_1,
404
    cirrus_bitblt_rop_bkwd_notsrc_and_dst,
405
    cirrus_bitblt_rop_bkwd_src_xor_dst,
406
    cirrus_bitblt_rop_bkwd_src_or_dst,
407
    cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
408
    cirrus_bitblt_rop_bkwd_src_notxor_dst,
409
    cirrus_bitblt_rop_bkwd_src_or_notdst,
410
    cirrus_bitblt_rop_bkwd_notsrc,
411
    cirrus_bitblt_rop_bkwd_notsrc_or_dst,
412
    cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
413
};
414

    
415
#define TRANSP_ROP(name) {\
416
    name ## _8,\
417
    name ## _16,\
418
        }
419
#define TRANSP_NOP(func) {\
420
    func,\
421
    func,\
422
        }
423

    
424
static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
425
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
426
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
427
    TRANSP_NOP(cirrus_bitblt_rop_nop),
428
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
429
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
430
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
431
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
432
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
433
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
434
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
435
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
436
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
437
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
438
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
439
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
440
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
441
};
442

    
443
static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
444
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
445
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
446
    TRANSP_NOP(cirrus_bitblt_rop_nop),
447
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
448
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
449
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
450
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
451
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
452
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
453
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
454
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
455
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
456
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
457
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
458
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
459
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
460
};
461

    
462
#define ROP2(name) {\
463
    name ## _8,\
464
    name ## _16,\
465
    name ## _24,\
466
    name ## _32,\
467
        }
468

    
469
#define ROP_NOP2(func) {\
470
    func,\
471
    func,\
472
    func,\
473
    func,\
474
        }
475

    
476
static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
477
    ROP2(cirrus_patternfill_0),
478
    ROP2(cirrus_patternfill_src_and_dst),
479
    ROP_NOP2(cirrus_bitblt_rop_nop),
480
    ROP2(cirrus_patternfill_src_and_notdst),
481
    ROP2(cirrus_patternfill_notdst),
482
    ROP2(cirrus_patternfill_src),
483
    ROP2(cirrus_patternfill_1),
484
    ROP2(cirrus_patternfill_notsrc_and_dst),
485
    ROP2(cirrus_patternfill_src_xor_dst),
486
    ROP2(cirrus_patternfill_src_or_dst),
487
    ROP2(cirrus_patternfill_notsrc_or_notdst),
488
    ROP2(cirrus_patternfill_src_notxor_dst),
489
    ROP2(cirrus_patternfill_src_or_notdst),
490
    ROP2(cirrus_patternfill_notsrc),
491
    ROP2(cirrus_patternfill_notsrc_or_dst),
492
    ROP2(cirrus_patternfill_notsrc_and_notdst),
493
};
494

    
495
static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
496
    ROP2(cirrus_colorexpand_transp_0),
497
    ROP2(cirrus_colorexpand_transp_src_and_dst),
498
    ROP_NOP2(cirrus_bitblt_rop_nop),
499
    ROP2(cirrus_colorexpand_transp_src_and_notdst),
500
    ROP2(cirrus_colorexpand_transp_notdst),
501
    ROP2(cirrus_colorexpand_transp_src),
502
    ROP2(cirrus_colorexpand_transp_1),
503
    ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
504
    ROP2(cirrus_colorexpand_transp_src_xor_dst),
505
    ROP2(cirrus_colorexpand_transp_src_or_dst),
506
    ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
507
    ROP2(cirrus_colorexpand_transp_src_notxor_dst),
508
    ROP2(cirrus_colorexpand_transp_src_or_notdst),
509
    ROP2(cirrus_colorexpand_transp_notsrc),
510
    ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
511
    ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
512
};
513

    
514
static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
515
    ROP2(cirrus_colorexpand_0),
516
    ROP2(cirrus_colorexpand_src_and_dst),
517
    ROP_NOP2(cirrus_bitblt_rop_nop),
518
    ROP2(cirrus_colorexpand_src_and_notdst),
519
    ROP2(cirrus_colorexpand_notdst),
520
    ROP2(cirrus_colorexpand_src),
521
    ROP2(cirrus_colorexpand_1),
522
    ROP2(cirrus_colorexpand_notsrc_and_dst),
523
    ROP2(cirrus_colorexpand_src_xor_dst),
524
    ROP2(cirrus_colorexpand_src_or_dst),
525
    ROP2(cirrus_colorexpand_notsrc_or_notdst),
526
    ROP2(cirrus_colorexpand_src_notxor_dst),
527
    ROP2(cirrus_colorexpand_src_or_notdst),
528
    ROP2(cirrus_colorexpand_notsrc),
529
    ROP2(cirrus_colorexpand_notsrc_or_dst),
530
    ROP2(cirrus_colorexpand_notsrc_and_notdst),
531
};
532

    
533
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
534
    ROP2(cirrus_colorexpand_pattern_transp_0),
535
    ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
536
    ROP_NOP2(cirrus_bitblt_rop_nop),
537
    ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
538
    ROP2(cirrus_colorexpand_pattern_transp_notdst),
539
    ROP2(cirrus_colorexpand_pattern_transp_src),
540
    ROP2(cirrus_colorexpand_pattern_transp_1),
541
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
542
    ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
543
    ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
544
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
545
    ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
546
    ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
547
    ROP2(cirrus_colorexpand_pattern_transp_notsrc),
548
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
549
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
550
};
551

    
552
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
553
    ROP2(cirrus_colorexpand_pattern_0),
554
    ROP2(cirrus_colorexpand_pattern_src_and_dst),
555
    ROP_NOP2(cirrus_bitblt_rop_nop),
556
    ROP2(cirrus_colorexpand_pattern_src_and_notdst),
557
    ROP2(cirrus_colorexpand_pattern_notdst),
558
    ROP2(cirrus_colorexpand_pattern_src),
559
    ROP2(cirrus_colorexpand_pattern_1),
560
    ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
561
    ROP2(cirrus_colorexpand_pattern_src_xor_dst),
562
    ROP2(cirrus_colorexpand_pattern_src_or_dst),
563
    ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
564
    ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
565
    ROP2(cirrus_colorexpand_pattern_src_or_notdst),
566
    ROP2(cirrus_colorexpand_pattern_notsrc),
567
    ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
568
    ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
569
};
570

    
571
static const cirrus_fill_t cirrus_fill[16][4] = {
572
    ROP2(cirrus_fill_0),
573
    ROP2(cirrus_fill_src_and_dst),
574
    ROP_NOP2(cirrus_bitblt_fill_nop),
575
    ROP2(cirrus_fill_src_and_notdst),
576
    ROP2(cirrus_fill_notdst),
577
    ROP2(cirrus_fill_src),
578
    ROP2(cirrus_fill_1),
579
    ROP2(cirrus_fill_notsrc_and_dst),
580
    ROP2(cirrus_fill_src_xor_dst),
581
    ROP2(cirrus_fill_src_or_dst),
582
    ROP2(cirrus_fill_notsrc_or_notdst),
583
    ROP2(cirrus_fill_src_notxor_dst),
584
    ROP2(cirrus_fill_src_or_notdst),
585
    ROP2(cirrus_fill_notsrc),
586
    ROP2(cirrus_fill_notsrc_or_dst),
587
    ROP2(cirrus_fill_notsrc_and_notdst),
588
};
589

    
590
static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
591
{
592
    unsigned int color;
593
    switch (s->cirrus_blt_pixelwidth) {
594
    case 1:
595
        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
596
        break;
597
    case 2:
598
        color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
599
        s->cirrus_blt_fgcol = le16_to_cpu(color);
600
        break;
601
    case 3:
602
        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
603
            (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
604
        break;
605
    default:
606
    case 4:
607
        color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
608
            (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
609
        s->cirrus_blt_fgcol = le32_to_cpu(color);
610
        break;
611
    }
612
}
613

    
614
static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
615
{
616
    unsigned int color;
617
    switch (s->cirrus_blt_pixelwidth) {
618
    case 1:
619
        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
620
        break;
621
    case 2:
622
        color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
623
        s->cirrus_blt_bgcol = le16_to_cpu(color);
624
        break;
625
    case 3:
626
        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
627
            (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
628
        break;
629
    default:
630
    case 4:
631
        color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
632
            (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
633
        s->cirrus_blt_bgcol = le32_to_cpu(color);
634
        break;
635
    }
636
}
637

    
638
static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
639
                                     int off_pitch, int bytesperline,
640
                                     int lines)
641
{
642
    int y;
643
    int off_cur;
644
    int off_cur_end;
645

    
646
    for (y = 0; y < lines; y++) {
647
        off_cur = off_begin;
648
        off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
649
        off_cur &= TARGET_PAGE_MASK;
650
        while (off_cur < off_cur_end) {
651
            cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
652
            off_cur += TARGET_PAGE_SIZE;
653
        }
654
        off_begin += off_pitch;
655
    }
656
}
657

    
658
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
659
                                            const uint8_t * src)
660
{
661
    uint8_t *dst;
662

    
663
    dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
664

    
665
    if (BLTUNSAFE(s))
666
        return 0;
667

    
668
    (*s->cirrus_rop) (s, dst, src,
669
                      s->cirrus_blt_dstpitch, 0,
670
                      s->cirrus_blt_width, s->cirrus_blt_height);
671
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
672
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
673
                             s->cirrus_blt_height);
674
    return 1;
675
}
676

    
677
/* fill */
678

    
679
static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
680
{
681
    cirrus_fill_t rop_func;
682

    
683
    if (BLTUNSAFE(s))
684
        return 0;
685
    rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
686
    rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
687
             s->cirrus_blt_dstpitch,
688
             s->cirrus_blt_width, s->cirrus_blt_height);
689
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
690
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
691
                             s->cirrus_blt_height);
692
    cirrus_bitblt_reset(s);
693
    return 1;
694
}
695

    
696
/***************************************
697
 *
698
 *  bitblt (video-to-video)
699
 *
700
 ***************************************/
701

    
702
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
703
{
704
    return cirrus_bitblt_common_patterncopy(s,
705
                                            s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
706
                                            s->cirrus_addr_mask));
707
}
708

    
709
static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
710
{
711
    int sx, sy;
712
    int dx, dy;
713
    int width, height;
714
    int depth;
715
    int notify = 0;
716

    
717
    depth = s->vga.get_bpp(&s->vga) / 8;
718
    s->vga.get_resolution(&s->vga, &width, &height);
719

    
720
    /* extra x, y */
721
    sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
722
    sy = (src / ABS(s->cirrus_blt_srcpitch));
723
    dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
724
    dy = (dst / ABS(s->cirrus_blt_dstpitch));
725

    
726
    /* normalize width */
727
    w /= depth;
728

    
729
    /* if we're doing a backward copy, we have to adjust
730
       our x/y to be the upper left corner (instead of the lower
731
       right corner) */
732
    if (s->cirrus_blt_dstpitch < 0) {
733
        sx -= (s->cirrus_blt_width / depth) - 1;
734
        dx -= (s->cirrus_blt_width / depth) - 1;
735
        sy -= s->cirrus_blt_height - 1;
736
        dy -= s->cirrus_blt_height - 1;
737
    }
738

    
739
    /* are we in the visible portion of memory? */
740
    if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
741
        (sx + w) <= width && (sy + h) <= height &&
742
        (dx + w) <= width && (dy + h) <= height) {
743
        notify = 1;
744
    }
745

    
746
    /* make to sure only copy if it's a plain copy ROP */
747
    if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&
748
        *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)
749
        notify = 0;
750

    
751
    /* we have to flush all pending changes so that the copy
752
       is generated at the appropriate moment in time */
753
    if (notify)
754
        vga_hw_update();
755

    
756
    (*s->cirrus_rop) (s, s->vga.vram_ptr +
757
                      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
758
                      s->vga.vram_ptr +
759
                      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
760
                      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
761
                      s->cirrus_blt_width, s->cirrus_blt_height);
762

    
763
    if (notify)
764
        qemu_console_copy(s->vga.ds,
765
                          sx, sy, dx, dy,
766
                          s->cirrus_blt_width / depth,
767
                          s->cirrus_blt_height);
768

    
769
    /* we don't have to notify the display that this portion has
770
       changed since qemu_console_copy implies this */
771

    
772
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
773
                                s->cirrus_blt_dstpitch, s->cirrus_blt_width,
774
                                s->cirrus_blt_height);
775
}
776

    
777
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
778
{
779
    if (BLTUNSAFE(s))
780
        return 0;
781

    
782
    cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
783
            s->cirrus_blt_srcaddr - s->vga.start_addr,
784
            s->cirrus_blt_width, s->cirrus_blt_height);
785

    
786
    return 1;
787
}
788

    
789
/***************************************
790
 *
791
 *  bitblt (cpu-to-video)
792
 *
793
 ***************************************/
794

    
795
static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
796
{
797
    int copy_count;
798
    uint8_t *end_ptr;
799

    
800
    if (s->cirrus_srccounter > 0) {
801
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
802
            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
803
        the_end:
804
            s->cirrus_srccounter = 0;
805
            cirrus_bitblt_reset(s);
806
        } else {
807
            /* at least one scan line */
808
            do {
809
                (*s->cirrus_rop)(s, s->vga.vram_ptr +
810
                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
811
                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
812
                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
813
                                         s->cirrus_blt_width, 1);
814
                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
815
                s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
816
                if (s->cirrus_srccounter <= 0)
817
                    goto the_end;
818
                /* more bytes than needed can be transfered because of
819
                   word alignment, so we keep them for the next line */
820
                /* XXX: keep alignment to speed up transfer */
821
                end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
822
                copy_count = s->cirrus_srcptr_end - end_ptr;
823
                memmove(s->cirrus_bltbuf, end_ptr, copy_count);
824
                s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
825
                s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
826
            } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
827
        }
828
    }
829
}
830

    
831
/***************************************
832
 *
833
 *  bitblt wrapper
834
 *
835
 ***************************************/
836

    
837
static void cirrus_bitblt_reset(CirrusVGAState * s)
838
{
839
    int need_update;
840

    
841
    s->vga.gr[0x31] &=
842
        ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
843
    need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
844
        || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
845
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
846
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
847
    s->cirrus_srccounter = 0;
848
    if (!need_update)
849
        return;
850
    cirrus_update_memory_access(s);
851
}
852

    
853
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
854
{
855
    int w;
856

    
857
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
858
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
859
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
860

    
861
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
862
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
863
            s->cirrus_blt_srcpitch = 8;
864
        } else {
865
            /* XXX: check for 24 bpp */
866
            s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
867
        }
868
        s->cirrus_srccounter = s->cirrus_blt_srcpitch;
869
    } else {
870
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
871
            w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
872
            if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
873
                s->cirrus_blt_srcpitch = ((w + 31) >> 5);
874
            else
875
                s->cirrus_blt_srcpitch = ((w + 7) >> 3);
876
        } else {
877
            /* always align input size to 32 bits */
878
            s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
879
        }
880
        s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
881
    }
882
    s->cirrus_srcptr = s->cirrus_bltbuf;
883
    s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
884
    cirrus_update_memory_access(s);
885
    return 1;
886
}
887

    
888
static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
889
{
890
    /* XXX */
891
#ifdef DEBUG_BITBLT
892
    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
893
#endif
894
    return 0;
895
}
896

    
897
static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
898
{
899
    int ret;
900

    
901
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
902
        ret = cirrus_bitblt_videotovideo_patterncopy(s);
903
    } else {
904
        ret = cirrus_bitblt_videotovideo_copy(s);
905
    }
906
    if (ret)
907
        cirrus_bitblt_reset(s);
908
    return ret;
909
}
910

    
911
static void cirrus_bitblt_start(CirrusVGAState * s)
912
{
913
    uint8_t blt_rop;
914

    
915
    s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
916

    
917
    s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
918
    s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
919
    s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
920
    s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
921
    s->cirrus_blt_dstaddr =
922
        (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
923
    s->cirrus_blt_srcaddr =
924
        (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
925
    s->cirrus_blt_mode = s->vga.gr[0x30];
926
    s->cirrus_blt_modeext = s->vga.gr[0x33];
927
    blt_rop = s->vga.gr[0x32];
928

    
929
#ifdef DEBUG_BITBLT
930
    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",
931
           blt_rop,
932
           s->cirrus_blt_mode,
933
           s->cirrus_blt_modeext,
934
           s->cirrus_blt_width,
935
           s->cirrus_blt_height,
936
           s->cirrus_blt_dstpitch,
937
           s->cirrus_blt_srcpitch,
938
           s->cirrus_blt_dstaddr,
939
           s->cirrus_blt_srcaddr,
940
           s->vga.gr[0x2f]);
941
#endif
942

    
943
    switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
944
    case CIRRUS_BLTMODE_PIXELWIDTH8:
945
        s->cirrus_blt_pixelwidth = 1;
946
        break;
947
    case CIRRUS_BLTMODE_PIXELWIDTH16:
948
        s->cirrus_blt_pixelwidth = 2;
949
        break;
950
    case CIRRUS_BLTMODE_PIXELWIDTH24:
951
        s->cirrus_blt_pixelwidth = 3;
952
        break;
953
    case CIRRUS_BLTMODE_PIXELWIDTH32:
954
        s->cirrus_blt_pixelwidth = 4;
955
        break;
956
    default:
957
#ifdef DEBUG_BITBLT
958
        printf("cirrus: bitblt - pixel width is unknown\n");
959
#endif
960
        goto bitblt_ignore;
961
    }
962
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
963

    
964
    if ((s->
965
         cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
966
                            CIRRUS_BLTMODE_MEMSYSDEST))
967
        == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
968
#ifdef DEBUG_BITBLT
969
        printf("cirrus: bitblt - memory-to-memory copy is requested\n");
970
#endif
971
        goto bitblt_ignore;
972
    }
973

    
974
    if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
975
        (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
976
                               CIRRUS_BLTMODE_TRANSPARENTCOMP |
977
                               CIRRUS_BLTMODE_PATTERNCOPY |
978
                               CIRRUS_BLTMODE_COLOREXPAND)) ==
979
         (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
980
        cirrus_bitblt_fgcol(s);
981
        cirrus_bitblt_solidfill(s, blt_rop);
982
    } else {
983
        if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
984
                                   CIRRUS_BLTMODE_PATTERNCOPY)) ==
985
            CIRRUS_BLTMODE_COLOREXPAND) {
986

    
987
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
988
                if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
989
                    cirrus_bitblt_bgcol(s);
990
                else
991
                    cirrus_bitblt_fgcol(s);
992
                s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
993
            } else {
994
                cirrus_bitblt_fgcol(s);
995
                cirrus_bitblt_bgcol(s);
996
                s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
997
            }
998
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
999
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
1000
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
1001
                    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
1002
                        cirrus_bitblt_bgcol(s);
1003
                    else
1004
                        cirrus_bitblt_fgcol(s);
1005
                    s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1006
                } else {
1007
                    cirrus_bitblt_fgcol(s);
1008
                    cirrus_bitblt_bgcol(s);
1009
                    s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1010
                }
1011
            } else {
1012
                s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1013
            }
1014
        } else {
1015
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
1016
                if (s->cirrus_blt_pixelwidth > 2) {
1017
                    printf("src transparent without colorexpand must be 8bpp or 16bpp\n");
1018
                    goto bitblt_ignore;
1019
                }
1020
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
1021
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
1022
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
1023
                    s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1024
                } else {
1025
                    s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1026
                }
1027
            } else {
1028
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
1029
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
1030
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
1031
                    s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
1032
                } else {
1033
                    s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
1034
                }
1035
            }
1036
        }
1037
        // setup bitblt engine.
1038
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
1039
            if (!cirrus_bitblt_cputovideo(s))
1040
                goto bitblt_ignore;
1041
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
1042
            if (!cirrus_bitblt_videotocpu(s))
1043
                goto bitblt_ignore;
1044
        } else {
1045
            if (!cirrus_bitblt_videotovideo(s))
1046
                goto bitblt_ignore;
1047
        }
1048
    }
1049
    return;
1050
  bitblt_ignore:;
1051
    cirrus_bitblt_reset(s);
1052
}
1053

    
1054
static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1055
{
1056
    unsigned old_value;
1057

    
1058
    old_value = s->vga.gr[0x31];
1059
    s->vga.gr[0x31] = reg_value;
1060

    
1061
    if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1062
        ((reg_value & CIRRUS_BLT_RESET) == 0)) {
1063
        cirrus_bitblt_reset(s);
1064
    } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1065
               ((reg_value & CIRRUS_BLT_START) != 0)) {
1066
        cirrus_bitblt_start(s);
1067
    }
1068
}
1069

    
1070

    
1071
/***************************************
1072
 *
1073
 *  basic parameters
1074
 *
1075
 ***************************************/
1076

    
1077
static void cirrus_get_offsets(VGACommonState *s1,
1078
                               uint32_t *pline_offset,
1079
                               uint32_t *pstart_addr,
1080
                               uint32_t *pline_compare)
1081
{
1082
    CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1083
    uint32_t start_addr, line_offset, line_compare;
1084

    
1085
    line_offset = s->vga.cr[0x13]
1086
        | ((s->vga.cr[0x1b] & 0x10) << 4);
1087
    line_offset <<= 3;
1088
    *pline_offset = line_offset;
1089

    
1090
    start_addr = (s->vga.cr[0x0c] << 8)
1091
        | s->vga.cr[0x0d]
1092
        | ((s->vga.cr[0x1b] & 0x01) << 16)
1093
        | ((s->vga.cr[0x1b] & 0x0c) << 15)
1094
        | ((s->vga.cr[0x1d] & 0x80) << 12);
1095
    *pstart_addr = start_addr;
1096

    
1097
    line_compare = s->vga.cr[0x18] |
1098
        ((s->vga.cr[0x07] & 0x10) << 4) |
1099
        ((s->vga.cr[0x09] & 0x40) << 3);
1100
    *pline_compare = line_compare;
1101
}
1102

    
1103
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1104
{
1105
    uint32_t ret = 16;
1106

    
1107
    switch (s->cirrus_hidden_dac_data & 0xf) {
1108
    case 0:
1109
        ret = 15;
1110
        break;                        /* Sierra HiColor */
1111
    case 1:
1112
        ret = 16;
1113
        break;                        /* XGA HiColor */
1114
    default:
1115
#ifdef DEBUG_CIRRUS
1116
        printf("cirrus: invalid DAC value %x in 16bpp\n",
1117
               (s->cirrus_hidden_dac_data & 0xf));
1118
#endif
1119
        ret = 15;                /* XXX */
1120
        break;
1121
    }
1122
    return ret;
1123
}
1124

    
1125
static int cirrus_get_bpp(VGACommonState *s1)
1126
{
1127
    CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1128
    uint32_t ret = 8;
1129

    
1130
    if ((s->vga.sr[0x07] & 0x01) != 0) {
1131
        /* Cirrus SVGA */
1132
        switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1133
        case CIRRUS_SR7_BPP_8:
1134
            ret = 8;
1135
            break;
1136
        case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1137
            ret = cirrus_get_bpp16_depth(s);
1138
            break;
1139
        case CIRRUS_SR7_BPP_24:
1140
            ret = 24;
1141
            break;
1142
        case CIRRUS_SR7_BPP_16:
1143
            ret = cirrus_get_bpp16_depth(s);
1144
            break;
1145
        case CIRRUS_SR7_BPP_32:
1146
            ret = 32;
1147
            break;
1148
        default:
1149
#ifdef DEBUG_CIRRUS
1150
            printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
1151
#endif
1152
            ret = 8;
1153
            break;
1154
        }
1155
    } else {
1156
        /* VGA */
1157
        ret = 0;
1158
    }
1159

    
1160
    return ret;
1161
}
1162

    
1163
static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1164
{
1165
    int width, height;
1166

    
1167
    width = (s->cr[0x01] + 1) * 8;
1168
    height = s->cr[0x12] |
1169
        ((s->cr[0x07] & 0x02) << 7) |
1170
        ((s->cr[0x07] & 0x40) << 3);
1171
    height = (height + 1);
1172
    /* interlace support */
1173
    if (s->cr[0x1a] & 0x01)
1174
        height = height * 2;
1175
    *pwidth = width;
1176
    *pheight = height;
1177
}
1178

    
1179
/***************************************
1180
 *
1181
 * bank memory
1182
 *
1183
 ***************************************/
1184

    
1185
static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1186
{
1187
    unsigned offset;
1188
    unsigned limit;
1189

    
1190
    if ((s->vga.gr[0x0b] & 0x01) != 0)        /* dual bank */
1191
        offset = s->vga.gr[0x09 + bank_index];
1192
    else                        /* single bank */
1193
        offset = s->vga.gr[0x09];
1194

    
1195
    if ((s->vga.gr[0x0b] & 0x20) != 0)
1196
        offset <<= 14;
1197
    else
1198
        offset <<= 12;
1199

    
1200
    if (s->real_vram_size <= offset)
1201
        limit = 0;
1202
    else
1203
        limit = s->real_vram_size - offset;
1204

    
1205
    if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1206
        if (limit > 0x8000) {
1207
            offset += 0x8000;
1208
            limit -= 0x8000;
1209
        } else {
1210
            limit = 0;
1211
        }
1212
    }
1213

    
1214
    if (limit > 0) {
1215
        /* Thinking about changing bank base? First, drop the dirty bitmap information
1216
         * on the current location, otherwise we lose this pointer forever */
1217
        if (s->vga.lfb_vram_mapped) {
1218
            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
1219
            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
1220
        }
1221
        s->cirrus_bank_base[bank_index] = offset;
1222
        s->cirrus_bank_limit[bank_index] = limit;
1223
    } else {
1224
        s->cirrus_bank_base[bank_index] = 0;
1225
        s->cirrus_bank_limit[bank_index] = 0;
1226
    }
1227
}
1228

    
1229
/***************************************
1230
 *
1231
 *  I/O access between 0x3c4-0x3c5
1232
 *
1233
 ***************************************/
1234

    
1235
static int cirrus_vga_read_sr(CirrusVGAState * s)
1236
{
1237
    switch (s->vga.sr_index) {
1238
    case 0x00:                        // Standard VGA
1239
    case 0x01:                        // Standard VGA
1240
    case 0x02:                        // Standard VGA
1241
    case 0x03:                        // Standard VGA
1242
    case 0x04:                        // Standard VGA
1243
        return s->vga.sr[s->vga.sr_index];
1244
    case 0x06:                        // Unlock Cirrus extensions
1245
        return s->vga.sr[s->vga.sr_index];
1246
    case 0x10:
1247
    case 0x30:
1248
    case 0x50:
1249
    case 0x70:                        // Graphics Cursor X
1250
    case 0x90:
1251
    case 0xb0:
1252
    case 0xd0:
1253
    case 0xf0:                        // Graphics Cursor X
1254
        return s->vga.sr[0x10];
1255
    case 0x11:
1256
    case 0x31:
1257
    case 0x51:
1258
    case 0x71:                        // Graphics Cursor Y
1259
    case 0x91:
1260
    case 0xb1:
1261
    case 0xd1:
1262
    case 0xf1:                        // Graphics Cursor Y
1263
        return s->vga.sr[0x11];
1264
    case 0x05:                        // ???
1265
    case 0x07:                        // Extended Sequencer Mode
1266
    case 0x08:                        // EEPROM Control
1267
    case 0x09:                        // Scratch Register 0
1268
    case 0x0a:                        // Scratch Register 1
1269
    case 0x0b:                        // VCLK 0
1270
    case 0x0c:                        // VCLK 1
1271
    case 0x0d:                        // VCLK 2
1272
    case 0x0e:                        // VCLK 3
1273
    case 0x0f:                        // DRAM Control
1274
    case 0x12:                        // Graphics Cursor Attribute
1275
    case 0x13:                        // Graphics Cursor Pattern Address
1276
    case 0x14:                        // Scratch Register 2
1277
    case 0x15:                        // Scratch Register 3
1278
    case 0x16:                        // Performance Tuning Register
1279
    case 0x17:                        // Configuration Readback and Extended Control
1280
    case 0x18:                        // Signature Generator Control
1281
    case 0x19:                        // Signal Generator Result
1282
    case 0x1a:                        // Signal Generator Result
1283
    case 0x1b:                        // VCLK 0 Denominator & Post
1284
    case 0x1c:                        // VCLK 1 Denominator & Post
1285
    case 0x1d:                        // VCLK 2 Denominator & Post
1286
    case 0x1e:                        // VCLK 3 Denominator & Post
1287
    case 0x1f:                        // BIOS Write Enable and MCLK select
1288
#ifdef DEBUG_CIRRUS
1289
        printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
1290
#endif
1291
        return s->vga.sr[s->vga.sr_index];
1292
    default:
1293
#ifdef DEBUG_CIRRUS
1294
        printf("cirrus: inport sr_index %02x\n", s->vga.sr_index);
1295
#endif
1296
        return 0xff;
1297
        break;
1298
    }
1299
}
1300

    
1301
static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
1302
{
1303
    switch (s->vga.sr_index) {
1304
    case 0x00:                        // Standard VGA
1305
    case 0x01:                        // Standard VGA
1306
    case 0x02:                        // Standard VGA
1307
    case 0x03:                        // Standard VGA
1308
    case 0x04:                        // Standard VGA
1309
        s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
1310
        if (s->vga.sr_index == 1)
1311
            s->vga.update_retrace_info(&s->vga);
1312
        break;
1313
    case 0x06:                        // Unlock Cirrus extensions
1314
        val &= 0x17;
1315
        if (val == 0x12) {
1316
            s->vga.sr[s->vga.sr_index] = 0x12;
1317
        } else {
1318
            s->vga.sr[s->vga.sr_index] = 0x0f;
1319
        }
1320
        break;
1321
    case 0x10:
1322
    case 0x30:
1323
    case 0x50:
1324
    case 0x70:                        // Graphics Cursor X
1325
    case 0x90:
1326
    case 0xb0:
1327
    case 0xd0:
1328
    case 0xf0:                        // Graphics Cursor X
1329
        s->vga.sr[0x10] = val;
1330
        s->hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
1331
        break;
1332
    case 0x11:
1333
    case 0x31:
1334
    case 0x51:
1335
    case 0x71:                        // Graphics Cursor Y
1336
    case 0x91:
1337
    case 0xb1:
1338
    case 0xd1:
1339
    case 0xf1:                        // Graphics Cursor Y
1340
        s->vga.sr[0x11] = val;
1341
        s->hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
1342
        break;
1343
    case 0x07:                        // Extended Sequencer Mode
1344
    cirrus_update_memory_access(s);
1345
    case 0x08:                        // EEPROM Control
1346
    case 0x09:                        // Scratch Register 0
1347
    case 0x0a:                        // Scratch Register 1
1348
    case 0x0b:                        // VCLK 0
1349
    case 0x0c:                        // VCLK 1
1350
    case 0x0d:                        // VCLK 2
1351
    case 0x0e:                        // VCLK 3
1352
    case 0x0f:                        // DRAM Control
1353
    case 0x12:                        // Graphics Cursor Attribute
1354
    case 0x13:                        // Graphics Cursor Pattern Address
1355
    case 0x14:                        // Scratch Register 2
1356
    case 0x15:                        // Scratch Register 3
1357
    case 0x16:                        // Performance Tuning Register
1358
    case 0x18:                        // Signature Generator Control
1359
    case 0x19:                        // Signature Generator Result
1360
    case 0x1a:                        // Signature Generator Result
1361
    case 0x1b:                        // VCLK 0 Denominator & Post
1362
    case 0x1c:                        // VCLK 1 Denominator & Post
1363
    case 0x1d:                        // VCLK 2 Denominator & Post
1364
    case 0x1e:                        // VCLK 3 Denominator & Post
1365
    case 0x1f:                        // BIOS Write Enable and MCLK select
1366
        s->vga.sr[s->vga.sr_index] = val;
1367
#ifdef DEBUG_CIRRUS
1368
        printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
1369
               s->vga.sr_index, val);
1370
#endif
1371
        break;
1372
    case 0x17:                        // Configuration Readback and Extended Control
1373
        s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
1374
                                   | (val & 0xc7);
1375
        cirrus_update_memory_access(s);
1376
        break;
1377
    default:
1378
#ifdef DEBUG_CIRRUS
1379
        printf("cirrus: outport sr_index %02x, sr_value %02x\n",
1380
               s->vga.sr_index, val);
1381
#endif
1382
        break;
1383
    }
1384
}
1385

    
1386
/***************************************
1387
 *
1388
 *  I/O access at 0x3c6
1389
 *
1390
 ***************************************/
1391

    
1392
static int cirrus_read_hidden_dac(CirrusVGAState * s)
1393
{
1394
    if (++s->cirrus_hidden_dac_lockindex == 5) {
1395
        s->cirrus_hidden_dac_lockindex = 0;
1396
        return s->cirrus_hidden_dac_data;
1397
    }
1398
    return 0xff;
1399
}
1400

    
1401
static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1402
{
1403
    if (s->cirrus_hidden_dac_lockindex == 4) {
1404
        s->cirrus_hidden_dac_data = reg_value;
1405
#if defined(DEBUG_CIRRUS)
1406
        printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1407
#endif
1408
    }
1409
    s->cirrus_hidden_dac_lockindex = 0;
1410
}
1411

    
1412
/***************************************
1413
 *
1414
 *  I/O access at 0x3c9
1415
 *
1416
 ***************************************/
1417

    
1418
static int cirrus_vga_read_palette(CirrusVGAState * s)
1419
{
1420
    int val;
1421

    
1422
    if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1423
        val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
1424
                                       s->vga.dac_sub_index];
1425
    } else {
1426
        val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
1427
    }
1428
    if (++s->vga.dac_sub_index == 3) {
1429
        s->vga.dac_sub_index = 0;
1430
        s->vga.dac_read_index++;
1431
    }
1432
    return val;
1433
}
1434

    
1435
static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
1436
{
1437
    s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
1438
    if (++s->vga.dac_sub_index == 3) {
1439
        if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1440
            memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
1441
                   s->vga.dac_cache, 3);
1442
        } else {
1443
            memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
1444
        }
1445
        /* XXX update cursor */
1446
        s->vga.dac_sub_index = 0;
1447
        s->vga.dac_write_index++;
1448
    }
1449
}
1450

    
1451
/***************************************
1452
 *
1453
 *  I/O access between 0x3ce-0x3cf
1454
 *
1455
 ***************************************/
1456

    
1457
static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
1458
{
1459
    switch (reg_index) {
1460
    case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1461
        return s->cirrus_shadow_gr0;
1462
    case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1463
        return s->cirrus_shadow_gr1;
1464
    case 0x02:                        // Standard VGA
1465
    case 0x03:                        // Standard VGA
1466
    case 0x04:                        // Standard VGA
1467
    case 0x06:                        // Standard VGA
1468
    case 0x07:                        // Standard VGA
1469
    case 0x08:                        // Standard VGA
1470
        return s->vga.gr[s->vga.gr_index];
1471
    case 0x05:                        // Standard VGA, Cirrus extended mode
1472
    default:
1473
        break;
1474
    }
1475

    
1476
    if (reg_index < 0x3a) {
1477
        return s->vga.gr[reg_index];
1478
    } else {
1479
#ifdef DEBUG_CIRRUS
1480
        printf("cirrus: inport gr_index %02x\n", reg_index);
1481
#endif
1482
        return 0xff;
1483
    }
1484
}
1485

    
1486
static void
1487
cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1488
{
1489
#if defined(DEBUG_BITBLT) && 0
1490
    printf("gr%02x: %02x\n", reg_index, reg_value);
1491
#endif
1492
    switch (reg_index) {
1493
    case 0x00:                        // Standard VGA, BGCOLOR 0x000000ff
1494
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1495
        s->cirrus_shadow_gr0 = reg_value;
1496
        break;
1497
    case 0x01:                        // Standard VGA, FGCOLOR 0x000000ff
1498
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1499
        s->cirrus_shadow_gr1 = reg_value;
1500
        break;
1501
    case 0x02:                        // Standard VGA
1502
    case 0x03:                        // Standard VGA
1503
    case 0x04:                        // Standard VGA
1504
    case 0x06:                        // Standard VGA
1505
    case 0x07:                        // Standard VGA
1506
    case 0x08:                        // Standard VGA
1507
        s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1508
        break;
1509
    case 0x05:                        // Standard VGA, Cirrus extended mode
1510
        s->vga.gr[reg_index] = reg_value & 0x7f;
1511
        cirrus_update_memory_access(s);
1512
        break;
1513
    case 0x09:                        // bank offset #0
1514
    case 0x0A:                        // bank offset #1
1515
        s->vga.gr[reg_index] = reg_value;
1516
        cirrus_update_bank_ptr(s, 0);
1517
        cirrus_update_bank_ptr(s, 1);
1518
        cirrus_update_memory_access(s);
1519
        break;
1520
    case 0x0B:
1521
        s->vga.gr[reg_index] = reg_value;
1522
        cirrus_update_bank_ptr(s, 0);
1523
        cirrus_update_bank_ptr(s, 1);
1524
        cirrus_update_memory_access(s);
1525
        break;
1526
    case 0x10:                        // BGCOLOR 0x0000ff00
1527
    case 0x11:                        // FGCOLOR 0x0000ff00
1528
    case 0x12:                        // BGCOLOR 0x00ff0000
1529
    case 0x13:                        // FGCOLOR 0x00ff0000
1530
    case 0x14:                        // BGCOLOR 0xff000000
1531
    case 0x15:                        // FGCOLOR 0xff000000
1532
    case 0x20:                        // BLT WIDTH 0x0000ff
1533
    case 0x22:                        // BLT HEIGHT 0x0000ff
1534
    case 0x24:                        // BLT DEST PITCH 0x0000ff
1535
    case 0x26:                        // BLT SRC PITCH 0x0000ff
1536
    case 0x28:                        // BLT DEST ADDR 0x0000ff
1537
    case 0x29:                        // BLT DEST ADDR 0x00ff00
1538
    case 0x2c:                        // BLT SRC ADDR 0x0000ff
1539
    case 0x2d:                        // BLT SRC ADDR 0x00ff00
1540
    case 0x2f:                  // BLT WRITEMASK
1541
    case 0x30:                        // BLT MODE
1542
    case 0x32:                        // RASTER OP
1543
    case 0x33:                        // BLT MODEEXT
1544
    case 0x34:                        // BLT TRANSPARENT COLOR 0x00ff
1545
    case 0x35:                        // BLT TRANSPARENT COLOR 0xff00
1546
    case 0x38:                        // BLT TRANSPARENT COLOR MASK 0x00ff
1547
    case 0x39:                        // BLT TRANSPARENT COLOR MASK 0xff00
1548
        s->vga.gr[reg_index] = reg_value;
1549
        break;
1550
    case 0x21:                        // BLT WIDTH 0x001f00
1551
    case 0x23:                        // BLT HEIGHT 0x001f00
1552
    case 0x25:                        // BLT DEST PITCH 0x001f00
1553
    case 0x27:                        // BLT SRC PITCH 0x001f00
1554
        s->vga.gr[reg_index] = reg_value & 0x1f;
1555
        break;
1556
    case 0x2a:                        // BLT DEST ADDR 0x3f0000
1557
        s->vga.gr[reg_index] = reg_value & 0x3f;
1558
        /* if auto start mode, starts bit blt now */
1559
        if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
1560
            cirrus_bitblt_start(s);
1561
        }
1562
        break;
1563
    case 0x2e:                        // BLT SRC ADDR 0x3f0000
1564
        s->vga.gr[reg_index] = reg_value & 0x3f;
1565
        break;
1566
    case 0x31:                        // BLT STATUS/START
1567
        cirrus_write_bitblt(s, reg_value);
1568
        break;
1569
    default:
1570
#ifdef DEBUG_CIRRUS
1571
        printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
1572
               reg_value);
1573
#endif
1574
        break;
1575
    }
1576
}
1577

    
1578
/***************************************
1579
 *
1580
 *  I/O access between 0x3d4-0x3d5
1581
 *
1582
 ***************************************/
1583

    
1584
static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
1585
{
1586
    switch (reg_index) {
1587
    case 0x00:                        // Standard VGA
1588
    case 0x01:                        // Standard VGA
1589
    case 0x02:                        // Standard VGA
1590
    case 0x03:                        // Standard VGA
1591
    case 0x04:                        // Standard VGA
1592
    case 0x05:                        // Standard VGA
1593
    case 0x06:                        // Standard VGA
1594
    case 0x07:                        // Standard VGA
1595
    case 0x08:                        // Standard VGA
1596
    case 0x09:                        // Standard VGA
1597
    case 0x0a:                        // Standard VGA
1598
    case 0x0b:                        // Standard VGA
1599
    case 0x0c:                        // Standard VGA
1600
    case 0x0d:                        // Standard VGA
1601
    case 0x0e:                        // Standard VGA
1602
    case 0x0f:                        // Standard VGA
1603
    case 0x10:                        // Standard VGA
1604
    case 0x11:                        // Standard VGA
1605
    case 0x12:                        // Standard VGA
1606
    case 0x13:                        // Standard VGA
1607
    case 0x14:                        // Standard VGA
1608
    case 0x15:                        // Standard VGA
1609
    case 0x16:                        // Standard VGA
1610
    case 0x17:                        // Standard VGA
1611
    case 0x18:                        // Standard VGA
1612
        return s->vga.cr[s->vga.cr_index];
1613
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1614
        return (s->vga.ar_flip_flop << 7);
1615
    case 0x19:                        // Interlace End
1616
    case 0x1a:                        // Miscellaneous Control
1617
    case 0x1b:                        // Extended Display Control
1618
    case 0x1c:                        // Sync Adjust and Genlock
1619
    case 0x1d:                        // Overlay Extended Control
1620
    case 0x22:                        // Graphics Data Latches Readback (R)
1621
    case 0x25:                        // Part Status
1622
    case 0x27:                        // Part ID (R)
1623
        return s->vga.cr[s->vga.cr_index];
1624
    case 0x26:                        // Attribute Controller Index Readback (R)
1625
        return s->vga.ar_index & 0x3f;
1626
        break;
1627
    default:
1628
#ifdef DEBUG_CIRRUS
1629
        printf("cirrus: inport cr_index %02x\n", reg_index);
1630
#endif
1631
        return 0xff;
1632
    }
1633
}
1634

    
1635
static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
1636
{
1637
    switch (s->vga.cr_index) {
1638
    case 0x00:                        // Standard VGA
1639
    case 0x01:                        // Standard VGA
1640
    case 0x02:                        // Standard VGA
1641
    case 0x03:                        // Standard VGA
1642
    case 0x04:                        // Standard VGA
1643
    case 0x05:                        // Standard VGA
1644
    case 0x06:                        // Standard VGA
1645
    case 0x07:                        // Standard VGA
1646
    case 0x08:                        // Standard VGA
1647
    case 0x09:                        // Standard VGA
1648
    case 0x0a:                        // Standard VGA
1649
    case 0x0b:                        // Standard VGA
1650
    case 0x0c:                        // Standard VGA
1651
    case 0x0d:                        // Standard VGA
1652
    case 0x0e:                        // Standard VGA
1653
    case 0x0f:                        // Standard VGA
1654
    case 0x10:                        // Standard VGA
1655
    case 0x11:                        // Standard VGA
1656
    case 0x12:                        // Standard VGA
1657
    case 0x13:                        // Standard VGA
1658
    case 0x14:                        // Standard VGA
1659
    case 0x15:                        // Standard VGA
1660
    case 0x16:                        // Standard VGA
1661
    case 0x17:                        // Standard VGA
1662
    case 0x18:                        // Standard VGA
1663
        /* handle CR0-7 protection */
1664
        if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
1665
            /* can always write bit 4 of CR7 */
1666
            if (s->vga.cr_index == 7)
1667
                s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
1668
            return;
1669
        }
1670
        s->vga.cr[s->vga.cr_index] = reg_value;
1671
        switch(s->vga.cr_index) {
1672
        case 0x00:
1673
        case 0x04:
1674
        case 0x05:
1675
        case 0x06:
1676
        case 0x07:
1677
        case 0x11:
1678
        case 0x17:
1679
            s->vga.update_retrace_info(&s->vga);
1680
            break;
1681
        }
1682
        break;
1683
    case 0x19:                        // Interlace End
1684
    case 0x1a:                        // Miscellaneous Control
1685
    case 0x1b:                        // Extended Display Control
1686
    case 0x1c:                        // Sync Adjust and Genlock
1687
    case 0x1d:                        // Overlay Extended Control
1688
        s->vga.cr[s->vga.cr_index] = reg_value;
1689
#ifdef DEBUG_CIRRUS
1690
        printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
1691
               s->vga.cr_index, reg_value);
1692
#endif
1693
        break;
1694
    case 0x22:                        // Graphics Data Latches Readback (R)
1695
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1696
    case 0x26:                        // Attribute Controller Index Readback (R)
1697
    case 0x27:                        // Part ID (R)
1698
        break;
1699
    case 0x25:                        // Part Status
1700
    default:
1701
#ifdef DEBUG_CIRRUS
1702
        printf("cirrus: outport cr_index %02x, cr_value %02x\n",
1703
               s->vga.cr_index, reg_value);
1704
#endif
1705
        break;
1706
    }
1707
}
1708

    
1709
/***************************************
1710
 *
1711
 *  memory-mapped I/O (bitblt)
1712
 *
1713
 ***************************************/
1714

    
1715
static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1716
{
1717
    int value = 0xff;
1718

    
1719
    switch (address) {
1720
    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1721
        value = cirrus_vga_read_gr(s, 0x00);
1722
        break;
1723
    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1724
        value = cirrus_vga_read_gr(s, 0x10);
1725
        break;
1726
    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1727
        value = cirrus_vga_read_gr(s, 0x12);
1728
        break;
1729
    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1730
        value = cirrus_vga_read_gr(s, 0x14);
1731
        break;
1732
    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1733
        value = cirrus_vga_read_gr(s, 0x01);
1734
        break;
1735
    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1736
        value = cirrus_vga_read_gr(s, 0x11);
1737
        break;
1738
    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1739
        value = cirrus_vga_read_gr(s, 0x13);
1740
        break;
1741
    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1742
        value = cirrus_vga_read_gr(s, 0x15);
1743
        break;
1744
    case (CIRRUS_MMIO_BLTWIDTH + 0):
1745
        value = cirrus_vga_read_gr(s, 0x20);
1746
        break;
1747
    case (CIRRUS_MMIO_BLTWIDTH + 1):
1748
        value = cirrus_vga_read_gr(s, 0x21);
1749
        break;
1750
    case (CIRRUS_MMIO_BLTHEIGHT + 0):
1751
        value = cirrus_vga_read_gr(s, 0x22);
1752
        break;
1753
    case (CIRRUS_MMIO_BLTHEIGHT + 1):
1754
        value = cirrus_vga_read_gr(s, 0x23);
1755
        break;
1756
    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1757
        value = cirrus_vga_read_gr(s, 0x24);
1758
        break;
1759
    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1760
        value = cirrus_vga_read_gr(s, 0x25);
1761
        break;
1762
    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1763
        value = cirrus_vga_read_gr(s, 0x26);
1764
        break;
1765
    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1766
        value = cirrus_vga_read_gr(s, 0x27);
1767
        break;
1768
    case (CIRRUS_MMIO_BLTDESTADDR + 0):
1769
        value = cirrus_vga_read_gr(s, 0x28);
1770
        break;
1771
    case (CIRRUS_MMIO_BLTDESTADDR + 1):
1772
        value = cirrus_vga_read_gr(s, 0x29);
1773
        break;
1774
    case (CIRRUS_MMIO_BLTDESTADDR + 2):
1775
        value = cirrus_vga_read_gr(s, 0x2a);
1776
        break;
1777
    case (CIRRUS_MMIO_BLTSRCADDR + 0):
1778
        value = cirrus_vga_read_gr(s, 0x2c);
1779
        break;
1780
    case (CIRRUS_MMIO_BLTSRCADDR + 1):
1781
        value = cirrus_vga_read_gr(s, 0x2d);
1782
        break;
1783
    case (CIRRUS_MMIO_BLTSRCADDR + 2):
1784
        value = cirrus_vga_read_gr(s, 0x2e);
1785
        break;
1786
    case CIRRUS_MMIO_BLTWRITEMASK:
1787
        value = cirrus_vga_read_gr(s, 0x2f);
1788
        break;
1789
    case CIRRUS_MMIO_BLTMODE:
1790
        value = cirrus_vga_read_gr(s, 0x30);
1791
        break;
1792
    case CIRRUS_MMIO_BLTROP:
1793
        value = cirrus_vga_read_gr(s, 0x32);
1794
        break;
1795
    case CIRRUS_MMIO_BLTMODEEXT:
1796
        value = cirrus_vga_read_gr(s, 0x33);
1797
        break;
1798
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1799
        value = cirrus_vga_read_gr(s, 0x34);
1800
        break;
1801
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1802
        value = cirrus_vga_read_gr(s, 0x35);
1803
        break;
1804
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1805
        value = cirrus_vga_read_gr(s, 0x38);
1806
        break;
1807
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1808
        value = cirrus_vga_read_gr(s, 0x39);
1809
        break;
1810
    case CIRRUS_MMIO_BLTSTATUS:
1811
        value = cirrus_vga_read_gr(s, 0x31);
1812
        break;
1813
    default:
1814
#ifdef DEBUG_CIRRUS
1815
        printf("cirrus: mmio read - address 0x%04x\n", address);
1816
#endif
1817
        break;
1818
    }
1819

    
1820
    return (uint8_t) value;
1821
}
1822

    
1823
static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
1824
                                  uint8_t value)
1825
{
1826
    switch (address) {
1827
    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1828
        cirrus_vga_write_gr(s, 0x00, value);
1829
        break;
1830
    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1831
        cirrus_vga_write_gr(s, 0x10, value);
1832
        break;
1833
    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1834
        cirrus_vga_write_gr(s, 0x12, value);
1835
        break;
1836
    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1837
        cirrus_vga_write_gr(s, 0x14, value);
1838
        break;
1839
    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1840
        cirrus_vga_write_gr(s, 0x01, value);
1841
        break;
1842
    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1843
        cirrus_vga_write_gr(s, 0x11, value);
1844
        break;
1845
    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1846
        cirrus_vga_write_gr(s, 0x13, value);
1847
        break;
1848
    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1849
        cirrus_vga_write_gr(s, 0x15, value);
1850
        break;
1851
    case (CIRRUS_MMIO_BLTWIDTH + 0):
1852
        cirrus_vga_write_gr(s, 0x20, value);
1853
        break;
1854
    case (CIRRUS_MMIO_BLTWIDTH + 1):
1855
        cirrus_vga_write_gr(s, 0x21, value);
1856
        break;
1857
    case (CIRRUS_MMIO_BLTHEIGHT + 0):
1858
        cirrus_vga_write_gr(s, 0x22, value);
1859
        break;
1860
    case (CIRRUS_MMIO_BLTHEIGHT + 1):
1861
        cirrus_vga_write_gr(s, 0x23, value);
1862
        break;
1863
    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1864
        cirrus_vga_write_gr(s, 0x24, value);
1865
        break;
1866
    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1867
        cirrus_vga_write_gr(s, 0x25, value);
1868
        break;
1869
    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1870
        cirrus_vga_write_gr(s, 0x26, value);
1871
        break;
1872
    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1873
        cirrus_vga_write_gr(s, 0x27, value);
1874
        break;
1875
    case (CIRRUS_MMIO_BLTDESTADDR + 0):
1876
        cirrus_vga_write_gr(s, 0x28, value);
1877
        break;
1878
    case (CIRRUS_MMIO_BLTDESTADDR + 1):
1879
        cirrus_vga_write_gr(s, 0x29, value);
1880
        break;
1881
    case (CIRRUS_MMIO_BLTDESTADDR + 2):
1882
        cirrus_vga_write_gr(s, 0x2a, value);
1883
        break;
1884
    case (CIRRUS_MMIO_BLTDESTADDR + 3):
1885
        /* ignored */
1886
        break;
1887
    case (CIRRUS_MMIO_BLTSRCADDR + 0):
1888
        cirrus_vga_write_gr(s, 0x2c, value);
1889
        break;
1890
    case (CIRRUS_MMIO_BLTSRCADDR + 1):
1891
        cirrus_vga_write_gr(s, 0x2d, value);
1892
        break;
1893
    case (CIRRUS_MMIO_BLTSRCADDR + 2):
1894
        cirrus_vga_write_gr(s, 0x2e, value);
1895
        break;
1896
    case CIRRUS_MMIO_BLTWRITEMASK:
1897
        cirrus_vga_write_gr(s, 0x2f, value);
1898
        break;
1899
    case CIRRUS_MMIO_BLTMODE:
1900
        cirrus_vga_write_gr(s, 0x30, value);
1901
        break;
1902
    case CIRRUS_MMIO_BLTROP:
1903
        cirrus_vga_write_gr(s, 0x32, value);
1904
        break;
1905
    case CIRRUS_MMIO_BLTMODEEXT:
1906
        cirrus_vga_write_gr(s, 0x33, value);
1907
        break;
1908
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1909
        cirrus_vga_write_gr(s, 0x34, value);
1910
        break;
1911
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1912
        cirrus_vga_write_gr(s, 0x35, value);
1913
        break;
1914
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1915
        cirrus_vga_write_gr(s, 0x38, value);
1916
        break;
1917
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1918
        cirrus_vga_write_gr(s, 0x39, value);
1919
        break;
1920
    case CIRRUS_MMIO_BLTSTATUS:
1921
        cirrus_vga_write_gr(s, 0x31, value);
1922
        break;
1923
    default:
1924
#ifdef DEBUG_CIRRUS
1925
        printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
1926
               address, value);
1927
#endif
1928
        break;
1929
    }
1930
}
1931

    
1932
/***************************************
1933
 *
1934
 *  write mode 4/5
1935
 *
1936
 * assume TARGET_PAGE_SIZE >= 16
1937
 *
1938
 ***************************************/
1939

    
1940
static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1941
                                             unsigned mode,
1942
                                             unsigned offset,
1943
                                             uint32_t mem_value)
1944
{
1945
    int x;
1946
    unsigned val = mem_value;
1947
    uint8_t *dst;
1948

    
1949
    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1950
    for (x = 0; x < 8; x++) {
1951
        if (val & 0x80) {
1952
            *dst = s->cirrus_shadow_gr1;
1953
        } else if (mode == 5) {
1954
            *dst = s->cirrus_shadow_gr0;
1955
        }
1956
        val <<= 1;
1957
        dst++;
1958
    }
1959
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
1960
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
1961
}
1962

    
1963
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1964
                                              unsigned mode,
1965
                                              unsigned offset,
1966
                                              uint32_t mem_value)
1967
{
1968
    int x;
1969
    unsigned val = mem_value;
1970
    uint8_t *dst;
1971

    
1972
    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1973
    for (x = 0; x < 8; x++) {
1974
        if (val & 0x80) {
1975
            *dst = s->cirrus_shadow_gr1;
1976
            *(dst + 1) = s->vga.gr[0x11];
1977
        } else if (mode == 5) {
1978
            *dst = s->cirrus_shadow_gr0;
1979
            *(dst + 1) = s->vga.gr[0x10];
1980
        }
1981
        val <<= 1;
1982
        dst += 2;
1983
    }
1984
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
1985
    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
1986
}
1987

    
1988
/***************************************
1989
 *
1990
 *  memory access between 0xa0000-0xbffff
1991
 *
1992
 ***************************************/
1993

    
1994
static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
1995
{
1996
    CirrusVGAState *s = opaque;
1997
    unsigned bank_index;
1998
    unsigned bank_offset;
1999
    uint32_t val;
2000

    
2001
    if ((s->vga.sr[0x07] & 0x01) == 0) {
2002
        return vga_mem_readb(s, addr);
2003
    }
2004

    
2005
    addr &= 0x1ffff;
2006

    
2007
    if (addr < 0x10000) {
2008
        /* XXX handle bitblt */
2009
        /* video memory */
2010
        bank_index = addr >> 15;
2011
        bank_offset = addr & 0x7fff;
2012
        if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2013
            bank_offset += s->cirrus_bank_base[bank_index];
2014
            if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2015
                bank_offset <<= 4;
2016
            } else if (s->vga.gr[0x0B] & 0x02) {
2017
                bank_offset <<= 3;
2018
            }
2019
            bank_offset &= s->cirrus_addr_mask;
2020
            val = *(s->vga.vram_ptr + bank_offset);
2021
        } else
2022
            val = 0xff;
2023
    } else if (addr >= 0x18000 && addr < 0x18100) {
2024
        /* memory-mapped I/O */
2025
        val = 0xff;
2026
        if ((s->vga.sr[0x17] & 0x44) == 0x04) {
2027
            val = cirrus_mmio_blt_read(s, addr & 0xff);
2028
        }
2029
    } else {
2030
        val = 0xff;
2031
#ifdef DEBUG_CIRRUS
2032
        printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
2033
#endif
2034
    }
2035
    return val;
2036
}
2037

    
2038
static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
2039
{
2040
    uint32_t v;
2041
#ifdef TARGET_WORDS_BIGENDIAN
2042
    v = cirrus_vga_mem_readb(opaque, addr) << 8;
2043
    v |= cirrus_vga_mem_readb(opaque, addr + 1);
2044
#else
2045
    v = cirrus_vga_mem_readb(opaque, addr);
2046
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2047
#endif
2048
    return v;
2049
}
2050

    
2051
static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
2052
{
2053
    uint32_t v;
2054
#ifdef TARGET_WORDS_BIGENDIAN
2055
    v = cirrus_vga_mem_readb(opaque, addr) << 24;
2056
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
2057
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
2058
    v |= cirrus_vga_mem_readb(opaque, addr + 3);
2059
#else
2060
    v = cirrus_vga_mem_readb(opaque, addr);
2061
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2062
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
2063
    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
2064
#endif
2065
    return v;
2066
}
2067

    
2068
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
2069
                                  uint32_t mem_value)
2070
{
2071
    CirrusVGAState *s = opaque;
2072
    unsigned bank_index;
2073
    unsigned bank_offset;
2074
    unsigned mode;
2075

    
2076
    if ((s->vga.sr[0x07] & 0x01) == 0) {
2077
        vga_mem_writeb(s, addr, mem_value);
2078
        return;
2079
    }
2080

    
2081
    addr &= 0x1ffff;
2082

    
2083
    if (addr < 0x10000) {
2084
        if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2085
            /* bitblt */
2086
            *s->cirrus_srcptr++ = (uint8_t) mem_value;
2087
            if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2088
                cirrus_bitblt_cputovideo_next(s);
2089
            }
2090
        } else {
2091
            /* video memory */
2092
            bank_index = addr >> 15;
2093
            bank_offset = addr & 0x7fff;
2094
            if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2095
                bank_offset += s->cirrus_bank_base[bank_index];
2096
                if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2097
                    bank_offset <<= 4;
2098
                } else if (s->vga.gr[0x0B] & 0x02) {
2099
                    bank_offset <<= 3;
2100
                }
2101
                bank_offset &= s->cirrus_addr_mask;
2102
                mode = s->vga.gr[0x05] & 0x7;
2103
                if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2104
                    *(s->vga.vram_ptr + bank_offset) = mem_value;
2105
                    cpu_physical_memory_set_dirty(s->vga.vram_offset +
2106
                                                  bank_offset);
2107
                } else {
2108
                    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2109
                        cirrus_mem_writeb_mode4and5_8bpp(s, mode,
2110
                                                         bank_offset,
2111
                                                         mem_value);
2112
                    } else {
2113
                        cirrus_mem_writeb_mode4and5_16bpp(s, mode,
2114
                                                          bank_offset,
2115
                                                          mem_value);
2116
                    }
2117
                }
2118
            }
2119
        }
2120
    } else if (addr >= 0x18000 && addr < 0x18100) {
2121
        /* memory-mapped I/O */
2122
        if ((s->vga.sr[0x17] & 0x44) == 0x04) {
2123
            cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
2124
        }
2125
    } else {
2126
#ifdef DEBUG_CIRRUS
2127
        printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr,
2128
               mem_value);
2129
#endif
2130
    }
2131
}
2132

    
2133
static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2134
{
2135
#ifdef TARGET_WORDS_BIGENDIAN
2136
    cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
2137
    cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
2138
#else
2139
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2140
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2141
#endif
2142
}
2143

    
2144
static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2145
{
2146
#ifdef TARGET_WORDS_BIGENDIAN
2147
    cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
2148
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2149
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2150
    cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
2151
#else
2152
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2153
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2154
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2155
    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2156
#endif
2157
}
2158

    
2159
static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
2160
    cirrus_vga_mem_readb,
2161
    cirrus_vga_mem_readw,
2162
    cirrus_vga_mem_readl,
2163
};
2164

    
2165
static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
2166
    cirrus_vga_mem_writeb,
2167
    cirrus_vga_mem_writew,
2168
    cirrus_vga_mem_writel,
2169
};
2170

    
2171
/***************************************
2172
 *
2173
 *  hardware cursor
2174
 *
2175
 ***************************************/
2176

    
2177
static inline void invalidate_cursor1(CirrusVGAState *s)
2178
{
2179
    if (s->last_hw_cursor_size) {
2180
        vga_invalidate_scanlines(&s->vga,
2181
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_start,
2182
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_end);
2183
    }
2184
}
2185

    
2186
static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
2187
{
2188
    const uint8_t *src;
2189
    uint32_t content;
2190
    int y, y_min, y_max;
2191

    
2192
    src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2193
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2194
        src += (s->vga.sr[0x13] & 0x3c) * 256;
2195
        y_min = 64;
2196
        y_max = -1;
2197
        for(y = 0; y < 64; y++) {
2198
            content = ((uint32_t *)src)[0] |
2199
                ((uint32_t *)src)[1] |
2200
                ((uint32_t *)src)[2] |
2201
                ((uint32_t *)src)[3];
2202
            if (content) {
2203
                if (y < y_min)
2204
                    y_min = y;
2205
                if (y > y_max)
2206
                    y_max = y;
2207
            }
2208
            src += 16;
2209
        }
2210
    } else {
2211
        src += (s->vga.sr[0x13] & 0x3f) * 256;
2212
        y_min = 32;
2213
        y_max = -1;
2214
        for(y = 0; y < 32; y++) {
2215
            content = ((uint32_t *)src)[0] |
2216
                ((uint32_t *)(src + 128))[0];
2217
            if (content) {
2218
                if (y < y_min)
2219
                    y_min = y;
2220
                if (y > y_max)
2221
                    y_max = y;
2222
            }
2223
            src += 4;
2224
        }
2225
    }
2226
    if (y_min > y_max) {
2227
        s->last_hw_cursor_y_start = 0;
2228
        s->last_hw_cursor_y_end = 0;
2229
    } else {
2230
        s->last_hw_cursor_y_start = y_min;
2231
        s->last_hw_cursor_y_end = y_max + 1;
2232
    }
2233
}
2234

    
2235
/* NOTE: we do not currently handle the cursor bitmap change, so we
2236
   update the cursor only if it moves. */
2237
static void cirrus_cursor_invalidate(VGACommonState *s1)
2238
{
2239
    CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2240
    int size;
2241

    
2242
    if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
2243
        size = 0;
2244
    } else {
2245
        if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
2246
            size = 64;
2247
        else
2248
            size = 32;
2249
    }
2250
    /* invalidate last cursor and new cursor if any change */
2251
    if (s->last_hw_cursor_size != size ||
2252
        s->last_hw_cursor_x != s->hw_cursor_x ||
2253
        s->last_hw_cursor_y != s->hw_cursor_y) {
2254

    
2255
        invalidate_cursor1(s);
2256

    
2257
        s->last_hw_cursor_size = size;
2258
        s->last_hw_cursor_x = s->hw_cursor_x;
2259
        s->last_hw_cursor_y = s->hw_cursor_y;
2260
        /* compute the real cursor min and max y */
2261
        cirrus_cursor_compute_yrange(s);
2262
        invalidate_cursor1(s);
2263
    }
2264
}
2265

    
2266
static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
2267
{
2268
    CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2269
    int w, h, bpp, x1, x2, poffset;
2270
    unsigned int color0, color1;
2271
    const uint8_t *palette, *src;
2272
    uint32_t content;
2273

    
2274
    if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
2275
        return;
2276
    /* fast test to see if the cursor intersects with the scan line */
2277
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2278
        h = 64;
2279
    } else {
2280
        h = 32;
2281
    }
2282
    if (scr_y < s->hw_cursor_y ||
2283
        scr_y >= (s->hw_cursor_y + h))
2284
        return;
2285

    
2286
    src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2287
    if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2288
        src += (s->vga.sr[0x13] & 0x3c) * 256;
2289
        src += (scr_y - s->hw_cursor_y) * 16;
2290
        poffset = 8;
2291
        content = ((uint32_t *)src)[0] |
2292
            ((uint32_t *)src)[1] |
2293
            ((uint32_t *)src)[2] |
2294
            ((uint32_t *)src)[3];
2295
    } else {
2296
        src += (s->vga.sr[0x13] & 0x3f) * 256;
2297
        src += (scr_y - s->hw_cursor_y) * 4;
2298
        poffset = 128;
2299
        content = ((uint32_t *)src)[0] |
2300
            ((uint32_t *)(src + 128))[0];
2301
    }
2302
    /* if nothing to draw, no need to continue */
2303
    if (!content)
2304
        return;
2305
    w = h;
2306

    
2307
    x1 = s->hw_cursor_x;
2308
    if (x1 >= s->vga.last_scr_width)
2309
        return;
2310
    x2 = s->hw_cursor_x + w;
2311
    if (x2 > s->vga.last_scr_width)
2312
        x2 = s->vga.last_scr_width;
2313
    w = x2 - x1;
2314
    palette = s->cirrus_hidden_palette;
2315
    color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
2316
                                 c6_to_8(palette[0x0 * 3 + 1]),
2317
                                 c6_to_8(palette[0x0 * 3 + 2]));
2318
    color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
2319
                                 c6_to_8(palette[0xf * 3 + 1]),
2320
                                 c6_to_8(palette[0xf * 3 + 2]));
2321
    bpp = ((ds_get_bits_per_pixel(s->vga.ds) + 7) >> 3);
2322
    d1 += x1 * bpp;
2323
    switch(ds_get_bits_per_pixel(s->vga.ds)) {
2324
    default:
2325
        break;
2326
    case 8:
2327
        vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
2328
        break;
2329
    case 15:
2330
        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
2331
        break;
2332
    case 16:
2333
        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
2334
        break;
2335
    case 32:
2336
        vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
2337
        break;
2338
    }
2339
}
2340

    
2341
/***************************************
2342
 *
2343
 *  LFB memory access
2344
 *
2345
 ***************************************/
2346

    
2347
static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
2348
{
2349
    CirrusVGAState *s = opaque;
2350
    uint32_t ret;
2351

    
2352
    addr &= s->cirrus_addr_mask;
2353

    
2354
    if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2355
        ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2356
        /* memory-mapped I/O */
2357
        ret = cirrus_mmio_blt_read(s, addr & 0xff);
2358
    } else if (0) {
2359
        /* XXX handle bitblt */
2360
        ret = 0xff;
2361
    } else {
2362
        /* video memory */
2363
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2364
            addr <<= 4;
2365
        } else if (s->vga.gr[0x0B] & 0x02) {
2366
            addr <<= 3;
2367
        }
2368
        addr &= s->cirrus_addr_mask;
2369
        ret = *(s->vga.vram_ptr + addr);
2370
    }
2371

    
2372
    return ret;
2373
}
2374

    
2375
static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
2376
{
2377
    uint32_t v;
2378
#ifdef TARGET_WORDS_BIGENDIAN
2379
    v = cirrus_linear_readb(opaque, addr) << 8;
2380
    v |= cirrus_linear_readb(opaque, addr + 1);
2381
#else
2382
    v = cirrus_linear_readb(opaque, addr);
2383
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2384
#endif
2385
    return v;
2386
}
2387

    
2388
static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
2389
{
2390
    uint32_t v;
2391
#ifdef TARGET_WORDS_BIGENDIAN
2392
    v = cirrus_linear_readb(opaque, addr) << 24;
2393
    v |= cirrus_linear_readb(opaque, addr + 1) << 16;
2394
    v |= cirrus_linear_readb(opaque, addr + 2) << 8;
2395
    v |= cirrus_linear_readb(opaque, addr + 3);
2396
#else
2397
    v = cirrus_linear_readb(opaque, addr);
2398
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2399
    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
2400
    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
2401
#endif
2402
    return v;
2403
}
2404

    
2405
static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
2406
                                 uint32_t val)
2407
{
2408
    CirrusVGAState *s = opaque;
2409
    unsigned mode;
2410

    
2411
    addr &= s->cirrus_addr_mask;
2412

    
2413
    if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2414
        ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
2415
        /* memory-mapped I/O */
2416
        cirrus_mmio_blt_write(s, addr & 0xff, val);
2417
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2418
        /* bitblt */
2419
        *s->cirrus_srcptr++ = (uint8_t) val;
2420
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2421
            cirrus_bitblt_cputovideo_next(s);
2422
        }
2423
    } else {
2424
        /* video memory */
2425
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2426
            addr <<= 4;
2427
        } else if (s->vga.gr[0x0B] & 0x02) {
2428
            addr <<= 3;
2429
        }
2430
        addr &= s->cirrus_addr_mask;
2431

    
2432
        mode = s->vga.gr[0x05] & 0x7;
2433
        if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2434
            *(s->vga.vram_ptr + addr) = (uint8_t) val;
2435
            cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
2436
        } else {
2437
            if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2438
                cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2439
            } else {
2440
                cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2441
            }
2442
        }
2443
    }
2444
}
2445

    
2446
static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
2447
                                 uint32_t val)
2448
{
2449
#ifdef TARGET_WORDS_BIGENDIAN
2450
    cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
2451
    cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
2452
#else
2453
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2454
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2455
#endif
2456
}
2457

    
2458
static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
2459
                                 uint32_t val)
2460
{
2461
#ifdef TARGET_WORDS_BIGENDIAN
2462
    cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
2463
    cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2464
    cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2465
    cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
2466
#else
2467
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2468
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2469
    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2470
    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2471
#endif
2472
}
2473

    
2474

    
2475
static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
2476
    cirrus_linear_readb,
2477
    cirrus_linear_readw,
2478
    cirrus_linear_readl,
2479
};
2480

    
2481
static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
2482
    cirrus_linear_writeb,
2483
    cirrus_linear_writew,
2484
    cirrus_linear_writel,
2485
};
2486

    
2487
/***************************************
2488
 *
2489
 *  system to screen memory access
2490
 *
2491
 ***************************************/
2492

    
2493

    
2494
static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
2495
{
2496
    uint32_t ret;
2497

    
2498
    /* XXX handle bitblt */
2499
    ret = 0xff;
2500
    return ret;
2501
}
2502

    
2503
static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
2504
{
2505
    uint32_t v;
2506
#ifdef TARGET_WORDS_BIGENDIAN
2507
    v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
2508
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
2509
#else
2510
    v = cirrus_linear_bitblt_readb(opaque, addr);
2511
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2512
#endif
2513
    return v;
2514
}
2515

    
2516
static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
2517
{
2518
    uint32_t v;
2519
#ifdef TARGET_WORDS_BIGENDIAN
2520
    v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
2521
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
2522
    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
2523
    v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
2524
#else
2525
    v = cirrus_linear_bitblt_readb(opaque, addr);
2526
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2527
    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
2528
    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
2529
#endif
2530
    return v;
2531
}
2532

    
2533
static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
2534
                                 uint32_t val)
2535
{
2536
    CirrusVGAState *s = opaque;
2537

    
2538
    if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2539
        /* bitblt */
2540
        *s->cirrus_srcptr++ = (uint8_t) val;
2541
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2542
            cirrus_bitblt_cputovideo_next(s);
2543
        }
2544
    }
2545
}
2546

    
2547
static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
2548
                                 uint32_t val)
2549
{
2550
#ifdef TARGET_WORDS_BIGENDIAN
2551
    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
2552
    cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
2553
#else
2554
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2555
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2556
#endif
2557
}
2558

    
2559
static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
2560
                                 uint32_t val)
2561
{
2562
#ifdef TARGET_WORDS_BIGENDIAN
2563
    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
2564
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2565
    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2566
    cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
2567
#else
2568
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2569
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2570
    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2571
    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2572
#endif
2573
}
2574

    
2575

    
2576
static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
2577
    cirrus_linear_bitblt_readb,
2578
    cirrus_linear_bitblt_readw,
2579
    cirrus_linear_bitblt_readl,
2580
};
2581

    
2582
static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
2583
    cirrus_linear_bitblt_writeb,
2584
    cirrus_linear_bitblt_writew,
2585
    cirrus_linear_bitblt_writel,
2586
};
2587

    
2588
static void map_linear_vram(CirrusVGAState *s)
2589
{
2590
    if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
2591
        s->vga.map_addr = s->vga.lfb_addr;
2592
        s->vga.map_end = s->vga.lfb_end;
2593
        cpu_register_physical_memory(s->vga.map_addr, s->vga.map_end - s->vga.map_addr, s->vga.vram_offset);
2594
    }
2595

    
2596
    if (!s->vga.map_addr)
2597
        return;
2598

    
2599
    s->vga.lfb_vram_mapped = 0;
2600

    
2601
    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
2602
        && !((s->vga.sr[0x07] & 0x01) == 0)
2603
        && !((s->vga.gr[0x0B] & 0x14) == 0x14)
2604
        && !(s->vga.gr[0x0B] & 0x02)) {
2605

    
2606
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
2607
                                    (s->vga.vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
2608
        cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
2609
                                    (s->vga.vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM);
2610

    
2611
        s->vga.lfb_vram_mapped = 1;
2612
    }
2613
    else {
2614
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2615
                                     s->vga.vga_io_memory);
2616
    }
2617

    
2618
    vga_dirty_log_start(&s->vga);
2619
}
2620

    
2621
static void unmap_linear_vram(CirrusVGAState *s)
2622
{
2623
    if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end)
2624
        s->vga.map_addr = s->vga.map_end = 0;
2625

    
2626
    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2627
                                 s->vga.vga_io_memory);
2628
}
2629

    
2630
/* Compute the memory access functions */
2631
static void cirrus_update_memory_access(CirrusVGAState *s)
2632
{
2633
    unsigned mode;
2634

    
2635
    if ((s->vga.sr[0x17] & 0x44) == 0x44) {
2636
        goto generic_io;
2637
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2638
        goto generic_io;
2639
    } else {
2640
        if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2641
            goto generic_io;
2642
        } else if (s->vga.gr[0x0B] & 0x02) {
2643
            goto generic_io;
2644
        }
2645

    
2646
        mode = s->vga.gr[0x05] & 0x7;
2647
        if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2648
            map_linear_vram(s);
2649
        } else {
2650
        generic_io:
2651
            unmap_linear_vram(s);
2652
        }
2653
    }
2654
}
2655

    
2656

    
2657
/* I/O ports */
2658

    
2659
static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
2660
{
2661
    CirrusVGAState *c = opaque;
2662
    VGACommonState *s = &c->vga;
2663
    int val, index;
2664

    
2665
    if (vga_ioport_invalid(s, addr)) {
2666
        val = 0xff;
2667
    } else {
2668
        switch (addr) {
2669
        case 0x3c0:
2670
            if (s->ar_flip_flop == 0) {
2671
                val = s->ar_index;
2672
            } else {
2673
                val = 0;
2674
            }
2675
            break;
2676
        case 0x3c1:
2677
            index = s->ar_index & 0x1f;
2678
            if (index < 21)
2679
                val = s->ar[index];
2680
            else
2681
                val = 0;
2682
            break;
2683
        case 0x3c2:
2684
            val = s->st00;
2685
            break;
2686
        case 0x3c4:
2687
            val = s->sr_index;
2688
            break;
2689
        case 0x3c5:
2690
            val = cirrus_vga_read_sr(c);
2691
            break;
2692
#ifdef DEBUG_VGA_REG
2693
            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2694
#endif
2695
            break;
2696
        case 0x3c6:
2697
            val = cirrus_read_hidden_dac(c);
2698
            break;
2699
        case 0x3c7:
2700
            val = s->dac_state;
2701
            break;
2702
        case 0x3c8:
2703
            val = s->dac_write_index;
2704
            c->cirrus_hidden_dac_lockindex = 0;
2705
            break;
2706
        case 0x3c9:
2707
            val = cirrus_vga_read_palette(c);
2708
            break;
2709
        case 0x3ca:
2710
            val = s->fcr;
2711
            break;
2712
        case 0x3cc:
2713
            val = s->msr;
2714
            break;
2715
        case 0x3ce:
2716
            val = s->gr_index;
2717
            break;
2718
        case 0x3cf:
2719
            val = cirrus_vga_read_gr(c, s->gr_index);
2720
#ifdef DEBUG_VGA_REG
2721
            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2722
#endif
2723
            break;
2724
        case 0x3b4:
2725
        case 0x3d4:
2726
            val = s->cr_index;
2727
            break;
2728
        case 0x3b5:
2729
        case 0x3d5:
2730
            val = cirrus_vga_read_cr(c, s->cr_index);
2731
#ifdef DEBUG_VGA_REG
2732
            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2733
#endif
2734
            break;
2735
        case 0x3ba:
2736
        case 0x3da:
2737
            /* just toggle to fool polling */
2738
            val = s->st01 = s->retrace(s);
2739
            s->ar_flip_flop = 0;
2740
            break;
2741
        default:
2742
            val = 0x00;
2743
            break;
2744
        }
2745
    }
2746
#if defined(DEBUG_VGA)
2747
    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2748
#endif
2749
    return val;
2750
}
2751

    
2752
static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2753
{
2754
    CirrusVGAState *c = opaque;
2755
    VGACommonState *s = &c->vga;
2756
    int index;
2757

    
2758
    /* check port range access depending on color/monochrome mode */
2759
    if (vga_ioport_invalid(s, addr)) {
2760
        return;
2761
    }
2762
#ifdef DEBUG_VGA
2763
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2764
#endif
2765

    
2766
    switch (addr) {
2767
    case 0x3c0:
2768
        if (s->ar_flip_flop == 0) {
2769
            val &= 0x3f;
2770
            s->ar_index = val;
2771
        } else {
2772
            index = s->ar_index & 0x1f;
2773
            switch (index) {
2774
            case 0x00 ... 0x0f:
2775
                s->ar[index] = val & 0x3f;
2776
                break;
2777
            case 0x10:
2778
                s->ar[index] = val & ~0x10;
2779
                break;
2780
            case 0x11:
2781
                s->ar[index] = val;
2782
                break;
2783
            case 0x12:
2784
                s->ar[index] = val & ~0xc0;
2785
                break;
2786
            case 0x13:
2787
                s->ar[index] = val & ~0xf0;
2788
                break;
2789
            case 0x14:
2790
                s->ar[index] = val & ~0xf0;
2791
                break;
2792
            default:
2793
                break;
2794
            }
2795
        }
2796
        s->ar_flip_flop ^= 1;
2797
        break;
2798
    case 0x3c2:
2799
        s->msr = val & ~0x10;
2800
        s->update_retrace_info(s);
2801
        break;
2802
    case 0x3c4:
2803
        s->sr_index = val;
2804
        break;
2805
    case 0x3c5:
2806
#ifdef DEBUG_VGA_REG
2807
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2808
#endif
2809
        cirrus_vga_write_sr(c, val);
2810
        break;
2811
        break;
2812
    case 0x3c6:
2813
        cirrus_write_hidden_dac(c, val);
2814
        break;
2815
    case 0x3c7:
2816
        s->dac_read_index = val;
2817
        s->dac_sub_index = 0;
2818
        s->dac_state = 3;
2819
        break;
2820
    case 0x3c8:
2821
        s->dac_write_index = val;
2822
        s->dac_sub_index = 0;
2823
        s->dac_state = 0;
2824
        break;
2825
    case 0x3c9:
2826
        cirrus_vga_write_palette(c, val);
2827
        break;
2828
    case 0x3ce:
2829
        s->gr_index = val;
2830
        break;
2831
    case 0x3cf:
2832
#ifdef DEBUG_VGA_REG
2833
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2834
#endif
2835
        cirrus_vga_write_gr(c, s->gr_index, val);
2836
        break;
2837
    case 0x3b4:
2838
    case 0x3d4:
2839
        s->cr_index = val;
2840
        break;
2841
    case 0x3b5:
2842
    case 0x3d5:
2843
#ifdef DEBUG_VGA_REG
2844
        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2845
#endif
2846
        cirrus_vga_write_cr(c, val);
2847
        break;
2848
    case 0x3ba:
2849
    case 0x3da:
2850
        s->fcr = val & 0x10;
2851
        break;
2852
    }
2853
}
2854

    
2855
/***************************************
2856
 *
2857
 *  memory-mapped I/O access
2858
 *
2859
 ***************************************/
2860

    
2861
static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
2862
{
2863
    CirrusVGAState *s = opaque;
2864

    
2865
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2866

    
2867
    if (addr >= 0x100) {
2868
        return cirrus_mmio_blt_read(s, addr - 0x100);
2869
    } else {
2870
        return cirrus_vga_ioport_read(s, addr + 0x3c0);
2871
    }
2872
}
2873

    
2874
static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
2875
{
2876
    uint32_t v;
2877
#ifdef TARGET_WORDS_BIGENDIAN
2878
    v = cirrus_mmio_readb(opaque, addr) << 8;
2879
    v |= cirrus_mmio_readb(opaque, addr + 1);
2880
#else
2881
    v = cirrus_mmio_readb(opaque, addr);
2882
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2883
#endif
2884
    return v;
2885
}
2886

    
2887
static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
2888
{
2889
    uint32_t v;
2890
#ifdef TARGET_WORDS_BIGENDIAN
2891
    v = cirrus_mmio_readb(opaque, addr) << 24;
2892
    v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
2893
    v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
2894
    v |= cirrus_mmio_readb(opaque, addr + 3);
2895
#else
2896
    v = cirrus_mmio_readb(opaque, addr);
2897
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2898
    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
2899
    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
2900
#endif
2901
    return v;
2902
}
2903

    
2904
static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
2905
                               uint32_t val)
2906
{
2907
    CirrusVGAState *s = opaque;
2908

    
2909
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2910

    
2911
    if (addr >= 0x100) {
2912
        cirrus_mmio_blt_write(s, addr - 0x100, val);
2913
    } else {
2914
        cirrus_vga_ioport_write(s, addr + 0x3c0, val);
2915
    }
2916
}
2917

    
2918
static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
2919
                               uint32_t val)
2920
{
2921
#ifdef TARGET_WORDS_BIGENDIAN
2922
    cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
2923
    cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
2924
#else
2925
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2926
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2927
#endif
2928
}
2929

    
2930
static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
2931
                               uint32_t val)
2932
{
2933
#ifdef TARGET_WORDS_BIGENDIAN
2934
    cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
2935
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2936
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2937
    cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
2938
#else
2939
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2940
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2941
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2942
    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2943
#endif
2944
}
2945

    
2946

    
2947
static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
2948
    cirrus_mmio_readb,
2949
    cirrus_mmio_readw,
2950
    cirrus_mmio_readl,
2951
};
2952

    
2953
static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
2954
    cirrus_mmio_writeb,
2955
    cirrus_mmio_writew,
2956
    cirrus_mmio_writel,
2957
};
2958

    
2959
/* load/save state */
2960

    
2961
static int cirrus_post_load(void *opaque, int version_id)
2962
{
2963
    CirrusVGAState *s = opaque;
2964

    
2965
    s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
2966
    s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
2967

    
2968
    cirrus_update_memory_access(s);
2969
    /* force refresh */
2970
    s->vga.graphic_mode = -1;
2971
    cirrus_update_bank_ptr(s, 0);
2972
    cirrus_update_bank_ptr(s, 1);
2973
    return 0;
2974
}
2975

    
2976
static const VMStateDescription vmstate_cirrus_vga = {
2977
    .name = "cirrus_vga",
2978
    .version_id = 2,
2979
    .minimum_version_id = 1,
2980
    .minimum_version_id_old = 1,
2981
    .post_load = cirrus_post_load,
2982
    .fields      = (VMStateField []) {
2983
        VMSTATE_UINT32(vga.latch, CirrusVGAState),
2984
        VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
2985
        VMSTATE_BUFFER(vga.sr, CirrusVGAState),
2986
        VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
2987
        VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
2988
        VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
2989
        VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
2990
        VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
2991
        VMSTATE_BUFFER(vga.ar, CirrusVGAState),
2992
        VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
2993
        VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
2994
        VMSTATE_BUFFER(vga.cr, CirrusVGAState),
2995
        VMSTATE_UINT8(vga.msr, CirrusVGAState),
2996
        VMSTATE_UINT8(vga.fcr, CirrusVGAState),
2997
        VMSTATE_UINT8(vga.st00, CirrusVGAState),
2998
        VMSTATE_UINT8(vga.st01, CirrusVGAState),
2999
        VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
3000
        VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
3001
        VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
3002
        VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
3003
        VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
3004
        VMSTATE_BUFFER(vga.palette, CirrusVGAState),
3005
        VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
3006
        VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
3007
        VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
3008
        VMSTATE_UINT32(hw_cursor_x, CirrusVGAState),
3009
        VMSTATE_UINT32(hw_cursor_y, CirrusVGAState),
3010
        /* XXX: we do not save the bitblt state - we assume we do not save
3011
           the state when the blitter is active */
3012
        VMSTATE_END_OF_LIST()
3013
    }
3014
};
3015

    
3016
static const VMStateDescription vmstate_pci_cirrus_vga = {
3017
    .name = "cirrus_vga",
3018
    .version_id = 2,
3019
    .minimum_version_id = 2,
3020
    .minimum_version_id_old = 2,
3021
    .post_load = cirrus_post_load,
3022
    .fields      = (VMStateField []) {
3023
        VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
3024
        VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
3025
                       vmstate_cirrus_vga, CirrusVGAState),
3026
        VMSTATE_END_OF_LIST()
3027
    }
3028
};
3029

    
3030
/***************************************
3031
 *
3032
 *  initialize
3033
 *
3034
 ***************************************/
3035

    
3036
static void cirrus_reset(void *opaque)
3037
{
3038
    CirrusVGAState *s = opaque;
3039

    
3040
    vga_common_reset(&s->vga);
3041
    unmap_linear_vram(s);
3042
    s->vga.sr[0x06] = 0x0f;
3043
    if (s->device_id == CIRRUS_ID_CLGD5446) {
3044
        /* 4MB 64 bit memory config, always PCI */
3045
        s->vga.sr[0x1F] = 0x2d;                // MemClock
3046
        s->vga.gr[0x18] = 0x0f;             // fastest memory configuration
3047
        s->vga.sr[0x0f] = 0x98;
3048
        s->vga.sr[0x17] = 0x20;
3049
        s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
3050
    } else {
3051
        s->vga.sr[0x1F] = 0x22;                // MemClock
3052
        s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
3053
        s->vga.sr[0x17] = s->bustype;
3054
        s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
3055
    }
3056
    s->vga.cr[0x27] = s->device_id;
3057

    
3058
    /* Win2K seems to assume that the pattern buffer is at 0xff
3059
       initially ! */
3060
    memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
3061

    
3062
    s->cirrus_hidden_dac_lockindex = 5;
3063
    s->cirrus_hidden_dac_data = 0;
3064
}
3065

    
3066
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
3067
{
3068
    int i;
3069
    static int inited;
3070

    
3071
    if (!inited) {
3072
        inited = 1;
3073
        for(i = 0;i < 256; i++)
3074
            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
3075
        rop_to_index[CIRRUS_ROP_0] = 0;
3076
        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
3077
        rop_to_index[CIRRUS_ROP_NOP] = 2;
3078
        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
3079
        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
3080
        rop_to_index[CIRRUS_ROP_SRC] = 5;
3081
        rop_to_index[CIRRUS_ROP_1] = 6;
3082
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
3083
        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
3084
        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
3085
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
3086
        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
3087
        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
3088
        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
3089
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
3090
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
3091
        s->device_id = device_id;
3092
        if (is_pci)
3093
            s->bustype = CIRRUS_BUSTYPE_PCI;
3094
        else
3095
            s->bustype = CIRRUS_BUSTYPE_ISA;
3096
    }
3097

    
3098
    register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
3099

    
3100
    register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
3101
    register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
3102
    register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
3103
    register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
3104

    
3105
    register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
3106

    
3107
    register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
3108
    register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
3109
    register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
3110
    register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
3111

    
3112
    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
3113
                                                  cirrus_vga_mem_write, s);
3114
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
3115
                                 s->vga.vga_io_memory);
3116
    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
3117

    
3118
    /* I/O handler for LFB */
3119
    s->cirrus_linear_io_addr =
3120
        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s);
3121

    
3122
    /* I/O handler for LFB */
3123
    s->cirrus_linear_bitblt_io_addr =
3124
        cpu_register_io_memory(cirrus_linear_bitblt_read,
3125
                               cirrus_linear_bitblt_write, s);
3126

    
3127
    /* I/O handler for memory-mapped I/O */
3128
    s->cirrus_mmio_io_addr =
3129
        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s);
3130

    
3131
    s->real_vram_size =
3132
        (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
3133

    
3134
    /* XXX: s->vga.vram_size must be a power of two */
3135
    s->cirrus_addr_mask = s->real_vram_size - 1;
3136
    s->linear_mmio_mask = s->real_vram_size - 256;
3137

    
3138
    s->vga.get_bpp = cirrus_get_bpp;
3139
    s->vga.get_offsets = cirrus_get_offsets;
3140
    s->vga.get_resolution = cirrus_get_resolution;
3141
    s->vga.cursor_invalidate = cirrus_cursor_invalidate;
3142
    s->vga.cursor_draw_line = cirrus_cursor_draw_line;
3143

    
3144
    qemu_register_reset(cirrus_reset, s);
3145
    cirrus_reset(s);
3146
}
3147

    
3148
/***************************************
3149
 *
3150
 *  ISA bus support
3151
 *
3152
 ***************************************/
3153

    
3154
void isa_cirrus_vga_init(void)
3155
{
3156
    CirrusVGAState *s;
3157

    
3158
    s = qemu_mallocz(sizeof(CirrusVGAState));
3159

    
3160
    vga_common_init(&s->vga, VGA_RAM_SIZE);
3161
    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
3162
    s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
3163
                                     s->vga.screen_dump, s->vga.text_update,
3164
                                     &s->vga);
3165
    vmstate_register(0, &vmstate_cirrus_vga, s);
3166
    rom_add_vga(VGABIOS_CIRRUS_FILENAME);
3167
    /* XXX ISA-LFB support */
3168
}
3169

    
3170
/***************************************
3171
 *
3172
 *  PCI bus support
3173
 *
3174
 ***************************************/
3175

    
3176
static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
3177
                               uint32_t addr, uint32_t size, int type)
3178
{
3179
    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
3180

    
3181
    /* XXX: add byte swapping apertures */
3182
    cpu_register_physical_memory(addr, s->vga.vram_size,
3183
                                 s->cirrus_linear_io_addr);
3184
    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
3185
                                 s->cirrus_linear_bitblt_io_addr);
3186

    
3187
    s->vga.map_addr = s->vga.map_end = 0;
3188
    s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
3189
    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
3190
    /* account for overflow */
3191
    if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
3192
        s->vga.lfb_end = addr + VGA_RAM_SIZE;
3193

    
3194
    vga_dirty_log_start(&s->vga);
3195
}
3196

    
3197
static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
3198
                                uint32_t addr, uint32_t size, int type)
3199
{
3200
    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
3201

    
3202
    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
3203
                                 s->cirrus_mmio_io_addr);
3204
}
3205

    
3206
static void pci_cirrus_write_config(PCIDevice *d,
3207
                                    uint32_t address, uint32_t val, int len)
3208
{
3209
    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
3210
    CirrusVGAState *s = &pvs->cirrus_vga;
3211

    
3212
    pci_default_write_config(d, address, val, len);
3213
    if (s->vga.map_addr && d->io_regions[0].addr == -1)
3214
        s->vga.map_addr = 0;
3215
    cirrus_update_memory_access(s);
3216
}
3217

    
3218
static int pci_cirrus_vga_initfn(PCIDevice *dev)
3219
{
3220
     PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
3221
     CirrusVGAState *s = &d->cirrus_vga;
3222
     uint8_t *pci_conf = d->dev.config;
3223
     int device_id = CIRRUS_ID_CLGD5446;
3224

    
3225
     /* setup VGA */
3226
     vga_common_init(&s->vga, VGA_RAM_SIZE);
3227
     cirrus_init_common(s, device_id, 1);
3228
     s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
3229
                                      s->vga.screen_dump, s->vga.text_update,
3230
                                      &s->vga);
3231

    
3232
     /* setup PCI */
3233
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
3234
     pci_config_set_device_id(pci_conf, device_id);
3235
     pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
3236
     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
3237
     pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
3238

    
3239
     /* setup memory space */
3240
     /* memory #0 LFB */
3241
     /* memory #1 memory-mapped I/O */
3242
     /* XXX: s->vga.vram_size must be a power of two */
3243
     pci_register_bar((PCIDevice *)d, 0, 0x2000000,
3244
                      PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
3245
     if (device_id == CIRRUS_ID_CLGD5446) {
3246
         pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
3247
                          PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
3248
     }
3249
     vmstate_register(0, &vmstate_pci_cirrus_vga, d);
3250

    
3251
     /* ROM BIOS */
3252
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
3253
     return 0;
3254
}
3255

    
3256
void pci_cirrus_vga_init(PCIBus *bus)
3257
{
3258
    pci_create_simple(bus, -1, "Cirrus VGA");
3259
}
3260

    
3261
static PCIDeviceInfo cirrus_vga_info = {
3262
    .qdev.name    = "Cirrus VGA",
3263
    .qdev.size    = sizeof(PCICirrusVGAState),
3264
    .init         = pci_cirrus_vga_initfn,
3265
    .config_write = pci_cirrus_write_config,
3266
};
3267

    
3268
static void cirrus_vga_register(void)
3269
{
3270
    pci_qdev_register(&cirrus_vga_info);
3271
}
3272
device_init(cirrus_vga_register);