Commit 78e127efdbac82f148ed4f7b42f8f4f2873b4c5b
1 parent
ee38b4c8
set memory size to 4MB for 5446 - fixed memory size probe (aka Win2000 bug) - fi…
…xed interlace support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@914 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
58 additions
and
14 deletions
hw/cirrus_vga.c
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | |
32 | 32 | /* |
33 | 33 | * TODO: |
34 | + * - fix 24 bpp pattern fills (source is 32 bpp in that case) | |
34 | 35 | * - add support for WRITEMASK (GR2F) |
35 | 36 | * - add support for scanline modulo in pattern fill |
36 | 37 | * - optimize linear mappings |
... | ... | @@ -233,6 +234,7 @@ typedef struct CirrusVGAState { |
233 | 234 | int cirrus_linear_bitblt_io_addr; |
234 | 235 | int cirrus_mmio_io_addr; |
235 | 236 | uint32_t cirrus_addr_mask; |
237 | + uint32_t linear_mmio_mask; | |
236 | 238 | uint8_t cirrus_shadow_gr0; |
237 | 239 | uint8_t cirrus_shadow_gr1; |
238 | 240 | uint8_t cirrus_hidden_dac_lockindex; |
... | ... | @@ -268,6 +270,7 @@ typedef struct CirrusVGAState { |
268 | 270 | int last_hw_cursor_y; |
269 | 271 | int last_hw_cursor_y_start; |
270 | 272 | int last_hw_cursor_y_end; |
273 | + int real_vram_size; /* XXX: suppress that */ | |
271 | 274 | } CirrusVGAState; |
272 | 275 | |
273 | 276 | typedef struct PCICirrusVGAState { |
... | ... | @@ -983,6 +986,22 @@ static int cirrus_get_bpp(VGAState *s1) |
983 | 986 | return ret; |
984 | 987 | } |
985 | 988 | |
989 | +static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight) | |
990 | +{ | |
991 | + int width, height; | |
992 | + | |
993 | + width = (s->cr[0x01] + 1) * 8; | |
994 | + height = s->cr[0x12] | | |
995 | + ((s->cr[0x07] & 0x02) << 7) | | |
996 | + ((s->cr[0x07] & 0x40) << 3); | |
997 | + height = (height + 1); | |
998 | + /* interlace support */ | |
999 | + if (s->cr[0x1a] & 0x01) | |
1000 | + height = height * 2; | |
1001 | + *pwidth = width; | |
1002 | + *pheight = height; | |
1003 | +} | |
1004 | + | |
986 | 1005 | /*************************************** |
987 | 1006 | * |
988 | 1007 | * bank memory |
... | ... | @@ -1970,7 +1989,7 @@ static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s) |
1970 | 1989 | uint32_t content; |
1971 | 1990 | int y, y_min, y_max; |
1972 | 1991 | |
1973 | - src = s->vram_ptr + 0x200000 - 16 * 1024; | |
1992 | + src = s->vram_ptr + s->real_vram_size - 16 * 1024; | |
1974 | 1993 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
1975 | 1994 | src += (s->sr[0x13] & 0x3c) * 256; |
1976 | 1995 | y_min = 64; |
... | ... | @@ -2064,7 +2083,7 @@ static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y) |
2064 | 2083 | scr_y >= (s->hw_cursor_y + h)) |
2065 | 2084 | return; |
2066 | 2085 | |
2067 | - src = s->vram_ptr + 0x200000 - 16 * 1024; | |
2086 | + src = s->vram_ptr + s->real_vram_size - 16 * 1024; | |
2068 | 2087 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
2069 | 2088 | src += (s->sr[0x13] & 0x3c) * 256; |
2070 | 2089 | src += (scr_y - s->hw_cursor_y) * 16; |
... | ... | @@ -2130,10 +2149,10 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) |
2130 | 2149 | CirrusVGAState *s = (CirrusVGAState *) opaque; |
2131 | 2150 | uint32_t ret; |
2132 | 2151 | |
2133 | - /* XXX: s->vram_size must be a power of two */ | |
2134 | 2152 | addr &= s->cirrus_addr_mask; |
2135 | 2153 | |
2136 | - if (((s->sr[0x17] & 0x44) == 0x44) && ((addr & 0x1fff00) == 0x1fff00)) { | |
2154 | + if (((s->sr[0x17] & 0x44) == 0x44) && | |
2155 | + ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { | |
2137 | 2156 | /* memory-mapped I/O */ |
2138 | 2157 | ret = cirrus_mmio_blt_read(s, addr & 0xff); |
2139 | 2158 | } else if (0) { |
... | ... | @@ -2190,8 +2209,9 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, |
2190 | 2209 | unsigned mode; |
2191 | 2210 | |
2192 | 2211 | addr &= s->cirrus_addr_mask; |
2193 | - | |
2194 | - if (((s->sr[0x17] & 0x44) == 0x44) && ((addr & 0x1fff00) == 0x1fff00)) { | |
2212 | + | |
2213 | + if (((s->sr[0x17] & 0x44) == 0x44) && | |
2214 | + ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { | |
2195 | 2215 | /* memory-mapped I/O */ |
2196 | 2216 | cirrus_mmio_blt_write(s, addr & 0xff, val); |
2197 | 2217 | } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { |
... | ... | @@ -2715,7 +2735,7 @@ static CPUWriteMemoryFunc *cirrus_mmio_write[3] = { |
2715 | 2735 | * |
2716 | 2736 | ***************************************/ |
2717 | 2737 | |
2718 | -static void cirrus_init_common(CirrusVGAState * s, int device_id) | |
2738 | +static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) | |
2719 | 2739 | { |
2720 | 2740 | int vga_io_memory, i; |
2721 | 2741 | static int inited; |
... | ... | @@ -2762,11 +2782,35 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) |
2762 | 2782 | vga_io_memory); |
2763 | 2783 | |
2764 | 2784 | s->sr[0x06] = 0x0f; |
2765 | - s->sr[0x0F] = CIRRUS_MEMSIZE_2M; | |
2766 | 2785 | s->sr[0x1F] = 0x22; // MemClock |
2767 | - | |
2786 | + if (device_id == CIRRUS_ID_CLGD5446) { | |
2787 | + /* 4MB 64 bit memory config, always PCI */ | |
2788 | +#if 1 | |
2789 | + s->sr[0x0f] = 0x98; | |
2790 | + s->sr[0x17] = 0x20; | |
2791 | + s->sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */ | |
2792 | + s->real_vram_size = 4096 * 1024; | |
2793 | +#else | |
2794 | + s->sr[0x0f] = 0x18; | |
2795 | + s->sr[0x17] = 0x20; | |
2796 | + s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */ | |
2797 | + s->real_vram_size = 2048 * 1024; | |
2798 | +#endif | |
2799 | + } else { | |
2800 | + s->sr[0x0F] = CIRRUS_MEMSIZE_2M; | |
2801 | + if (is_pci) | |
2802 | + s->sr[0x17] = CIRRUS_BUSTYPE_PCI; | |
2803 | + else | |
2804 | + s->sr[0x17] = CIRRUS_BUSTYPE_ISA; | |
2805 | + s->real_vram_size = 2048 * 1024; | |
2806 | + s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */ | |
2807 | + } | |
2768 | 2808 | s->cr[0x27] = device_id; |
2769 | 2809 | |
2810 | + /* Win2K seems to assume that the pattern buffer is at 0xff | |
2811 | + initially ! */ | |
2812 | + memset(s->vram_ptr, 0xff, s->real_vram_size); | |
2813 | + | |
2770 | 2814 | s->cirrus_hidden_dac_lockindex = 5; |
2771 | 2815 | s->cirrus_hidden_dac_data = 0; |
2772 | 2816 | |
... | ... | @@ -2784,10 +2828,12 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) |
2784 | 2828 | cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s); |
2785 | 2829 | |
2786 | 2830 | /* XXX: s->vram_size must be a power of two */ |
2787 | - s->cirrus_addr_mask = s->vram_size - 1; | |
2831 | + s->cirrus_addr_mask = s->real_vram_size - 1; | |
2832 | + s->linear_mmio_mask = s->real_vram_size - 256; | |
2788 | 2833 | |
2789 | 2834 | s->get_bpp = cirrus_get_bpp; |
2790 | 2835 | s->get_offsets = cirrus_get_offsets; |
2836 | + s->get_resolution = cirrus_get_resolution; | |
2791 | 2837 | s->cursor_invalidate = cirrus_cursor_invalidate; |
2792 | 2838 | s->cursor_draw_line = cirrus_cursor_draw_line; |
2793 | 2839 | } |
... | ... | @@ -2807,8 +2853,7 @@ void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, |
2807 | 2853 | |
2808 | 2854 | vga_common_init((VGAState *)s, |
2809 | 2855 | ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
2810 | - cirrus_init_common(s, CIRRUS_ID_CLGD5430); | |
2811 | - s->sr[0x17] = CIRRUS_BUSTYPE_ISA; | |
2856 | + cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0); | |
2812 | 2857 | /* XXX ISA-LFB support */ |
2813 | 2858 | } |
2814 | 2859 | |
... | ... | @@ -2867,8 +2912,7 @@ void pci_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, |
2867 | 2912 | s = &d->cirrus_vga; |
2868 | 2913 | vga_common_init((VGAState *)s, |
2869 | 2914 | ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
2870 | - cirrus_init_common(s, device_id); | |
2871 | - s->sr[0x17] = CIRRUS_BUSTYPE_PCI; | |
2915 | + cirrus_init_common(s, device_id, 1); | |
2872 | 2916 | |
2873 | 2917 | /* setup memory space */ |
2874 | 2918 | /* memory #0 LFB */ | ... | ... |