Statistics
| Branch: | Revision:

root / hw / cirrus_vga.c @ deb54399

History | View | Annotate | Download (100 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

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

    
43
//#define DEBUG_CIRRUS
44
//#define DEBUG_BITBLT
45

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

    
52
#define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
53

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

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

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

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

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

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

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

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

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

    
137
#define CIRRUS_ROP_NOP_INDEX 2
138
#define CIRRUS_ROP_SRC_INDEX 5
139

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

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

    
176
// PCI 0x02: device
177
#define PCI_DEVICE_CLGD5462           0x00d0
178
#define PCI_DEVICE_CLGD5465           0x00d6
179

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

    
216
#define CIRRUS_PNPMMIO_SIZE         0x1000
217

    
218

    
219
/* I/O and memory hook */
220
#define CIRRUS_HOOK_NOT_HANDLED 0
221
#define CIRRUS_HOOK_HANDLED 1
222

    
223
#define ABS(a) ((signed)(a) > 0 ? a : -a)
224

    
225
#define BLTUNSAFE(s) \
226
    ( \
227
        ( /* check dst is within bounds */ \
228
            (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
229
                + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
230
                    (s)->vram_size \
231
        ) || \
232
        ( /* check src is within bounds */ \
233
            (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
234
                + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
235
                    (s)->vram_size \
236
        ) \
237
    )
238

    
239
struct CirrusVGAState;
240
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
241
                                     uint8_t * dst, const uint8_t * src,
242
                                     int dstpitch, int srcpitch,
243
                                     int bltwidth, int bltheight);
244
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
245
                              uint8_t *dst, int dst_pitch, int width, int height);
246

    
247
typedef struct CirrusVGAState {
248
    VGA_STATE_COMMON
249

    
250
    int cirrus_linear_io_addr;
251
    int cirrus_linear_bitblt_io_addr;
252
    int cirrus_mmio_io_addr;
253
    uint32_t cirrus_addr_mask;
254
    uint32_t linear_mmio_mask;
255
    uint8_t cirrus_shadow_gr0;
256
    uint8_t cirrus_shadow_gr1;
257
    uint8_t cirrus_hidden_dac_lockindex;
258
    uint8_t cirrus_hidden_dac_data;
259
    uint32_t cirrus_bank_base[2];
260
    uint32_t cirrus_bank_limit[2];
261
    uint8_t cirrus_hidden_palette[48];
262
    uint32_t hw_cursor_x;
263
    uint32_t hw_cursor_y;
264
    int cirrus_blt_pixelwidth;
265
    int cirrus_blt_width;
266
    int cirrus_blt_height;
267
    int cirrus_blt_dstpitch;
268
    int cirrus_blt_srcpitch;
269
    uint32_t cirrus_blt_fgcol;
270
    uint32_t cirrus_blt_bgcol;
271
    uint32_t cirrus_blt_dstaddr;
272
    uint32_t cirrus_blt_srcaddr;
273
    uint8_t cirrus_blt_mode;
274
    uint8_t cirrus_blt_modeext;
275
    cirrus_bitblt_rop_t cirrus_rop;
276
#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
277
    uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
278
    uint8_t *cirrus_srcptr;
279
    uint8_t *cirrus_srcptr_end;
280
    uint32_t cirrus_srccounter;
281
    /* hwcursor display state */
282
    int last_hw_cursor_size;
283
    int last_hw_cursor_x;
284
    int last_hw_cursor_y;
285
    int last_hw_cursor_y_start;
286
    int last_hw_cursor_y_end;
287
    int real_vram_size; /* XXX: suppress that */
288
    CPUWriteMemoryFunc **cirrus_linear_write;
289
    int device_id;
290
    int bustype;
291
} CirrusVGAState;
292

    
293
typedef struct PCICirrusVGAState {
294
    PCIDevice dev;
295
    CirrusVGAState cirrus_vga;
296
} PCICirrusVGAState;
297

    
298
static uint8_t rop_to_index[256];
299

    
300
/***************************************
301
 *
302
 *  prototypes.
303
 *
304
 ***************************************/
305

    
306

    
307
static void cirrus_bitblt_reset(CirrusVGAState *s);
308
static void cirrus_update_memory_access(CirrusVGAState *s);
309

    
310
/***************************************
311
 *
312
 *  raster operations
313
 *
314
 ***************************************/
315

    
316
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
317
                                  uint8_t *dst,const uint8_t *src,
318
                                  int dstpitch,int srcpitch,
319
                                  int bltwidth,int bltheight)
320
{
321
}
322

    
323
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
324
                                   uint8_t *dst,
325
                                   int dstpitch, int bltwidth,int bltheight)
326
{
327
}
328

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

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

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

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

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

    
349
#define ROP_NAME 1
350
#define ROP_OP(d, s) d = ~0
351
#include "cirrus_vga_rop.h"
352

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

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

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

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

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

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

    
377
#define ROP_NAME notsrc
378
#define ROP_OP(d, s) d = (~(s))
379
#include "cirrus_vga_rop.h"
380

    
381
#define ROP_NAME notsrc_or_dst
382
#define ROP_OP(d, s) d = (~(s)) | (d)
383
#include "cirrus_vga_rop.h"
384

    
385
#define ROP_NAME notsrc_and_notdst
386
#define ROP_OP(d, s) d = (~(s)) & (~(d))
387
#include "cirrus_vga_rop.h"
388

    
389
static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
390
    cirrus_bitblt_rop_fwd_0,
391
    cirrus_bitblt_rop_fwd_src_and_dst,
392
    cirrus_bitblt_rop_nop,
393
    cirrus_bitblt_rop_fwd_src_and_notdst,
394
    cirrus_bitblt_rop_fwd_notdst,
395
    cirrus_bitblt_rop_fwd_src,
396
    cirrus_bitblt_rop_fwd_1,
397
    cirrus_bitblt_rop_fwd_notsrc_and_dst,
398
    cirrus_bitblt_rop_fwd_src_xor_dst,
399
    cirrus_bitblt_rop_fwd_src_or_dst,
400
    cirrus_bitblt_rop_fwd_notsrc_or_notdst,
401
    cirrus_bitblt_rop_fwd_src_notxor_dst,
402
    cirrus_bitblt_rop_fwd_src_or_notdst,
403
    cirrus_bitblt_rop_fwd_notsrc,
404
    cirrus_bitblt_rop_fwd_notsrc_or_dst,
405
    cirrus_bitblt_rop_fwd_notsrc_and_notdst,
406
};
407

    
408
static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
409
    cirrus_bitblt_rop_bkwd_0,
410
    cirrus_bitblt_rop_bkwd_src_and_dst,
411
    cirrus_bitblt_rop_nop,
412
    cirrus_bitblt_rop_bkwd_src_and_notdst,
413
    cirrus_bitblt_rop_bkwd_notdst,
414
    cirrus_bitblt_rop_bkwd_src,
415
    cirrus_bitblt_rop_bkwd_1,
416
    cirrus_bitblt_rop_bkwd_notsrc_and_dst,
417
    cirrus_bitblt_rop_bkwd_src_xor_dst,
418
    cirrus_bitblt_rop_bkwd_src_or_dst,
419
    cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
420
    cirrus_bitblt_rop_bkwd_src_notxor_dst,
421
    cirrus_bitblt_rop_bkwd_src_or_notdst,
422
    cirrus_bitblt_rop_bkwd_notsrc,
423
    cirrus_bitblt_rop_bkwd_notsrc_or_dst,
424
    cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
425
};
426

    
427
#define TRANSP_ROP(name) {\
428
    name ## _8,\
429
    name ## _16,\
430
        }
431
#define TRANSP_NOP(func) {\
432
    func,\
433
    func,\
434
        }
435

    
436
static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
437
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
438
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
439
    TRANSP_NOP(cirrus_bitblt_rop_nop),
440
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
441
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
442
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
443
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
444
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
445
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
446
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
447
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
448
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
449
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
450
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
451
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
452
    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
453
};
454

    
455
static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
456
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
457
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
458
    TRANSP_NOP(cirrus_bitblt_rop_nop),
459
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
460
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
461
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
462
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
463
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
464
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
465
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
466
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
467
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
468
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
469
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
470
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
471
    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
472
};
473

    
474
#define ROP2(name) {\
475
    name ## _8,\
476
    name ## _16,\
477
    name ## _24,\
478
    name ## _32,\
479
        }
480

    
481
#define ROP_NOP2(func) {\
482
    func,\
483
    func,\
484
    func,\
485
    func,\
486
        }
487

    
488
static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
489
    ROP2(cirrus_patternfill_0),
490
    ROP2(cirrus_patternfill_src_and_dst),
491
    ROP_NOP2(cirrus_bitblt_rop_nop),
492
    ROP2(cirrus_patternfill_src_and_notdst),
493
    ROP2(cirrus_patternfill_notdst),
494
    ROP2(cirrus_patternfill_src),
495
    ROP2(cirrus_patternfill_1),
496
    ROP2(cirrus_patternfill_notsrc_and_dst),
497
    ROP2(cirrus_patternfill_src_xor_dst),
498
    ROP2(cirrus_patternfill_src_or_dst),
499
    ROP2(cirrus_patternfill_notsrc_or_notdst),
500
    ROP2(cirrus_patternfill_src_notxor_dst),
501
    ROP2(cirrus_patternfill_src_or_notdst),
502
    ROP2(cirrus_patternfill_notsrc),
503
    ROP2(cirrus_patternfill_notsrc_or_dst),
504
    ROP2(cirrus_patternfill_notsrc_and_notdst),
505
};
506

    
507
static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
508
    ROP2(cirrus_colorexpand_transp_0),
509
    ROP2(cirrus_colorexpand_transp_src_and_dst),
510
    ROP_NOP2(cirrus_bitblt_rop_nop),
511
    ROP2(cirrus_colorexpand_transp_src_and_notdst),
512
    ROP2(cirrus_colorexpand_transp_notdst),
513
    ROP2(cirrus_colorexpand_transp_src),
514
    ROP2(cirrus_colorexpand_transp_1),
515
    ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
516
    ROP2(cirrus_colorexpand_transp_src_xor_dst),
517
    ROP2(cirrus_colorexpand_transp_src_or_dst),
518
    ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
519
    ROP2(cirrus_colorexpand_transp_src_notxor_dst),
520
    ROP2(cirrus_colorexpand_transp_src_or_notdst),
521
    ROP2(cirrus_colorexpand_transp_notsrc),
522
    ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
523
    ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
524
};
525

    
526
static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
527
    ROP2(cirrus_colorexpand_0),
528
    ROP2(cirrus_colorexpand_src_and_dst),
529
    ROP_NOP2(cirrus_bitblt_rop_nop),
530
    ROP2(cirrus_colorexpand_src_and_notdst),
531
    ROP2(cirrus_colorexpand_notdst),
532
    ROP2(cirrus_colorexpand_src),
533
    ROP2(cirrus_colorexpand_1),
534
    ROP2(cirrus_colorexpand_notsrc_and_dst),
535
    ROP2(cirrus_colorexpand_src_xor_dst),
536
    ROP2(cirrus_colorexpand_src_or_dst),
