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 29 #include "vl.h"
30 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 40 //#define DEBUG_CIRRUS
33 41 //#define DEBUG_BITBLT
34 42  
... ... @@ -103,6 +111,7 @@
103 111 #define CIRRUS_BLT_START 0x02
104 112 #define CIRRUS_BLT_RESET 0x04
105 113 #define CIRRUS_BLT_FIFOUSED 0x10
  114 +#define CIRRUS_BLT_AUTOSTART 0x80
106 115  
107 116 // control 0x32
108 117 #define CIRRUS_ROP_0 0x00
... ... @@ -122,8 +131,12 @@
122 131 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
123 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 137 // control 0x33
126   -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
  138 +#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
  139 +#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
127 140  
128 141 // memory-mapped IO
129 142 #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
... ... @@ -204,16 +217,19 @@
204 217 #define CIRRUS_HOOK_NOT_HANDLED 0
205 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 223 int dstpitch, int srcpitch,
209 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 228 typedef struct CirrusVGAState {
214 229 VGA_STATE_COMMON
215 230  
216 231 int cirrus_linear_io_addr;
  232 + int cirrus_linear_bitblt_io_addr;
217 233 int cirrus_mmio_io_addr;
218 234 uint32_t cirrus_addr_mask;
219 235 uint8_t cirrus_shadow_gr0;
... ... @@ -223,18 +239,21 @@ typedef struct CirrusVGAState {
223 239 uint32_t cirrus_bank_base[2];
224 240 uint32_t cirrus_bank_limit[2];
225 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 244 int cirrus_blt_pixelwidth;
229 245 int cirrus_blt_width;
230 246 int cirrus_blt_height;
231 247 int cirrus_blt_dstpitch;
232 248 int cirrus_blt_srcpitch;
  249 + uint32_t cirrus_blt_fgcol;
  250 + uint32_t cirrus_blt_bgcol;
233 251 uint32_t cirrus_blt_dstaddr;
234 252 uint32_t cirrus_blt_srcaddr;
235 253 uint8_t cirrus_blt_mode;
  254 + uint8_t cirrus_blt_modeext;
236 255 cirrus_bitblt_rop_t cirrus_rop;
237   -#define CIRRUS_BLTBUFSIZE 256
  256 +#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
238 257 uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
239 258 uint8_t *cirrus_srcptr;
240 259 uint8_t *cirrus_srcptr_end;
... ... @@ -242,8 +261,12 @@ typedef struct CirrusVGAState {
242 261 uint8_t *cirrus_dstptr;
243 262 uint8_t *cirrus_dstptr_end;
244 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 270 } CirrusVGAState;
248 271  
249 272 typedef struct PCICirrusVGAState {
... ... @@ -251,6 +274,8 @@ typedef struct PCICirrusVGAState {
251 274 CirrusVGAState cirrus_vga;
252 275 } PCICirrusVGAState;
253 276  
  277 +static uint8_t rop_to_index[256];
  278 +
254 279 /***************************************
255 280 *
256 281 * prototypes.
... ... @@ -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 503 switch (s->cirrus_blt_pixelwidth) {
588 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 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 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 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 541 }
627 542 }
628 543  
629   -
630   -
631 544 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
632 545 const uint8_t * src)
633 546 {
... ... @@ -639,12 +552,16 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
639 552 int patternbytes = s->cirrus_blt_pixelwidth * 8;
640 553  
641 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 560 src = work_colorexp;
644 561 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND;
645 562 }
646 563 if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) {
647   -#ifdef DEBUG_CIRRUS
  564 +#ifdef DEBUG_BITBLT
648 565 printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n",
649 566 s->cirrus_blt_mode);
650 567 #endif
... ... @@ -657,7 +574,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
657 574 tileheight = qemu_MIN(8, s->cirrus_blt_height - y);
658 575 for (x = 0; x < s->cirrus_blt_width; x += patternbytes) {
659 576 tilewidth = qemu_MIN(patternbytes, s->cirrus_blt_width - x);
660   - (*s->cirrus_rop) (dstc, src,
  577 + (*s->cirrus_rop) (s, dstc, src,
661 578 s->cirrus_blt_dstpitch, patternbytes,
662 579 tilewidth, tileheight);
663 580 dstc += patternbytes;
... ... @@ -672,111 +589,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
672 589  
673 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 600 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
781 601 s->cirrus_blt_dstpitch, s->cirrus_blt_width,
782 602 s->cirrus_blt_height);
... ... @@ -799,21 +619,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
799 619  
800 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 623 s->vram_ptr + s->cirrus_blt_srcaddr,
818 624 s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
819 625 s->cirrus_blt_width, s->cirrus_blt_height);
... ... @@ -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 638 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
940 639 {
941 640 int copy_count;
942   - int avail_count;
943   -
944   - s->cirrus_blt_handler(s);
945   -
  641 + uint8_t *end_ptr;
  642 +
946 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 686 s->cirrus_dstptr = &s->cirrus_bltbuf[0];
973 687 s->cirrus_dstptr_end = &s->cirrus_bltbuf[0];
974 688 s->cirrus_dstcounter = 0;
975   - s->cirrus_blt_handler = NULL;
976 689 }
977 690  
978 691 static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
979 692 {
  693 + int w;
  694 +
980 695 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
981 696 s->cirrus_srcptr = &s->cirrus_bltbuf[0];
982 697 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
983 698  
984 699 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
985 700 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
986   - s->cirrus_srccounter = 8;
  701 + s->cirrus_blt_srcpitch = 8;
987 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 706 } else {
993 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 713 } else {
999   - s->cirrus_srccounter =
1000   - s->cirrus_blt_width * s->cirrus_blt_height;
1001 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 720 return 1;
1012 721 }
1013 722  
1014 723 static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
1015 724 {
1016 725 /* XXX */
1017   -#ifdef DEBUG_CIRRUS
  726 +#ifdef DEBUG_BITBLT
1018 727 printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
1019 728 #endif
1020 729 return 0;
... ... @@ -1029,7 +738,6 @@ static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
1029 738 } else {
1030 739 ret = cirrus_bitblt_videotovideo_copy(s);
1031 740 }
1032   -
1033 741 if (ret)
1034 742 cirrus_bitblt_reset(s);
1035 743 return ret;
... ... @@ -1039,6 +747,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1039 747 {
1040 748 uint8_t blt_rop;
1041 749  
  750 + s->gr[0x31] |= CIRRUS_BLT_BUSY;
  751 +
1042 752 s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
1043 753 s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
1044 754 s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
... ... @@ -1048,19 +758,21 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1048 758 s->cirrus_blt_srcaddr =
1049 759 (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
1050 760 s->cirrus_blt_mode = s->gr[0x30];
  761 + s->cirrus_blt_modeext = s->gr[0x33];
1051 762 blt_rop = s->gr[0x32];
1052 763  
1053 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 766 blt_rop,
1056 767 s->cirrus_blt_mode,
1057   - s->gr[0x33],
  768 + s->cirrus_blt_modeext,
1058 769 s->cirrus_blt_width,
1059 770 s->cirrus_blt_height,
1060 771 s->cirrus_blt_dstpitch,
1061 772 s->cirrus_blt_srcpitch,
1062 773 s->cirrus_blt_dstaddr,
1063   - s->cirrus_blt_srcaddr);
  774 + s->cirrus_blt_srcaddr,
  775 + s->sr[0x2f]);
1064 776 #endif
1065 777  
1066 778 switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
... ... @@ -1077,7 +789,7 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1077 789 s->cirrus_blt_pixelwidth = 4;
1078 790 break;
1079 791 default:
1080   -#ifdef DEBUG_CIRRUS
  792 +#ifdef DEBUG_BITBLT
1081 793 printf("cirrus: bitblt - pixel width is unknown\n");
1082 794 #endif
1083 795 goto bitblt_ignore;
... ... @@ -1088,26 +800,41 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
1088 800 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
1089 801 CIRRUS_BLTMODE_MEMSYSDEST))
1090 802 == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
1091   -#ifdef DEBUG_CIRRUS
  803 +#ifdef DEBUG_BITBLT
