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    uint32_t val;
 704    val = s->vbe_index;
 705    return val;
 706}
 707
 708uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
 709{
 710    VGACommonState *s = opaque;
 711    uint32_t val;
 712
 713    if (s->vbe_index < VBE_DISPI_INDEX_NB) {
 714        if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
 715            switch(s->vbe_index) {
 716                /* XXX: do not hardcode ? */
 717            case VBE_DISPI_INDEX_XRES:
 718                val = VBE_DISPI_MAX_XRES;
 719                break;
 720            case VBE_DISPI_INDEX_YRES:
 721                val = VBE_DISPI_MAX_YRES;
 722                break;
 723            case VBE_DISPI_INDEX_BPP:
 724                val = VBE_DISPI_MAX_BPP;
 725                break;
 726            default:
 727                val = s->vbe_regs[s->vbe_index];
 728                break;
 729            }
 730        } else {
 731            val = s->vbe_regs[s->vbe_index];
 732        }
 733    } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
 734        val = s->vbe_size / (64 * 1024);
 735    } else {
 736        val = 0;
 737    }
 738#ifdef DEBUG_BOCHS_VBE
 739    printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
 740#endif
 741    return val;
 742}
 743
 744void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
 745{
 746    VGACommonState *s = opaque;
 747    s->vbe_index = val;
 748}
 749
 750void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 751{
 752    VGACommonState *s = opaque;
 753
 754    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
 755#ifdef DEBUG_BOCHS_VBE
 756        printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
 757#endif
 758        switch(s->vbe_index) {
 759        case VBE_DISPI_INDEX_ID:
 760            if (val == VBE_DISPI_ID0 ||
 761                val == VBE_DISPI_ID1 ||
 762                val == VBE_DISPI_ID2 ||
 763                val == VBE_DISPI_ID3 ||
 764                val == VBE_DISPI_ID4) {
 765                s->vbe_regs[s->vbe_index] = val;
 766            }
 767            break;
 768        case VBE_DISPI_INDEX_XRES:
 769        case VBE_DISPI_INDEX_YRES:
 770        case VBE_DISPI_INDEX_BPP:
 771        case VBE_DISPI_INDEX_VIRT_WIDTH:
 772        case VBE_DISPI_INDEX_X_OFFSET:
 773        case VBE_DISPI_INDEX_Y_OFFSET:
 774            s->vbe_regs[s->vbe_index] = val;
 775            vbe_fixup_regs(s);
 776            vbe_update_vgaregs(s);
 777            break;
 778        case VBE_DISPI_INDEX_BANK:
 779            val &= s->vbe_bank_mask;
 780            s->vbe_regs[s->vbe_index] = val;
 781            s->bank_offset = (val << 16);
 782            vga_update_memory_access(s);
 783            break;
 784        case VBE_DISPI_INDEX_ENABLE:
 785            if ((val & VBE_DISPI_ENABLED) &&
 786                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
 787
 788                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
 789                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
 790                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
 791                s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
 792                vbe_fixup_regs(s);
 793                vbe_update_vgaregs(s);
 794
 795                /* clear the screen */
 796                if (!(val & VBE_DISPI_NOCLEARMEM)) {
 797                    memset(s->vram_ptr, 0,
 798                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 799                }
 800            } else {
 801                s->bank_offset = 0;
 802            }
 803            s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
 804            s->vbe_regs[s->vbe_index] = val;
 805            vga_update_memory_access(s);
 806            break;
 807        default:
 808            break;
 809        }
 810    }
 811}
 812
 813/* called for accesses between 0xa0000 and 0xc0000 */
 814uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
 815{
 816    int memory_map_mode, plane;
 817    uint32_t ret;
 818
 819    /* convert to VGA memory offset */
 820    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
 821    addr &= 0x1ffff;
 822    switch(memory_map_mode) {
 823    case 0:
 824        break;
 825    case 1:
 826        if (addr >= 0x10000)
 827            return 0xff;
 828        addr += s->bank_offset;
 829        break;
 830    case 2:
 831        addr -= 0x10000;
 832        if (addr >= 0x8000)
 833            return 0xff;
 834        break;
 835    default:
 836    case 3:
 837        addr -= 0x18000;
 838        if (addr >= 0x8000)
 839            return 0xff;
 840        break;
 841    }
 842
 843    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
 844        /* chain 4 mode : simplest access */
 845        assert(addr < s->vram_size);
 846        ret = s->vram_ptr[addr];
 847    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 848        /* odd/even mode (aka text mode mapping) */
 849        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 850        addr = ((addr & ~1) << 1) | plane;
 851        if (addr >= s->vram_size) {
 852            return 0xff;
 853        }
 854        ret = s->vram_ptr[addr];
 855    } else {
 856        /* standard VGA latched access */
 857        if (addr * sizeof(uint32_t) >= s->vram_size) {
 858            return 0xff;
 859        }
 860        s->latch = ((uint32_t *)s->vram_ptr)[addr];
 861
 862        if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
 863            /* read mode 0 */
 864            plane = s->gr[VGA_GFX_PLANE_READ];
 865            ret = GET_PLANE(s->latch, plane);
 866        } else {
 867            /* read mode 1 */
 868            ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
 869                mask16[s->gr[VGA_GFX_COMPARE_MASK]];
 870            ret |= ret >> 16;
 871            ret |= ret >> 8;
 872            ret = (~ret) & 0xff;
 873        }
 874    }
 875    return ret;
 876}
 877
 878/* called for accesses between 0xa0000 and 0xc0000 */
 879void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 880{
 881    int memory_map_mode, plane, write_mode, b, func_select, mask;
 882    uint32_t write_mask, bit_mask, set_mask;
 883
 884#ifdef DEBUG_VGA_MEM
 885    printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
 886#endif
 887    /* convert to VGA memory offset */
 888    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
 889    addr &= 0x1ffff;
 890    switch(memory_map_mode) {
 891    case 0:
 892        break;
 893    case 1:
 894        if (addr >= 0x10000)
 895            return;
 896        addr += s->bank_offset;
 897        break;
 898    case 2:
 899        addr -= 0x10000;
 900        if (addr >= 0x8000)
 901            return;
 902        break;
 903    default:
 904    case 3:
 905        addr -= 0x18000;
 906        if (addr >= 0x8000)
 907            return;
 908        break;
 909    }
 910
 911    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
 912        /* chain 4 mode : simplest access */
 913        plane = addr & 3;
 914        mask = (1 << plane);
 915        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
 916            assert(addr < s->vram_size);
 917            s->vram_ptr[addr] = val;
 918#ifdef DEBUG_VGA_MEM
 919            printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 920#endif
 921            s->plane_updated |= mask; /* only used to detect font change */
 922            memory_region_set_dirty(&s->vram, addr, 1);
 923        }
 924    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 925        /* odd/even mode (aka text mode mapping) */
 926        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 927        mask = (1 << plane);
 928        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
 929            addr = ((addr & ~1) << 1) | plane;
 930            if (addr >= s->vram_size) {
 931                return;
 932            }
 933            s->vram_ptr[addr] = val;
 934#ifdef DEBUG_VGA_MEM
 935            printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 936#endif
 937            s->plane_updated |= mask; /* only used to detect font change */
 938            memory_region_set_dirty(&s->vram, addr, 1);
 939        }
 940    } else {
 941        /* standard VGA latched access */
 942        write_mode = s->gr[VGA_GFX_MODE] & 3;
 943        switch(write_mode) {
 944        default:
 945        case 0:
 946            /* rotate */
 947            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
 948            val = ((val >> b) | (val << (8 - b))) & 0xff;
 949            val |= val << 8;
 950            val |= val << 16;
 951
 952            /* apply set/reset mask */
 953            set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
 954            val = (val & ~set_mask) |
 955                (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
 956            bit_mask = s->gr[VGA_GFX_BIT_MASK];
 957            break;
 958        case 1:
 959            val = s->latch;
 960            goto do_write;
 961        case 2:
 962            val = mask16[val & 0x0f];
 963            bit_mask = s->gr[VGA_GFX_BIT_MASK];
 964            break;
 965        case 3:
 966            /* rotate */
 967            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
 968            val = (val >> b) | (val << (8 - b));
 969
 970            bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
 971            val = mask16[s->gr[VGA_GFX_SR_VALUE]];
 972            break;
 973        }
 974
 975        /* apply logical operation */
 976        func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
 977        switch(func_select) {
 978        case 0:
 979        default:
 980            /* nothing to do */
 981            break;
 982        case 1:
 983            /* and */
 984            val &= s->latch;
 985            break;
 986        case 2:
 987            /* or */
 988            val |= s->latch;
 989            break;
 990        case 3:
 991            /* xor */
 992            val ^= s->latch;
 993            break;
 994        }
 995
 996        /* apply bit mask */
 997        bit_mask |= bit_mask << 8;
 998        bit_mask |= bit_mask << 16;
 999        val = (val & bit_mask) | (s->latch & ~bit_mask);
1000
1001    do_write:
1002        /* mask data according to sr[2] */
1003        mask = sr(s, VGA_SEQ_PLANE_WRITE);
1004        s->plane_updated |= mask; /* only used to detect font change */
1005        write_mask = mask16[mask];
1006        if (addr * sizeof(uint32_t) >= s->vram_size) {
1007            return;
1008        }
1009        ((uint32_t *)s->vram_ptr)[addr] =
1010            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
1011            (val & write_mask);
1012#ifdef DEBUG_VGA_MEM
1013        printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
1014               addr * 4, write_mask, val);
1015#endif
1016        memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
1017    }
1018}
1019
1020typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
1021                                const uint8_t *s, int width);
1022
1023#include "vga-helpers.h"
1024
1025/* return true if the palette was modified */
1026static int update_palette16(VGACommonState *s)
1027{
1028    int full_update, i;
1029    uint32_t v, col, *palette;
1030
1031    full_update = 0;
1032    palette = s->last_palette;
1033    for(i = 0; i < 16; i++) {
1034        v = s->ar[i];
1035        if (s->ar[VGA_ATC_MODE] & 0x80) {
1036            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1037        } else {
1038            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1039        }
1040        v = v * 3;
1041        col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1042                             c6_to_8(s->palette[v + 1]),
1043                             c6_to_8(s->palette[v + 2]));
1044        if (col != palette[i]) {
1045            full_update = 1;
1046            palette[i] = col;
1047        }
1048    }
1049    return full_update;
1050}
1051
1052/* return true if the palette was modified */
1053static int update_palette256(VGACommonState *s)
1054{
1055    int full_update, i;
1056    uint32_t v, col, *palette;
1057
1058    full_update = 0;
1059    palette = s->last_palette;
1060    v = 0;
1061    for(i = 0; i < 256; i++) {
1062        if (s->dac_8bit) {
1063            col = rgb_to_pixel32(s->palette[v],
1064                                 s->palette[v + 1],
1065                                 s->palette[v + 2]);
1066        } else {
1067            col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1068                                 c6_to_8(s->palette[v + 1]),
1069                                 c6_to_8(s->palette[v + 2]));
1070        }
1071        if (col != palette[i]) {
1072            full_update = 1;
1073            palette[i] = col;
1074        }
1075        v += 3;
1076    }
1077    return full_update;
1078}
1079
1080static void vga_get_offsets(VGACommonState *s,
1081                            uint32_t *pline_offset,
1082                            uint32_t *pstart_addr,
1083                            uint32_t *pline_compare)
1084{
1085    uint32_t start_addr, line_offset, line_compare;
1086
1087    if (vbe_enabled(s)) {
1088        line_offset = s->vbe_line_offset;
1089        start_addr = s->vbe_start_addr;
1090        line_compare = 65535;
1091    } else {
1092        /* compute line_offset in bytes */
1093        line_offset = s->cr[VGA_CRTC_OFFSET];
1094        line_offset <<= 3;
1095
1096        /* starting address */
1097        start_addr = s->cr[VGA_CRTC_START_LO] |
1098            (s->cr[VGA_CRTC_START_HI] << 8);
1099
1100        /* line compare */
1101        line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1102            ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1103            ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1104    }
1105    *pline_offset = line_offset;
1106    *pstart_addr = start_addr;
1107    *pline_compare = line_compare;
1108}
1109
1110/* update start_addr and line_offset. Return TRUE if modified */
1111static int update_basic_params(VGACommonState *s)
1112{
1113    int full_update;
1114    uint32_t start_addr, line_offset, line_compare;
1115
1116    full_update = 0;
1117
1118    s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1119
1120    if (line_offset != s->line_offset ||
1121        start_addr != s->start_addr ||
1122        line_compare != s->line_compare) {
1123        s->line_offset = line_offset;
1124        s->start_addr = start_addr;
1125        s->line_compare = line_compare;
1126        full_update = 1;
1127    }
1128    return full_update;
1129}
1130
1131
1132static const uint8_t cursor_glyph[32 * 4] = {
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    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1148    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1149};
1150
1151static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1152                                    int *pcwidth, int *pcheight)
1153{
1154    int width, cwidth, height, cheight;
1155
1156    /* total width & height */
1157    cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1158    cwidth = 8;
1159    if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1160        cwidth = 9;
1161    }
1162    if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1163        cwidth = 16; /* NOTE: no 18 pixel wide */
1164    }
1165    width = (s->cr[VGA_CRTC_H_DISP] + 1);
1166    if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1167        /* ugly hack for CGA 160x100x16 - explain me the logic */
1168        height = 100;
1169    } else {
1170        height = s->cr[VGA_CRTC_V_DISP_END] |
1171            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1172            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1173        height = (height + 1) / cheight;
1174    }
1175
1176    *pwidth = width;
1177    *pheight = height;
1178    *pcwidth = cwidth;
1179    *pcheight = cheight;
1180}
1181
1182/*
1183 * Text mode update
1184 * Missing:
1185 * - double scan
1186 * - double width
1187 * - underline
1188 * - flashing
1189 */
1190static void vga_draw_text(VGACommonState *s, int full_update)
1191{
1192    DisplaySurface *surface = qemu_console_surface(s->con);
1193    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1194    int cx_min, cx_max, linesize, x_incr, line, line1;
1195    uint32_t offset, fgcol, bgcol, v, cursor_offset;
1196    uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1197    const uint8_t *font_ptr, *font_base[2];
1198    int dup9, line_offset;
1199    uint32_t *palette;
1200    uint32_t *ch_attr_ptr;
1201    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1202
1203    /* compute font data address (in plane 2) */
1204    v = sr(s, VGA_SEQ_CHARACTER_MAP);
1205    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1206    if (offset != s->font_offsets[0]) {
1207        s->font_offsets[0] = offset;
1208        full_update = 1;
1209    }
1210    font_base[0] = s->vram_ptr + offset;
1211
1212    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1213    font_base[1] = s->vram_ptr + offset;
1214    if (offset != s->font_offsets[1]) {
1215        s->font_offsets[1] = offset;
1216        full_update = 1;
1217    }
1218    if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
1219        /* if the plane 2 was modified since the last display, it
1220           indicates the font may have been modified */
1221        s->plane_updated = 0;
1222        full_update = 1;
1223    }
1224    full_update |= update_basic_params(s);
1225
1226    line_offset = s->line_offset;
1227
1228    vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1229    if ((height * width) <= 1) {
1230        /* better than nothing: exit if transient size is too small */
1231        return;
1232    }
1233    if ((height * width) > CH_ATTR_SIZE) {
1234        /* better than nothing: exit if transient size is too big */
1235        return;
1236    }
1237
1238    if (width != s->last_width || height != s->last_height ||
1239        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1240        s->last_scr_width = width * cw;
1241        s->last_scr_height = height * cheight;
1242        qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1243        surface = qemu_console_surface(s->con);
1244        dpy_text_resize(s->con, width, height);
1245        s->last_depth = 0;
1246        s->last_width = width;
1247        s->last_height = height;
1248        s->last_ch = cheight;
1249        s->last_cw = cw;
1250        full_update = 1;
1251    }
1252    full_update |= update_palette16(s);
1253    palette = s->last_palette;
1254    x_incr = cw * surface_bytes_per_pixel(surface);
1255
1256    if (full_update) {
1257        s->full_update_text = 1;
1258    }
1259    if (s->full_update_gfx) {
1260        s->full_update_gfx = 0;
1261        full_update |= 1;
1262    }
1263
1264    cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1265                     s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1266    if (cursor_offset != s->cursor_offset ||
1267        s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1268        s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1269      /* if the cursor position changed, we update the old and new
1270         chars */
1271        if (s->cursor_offset < CH_ATTR_SIZE)
1272            s->last_ch_attr[s->cursor_offset] = -1;
1273        if (cursor_offset < CH_ATTR_SIZE)
1274            s->last_ch_attr[cursor_offset] = -1;
1275        s->cursor_offset = cursor_offset;
1276        s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1277        s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1278    }
1279    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1280    if (now >= s->cursor_blink_time) {
1281        s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1282        s->cursor_visible_phase = !s->cursor_visible_phase;
1283    }
1284
1285    dest = surface_data(surface);
1286    linesize = surface_stride(surface);
1287    ch_attr_ptr = s->last_ch_attr;
1288    line = 0;
1289    offset = s->start_addr * 4;
1290    for(cy = 0; cy < height; cy++) {
1291        d1 = dest;
1292        src = s->vram_ptr + offset;
1293        cx_min = width;
1294        cx_max = -1;
1295        for(cx = 0; cx < width; cx++) {
1296            ch_attr = *(uint16_t *)src;
1297            if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1298                if (cx < cx_min)
1299                    cx_min = cx;
1300                if (cx > cx_max)
1301                    cx_max = cx;
1302                *ch_attr_ptr = ch_attr;
1303#ifdef HOST_WORDS_BIGENDIAN
1304                ch = ch_attr >> 8;
1305                cattr = ch_attr & 0xff;
1306#else
1307                ch = ch_attr & 0xff;
1308                cattr = ch_attr >> 8;
1309#endif
1310                font_ptr = font_base[(cattr >> 3) & 1];
1311                font_ptr += 32 * 4 * ch;
1312                bgcol = palette[cattr >> 4];
1313                fgcol = palette[cattr & 0x0f];
1314                if (cw == 16) {
1315                    vga_draw_glyph16(d1, linesize,
1316                                     font_ptr, cheight, fgcol, bgcol);
1317                } else if (cw != 9) {
1318                    vga_draw_glyph8(d1, linesize,
1319                                    font_ptr, cheight, fgcol, bgcol);
1320                } else {
1321                    dup9 = 0;
1322                    if (ch >= 0xb0 && ch <= 0xdf &&
1323                        (s->ar[VGA_ATC_MODE] & 0x04)) {
1324                        dup9 = 1;
1325                    }
1326                    vga_draw_glyph9(d1, linesize,
1327                                    font_ptr, cheight, fgcol, bgcol, dup9);
1328                }
1329                if (src == cursor_ptr &&
1330                    !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1331                    s->cursor_visible_phase) {
1332                    int line_start, line_last, h;
1333                    /* draw the cursor */
1334                    line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1335                    line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1336                    /* XXX: check that */
1337                    if (line_last > cheight - 1)
1338                        line_last = cheight - 1;
1339                    if (line_last >= line_start && line_start < cheight) {
1340                        h = line_last - line_start + 1;
1341                        d = d1 + linesize * line_start;
1342                        if (cw == 16) {
1343                            vga_draw_glyph16(d, linesize,
1344                                             cursor_glyph, h, fgcol, bgcol);
1345                        } else if (cw != 9) {
1346                            vga_draw_glyph8(d, linesize,
1347                                            cursor_glyph, h, fgcol, bgcol);
1348                        } else {
1349                            vga_draw_glyph9(d, linesize,
1350                                            cursor_glyph, h, fgcol, bgcol, 1);
1351                        }
1352                    }
1353                }
1354            }
1355            d1 += x_incr;
1356            src += 4;
1357            ch_attr_ptr++;
1358        }
1359        if (cx_max != -1) {
1360            dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1361                           (cx_max - cx_min + 1) * cw, cheight);
1362        }
1363        dest += linesize * cheight;
1364        line1 = line + cheight;
1365        offset += line_offset;
1366        if (line < s->line_compare && line1 >= s->line_compare) {
1367            offset = 0;
1368        }
1369        line = line1;
1370    }
1371}
1372
1373enum {
1374    VGA_DRAW_LINE2,
1375    VGA_DRAW_LINE2D2,
1376    VGA_DRAW_LINE4,
1377    VGA_DRAW_LINE4D2,
1378    VGA_DRAW_LINE8D2,
1379    VGA_DRAW_LINE8,
1380    VGA_DRAW_LINE15_LE,
1381    VGA_DRAW_LINE16_LE,
1382    VGA_DRAW_LINE24_LE,
1383    VGA_DRAW_LINE32_LE,
1384    VGA_DRAW_LINE15_BE,
1385    VGA_DRAW_LINE16_BE,
1386    VGA_DRAW_LINE24_BE,
1387    VGA_DRAW_LINE32_BE,
1388    VGA_DRAW_LINE_NB,
1389};
1390
1391static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
1392    vga_draw_line2,
1393    vga_draw_line2d2,
1394    vga_draw_line4,
1395    vga_draw_line4d2,
1396    vga_draw_line8d2,
1397    vga_draw_line8,
1398    vga_draw_line15_le,
1399    vga_draw_line16_le,
1400    vga_draw_line24_le,
1401    vga_draw_line32_le,
1402    vga_draw_line15_be,
1403    vga_draw_line16_be,
1404    vga_draw_line24_be,
1405    vga_draw_line32_be,
1406};
1407
1408static int vga_get_bpp(VGACommonState *s)
1409{
1410    int ret;
1411
1412    if (vbe_enabled(s)) {
1413        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1414    } else {
1415        ret = 0;
1416    }
1417    return ret;
1418}
1419
1420static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1421{
1422    int width, height;
1423
1424    if (vbe_enabled(s)) {
1425        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1426        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1427    } else {
1428        width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1429        height = s->cr[VGA_CRTC_V_DISP_END] |
1430            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1431            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1432        height = (height + 1);
1433    }
1434    *pwidth = width;
1435    *pheight = height;
1436}
1437
1438void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1439{
1440    int y;
1441    if (y1 >= VGA_MAX_HEIGHT)
1442        return;
1443    if (y2 >= VGA_MAX_HEIGHT)
1444        y2 = VGA_MAX_HEIGHT;
1445    for(y = y1; y < y2; y++) {
1446        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1447    }
1448}
1449
1450void vga_sync_dirty_bitmap(VGACommonState *s)
1451{
1452    memory_region_sync_dirty_bitmap(&s->vram);
1453}
1454
1455void vga_dirty_log_start(VGACommonState *s)
1456{
1457    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1458}
1459
1460void vga_dirty_log_stop(VGACommonState *s)
1461{
1462    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1463}
1464
1465/*
1466 * graphic modes
1467 */
1468static void vga_draw_graphic(VGACommonState *s, int full_update)
1469{
1470    DisplaySurface *surface = qemu_console_surface(s->con);
1471    int y1, y, update, linesize, y_start, double_scan, mask, depth;
1472    int width, height, shift_control, line_offset, bwidth, bits;
1473    ram_addr_t page0, page1, page_min, page_max;
1474    int disp_width, multi_scan, multi_run;
1475    uint8_t *d;
1476    uint32_t v, addr1, addr;
1477    vga_draw_line_func *vga_draw_line = NULL;
1478    bool share_surface;
1479    pixman_format_code_t format;
1480#ifdef HOST_WORDS_BIGENDIAN
1481    bool byteswap = !s->big_endian_fb;
1482#else
1483    bool byteswap = s->big_endian_fb;
1484#endif
1485
1486    full_update |= update_basic_params(s);
1487
1488    if (!full_update)
1489        vga_sync_dirty_bitmap(s);
1490
1491    s->get_resolution(s, &width, &height);
1492    disp_width = width;
1493
1494    shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1495    double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1496    if (shift_control != 1) {
1497        multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1498            - 1;
1499    } else {
1500        /* in CGA modes, multi_scan is ignored */
1501        /* XXX: is it correct ? */
1502        multi_scan = double_scan;
1503    }
1504    multi_run = multi_scan;
1505    if (shift_control != s->shift_control ||
1506        double_scan != s->double_scan) {
1507        full_update = 1;
1508        s->shift_control = shift_control;
1509        s->double_scan = double_scan;
1510    }
1511
1512    if (shift_control == 0) {
1513        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1514            disp_width <<= 1;
1515        }
1516    } else if (shift_control == 1) {
1517        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1518            disp_width <<= 1;
1519        }
1520    }
1521
1522    depth = s->get_bpp(s);
1523
1524    /*
1525     * Check whether we can share the surface with the backend
1526     * or whether we need a shadow surface. We share native
1527     * endian surfaces for 15bpp and above and byteswapped
1528     * surfaces for 24bpp and above.
1529     */
1530    format = qemu_default_pixman_format(depth, !byteswap);
1531    if (format) {
1532        share_surface = dpy_gfx_check_format(s->con, format)
1533            && !s->force_shadow;
1534    } else {
1535        share_surface = false;
1536    }
1537    if (s->line_offset != s->last_line_offset ||
1538        disp_width != s->last_width ||
1539        height != s->last_height ||
1540        s->last_depth != depth ||
1541        s->last_byteswap != byteswap ||
1542        share_surface != is_buffer_shared(surface)) {
1543        if (share_surface) {
1544            surface = qemu_create_displaysurface_from(disp_width,
1545                    height, format, s->line_offset,
1546                    s->vram_ptr + (s->start_addr * 4));
1547            dpy_gfx_replace_surface(s->con, surface);
1548#ifdef DEBUG_VGA
1549            printf("VGA: Using shared surface for depth=%d swap=%d\n",
1550                   depth, byteswap);
1551#endif
1552        } else {
1553            qemu_console_resize(s->con, disp_width, height);
1554            surface = qemu_console_surface(s->con);
1555#ifdef DEBUG_VGA
1556            printf("VGA: Using shadow surface for depth=%d swap=%d\n",
1557                   depth, byteswap);
1558#endif
1559        }
1560        s->last_scr_width = disp_width;
1561        s->last_scr_height = height;
1562        s->last_width = disp_width;
1563        s->last_height = height;
1564        s->last_line_offset = s->line_offset;
1565        s->last_depth = depth;
1566        s->last_byteswap = byteswap;
1567        full_update = 1;
1568    } else if (is_buffer_shared(surface) &&
1569               (full_update || surface_data(surface) != s->vram_ptr
1570                + (s->start_addr * 4))) {
1571        pixman_format_code_t format =
1572            qemu_default_pixman_format(depth, !byteswap);
1573        surface = qemu_create_displaysurface_from(disp_width,
1574                height, format, s->line_offset,
1575                s->vram_ptr + (s->start_addr * 4));
1576        dpy_gfx_replace_surface(s->con, surface);
1577    }
1578
1579    if (shift_control == 0) {
1580        full_update |= update_palette16(s);
1581        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1582            v = VGA_DRAW_LINE4D2;
1583        } else {
1584            v = VGA_DRAW_LINE4;
1585        }
1586        bits = 4;
1587    } else if (shift_control == 1) {
1588        full_update |= update_palette16(s);
1589        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1590            v = VGA_DRAW_LINE2D2;
1591        } else {
1592            v = VGA_DRAW_LINE2;
1593        }
1594        bits = 4;
1595    } else {
1596        switch(s->get_bpp(s)) {
1597        default:
1598        case 0:
1599            full_update |= update_palette256(s);
1600            v = VGA_DRAW_LINE8D2;
1601            bits = 4;
1602            break;
1603        case 8:
1604            full_update |= update_palette256(s);
1605            v = VGA_DRAW_LINE8;
1606            bits = 8;
1607            break;
1608        case 15:
1609            v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1610            bits = 16;
1611            break;
1612        case 16:
1613            v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1614            bits = 16;
1615            break;
1616        case 24:
1617            v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1618            bits = 24;
1619            break;
1620        case 32:
1621            v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1622            bits = 32;
1623            break;
1624        }
1625    }
1626    vga_draw_line = vga_draw_line_table[v];
1627
1628    if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1629        s->cursor_invalidate(s);
1630    }
1631
1632    line_offset = s->line_offset;
1633#if 0
1634    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",
1635           width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1636           s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1637#endif
1638    addr1 = (s->start_addr * 4);
1639    bwidth = (width * bits + 7) / 8;
1640    y_start = -1;
1641    page_min = -1;
1642    page_max = 0;
1643    d = surface_data(surface);
1644    linesize = surface_stride(surface);
1645    y1 = 0;
1646    for(y = 0; y < height; y++) {
1647        addr = addr1;
1648        if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1649            int shift;
1650            /* CGA compatibility handling */
1651            shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1652            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1653        }
1654        if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1655            addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1656        }
1657        update = full_update;
1658        page0 = addr;
1659        page1 = addr + bwidth - 1;
1660        update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1661                                          DIRTY_MEMORY_VGA);
1662        /* explicit invalidation for the hardware cursor */
1663        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1664        if (update) {
1665            if (y_start < 0)
1666                y_start = y;
1667            if (page0 < page_min)
1668                page_min = page0;
1669            if (page1 > page_max)
1670                page_max = page1;
1671            if (!(is_buffer_shared(surface))) {
1672                vga_draw_line(s, d, s->vram_ptr + addr, width);
1673                if (s->cursor_draw_line)
1674                    s->cursor_draw_line(s, d, y);
1675            }
1676        } else {
1677            if (y_start >= 0) {
1678                /* flush to display */
1679                dpy_gfx_update(s->con, 0, y_start,
1680                               disp_width, y - y_start);
1681                y_start = -1;
1682            }
1683        }
1684        if (!multi_run) {
1685            mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1686            if ((y1 & mask) == mask)
1687                addr1 += line_offset;
1688            y1++;
1689            multi_run = multi_scan;
1690        } else {
1691            multi_run--;
1692        }
1693        /* line compare acts on the displayed lines */
1694        if (y == s->line_compare)
1695            addr1 = 0;
1696        d += linesize;
1697    }
1698    if (y_start >= 0) {
1699        /* flush to display */
1700        dpy_gfx_update(s->con, 0, y_start,
1701                       disp_width, y - y_start);
1702    }
1703    /* reset modified pages */
1704    if (page_max >= page_min) {
1705        memory_region_reset_dirty(&s->vram,
1706                                  page_min,
1707                                  page_max - page_min,
1708                                  DIRTY_MEMORY_VGA);
1709    }
1710    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1711}
1712
1713static void vga_draw_blank(VGACommonState *s, int full_update)
1714{
1715    DisplaySurface *surface = qemu_console_surface(s->con);
1716    int i, w;
1717    uint8_t *d;
1718
1719    if (!full_update)
1720        return;
1721    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1722        return;
1723
1724    w = s->last_scr_width * surface_bytes_per_pixel(surface);
1725    d = surface_data(surface);
1726    for(i = 0; i < s->last_scr_height; i++) {
1727        memset(d, 0, w);
1728        d += surface_stride(surface);
1729    }
1730    dpy_gfx_update(s->con, 0, 0,
1731                   s->last_scr_width, s->last_scr_height);
1732}
1733
1734#define GMODE_TEXT     0
1735#define GMODE_GRAPH    1
1736#define GMODE_BLANK 2
1737
1738static void vga_update_display(void *opaque)
1739{
1740    VGACommonState *s = opaque;
1741    DisplaySurface *surface = qemu_console_surface(s->con);
1742    int full_update, graphic_mode;
1743
1744    qemu_flush_coalesced_mmio_buffer();
1745
1746    if (surface_bits_per_pixel(surface) == 0) {
1747        /* nothing to do */
1748    } else {
1749        full_update = 0;
1750        if (!(s->ar_index & 0x20)) {
1751            graphic_mode = GMODE_BLANK;
1752        } else {
1753            graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1754        }
1755        if (graphic_mode != s->graphic_mode) {
1756            s->graphic_mode = graphic_mode;
1757            s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1758            full_update = 1;
1759        }
1760        switch(graphic_mode) {
1761        case GMODE_TEXT:
1762            vga_draw_text(s, full_update);
1763            break;
1764        case GMODE_GRAPH:
1765            vga_draw_graphic(s, full_update);
1766            break;
1767        case GMODE_BLANK:
1768        default:
1769            vga_draw_blank(s, full_update);
1770            break;
1771        }
1772    }
1773}
1774
1775/* force a full display refresh */
1776static void vga_invalidate_display(void *opaque)
1777{
1778    VGACommonState *s = opaque;
1779
1780    s->last_width = -1;
1781    s->last_height = -1;
1782}
1783
1784void vga_common_reset(VGACommonState *s)
1785{
1786    s->sr_index = 0;
1787    memset(s->sr, '\0', sizeof(s->sr));
1788    memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1789    s->gr_index = 0;
1790    memset(s->gr, '\0', sizeof(s->gr));
1791    s->ar_index = 0;
1792    memset(s->ar, '\0', sizeof(s->ar));
1793    s->ar_flip_flop = 0;
1794    s->cr_index = 0;
1795    memset(s->cr, '\0', sizeof(s->cr));
1796    s->msr = 0;
1797    s->fcr = 0;
1798    s->st00 = 0;
1799    s->st01 = 0;
1800    s->dac_state = 0;
1801    s->dac_sub_index = 0;
1802    s->dac_read_index = 0;
1803    s->dac_write_index = 0;
1804    memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1805    s->dac_8bit = 0;
1806    memset(s->palette, '\0', sizeof(s->palette));
1807    s->bank_offset = 0;
1808    s->vbe_index = 0;
1809    memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1810    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1811    s->vbe_start_addr = 0;
1812    s->vbe_line_offset = 0;
1813    s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1814    memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1815    s->graphic_mode = -1; /* force full update */
1816    s->shift_control = 0;
1817    s->double_scan = 0;
1818    s->line_offset = 0;
1819    s->line_compare = 0;
1820    s->start_addr = 0;
1821    s->plane_updated = 0;
1822    s->last_cw = 0;
1823    s->last_ch = 0;
1824    s->last_width = 0;
1825    s->last_height = 0;
1826    s->last_scr_width = 0;
1827    s->last_scr_height = 0;
1828    s->cursor_start = 0;
1829    s->cursor_end = 0;
1830    s->cursor_offset = 0;
1831    s->big_endian_fb = s->default_endian_fb;
1832    memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1833    memset(s->last_palette, '\0', sizeof(s->last_palette));
1834    memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1835    switch (vga_retrace_method) {
1836    case VGA_RETRACE_DUMB:
1837        break;
1838    case VGA_RETRACE_PRECISE:
1839        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1840        break;
1841    }
1842    vga_update_memory_access(s);
1843}
1844
1845static void vga_reset(void *opaque)
1846{
1847    VGACommonState *s =  opaque;
1848    vga_common_reset(s);
1849}
1850
1851#define TEXTMODE_X(x)   ((x) % width)
1852#define TEXTMODE_Y(x)   ((x) / width)
1853#define VMEM2CHTYPE(v)  ((v & 0xff0007ff) | \
1854        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1855/* relay text rendering to the display driver
1856 * instead of doing a full vga_update_display() */
1857static void vga_update_text(void *opaque, console_ch_t *chardata)
1858{
1859    VGACommonState *s =  opaque;
1860    int graphic_mode, i, cursor_offset, cursor_visible;
1861    int cw, cheight, width, height, size, c_min, c_max;
1862    uint32_t *src;
1863    console_ch_t *dst, val;
1864    char msg_buffer[80];
1865    int full_update = 0;
1866
1867    qemu_flush_coalesced_mmio_buffer();
1868
1869    if (!(s->ar_index & 0x20)) {
1870        graphic_mode = GMODE_BLANK;
1871    } else {
1872        graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1873    }
1874    if (graphic_mode != s->graphic_mode) {
1875        s->graphic_mode = graphic_mode;
1876        full_update = 1;
1877    }
1878    if (s->last_width == -1) {
1879        s->last_width = 0;
1880        full_update = 1;
1881    }
1882
1883    switch (graphic_mode) {
1884    case GMODE_TEXT:
1885        /* TODO: update palette */
1886        full_update |= update_basic_params(s);
1887
1888        /* total width & height */
1889        cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1890        cw = 8;
1891        if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1892            cw = 9;
1893        }
1894        if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1895            cw = 16; /* NOTE: no 18 pixel wide */
1896        }
1897        width = (s->cr[VGA_CRTC_H_DISP] + 1);
1898        if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1899            /* ugly hack for CGA 160x100x16 - explain me the logic */
1900            height = 100;
1901        } else {
1902            height = s->cr[VGA_CRTC_V_DISP_END] |
1903                ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1904                ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1905            height = (height + 1) / cheight;
1906        }
1907
1908        size = (height * width);
1909        if (size > CH_ATTR_SIZE) {
1910            if (!full_update)
1911                return;
1912
1913            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1914                     width, height);
1915            break;
1916        }
1917
1918        if (width != s->last_width || height != s->last_height ||
1919            cw != s->last_cw || cheight != s->last_ch) {
1920            s->last_scr_width = width * cw;
1921            s->last_scr_height = height * cheight;
1922            qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1923            dpy_text_resize(s->con, width, height);
1924            s->last_depth = 0;
1925            s->last_width = width;
1926            s->last_height = height;
1927            s->last_ch = cheight;
1928            s->last_cw = cw;
1929            full_update = 1;
1930        }
1931
1932        if (full_update) {
1933            s->full_update_gfx = 1;
1934        }
1935        if (s->full_update_text) {
1936            s->full_update_text = 0;
1937            full_update |= 1;
1938        }
1939
1940        /* Update "hardware" cursor */
1941        cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1942                         s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1943        if (cursor_offset != s->cursor_offset ||
1944            s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1945            s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1946            cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1947            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1948                dpy_text_cursor(s->con,
1949                                TEXTMODE_X(cursor_offset),
1950                                TEXTMODE_Y(cursor_offset));
1951            else
1952                dpy_text_cursor(s->con, -1, -1);
1953            s->cursor_offset = cursor_offset;
1954            s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1955            s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1956        }
1957
1958        src = (uint32_t *) s->vram_ptr + s->start_addr;
1959        dst = chardata;
1960
1961        if (full_update) {
1962            for (i = 0; i < size; src ++, dst ++, i ++)
1963                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1964
1965            dpy_text_update(s->con, 0, 0, width, height);
1966        } else {
1967            c_max = 0;
1968
1969            for (i = 0; i < size; src ++, dst ++, i ++) {
1970                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1971                if (*dst != val) {
1972                    *dst = val;
1973                    c_max = i;
1974                    break;
1975                }
1976            }
1977            c_min = i;
1978            for (; i < size; src ++, dst ++, i ++) {
1979                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1980                if (*dst != val) {
1981                    *dst = val;
1982                    c_max = i;
1983                }
1984            }
1985
1986            if (c_min <= c_max) {
1987                i = TEXTMODE_Y(c_min);
1988                dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
1989            }
1990        }
1991
1992        return;
1993    case GMODE_GRAPH:
1994        if (!full_update)
1995            return;
1996
1997        s->get_resolution(s, &width, &height);
1998        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
1999                 width, height);
2000        break;
2001    case GMODE_BLANK:
2002    default:
2003        if (!full_update)
2004            return;
2005
2006        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2007        break;
2008    }
2009
2010    /* Display a message */
2011    s->last_width = 60;
2012    s->last_height = height = 3;
2013    dpy_text_cursor(s->con, -1, -1);
2014    dpy_text_resize(s->con, s->last_width, height);
2015
2016    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2017        console_write_ch(dst ++, ' ');
2018
2019    size = strlen(msg_buffer);
2020    width = (s->last_width - size) / 2;
2021    dst = chardata + s->last_width + width;
2022    for (i = 0; i < size; i ++)
2023        console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2024                                             QEMU_COLOR_BLACK, 1));
2025
2026    dpy_text_update(s->con, 0, 0, s->last_width, height);
2027}
2028
2029static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2030                             unsigned size)
2031{
2032    VGACommonState *s = opaque;
2033
2034    return vga_mem_readb(s, addr);
2035}
2036
2037static void vga_mem_write(void *opaque, hwaddr addr,
2038                          uint64_t data, unsigned size)
2039{
2040    VGACommonState *s = opaque;
2041
2042    vga_mem_writeb(s, addr, data);
2043}
2044
2045const MemoryRegionOps vga_mem_ops = {
2046    .read = vga_mem_read,
2047    .write = vga_mem_write,
2048    .endianness = DEVICE_LITTLE_ENDIAN,
2049    .impl = {
2050        .min_access_size = 1,
2051        .max_access_size = 1,
2052    },
2053};
2054
2055static int vga_common_post_load(void *opaque, int version_id)
2056{
2057    VGACommonState *s = opaque;
2058
2059    /* force refresh */
2060    s->graphic_mode = -1;
2061    vbe_update_vgaregs(s);
2062    return 0;
2063}
2064
2065static bool vga_endian_state_needed(void *opaque)
2066{
2067    VGACommonState *s = opaque;
2068
2069    /*
2070     * Only send the endian state if it's different from the
2071     * default one, thus ensuring backward compatibility for
2072     * migration of the common case
2073     */
2074    return s->default_endian_fb != s->big_endian_fb;
2075}
2076
2077static const VMStateDescription vmstate_vga_endian = {
2078    .name = "vga.endian",
2079    .version_id = 1,
2080    .minimum_version_id = 1,
2081    .needed = vga_endian_state_needed,
2082    .fields = (VMStateField[]) {
2083        VMSTATE_BOOL(big_endian_fb, VGACommonState),
2084        VMSTATE_END_OF_LIST()
2085    }
2086};
2087
2088const VMStateDescription vmstate_vga_common = {
2089    .name = "vga",
2090    .version_id = 2,
2091    .minimum_version_id = 2,
2092    .post_load = vga_common_post_load,
2093    .fields = (VMStateField[]) {
2094        VMSTATE_UINT32(latch, VGACommonState),
2095        VMSTATE_UINT8(sr_index, VGACommonState),
2096        VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2097        VMSTATE_UINT8(gr_index, VGACommonState),
2098        VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2099        VMSTATE_UINT8(ar_index, VGACommonState),
2100        VMSTATE_BUFFER(ar, VGACommonState),
2101        VMSTATE_INT32(ar_flip_flop, VGACommonState),
2102        VMSTATE_UINT8(cr_index, VGACommonState),
2103        VMSTATE_BUFFER(cr, VGACommonState),
2104        VMSTATE_UINT8(msr, VGACommonState),
2105        VMSTATE_UINT8(fcr, VGACommonState),
2106        VMSTATE_UINT8(st00, VGACommonState),
2107        VMSTATE_UINT8(st01, VGACommonState),
2108
2109        VMSTATE_UINT8(dac_state, VGACommonState),
2110        VMSTATE_UINT8(dac_sub_index, VGACommonState),
2111        VMSTATE_UINT8(dac_read_index, VGACommonState),
2112        VMSTATE_UINT8(dac_write_index, VGACommonState),
2113        VMSTATE_BUFFER(dac_cache, VGACommonState),
2114        VMSTATE_BUFFER(palette, VGACommonState),
2115
2116        VMSTATE_INT32(bank_offset, VGACommonState),
2117        VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2118        VMSTATE_UINT16(vbe_index, VGACommonState),
2119        VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2120        VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2121        VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2122        VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2123        VMSTATE_END_OF_LIST()
2124    },
2125    .subsections = (const VMStateDescription*[]) {
2126        &vmstate_vga_endian,
2127        NULL
2128    }
2129};
2130
2131static const GraphicHwOps vga_ops = {
2132    .invalidate  = vga_invalidate_display,
2133    .gfx_update  = vga_update_display,
2134    .text_update = vga_update_text,
2135};
2136
2137static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2138{
2139    if (val < vmin) {
2140        return vmin;
2141    }
2142    if (val > vmax) {
2143        return vmax;
2144    }
2145    return val;
2146}
2147
2148void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
2149{
2150    int i, j, v, b;
2151
2152    for(i = 0;i < 256; i++) {
2153        v = 0;
2154        for(j = 0; j < 8; j++) {
2155            v |= ((i >> j) & 1) << (j * 4);
2156        }
2157        expand4[i] = v;
2158
2159        v = 0;
2160        for(j = 0; j < 4; j++) {
2161            v |= ((i >> (2 * j)) & 3) << (j * 4);
2162        }
2163        expand2[i] = v;
2164    }
2165    for(i = 0; i < 16; i++) {
2166        v = 0;
2167        for(j = 0; j < 4; j++) {
2168            b = ((i >> j) & 1);
2169            v |= b << (2 * j);
2170            v |= b << (2 * j + 1);
2171        }
2172        expand4to8[i] = v;
2173    }
2174
2175    s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2176    s->vram_size_mb = pow2ceil(s->vram_size_mb);
2177    s->vram_size = s->vram_size_mb << 20;
2178
2179    if (!s->vbe_size) {
2180        s->vbe_size = s->vram_size;
2181    }
2182
2183    s->is_vbe_vmstate = 1;
2184    memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size,
2185                           &error_fatal);
2186    vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj));
2187    xen_register_framebuffer(&s->vram);
2188    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2189    s->get_bpp = vga_get_bpp;
2190    s->get_offsets = vga_get_offsets;
2191    s->get_resolution = vga_get_resolution;
2192    s->hw_ops = &vga_ops;
2193    switch (vga_retrace_method) {
2194    case VGA_RETRACE_DUMB:
2195        s->retrace = vga_dumb_retrace;
2196        s->update_retrace_info = vga_dumb_update_retrace_info;
2197        break;
2198
2199    case VGA_RETRACE_PRECISE:
2200        s->retrace = vga_precise_retrace;
2201        s->update_retrace_info = vga_precise_update_retrace_info;
2202        break;
2203    }
2204
2205    /*
2206     * Set default fb endian based on target, could probably be turned
2207     * into a device attribute set by the machine/platform to remove
2208     * all target endian dependencies from this file.
2209     */
2210#ifdef TARGET_WORDS_BIGENDIAN
2211    s->default_endian_fb = true;
2212#else
2213    s->default_endian_fb = false;
2214#endif
2215    vga_dirty_log_start(s);
2216}
2217
2218static const MemoryRegionPortio vga_portio_list[] = {
2219    { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2220    { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2221    { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2222    { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2223    { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2224    PORTIO_END_OF_LIST(),
2225};
2226
2227static const MemoryRegionPortio vbe_portio_list[] = {
2228    { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2229# ifdef TARGET_I386
2230    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2231# endif
2232    { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2233    PORTIO_END_OF_LIST(),
2234};
2235
2236/* Used by both ISA and PCI */
2237MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2238                          const MemoryRegionPortio **vga_ports,
2239                          const MemoryRegionPortio **vbe_ports)
2240{
2241    MemoryRegion *vga_mem;
2242
2243    *vga_ports = vga_portio_list;
2244    *vbe_ports = vbe_portio_list;
2245
2246    vga_mem = g_malloc(sizeof(*vga_mem));
2247    memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2248                          "vga-lowmem", 0x20000);
2249    memory_region_set_flush_coalesced(vga_mem);
2250
2251    return vga_mem;
2252}
2253
2254void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2255              MemoryRegion *address_space_io, bool init_vga_ports)
2256{
2257    MemoryRegion *vga_io_memory;
2258    const MemoryRegionPortio *vga_ports, *vbe_ports;
2259
2260    qemu_register_reset(vga_reset, s);
2261
2262    s->bank_offset = 0;
2263
2264    s->legacy_address_space = address_space;
2265
2266    vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2267    memory_region_add_subregion_overlap(address_space,
2268                                        0x000a0000,
2269                                        vga_io_memory,
2270                                        1);
2271    memory_region_set_coalescing(vga_io_memory);
2272    if (init_vga_ports) {
2273        portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2274        portio_list_set_flush_coalesced(&s->vga_port_list);
2275        portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2276    }
2277    if (vbe_ports) {
2278        portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2279        portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2280    }
2281}
2282
2283void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2284{
2285    /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2286     * so use an alias to avoid double-mapping the same region.
2287     */
2288    memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2289                             &s->vram, 0, memory_region_size(&s->vram));
2290    /* XXX: use optimized standard vga accesses */
2291    memory_region_add_subregion(system_memory,
2292                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2293                                &s->vram_vbe);
2294    s->vbe_mapped = 1;
2295}
2296