537
    ROP2(cirrus_colorexpand_notsrc_or_notdst),
538
    ROP2(cirrus_colorexpand_src_notxor_dst),
539
    ROP2(cirrus_colorexpand_src_or_notdst),
540
    ROP2(cirrus_colorexpand_notsrc),
541
    ROP2(cirrus_colorexpand_notsrc_or_dst),
542
    ROP2(cirrus_colorexpand_notsrc_and_notdst),
543
};
544

    
545
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
546
    ROP2(cirrus_colorexpand_pattern_transp_0),
547
    ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
548
    ROP_NOP2(cirrus_bitblt_rop_nop),
549
    ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
550
    ROP2(cirrus_colorexpand_pattern_transp_notdst),
551
    ROP2(cirrus_colorexpand_pattern_transp_src),
552
    ROP2(cirrus_colorexpand_pattern_transp_1),
553
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
554
    ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
555
    ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
556
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
557
    ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
558
    ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
559
    ROP2(cirrus_colorexpand_pattern_transp_notsrc),
560
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
561
    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
562
};
563

    
564
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
565
    ROP2(cirrus_colorexpand_pattern_0),
566
    ROP2(cirrus_colorexpand_pattern_src_and_dst),
567
    ROP_NOP2(cirrus_bitblt_rop_nop),
568
    ROP2(cirrus_colorexpand_pattern_src_and_notdst),
569
    ROP2(cirrus_colorexpand_pattern_notdst),
570
    ROP2(cirrus_colorexpand_pattern_src),
571
    ROP2(cirrus_colorexpand_pattern_1),
572
    ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
573
    ROP2(cirrus_colorexpand_pattern_src_xor_dst),
574
    ROP2(cirrus_colorexpand_pattern_src_or_dst),
575
    ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
576
    ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
577
    ROP2(cirrus_colorexpand_pattern_src_or_notdst),
578
    ROP2(cirrus_colorexpand_pattern_notsrc),
579
    ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
580
    ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
581
};
582

    
583
static const cirrus_fill_t cirrus_fill[16][4] = {
584
    ROP2(cirrus_fill_0),
585
    ROP2(cirrus_fill_src_and_dst),
586
    ROP_NOP2(cirrus_bitblt_fill_nop),
587
    ROP2(cirrus_fill_src_and_notdst),
588
    ROP2(cirrus_fill_notdst),
589
    ROP2(cirrus_fill_src),
590
    ROP2(cirrus_fill_1),
591
    ROP2(cirrus_fill_notsrc_and_dst),
592
    ROP2(cirrus_fill_src_xor_dst),
593
    ROP2(cirrus_fill_src_or_dst),
594
    ROP2(cirrus_fill_notsrc_or_notdst),
595
    ROP2(cirrus_fill_src_notxor_dst),
596
    ROP2(cirrus_fill_src_or_notdst),
597
    ROP2(cirrus_fill_notsrc),
598
    ROP2(cirrus_fill_notsrc_or_dst),
599
    ROP2(cirrus_fill_notsrc_and_notdst),
600
};
601

    
602
static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
603
{
604
    unsigned int color;
605
    switch (s->cirrus_blt_pixelwidth) {
606
    case 1:
607
        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
608
        break;
609
    case 2:
610
        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);
611
        s->cirrus_blt_fgcol = le16_to_cpu(color);
612
        break;
613
    case 3:
614
        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
615
            (s->gr[0x11] << 8) | (s->gr[0x13] << 16);
616
        break;
617
    default:
618
    case 4:
619
        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |
620
            (s->gr[0x13] << 16) | (s->gr[0x15] << 24);
621
        s->cirrus_blt_fgcol = le32_to_cpu(color);
622
        break;
623
    }
624
}
625

    
626
static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
627
{
628
    unsigned int color;
629
    switch (s->cirrus_blt_pixelwidth) {
630
    case 1:
631
        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
632
        break;
633
    case 2:
634
        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);
635
        s->cirrus_blt_bgcol = le16_to_cpu(color);
636
        break;
637
    case 3:
638
        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
639
            (s->gr[0x10] << 8) | (s->gr[0x12] << 16);
640
        break;
641
    default:
642
    case 4:
643
        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |
644
            (s->gr[0x12] << 16) | (s->gr[0x14] << 24);
645
        s->cirrus_blt_bgcol = le32_to_cpu(color);
646
        break;
647
    }
648
}
649

    
650
static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
651
                                     int off_pitch, int bytesperline,
652
                                     int lines)
653
{
654
    int y;
655
    int off_cur;
656
    int off_cur_end;
657

    
658
    for (y = 0; y < lines; y++) {
659
        off_cur = off_begin;
660
        off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
661
        off_cur &= TARGET_PAGE_MASK;
662
        while (off_cur < off_cur_end) {
663
            cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
664
            off_cur += TARGET_PAGE_SIZE;
665
        }
666
        off_begin += off_pitch;
667
    }
668
}
669

    
670
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
671
                                            const uint8_t * src)
672
{
673
    uint8_t *dst;
674

    
675
    dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
676

    
677
    if (BLTUNSAFE(s))
678
        return 0;
679

    
680
    (*s->cirrus_rop) (s, dst, src,
681
                      s->cirrus_blt_dstpitch, 0,
682
                      s->cirrus_blt_width, s->cirrus_blt_height);
683
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
684
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
685
                             s->cirrus_blt_height);
686
    return 1;
687
}
688

    
689
/* fill */
690

    
691
static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
692
{
693
    cirrus_fill_t rop_func;
694

    
695
    if (BLTUNSAFE(s))
696
        return 0;
697
    rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
698
    rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
699
             s->cirrus_blt_dstpitch,
700
             s->cirrus_blt_width, s->cirrus_blt_height);
701
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
702
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
703
                             s->cirrus_blt_height);
704
    cirrus_bitblt_reset(s);
705
    return 1;
706
}
707

    
708
/***************************************
709
 *
710
 *  bitblt (video-to-video)
711
 *
712
 ***************************************/
713

    
714
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
715
{
716
    return cirrus_bitblt_common_patterncopy(s,
717
                                            s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
718
                                            s->cirrus_addr_mask));
719
}
720

    
721
static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
722
{
723
    int sx, sy;
724
    int dx, dy;
725
    int width, height;
726
    int depth;
727
    int notify = 0;
728

    
729
    depth = s->get_bpp((VGAState *)s) / 8;
730
    s->get_resolution((VGAState *)s, &width, &height);
731

    
732
    /* extra x, y */
733
    sx = (src % (width * depth)) / depth;
734
    sy = (src / (width * depth));
735
    dx = (dst % (width *depth)) / depth;
736
    dy = (dst / (width * depth));
737

    
738
    /* normalize width */
739
    w /= depth;
740

    
741
    /* if we're doing a backward copy, we have to adjust
742
       our x/y to be the upper left corner (instead of the lower
743
       right corner) */
744
    if (s->cirrus_blt_dstpitch < 0) {
745
        sx -= (s->cirrus_blt_width / depth) - 1;
746
        dx -= (s->cirrus_blt_width / depth) - 1;
747
        sy -= s->cirrus_blt_height - 1;
748
        dy -= s->cirrus_blt_height - 1;
749
    }
750

    
751
    /* are we in the visible portion of memory? */
752
    if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
753
        (sx + w) <= width && (sy + h) <= height &&
754
        (dx + w) <= width && (dy + h) <= height) {
755
        notify = 1;
756
    }
757

    
758
    /* make to sure only copy if it's a plain copy ROP */
759
    if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&
760
        *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)
761
        notify = 0;
762

    
763
    /* we have to flush all pending changes so that the copy
764
       is generated at the appropriate moment in time */
765
    if (notify)
766
        vga_hw_update();
767

    
768
    (*s->cirrus_rop) (s, s->vram_ptr +
769
                      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
770
                      s->vram_ptr +
771
                      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
772
                      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
773
                      s->cirrus_blt_width, s->cirrus_blt_height);
774

    
775
    if (notify)
776
        qemu_console_copy(s->ds,
777
                          sx, sy, dx, dy,
778
                          s->cirrus_blt_width / depth,
779
                          s->cirrus_blt_height);
780

    
781
    /* we don't have to notify the display that this portion has
782
       changed since qemu_console_copy implies this */
783

    
784
    if (!notify)
785
        cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
786
                                 s->cirrus_blt_dstpitch, s->cirrus_blt_width,
787
                                 s->cirrus_blt_height);
788
}
789

    
790
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
791
{
792
    if (BLTUNSAFE(s))
793
        return 0;
794

    
795
    cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
796
            s->cirrus_blt_srcaddr - s->start_addr,
797
            s->cirrus_blt_width, s->cirrus_blt_height);
798

    
799
    return 1;
800
}
801

    
802
/***************************************
803
 *
804
 *  bitblt (cpu-to-video)
805
 *
806
 ***************************************/
807

    
808
static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
809
{
810
    int copy_count;
811
    uint8_t *end_ptr;
812

    
813
    if (s->cirrus_srccounter > 0) {
814
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
815
            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
816
        the_end:
817
            s->cirrus_srccounter = 0;
818
            cirrus_bitblt_reset(s);
819
        } else {
820
            /* at least one scan line */
821
            do {
822
                (*s->cirrus_rop)(s, s->vram_ptr +
823
                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
824
                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
825
                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
826
                                         s->cirrus_blt_width, 1);
827
                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
828
                s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
829
                if (s->cirrus_srccounter <= 0)
830
                    goto the_end;
831
                /* more bytes than needed can be transfered because of
832
                   word alignment, so we keep them for the next line */
833
                /* XXX: keep alignment to speed up transfer */
834
                end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
835
                copy_count = s->cirrus_srcptr_end - end_ptr;
836
                memmove(s->cirrus_bltbuf, end_ptr, copy_count);
837
                s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
838
                s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
839
            } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
840
        }
841
    }
842
}
843

    
844
/***************************************
845
 *
846
 *  bitblt wrapper
847
 *
848
 ***************************************/
849

    
850
static void cirrus_bitblt_reset(CirrusVGAState * s)
851
{
852
    int need_update;
853

    
854
    s->gr[0x31] &=
855
        ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
856
    need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
857
        || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
858
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
859
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
860
    s->cirrus_srccounter = 0;
861
    if (!need_update)
862
        return;
863
    cirrus_update_memory_access(s);
864
}
865

    
866
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
867
{
868
    int w;
869

    
870
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
871
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
872
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
873

    
874
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
875
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
876
            s->cirrus_blt_srcpitch = 8;
877
        } else {
878
            /* XXX: check for 24 bpp */
879
            s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
880
        }
881
        s->cirrus_srccounter = s->cirrus_blt_srcpitch;
882
    } else {
883
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
884
            w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
885
            if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
886
                s->cirrus_blt_srcpitch = ((w + 31) >> 5);
887
            else
888
                s->cirrus_blt_srcpitch = ((w + 7) >> 3);
889
        } else {
890
            /* always align input size to 32 bits */
891
            s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
892
        }
893
        s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
894
    }
895
    s->cirrus_srcptr = s->cirrus_bltbuf;
896
    s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
