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