Commit a5082316e97abb65d3e10085c50b6497473a9265

Authored by bellard
1 parent 20ba3ae1

hardware cursor support - fill with rop support - color expand and color expand …

…with transparent support - various optimisations


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@902 c046a42c-6fe2-441c-8c8c-71466251a162
hw/cirrus_vga.c
@@ -29,6 +29,14 @@ @@ -29,6 +29,14 @@
29 #include "vl.h" 29 #include "vl.h"
30 #include "vga_int.h" 30 #include "vga_int.h"
31 31
  32 +/*
  33 + * TODO:
  34 + * - add support for WRITEMASK (GR2F)
  35 + * - add support for scanline modulo in pattern fill
  36 + * - optimize linear mappings
  37 + * - optimize bitblt functions
  38 + */
  39 +
32 //#define DEBUG_CIRRUS 40 //#define DEBUG_CIRRUS
33 //#define DEBUG_BITBLT 41 //#define DEBUG_BITBLT
34 42
@@ -103,6 +111,7 @@ @@ -103,6 +111,7 @@
103 #define CIRRUS_BLT_START 0x02 111 #define CIRRUS_BLT_START 0x02
104 #define CIRRUS_BLT_RESET 0x04 112 #define CIRRUS_BLT_RESET 0x04
105 #define CIRRUS_BLT_FIFOUSED 0x10 113 #define CIRRUS_BLT_FIFOUSED 0x10
  114 +#define CIRRUS_BLT_AUTOSTART 0x80
106 115
107 // control 0x32 116 // control 0x32
108 #define CIRRUS_ROP_0 0x00 117 #define CIRRUS_ROP_0 0x00
@@ -122,8 +131,12 @@ @@ -122,8 +131,12 @@
122 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 131 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
123 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda 132 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
124 133
  134 +#define CIRRUS_ROP_NOP_INDEX 2
  135 +#define CIRRUS_ROP_SRC_INDEX 5
  136 +
125 // control 0x33 137 // control 0x33
126 -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 138 +#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
  139 +#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
127 140
128 // memory-mapped IO 141 // memory-mapped IO
129 #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword 142 #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
@@ -204,16 +217,19 @@ @@ -204,16 +217,19 @@
204 #define CIRRUS_HOOK_NOT_HANDLED 0 217 #define CIRRUS_HOOK_NOT_HANDLED 0
205 #define CIRRUS_HOOK_HANDLED 1 218 #define CIRRUS_HOOK_HANDLED 1
206 219
207 -typedef void (*cirrus_bitblt_rop_t) (uint8_t * dst, const uint8_t * src, 220 +struct CirrusVGAState;
  221 +typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
  222 + uint8_t * dst, const uint8_t * src,
208 int dstpitch, int srcpitch, 223 int dstpitch, int srcpitch,
209 int bltwidth, int bltheight); 224 int bltwidth, int bltheight);
210 -  
211 -typedef void (*cirrus_bitblt_handler_t) (void *opaque); 225 +typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
  226 + uint8_t *dst, int dst_pitch, int width, int height);
212 227
213 typedef struct CirrusVGAState { 228 typedef struct CirrusVGAState {
214 VGA_STATE_COMMON 229 VGA_STATE_COMMON
215 230
216 int cirrus_linear_io_addr; 231 int cirrus_linear_io_addr;
  232 + int cirrus_linear_bitblt_io_addr;
217 int cirrus_mmio_io_addr; 233 int cirrus_mmio_io_addr;
218 uint32_t cirrus_addr_mask; 234 uint32_t cirrus_addr_mask;
219 uint8_t cirrus_shadow_gr0; 235 uint8_t cirrus_shadow_gr0;
@@ -223,18 +239,21 @@ typedef struct CirrusVGAState { @@ -223,18 +239,21 @@ typedef struct CirrusVGAState {
223 uint32_t cirrus_bank_base[2]; 239 uint32_t cirrus_bank_base[2];
224 uint32_t cirrus_bank_limit[2]; 240 uint32_t cirrus_bank_limit[2];
225 uint8_t cirrus_hidden_palette[48]; 241 uint8_t cirrus_hidden_palette[48];
226 - uint32_t cirrus_hw_cursor_x;  
227 - uint32_t cirrus_hw_cursor_y; 242 + uint32_t hw_cursor_x;
  243 + uint32_t hw_cursor_y;
228 int cirrus_blt_pixelwidth; 244 int cirrus_blt_pixelwidth;
229 int cirrus_blt_width; 245 int cirrus_blt_width;
230 int cirrus_blt_height; 246 int cirrus_blt_height;
231 int cirrus_blt_dstpitch; 247 int cirrus_blt_dstpitch;
232 int cirrus_blt_srcpitch; 248 int cirrus_blt_srcpitch;
  249 + uint32_t cirrus_blt_fgcol;
  250 + uint32_t cirrus_blt_bgcol;
233 uint32_t cirrus_blt_dstaddr; 251 uint32_t cirrus_blt_dstaddr;
234 uint32_t cirrus_blt_srcaddr; 252 uint32_t cirrus_blt_srcaddr;
235 uint8_t cirrus_blt_mode; 253 uint8_t cirrus_blt_mode;
  254 + uint8_t cirrus_blt_modeext;
236 cirrus_bitblt_rop_t cirrus_rop; 255 cirrus_bitblt_rop_t cirrus_rop;
237 -#define CIRRUS_BLTBUFSIZE 256 256 +#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
238 uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE]; 257 uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
239 uint8_t *cirrus_srcptr; 258 uint8_t *cirrus_srcptr;
240 uint8_t *cirrus_srcptr_end; 259 uint8_t *cirrus_srcptr_end;
@@ -242,8 +261,12 @@ typedef struct CirrusVGAState { @@ -242,8 +261,12 @@ typedef struct CirrusVGAState {
242 uint8_t *cirrus_dstptr; 261 uint8_t *cirrus_dstptr;
243 uint8_t *cirrus_dstptr_end; 262 uint8_t *cirrus_dstptr_end;
244 uint32_t cirrus_dstcounter; 263 uint32_t cirrus_dstcounter;
245 - cirrus_bitblt_handler_t cirrus_blt_handler;  
246 - int cirrus_blt_horz_counter; 264 + /* hwcursor display state */
  265 + int last_hw_cursor_size;
  266 + int last_hw_cursor_x;
  267 + int last_hw_cursor_y;
  268 + int last_hw_cursor_y_start;
  269 + int last_hw_cursor_y_end;
247 } CirrusVGAState; 270 } CirrusVGAState;
248 271
249 typedef struct PCICirrusVGAState { 272 typedef struct PCICirrusVGAState {
@@ -251,6 +274,8 @@ typedef struct PCICirrusVGAState { @@ -251,6 +274,8 @@ typedef struct PCICirrusVGAState {
251 CirrusVGAState cirrus_vga; 274 CirrusVGAState cirrus_vga;
252 } PCICirrusVGAState; 275 } PCICirrusVGAState;
253 276
  277 +static uint8_t rop_to_index[256];
  278 +
254 /*************************************** 279 /***************************************
255 * 280 *
256 * prototypes. 281 * prototypes.
@@ -266,343 +291,233 @@ static void cirrus_bitblt_reset(CirrusVGAState * s); @@ -266,343 +291,233 @@ static void cirrus_bitblt_reset(CirrusVGAState * s);
266 * 291 *
267 ***************************************/ 292 ***************************************/
268 293
269 -#define IMPLEMENT_BITBLT(name,opline) \  
270 - static void \  
271 - cirrus_bitblt_rop_fwd_##name( \  
272 - uint8_t *dst,const uint8_t *src, \  
273 - int dstpitch,int srcpitch, \  
274 - int bltwidth,int bltheight) \  
275 - { \  
276 - int x,y; \  
277 - dstpitch -= bltwidth; \  
278 - srcpitch -= bltwidth; \  
279 - for (y = 0; y < bltheight; y++) { \  
280 - for (x = 0; x < bltwidth; x++) { \  
281 - opline; \  
282 - dst++; \  
283 - src++; \  
284 - } \  
285 - dst += dstpitch; \  
286 - src += srcpitch; \  
287 - } \  
288 - } \  
289 - \  
290 - static void \  
291 - cirrus_bitblt_rop_bkwd_##name( \  
292 - uint8_t *dst,const uint8_t *src, \  
293 - int dstpitch,int srcpitch, \  
294 - int bltwidth,int bltheight) \  
295 - { \  
296 - int x,y; \  
297 - dstpitch += bltwidth; \  
298 - srcpitch += bltwidth; \  
299 - for (y = 0; y < bltheight; y++) { \  
300 - for (x = 0; x < bltwidth; x++) { \  
301 - opline; \  
302 - dst--; \  
303 - src--; \  
304 - } \  
305 - dst += dstpitch; \  
306 - src += srcpitch; \  
307 - } \  
308 - }  
309 -  
310 -IMPLEMENT_BITBLT(0, *dst = 0)  
311 -IMPLEMENT_BITBLT(src_and_dst, *dst = (*src) & (*dst))  
312 -IMPLEMENT_BITBLT(nop, (void) 0)  
313 -IMPLEMENT_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))  
314 -IMPLEMENT_BITBLT(notdst, *dst = ~(*dst))  
315 -IMPLEMENT_BITBLT(src, *dst = *src)  
316 -IMPLEMENT_BITBLT(1, *dst = 0xff)  
317 -IMPLEMENT_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))  
318 -IMPLEMENT_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))  
319 -IMPLEMENT_BITBLT(src_or_dst, *dst = (*src) | (*dst))  
320 -IMPLEMENT_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))  
321 -IMPLEMENT_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))  
322 -IMPLEMENT_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))  
323 -IMPLEMENT_BITBLT(notsrc, *dst = (~(*src)))  
324 -IMPLEMENT_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))  
325 -IMPLEMENT_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))  
326 -  
327 -static cirrus_bitblt_rop_t cirrus_get_fwd_rop_handler(uint8_t rop)  
328 -{  
329 - cirrus_bitblt_rop_t rop_handler = cirrus_bitblt_rop_fwd_nop;  
330 -  
331 - switch (rop) {  
332 - case CIRRUS_ROP_0:  
333 - rop_handler = cirrus_bitblt_rop_fwd_0;  
334 - break;  
335 - case CIRRUS_ROP_SRC_AND_DST:  
336 - rop_handler = cirrus_bitblt_rop_fwd_src_and_dst;  
337 - break;  
338 - case CIRRUS_ROP_NOP:  
339 - rop_handler = cirrus_bitblt_rop_fwd_nop;  
340 - break;  
341 - case CIRRUS_ROP_SRC_AND_NOTDST:  
342 - rop_handler = cirrus_bitblt_rop_fwd_src_and_notdst;  
343 - break;  
344 - case CIRRUS_ROP_NOTDST:  
345 - rop_handler = cirrus_bitblt_rop_fwd_notdst;  
346 - break;  
347 - case CIRRUS_ROP_SRC:  
348 - rop_handler = cirrus_bitblt_rop_fwd_src;  
349 - break;  
350 - case CIRRUS_ROP_1:  
351 - rop_handler = cirrus_bitblt_rop_fwd_1;  
352 - break;  
353 - case CIRRUS_ROP_NOTSRC_AND_DST:  
354 - rop_handler = cirrus_bitblt_rop_fwd_notsrc_and_dst;  
355 - break;  
356 - case CIRRUS_ROP_SRC_XOR_DST:  
357 - rop_handler = cirrus_bitblt_rop_fwd_src_xor_dst;  
358 - break;  
359 - case CIRRUS_ROP_SRC_OR_DST:  
360 - rop_handler = cirrus_bitblt_rop_fwd_src_or_dst;  
361 - break;  
362 - case CIRRUS_ROP_NOTSRC_OR_NOTDST:  
363 - rop_handler = cirrus_bitblt_rop_fwd_notsrc_or_notdst;  
364 - break;  
365 - case CIRRUS_ROP_SRC_NOTXOR_DST:  
366 - rop_handler = cirrus_bitblt_rop_fwd_src_notxor_dst;  
367 - break;  
368 - case CIRRUS_ROP_SRC_OR_NOTDST:  
369 - rop_handler = cirrus_bitblt_rop_fwd_src_or_notdst;  
370 - break;  
371 - case CIRRUS_ROP_NOTSRC:  
372 - rop_handler = cirrus_bitblt_rop_fwd_notsrc;  
373 - break;  
374 - case CIRRUS_ROP_NOTSRC_OR_DST:  
375 - rop_handler = cirrus_bitblt_rop_fwd_notsrc_or_dst;  
376 - break;  
377 - case CIRRUS_ROP_NOTSRC_AND_NOTDST:  
378 - rop_handler = cirrus_bitblt_rop_fwd_notsrc_and_notdst;  
379 - break;  
380 - default:  
381 -#ifdef DEBUG_CIRRUS  
382 - printf("unknown ROP %02x\n", rop);  
383 -#endif  
384 - break;  
385 - }  
386 -  
387 - return rop_handler; 294 +static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
  295 + uint8_t *dst,const uint8_t *src,
  296 + int dstpitch,int srcpitch,
  297 + int bltwidth,int bltheight)
  298 +{
388 } 299 }
389 300
390 -static cirrus_bitblt_rop_t cirrus_get_bkwd_rop_handler(uint8_t rop) 301 +static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
  302 + uint8_t *dst,
  303 + int dstpitch, int bltwidth,int bltheight)