897
    cirrus_update_memory_access(s);
898
    return 1;
899
}
900

    
901
static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
902
{
903
    /* XXX */
904
#ifdef DEBUG_BITBLT
905
    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
906
#endif
907
    return 0;
908
}
909

    
910
static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
911
{
912
    int ret;
913

    
914
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
915
        ret = cirrus_bitblt_videotovideo_patterncopy(s);
916
    } else {
917
        ret = cirrus_bitblt_videotovideo_copy(s);
918
    }
919
    if (ret)
920
        cirrus_bitblt_reset(s);
921
    return ret;
922
}
923

    
924
static void cirrus_bitblt_start(CirrusVGAState * s)
925
{
926
    uint8_t blt_rop;
927

    
928
    s->gr[0x31] |= CIRRUS_BLT_BUSY;
929

    
930
    s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
931
    s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
932
    s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
933
    s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));
934
    s->cirrus_blt_dstaddr =
935
        (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));
936
    s->cirrus_blt_srcaddr =
937
        (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
938
    s->cirrus_blt_mode = s->gr[0x30];
939
    s->cirrus_blt_modeext = s->gr[0x33];
940
    blt_rop = s->gr[0x32];
941

    
942
#ifdef DEBUG_BITBLT
943
    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",
944
           blt_rop,
945
           s->cirrus_blt_mode,
946
           s->cirrus_blt_modeext,
947
           s->cirrus_blt_width,
948
           s->cirrus_blt_height,
949
           s->cirrus_blt_dstpitch,
950
           s->cirrus_blt_srcpitch,
951
           s->cirrus_blt_dstaddr,
952
           s->cirrus_blt_srcaddr,
953
           s->gr[0x2f]);
954
#endif
955

    
956
    switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
957
    case CIRRUS_BLTMODE_PIXELWIDTH8:
958
        s->cirrus_blt_pixelwidth = 1;
959
        break;
960
    case CIRRUS_BLTMODE_PIXELWIDTH16:
961
        s->cirrus_blt_pixelwidth = 2;
962
        break;
963
    case CIRRUS_BLTMODE_PIXELWIDTH24:
964
        s->cirrus_blt_pixelwidth = 3;
965
        break;
966
    case CIRRUS_BLTMODE_PIXELWIDTH32:
967
        s->cirrus_blt_pixelwidth = 4;
968
        break;
969
    default:
970
#ifdef DEBUG_BITBLT
971
        printf("cirrus: bitblt - pixel width is unknown\n");
972
#endif
973
        goto bitblt_ignore;
974
    }
975
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
976

    
977
    if ((s->
978
         cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
979
                            CIRRUS_BLTMODE_MEMSYSDEST))
980
        == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
981
#ifdef DEBUG_BITBLT
982
        printf("cirrus: bitblt - memory-to-memory copy is requested\n");
983
#endif
984
        goto bitblt_ignore;
985
    }
986

    
987
    if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
988
        (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
989
                               CIRRUS_BLTMODE_TRANSPARENTCOMP |
990
                               CIRRUS_BLTMODE_PATTERNCOPY |
991
                               CIRRUS_BLTMODE_COLOREXPAND)) ==
992
         (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
993
        cirrus_bitblt_fgcol(s);
994
        cirrus_bitblt_solidfill(s, blt_rop);
995
    } else {
996
        if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
997
                                   CIRRUS_BLTMODE_PATTERNCOPY)) ==
998
            CIRRUS_BLTMODE_COLOREXPAND) {
999

    
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_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[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1010
            }
1011
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
1012
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
1013
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
1014
                    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
1015
                        cirrus_bitblt_bgcol(s);
1016
                    else
1017
                        cirrus_bitblt_fgcol(s);
1018
                    s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1019
                } else {
1020
                    cirrus_bitblt_fgcol(s);
1021
                    cirrus_bitblt_bgcol(s);
1022
                    s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1023
                }
1024
            } else {
1025
                s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1026
            }
1027
        } else {
1028
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
1029
                if (s->cirrus_blt_pixelwidth > 2) {
1030
                    printf("src transparent without colorexpand must be 8bpp or 16bpp\n");
1031
                    goto bitblt_ignore;
1032
                }
1033
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
1034
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
1035
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
1036
                    s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1037
                } else {
1038
                    s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
1039
                }
1040
            } else {
1041
                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
1042
                    s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
1043
                    s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
1044
                    s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
1045
                } else {
1046
                    s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
1047
                }
1048
            }
1049
        }
1050
        // setup bitblt engine.
1051
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
1052
            if (!cirrus_bitblt_cputovideo(s))
1053
                goto bitblt_ignore;
1054
        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
1055
            if (!cirrus_bitblt_videotocpu(s))
1056
                goto bitblt_ignore;
1057
        } else {
1058
            if (!cirrus_bitblt_videotovideo(s))
1059
                goto bitblt_ignore;
1060
        }
1061
    }
1062
    return;
1063
  bitblt_ignore:;
1064
    cirrus_bitblt_reset(s);
1065
}
1066

    
1067
static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1068
{
1069
    unsigned old_value;
1070

    
1071
    old_value = s->gr[0x31];
1072
    s->gr[0x31] = reg_value;
1073

    
1074
    if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1075
        ((reg_value & CIRRUS_BLT_RESET) == 0)) {
1076
        cirrus_bitblt_reset(s);
1077
    } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1078
               ((reg_value & CIRRUS_BLT_START) != 0)) {
1079
        cirrus_bitblt_start(s);
1080
    }
1081
}
1082

    
1083

    
1084
/***************************************
1085
 *
1086
 *  basic parameters
1087
 *
1088
 ***************************************/
1089

    
1090
static void cirrus_get_offsets(VGAState *s1,
1091
                               uint32_t *pline_offset,
1092
                               uint32_t *pstart_addr,
1093
                               uint32_t *pline_compare)
1094
{
1095
    CirrusVGAState * s = (CirrusVGAState *)s1;
1096
    uint32_t start_addr, line_offset, line_compare;
1097

    
1098
    line_offset = s->cr[0x13]
1099
        | ((s->cr[0x1b] & 0x10) << 4);
1100
    line_offset <<= 3;
1101
    *pline_offset = line_offset;
1102

    
1103
    start_addr = (s->cr[0x0c] << 8)
1104
        | s->cr[0x0d]
1105
        | ((s->cr[0x1b] & 0x01) << 16)
1106
        | ((s->cr[0x1b] & 0x0c) << 15)
1107
        | ((s->cr[0x1d] & 0x80) << 12);
1108
    *pstart_addr = start_addr;
1109

    
1110
    line_compare = s->cr[0x18] |
1111
        ((s->cr[0x07] & 0x10) << 4) |
1112
        ((s->cr[0x09] & 0x40) << 3);
1113
    *pline_compare = line_compare;
1114
}
1115

    
1116
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1117
{
1118
    uint32_t ret = 16;
1119

    
1120
    switch (s->cirrus_hidden_dac_data & 0xf) {
1121
    case 0:
1122
        ret = 15;
1123
        break;                        /* Sierra HiColor */
1124
    case 1:
1125
        ret = 16;
1126
        break;                        /* XGA HiColor */
1127
    default:
1128
#ifdef DEBUG_CIRRUS
1129
        printf("cirrus: invalid DAC value %x in 16bpp\n",
1130
               (s->cirrus_hidden_dac_data & 0xf));
1131
#endif
1132
        ret = 15;                /* XXX */
1133
        break;
1134
    }
1135
    return ret;
1136
}
1137

    
1138
static int cirrus_get_bpp(VGAState *s1)
1139
{
1140
    CirrusVGAState * s = (CirrusVGAState *)s1;
1141
    uint32_t ret = 8;
1142

    
1143
    if ((s->sr[0x07] & 0x01) != 0) {
1144
        /* Cirrus SVGA */
1145
        switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1146
        case CIRRUS_SR7_BPP_8:
1147
            ret = 8;
1148
            break;
1149
        case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1150
            ret = cirrus_get_bpp16_depth(s);
1151
            break;
1152
        case CIRRUS_SR7_BPP_24:
1153
            ret = 24;
1154
            break;
1155
        case CIRRUS_SR7_BPP_16:
1156
            ret = cirrus_get_bpp16_depth(s);
1157
            break;
1158
        case CIRRUS_SR7_BPP_32:
1159
            ret = 32;
1160
            break;
1161
        default:
1162
#ifdef DEBUG_CIRRUS
1163
            printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);
1164
#endif
1165
            ret = 8;
1166
            break;
1167
        }
1168
    } else {
1169
        /* VGA */
1170
        ret = 0;
1171
    }
1172

    
1173
    return ret;
1174
}
1175

    
1176
static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight)
1177
{
1178
    int width, height;
1179

    
1180
    width = (s->cr[0x01] + 1) * 8;
1181
    height = s->cr[0x12] |
1182
        ((s->cr[0x07] & 0x02) << 7) |
1183
        ((s->cr[0x07] & 0x40) << 3);
1184
    height = (height + 1);
1185
    /* interlace support */
1186
    if (s->cr[0x1a] & 0x01)
1187
        height = height * 2;
1188
    *pwidth = width;
1189
    *pheight = height;
1190
}
1191

    
1192
/***************************************
1193
 *
1194
 * bank memory
1195
 *
1196
 ***************************************/
1197

    
1198
static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1199
{
1200
    unsigned offset;
1201
    unsigned limit;
1202

    
1203
    if ((s->gr[0x0b] & 0x01) != 0)        /* dual bank */
1204
        offset = s->gr[0x09 + bank_index];
1205
    else                        /* single bank */
1206
        offset = s->gr[0x09];
1207

    
1208
    if ((s->gr[0x0b] & 0x20) != 0)
1209
        offset <<= 14;
1210
    else
1211
        offset <<= 12;
1212

    
1213
    if (s->real_vram_size <= offset)
1214
        limit = 0;
1215
    else
1216
        limit = s->real_vram_size - offset;
1217

    
1218
    if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1219
        if (limit > 0x8000) {
1220
            offset += 0x8000;
1221
            limit -= 0x8000;
1222
        } else {
1223
            limit = 0;
1224
        }
1225
    }
1226

    
1227
    if (limit > 0) {
1228
        /* Thinking about changing bank base? First, drop the dirty bitmap information
1229
         * on the current location, otherwise we lose this pointer forever */
1230
        if (s->lfb_vram_mapped) {
1231
            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
1232
            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
1233
        }
1234
        s->cirrus_bank_base[bank_index] = offset;
1235
        s->cirrus_bank_limit[bank_index] = limit;
1236
    } else {
1237
        s->cirrus_bank_base[bank_index] = 0;
1238
        s->cirrus_bank_limit[bank_index] = 0;
1239
    }
1240
}
1241

    
1242
/***************************************
1243
 *
1244
 *  I/O access between 0x3c4-0x3c5
1245
 *
1246
 ***************************************/
1247

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

    
1318
    return CIRRUS_HOOK_HANDLED;
