Revision 9586fefe

b/hw/cirrus_vga.c
1392 1392
	break;
1393 1393
    }
1394 1394

  
1395
    vga_update_resolution((VGAState *)s);
1396

  
1395 1397
    return CIRRUS_HOOK_HANDLED;
1396 1398
}
1397 1399

  
......
1419 1421
#endif
1420 1422
    }
1421 1423
    s->cirrus_hidden_dac_lockindex = 0;
1424
    vga_update_resolution((VGAState *)s);
1422 1425
}
1423 1426

  
1424 1427
/***************************************
......
1705 1708
	break;
1706 1709
    }
1707 1710

  
1711
    vga_update_resolution((VGAState *)s);
1712

  
1708 1713
    return CIRRUS_HOOK_HANDLED;
1709 1714
}
1710 1715

  
......
2830 2835
	if (s->ar_flip_flop == 0) {
2831 2836
	    val &= 0x3f;
2832 2837
	    s->ar_index = val;
2838
            vga_update_resolution((VGAState *)s);
2833 2839
	} else {
2834 2840
	    index = s->ar_index & 0x1f;
2835 2841
	    switch (index) {
......
2923 2929
	    /* can always write bit 4 of CR7 */
2924 2930
	    if (s->cr_index == 7)
2925 2931
		s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
2932
            vga_update_resolution((VGAState *)s);
2926 2933
	    return;
2927 2934
	}
2928 2935
	switch (s->cr_index) {
......
2951 2958
	    s->update_retrace_info((VGAState *) s);
2952 2959
	    break;
2953 2960
	}
2961
        vga_update_resolution((VGAState *)s);
2954 2962
	break;
2955 2963
    case 0x3ba:
2956 2964
    case 0x3da:
......
3157 3165

  
3158 3166
    cirrus_update_memory_access(s);
3159 3167
    /* force refresh */
3160
    s->graphic_mode = -1;
3168
    vga_update_resolution((VGAState *)s);
3169
    s->want_full_update = 1;
3161 3170
    cirrus_update_bank_ptr(s, 0);
3162 3171
    cirrus_update_bank_ptr(s, 1);
3163 3172
    return 0;
b/hw/vga.c
36 36

  
37 37
//#define DEBUG_BOCHS_VBE
38 38

  
39
#define GMODE_TEXT     0
40
#define GMODE_GRAPH    1
41
#define GMODE_BLANK 2
42

  
39 43
/* force some bits to zero */
40 44
const uint8_t sr_mask[8] = {
41 45
    0x03,
......
393 397
        if (s->ar_flip_flop == 0) {
394 398
            val &= 0x3f;
395 399
            s->ar_index = val;
400
            vga_update_resolution(s);
396 401
        } else {
397 402
            index = s->ar_index & 0x1f;
398 403
            switch(index) {
......
433 438
#endif
434 439
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
435 440
        if (s->sr_index == 1) s->update_retrace_info(s);
441
        vga_update_resolution(s);
436 442
        break;
437 443
    case 0x3c7:
438 444
        s->dac_read_index = val;
......
460 466
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
461 467
#endif
462 468
        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
469
        vga_update_resolution(s);
463 470
        break;
464 471
    case 0x3b4:
465 472
    case 0x3d4:
......
475 482
            /* can always write bit 4 of CR7 */
476 483
            if (s->cr_index == 7)
477 484
                s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
485
            vga_update_resolution(s);
478 486
            return;
479 487
        }
480 488
        switch(s->cr_index) {
......
502 510
            s->update_retrace_info(s);
503 511
            break;
504 512
        }
513
        vga_update_resolution(s);
505 514
        break;
506 515
    case 0x3ba:
507 516
    case 0x3da:
......
581 590
            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
582 591
                s->vbe_regs[s->vbe_index] = val;
583 592
            }
593
            vga_update_resolution(s);
584 594
            break;
585 595
        case VBE_DISPI_INDEX_YRES:
586 596
            if (val <= VBE_DISPI_MAX_YRES) {
587 597
                s->vbe_regs[s->vbe_index] = val;
588 598
            }
599
            vga_update_resolution(s);
589 600
            break;
590 601
        case VBE_DISPI_INDEX_BPP:
591 602
            if (val == 0)
......
594 605
                val == 16 || val == 24 || val == 32) {
595 606
                s->vbe_regs[s->vbe_index] = val;
596 607
            }
608
            vga_update_resolution(s);
597 609
            break;
