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,6 +31,7 @@ | ||
31 | 31 | ||
32 | /* | 32 | /* |
33 | * TODO: | 33 | * TODO: |
34 | + * - fix 24 bpp pattern fills (source is 32 bpp in that case) | ||
34 | * - add support for WRITEMASK (GR2F) | 35 | * - add support for WRITEMASK (GR2F) |
35 | * - add support for scanline modulo in pattern fill | 36 | * - add support for scanline modulo in pattern fill |
36 | * - optimize linear mappings | 37 | * - optimize linear mappings |
@@ -233,6 +234,7 @@ typedef struct CirrusVGAState { | @@ -233,6 +234,7 @@ typedef struct CirrusVGAState { | ||
233 | int cirrus_linear_bitblt_io_addr; | 234 | int cirrus_linear_bitblt_io_addr; |
234 | int cirrus_mmio_io_addr; | 235 | int cirrus_mmio_io_addr; |
235 | uint32_t cirrus_addr_mask; | 236 | uint32_t cirrus_addr_mask; |
237 | + uint32_t linear_mmio_mask; | ||
236 | uint8_t cirrus_shadow_gr0; | 238 | uint8_t cirrus_shadow_gr0; |
237 | uint8_t cirrus_shadow_gr1; | 239 | uint8_t cirrus_shadow_gr1; |
238 | uint8_t cirrus_hidden_dac_lockindex; | 240 | uint8_t cirrus_hidden_dac_lockindex; |
@@ -268,6 +270,7 @@ typedef struct CirrusVGAState { | @@ -268,6 +270,7 @@ typedef struct CirrusVGAState { | ||
268 | int last_hw_cursor_y; | 270 | int last_hw_cursor_y; |
269 | int last_hw_cursor_y_start; | 271 | int last_hw_cursor_y_start; |
270 | int last_hw_cursor_y_end; | 272 | int last_hw_cursor_y_end; |
273 | + int real_vram_size; /* XXX: suppress that */ | ||
271 | } CirrusVGAState; | 274 | } CirrusVGAState; |
272 | 275 | ||
273 | typedef struct PCICirrusVGAState { | 276 | typedef struct PCICirrusVGAState { |
@@ -983,6 +986,22 @@ static int cirrus_get_bpp(VGAState *s1) | @@ -983,6 +986,22 @@ static int cirrus_get_bpp(VGAState *s1) | ||
983 | return ret; | 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 | * bank memory | 1007 | * bank memory |
@@ -1970,7 +1989,7 @@ static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s) | @@ -1970,7 +1989,7 @@ static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s) | ||
1970 | uint32_t content; | 1989 | uint32_t content; |
1971 | int y, y_min, y_max; | 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 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { | 1993 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
1975 | src += (s->sr[0x13] & 0x3c) * 256; | 1994 | src += (s->sr[0x13] & 0x3c) * 256; |
1976 | y_min = 64; | 1995 | y_min = 64; |
@@ -2064,7 +2083,7 @@ static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y) | @@ -2064,7 +2083,7 @@ static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y) | ||
2064 | scr_y >= (s->hw_cursor_y + h)) | 2083 | scr_y >= (s->hw_cursor_y + h)) |
2065 | return; | 2084 | return; |
2066 | 2085 | ||
2067 | - src = s->vram_ptr + 0x200000 - 16 * 1024; | 2086 | + src = s->vram_ptr + s->real_vram_size - 16 * 1024; |
2068 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { | 2087 | if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { |
2069 | src += (s->sr[0x13] & 0x3c) * 256; | 2088 | src += (s->sr[0x13] & 0x3c) * 256; |
2070 | src += (scr_y - s->hw_cursor_y) * 16; | 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,10 +2149,10 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) | ||
2130 | CirrusVGAState *s = (CirrusVGAState *) opaque; | 2149 | CirrusVGAState *s = (CirrusVGAState *) opaque; |
2131 | uint32_t ret; | 2150 | uint32_t ret; |
2132 | 2151 | ||
2133 | - /* XXX: s->vram_size must be a power of two */ | ||
2134 | addr &= s->cirrus_addr_mask; | 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 | /* memory-mapped I/O */ | 2156 | /* memory-mapped I/O */ |
2138 | ret = cirrus_mmio_blt_read(s, addr & 0xff); | 2157 | ret = cirrus_mmio_blt_read(s, addr & 0xff); |
2139 | } else if (0) { | 2158 | } else if (0) { |
@@ -2190,8 +2209,9 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, | @@ -2190,8 +2209,9 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, | ||
2190 | unsigned mode; | 2209 | unsigned mode; |
2191 | 2210 | ||
2192 | addr &= s->cirrus_addr_mask; | 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 | /* memory-mapped I/O */ | 2215 | /* memory-mapped I/O */ |
2196 | cirrus_mmio_blt_write(s, addr & 0xff, val); | 2216 | cirrus_mmio_blt_write(s, addr & 0xff, val); |
2197 | } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { | 2217 | } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { |
@@ -2715,7 +2735,7 @@ static CPUWriteMemoryFunc *cirrus_mmio_write[3] = { | @@ -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 | int vga_io_memory, i; | 2740 | int vga_io_memory, i; |
2721 | static int inited; | 2741 | static int inited; |
@@ -2762,11 +2782,35 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) | @@ -2762,11 +2782,35 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) | ||
2762 | vga_io_memory); | 2782 | vga_io_memory); |
2763 | 2783 | ||
2764 | s->sr[0x06] = 0x0f; | 2784 | s->sr[0x06] = 0x0f; |
2765 | - s->sr[0x0F] = CIRRUS_MEMSIZE_2M; | ||
2766 | s->sr[0x1F] = 0x22; // MemClock | 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 | s->cr[0x27] = device_id; | 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 | s->cirrus_hidden_dac_lockindex = 5; | 2814 | s->cirrus_hidden_dac_lockindex = 5; |
2771 | s->cirrus_hidden_dac_data = 0; | 2815 | s->cirrus_hidden_dac_data = 0; |
2772 | 2816 | ||
@@ -2784,10 +2828,12 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) | @@ -2784,10 +2828,12 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id) | ||
2784 | cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s); | 2828 | cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s); |
2785 | 2829 | ||
2786 | /* XXX: s->vram_size must be a power of two */ | 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 | s->get_bpp = cirrus_get_bpp; | 2834 | s->get_bpp = cirrus_get_bpp; |
2790 | s->get_offsets = cirrus_get_offsets; | 2835 | s->get_offsets = cirrus_get_offsets; |
2836 | + s->get_resolution = cirrus_get_resolution; | ||
2791 | s->cursor_invalidate = cirrus_cursor_invalidate; | 2837 | s->cursor_invalidate = cirrus_cursor_invalidate; |
2792 | s->cursor_draw_line = cirrus_cursor_draw_line; | 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,8 +2853,7 @@ void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, | ||
2807 | 2853 | ||
2808 | vga_common_init((VGAState *)s, | 2854 | vga_common_init((VGAState *)s, |
2809 | ds, vga_ram_base, vga_ram_offset, vga_ram_size); | 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 | /* XXX ISA-LFB support */ | 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,8 +2912,7 @@ void pci_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, | ||
2867 | s = &d->cirrus_vga; | 2912 | s = &d->cirrus_vga; |
2868 | vga_common_init((VGAState *)s, | 2913 | vga_common_init((VGAState *)s, |
2869 | ds, vga_ram_base, vga_ram_offset, vga_ram_size); | 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 | /* setup memory space */ | 2917 | /* setup memory space */ |
2874 | /* memory #0 LFB */ | 2918 | /* memory #0 LFB */ |