2
* QEMU Cirrus CLGD 54xx VGA Emulator.
4
* Copyright (c) 2004 Fabrice Bellard
5
* Copyright (c) 2004 Makoto Suzuki (suzu)
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:
14
* The above copyright notice and this permission notice shall be included in
15
* all copies or substantial portions of the Software.
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
26
* Reference: Finn Thogersons' VGADOC4b
27
* available at http://home.worldonline.dk/~finth/
38
* - destination write mask support not complete (bits 5..7)
39
* - optimize linear mappings
40
* - optimize bitblt functions
43
//#define DEBUG_CIRRUS
44
//#define DEBUG_BITBLT
46
/***************************************
50
***************************************/
53
#define CIRRUS_ID_CLGD5422 (0x23<<2)
54
#define CIRRUS_ID_CLGD5426 (0x24<<2)
55
#define CIRRUS_ID_CLGD5424 (0x25<<2)
56
#define CIRRUS_ID_CLGD5428 (0x26<<2)
57
#define CIRRUS_ID_CLGD5430 (0x28<<2)
58
#define CIRRUS_ID_CLGD5434 (0x2A<<2)
59
#define CIRRUS_ID_CLGD5436 (0x2B<<2)
60
#define CIRRUS_ID_CLGD5446 (0x2E<<2)
63
#define CIRRUS_SR7_BPP_VGA 0x00
64
#define CIRRUS_SR7_BPP_SVGA 0x01
65
#define CIRRUS_SR7_BPP_MASK 0x0e
66
#define CIRRUS_SR7_BPP_8 0x00
67
#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
68
#define CIRRUS_SR7_BPP_24 0x04
69
#define CIRRUS_SR7_BPP_16 0x06
70
#define CIRRUS_SR7_BPP_32 0x08
71
#define CIRRUS_SR7_ISAADDR_MASK 0xe0
74
#define CIRRUS_MEMSIZE_512k 0x08
75
#define CIRRUS_MEMSIZE_1M 0x10
76
#define CIRRUS_MEMSIZE_2M 0x18
77
#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
80
#define CIRRUS_CURSOR_SHOW 0x01
81
#define CIRRUS_CURSOR_HIDDENPEL 0x02
82
#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
85
#define CIRRUS_BUSTYPE_VLBFAST 0x10
86
#define CIRRUS_BUSTYPE_PCI 0x20
87
#define CIRRUS_BUSTYPE_VLBSLOW 0x30
88
#define CIRRUS_BUSTYPE_ISA 0x38
89
#define CIRRUS_MMIO_ENABLE 0x04
90
#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
91
#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
94
#define CIRRUS_BANKING_DUAL 0x01
95
#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
98
#define CIRRUS_BLTMODE_BACKWARDS 0x01
99
#define CIRRUS_BLTMODE_MEMSYSDEST 0x02
100
#define CIRRUS_BLTMODE_MEMSYSSRC 0x04
101
#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
102
#define CIRRUS_BLTMODE_PATTERNCOPY 0x40
103
#define CIRRUS_BLTMODE_COLOREXPAND 0x80
104
#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
105
#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
106
#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
107
#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
108
#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
111
#define CIRRUS_BLT_BUSY 0x01
112
#define CIRRUS_BLT_START 0x02
113
#define CIRRUS_BLT_RESET 0x04
114
#define CIRRUS_BLT_FIFOUSED 0x10
115
#define CIRRUS_BLT_AUTOSTART 0x80
118
#define CIRRUS_ROP_0 0x00
119
#define CIRRUS_ROP_SRC_AND_DST 0x05
120
#define CIRRUS_ROP_NOP 0x06
121
#define CIRRUS_ROP_SRC_AND_NOTDST 0x09
122
#define CIRRUS_ROP_NOTDST 0x0b
123
#define CIRRUS_ROP_SRC 0x0d
124
#define CIRRUS_ROP_1 0x0e
125
#define CIRRUS_ROP_NOTSRC_AND_DST 0x50
126
#define CIRRUS_ROP_SRC_XOR_DST 0x59
127
#define CIRRUS_ROP_SRC_OR_DST 0x6d
128
#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
129
#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
130
#define CIRRUS_ROP_SRC_OR_NOTDST 0xad
131
#define CIRRUS_ROP_NOTSRC 0xd0
132
#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
133
#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
135
#define CIRRUS_ROP_NOP_INDEX 2
136
#define CIRRUS_ROP_SRC_INDEX 5
139
#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
140
#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
141
#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
144
#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
145
#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword
146
#define CIRRUS_MMIO_BLTWIDTH 0x08 // word
147
#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word
148
#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word
149
#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word
150
#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword
151
#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword
152
#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte
153
#define CIRRUS_MMIO_BLTMODE 0x18 // byte
154
#define CIRRUS_MMIO_BLTROP 0x1a // byte
155
#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte
156
#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
157
#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
158
#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word
159
#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word
160
#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word
161
#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word
162
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte
163
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
164
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte
165
#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte
166
#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word
167
#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word
168
#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word
169
#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
170
#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte
171
#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte
172
#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte
174
#define CIRRUS_PNPMMIO_SIZE 0x1000
176
#define BLTUNSAFE(s) \
178
( /* check dst is within bounds */ \
179
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
180
+ ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
183
( /* check src is within bounds */ \
184
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
185
+ ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
190
struct CirrusVGAState;
191
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
192
uint8_t * dst, const uint8_t * src,
193
int dstpitch, int srcpitch,
194
int bltwidth, int bltheight);
195
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
196
uint8_t *dst, int dst_pitch, int width, int height);
198
typedef struct CirrusVGAState {
201
MemoryRegion cirrus_linear_io;
202
MemoryRegion cirrus_linear_bitblt_io;
203
MemoryRegion cirrus_mmio_io;
204
MemoryRegion pci_bar;
205
bool linear_vram; /* vga.vram mapped over cirrus_linear_io */
206
MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
207
MemoryRegion low_mem; /* always mapped, overridden by: */
208
MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */
209
uint32_t cirrus_addr_mask;
210
uint32_t linear_mmio_mask;
211
uint8_t cirrus_shadow_gr0;
212
uint8_t cirrus_shadow_gr1;
213
uint8_t cirrus_hidden_dac_lockindex;
214
uint8_t cirrus_hidden_dac_data;
215
uint32_t cirrus_bank_base[2];
216
uint32_t cirrus_bank_limit[2];
217
uint8_t cirrus_hidden_palette[48];
218
uint32_t hw_cursor_x;
219
uint32_t hw_cursor_y;
220
int cirrus_blt_pixelwidth;
221
int cirrus_blt_width;
222
int cirrus_blt_height;
223
int cirrus_blt_dstpitch;
224
int cirrus_blt_srcpitch;
225
uint32_t cirrus_blt_fgcol;
226
uint32_t cirrus_blt_bgcol;
227
uint32_t cirrus_blt_dstaddr;
228
uint32_t cirrus_blt_srcaddr;
229
uint8_t cirrus_blt_mode;
230
uint8_t cirrus_blt_modeext;
231
cirrus_bitblt_rop_t cirrus_rop;
232
#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
233
uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
234
uint8_t *cirrus_srcptr;
235
uint8_t *cirrus_srcptr_end;
236
uint32_t cirrus_srccounter;
237
/* hwcursor display state */
238
int last_hw_cursor_size;
239
int last_hw_cursor_x;
240
int last_hw_cursor_y;
241
int last_hw_cursor_y_start;
242
int last_hw_cursor_y_end;
243
int real_vram_size; /* XXX: suppress that */
248
typedef struct PCICirrusVGAState {
250
CirrusVGAState cirrus_vga;
253
static uint8_t rop_to_index[256];
255
/***************************************
259
***************************************/
262
static void cirrus_bitblt_reset(CirrusVGAState *s);
263
static void cirrus_update_memory_access(CirrusVGAState *s);
265
/***************************************
269
***************************************/
271
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
272
uint8_t *dst,const uint8_t *src,
273
int dstpitch,int srcpitch,
274
int bltwidth,int bltheight)
278
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
280
int dstpitch, int bltwidth,int bltheight)
285
#define ROP_FN(d, s) 0
286
#include "cirrus_vga_rop.h"
288
#define ROP_NAME src_and_dst
289
#define ROP_FN(d, s) (s) & (d)
290
#include "cirrus_vga_rop.h"
292
#define ROP_NAME src_and_notdst
293
#define ROP_FN(d, s) (s) & (~(d))
294
#include "cirrus_vga_rop.h"
296
#define ROP_NAME notdst
297
#define ROP_FN(d, s) ~(d)
298
#include "cirrus_vga_rop.h"
301
#define ROP_FN(d, s) s
302
#include "cirrus_vga_rop.h"
305
#define ROP_FN(d, s) ~0
306
#include "cirrus_vga_rop.h"
308
#define ROP_NAME notsrc_and_dst
309
#define ROP_FN(d, s) (~(s)) & (d)
310
#include "cirrus_vga_rop.h"
312
#define ROP_NAME src_xor_dst
313
#define ROP_FN(d, s) (s) ^ (d)
314
#include "cirrus_vga_rop.h"
316
#define ROP_NAME src_or_dst
317
#define ROP_FN(d, s) (s) | (d)
318
#include "cirrus_vga_rop.h"
320
#define ROP_NAME notsrc_or_notdst
321
#define ROP_FN(d, s) (~(s)) | (~(d))
322
#include "cirrus_vga_rop.h"
324
#define ROP_NAME src_notxor_dst
325
#define ROP_FN(d, s) ~((s) ^ (d))
326
#include "cirrus_vga_rop.h"
328
#define ROP_NAME src_or_notdst
329
#define ROP_FN(d, s) (s) | (~(d))
330
#include "cirrus_vga_rop.h"
332
#define ROP_NAME notsrc
333
#define ROP_FN(d, s) (~(s))
334
#include "cirrus_vga_rop.h"
336
#define ROP_NAME notsrc_or_dst
337
#define ROP_FN(d, s) (~(s)) | (d)
338
#include "cirrus_vga_rop.h"
340
#define ROP_NAME notsrc_and_notdst
341
#define ROP_FN(d, s) (~(s)) & (~(d))
342
#include "cirrus_vga_rop.h"
344
static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
345
cirrus_bitblt_rop_fwd_0,
346
cirrus_bitblt_rop_fwd_src_and_dst,
347
cirrus_bitblt_rop_nop,
348
cirrus_bitblt_rop_fwd_src_and_notdst,
349
cirrus_bitblt_rop_fwd_notdst,
350
cirrus_bitblt_rop_fwd_src,
351
cirrus_bitblt_rop_fwd_1,
352
cirrus_bitblt_rop_fwd_notsrc_and_dst,
353
cirrus_bitblt_rop_fwd_src_xor_dst,
354
cirrus_bitblt_rop_fwd_src_or_dst,
355
cirrus_bitblt_rop_fwd_notsrc_or_notdst,
356
cirrus_bitblt_rop_fwd_src_notxor_dst,
357
cirrus_bitblt_rop_fwd_src_or_notdst,
358
cirrus_bitblt_rop_fwd_notsrc,
359
cirrus_bitblt_rop_fwd_notsrc_or_dst,
360
cirrus_bitblt_rop_fwd_notsrc_and_notdst,
363
static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
364
cirrus_bitblt_rop_bkwd_0,
365
cirrus_bitblt_rop_bkwd_src_and_dst,
366
cirrus_bitblt_rop_nop,
367
cirrus_bitblt_rop_bkwd_src_and_notdst,
368
cirrus_bitblt_rop_bkwd_notdst,
369
cirrus_bitblt_rop_bkwd_src,
370
cirrus_bitblt_rop_bkwd_1,
371
cirrus_bitblt_rop_bkwd_notsrc_and_dst,
372
cirrus_bitblt_rop_bkwd_src_xor_dst,
373
cirrus_bitblt_rop_bkwd_src_or_dst,
374
cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
375
cirrus_bitblt_rop_bkwd_src_notxor_dst,
376
cirrus_bitblt_rop_bkwd_src_or_notdst,
377
cirrus_bitblt_rop_bkwd_notsrc,
378
cirrus_bitblt_rop_bkwd_notsrc_or_dst,
379
cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
382
#define TRANSP_ROP(name) {\
386
#define TRANSP_NOP(func) {\
391
static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
392
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
393
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
394
TRANSP_NOP(cirrus_bitblt_rop_nop),
395
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
396
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
397
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
398
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
399
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
400
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
401
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
402
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
403
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
404
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
405
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
406
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
407
TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
410
static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
411
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
412
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
413
TRANSP_NOP(cirrus_bitblt_rop_nop),
414
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
415
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
416
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
417
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
418
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
419
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
420
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
421
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
422
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
423
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
424
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
425
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
426
TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
429
#define ROP2(name) {\
436
#define ROP_NOP2(func) {\
443
static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
444
ROP2(cirrus_patternfill_0),
445
ROP2(cirrus_patternfill_src_and_dst),
446
ROP_NOP2(cirrus_bitblt_rop_nop),
447
ROP2(cirrus_patternfill_src_and_notdst),
448
ROP2(cirrus_patternfill_notdst),
449
ROP2(cirrus_patternfill_src),
450
ROP2(cirrus_patternfill_1),
451
ROP2(cirrus_patternfill_notsrc_and_dst),
452
ROP2(cirrus_patternfill_src_xor_dst),
453
ROP2(cirrus_patternfill_src_or_dst),
454
ROP2(cirrus_patternfill_notsrc_or_notdst),
455
ROP2(cirrus_patternfill_src_notxor_dst),
456
ROP2(cirrus_patternfill_src_or_notdst),
457
ROP2(cirrus_patternfill_notsrc),
458
ROP2(cirrus_patternfill_notsrc_or_dst),
459
ROP2(cirrus_patternfill_notsrc_and_notdst),
462
static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
463
ROP2(cirrus_colorexpand_transp_0),
464
ROP2(cirrus_colorexpand_transp_src_and_dst),
465
ROP_NOP2(cirrus_bitblt_rop_nop),
466
ROP2(cirrus_colorexpand_transp_src_and_notdst),
467
ROP2(cirrus_colorexpand_transp_notdst),
468
ROP2(cirrus_colorexpand_transp_src),
469
ROP2(cirrus_colorexpand_transp_1),
470
ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
471
ROP2(cirrus_colorexpand_transp_src_xor_dst),
472
ROP2(cirrus_colorexpand_transp_src_or_dst),
473
ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
474
ROP2(cirrus_colorexpand_transp_src_notxor_dst),
475
ROP2(cirrus_colorexpand_transp_src_or_notdst),
476
ROP2(cirrus_colorexpand_transp_notsrc),
477
ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
478
ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
481
static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
482
ROP2(cirrus_colorexpand_0),
483
ROP2(cirrus_colorexpand_src_and_dst),
484
ROP_NOP2(cirrus_bitblt_rop_nop),
485
ROP2(cirrus_colorexpand_src_and_notdst),
486
ROP2(cirrus_colorexpand_notdst),
487
ROP2(cirrus_colorexpand_src),
488
ROP2(cirrus_colorexpand_1),
489
ROP2(cirrus_colorexpand_notsrc_and_dst),
490
ROP2(cirrus_colorexpand_src_xor_dst),
491
ROP2(cirrus_colorexpand_src_or_dst),
492
ROP2(cirrus_colorexpand_notsrc_or_notdst),
493
ROP2(cirrus_colorexpand_src_notxor_dst),
494
ROP2(cirrus_colorexpand_src_or_notdst),
495
ROP2(cirrus_colorexpand_notsrc),
496
ROP2(cirrus_colorexpand_notsrc_or_dst),
497
ROP2(cirrus_colorexpand_notsrc_and_notdst),
500
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
501
ROP2(cirrus_colorexpand_pattern_transp_0),
502
ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
503
ROP_NOP2(cirrus_bitblt_rop_nop),
504
ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
505
ROP2(cirrus_colorexpand_pattern_transp_notdst),
506
ROP2(cirrus_colorexpand_pattern_transp_src),
507
ROP2(cirrus_colorexpand_pattern_transp_1),
508
ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
509
ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
510
ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
511
ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
512
ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
513
ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
514
ROP2(cirrus_colorexpand_pattern_transp_notsrc),
515
ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
516
ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
519
static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
520
ROP2(cirrus_colorexpand_pattern_0),
521
ROP2(cirrus_colorexpand_pattern_src_and_dst),
522
ROP_NOP2(cirrus_bitblt_rop_nop),
523
ROP2(cirrus_colorexpand_pattern_src_and_notdst),
524
ROP2(cirrus_colorexpand_pattern_notdst),
525
ROP2(cirrus_colorexpand_pattern_src),
526
ROP2(cirrus_colorexpand_pattern_1),
527
ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
528
ROP2(cirrus_colorexpand_pattern_src_xor_dst),
529
ROP2(cirrus_colorexpand_pattern_src_or_dst),
530
ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
531
ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
532
ROP2(cirrus_colorexpand_pattern_src_or_notdst),
533
ROP2(cirrus_colorexpand_pattern_notsrc),
534
ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
535
ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
538
static const cirrus_fill_t cirrus_fill[16][4] = {
540
ROP2(cirrus_fill_src_and_dst),
541
ROP_NOP2(cirrus_bitblt_fill_nop),
542
ROP2(cirrus_fill_src_and_notdst),
543
ROP2(cirrus_fill_notdst),
544
ROP2(cirrus_fill_src),
546
ROP2(cirrus_fill_notsrc_and_dst),
547
ROP2(cirrus_fill_src_xor_dst),
548
ROP2(cirrus_fill_src_or_dst),
549
ROP2(cirrus_fill_notsrc_or_notdst),
550
ROP2(cirrus_fill_src_notxor_dst),
551
ROP2(cirrus_fill_src_or_notdst),
552
ROP2(cirrus_fill_notsrc),
553
ROP2(cirrus_fill_notsrc_or_dst),
554
ROP2(cirrus_fill_notsrc_and_notdst),
557
static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
560
switch (s->cirrus_blt_pixelwidth) {
562
s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
565
color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
566
s->cirrus_blt_fgcol = le16_to_cpu(color);
569
s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
570
(s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
574
color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
575
(s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
576
s->cirrus_blt_fgcol = le32_to_cpu(color);
581
static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
584
switch (s->cirrus_blt_pixelwidth) {
586
s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
589
color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
590
s->cirrus_blt_bgcol = le16_to_cpu(color);
593
s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
594
(s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
598
color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
599
(s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
600
s->cirrus_blt_bgcol = le32_to_cpu(color);
605
static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
606
int off_pitch, int bytesperline,
613
for (y = 0; y < lines; y++) {
615
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
616
off_cur &= TARGET_PAGE_MASK;
617
while (off_cur < off_cur_end) {
618
memory_region_set_dirty(&s->vga.vram, off_cur);
619
off_cur += TARGET_PAGE_SIZE;
621
off_begin += off_pitch;
625
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
630
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
635
(*s->cirrus_rop) (s, dst, src,
636
s->cirrus_blt_dstpitch, 0,
637
s->cirrus_blt_width, s->cirrus_blt_height);
638
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
639
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
640
s->cirrus_blt_height);
646
static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
648
cirrus_fill_t rop_func;
652
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
653
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
654
s->cirrus_blt_dstpitch,
655
s->cirrus_blt_width, s->cirrus_blt_height);
656
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
657
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
658
s->cirrus_blt_height);
659
cirrus_bitblt_reset(s);
663
/***************************************
665
* bitblt (video-to-video)
667
***************************************/
669
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
671
return cirrus_bitblt_common_patterncopy(s,
672
s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
673
s->cirrus_addr_mask));
676
static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
683
/* make sure to only copy if it's a plain copy ROP */
684
if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
685
*s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
689
depth = s->vga.get_bpp(&s->vga) / 8;
690
s->vga.get_resolution(&s->vga, &width, &height);
693
sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
694
sy = (src / ABS(s->cirrus_blt_srcpitch));
695
dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
696
dy = (dst / ABS(s->cirrus_blt_dstpitch));
698
/* normalize width */
701
/* if we're doing a backward copy, we have to adjust
702
our x/y to be the upper left corner (instead of the lower
704
if (s->cirrus_blt_dstpitch < 0) {
705
sx -= (s->cirrus_blt_width / depth) - 1;
706
dx -= (s->cirrus_blt_width / depth) - 1;
707
sy -= s->cirrus_blt_height - 1;
708
dy -= s->cirrus_blt_height - 1;
711
/* are we in the visible portion of memory? */
712
if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
713
(sx + w) <= width && (sy + h) <= height &&
714
(dx + w) <= width && (dy + h) <= height) {
719
/* we have to flush all pending changes so that the copy
720
is generated at the appropriate moment in time */
724
(*s->cirrus_rop) (s, s->vga.vram_ptr +
725
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
727
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
728
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
729
s->cirrus_blt_width, s->cirrus_blt_height);
732
qemu_console_copy(s->vga.ds,
734
s->cirrus_blt_width / depth,
735
s->cirrus_blt_height);
737
/* we don't have to notify the display that this portion has
738
changed since qemu_console_copy implies this */
740
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
741
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
742
s->cirrus_blt_height);
745
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
750
cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
751
s->cirrus_blt_srcaddr - s->vga.start_addr,
752
s->cirrus_blt_width, s->cirrus_blt_height);
757
/***************************************
759
* bitblt (cpu-to-video)
761
***************************************/
763
static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
768
if (s->cirrus_srccounter > 0) {
769
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
770
cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
772
s->cirrus_srccounter = 0;
773
cirrus_bitblt_reset(s);
775
/* at least one scan line */
777
(*s->cirrus_rop)(s, s->vga.vram_ptr +
778
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
779
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
780
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
781
s->cirrus_blt_width, 1);
782
s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
783
s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
784
if (s->cirrus_srccounter <= 0)
786
/* more bytes than needed can be transfered because of
787
word alignment, so we keep them for the next line */
788
/* XXX: keep alignment to speed up transfer */
789
end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
790
copy_count = s->cirrus_srcptr_end - end_ptr;
791
memmove(s->cirrus_bltbuf, end_ptr, copy_count);
792
s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
793
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
794
} while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
799
/***************************************
803
***************************************/
805
static void cirrus_bitblt_reset(CirrusVGAState * s)
810
~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
811
need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
812
|| s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
813
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
814
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
815
s->cirrus_srccounter = 0;
818
cirrus_update_memory_access(s);
821
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
825
s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
826
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
827
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
829
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
830
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
831
s->cirrus_blt_srcpitch = 8;
833
/* XXX: check for 24 bpp */
834
s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
836
s->cirrus_srccounter = s->cirrus_blt_srcpitch;
838
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
839
w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
840
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
841
s->cirrus_blt_srcpitch = ((w + 31) >> 5);
843
s->cirrus_blt_srcpitch = ((w + 7) >> 3);
845
/* always align input size to 32 bits */
846
s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
848
s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
850
s->cirrus_srcptr = s->cirrus_bltbuf;
851
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
852
cirrus_update_memory_access(s);
856
static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
860
printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
865
static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
869
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
870
ret = cirrus_bitblt_videotovideo_patterncopy(s);
872
ret = cirrus_bitblt_videotovideo_copy(s);
875
cirrus_bitblt_reset(s);
879
static void cirrus_bitblt_start(CirrusVGAState * s)
883
s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
885
s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
886
s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
887
s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
888
s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
889
s->cirrus_blt_dstaddr =
890
(s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
891
s->cirrus_blt_srcaddr =
892
(s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
893
s->cirrus_blt_mode = s->vga.gr[0x30];
894
s->cirrus_blt_modeext = s->vga.gr[0x33];
895
blt_rop = s->vga.gr[0x32];
898
printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
901
s->cirrus_blt_modeext,
903
s->cirrus_blt_height,
904
s->cirrus_blt_dstpitch,
905
s->cirrus_blt_srcpitch,
906
s->cirrus_blt_dstaddr,
907
s->cirrus_blt_srcaddr,
911
switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
912
case CIRRUS_BLTMODE_PIXELWIDTH8:
913
s->cirrus_blt_pixelwidth = 1;
915
case CIRRUS_BLTMODE_PIXELWIDTH16:
916
s->cirrus_blt_pixelwidth = 2;
918
case CIRRUS_BLTMODE_PIXELWIDTH24:
919
s->cirrus_blt_pixelwidth = 3;
921
case CIRRUS_BLTMODE_PIXELWIDTH32:
922
s->cirrus_blt_pixelwidth = 4;
926
printf("cirrus: bitblt - pixel width is unknown\n");
930
s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
933
cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
934
CIRRUS_BLTMODE_MEMSYSDEST))
935
== (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
937
printf("cirrus: bitblt - memory-to-memory copy is requested\n");
942
if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
943
(s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
944
CIRRUS_BLTMODE_TRANSPARENTCOMP |
945
CIRRUS_BLTMODE_PATTERNCOPY |
946
CIRRUS_BLTMODE_COLOREXPAND)) ==
947
(CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
948
cirrus_bitblt_fgcol(s);
949
cirrus_bitblt_solidfill(s, blt_rop);
951
if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
952
CIRRUS_BLTMODE_PATTERNCOPY)) ==
953
CIRRUS_BLTMODE_COLOREXPAND) {
955
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
956
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
957
cirrus_bitblt_bgcol(s);
959
cirrus_bitblt_fgcol(s);
960
s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
962
cirrus_bitblt_fgcol(s);
963
cirrus_bitblt_bgcol(s);
964
s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
966
} else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
967
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
968
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
969
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
970
cirrus_bitblt_bgcol(s);
972
cirrus_bitblt_fgcol(s);
973
s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
975
cirrus_bitblt_fgcol(s);
976
cirrus_bitblt_bgcol(s);
977
s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
980
s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
983
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
984
if (s->cirrus_blt_pixelwidth > 2) {
985
printf("src transparent without colorexpand must be 8bpp or 16bpp\n");
988
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
989
s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
990
s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
991
s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
993
s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
996
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
997
s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
998
s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
999
s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
1001
s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
1005
// setup bitblt engine.
1006
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
1007
if (!cirrus_bitblt_cputovideo(s))
1009
} else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
1010
if (!cirrus_bitblt_videotocpu(s))
1013
if (!cirrus_bitblt_videotovideo(s))
1019
cirrus_bitblt_reset(s);
1022
static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1026
old_value = s->vga.gr[0x31];
1027
s->vga.gr[0x31] = reg_value;
1029
if (((old_value & CIRRUS_BLT_RESET) != 0) &&
1030
((reg_value & CIRRUS_BLT_RESET) == 0)) {
1031
cirrus_bitblt_reset(s);
1032
} else if (((old_value & CIRRUS_BLT_START) == 0) &&
1033
((reg_value & CIRRUS_BLT_START) != 0)) {
1034
cirrus_bitblt_start(s);
1039
/***************************************
1043
***************************************/
1045
static void cirrus_get_offsets(VGACommonState *s1,
1046
uint32_t *pline_offset,
1047
uint32_t *pstart_addr,
1048
uint32_t *pline_compare)
1050
CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1051
uint32_t start_addr, line_offset, line_compare;
1053
line_offset = s->vga.cr[0x13]
1054
| ((s->vga.cr[0x1b] & 0x10) << 4);
1056
*pline_offset = line_offset;
1058
start_addr = (s->vga.cr[0x0c] << 8)
1060
| ((s->vga.cr[0x1b] & 0x01) << 16)
1061
| ((s->vga.cr[0x1b] & 0x0c) << 15)
1062
| ((s->vga.cr[0x1d] & 0x80) << 12);
1063
*pstart_addr = start_addr;
1065
line_compare = s->vga.cr[0x18] |
1066
((s->vga.cr[0x07] & 0x10) << 4) |
1067
((s->vga.cr[0x09] & 0x40) << 3);
1068
*pline_compare = line_compare;
1071
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
1075
switch (s->cirrus_hidden_dac_data & 0xf) {
1078
break; /* Sierra HiColor */
1081
break; /* XGA HiColor */
1084
printf("cirrus: invalid DAC value %x in 16bpp\n",
1085
(s->cirrus_hidden_dac_data & 0xf));
1093
static int cirrus_get_bpp(VGACommonState *s1)
1095
CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
1098
if ((s->vga.sr[0x07] & 0x01) != 0) {
1100
switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
1101
case CIRRUS_SR7_BPP_8:
1104
case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1105
ret = cirrus_get_bpp16_depth(s);
1107
case CIRRUS_SR7_BPP_24:
1110
case CIRRUS_SR7_BPP_16:
1111
ret = cirrus_get_bpp16_depth(s);
1113
case CIRRUS_SR7_BPP_32:
1118
printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
1131
static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1135
width = (s->cr[0x01] + 1) * 8;
1136
height = s->cr[0x12] |
1137
((s->cr[0x07] & 0x02) << 7) |
1138
((s->cr[0x07] & 0x40) << 3);
1139
height = (height + 1);
1140
/* interlace support */
1141
if (s->cr[0x1a] & 0x01)
1142
height = height * 2;
1147
/***************************************
1151
***************************************/
1153
static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
1158
if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */
1159
offset = s->vga.gr[0x09 + bank_index];
1160
else /* single bank */
1161
offset = s->vga.gr[0x09];
1163
if ((s->vga.gr[0x0b] & 0x20) != 0)
1168
if (s->real_vram_size <= offset)
1171
limit = s->real_vram_size - offset;
1173
if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
1174
if (limit > 0x8000) {
1183
s->cirrus_bank_base[bank_index] = offset;
1184
s->cirrus_bank_limit[bank_index] = limit;
1186
s->cirrus_bank_base[bank_index] = 0;
1187
s->cirrus_bank_limit[bank_index] = 0;
1191
/***************************************
1193
* I/O access between 0x3c4-0x3c5
1195
***************************************/
1197
static int cirrus_vga_read_sr(CirrusVGAState * s)
1199
switch (s->vga.sr_index) {
1200
case 0x00: // Standard VGA
1201
case 0x01: // Standard VGA
1202
case 0x02: // Standard VGA
1203
case 0x03: // Standard VGA
1204
case 0x04: // Standard VGA
1205
return s->vga.sr[s->vga.sr_index];
1206
case 0x06: // Unlock Cirrus extensions
1207
return s->vga.sr[s->vga.sr_index];
1211
case 0x70: // Graphics Cursor X
1215
case 0xf0: // Graphics Cursor X
1216
return s->vga.sr[0x10];
1220
case 0x71: // Graphics Cursor Y
1224
case 0xf1: // Graphics Cursor Y
1225
return s->vga.sr[0x11];
1227
case 0x07: // Extended Sequencer Mode
1228
case 0x08: // EEPROM Control
1229
case 0x09: // Scratch Register 0
1230
case 0x0a: // Scratch Register 1
1231
case 0x0b: // VCLK 0
1232
case 0x0c: // VCLK 1
1233
case 0x0d: // VCLK 2
1234
case 0x0e: // VCLK 3
1235
case 0x0f: // DRAM Control
1236
case 0x12: // Graphics Cursor Attribute
1237
case 0x13: // Graphics Cursor Pattern Address
1238
case 0x14: // Scratch Register 2
1239
case 0x15: // Scratch Register 3
1240
case 0x16: // Performance Tuning Register
1241
case 0x17: // Configuration Readback and Extended Control
1242
case 0x18: // Signature Generator Control
1243
case 0x19: // Signal Generator Result
1244
case 0x1a: // Signal Generator Result
1245
case 0x1b: // VCLK 0 Denominator & Post
1246
case 0x1c: // VCLK 1 Denominator & Post
1247
case 0x1d: // VCLK 2 Denominator & Post
1248
case 0x1e: // VCLK 3 Denominator & Post
1249
case 0x1f: // BIOS Write Enable and MCLK select
1251
printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
1253
return s->vga.sr[s->vga.sr_index];
1256
printf("cirrus: inport sr_index %02x\n", s->vga.sr_index);
1263
static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
1265
switch (s->vga.sr_index) {
1266
case 0x00: // Standard VGA
1267
case 0x01: // Standard VGA
1268
case 0x02: // Standard VGA
1269
case 0x03: // Standard VGA
1270
case 0x04: // Standard VGA
1271
s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
1272
if (s->vga.sr_index == 1)
1273
s->vga.update_retrace_info(&s->vga);
1275
case 0x06: // Unlock Cirrus extensions
1278
s->vga.sr[s->vga.sr_index] = 0x12;
1280
s->vga.sr[s->vga.sr_index] = 0x0f;
1286
case 0x70: // Graphics Cursor X
1290
case 0xf0: // Graphics Cursor X
1291
s->vga.sr[0x10] = val;
1292
s->hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
1297
case 0x71: // Graphics Cursor Y
1301
case 0xf1: // Graphics Cursor Y
1302
s->vga.sr[0x11] = val;
1303
s->hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
1305
case 0x07: // Extended Sequencer Mode
1306
cirrus_update_memory_access(s);
1307
case 0x08: // EEPROM Control
1308
case 0x09: // Scratch Register 0
1309
case 0x0a: // Scratch Register 1
1310
case 0x0b: // VCLK 0
1311
case 0x0c: // VCLK 1
1312
case 0x0d: // VCLK 2
1313
case 0x0e: // VCLK 3
1314
case 0x0f: // DRAM Control
1315
case 0x12: // Graphics Cursor Attribute
1316
case 0x13: // Graphics Cursor Pattern Address
1317
case 0x14: // Scratch Register 2
1318
case 0x15: // Scratch Register 3
1319
case 0x16: // Performance Tuning Register
1320
case 0x18: // Signature Generator Control
1321
case 0x19: // Signature Generator Result
1322
case 0x1a: // Signature Generator Result
1323
case 0x1b: // VCLK 0 Denominator & Post
1324
case 0x1c: // VCLK 1 Denominator & Post
1325
case 0x1d: // VCLK 2 Denominator & Post
1326
case 0x1e: // VCLK 3 Denominator & Post
1327
case 0x1f: // BIOS Write Enable and MCLK select
1328
s->vga.sr[s->vga.sr_index] = val;
1330
printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
1331
s->vga.sr_index, val);
1334
case 0x17: // Configuration Readback and Extended Control
1335
s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
1337
cirrus_update_memory_access(s);
1341
printf("cirrus: outport sr_index %02x, sr_value %02x\n",
1342
s->vga.sr_index, val);
1348
/***************************************
1350
* I/O access at 0x3c6
1352
***************************************/
1354
static int cirrus_read_hidden_dac(CirrusVGAState * s)
1356
if (++s->cirrus_hidden_dac_lockindex == 5) {
1357
s->cirrus_hidden_dac_lockindex = 0;
1358
return s->cirrus_hidden_dac_data;
1363
static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1365
if (s->cirrus_hidden_dac_lockindex == 4) {
1366
s->cirrus_hidden_dac_data = reg_value;
1367
#if defined(DEBUG_CIRRUS)
1368
printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
1371
s->cirrus_hidden_dac_lockindex = 0;
1374
/***************************************
1376
* I/O access at 0x3c9
1378
***************************************/
1380
static int cirrus_vga_read_palette(CirrusVGAState * s)
1384
if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1385
val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
1386
s->vga.dac_sub_index];
1388
val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
1390
if (++s->vga.dac_sub_index == 3) {
1391
s->vga.dac_sub_index = 0;
1392
s->vga.dac_read_index++;
1397
static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
1399
s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
1400
if (++s->vga.dac_sub_index == 3) {
1401
if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
1402
memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
1403
s->vga.dac_cache, 3);
1405
memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
1407
/* XXX update cursor */
1408
s->vga.dac_sub_index = 0;
1409
s->vga.dac_write_index++;
1413
/***************************************
1415
* I/O access between 0x3ce-0x3cf
1417
***************************************/
1419
static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
1421
switch (reg_index) {
1422
case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1423
return s->cirrus_shadow_gr0;
1424
case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1425
return s->cirrus_shadow_gr1;
1426
case 0x02: // Standard VGA
1427
case 0x03: // Standard VGA
1428
case 0x04: // Standard VGA
1429
case 0x06: // Standard VGA
1430
case 0x07: // Standard VGA
1431
case 0x08: // Standard VGA
1432
return s->vga.gr[s->vga.gr_index];
1433
case 0x05: // Standard VGA, Cirrus extended mode
1438
if (reg_index < 0x3a) {
1439
return s->vga.gr[reg_index];
1442
printf("cirrus: inport gr_index %02x\n", reg_index);
1449
cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1451
#if defined(DEBUG_BITBLT) && 0
1452
printf("gr%02x: %02x\n", reg_index, reg_value);
1454
switch (reg_index) {
1455
case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1456
s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1457
s->cirrus_shadow_gr0 = reg_value;
1459
case 0x01: // Standard VGA, FGCOLOR 0x000000ff
1460
s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1461
s->cirrus_shadow_gr1 = reg_value;
1463
case 0x02: // Standard VGA
1464
case 0x03: // Standard VGA
1465
case 0x04: // Standard VGA
1466
case 0x06: // Standard VGA
1467
case 0x07: // Standard VGA
1468
case 0x08: // Standard VGA
1469
s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
1471
case 0x05: // Standard VGA, Cirrus extended mode
1472
s->vga.gr[reg_index] = reg_value & 0x7f;
1473
cirrus_update_memory_access(s);
1475
case 0x09: // bank offset #0
1476
case 0x0A: // bank offset #1
1477
s->vga.gr[reg_index] = reg_value;
1478
cirrus_update_bank_ptr(s, 0);
1479
cirrus_update_bank_ptr(s, 1);
1480
cirrus_update_memory_access(s);
1483
s->vga.gr[reg_index] = reg_value;
1484
cirrus_update_bank_ptr(s, 0);
1485
cirrus_update_bank_ptr(s, 1);
1486
cirrus_update_memory_access(s);
1488
case 0x10: // BGCOLOR 0x0000ff00
1489
case 0x11: // FGCOLOR 0x0000ff00
1490
case 0x12: // BGCOLOR 0x00ff0000
1491
case 0x13: // FGCOLOR 0x00ff0000
1492
case 0x14: // BGCOLOR 0xff000000
1493
case 0x15: // FGCOLOR 0xff000000
1494
case 0x20: // BLT WIDTH 0x0000ff
1495
case 0x22: // BLT HEIGHT 0x0000ff
1496
case 0x24: // BLT DEST PITCH 0x0000ff
1497
case 0x26: // BLT SRC PITCH 0x0000ff
1498
case 0x28: // BLT DEST ADDR 0x0000ff
1499
case 0x29: // BLT DEST ADDR 0x00ff00
1500
case 0x2c: // BLT SRC ADDR 0x0000ff
1501
case 0x2d: // BLT SRC ADDR 0x00ff00
1502
case 0x2f: // BLT WRITEMASK
1503
case 0x30: // BLT MODE
1504
case 0x32: // RASTER OP
1505
case 0x33: // BLT MODEEXT
1506
case 0x34: // BLT TRANSPARENT COLOR 0x00ff
1507
case 0x35: // BLT TRANSPARENT COLOR 0xff00
1508
case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
1509
case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
1510
s->vga.gr[reg_index] = reg_value;
1512
case 0x21: // BLT WIDTH 0x001f00
1513
case 0x23: // BLT HEIGHT 0x001f00
1514
case 0x25: // BLT DEST PITCH 0x001f00
1515
case 0x27: // BLT SRC PITCH 0x001f00
1516
s->vga.gr[reg_index] = reg_value & 0x1f;
1518
case 0x2a: // BLT DEST ADDR 0x3f0000
1519
s->vga.gr[reg_index] = reg_value & 0x3f;
1520
/* if auto start mode, starts bit blt now */
1521
if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
1522
cirrus_bitblt_start(s);
1525
case 0x2e: // BLT SRC ADDR 0x3f0000
1526
s->vga.gr[reg_index] = reg_value & 0x3f;
1528
case 0x31: // BLT STATUS/START
1529
cirrus_write_bitblt(s, reg_value);
1533
printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
1540
/***************************************
1542
* I/O access between 0x3d4-0x3d5
1544
***************************************/
1546
static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
1548
switch (reg_index) {
1549
case 0x00: // Standard VGA
1550
case 0x01: // Standard VGA
1551
case 0x02: // Standard VGA
1552
case 0x03: // Standard VGA
1553
case 0x04: // Standard VGA
1554
case 0x05: // Standard VGA
1555
case 0x06: // Standard VGA
1556
case 0x07: // Standard VGA
1557
case 0x08: // Standard VGA
1558
case 0x09: // Standard VGA
1559
case 0x0a: // Standard VGA
1560
case 0x0b: // Standard VGA
1561
case 0x0c: // Standard VGA
1562
case 0x0d: // Standard VGA
1563
case 0x0e: // Standard VGA
1564
case 0x0f: // Standard VGA
1565
case 0x10: // Standard VGA
1566
case 0x11: // Standard VGA
1567
case 0x12: // Standard VGA
1568
case 0x13: // Standard VGA
1569
case 0x14: // Standard VGA
1570
case 0x15: // Standard VGA
1571
case 0x16: // Standard VGA
1572
case 0x17: // Standard VGA
1573
case 0x18: // Standard VGA
1574
return s->vga.cr[s->vga.cr_index];
1575
case 0x24: // Attribute Controller Toggle Readback (R)
1576
return (s->vga.ar_flip_flop << 7);
1577
case 0x19: // Interlace End
1578
case 0x1a: // Miscellaneous Control
1579
case 0x1b: // Extended Display Control
1580
case 0x1c: // Sync Adjust and Genlock
1581
case 0x1d: // Overlay Extended Control
1582
case 0x22: // Graphics Data Latches Readback (R)
1583
case 0x25: // Part Status
1584
case 0x27: // Part ID (R)
1585
return s->vga.cr[s->vga.cr_index];
1586
case 0x26: // Attribute Controller Index Readback (R)
1587
return s->vga.ar_index & 0x3f;
1591
printf("cirrus: inport cr_index %02x\n", reg_index);
1597
static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
1599
switch (s->vga.cr_index) {
1600
case 0x00: // Standard VGA
1601
case 0x01: // Standard VGA
1602
case 0x02: // Standard VGA
1603
case 0x03: // Standard VGA
1604
case 0x04: // Standard VGA
1605
case 0x05: // Standard VGA
1606
case 0x06: // Standard VGA
1607
case 0x07: // Standard VGA
1608
case 0x08: // Standard VGA
1609
case 0x09: // Standard VGA
1610
case 0x0a: // Standard VGA
1611
case 0x0b: // Standard VGA
1612
case 0x0c: // Standard VGA
1613
case 0x0d: // Standard VGA
1614
case 0x0e: // Standard VGA
1615
case 0x0f: // Standard VGA
1616
case 0x10: // Standard VGA
1617
case 0x11: // Standard VGA
1618
case 0x12: // Standard VGA
1619
case 0x13: // Standard VGA
1620
case 0x14: // Standard VGA
1621
case 0x15: // Standard VGA
1622
case 0x16: // Standard VGA
1623
case 0x17: // Standard VGA
1624
case 0x18: // Standard VGA
1625
/* handle CR0-7 protection */
1626
if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
1627
/* can always write bit 4 of CR7 */
1628
if (s->vga.cr_index == 7)
1629
s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
1632
s->vga.cr[s->vga.cr_index] = reg_value;
1633
switch(s->vga.cr_index) {
1641
s->vga.update_retrace_info(&s->vga);
1645
case 0x19: // Interlace End
1646
case 0x1a: // Miscellaneous Control
1647
case 0x1b: // Extended Display Control
1648
case 0x1c: // Sync Adjust and Genlock
1649
case 0x1d: // Overlay Extended Control
1650
s->vga.cr[s->vga.cr_index] = reg_value;
1652
printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
1653
s->vga.cr_index, reg_value);
1656
case 0x22: // Graphics Data Latches Readback (R)
1657
case 0x24: // Attribute Controller Toggle Readback (R)
1658
case 0x26: // Attribute Controller Index Readback (R)
1659
case 0x27: // Part ID (R)
1661
case 0x25: // Part Status
1664
printf("cirrus: outport cr_index %02x, cr_value %02x\n",
1665
s->vga.cr_index, reg_value);
1671
/***************************************
1673
* memory-mapped I/O (bitblt)
1675
***************************************/
1677
static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
1682
case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1683
value = cirrus_vga_read_gr(s, 0x00);
1685
case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1686
value = cirrus_vga_read_gr(s, 0x10);
1688
case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1689
value = cirrus_vga_read_gr(s, 0x12);
1691
case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1692
value = cirrus_vga_read_gr(s, 0x14);
1694
case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1695
value = cirrus_vga_read_gr(s, 0x01);
1697
case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1698
value = cirrus_vga_read_gr(s, 0x11);
1700
case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1701
value = cirrus_vga_read_gr(s, 0x13);
1703
case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1704
value = cirrus_vga_read_gr(s, 0x15);
1706
case (CIRRUS_MMIO_BLTWIDTH + 0):
1707
value = cirrus_vga_read_gr(s, 0x20);
1709
case (CIRRUS_MMIO_BLTWIDTH + 1):
1710
value = cirrus_vga_read_gr(s, 0x21);
1712
case (CIRRUS_MMIO_BLTHEIGHT + 0):
1713
value = cirrus_vga_read_gr(s, 0x22);
1715
case (CIRRUS_MMIO_BLTHEIGHT + 1):
1716
value = cirrus_vga_read_gr(s, 0x23);
1718
case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1719
value = cirrus_vga_read_gr(s, 0x24);
1721
case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1722
value = cirrus_vga_read_gr(s, 0x25);
1724
case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1725
value = cirrus_vga_read_gr(s, 0x26);
1727
case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1728
value = cirrus_vga_read_gr(s, 0x27);
1730
case (CIRRUS_MMIO_BLTDESTADDR + 0):
1731
value = cirrus_vga_read_gr(s, 0x28);
1733
case (CIRRUS_MMIO_BLTDESTADDR + 1):
1734
value = cirrus_vga_read_gr(s, 0x29);
1736
case (CIRRUS_MMIO_BLTDESTADDR + 2):
1737
value = cirrus_vga_read_gr(s, 0x2a);
1739
case (CIRRUS_MMIO_BLTSRCADDR + 0):
1740
value = cirrus_vga_read_gr(s, 0x2c);
1742
case (CIRRUS_MMIO_BLTSRCADDR + 1):
1743
value = cirrus_vga_read_gr(s, 0x2d);
1745
case (CIRRUS_MMIO_BLTSRCADDR + 2):
1746
value = cirrus_vga_read_gr(s, 0x2e);
1748
case CIRRUS_MMIO_BLTWRITEMASK:
1749
value = cirrus_vga_read_gr(s, 0x2f);
1751
case CIRRUS_MMIO_BLTMODE:
1752
value = cirrus_vga_read_gr(s, 0x30);
1754
case CIRRUS_MMIO_BLTROP:
1755
value = cirrus_vga_read_gr(s, 0x32);
1757
case CIRRUS_MMIO_BLTMODEEXT:
1758
value = cirrus_vga_read_gr(s, 0x33);
1760
case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1761
value = cirrus_vga_read_gr(s, 0x34);
1763
case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1764
value = cirrus_vga_read_gr(s, 0x35);
1766
case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1767
value = cirrus_vga_read_gr(s, 0x38);
1769
case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1770
value = cirrus_vga_read_gr(s, 0x39);
1772
case CIRRUS_MMIO_BLTSTATUS:
1773
value = cirrus_vga_read_gr(s, 0x31);
1777
printf("cirrus: mmio read - address 0x%04x\n", address);
1782
return (uint8_t) value;
1785
static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
1789
case (CIRRUS_MMIO_BLTBGCOLOR + 0):
1790
cirrus_vga_write_gr(s, 0x00, value);
1792
case (CIRRUS_MMIO_BLTBGCOLOR + 1):
1793
cirrus_vga_write_gr(s, 0x10, value);
1795
case (CIRRUS_MMIO_BLTBGCOLOR + 2):
1796
cirrus_vga_write_gr(s, 0x12, value);
1798
case (CIRRUS_MMIO_BLTBGCOLOR + 3):
1799
cirrus_vga_write_gr(s, 0x14, value);
1801
case (CIRRUS_MMIO_BLTFGCOLOR + 0):
1802
cirrus_vga_write_gr(s, 0x01, value);
1804
case (CIRRUS_MMIO_BLTFGCOLOR + 1):
1805
cirrus_vga_write_gr(s, 0x11, value);
1807
case (CIRRUS_MMIO_BLTFGCOLOR + 2):
1808
cirrus_vga_write_gr(s, 0x13, value);
1810
case (CIRRUS_MMIO_BLTFGCOLOR + 3):
1811
cirrus_vga_write_gr(s, 0x15, value);
1813
case (CIRRUS_MMIO_BLTWIDTH + 0):
1814
cirrus_vga_write_gr(s, 0x20, value);
1816
case (CIRRUS_MMIO_BLTWIDTH + 1):
1817
cirrus_vga_write_gr(s, 0x21, value);
1819
case (CIRRUS_MMIO_BLTHEIGHT + 0):
1820
cirrus_vga_write_gr(s, 0x22, value);
1822
case (CIRRUS_MMIO_BLTHEIGHT + 1):
1823
cirrus_vga_write_gr(s, 0x23, value);
1825
case (CIRRUS_MMIO_BLTDESTPITCH + 0):
1826
cirrus_vga_write_gr(s, 0x24, value);
1828
case (CIRRUS_MMIO_BLTDESTPITCH + 1):
1829
cirrus_vga_write_gr(s, 0x25, value);
1831
case (CIRRUS_MMIO_BLTSRCPITCH + 0):
1832
cirrus_vga_write_gr(s, 0x26, value);
1834
case (CIRRUS_MMIO_BLTSRCPITCH + 1):
1835
cirrus_vga_write_gr(s, 0x27, value);
1837
case (CIRRUS_MMIO_BLTDESTADDR + 0):
1838
cirrus_vga_write_gr(s, 0x28, value);
1840
case (CIRRUS_MMIO_BLTDESTADDR + 1):
1841
cirrus_vga_write_gr(s, 0x29, value);
1843
case (CIRRUS_MMIO_BLTDESTADDR + 2):
1844
cirrus_vga_write_gr(s, 0x2a, value);
1846
case (CIRRUS_MMIO_BLTDESTADDR + 3):
1849
case (CIRRUS_MMIO_BLTSRCADDR + 0):
1850
cirrus_vga_write_gr(s, 0x2c, value);
1852
case (CIRRUS_MMIO_BLTSRCADDR + 1):
1853
cirrus_vga_write_gr(s, 0x2d, value);
1855
case (CIRRUS_MMIO_BLTSRCADDR + 2):
1856
cirrus_vga_write_gr(s, 0x2e, value);
1858
case CIRRUS_MMIO_BLTWRITEMASK:
1859
cirrus_vga_write_gr(s, 0x2f, value);
1861
case CIRRUS_MMIO_BLTMODE:
1862
cirrus_vga_write_gr(s, 0x30, value);
1864
case CIRRUS_MMIO_BLTROP:
1865
cirrus_vga_write_gr(s, 0x32, value);
1867
case CIRRUS_MMIO_BLTMODEEXT:
1868
cirrus_vga_write_gr(s, 0x33, value);
1870
case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
1871
cirrus_vga_write_gr(s, 0x34, value);
1873
case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
1874
cirrus_vga_write_gr(s, 0x35, value);
1876
case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
1877
cirrus_vga_write_gr(s, 0x38, value);
1879
case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
1880
cirrus_vga_write_gr(s, 0x39, value);
1882
case CIRRUS_MMIO_BLTSTATUS:
1883
cirrus_vga_write_gr(s, 0x31, value);
1887
printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
1894
/***************************************
1898
* assume TARGET_PAGE_SIZE >= 16
1900
***************************************/
1902
static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
1908
unsigned val = mem_value;
1911
dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1912
for (x = 0; x < 8; x++) {
1914
*dst = s->cirrus_shadow_gr1;
1915
} else if (mode == 5) {
1916
*dst = s->cirrus_shadow_gr0;
1921
memory_region_set_dirty(&s->vga.vram, offset);
1922
memory_region_set_dirty(&s->vga.vram, offset + 7);
1925
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
1931
unsigned val = mem_value;
1934
dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
1935
for (x = 0; x < 8; x++) {
1937
*dst = s->cirrus_shadow_gr1;
1938
*(dst + 1) = s->vga.gr[0x11];
1939
} else if (mode == 5) {
1940
*dst = s->cirrus_shadow_gr0;
1941
*(dst + 1) = s->vga.gr[0x10];
1946
memory_region_set_dirty(&s->vga.vram, offset);
1947
memory_region_set_dirty(&s->vga.vram, offset + 15);
1950
/***************************************
1952
* memory access between 0xa0000-0xbffff
1954
***************************************/
1956
static uint64_t cirrus_vga_mem_read(void *opaque,
1957
target_phys_addr_t addr,
1960
CirrusVGAState *s = opaque;
1961
unsigned bank_index;
1962
unsigned bank_offset;
1965
if ((s->vga.sr[0x07] & 0x01) == 0) {
1966
return vga_mem_readb(&s->vga, addr);
1969
if (addr < 0x10000) {
1970
/* XXX handle bitblt */
1972
bank_index = addr >> 15;
1973
bank_offset = addr & 0x7fff;
1974
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
1975
bank_offset += s->cirrus_bank_base[bank_index];
1976
if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
1978
} else if (s->vga.gr[0x0B] & 0x02) {
1981
bank_offset &= s->cirrus_addr_mask;
1982
val = *(s->vga.vram_ptr + bank_offset);
1985
} else if (addr >= 0x18000 && addr < 0x18100) {
1986
/* memory-mapped I/O */
1988
if ((s->vga.sr[0x17] & 0x44) == 0x04) {
1989
val = cirrus_mmio_blt_read(s, addr & 0xff);
1994
printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
2000
static void cirrus_vga_mem_write(void *opaque,
2001
target_phys_addr_t addr,
2005
CirrusVGAState *s = opaque;
2006
unsigned bank_index;
2007
unsigned bank_offset;
2010
if ((s->vga.sr[0x07] & 0x01) == 0) {
2011
vga_mem_writeb(&s->vga, addr, mem_value);
2015
if (addr < 0x10000) {
2016
if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2018
*s->cirrus_srcptr++ = (uint8_t) mem_value;
2019
if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2020
cirrus_bitblt_cputovideo_next(s);
2024
bank_index = addr >> 15;
2025
bank_offset = addr & 0x7fff;
2026
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
2027
bank_offset += s->cirrus_bank_base[bank_index];
2028
if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2030
} else if (s->vga.gr[0x0B] & 0x02) {
2033
bank_offset &= s->cirrus_addr_mask;
2034
mode = s->vga.gr[0x05] & 0x7;
2035
if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2036
*(s->vga.vram_ptr + bank_offset) = mem_value;
2037
memory_region_set_dirty(&s->vga.vram, bank_offset);
2039
if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2040
cirrus_mem_writeb_mode4and5_8bpp(s, mode,
2044
cirrus_mem_writeb_mode4and5_16bpp(s, mode,
2051
} else if (addr >= 0x18000 && addr < 0x18100) {
2052
/* memory-mapped I/O */
2053
if ((s->vga.sr[0x17] & 0x44) == 0x04) {
2054
cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
2058
printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr,
2064
static const MemoryRegionOps cirrus_vga_mem_ops = {
2065
.read = cirrus_vga_mem_read,
2066
.write = cirrus_vga_mem_write,
2067
.endianness = DEVICE_LITTLE_ENDIAN,
2069
.min_access_size = 1,
2070
.max_access_size = 1,
2074
/***************************************
2078
***************************************/
2080
static inline void invalidate_cursor1(CirrusVGAState *s)
2082
if (s->last_hw_cursor_size) {
2083
vga_invalidate_scanlines(&s->vga,
2084
s->last_hw_cursor_y + s->last_hw_cursor_y_start,
2085
s->last_hw_cursor_y + s->last_hw_cursor_y_end);
2089
static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
2093
int y, y_min, y_max;
2095
src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2096
if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2097
src += (s->vga.sr[0x13] & 0x3c) * 256;
2100
for(y = 0; y < 64; y++) {
2101
content = ((uint32_t *)src)[0] |
2102
((uint32_t *)src)[1] |
2103
((uint32_t *)src)[2] |
2104
((uint32_t *)src)[3];
2114
src += (s->vga.sr[0x13] & 0x3f) * 256;
2117
for(y = 0; y < 32; y++) {
2118
content = ((uint32_t *)src)[0] |
2119
((uint32_t *)(src + 128))[0];
2129
if (y_min > y_max) {
2130
s->last_hw_cursor_y_start = 0;
2131
s->last_hw_cursor_y_end = 0;
2133
s->last_hw_cursor_y_start = y_min;
2134
s->last_hw_cursor_y_end = y_max + 1;
2138
/* NOTE: we do not currently handle the cursor bitmap change, so we
2139
update the cursor only if it moves. */
2140
static void cirrus_cursor_invalidate(VGACommonState *s1)
2142
CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2145
if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
2148
if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
2153
/* invalidate last cursor and new cursor if any change */
2154
if (s->last_hw_cursor_size != size ||
2155
s->last_hw_cursor_x != s->hw_cursor_x ||
2156
s->last_hw_cursor_y != s->hw_cursor_y) {
2158
invalidate_cursor1(s);
2160
s->last_hw_cursor_size = size;
2161
s->last_hw_cursor_x = s->hw_cursor_x;
2162
s->last_hw_cursor_y = s->hw_cursor_y;
2163
/* compute the real cursor min and max y */
2164
cirrus_cursor_compute_yrange(s);
2165
invalidate_cursor1(s);
2169
static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
2171
CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
2172
int w, h, bpp, x1, x2, poffset;
2173
unsigned int color0, color1;
2174
const uint8_t *palette, *src;
2177
if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
2179
/* fast test to see if the cursor intersects with the scan line */
2180
if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2185
if (scr_y < s->hw_cursor_y ||
2186
scr_y >= (s->hw_cursor_y + h))
2189
src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
2190
if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
2191
src += (s->vga.sr[0x13] & 0x3c) * 256;
2192
src += (scr_y - s->hw_cursor_y) * 16;
2194
content = ((uint32_t *)src)[0] |
2195
((uint32_t *)src)[1] |
2196
((uint32_t *)src)[2] |
2197
((uint32_t *)src)[3];
2199
src += (s->vga.sr[0x13] & 0x3f) * 256;
2200
src += (scr_y - s->hw_cursor_y) * 4;
2202
content = ((uint32_t *)src)[0] |
2203
((uint32_t *)(src + 128))[0];
2205
/* if nothing to draw, no need to continue */
2210
x1 = s->hw_cursor_x;
2211
if (x1 >= s->vga.last_scr_width)
2213
x2 = s->hw_cursor_x + w;
2214
if (x2 > s->vga.last_scr_width)
2215
x2 = s->vga.last_scr_width;
2217
palette = s->cirrus_hidden_palette;
2218
color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
2219
c6_to_8(palette[0x0 * 3 + 1]),
2220
c6_to_8(palette[0x0 * 3 + 2]));
2221
color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
2222
c6_to_8(palette[0xf * 3 + 1]),
2223
c6_to_8(palette[0xf * 3 + 2]));
2224
bpp = ((ds_get_bits_per_pixel(s->vga.ds) + 7) >> 3);
2226
switch(ds_get_bits_per_pixel(s->vga.ds)) {
2230
vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
2233
vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
2236
vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
2239
vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
2244
/***************************************
2248
***************************************/
2250
static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
2253
CirrusVGAState *s = opaque;
2256
addr &= s->cirrus_addr_mask;
2258
if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2259
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2260
/* memory-mapped I/O */
2261
ret = cirrus_mmio_blt_read(s, addr & 0xff);
2263
/* XXX handle bitblt */
2267
if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2269
} else if (s->vga.gr[0x0B] & 0x02) {
2272
addr &= s->cirrus_addr_mask;
2273
ret = *(s->vga.vram_ptr + addr);
2279
static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
2280
uint64_t val, unsigned size)
2282
CirrusVGAState *s = opaque;
2285
addr &= s->cirrus_addr_mask;
2287
if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
2288
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
2289
/* memory-mapped I/O */
2290
cirrus_mmio_blt_write(s, addr & 0xff, val);
2291
} else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2293
*s->cirrus_srcptr++ = (uint8_t) val;
2294
if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2295
cirrus_bitblt_cputovideo_next(s);
2299
if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2301
} else if (s->vga.gr[0x0B] & 0x02) {
2304
addr &= s->cirrus_addr_mask;
2306
mode = s->vga.gr[0x05] & 0x7;
2307
if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2308
*(s->vga.vram_ptr + addr) = (uint8_t) val;
2309
memory_region_set_dirty(&s->vga.vram, addr);
2311
if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
2312
cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
2314
cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
2320
/***************************************
2322
* system to screen memory access
2324
***************************************/
2327
static uint64_t cirrus_linear_bitblt_read(void *opaque,
2328
target_phys_addr_t addr,
2331
CirrusVGAState *s = opaque;
2334
/* XXX handle bitblt */
2340
static void cirrus_linear_bitblt_write(void *opaque,
2341
target_phys_addr_t addr,
2345
CirrusVGAState *s = opaque;
2347
if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2349
*s->cirrus_srcptr++ = (uint8_t) val;
2350
if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2351
cirrus_bitblt_cputovideo_next(s);
2356
static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
2357
.read = cirrus_linear_bitblt_read,
2358
.write = cirrus_linear_bitblt_write,
2359
.endianness = DEVICE_LITTLE_ENDIAN,
2361
.min_access_size = 1,
2362
.max_access_size = 1,
2366
static void unmap_bank(CirrusVGAState *s, unsigned bank)
2368
if (s->cirrus_bank[bank]) {
2369
memory_region_del_subregion(&s->low_mem_container,
2370
s->cirrus_bank[bank]);
2371
memory_region_destroy(s->cirrus_bank[bank]);
2372
g_free(s->cirrus_bank[bank]);
2373
s->cirrus_bank[bank] = NULL;
2377
static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
2380
static const char *names[] = { "vga.bank0", "vga.bank1" };
2382
if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
2383
&& !((s->vga.sr[0x07] & 0x01) == 0)
2384
&& !((s->vga.gr[0x0B] & 0x14) == 0x14)
2385
&& !(s->vga.gr[0x0B] & 0x02)) {
2387
mr = g_malloc(sizeof(*mr));
2388
memory_region_init_alias(mr, names[bank], &s->vga.vram,
2389
s->cirrus_bank_base[bank], 0x8000);
2390
memory_region_add_subregion_overlap(
2391
&s->low_mem_container,
2395
unmap_bank(s, bank);
2396
s->cirrus_bank[bank] = mr;
2398
unmap_bank(s, bank);
2402
static void map_linear_vram(CirrusVGAState *s)
2404
if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) {
2405
s->linear_vram = true;
2406
memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
2408
map_linear_vram_bank(s, 0);
2409
map_linear_vram_bank(s, 1);
2412
static void unmap_linear_vram(CirrusVGAState *s)
2414
if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) {
2415
s->linear_vram = false;
2416
memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
2422
/* Compute the memory access functions */
2423
static void cirrus_update_memory_access(CirrusVGAState *s)
2427
memory_region_transaction_begin();
2428
if ((s->vga.sr[0x17] & 0x44) == 0x44) {
2430
} else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2433
if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
2435
} else if (s->vga.gr[0x0B] & 0x02) {
2439
mode = s->vga.gr[0x05] & 0x7;
2440
if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
2444
unmap_linear_vram(s);
2447
memory_region_transaction_commit();
2453
static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
2455
CirrusVGAState *c = opaque;
2456
VGACommonState *s = &c->vga;
2459
if (vga_ioport_invalid(s, addr)) {
2464
if (s->ar_flip_flop == 0) {
2471
index = s->ar_index & 0x1f;
2484
val = cirrus_vga_read_sr(c);
2486
#ifdef DEBUG_VGA_REG
2487
printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
2491
val = cirrus_read_hidden_dac(c);
2497
val = s->dac_write_index;
2498
c->cirrus_hidden_dac_lockindex = 0;
2501
val = cirrus_vga_read_palette(c);
2513
val = cirrus_vga_read_gr(c, s->gr_index);
2514
#ifdef DEBUG_VGA_REG
2515
printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
2524
val = cirrus_vga_read_cr(c, s->cr_index);
2525
#ifdef DEBUG_VGA_REG
2526
printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
2531
/* just toggle to fool polling */
2532
val = s->st01 = s->retrace(s);
2533
s->ar_flip_flop = 0;
2540
#if defined(DEBUG_VGA)
2541
printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
2546
static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2548
CirrusVGAState *c = opaque;
2549
VGACommonState *s = &c->vga;
2552
/* check port range access depending on color/monochrome mode */
2553
if (vga_ioport_invalid(s, addr)) {
2557
printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
2562
if (s->ar_flip_flop == 0) {
2566
index = s->ar_index & 0x1f;
2569
s->ar[index] = val & 0x3f;
2572
s->ar[index] = val & ~0x10;
2578
s->ar[index] = val & ~0xc0;
2581
s->ar[index] = val & ~0xf0;
2584
s->ar[index] = val & ~0xf0;
2590
s->ar_flip_flop ^= 1;
2593
s->msr = val & ~0x10;
2594
s->update_retrace_info(s);
2600
#ifdef DEBUG_VGA_REG
2601
printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
2603
cirrus_vga_write_sr(c, val);
2607
cirrus_write_hidden_dac(c, val);
2610
s->dac_read_index = val;
2611
s->dac_sub_index = 0;
2615
s->dac_write_index = val;
2616
s->dac_sub_index = 0;
2620
cirrus_vga_write_palette(c, val);
2626
#ifdef DEBUG_VGA_REG
2627
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
2629
cirrus_vga_write_gr(c, s->gr_index, val);
2637
#ifdef DEBUG_VGA_REG
2638
printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
2640
cirrus_vga_write_cr(c, val);
2644
s->fcr = val & 0x10;
2649
/***************************************
2651
* memory-mapped I/O access
2653
***************************************/
2655
static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
2658
CirrusVGAState *s = opaque;
2660
if (addr >= 0x100) {
2661
return cirrus_mmio_blt_read(s, addr - 0x100);
2663
return cirrus_vga_ioport_read(s, addr + 0x3c0);
2667
static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
2668
uint64_t val, unsigned size)
2670
CirrusVGAState *s = opaque;
2672
if (addr >= 0x100) {
2673
cirrus_mmio_blt_write(s, addr - 0x100, val);
2675
cirrus_vga_ioport_write(s, addr + 0x3c0, val);
2679
static const MemoryRegionOps cirrus_mmio_io_ops = {
2680
.read = cirrus_mmio_read,
2681
.write = cirrus_mmio_write,
2682
.endianness = DEVICE_LITTLE_ENDIAN,
2684
.min_access_size = 1,
2685
.max_access_size = 1,
2689
/* load/save state */
2691
static int cirrus_post_load(void *opaque, int version_id)
2693
CirrusVGAState *s = opaque;
2695
s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
2696
s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
2698
cirrus_update_memory_access(s);
2700
s->vga.graphic_mode = -1;
2701
cirrus_update_bank_ptr(s, 0);
2702
cirrus_update_bank_ptr(s, 1);
2706
static const VMStateDescription vmstate_cirrus_vga = {
2707
.name = "cirrus_vga",
2709
.minimum_version_id = 1,
2710
.minimum_version_id_old = 1,
2711
.post_load = cirrus_post_load,
2712
.fields = (VMStateField []) {
2713
VMSTATE_UINT32(vga.latch, CirrusVGAState),
2714
VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
2715
VMSTATE_BUFFER(vga.sr, CirrusVGAState),
2716
VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
2717
VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
2718
VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
2719
VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
2720
VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
2721
VMSTATE_BUFFER(vga.ar, CirrusVGAState),
2722
VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
2723
VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
2724
VMSTATE_BUFFER(vga.cr, CirrusVGAState),
2725
VMSTATE_UINT8(vga.msr, CirrusVGAState),
2726
VMSTATE_UINT8(vga.fcr, CirrusVGAState),
2727
VMSTATE_UINT8(vga.st00, CirrusVGAState),
2728
VMSTATE_UINT8(vga.st01, CirrusVGAState),
2729
VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
2730
VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
2731
VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
2732
VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
2733
VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
2734
VMSTATE_BUFFER(vga.palette, CirrusVGAState),
2735
VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
2736
VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
2737
VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
2738
VMSTATE_UINT32(hw_cursor_x, CirrusVGAState),
2739
VMSTATE_UINT32(hw_cursor_y, CirrusVGAState),
2740
/* XXX: we do not save the bitblt state - we assume we do not save
2741
the state when the blitter is active */
2742
VMSTATE_END_OF_LIST()
2746
static const VMStateDescription vmstate_pci_cirrus_vga = {
2747
.name = "cirrus_vga",
2749
.minimum_version_id = 2,
2750
.minimum_version_id_old = 2,
2751
.fields = (VMStateField []) {
2752
VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
2753
VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
2754
vmstate_cirrus_vga, CirrusVGAState),
2755
VMSTATE_END_OF_LIST()
2759
/***************************************
2763
***************************************/
2765
static void cirrus_reset(void *opaque)
2767
CirrusVGAState *s = opaque;
2769
vga_common_reset(&s->vga);
2770
unmap_linear_vram(s);
2771
s->vga.sr[0x06] = 0x0f;
2772
if (s->device_id == CIRRUS_ID_CLGD5446) {
2773
/* 4MB 64 bit memory config, always PCI */
2774
s->vga.sr[0x1F] = 0x2d; // MemClock
2775
s->vga.gr[0x18] = 0x0f; // fastest memory configuration
2776
s->vga.sr[0x0f] = 0x98;
2777
s->vga.sr[0x17] = 0x20;
2778
s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
2780
s->vga.sr[0x1F] = 0x22; // MemClock
2781
s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
2782
s->vga.sr[0x17] = s->bustype;
2783
s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
2785
s->vga.cr[0x27] = s->device_id;
2787
/* Win2K seems to assume that the pattern buffer is at 0xff
2789
memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
2791
s->cirrus_hidden_dac_lockindex = 5;
2792
s->cirrus_hidden_dac_data = 0;
2795
static const MemoryRegionOps cirrus_linear_io_ops = {
2796
.read = cirrus_linear_read,
2797
.write = cirrus_linear_write,
2798
.endianness = DEVICE_LITTLE_ENDIAN,
2800
.min_access_size = 1,
2801
.max_access_size = 1,
2805
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
2806
MemoryRegion *system_memory)
2813
for(i = 0;i < 256; i++)
2814
rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
2815
rop_to_index[CIRRUS_ROP_0] = 0;
2816
rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
2817
rop_to_index[CIRRUS_ROP_NOP] = 2;
2818
rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
2819
rop_to_index[CIRRUS_ROP_NOTDST] = 4;
2820
rop_to_index[CIRRUS_ROP_SRC] = 5;
2821
rop_to_index[CIRRUS_ROP_1] = 6;
2822
rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
2823
rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
2824
rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
2825
rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
2826
rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
2827
rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
2828
rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
2829
rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
2830
rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
2831
s->device_id = device_id;
2833
s->bustype = CIRRUS_BUSTYPE_PCI;
2835
s->bustype = CIRRUS_BUSTYPE_ISA;
2838
register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
2840
register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
2841
register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
2842
register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
2843
register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
2845
register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
2847
register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
2848
register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
2849
register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
2850
register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
2852
memory_region_init(&s->low_mem_container,
2853
"cirrus-lowmem-container",
2856
memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
2857
"cirrus-low-memory", 0x20000);
2858
memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
2859
memory_region_add_subregion_overlap(system_memory,
2860
isa_mem_base + 0x000a0000,
2861
&s->low_mem_container,
2863
memory_region_set_coalescing(&s->low_mem);
2865
/* I/O handler for LFB */
2866
memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
2867
"cirrus-linear-io", VGA_RAM_SIZE);
2869
/* I/O handler for LFB */
2870
memory_region_init_io(&s->cirrus_linear_bitblt_io,
2871
&cirrus_linear_bitblt_io_ops,
2873
"cirrus-bitblt-mmio",
2876
/* I/O handler for memory-mapped I/O */
2877
memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
2878
"cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
2881
(s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
2883
/* XXX: s->vga.vram_size must be a power of two */
2884
s->cirrus_addr_mask = s->real_vram_size - 1;
2885
s->linear_mmio_mask = s->real_vram_size - 256;
2887
s->vga.get_bpp = cirrus_get_bpp;
2888
s->vga.get_offsets = cirrus_get_offsets;
2889
s->vga.get_resolution = cirrus_get_resolution;
2890
s->vga.cursor_invalidate = cirrus_cursor_invalidate;
2891
s->vga.cursor_draw_line = cirrus_cursor_draw_line;
2893
qemu_register_reset(cirrus_reset, s);
2896
/***************************************
2900
***************************************/
2902
void isa_cirrus_vga_init(MemoryRegion *system_memory)
2906
s = g_malloc0(sizeof(CirrusVGAState));
2908
vga_common_init(&s->vga, VGA_RAM_SIZE);
2909
cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory);
2910
s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
2911
s->vga.screen_dump, s->vga.text_update,
2913
vmstate_register(NULL, 0, &vmstate_cirrus_vga, s);
2914
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
2915
/* XXX ISA-LFB support */
2918
/***************************************
2922
***************************************/
2924
static int pci_cirrus_vga_initfn(PCIDevice *dev)
2926
PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
2927
CirrusVGAState *s = &d->cirrus_vga;
2928
PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info);
2929
int16_t device_id = info->device_id;
2932
vga_common_init(&s->vga, VGA_RAM_SIZE);
2933
cirrus_init_common(s, device_id, 1, pci_address_space(dev));
2934
s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
2935
s->vga.screen_dump, s->vga.text_update,
2940
memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
2942
/* XXX: add byte swapping apertures */
2943
memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
2944
memory_region_add_subregion(&s->pci_bar, 0x1000000,
2945
&s->cirrus_linear_bitblt_io);
2947
/* setup memory space */
2949
/* memory #1 memory-mapped I/O */
2950
/* XXX: s->vga.vram_size must be a power of two */
2951
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
2952
if (device_id == CIRRUS_ID_CLGD5446) {
2953
pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
2958
void pci_cirrus_vga_init(PCIBus *bus)
2960
pci_create_simple(bus, -1, "cirrus-vga");
2963
static PCIDeviceInfo cirrus_vga_info = {
2964
.qdev.name = "cirrus-vga",
2965
.qdev.desc = "Cirrus CLGD 54xx VGA",
2966
.qdev.size = sizeof(PCICirrusVGAState),
2967
.qdev.vmsd = &vmstate_pci_cirrus_vga,
2969
.init = pci_cirrus_vga_initfn,
2970
.romfile = VGABIOS_CIRRUS_FILENAME,
2971
.vendor_id = PCI_VENDOR_ID_CIRRUS,
2972
.device_id = CIRRUS_ID_CLGD5446,
2973
.class_id = PCI_CLASS_DISPLAY_VGA,
2976
static void cirrus_vga_register(void)
2978
pci_qdev_register(&cirrus_vga_info);
2980
device_init(cirrus_vga_register);