598 610
        case VBE_DISPI_INDEX_BANK:
599 611
            if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
......
662 674
            }
663 675
            s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
664 676
            s->vbe_regs[s->vbe_index] = val;
677
            vga_update_resolution(s);
665 678
            break;
666 679
        case VBE_DISPI_INDEX_VIRT_WIDTH:
667 680
            {
......
682 695
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
683 696
                s->vbe_line_offset = line_offset;
684 697
            }
698
            vga_update_resolution(s);
685 699
            break;
686 700
        case VBE_DISPI_INDEX_X_OFFSET:
687 701
        case VBE_DISPI_INDEX_Y_OFFSET:
......
696 710
                    s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
697 711
                s->vbe_start_addr >>= 2;
698 712
            }
713
            vga_update_resolution(s);
699 714
            break;
700 715
        default:
701 716
            break;
......
1302 1317
        s->plane_updated = 0;
1303 1318
        full_update = 1;
1304 1319
    }
1305
    full_update |= update_basic_params(s);
1306 1320

  
1307 1321
    line_offset = s->line_offset;
1308 1322
    s1 = s->vram_ptr + (s->start_addr * 4);
......
1314 1328
        return;
1315 1329
    }
1316 1330

  
1317
    if (width != s->last_width || height != s->last_height ||
1318
        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1319
        s->last_scr_width = width * cw;
1320
        s->last_scr_height = height * cheight;
1321
        qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
1322
        s->last_depth = 0;
1323
        s->last_width = width;
1324
        s->last_height = height;
1325
        s->last_ch = cheight;
1326
        s->last_cw = cw;
1327
        full_update = 1;
1328
    }
1329 1331
    s->rgb_to_pixel =
1330 1332
        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1331 1333
    full_update |= update_palette16(s);
......
1582 1584
    vga_dirty_log_start(s);
1583 1585
}
1584 1586

  
1585
/*
1586
 * graphic modes
1587
 */
1588
static void vga_draw_graphic(VGAState *s, int full_update)
1587
static void vga_update_resolution_graphics(VGAState *s)
1589 1588
{
1590
    int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;
1591
    int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
1589
    int depth = s->get_bpp(s);
1590
    int width, height, shift_control, double_scan;
1592 1591
    int disp_width, multi_scan, multi_run;
1593
    uint8_t *d;
1594
    uint32_t v, addr1, addr;
1595
    vga_draw_line_func *vga_draw_line;
1596

  
1597
    full_update |= update_basic_params(s);
1598

  
1599
    if (!full_update)
1600
        vga_sync_dirty_bitmap(s);
1601 1592

  
1602 1593
    s->get_resolution(s, &width, &height);
1603 1594
    disp_width = width;
1604 1595

  
1605 1596
    shift_control = (s->gr[0x05] >> 5) & 3;
1606 1597
    double_scan = (s->cr[0x09] >> 7);
1607
    if (shift_control != 1) {
1608
        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
1609
    } else {
1610
        /* in CGA modes, multi_scan is ignored */
1611
        /* XXX: is it correct ? */
1612
        multi_scan = double_scan;
1613
    }
1614
    multi_run = multi_scan;
1598

  
1615 1599
    if (shift_control != s->shift_control ||
1616 1600
        double_scan != s->double_scan) {
1617
        full_update = 1;
1601
        s->want_full_update = 1;
1618 1602
        s->shift_control = shift_control;
1619 1603
        s->double_scan = double_scan;
1620 1604
    }
......
1628 1612
            disp_width <<= 1;
1629 1613
        }
1630 1614
    }
1615
    disp_width = width;
1616

  
1617
    if (shift_control != 1) {
1618
        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
1619
    } else {
1620
        /* in CGA modes, multi_scan is ignored */
1621
        /* XXX: is it correct ? */
1622
        multi_scan = double_scan;
1623
    }
1624

  
1625
    multi_run = multi_scan;
1631 1626

  
1632
    depth = s->get_bpp(s);