391 { 304 {
392 - cirrus_bitblt_rop_t rop_handler = cirrus_bitblt_rop_bkwd_nop; 305 +}
393 306
394 - switch (rop) {  
395 - case CIRRUS_ROP_0:  
396 - rop_handler = cirrus_bitblt_rop_bkwd_0;  
397 - break;  
398 - case CIRRUS_ROP_SRC_AND_DST:  
399 - rop_handler = cirrus_bitblt_rop_bkwd_src_and_dst;  
400 - break;  
401 - case CIRRUS_ROP_NOP:  
402 - rop_handler = cirrus_bitblt_rop_bkwd_nop;  
403 - break;  
404 - case CIRRUS_ROP_SRC_AND_NOTDST:  
405 - rop_handler = cirrus_bitblt_rop_bkwd_src_and_notdst;  
406 - break;  
407 - case CIRRUS_ROP_NOTDST:  
408 - rop_handler = cirrus_bitblt_rop_bkwd_notdst;  
409 - break;  
410 - case CIRRUS_ROP_SRC:  
411 - rop_handler = cirrus_bitblt_rop_bkwd_src;  
412 - break;  
413 - case CIRRUS_ROP_1:  
414 - rop_handler = cirrus_bitblt_rop_bkwd_1;  
415 - break;  
416 - case CIRRUS_ROP_NOTSRC_AND_DST:  
417 - rop_handler = cirrus_bitblt_rop_bkwd_notsrc_and_dst;  
418 - break;  
419 - case CIRRUS_ROP_SRC_XOR_DST:  
420 - rop_handler = cirrus_bitblt_rop_bkwd_src_xor_dst;  
421 - break;  
422 - case CIRRUS_ROP_SRC_OR_DST:  
423 - rop_handler = cirrus_bitblt_rop_bkwd_src_or_dst;  
424 - break;  
425 - case CIRRUS_ROP_NOTSRC_OR_NOTDST:  
426 - rop_handler = cirrus_bitblt_rop_bkwd_notsrc_or_notdst;  
427 - break;  
428 - case CIRRUS_ROP_SRC_NOTXOR_DST:  
429 - rop_handler = cirrus_bitblt_rop_bkwd_src_notxor_dst;  
430 - break;  
431 - case CIRRUS_ROP_SRC_OR_NOTDST:  
432 - rop_handler = cirrus_bitblt_rop_bkwd_src_or_notdst;  
433 - break;  
434 - case CIRRUS_ROP_NOTSRC:  
435 - rop_handler = cirrus_bitblt_rop_bkwd_notsrc;  
436 - break;  
437 - case CIRRUS_ROP_NOTSRC_OR_DST:  
438 - rop_handler = cirrus_bitblt_rop_bkwd_notsrc_or_dst;  
439 - break;  
440 - case CIRRUS_ROP_NOTSRC_AND_NOTDST:  
441 - rop_handler = cirrus_bitblt_rop_bkwd_notsrc_and_notdst;  
442 - break;  
443 - default:  
444 -#ifdef DEBUG_CIRRUS  
445 - printf("unknown ROP %02x\n", rop);  
446 -#endif  
447 - break;  
448 - } 307 +#define ROP_NAME 0
  308 +#define ROP_OP(d, s) d = 0
  309 +#include "cirrus_vga_rop.h"
449 310
450 - return rop_handler;  
451 -} 311 +#define ROP_NAME src_and_dst
  312 +#define ROP_OP(d, s) d = (s) & (d)
  313 +#include "cirrus_vga_rop.h"
452 314
453 -/***************************************  
454 - *  
455 - * color expansion  
456 - *  
457 - ***************************************/ 315 +#define ROP_NAME src_and_notdst
  316 +#define ROP_OP(d, s) d = (s) & (~(d))
  317 +#include "cirrus_vga_rop.h"
458 318
459 -static void  
460 -cirrus_colorexpand_8(CirrusVGAState * s, uint8_t * dst,  
461 - const uint8_t * src, int count)  
462 -{  
463 - int x;  
464 - uint8_t colors[2];  
465 - unsigned bits;  
466 - unsigned bitmask;  
467 - int srcskipleft = 0;  
468 -  
469 - colors[0] = s->cirrus_shadow_gr0;  
470 - colors[1] = s->cirrus_shadow_gr1;  
471 -  
472 - bitmask = 0x80 >> srcskipleft;  
473 - bits = *src++;  
474 - for (x = 0; x < count; x++) {  
475 - if ((bitmask & 0xff) == 0) {  
476 - bitmask = 0x80;  
477 - bits = *src++;  
478 - }  
479 - *dst++ = colors[!!(bits & bitmask)];  
480 - bitmask >>= 1;  
481 - }  
482 -} 319 +#define ROP_NAME notdst
  320 +#define ROP_OP(d, s) d = ~(d)
  321 +#include "cirrus_vga_rop.h"
483 322
484 -static void  
485 -cirrus_colorexpand_16(CirrusVGAState * s, uint8_t * dst,  
486 - const uint8_t * src, int count)  
487 -{  
488 - int x;  
489 - uint8_t colors[2][2];  
490 - unsigned bits;  
491 - unsigned bitmask;  
492 - unsigned index;  
493 - int srcskipleft = 0;  
494 -  
495 - colors[0][0] = s->cirrus_shadow_gr0;  
496 - colors[0][1] = s->gr[0x10];  
497 - colors[1][0] = s->cirrus_shadow_gr1;  
498 - colors[1][1] = s->gr[0x11];  
499 -  
500 - bitmask = 0x80 >> srcskipleft;  
501 - bits = *src++;  
502 - for (x = 0; x < count; x++) {  
503 - if ((bitmask & 0xff) == 0) {  
504 - bitmask = 0x80;  
505 - bits = *src++;  
506 - }  
507 - index = !!(bits & bitmask);  
508 - *dst++ = colors[index][0];  
509 - *dst++ = colors[index][1];  
510 - bitmask >>= 1;  
511 - }  
512 -} 323 +#define ROP_NAME src
  324 +#define ROP_OP(d, s) d = s
  325 +#include "cirrus_vga_rop.h"
513 326
514 -static void  
515 -cirrus_colorexpand_24(CirrusVGAState * s, uint8_t * dst,  
516 - const uint8_t * src, int count)  
517 -{  
518 - int x;  
519 - uint8_t colors[2][3];  
520 - unsigned bits;  
521 - unsigned bitmask;  
522 - unsigned index;  
523 - int srcskipleft = 0;  
524 -  
525 - colors[0][0] = s->cirrus_shadow_gr0;  
526 - colors[0][1] = s->gr[0x10];  
527 - colors[0][2] = s->gr[0x12];  
528 - colors[1][0] = s->cirrus_shadow_gr1;  
529 - colors[1][1] = s->gr[0x11];  
530 - colors[1][2] = s->gr[0x13];  
531 -  
532 - bitmask = 0x80 << srcskipleft;  
533 - bits = *src++;  
534 - for (x = 0; x < count; x++) {  
535 - if ((bitmask & 0xff) == 0) {  
536 - bitmask = 0x80;  
537 - bits = *src++;  
538 - }  
539 - index = !!(bits & bitmask);  
540 - *dst++ = colors[index][0];  
541 - *dst++ = colors[index][1];  
542 - *dst++ = colors[index][2];  
543 - bitmask >>= 1;  
544 - }  
545 -} 327 +#define ROP_NAME 1
  328 +#define ROP_OP(d, s) d = 0xff
  329 +#include "cirrus_vga_rop.h"
  330 +
  331 +#define ROP_NAME notsrc_and_dst
  332 +#define ROP_OP(d, s) d = (~(s)) & (d)
  333 +#include "cirrus_vga_rop.h"
  334 +
  335 +#define ROP_NAME src_xor_dst
  336 +#define ROP_OP(d, s) d = (s) ^ (d)
  337 +#include "cirrus_vga_rop.h"
  338 +
  339 +#define ROP_NAME src_or_dst
  340 +#define ROP_OP(d, s) d = (s) | (d)
  341 +#include "cirrus_vga_rop.h"
  342 +
  343 +#define ROP_NAME notsrc_or_notdst
  344 +#define ROP_OP(d, s) d = (~(s)) | (~(d))
  345 +#include "cirrus_vga_rop.h"
  346 +
  347 +#define ROP_NAME src_notxor_dst
  348 +#define ROP_OP(d, s) d = ~((s) ^ (d))
  349 +#include "cirrus_vga_rop.h"
