Revision a5082316 hw/cirrus_vga.c

b/hw/cirrus_vga.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff