Statistics
| Branch: | Revision:

root / hw / cirrus_vga.c @ e6e5ad80

History | View | Annotate | Download (73.8 kB)

1
/*
2
 * QEMU Cirrus VGA Emulator.
3
 * 
4
 * Copyright (c) 2004 Fabrice Bellard
5
 * Copyright (c) 2004 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
#include "vl.h"
26
#include "vga_int.h"
27

    
28
/***************************************
29
 *
30
 *  definitions
31
 *
32
 ***************************************/
33

    
34
#define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
35

    
36
// ID
37
#define CIRRUS_ID_CLGD5422  (0x23<<2)
38
#define CIRRUS_ID_CLGD5426  (0x24<<2)
39
#define CIRRUS_ID_CLGD5424  (0x25<<2)
40
#define CIRRUS_ID_CLGD5428  (0x26<<2)
41
#define CIRRUS_ID_CLGD5430  (0x28<<2)
42
#define CIRRUS_ID_CLGD5434  (0x2A<<2)
43
#define CIRRUS_ID_CLGD5446  (0x2E<<2)
44

    
45
// sequencer 0x07
46
#define CIRRUS_SR7_BPP_VGA            0x00
47
#define CIRRUS_SR7_BPP_SVGA           0x01
48
#define CIRRUS_SR7_BPP_MASK           0x0e
49
#define CIRRUS_SR7_BPP_8              0x00
50
#define CIRRUS_SR7_BPP_16_DOUBLEVCLK  0x02
51
#define CIRRUS_SR7_BPP_24             0x04
52
#define CIRRUS_SR7_BPP_16             0x06
53
#define CIRRUS_SR7_BPP_32             0x08
54
#define CIRRUS_SR7_ISAADDR_MASK       0xe0
55

    
56
// sequencer 0x0f
57
#define CIRRUS_MEMSIZE_512k        0x08
58
#define CIRRUS_MEMSIZE_1M          0x10
59
#define CIRRUS_MEMSIZE_2M          0x18
60
#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80        // bank switching is enabled.
61

    
62
// sequencer 0x12
63
#define CIRRUS_CURSOR_SHOW         0x01
64
#define CIRRUS_CURSOR_HIDDENPEL    0x02
65
#define CIRRUS_CURSOR_LARGE        0x04        // 64x64 if set, 32x32 if clear
66

    
67
// sequencer 0x17
68
#define CIRRUS_BUSTYPE_VLBFAST   0x10
69
#define CIRRUS_BUSTYPE_PCI       0x20
70
#define CIRRUS_BUSTYPE_VLBSLOW   0x30
71
#define CIRRUS_BUSTYPE_ISA       0x38
72
#define CIRRUS_MMIO_ENABLE       0x04
73
#define CIRRUS_MMIO_USE_PCIADDR  0x40        // 0xb8000 if cleared.
74
#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
75

    
76
// control 0x0b
77
#define CIRRUS_BANKING_DUAL             0x01
78
#define CIRRUS_BANKING_GRANULARITY_16K  0x20        // set:16k, clear:4k
79

    
80
// control 0x30
81
#define CIRRUS_BLTMODE_BACKWARDS        0x01
82
#define CIRRUS_BLTMODE_MEMSYSDEST       0x02
83
#define CIRRUS_BLTMODE_MEMSYSSRC        0x04
84
#define CIRRUS_BLTMODE_TRANSPARENTCOMP  0x08
85
#define CIRRUS_BLTMODE_PATTERNCOPY      0x40
86
#define CIRRUS_BLTMODE_COLOREXPAND      0x80
87
#define CIRRUS_BLTMODE_PIXELWIDTHMASK   0x30
88
#define CIRRUS_BLTMODE_PIXELWIDTH8      0x00
89
#define CIRRUS_BLTMODE_PIXELWIDTH16     0x10
90
#define CIRRUS_BLTMODE_PIXELWIDTH24     0x20
91
#define CIRRUS_BLTMODE_PIXELWIDTH32     0x30
92

    
93
// control 0x31
94
#define CIRRUS_BLT_BUSY                 0x01
95
#define CIRRUS_BLT_START                0x02
96
#define CIRRUS_BLT_RESET                0x04
97
#define CIRRUS_BLT_FIFOUSED             0x10
98

    
99
// control 0x32
100
#define CIRRUS_ROP_0                    0x00
101
#define CIRRUS_ROP_SRC_AND_DST          0x05
102
#define CIRRUS_ROP_NOP                  0x06
103
#define CIRRUS_ROP_SRC_AND_NOTDST       0x09
104
#define CIRRUS_ROP_NOTDST               0x0b
105
#define CIRRUS_ROP_SRC                  0x0d
106
#define CIRRUS_ROP_1                    0x0e
107
#define CIRRUS_ROP_NOTSRC_AND_DST       0x50
108
#define CIRRUS_ROP_SRC_XOR_DST          0x59
109
#define CIRRUS_ROP_SRC_OR_DST           0x6d
110
#define CIRRUS_ROP_NOTSRC_OR_NOTDST     0x90
111
#define CIRRUS_ROP_SRC_NOTXOR_DST       0x95
112
#define CIRRUS_ROP_SRC_OR_NOTDST        0xad
113
#define CIRRUS_ROP_NOTSRC               0xd0
114
#define CIRRUS_ROP_NOTSRC_OR_DST        0xd6
115
#define CIRRUS_ROP_NOTSRC_AND_NOTDST    0xda
116

    
117
// memory-mapped IO
118
#define CIRRUS_MMIO_BLTBGCOLOR        0x00        // dword
119
#define CIRRUS_MMIO_BLTFGCOLOR        0x04        // dword
120
#define CIRRUS_MMIO_BLTWIDTH          0x08        // word
121
#define CIRRUS_MMIO_BLTHEIGHT         0x0a        // word
122
#define CIRRUS_MMIO_BLTDESTPITCH      0x0c        // word
123
#define CIRRUS_MMIO_BLTSRCPITCH       0x0e        // word
124
#define CIRRUS_MMIO_BLTDESTADDR       0x10        // dword
125
#define CIRRUS_MMIO_BLTSRCADDR        0x14        // dword
126
#define CIRRUS_MMIO_BLTWRITEMASK      0x17        // byte
127
#define CIRRUS_MMIO_BLTMODE           0x18        // byte
128
#define CIRRUS_MMIO_BLTROP            0x1a        // byte
129
#define CIRRUS_MMIO_BLTMODEEXT        0x1b        // byte
130
#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c        // word?
131
#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20        // word?
132
#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24        // word
133
#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26        // word
134
#define CIRRUS_MMIO_LINEARDRAW_END_X  0x28        // word
135
#define CIRRUS_MMIO_LINEARDRAW_END_Y  0x2a        // word
136
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c        // byte
137
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d        // byte
138
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e        // byte
139
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f        // byte
140
#define CIRRUS_MMIO_BRESENHAM_K1      0x30        // word
141
#define CIRRUS_MMIO_BRESENHAM_K3      0x32        // word
142
#define CIRRUS_MMIO_BRESENHAM_ERROR   0x34        // word
143
#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36        // word
144
#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38        // byte
145
#define CIRRUS_MMIO_LINEDRAW_MODE     0x39        // byte
146
#define CIRRUS_MMIO_BLTSTATUS         0x40        // byte
147

    
148
// PCI 0x00: vendor, 0x02: device
149
#define PCI_VENDOR_CIRRUS             0x1013
150
#define PCI_DEVICE_CLGD5430           0x00a0        // CLGD5430 or CLGD5440
151
#define PCI_DEVICE_CLGD5434           0x00a8
152
#define PCI_DEVICE_CLGD5436           0x00ac
153
#define PCI_DEVICE_CLGD5446           0x00b8
154
#define PCI_DEVICE_CLGD5462           0x00d0
155
#define PCI_DEVICE_CLGD5465           0x00d6
156
// PCI 0x04: command(word), 0x06(word): status
157
#define PCI_COMMAND_IOACCESS                0x0001
158
#define PCI_COMMAND_MEMACCESS               0x0002
159
#define PCI_COMMAND_BUSMASTER               0x0004
160
#define PCI_COMMAND_SPECIALCYCLE            0x0008
161
#define PCI_COMMAND_MEMWRITEINVALID         0x0010
162
#define PCI_COMMAND_PALETTESNOOPING         0x0020
163
#define PCI_COMMAND_PARITYDETECTION         0x0040
164
#define PCI_COMMAND_ADDRESSDATASTEPPING     0x0080
165
#define PCI_COMMAND_SERR                    0x0100
166
#define PCI_COMMAND_BACKTOBACKTRANS         0x0200
167
// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
168
#define PCI_CLASS_BASE_DISPLAY        0x03
169
// PCI 0x08, 0x00ff0000
170
#define PCI_CLASS_SUB_VGA             0x00
171
// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
172
#define PCI_CLASS_HEADERTYPE_00h  0x00
173
// 0x10-0x3f (headertype 00h)
174
// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
175
//   0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
176
#define PCI_MAP_MEM                 0x0
177
#define PCI_MAP_IO                  0x1
178
#define PCI_MAP_MEM_ADDR_MASK       (~0xf)
179
#define PCI_MAP_IO_ADDR_MASK        (~0x3)
180
#define PCI_MAP_MEMFLAGS_32BIT      0x0
181
#define PCI_MAP_MEMFLAGS_32BIT_1M   0x1
182
#define PCI_MAP_MEMFLAGS_64BIT      0x4
183
#define PCI_MAP_MEMFLAGS_CACHEABLE  0x8
184
// PCI 0x28: cardbus CIS pointer
185
// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
186
// PCI 0x30: expansion ROM base address
187
#define PCI_ROMBIOS_ENABLED         0x1
188
// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
189
// PCI 0x38: reserved
190
// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
191

    
192
#define CIRRUS_PNPMMIO_SIZE         0x800
193

    
194

    
195
/* I/O and memory hook */
196
#define CIRRUS_HOOK_NOT_HANDLED 0
197
#define CIRRUS_HOOK_HANDLED 1
198

    
199
typedef void (*cirrus_bitblt_rop_t) (uint8_t * dst, const uint8_t * src,
200
                                     int dstpitch, int srcpitch,
201
                                     int bltwidth, int bltheight);