1633 1627
    if (s->line_offset != s->last_line_offset ||
1634 1628
        disp_width != s->last_width ||
1635 1629
        height != s->last_height ||
1636
        s->last_depth != depth) {
1630
        s->last_depth != depth ||
1631
        s->multi_run != multi_run ||
1632
        s->multi_scan != multi_scan ||
1633
        s->want_full_update) {
1634
        if (s->ds->surface->pf.depth == 0) {
1635
            goto dont_touch_display_surface;
1636
        }
1637 1637
#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1638 1638
        if (depth == 16 || depth == 32) {
1639 1639
#else
......
1650 1650
        } else {
1651 1651
            qemu_console_resize(s->ds, disp_width, height);
1652 1652
        }
1653
    dont_touch_display_surface:
1653 1654
        s->last_scr_width = disp_width;
1654 1655
        s->last_scr_height = height;
1655 1656
        s->last_width = disp_width;
1656 1657
        s->last_height = height;
1657 1658
        s->last_line_offset = s->line_offset;
1658 1659
        s->last_depth = depth;
1659
        full_update = 1;
1660
    } else if (is_buffer_shared(s->ds->surface) &&
1660
        s->multi_run = multi_run;
1661
        s->multi_scan = multi_scan;
1662
        s->want_full_update = 1;
1663
    }
1664
}
1665

  
1666
static void vga_update_resolution_text(VGAState *s)
1667
{
1668
    int width, height, cw, cheight;
1669

  
1670
    vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1671
    if (width != s->last_width || height != s->last_height ||
1672
        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1673
        s->last_scr_width = width * cw;
1674
        s->last_scr_height = height * cheight;
1675
        if (s->ds->surface->pf.depth != 0) {
1676
            qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
1677
        } else {
1678
            /*
1679
             * curses expects width and height to be in character cell
1680
             * dimensions, not pixels.
1681
             */
1682
            s->ds->surface->width = width;
1683
            s->ds->surface->height = height;
1684
            dpy_resize(s->ds);
1685
        }
1686
        s->last_depth = 0;
1687
        s->last_width = width;
1688
        s->last_height = height;
1689
        s->last_ch = cheight;
1690
        s->last_cw = cw;
1691
        s->want_full_update = 1;
1692
    }
1693
}
1694

  
1695
void vga_update_resolution(VGAState *s)
1696
{
1697
    int graphic_mode;
1698

  
1699
    if (!(s->ar_index & 0x20)) {
1700
        graphic_mode = GMODE_BLANK;
1701
    } else {
1702
        graphic_mode = s->gr[6] & 1;
1703
    }
1704
    if (graphic_mode != s->graphic_mode) {
1705
        s->graphic_mode = graphic_mode;
1706
        s->want_full_update = 1;
1707
    }
1708
    s->want_full_update |= update_basic_params(s);
1709
    switch (graphic_mode) {
1710
    case GMODE_TEXT:
1711
        vga_update_resolution_text(s);
1712
        break;
1713
    case GMODE_GRAPH:
1714
        vga_update_resolution_graphics(s);
1715
        break;
1716
    }
1717
}
1718

  
1719
/*
1720
 * graphic modes
1721
 */