546 350
547 -static void  
548 -cirrus_colorexpand_32(CirrusVGAState * s, uint8_t * dst,  
549 - const uint8_t * src, int count) 351 +#define ROP_NAME src_or_notdst
  352 +#define ROP_OP(d, s) d = (s) | (~(d))
  353 +#include "cirrus_vga_rop.h"
  354 +
  355 +#define ROP_NAME notsrc
  356 +#define ROP_OP(d, s) d = (~(s))
  357 +#include "cirrus_vga_rop.h"
  358 +
  359 +#define ROP_NAME notsrc_or_dst
  360 +#define ROP_OP(d, s) d = (~(s)) | (d)
  361 +#include "cirrus_vga_rop.h"
  362 +
  363 +#define ROP_NAME notsrc_and_notdst
  364 +#define ROP_OP(d, s) d = (~(s)) & (~(d))
  365 +#include "cirrus_vga_rop.h"
  366 +
  367 +static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
  368 + cirrus_bitblt_rop_fwd_0,
  369 + cirrus_bitblt_rop_fwd_src_and_dst,
  370 + cirrus_bitblt_rop_nop,
  371 + cirrus_bitblt_rop_fwd_src_and_notdst,
  372 + cirrus_bitblt_rop_fwd_notdst,
  373 + cirrus_bitblt_rop_fwd_src,
  374 + cirrus_bitblt_rop_fwd_1,
  375 + cirrus_bitblt_rop_fwd_notsrc_and_dst,
  376 + cirrus_bitblt_rop_fwd_src_xor_dst,
  377 + cirrus_bitblt_rop_fwd_src_or_dst,
  378 + cirrus_bitblt_rop_fwd_notsrc_or_notdst,
  379 + cirrus_bitblt_rop_fwd_src_notxor_dst,
  380 + cirrus_bitblt_rop_fwd_src_or_notdst,
  381 + cirrus_bitblt_rop_fwd_notsrc,
  382 + cirrus_bitblt_rop_fwd_notsrc_or_dst,
  383 + cirrus_bitblt_rop_fwd_notsrc_and_notdst,
  384 +};
  385 +
  386 +static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
  387 + cirrus_bitblt_rop_bkwd_0,
  388 + cirrus_bitblt_rop_bkwd_src_and_dst,
  389 + cirrus_bitblt_rop_nop,
  390 + cirrus_bitblt_rop_bkwd_src_and_notdst,
  391 + cirrus_bitblt_rop_bkwd_notdst,
  392 + cirrus_bitblt_rop_bkwd_src,
  393 + cirrus_bitblt_rop_bkwd_1,
  394 + cirrus_bitblt_rop_bkwd_notsrc_and_dst,
  395 + cirrus_bitblt_rop_bkwd_src_xor_dst,
  396 + cirrus_bitblt_rop_bkwd_src_or_dst,
  397 + cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
  398 + cirrus_bitblt_rop_bkwd_src_notxor_dst,
  399 + cirrus_bitblt_rop_bkwd_src_or_notdst,
  400 + cirrus_bitblt_rop_bkwd_notsrc,
  401 + cirrus_bitblt_rop_bkwd_notsrc_or_dst,
  402 + cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
  403 +};
  404 +
  405 +#define ROP2(name) {\
  406 + name ## _8,\
  407 + name ## _16,\
  408 + name ## _24,\
  409 + name ## _32,\
  410 + }
  411 +
  412 +#define ROP_NOP2(func) {\
  413 + func,\
  414 + func,\
  415 + func,\
  416 + func,\
  417 + }
  418 +
  419 +static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
  420 + ROP2(cirrus_colorexpand_transp_0),
  421 + ROP2(cirrus_colorexpand_transp_src_and_dst),
  422 + ROP_NOP2(cirrus_bitblt_rop_nop),
  423 + ROP2(cirrus_colorexpand_transp_src_and_notdst),
  424 + ROP2(cirrus_colorexpand_transp_notdst),
  425 + ROP2(cirrus_colorexpand_transp_src),
  426 + ROP2(cirrus_colorexpand_transp_1),
  427 + ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
  428 + ROP2(cirrus_colorexpand_transp_src_xor_dst),
  429 + ROP2(cirrus_colorexpand_transp_src_or_dst),
  430 + ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
  431 + ROP2(cirrus_colorexpand_transp_src_notxor_dst),
  432 + ROP2(cirrus_colorexpand_transp_src_or_notdst),
  433 + ROP2(cirrus_colorexpand_transp_notsrc),
  434 + ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
  435 + ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
  436 +};
  437 +
  438 +static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
  439 + ROP2(cirrus_colorexpand_0),
  440 + ROP2(cirrus_colorexpand_src_and_dst),
  441 + ROP_NOP2(cirrus_bitblt_rop_nop),
  442 + ROP2(cirrus_colorexpand_src_and_notdst),
  443 + ROP2(cirrus_colorexpand_notdst),
  444 + ROP2(cirrus_colorexpand_src),
  445 + ROP2(cirrus_colorexpand_1),
  446 + ROP2(cirrus_colorexpand_notsrc_and_dst),
  447 + ROP2(cirrus_colorexpand_src_xor_dst),
  448 + ROP2(cirrus_colorexpand_src_or_dst),
  449 + ROP2(cirrus_colorexpand_notsrc_or_notdst),
  450 + ROP2(cirrus_colorexpand_src_notxor_dst),
  451 + ROP2(cirrus_colorexpand_src_or_notdst),
  452 + ROP2(cirrus_colorexpand_notsrc),
  453 + ROP2(cirrus_colorexpand_notsrc_or_dst),
  454 + ROP2(cirrus_colorexpand_notsrc_and_notdst),
  455 +};
  456 +
  457 +static const cirrus_fill_t cirrus_fill[16][4] = {
  458 + ROP2(cirrus_fill_0),
  459 + ROP2(cirrus_fill_src_and_dst),
  460 + ROP_NOP2(cirrus_bitblt_fill_nop),
  461 + ROP2(cirrus_fill_src_and_notdst),
  462 + ROP2(cirrus_fill_notdst),
  463 + ROP2(cirrus_fill_src),
  464 + ROP2(cirrus_fill_1),
  465 + ROP2(cirrus_fill_notsrc_and_dst),
  466 + ROP2(cirrus_fill_src_xor_dst),
  467 + ROP2(cirrus_fill_src_or_dst),
  468 + ROP2(cirrus_fill_notsrc_or_notdst),
  469 + ROP2(cirrus_fill_src_notxor_dst),
  470 + ROP2(cirrus_fill_src_or_notdst),
  471 + ROP2(cirrus_fill_notsrc),
  472 + ROP2(cirrus_fill_notsrc_or_dst),
  473 + ROP2(cirrus_fill_notsrc_and_notdst),
  474 +};
  475 +
  476 +static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