202

    
203
typedef void (*cirrus_bitblt_handler_t) (void *opaque);
204

    
205
typedef struct CirrusVGAState {
206
    /* XXX: we use the anonymous struct/union gcc 3.x extension */
207
    struct VGAState;
208

    
209
    int cirrus_linear_io_addr;
210
    int cirrus_mmio_io_addr;
211
    uint32_t cirrus_addr_mask;
212
    uint8_t cirrus_shadow_gr0;
213
    uint8_t cirrus_shadow_gr1;
214
    uint8_t cirrus_hidden_dac_lockindex;
215
    uint8_t cirrus_hidden_dac_data;
216
    uint32_t cirrus_bank_base[2];
217
    uint32_t cirrus_bank_limit[2];
218
    uint8_t cirrus_hidden_palette[48];
219
    uint32_t cirrus_hw_cursor_x;
220
    uint32_t cirrus_hw_cursor_y;
221
    int cirrus_blt_pixelwidth;
222
    int cirrus_blt_width;
223
    int cirrus_blt_height;
224
    int cirrus_blt_dstpitch;
225
    int cirrus_blt_srcpitch;
226
    uint32_t cirrus_blt_dstaddr;
227
    uint32_t cirrus_blt_srcaddr;
228
    uint8_t cirrus_blt_mode;
229
    cirrus_bitblt_rop_t cirrus_rop;
230
#define CIRRUS_BLTBUFSIZE 256
231
    uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
232
    uint8_t *cirrus_srcptr;
233
    uint8_t *cirrus_srcptr_end;
234
    uint32_t cirrus_srccounter;
235
    uint8_t *cirrus_dstptr;
236
    uint8_t *cirrus_dstptr_end;
237
    uint32_t cirrus_dstcounter;
238
    cirrus_bitblt_handler_t cirrus_blt_handler;
239
    int cirrus_blt_horz_counter;
240
} CirrusVGAState;
241

    
242
typedef struct PCICirrusVGAState {
243
    PCIDevice dev;
244
    CirrusVGAState cirrus_vga;
245
} PCICirrusVGAState;
246

    
247
/***************************************
248
 *
249
 *  prototypes.
250
 *
251
 ***************************************/
252

    
253

    
254
static void cirrus_bitblt_reset(CirrusVGAState * s);
255

    
256
/***************************************
257
 *
258
 *  raster operations
259
 *
260
 ***************************************/
261

    
262
#define IMPLEMENT_FORWARD_BITBLT(name,opline) \
263
  static void \
264
  cirrus_bitblt_rop_fwd_##name( \
265
    uint8_t *dst,const uint8_t *src, \
266
    int dstpitch,int srcpitch, \
267
    int bltwidth,int bltheight) \
268
  { \
269
    int x,y; \
270
    dstpitch -= bltwidth; \
271
    srcpitch -= bltwidth; \
272
    for (y = 0; y < bltheight; y++) { \
273
      for (x = 0; x < bltwidth; x++) { \
274
        opline; \
275
        dst++; \
276
        src++; \
277
        } \
278
      dst += dstpitch; \
279
      src += srcpitch; \
280
      } \
281
    }
282

    
283
#define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
284
  static void \
285
  cirrus_bitblt_rop_bkwd_##name( \
286
    uint8_t *dst,const uint8_t *src, \
287
    int dstpitch,int srcpitch, \
288
    int bltwidth,int bltheight) \
289
  { \
290
    int x,y; \
291
    dstpitch += bltwidth; \
292
    srcpitch += bltwidth; \
293
    for (y = 0; y < bltheight; y++) { \
294
      for (x = 0; x < bltwidth; x++) { \
295
        opline; \
296
        dst--; \
297
        src--; \
298
      } \
299
      dst += dstpitch; \
300
      src += srcpitch; \
301
    } \
302
  }
303

    
304
IMPLEMENT_FORWARD_BITBLT(0, *dst = 0)
305
    IMPLEMENT_FORWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
306
    IMPLEMENT_FORWARD_BITBLT(nop, (void) 0)
307
    IMPLEMENT_FORWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
308
    IMPLEMENT_FORWARD_BITBLT(notdst, *dst = ~(*dst))
309
    IMPLEMENT_FORWARD_BITBLT(src, *dst = *src)
310
    IMPLEMENT_FORWARD_BITBLT(1, *dst = 0xff)
311
    IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
312
    IMPLEMENT_FORWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
313
    IMPLEMENT_FORWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
314
    IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
315
    IMPLEMENT_FORWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
316
    IMPLEMENT_FORWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
317
    IMPLEMENT_FORWARD_BITBLT(notsrc, *dst = (~(*src)))
318
    IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
319
    IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
320

    
321
    IMPLEMENT_BACKWARD_BITBLT(0, *dst = 0)
322
    IMPLEMENT_BACKWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
323
    IMPLEMENT_BACKWARD_BITBLT(nop, (void) 0)
324
    IMPLEMENT_BACKWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
325
    IMPLEMENT_BACKWARD_BITBLT(notdst, *dst = ~(*dst))
326
    IMPLEMENT_BACKWARD_BITBLT(src, *dst = *src)
327
    IMPLEMENT_BACKWARD_BITBLT(1, *dst = 0xff)
328
    IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
329
    IMPLEMENT_BACKWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
330
    IMPLEMENT_BACKWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
331
    IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
332
    IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
333
    IMPLEMENT_BACKWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
334
    IMPLEMENT_BACKWARD_BITBLT(notsrc, *dst = (~(*src)))
335
    IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
336
    IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
337

    
338
static cirrus_bitblt_rop_t cirrus_get_fwd_rop_handler(uint8_t rop)
339
{
340
    cirrus_bitblt_rop_t rop_handler = cirrus_bitblt_rop_fwd_nop;
341

    
342
    switch (rop) {
343
    case CIRRUS_ROP_0:
344
        rop_handler = cirrus_bitblt_rop_fwd_0;
345
        break;
346
    case CIRRUS_ROP_SRC_AND_DST:
347
        rop_handler = cirrus_bitblt_rop_fwd_src_and_dst;
348
        break;
349
    case CIRRUS_ROP_NOP:
350
        rop_handler = cirrus_bitblt_rop_fwd_nop;
351
        break;
352
    case CIRRUS_ROP_SRC_AND_NOTDST:
353
        rop_handler = cirrus_bitblt_rop_fwd_src_and_notdst;
354
        break;
355
    case CIRRUS_ROP_NOTDST:
356
        rop_handler = cirrus_bitblt_rop_fwd_notdst;
357
        break;
358
    case CIRRUS_ROP_SRC:
359
        rop_handler = cirrus_bitblt_rop_fwd_src;
360
        break;
361
    case CIRRUS_ROP_1:
362
        rop_handler = cirrus_bitblt_rop_fwd_1;
363
        break;
364
    case CIRRUS_ROP_NOTSRC_AND_DST:
365
        rop_handler = cirrus_bitblt_rop_fwd_notsrc_and_dst;
366
        break;
367
    case CIRRUS_ROP_SRC_XOR_DST:
368
        rop_handler = cirrus_bitblt_rop_fwd_src_xor_dst;
369
        break;
370
    case CIRRUS_ROP_SRC_OR_DST:
371
        rop_handler = cirrus_bitblt_rop_fwd_src_or_dst;
372
        break;
373
    case CIRRUS_ROP_NOTSRC_OR_NOTDST:
374
        rop_handler = cirrus_bitblt_rop_fwd_notsrc_or_notdst;
375
        break;
376
    case CIRRUS_ROP_SRC_NOTXOR_DST:
377
        rop_handler = cirrus_bitblt_rop_fwd_src_notxor_dst;
378
        break;
379
    case CIRRUS_ROP_SRC_OR_NOTDST:
380
        rop_handler = cirrus_bitblt_rop_fwd_src_or_notdst;
381
        break;
382
    case CIRRUS_ROP_NOTSRC:
383
        rop_handler = cirrus_bitblt_rop_fwd_notsrc;
384
        break;
385
    case CIRRUS_ROP_NOTSRC_OR_DST:
386
        rop_handler = cirrus_bitblt_rop_fwd_notsrc_or_dst;
387
        break;
388
    case CIRRUS_ROP_NOTSRC_AND_NOTDST:
389
        rop_handler = cirrus_bitblt_rop_fwd_notsrc_and_notdst;
390
        break;
391
    default:
392
#ifdef DEBUG_CIRRUS
393
        printf("unknown ROP %02x\n", rop);
394
#endif
395
        break;
396
    }
397

    
398
    return rop_handler;
399
}
400

    
401
static cirrus_bitblt_rop_t cirrus_get_bkwd_rop_handler(uint8_t rop)
402
{
403
    cirrus_bitblt_rop_t rop_handler = cirrus_bitblt_rop_bkwd_nop;
404

    
405
    switch (rop) {
406
    case CIRRUS_ROP_0:
407
        rop_handler = cirrus_bitblt_rop_bkwd_0;
408
        break;
409
    case CIRRUS_ROP_SRC_AND_DST:
410
        rop_handler = cirrus_bitblt_rop_bkwd_src_and_dst;
411
        break;
412
    case CIRRUS_ROP_NOP:
413
        rop_handler = cirrus_bitblt_rop_bkwd_nop;
414
        break;
415
    case CIRRUS_ROP_SRC_AND_NOTDST:
416
        rop_handler = cirrus_bitblt_rop_bkwd_src_and_notdst;
417
        break;
418
    case CIRRUS_ROP_NOTDST:
419
        rop_handler = cirrus_bitblt_rop_bkwd_notdst;
420
        break;
421
    case CIRRUS_ROP_SRC:
422
        rop_handler = cirrus_bitblt_rop_bkwd_src;
423
        break;
424
    case CIRRUS_ROP_1:
425
        rop_handler = cirrus_bitblt_rop_bkwd_1;
426
        break;
427
    case CIRRUS_ROP_NOTSRC_AND_DST:
428
        rop_handler = cirrus_bitblt_rop_bkwd_notsrc_and_dst;
429
        break;
430
    case CIRRUS_ROP_SRC_XOR_DST:
431
        rop_handler = cirrus_bitblt_rop_bkwd_src_xor_dst;
432
        break;
433
    case CIRRUS_ROP_SRC_OR_DST:
434
        rop_handler = cirrus_bitblt_rop_bkwd_src_or_dst;
435
        break;
436
    case CIRRUS_ROP_NOTSRC_OR_NOTDST:
437
        rop_handler = cirrus_bitblt_rop_bkwd_notsrc_or_notdst;
438
        break;
439
    case CIRRUS_ROP_SRC_NOTXOR_DST:
440
        rop_handler = cirrus_bitblt_rop_bkwd_src_notxor_dst;
441
        break;
442
    case CIRRUS_ROP_SRC_OR_NOTDST:
443
        rop_handler = cirrus_bitblt_rop_bkwd_src_or_notdst;
444
        break;
445
    case CIRRUS_ROP_NOTSRC:
446
        rop_handler = cirrus_bitblt_rop_bkwd_notsrc;
447
        break;
448
    case CIRRUS_ROP_NOTSRC_OR_DST:
449
        rop_handler = cirrus_bitblt_rop_bkwd_notsrc_or_dst;
450
        break;
451
    case CIRRUS_ROP_NOTSRC_AND_NOTDST:
452
        rop_handler = cirrus_bitblt_rop_bkwd_notsrc_and_notdst;
453
        break;
454
    default:
455
#ifdef DEBUG_CIRRUS
456
        printf("unknown ROP %02x\n", rop);
457
#endif
458
        break;
459
    }
460

    
461
    return rop_handler;
462
}
463

    
464
/***************************************
465
 *
466
 *  color expansion
467
 *
468
 ***************************************/
469

    
470
static void
471
cirrus_colorexpand_8(CirrusVGAState * s, uint8_t * dst,
472
                     const uint8_t * src, int count)
473
{
474
    int x;
475
    uint8_t colors[2];
476
    unsigned bits;
477
    unsigned bitmask;
478
    int srcskipleft = 0;
479

    
480
    colors[0] = s->gr[0x00];
481
    colors[1] = s->gr[0x01];
482

    
483
    bitmask = 0x80 >> srcskipleft;
484
    bits = *src++;
485
    for (x = 0; x < count; x++) {
486
        if ((bitmask & 0xff) == 0) {
487
            bitmask = 0x80;
488
            bits = *src++;
489
        }
490
        *dst++ = colors[!!(bits & bitmask)];
491
        bitmask >>= 1;
492
    }
493
}
494

    
495
static void
496
cirrus_colorexpand_16(CirrusVGAState * s, uint8_t * dst,
497
                      const uint8_t * src, int count)
