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        update = full_update;
1678        page0 = addr & s->vbe_size_mask;
1679        page1 = (addr + bwidth - 1) & s->vbe_size_mask;
1680        if (full_update) {
1681            update = 1;
1682        } else if (page1 < page0) {
1683            /* scanline wraps from end of video memory to the start */
1684            assert(force_shadow);
1685            update = memory_region_snapshot_get_dirty(&s->vram, snap,
1686                                                      page0, s->vbe_size - page0);
1687            update |= memory_region_snapshot_get_dirty(&s->vram, snap,
1688                                                       0, page1);
1689        } else {
1690            update = memory_region_snapshot_get_dirty(&s->vram, snap,
1691                                                      page0, page1 - page0);
1692        }
1693        /* explicit invalidation for the hardware cursor (cirrus only) */
1694        update |= vga_scanline_invalidated(s, y);
1695        if (update) {
1696            if (y_start < 0)
1697                y_start = y;
1698            if (!(is_buffer_shared(surface))) {
1699                vga_draw_line(s, d, addr, width);
1700                if (s->cursor_draw_line)
1701                    s->cursor_draw_line(s, d, y);
1702            }
1703        } else {
1704            if (y_start >= 0) {
1705                /* flush to display */
1706                dpy_gfx_update(s->con, 0, y_start,
1707                               disp_width, y - y_start);
1708                y_start = -1;
1709            }
1710        }
1711        if (!multi_run) {
1712            mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1713            if ((y1 & mask) == mask)
1714                addr1 += s->line_offset;
1715            y1++;
1716            multi_run = multi_scan;
1717        } else {
1718            multi_run--;
1719        }
1720        /* line compare acts on the displayed lines */
1721        if (y == s->line_compare)
1722            addr1 = 0;
1723        d += linesize;
1724    }
1725    if (y_start >= 0) {
1726        /* flush to display */
1727        dpy_gfx_update(s->con, 0, y_start,
1728                       disp_width, y - y_start);
1729    }
1730    g_free(snap);
1731    memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
1732}
1733
1734static void vga_draw_blank(VGACommonState *s, int full_update)
1735{
1736    DisplaySurface *surface = qemu_console_surface(s->con);
1737    int i, w;
1738    uint8_t *d;
1739
1740    if (!full_update)
1741        return;
1742    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1743        return;
1744
1745    w = s->last_scr_width * surface_bytes_per_pixel(surface);
1746    d = surface_data(surface);
1747    for(i = 0; i < s->last_scr_height; i++) {
1748        memset(d, 0, w);
1749        d += surface_stride(surface);
1750    }
1751    dpy_gfx_update_full(s->con);
1752}
1753
1754#define GMODE_TEXT     0
1755#define GMODE_GRAPH    1
1756#define GMODE_BLANK 2
1757
1758static void vga_update_display(void *opaque)
1759{
1760    VGACommonState *s = opaque;
1761    DisplaySurface *surface = qemu_console_surface(s->con);
1762    int full_update, graphic_mode;
1763
1764    qemu_flush_coalesced_mmio_buffer();
1765
1766    if (surface_bits_per_pixel(surface) == 0) {
1767        /* nothing to do */
1768    } else {
1769        full_update = 0;
1770        if (!(s->ar_index & 0x20)) {
1771            graphic_mode = GMODE_BLANK;
1772        } else {
1773            graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1774        }
1775        if (graphic_mode != s->graphic_mode) {
1776            s->graphic_mode = graphic_mode;
1777            s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1778            full_update = 1;
1779        }
1780        switch(graphic_mode) {
1781        case GMODE_TEXT:
1782            vga_draw_text(s, full_update);
1783            break;
1784        case GMODE_GRAPH:
1785            vga_draw_graphic(s, full_update);
1786            break;
1787        case GMODE_BLANK:
1788        default:
1789            vga_draw_blank(s, full_update);
1790            break;
1791        }
1792    }
1793}
1794
1795/* force a full display refresh */
1796static void vga_invalidate_display(void *opaque)
1797{
1798    VGACommonState *s = opaque;
1799
1800    s->last_width = -1;
1801    s->last_height = -1;
1802}
1803
1804void vga_common_reset(VGACommonState *s)
1805{
1806    s->sr_index = 0;
1807    memset(s->sr, '\0', sizeof(s->sr));
1808    memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1809    s->gr_index = 0;
1810    memset(s->gr, '\0', sizeof(s->gr));
1811    s->ar_index = 0;
1812    memset(s->ar, '\0', sizeof(s->ar));
1813    s->ar_flip_flop = 0;
1814    s->cr_index = 0;
1815    memset(s->cr, '\0', sizeof(s->cr));
1816    s->msr = 0;
1817    s->fcr = 0;
1818    s->st00 = 0;
1819    s->st01 = 0;
1820    s->dac_state = 0;
1821    s->dac_sub_index = 0;
1822    s->dac_read_index = 0;
1823    s->dac_write_index = 0;
1824    memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1825    s->dac_8bit = 0;
1826    memset(s->palette, '\0', sizeof(s->palette));
1827    s->bank_offset = 0;
1828    s->vbe_index = 0;
1829    memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1830    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1831    s->vbe_start_addr = 0;
1832    s->vbe_line_offset = 0;
1833    s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1834    memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1835    s->graphic_mode = -1; /* force full update */
1836    s->shift_control = 0;
1837    s->double_scan = 0;
1838    s->line_offset = 0;
1839    s->line_compare = 0;
1840    s->start_addr = 0;
1841    s->plane_updated = 0;
1842    s->last_cw = 0;
1843    s->last_ch = 0;
1844    s->last_width = 0;
1845    s->last_height = 0;
1846    s->last_scr_width = 0;
1847    s->last_scr_height = 0;
1848    s->cursor_start = 0;
1849    s->cursor_end = 0;
1850    s->cursor_offset = 0;
1851    s->big_endian_fb = s->default_endian_fb;
1852    memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1853    memset(s->last_palette, '\0', sizeof(s->last_palette));
1854    memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1855    switch (vga_retrace_method) {
1856    case VGA_RETRACE_DUMB:
1857        break;
1858    case VGA_RETRACE_PRECISE:
1859        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1860        break;
1861    }
1862    vga_update_memory_access(s);
1863}
1864
1865static void vga_reset(void *opaque)
1866{
1867    VGACommonState *s =  opaque;
1868    vga_common_reset(s);
1869}
1870
1871#define TEXTMODE_X(x)   ((x) % width)
1872#define TEXTMODE_Y(x)   ((x) / width)
1873#define VMEM2CHTYPE(v)  ((v & 0xff0007ff) | \
1874        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1875/* relay text rendering to the display driver
1876 * instead of doing a full vga_update_display() */
1877static void vga_update_text(void *opaque, console_ch_t *chardata)
1878{
1879    VGACommonState *s =  opaque;
1880    int graphic_mode, i, cursor_offset, cursor_visible;
1881    int cw, cheight, width, height, size, c_min, c_max;
1882    uint32_t *src;
1883    console_ch_t *dst, val;
1884    char msg_buffer[80];
1885    int full_update = 0;
1886
1887    qemu_flush_coalesced_mmio_buffer();
1888
1889    if (!(s->ar_index & 0x20)) {
1890        graphic_mode = GMODE_BLANK;
1891    } else {
1892        graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1893    }
1894    if (graphic_mode != s->graphic_mode) {
1895        s->graphic_mode = graphic_mode;
1896        full_update = 1;
1897    }
1898    if (s->last_width == -1) {
1899        s->last_width = 0;
1900        full_update = 1;
1901    }
1902
1903    switch (graphic_mode) {
1904    case GMODE_TEXT:
1905        /* TODO: update palette */
1906        full_update |= update_basic_params(s);
1907
1908        /* total width & height */
1909        cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1910        cw = 8;
1911        if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1912            cw = 9;
1913        }
1914        if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1915            cw = 16; /* NOTE: no 18 pixel wide */
1916        }
1917        width = (s->cr[VGA_CRTC_H_DISP] + 1);
1918        if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1919            /* ugly hack for CGA 160x100x16 - explain me the logic */
1920            height = 100;
1921        } else {
1922            height = s->cr[VGA_CRTC_V_DISP_END] |
1923                ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1924                ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1925            height = (height + 1) / cheight;
1926        }
1927
1928        size = (height * width);
1929        if (size > CH_ATTR_SIZE) {
1930            if (!full_update)
1931                return;
1932
1933            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1934                     width, height);
1935            break;
1936        }
1937
1938        if (width != s->last_width || height != s->last_height ||
1939            cw != s->last_cw || cheight != s->last_ch) {
1940            s->last_scr_width = width * cw;
1941            s->last_scr_height = height * cheight;
1942            qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1943            dpy_text_resize(s->con, width, height);
1944            s->last_depth = 0;
1945            s->last_width = width;
1946            s->last_height = height;
1947            s->last_ch = cheight;
1948            s->last_cw = cw;
1949            full_update = 1;
1950        }
1951
1952        if (full_update) {
1953            s->full_update_gfx = 1;
1954        }
1955        if (s->full_update_text) {
1956            s->full_update_text = 0;
1957            full_update |= 1;
1958        }
1959
1960        /* Update "hardware" cursor */
1961        cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1962                         s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1963        if (cursor_offset != s->cursor_offset ||
1964            s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1965            s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1966            cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1967            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1968                dpy_text_cursor(s->con,
1969                                TEXTMODE_X(cursor_offset),
1970                                TEXTMODE_Y(cursor_offset));
1971            else
1972                dpy_text_cursor(s->con, -1, -1);
1973            s->cursor_offset = cursor_offset;
1974            s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1975            s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1976        }
1977
1978        src = (uint32_t *) s->vram_ptr + s->start_addr;
1979        dst = chardata;
1980
1981        if (full_update) {
1982            for (i = 0; i < size; src ++, dst ++, i ++)
1983                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1984
1985            dpy_text_update(s->con, 0, 0, width, height);
1986        } else {
1987            c_max = 0;
1988
1989            for (i = 0; i < size; src ++, dst ++, i ++) {
1990                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1991                if (*dst != val) {
1992                    *dst = val;
1993                    c_max = i;
1994                    break;
1995                }
1996            }
1997            c_min = i;
1998            for (; i < size; src ++, dst ++, i ++) {
1999                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2000                if (*dst != val) {
2001                    *dst = val;
2002                    c_max = i;
2003                }
2004            }
2005
2006            if (c_min <= c_max) {
2007                i = TEXTMODE_Y(c_min);
2008                dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2009            }
2010        }
2011
2012        return;
2013    case GMODE_GRAPH:
2014        if (!full_update)
2015            return;
2016
2017        s->get_resolution(s, &width, &height);
2018        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2019                 width, height);
2020        break;
2021    case GMODE_BLANK:
2022    default:
2023        if (!full_update)
2024            return;
2025
2026        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2027        break;
2028    }
2029
2030    /* Display a message */
2031    s->last_width = 60;
2032    s->last_height = height = 3;
2033    dpy_text_cursor(s->con, -1, -1);
2034    dpy_text_resize(s->con, s->last_width, height);
2035
2036    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2037        console_write_ch(dst ++, ' ');
2038
2039    size = strlen(msg_buffer);
2040    width = (s->last_width - size) / 2;
2041    dst = chardata + s->last_width + width;
2042    for (i = 0; i < size; i ++)
2043        console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2044                                             QEMU_COLOR_BLACK, 1));
2045
2046    dpy_text_update(s->con, 0, 0, s->last_width, height);
2047}
2048
2049static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2050                             unsigned size)
2051{
2052    VGACommonState *s = opaque;
2053
2054    return vga_mem_readb(s, addr);
2055}
2056
2057static void vga_mem_write(void *opaque, hwaddr addr,
2058                          uint64_t data, unsigned size)
2059{
2060    VGACommonState *s = opaque;
2061
2062    vga_mem_writeb(s, addr, data);
2063}
2064
2065const MemoryRegionOps vga_mem_ops = {
2066    .read = vga_mem_read,
2067    .write = vga_mem_write,
2068    .endianness = DEVICE_LITTLE_ENDIAN,
2069    .impl = {
2070        .min_access_size = 1,
2071        .max_access_size = 1,
2072    },
2073};
2074
2075static int vga_common_post_load(void *opaque, int version_id)
2076{
2077    VGACommonState *s = opaque;
2078
2079    /* force refresh */
2080    s->graphic_mode = -1;
2081    vbe_update_vgaregs(s);
2082    vga_update_memory_access(s);
2083    return 0;
2084}
2085
2086static bool vga_endian_state_needed(void *opaque)
2087{
2088    VGACommonState *s = opaque;
2089
2090    /*
2091     * Only send the endian state if it's different from the
2092     * default one, thus ensuring backward compatibility for
2093     * migration of the common case
2094     */
2095    return s->default_endian_fb != s->big_endian_fb;
2096}
2097
2098static const VMStateDescription vmstate_vga_endian = {
2099    .name = "vga.endian",
2100    .version_id = 1,
2101    .minimum_version_id = 1,
2102    .needed = vga_endian_state_needed,
2103    .fields = (VMStateField[]) {
2104        VMSTATE_BOOL(big_endian_fb, VGACommonState),
2105        VMSTATE_END_OF_LIST()
2106    }
2107};
2108
2109const VMStateDescription vmstate_vga_common = {
2110    .name = "vga",
2111    .version_id = 2,
2112    .minimum_version_id = 2,
2113    .post_load = vga_common_post_load,
2114    .fields = (VMStateField[]) {
2115        VMSTATE_UINT32(latch, VGACommonState),
2116        VMSTATE_UINT8(sr_index, VGACommonState),
2117        VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2118        VMSTATE_UINT8(gr_index, VGACommonState),
2119        VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2120        VMSTATE_UINT8(ar_index, VGACommonState),
2121        VMSTATE_BUFFER(ar, VGACommonState),
2122        VMSTATE_INT32(ar_flip_flop, VGACommonState),
2123        VMSTATE_UINT8(cr_index, VGACommonState),
2124        VMSTATE_BUFFER(cr, VGACommonState),
2125        VMSTATE_UINT8(msr, VGACommonState),
2126        VMSTATE_UINT8(fcr, VGACommonState),
2127        VMSTATE_UINT8(st00, VGACommonState),
2128        VMSTATE_UINT8(st01, VGACommonState),
2129
2130        VMSTATE_UINT8(dac_state, VGACommonState),
2131        VMSTATE_UINT8(dac_sub_index, VGACommonState),
2132        VMSTATE_UINT8(dac_read_index, VGACommonState),
2133        VMSTATE_UINT8(dac_write_index, VGACommonState),
2134        VMSTATE_BUFFER(dac_cache, VGACommonState),
2135        VMSTATE_BUFFER(palette, VGACommonState),
2136
2137        VMSTATE_INT32(bank_offset, VGACommonState),
2138        VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
2139        VMSTATE_UINT16(vbe_index, VGACommonState),
2140        VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2141        VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2142        VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2143        VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2144        VMSTATE_END_OF_LIST()
2145    },
2146    .subsections = (const VMStateDescription*[]) {
2147        &vmstate_vga_endian,
2148        NULL
2149    }
2150};
2151
2152static const GraphicHwOps vga_ops = {
2153    .invalidate  = vga_invalidate_display,
2154    .gfx_update  = vga_update_display,
2155    .text_update = vga_update_text,
2156};
2157
2158static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2159{
2160    if (val < vmin) {
2161        return vmin;
2162    }
2163    if (val > vmax) {
2164        return vmax;
2165    }
2166    return val;
2167}
2168
2169void vga_common_init(VGACommonState *s, Object *obj)
2170{
2171    int i, j, v, b;
2172
2173    for(i = 0;i < 256; i++) {
2174        v = 0;
2175        for(j = 0; j < 8; j++) {
2176            v |= ((i >> j) & 1) << (j * 4);
2177        }
2178        expand4[i] = v;
2179
2180        v = 0;
2181        for(j = 0; j < 4; j++) {
2182            v |= ((i >> (2 * j)) & 3) << (j * 4);
2183        }
2184        expand2[i] = v;
2185    }
2186    for(i = 0; i < 16; i++) {
2187        v = 0;
2188        for(j = 0; j < 4; j++) {
2189            b = ((i >> j) & 1);
2190            v |= b << (2 * j);
2191            v |= b << (2 * j + 1);
2192        }
2193        expand4to8[i] = v;
2194    }
2195
2196    s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2197    s->vram_size_mb = pow2ceil(s->vram_size_mb);
2198    s->vram_size = s->vram_size_mb * MiB;
2199
2200    if (!s->vbe_size) {
2201        s->vbe_size = s->vram_size;
2202    }
2203    s->vbe_size_mask = s->vbe_size - 1;
2204
2205    s->is_vbe_vmstate = 1;
2206    memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
2207                           &error_fatal);
2208    vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj));
2209    xen_register_framebuffer(&s->vram);
2210    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2211    s->get_bpp = vga_get_bpp;
2212    s->get_offsets = vga_get_offsets;
2213    s->get_resolution = vga_get_resolution;
2214    s->hw_ops = &vga_ops;
2215    switch (vga_retrace_method) {
2216    case VGA_RETRACE_DUMB:
2217        s->retrace = vga_dumb_retrace;
2218        s->update_retrace_info = vga_dumb_update_retrace_info;
2219        break;
2220
2221    case VGA_RETRACE_PRECISE:
2222        s->retrace = vga_precise_retrace;
2223        s->update_retrace_info = vga_precise_update_retrace_info;
2224        break;
2225    }
2226
2227    /*
2228     * Set default fb endian based on target, could probably be turned
2229     * into a device attribute set by the machine/platform to remove
2230     * all target endian dependencies from this file.
2231     */
2232#ifdef TARGET_WORDS_BIGENDIAN
2233    s->default_endian_fb = true;
2234#else
2235    s->default_endian_fb = false;
2236#endif
2237    vga_dirty_log_start(s);
2238}
2239
2240static const MemoryRegionPortio vga_portio_list[] = {
2241    { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2242    { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2243    { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2244    { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2245    { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2246    PORTIO_END_OF_LIST(),
2247};
2248
2249static const MemoryRegionPortio vbe_portio_list[] = {
2250    { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2251# ifdef TARGET_I386
2252    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2253# endif
2254    { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2255    PORTIO_END_OF_LIST(),
2256};
2257
2258/* Used by both ISA and PCI */
2259MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2260                          const MemoryRegionPortio **vga_ports,
2261                          const MemoryRegionPortio **vbe_ports)
2262{
2263    MemoryRegion *vga_mem;
2264
2265    *vga_ports = vga_portio_list;
2266    *vbe_ports = vbe_portio_list;
2267
2268    vga_mem = g_malloc(sizeof(*vga_mem));
2269    memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2270                          "vga-lowmem", 0x20000);
2271    memory_region_set_flush_coalesced(vga_mem);
2272
2273    return vga_mem;
2274}
2275
2276void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2277              MemoryRegion *address_space_io, bool init_vga_ports)
2278{
2279    MemoryRegion *vga_io_memory;
2280    const MemoryRegionPortio *vga_ports, *vbe_ports;
2281
2282    qemu_register_reset(vga_reset, s);
2283
2284    s->bank_offset = 0;
2285
2286    s->legacy_address_space = address_space;
2287
2288    vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2289    memory_region_add_subregion_overlap(address_space,
2290                                        0x000a0000,
2291                                        vga_io_memory,
2292                                        1);
2293    memory_region_set_coalescing(vga_io_memory);
2294    if (init_vga_ports) {
2295        portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2296        portio_list_set_flush_coalesced(&s->vga_port_list);
2297        portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2298    }
2299    if (vbe_ports) {
2300        portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2301        portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2302    }
2303}
2304
2305void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2306{
2307    /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2308     * so use an alias to avoid double-mapping the same region.
2309     */
2310    memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2311                             &s->vram, 0, memory_region_size(&s->vram));
2312    /* XXX: use optimized standard vga accesses */
2313    memory_region_add_subregion(system_memory,
2314                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2315                                &s->vram_vbe);
2316    s->vbe_mapped = 1;
2317}
2318