550 { 477 {
551 - int x;  
552 - uint8_t colors[2][4];  
553 - unsigned bits;  
554 - unsigned bitmask;  
555 - unsigned index;  
556 - int srcskipleft = 0;  
557 -  
558 - colors[0][0] = s->cirrus_shadow_gr0;  
559 - colors[0][1] = s->gr[0x10];  
560 - colors[0][2] = s->gr[0x12];  
561 - colors[0][3] = s->gr[0x14];  
562 - colors[1][0] = s->cirrus_shadow_gr1;  
563 - colors[1][1] = s->gr[0x11];  
564 - colors[1][2] = s->gr[0x13];  
565 - colors[1][3] = s->gr[0x15];  
566 -  
567 - bitmask = 0x80 << srcskipleft;  
568 - bits = *src++;  
569 - for (x = 0; x < count; x++) {  
570 - if ((bitmask & 0xff) == 0) {  
571 - bitmask = 0x80;  
572 - bits = *src++;  
573 - }  
574 - index = !!(bits & bitmask);  
575 - *dst++ = colors[index][0];  
576 - *dst++ = colors[index][1];  
577 - *dst++ = colors[index][2];  
578 - *dst++ = colors[index][3];  
579 - bitmask >>= 1; 478 + unsigned int color;
  479 + switch (s->cirrus_blt_pixelwidth) {
  480 + case 1:
  481 + s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
  482 + break;
  483 + case 2:
  484 + color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);
  485 + s->cirrus_blt_fgcol = le16_to_cpu(color);
  486 + break;
  487 + case 3:
  488 + s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
  489 + (s->gr[0x11] << 8) | (s->gr[0x13] << 16);
  490 + break;
  491 + default:
  492 + case 4:
  493 + color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |
  494 + (s->gr[0x13] << 16) | (s->gr[0x15] << 24);
  495 + s->cirrus_blt_fgcol = le32_to_cpu(color);
  496 + break;
580 } 497 }
581 } 498 }
582 499
583 -static void  
584 -cirrus_colorexpand(CirrusVGAState * s, uint8_t * dst, const uint8_t * src,  
585 - int count) 500 +static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
586 { 501 {
  502 + unsigned int color;
587 switch (s->cirrus_blt_pixelwidth) { 503 switch (s->cirrus_blt_pixelwidth) {
588 case 1: 504 case 1:
589 - cirrus_colorexpand_8(s, dst, src, count);  
590 - break; 505 + s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
  506 + break;
591 case 2: 507 case 2:
592 - cirrus_colorexpand_16(s, dst, src, count);  
593 - break; 508 + color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);
  509 + s->cirrus_blt_bgcol = le16_to_cpu(color);
  510 + break;
594 case 3: 511 case 3:
595 - cirrus_colorexpand_24(s, dst, src, count);  
596 - break;  
597 - case 4:  
598 - cirrus_colorexpand_32(s, dst, src, count);  
599 - break; 512 + s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
  513 + (s->gr[0x10] << 8) | (s->gr[0x12] << 16);
  514 + break;
600 default: 515 default:
601 -#ifdef DEBUG_CIRRUS  
602 - printf("cirrus: COLOREXPAND pixelwidth %d - unimplemented\n",  
603 - s->cirrus_blt_pixelwidth);  
604 -#endif  
605 - break; 516 + case 4:
  517 + color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |
  518 + (s->gr[0x12] << 16) | (s->gr[0x14] << 24);
  519 + s->cirrus_blt_bgcol = le32_to_cpu(color);
  520 + break;
606 } 521 }
607 } 522 }
608 523
@@ -626,8 +541,6 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, @@ -626,8 +541,6 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
626 } 541 }
627 } 542 }
628 543
629 -  
630 -  
631 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, 544 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
632 const uint8_t * src) 545 const uint8_t * src)
633 { 546 {
@@ -639,12 +552,16 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, @@ -639,12 +552,16 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
639 int patternbytes = s->cirrus_blt_pixelwidth * 8; 552 int patternbytes = s->cirrus_blt_pixelwidth * 8;
640 553
641 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 554 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
642 - cirrus_colorexpand(s, work_colorexp, src, 8 * 8); 555 + cirrus_bitblt_rop_t rop_func;
  556 + cirrus_bitblt_fgcol(s);
  557 + cirrus_bitblt_bgcol(s);
  558 + rop_func = cirrus_colorexpand[CIRRUS_ROP_SRC_INDEX][s->cirrus_blt_pixelwidth - 1];
  559 + rop_func(s, work_colorexp, src, patternbytes, 1, patternbytes, 8);
643 src = work_colorexp; 560 src = work_colorexp;
644 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND; 561 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND;
645 } 562 }
646 if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) { 563 if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) {
647 -#ifdef DEBUG_CIRRUS 564 +#ifdef DEBUG_BITBLT
648 printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n", 565 printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n",
649 s->cirrus_blt_mode); 566 s->cirrus_blt_mode);
650 #endif 567 #endif
@@ -657,7 +574,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, @@ -657,7 +574,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
657 tileheight = qemu_MIN(8, s->cirrus_blt_height - y); 574 tileheight = qemu_MIN(8, s->cirrus_blt_height - y);
658 for (x = 0; x < s->cirrus_blt_width; x += patternbytes) { 575 for (x = 0; x < s->cirrus_blt_width; x += patternbytes) {
659 tilewidth = qemu_MIN(patternbytes, s->cirrus_blt_width - x); 576 tilewidth = qemu_MIN(patternbytes, s->cirrus_blt_width - x);
660 - (*s->cirrus_rop) (dstc, src, 577 + (*s->cirrus_rop) (s, dstc, src,
661 s->cirrus_blt_dstpitch, patternbytes, 578 s->cirrus_blt_dstpitch, patternbytes,
662 tilewidth, tileheight); 579 tilewidth, tileheight);
663 dstc += patternbytes; 580 dstc += patternbytes;
@@ -672,111 +589,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, @@ -672,111 +589,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
672 589
673 /* fill */ 590 /* fill */
674 591
675 -static void cirrus_fill_8(CirrusVGAState *s,  
676 - uint8_t *dst, int dst_pitch, int width, int height) 592 +static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
677 { 593 {
678 - uint8_t *d, *d1;  
679 - uint32_t val;  
680 - int x, y; 594 + cirrus_fill_t rop_func;
681 595
682 - val = s->cirrus_shadow_gr1;  
683 -  
684 - d1 = dst;  
685 - for(y = 0; y < height; y++) {  
686 - d = d1;  
687 - for(x = 0; x < width; x++) {  
688 - *d++ = val;  
689 - }  
690 - d1 += dst_pitch;  
691 - }  
692 -}  
693 -  
694 -static void cirrus_fill_16(CirrusVGAState *s,  
695 - uint8_t *dst, int dst_pitch, int width, int height)  
696 -{  
697 - uint8_t *d, *d1;  
698 - uint32_t val;  
699 - int x, y;  
700 -  
701 - val = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);  
702 - val = le16_to_cpu(val);  
703 - width >>= 1;  
704 -  
705 - d1 = dst;  
706 - for(y = 0; y < height; y++) {  
707 - d = d1;  
708 - for(x = 0; x < width; x++) {  
709 - ((uint16_t *)d)[0] = val;  
710 - d += 2;  
711 - }  
712 - d1 += dst_pitch;  
713 - }  
714 -}  
715 -  
716 -static void cirrus_fill_24(CirrusVGAState *s,  
717 - uint8_t *dst, int dst_pitch, int width, int height)  
718 -{  
719 - uint8_t *d, *d1;  
720 - int x, y;  
721 -  
722 - d1 = dst;  
723 - for(y = 0; y < height; y++) {  
724 - d = d1;  
725 - for(x = 0; x < width; x += 3) {  
726 - *d++ = s->cirrus_shadow_gr1;  
727 - *d++ = s->gr[0x11];  
728 - *d++ = s->gr[0x13];  
729 - }  
730 - d1 += dst_pitch;  
731 - }  
732 -}  
733 -  
734 -static void cirrus_fill_32(CirrusVGAState *s,  
735 - uint8_t *dst, int dst_pitch, int width, int height)  
736 -{  
737 - uint8_t *d, *d1;  
738 - uint32_t val;  
739 - int x, y;  
740 -  
741 - val = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |  
742 - (s->gr[0x13] << 8) | (s->gr[0x15] << 8);  
743 - val = le32_to_cpu(val);  
744 - width >>= 2;  
745 -  
746 - d1 = dst;  
747 - for(y = 0; y < height; y++) {  
748 - d = d1;  
749 - for(x = 0; x < width; x++) {  
750 - ((uint32_t *)d)[0] = val;  
751 - d += 4;  
752 - }  
753 - d1 += dst_pitch;  
754 - }  
755 -}  
756 -  
757 -static int cirrus_bitblt_solidfill(CirrusVGAState *s)  
758 -{  
759 - uint8_t *dst;  
760 - dst = s->vram_ptr + s->cirrus_blt_dstaddr;  
761 - switch (s->cirrus_blt_pixelwidth) {  
762 - case 1:  
763 - cirrus_fill_8(s, dst, s->cirrus_blt_dstpitch,  
764 - s->cirrus_blt_width, s->cirrus_blt_height);  
765 - break;  
766 - case 2:  
767 - cirrus_fill_16(s, dst, s->cirrus_blt_dstpitch,  
768 - s->cirrus_blt_width, s->cirrus_blt_height);  
769 - break;  
770 - case 3:  
771 - cirrus_fill_24(s, dst, s->cirrus_blt_dstpitch,  
772 - s->cirrus_blt_width, s->cirrus_blt_height);  
773 - break;  
774 - default:  
775 - case 4:  
776 - cirrus_fill_32(s, dst, s->cirrus_blt_dstpitch,  
777 - s->cirrus_blt_width, s->cirrus_blt_height);  
778 - break;  
779 - } 596 + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  597 + rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
  598 + s->cirrus_blt_dstpitch,
  599 + s->cirrus_blt_width, s->cirrus_blt_height);
780 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 600 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
781 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 601 s->cirrus_blt_dstpitch, s->cirrus_blt_width,
782 s->cirrus_blt_height); 602 s->cirrus_blt_height);
@@ -799,21 +619,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) @@ -799,21 +619,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
799 619
800 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) 620 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
801 { 621 {
802 - if ((s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) != 0) {  
803 -#ifdef DEBUG_CIRRUS  
804 - printf("cirrus: CIRRUS_BLTMODE_COLOREXPAND - unimplemented\n");  
805 -#endif  
806 - return 0;  
807 - }  
808 - if ((s->cirrus_blt_mode & (~CIRRUS_BLTMODE_BACKWARDS)) != 0) {  
809 -#ifdef DEBUG_CIRRUS  
810 - printf("cirrus: blt mode %02x - unimplemented\n",  
811 - s->cirrus_blt_mode);  
812 -#endif  
813 - return 0;  
814 - }  
815 -  
816 - (*s->cirrus_rop) (s->vram_ptr + s->cirrus_blt_dstaddr, 622 + (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
817 s->vram_ptr + s->cirrus_blt_srcaddr, 623 s->vram_ptr + s->cirrus_blt_srcaddr,
818 s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, 624 s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
819 s->cirrus_blt_width, s->cirrus_blt_height); 625 s->cirrus_blt_width, s->cirrus_blt_height);
@@ -829,130 +635,38 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) @@ -829,130 +635,38 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
829 * 635 *
830 ***************************************/ 636 ***************************************/
831 637
832 -static void cirrus_bitblt_cputovideo_patterncopy(void *opaque)  
833 -{  
834 - CirrusVGAState *s = (CirrusVGAState *) opaque;  
835 - int data_count;  
836 -  
837 - data_count = s->cirrus_srcptr - &s->cirrus_bltbuf[0];  
838 -  
839 - if (data_count > 0) {  
840 - if (data_count != s->cirrus_srccounter) {  
841 -#ifdef DEBUG_CIRRUS  
842 - printf("cirrus: internal error\n");  
843 -#endif  
844 - } else {  
845 - cirrus_bitblt_common_patterncopy(s, &s->cirrus_bltbuf[0]);  
846 - }  
847 - cirrus_bitblt_reset(s);  
848 - }  
849 -}  
850 -  
851 -static void cirrus_bitblt_cputovideo_copy(void *opaque)  
852 -{  
853 - CirrusVGAState *s = (CirrusVGAState *) opaque;  
854 - int data_count;  
855 - int data_avail;  
856 - uint8_t work_colorexp[256];  
857 - uint8_t *src_ptr = NULL;  
858 - int src_avail = 0;  
859 - int src_processing;  
860 - int src_linepad = 0;  
861 -  
862 - if (s->cirrus_blt_height <= 0) {  
863 - s->cirrus_srcptr = s->cirrus_srcptr_end;  
864 - return;  
865 - }  
866 -  
867 - s->cirrus_srcptr = &s->cirrus_bltbuf[0];  
868 - while (1) {  
869 - /* get BLT source. */  
870 - if (src_avail <= 0) {  
871 - data_count = s->cirrus_srcptr_end - s->cirrus_srcptr;  
872 - if (data_count <= 0)  
873 - break;  
874 -  
875 - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {  
876 - if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_COLOREXPAND) {  
877 -#ifdef DEBUG_CIRRUS  
878 - printf("cirrus: unsupported\n");  
879 -#endif  
880 - cirrus_bitblt_reset(s);  
881 - return;  
882 - }  
883 - data_avail = qemu_MIN(data_count, 256 / 32);  
884 - cirrus_colorexpand(s, work_colorexp, s->cirrus_srcptr,  
885 - data_avail * 8);  
886 - src_ptr = &work_colorexp[0];  
887 - src_avail = data_avail * 8 * s->cirrus_blt_pixelwidth;  
888 - s->cirrus_srcptr += data_avail;  
889 - src_linepad =  
890 - ((s->cirrus_blt_width + 7) / 8) * 8 -  
891 - s->cirrus_blt_width;  
892 - src_linepad *= s->cirrus_blt_pixelwidth;  
893 - } else {  
894 - if (s->cirrus_blt_mode != 0) {  
895 -#ifdef DEBUG_CIRRUS  
896 - printf("cirrus: unsupported\n");  
897 -#endif  
898 - cirrus_bitblt_reset(s);  
899 - return;  
900 - }  
901 - src_ptr = s->cirrus_srcptr;  
902 - src_avail =  
903 - data_count / s->cirrus_blt_pixelwidth *  
904 - s->cirrus_blt_pixelwidth;  
905 - s->cirrus_srcptr += src_avail;  
906 - }  
907 - if (src_avail <= 0)  
908 - break;  
909 - }  
910 -  
911 - /* 1-line BLT */  
912 - src_processing =  
913 - s->cirrus_blt_srcpitch - s->cirrus_blt_horz_counter;  
914 - src_processing = qemu_MIN(src_avail, src_processing);  
915 - (*s->cirrus_rop) (s->vram_ptr + s->cirrus_blt_dstaddr,  
916 - src_ptr, 0, 0, src_processing, 1);  
917 - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,  
918 - src_processing, 1);  
919 -  
920 - s->cirrus_blt_dstaddr += src_processing;  
921 - src_ptr += src_processing;  
922 - src_avail -= src_processing;  
923 - s->cirrus_blt_horz_counter += src_processing;  
924 - if (s->cirrus_blt_horz_counter >= s->cirrus_blt_srcpitch) {  
925 - src_ptr += src_linepad;  
926 - src_avail -= src_linepad;  
927 - s->cirrus_blt_dstaddr +=  
928 - s->cirrus_blt_dstpitch - s->cirrus_blt_srcpitch;  
929 - s->cirrus_blt_horz_counter = 0;  
930 - s->cirrus_blt_height--;  
931 - if (s->cirrus_blt_height <= 0) {  
932 - s->cirrus_srcptr = s->cirrus_srcptr_end;  
933 - return;  
934 - }  
935 - }  
936 - }  
937 -}  
938 -  
939 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) 638 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
940 { 639 {
941 int copy_count; 640 int copy_count;
942 - int avail_count;  
943 -  
944 - s->cirrus_blt_handler(s);  
945 - 641 + uint8_t *end_ptr;
  642 +
946 if (s->cirrus_srccounter > 0) { 643 if (s->cirrus_srccounter > 0) {
947 - s->cirrus_srccounter -= s->cirrus_srcptr - &s->cirrus_bltbuf[0];  
948 - copy_count = s->cirrus_srcptr_end - s->cirrus_srcptr;  
949 - memmove(&s->cirrus_bltbuf[0], s->cirrus_srcptr, copy_count);  
950 - avail_count = qemu_MIN(CIRRUS_BLTBUFSIZE, s->cirrus_srccounter);  
951 - s->cirrus_srcptr = &s->cirrus_bltbuf[0];  
952 - s->cirrus_srcptr_end = s->cirrus_srcptr + avail_count;  
953 - if (s->cirrus_srccounter <= 0) {  
954 - cirrus_bitblt_reset(s);  
955 - } 644 + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
  645 + cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
  646 + the_end:
  647 + s->cirrus_srccounter = 0;
  648 + cirrus_bitblt_reset(s);
  649 + } else {
  650 + /* at least one scan line */
  651 + do {
  652 + (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
  653 + s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
  654 + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
  655 + s->cirrus_blt_width, 1);
  656 + s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
  657 + s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
  658 + if (s->cirrus_srccounter <= 0)
  659 + goto the_end;
  660 + /* more bytes than needed can be transfered because of
  661 + word alignment, so we keep them for the next line */
  662 + /* XXX: keep alignment to speed up transfer */
  663 + end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  664 + copy_count = s->cirrus_srcptr_end - end_ptr;
  665 + memmove(s->cirrus_bltbuf, end_ptr, copy_count);
  666 + s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
  667 + s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  668 + } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
  669 + }
956 } 670 }
957 } 671 }
958 672
@@ -972,49 +686,44 @@ static void cirrus_bitblt_reset(CirrusVGAState * s) @@ -972,49 +686,44 @@ static void cirrus_bitblt_reset(CirrusVGAState * s)
972 s->cirrus_dstptr = &s->cirrus_bltbuf[0]; 686 s->cirrus_dstptr = &s->cirrus_bltbuf[0];
973 s->cirrus_dstptr_end = &s->cirrus_bltbuf[0]; 687 s->cirrus_dstptr_end = &s->cirrus_bltbuf[0];
974 s->cirrus_dstcounter = 0; 688 s->cirrus_dstcounter = 0;
975 - s->cirrus_blt_handler = NULL;  
976 } 689 }
977 690
978 static int cirrus_bitblt_cputovideo(CirrusVGAState * s) 691 static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
979 { 692 {
  693 + int w;
  694 +
980 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; 695 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
981 s->cirrus_srcptr = &s->cirrus_bltbuf[0]; 696 s->cirrus_srcptr = &s->cirrus_bltbuf[0];
982 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; 697 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
983 698
984 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 699 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
985 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 700 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
986 - s->cirrus_srccounter = 8; 701 + s->cirrus_blt_srcpitch = 8;
987 } else { 702 } else {
988 - s->cirrus_srccounter = 8 * 8 * s->cirrus_blt_pixelwidth; 703 + s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
989 } 704 }
990 - s->cirrus_blt_srcpitch = 0;  
991 - s->cirrus_blt_handler = cirrus_bitblt_cputovideo_patterncopy; 705 + s->cirrus_srccounter = s->cirrus_blt_srcpitch;
992 } else { 706 } else {
993 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 707 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
994 - s->cirrus_srccounter =  
995 - ((s->cirrus_blt_width + 7) / 8) * s->cirrus_blt_height;  
996 - s->cirrus_blt_srcpitch =  
997 - s->cirrus_blt_width * s->cirrus_blt_pixelwidth; 708 + w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
  709 + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
  710 + s->cirrus_blt_srcpitch = ((w + 31) >> 5);
  711 + else
  712 + s->cirrus_blt_srcpitch = ((w + 7) >> 3);
998 } else { 713 } else {
999 - s->cirrus_srccounter =  
1000 - s->cirrus_blt_width * s->cirrus_blt_height;  
1001 s->cirrus_blt_srcpitch = s->cirrus_blt_width; 714 s->cirrus_blt_srcpitch = s->cirrus_blt_width;
1002 } 715 }
1003 - /* 4-byte alignment */  
1004 - s->cirrus_srccounter = (s->cirrus_srccounter + 3) & (~3);  
1005 -  
1006 - s->cirrus_blt_handler = cirrus_bitblt_cputovideo_copy;  
1007 - s->cirrus_blt_horz_counter = 0; 716 + s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
1008 } 717 }
1009 -  
1010 - cirrus_bitblt_cputovideo_next(s); 718 + s->cirrus_srcptr = s->cirrus_bltbuf;
  719 + s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