498
{
499
    int x;
500
    uint8_t colors[2][2];
501
    unsigned bits;
502
    unsigned bitmask;
503
    unsigned index;
504
    int srcskipleft = 0;
505

    
506
    colors[0][0] = s->gr[0x00];
507
    colors[0][1] = s->gr[0x10];
508
    colors[1][0] = s->gr[0x01];
509
    colors[1][1] = s->gr[0x11];
510

    
511
    bitmask = 0x80 >> srcskipleft;
512
    bits = *src++;
513
    for (x = 0; x < count; x++) {
514
        if ((bitmask & 0xff) == 0) {
515
            bitmask = 0x80;
516
            bits = *src++;
517
        }
518
        index = !!(bits & bitmask);
519
        *dst++ = colors[index][0];
520
        *dst++ = colors[index][1];
521
        bitmask >>= 1;
522
    }
523
}
524

    
525
static void
526
cirrus_colorexpand_24(CirrusVGAState * s, uint8_t * dst,
527
                      const uint8_t * src, int count)
528
{
529
    int x;
530
    uint8_t colors[2][3];
531
    unsigned bits;
532
    unsigned bitmask;
533
    unsigned index;
534
    int srcskipleft = 0;
535

    
536
    colors[0][0] = s->gr[0x00];
537
    colors[0][1] = s->gr[0x10];
538
    colors[0][2] = s->gr[0x12];
539
    colors[1][0] = s->gr[0x01];
540
    colors[1][1] = s->gr[0x11];
541
    colors[1][2] = s->gr[0x13];
542

    
543
    bitmask = 0x80 << srcskipleft;
544
    bits = *src++;
545
    for (x = 0; x < count; x++) {
546
        if ((bitmask & 0xff) == 0) {
547
            bitmask = 0x80;
548
            bits = *src++;
549
        }
550
        index = !!(bits & bitmask);
551
        *dst++ = colors[index][0];
552
        *dst++ = colors[index][1];
553
        *dst++ = colors[index][2];
554
        bitmask >>= 1;
555
    }
556
}
557

    
558
static void
559
cirrus_colorexpand_32(CirrusVGAState * s, uint8_t * dst,
560
                      const uint8_t * src, int count)
561
{
562
    int x;
563
    uint8_t colors[2][4];
564
    unsigned bits;
565
    unsigned bitmask;
566
    unsigned index;
567
    int srcskipleft = 0;
568

    
569
    colors[0][0] = s->gr[0x00];
570
    colors[0][1] = s->gr[0x10];
571
    colors[0][2] = s->gr[0x12];
572
    colors[0][3] = s->gr[0x14];
573
    colors[1][0] = s->gr[0x01];
574
    colors[1][1] = s->gr[0x11];
575
    colors[1][2] = s->gr[0x13];
576
    colors[1][3] = s->gr[0x15];
577

    
578
    bitmask = 0x80 << srcskipleft;
579
    bits = *src++;
580
    for (x = 0; x < count; x++) {
581
        if ((bitmask & 0xff) == 0) {
582
            bitmask = 0x80;
583
            bits = *src++;
584
        }
585
        index = !!(bits & bitmask);
586
        *dst++ = colors[index][0];
587
        *dst++ = colors[index][1];
588
        *dst++ = colors[index][2];
589
        *dst++ = colors[index][3];
590
        bitmask >>= 1;
591
    }
592
}
593

    
594
static void
595
cirrus_colorexpand(CirrusVGAState * s, uint8_t * dst, const uint8_t * src,
596
                   int count)
597
{
598
    switch (s->cirrus_blt_pixelwidth) {
599
    case 1:
600
        cirrus_colorexpand_8(s, dst, src, count);
601
        break;
602
    case 2:
603
        cirrus_colorexpand_16(s, dst, src, count);
604
        break;
605
    case 3:
606
        cirrus_colorexpand_24(s, dst, src, count);
607
        break;
608
    case 4:
609
        cirrus_colorexpand_32(s, dst, src, count);
610
        break;
611
    default:
612
#ifdef DEBUG_CIRRUS
613
        printf("cirrus: COLOREXPAND pixelwidth %d - unimplemented\n",
614
               s->cirrus_blt_pixelwidth);
615
#endif
616
        break;
617
    }
618
}
619

    
620
static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
621
                                     int off_pitch, int bytesperline,
622
                                     int lines)
623
{
624
    int y;
625
    int off_cur;
626
    int off_cur_end;
627

    
628
    for (y = 0; y < lines; y++) {
629
        off_cur = off_begin;
630
        off_cur_end = off_cur + bytesperline;
631
        off_cur &= TARGET_PAGE_MASK;
632
        while (off_cur < off_cur_end) {
633
            cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
634
            off_cur += TARGET_PAGE_SIZE;
635
        }
636
        off_begin += off_pitch;
637
    }
638
}
639

    
640

    
641

    
642
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
643
                                            const uint8_t * src)
644
{
645
    uint8_t work_colorexp[256];
646
    uint8_t *dst;
647
    uint8_t *dstc;
648
    int x, y;
649
    int tilewidth, tileheight;
650
    int patternbytes = s->cirrus_blt_pixelwidth * 8;
651

    
652
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
653
        cirrus_colorexpand(s, work_colorexp, src, 8 * 8);
654
        src = work_colorexp;
655
        s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND;
656
    }
657
    if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) {
658
#ifdef DEBUG_CIRRUS
659
        printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n",
660
               s->cirrus_blt_mode);
661
#endif
662
        return 0;
663
    }
664

    
665
    dst = s->vram_ptr + s->cirrus_blt_dstaddr;
666
    for (y = 0; y < s->cirrus_blt_height; y += 8) {
667
        dstc = dst;
668
        tileheight = qemu_MIN(8, s->cirrus_blt_height - y);
669
        for (x = 0; x < s->cirrus_blt_width; x += patternbytes) {
670
            tilewidth = qemu_MIN(patternbytes, s->cirrus_blt_width - x);
671
            (*s->cirrus_rop) (dstc, src,
672
                              s->cirrus_blt_dstpitch, patternbytes,
673
                              tilewidth, tileheight);
674
            dstc += patternbytes;
675
        }
676
        dst += s->cirrus_blt_dstpitch * 8;
677
    }
678
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
679
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
680
                             s->cirrus_blt_height);
681
    return 1;
682
}
683

    
684
/***************************************
685
 *
686
 *  bitblt (video-to-video)
687
 *
688
 ***************************************/
689

    
690
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
691
{
692
    return cirrus_bitblt_common_patterncopy(s,
693
                                            s->vram_ptr +
694
                                            s->cirrus_blt_srcaddr);
695
}
696

    
697
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
698
{
699
    if ((s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) != 0) {
700
#ifdef DEBUG_CIRRUS
701
        printf("cirrus: CIRRUS_BLTMODE_COLOREXPAND - unimplemented\n");
702
#endif
703
        return 0;
704
    }
705
    if ((s->cirrus_blt_mode & (~CIRRUS_BLTMODE_BACKWARDS)) != 0) {
706
#ifdef DEBUG_CIRRUS
707
        printf("cirrus: blt mode %02x - unimplemented\n",
708
               s->cirrus_blt_mode);
709
#endif
710
        return 0;
711
    }
712

    
713
    (*s->cirrus_rop) (s->vram_ptr + s->cirrus_blt_dstaddr,
714
                      s->vram_ptr + s->cirrus_blt_srcaddr,
715
                      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
716
                      s->cirrus_blt_width, s->cirrus_blt_height);
717
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
718
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
719
                             s->cirrus_blt_height);
720
    return 1;
721
}
722

    
723
/***************************************
724
 *
725
 *  bitblt (cpu-to-video)
726
 *
727
 ***************************************/
728

    
729
static void cirrus_bitblt_cputovideo_patterncopy(void *opaque)
730
{
731
    CirrusVGAState *s = (CirrusVGAState *) opaque;
732
    int data_count;
733

    
734
    data_count = s->cirrus_srcptr - &s->cirrus_bltbuf[0];
735

    
736
    if (data_count > 0) {
737
        if (data_count != s->cirrus_srccounter) {
738
#ifdef DEBUG_CIRRUS
739
            printf("cirrus: internal error\n");
740
#endif
741
        } else {
742
            cirrus_bitblt_common_patterncopy(s, &s->cirrus_bltbuf[0]);
743
        }
744
        cirrus_bitblt_reset(s);
745
    }
746
}
747

    
748
static void cirrus_bitblt_cputovideo_copy(void *opaque)
749
{
750
    CirrusVGAState *s = (CirrusVGAState *) opaque;
751
    int data_count;
752
    int data_avail;
753
    uint8_t work_colorexp[256];
754
    uint8_t *src_ptr = NULL;
755
    int src_avail = 0;
756
    int src_processing;
757
    int src_linepad = 0;
758

    
759
    if (s->cirrus_blt_height <= 0) {
760
        s->cirrus_srcptr = s->cirrus_srcptr_end;
761
        return;
762
    }
763

    
764
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
765
    while (1) {
766
        /* get BLT source. */
767
        if (src_avail <= 0) {
768
            data_count = s->cirrus_srcptr_end - s->cirrus_srcptr;
769
            if (data_count <= 0)
770
                break;
771

    
772
            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
773
                if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_COLOREXPAND) {
774
#ifdef DEBUG_CIRRUS
775
                    printf("cirrus: unsupported\n");
776
#endif
777
                    cirrus_bitblt_reset(s);
778
                    return;
779
                }
780
                data_avail = qemu_MIN(data_count, 256 / 32);
781
                cirrus_colorexpand(s, work_colorexp, s->cirrus_srcptr,
782
                                   data_avail * 8);
783
                src_ptr = &work_colorexp[0];
784
                src_avail = data_avail * 8 * s->cirrus_blt_pixelwidth;
785
                s->cirrus_srcptr += data_avail;
786
                src_linepad =
787
                    ((s->cirrus_blt_width + 7) / 8) * 8 -
788
                    s->cirrus_blt_width;
789
                src_linepad *= s->cirrus_blt_pixelwidth;
790
            } else {
791
                if (s->cirrus_blt_mode != 0) {
792
#ifdef DEBUG_CIRRUS
793
                    printf("cirrus: unsupported\n");
794
#endif
795
                    cirrus_bitblt_reset(s);
796
                    return;
797
                }
798
                src_ptr = s->cirrus_srcptr;
799
                src_avail =
800
                    data_count / s->cirrus_blt_pixelwidth *
801
                    s->cirrus_blt_pixelwidth;
802
                s->cirrus_srcptr += src_avail;
803
            }
804
            if (src_avail <= 0)
805
                break;
806
        }
807

    
808
        /* 1-line BLT */
809
        src_processing =
810
            s->cirrus_blt_srcpitch - s->cirrus_blt_horz_counter;
811
        src_processing = qemu_MIN(src_avail, src_processing);
812
        (*s->cirrus_rop) (s->vram_ptr + s->cirrus_blt_dstaddr,
813
                          src_ptr, 0, 0, src_processing, 1);
814
        cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
815
                                 src_processing, 1);
816

    
817
        s->cirrus_blt_dstaddr += src_processing;
818
        src_ptr += src_processing;
819
        src_avail -= src_processing;
820
        s->cirrus_blt_horz_counter += src_processing;
821
        if (s->cirrus_blt_horz_counter >= s->cirrus_blt_srcpitch) {
822
            src_ptr += src_linepad;
823
            src_avail -= src_linepad;
824
            s->cirrus_blt_dstaddr +=
825
                s->cirrus_blt_dstpitch - s->cirrus_blt_srcpitch;
826
            s->cirrus_blt_horz_counter = 0;
827
            s->cirrus_blt_height--;
828
            if (s->cirrus_blt_height <= 0) {
829
                s->cirrus_srcptr = s->cirrus_srcptr_end;
830
                return;
831
            }
832
        }
833
    }
834
}
835

    
836
static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
837
{
838
    int copy_count;
839
    int avail_count;
840

    
841
    s->cirrus_blt_handler(s);
842

    
843
    if (s->cirrus_srccounter > 0) {
844
        s->cirrus_srccounter -= s->cirrus_srcptr - &s->cirrus_bltbuf[0];
845
        copy_count = s->cirrus_srcptr_end - s->cirrus_srcptr;
846
        memmove(&s->cirrus_bltbuf[0], s->cirrus_srcptr, copy_count);
847
        avail_count = qemu_MIN(CIRRUS_BLTBUFSIZE, s->cirrus_srccounter);
848
        s->cirrus_srcptr = &s->cirrus_bltbuf[0];
849
        s->cirrus_srcptr_end = s->cirrus_srcptr + avail_count;
850
        if (s->cirrus_srccounter <= 0) {
851
            cirrus_bitblt_reset(s);
852
        }
853
    }
854
}
855

    
856
/***************************************
857
 *
858
 *  bitblt wrapper
859
 *
860
 ***************************************/
861

    
862
static void cirrus_bitblt_reset(CirrusVGAState * s)
863
{
864
    s->gr[0x31] &=
865
        ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
866
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
867
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
868
    s->cirrus_srccounter = 0;
869
    s->cirrus_dstptr = &s->cirrus_bltbuf[0];
870
    s->cirrus_dstptr_end = &s->cirrus_bltbuf[0];
871
    s->cirrus_dstcounter = 0;
872
    s->cirrus_blt_handler = NULL;
873
}
874

    
875
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
876
{
877
    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
878
    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
879
    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
880

    
881
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
882
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
883
            s->cirrus_srccounter = 8;
884
        } else {
885
            s->cirrus_srccounter = 8 * 8 * s->cirrus_blt_pixelwidth;
886
        }
887
        s->cirrus_blt_srcpitch = 0;
888
        s->cirrus_blt_handler = cirrus_bitblt_cputovideo_patterncopy;
889
    } else {
890
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
891
            s->cirrus_srccounter =
892
                ((s->cirrus_blt_width + 7) / 8) * s->cirrus_blt_height;
893
            s->cirrus_blt_srcpitch =
894
                s->cirrus_blt_width * s->cirrus_blt_pixelwidth;
895
        } else {
896
            s->cirrus_srccounter =
897
                s->cirrus_blt_width * s->cirrus_blt_height;
898
            s->cirrus_blt_srcpitch = s->cirrus_blt_width;
899
        }
900
        /* 4-byte alignment */
901
        s->cirrus_srccounter = (s->cirrus_srccounter + 3) & (~3);
902

    
903
        s->cirrus_blt_handler = cirrus_bitblt_cputovideo_copy;
904
        s->cirrus_blt_horz_counter = 0;
905
    }
906

    
907
    cirrus_bitblt_cputovideo_next(s);
908
    return 1;
909
}
910

    
911
static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
912
{
913
    /* XXX */
914
#ifdef DEBUG_CIRRUS
915
    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
916
#endif
917
    return 0;
918
}
919

    
920
static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
921
{
922
    int ret;
923

    
924
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
925
        ret = cirrus_bitblt_videotovideo_patterncopy(s);
926
    } else {
927
        ret = cirrus_bitblt_videotovideo_copy(s);
928
    }
929

    
930
    if (ret)
931
        cirrus_bitblt_reset(s);
932
    return ret;
933
}
934

    
935
static void cirrus_bitblt_start(CirrusVGAState * s)
936
{
937
    uint8_t blt_rop;
938

    
939
    s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
940
    s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
941
    s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
942
    s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));
943
    s->cirrus_blt_dstaddr =
944
        (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));
945
    s->cirrus_blt_srcaddr =
946
        (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
947
    s->cirrus_blt_mode = s->gr[0x30];
948
    blt_rop = s->gr[0x32];
949

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

    
971
    if ((s->
972
         cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
973
                            CIRRUS_BLTMODE_MEMSYSDEST))
974
        == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
975
#ifdef DEBUG_CIRRUS
976
        printf("cirrus: bitblt - memory-to-memory copy is requested\n");
977
#endif
978
        goto bitblt_ignore;
979
    }
980

    
981
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
982
        s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
983
        s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
984
        s->cirrus_rop = cirrus_get_bkwd_rop_handler(blt_rop);
985
    } else {
986
        s->cirrus_rop = cirrus_get_fwd_rop_handler(blt_rop);
987
    }
988

    
989
    // setup bitblt engine.
990
    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
991
        if (!cirrus_bitblt_cputovideo(s))
992
            goto bitblt_ignore;
993
    } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
994
        if (!cirrus_bitblt_videotocpu(s))
995
            goto bitblt_ignore;
996
    } else {
997
        if (!cirrus_bitblt_videotovideo(s))
998
            goto bitblt_ignore;
999
    }
1000

    
1001
    return;
1002
  bitblt_ignore:;
1003
    cirrus_bitblt_reset(s);
1004
}
1005

    
1006
static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1007
{
1008
    unsigned old_value;
1009

    
1010
    old_value = s->gr[0x31];
1011
    s->gr[0x31] = reg_value;
1012

    
1013
    if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1014
        ((reg_value & CIRRUS_BLT_RESET) == 0)) {
1015
        cirrus_bitblt_reset(s);
1016
    } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1017
               ((reg_value & CIRRUS_BLT_START) != 0)) {
1018
        s->gr[0x31] |= CIRRUS_BLT_BUSY;
1019
        cirrus_bitblt_start(s);
1020
    }
1021
}
1022

    
1023

    
1024
/***************************************
1025
 *
1026
 *  basic parameters
1027
 *
1028
 ***************************************/
1029

    
1030
static void cirrus_get_offsets(VGAState *s1, 
1031
                                   uint32_t *pline_offset,
1032
                                   uint32_t *pstart_addr)
1033
{
1034
    CirrusVGAState * s = (CirrusVGAState *)s1;
1035
    uint32_t start_addr;
1036
    uint32_t line_offset;
1037

    
1038
    line_offset = s->cr[0x13]
1039
        | ((s->cr[0x1b] & 0x10) << 8);
1040
    line_offset <<= 3;
1041
    *pline_offset = line_offset;
1042

    
1043
    start_addr = (s->cr[0x0c] << 8)
1044
        | s->cr[0x0d]
1045
        | ((s->cr[0x1b] & 0x01) << 16)
1046
        | ((s->cr[0x1b] & 0x0c) << 15)
1047
        | ((s->cr[0x1d] & 0x80) << 12);
1048
    *pstart_addr = start_addr;
1049
}
1050

    
1051
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1052
{
1053
    uint32_t ret = 16;
1054

    
1055
    switch (s->cirrus_hidden_dac_data & 0xf) {
1056
    case 0:
1057
        ret = 15;
1058
        break;                        /* Sierra HiColor */
1059
    case 1:
1060
        ret = 16;
1061
        break;                        /* XGA HiColor */
1062
    default:
1063
#ifdef DEBUG_CIRRUS
1064
        printf("cirrus: invalid DAC value %x in 16bpp\n",
1065
               (s->cirrus_hidden_dac_data & 0xf));
1066
#endif
1067
        ret = 15;                /* XXX */
1068
        break;
1069
    }
1070
    return ret;
1071
}
1072

    
1073
static int cirrus_get_bpp(VGAState *s1)
1074
{
1075
    CirrusVGAState * s = (CirrusVGAState *)s1;
1076
    uint32_t ret = 8;
1077

    
1078
    if ((s->sr[0x07] & 0x01) != 0) {
1079
        /* Cirrus SVGA */
1080
        switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1081
        case CIRRUS_SR7_BPP_8:
1082
            ret = 8;
1083
            break;
1084
        case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1085
            ret = cirrus_get_bpp16_depth(s);
1086
            break;
1087
        case CIRRUS_SR7_BPP_24:
1088
            ret = 24;
1089
            break;
1090
        case CIRRUS_SR7_BPP_16:
1091
            ret = cirrus_get_bpp16_depth(s);
1092
            break;
1093
        case CIRRUS_SR7_BPP_32:
1094
            ret = 32;
1095
            break;
1096
        default:
1097
#ifdef DEBUG_CIRRUS
1098
            printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);
1099
#endif
1100
            ret = 8;
1101
            break;
1102
        }
1103
    } else {
1104
        /* VGA */
1105
        ret = 8;
1106
    }
1107

    
1108
    return ret;
1109
}
1110

    
1111
/***************************************
1112
 *
1113
 * bank memory
1114
 *
1115
 ***************************************/
1116

    
1117
static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1118
{
1119
    unsigned offset;
1120
    unsigned limit;
1121

    
1122
    if ((s->gr[0x0b] & 0x01) != 0)        /* dual bank */
1123
        offset = s->gr[0x09 + bank_index];
1124
    else                        /* single bank */
1125
        offset = s->gr[0x09];
1126

    
1127
    if ((s->gr[0x0b] & 0x20) != 0)
1128
        offset <<= 14;
1129
    else
1130
        offset <<= 12;
1131

    
1132
    if (s->vram_size <= offset)
1133
        limit = 0;
1134
    else
1135
        limit = s->vram_size - offset;
1136

    
1137
    if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1138
        if (limit > 0x8000) {
1139
            offset += 0x8000;
1140
            limit -= 0x8000;
1141
        } else {
1142
            limit = 0;
1143
        }
1144
    }
1145

    
1146
    if (limit > 0) {
1147
        s->cirrus_bank_base[bank_index] = offset;
1148
        s->cirrus_bank_limit[bank_index] = limit;
1149
    } else {
1150
        s->cirrus_bank_base[bank_index] = 0;
1151
        s->cirrus_bank_limit[bank_index] = 0;
1152
    }
1153
}
1154

    
1155
/***************************************
1156
 *
1157
 *  I/O access between 0x3c4-0x3c5
1158
 *
1159
 ***************************************/
1160

    
1161
static int
1162
cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1163
{
1164
    switch (reg_index) {
1165
    case 0x00:                        // Standard VGA
1166
    case 0x01:                        // Standard VGA
1167
    case 0x02:                        // Standard VGA
1168
    case 0x03:                        // Standard VGA
1169
    case 0x04:                        // Standard VGA
1170
        return CIRRUS_HOOK_NOT_HANDLED;
1171
    case 0x06:                        // Unlock Cirrus extensions
1172
        *reg_value = s->sr[reg_index];
1173
        break;
1174
    case 0x05:                        // ???
1175
    case 0x07:                        // Extended Sequencer Mode
1176
    case 0x08:                        // EEPROM Control
1177
    case 0x09:                        // Scratch Register 0
1178
    case 0x0a:                        // Scratch Register 1
1179
    case 0x0b:                        // VCLK 0
1180
    case 0x0c:                        // VCLK 1
1181
    case 0x0d:                        // VCLK 2
1182
    case 0x0e:                        // VCLK 3
1183
    case 0x0f:                        // DRAM Control
1184
    case 0x10:
1185
    case 0x30:
1186
    case 0x50:
1187
    case 0x70:                        // Graphics Cursor X
1188
    case 0x90:
1189
    case 0xb0:
1190
    case 0xd0:
1191
    case 0xf0:                        // Graphics Cursor X
1192
    case 0x11:
1193
    case 0x31:
1194
    case 0x51:
1195
    case 0x71:                        // Graphics Cursor Y
1196
    case 0x91:
1197
    case 0xb1:
1198
    case 0xd1:
1199
    case 0xf1:                        // Graphics Cursor Y
1200
    case 0x12:                        // Graphics Cursor Attribute
1201
    case 0x13:                        // Graphics Cursor Pattern Address
1202
    case 0x14:                        // Scratch Register 2
1203
    case 0x15:                        // Scratch Register 3
1204
    case 0x16:                        // Performance Tuning Register
1205
    case 0x17:                        // Configuration Readback and Extended Control
1206
    case 0x18:                        // Signature Generator Control
1207
    case 0x19:                        // Signal Generator Result
1208
    case 0x1a:                        // Signal Generator Result
1209
    case 0x1b:                        // VCLK 0 Denominator & Post
1210
    case 0x1c:                        // VCLK 1 Denominator & Post
1211
    case 0x1d:                        // VCLK 2 Denominator & Post
1212
    case 0x1e:                        // VCLK 3 Denominator & Post
1213
    case 0x1f:                        // BIOS Write Enable and MCLK select
1214
#ifdef DEBUG_CIRRUS
1215
        printf("cirrus: handled inport sr_index %02x\n", reg_index);
1216
#endif
1217
        *reg_value = s->sr[reg_index];
1218
        break;
1219
    default:
1220
#ifdef DEBUG_CIRRUS
1221
        printf("cirrus: inport sr_index %02x\n", reg_index);
1222
#endif
1223
        *reg_value = 0xff;
1224
        break;
1225
    }
1226

    
1227
    return CIRRUS_HOOK_HANDLED;
1228
}
1229

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

    
1307
    return CIRRUS_HOOK_HANDLED;
1308
}
1309

    
1310
/***************************************
1311
 *
1312
 *  I/O access at 0x3c6
1313
 *
1314
 ***************************************/
1315

    
1316
static void cirrus_read_hidden_dac(CirrusVGAState * s, int *reg_value)
1317
{
1318
    *reg_value = 0xff;
1319
    if (s->cirrus_hidden_dac_lockindex < 5) {
1320
        if (s->cirrus_hidden_dac_lockindex == 4) {
1321
            *reg_value = s->cirrus_hidden_dac_data;
1322
        }
1323
        s->cirrus_hidden_dac_lockindex++;
1324
    }
1325
}
1326

    
1327
static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1328
{
1329
    if (s->cirrus_hidden_dac_lockindex == 4) {
1330
        s->cirrus_hidden_dac_data = reg_value;
1331
#ifdef DEBUG_CIRRUS
1332
        printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1333
#endif
1334
    }
1335
    s->cirrus_hidden_dac_lockindex = 0;
1336
}
1337

    
1338
/***************************************
1339
 *
1340
 *  I/O access at 0x3c9
1341
 *
1342
 ***************************************/
1343

    
1344
static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
1345
{
1346
    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1347
        return CIRRUS_HOOK_NOT_HANDLED;
1348
    if (s->dac_read_index < 0x10) {
1349
        *reg_value =
1350
            s->cirrus_hidden_palette[s->dac_read_index * 3 +
1351
                                     s->dac_sub_index];
1352
    } else {
1353
        *reg_value = 0xff;        /* XXX */
1354
    }
1355
    if (++s->dac_sub_index == 3) {
1356
        s->dac_sub_index = 0;
1357
        s->dac_read_index++;
1358
    }
1359
    return CIRRUS_HOOK_HANDLED;
1360
}
1361

    
1362
static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
1363
{
1364
    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1365
        return CIRRUS_HOOK_NOT_HANDLED;
1366
    s->dac_cache[s->dac_sub_index] = reg_value;
1367
    if (++s->dac_sub_index == 3) {
1368
        if (s->dac_read_index < 0x10) {
1369
            memcpy(&s->cirrus_hidden_palette[s->dac_write_index * 3],
1370
                   s->dac_cache, 3);
1371
            /* XXX update cursor */
1372
        }
1373
        s->dac_sub_index = 0;
1374
        s->dac_write_index++;
1375
    }
1376
    return CIRRUS_HOOK_HANDLED;
1377
}
1378

    
1379
/***************************************
1380
 *
1381
 *  I/O access between 0x3ce-0x3cf
1382
 *
1383
 ***************************************/
1384

    
1385
static int
1386
cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1387
{
1388
    switch (reg_index) {
1389
    case 0x02:                        // Standard VGA
1390
    case 0x03:                        // Standard VGA
1391
    case 0x04:                        // Standard VGA
1392
    case 0x06:                        // Standard VGA
1393
    case 0x07:                        // Standard VGA
1394
    case 0x08:                        // Standard VGA
1395
        return CIRRUS_HOOK_NOT_HANDLED;
1396
    case 0x05:                        // Standard VGA, Cirrus extended mode
1397
    default:
1398
        break;
1399
    }
1400

    
1401
    if (reg_index < 0x3a) {
1402
        *reg_value = s->gr[reg_index];
1403
    } else {
1404
#ifdef DEBUG_CIRRUS
1405
        printf("cirrus: inport gr_index %02x\n", reg_index);
1406
#endif
1407
        *reg_value = 0xff;
1408
    }
1409

    
1410
    return CIRRUS_HOOK_HANDLED;
1411
}
1412

    
1413
static int
1414
cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1415
{
1416
    switch (reg_index) {
1417
    case 0x00:                        // Standard VGA, BGCOLOR 0x000000ff
1418
        s->gr[0x00] = reg_value;
1419
        return CIRRUS_HOOK_NOT_HANDLED;
1420
    case 0x01:                        // Standard VGA, FGCOLOR 0x000000ff
1421
        s->gr[0x01] = reg_value;
1422
        return CIRRUS_HOOK_NOT_HANDLED;
1423
    case 0x02:                        // Standard VGA
1424
    case 0x03:                        // Standard VGA
1425
    case 0x04:                        // Standard VGA
1426
    case 0x06:                        // Standard VGA
1427
    case 0x07:                        // Standard VGA
1428
    case 0x08:                        // Standard VGA
1429
        return CIRRUS_HOOK_NOT_HANDLED;
1430
    case 0x05:                        // Standard VGA, Cirrus extended mode
1431
        s->gr[reg_index] = reg_value & 0x7f;
1432
        break;
1433
    case 0x09:                        // bank offset #0
1434
    case 0x0A:                        // bank offset #1
1435
    case 0x0B:
1436
        s->gr[reg_index] = reg_value;
1437
        cirrus_update_bank_ptr(s, 0);
1438
        cirrus_update_bank_ptr(s, 1);
1439
        break;
1440
    case 0x10:                        // BGCOLOR 0x0000ff00
1441
    case 0x11:                        // FGCOLOR 0x0000ff00
1442
    case 0x12:                        // BGCOLOR 0x00ff0000
1443
    case 0x13:                        // FGCOLOR 0x00ff0000
1444
    case 0x14:                        // BGCOLOR 0xff000000
1445
    case 0x15:                        // FGCOLOR 0xff000000
1446
    case 0x20:                        // BLT WIDTH 0x0000ff
1447
    case 0x22:                        // BLT HEIGHT 0x0000ff
1448
    case 0x24:                        // BLT DEST PITCH 0x0000ff
1449
    case 0x26:                        // BLT SRC PITCH 0x0000ff
1450
    case 0x28:                        // BLT DEST ADDR 0x0000ff
1451
    case 0x29:                        // BLT DEST ADDR 0x00ff00
1452
    case 0x2c:                        // BLT SRC ADDR 0x0000ff
1453
    case 0x2d:                        // BLT SRC ADDR 0x00ff00
1454
    case 0x30:                        // BLT MODE
1455
    case 0x32:                        // RASTER OP
1456
    case 0x34:                        // BLT TRANSPARENT COLOR 0x00ff
1457
    case 0x35:                        // BLT TRANSPARENT COLOR 0xff00
1458
    case 0x38:                        // BLT TRANSPARENT COLOR MASK 0x00ff
1459
    case 0x39:                        // BLT TRANSPARENT COLOR MASK 0xff00
1460
        s->gr[reg_index] = reg_value;
1461
        break;
1462
    case 0x21:                        // BLT WIDTH 0x001f00
1463
    case 0x23:                        // BLT HEIGHT 0x001f00
1464
    case 0x25:                        // BLT DEST PITCH 0x001f00
1465
    case 0x27:                        // BLT SRC PITCH 0x001f00
1466
        s->gr[reg_index] = reg_value & 0x1f;
1467
        break;
1468
    case 0x2a:                        // BLT DEST ADDR 0x3f0000
1469
    case 0x2e:                        // BLT SRC ADDR 0x3f0000
1470
        s->gr[reg_index] = reg_value & 0x3f;
1471
        break;
1472
    case 0x31:                        // BLT STATUS/START
1473
        cirrus_write_bitblt(s, reg_value);
1474
        break;
1475
    default:
1476
#ifdef DEBUG_CIRRUS
1477
        printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
1478
               reg_value);
1479
#endif
1480
        break;
1481
    }
1482

    
1483
    return CIRRUS_HOOK_HANDLED;
1484
}
1485

    
1486
/***************************************
1487
 *
1488
 *  I/O access between 0x3d4-0x3d5
1489
 *
1490
 ***************************************/
