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