1319
}
1320

    
1321
static int
1322
cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1323
{
1324
    switch (reg_index) {
1325
    case 0x00:                        // Standard VGA
1326
    case 0x01:                        // Standard VGA
1327
    case 0x02:                        // Standard VGA
1328
    case 0x03:                        // Standard VGA
1329
    case 0x04:                        // Standard VGA
1330
        return CIRRUS_HOOK_NOT_HANDLED;
1331
    case 0x06:                        // Unlock Cirrus extensions
1332
        reg_value &= 0x17;
1333
        if (reg_value == 0x12) {
1334
            s->sr[reg_index] = 0x12;
1335
        } else {
1336
            s->sr[reg_index] = 0x0f;
1337
        }
1338
        break;
1339
    case 0x10:
1340
    case 0x30:
1341
    case 0x50:
1342
    case 0x70:                        // Graphics Cursor X
1343
    case 0x90:
1344
    case 0xb0:
1345
    case 0xd0:
1346
    case 0xf0:                        // Graphics Cursor X
1347
        s->sr[0x10] = reg_value;
1348
        s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);
1349
        break;
1350
    case 0x11:
1351
    case 0x31:
1352
    case 0x51:
1353
    case 0x71:                        // Graphics Cursor Y
1354
    case 0x91:
1355
    case 0xb1:
1356
    case 0xd1:
1357
    case 0xf1:                        // Graphics Cursor Y
1358
        s->sr[0x11] = reg_value;
1359
        s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
1360
        break;
1361
    case 0x07:                        // Extended Sequencer Mode
1362
    cirrus_update_memory_access(s);
1363
    case 0x08:                        // EEPROM Control
1364
    case 0x09:                        // Scratch Register 0
1365
    case 0x0a:                        // Scratch Register 1
1366
    case 0x0b:                        // VCLK 0
1367
    case 0x0c:                        // VCLK 1
1368
    case 0x0d:                        // VCLK 2
1369
    case 0x0e:                        // VCLK 3
1370
    case 0x0f:                        // DRAM Control
1371
    case 0x12:                        // Graphics Cursor Attribute
1372
    case 0x13:                        // Graphics Cursor Pattern Address
1373
    case 0x14:                        // Scratch Register 2
1374
    case 0x15:                        // Scratch Register 3
1375
    case 0x16:                        // Performance Tuning Register
1376
    case 0x18:                        // Signature Generator Control
1377
    case 0x19:                        // Signature Generator Result
1378
    case 0x1a:                        // Signature Generator Result
1379
    case 0x1b:                        // VCLK 0 Denominator & Post
1380
    case 0x1c:                        // VCLK 1 Denominator & Post
1381
    case 0x1d:                        // VCLK 2 Denominator & Post
1382
    case 0x1e:                        // VCLK 3 Denominator & Post
1383
    case 0x1f:                        // BIOS Write Enable and MCLK select
1384
        s->sr[reg_index] = reg_value;
1385
#ifdef DEBUG_CIRRUS
1386
        printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
1387
               reg_index, reg_value);
1388
#endif
1389
        break;
1390
    case 0x17:                        // Configuration Readback and Extended Control
1391
        s->sr[reg_index] = (s->sr[reg_index] & 0x38) | (reg_value & 0xc7);
1392
        cirrus_update_memory_access(s);
1393
        break;
1394
    default:
1395
#ifdef DEBUG_CIRRUS
1396
        printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
1397
               reg_value);
1398
#endif
1399
        break;
1400
    }
1401

    
1402
    return CIRRUS_HOOK_HANDLED;
1403
}
1404

    
1405
/***************************************
1406
 *
1407
 *  I/O access at 0x3c6
1408
 *
1409
 ***************************************/
1410

    
1411
static void cirrus_read_hidden_dac(CirrusVGAState * s, int *reg_value)
1412
{
1413
    *reg_value = 0xff;
1414
    if (++s->cirrus_hidden_dac_lockindex == 5) {
1415
        *reg_value = s->cirrus_hidden_dac_data;
1416
        s->cirrus_hidden_dac_lockindex = 0;
1417
    }
1418
}
1419

    
1420
static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1421
{
1422
    if (s->cirrus_hidden_dac_lockindex == 4) {
1423
        s->cirrus_hidden_dac_data = reg_value;
1424
#if defined(DEBUG_CIRRUS)
1425
        printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1426
#endif
1427
    }
1428
    s->cirrus_hidden_dac_lockindex = 0;
1429
}
1430

    
1431
/***************************************
1432
 *
1433
 *  I/O access at 0x3c9
1434
 *
1435
 ***************************************/
1436

    
1437
static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
1438
{
1439
    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1440
        return CIRRUS_HOOK_NOT_HANDLED;
1441
    *reg_value =
1442
        s->cirrus_hidden_palette[(s->dac_read_index & 0x0f) * 3 +
1443
                                 s->dac_sub_index];
1444
    if (++s->dac_sub_index == 3) {
1445
        s->dac_sub_index = 0;
1446
        s->dac_read_index++;
1447
    }
1448
    return CIRRUS_HOOK_HANDLED;
1449
}
1450

    
1451
static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
1452
{
1453
    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1454
        return CIRRUS_HOOK_NOT_HANDLED;
1455
    s->dac_cache[s->dac_sub_index] = reg_value;
1456
    if (++s->dac_sub_index == 3) {
1457
        memcpy(&s->cirrus_hidden_palette[(s->dac_write_index & 0x0f) * 3],
1458
               s->dac_cache, 3);
1459
        /* XXX update cursor */
1460
        s->dac_sub_index = 0;
1461
        s->dac_write_index++;
1462
    }
1463
    return CIRRUS_HOOK_HANDLED;
1464
}
1465

    
1466
/***************************************
1467
 *
1468
 *  I/O access between 0x3ce-0x3cf
1469
 *
1470
 ***************************************/
1471

    
1472
static int
1473
cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1474
{
1475
    switch (reg_index) {
1476
    case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1477
      *reg_value = s->cirrus_shadow_gr0;
1478
      return CIRRUS_HOOK_HANDLED;
1479
    case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1480
      *reg_value = s->cirrus_shadow_gr1;
1481
      return CIRRUS_HOOK_HANDLED;
1482
    case 0x02:                        // Standard VGA
1483
    case 0x03:                        // Standard VGA
1484
    case 0x04:                        // Standard VGA
1485
    case 0x06:                        // Standard VGA
1486
    case 0x07:                        // Standard VGA
1487
    case 0x08:                        // Standard VGA
1488
        return CIRRUS_HOOK_NOT_HANDLED;
1489
    case 0x05:                        // Standard VGA, Cirrus extended mode
1490
    default:
1491
        break;
1492
    }
1493

    
1494
    if (reg_index < 0x3a) {
1495
        *reg_value = s->gr[reg_index];
1496
    } else {
1497
#ifdef DEBUG_CIRRUS
1498
        printf("cirrus: inport gr_index %02x\n", reg_index);
1499
#endif
1500
        *reg_value = 0xff;
1501
    }
1502

    
1503
    return CIRRUS_HOOK_HANDLED;
1504
}
1505

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

    
1594
    return CIRRUS_HOOK_HANDLED;
1595
}
1596

    
1597
/***************************************
1598
 *
1599
 *  I/O access between 0x3d4-0x3d5
1600
 *
1601
 ***************************************/
1602

    
1603
static int
1604
cirrus_hook_read_cr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1605
{
1606
    switch (reg_index) {
1607
    case 0x00:                        // Standard VGA
1608
    case 0x01:                        // Standard VGA
1609
    case 0x02:                        // Standard VGA
1610
    case 0x03:                        // Standard VGA
1611
    case 0x04:                        // Standard VGA
1612
    case 0x05:                        // Standard VGA
1613
    case 0x06:                        // Standard VGA
1614
    case 0x07:                        // Standard VGA
1615
    case 0x08:                        // Standard VGA
1616
    case 0x09:                        // Standard VGA
1617
    case 0x0a:                        // Standard VGA
1618
    case 0x0b:                        // Standard VGA
1619
    case 0x0c:                        // Standard VGA
1620
    case 0x0d:                        // Standard VGA
1621
    case 0x0e:                        // Standard VGA
1622
    case 0x0f:                        // Standard VGA
1623
    case 0x10:                        // Standard VGA
1624
    case 0x11:                        // Standard VGA
1625
    case 0x12:                        // Standard VGA
1626
    case 0x13:                        // Standard VGA
1627
    case 0x14:                        // Standard VGA
1628
    case 0x15:                        // Standard VGA
1629
    case 0x16:                        // Standard VGA
1630
    case 0x17:                        // Standard VGA
1631
    case 0x18:                        // Standard VGA
1632
        return CIRRUS_HOOK_NOT_HANDLED;
1633
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1634
        *reg_value = (s->ar_flip_flop << 7);
1635
        break;
1636
    case 0x19:                        // Interlace End
1637
    case 0x1a:                        // Miscellaneous Control
1638
    case 0x1b:                        // Extended Display Control
1639
    case 0x1c:                        // Sync Adjust and Genlock
1640
    case 0x1d:                        // Overlay Extended Control
1641
    case 0x22:                        // Graphics Data Latches Readback (R)
1642
    case 0x25:                        // Part Status
1643
    case 0x27:                        // Part ID (R)
1644
        *reg_value = s->cr[reg_index];
1645
        break;
1646
    case 0x26:                        // Attribute Controller Index Readback (R)
1647
        *reg_value = s->ar_index & 0x3f;
1648
        break;
1649
    default:
1650
#ifdef DEBUG_CIRRUS
1651
        printf("cirrus: inport cr_index %02x\n", reg_index);
1652
        *reg_value = 0xff;
1653
#endif
1654
        break;
1655
    }
1656

    
1657
    return CIRRUS_HOOK_HANDLED;
1658
}
1659

    
1660
static int
1661
cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1662
{
1663
    switch (reg_index) {
1664
    case 0x00:                        // Standard VGA
1665
    case 0x01:                        // Standard VGA
1666
    case 0x02:                        // Standard VGA
1667
    case 0x03:                        // Standard VGA
1668
    case 0x04:                        // Standard VGA
1669
    case 0x05:                        // Standard VGA
1670
    case 0x06:                        // Standard VGA
1671
    case 0x07:                        // Standard VGA
1672
    case 0x08:                        // Standard VGA
1673
    case 0x09:                        // Standard VGA
1674
    case 0x0a:                        // Standard VGA
1675
    case 0x0b:                        // Standard VGA
1676
    case 0x0c:                        // Standard VGA
1677
    case 0x0d:                        // Standard VGA
1678
    case 0x0e:                        // Standard VGA
1679
    case 0x0f:                        // Standard VGA
1680
    case 0x10:                        // Standard VGA
1681
    case 0x11:                        // Standard VGA
1682
    case 0x12:                        // Standard VGA
1683
    case 0x13:                        // Standard VGA
1684
    case 0x14:                        // Standard VGA
1685
    case 0x15:                        // Standard VGA
1686
    case 0x16:                        // Standard VGA
1687
    case 0x17:                        // Standard VGA
1688
    case 0x18:                        // Standard VGA
1689
        return CIRRUS_HOOK_NOT_HANDLED;
1690
    case 0x19:                        // Interlace End
1691
    case 0x1a:                        // Miscellaneous Control
1692
    case 0x1b:                        // Extended Display Control
1693
    case 0x1c:                        // Sync Adjust and Genlock
1694
    case 0x1d:                        // Overlay Extended Control
1695
        s->cr[reg_index] = reg_value;
1696
#ifdef DEBUG_CIRRUS
1697
        printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
1698
               reg_index, reg_value);
1699
#endif
1700
        break;
1701
    case 0x22:                        // Graphics Data Latches Readback (R)
1702
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1703
    case 0x26:                        // Attribute Controller Index Readback (R)
1704
    case 0x27:                        // Part ID (R)
1705
        break;
1706
    case 0x25:                        // Part Status
1707
    default:
1708
#ifdef DEBUG_CIRRUS
1709
        printf("cirrus: outport cr_index %02x, cr_value %02x\n", reg_index,
1710
               reg_value);
1711
#endif
1712
        break;
1713
    }