1491

    
1492
static int
1493
cirrus_hook_read_cr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1494
{
1495
    switch (reg_index) {
1496
    case 0x00:                        // Standard VGA
1497
    case 0x01:                        // Standard VGA
1498
    case 0x02:                        // Standard VGA
1499
    case 0x03:                        // Standard VGA
1500
    case 0x04:                        // Standard VGA
1501
    case 0x05:                        // Standard VGA
1502
    case 0x06:                        // Standard VGA
1503
    case 0x07:                        // Standard VGA
1504
    case 0x08:                        // Standard VGA
1505
    case 0x09:                        // Standard VGA
1506
    case 0x0a:                        // Standard VGA
1507
    case 0x0b:                        // Standard VGA
1508
    case 0x0c:                        // Standard VGA
1509
    case 0x0d:                        // Standard VGA
1510
    case 0x0e:                        // Standard VGA
1511
    case 0x0f:                        // Standard VGA
1512
    case 0x10:                        // Standard VGA
1513
    case 0x11:                        // Standard VGA
1514
    case 0x12:                        // Standard VGA
1515
    case 0x13:                        // Standard VGA
1516
    case 0x14:                        // Standard VGA
1517
    case 0x15:                        // Standard VGA
1518
    case 0x16:                        // Standard VGA
1519
    case 0x17:                        // Standard VGA
1520
    case 0x18:                        // Standard VGA
1521
        return CIRRUS_HOOK_NOT_HANDLED;
1522
    case 0x19:                        // Interlace End
1523
    case 0x1a:                        // Miscellaneous Control
1524
    case 0x1b:                        // Extended Display Control
1525
    case 0x1c:                        // Sync Adjust and Genlock
1526
    case 0x1d:                        // Overlay Extended Control
1527
    case 0x22:                        // Graphics Data Latches Readback (R)
1528
    case 0x24:                        // Attribute Controller Toggle Readback (R)
1529
    case 0x25:                        // Part Status
1530
    case 0x27:                        // Part ID (R)
1531
        *reg_value = s->cr[reg_index];
1532
        break;
1533
    case 0x26:                        // Attribute Controller Index Readback (R)
1534
        *reg_value = s->ar_index & 0x3f;
1535
        break;
1536
    default:
1537
#ifdef DEBUG_CIRRUS
1538
        printf("cirrus: inport cr_index %02x\n", reg_index);
1539
        *reg_value = 0xff;
1540
#endif
1541
        break;
1542
    }
1543

    
1544
    return CIRRUS_HOOK_HANDLED;
1545
}
1546

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

    
1602
    return CIRRUS_HOOK_HANDLED;
1603
}
1604

    
1605
/***************************************
1606
 *
1607
 *  memory-mapped I/O (bitblt)
1608
 *
1609
 ***************************************/
1610

    
1611
static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1612
{
1613
    int value = 0xff;
1614

    
1615
    switch (address) {
1616
    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1617
        cirrus_hook_read_gr(s, 0x00, &value);
1618
        break;
1619
    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1620
        cirrus_hook_read_gr(s, 0x10, &value);
1621
        break;
1622
    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1623
        cirrus_hook_read_gr(s, 0x12, &value);
1624
        break;
1625
    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1626
        cirrus_hook_read_gr(s, 0x14, &value);
1627
        break;
1628
    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1629
        cirrus_hook_read_gr(s, 0x01, &value);
1630
        break;
1631
    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1632
        cirrus_hook_read_gr(s, 0x11, &value);
1633
        break;
1634
    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1635
        cirrus_hook_read_gr(s, 0x13, &value);
1636
        break;
1637
    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1638
        cirrus_hook_read_gr(s, 0x15, &value);
1639
        break;
1640
    case (CIRRUS_MMIO_BLTWIDTH + 0):
1641
        cirrus_hook_read_gr(s, 0x20, &value);
1642
        break;
1643
    case (CIRRUS_MMIO_BLTWIDTH + 1):
1644
        cirrus_hook_read_gr(s, 0x21, &value);
1645
        break;
1646
    case (CIRRUS_MMIO_BLTHEIGHT + 0):
1647
        cirrus_hook_read_gr(s, 0x22, &value);
1648
        break;
1649
    case (CIRRUS_MMIO_BLTHEIGHT + 1):
1650
        cirrus_hook_read_gr(s, 0x23, &value);
1651
        break;
1652
    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1653
        cirrus_hook_read_gr(s, 0x24, &value);
1654
        break;
1655
    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1656
        cirrus_hook_read_gr(s, 0x25, &value);
1657
        break;
1658
    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1659
        cirrus_hook_read_gr(s, 0x26, &value);
1660
        break;
1661
    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1662
        cirrus_hook_read_gr(s, 0x27, &value);
1663
        break;
1664
    case (CIRRUS_MMIO_BLTDESTADDR + 0):
1665
        cirrus_hook_read_gr(s, 0x28, &value);
1666
        break;
1667
    case (CIRRUS_MMIO_BLTDESTADDR + 1):
1668
        cirrus_hook_read_gr(s, 0x29, &value);
1669
        break;
1670
    case (CIRRUS_MMIO_BLTDESTADDR + 2):
1671
        cirrus_hook_read_gr(s, 0x2a, &value);
1672
        break;
1673
    case (CIRRUS_MMIO_BLTSRCADDR + 0):
1674
        cirrus_hook_read_gr(s, 0x2c, &value);
1675
        break;
1676
    case (CIRRUS_MMIO_BLTSRCADDR + 1):
1677
        cirrus_hook_read_gr(s, 0x2d, &value);
1678
        break;
1679
    case (CIRRUS_MMIO_BLTSRCADDR + 2):
1680
        cirrus_hook_read_gr(s, 0x2e, &value);
1681
        break;
1682
    case CIRRUS_MMIO_BLTWRITEMASK:
1683
        cirrus_hook_read_gr(s, 0x2f, &value);
1684
        break;
1685
    case CIRRUS_MMIO_BLTMODE:
1686
        cirrus_hook_read_gr(s, 0x30, &value);
1687
        break;
1688
    case CIRRUS_MMIO_BLTROP:
1689
        cirrus_hook_read_gr(s, 0x32, &value);
1690
        break;
1691
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1692
        cirrus_hook_read_gr(s, 0x34, &value);
1693
        break;
1694
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1695
        cirrus_hook_read_gr(s, 0x35, &value);
1696
        break;
1697
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1698
        cirrus_hook_read_gr(s, 0x38, &value);
1699
        break;
1700
    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1701
        cirrus_hook_read_gr(s, 0x39, &value);
1702
        break;
1703
    case CIRRUS_MMIO_BLTSTATUS:
1704
        cirrus_hook_read_gr(s, 0x31, &value);
1705
        break;
1706
    default:
1707
#ifdef DEBUG_CIRRUS
1708
        printf("cirrus: mmio read - address 0x%04x\n", address);
1709
#endif
1710
        break;
1711
    }
1712

    
1713
    return (uint8_t) value;
1714
}
1715

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

    
1822
/***************************************
1823
 *
1824
 *  memory-mapped I/O (vga)
1825
 *
1826
 ***************************************/
1827

    
1828
static uint8_t cirrus_mmio_vga_read(CirrusVGAState * s, unsigned address)
1829
{
1830
#ifdef DEBUG_CIRRUS
1831
    printf("cirrus: mmio vga read (unimplemented) - address 0x%04x\n",
1832
           address);
1833
#endif
1834
    return 0xff;
1835
}
1836

    
1837
static void cirrus_mmio_vga_write(CirrusVGAState * s, unsigned address,
1838
                                  uint8_t value)
1839
{
1840
#ifdef DEBUG_CIRRUS
1841
    printf
1842
        ("cirrus: mmio vga write (unimplemented) - address 0x%04x, value 0x%02x\n",
1843
         address, value);
1844
#endif
1845
}
1846

    
1847
/***************************************
1848
 *
1849
 *  write mode 4/5
1850
 *
1851
 * assume TARGET_PAGE_SIZE >= 16
1852
 *
1853
 ***************************************/
1854

    
1855
static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1856
                                             unsigned mode,
1857
                                             unsigned offset,
1858
                                             uint32_t mem_value)
1859
{
1860
    int x;
1861
    unsigned val = mem_value;
1862
    uint8_t *dst;
1863

    
1864
    dst = s->vram_ptr + offset;
1865
    for (x = 0; x < 8; x++) {
1866
        if (val & 0x80) {
1867
            *dst++ = s->gr[0x01];
1868
        } else if (mode == 5) {
1869
            *dst++ = s->gr[0x00];
1870
        }
1871
        val <<= 1;
1872
    }
1873
    cpu_physical_memory_set_dirty(s->vram_offset + offset);
1874
    cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
1875
}
1876

    
1877
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1878
                                              unsigned mode,
1879
                                              unsigned offset,
1880
                                              uint32_t mem_value)
1881
{
1882
    int x;
1883
    unsigned val = mem_value;
1884
    uint8_t *dst;
1885

    
1886
    dst = s->vram_ptr + offset;
1887
    for (x = 0; x < 8; x++) {
1888
        if (val & 0x80) {
1889
            *dst++ = s->gr[0x01];
1890
            *dst++ = s->gr[0x11];
1891
        } else if (mode == 5) {
1892
            *dst++ = s->gr[0x00];
1893
            *dst++ = s->gr[0x10];
1894
        }
1895
        val <<= 1;
1896
    }
1897
    cpu_physical_memory_set_dirty(s->vram_offset + offset);
1898
    cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);
1899
}
1900

    
1901
/***************************************
1902
 *
1903
 *  memory access between 0xa0000-0xbffff
1904
 *
1905
 ***************************************/
1906

    
1907
static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
1908
{
1909
    CirrusVGAState *s = opaque;
1910
    unsigned bank_index;
1911
    unsigned bank_offset;
1912
    uint32_t val;
1913

    
1914
    if ((s->sr[0x07] & 0x01) == 0) {
1915
        return vga_mem_readb(s, addr);
1916
    }
1917

    
1918
    if (addr < 0x10000) {
1919
        /* XXX handle bitblt */
1920
        /* video memory */
1921
        bank_index = addr >> 15;
1922
        bank_offset = addr & 0x7fff;
1923
        if (bank_offset < s->cirrus_bank_limit[bank_index]) {
1924
            bank_offset += s->cirrus_bank_base[bank_index];
1925
            if ((s->gr[0x0B] & 0x14) == 0x14) {
1926
                bank_offset <<= 4;
1927
            } else if (s->gr[0x0B] & 0x02) {
1928
                bank_offset <<= 3;
1929
            }
1930
            bank_offset &= s->cirrus_addr_mask;
1931
            val = *(s->vram_ptr + bank_offset);
1932
        } else
1933
            val = 0xff;
1934
    } else if (addr >= 0x18000 && addr < 0x18100) {
1935
        /* memory-mapped I/O */
1936
        val = 0xff;
1937
        if ((s->sr[0x17] & 0x44) == 0x04) {
1938
            val = cirrus_mmio_blt_read(s, addr & 0xff);
1939
        }
1940
    } else {
1941
        val = 0xff;
1942
#ifdef DEBUG_CIRRUS
1943
        printf("cirrus: mem_readb %06x\n", addr);
1944
#endif
1945
    }
1946
    return val;
1947
}
1948

    
1949
static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
1950
{
1951
    uint32_t v;
1952
#ifdef TARGET_WORDS_BIGENDIAN
1953
    v = cirrus_vga_mem_readb(opaque, addr) << 8;
1954
    v |= cirrus_vga_mem_readb(opaque, addr + 1);
1955
#else
1956
    v = cirrus_vga_mem_readb(opaque, addr);
1957
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
1958
#endif
1959
    return v;
1960
}
1961

    
1962
static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
1963
{
1964
    uint32_t v;
1965
#ifdef TARGET_WORDS_BIGENDIAN
1966
    v = cirrus_vga_mem_readb(opaque, addr) << 24;
1967
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
1968
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
1969
    v |= cirrus_vga_mem_readb(opaque, addr + 3);
1970
#else
1971
    v = cirrus_vga_mem_readb(opaque, addr);
1972
    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
1973
    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
1974
    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
1975
#endif
1976
    return v;
1977
}
1978

    
1979
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, 
1980
                                  uint32_t mem_value)
