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