1714

    
1715
    return CIRRUS_HOOK_HANDLED;
1716
}
1717

    
1718
/***************************************
1719
 *
1720
 *  memory-mapped I/O (bitblt)
1721
 *
1722
 ***************************************/
1723

    
1724
static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1725
{
1726
    int value = 0xff;
1727

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

    
1829
    return (uint8_t) value;
1830
}
1831

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

    
1941
/***************************************
1942
 *
1943
 *  write mode 4/5
1944
 *
1945
 * assume TARGET_PAGE_SIZE >= 16
1946
 *
1947
 ***************************************/
1948

    
1949
static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1950
                                             unsigned mode,
1951
                                             unsigned offset,
1952
                                             uint32_t mem_value)
1953
{
1954
    int x;
1955
    unsigned val = mem_value;
1956
    uint8_t *dst;
1957

    
1958
    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
1959
    for (x = 0; x < 8; x++) {
1960
        if (val & 0x80) {
1961
            *dst = s->cirrus_shadow_gr1;
1962
        } else if (mode == 5) {
1963
            *dst = s->cirrus_shadow_gr0;
1964
        }
1965
        val <<= 1;
1966
        dst++;
1967
    }
1968
    cpu_physical_memory_set_dirty(s->vram_offset + offset);
1969
    cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
1970
}
1971

    
1972
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1973
                                              unsigned mode,
1974
                                              unsigned offset,
1975
                                              uint32_t mem_value)
1976
{
1977
    int x;
1978
    unsigned val = mem_value;
1979
    uint8_t *dst;
1980

    
1981
    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
1982
    for (x = 0; x < 8; x++) {
1983
        if (val & 0x80) {
1984
            *dst = s->cirrus_shadow_gr1;
1985
            *(dst + 1) = s->gr[0x11];
1986
        } else if (mode == 5) {
1987
            *dst = s->cirrus_shadow_gr0;
1988
            *(dst + 1) = s->gr[0x10];
1989
        }
1990
        val <<= 1;
1991
        dst += 2;
1992
    }
1993
    cpu_physical_memory_set_dirty(s->vram_offset + offset);
1994
    cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);
1995
}
1996

    
1997
/***************************************
1998
 *
1999
 *  memory access between 0xa0000-0xbffff
2000
 *
2001
 ***************************************/
2002

    
2003
static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
2004
{
2005
    CirrusVGAState *s = opaque;
2006
    unsigned bank_index;
2007
    unsigned bank_offset;
2008
    uint32_t val;
2009

    
2010
    if ((s->sr[0x07] & 0x01) == 0) {
2011
        return vga_mem_readb(s, addr);
2012
    }
2013

    
2014
    addr &= 0x1ffff;
2015

    
2016
    if (addr < 0x10000) {
2017
        /* XXX handle bitblt */
2018
        /* video memory */
2019
        bank_index = addr >> 15;
2020
        bank_offset = addr & 0x7fff;
2021
        if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2022
            bank_offset += s->cirrus_bank_base[bank_index];
2023
            if ((s->gr[0x0B] & 0x14) == 0x14) {
2024
                bank_offset <<= 4;
2025
            } else if (s->gr[0x0B] & 0x02) {
2026
                bank_offset <<= 3;
2027
            }
2028
            bank_offset &= s->cirrus_addr_mask;
2029
            val = *(s->vram_ptr + bank_offset);
2030
        } else
2031
            val = 0xff;
2032
    } else if (addr >= 0x18000 && addr < 0x18100) {
2033
        /* memory-mapped I/O */
2034
        val = 0xff;
2035
        if ((s->sr[0x17] & 0x44) == 0x04) {
2036
            val = cirrus_mmio_blt_read(s, addr & 0xff);
2037
        }
2038
    } else {
2039
        val = 0xff;
2040
#ifdef DEBUG_CIRRUS
2041
        printf("cirrus: mem_readb %06x\n", addr);
2042
#endif
2043
    }
2044
    return val;
2045
}
2046

    
2047
static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
2048
{
2049
    uint32_t v;
2050
#ifdef TARGET_WORDS_BIGENDIAN
2051
    v = cirrus_vga_mem_readb(opaque, addr) << 8;
2052
    v |= cirrus_vga_mem_readb(opaque, addr + 1);
2053
#else
2054
    v = cirrus_vga_mem_readb(opaque, addr);
2055
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2056
#endif
2057
    return v;
2058
}
2059

    
2060
static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
2061
{
2062
    uint32_t v;
2063
#ifdef TARGET_WORDS_BIGENDIAN
2064
    v = cirrus_vga_mem_readb(opaque, addr) << 24;
2065
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
2066
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
2067
    v |= cirrus_vga_mem_readb(opaque, addr + 3);
2068
#else
2069
    v = cirrus_vga_mem_readb(opaque, addr);
2070
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
2071
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
2072
    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
2073
#endif
2074
    return v;
2075
}
2076

    
2077
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
2078
                                  uint32_t mem_value)
2079
{
2080
    CirrusVGAState *s = opaque;
2081
    unsigned bank_index;
2082
    unsigned bank_offset;
2083
    unsigned mode;
2084

    
2085
    if ((s->sr[0x07] & 0x01) == 0) {
2086
        vga_mem_writeb(s, addr, mem_value);
2087
        return;
2088
    }
2089

    
2090
    addr &= 0x1ffff;
2091

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

    
2141
static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2142
{
2143
#ifdef TARGET_WORDS_BIGENDIAN
2144
    cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
2145
    cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
2146
#else
2147
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2148
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2149
#endif
2150
}
2151

    
2152
static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2153
{
2154
#ifdef TARGET_WORDS_BIGENDIAN
2155
    cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
2156
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2157
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2158
    cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
2159
#else
2160
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2161
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2162
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2163
    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2164
#endif
2165
}
2166

    
2167
static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = {
2168
    cirrus_vga_mem_readb,
2169
    cirrus_vga_mem_readw,
2170
    cirrus_vga_mem_readl,
2171
};
2172

    
2173
static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
2174
    cirrus_vga_mem_writeb,
2175
    cirrus_vga_mem_writew,
2176
    cirrus_vga_mem_writel,
2177
};
2178

    
2179
/***************************************
2180
 *
2181
 *  hardware cursor
2182
 *
2183
 ***************************************/
2184

    
2185
static inline void invalidate_cursor1(CirrusVGAState *s)
2186
{
2187
    if (s->last_hw_cursor_size) {
2188
        vga_invalidate_scanlines((VGAState *)s,
2189
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_start,
2190
                                 s->last_hw_cursor_y + s->last_hw_cursor_y_end);
2191
    }
2192
}
2193

    
2194
static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
2195
{
2196
    const uint8_t *src;
2197
    uint32_t content;
2198
    int y, y_min, y_max;
2199

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

    
2243
/* NOTE: we do not currently handle the cursor bitmap change, so we
2244
   update the cursor only if it moves. */
2245
static void cirrus_cursor_invalidate(VGAState *s1)
2246
{
2247
    CirrusVGAState *s = (CirrusVGAState *)s1;
2248
    int size;
2249

    
2250
    if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) {
2251
        size = 0;
2252
    } else {
2253
        if (s->sr[0x12] & CIRRUS_CURSOR_LARGE)
2254
            size = 64;
2255
        else
2256
            size = 32;
2257
    }
2258
    /* invalidate last cursor and new cursor if any change */
2259
    if (s->last_hw_cursor_size != size ||
2260
        s->last_hw_cursor_x != s->hw_cursor_x ||
2261
        s->last_hw_cursor_y != s->hw_cursor_y) {
2262

    
2263
        invalidate_cursor1(s);
2264

    
2265
        s->last_hw_cursor_size = size;
2266
        s->last_hw_cursor_x = s->hw_cursor_x;
2267
        s->last_hw_cursor_y = s->hw_cursor_y;
2268
        /* compute the real cursor min and max y */
2269
        cirrus_cursor_compute_yrange(s);
2270
        invalidate_cursor1(s);
2271
    }
2272
}
2273

    
2274
static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
2275
{
2276
    CirrusVGAState *s = (CirrusVGAState *)s1;
2277
    int w, h, bpp, x1, x2, poffset;
2278
    unsigned int color0, color1;
2279
    const uint8_t *palette, *src;
2280
    uint32_t content;
2281

    
2282
    if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
2283
        return;
2284
    /* fast test to see if the cursor intersects with the scan line */
2285
    if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
2286
        h = 64;
2287
    } else {
2288
        h = 32;
2289
    }
2290
    if (scr_y < s->hw_cursor_y ||
2291
        scr_y >= (s->hw_cursor_y + h))
2292
        return;
2293

    
2294
    src = s->vram_ptr + s->real_vram_size - 16 * 1024;
2295
    if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
2296
        src += (s->sr[0x13] & 0x3c) * 256;
2297
        src += (scr_y - s->hw_cursor_y) * 16;
2298
        poffset = 8;
2299
        content = ((uint32_t *)src)[0] |
2300
            ((uint32_t *)src)[1] |
2301
            ((uint32_t *)src)[2] |
2302
            ((uint32_t *)src)[3];
2303
    } else {
2304
        src += (s->sr[0x13] & 0x3f) * 256;
2305
        src += (scr_y - s->hw_cursor_y) * 4;
2306
        poffset = 128;
2307
        content = ((uint32_t *)src)[0] |
2308
            ((uint32_t *)(src + 128))[0];
2309
    }
2310
    /* if nothing to draw, no need to continue */
2311
    if (!content)
2312
        return;
2313
    w = h;
2314

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

    
2349
/***************************************
2350
 *
2351
 *  LFB memory access
2352
 *
2353
 ***************************************/