1011 return 1; 720 return 1;
1012 } 721 }
1013 722
1014 static int cirrus_bitblt_videotocpu(CirrusVGAState * s) 723 static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
1015 { 724 {
1016 /* XXX */ 725 /* XXX */
1017 -#ifdef DEBUG_CIRRUS 726 +#ifdef DEBUG_BITBLT
1018 printf("cirrus: bitblt (video to cpu) is not implemented yet\n"); 727 printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
1019 #endif 728 #endif
1020 return 0; 729 return 0;
@@ -1029,7 +738,6 @@ static int cirrus_bitblt_videotovideo(CirrusVGAState * s) @@ -1029,7 +738,6 @@ static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
1029 } else { 738 } else {
1030 ret = cirrus_bitblt_videotovideo_copy(s); 739 ret = cirrus_bitblt_videotovideo_copy(s);
1031 } 740 }
1032 -  
1033 if (ret) 741 if (ret)
1034 cirrus_bitblt_reset(s); 742 cirrus_bitblt_reset(s);
1035 return ret; 743 return ret;
@@ -1039,6 +747,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) @@ -1039,6 +747,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1039 { 747 {
1040 uint8_t blt_rop; 748 uint8_t blt_rop;
1041 749
  750 + s->gr[0x31] |= CIRRUS_BLT_BUSY;
  751 +
1042 s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1; 752 s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
1043 s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1; 753 s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
1044 s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8)); 754 s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
@@ -1048,19 +758,21 @@ static void cirrus_bitblt_start(CirrusVGAState * s) @@ -1048,19 +758,21 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1048 s->cirrus_blt_srcaddr = 758 s->cirrus_blt_srcaddr =
1049 (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16)); 759 (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
1050 s->cirrus_blt_mode = s->gr[0x30]; 760 s->cirrus_blt_mode = s->gr[0x30];
  761 + s->cirrus_blt_modeext = s->gr[0x33];
1051 blt_rop = s->gr[0x32]; 762 blt_rop = s->gr[0x32];
1052 763
1053 #ifdef DEBUG_BITBLT 764 #ifdef DEBUG_BITBLT
1054 - printf("rop=%02x mode=%02x modeext=%02x w=%d h=%d dpitch=%d spicth=%d daddr=%08x saddr=%08x\n", 765 + printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spicth=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
1055 blt_rop, 766 blt_rop,
1056 s->cirrus_blt_mode, 767 s->cirrus_blt_mode,
1057 - s->gr[0x33], 768 + s->cirrus_blt_modeext,
1058 s->cirrus_blt_width, 769 s->cirrus_blt_width,
1059 s->cirrus_blt_height, 770 s->cirrus_blt_height,
1060 s->cirrus_blt_dstpitch, 771 s->cirrus_blt_dstpitch,
1061 s->cirrus_blt_srcpitch, 772 s->cirrus_blt_srcpitch,
1062 s->cirrus_blt_dstaddr, 773 s->cirrus_blt_dstaddr,
1063 - s->cirrus_blt_srcaddr); 774 + s->cirrus_blt_srcaddr,
  775 + s->sr[0x2f]);
