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