2354

    
2355
static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
2356
{
2357
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2358
    uint32_t ret;
2359

    
2360
    addr &= s->cirrus_addr_mask;
2361

    
2362
    if (((s->sr[0x17] & 0x44) == 0x44) &&
2363
        ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2364
        /* memory-mapped I/O */
2365
        ret = cirrus_mmio_blt_read(s, addr & 0xff);
2366
    } else if (0) {
2367
        /* XXX handle bitblt */
2368
        ret = 0xff;
2369
    } else {
2370
        /* video memory */
2371
        if ((s->gr[0x0B] & 0x14) == 0x14) {
2372
            addr <<= 4;
2373
        } else if (s->gr[0x0B] & 0x02) {
2374
            addr <<= 3;
2375
        }
2376
        addr &= s->cirrus_addr_mask;
2377
        ret = *(s->vram_ptr + addr);
2378
    }
2379

    
2380
    return ret;
2381
}
2382

    
2383
static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
2384
{
2385
    uint32_t v;
2386
#ifdef TARGET_WORDS_BIGENDIAN
2387
    v = cirrus_linear_readb(opaque, addr) << 8;
2388
    v |= cirrus_linear_readb(opaque, addr + 1);
2389
#else
2390
    v = cirrus_linear_readb(opaque, addr);
2391
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2392
#endif
2393
    return v;
2394
}
2395

    
2396
static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
2397
{
2398
    uint32_t v;
2399
#ifdef TARGET_WORDS_BIGENDIAN
2400
    v = cirrus_linear_readb(opaque, addr) << 24;
2401
    v |= cirrus_linear_readb(opaque, addr + 1) << 16;
2402
    v |= cirrus_linear_readb(opaque, addr + 2) << 8;
2403
    v |= cirrus_linear_readb(opaque, addr + 3);
2404
#else
2405
    v = cirrus_linear_readb(opaque, addr);
2406
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2407
    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
2408
    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
2409
#endif
2410
    return v;
2411
}
2412

    
2413
static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
2414
                                 uint32_t val)
2415
{
2416
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2417
    unsigned mode;
2418

    
2419
    addr &= s->cirrus_addr_mask;
2420

    
2421
    if (((s->sr[0x17] & 0x44) == 0x44) &&
2422
        ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
2423
        /* memory-mapped I/O */
2424
        cirrus_mmio_blt_write(s, addr & 0xff, val);
2425
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2426
        /* bitblt */
2427
        *s->cirrus_srcptr++ = (uint8_t) val;
2428
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2429
            cirrus_bitblt_cputovideo_next(s);
2430
        }
2431
    } else {
2432
        /* video memory */
2433
        if ((s->gr[0x0B] & 0x14) == 0x14) {
2434
            addr <<= 4;
2435
        } else if (s->gr[0x0B] & 0x02) {
2436
            addr <<= 3;
2437
        }
2438
        addr &= s->cirrus_addr_mask;
2439

    
2440
        mode = s->gr[0x05] & 0x7;
2441
        if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
2442
            *(s->vram_ptr + addr) = (uint8_t) val;
2443
            cpu_physical_memory_set_dirty(s->vram_offset + addr);
2444
        } else {
2445
            if ((s->gr[0x0B] & 0x14) != 0x14) {
2446
                cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2447
            } else {
2448
                cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2449
            }
2450
        }
2451
    }
2452
}
2453

    
2454
static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
2455
                                 uint32_t val)
2456
{
2457
#ifdef TARGET_WORDS_BIGENDIAN
2458
    cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
2459
    cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
2460
#else
2461
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2462
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2463
#endif
2464
}
2465

    
2466
static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
2467
                                 uint32_t val)
2468
{
2469
#ifdef TARGET_WORDS_BIGENDIAN
2470
    cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
2471
    cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2472
    cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2473
    cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
2474
#else
2475
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2476
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2477
    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2478
    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2479
#endif
2480
}
2481

    
2482

    
2483
static CPUReadMemoryFunc *cirrus_linear_read[3] = {
2484
    cirrus_linear_readb,
2485
    cirrus_linear_readw,
2486
    cirrus_linear_readl,
2487
};
2488

    
2489
static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
2490
    cirrus_linear_writeb,
2491
    cirrus_linear_writew,
2492
    cirrus_linear_writel,
2493
};
2494

    
2495
static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr,
2496
                                     uint32_t val)
2497
{
2498
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2499

    
2500
    addr &= s->cirrus_addr_mask;
2501
    *(s->vram_ptr + addr) = val;
2502
    cpu_physical_memory_set_dirty(s->vram_offset + addr);
2503
}
2504

    
2505
static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr,
2506
                                     uint32_t val)
2507
{
2508
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2509

    
2510
    addr &= s->cirrus_addr_mask;
2511
    cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val);
2512
    cpu_physical_memory_set_dirty(s->vram_offset + addr);
2513
}
2514

    
2515
static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr,
2516
                                     uint32_t val)
2517
{
2518
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2519

    
2520
    addr &= s->cirrus_addr_mask;
2521
    cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val);
2522
    cpu_physical_memory_set_dirty(s->vram_offset + addr);
2523
}
2524

    
2525
/***************************************
2526
 *
2527
 *  system to screen memory access
2528
 *
2529
 ***************************************/
2530

    
2531

    
2532
static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
2533
{
2534
    uint32_t ret;
2535

    
2536
    /* XXX handle bitblt */
2537
    ret = 0xff;
2538
    return ret;
2539
}
2540

    
2541
static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
2542
{
2543
    uint32_t v;
2544
#ifdef TARGET_WORDS_BIGENDIAN
2545
    v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
2546
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
2547
#else
2548
    v = cirrus_linear_bitblt_readb(opaque, addr);
2549
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2550
#endif
2551
    return v;
2552
}
2553

    
2554
static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
2555
{
2556
    uint32_t v;
2557
#ifdef TARGET_WORDS_BIGENDIAN
2558
    v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
2559
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
2560
    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
2561
    v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
2562
#else
2563
    v = cirrus_linear_bitblt_readb(opaque, addr);
2564
    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
2565
    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
2566
    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
2567
#endif
2568
    return v;
2569
}
2570

    
2571
static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
2572
                                 uint32_t val)
2573
{
2574
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2575

    
2576
    if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2577
        /* bitblt */
2578
        *s->cirrus_srcptr++ = (uint8_t) val;
2579
        if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2580
            cirrus_bitblt_cputovideo_next(s);
2581
        }
2582
    }
2583
}
2584

    
2585
static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
2586
                                 uint32_t val)
2587
{
2588
#ifdef TARGET_WORDS_BIGENDIAN
2589
    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
2590
    cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
2591
#else
2592
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2593
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2594
#endif
2595
}
2596

    
2597
static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
2598
                                 uint32_t val)
2599
{
2600
#ifdef TARGET_WORDS_BIGENDIAN
2601
    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
2602
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2603
    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2604
    cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
2605
#else
2606
    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
2607
    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2608
    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2609
    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2610
#endif
2611
}
2612

    
2613

    
2614
static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = {
2615
    cirrus_linear_bitblt_readb,
2616
    cirrus_linear_bitblt_readw,
2617
    cirrus_linear_bitblt_readl,
2618
};
2619

    
2620
static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
2621
    cirrus_linear_bitblt_writeb,
2622
    cirrus_linear_bitblt_writew,
2623
    cirrus_linear_bitblt_writel,
2624
};
2625

    
2626
static void map_linear_vram(CirrusVGAState *s)
2627
{
2628
    vga_dirty_log_stop((VGAState *)s);
2629

    
2630
    if (!s->map_addr && s->lfb_addr && s->lfb_end) {
2631
        s->map_addr = s->lfb_addr;
2632
        s->map_end = s->lfb_end;
2633
        cpu_register_physical_memory(s->map_addr, s->map_end - s->map_addr, s->vram_offset);
2634
    }
2635

    
2636
    if (!s->map_addr)
2637
        return;
2638

    
2639
    s->lfb_vram_mapped = 0;
2640

    
2641
    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
2642
        && !((s->sr[0x07] & 0x01) == 0)
2643
        && !((s->gr[0x0B] & 0x14) == 0x14)
2644
        && !(s->gr[0x0B] & 0x02)) {
2645

    
2646
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
2647
                                    (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
2648
        cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
2649
                                    (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM);
2650

    
2651
        s->lfb_vram_mapped = 1;
2652
    }
2653
    else {
2654
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2655
                                     s->vga_io_memory);
2656
    }
2657

    
2658
    vga_dirty_log_start((VGAState *)s);
2659
}
2660

    
2661
static void unmap_linear_vram(CirrusVGAState *s)
2662
{
2663
    vga_dirty_log_stop((VGAState *)s);
2664

    
2665
    if (s->map_addr && s->lfb_addr && s->lfb_end)
2666
        s->map_addr = s->map_end = 0;
2667

    
2668
    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
2669
                                 s->vga_io_memory);
2670

    
2671
    vga_dirty_log_start((VGAState *)s);
2672
}
2673

    
2674
/* Compute the memory access functions */
2675
static void cirrus_update_memory_access(CirrusVGAState *s)
2676
{
2677
    unsigned mode;
2678

    
2679
    if ((s->sr[0x17] & 0x44) == 0x44) {
2680
        goto generic_io;
2681
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2682
        goto generic_io;
2683
    } else {
2684
        if ((s->gr[0x0B] & 0x14) == 0x14) {
2685
            goto generic_io;
2686
        } else if (s->gr[0x0B] & 0x02) {
2687
            goto generic_io;
2688
        }
2689

    
2690
        mode = s->gr[0x05] & 0x7;
2691
        if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
2692
            map_linear_vram(s);
2693
            s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
2694
            s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
2695
            s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
2696
        } else {
2697
        generic_io:
2698
            unmap_linear_vram(s);
2699
            s->cirrus_linear_write[0] = cirrus_linear_writeb;
2700
            s->cirrus_linear_write[1] = cirrus_linear_writew;
2701
            s->cirrus_linear_write[2] = cirrus_linear_writel;
2702
        }
2703
    }