1981
{
1982
    CirrusVGAState *s = opaque;
1983
    unsigned bank_index;
1984
    unsigned bank_offset;
1985
    unsigned mode;
1986

    
1987
    if ((s->sr[0x07] & 0x01) == 0) {
1988
        vga_mem_writeb(s, addr, mem_value);
1989
        return;
1990
    }
1991

    
1992
    if (addr < 0x10000) {
1993
        if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
1994
            /* bitblt */
1995
            *s->cirrus_srcptr++ = (uint8_t) mem_value;
1996
            if (s->cirrus_srcptr == s->cirrus_srcptr_end) {
1997
                cirrus_bitblt_cputovideo_next(s);
1998
            }
1999
        } else {
2000
            /* video memory */
2001
            bank_index = addr >> 15;
2002
            bank_offset = addr & 0x7fff;
2003
            if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2004
                bank_offset += s->cirrus_bank_base[bank_index];
2005
                if ((s->gr[0x0B] & 0x14) == 0x14) {
2006
                    bank_offset <<= 4;
2007
                } else if (s->gr[0x0B] & 0x02) {
2008
                    bank_offset <<= 3;
2009
                }
2010
                bank_offset &= s->cirrus_addr_mask;
2011
                mode = s->gr[0x05] & 0x7;
2012
                if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
2013
                    *(s->vram_ptr + bank_offset) = mem_value;
2014
                    cpu_physical_memory_set_dirty(s->vram_offset +
2015
                                                  bank_offset);
2016
                } else {
2017
                    if ((s->gr[0x0B] & 0x14) != 0x14) {
2018
                        cirrus_mem_writeb_mode4and5_8bpp(s, mode,
2019
                                                         bank_offset,
2020
                                                         mem_value);
2021
                    } else {
2022
                        cirrus_mem_writeb_mode4and5_16bpp(s, mode,
2023
                                                          bank_offset,
2024
                                                          mem_value);
2025
                    }
2026
                }
2027
            }
2028
        }
2029
    } else if (addr >= 0x18000 && addr < 0x18100) {
2030
        /* memory-mapped I/O */
2031
        if ((s->sr[0x17] & 0x44) == 0x04) {
2032
            cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
2033
        }
2034
    } else {
2035
#ifdef DEBUG_CIRRUS
2036
        printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
2037
#endif
2038
    }
2039
}
2040

    
2041
static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2042
{
2043
#ifdef TARGET_WORDS_BIGENDIAN
2044
    cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
2045
    cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
2046
#else
2047
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2048
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2049
#endif
2050
}
2051

    
2052
static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2053
{
2054
#ifdef TARGET_WORDS_BIGENDIAN
2055
    cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
2056
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2057
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2058
    cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
2059
#else
2060
    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
2061
    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2062
    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2063
    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2064
#endif
2065
}
2066

    
2067
static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = {
2068
    cirrus_vga_mem_readb,
2069
    cirrus_vga_mem_readw,
2070
    cirrus_vga_mem_readl,
2071
};
2072

    
2073
static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
2074
    cirrus_vga_mem_writeb,
2075
    cirrus_vga_mem_writew,
2076
    cirrus_vga_mem_writel,
2077
};
2078

    
2079
/***************************************
2080
 *
2081
 *  LFB memory access
2082
 *
2083
 ***************************************/
2084

    
2085
static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
2086
{
2087
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2088
    uint32_t ret;
2089

    
2090
    /* XXX: s->vram_size must be a power of two */
2091
    addr &= s->cirrus_addr_mask;
2092

    
2093
    if (((s->sr[0x17] & 0x44) == 0x44) && ((addr & 0x1fff00) == 0x1fff00)) {
2094
        /* memory-mapped I/O */
2095
        ret = cirrus_mmio_blt_read(s, addr & 0xff);
2096
    } else if (0) {
2097
        /* XXX handle bitblt */
2098
        ret = 0xff;
2099
    } else {
2100
        /* video memory */
2101
        if ((s->gr[0x0B] & 0x14) == 0x14) {
2102
            addr <<= 4;
2103
        } else if (s->gr[0x0B] & 0x02) {
2104
            addr <<= 3;
2105
        }
2106
        addr &= s->cirrus_addr_mask;
2107
        ret = *(s->vram_ptr + addr);
2108
    }
2109

    
2110
    return ret;
2111
}
2112

    
2113
static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
2114
{
2115
    uint32_t v;
2116
#ifdef TARGET_WORDS_BIGENDIAN
2117
    v = cirrus_linear_readb(opaque, addr) << 8;
2118
    v |= cirrus_linear_readb(opaque, addr + 1);
2119
#else
2120
    v = cirrus_linear_readb(opaque, addr);
2121
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2122
#endif
2123
    return v;
2124
}
2125

    
2126
static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
2127
{
2128
    uint32_t v;
2129
#ifdef TARGET_WORDS_BIGENDIAN
2130
    v = cirrus_linear_readb(opaque, addr) << 24;
2131
    v |= cirrus_linear_readb(opaque, addr + 1) << 16;
2132
    v |= cirrus_linear_readb(opaque, addr + 2) << 8;
2133
    v |= cirrus_linear_readb(opaque, addr + 3);
2134
#else
2135
    v = cirrus_linear_readb(opaque, addr);
2136
    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
2137
    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
2138
    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
2139
#endif
2140
    return v;
2141
}
2142

    
2143
static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
2144
                                 uint32_t val)
2145
{
2146
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2147
    unsigned mode;
2148

    
2149
    addr &= s->cirrus_addr_mask;
2150

    
2151
    if (((s->sr[0x17] & 0x44) == 0x44) && ((addr & 0x1fff00) == 0x1fff00)) {
2152
        /* memory-mapped I/O */
2153
        cirrus_mmio_blt_write(s, addr & 0xff, val);
2154
    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2155
        /* bitblt */
2156
        *s->cirrus_srcptr++ = (uint8_t) val;
2157
        if (s->cirrus_srcptr == s->cirrus_srcptr_end) {
2158
            cirrus_bitblt_cputovideo_next(s);
2159
        }
2160
    } else {
2161
        /* video memory */
2162
        if ((s->gr[0x0B] & 0x14) == 0x14) {
2163
            addr <<= 4;
2164
        } else if (s->gr[0x0B] & 0x02) {
2165
            addr <<= 3;
2166
        }
2167
        addr &= s->cirrus_addr_mask;
2168

    
2169
        mode = s->gr[0x05] & 0x7;
2170
        if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
2171
            *(s->vram_ptr + addr) = (uint8_t) val;
2172
            cpu_physical_memory_set_dirty(s->vram_offset + addr);
2173
        } else {
2174
            if ((s->gr[0x0B] & 0x14) != 0x14) {
2175
                cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2176
            } else {
2177
                cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2178
            }
2179
        }
2180
    }
2181
}
2182

    
2183
static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
2184
                                 uint32_t val)
2185
{
2186
#ifdef TARGET_WORDS_BIGENDIAN
2187
    cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
2188
    cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
2189
#else
2190
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2191
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2192
#endif
2193
}
2194

    
2195
static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
2196
                                 uint32_t val)
2197
{
2198
#ifdef TARGET_WORDS_BIGENDIAN
2199
    cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
2200
    cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2201
    cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2202
    cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
2203
#else
2204
    cirrus_linear_writeb(opaque, addr, val & 0xff);
2205
    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2206
    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2207
    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2208
#endif
2209
}
2210

    
2211

    
2212
static CPUReadMemoryFunc *cirrus_linear_read[3] = {
2213
    cirrus_linear_readb,
2214
    cirrus_linear_readw,
2215
    cirrus_linear_readl,
2216
};
2217

    
2218
static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
2219
    cirrus_linear_writeb,
2220
    cirrus_linear_writew,
2221
    cirrus_linear_writel,
2222
};
2223

    
2224
/***************************************
2225
 *
2226
 *  memory-mapped I/O access
2227
 *
2228
 ***************************************/
2229

    
2230
static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
2231
{
2232
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2233

    
2234
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2235
    /* ??? Does CLGD5430 have memory-mapped VGA registers ??? */
2236
    return (addr >= 0x100) ?
2237
        cirrus_mmio_blt_read(s, addr - 0x100) :
2238
        cirrus_mmio_vga_read(s, addr);
2239
}
2240

    
2241
static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
2242
{
2243
    uint32_t v;
2244
#ifdef TARGET_WORDS_BIGENDIAN
2245
    v = cirrus_mmio_readb(opaque, addr) << 8;
2246
    v |= cirrus_mmio_readb(opaque, addr + 1);
2247
#else
2248
    v = cirrus_mmio_readb(opaque, addr);
2249
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2250
#endif
2251
    return v;
2252
}
2253

    
2254
static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
2255
{
2256
    uint32_t v;
2257
#ifdef TARGET_WORDS_BIGENDIAN
2258
    v = cirrus_mmio_readb(opaque, addr) << 24;
2259
    v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
2260
    v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
2261
    v |= cirrus_mmio_readb(opaque, addr + 3);
2262
#else
2263
    v = cirrus_mmio_readb(opaque, addr);
2264
    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
2265
    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
2266
    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
2267
#endif
2268
    return v;
2269
}
2270

    
2271
static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
2272
                               uint32_t val)
2273
{
2274
    CirrusVGAState *s = (CirrusVGAState *) opaque;
2275

    
2276
    addr &= CIRRUS_PNPMMIO_SIZE - 1;
2277
    /* ??? Does CLGD5430 have memory-mapped VGA registers ??? */
2278
    if (addr >= 0x100) {
2279
        cirrus_mmio_blt_write(s, addr - 0x100, val);
2280
    } else {
2281
        cirrus_mmio_vga_write(s, addr, val);
2282
    }
2283
}
2284

    
2285
static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
2286
                               uint32_t val)
2287
{
2288
#ifdef TARGET_WORDS_BIGENDIAN
2289
    cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
2290
    cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
2291
#else
2292
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2293
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2294
#endif
2295
}
2296

    
2297
static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
2298
                               uint32_t val)
2299
{
2300
#ifdef TARGET_WORDS_BIGENDIAN
2301
    cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
2302
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
2303
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
2304
    cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
2305
#else
2306
    cirrus_mmio_writeb(opaque, addr, val & 0xff);
2307
    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
2308
    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
2309
    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
2310
#endif
2311
}
2312

    
2313

    
2314
static CPUReadMemoryFunc *cirrus_mmio_read[3] = {
2315
    cirrus_mmio_readb,
2316
    cirrus_mmio_readw,
2317
    cirrus_mmio_readl,
2318
};
2319

    
2320
static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
2321
    cirrus_mmio_writeb,
2322
    cirrus_mmio_writew,
2323
    cirrus_mmio_writel,