1064 #endif 776 #endif
1065 777
1066 switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { 778 switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
@@ -1077,7 +789,7 @@ static void cirrus_bitblt_start(CirrusVGAState * s) @@ -1077,7 +789,7 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1077 s->cirrus_blt_pixelwidth = 4; 789 s->cirrus_blt_pixelwidth = 4;
1078 break; 790 break;
1079 default: 791 default:
1080 -#ifdef DEBUG_CIRRUS 792 +#ifdef DEBUG_BITBLT
1081 printf("cirrus: bitblt - pixel width is unknown\n"); 793 printf("cirrus: bitblt - pixel width is unknown\n");
1082 #endif 794 #endif
1083 goto bitblt_ignore; 795 goto bitblt_ignore;
@@ -1088,26 +800,41 @@ static void cirrus_bitblt_start(CirrusVGAState * s) @@ -1088,26 +800,41 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1088 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | 800 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
1089 CIRRUS_BLTMODE_MEMSYSDEST)) 801 CIRRUS_BLTMODE_MEMSYSDEST))
1090 == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { 802 == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
1091 -#ifdef DEBUG_CIRRUS 803 +#ifdef DEBUG_BITBLT
1092 printf("cirrus: bitblt - memory-to-memory copy is requested\n"); 804 printf("cirrus: bitblt - memory-to-memory copy is requested\n");
1093 #endif 805 #endif
1094 goto bitblt_ignore; 806 goto bitblt_ignore;
1095 } 807 }
1096 808
1097 - if ((s->gr[0x33] & CIRRUS_BLTMODEEXT_SOLIDFILL) && 809 + if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
1098 (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST | 810 (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
1099 CIRRUS_BLTMODE_TRANSPARENTCOMP | 811 CIRRUS_BLTMODE_TRANSPARENTCOMP |
1100 CIRRUS_BLTMODE_PATTERNCOPY | 812 CIRRUS_BLTMODE_PATTERNCOPY |
1101 CIRRUS_BLTMODE_COLOREXPAND)) == 813 CIRRUS_BLTMODE_COLOREXPAND)) ==
1102 (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) { 814 (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
1103 - cirrus_bitblt_solidfill(s); 815 + cirrus_bitblt_fgcol(s);
  816 + cirrus_bitblt_solidfill(s, blt_rop);
1104 } else { 817 } else {
1105 - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {  
1106 - s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;  
1107 - s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;  
1108 - s->cirrus_rop = cirrus_get_bkwd_rop_handler(blt_rop); 818 + if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
  819 + CIRRUS_BLTMODE_PATTERNCOPY)) ==
  820 + CIRRUS_BLTMODE_COLOREXPAND) {
  821 +
  822 + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
  823 + cirrus_bitblt_fgcol(s);
  824 + s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  825 + } else {
  826 + cirrus_bitblt_fgcol(s);
  827 + cirrus_bitblt_bgcol(s);
  828 + s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  829 + }
1109 } else { 830 } else {
1110 - s->cirrus_rop = cirrus_get_fwd_rop_handler(blt_rop); 831 + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
  832 + s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
  833 + s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
  834 + s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
  835 + } else {
  836 + s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
  837 + }
1111 } 838 }
1112 839
1113 // setup bitblt engine. 840 // setup bitblt engine.
@@ -1139,7 +866,6 @@ static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value) @@ -1139,7 +866,6 @@ static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1139 cirrus_bitblt_reset(s); 866 cirrus_bitblt_reset(s);
1140 } else if (((old_value & CIRRUS_BLT_START) == 0) && 867 } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1141 ((reg_value & CIRRUS_BLT_START) != 0)) { 868 ((reg_value & CIRRUS_BLT_START) != 0)) {
1142 - s->gr[0x31] |= CIRRUS_BLT_BUSY;  
1143 cirrus_bitblt_start(s); 869 cirrus_bitblt_start(s);
1144 } 870 }
1145 } 871 }
@@ -1312,6 +1038,7 @@ cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value) @@ -1312,6 +1038,7 @@ cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1312 case 0x91: 1038 case 0x91:
1313 case 0xb1: 1039 case 0xb1:
1314 case 0xd1: 1040 case 0xd1:
  1041 + case 0xf1: // Graphics Cursor Y