2704
}
2705

    
2706

    
2707
/* I/O ports */
2708

    
2709
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
2710
{
2711
    CirrusVGAState *s = opaque;
2712
    int val, index;
2713

    
2714
    /* check port range access depending on color/monochrome mode */
2715
    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
2716
        || (addr >= 0x3d0 && addr <= 0x3df
2717
            && !(s->msr & MSR_COLOR_EMULATION))) {
2718
        val = 0xff;
2719
    } else {
2720
        switch (addr) {
2721
        case 0x3c0:
2722
            if (s->ar_flip_flop == 0) {
2723
                val = s->ar_index;
2724
            } else {
2725
                val = 0;
2726
            }
2727
            break;
2728
        case 0x3c1:
2729
            index = s->ar_index & 0x1f;
2730
            if (index < 21)
2731
                val = s->ar[index];
2732
            else
2733
                val = 0;
2734
            break;
2735
        case 0x3c2:
2736
            val = s->st00;
2737
            break;
2738
        case 0x3c4:
2739
            val = s->sr_index;
2740
            break;
2741
        case 0x3c5:
2742
            if (cirrus_hook_read_sr(s, s->sr_index, &val))
2743
                break;
2744
            val = s->sr[s->sr_index];
2745
#ifdef DEBUG_VGA_REG
2746
            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2747
#endif
2748
            break;
2749
        case 0x3c6:
2750
            cirrus_read_hidden_dac(s, &val);
2751
            break;
2752
        case 0x3c7:
2753
            val = s->dac_state;
2754
            break;
2755
        case 0x3c8:
2756
            val = s->dac_write_index;
2757
            s->cirrus_hidden_dac_lockindex = 0;
2758
            break;
2759
        case 0x3c9:
2760
            if (cirrus_hook_read_palette(s, &val))
2761
                break;
2762
            val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
2763
            if (++s->dac_sub_index == 3) {
2764
                s->dac_sub_index = 0;
2765
                s->dac_read_index++;
2766
            }
2767
            break;
2768
        case 0x3ca:
2769
            val = s->fcr;
2770
            break;
2771
        case 0x3cc:
2772
            val = s->msr;
2773
            break;
2774
        case 0x3ce:
2775
            val = s->gr_index;
2776
            break;
2777
        case 0x3cf:
2778
            if (cirrus_hook_read_gr(s, s->gr_index, &val))
2779
                break;
2780
            val = s->gr[s->gr_index];
2781
#ifdef DEBUG_VGA_REG
2782
            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2783
#endif
2784
            break;
2785
        case 0x3b4:
2786
        case 0x3d4:
2787
            val = s->cr_index;
2788
            break;
2789
        case 0x3b5:
2790
        case 0x3d5:
2791
            if (cirrus_hook_read_cr(s, s->cr_index, &val))
2792
                break;
2793
            val = s->cr[s->cr_index];
2794
#ifdef DEBUG_VGA_REG
2795
            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2796
#endif
2797
            break;
2798
        case 0x3ba:
2799
        case 0x3da:
2800
            /* just toggle to fool polling */
2801
            val = s->st01 = s->retrace((VGAState *) s);
2802
            s->ar_flip_flop = 0;
2803
            break;
2804
        default:
2805
            val = 0x00;
2806
            break;
2807
        }
2808
    }
2809
#if defined(DEBUG_VGA)
2810
    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2811
#endif
2812
    return val;
2813
}
2814

    
2815
static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2816
{
2817
    CirrusVGAState *s = opaque;
2818
    int index;
2819

    
2820
    /* check port range access depending on color/monochrome mode */
2821
    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
2822
        || (addr >= 0x3d0 && addr <= 0x3df
2823
            && !(s->msr & MSR_COLOR_EMULATION)))
2824
        return;
2825

    
2826
#ifdef DEBUG_VGA
2827
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2828
#endif
2829

    
2830
    switch (addr) {
2831
    case 0x3c0:
2832
        if (s->ar_flip_flop == 0) {
2833
            val &= 0x3f;
2834
            s->ar_index = val;
2835
        } else {
2836
            index = s->ar_index & 0x1f;
2837
            switch (index) {
2838
            case 0x00 ... 0x0f:
2839
                s->ar[index] = val & 0x3f;
2840
                break;
2841
            case 0x10:
2842
                s->ar[index] = val & ~0x10;
2843
                break;
2844
            case 0x11:
2845
                s->ar[index] = val;
2846
                break;
2847
            case 0x12:
2848
                s->ar[index] = val & ~0xc0;
2849
                break;
2850
            case 0x13:
2851
                s->ar[index] = val & ~0xf0;
2852
                break;
2853
            case 0x14:
2854
                s->ar[index] = val & ~0xf0;
2855
                break;
2856
            default:
2857
                break;
2858
            }
2859
        }
2860
        s->ar_flip_flop ^= 1;
2861
        break;
2862
    case 0x3c2:
2863
        s->msr = val & ~0x10;
2864
        s->update_retrace_info((VGAState *) s);
2865
        break;
2866
    case 0x3c4:
2867
        s->sr_index = val;
2868
        break;
2869
    case 0x3c5:
2870
        if (cirrus_hook_write_sr(s, s->sr_index, val))
2871
            break;
2872
#ifdef DEBUG_VGA_REG
2873
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2874
#endif
2875
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
2876
        if (s->sr_index == 1) s->update_retrace_info((VGAState *) s);
2877
        break;
2878
    case 0x3c6:
2879
        cirrus_write_hidden_dac(s, val);
2880
        break;
2881
    case 0x3c7:
2882
        s->dac_read_index = val;
2883
        s->dac_sub_index = 0;
2884
        s->dac_state = 3;
2885
        break;
2886
    case 0x3c8:
2887
        s->dac_write_index = val;
2888
        s->dac_sub_index = 0;
2889
        s->dac_state = 0;
2890
        break;
2891
    case 0x3c9:
2892
        if (cirrus_hook_write_palette(s, val))
2893
            break;
2894
        s->dac_cache[s->dac_sub_index] = val;
2895
        if (++s->dac_sub_index == 3) {
2896
            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
2897
            s->dac_sub_index = 0;
2898
            s->dac_write_index++;
2899
        }
2900
        break;
2901
    case 0x3ce:
2902
        s->gr_index = val;
2903
        break;
2904
    case 0x3cf:
2905
        if (cirrus_hook_write_gr(s, s->gr_index, val))
2906
            break;
2907
#ifdef DEBUG_VGA_REG
2908
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2909
#endif
2910
        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
2911
        break;
2912
    case 0x3b4:
2913
    case 0x3d4:
2914
        s->cr_index = val;
2915
        break;
2916
    case 0x3b5:
2917
    case 0x3d5:
2918
        if (cirrus_hook_write_cr(s, s->cr_index, val))
2919
            break;
2920
#ifdef DEBUG_VGA_REG
2921
        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2922
#endif
2923
        /* handle CR0-7 protection */
2924
        if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
2925
            /* can always write bit 4 of CR7 */
2926
            if (s->cr_index == 7)
2927
                s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
2928
            return;
2929
        }
2930
        switch (s->cr_index) {
2931
        case 0x01:                /* horizontal display end */
2932
        case 0x07:
2933
        case 0x09:
2934
        case 0x0c:
2935
        case 0x0d:
2936
        case 0x12:                /* vertical display end */
2937
            s->cr[s->cr_index] = val;
2938
            break;
2939

    
2940
        default:
2941
            s->cr[s->cr_index] = val;
2942
            break;
2943
        }
2944

    
2945
        switch(s->cr_index) {
2946
        case 0x00:
2947
        case 0x04:
2948
        case 0x05:
2949
        case 0x06:
2950
        case 0x07:
2951
        case 0x11:
2952
        case 0x17:
2953
            s->update_retrace_info((VGAState *) s);
2954
            break;
2955
        }
2956
        break;
2957
    case 0x3ba:
2958
    case 0x3da:
2959
        s->fcr = val & 0x10;
2960
        break;
2961
    }
2962
}
2963

    
2964
/***************************************
2965
 *
2966
 *  memory-mapped I/O access
2967
 *
2968
 ***************************************/
2969

    
2970
static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
2971
{
2972
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2973

    
2974
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2975

    
2976
    if (addr >= 0x100) {
2977
        return cirrus_mmio_blt_read(s, addr - 0x100);
2978
    } else {
2979
        return vga_ioport_read(s, addr + 0x3c0);
2980
    }
2981
}
2982

    
2983
static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
2984
{
2985
    uint32_t v;
2986
#ifdef TARGET_WORDS_BIGENDIAN
2987
    v = cirrus_mmio_readb(opaque, addr) << 8;
2988
    v |= cirrus_mmio_readb(opaque, addr + 1);
2989
#else
2990
    v = cirrus_mmio_readb(opaque, addr);
2991
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2992
#endif
2993
    return v;
2994
}
2995

    
2996
static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
2997
{
2998
    uint32_t v;
2999
#ifdef TARGET_WORDS_BIGENDIAN
3000
    v = cirrus_mmio_readb(opaque, addr) << 24;
3001
    v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
3002
    v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
3003
    v |= cirrus_mmio_readb(opaque, addr + 3);
3004
#else
3005
    v = cirrus_mmio_readb(opaque, addr);
3006
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
3007
    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
3008
    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
3009
#endif
3010
    return v;
3011
}
3012

    
3013
static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
3014
                               uint32_t val)
3015
{
3016
    CirrusVGAState *s = (CirrusVGAState *) opaque;
3017

    
3018
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
3019

    
3020
    if (addr >= 0x100) {
3021
        cirrus_mmio_blt_write(s, addr - 0x100, val);
3022
    } else {
3023
        vga_ioport_write(s, addr + 0x3c0, val);
3024
    }
3025
}
3026

    
3027
static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
3028
                               uint32_t val)
3029
{
3030
#ifdef TARGET_WORDS_BIGENDIAN
3031
    cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
3032
    cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
3033
#else
3034
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
3035
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
3036
#endif
3037
}
3038

    
3039
static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
3040
                               uint32_t val)
3041
{
3042
#ifdef TARGET_WORDS_BIGENDIAN
3043
    cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
3044
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
3045
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
3046
    cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
3047
#else
3048
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
3049
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
3050
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
3051
    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
3052
#endif
3053
}
3054

    
3055

    
3056
static CPUReadMemoryFunc *cirrus_mmio_read[3] = {
3057
    cirrus_mmio_readb,
3058
    cirrus_mmio_readw,
3059
    cirrus_mmio_readl,
3060
};
3061

    
3062
static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
3063
    cirrus_mmio_writeb,
3064
    cirrus_mmio_writew,
3065
    cirrus_mmio_writel,
3066
};
3067

    
3068
/* load/save state */
3069

    
3070
static void cirrus_vga_save(QEMUFile *f, void *opaque)
3071
{
3072
    CirrusVGAState *s = opaque;
3073

    
3074
    if (s->pci_dev)
3075
        pci_device_save(s->pci_dev, f);
3076

    
3077
    qemu_put_be32s(f, &s->latch);
3078
    qemu_put_8s(f, &s->sr_index);
3079
    qemu_put_buffer(f, s->sr, 256);
3080
    qemu_put_8s(f, &s->gr_index);
3081
    qemu_put_8s(f, &s->cirrus_shadow_gr0);
3082
    qemu_put_8s(f, &s->cirrus_shadow_gr1);
3083
    qemu_put_buffer(f, s->gr + 2, 254);
3084
    qemu_put_8s(f, &s->ar_index);
3085
    qemu_put_buffer(f, s->ar, 21);
3086
    qemu_put_be32(f, s->ar_flip_flop);
3087
    qemu_put_8s(f, &s->cr_index);
3088
    qemu_put_buffer(f, s->cr, 256);
3089
    qemu_put_8s(f, &s->msr);
3090
    qemu_put_8s(f, &s->fcr);
3091
    qemu_put_8s(f, &s->st00);
3092
    qemu_put_8s(f, &s->st01);
3093

    
3094
    qemu_put_8s(f, &s->dac_state);
3095
    qemu_put_8s(f, &s->dac_sub_index);
3096
    qemu_put_8s(f, &s->dac_read_index);
3097
    qemu_put_8s(f, &s->dac_write_index);
3098
    qemu_put_buffer(f, s->dac_cache, 3);
3099
    qemu_put_buffer(f, s->palette, 768);
3100

    
3101
    qemu_put_be32(f, s->bank_offset);
3102

    
3103
    qemu_put_8s(f, &s->cirrus_hidden_dac_lockindex);
3104
    qemu_put_8s(f, &s->cirrus_hidden_dac_data);
3105

    
3106
    qemu_put_be32s(f, &s->hw_cursor_x);
3107
    qemu_put_be32s(f, &s->hw_cursor_y);
3108
    /* XXX: we do not save the bitblt state - we assume we do not save
3109
       the state when the blitter is active */
3110
}
3111

    
3112
static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
3113
{
3114
    CirrusVGAState *s = opaque;
3115
    int ret;
3116

    
3117
    if (version_id > 2)
3118
        return -EINVAL;
3119

    
3120
    if (s->pci_dev && version_id >= 2) {
3121
        ret = pci_device_load(s->pci_dev, f);
3122
        if (ret < 0)
3123
            return ret;
3124
    }
3125

    
3126
    qemu_get_be32s(f, &s->latch);
3127
    qemu_get_8s(f, &s->sr_index);
3128
    qemu_get_buffer(f, s->sr, 256);
3129
    qemu_get_8s(f, &s->gr_index);
3130
    qemu_get_8s(f, &s->cirrus_shadow_gr0);
3131
    qemu_get_8s(f, &s->cirrus_shadow_gr1);
3132
    s->gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
3133
    s->gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
3134
    qemu_get_buffer(f, s->gr + 2, 254);
3135
    qemu_get_8s(f, &s->ar_index);
3136
    qemu_get_buffer(f, s->ar, 21);
3137
    s->ar_flip_flop=qemu_get_be32(f);
3138
    qemu_get_8s(f, &s->cr_index);
3139
    qemu_get_buffer(f, s->cr, 256);
3140
    qemu_get_8s(f, &s->msr);
3141
    qemu_get_8s(f, &s->fcr);
3142
    qemu_get_8s(f, &s->st00);
3143
    qemu_get_8s(f, &s->st01);
3144

    
3145
    qemu_get_8s(f, &s->dac_state);
3146
    qemu_get_8s(f, &s->dac_sub_index);
3147
    qemu_get_8s(f, &s->dac_read_index);
3148
    qemu_get_8s(f, &s->dac_write_index);
3149
    qemu_get_buffer(f, s->dac_cache, 3);
3150
    qemu_get_buffer(f, s->palette, 768);
3151

    
3152
    s->bank_offset=qemu_get_be32(f);
3153

    
3154
    qemu_get_8s(f, &s->cirrus_hidden_dac_lockindex);
3155
    qemu_get_8s(f, &s->cirrus_hidden_dac_data);
3156

    
3157
    qemu_get_be32s(f, &s->hw_cursor_x);
3158
    qemu_get_be32s(f, &s->hw_cursor_y);
3159

    
3160
    cirrus_update_memory_access(s);
3161
    /* force refresh */
3162
    s->graphic_mode = -1;
3163
    cirrus_update_bank_ptr(s, 0);
3164
    cirrus_update_bank_ptr(s, 1);
3165
    return 0;
3166
}
3167

    
3168
/***************************************
3169
 *
3170
 *  initialize
3171
 *
3172
 ***************************************/
3173

    
3174
static void cirrus_reset(void *opaque)
3175
{
3176
    CirrusVGAState *s = opaque;
3177

    
3178
    vga_reset(s);
3179
    unmap_linear_vram(s);
3180
    s->sr[0x06] = 0x0f;
3181
    if (s->device_id == CIRRUS_ID_CLGD5446) {
3182
        /* 4MB 64 bit memory config, always PCI */
3183
        s->sr[0x1F] = 0x2d;                // MemClock
3184
        s->gr[0x18] = 0x0f;             // fastest memory configuration
3185
        s->sr[0x0f] = 0x98;
3186
        s->sr[0x17] = 0x20;
3187
        s->sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
3188
    } else {
3189
        s->sr[0x1F] = 0x22;                // MemClock
3190
        s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
3191
        s->sr[0x17] = s->bustype;
3192
        s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
3193
    }
3194
    s->cr[0x27] = s->device_id;
3195

    
3196
    /* Win2K seems to assume that the pattern buffer is at 0xff
3197
       initially ! */
3198
    memset(s->vram_ptr, 0xff, s->real_vram_size);
3199

    
3200
    s->cirrus_hidden_dac_lockindex = 5;
3201
    s->cirrus_hidden_dac_data = 0;
3202
}
3203

    
3204
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
3205
{
3206
    int i;
3207
    static int inited;
3208

    
3209
    if (!inited) {
3210
        inited = 1;
3211
        for(i = 0;i < 256; i++)
3212
            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
3213
        rop_to_index[CIRRUS_ROP_0] = 0;
3214
        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
3215
        rop_to_index[CIRRUS_ROP_NOP] = 2;
3216
        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
3217
        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
3218
        rop_to_index[CIRRUS_ROP_SRC] = 5;
3219
        rop_to_index[CIRRUS_ROP_1] = 6;
3220
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
3221
        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
3222
        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
3223
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
3224
        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
3225
        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
3226
        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
3227
        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
3228
        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
3229
        s->device_id = device_id;
3230
        if (is_pci)
3231
            s->bustype = CIRRUS_BUSTYPE_PCI;
3232
        else
3233
            s->bustype = CIRRUS_BUSTYPE_ISA;
3234
    }
3235

    
3236
    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
3237

    
3238
    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
3239
    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
3240
    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
3241
    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
3242

    
3243
    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
3244

    
3245
    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
3246
    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
3247
    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
3248
    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
3249

    
3250
    s->vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
3251
                                           cirrus_vga_mem_write, s);
3252
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
3253
                                 s->vga_io_memory);
3254
    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
3255

    
3256
    /* I/O handler for LFB */
3257
    s->cirrus_linear_io_addr =
3258
        cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, s);
3259
    s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
3260

    
3261
    /* I/O handler for LFB */
3262
    s->cirrus_linear_bitblt_io_addr =
3263
        cpu_register_io_memory(0, cirrus_linear_bitblt_read,
3264
                               cirrus_linear_bitblt_write, s);
3265

    
3266
    /* I/O handler for memory-mapped I/O */
3267
    s->cirrus_mmio_io_addr =
3268
        cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
3269

    
3270
    s->real_vram_size =
3271
        (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
3272

    
3273
    /* XXX: s->vram_size must be a power of two */
3274
    s->cirrus_addr_mask = s->real_vram_size - 1;
3275
    s->linear_mmio_mask = s->real_vram_size - 256;
3276

    
3277
    s->get_bpp = cirrus_get_bpp;
3278
    s->get_offsets = cirrus_get_offsets;
3279
    s->get_resolution = cirrus_get_resolution;
3280
    s->cursor_invalidate = cirrus_cursor_invalidate;
3281
    s->cursor_draw_line = cirrus_cursor_draw_line;
3282

    
3283
    qemu_register_reset(cirrus_reset, s);
3284
    cirrus_reset(s);
3285
    register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);
3286
}
3287

    
3288
/***************************************
3289
 *
3290
 *  ISA bus support
3291
 *
3292
 ***************************************/
3293

    
3294
void isa_cirrus_vga_init(uint8_t *vga_ram_base,
3295
                         ram_addr_t vga_ram_offset, int vga_ram_size)
3296
{
3297
    CirrusVGAState *s;
3298

    
3299
    s = qemu_mallocz(sizeof(CirrusVGAState));
3300

    
3301
    vga_common_init((VGAState *)s,
3302
                    vga_ram_base, vga_ram_offset, vga_ram_size);
3303
    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
3304
    s->ds = graphic_console_init(s->update, s->invalidate,
3305
                                 s->screen_dump, s->text_update, s);
3306
    /* XXX ISA-LFB support */
3307
}
3308

    
3309
/***************************************
3310
 *
3311
 *  PCI bus support
3312
 *
3313
 ***************************************/
3314

    
3315
static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
3316
                               uint32_t addr, uint32_t size, int type)
3317
{
3318
    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
3319

    
3320
    vga_dirty_log_stop((VGAState *)s);
3321

    
3322
    /* XXX: add byte swapping apertures */
3323
    cpu_register_physical_memory(addr, s->vram_size,
3324
                                 s->cirrus_linear_io_addr);
3325
    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
3326
                                 s->cirrus_linear_bitblt_io_addr);
3327

    
3328
    s->map_addr = s->map_end = 0;
3329
    s->lfb_addr = addr & TARGET_PAGE_MASK;
3330
    s->lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
3331
    /* account for overflow */
3332
    if (s->lfb_end < addr + VGA_RAM_SIZE)
3333
        s->lfb_end = addr + VGA_RAM_SIZE;
3334

    
3335
    vga_dirty_log_start((VGAState *)s);
3336
}
3337

    
3338
static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
3339
                                uint32_t addr, uint32_t size, int type)
3340
{
3341
    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
3342

    
3343
    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
3344
                                 s->cirrus_mmio_io_addr);
3345
}
3346

    
3347
static void pci_cirrus_write_config(PCIDevice *d,
3348
                                    uint32_t address, uint32_t val, int len)
3349
{
3350
    PCICirrusVGAState *pvs = container_of(d, PCICirrusVGAState, dev);
3351
    CirrusVGAState *s = &pvs->cirrus_vga;
3352

    
3353
    vga_dirty_log_stop((VGAState *)s);
3354

    
3355
    pci_default_write_config(d, address, val, len);
3356
    if (s->map_addr && pvs->dev.io_regions[0].addr == -1)
3357
        s->map_addr = 0;
3358
    cirrus_update_memory_access(s);
3359

    
3360
    vga_dirty_log_start((VGAState *)s);
3361
}
3362

    
3363
void pci_cirrus_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
3364
                         ram_addr_t vga_ram_offset, int vga_ram_size)
3365
{
3366
    PCICirrusVGAState *d;
3367
    uint8_t *pci_conf;
3368
    CirrusVGAState *s;
3369
    int device_id;
3370

    
3371
    device_id = CIRRUS_ID_CLGD5446;
3372

    
3373
    /* setup PCI configuration registers */
3374
    d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
3375
                                                 sizeof(PCICirrusVGAState),
3376
                                                 -1, NULL, pci_cirrus_write_config);
3377
    pci_conf = d->dev.config;
3378
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
3379
    pci_config_set_device_id(pci_conf, device_id);
3380
    pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
3381
    pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
3382
    pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
3383
    pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
3384

    
3385
    /* setup VGA */
3386
    s = &d->cirrus_vga;
3387
    vga_common_init((VGAState *)s,
3388
                    vga_ram_base, vga_ram_offset, vga_ram_size);
3389
    cirrus_init_common(s, device_id, 1);
3390

    
3391
    s->ds = graphic_console_init(s->update, s->invalidate,
3392
                                 s->screen_dump, s->text_update, s);
3393

    
3394
    s->pci_dev = (PCIDevice *)d;
3395

    
3396
    /* setup memory space */
3397
    /* memory #0 LFB */
3398
    /* memory #1 memory-mapped I/O */
3399
    /* XXX: s->vram_size must be a power of two */
3400
    pci_register_io_region((PCIDevice *)d, 0, 0x2000000,
3401
                           PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
3402
    if (device_id == CIRRUS_ID_CLGD5446) {
3403
        pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
3404
                               PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
3405
    }
3406
    /* XXX: ROM BIOS */
3407
}