2324
};
2325

    
2326
/* I/O ports */
2327

    
2328
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
2329
{
2330
    CirrusVGAState *s = opaque;
2331
    int val, index;
2332

    
2333
    /* check port range access depending on color/monochrome mode */
2334
    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
2335
        || (addr >= 0x3d0 && addr <= 0x3df
2336
            && !(s->msr & MSR_COLOR_EMULATION))) {
2337
        val = 0xff;
2338
    } else {
2339
        switch (addr) {
2340
        case 0x3c0:
2341
            if (s->ar_flip_flop == 0) {
2342
                val = s->ar_index;
2343
            } else {
2344
                val = 0;
2345
            }
2346
            break;
2347
        case 0x3c1:
2348
            index = s->ar_index & 0x1f;
2349
            if (index < 21)
2350
                val = s->ar[index];
2351
            else
2352
                val = 0;
2353
            break;
2354
        case 0x3c2:
2355
            val = s->st00;
2356
            break;
2357
        case 0x3c4:
2358
            val = s->sr_index;
2359
            break;
2360
        case 0x3c5:
2361
            if (cirrus_hook_read_sr(s, s->sr_index, &val))
2362
                break;
2363
            val = s->sr[s->sr_index];
2364
#ifdef DEBUG_VGA_REG
2365
            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2366
#endif
2367
            break;
2368
        case 0x3c6:
2369
            cirrus_read_hidden_dac(s, &val);
2370
            break;
2371
        case 0x3c7:
2372
            val = s->dac_state;
2373
            break;
2374
        case 0x3c9:
2375
            if (cirrus_hook_read_palette(s, &val))
2376
                break;
2377
            val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
2378
            if (++s->dac_sub_index == 3) {
2379
                s->dac_sub_index = 0;
2380
                s->dac_read_index++;
2381
            }
2382
            break;
2383
        case 0x3ca:
2384
            val = s->fcr;
2385
            break;
2386
        case 0x3cc:
2387
            val = s->msr;
2388
            break;
2389
        case 0x3ce:
2390
            val = s->gr_index;
2391
            break;
2392
        case 0x3cf:
2393
            if (cirrus_hook_read_gr(s, s->gr_index, &val))
2394
                break;
2395
            val = s->gr[s->gr_index];
2396
#ifdef DEBUG_VGA_REG
2397
            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2398
#endif
2399
            break;
2400
        case 0x3b4:
2401
        case 0x3d4:
2402
            val = s->cr_index;
2403
            break;
2404
        case 0x3b5:
2405
        case 0x3d5:
2406
            if (cirrus_hook_read_cr(s, s->cr_index, &val))
2407
                break;
2408
            val = s->cr[s->cr_index];
2409
#ifdef DEBUG_VGA_REG
2410
            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2411
#endif
2412
#ifdef DEBUG_S3
2413
            if (s->cr_index >= 0x20)
2414
                printf("S3: CR read index=0x%x val=0x%x\n",
2415
                       s->cr_index, val);
2416
#endif
2417
            break;
2418
        case 0x3ba:
2419
        case 0x3da:
2420
            /* just toggle to fool polling */
2421
            s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
2422
            val = s->st01;
2423
            s->ar_flip_flop = 0;
2424
            break;
2425
        default:
2426
            val = 0x00;
2427
            break;
2428
        }
2429
    }
2430
#if defined(DEBUG_VGA)
2431
    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2432
#endif
2433
    return val;
2434
}
2435

    
2436
static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2437
{
2438
    CirrusVGAState *s = opaque;
2439
    int index;
2440

    
2441
    /* check port range access depending on color/monochrome mode */
2442
    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
2443
        || (addr >= 0x3d0 && addr <= 0x3df
2444
            && !(s->msr & MSR_COLOR_EMULATION)))
2445
        return;
2446

    
2447
#ifdef DEBUG_VGA
2448
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2449
#endif
2450

    
2451
    switch (addr) {
2452
    case 0x3c0:
2453
        if (s->ar_flip_flop == 0) {
2454
            val &= 0x3f;
2455
            s->ar_index = val;
2456
        } else {
2457
            index = s->ar_index & 0x1f;
2458
            switch (index) {
2459
            case 0x00 ... 0x0f:
2460
                s->ar[index] = val & 0x3f;
2461
                break;
2462
            case 0x10:
2463
                s->ar[index] = val & ~0x10;
2464
                break;
2465
            case 0x11:
2466
                s->ar[index] = val;
2467
                break;
2468
            case 0x12:
2469
                s->ar[index] = val & ~0xc0;
2470
                break;
2471
            case 0x13:
2472
                s->ar[index] = val & ~0xf0;
2473
                break;
2474
            case 0x14:
2475
                s->ar[index] = val & ~0xf0;
2476
                break;
2477
            default:
2478
                break;
2479
            }
2480
        }
2481
        s->ar_flip_flop ^= 1;
2482
        break;
2483
    case 0x3c2:
2484
        s->msr = val & ~0x10;
2485
        break;
2486
    case 0x3c4:
2487
        s->sr_index = val;
2488
        break;
2489
    case 0x3c5:
2490
        if (cirrus_hook_write_sr(s, s->sr_index, val))
2491
            break;
2492
#ifdef DEBUG_VGA_REG
2493
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2494
#endif
2495
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
2496
        break;
2497
    case 0x3c6:
2498
        cirrus_write_hidden_dac(s, val);
2499
        break;
2500
    case 0x3c7:
2501
        s->dac_read_index = val;
2502
        s->dac_sub_index = 0;
2503
        s->dac_state = 3;
2504
        break;
2505
    case 0x3c8:
2506
        s->dac_write_index = val;
2507
        s->dac_sub_index = 0;
2508
        s->dac_state = 0;
2509
        break;
2510
    case 0x3c9:
2511
        if (cirrus_hook_write_palette(s, val))
2512
            break;
2513
        s->dac_cache[s->dac_sub_index] = val;
2514
        if (++s->dac_sub_index == 3) {
2515
            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
2516
            s->dac_sub_index = 0;
2517
            s->dac_write_index++;
2518
        }
2519
        break;
2520
    case 0x3ce:
2521
        s->gr_index = val;
2522
        break;
2523
    case 0x3cf:
2524
        if (cirrus_hook_write_gr(s, s->gr_index, val))
2525
            break;
2526
#ifdef DEBUG_VGA_REG
2527
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2528
#endif
2529
        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
2530
        break;
2531
    case 0x3b4:
2532
    case 0x3d4:
2533
        s->cr_index = val;
2534
        break;
2535
    case 0x3b5:
2536
    case 0x3d5:
2537
        if (cirrus_hook_write_cr(s, s->cr_index, val))
2538
            break;
2539
#ifdef DEBUG_VGA_REG
2540
        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2541
#endif
2542
        /* handle CR0-7 protection */
2543
        if ((s->cr[11] & 0x80) && s->cr_index <= 7) {
2544
            /* can always write bit 4 of CR7 */
2545
            if (s->cr_index == 7)
2546
                s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
2547
            return;
2548
        }
2549
        switch (s->cr_index) {
2550
        case 0x01:                /* horizontal display end */
2551
        case 0x07:
2552
        case 0x09:
2553
        case 0x0c:
2554
        case 0x0d:
2555
        case 0x12:                /* veritcal display end */
2556
            s->cr[s->cr_index] = val;
2557
            break;
2558

    
2559
        default:
2560
            s->cr[s->cr_index] = val;
2561
            break;
2562
        }
2563
        break;
2564
    case 0x3ba:
2565
    case 0x3da:
2566
        s->fcr = val & 0x10;
2567
        break;
2568
    }
2569
}
2570

    
2571
/***************************************
2572
 *
2573
 *  initialize
2574
 *
2575
 ***************************************/
2576

    
2577
static void cirrus_init_common(CirrusVGAState * s)
2578
{
2579
    int vga_io_memory;
2580

    
2581
    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
2582

    
2583
    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
2584
    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
2585
    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
2586
    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
2587

    
2588
    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
2589

    
2590
    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
2591
    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
2592
    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
2593
    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
2594

    
2595
    vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read, 
2596
                                           cirrus_vga_mem_write, s);
2597
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
2598
                                 vga_io_memory);
2599

    
2600
    s->sr[0x06] = 0x0f;
2601
    s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
2602
    s->sr[0x1F] = 0x22;                // MemClock
2603

    
2604
    s->cr[0x27] = CIRRUS_ID_CLGD5430;
2605

    
2606
    s->cirrus_hidden_dac_lockindex = 5;
2607
    s->cirrus_hidden_dac_data = 0;
2608

    
2609
    /* I/O handler for LFB */
2610
    s->cirrus_linear_io_addr =
2611
        cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
2612
                               s);
2613
    /* I/O handler for memory-mapped I/O */
2614
    s->cirrus_mmio_io_addr =
2615
        cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
2616

    
2617
    /* XXX: s->vram_size must be a power of two */
2618
    s->cirrus_addr_mask = s->vram_size - 1;
2619

    
2620
    s->get_bpp = cirrus_get_bpp;
2621
    s->get_offsets = cirrus_get_offsets;
2622
}
2623

    
2624
/***************************************
2625
 *
2626
 *  ISA bus support
2627
 *
2628
 ***************************************/
2629

    
2630
void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
2631
                         unsigned long vga_ram_offset, int vga_ram_size)
2632
{
2633
    CirrusVGAState *s;
2634

    
2635
    s = qemu_mallocz(sizeof(CirrusVGAState));
2636
    
2637
    vga_common_init((VGAState *)s, 
2638
                    ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2639
    cirrus_init_common(s);
2640
    s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
2641
    /* XXX ISA-LFB support */
2642
}
2643

    
2644
/***************************************
2645
 *
2646
 *  PCI bus support
2647
 *
2648
 ***************************************/
2649

    
2650
static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
2651
                               uint32_t addr, uint32_t size, int type)
2652
{
2653
    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
2654

    
2655
    cpu_register_physical_memory(addr, s->vram_size,
2656
                                 s->cirrus_linear_io_addr);
2657
}
2658

    
2659
static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
2660
                                uint32_t addr, uint32_t size, int type)
2661
{
2662
    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
2663

    
2664
    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
2665
                                 s->cirrus_mmio_io_addr);
2666
}
2667

    
2668
void pci_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
2669
                         unsigned long vga_ram_offset, int vga_ram_size)
2670
{
2671
    PCICirrusVGAState *d;
2672
    uint8_t *pci_conf;
2673
    CirrusVGAState *s;
2674

    
2675
    /* setup PCI configuration registers */
2676
    d = (PCICirrusVGAState *)pci_register_device("Cirrus VGA", 
2677
                                                 sizeof(PCICirrusVGAState), 
2678
                                                 0, -1, NULL, NULL);
2679
    pci_conf = d->dev.config;
2680
    pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
2681
    pci_conf[0x01] = (uint8_t) (PCI_VENDOR_CIRRUS >> 8);
2682
    pci_conf[0x02] = (uint8_t) (PCI_DEVICE_CLGD5430 & 0xff);
2683
    pci_conf[0x03] = (uint8_t) (PCI_DEVICE_CLGD5430 >> 8);
2684
    pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
2685
    pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
2686
    pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
2687
    pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
2688

    
2689
    /* setup VGA */
2690
    s = &d->cirrus_vga;
2691
    vga_common_init((VGAState *)s, 
2692
                    ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2693
    cirrus_init_common(s);
2694
    s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
2695

    
2696
    /* setup memory space */
2697
    /* memory #0 LFB */
2698
    /* memory #1 memory-mapped I/O */
2699
    /* XXX: s->vram_size must be a power of two */
2700
    pci_register_io_region((PCIDevice *)d, 0, s->vram_size,
2701
                           PCI_ADDRESS_SPACE_MEM, cirrus_pci_lfb_map);
2702
    pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
2703
                           PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
2704
    /* XXX: ROM BIOS */
2705
}