1722
static void vga_draw_graphic(VGAState *s, int full_update)
1723
{
1724
    int y1, y, update, linesize, y_start, mask;
1725
    int width, height, line_offset, bwidth, bits;
1726
    int multi_run;
1727
    uint8_t *d;
1728
    uint32_t v, addr1, addr;
1729
    long page0, page1, page_min, page_max;
1730
    vga_draw_line_func *vga_draw_line;
1731

  
1732
    if (!full_update)
1733
        vga_sync_dirty_bitmap(s);
1734

  
1735
    s->get_resolution(s, &width, &height);
1736
    multi_run = s->multi_run;
1737
    if (is_buffer_shared(s->ds->surface) &&
1661 1738
               (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
1662 1739
        s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
1663 1740
        dpy_setdata(s->ds);
......
1666 1743
    s->rgb_to_pixel =
1667 1744
        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1668 1745

  
1669
    if (shift_control == 0) {
1746
    if (s->shift_control == 0) {
1670 1747
        full_update |= update_palette16(s);
1671 1748
        if (s->sr[0x01] & 8) {
1672 1749
            v = VGA_DRAW_LINE4D2;
......
1674 1751
            v = VGA_DRAW_LINE4;
1675 1752
        }
1676 1753
        bits = 4;
1677
    } else if (shift_control == 1) {
1754
    } else if (s->shift_control == 1) {
1678 1755
        full_update |= update_palette16(s);
1679 1756
        if (s->sr[0x01] & 8) {
1680 1757
            v = VGA_DRAW_LINE2D2;
......
1770 1847
            if (y_start >= 0) {
1771 1848
                /* flush to display */
1772 1849
                dpy_update(s->ds, 0, y_start,
1773
                           disp_width, y - y_start);
1850
                           s->last_width, y - y_start);
1774 1851
                y_start = -1;
1775 1852
            }
1776 1853
        }
......
1779 1856
            if ((y1 & mask) == mask)
1780 1857
                addr1 += line_offset;
1781 1858
            y1++;
1782
            multi_run = multi_scan;
1859
            multi_run = s->multi_scan;
1783 1860
        } else {
1784 1861
            multi_run--;
1785 1862
        }
......
1791 1868
    if (y_start >= 0) {
1792 1869
        /* flush to display */
1793 1870
        dpy_update(s->ds, 0, y_start,
1794
                   disp_width, y - y_start);
1871
                   s->last_width, y - y_start);
1795 1872
    }
1796 1873
    /* reset modified pages */
1797 1874
    if (page_max != -1) {
......
1828 1905
               s->last_scr_width, s->last_scr_height);
1829 1906
}
1830 1907

  
1831
#define GMODE_TEXT     0
1832
#define GMODE_GRAPH    1
1833
#define GMODE_BLANK 2
1834

  
1835 1908
static void vga_update_display(void *opaque)
1836 1909
{
1837 1910
    VGAState *s = (VGAState *)opaque;
1838
    int full_update, graphic_mode;
1911
    int full_update;
1839 1912

  
1840 1913
    if (ds_get_bits_per_pixel(s->ds) == 0) {
1841 1914
        /* nothing to do */
1842 1915
    } else {
1843
        full_update = 0;
1844
        if (!(s->ar_index & 0x20)) {
1845
            graphic_mode = GMODE_BLANK;
1846
        } else {
1847
            graphic_mode = s->gr[6] & 1;
1848
        }
1849
        if (graphic_mode != s->graphic_mode) {
1850
            s->graphic_mode = graphic_mode;
1851
            full_update = 1;
1852
        }
1853
        switch(graphic_mode) {
1916
        full_update = s->want_full_update;
1917
        s->want_full_update = 0;
1918
        switch(s->graphic_mode) {
1854 1919
        case GMODE_TEXT:
1855 1920
            vga_draw_text(s, full_update);
1856 1921
            break;
......
1870 1935
{
1871 1936
    VGAState *s = (VGAState *)opaque;
1872 1937

  
1873
    s->last_width = -1;
1874
    s->last_height = -1;
1938
    vga_update_resolution(s);
1939
    s->want_full_update = 1;
1875 1940
}
1876 1941

  
1877 1942
void vga_reset(void *opaque)
......
1915 1980
    s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1916 1981
#endif
1917 1982
    memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1918
    s->graphic_mode = -1; /* force full update */
1919 1983
    s->shift_control = 0;
1920 1984
    s->double_scan = 0;
1921 1985
    s->line_offset = 0;
......
1941 2005
        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1942 2006
        break;
1943 2007
    }
2008
    vga_update_resolution(s);
1944 2009
}
1945 2010

  
1946 2011
#define TEXTMODE_X(x)	((x) % width)
......
1952 2017
static void vga_update_text(void *opaque, console_ch_t *chardata)
1953 2018
{
1954 2019
    VGAState *s = (VGAState *) opaque;
1955
    int graphic_mode, i, cursor_offset, cursor_visible;
2020
    int i, cursor_offset, cursor_visible;
1956 2021
    int cw, cheight, width, height, size, c_min, c_max;
1957 2022
    uint32_t *src;
1958 2023
    console_ch_t *dst, val;
1959 2024
    char msg_buffer[80];
1960
    int full_update = 0;
1961

  
1962
    if (!(s->ar_index & 0x20)) {
1963
        graphic_mode = GMODE_BLANK;
1964
    } else {
1965
        graphic_mode = s->gr[6] & 1;
1966
    }
1967
    if (graphic_mode != s->graphic_mode) {
1968
        s->graphic_mode = graphic_mode;
1969
        full_update = 1;
1970
    }
1971
    if (s->last_width == -1) {
1972
        s->last_width = 0;
1973
        full_update = 1;
1974
    }
2025
    int full_update = s->want_full_update;
1975 2026

  
1976
    switch (graphic_mode) {
2027
    s->want_full_update = 0;
2028
    switch (s->graphic_mode) {
1977 2029
    case GMODE_TEXT:
1978 2030
        /* TODO: update palette */
1979
        full_update |= update_basic_params(s);
1980 2031

  
1981
        /* total width & height */
1982
        cheight = (s->cr[9] & 0x1f) + 1;
1983
        cw = 8;
1984
        if (!(s->sr[1] & 0x01))
1985
            cw = 9;
1986
        if (s->sr[1] & 0x08)
1987
            cw = 16; /* NOTE: no 18 pixel wide */
1988
        width = (s->cr[0x01] + 1);
1989
        if (s->cr[0x06] == 100) {
1990
            /* ugly hack for CGA 160x100x16 - explain me the logic */
1991
            height = 100;
1992
        } else {
1993
            height = s->cr[0x12] | 
1994
                ((s->cr[0x07] & 0x02) << 7) | 
1995
                ((s->cr[0x07] & 0x40) << 3);
1996
            height = (height + 1) / cheight;
2032
        vga_get_text_resolution(s, &width, &height, &cw, &cheight);
2033

  
2034
        if (s->ds->surface->width != width
2035
            || s->ds->surface->height != height) {
2036
            s->ds->surface->width = width;
2037
            s->ds->surface->height = height;
2038
            dpy_resize(s->ds);
1997 2039
        }
1998 2040

  
2041
        /* total width & height */
1999 2042
        size = (height * width);
2000 2043
        if (size > CH_ATTR_SIZE) {
2001 2044
            if (!full_update)
......
2006 2049
            break;
2007 2050
        }
2008 2051

  
2009
        if (width != s->last_width || height != s->last_height ||
2010
            cw != s->last_cw || cheight != s->last_ch) {
2011
            s->last_scr_width = width * cw;
2012
            s->last_scr_height = height * cheight;
2013
            s->ds->surface->width = width;
2014
            s->ds->surface->height = height;
2015
            dpy_resize(s->ds);
2016
            s->last_width = width;
2017
            s->last_height = height;
2018
            s->last_ch = cheight;
2019
            s->last_cw = cw;
2020
            full_update = 1;
2021
        }
2022

  
2023 2052
        /* Update "hardware" cursor */
2024 2053
        cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
2025 2054
        if (cursor_offset != s->cursor_offset ||
......
2218 2247
#endif
2219 2248

  
2220 2249
    /* force refresh */
2221
    s->graphic_mode = -1;
2250
    vga_update_resolution(s);
2251
    s->want_full_update = 1;
2222 2252
    return 0;
2223 2253
}
2224 2254

  
......
2641 2671
    ds->surface = qemu_create_displaysurface(ds, w, h);
2642 2672

  
2643 2673
    s->ds = ds;
2644
    s->graphic_mode = -1;
2674
    vga_update_resolution(s);
2675
    s->want_full_update = 1;
2645 2676
    vga_update_display(s);
2646 2677

  
2647 2678
    ppm_save(filename, ds->surface);
......
2672 2703
{
2673 2704
    VGAState *s = (VGAState *)opaque;
2674 2705

  
2675
    if (!(s->ar_index & 0x20))
2676
        vga_screen_dump_blank(s, filename);
2677
    else if (s->gr[6] & 1)
2678
        vga_screen_dump_graphic(s, filename);
2679
    else
2706
    switch (s->graphic_mode) {
2707
    case GMODE_TEXT:
2680 2708
        vga_screen_dump_text(s, filename);
2709
        break;
2710
    case GMODE_GRAPH:
2711
        vga_screen_dump_graphic(s, filename);
2712
        break;
2713
    case GMODE_BLANK:
2714
    default:
2715
        vga_screen_dump_blank(s, filename);
2716
        break;
2717
    }
2681 2718
}
b/hw/vga_int.h
147 147
    DisplayState *ds;                                                   \
148 148
    uint32_t font_offsets[2];                                           \
149 149
    int graphic_mode;                                                   \
150
    int want_full_update;                                               \
150 151
    uint8_t shift_control;                                              \
151 152
    uint8_t double_scan;                                                \
153
    uint8_t multi_run;                                                  \
154
    uint8_t multi_scan;                                                 \
152 155
    uint32_t line_offset;                                               \
153 156
    uint32_t line_compare;                                              \
154 157
    uint32_t start_addr;                                                \
......
195 198
                     ram_addr_t vga_ram_offset, int vga_ram_size);
196 199
void vga_init(VGAState *s);
197 200
void vga_reset(void *s);
201
void vga_update_resolution(VGAState *s);
198 202

  
199 203
void vga_dirty_log_start(VGAState *s);
200 204
void vga_dirty_log_stop(VGAState *s);

Also available in: Unified diff