Revision 5fafdf24 hw/cirrus_vga.c
b/hw/cirrus_vga.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU Cirrus CLGD 54xx VGA Emulator. |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2004 Fabrice Bellard |
5 | 5 |
* Copyright (c) 2004 Makoto Suzuki (suzu) |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | 8 |
* of this software and associated documentation files (the "Software"), to deal |
9 | 9 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
275 | 275 |
} PCICirrusVGAState; |
276 | 276 |
|
277 | 277 |
static uint8_t rop_to_index[256]; |
278 |
|
|
278 |
|
|
279 | 279 |
/*************************************** |
280 | 280 |
* |
281 | 281 |
* prototypes. |
... | ... | |
590 | 590 |
s->cirrus_blt_fgcol = le16_to_cpu(color); |
591 | 591 |
break; |
592 | 592 |
case 3: |
593 |
s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
|
|
593 |
s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 | |
|
594 | 594 |
(s->gr[0x11] << 8) | (s->gr[0x13] << 16); |
595 | 595 |
break; |
596 | 596 |
default: |
... | ... | |
614 | 614 |
s->cirrus_blt_bgcol = le16_to_cpu(color); |
615 | 615 |
break; |
616 | 616 |
case 3: |
617 |
s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
|
|
617 |
s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 | |
|
618 | 618 |
(s->gr[0x10] << 8) | (s->gr[0x12] << 16); |
619 | 619 |
break; |
620 | 620 |
default: |
... | ... | |
653 | 653 |
|
654 | 654 |
dst = s->vram_ptr + s->cirrus_blt_dstaddr; |
655 | 655 |
(*s->cirrus_rop) (s, dst, src, |
656 |
s->cirrus_blt_dstpitch, 0,
|
|
656 |
s->cirrus_blt_dstpitch, 0, |
|
657 | 657 |
s->cirrus_blt_width, s->cirrus_blt_height); |
658 | 658 |
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, |
659 | 659 |
s->cirrus_blt_dstpitch, s->cirrus_blt_width, |
... | ... | |
668 | 668 |
cirrus_fill_t rop_func; |
669 | 669 |
|
670 | 670 |
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
671 |
rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
|
|
671 |
rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr, |
|
672 | 672 |
s->cirrus_blt_dstpitch, |
673 | 673 |
s->cirrus_blt_width, s->cirrus_blt_height); |
674 | 674 |
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, |
... | ... | |
687 | 687 |
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) |
688 | 688 |
{ |
689 | 689 |
return cirrus_bitblt_common_patterncopy(s, |
690 |
s->vram_ptr +
|
|
690 |
s->vram_ptr + |
|
691 | 691 |
(s->cirrus_blt_srcaddr & ~7)); |
692 | 692 |
} |
693 | 693 |
|
... | ... | |
788 | 788 |
{ |
789 | 789 |
int copy_count; |
790 | 790 |
uint8_t *end_ptr; |
791 |
|
|
791 |
|
|
792 | 792 |
if (s->cirrus_srccounter > 0) { |
793 | 793 |
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { |
794 | 794 |
cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf); |
... | ... | |
854 | 854 |
} else { |
855 | 855 |
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { |
856 | 856 |
w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth; |
857 |
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
|
|
857 |
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) |
|
858 | 858 |
s->cirrus_blt_srcpitch = ((w + 31) >> 5); |
859 | 859 |
else |
860 | 860 |
s->cirrus_blt_srcpitch = ((w + 7) >> 3); |
... | ... | |
913 | 913 |
|
914 | 914 |
#ifdef DEBUG_BITBLT |
915 | 915 |
printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n", |
916 |
blt_rop,
|
|
916 |
blt_rop, |
|
917 | 917 |
s->cirrus_blt_mode, |
918 | 918 |
s->cirrus_blt_modeext, |
919 | 919 |
s->cirrus_blt_width, |
... | ... | |
957 | 957 |
} |
958 | 958 |
|
959 | 959 |
if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) && |
960 |
(s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
|
|
960 |
(s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST | |
|
961 | 961 |
CIRRUS_BLTMODE_TRANSPARENTCOMP | |
962 |
CIRRUS_BLTMODE_PATTERNCOPY |
|
|
963 |
CIRRUS_BLTMODE_COLOREXPAND)) ==
|
|
962 |
CIRRUS_BLTMODE_PATTERNCOPY | |
|
963 |
CIRRUS_BLTMODE_COLOREXPAND)) == |
|
964 | 964 |
(CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) { |
965 | 965 |
cirrus_bitblt_fgcol(s); |
966 | 966 |
cirrus_bitblt_solidfill(s, blt_rop); |
967 | 967 |
} else { |
968 |
if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
|
|
969 |
CIRRUS_BLTMODE_PATTERNCOPY)) ==
|
|
968 |
if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND | |
|
969 |
CIRRUS_BLTMODE_PATTERNCOPY)) == |
|
970 | 970 |
CIRRUS_BLTMODE_COLOREXPAND) { |
971 | 971 |
|
972 | 972 |
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { |
... | ... | |
1059 | 1059 |
* |
1060 | 1060 |
***************************************/ |
1061 | 1061 |
|
1062 |
static void cirrus_get_offsets(VGAState *s1,
|
|
1062 |
static void cirrus_get_offsets(VGAState *s1, |
|
1063 | 1063 |
uint32_t *pline_offset, |
1064 | 1064 |
uint32_t *pstart_addr, |
1065 | 1065 |
uint32_t *pline_compare) |
... | ... | |
1079 | 1079 |
| ((s->cr[0x1d] & 0x80) << 12); |
1080 | 1080 |
*pstart_addr = start_addr; |
1081 | 1081 |
|
1082 |
line_compare = s->cr[0x18] |
|
|
1082 |
line_compare = s->cr[0x18] | |
|
1083 | 1083 |
((s->cr[0x07] & 0x10) << 4) | |
1084 | 1084 |
((s->cr[0x09] & 0x40) << 3); |
1085 | 1085 |
*pline_compare = line_compare; |
... | ... | |
1148 | 1148 |
static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight) |
1149 | 1149 |
{ |
1150 | 1150 |
int width, height; |
1151 |
|
|
1151 |
|
|
1152 | 1152 |
width = (s->cr[0x01] + 1) * 8; |
1153 |
height = s->cr[0x12] |
|
|
1154 |
((s->cr[0x07] & 0x02) << 7) |
|
|
1153 |
height = s->cr[0x12] | |
|
1154 |
((s->cr[0x07] & 0x02) << 7) | |
|
1155 | 1155 |
((s->cr[0x07] & 0x40) << 3); |
1156 | 1156 |
height = (height + 1); |
1157 | 1157 |
/* interlace support */ |
... | ... | |
2036 | 2036 |
return v; |
2037 | 2037 |
} |
2038 | 2038 |
|
2039 |
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
|
|
2039 |
static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, |
|
2040 | 2040 |
uint32_t mem_value) |
2041 | 2041 |
{ |
2042 | 2042 |
CirrusVGAState *s = opaque; |
... | ... | |
2147 | 2147 |
static inline void invalidate_cursor1(CirrusVGAState *s) |
2148 | 2148 |
{ |
2149 | 2149 |
if (s->last_hw_cursor_size) { |
2150 |
vga_invalidate_scanlines((VGAState *)s,
|
|
2150 |
vga_invalidate_scanlines((VGAState *)s, |
|
2151 | 2151 |
s->last_hw_cursor_y + s->last_hw_cursor_y_start, |
2152 | 2152 |
s->last_hw_cursor_y + s->last_hw_cursor_y_end); |
2153 | 2153 |
} |
... | ... | |
2223 | 2223 |
s->last_hw_cursor_y != s->hw_cursor_y) { |
2224 | 2224 |
|
2225 | 2225 |
invalidate_cursor1(s); |
2226 |
|
|
2226 |
|
|
2227 | 2227 |
s->last_hw_cursor_size = size; |
2228 | 2228 |
s->last_hw_cursor_x = s->hw_cursor_x; |
2229 | 2229 |
s->last_hw_cursor_y = s->hw_cursor_y; |
... | ... | |
2240 | 2240 |
unsigned int color0, color1; |
2241 | 2241 |
const uint8_t *palette, *src; |
2242 | 2242 |
uint32_t content; |
2243 |
|
|
2244 |
if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
|
|
2243 |
|
|
2244 |
if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW)) |
|
2245 | 2245 |
return; |
2246 | 2246 |
/* fast test to see if the cursor intersects with the scan line */ |
2247 | 2247 |
if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
... | ... | |
2252 | 2252 |
if (scr_y < s->hw_cursor_y || |
2253 | 2253 |
scr_y >= (s->hw_cursor_y + h)) |
2254 | 2254 |
return; |
2255 |
|
|
2255 |
|
|
2256 | 2256 |
src = s->vram_ptr + s->real_vram_size - 16 * 1024; |
2257 | 2257 |
if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
2258 | 2258 |
src += (s->sr[0x13] & 0x3c) * 256; |
... | ... | |
2282 | 2282 |
x2 = s->last_scr_width; |
2283 | 2283 |
w = x2 - x1; |
2284 | 2284 |
palette = s->cirrus_hidden_palette; |
2285 |
color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
|
|
2286 |
c6_to_8(palette[0x0 * 3 + 1]),
|
|
2285 |
color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]), |
|
2286 |
c6_to_8(palette[0x0 * 3 + 1]), |
|
2287 | 2287 |
c6_to_8(palette[0x0 * 3 + 2])); |
2288 |
color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
|
|
2289 |
c6_to_8(palette[0xf * 3 + 1]),
|
|
2288 |
color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]), |
|
2289 |
c6_to_8(palette[0xf * 3 + 1]), |
|
2290 | 2290 |
c6_to_8(palette[0xf * 3 + 2])); |
2291 | 2291 |
bpp = ((s->ds->depth + 7) >> 3); |
2292 | 2292 |
d1 += x1 * bpp; |
... | ... | |
2321 | 2321 |
|
2322 | 2322 |
addr &= s->cirrus_addr_mask; |
2323 | 2323 |
|
2324 |
if (((s->sr[0x17] & 0x44) == 0x44) &&
|
|
2324 |
if (((s->sr[0x17] & 0x44) == 0x44) && |
|
2325 | 2325 |
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { |
2326 | 2326 |
/* memory-mapped I/O */ |
2327 | 2327 |
ret = cirrus_mmio_blt_read(s, addr & 0xff); |
... | ... | |
2379 | 2379 |
unsigned mode; |
2380 | 2380 |
|
2381 | 2381 |
addr &= s->cirrus_addr_mask; |
2382 |
|
|
2383 |
if (((s->sr[0x17] & 0x44) == 0x44) &&
|
|
2382 |
|
|
2383 |
if (((s->sr[0x17] & 0x44) == 0x44) && |
|
2384 | 2384 |
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { |
2385 | 2385 |
/* memory-mapped I/O */ |
2386 | 2386 |
cirrus_mmio_blt_write(s, addr & 0xff, val); |
... | ... | |
2600 | 2600 |
} else if (s->gr[0x0B] & 0x02) { |
2601 | 2601 |
goto generic_io; |
2602 | 2602 |
} |
2603 |
|
|
2603 |
|
|
2604 | 2604 |
mode = s->gr[0x05] & 0x7; |
2605 | 2605 |
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { |
2606 | 2606 |
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; |
... | ... | |
3110 | 3110 |
register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s); |
3111 | 3111 |
register_ioport_read(0x3da, 1, 1, vga_ioport_read, s); |
3112 | 3112 |
|
3113 |
vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
|
|
3113 |
vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read, |
|
3114 | 3114 |
cirrus_vga_mem_write, s); |
3115 |
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
|
|
3115 |
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, |
|
3116 | 3116 |
vga_io_memory); |
3117 | 3117 |
|
3118 | 3118 |
s->sr[0x06] = 0x0f; |
... | ... | |
3134 | 3134 |
} else { |
3135 | 3135 |
s->sr[0x1F] = 0x22; // MemClock |
3136 | 3136 |
s->sr[0x0F] = CIRRUS_MEMSIZE_2M; |
3137 |
if (is_pci)
|
|
3137 |
if (is_pci) |
|
3138 | 3138 |
s->sr[0x17] = CIRRUS_BUSTYPE_PCI; |
3139 | 3139 |
else |
3140 | 3140 |
s->sr[0x17] = CIRRUS_BUSTYPE_ISA; |
... | ... | |
3184 | 3184 |
* |
3185 | 3185 |
***************************************/ |
3186 | 3186 |
|
3187 |
void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
|
|
3187 |
void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, |
|
3188 | 3188 |
unsigned long vga_ram_offset, int vga_ram_size) |
3189 | 3189 |
{ |
3190 | 3190 |
CirrusVGAState *s; |
3191 | 3191 |
|
3192 | 3192 |
s = qemu_mallocz(sizeof(CirrusVGAState)); |
3193 |
|
|
3194 |
vga_common_init((VGAState *)s,
|
|
3193 |
|
|
3194 |
vga_common_init((VGAState *)s, |
|
3195 | 3195 |
ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
3196 | 3196 |
cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0); |
3197 | 3197 |
/* XXX ISA-LFB support */ |
... | ... | |
3224 | 3224 |
s->cirrus_mmio_io_addr); |
3225 | 3225 |
} |
3226 | 3226 |
|
3227 |
void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
|
|
3227 |
void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, |
|
3228 | 3228 |
unsigned long vga_ram_offset, int vga_ram_size) |
3229 | 3229 |
{ |
3230 | 3230 |
PCICirrusVGAState *d; |
3231 | 3231 |
uint8_t *pci_conf; |
3232 | 3232 |
CirrusVGAState *s; |
3233 | 3233 |
int device_id; |
3234 |
|
|
3234 |
|
|
3235 | 3235 |
device_id = CIRRUS_ID_CLGD5446; |
3236 | 3236 |
|
3237 | 3237 |
/* setup PCI configuration registers */ |
3238 |
d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
|
|
3239 |
sizeof(PCICirrusVGAState),
|
|
3238 |
d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA", |
|
3239 |
sizeof(PCICirrusVGAState), |
|
3240 | 3240 |
-1, NULL, NULL); |
3241 | 3241 |
pci_conf = d->dev.config; |
3242 | 3242 |
pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff); |
... | ... | |
3250 | 3250 |
|
3251 | 3251 |
/* setup VGA */ |
3252 | 3252 |
s = &d->cirrus_vga; |
3253 |
vga_common_init((VGAState *)s,
|
|
3253 |
vga_common_init((VGAState *)s, |
|
3254 | 3254 |
ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
3255 | 3255 |
cirrus_init_common(s, device_id, 1); |
3256 | 3256 |
|
Also available in: Unified diff