1092 804 printf("cirrus: bitblt - memory-to-memory copy is requested\n");
1093 805 #endif
1094 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 810 (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
1099 811 CIRRUS_BLTMODE_TRANSPARENTCOMP |
1100 812 CIRRUS_BLTMODE_PATTERNCOPY |
1101 813 CIRRUS_BLTMODE_COLOREXPAND)) ==
1102 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 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 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 840 // setup bitblt engine.
... ... @@ -1139,7 +866,6 @@ static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
1139 866 cirrus_bitblt_reset(s);
1140 867 } else if (((old_value & CIRRUS_BLT_START) == 0) &&
1141 868 ((reg_value & CIRRUS_BLT_START) != 0)) {
1142   - s->gr[0x31] |= CIRRUS_BLT_BUSY;
1143 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 1038 case 0x91:
1313 1039 case 0xb1:
1314 1040 case 0xd1:
  1041 + case 0xf1: // Graphics Cursor Y
1315 1042 *reg_value = s->sr[0x11];
1316 1043 break;
1317 1044 case 0x05: // ???
... ... @@ -1324,7 +1051,6 @@ cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1324 1051 case 0x0d: // VCLK 2
1325 1052 case 0x0e: // VCLK 3
1326 1053 case 0x0f: // DRAM Control
1327   - case 0xf1: // Graphics Cursor Y
1328 1054 case 0x12: // Graphics Cursor Attribute
1329 1055 case 0x13: // Graphics Cursor Pattern Address
1330 1056 case 0x14: // Scratch Register 2
... ... @@ -1382,7 +1108,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1382 1108 case 0xd0:
1383 1109 case 0xf0: // Graphics Cursor X
1384 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 1112 break;
1387 1113 case 0x11:
1388 1114 case 0x31:
... ... @@ -1393,7 +1119,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1393 1119 case 0xd1:
1394 1120 case 0xf1: // Graphics Cursor Y
1395 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 1123 break;
1398 1124 case 0x07: // Extended Sequencer Mode
1399 1125 case 0x08: // EEPROM Control
... ... @@ -1471,13 +1197,9 @@ static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
1471 1197 {
1472 1198 if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
1473 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 1203 if (++s->dac_sub_index == 3) {
1482 1204 s->dac_sub_index = 0;
1483 1205 s->dac_read_index++;
... ... @@ -1491,11 +1213,9 @@ static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
1491 1213 return CIRRUS_HOOK_NOT_HANDLED;
1492 1214 s->dac_cache[s->dac_sub_index] = reg_value;
1493 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 1219 s->dac_sub_index = 0;
1500 1220 s->dac_write_index++;
1501 1221 }
... ... @@ -1545,6 +1265,9 @@ cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
1545 1265 static int
1546 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 1271 switch (reg_index) {
1549 1272 case 0x00: // Standard VGA, BGCOLOR 0x000000ff
1550 1273 s->cirrus_shadow_gr0 = reg_value;
... ... @@ -1583,6 +1306,7 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1583 1306 case 0x29: // BLT DEST ADDR 0x00ff00
1584 1307 case 0x2c: // BLT SRC ADDR 0x0000ff
1585 1308 case 0x2d: // BLT SRC ADDR 0x00ff00
  1309 + case 0x2f: // BLT WRITEMASK
1586 1310 case 0x30: // BLT MODE
1587 1311 case 0x32: // RASTER OP
1588 1312 case 0x33: // BLT MODEEXT
... ... @@ -1599,6 +1323,12 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1599 1323 s->gr[reg_index] = reg_value & 0x1f;
1600 1324 break;
1601 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 1332 case 0x2e: // BLT SRC ADDR 0x3f0000
1603 1333 s->gr[reg_index] = reg_value & 0x3f;
1604 1334 break;
... ... @@ -2111,7 +1841,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
2111 1841 if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2112 1842 /* bitblt */
2113 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 1845 cirrus_bitblt_cputovideo_next(s);
2116 1846 }
2117 1847 } else {
... ... @@ -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 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 2172 } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
2273 2173 /* bitblt */
2274 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 2176 cirrus_bitblt_cputovideo_next(s);
2277 2177 }
2278 2178 } else {
... ... @@ -2339,6 +2239,107 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
2339 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 2343 /* I/O ports */
2343 2344  
2344 2345 static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
... ... @@ -2691,7 +2692,30 @@ static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
2691 2692  
2692 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 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 2749 s->cirrus_linear_io_addr =
2726 2750 cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
2727 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 2757 /* I/O handler for memory-mapped I/O */
2729 2758 s->cirrus_mmio_io_addr =
2730 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 2763  
2735 2764 s->get_bpp = cirrus_get_bpp;
2736 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 2798 {
2768 2799 CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
2769 2800  
  2801 + /* XXX: add byte swapping apertures */
2770 2802 cpu_register_physical_memory(addr, s->vram_size,
2771 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 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 2849 /* memory #0 LFB */
2816 2850 /* memory #1 memory-mapped I/O */
2817 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 2853 PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
2820 2854 if (device_id == CIRRUS_ID_CLGD5446) {
2821 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
... ...