qemu/hw/display/vga.c
<<
>>
Prefs
   1/*
   2 * QEMU VGA Emulator.
   3 *
   4 * Copyright (c) 2003 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24#include "qemu/osdep.h"
  25#include "qapi/error.h"
  26#include "hw/hw.h"
  27#include "hw/display/vga.h"
  28#include "hw/pci/pci.h"
  29#include "vga_int.h"
  30#include "vga_regs.h"
  31#include "ui/pixel_ops.h"
  32#include "qemu/timer.h"
  33#include "hw/xen/xen.h"
  34#include "trace.h"
  35
  36//#define DEBUG_VGA_MEM
  37//#define DEBUG_VGA_REG
  38
  39/* 16 state changes per vertical frame @60 Hz */
  40#define VGA_TEXT_CURSOR_PERIOD_MS       (1000 * 2 * 16 / 60)
  41
  42/*
  43 * Video Graphics Array (VGA)
  44 *
  45 * Chipset docs for original IBM VGA:
  46 * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
  47 *
  48 * FreeVGA site:
  49 * http://www.osdever.net/FreeVGA/home.htm
  50 *
  51 * Standard VGA features and Bochs VBE extensions are implemented.
  52 */
  53
  54/* force some bits to zero */
  55const uint8_t sr_mask[8] = {
  56    0x03,
  57    0x3d,
  58    0x0f,
  59    0x3f,
  60    0x0e,
  61    0x00,
  62    0x00,
  63    0xff,
  64};
  65
  66const uint8_t gr_mask[16] = {
  67    0x0f, /* 0x00 */
  68    0x0f, /* 0x01 */
  69    0x0f, /* 0x02 */
  70    0x1f, /* 0x03 */
  71    0x03, /* 0x04 */
  72    0x7b, /* 0x05 */
  73    0x0f, /* 0x06 */
  74    0x0f, /* 0x07 */
  75    0xff, /* 0x08 */
  76    0x00, /* 0x09 */
  77    0x00, /* 0x0a */
  78    0x00, /* 0x0b */
  79    0x00, /* 0x0c */
  80    0x00, /* 0x0d */
  81    0x00, /* 0x0e */
  82    0x00, /* 0x0f */
  83};
  84
  85#define cbswap_32(__x) \
  86((uint32_t)( \
  87                (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
  88                (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
  89                (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
  90                (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
  91
  92#ifdef HOST_WORDS_BIGENDIAN
  93#define PAT(x) cbswap_32(x)
  94#else
  95#define PAT(x) (x)
  96#endif
  97
  98#ifdef HOST_WORDS_BIGENDIAN
  99#define BIG 1
 100#else
 101#define BIG 0
 102#endif
 103
 104#ifdef HOST_WORDS_BIGENDIAN
 105#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
 106#else
 107#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
 108#endif
 109
 110static const uint32_t mask16[16] = {
 111    PAT(0x00000000),
 112    PAT(0x000000ff),
 113    PAT(0x0000ff00),
 114    PAT(0x0000ffff),
 115    PAT(0x00ff0000),
 116    PAT(0x00ff00ff),
 117    PAT(0x00ffff00),
 118    PAT(0x00ffffff),
 119    PAT(0xff000000),
 120    PAT(0xff0000ff),
 121    PAT(0xff00ff00),
 122    PAT(0xff00ffff),
 123    PAT(0xffff0000),
 124    PAT(0xffff00ff),
 125    PAT(0xffffff00),
 126    PAT(0xffffffff),
 127};
 128
 129#undef PAT
 130
 131#ifdef HOST_WORDS_BIGENDIAN
 132#define PAT(x) (x)
 133#else
 134#define PAT(x) cbswap_32(x)
 135#endif
 136
 137static uint32_t expand4[256];
 138static uint16_t expand2[256];
 139static uint8_t expand4to8[16];
 140
 141static void vbe_update_vgaregs(VGACommonState *s);
 142
 143static inline bool vbe_enabled(VGACommonState *s)
 144{
 145    return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
 146}
 147
 148static inline uint8_t sr(VGACommonState *s, int idx)
 149{
 150    return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx];
 151}
 152
 153static void vga_update_memory_access(VGACommonState *s)
 154{
 155    hwaddr base, offset, size;
 156
 157    if (s->legacy_address_space == NULL) {
 158        return;
 159    }
 160
 161    if (s->has_chain4_alias) {
 162        memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);
 163        object_unparent(OBJECT(&s->chain4_alias));
 164        s->has_chain4_alias = false;
 165        s->plane_updated = 0xf;
 166    }
 167    if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) ==
 168        VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
 169        offset = 0;
 170        switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
 171        case 0:
 172            base = 0xa0000;
 173            size = 0x20000;
 174            break;
 175        case 1:
 176            base = 0xa0000;
 177            size = 0x10000;
 178            offset = s->bank_offset;
 179            break;
 180        case 2:
 181            base = 0xb0000;
 182            size = 0x8000;
 183            break;
 184        case 3:
 185        default:
 186            base = 0xb8000;
 187            size = 0x8000;
 188            break;
 189        }
 190        assert(offset + size <= s->vram_size);
 191        memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
 192                                 "vga.chain4", &s->vram, offset, size);
 193        memory_region_add_subregion_overlap(s->legacy_address_space, base,
 194                                            &s->chain4_alias, 2);
 195        s->has_chain4_alias = true;
 196    }
 197}
 198
 199static void vga_dumb_update_retrace_info(VGACommonState *s)
 200{
 201    (void) s;
 202}
 203
 204static void vga_precise_update_retrace_info(VGACommonState *s)
 205{
 206    int htotal_chars;
 207    int hretr_start_char;
 208    int hretr_skew_chars;
 209    int hretr_end_char;
 210
 211    int vtotal_lines;
 212    int vretr_start_line;
 213    int vretr_end_line;
 214
 215    int dots;
 216#if 0
 217    int div2, sldiv2;
 218#endif
 219    int clocking_mode;
 220    int clock_sel;
 221    const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
 222    int64_t chars_per_sec;
 223    struct vga_precise_retrace *r = &s->retrace_info.precise;
 224
 225    htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
 226    hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
 227    hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
 228    hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
 229
 230    vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
 231                    (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
 232                      ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
 233    vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
 234        ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
 235          ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
 236    vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
 237
 238    clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1;
 239    clock_sel = (s->msr >> 2) & 3;
 240    dots = (s->msr & 1) ? 8 : 9;
 241
 242    chars_per_sec = clk_hz[clock_sel] / dots;
 243
 244    htotal_chars <<= clocking_mode;
 245
 246    r->total_chars = vtotal_lines * htotal_chars;
 247    if (r->freq) {
 248        r->ticks_per_char = NANOSECONDS_PER_SECOND / (r->total_chars * r->freq);
 249    } else {
 250        r->ticks_per_char = NANOSECONDS_PER_SECOND / chars_per_sec;
 251    }
 252
 253    r->vstart = vretr_start_line;
 254    r->vend = r->vstart + vretr_end_line + 1;
 255
 256    r->hstart = hretr_start_char + hretr_skew_chars;
 257    r->hend = r->hstart + hretr_end_char + 1;
 258    r->htotal = htotal_chars;
 259
 260#if 0
 261    div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
 262    sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
 263    printf (
 264        "hz=%f\n"
 265        "htotal = %d\n"
 266        "hretr_start = %d\n"
 267        "hretr_skew = %d\n"
 268        "hretr_end = %d\n"
 269        "vtotal = %d\n"
 270        "vretr_start = %d\n"
 271        "vretr_end = %d\n"
 272        "div2 = %d sldiv2 = %d\n"
 273        "clocking_mode = %d\n"
 274        "clock_sel = %d %d\n"
 275        "dots = %d\n"
 276        "ticks/char = %" PRId64 "\n"
 277        "\n",
 278        (double) NANOSECONDS_PER_SECOND / (r->ticks_per_char * r->total_chars),
 279        htotal_chars,
 280        hretr_start_char,
 281        hretr_skew_chars,
 282        hretr_end_char,
 283        vtotal_lines,
 284        vretr_start_line,
 285        vretr_end_line,
 286        div2, sldiv2,
 287        clocking_mode,
 288        clock_sel,
 289        clk_hz[clock_sel],
 290        dots,
 291        r->ticks_per_char
 292        );
 293#endif
 294}
 295
 296static uint8_t vga_precise_retrace(VGACommonState *s)
 297{
 298    struct vga_precise_retrace *r = &s->retrace_info.precise;
 299    uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
 300
 301    if (r->total_chars) {
 302        int cur_line, cur_line_char, cur_char;
 303        int64_t cur_tick;
 304
 305        cur_tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 306
 307        cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
 308        cur_line = cur_char / r->htotal;
 309
 310        if (cur_line >= r->vstart && cur_line <= r->vend) {
 311            val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
 312        } else {
 313            cur_line_char = cur_char % r->htotal;
 314            if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
 315                val |= ST01_DISP_ENABLE;
 316            }
 317        }
 318
 319        return val;
 320    } else {
 321        return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
 322    }
 323}
 324
 325static uint8_t vga_dumb_retrace(VGACommonState *s)
 326{
 327    return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
 328}
 329
 330int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
 331{
 332    if (s->msr & VGA_MIS_COLOR) {
 333        /* Color */
 334        return (addr >= 0x3b0 && addr <= 0x3bf);
 335    } else {
 336        /* Monochrome */
 337        return (addr >= 0x3d0 && addr <= 0x3df);
 338    }
 339}
 340
 341uint32_t vga_ioport_read(void *opaque, uint32_t addr)
 342{
 343    VGACommonState *s = opaque;
 344    int val, index;
 345
 346    if (vga_ioport_invalid(s, addr)) {
 347        val = 0xff;
 348    } else {
 349        switch(addr) {
 350        case VGA_ATT_W:
 351            if (s->ar_flip_flop == 0) {
 352                val = s->ar_index;
 353            } else {
 354                val = 0;
 355            }
 356            break;
 357        case VGA_ATT_R:
 358            index = s->ar_index & 0x1f;
 359            if (index < VGA_ATT_C) {
 360                val = s->ar[index];
 361            } else {
 362                val = 0;
 363            }
 364            break;
 365        case VGA_MIS_W:
 366            val = s->st00;
 367            break;
 368        case VGA_SEQ_I:
 369            val = s->sr_index;
 370            break;
 371        case VGA_SEQ_D:
 372            val = s->sr[s->sr_index];
 373#ifdef DEBUG_VGA_REG
 374            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
 375#endif
 376            break;
 377        case VGA_PEL_IR:
 378            val = s->dac_state;
 379            break;
 380        case VGA_PEL_IW:
 381            val = s->dac_write_index;
 382            break;
 383        case VGA_PEL_D:
 384            val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
 385            if (++s->dac_sub_index == 3) {
 386                s->dac_sub_index = 0;
 387                s->dac_read_index++;
 388            }
 389            break;
 390        case VGA_FTC_R:
 391            val = s->fcr;
 392            break;
 393        case VGA_MIS_R:
 394            val = s->msr;
 395            break;
 396        case VGA_GFX_I:
 397            val = s->gr_index;
 398            break;
 399        case VGA_GFX_D:
 400            val = s->gr[s->gr_index];
 401#ifdef DEBUG_VGA_REG
 402            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
 403#endif
 404            break;
 405        case VGA_CRT_IM:
 406        case VGA_CRT_IC:
 407            val = s->cr_index;
 408            break;
 409        case VGA_CRT_DM:
 410        case VGA_CRT_DC:
 411            val = s->cr[s->cr_index];
 412#ifdef DEBUG_VGA_REG
 413            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
 414#endif
 415            break;
 416        case VGA_IS1_RM:
 417        case VGA_IS1_RC:
 418            /* just toggle to fool polling */
 419            val = s->st01 = s->retrace(s);
 420            s->ar_flip_flop = 0;
 421            break;
 422        default:
 423            val = 0x00;
 424            break;
 425        }
 426    }
 427    trace_vga_std_read_io(addr, val);
 428    return val;
 429}
 430
 431void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 432{
 433    VGACommonState *s = opaque;
 434    int index;
 435
 436    /* check port range access depending on color/monochrome mode */
 437    if (vga_ioport_invalid(s, addr)) {
 438        return;
 439    }
 440    trace_vga_std_write_io(addr, val);
 441
 442    switch(addr) {
 443    case VGA_ATT_W:
 444        if (s->ar_flip_flop == 0) {
 445            val &= 0x3f;
 446            s->ar_index = val;
 447        } else {
 448            index = s->ar_index & 0x1f;
 449            switch(index) {
 450            case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
 451                s->ar[index] = val & 0x3f;
 452                break;
 453            case VGA_ATC_MODE:
 454                s->ar[index] = val & ~0x10;
 455                break;
 456            case VGA_ATC_OVERSCAN:
 457                s->ar[index] = val;
 458                break;
 459            case VGA_ATC_PLANE_ENABLE:
 460                s->ar[index] = val & ~0xc0;
 461                break;
 462            case VGA_ATC_PEL:
 463                s->ar[index] = val & ~0xf0;
 464                break;
 465            case VGA_ATC_COLOR_PAGE:
 466                s->ar[index] = val & ~0xf0;
 467                break;
 468            default:
 469                break;
 470            }
 471        }
 472        s->ar_flip_flop ^= 1;
 473        break;
 474    case VGA_MIS_W:
 475        s->msr = val & ~0x10;
 476        s->update_retrace_info(s);
 477        break;
 478    case VGA_SEQ_I:
 479        s->sr_index = val & 7;
 480        break;
 481    case VGA_SEQ_D:
 482#ifdef DEBUG_VGA_REG
 483        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
 484#endif
 485        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
 486        if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
 487            s->update_retrace_info(s);
 488        }
 489        vga_update_memory_access(s);
 490        break;
 491    case VGA_PEL_IR:
 492        s->dac_read_index = val;
 493        s->dac_sub_index = 0;
 494        s->dac_state = 3;
 495        break;
 496    case VGA_PEL_IW:
 497        s->dac_write_index = val;
 498        s->dac_sub_index = 0;
 499        s->dac_state = 0;
 500        break;
 501    case VGA_PEL_D:
 502        s->dac_cache[s->dac_sub_index] = val;
 503        if (++s->dac_sub_index == 3) {
 504            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
 505            s->dac_sub_index = 0;
 506            s->dac_write_index++;
 507        }
 508        break;
 509    case VGA_GFX_I:
 510        s->gr_index = val & 0x0f;
 511        break;
 512    case VGA_GFX_D:
 513#ifdef DEBUG_VGA_REG
 514        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
 515#endif
 516        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
 517        vbe_update_vgaregs(s);
 518        vga_update_memory_access(s);
 519        break;
 520    case VGA_CRT_IM:
 521    case VGA_CRT_IC:
 522        s->cr_index = val;
 523        break;
 524    case VGA_CRT_DM:
 525    case VGA_CRT_DC:
 526#ifdef DEBUG_VGA_REG
 527        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
 528#endif
 529        /* handle CR0-7 protection */
 530        if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
 531            s->cr_index <= VGA_CRTC_OVERFLOW) {
 532            /* can always write bit 4 of CR7 */
 533            if (s->cr_index == VGA_CRTC_OVERFLOW) {
 534                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
 535                    (val & 0x10);
 536                vbe_update_vgaregs(s);
 537            }
 538            return;
 539        }
 540        s->cr[s->cr_index] = val;
 541        vbe_update_vgaregs(s);
 542
 543        switch(s->cr_index) {
 544        case VGA_CRTC_H_TOTAL:
 545        case VGA_CRTC_H_SYNC_START:
 546        case VGA_CRTC_H_SYNC_END:
 547        case VGA_CRTC_V_TOTAL:
 548        case VGA_CRTC_OVERFLOW:
 549        case VGA_CRTC_V_SYNC_END:
 550        case VGA_CRTC_MODE:
 551            s->update_retrace_info(s);
 552            break;
 553        }
 554        break;
 555    case VGA_IS1_RM:
 556    case VGA_IS1_RC:
 557        s->fcr = val & 0x10;
 558        break;
 559    }
 560}
 561
 562/*
 563 * Sanity check vbe register writes.
 564 *
 565 * As we don't have a way to signal errors to the guest in the bochs
 566 * dispi interface we'll go adjust the registers to the closest valid
 567 * value.
 568 */
 569static void vbe_fixup_regs(VGACommonState *s)
 570{
 571    uint16_t *r = s->vbe_regs;
 572    uint32_t bits, linelength, maxy, offset;
 573
 574    if (!vbe_enabled(s)) {
 575        /* vbe is turned off -- nothing to do */
 576        return;
 577    }
 578
 579    /* check depth */
 580    switch (r[VBE_DISPI_INDEX_BPP]) {
 581    case 4:
 582    case 8:
 583    case 16:
 584    case 24:
 585    case 32:
 586        bits = r[VBE_DISPI_INDEX_BPP];
 587        break;
 588    case 15:
 589        bits = 16;
 590        break;
 591    default:
 592        bits = r[VBE_DISPI_INDEX_BPP] = 8;
 593        break;
 594    }
 595
 596    /* check width */
 597    r[VBE_DISPI_INDEX_XRES] &= ~7u;
 598    if (r[VBE_DISPI_INDEX_XRES] == 0) {
 599        r[VBE_DISPI_INDEX_XRES] = 8;
 600    }
 601    if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
 602        r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
 603    }
 604    r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
 605    if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
 606        r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
 607    }
 608    if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
 609        r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
 610    }
 611
 612    /* check height */
 613    linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
 614    maxy = s->vbe_size / linelength;
 615    if (r[VBE_DISPI_INDEX_YRES] == 0) {
 616        r[VBE_DISPI_INDEX_YRES] = 1;
 617    }
 618    if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
 619        r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
 620    }
 621    if (r[VBE_DISPI_INDEX_YRES] > maxy) {
 622        r[VBE_DISPI_INDEX_YRES] = maxy;
 623    }
 624
 625    /* check offset */
 626    if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
 627        r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
 628    }
 629    if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
 630        r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
 631    }
 632    offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
 633    offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
 634    if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
 635        r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
 636        offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
 637        if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
 638            r[VBE_DISPI_INDEX_X_OFFSET] = 0;
 639            offset = 0;
 640        }
 641    }
 642
 643    /* update vga state */
 644    r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
 645    s->vbe_line_offset = linelength;
 646    s->vbe_start_addr  = offset / 4;
 647}
 648
 649/* we initialize the VGA graphic mode */
 650static void vbe_update_vgaregs(VGACommonState *s)
 651{
 652    int h, shift_control;
 653
 654    if (!vbe_enabled(s)) {
 655        /* vbe is turned off -- nothing to do */
 656        return;
 657    }
 658
 659    /* graphic mode + memory map 1 */
 660    s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
 661        VGA_GR06_GRAPHICS_MODE;
 662    s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
 663    s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
 664    /* width */
 665    s->cr[VGA_CRTC_H_DISP] =
 666        (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
 667    /* height (only meaningful if < 1024) */
 668    h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
 669    s->cr[VGA_CRTC_V_DISP_END] = h;
 670    s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
 671        ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
 672    /* line compare to 1023 */
 673    s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
 674    s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
 675    s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
 676
 677    if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
 678        shift_control = 0;
 679        s->sr_vbe[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
 680    } else {
 681        shift_control = 2;
 682        /* set chain 4 mode */
 683        s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
 684        /* activate all planes */
 685        s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
 686    }
 687    s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
 688        (shift_control << 5);
 689    s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
 690}
 691
 692static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 693{
 694    VGACommonState *s = opaque;
 695    return s->vbe_index;
 696}
 697
 698uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
 699{
 700    VGACommonState *s = opaque;
 701    uint32_t val;
 702
 703    if (s->vbe_index < VBE_DISPI_INDEX_NB) {
 704        if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
 705            switch(s->vbe_index) {
 706                /* XXX: do not hardcode ? */
 707            case VBE_DISPI_INDEX_XRES:
 708                val = VBE_DISPI_MAX_XRES;
 709                break;
 710            case VBE_DISPI_INDEX_YRES:
 711                val = VBE_DISPI_MAX_YRES;
 712                break;
 713            case VBE_DISPI_INDEX_BPP:
 714                val = VBE_DISPI_MAX_BPP;
 715                break;
 716            default:
 717                val = s->vbe_regs[s->vbe_index];
 718                break;
 719            }
 720        } else {
 721            val = s->vbe_regs[s->vbe_index];
 722        }
 723    } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
 724        val = s->vbe_size / (64 * 1024);
 725    } else {
 726        val = 0;
 727    }
 728    trace_vga_vbe_read(s->vbe_index, val);
 729    return val;
 730}
 731
 732void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
 733{
 734    VGACommonState *s = opaque;
 735    s->vbe_index = val;
 736}
 737
 738void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 739{
 740    VGACommonState *s = opaque;
 741
 742    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
 743        trace_vga_vbe_write(s->vbe_index, val);
 744        switch(s->vbe_index) {
 745        case VBE_DISPI_INDEX_ID:
 746            if (val == VBE_DISPI_ID0 ||
 747                val == VBE_DISPI_ID1 ||
 748                val == VBE_DISPI_ID2 ||
 749                val == VBE_DISPI_ID3 ||
 750                val == VBE_DISPI_ID4) {
 751                s->vbe_regs[s->vbe_index] = val;
 752            }
 753            break;
 754        case VBE_DISPI_INDEX_XRES:
 755        case VBE_DISPI_INDEX_YRES:
 756        case VBE_DISPI_INDEX_BPP:
 757        case VBE_DISPI_INDEX_VIRT_WIDTH:
 758        case VBE_DISPI_INDEX_X_OFFSET:
 759        case VBE_DISPI_INDEX_Y_OFFSET:
 760            s->vbe_regs[s->vbe_index] = val;
 761            vbe_fixup_regs(s);
 762            vbe_update_vgaregs(s);
 763            break;
 764        case VBE_DISPI_INDEX_BANK:
 765            val &= s->vbe_bank_mask;
 766            s->vbe_regs[s->vbe_index] = val;
 767            s->bank_offset = (val << 16);
 768            vga_update_memory_access(s);
 769            break;
 770        case VBE_DISPI_INDEX_ENABLE:
 771            if ((val & VBE_DISPI_ENABLED) &&
 772                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
 773
 774                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
 775                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
 776                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
 777                s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
 778                vbe_fixup_regs(s);
 779                vbe_update_vgaregs(s);
 780
 781                /* clear the screen */
 782                if (!(val & VBE_DISPI_NOCLEARMEM)) {
 783                    memset(s->vram_ptr, 0,
 784                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 785                }
 786            } else {
 787                s->bank_offset = 0;
 788            }
 789            s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
 790            s->vbe_regs[s->vbe_index] = val;
 791            vga_update_memory_access(s);
 792            break;
 793        default:
 794            break;
 795        }
 796    }
 797}
 798
 799/* called for accesses between 0xa0000 and 0xc0000 */
 800uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
 801{
 802    int memory_map_mode, plane;
 803    uint32_t ret;
 804
 805    /* convert to VGA memory offset */
 806    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
 807    addr &= 0x1ffff;
 808    switch(memory_map_mode) {
 809    case 0:
 810        break;
 811    case 1:
 812        if (addr >= 0x10000)
 813            return 0xff;
 814        addr += s->bank_offset;
 815        break;
 816    case 2:
 817        addr -= 0x10000;
 818        if (addr >= 0x8000)
 819            return 0xff;
 820        break;
 821    default:
 822    case 3:
 823        addr -= 0x18000;
 824        if (addr >= 0x8000)
 825            return 0xff;
 826        break;
 827    }
 828
 829    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
 830        /* chain 4 mode : simplest access */
 831        assert(addr < s->vram_size);
 832        ret = s->vram_ptr[addr];
 833    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 834        /* odd/even mode (aka text mode mapping) */
 835        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 836        addr = ((addr & ~1) << 1) | plane;
 837        if (addr >= s->vram_size) {
 838            return 0xff;
 839        }
 840        ret = s->vram_ptr[addr];
 841    } else {
 842        /* standard VGA latched access */
 843        if (addr * sizeof(uint32_t) >= s->vram_size) {
 844            return 0xff;
 845        }
 846        s->latch = ((uint32_t *)s->vram_ptr)[addr];
 847
 848        if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
 849            /* read mode 0 */
 850            plane = s->gr[VGA_GFX_PLANE_READ];
 851            ret = GET_PLANE(s->latch, plane);
 852        } else {
 853            /* read mode 1 */
 854            ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
 855                mask16[s->gr[VGA_GFX_COMPARE_MASK]];
 856            ret |= ret >> 16;
 857            ret |= ret >> 8;
 858            ret = (~ret) & 0xff;
 859        }
 860    }
 861    return ret;
 862}
 863
 864/* called for accesses between 0xa0000 and 0xc0000 */
 865void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 866{
 867    int memory_map_mode, plane, write_mode, b, func_select, mask;
 868    uint32_t write_mask, bit_mask, set_mask;
 869
 870#ifdef DEBUG_VGA_MEM
 871    printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
 872#endif
 873    /* convert to VGA memory offset */
 874    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
 875    addr &= 0x1ffff;
 876    switch(memory_map_mode) {
 877    case 0:
 878        break;
 879    case 1:
 880        if (addr >= 0x10000)
 881            return;
 882        addr += s->bank_offset;
 883        break;
 884    case 2:
 885        addr -= 0x10000;
 886        if (addr >= 0x8000)
 887            return;
 888        break;
 889    default:
 890    case 3:
 891        addr -= 0x18000;
 892        if (addr >= 0x8000)
 893            return;
 894        break;
 895    }
 896
 897    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
 898        /* chain 4 mode : simplest access */
 899        plane = addr & 3;
 900        mask = (1 << plane);
 901        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
 902            assert(addr < s->vram_size);
 903            s->vram_ptr[addr] = val;
 904#ifdef DEBUG_VGA_MEM
 905            printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 906#endif
 907            s->plane_updated |= mask; /* only used to detect font change */
 908            memory_region_set_dirty(&s->vram, addr, 1);
 909        }
 910    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 911        /* odd/even mode (aka text mode mapping) */
 912        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 913        mask = (1 << plane);
 914        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
 915            addr = ((addr & ~1) << 1) | plane;
 916            if (addr >= s->vram_size) {
 917                return;
 918            }
 919            s->vram_ptr[addr] = val;
 920#ifdef DEBUG_VGA_MEM
 921            printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 922#endif
 923            s->plane_updated |= mask; /* only used to detect font change */
 924            memory_region_set_dirty(&s->vram, addr, 1);
 925        }
 926    } else {
 927        /* standard VGA latched access */
 928        write_mode = s->gr[VGA_GFX_MODE] & 3;
 929        switch(write_mode) {
 930        default:
 931        case 0:
 932            /* rotate */
 933            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
 934            val = ((val >> b) | (val << (8 - b))) & 0xff;
 935            val |= val << 8;
 936            val |= val << 16;
 937
 938            /* apply set/reset mask */
 939            set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
 940            val = (val & ~set_mask) |
 941                (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
 942            bit_mask = s->gr[VGA_GFX_BIT_MASK];
 943            break;
 944        case 1:
 945            val = s->latch;
 946            goto do_write;
 947        case 2:
 948            val = mask16[val & 0x0f];
 949            bit_mask = s->gr[VGA_GFX_BIT_MASK];
 950            break;
 951        case 3:
 952            /* rotate */
 953            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
 954            val = (val >> b) | (val << (8 - b));
 955
 956            bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
 957            val = mask16[s->gr[VGA_GFX_SR_VALUE]];
 958            break;
 959        }
 960
 961        /* apply logical operation */
 962        func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
 963        switch(func_select) {
 964        case 0:
 965        default:
 966            /* nothing to do */
 967            break;
 968        case 1:
 969            /* and */
 970            val &= s->latch;
 971            break;
 972        case 2:
 973            /* or */
 974            val |= s->latch;
 975            break;
 976        case 3:
 977            /* xor */
 978            val ^= s->latch;
 979            break;
 980        }
 981
 982        /* apply bit mask */
 983        bit_mask |= bit_mask << 8;
 984        bit_mask |= bit_mask << 16;
 985        val = (val & bit_mask) | (s->latch & ~bit_mask);
 986
 987    do_write:
 988        /* mask data according to sr[2] */
 989        mask = sr(s, VGA_SEQ_PLANE_WRITE);
 990        s->plane_updated |= mask; /* only used to detect font change */
 991        write_mask = mask16[mask];
 992        if (addr * sizeof(uint32_t) >= s->vram_size) {
 993            return;
 994        }
 995        ((uint32_t *)s->vram_ptr)[addr] =
 996            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
 997            (val & write_mask);
 998#ifdef DEBUG_VGA_MEM
 999        printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
1000               addr * 4, write_mask, val);
1001#endif
1002        memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
1003    }
1004}
1005
1006typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
1007                                uint32_t srcaddr, int width);
1008
1009#include "vga-helpers.h"
1010
1011/* return true if the palette was modified */
1012static int update_palette16(VGACommonState *s)
1013{
1014    int full_update, i;
1015    uint32_t v, col, *palette;
1016
1017    full_update = 0;
1018    palette = s->last_palette;
1019    for(i = 0; i < 16; i++) {
1020        v = s->ar[i];
1021        if (s->ar[VGA_ATC_MODE] & 0x80) {
1022            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1023        } else {
1024            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1025        }
1026        v = v * 3;
1027        col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1028                             c6_to_8(s->palette[v + 1]),
1029                             c6_to_8(s->palette[v + 2]));
1030        if (col != palette[i]) {
1031            full_update = 1;
1032            palette[i] = col;
1033        }
1034    }
1035    return full_update;
1036}
1037
1038/* return true if the palette was modified */
1039static int update_palette256(VGACommonState *s)
1040{
1041    int full_update, i;
1042    uint32_t v, col, *palette;
1043
1044    full_update = 0;
1045    palette = s->last_palette;
1046    v = 0;
1047    for(i = 0; i < 256; i++) {
1048        if (s->dac_8bit) {
1049            col = rgb_to_pixel32(s->palette[v],
1050                                 s->palette[v + 1],
1051                                 s->palette[v + 2]);
1052        } else {
1053            col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1054                                 c6_to_8(s->palette[v + 1]),
1055                                 c6_to_8(s->palette[v + 2]));
1056        }
1057        if (col != palette[i]) {
1058            full_update = 1;
1059            palette[i] = col;
1060        }
1061        v += 3;
1062    }
1063    return full_update;
1064}
1065
1066static void vga_get_offsets(VGACommonState *s,
1067                            uint32_t *pline_offset,
1068                            uint32_t *pstart_addr,
1069                            uint32_t *pline_compare)
1070{
1071    uint32_t start_addr, line_offset, line_compare;
1072
1073    if (vbe_enabled(s)) {
1074        line_offset = s->vbe_line_offset;
1075        start_addr = s->vbe_start_addr;
1076        line_compare = 65535;
1077    } else {
1078        /* compute line_offset in bytes */
1079        line_offset = s->cr[VGA_CRTC_OFFSET];
1080        line_offset <<= 3;
1081
1082        /* starting address */
1083        start_addr = s->cr[VGA_CRTC_START_LO] |
1084            (s->cr[VGA_CRTC_START_HI] << 8);
1085
1086        /* line compare */
1087        line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1088            ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1089            ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1090    }
1091    *pline_offset = line_offset;
1092    *pstart_addr = start_addr;
1093    *pline_compare = line_compare;
1094}
1095
1096/* update start_addr and line_offset. Return TRUE if modified */
1097static int update_basic_params(VGACommonState *s)
1098{
1099    int full_update;
1100    uint32_t start_addr, line_offset, line_compare;
1101
1102    full_update = 0;
1103
1104    s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1105
1106    if (line_offset != s->line_offset ||
1107        start_addr != s->start_addr ||
1108        line_compare != s->line_compare) {
1109        s->line_offset = line_offset;
1110        s->start_addr = start_addr;
1111        s->line_compare = line_compare;
1112        full_update = 1;
1113    }
1114    return full_update;
1115}
1116
1117
1118static const uint8_t cursor_glyph[32 * 4] = {
1119    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1120    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1121    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1122    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1123    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1124    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1125    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1126    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1127    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1128    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1129    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1131    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1132    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1133    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1134    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1135};
1136
1137static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1138                                    int *pcwidth, int *pcheight)
1139{
1140    int width, cwidth, height, cheight;
1141
1142    /* total width & height */
1143    cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1144    cwidth = 8;
1145    if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1146        cwidth = 9;
1147    }
1148    if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1149        cwidth = 16; /* NOTE: no 18 pixel wide */
1150    }
1151    width = (s->cr[VGA_CRTC_H_DISP] + 1);
1152    if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1153        /* ugly hack for CGA 160x100x16 - explain me the logic */
1154        height = 100;
1155    } else {
1156        height = s->cr[VGA_CRTC_V_DISP_END] |
1157            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1158            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1159        height = (height + 1) / cheight;
1160    }
1161
1162    *pwidth = width;
1163    *pheight = height;
1164    *pcwidth = cwidth;
1165    *pcheight = cheight;
1166}
1167
1168/*
1169 * Text mode update
1170 * Missing:
1171 * - double scan
1172 * - double width
1173 * - underline
1174 * - flashing
1175 */
1176static void vga_draw_text(VGACommonState *s, int full_update)
1177{
1178    DisplaySurface *surface = qemu_console_surface(s->con);
1179    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1180    int cx_min, cx_max, linesize, x_incr, line, line1;
1181    uint32_t offset, fgcol, bgcol, v, cursor_offset;
1182    uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1183    const uint8_t *font_ptr, *font_base[2];
1184    int dup9, line_offset;
1185    uint32_t *palette;
1186    uint32_t *ch_attr_ptr;
1187    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1188
1189    /* compute font data address (in plane 2) */
1190    v = sr(s, VGA_SEQ_CHARACTER_MAP);
1191    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1192    if (offset != s->font_offsets[0]) {
1193        s->font_offsets[0] = offset;
1194        full_update = 1;
1195    }
1196    font_base[0] = s->vram_ptr + offset;
1197
1198    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1199    font_base[1] = s->vram_ptr + offset;
1200    if (offset != s->font_offsets[1]) {
1201        s->font_offsets[1] = offset;
1202        full_update = 1;
1203    }
1204    if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
1205        /* if the plane 2 was modified since the last display, it
1206           indicates the font may have been modified */
1207        s->plane_updated = 0;
1208        full_update = 1;
1209    }
1210    full_update |= update_basic_params(s);
1211
1212    line_offset = s->line_offset;
1213
1214    vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1215    if ((height * width) <= 1) {
1216        /* better than nothing: exit if transient size is too small */
1217        return;
1218    }
1219    if ((height * width) > CH_ATTR_SIZE) {
1220        /* better than nothing: exit if transient size is too big */
1221        return;
1222    }
1223
1224    if (width != s->last_width || height != s->last_height ||
1225        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1226        s->last_scr_width = width * cw;
1227        s->last_scr_height = height * cheight;
1228        qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1229        surface = qemu_console_surface(s->con);
1230        dpy_text_resize(s->con, width, height);
1231        s->last_depth = 0;
1232        s->last_width = width;
1233        s->last_height = height;
1234        s->last_ch = cheight;
1235        s->last_cw = cw;
1236        full_update = 1;
1237    }
1238    full_update |= update_palette16(s);
1239    palette = s->last_palette;
1240    x_incr = cw * surface_bytes_per_pixel(surface);
1241
1242    if (full_update) {
1243        s->full_update_text = 1;
1244    }
1245    if (s->full_update_gfx) {
1246        s->full_update_gfx = 0;
1247        full_update |= 1;
1248    }
1249
1250    cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1251                     s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1252    if (cursor_offset != s->cursor_offset ||
1253        s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1254        s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1255      /* if the cursor position changed, we update the old and new
1256         chars */
1257        if (s->cursor_offset < CH_ATTR_SIZE)
1258            s->last_ch_attr[s->cursor_offset] = -1;
1259        if (cursor_offset < CH_ATTR_SIZE)
1260            s->last_ch_attr[cursor_offset] = -1;
1261        s->cursor_offset = cursor_offset;
1262        s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1263        s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1264    }
1265    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1266    if (now >= s->cursor_blink_time) {
1267        s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1268        s->cursor_visible_phase = !s->cursor_visible_phase;
1269    }
1270
1271    dest = surface_data(surface);
1272    linesize = surface_stride(surface);
1273    ch_attr_ptr = s->last_ch_attr;
1274    line = 0;
1275    offset = s->start_addr * 4;
1276    for(cy = 0; cy < height; cy++) {
1277        d1 = dest;
1278        src = s->vram_ptr + offset;
1279        cx_min = width;
1280        cx_max = -1;
1281        for(cx = 0; cx < width; cx++) {
1282            if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
1283                break;
1284            }
1285            ch_attr = *(uint16_t *)src;
1286            if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1287                if (cx < cx_min)
1288                    cx_min = cx;
1289                if (cx > cx_max)
1290                    cx_max = cx;
1291                *ch_attr_ptr = ch_attr;
1292#ifdef HOST_WORDS_BIGENDIAN
1293                ch = ch_attr >> 8;
1294                cattr = ch_attr & 0xff;
1295#else
1296                ch = ch_attr & 0xff;
1297                cattr = ch_attr >> 8;
1298#endif
1299                font_ptr = font_base[(cattr >> 3) & 1];
1300                font_ptr += 32 * 4 * ch;
1301                bgcol = palette[cattr >> 4];
1302                fgcol = palette[cattr & 0x0f];
1303                if (cw == 16) {
1304                    vga_draw_glyph16(d1, linesize,
1305                                     font_ptr, cheight, fgcol, bgcol);
1306                } else if (cw != 9) {
1307                    vga_draw_glyph8(d1, linesize,
1308                                    font_ptr, cheight, fgcol, bgcol);
1309                } else {
1310                    dup9 = 0;
1311                    if (ch >= 0xb0 && ch <= 0xdf &&
1312                        (s->ar[VGA_ATC_MODE] & 0x04)) {
1313                        dup9 = 1;
1314                    }
1315                    vga_draw_glyph9(d1, linesize,
1316                                    font_ptr, cheight, fgcol, bgcol, dup9);
1317                }
1318                if (src == cursor_ptr &&
1319                    !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1320                    s->cursor_visible_phase) {
1321                    int line_start, line_last, h;
1322                    /* draw the cursor */
1323                    line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1324                    line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1325                    /* XXX: check that */
1326                    if (line_last > cheight - 1)
1327                        line_last = cheight - 1;
1328                    if (line_last >= line_start && line_start < cheight) {
1329                        h = line_last - line_start + 1;
1330                        d = d1 + linesize * line_start;
1331                        if (cw == 16) {
1332                            vga_draw_glyph16(d, linesize,
1333                                             cursor_glyph, h, fgcol, bgcol);
1334                        } else if (cw != 9) {
1335                            vga_draw_glyph8(d, linesize,
1336                                            cursor_glyph, h, fgcol, bgcol);
1337                        } else {
1338                            vga_draw_glyph9(d, linesize,
1339                                            cursor_glyph, h, fgcol, bgcol, 1);
1340                        }
1341                    }
1342                }
1343            }
1344            d1 += x_incr;
1345            src += 4;
1346            ch_attr_ptr++;
1347        }
1348        if (cx_max != -1) {
1349            dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1350                           (cx_max - cx_min + 1) * cw, cheight);
1351        }
1352        dest += linesize * cheight;
1353        line1 = line + cheight;
1354        offset += line_offset;
1355        if (line < s->line_compare && line1 >= s->line_compare) {
1356            offset = 0;
1357        }
1358        line = line1;
1359    }
1360}
1361
1362enum {
1363    VGA_DRAW_LINE2,
1364    VGA_DRAW_LINE2D2,
1365    VGA_DRAW_LINE4,
1366    VGA_DRAW_LINE4D2,
1367    VGA_DRAW_LINE8D2,
1368    VGA_DRAW_LINE8,
1369    VGA_DRAW_LINE15_LE,
1370    VGA_DRAW_LINE16_LE,
1371    VGA_DRAW_LINE24_LE,
1372    VGA_DRAW_LINE32_LE,
1373    VGA_DRAW_LINE15_BE,
1374    VGA_DRAW_LINE16_BE,
1375    VGA_DRAW_LINE24_BE,
1376    VGA_DRAW_LINE32_BE,
1377    VGA_DRAW_LINE_NB,
1378};
1379
1380static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
1381    vga_draw_line2,
1382    vga_draw_line2d2,
1383    vga_draw_line4,
1384    vga_draw_line4d2,
1385    vga_draw_line8d2,
1386    vga_draw_line8,
1387    vga_draw_line15_le,
1388    vga_draw_line16_le,
1389    vga_draw_line24_le,
1390    vga_draw_line32_le,
1391    vga_draw_line15_be,
1392    vga_draw_line16_be,
1393    vga_draw_line24_be,
1394    vga_draw_line32_be,
1395};
1396
1397static int vga_get_bpp(VGACommonState *s)
1398{
1399    int ret;
1400
1401    if (vbe_enabled(s)) {
1402        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1403    } else {
1404        ret = 0;
1405    }
1406    return ret;
1407}
1408
1409static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1410{
1411    int width, height;
1412
1413    if (vbe_enabled(s)) {
1414        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1415        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1416    } else {
1417        width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1418        height = s->cr[VGA_CRTC_V_DISP_END] |
1419            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1420            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1421        height = (height + 1);
1422    }
1423    *pwidth = width;
1424    *pheight = height;
1425}
1426
1427void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1428{
1429    int y;
1430    if (y1 >= VGA_MAX_HEIGHT)
1431        return;
1432    if (y2 >= VGA_MAX_HEIGHT)
1433        y2 = VGA_MAX_HEIGHT;
1434    for(y = y1; y < y2; y++) {
1435        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1436    }
1437}
1438
1439static bool vga_scanline_invalidated(VGACommonState *s, int y)
1440{
1441    if (y >= VGA_MAX_HEIGHT) {
1442        return false;
1443    }
1444    return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
1445}
1446
1447void vga_dirty_log_start(VGACommonState *s)
1448{
1449    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1450}
1451
1452void vga_dirty_log_stop(VGACommonState *s)
1453{
1454    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1455}
1456
1457/*
1458 * graphic modes
1459 */
1460static void vga_draw_graphic(VGACommonState *s, int full_update)
1461{
1462    DisplaySurface *surface = qemu_console_surface(s->con);
1463    int y1, y, update, linesize, y_start, double_scan, mask, depth;
1464    int width, height, shift_control, bwidth, bits;
1465    ram_addr_t page0, page1, region_start, region_end;
1466    DirtyBitmapSnapshot *snap = NULL;
1467    int disp_width, multi_scan, multi_run;
1468    uint8_t *d;
1469    uint32_t v, addr1, addr;
1470    vga_draw_line_func *vga_draw_line = NULL;
1471    bool share_surface, force_shadow = false;
1472    pixman_format_code_t format;
1473#ifdef HOST_WORDS_BIGENDIAN
1474    bool byteswap = !s->big_endian_fb;
1475#else
1476    bool byteswap = s->big_endian_fb;
1477#endif
1478
1479    full_update |= update_basic_params(s);
1480
1481    s->get_resolution(s, &width, &height);
1482    disp_width = width;
1483
1484    region_start = (s->start_addr * 4);
1485    region_end = region_start + (ram_addr_t)s->line_offset * height;
1486    region_end += width * s->get_bpp(s) / 8; /* scanline length */
1487    region_end -= s->line_offset;
1488    if (region_end > s->vbe_size) {
1489        /* wraps around (can happen with cirrus vbe modes) */
1490        region_start = 0;
1491        region_end = s->vbe_size;
1492        force_shadow = true;
1493    }
1494
1495    shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1496    double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1497    if (shift_control != 1) {
1498        multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1499            - 1;
1500    } else {
1501        /* in CGA modes, multi_scan is ignored */
1502        /* XXX: is it correct ? */
1503        multi_scan = double_scan;
1504    }
1505    multi_run = multi_scan;
1506    if (shift_control != s->shift_control ||
1507        double_scan != s->double_scan) {
1508        full_update = 1;
1509        s->shift_control = shift_control;
1510        s->double_scan = double_scan;
1511    }
1512
1513    if (shift_control == 0) {
1514        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1515            disp_width <<= 1;
1516        }
1517    } else if (shift_control == 1) {
1518        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1519            disp_width <<= 1;
1520        }
1521    }
1522
1523    depth = s->get_bpp(s);
1524
1525    /*
1526     * Check whether we can share the surface with the backend
1527     * or whether we need a shadow surface. We share native
1528     * endian surfaces for 15bpp and above and byteswapped
1529     * surfaces for 24bpp and above.
1530     */
1531    format = qemu_default_pixman_format(depth, !byteswap);
1532    if (format) {
1533        share_surface = dpy_gfx_check_format(s->con, format)
1534            && !s->force_shadow && !force_shadow;
1535    } else {
1536        share_surface = false;
1537    }
1538    if (s->line_offset != s->last_line_offset ||
1539        disp_width != s->last_width ||
1540        height != s->last_height ||
1541        s->last_depth != depth ||
1542        s->last_byteswap != byteswap ||
1543        share_surface != is_buffer_shared(surface)) {
1544        if (share_surface) {
1545            surface = qemu_create_displaysurface_from(disp_width,
1546                    height, format, s->line_offset,
1547                    s->vram_ptr + (s->start_addr * 4));
1548            dpy_gfx_replace_surface(s->con, surface);
1549        } else {
1550            qemu_console_resize(s->con, disp_width, height);
1551            surface = qemu_console_surface(s->con);
1552        }
1553        s->last_scr_width = disp_width;
1554        s->last_scr_height = height;
1555        s->last_width = disp_width;
1556        s->last_height = height;
1557        s->last_line_offset = s->line_offset;
1558        s->last_depth = depth;
1559        s->last_byteswap = byteswap;
1560        full_update = 1;
1561    } else if (is_buffer_shared(surface) &&
1562               (full_update || surface_data(surface) != s->vram_ptr
1563                + (s->start_addr * 4))) {
1564        pixman_format_code_t format =
1565            qemu_default_pixman_format(depth, !byteswap);
1566        surface = qemu_create_displaysurface_from(disp_width,
1567                height, format, s->line_offset,
1568                s->vram_ptr + (s->start_addr * 4));
1569        dpy_gfx_replace_surface(s->con, surface);
1570    }
1571
1572    if (shift_control == 0) {
1573        full_update |= update_palette16(s);
1574        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1575            v = VGA_DRAW_LINE4D2;
1576        } else {
1577            v = VGA_DRAW_LINE4;
1578        }
1579        bits = 4;
1580    } else if (shift_control == 1) {
1581        full_update |= update_palette16(s);
1582        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1583            v = VGA_DRAW_LINE2D2;
1584        } else {
1585            v = VGA_DRAW_LINE2;
1586        }
1587        bits = 4;
1588    } else {
1589        switch(s->get_bpp(s)) {
1590        default:
1591        case 0:
1592            full_update |= update_palette256(s);
1593            v = VGA_DRAW_LINE8D2;
1594            bits = 4;
1595            break;
1596        case 8:
1597            full_update |= update_palette256(s);
1598            v = VGA_DRAW_LINE8;
1599            bits = 8;
1600            break;
1601        case 15:
1602            v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1603            bits = 16;
1604            break;
1605        case 16:
1606            v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1607            bits = 16;
1608            break;
1609        case 24:
1610            v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1611            bits = 24;
1612            break;
1613        case 32:
1614            v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1615            bits = 32;
1616            break;
1617        }
1618    }
1619    vga_draw_line = vga_draw_line_table[v];
1620
1621    if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1622        s->cursor_invalidate(s);
1623    }
1624
1625#if 0
1626    printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
1627           width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1628           s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1629#endif
1630    addr1 = (s->start_addr * 4);
1631    bwidth = DIV_ROUND_UP(width * bits, 8);
1632    y_start = -1;
1633    d = surface_data(surface);
1634    linesize = surface_stride(surface);
1635    y1 = 0;
1636
1637    if (!full_update) {
1638        if (s->line_compare < height) {
1639            /* split screen mode */
1640            region_start = 0;
1641        }
1642        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
1643                                                      region_end - region_start,
1644                                                      DIRTY_MEMORY_VGA);
1645    }
1646
1647    for(y = 0; y < height; y++) {
1648        addr = addr1;
1649        if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1650            int shift;
1651            /* CGA compatibility handling */
1652            shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1653            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1654        }
1655        if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1656            addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1657        }
1658        update = full_update;
1659        page0 = addr & s->vbe_size_mask;
1660        page1 = (addr + bwidth - 1) & s->vbe_size_mask;
1661        if (full_update) {
1662            update = 1;
1663        } else if (page1 < page0) {
1664            /* scanline wraps from end of video memory to the start */
1665            assert(force_shadow);
1666            update = memory_region_snapshot_get_dirty(&s->vram, snap,
1667                                                      page0, s->vbe_size - page0);
1668            update |= memory_region_snapshot_get_dirty(&s->vram, snap,
1669                                                       0, page1);
1670        } else {
1671            update = memory_region_snapshot_get_dirty(&s->vram, snap,
1672                                                      page0, page1 - page0);
1673        }
1674        /* explicit invalidation for the hardware cursor (cirrus only) */
1675        update |= vga_scanline_invalidated(s, y);
1676        if (update) {
1677            if (y_start < 0)
1678                y_start = y;
1679            if (!(is_buffer_shared(surface))) {
1680                vga_draw_line(s, d, addr, width);
1681                if (s->cursor_draw_line)
1682                    s->cursor_draw_line(s, d, y);
1683            }
1684        } else {
1685            if (y_start >= 0) {
1686                /* flush to display */
1687                dpy_gfx_update(s->con, 0, y_start,
1688                               disp_width, y - y_start);
1689                y_start = -1;
1690            }
1691        }
1692        if (!multi_run) {
1693            mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1694            if ((y1 & mask) == mask)
1695                addr1 += s->line_offset;
1696            y1++;
1697            multi_run = multi_scan;
1698        } else {
1699            multi_run--;
1700        }
1701        /* line compare acts on the displayed lines */
1702        if (y == s->line_compare)
1703            addr1 = 0;
1704        d += linesize;
1705    }
1706    if (y_start >= 0) {
1707        /* flush to display */
1708        dpy_gfx_update(s->con, 0, y_start,
1709                       disp_width, y - y_start);
1710    }
1711    g_free(snap);
1712    memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
1713}
1714
1715static void vga_draw_blank(VGACommonState *s, int full_update)
1716{
1717    DisplaySurface *surface = qemu_console_surface(s->con);
1718    int i, w;
1719    uint8_t *d;
1720
1721    if (!full_update)
1722        return;
1723    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1724        return;
1725
1726    w = s->last_scr_width * surface_bytes_per_pixel(surface);
1727    d = surface_data(surface);
1728    for(i = 0; i < s->last_scr_height; i++) {
1729        memset(d, 0, w);
1730        d += surface_stride(surface);
1731    }
1732    dpy_gfx_update(s->con, 0, 0,
1733                   s->last_scr_width, s->last_scr_height);
1734}
1735
1736#define GMODE_TEXT     0
1737#define GMODE_GRAPH    1
1738#define GMODE_BLANK 2
1739
1740static void vga_update_display(void *opaque)
1741{
1742    VGACommonState *s = opaque;
1743    DisplaySurface *surface = qemu_console_surface(s->con);
1744    int full_update, graphic_mode;
1745
1746    qemu_flush_coalesced_mmio_buffer();
1747
1748    if (surface_bits_per_pixel(surface) == 0) {
1749        /* nothing to do */
1750    } else {
1751        full_update = 0;
1752        if (!(s->ar_index & 0x20)) {
1753            graphic_mode = GMODE_BLANK;
1754        } else {
1755            graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1756        }
1757        if (graphic_mode != s->graphic_mode) {
1758            s->graphic_mode = graphic_mode;
1759            s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1760            full_update = 1;
1761        }
1762        switch(graphic_mode) {
1763        case GMODE_TEXT:
1764            vga_draw_text(s, full_update);
1765            break;
1766        case GMODE_GRAPH:
1767            vga_draw_graphic(s, full_update);
1768            break;
1769        case GMODE_BLANK:
1770        default:
1771            vga_draw_blank(s, full_update);
1772            break;
1773        }
1774    }
1775}
1776
1777/* force a full display refresh */
1778static void vga_invalidate_display(void *opaque)
1779{
1780    VGACommonState *s = opaque;
1781
1782    s->last_width = -1;
1783    s->last_height = -1;
1784}
1785
1786void vga_common_reset(VGACommonState *s)
1787{
1788    s->sr_index = 0;
1789    memset(s->sr, '\0', sizeof(s->sr));
1790    memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1791    s->gr_index = 0;
1792    memset(s->gr, '\0', sizeof(s->gr));
1793    s->ar_index = 0;
1794    memset(s->ar, '\0', sizeof(s->ar));
1795    s->ar_flip_flop = 0;
1796    s->cr_index = 0;
1797    memset(s->cr, '\0', sizeof(s->cr));
1798    s->msr = 0;
1799    s->fcr = 0;
1800    s->st00 = 0;
1801    s->st01 = 0;
1802    s->dac_state = 0;
1803    s->dac_sub_index = 0;
1804    s->dac_read_index = 0;
1805    s->dac_write_index = 0;
1806    memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1807    s->dac_8bit = 0;
1808    memset(s->palette, '\0', sizeof(s->palette));
1809    s->bank_offset = 0;
1810    s->vbe_index = 0;
1811    memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1812    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1813    s->vbe_start_addr = 0;
1814    s->vbe_line_offset = 0;
1815    s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1816    memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1817    s->graphic_mode = -1; /* force full update */
1818    s->shift_control = 0;
1819    s->double_scan = 0;
1820    s->line_offset = 0;
1821    s->line_compare = 0;
1822    s->start_addr = 0;
1823    s->plane_updated = 0;
1824    s->last_cw = 0;
1825    s->last_ch = 0;
1826    s->last_width = 0;
1827    s->last_height = 0;
1828    s->last_scr_width = 0;
1829    s->last_scr_height = 0;
1830    s->cursor_start = 0;
1831    s->cursor_end = 0;
1832    s->cursor_offset = 0;
1833    s->big_endian_fb = s->default_endian_fb;
1834    memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1835    memset(s->last_palette, '\0', sizeof(s->last_palette));
1836    memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1837    switch (vga_retrace_method) {
1838    case VGA_RETRACE_DUMB:
1839        break;
1840    case VGA_RETRACE_PRECISE:
1841        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1842        break;
1843    }
1844    vga_update_memory_access(s);
1845}
1846
1847static void vga_reset(void *opaque)
1848{
1849    VGACommonState *s =  opaque;
1850    vga_common_reset(s);
1851}
1852
1853#define TEXTMODE_X(x)   ((x) % width)
1854#define TEXTMODE_Y(x)   ((x) / width)
1855#define VMEM2CHTYPE(v)  ((v & 0xff0007ff) | \
1856        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1857/* relay text rendering to the display driver
1858 * instead of doing a full vga_update_display() */
1859static void vga_update_text(void *opaque, console_ch_t *chardata)
1860{
1861    VGACommonState *s =  opaque;
1862    int graphic_mode, i, cursor_offset, cursor_visible;
1863    int cw, cheight, width, height, size, c_min, c_max;
1864    uint32_t *src;
1865    console_ch_t *dst, val;
1866    char msg_buffer[80];
1867    int full_update = 0;
1868
1869    qemu_flush_coalesced_mmio_buffer();
1870
1871    if (!(s->ar_index & 0x20)) {
1872        graphic_mode = GMODE_BLANK;
1873    } else {
1874        graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1875    }
1876    if (graphic_mode != s->graphic_mode) {
1877        s->graphic_mode = graphic_mode;
1878        full_update = 1;
1879    }
1880    if (s->last_width == -1) {
1881        s->last_width = 0;
1882        full_update = 1;
1883    }
1884
1885    switch (graphic_mode) {
1886    case GMODE_TEXT:
1887        /* TODO: update palette */
1888        full_update |= update_basic_params(s);
1889
1890        /* total width & height */
1891        cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1892        cw = 8;
1893        if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1894            cw = 9;
1895        }
1896        if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1897            cw = 16; /* NOTE: no 18 pixel wide */
1898        }
1899        width = (s->cr[VGA_CRTC_H_DISP] + 1);
1900        if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1901            /* ugly hack for CGA 160x100x16 - explain me the logic */
1902            height = 100;
1903        } else {
1904            height = s->cr[VGA_CRTC_V_DISP_END] |
1905                ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1906                ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1907            height = (height + 1) / cheight;
1908        }
1909
1910        size = (height * width);
1911        if (size > CH_ATTR_SIZE) {
1912            if (!full_update)
1913                return;
1914
1915            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1916                     width, height);
1917            break;
1918        }
1919
1920        if (width != s->last_width || height != s->last_height ||
1921            cw != s->last_cw || cheight != s->last_ch) {
1922            s->last_scr_width = width * cw;
1923            s->last_scr_height = height * cheight;
1924            qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1925            dpy_text_resize(s->con, width, height);
1926            s->last_depth = 0;
1927            s->last_width = width;
1928            s->last_height = height;
1929            s->last_ch = cheight;
1930            s->last_cw = cw;
1931            full_update = 1;
1932        }
1933
1934        if (full_update) {
1935            s->full_update_gfx = 1;
1936        }
1937        if (s->full_update_text) {
1938            s->full_update_text = 0;
1939            full_update |= 1;
1940        }
1941
1942        /* Update "hardware" cursor */
1943        cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1944                         s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1945        if (cursor_offset != s->cursor_offset ||
1946            s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1947            s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1948            cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1949            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1950                dpy_text_cursor(s->con,
1951                                TEXTMODE_X(cursor_offset),
1952                                TEXTMODE_Y(cursor_offset));
1953            else
1954                dpy_text_cursor(s->con, -1, -1);
1955            s->cursor_offset = cursor_offset;
1956            s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1957            s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1958        }
1959
1960        src = (uint32_t *) s->vram_ptr + s->start_addr;
1961        dst = chardata;
1962
1963        if (full_update) {
1964            for (i = 0; i < size; src ++, dst ++, i ++)
1965                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1966
1967            dpy_text_update(s->con, 0, 0, width, height);
1968        } else {
1969            c_max = 0;
1970
1971            for (i = 0; i < size; src ++, dst ++, i ++) {
1972                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1973                if (*dst != val) {
1974                    *dst = val;
1975                    c_max = i;
1976                    break;
1977                }
1978            }
1979            c_min = i;
1980            for (; i < size; src ++, dst ++, i ++) {
1981                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1982                if (*dst != val) {
1983                    *dst = val;
1984                    c_max = i;
1985                }
1986            }
1987
1988            if (c_min <= c_max) {
1989                i = TEXTMODE_Y(c_min);
1990                dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
1991            }
1992        }
1993
1994        return;
1995    case GMODE_GRAPH:
1996        if (!full_update)
1997            return;
1998
1999        s->get_resolution(s, &width, &height);
2000        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2001                 width, height);
2002        break;
2003    case GMODE_BLANK:
2004    default:
2005        if (!full_update)
2006            return;
2007
2008        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2009        break;
2010    }
2011
2012    /* Display a message */
2013    s->last_width = 60;
2014    s->last_height = height = 3;
2015    dpy_text_cursor(s->con, -1, -1);
2016    dpy_text_resize(s->con, s->last_width, height);
2017
2018    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2019        console_write_ch(dst ++, ' ');
2020
2021    size = strlen(msg_buffer);
2022    width = (s->last_width - size) / 2;
2023    dst = chardata + s->last_width + width;
2024    for (i = 0; i < size; i ++)
2025        console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2026                                             QEMU_COLOR_BLACK, 1));
2027
2028    dpy_text_update(s->con, 0, 0, s->last_width, height);
2029}
2030
2031static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2032                             unsigned size)
2033{
2034    VGACommonState *s = opaque;
2035
2036    return vga_mem_readb(s, addr);
2037}
2038
2039static void vga_mem_write(void *opaque, hwaddr addr,
2040                          uint64_t data, unsigned size)
2041{
2042    VGACommonState *s = opaque;
2043
2044    vga_mem_writeb(s, addr, data);
2045}
2046
2047const MemoryRegionOps vga_mem_ops = {
2048    .read = vga_mem_read,
2049    .write = vga_mem_write,
2050    .endianness = DEVICE_LITTLE_ENDIAN,
2051    .impl = {
2052        .min_access_size = 1,
2053        .max_access_size = 1,
2054    },
2055};
2056
2057static int vga_common_post_load(void *opaque, int version_id)
2058{
2059    VGACommonState *s = opaque;
2060
2061    /* force refresh */
2062    s->graphic_mode = -1;
2063    vbe_update_vgaregs(s);
2064    vga_update_memory_access(s);
2065    return 0;
2066}
2067
2068static bool vga_endian_state_needed(void *opaque)
2069{
2070    VGACommonState *s = opaque;
2071
2072    /*
2073     * Only send the endian state if it's different from the
2074     * default one, thus ensuring backward compatibility for
2075     * migration of the common case
2076     */
2077    return s->default_endian_fb != s->big_endian_fb;
2078}
2079
2080static const VMStateDescription vmstate_vga_endian = {
2081    .name = "vga.endian",
2082    .version_id = 1,
2083    .minimum_version_id = 1,
2084    .needed = vga_endian_state_needed,
2085    .fields = (VMStateField[]) {
2086        VMSTATE_BOOL(big_endian_fb, VGACommonState),
2087        VMSTATE_END_OF_LIST()
2088    }
2089};
2090
2091const VMStateDescription vmstate_vga_common = {
2092    .name = "vga",
2093    .version_id = 2,
2094    .minimum_version_id = 2,
2095    .post_load = vga_common_post_load,
2096    .fields = (VMStateField[]) {
2097        VMSTATE_UINT32(latch, VGACommonState),
2098        VMSTATE_UINT8(sr_index, VGACommonState),
2099        VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2100        VMSTATE_UINT8(gr_index, VGACommonState),
2101        VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2102        VMSTATE_UINT8(ar_index, VGACommonState),
2103        VMSTATE_BUFFER(ar, VGACommonState),
2104        VMSTATE_INT32(ar_flip_flop, VGACommonState),
2105        VMSTATE_UINT8(cr_index, VGACommonState),
2106        VMSTATE_BUFFER(cr, VGACommonState),
2107        VMSTATE_UINT8(msr, VGACommonState),
2108        VMSTATE_UINT8(fcr, VGACommonState),
2109        VMSTATE_UINT8(st00, VGACommonState),
2110        VMSTATE_UINT8(st01, VGACommonState),
2111
2112        VMSTATE_UINT8(dac_state, VGACommonState),
2113        VMSTATE_UINT8(dac_sub_index, VGACommonState),
2114        VMSTATE_UINT8(dac_read_index, VGACommonState),
2115        VMSTATE_UINT8(dac_write_index, VGACommonState),
2116        VMSTATE_BUFFER(dac_cache, VGACommonState),
2117        VMSTATE_BUFFER(palette, VGACommonState),
2118
2119        VMSTATE_INT32(bank_offset, VGACommonState),
2120        VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
2121        VMSTATE_UINT16(vbe_index, VGACommonState),
2122        VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2123        VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2124        VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2125        VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2126        VMSTATE_END_OF_LIST()
2127    },
2128    .subsections = (const VMStateDescription*[]) {
2129        &vmstate_vga_endian,
2130        NULL
2131    }
2132};
2133
2134static const GraphicHwOps vga_ops = {
2135    .invalidate  = vga_invalidate_display,
2136    .gfx_update  = vga_update_display,
2137    .text_update = vga_update_text,
2138};
2139
2140static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2141{
2142    if (val < vmin) {
2143        return vmin;
2144    }
2145    if (val > vmax) {
2146        return vmax;
2147    }
2148    return val;
2149}
2150
2151void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
2152{
2153    int i, j, v, b;
2154
2155    for(i = 0;i < 256; i++) {
2156        v = 0;
2157        for(j = 0; j < 8; j++) {
2158            v |= ((i >> j) & 1) << (j * 4);
2159        }
2160        expand4[i] = v;
2161
2162        v = 0;
2163        for(j = 0; j < 4; j++) {
2164            v |= ((i >> (2 * j)) & 3) << (j * 4);
2165        }
2166        expand2[i] = v;
2167    }
2168    for(i = 0; i < 16; i++) {
2169        v = 0;
2170        for(j = 0; j < 4; j++) {
2171            b = ((i >> j) & 1);
2172            v |= b << (2 * j);
2173            v |= b << (2 * j + 1);
2174        }
2175        expand4to8[i] = v;
2176    }
2177
2178    s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2179    s->vram_size_mb = pow2ceil(s->vram_size_mb);
2180    s->vram_size = s->vram_size_mb << 20;
2181
2182    if (!s->vbe_size) {
2183        s->vbe_size = s->vram_size;
2184    }
2185    s->vbe_size_mask = s->vbe_size - 1;
2186
2187    s->is_vbe_vmstate = 1;
2188    memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
2189                           &error_fatal);
2190    vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj));
2191    xen_register_framebuffer(&s->vram);
2192    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2193    s->get_bpp = vga_get_bpp;
2194    s->get_offsets = vga_get_offsets;
2195    s->get_resolution = vga_get_resolution;
2196    s->hw_ops = &vga_ops;
2197    switch (vga_retrace_method) {
2198    case VGA_RETRACE_DUMB:
2199        s->retrace = vga_dumb_retrace;
2200        s->update_retrace_info = vga_dumb_update_retrace_info;
2201        break;
2202
2203    case VGA_RETRACE_PRECISE:
2204        s->retrace = vga_precise_retrace;
2205        s->update_retrace_info = vga_precise_update_retrace_info;
2206        break;
2207    }
2208
2209    /*
2210     * Set default fb endian based on target, could probably be turned
2211     * into a device attribute set by the machine/platform to remove
2212     * all target endian dependencies from this file.
2213     */
2214#ifdef TARGET_WORDS_BIGENDIAN
2215    s->default_endian_fb = true;
2216#else
2217    s->default_endian_fb = false;
2218#endif
2219    vga_dirty_log_start(s);
2220}
2221
2222static const MemoryRegionPortio vga_portio_list[] = {
2223    { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2224    { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2225    { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2226    { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2227    { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2228    PORTIO_END_OF_LIST(),
2229};
2230
2231static const MemoryRegionPortio vbe_portio_list[] = {
2232    { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2233# ifdef TARGET_I386
2234    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2235# endif
2236    { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2237    PORTIO_END_OF_LIST(),
2238};
2239
2240/* Used by both ISA and PCI */
2241MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2242                          const MemoryRegionPortio **vga_ports,
2243                          const MemoryRegionPortio **vbe_ports)
2244{
2245    MemoryRegion *vga_mem;
2246
2247    *vga_ports = vga_portio_list;
2248    *vbe_ports = vbe_portio_list;
2249
2250    vga_mem = g_malloc(sizeof(*vga_mem));
2251    memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2252                          "vga-lowmem", 0x20000);
2253    memory_region_set_flush_coalesced(vga_mem);
2254
2255    return vga_mem;
2256}
2257
2258void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2259              MemoryRegion *address_space_io, bool init_vga_ports)
2260{
2261    MemoryRegion *vga_io_memory;
2262    const MemoryRegionPortio *vga_ports, *vbe_ports;
2263
2264    qemu_register_reset(vga_reset, s);
2265
2266    s->bank_offset = 0;
2267
2268    s->legacy_address_space = address_space;
2269
2270    vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2271    memory_region_add_subregion_overlap(address_space,
2272                                        0x000a0000,
2273                                        vga_io_memory,
2274                                        1);
2275    memory_region_set_coalescing(vga_io_memory);
2276    if (init_vga_ports) {
2277        portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2278        portio_list_set_flush_coalesced(&s->vga_port_list);
2279        portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2280    }
2281    if (vbe_ports) {
2282        portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2283        portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2284    }
2285}
2286
2287void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2288{
2289    /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2290     * so use an alias to avoid double-mapping the same region.
2291     */
2292    memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2293                             &s->vram, 0, memory_region_size(&s->vram));
2294    /* XXX: use optimized standard vga accesses */
2295    memory_region_add_subregion(system_memory,
2296                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2297                                &s->vram_vbe);
2298    s->vbe_mapped = 1;
2299}
2300