1315 *reg_value = s->sr[0x11]; 1042 *reg_value = s->sr[0x11];
1316 break; 1043 break;
1317 case 0x05: // ??? 1044 case 0x05: // ???
@@ -1324,7 +1051,6 @@ cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value) @@ -1324,7 +1051,6 @@ cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1324 case 0x0d: // VCLK 2 1051 case 0x0d: // VCLK 2
1325 case 0x0e: // VCLK 3 1052 case 0x0e: // VCLK 3
1326 case 0x0f: // DRAM Control 1053 case 0x0f: // DRAM Control
1327 - case 0xf1: // Graphics Cursor Y  
1328 case 0x12: // Graphics Cursor Attribute 1054 case 0x12: // Graphics Cursor Attribute
1329 case 0x13: // Graphics Cursor Pattern Address 1055 case 0x13: // Graphics Cursor Pattern Address
1330 case 0x14: // Scratch Register 2 1056 case 0x14: // Scratch Register 2
@@ -1382,7 +1108,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) @@ -1382,7 +1108,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1382 case 0xd0: 1108 case 0xd0:
1383 case 0xf0: // Graphics Cursor X 1109 case 0xf0: // Graphics Cursor X
1384 s->sr[0x10] = reg_value; 1110 s->sr[0x10] = reg_value;
1385 - s->cirrus_hw_cursor_x = ((reg_index << 3) & 0x700) | reg_value; 1111 + s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);
1386 break; 1112 break;
1387 case 0x11: 1113 case 0x11:
1388 case 0x31: 1114 case 0x31:
@@ -1393,7 +1119,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) @@ -1393,7 +1119,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1393 case 0xd1: 1119 case 0xd1:
1394 case 0xf1: // Graphics Cursor Y 1120 case 0xf1: // Graphics Cursor Y
1395 s->sr[0x11] = reg_value; 1121 s->sr[0x11] = reg_value;
1396 - s->cirrus_hw_cursor_y = ((reg_index << 3) & 0x700) | reg_value; 1122 + s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
1397 break; 1123 break;
1398 case 0x07: // Extended Sequencer Mode 1124 case 0x07: // Extended Sequencer Mode
1399 case 0x08: // EEPROM Control 1125 case 0x08: // EEPROM Control
@@ -1471,13 +1197,9 @@ static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value) @@ -1471,13 +1197,9 @@ static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
1471 { 1197 {
1472 if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) 1198 if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1473 return CIRRUS_HOOK_NOT_HANDLED; 1199 return CIRRUS_HOOK_NOT_HANDLED;
1474 - if (s->dac_read_index < 0x10) {  
1475 - *reg_value =  
1476 - s->cirrus_hidden_palette[s->dac_read_index * 3 +  
1477 - s->dac_sub_index];  
1478 - } else {  
1479 - *reg_value = 0xff; /* XXX */  
1480 - } 1200 + *reg_value =
  1201 + s->cirrus_hidden_palette[(s->dac_read_index & 0x0f) * 3 +
  1202 + s->dac_sub_index];
1481 if (++s->dac_sub_index == 3) { 1203 if (++s->dac_sub_index == 3) {
1482 s->dac_sub_index = 0; 1204 s->dac_sub_index = 0;
1483 s->dac_read_index++; 1205 s->dac_read_index++;
@@ -1491,11 +1213,9 @@ static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value) @@ -1491,11 +1213,9 @@ static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
1491 return CIRRUS_HOOK_NOT_HANDLED; 1213 return CIRRUS_HOOK_NOT_HANDLED;
1492 s->dac_cache[s->dac_sub_index] = reg_value; 1214 s->dac_cache[s->dac_sub_index] = reg_value;
1493 if (++s->dac_sub_index == 3) { 1215 if (++s->dac_sub_index == 3) {
1494 - if (s->dac_read_index < 0x10) {  
1495 - memcpy(&s->cirrus_hidden_palette[s->dac_write_index * 3],  
1496 - s->dac_cache, 3);  
1497 - /* XXX update cursor */  
1498 - } 1216 + memcpy(&s->cirrus_hidden_palette[(s->dac_write_index & 0x0f) * 3],
  1217 + s->dac_cache, 3);
  1218 + /* XXX update cursor */
1499 s->dac_sub_index = 0; 1219 s->dac_sub_index = 0;
1500 s->dac_write_index++; 1220 s->dac_write_index++;
1501 } 1221 }
@@ -1545,6 +1265,9 @@ cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value) @@ -1545,6 +1265,9 @@ cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1545 static int 1265 static int
1546 cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) 1266 cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1547 { 1267 {
  1268 +#if defined(DEBUG_BITBLT) && 0
  1269 + printf("gr%02x: %02x\n", reg_index, reg_value);
  1270 +#endif
1548 switch (reg_index) { 1271 switch (reg_index) {
1549 case 0x00: // Standard VGA, BGCOLOR 0x000000ff 1272 case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1550 s->cirrus_shadow_gr0 = reg_value; 1273 s->cirrus_shadow_gr0 = reg_value;
@@ -1583,6 +1306,7 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) @@ -1583,6 +1306,7 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1583 case 0x29: // BLT DEST ADDR 0x00ff00 1306 case 0x29: // BLT DEST ADDR 0x00ff00
1584 case 0x2c: // BLT SRC ADDR 0x0000ff 1307 case 0x2c: // BLT SRC ADDR 0x0000ff
1585 case 0x2d: // BLT SRC ADDR 0x00ff00 1308 case 0x2d: // BLT SRC ADDR 0x00ff00
  1309 + case 0x2f: // BLT WRITEMASK
1586 case 0x30: // BLT MODE 1310 case 0x30: // BLT MODE
1587 case 0x32: // RASTER OP 1311 case 0x32: // RASTER OP
1588 case 0x33: // BLT MODEEXT 1312 case 0x33: // BLT MODEEXT
@@ -1599,6 +1323,12 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) @@ -1599,6 +1323,12 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1599 s->gr[reg_index] = reg_value & 0x1f; 1323 s->gr[reg_index] = reg_value & 0x1f;
1600 break; 1324 break;
1601 case 0x2a: // BLT DEST ADDR 0x3f0000 1325 case 0x2a: // BLT DEST ADDR 0x3f0000
  1326 + s->gr[reg_index] = reg_value & 0x3f;
  1327 + /* if auto start mode, starts bit blt now */
  1328 + if (s->gr[0x31] & CIRRUS_BLT_AUTOSTART) {
  1329 + cirrus_bitblt_start(s);
  1330 + }
  1331 + break;
1602 case 0x2e: // BLT SRC ADDR 0x3f0000 1332 case 0x2e: // BLT SRC ADDR 0x3f0000
1603 s->gr[reg_index] = reg_value & 0x3f; 1333 s->gr[reg_index] = reg_value & 0x3f;
1604 break; 1334 break;
@@ -2111,7 +1841,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, @@ -2111,7 +1841,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
2111 if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 1841 if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2112 /* bitblt */ 1842 /* bitblt */
2113 *s->cirrus_srcptr++ = (uint8_t) mem_value; 1843 *s->cirrus_srcptr++ = (uint8_t) mem_value;
2114 - if (s->cirrus_srcptr == s->cirrus_srcptr_end) { 1844 + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2115 cirrus_bitblt_cputovideo_next(s); 1845 cirrus_bitblt_cputovideo_next(s);
2116 } 1846 }
2117 } else { 1847 } else {
@@ -2196,6 +1926,176 @@ static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = { @@ -2196,6 +1926,176 @@ static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
2196 1926
2197 /*************************************** 1927 /***************************************
2198 * 1928 *
  1929 + * hardware cursor
  1930 + *
  1931 + ***************************************/
  1932 +
  1933 +static inline void invalidate_cursor1(CirrusVGAState *s)
  1934 +{
  1935 + if (s->last_hw_cursor_size) {
  1936 + vga_invalidate_scanlines((VGAState *)s,
  1937 + s->last_hw_cursor_y + s->last_hw_cursor_y_start,
  1938 + s->last_hw_cursor_y + s->last_hw_cursor_y_end);
  1939 + }
  1940 +}
  1941 +
  1942 +static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
  1943 +{
  1944 + const uint8_t *src;
  1945 + uint32_t content;
  1946 + int y, y_min, y_max;
  1947 +
  1948 + src = s->vram_ptr + 0x200000 - 16 * 1024;
  1949 + if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
  1950 + src += (s->sr[0x13] & 0x3c) * 256;
  1951 + y_min = 64;
  1952 + y_max = -1;
  1953 + for(y = 0; y < 64; y++) {
  1954 + content = ((uint32_t *)src)[0] |
  1955 + ((uint32_t *)src)[1] |
  1956 + ((uint32_t *)src)[2] |
  1957 + ((uint32_t *)src)[3];
  1958 + if (content) {
  1959 + if (y < y_min)
  1960 + y_min = y;
  1961 + if (y > y_max)
  1962 + y_max = y;
  1963 + }
  1964 + src += 16;
  1965 + }
  1966 + } else {
  1967 + src += (s->sr[0x13] & 0x3f) * 256;
  1968 + y_min = 32;
  1969 + y_max = -1;
  1970 + for(y = 0; y < 32; y++) {
  1971 + content = ((uint32_t *)src)[0] |
  1972 + ((uint32_t *)(src + 128))[0];
  1973 + if (content) {
  1974 + if (y < y_min)
  1975 + y_min = y;
  1976 + if (y > y_max)
  1977 + y_max = y;
  1978 + }
  1979 + src += 4;
  1980 + }
  1981 + }
  1982 + if (y_min > y_max) {
  1983 + s->last_hw_cursor_y_start = 0;
  1984 + s->last_hw_cursor_y_end = 0;
  1985 + } else {
  1986 + s->last_hw_cursor_y_start = y_min;
  1987 + s->last_hw_cursor_y_end = y_max + 1;
  1988 + }
  1989 +}
  1990 +
  1991 +/* NOTE: we do not currently handle the cursor bitmap change, so we
  1992 + update the cursor only if it moves. */
  1993 +static void cirrus_cursor_invalidate(VGAState *s1)
  1994 +{
  1995 + CirrusVGAState *s = (CirrusVGAState *)s1;
  1996 + int size;
  1997 +
  1998 + if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) {
  1999 + size = 0;
  2000 + } else {
  2001 + if (s->sr[0x12] & CIRRUS_CURSOR_LARGE)
  2002 + size = 64;
  2003 + else
  2004 + size = 32;
  2005 + }
  2006 + /* invalidate last cursor and new cursor if any change */
  2007 + if (s->last_hw_cursor_size != size ||
  2008 + s->last_hw_cursor_x != s->hw_cursor_x ||
  2009 + s->last_hw_cursor_y != s->hw_cursor_y) {
  2010 +
  2011 + invalidate_cursor1(s);
  2012 +
  2013 + s->last_hw_cursor_size = size;
  2014 + s->last_hw_cursor_x = s->hw_cursor_x;
  2015 + s->last_hw_cursor_y = s->hw_cursor_y;
  2016 + /* compute the real cursor min and max y */
  2017 + cirrus_cursor_compute_yrange(s);
  2018 + invalidate_cursor1(s);
  2019 + }
  2020 +}
  2021 +
  2022 +static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
  2023 +{
  2024 + CirrusVGAState *s = (CirrusVGAState *)s1;
  2025 + int w, h, bpp, x1, x2, poffset;
  2026 + unsigned int color0, color1;
  2027 + const uint8_t *palette, *src;
  2028 + uint32_t content;
  2029 +
  2030 + if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
  2031 + return;
  2032 + /* fast test to see if the cursor intersects with the scan line */
  2033 + if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
  2034 + h = 64;
  2035 + } else {
  2036 + h = 32;
  2037 + }
  2038 + if (scr_y < s->hw_cursor_y ||
  2039 + scr_y >= (s->hw_cursor_y + h))
  2040 + return;
  2041 +
  2042 + src = s->vram_ptr + 0x200000 - 16 * 1024;
  2043 + if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
  2044 + src += (s->sr[0x13] & 0x3c) * 256;
  2045 + src += (scr_y - s->hw_cursor_y) * 16;
  2046 + poffset = 8;
  2047 + content = ((uint32_t *)src)[0] |
  2048 + ((uint32_t *)src)[1] |
  2049 + ((uint32_t *)src)[2] |
  2050 + ((uint32_t *)src)[3];
  2051 + } else {
  2052 + src += (s->sr[0x13] & 0x3f) * 256;
  2053 + src += (scr_y - s->hw_cursor_y) * 4;
  2054 + poffset = 128;
  2055 + content = ((uint32_t *)src)[0] |
  2056 + ((uint32_t *)(src + 128))[0];
  2057 + }
  2058 + /* if nothing to draw, no need to continue */
  2059 + if (!content)
  2060 + return;
  2061 + w = h;
  2062 +
  2063 + x1 = s->hw_cursor_x;
  2064 + if (x1 >= s->last_scr_width)
  2065 + return;
  2066 + x2 = s->hw_cursor_x + w;
  2067 + if (x2 > s->last_scr_width)
  2068 + x2 = s->last_scr_width;
  2069 + w = x2 - x1;
  2070 + palette = s->cirrus_hidden_palette;
  2071 + color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
  2072 + c6_to_8(palette[0x0 * 3 + 1]),
  2073 + c6_to_8(palette[0x0 * 3 + 2]));
  2074 + color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
  2075 + c6_to_8(palette[0xf * 3 + 1]),
  2076 + c6_to_8(palette[0xf * 3 + 2]));
  2077 + bpp = ((s->ds->depth + 7) >> 3);
  2078 + d1 += x1 * bpp;
  2079 + switch(s->ds->depth) {
  2080 + default:
  2081 + break;
  2082 + case 8:
  2083 + vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
  2084 + break;
  2085 + case 15:
  2086 + vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
  2087 + break;
  2088 + case 16:
  2089 + vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
  2090 + break;
  2091 + case 32:
  2092 + vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
  2093 + break;
  2094 + }
  2095 +}
  2096 +
  2097 +/***************************************
  2098 + *
2199 * LFB memory access 2099 * LFB memory access
2200 * 2100 *
2201 ***************************************/ 2101 ***************************************/
@@ -2272,7 +2172,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, @@ -2272,7 +2172,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
2272 } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 2172 } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2273 /* bitblt */ 2173 /* bitblt */
2274 *s->cirrus_srcptr++ = (uint8_t) val; 2174 *s->cirrus_srcptr++ = (uint8_t) val;
2275 - if (s->cirrus_srcptr == s->cirrus_srcptr_end) { 2175 + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
2276 cirrus_bitblt_cputovideo_next(s); 2176 cirrus_bitblt_cputovideo_next(s);
2277 } 2177 }
2278 } else { 2178 } else {
@@ -2339,6 +2239,107 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = { @@ -2339,6 +2239,107 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
2339 cirrus_linear_writel, 2239 cirrus_linear_writel,
2340 }; 2240 };
2341 2241
  2242 +/***************************************
  2243 + *
  2244 + * system to screen memory access
  2245 + *
  2246 + ***************************************/
  2247 +
  2248 +
  2249 +static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
  2250 +{
  2251 + uint32_t ret;
  2252 +
  2253 + /* XXX handle bitblt */
  2254 + ret = 0xff;
  2255 + return ret;
  2256 +}
  2257 +
  2258 +static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
  2259 +{
  2260 + uint32_t v;
  2261 +#ifdef TARGET_WORDS_BIGENDIAN
  2262 + v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
  2263 + v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
  2264 +#else
  2265 + v = cirrus_linear_bitblt_readb(opaque, addr);
  2266 + v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
  2267 +#endif
  2268 + return v;
  2269 +}
  2270 +
  2271 +static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
  2272 +{
  2273 + uint32_t v;
  2274 +#ifdef TARGET_WORDS_BIGENDIAN
  2275 + v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
  2276 + v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
  2277 + v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
  2278 + v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
  2279 +#else
  2280 + v = cirrus_linear_bitblt_readb(opaque, addr);
  2281 + v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
  2282 + v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
  2283 + v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
  2284 +#endif
  2285 + return v;
  2286 +}
  2287 +
  2288 +static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
  2289 + uint32_t val)
  2290 +{
  2291 + CirrusVGAState *s = (CirrusVGAState *) opaque;
  2292 +
  2293 + if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
  2294 + /* bitblt */
  2295 + *s->cirrus_srcptr++ = (uint8_t) val;
  2296 + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
  2297 + cirrus_bitblt_cputovideo_next(s);
  2298 + }
  2299 + }
  2300 +}
  2301 +
  2302 +static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
  2303 + uint32_t val)
  2304 +{
  2305 +#ifdef TARGET_WORDS_BIGENDIAN
  2306 + cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
  2307 + cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
  2308 +#else
  2309 + cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
  2310 + cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  2311 +#endif
  2312 +}
  2313 +
  2314 +static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
  2315 + uint32_t val)
  2316 +{
  2317 +#ifdef TARGET_WORDS_BIGENDIAN
  2318 + cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
  2319 + cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
  2320 + cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
  2321 + cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
  2322 +#else
  2323 + cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
  2324 + cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  2325 + cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
  2326 + cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
  2327 +#endif
  2328 +}
  2329 +
  2330 +
  2331 +static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = {
  2332 + cirrus_linear_bitblt_readb,
  2333 + cirrus_linear_bitblt_readw,
  2334 + cirrus_linear_bitblt_readl,
  2335 +};
  2336 +
  2337 +static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
  2338 + cirrus_linear_bitblt_writeb,
  2339 + cirrus_linear_bitblt_writew,
  2340 + cirrus_linear_bitblt_writel,
  2341 +};
  2342 +
