1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include "hw.h"
30: #include "pc.h"
31: #include "pci.h"
32: #include "console.h"
33: #include "vga_int.h"
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51: #define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
52:
53:
54: #define CIRRUS_ID_CLGD5422 (0x23<<2)
55: #define CIRRUS_ID_CLGD5426 (0x24<<2)
56: #define CIRRUS_ID_CLGD5424 (0x25<<2)
57: #define CIRRUS_ID_CLGD5428 (0x26<<2)
58: #define CIRRUS_ID_CLGD5430 (0x28<<2)
59: #define CIRRUS_ID_CLGD5434 (0x2A<<2)
60: #define CIRRUS_ID_CLGD5436 (0x2B<<2)
61: #define CIRRUS_ID_CLGD5446 (0x2E<<2)
62:
63:
64: #define CIRRUS_SR7_BPP_VGA 0x00
65: #define CIRRUS_SR7_BPP_SVGA 0x01
66: #define CIRRUS_SR7_BPP_MASK 0x0e
67: #define CIRRUS_SR7_BPP_8 0x00
68: #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
69: #define CIRRUS_SR7_BPP_24 0x04
70: #define CIRRUS_SR7_BPP_16 0x06
71: #define CIRRUS_SR7_BPP_32 0x08
72: #define CIRRUS_SR7_ISAADDR_MASK 0xe0
73:
74:
75: #define CIRRUS_MEMSIZE_512k 0x08
76: #define CIRRUS_MEMSIZE_1M 0x10
77: #define CIRRUS_MEMSIZE_2M 0x18
78: #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80
79:
80:
81: #define CIRRUS_CURSOR_SHOW 0x01
82: #define CIRRUS_CURSOR_HIDDENPEL 0x02
83: #define CIRRUS_CURSOR_LARGE 0x04
84:
85:
86: #define CIRRUS_BUSTYPE_VLBFAST 0x10
87: #define CIRRUS_BUSTYPE_PCI 0x20
88: #define CIRRUS_BUSTYPE_VLBSLOW 0x30
89: #define CIRRUS_BUSTYPE_ISA 0x38
90: #define CIRRUS_MMIO_ENABLE 0x04
91: #define CIRRUS_MMIO_USE_PCIADDR 0x40
92: #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
93:
94:
95: #define CIRRUS_BANKING_DUAL 0x01
96: #define CIRRUS_BANKING_GRANULARITY_16K 0x20
97:
98:
99: #define CIRRUS_BLTMODE_BACKWARDS 0x01
100: #define CIRRUS_BLTMODE_MEMSYSDEST 0x02
101: #define CIRRUS_BLTMODE_MEMSYSSRC 0x04
102: #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
103: #define CIRRUS_BLTMODE_PATTERNCOPY 0x40
104: #define CIRRUS_BLTMODE_COLOREXPAND 0x80
105: #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
106: #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
107: #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
108: #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
109: #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
110:
111:
112: #define CIRRUS_BLT_BUSY 0x01
113: #define CIRRUS_BLT_START 0x02
114: #define CIRRUS_BLT_RESET 0x04
115: #define CIRRUS_BLT_FIFOUSED 0x10
116: #define CIRRUS_BLT_AUTOSTART 0x80
117:
118:
119: #define CIRRUS_ROP_0 0x00
120: #define CIRRUS_ROP_SRC_AND_DST 0x05
121: #define CIRRUS_ROP_NOP 0x06
122: #define CIRRUS_ROP_SRC_AND_NOTDST 0x09
123: #define CIRRUS_ROP_NOTDST 0x0b
124: #define CIRRUS_ROP_SRC 0x0d
125: #define CIRRUS_ROP_1 0x0e
126: #define CIRRUS_ROP_NOTSRC_AND_DST 0x50
127: #define CIRRUS_ROP_SRC_XOR_DST 0x59
128: #define CIRRUS_ROP_SRC_OR_DST 0x6d
129: #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
130: #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
131: #define CIRRUS_ROP_SRC_OR_NOTDST 0xad
132: #define CIRRUS_ROP_NOTSRC 0xd0
133: #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
134: #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
135:
136: #define CIRRUS_ROP_NOP_INDEX 2
137: #define CIRRUS_ROP_SRC_INDEX 5
138:
139:
140: #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
141: #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
142: #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
143:
144:
145: #define CIRRUS_MMIO_BLTBGCOLOR 0x00
146: #define CIRRUS_MMIO_BLTFGCOLOR 0x04
147: #define CIRRUS_MMIO_BLTWIDTH 0x08
148: #define CIRRUS_MMIO_BLTHEIGHT 0x0a
149: #define CIRRUS_MMIO_BLTDESTPITCH 0x0c
150: #define CIRRUS_MMIO_BLTSRCPITCH 0x0e
151: #define CIRRUS_MMIO_BLTDESTADDR 0x10
152: #define CIRRUS_MMIO_BLTSRCADDR 0x14
153: #define CIRRUS_MMIO_BLTWRITEMASK 0x17
154: #define CIRRUS_MMIO_BLTMODE 0x18
155: #define CIRRUS_MMIO_BLTROP 0x1a
156: #define CIRRUS_MMIO_BLTMODEEXT 0x1b
157: #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c
158: #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20
159: #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24
160: #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26
161: #define CIRRUS_MMIO_LINEARDRAW_END_X 0x28
162: #define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a
163: #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c
164: #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d
165: #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e
166: #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f
167: #define CIRRUS_MMIO_BRESENHAM_K1 0x30
168: #define CIRRUS_MMIO_BRESENHAM_K3 0x32
169: #define CIRRUS_MMIO_BRESENHAM_ERROR 0x34
170: #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36
171: #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38
172: #define CIRRUS_MMIO_LINEDRAW_MODE 0x39
173: #define CIRRUS_MMIO_BLTSTATUS 0x40
174:
175:
176: #define PCI_VENDOR_CIRRUS 0x1013
177: #define PCI_DEVICE_CLGD5462 0x00d0
178: #define PCI_DEVICE_CLGD5465 0x00d6
179:
180:
181: #define PCI_COMMAND_IOACCESS 0x0001
182: #define PCI_COMMAND_MEMACCESS 0x0002
183: #define PCI_COMMAND_BUSMASTER 0x0004
184: #define PCI_COMMAND_SPECIALCYCLE 0x0008
185: #define PCI_COMMAND_MEMWRITEINVALID 0x0010
186: #define PCI_COMMAND_PALETTESNOOPING 0x0020
187: #define PCI_COMMAND_PARITYDETECTION 0x0040
188: #define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
189: #define PCI_COMMAND_SERR 0x0100
190: #define PCI_COMMAND_BACKTOBACKTRANS 0x0200
191:
192: #define PCI_CLASS_BASE_DISPLAY 0x03
193:
194: #define PCI_CLASS_SUB_VGA 0x00
195:
196: #define PCI_CLASS_HEADERTYPE_00h 0x00
197:
198:
199:
200: #define PCI_MAP_MEM 0x0
201: #define PCI_MAP_IO 0x1
202: #define PCI_MAP_MEM_ADDR_MASK (~0xf)
203: #define PCI_MAP_IO_ADDR_MASK (~0x3)
204: #define PCI_MAP_MEMFLAGS_32BIT 0x0
205: #define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
206: #define PCI_MAP_MEMFLAGS_64BIT 0x4
207: #define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
208:
209:
210:
211: #define PCI_ROMBIOS_ENABLED 0x1
212:
213:
214:
215:
216: #define CIRRUS_PNPMMIO_SIZE 0x1000
217:
218:
219:
220: #define CIRRUS_HOOK_NOT_HANDLED 0
221: #define CIRRUS_HOOK_HANDLED 1
222:
223: struct CirrusVGAState;
224: typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
225: uint8_t * dst, const uint8_t * src,
226: int dstpitch, int srcpitch,
227: int bltwidth, int bltheight);
228: typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
229: uint8_t *dst, int dst_pitch, int width, int height);
230:
231: typedef struct CirrusVGAState {
232: VGA_STATE_COMMON
233:
234: int cirrus_linear_io_addr;
235: int cirrus_linear_bitblt_io_addr;
236: int cirrus_mmio_io_addr;
237: uint32_t cirrus_addr_mask;
238: uint32_t linear_mmio_mask;
239: uint8_t cirrus_shadow_gr0;
240: uint8_t cirrus_shadow_gr1;
241: uint8_t cirrus_hidden_dac_lockindex;
242: uint8_t cirrus_hidden_dac_data;
243: uint32_t cirrus_bank_base[2];
244: uint32_t cirrus_bank_limit[2];
245: uint8_t cirrus_hidden_palette[48];
246: uint32_t hw_cursor_x;
247: uint32_t hw_cursor_y;
248: int cirrus_blt_pixelwidth;
249: int cirrus_blt_width;
250: int cirrus_blt_height;
251: int cirrus_blt_dstpitch;
252: int cirrus_blt_srcpitch;
253: uint32_t cirrus_blt_fgcol;
254: uint32_t cirrus_blt_bgcol;
255: uint32_t cirrus_blt_dstaddr;
256: uint32_t cirrus_blt_srcaddr;
257: uint8_t cirrus_blt_mode;
258: uint8_t cirrus_blt_modeext;
259: cirrus_bitblt_rop_t cirrus_rop;
260: #define CIRRUS_BLTBUFSIZE (2048 * 4)
261: uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
262: uint8_t *cirrus_srcptr;
263: uint8_t *cirrus_srcptr_end;
264: uint32_t cirrus_srccounter;
265:
266: int last_hw_cursor_size;
267: int last_hw_cursor_x;
268: int last_hw_cursor_y;
269: int last_hw_cursor_y_start;
270: int last_hw_cursor_y_end;
271: int real_vram_size;
272: CPUWriteMemoryFunc **cirrus_linear_write;
273: } CirrusVGAState;
274:
275: typedef struct PCICirrusVGAState {
276: PCIDevice dev;
277: CirrusVGAState cirrus_vga;
278: } PCICirrusVGAState;
279:
280: static uint8_t rop_to_index[256];
281:
282:
283:
284:
285:
286:
287:
288:
289: static void cirrus_bitblt_reset(CirrusVGAState *s);
290: static void cirrus_update_memory_access(CirrusVGAState *s);
291:
292:
293:
294:
295:
296:
297:
298: static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
299: uint8_t *dst,const uint8_t *src,
300: int dstpitch,int srcpitch,
301: int bltwidth,int bltheight)
302: {
303: }
304:
305: static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
306: uint8_t *dst,
307: int dstpitch, int bltwidth,int bltheight)
308: {
309: }
310:
311: #define ROP_NAME 0
312: #define ROP_OP(d, s) d = 0
313: #include "cirrus_vga_rop.h"
314:
315: #define ROP_NAME src_and_dst
316: #define ROP_OP(d, s) d = (s) & (d)
317: #include "cirrus_vga_rop.h"
318:
319: #define ROP_NAME src_and_notdst
320: #define ROP_OP(d, s) d = (s) & (~(d))
321: #include "cirrus_vga_rop.h"
322:
323: #define ROP_NAME notdst
324: #define ROP_OP(d, s) d = ~(d)
325: #include "cirrus_vga_rop.h"
326:
327: #define ROP_NAME src
328: #define ROP_OP(d, s) d = s
329: #include "cirrus_vga_rop.h"
330:
331: #define ROP_NAME 1
332: #define ROP_OP(d, s) d = ~0
333: #include "cirrus_vga_rop.h"
334:
335: #define ROP_NAME notsrc_and_dst
336: #define ROP_OP(d, s) d = (~(s)) & (d)
337: #include "cirrus_vga_rop.h"
338:
339: #define ROP_NAME src_xor_dst
340: #define ROP_OP(d, s) d = (s) ^ (d)
341: #include "cirrus_vga_rop.h"
342:
343: #define ROP_NAME src_or_dst
344: #define ROP_OP(d, s) d = (s) | (d)
345: #include "cirrus_vga_rop.h"
346:
347: #define ROP_NAME notsrc_or_notdst
348: #define ROP_OP(d, s) d = (~(s)) | (~(d))
349: #include "cirrus_vga_rop.h"
350:
351: #define ROP_NAME src_notxor_dst
352: #define ROP_OP(d, s) d = ~((s) ^ (d))
353: #include "cirrus_vga_rop.h"
354:
355: #define ROP_NAME src_or_notdst
356: #define ROP_OP(d, s) d = (s) | (~(d))
357: #include "cirrus_vga_rop.h"
358:
359: #define ROP_NAME notsrc
360: #define ROP_OP(d, s) d = (~(s))
361: #include "cirrus_vga_rop.h"
362:
363: #define ROP_NAME notsrc_or_dst
364: #define ROP_OP(d, s) d = (~(s)) | (d)
365: #include "cirrus_vga_rop.h"
366:
367: #define ROP_NAME notsrc_and_notdst
368: #define ROP_OP(d, s) d = (~(s)) & (~(d))
369: #include "cirrus_vga_rop.h"
370:
371: static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
372: cirrus_bitblt_rop_fwd_0,
373: cirrus_bitblt_rop_fwd_src_and_dst,
374: cirrus_bitblt_rop_nop,
375: cirrus_bitblt_rop_fwd_src_and_notdst,
376: cirrus_bitblt_rop_fwd_notdst,
377: cirrus_bitblt_rop_fwd_src,
378: cirrus_bitblt_rop_fwd_1,
379: cirrus_bitblt_rop_fwd_notsrc_and_dst,
380: cirrus_bitblt_rop_fwd_src_xor_dst,
381: cirrus_bitblt_rop_fwd_src_or_dst,
382: cirrus_bitblt_rop_fwd_notsrc_or_notdst,
383: cirrus_bitblt_rop_fwd_src_notxor_dst,
384: cirrus_bitblt_rop_fwd_src_or_notdst,
385: cirrus_bitblt_rop_fwd_notsrc,
386: cirrus_bitblt_rop_fwd_notsrc_or_dst,
387: cirrus_bitblt_rop_fwd_notsrc_and_notdst,
388: };
389:
390: static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
391: cirrus_bitblt_rop_bkwd_0,
392: cirrus_bitblt_rop_bkwd_src_and_dst,
393: cirrus_bitblt_rop_nop,
394: cirrus_bitblt_rop_bkwd_src_and_notdst,
395: cirrus_bitblt_rop_bkwd_notdst,
396: cirrus_bitblt_rop_bkwd_src,
397: cirrus_bitblt_rop_bkwd_1,
398: cirrus_bitblt_rop_bkwd_notsrc_and_dst,
399: cirrus_bitblt_rop_bkwd_src_xor_dst,
400: cirrus_bitblt_rop_bkwd_src_or_dst,
401: cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
402: cirrus_bitblt_rop_bkwd_src_notxor_dst,
403: cirrus_bitblt_rop_bkwd_src_or_notdst,
404: cirrus_bitblt_rop_bkwd_notsrc,
405: cirrus_bitblt_rop_bkwd_notsrc_or_dst,
406: cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
407: };
408:
409: #define TRANSP_ROP(name) {\
410: name ## _8,\
411: name ## _16,\
412: }
413: #define TRANSP_NOP(func) {\
414: func,\
415: func,\
416: }
417:
418: static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
419: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
420: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
421: TRANSP_NOP(cirrus_bitblt_rop_nop),
422: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
423: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
424: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
425: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
426: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
427: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
428: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
429: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
430: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
431: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
432: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
433: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
434: TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
435: };
436:
437: static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
438: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
439: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
440: TRANSP_NOP(cirrus_bitblt_rop_nop),
441: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
442: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
443: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
444: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
445: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
446: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
447: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
448: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
449: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
450: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
451: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
452: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
453: TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
454: };
455:
456: #define ROP2(name) {\
457: name ## _8,\
458: name ## _16,\
459: name ## _24,\
460: name ## _32,\
461: }
462:
463: #define ROP_NOP2(func) {\
464: func,\
465: func,\
466: func,\
467: func,\
468: }
469:
470: static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
471: ROP2(cirrus_patternfill_0),
472: ROP2(cirrus_patternfill_src_and_dst),
473: ROP_NOP2(cirrus_bitblt_rop_nop),
474: ROP2(cirrus_patternfill_src_and_notdst),
475: ROP2(cirrus_patternfill_notdst),
476: ROP2(cirrus_patternfill_src),
477: ROP2(cirrus_patternfill_1),
478: ROP2(cirrus_patternfill_notsrc_and_dst),
479: ROP2(cirrus_patternfill_src_xor_dst),
480: ROP2(cirrus_patternfill_src_or_dst),
481: ROP2(cirrus_patternfill_notsrc_or_notdst),
482: ROP2(cirrus_patternfill_src_notxor_dst),
483: ROP2(cirrus_patternfill_src_or_notdst),
484: ROP2(cirrus_patternfill_notsrc),
485: ROP2(cirrus_patternfill_notsrc_or_dst),
486: ROP2(cirrus_patternfill_notsrc_and_notdst),
487: };
488:
489: static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
490: ROP2(cirrus_colorexpand_transp_0),
491: ROP2(cirrus_colorexpand_transp_src_and_dst),
492: ROP_NOP2(cirrus_bitblt_rop_nop),
493: ROP2(cirrus_colorexpand_transp_src_and_notdst),
494: ROP2(cirrus_colorexpand_transp_notdst),
495: ROP2(cirrus_colorexpand_transp_src),
496: ROP2(cirrus_colorexpand_transp_1),
497: ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
498: ROP2(cirrus_colorexpand_transp_src_xor_dst),
499: ROP2(cirrus_colorexpand_transp_src_or_dst),
500: ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
501: ROP2(cirrus_colorexpand_transp_src_notxor_dst),
502: ROP2(cirrus_colorexpand_transp_src_or_notdst),
503: ROP2(cirrus_colorexpand_transp_notsrc),
504: ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
505: ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
506: };
507:
508: static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
509: ROP2(cirrus_colorexpand_0),
510: ROP2(cirrus_colorexpand_src_and_dst),
511: ROP_NOP2(cirrus_bitblt_rop_nop),
512: ROP2(cirrus_colorexpand_src_and_notdst),
513: ROP2(cirrus_colorexpand_notdst),
514: ROP2(cirrus_colorexpand_src),
515: ROP2(cirrus_colorexpand_1),
516: ROP2(cirrus_colorexpand_notsrc_and_dst),
517: ROP2(cirrus_colorexpand_src_xor_dst