2342 /* I/O ports */ 2343 /* I/O ports */
2343 2344
2344 static uint32_t vga_ioport_read(void *opaque, uint32_t addr) 2345 static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
@@ -2691,7 +2692,30 @@ static CPUWriteMemoryFunc *cirrus_mmio_write[3] = { @@ -2691,7 +2692,30 @@ static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
2691 2692
2692 static void cirrus_init_common(CirrusVGAState * s, int device_id) 2693 static void cirrus_init_common(CirrusVGAState * s, int device_id)
2693 { 2694 {
2694 - int vga_io_memory; 2695 + int vga_io_memory, i;
  2696 + static int inited;
  2697 +
  2698 + if (!inited) {
  2699 + inited = 1;
  2700 + for(i = 0;i < 256; i++)
  2701 + rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
  2702 + rop_to_index[CIRRUS_ROP_0] = 0;
  2703 + rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
  2704 + rop_to_index[CIRRUS_ROP_NOP] = 2;
  2705 + rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
  2706 + rop_to_index[CIRRUS_ROP_NOTDST] = 4;
  2707 + rop_to_index[CIRRUS_ROP_SRC] = 5;
  2708 + rop_to_index[CIRRUS_ROP_1] = 6;
  2709 + rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
  2710 + rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
  2711 + rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
  2712 + rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
  2713 + rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
  2714 + rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
  2715 + rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
  2716 + rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
  2717 + rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
  2718 + }
2695 2719
2696 register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); 2720 register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
2697 2721
@@ -2725,6 +2749,11 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) @@ -2725,6 +2749,11 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id)
2725 s->cirrus_linear_io_addr = 2749 s->cirrus_linear_io_addr =
2726 cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, 2750 cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
2727 s); 2751 s);
  2752 + /* I/O handler for LFB */
  2753 + s->cirrus_linear_bitblt_io_addr =
  2754 + cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
  2755 + s);
  2756 +
2728 /* I/O handler for memory-mapped I/O */ 2757 /* I/O handler for memory-mapped I/O */
2729 s->cirrus_mmio_io_addr = 2758 s->cirrus_mmio_io_addr =
2730 cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s); 2759 cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
@@ -2734,6 +2763,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) @@ -2734,6 +2763,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id)
2734 2763
2735 s->get_bpp = cirrus_get_bpp; 2764 s->get_bpp = cirrus_get_bpp;
2736 s->get_offsets = cirrus_get_offsets; 2765 s->get_offsets = cirrus_get_offsets;
  2766 + s->cursor_invalidate = cirrus_cursor_invalidate;
  2767 + s->cursor_draw_line = cirrus_cursor_draw_line;
2737 } 2768 }
2738 2769
2739 /*************************************** 2770 /***************************************
@@ -2767,8 +2798,11 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, @@ -2767,8 +2798,11 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
2767 { 2798 {
2768 CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga; 2799 CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
2769 2800
  2801 + /* XXX: add byte swapping apertures */
2770 cpu_register_physical_memory(addr, s->vram_size, 2802 cpu_register_physical_memory(addr, s->vram_size,
2771 s->cirrus_linear_io_addr); 2803 s->cirrus_linear_io_addr);
  2804 + cpu_register_physical_memory(addr + 0x1000000, 0x400000,
  2805 + s->cirrus_linear_bitblt_io_addr);
2772 } 2806 }
2773 2807
2774 static void cirrus_pci_mmio_map(PCIDevice *d, int region_num, 2808 static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
@@ -2815,7 +2849,7 @@ void pci_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, @@ -2815,7 +2849,7 @@ void pci_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
2815 /* memory #0 LFB */ 2849 /* memory #0 LFB */
2816 /* memory #1 memory-mapped I/O */ 2850 /* memory #1 memory-mapped I/O */
2817 /* XXX: s->vram_size must be a power of two */ 2851 /* XXX: s->vram_size must be a power of two */
2818 - pci_register_io_region((PCIDevice *)d, 0, s->vram_size, 2852 + pci_register_io_region((PCIDevice *)d, 0, 0x2000000,
2819 PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map); 2853 PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
2820 if (device_id == CIRRUS_ID_CLGD5446) { 2854 if (device_id == CIRRUS_ID_CLGD5446) {
2821 pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, 2855 pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
hw/cirrus_vga_rop.h 0 → 100644
  1 +/*
  2 + * QEMU Cirrus CLGD 54xx VGA Emulator.
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +static void
  26 +glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
  27 + uint8_t *dst,const uint8_t *src,
  28 + int dstpitch,int srcpitch,
  29 + int bltwidth,int bltheight)
  30 +{
  31 + int x,y;
  32 + dstpitch -= bltwidth;
  33 + srcpitch -= bltwidth;
  34 + for (y = 0; y < bltheight; y++) {
  35 + for (x = 0; x < bltwidth; x++) {
  36 + ROP_OP(*dst, *src);
  37 + dst++;
  38 + src++;
  39 + }
  40 + dst += dstpitch;
  41 + src += srcpitch;
  42 + }
  43 +}
  44 +
  45 +static void
  46 +glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
  47 + uint8_t *dst,const uint8_t *src,
  48 + int dstpitch,int srcpitch,
  49 + int bltwidth,int bltheight)
  50 +{
  51 + int x,y;
  52 + dstpitch += bltwidth;
  53 + srcpitch += bltwidth;
  54 + for (y = 0; y < bltheight; y++) {
  55 + for (x = 0; x < bltwidth; x++) {
  56 + ROP_OP(*dst, *src);
  57 + dst--;
  58 + src--;
  59 + }
  60 + dst += dstpitch;
  61 + src += srcpitch;
  62 + }
  63 +}
  64 +
  65 +#define DEPTH 8
  66 +#include "cirrus_vga_rop2.h"
  67 +
  68 +#define DEPTH 16
  69 +#include "cirrus_vga_rop2.h"
  70 +
  71 +#define DEPTH 24
  72 +#include "cirrus_vga_rop2.h"
  73 +
  74 +#define DEPTH 32
  75 +#include "cirrus_vga_rop2.h"
  76 +
  77 +#undef ROP_NAME
  78 +#undef ROP_OP
hw/cirrus_vga_rop2.h 0 → 100644
  1 +/*
  2 + * QEMU Cirrus CLGD 54xx VGA Emulator.
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#if DEPTH == 8
  26 +#define PUTPIXEL() ROP_OP(d[0], col)
  27 +#elif DEPTH == 16
  28 +#define PUTPIXEL() ROP_OP(((uint16_t *)d)[0], col);
  29 +#elif DEPTH == 24
  30 +#define PUTPIXEL() ROP_OP(d[0], col); \
  31 + ROP_OP(d[1], (col >> 8)); \
  32 + ROP_OP(d[2], (col >> 16))
  33 +#elif DEPTH == 32
  34 +#define PUTPIXEL() ROP_OP(((uint32_t *)d)[0], col)
  35 +#else
  36 +#error unsupported DEPTH
  37 +#endif
  38 +
  39 +static void
  40 +glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
  41 + (CirrusVGAState * s, uint8_t * dst,
  42 + const uint8_t * src1,
  43 + int dstpitch, int srcpitch,
  44 + int bltwidth, int bltheight)
  45 +{
  46 + const uint8_t *src;
  47 + uint8_t *d;
  48 + int x, y;
  49 + unsigned bits;
  50 + unsigned int col;
  51 + unsigned bitmask;
  52 + unsigned index;
  53 + int srcskipleft = 0;
  54 +
  55 + col = s->cirrus_blt_fgcol;
  56 + for(y = 0; y < bltheight; y++) {
  57 + src = src1;
  58 + bitmask = 0x80 >> srcskipleft;
  59 + bits = *src++;
  60 + d = dst;
  61 + for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
  62 + if ((bitmask & 0xff) == 0) {
  63 + bitmask = 0x80;
  64 + bits = *src++;
  65 + }
  66 + index = (bits & bitmask);
  67 + if (index) {
  68 + PUTPIXEL();
  69 + }
  70 + d += (DEPTH / 8);
  71 + bitmask >>= 1;
  72 + }
  73 + src1 += srcpitch;
  74 + dst += dstpitch;
  75 + }
  76 +}
  77 +
  78 +static void
  79 +glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
  80 + (CirrusVGAState * s, uint8_t * dst,
  81 + const uint8_t * src1,
  82 + int dstpitch, int srcpitch,
  83 + int bltwidth, int bltheight)
  84 +{
  85 + const uint8_t *src;
  86 + uint32_t colors[2];
  87 + uint8_t *d;
  88 + int x, y;
  89 + unsigned bits;
  90 + unsigned int col;
  91 + unsigned bitmask;
  92 + int srcskipleft = 0;
  93 +
  94 + colors[0] = s->cirrus_blt_bgcol;
  95 + colors[1] = s->cirrus_blt_fgcol;
  96 + for(y = 0; y < bltheight; y++) {
  97 + src = src1;
  98 + bitmask = 0x80 >> srcskipleft;
  99 + bits = *src++;
  100 + d = dst;
  101 + for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
  102 + if ((bitmask & 0xff) == 0) {
  103 + bitmask = 0x80;
  104 + bits = *src++;
  105 + }
  106 + col = colors[!!(bits & bitmask)];
  107 + PUTPIXEL();
  108 + d += (DEPTH / 8);
  109 + bitmask >>= 1;
  110 + }
  111 + src1 += srcpitch;
  112 + dst += dstpitch;
  113 + }
  114 +}
  115 +
  116 +static void
  117 +glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
  118 + (CirrusVGAState *s,
  119 + uint8_t *dst, int dst_pitch,
  120 + int width, int height)
  121 +{
  122 + uint8_t *d, *d1;
  123 + uint32_t col;
  124 + int x, y;
  125 +
  126 + col = s->cirrus_blt_fgcol;
  127 +
  128 + d1 = dst;
  129 + for(y = 0; y < height; y++) {
  130 + d = d1;
  131 + for(x = 0; x < width; x += (DEPTH / 8)) {
  132 + PUTPIXEL();
  133 + d += (DEPTH / 8);
  134 + }
  135 + d1 += dst_pitch;
  136 + }
  137 +}
  138 +
  139 +#undef DEPTH
  140 +#undef PUTPIXEL