Statistics
| Branch: | Revision:

root / hw / vga.c @ d36b66f7

History | View | Annotate | Download (71.8 kB)

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.h"
25
#include "vga.h"
26
#include "console.h"
27
#include "pc.h"
28
#include "pci.h"
29
#include "vga_int.h"
30
#include "pixel_ops.h"
31
#include "qemu-timer.h"
32
#include "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 */
57
const uint8_t sr_mask[8] = {
58
    0x03,
59
    0x3d,
60
    0x0f,
61
    0x3f,
62
    0x0e,
63
    0x00,
64
    0x00,
65
    0xff,
66
};
67

    
68
const 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

    
112
static 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

    
139
static const uint32_t dmask16[16] = {
140
    PAT(0x00000000),
141
    PAT(0x000000ff),
142
    PAT(0x0000ff00),
143
    PAT(0x0000ffff),
144
    PAT(0x00ff0000),
145
    PAT(0x00ff00ff),
146
    PAT(0x00ffff00),
147
    PAT(0x00ffffff),
148
    PAT(0xff000000),
149
    PAT(0xff0000ff),
150
    PAT(0xff00ff00),
151
    PAT(0xff00ffff),
152
    PAT(0xffff0000),
153
    PAT(0xffff00ff),
154
    PAT(0xffffff00),
155
    PAT(0xffffffff),
156
};
157

    
158
static const uint32_t dmask4[4] = {
159
    PAT(0x00000000),
160
    PAT(0x0000ffff),
161
    PAT(0xffff0000),
162
    PAT(0xffffffff),
163
};
164

    
165
static uint32_t expand4[256];
166
static uint16_t expand2[256];
167
static uint8_t expand4to8[16];
168

    
169
static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
170
                            Error **errp);
171

    
172
static void vga_update_memory_access(VGACommonState *s)
173
{
174
    MemoryRegion *region, *old_region = s->chain4_alias;
175
    hwaddr base, offset, size;
176

    
177
    s->chain4_alias = NULL;
178

    
179
    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
180
        VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
181
        offset = 0;
182
        switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
183
        case 0:
184
            base = 0xa0000;
185
            size = 0x20000;
186
            break;
187
        case 1:
188
            base = 0xa0000;
189
            size = 0x10000;
190
            offset = s->bank_offset;
191
            break;
192
        case 2:
193
            base = 0xb0000;
194
            size = 0x8000;
195
            break;
196
        case 3:
197
        default:
198
            base = 0xb8000;
199
            size = 0x8000;
200
            break;
201
        }
202
        base += isa_mem_base;
203
        region = g_malloc(sizeof(*region));
204
        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
205
        memory_region_add_subregion_overlap(s->legacy_address_space, base,
206
                                            region, 2);
207
        s->chain4_alias = region;
208
    }
209
    if (old_region) {
210
        memory_region_del_subregion(s->legacy_address_space, old_region);
211
        memory_region_destroy(old_region);
212
        g_free(old_region);
213
        s->plane_updated = 0xf;
214
    }
215
}
216

    
217
static void vga_dumb_update_retrace_info(VGACommonState *s)
218
{
219
    (void) s;
220
}
221

    
222
static void vga_precise_update_retrace_info(VGACommonState *s)
223
{
224
    int htotal_chars;
225
    int hretr_start_char;
226
    int hretr_skew_chars;
227
    int hretr_end_char;
228

    
229
    int vtotal_lines;
230
    int vretr_start_line;
231
    int vretr_end_line;
232

    
233
    int dots;
234
#if 0
235
    int div2, sldiv2;
236
#endif
237
    int clocking_mode;
238
    int clock_sel;
239
    const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
240
    int64_t chars_per_sec;
241
    struct vga_precise_retrace *r = &s->retrace_info.precise;
242

    
243
    htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
244
    hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
245
    hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
246
    hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
247

    
248
    vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
249
                    (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
250
                      ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
251
    vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
252
        ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
253
          ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
254
    vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
255

    
256
    clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
257
    clock_sel = (s->msr >> 2) & 3;
258
    dots = (s->msr & 1) ? 8 : 9;
259

    
260
    chars_per_sec = clk_hz[clock_sel] / dots;
261

    
262
    htotal_chars <<= clocking_mode;
263

    
264
    r->total_chars = vtotal_lines * htotal_chars;
265
    if (r->freq) {
266
        r->ticks_per_char = get_ticks_per_sec() / (r->total_chars * r->freq);
267
    } else {
268
        r->ticks_per_char = get_ticks_per_sec() / chars_per_sec;
269
    }
270

    
271
    r->vstart = vretr_start_line;
272
    r->vend = r->vstart + vretr_end_line + 1;
273

    
274
    r->hstart = hretr_start_char + hretr_skew_chars;
275
    r->hend = r->hstart + hretr_end_char + 1;
276
    r->htotal = htotal_chars;
277

    
278
#if 0
279
    div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
280
    sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
281
    printf (
282
        "hz=%f\n"
283
        "htotal = %d\n"
284
        "hretr_start = %d\n"
285
        "hretr_skew = %d\n"
286
        "hretr_end = %d\n"
287
        "vtotal = %d\n"
288
        "vretr_start = %d\n"
289
        "vretr_end = %d\n"
290
        "div2 = %d sldiv2 = %d\n"
291
        "clocking_mode = %d\n"
292
        "clock_sel = %d %d\n"
293
        "dots = %d\n"
294
        "ticks/char = %" PRId64 "\n"
295
        "\n",
296
        (double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars),
297
        htotal_chars,
298
        hretr_start_char,
299
        hretr_skew_chars,
300
        hretr_end_char,
301
        vtotal_lines,
302
        vretr_start_line,
303
        vretr_end_line,
304
        div2, sldiv2,
305
        clocking_mode,
306
        clock_sel,
307
        clk_hz[clock_sel],
308
        dots,
309
        r->ticks_per_char
310
        );
311
#endif
312
}
313

    
314
static uint8_t vga_precise_retrace(VGACommonState *s)
315
{
316
    struct vga_precise_retrace *r = &s->retrace_info.precise;
317
    uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
318

    
319
    if (r->total_chars) {
320
        int cur_line, cur_line_char, cur_char;
321
        int64_t cur_tick;
322

    
323
        cur_tick = qemu_get_clock_ns(vm_clock);
324

    
325
        cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
326
        cur_line = cur_char / r->htotal;
327

    
328
        if (cur_line >= r->vstart && cur_line <= r->vend) {
329
            val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
330
        } else {
331
            cur_line_char = cur_char % r->htotal;
332
            if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
333
                val |= ST01_DISP_ENABLE;
334
            }
335
        }
336

    
337
        return val;
338
    } else {
339
        return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
340
    }
341
}
342

    
343
static uint8_t vga_dumb_retrace(VGACommonState *s)
344
{
345
    return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
346
}
347

    
348
int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
349
{
350
    if (s->msr & VGA_MIS_COLOR) {
351
        /* Color */
352
        return (addr >= 0x3b0 && addr <= 0x3bf);
353
    } else {
354
        /* Monochrome */
355
        return (addr >= 0x3d0 && addr <= 0x3df);
356
    }
357
}
358

    
359
uint32_t vga_ioport_read(void *opaque, uint32_t addr)
360
{
361
    VGACommonState *s = opaque;
362
    int val, index;
363

    
364
    qemu_flush_coalesced_mmio_buffer();
365

    
366
    if (vga_ioport_invalid(s, addr)) {
367
        val = 0xff;
368
    } else {
369
        switch(addr) {
370
        case VGA_ATT_W:
371
            if (s->ar_flip_flop == 0) {
372
                val = s->ar_index;
373
            } else {
374
                val = 0;
375
            }
376
            break;
377
        case VGA_ATT_R:
378
            index = s->ar_index & 0x1f;
379
            if (index < VGA_ATT_C) {
380
                val = s->ar[index];
381
            } else {
382
                val = 0;
383
            }
384
            break;
385
        case VGA_MIS_W:
386
            val = s->st00;
387
            break;
388
        case VGA_SEQ_I:
389
            val = s->sr_index;
390
            break;
391
        case VGA_SEQ_D:
392
            val = s->sr[s->sr_index];
393
#ifdef DEBUG_VGA_REG
394
            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
395
#endif
396
            break;
397
        case VGA_PEL_IR:
398
            val = s->dac_state;
399
            break;
400
        case VGA_PEL_IW:
401
            val = s->dac_write_index;
402
            break;
403
        case VGA_PEL_D:
404
            val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
405
            if (++s->dac_sub_index == 3) {
406
                s->dac_sub_index = 0;
407
                s->dac_read_index++;
408
            }
409
            break;
410
        case VGA_FTC_R:
411
            val = s->fcr;
412
            break;
413
        case VGA_MIS_R:
414
            val = s->msr;
415
            break;
416
        case VGA_GFX_I:
417
            val = s->gr_index;
418
            break;
419
        case VGA_GFX_D:
420
            val = s->gr[s->gr_index];
421
#ifdef DEBUG_VGA_REG
422
            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
423
#endif
424
            break;
425
        case VGA_CRT_IM:
426
        case VGA_CRT_IC:
427
            val = s->cr_index;
428
            break;
429
        case VGA_CRT_DM:
430
        case VGA_CRT_DC:
431
            val = s->cr[s->cr_index];
432
#ifdef DEBUG_VGA_REG
433
            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
434
#endif
435
            break;
436
        case VGA_IS1_RM:
437
        case VGA_IS1_RC:
438
            /* just toggle to fool polling */
439
            val = s->st01 = s->retrace(s);
440
            s->ar_flip_flop = 0;
441
            break;
442
        default:
443
            val = 0x00;
444
            break;
445
        }
446
    }
447
#if defined(DEBUG_VGA)
448
    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
449
#endif
450
    return val;
451
}
452

    
453
void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
454
{
455
    VGACommonState *s = opaque;
456
    int index;
457

    
458
    qemu_flush_coalesced_mmio_buffer();
459

    
460
    /* check port range access depending on color/monochrome mode */
461
    if (vga_ioport_invalid(s, addr)) {
462
        return;
463
    }
464
#ifdef DEBUG_VGA
465
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
466
#endif
467

    
468
    switch(addr) {
469
    case VGA_ATT_W:
470
        if (s->ar_flip_flop == 0) {
471
            val &= 0x3f;
472
            s->ar_index = val;
473
        } else {
474
            index = s->ar_index & 0x1f;
475
            switch(index) {
476
            case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
477
                s->ar[index] = val & 0x3f;
478
                break;
479
            case VGA_ATC_MODE:
480
                s->ar[index] = val & ~0x10;
481
                break;
482
            case VGA_ATC_OVERSCAN:
483
                s->ar[index] = val;
484
                break;
485
            case VGA_ATC_PLANE_ENABLE:
486
                s->ar[index] = val & ~0xc0;
487
                break;
488
            case VGA_ATC_PEL:
489
                s->ar[index] = val & ~0xf0;
490
                break;
491
            case VGA_ATC_COLOR_PAGE:
492
                s->ar[index] = val & ~0xf0;
493
                break;
494
            default:
495
                break;
496
            }
497
        }
498
        s->ar_flip_flop ^= 1;
499
        break;
500
    case VGA_MIS_W:
501
        s->msr = val & ~0x10;
502
        s->update_retrace_info(s);
503
        break;
504
    case VGA_SEQ_I:
505
        s->sr_index = val & 7;
506
        break;
507
    case VGA_SEQ_D:
508
#ifdef DEBUG_VGA_REG
509
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
510
#endif
511
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
512
        if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
513
            s->update_retrace_info(s);
514
        }
515
        vga_update_memory_access(s);
516
        break;
517
    case VGA_PEL_IR:
518
        s->dac_read_index = val;
519
        s->dac_sub_index = 0;
520
        s->dac_state = 3;
521
        break;
522
    case VGA_PEL_IW:
523
        s->dac_write_index = val;
524
        s->dac_sub_index = 0;
525
        s->dac_state = 0;
526
        break;
527
    case VGA_PEL_D:
528
        s->dac_cache[s->dac_sub_index] = val;
529
        if (++s->dac_sub_index == 3) {
530
            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
531
            s->dac_sub_index = 0;
532
            s->dac_write_index++;
533
        }
534
        break;
535
    case VGA_GFX_I:
536
        s->gr_index = val & 0x0f;
537
        break;
538
    case VGA_GFX_D:
539
#ifdef DEBUG_VGA_REG
540
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
541
#endif
542
        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
543
        vga_update_memory_access(s);
544
        break;
545
    case VGA_CRT_IM:
546
    case VGA_CRT_IC:
547
        s->cr_index = val;
548
        break;
549
    case VGA_CRT_DM:
550
    case VGA_CRT_DC:
551
#ifdef DEBUG_VGA_REG
552
        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
553
#endif
554
        /* handle CR0-7 protection */
555
        if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
556
            s->cr_index <= VGA_CRTC_OVERFLOW) {
557
            /* can always write bit 4 of CR7 */
558
            if (s->cr_index == VGA_CRTC_OVERFLOW) {
559
                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
560
                    (val & 0x10);
561
            }
562
            return;
563
        }
564
        s->cr[s->cr_index] = val;
565

    
566
        switch(s->cr_index) {
567
        case VGA_CRTC_H_TOTAL:
568
        case VGA_CRTC_H_SYNC_START:
569
        case VGA_CRTC_H_SYNC_END:
570
        case VGA_CRTC_V_TOTAL:
571
        case VGA_CRTC_OVERFLOW:
572
        case VGA_CRTC_V_SYNC_END:
573
        case VGA_CRTC_MODE:
574
            s->update_retrace_info(s);
575
            break;
576
        }
577
        break;
578
    case VGA_IS1_RM:
579
    case VGA_IS1_RC:
580
        s->fcr = val & 0x10;
581
        break;
582
    }
583
}
584

    
585
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
586
{
587
    VGACommonState *s = opaque;
588
    uint32_t val;
589
    val = s->vbe_index;
590
    return val;
591
}
592

    
593
uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
594
{
595
    VGACommonState *s = opaque;
596
    uint32_t val;
597

    
598
    if (s->vbe_index < VBE_DISPI_INDEX_NB) {
599
        if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
600
            switch(s->vbe_index) {
601
                /* XXX: do not hardcode ? */
602
            case VBE_DISPI_INDEX_XRES:
603
                val = VBE_DISPI_MAX_XRES;
604
                break;
605
            case VBE_DISPI_INDEX_YRES:
606
                val = VBE_DISPI_MAX_YRES;
607
                break;
608
            case VBE_DISPI_INDEX_BPP:
609
                val = VBE_DISPI_MAX_BPP;
610
                break;
611
            default:
612
                val = s->vbe_regs[s->vbe_index];
613
                break;
614
            }
615
        } else {
616
            val = s->vbe_regs[s->vbe_index];
617
        }
618
    } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
619
        val = s->vram_size / (64 * 1024);
620
    } else {
621
        val = 0;
622
    }
623
#ifdef DEBUG_BOCHS_VBE
624
    printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
625
#endif
626
    return val;
627
}
628

    
629
void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
630
{
631
    VGACommonState *s = opaque;
632
    s->vbe_index = val;
633
}
634

    
635
void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
636
{
637
    VGACommonState *s = opaque;
638

    
639
    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
640
#ifdef DEBUG_BOCHS_VBE
641
        printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
642
#endif
643
        switch(s->vbe_index) {
644
        case VBE_DISPI_INDEX_ID:
645
            if (val == VBE_DISPI_ID0 ||
646
                val == VBE_DISPI_ID1 ||
647
                val == VBE_DISPI_ID2 ||
648
                val == VBE_DISPI_ID3 ||
649
                val == VBE_DISPI_ID4) {
650
                s->vbe_regs[s->vbe_index] = val;
651
            }
652
            break;
653
        case VBE_DISPI_INDEX_XRES:
654
            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
655
                s->vbe_regs[s->vbe_index] = val;
656
            }
657
            break;
658
        case VBE_DISPI_INDEX_YRES:
659
            if (val <= VBE_DISPI_MAX_YRES) {
660
                s->vbe_regs[s->vbe_index] = val;
661
            }
662
            break;
663
        case VBE_DISPI_INDEX_BPP:
664
            if (val == 0)
665
                val = 8;
666
            if (val == 4 || val == 8 || val == 15 ||
667
                val == 16 || val == 24 || val == 32) {
668
                s->vbe_regs[s->vbe_index] = val;
669
            }
670
            break;
671
        case VBE_DISPI_INDEX_BANK:
672
            if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
673
              val &= (s->vbe_bank_mask >> 2);
674
            } else {
675
              val &= s->vbe_bank_mask;
676
            }
677
            s->vbe_regs[s->vbe_index] = val;
678
            s->bank_offset = (val << 16);
679
            vga_update_memory_access(s);
680
            break;
681
        case VBE_DISPI_INDEX_ENABLE:
682
            if ((val & VBE_DISPI_ENABLED) &&
683
                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
684
                int h, shift_control;
685

    
686
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
687
                    s->vbe_regs[VBE_DISPI_INDEX_XRES];
688
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
689
                    s->vbe_regs[VBE_DISPI_INDEX_YRES];
690
                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
691
                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
692

    
693
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
694
                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
695
                else
696
                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
697
                        ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
698
                s->vbe_start_addr = 0;
699

    
700
                /* clear the screen (should be done in BIOS) */
701
                if (!(val & VBE_DISPI_NOCLEARMEM)) {
702
                    memset(s->vram_ptr, 0,
703
                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
704
                }
705

    
706
                /* we initialize the VGA graphic mode (should be done
707
                   in BIOS) */
708
                /* graphic mode + memory map 1 */
709
                s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
710
                    VGA_GR06_GRAPHICS_MODE;
711
                s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
712
                s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
713
                /* width */
714
                s->cr[VGA_CRTC_H_DISP] =
715
                    (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
716
                /* height (only meaningful if < 1024) */
717
                h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
718
                s->cr[VGA_CRTC_V_DISP_END] = h;
719
                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
720
                    ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
721
                /* line compare to 1023 */
722
                s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
723
                s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
724
                s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
725

    
726
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
727
                    shift_control = 0;
728
                    s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
729
                } else {
730
                    shift_control = 2;
731
                    /* set chain 4 mode */
732
                    s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
733
                    /* activate all planes */
734
                    s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
735
                }
736
                s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
737
                    (shift_control << 5);
738
                s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
739
            } else {
740
                /* XXX: the bios should do that */
741
                s->bank_offset = 0;
742
            }
743
            s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
744
            s->vbe_regs[s->vbe_index] = val;
745
            vga_update_memory_access(s);
746
            break;
747
        case VBE_DISPI_INDEX_VIRT_WIDTH:
748
            {
749
                int w, h, line_offset;
750

    
751
                if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
752
                    return;
753
                w = val;
754
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
755
                    line_offset = w >> 1;
756
                else
757
                    line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
758
                h = s->vram_size / line_offset;
759
                /* XXX: support weird bochs semantics ? */
760
                if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
761
                    return;
762
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
763
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
764
                s->vbe_line_offset = line_offset;
765
            }
766
            break;
767
        case VBE_DISPI_INDEX_X_OFFSET:
768
        case VBE_DISPI_INDEX_Y_OFFSET:
769
            {
770
                int x;
771
                s->vbe_regs[s->vbe_index] = val;
772
                s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
773
                x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
774
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
775
                    s->vbe_start_addr += x >> 1;
776
                else
777
                    s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
778
                s->vbe_start_addr >>= 2;
779
            }
780
            break;
781
        default:
782
            break;
783
        }
784
    }
785
}
786

    
787
/* called for accesses between 0xa0000 and 0xc0000 */
788
uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
789
{
790
    int memory_map_mode, plane;
791
    uint32_t ret;
792

    
793
    /* convert to VGA memory offset */
794
    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
795
    addr &= 0x1ffff;
796
    switch(memory_map_mode) {
797
    case 0:
798
        break;
799
    case 1:
800
        if (addr >= 0x10000)
801
            return 0xff;
802
        addr += s->bank_offset;
803
        break;
804
    case 2:
805
        addr -= 0x10000;
806
        if (addr >= 0x8000)
807
            return 0xff;
808
        break;
809
    default:
810
    case 3:
811
        addr -= 0x18000;
812
        if (addr >= 0x8000)
813
            return 0xff;
814
        break;
815
    }
816

    
817
    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
818
        /* chain 4 mode : simplest access */
819
        ret = s->vram_ptr[addr];
820
    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
821
        /* odd/even mode (aka text mode mapping) */
822
        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
823
        ret = s->vram_ptr[((addr & ~1) << 1) | plane];
824
    } else {
825
        /* standard VGA latched access */
826
        s->latch = ((uint32_t *)s->vram_ptr)[addr];
827

    
828
        if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
829
            /* read mode 0 */
830
            plane = s->gr[VGA_GFX_PLANE_READ];
831
            ret = GET_PLANE(s->latch, plane);
832
        } else {
833
            /* read mode 1 */
834
            ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
835
                mask16[s->gr[VGA_GFX_COMPARE_MASK]];
836
            ret |= ret >> 16;
837
            ret |= ret >> 8;
838
            ret = (~ret) & 0xff;
839
        }
840
    }
841
    return ret;
842
}
843

    
844
/* called for accesses between 0xa0000 and 0xc0000 */
845
void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
846
{
847
    int memory_map_mode, plane, write_mode, b, func_select, mask;
848
    uint32_t write_mask, bit_mask, set_mask;
849

    
850
#ifdef DEBUG_VGA_MEM
851
    printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
852
#endif
853
    /* convert to VGA memory offset */
854
    memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
855
    addr &= 0x1ffff;
856
    switch(memory_map_mode) {
857
    case 0:
858
        break;
859
    case 1:
860
        if (addr >= 0x10000)
861
            return;
862
        addr += s->bank_offset;
863
        break;
864
    case 2:
865
        addr -= 0x10000;
866
        if (addr >= 0x8000)
867
            return;
868
        break;
869
    default:
870
    case 3:
871
        addr -= 0x18000;
872
        if (addr >= 0x8000)
873
            return;
874
        break;
875
    }
876

    
877
    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
878
        /* chain 4 mode : simplest access */
879
        plane = addr & 3;
880
        mask = (1 << plane);
881
        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
882
            s->vram_ptr[addr] = val;
883
#ifdef DEBUG_VGA_MEM
884
            printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
885
#endif
886
            s->plane_updated |= mask; /* only used to detect font change */
887
            memory_region_set_dirty(&s->vram, addr, 1);
888
        }
889
    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
890
        /* odd/even mode (aka text mode mapping) */
891
        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
892
        mask = (1 << plane);
893
        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
894
            addr = ((addr & ~1) << 1) | plane;
895
            s->vram_ptr[addr] = val;
896
#ifdef DEBUG_VGA_MEM
897
            printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
898
#endif
899
            s->plane_updated |= mask; /* only used to detect font change */
900
            memory_region_set_dirty(&s->vram, addr, 1);
901
        }
902
    } else {
903
        /* standard VGA latched access */
904
        write_mode = s->gr[VGA_GFX_MODE] & 3;
905
        switch(write_mode) {
906
        default:
907
        case 0:
908
            /* rotate */
909
            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
910
            val = ((val >> b) | (val << (8 - b))) & 0xff;
911
            val |= val << 8;
912
            val |= val << 16;
913

    
914
            /* apply set/reset mask */
915
            set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
916
            val = (val & ~set_mask) |
917
                (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
918
            bit_mask = s->gr[VGA_GFX_BIT_MASK];
919
            break;
920
        case 1:
921
            val = s->latch;
922
            goto do_write;
923
        case 2:
924
            val = mask16[val & 0x0f];
925
            bit_mask = s->gr[VGA_GFX_BIT_MASK];
926
            break;
927
        case 3:
928
            /* rotate */
929
            b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
930
            val = (val >> b) | (val << (8 - b));
931

    
932
            bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
933
            val = mask16[s->gr[VGA_GFX_SR_VALUE]];
934
            break;
935
        }
936

    
937
        /* apply logical operation */
938
        func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
939
        switch(func_select) {
940
        case 0:
941
        default:
942
            /* nothing to do */
943
            break;
944
        case 1:
945
            /* and */
946
            val &= s->latch;
947
            break;
948
        case 2:
949
            /* or */
950
            val |= s->latch;
951
            break;
952
        case 3:
953
            /* xor */
954
            val ^= s->latch;
955
            break;
956
        }
957

    
958
        /* apply bit mask */
959
        bit_mask |= bit_mask << 8;
960
        bit_mask |= bit_mask << 16;
961
        val = (val & bit_mask) | (s->latch & ~bit_mask);
962

    
963
    do_write:
964
        /* mask data according to sr[2] */
965
        mask = s->sr[VGA_SEQ_PLANE_WRITE];
966
        s->plane_updated |= mask; /* only used to detect font change */
967
        write_mask = mask16[mask];
968
        ((uint32_t *)s->vram_ptr)[addr] =
969
            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
970
            (val & write_mask);
971
#ifdef DEBUG_VGA_MEM
972
        printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
973
               addr * 4, write_mask, val);
974
#endif
975
        memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
976
    }
977
}
978

    
979
typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
980
                             const uint8_t *font_ptr, int h,
981
                             uint32_t fgcol, uint32_t bgcol);
982
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
983
                                  const uint8_t *font_ptr, int h,
984
                                  uint32_t fgcol, uint32_t bgcol, int dup9);
985
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
986
                                const uint8_t *s, int width);
987

    
988
#define DEPTH 8
989
#include "vga_template.h"
990

    
991
#define DEPTH 15
992
#include "vga_template.h"
993

    
994
#define BGR_FORMAT
995
#define DEPTH 15
996
#include "vga_template.h"
997

    
998
#define DEPTH 16
999
#include "vga_template.h"
1000

    
1001
#define BGR_FORMAT
1002
#define DEPTH 16
1003
#include "vga_template.h"
1004

    
1005
#define DEPTH 32
1006
#include "vga_template.h"
1007

    
1008
#define BGR_FORMAT
1009
#define DEPTH 32
1010
#include "vga_template.h"
1011

    
1012
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
1013
{
1014
    unsigned int col;
1015
    col = rgb_to_pixel8(r, g, b);
1016
    col |= col << 8;
1017
    col |= col << 16;
1018
    return col;
1019
}
1020

    
1021
static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
1022
{
1023
    unsigned int col;
1024
    col = rgb_to_pixel15(r, g, b);
1025
    col |= col << 16;
1026
    return col;
1027
}
1028

    
1029
static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
1030
                                          unsigned int b)
1031
{
1032
    unsigned int col;
1033
    col = rgb_to_pixel15bgr(r, g, b);
1034
    col |= col << 16;
1035
    return col;
1036
}
1037

    
1038
static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
1039
{
1040
    unsigned int col;
1041
    col = rgb_to_pixel16(r, g, b);
1042
    col |= col << 16;
1043
    return col;
1044
}
1045

    
1046
static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
1047
                                          unsigned int b)
1048
{
1049
    unsigned int col;
1050
    col = rgb_to_pixel16bgr(r, g, b);
1051
    col |= col << 16;
1052
    return col;
1053
}
1054

    
1055
static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
1056
{
1057
    unsigned int col;
1058
    col = rgb_to_pixel32(r, g, b);
1059
    return col;
1060
}
1061

    
1062
static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
1063
{
1064
    unsigned int col;
1065
    col = rgb_to_pixel32bgr(r, g, b);
1066
    return col;
1067
}
1068

    
1069
/* return true if the palette was modified */
1070
static int update_palette16(VGACommonState *s)
1071
{
1072
    int full_update, i;
1073
    uint32_t v, col, *palette;
1074

    
1075
    full_update = 0;
1076
    palette = s->last_palette;
1077
    for(i = 0; i < 16; i++) {
1078
        v = s->ar[i];
1079
        if (s->ar[VGA_ATC_MODE] & 0x80) {
1080
            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1081
        } else {
1082
            v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1083
        }
1084
        v = v * 3;
1085
        col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1086
                              c6_to_8(s->palette[v + 1]),
1087
                              c6_to_8(s->palette[v + 2]));
1088
        if (col != palette[i]) {
1089
            full_update = 1;
1090
            palette[i] = col;
1091
        }
1092
    }
1093
    return full_update;
1094
}
1095

    
1096
/* return true if the palette was modified */
1097
static int update_palette256(VGACommonState *s)
1098
{
1099
    int full_update, i;
1100
    uint32_t v, col, *palette;
1101

    
1102
    full_update = 0;
1103
    palette = s->last_palette;
1104
    v = 0;
1105
    for(i = 0; i < 256; i++) {
1106
        if (s->dac_8bit) {
1107
          col = s->rgb_to_pixel(s->palette[v],
1108
                                s->palette[v + 1],
1109
                                s->palette[v + 2]);
1110
        } else {
1111
          col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1112
                                c6_to_8(s->palette[v + 1]),
1113
                                c6_to_8(s->palette[v + 2]));
1114
        }
1115
        if (col != palette[i]) {
1116
            full_update = 1;
1117
            palette[i] = col;
1118
        }
1119
        v += 3;
1120
    }
1121
    return full_update;
1122
}
1123

    
1124
static void vga_get_offsets(VGACommonState *s,
1125
                            uint32_t *pline_offset,
1126
                            uint32_t *pstart_addr,
1127
                            uint32_t *pline_compare)
1128
{
1129
    uint32_t start_addr, line_offset, line_compare;
1130

    
1131
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1132
        line_offset = s->vbe_line_offset;
1133
        start_addr = s->vbe_start_addr;
1134
        line_compare = 65535;
1135
    } else {
1136
        /* compute line_offset in bytes */
1137
        line_offset = s->cr[VGA_CRTC_OFFSET];
1138
        line_offset <<= 3;
1139

    
1140
        /* starting address */
1141
        start_addr = s->cr[VGA_CRTC_START_LO] |
1142
            (s->cr[VGA_CRTC_START_HI] << 8);
1143

    
1144
        /* line compare */
1145
        line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1146
            ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1147
            ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1148
    }
1149
    *pline_offset = line_offset;
1150
    *pstart_addr = start_addr;
1151
    *pline_compare = line_compare;
1152
}
1153

    
1154
/* update start_addr and line_offset. Return TRUE if modified */
1155
static int update_basic_params(VGACommonState *s)
1156
{
1157
    int full_update;
1158
    uint32_t start_addr, line_offset, line_compare;
1159

    
1160
    full_update = 0;
1161

    
1162
    s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1163

    
1164
    if (line_offset != s->line_offset ||
1165
        start_addr != s->start_addr ||
1166
        line_compare != s->line_compare) {
1167
        s->line_offset = line_offset;
1168
        s->start_addr = start_addr;
1169
        s->line_compare = line_compare;
1170
        full_update = 1;
1171
    }
1172
    return full_update;
1173
}
1174

    
1175
#define NB_DEPTHS 7
1176

    
1177
static inline int get_depth_index(DisplayState *s)
1178
{
1179
    switch(ds_get_bits_per_pixel(s)) {
1180
    default:
1181
    case 8:
1182
        return 0;
1183
    case 15:
1184
        return 1;
1185
    case 16:
1186
        return 2;
1187
    case 32:
1188
        if (is_surface_bgr(s->surface))
1189
            return 4;
1190
        else
1191
            return 3;
1192
    }
1193
}
1194

    
1195
static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
1196
    vga_draw_glyph8_8,
1197
    vga_draw_glyph8_16,
1198
    vga_draw_glyph8_16,
1199
    vga_draw_glyph8_32,
1200
    vga_draw_glyph8_32,
1201
    vga_draw_glyph8_16,
1202
    vga_draw_glyph8_16,
1203
};
1204

    
1205
static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
1206
    vga_draw_glyph16_8,
1207
    vga_draw_glyph16_16,
1208
    vga_draw_glyph16_16,
1209
    vga_draw_glyph16_32,
1210
    vga_draw_glyph16_32,
1211
    vga_draw_glyph16_16,
1212
    vga_draw_glyph16_16,
1213
};
1214

    
1215
static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
1216
    vga_draw_glyph9_8,
1217
    vga_draw_glyph9_16,
1218
    vga_draw_glyph9_16,
1219
    vga_draw_glyph9_32,
1220
    vga_draw_glyph9_32,
1221
    vga_draw_glyph9_16,
1222
    vga_draw_glyph9_16,
1223
};
1224

    
1225
static const uint8_t cursor_glyph[32 * 4] = {
1226
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1227
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1228
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1229
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1231
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1232
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1233
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1234
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1235
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1236
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1237
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1238
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1239
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1240
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1241
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1242
};
1243

    
1244
static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1245
                                    int *pcwidth, int *pcheight)
1246
{
1247
    int width, cwidth, height, cheight;
1248

    
1249
    /* total width & height */
1250
    cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1251
    cwidth = 8;
1252
    if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
1253
        cwidth = 9;
1254
    }
1255
    if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
1256
        cwidth = 16; /* NOTE: no 18 pixel wide */
1257
    }
1258
    width = (s->cr[VGA_CRTC_H_DISP] + 1);
1259
    if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1260
        /* ugly hack for CGA 160x100x16 - explain me the logic */
1261
        height = 100;
1262
    } else {
1263
        height = s->cr[VGA_CRTC_V_DISP_END] |
1264
            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1265
            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1266
        height = (height + 1) / cheight;
1267
    }
1268

    
1269
    *pwidth = width;
1270
    *pheight = height;
1271
    *pcwidth = cwidth;
1272
    *pcheight = cheight;
1273
}
1274

    
1275
typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
1276

    
1277
static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
1278
    rgb_to_pixel8_dup,
1279
    rgb_to_pixel15_dup,
1280
    rgb_to_pixel16_dup,
1281
    rgb_to_pixel32_dup,
1282
    rgb_to_pixel32bgr_dup,
1283
    rgb_to_pixel15bgr_dup,
1284
    rgb_to_pixel16bgr_dup,
1285
};
1286

    
1287
/*
1288
 * Text mode update
1289
 * Missing:
1290
 * - double scan
1291
 * - double width
1292
 * - underline
1293
 * - flashing
1294
 */
1295
static void vga_draw_text(VGACommonState *s, int full_update)
1296
{
1297
    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1298
    int cx_min, cx_max, linesize, x_incr, line, line1;
1299
    uint32_t offset, fgcol, bgcol, v, cursor_offset;
1300
    uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1301
    const uint8_t *font_ptr, *font_base[2];
1302
    int dup9, line_offset, depth_index;
1303
    uint32_t *palette;
1304
    uint32_t *ch_attr_ptr;
1305
    vga_draw_glyph8_func *vga_draw_glyph8;
1306
    vga_draw_glyph9_func *vga_draw_glyph9;
1307
    int64_t now = qemu_get_clock_ms(vm_clock);
1308

    
1309
    /* compute font data address (in plane 2) */
1310
    v = s->sr[VGA_SEQ_CHARACTER_MAP];
1311
    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1312
    if (offset != s->font_offsets[0]) {
1313
        s->font_offsets[0] = offset;
1314
        full_update = 1;
1315
    }
1316
    font_base[0] = s->vram_ptr + offset;
1317

    
1318
    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1319
    font_base[1] = s->vram_ptr + offset;
1320
    if (offset != s->font_offsets[1]) {
1321
        s->font_offsets[1] = offset;
1322
        full_update = 1;
1323
    }
1324
    if (s->plane_updated & (1 << 2) || s->chain4_alias) {
1325
        /* if the plane 2 was modified since the last display, it
1326
           indicates the font may have been modified */
1327
        s->plane_updated = 0;
1328
        full_update = 1;
1329
    }
1330
    full_update |= update_basic_params(s);
1331

    
1332
    line_offset = s->line_offset;
1333

    
1334
    vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1335
    if ((height * width) <= 1) {
1336
        /* better than nothing: exit if transient size is too small */
1337
        return;
1338
    }
1339
    if ((height * width) > CH_ATTR_SIZE) {
1340
        /* better than nothing: exit if transient size is too big */
1341
        return;
1342
    }
1343

    
1344
    if (width != s->last_width || height != s->last_height ||
1345
        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1346
        s->last_scr_width = width * cw;
1347
        s->last_scr_height = height * cheight;
1348
        qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
1349
        dpy_text_resize(s->ds, width, height);
1350
        s->last_depth = 0;
1351
        s->last_width = width;
1352
        s->last_height = height;
1353
        s->last_ch = cheight;
1354
        s->last_cw = cw;
1355
        full_update = 1;
1356
    }
1357
    s->rgb_to_pixel =
1358
        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1359
    full_update |= update_palette16(s);
1360
    palette = s->last_palette;
1361
    x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
1362

    
1363
    if (full_update) {
1364
        s->full_update_text = 1;
1365
    }
1366
    if (s->full_update_gfx) {
1367
        s->full_update_gfx = 0;
1368
        full_update |= 1;
1369
    }
1370

    
1371
    cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1372
                     s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1373
    if (cursor_offset != s->cursor_offset ||
1374
        s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1375
        s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1376
      /* if the cursor position changed, we update the old and new
1377
         chars */
1378
        if (s->cursor_offset < CH_ATTR_SIZE)
1379
            s->last_ch_attr[s->cursor_offset] = -1;
1380
        if (cursor_offset < CH_ATTR_SIZE)
1381
            s->last_ch_attr[cursor_offset] = -1;
1382
        s->cursor_offset = cursor_offset;
1383
        s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1384
        s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1385
    }
1386
    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1387
    if (now >= s->cursor_blink_time) {
1388
        s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1389
        s->cursor_visible_phase = !s->cursor_visible_phase;
1390
    }
1391

    
1392
    depth_index = get_depth_index(s->ds);
1393
    if (cw == 16)
1394
        vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
1395
    else
1396
        vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
1397
    vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
1398

    
1399
    dest = ds_get_data(s->ds);
1400
    linesize = ds_get_linesize(s->ds);
1401
    ch_attr_ptr = s->last_ch_attr;
1402
    line = 0;
1403
    offset = s->start_addr * 4;
1404
    for(cy = 0; cy < height; cy++) {
1405
        d1 = dest;
1406
        src = s->vram_ptr + offset;
1407
        cx_min = width;
1408
        cx_max = -1;
1409
        for(cx = 0; cx < width; cx++) {
1410
            ch_attr = *(uint16_t *)src;
1411
            if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1412
                if (cx < cx_min)
1413
                    cx_min = cx;
1414
                if (cx > cx_max)
1415
                    cx_max = cx;
1416
                *ch_attr_ptr = ch_attr;
1417
#ifdef HOST_WORDS_BIGENDIAN
1418
                ch = ch_attr >> 8;
1419
                cattr = ch_attr & 0xff;
1420
#else
1421
                ch = ch_attr & 0xff;
1422
                cattr = ch_attr >> 8;
1423
#endif
1424
                font_ptr = font_base[(cattr >> 3) & 1];
1425
                font_ptr += 32 * 4 * ch;
1426
                bgcol = palette[cattr >> 4];
1427
                fgcol = palette[cattr & 0x0f];
1428
                if (cw != 9) {
1429
                    vga_draw_glyph8(d1, linesize,
1430
                                    font_ptr, cheight, fgcol, bgcol);
1431
                } else {
1432
                    dup9 = 0;
1433
                    if (ch >= 0xb0 && ch <= 0xdf &&
1434
                        (s->ar[VGA_ATC_MODE] & 0x04)) {
1435
                        dup9 = 1;
1436
                    }
1437
                    vga_draw_glyph9(d1, linesize,
1438
                                    font_ptr, cheight, fgcol, bgcol, dup9);
1439
                }
1440
                if (src == cursor_ptr &&
1441
                    !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1442
                    s->cursor_visible_phase) {
1443
                    int line_start, line_last, h;
1444
                    /* draw the cursor */
1445
                    line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1446
                    line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1447
                    /* XXX: check that */
1448
                    if (line_last > cheight - 1)
1449
                        line_last = cheight - 1;
1450
                    if (line_last >= line_start && line_start < cheight) {
1451
                        h = line_last - line_start + 1;
1452
                        d = d1 + linesize * line_start;
1453
                        if (cw != 9) {
1454
                            vga_draw_glyph8(d, linesize,
1455
                                            cursor_glyph, h, fgcol, bgcol);
1456
                        } else {
1457
                            vga_draw_glyph9(d, linesize,
1458
                                            cursor_glyph, h, fgcol, bgcol, 1);
1459
                        }
1460
                    }
1461
                }
1462
            }
1463
            d1 += x_incr;
1464
            src += 4;
1465
            ch_attr_ptr++;
1466
        }
1467
        if (cx_max != -1) {
1468
            dpy_gfx_update(s->ds, cx_min * cw, cy * cheight,
1469
                           (cx_max - cx_min + 1) * cw, cheight);
1470
        }
1471
        dest += linesize * cheight;
1472
        line1 = line + cheight;
1473
        offset += line_offset;
1474
        if (line < s->line_compare && line1 >= s->line_compare) {
1475
            offset = 0;
1476
        }
1477
        line = line1;
1478
    }
1479
}
1480

    
1481
enum {
1482
    VGA_DRAW_LINE2,
1483
    VGA_DRAW_LINE2D2,
1484
    VGA_DRAW_LINE4,
1485
    VGA_DRAW_LINE4D2,
1486
    VGA_DRAW_LINE8D2,
1487
    VGA_DRAW_LINE8,
1488
    VGA_DRAW_LINE15,
1489
    VGA_DRAW_LINE16,
1490
    VGA_DRAW_LINE24,
1491
    VGA_DRAW_LINE32,
1492
    VGA_DRAW_LINE_NB,
1493
};
1494

    
1495
static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
1496
    vga_draw_line2_8,
1497
    vga_draw_line2_16,
1498
    vga_draw_line2_16,
1499
    vga_draw_line2_32,
1500
    vga_draw_line2_32,
1501
    vga_draw_line2_16,
1502
    vga_draw_line2_16,
1503

    
1504
    vga_draw_line2d2_8,
1505
    vga_draw_line2d2_16,
1506
    vga_draw_line2d2_16,
1507
    vga_draw_line2d2_32,
1508
    vga_draw_line2d2_32,
1509
    vga_draw_line2d2_16,
1510
    vga_draw_line2d2_16,
1511

    
1512
    vga_draw_line4_8,
1513
    vga_draw_line4_16,
1514
    vga_draw_line4_16,
1515
    vga_draw_line4_32,
1516
    vga_draw_line4_32,
1517
    vga_draw_line4_16,
1518
    vga_draw_line4_16,
1519

    
1520
    vga_draw_line4d2_8,
1521
    vga_draw_line4d2_16,
1522
    vga_draw_line4d2_16,
1523
    vga_draw_line4d2_32,
1524
    vga_draw_line4d2_32,
1525
    vga_draw_line4d2_16,
1526
    vga_draw_line4d2_16,
1527

    
1528
    vga_draw_line8d2_8,
1529
    vga_draw_line8d2_16,
1530
    vga_draw_line8d2_16,
1531
    vga_draw_line8d2_32,
1532
    vga_draw_line8d2_32,
1533
    vga_draw_line8d2_16,
1534
    vga_draw_line8d2_16,
1535

    
1536
    vga_draw_line8_8,
1537
    vga_draw_line8_16,
1538
    vga_draw_line8_16,
1539
    vga_draw_line8_32,
1540
    vga_draw_line8_32,
1541
    vga_draw_line8_16,
1542
    vga_draw_line8_16,
1543

    
1544
    vga_draw_line15_8,
1545
    vga_draw_line15_15,
1546
    vga_draw_line15_16,
1547
    vga_draw_line15_32,
1548
    vga_draw_line15_32bgr,
1549
    vga_draw_line15_15bgr,
1550
    vga_draw_line15_16bgr,
1551

    
1552
    vga_draw_line16_8,
1553
    vga_draw_line16_15,
1554
    vga_draw_line16_16,
1555
    vga_draw_line16_32,
1556
    vga_draw_line16_32bgr,
1557
    vga_draw_line16_15bgr,
1558
    vga_draw_line16_16bgr,
1559

    
1560
    vga_draw_line24_8,
1561
    vga_draw_line24_15,
1562
    vga_draw_line24_16,
1563
    vga_draw_line24_32,
1564
    vga_draw_line24_32bgr,
1565
    vga_draw_line24_15bgr,
1566
    vga_draw_line24_16bgr,
1567

    
1568
    vga_draw_line32_8,
1569
    vga_draw_line32_15,
1570
    vga_draw_line32_16,
1571
    vga_draw_line32_32,
1572
    vga_draw_line32_32bgr,
1573
    vga_draw_line32_15bgr,
1574
    vga_draw_line32_16bgr,
1575
};
1576

    
1577
static int vga_get_bpp(VGACommonState *s)
1578
{
1579
    int ret;
1580

    
1581
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1582
        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1583
    } else {
1584
        ret = 0;
1585
    }
1586
    return ret;
1587
}
1588

    
1589
static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1590
{
1591
    int width, height;
1592

    
1593
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1594
        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1595
        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1596
    } else {
1597
        width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1598
        height = s->cr[VGA_CRTC_V_DISP_END] |
1599
            ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1600
            ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1601
        height = (height + 1);
1602
    }
1603
    *pwidth = width;
1604
    *pheight = height;
1605
}
1606

    
1607
void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1608
{
1609
    int y;
1610
    if (y1 >= VGA_MAX_HEIGHT)
1611
        return;
1612
    if (y2 >= VGA_MAX_HEIGHT)
1613
        y2 = VGA_MAX_HEIGHT;
1614
    for(y = y1; y < y2; y++) {
1615
        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1616
    }
1617
}
1618

    
1619
void vga_sync_dirty_bitmap(VGACommonState *s)
1620
{
1621
    memory_region_sync_dirty_bitmap(&s->vram);
1622
}
1623

    
1624
void vga_dirty_log_start(VGACommonState *s)
1625
{
1626
    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1627
}
1628

    
1629
void vga_dirty_log_stop(VGACommonState *s)
1630
{
1631
    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1632
}
1633

    
1634
/*
1635
 * graphic modes
1636
 */
1637
static void vga_draw_graphic(VGACommonState *s, int full_update)
1638
{
1639
    int y1, y, update, linesize, y_start, double_scan, mask, depth;
1640
    int width, height, shift_control, line_offset, bwidth, bits;
1641
    ram_addr_t page0, page1, page_min, page_max;
1642
    int disp_width, multi_scan, multi_run;
1643
    uint8_t *d;
1644
    uint32_t v, addr1, addr;
1645
    vga_draw_line_func *vga_draw_line;
1646

    
1647
    full_update |= update_basic_params(s);
1648

    
1649
    if (!full_update)
1650
        vga_sync_dirty_bitmap(s);
1651

    
1652
    s->get_resolution(s, &width, &height);
1653
    disp_width = width;
1654

    
1655
    shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1656
    double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1657
    if (shift_control != 1) {
1658
        multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1659
            - 1;
1660
    } else {
1661
        /* in CGA modes, multi_scan is ignored */
1662
        /* XXX: is it correct ? */
1663
        multi_scan = double_scan;
1664
    }
1665
    multi_run = multi_scan;
1666
    if (shift_control != s->shift_control ||
1667
        double_scan != s->double_scan) {
1668
        full_update = 1;
1669
        s->shift_control = shift_control;
1670
        s->double_scan = double_scan;
1671
    }
1672

    
1673
    if (shift_control == 0) {
1674
        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1675
            disp_width <<= 1;
1676
        }
1677
    } else if (shift_control == 1) {
1678
        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1679
            disp_width <<= 1;
1680
        }
1681
    }
1682

    
1683
    depth = s->get_bpp(s);
1684
    if (s->line_offset != s->last_line_offset ||
1685
        disp_width != s->last_width ||
1686
        height != s->last_height ||
1687
        s->last_depth != depth) {
1688
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1689
        if (depth == 16 || depth == 32) {
1690
#else
1691
        if (depth == 32) {
1692
#endif
1693
            qemu_free_displaysurface(s->ds);
1694
            s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
1695
                    s->line_offset,
1696
                    s->vram_ptr + (s->start_addr * 4));
1697
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
1698
            s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
1699
#endif
1700
            dpy_gfx_resize(s->ds);
1701
        } else {
1702
            qemu_console_resize(s->ds, disp_width, height);
1703
        }
1704
        s->last_scr_width = disp_width;
1705
        s->last_scr_height = height;
1706
        s->last_width = disp_width;
1707
        s->last_height = height;
1708
        s->last_line_offset = s->line_offset;
1709
        s->last_depth = depth;
1710
        full_update = 1;
1711
    } else if (is_buffer_shared(s->ds->surface) &&
1712
               (full_update || ds_get_data(s->ds) != s->vram_ptr
1713
                + (s->start_addr * 4))) {
1714
        qemu_free_displaysurface(s->ds);
1715
        s->ds->surface = qemu_create_displaysurface_from(disp_width,
1716
                height, depth,
1717
                s->line_offset,
1718
                s->vram_ptr + (s->start_addr * 4));
1719
        dpy_gfx_setdata(s->ds);
1720
    }
1721

    
1722
    s->rgb_to_pixel =
1723
        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1724

    
1725
    if (shift_control == 0) {
1726
        full_update |= update_palette16(s);
1727
        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1728
            v = VGA_DRAW_LINE4D2;
1729
        } else {
1730
            v = VGA_DRAW_LINE4;
1731
        }
1732
        bits = 4;
1733
    } else if (shift_control == 1) {
1734
        full_update |= update_palette16(s);
1735
        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1736
            v = VGA_DRAW_LINE2D2;
1737
        } else {
1738
            v = VGA_DRAW_LINE2;
1739
        }
1740
        bits = 4;
1741
    } else {
1742
        switch(s->get_bpp(s)) {
1743
        default:
1744
        case 0:
1745
            full_update |= update_palette256(s);
1746
            v = VGA_DRAW_LINE8D2;
1747
            bits = 4;
1748
            break;
1749
        case 8:
1750
            full_update |= update_palette256(s);
1751
            v = VGA_DRAW_LINE8;
1752
            bits = 8;
1753
            break;
1754
        case 15:
1755
            v = VGA_DRAW_LINE15;
1756
            bits = 16;
1757
            break;
1758
        case 16:
1759
            v = VGA_DRAW_LINE16;
1760
            bits = 16;
1761
            break;
1762
        case 24:
1763
            v = VGA_DRAW_LINE24;
1764
            bits = 24;
1765
            break;
1766
        case 32:
1767
            v = VGA_DRAW_LINE32;
1768
            bits = 32;
1769
            break;
1770
        }
1771
    }
1772
    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
1773

    
1774
    if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
1775
        s->cursor_invalidate(s);
1776

    
1777
    line_offset = s->line_offset;
1778
#if 0
1779
    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",
1780
           width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1781
           s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1782
#endif
1783
    addr1 = (s->start_addr * 4);
1784
    bwidth = (width * bits + 7) / 8;
1785
    y_start = -1;
1786
    page_min = -1;
1787
    page_max = 0;
1788
    d = ds_get_data(s->ds);
1789
    linesize = ds_get_linesize(s->ds);
1790
    y1 = 0;
1791
    for(y = 0; y < height; y++) {
1792
        addr = addr1;
1793
        if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1794
            int shift;
1795
            /* CGA compatibility handling */
1796
            shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1797
            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1798
        }
1799
        if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1800
            addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1801
        }
1802
        update = full_update;
1803
        page0 = addr;
1804
        page1 = addr + bwidth - 1;
1805
        update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1806
                                          DIRTY_MEMORY_VGA);
1807
        /* explicit invalidation for the hardware cursor */
1808
        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1809
        if (update) {
1810
            if (y_start < 0)
1811
                y_start = y;
1812
            if (page0 < page_min)
1813
                page_min = page0;
1814
            if (page1 > page_max)
1815
                page_max = page1;
1816
            if (!(is_buffer_shared(s->ds->surface))) {
1817
                vga_draw_line(s, d, s->vram_ptr + addr, width);
1818
                if (s->cursor_draw_line)
1819
                    s->cursor_draw_line(s, d, y);
1820
            }
1821
        } else {
1822
            if (y_start >= 0) {
1823
                /* flush to display */
1824
                dpy_gfx_update(s->ds, 0, y_start,
1825
                               disp_width, y - y_start);
1826
                y_start = -1;
1827
            }
1828
        }
1829
        if (!multi_run) {
1830
            mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1831
            if ((y1 & mask) == mask)
1832
                addr1 += line_offset;
1833
            y1++;
1834
            multi_run = multi_scan;
1835
        } else {
1836
            multi_run--;
1837
        }
1838
        /* line compare acts on the displayed lines */
1839
        if (y == s->line_compare)
1840
            addr1 = 0;
1841
        d += linesize;
1842
    }
1843
    if (y_start >= 0) {
1844
        /* flush to display */
1845
        dpy_gfx_update(s->ds, 0, y_start,
1846
                       disp_width, y - y_start);
1847
    }
1848
    /* reset modified pages */
1849
    if (page_max >= page_min) {
1850
        memory_region_reset_dirty(&s->vram,
1851
                                  page_min,
1852
                                  page_max - page_min,
1853
                                  DIRTY_MEMORY_VGA);
1854
    }
1855
    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1856
}
1857

    
1858
static void vga_draw_blank(VGACommonState *s, int full_update)
1859
{
1860
    int i, w, val;
1861
    uint8_t *d;
1862

    
1863
    if (!full_update)
1864
        return;
1865
    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1866
        return;
1867

    
1868
    s->rgb_to_pixel =
1869
        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1870
    if (ds_get_bits_per_pixel(s->ds) == 8)
1871
        val = s->rgb_to_pixel(0, 0, 0);
1872
    else
1873
        val = 0;
1874
    w = s->last_scr_width * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
1875
    d = ds_get_data(s->ds);
1876
    for(i = 0; i < s->last_scr_height; i++) {
1877
        memset(d, val, w);
1878
        d += ds_get_linesize(s->ds);
1879
    }
1880
    dpy_gfx_update(s->ds, 0, 0,
1881
                   s->last_scr_width, s->last_scr_height);
1882
}
1883

    
1884
#define GMODE_TEXT     0
1885
#define GMODE_GRAPH    1
1886
#define GMODE_BLANK 2
1887

    
1888
static void vga_update_display(void *opaque)
1889
{
1890
    VGACommonState *s = opaque;
1891
    int full_update, graphic_mode;
1892

    
1893
    qemu_flush_coalesced_mmio_buffer();
1894

    
1895
    if (ds_get_bits_per_pixel(s->ds) == 0) {
1896
        /* nothing to do */
1897
    } else {
1898
        full_update = 0;
1899
        if (!(s->ar_index & 0x20)) {
1900
            graphic_mode = GMODE_BLANK;
1901
        } else {
1902
            graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1903
        }
1904
        if (graphic_mode != s->graphic_mode) {
1905
            s->graphic_mode = graphic_mode;
1906
            s->cursor_blink_time = qemu_get_clock_ms(vm_clock);
1907
            full_update = 1;
1908
        }
1909
        switch(graphic_mode) {
1910
        case GMODE_TEXT:
1911
            vga_draw_text(s, full_update);
1912
            break;
1913
        case GMODE_GRAPH:
1914
            vga_draw_graphic(s, full_update);
1915
            break;
1916
        case GMODE_BLANK:
1917
        default:
1918
            vga_draw_blank(s, full_update);
1919
            break;
1920
        }
1921
    }
1922
}
1923

    
1924
/* force a full display refresh */
1925
static void vga_invalidate_display(void *opaque)
1926
{
1927
    VGACommonState *s = opaque;
1928

    
1929
    s->last_width = -1;
1930
    s->last_height = -1;
1931
}
1932

    
1933
void vga_common_reset(VGACommonState *s)
1934
{
1935
    s->sr_index = 0;
1936
    memset(s->sr, '\0', sizeof(s->sr));
1937
    s->gr_index = 0;
1938
    memset(s->gr, '\0', sizeof(s->gr));
1939
    s->ar_index = 0;
1940
    memset(s->ar, '\0', sizeof(s->ar));
1941
    s->ar_flip_flop = 0;
1942
    s->cr_index = 0;
1943
    memset(s->cr, '\0', sizeof(s->cr));
1944
    s->msr = 0;
1945
    s->fcr = 0;
1946
    s->st00 = 0;
1947
    s->st01 = 0;
1948
    s->dac_state = 0;
1949
    s->dac_sub_index = 0;
1950
    s->dac_read_index = 0;
1951
    s->dac_write_index = 0;
1952
    memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1953
    s->dac_8bit = 0;
1954
    memset(s->palette, '\0', sizeof(s->palette));
1955
    s->bank_offset = 0;
1956
    s->vbe_index = 0;
1957
    memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1958
    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1959
    s->vbe_start_addr = 0;
1960
    s->vbe_line_offset = 0;
1961
    s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1962
    memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1963
    s->graphic_mode = -1; /* force full update */
1964
    s->shift_control = 0;
1965
    s->double_scan = 0;
1966
    s->line_offset = 0;
1967
    s->line_compare = 0;
1968
    s->start_addr = 0;
1969
    s->plane_updated = 0;
1970
    s->last_cw = 0;
1971
    s->last_ch = 0;
1972
    s->last_width = 0;
1973
    s->last_height = 0;
1974
    s->last_scr_width = 0;
1975
    s->last_scr_height = 0;
1976
    s->cursor_start = 0;
1977
    s->cursor_end = 0;
1978
    s->cursor_offset = 0;
1979
    memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1980
    memset(s->last_palette, '\0', sizeof(s->last_palette));
1981
    memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1982
    switch (vga_retrace_method) {
1983
    case VGA_RETRACE_DUMB:
1984
        break;
1985
    case VGA_RETRACE_PRECISE:
1986
        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1987
        break;
1988
    }
1989
    vga_update_memory_access(s);
1990
}
1991

    
1992
static void vga_reset(void *opaque)
1993
{
1994
    VGACommonState *s =  opaque;
1995
    vga_common_reset(s);
1996
}
1997

    
1998
#define TEXTMODE_X(x)        ((x) % width)
1999
#define TEXTMODE_Y(x)        ((x) / width)
2000
#define VMEM2CHTYPE(v)        ((v & 0xff0007ff) | \
2001
        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
2002
/* relay text rendering to the display driver
2003
 * instead of doing a full vga_update_display() */
2004
static void vga_update_text(void *opaque, console_ch_t *chardata)
2005
{
2006
    VGACommonState *s =  opaque;
2007
    int graphic_mode, i, cursor_offset, cursor_visible;
2008
    int cw, cheight, width, height, size, c_min, c_max;
2009
    uint32_t *src;
2010
    console_ch_t *dst, val;
2011
    char msg_buffer[80];
2012
    int full_update = 0;
2013

    
2014
    qemu_flush_coalesced_mmio_buffer();
2015

    
2016
    if (!(s->ar_index & 0x20)) {
2017
        graphic_mode = GMODE_BLANK;
2018
    } else {
2019
        graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
2020
    }
2021
    if (graphic_mode != s->graphic_mode) {
2022
        s->graphic_mode = graphic_mode;
2023
        full_update = 1;
2024
    }
2025
    if (s->last_width == -1) {
2026
        s->last_width = 0;
2027
        full_update = 1;
2028
    }
2029

    
2030
    switch (graphic_mode) {
2031
    case GMODE_TEXT:
2032
        /* TODO: update palette */
2033
        full_update |= update_basic_params(s);
2034

    
2035
        /* total width & height */
2036
        cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
2037
        cw = 8;
2038
        if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
2039
            cw = 9;
2040
        }
2041
        if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
2042
            cw = 16; /* NOTE: no 18 pixel wide */
2043
        }
2044
        width = (s->cr[VGA_CRTC_H_DISP] + 1);
2045
        if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
2046
            /* ugly hack for CGA 160x100x16 - explain me the logic */
2047
            height = 100;
2048
        } else {
2049
            height = s->cr[VGA_CRTC_V_DISP_END] |
2050
                ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
2051
                ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
2052
            height = (height + 1) / cheight;
2053
        }
2054

    
2055
        size = (height * width);
2056
        if (size > CH_ATTR_SIZE) {
2057
            if (!full_update)
2058
                return;
2059

    
2060
            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
2061
                     width, height);
2062
            break;
2063
        }
2064

    
2065
        if (width != s->last_width || height != s->last_height ||
2066
            cw != s->last_cw || cheight != s->last_ch) {
2067
            s->last_scr_width = width * cw;
2068
            s->last_scr_height = height * cheight;
2069
            qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
2070
            dpy_text_resize(s->ds, width, height);
2071
            s->last_depth = 0;
2072
            s->last_width = width;
2073
            s->last_height = height;
2074
            s->last_ch = cheight;
2075
            s->last_cw = cw;
2076
            full_update = 1;
2077
        }
2078

    
2079
        if (full_update) {
2080
            s->full_update_gfx = 1;
2081
        }
2082
        if (s->full_update_text) {
2083
            s->full_update_text = 0;
2084
            full_update |= 1;
2085
        }
2086

    
2087
        /* Update "hardware" cursor */
2088
        cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
2089
                         s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
2090
        if (cursor_offset != s->cursor_offset ||
2091
            s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
2092
            s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
2093
            cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
2094
            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
2095
                dpy_text_cursor(s->ds,
2096
                                TEXTMODE_X(cursor_offset),
2097
                                TEXTMODE_Y(cursor_offset));
2098
            else
2099
                dpy_text_cursor(s->ds, -1, -1);
2100
            s->cursor_offset = cursor_offset;
2101
            s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2102
            s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2103
        }
2104

    
2105
        src = (uint32_t *) s->vram_ptr + s->start_addr;
2106
        dst = chardata;
2107

    
2108
        if (full_update) {
2109
            for (i = 0; i < size; src ++, dst ++, i ++)
2110
                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2111

    
2112
            dpy_text_update(s->ds, 0, 0, width, height);
2113
        } else {
2114
            c_max = 0;
2115

    
2116
            for (i = 0; i < size; src ++, dst ++, i ++) {
2117
                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2118
                if (*dst != val) {
2119
                    *dst = val;
2120
                    c_max = i;
2121
                    break;
2122
                }
2123
            }
2124
            c_min = i;
2125
            for (; i < size; src ++, dst ++, i ++) {
2126
                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2127
                if (*dst != val) {
2128
                    *dst = val;
2129
                    c_max = i;
2130
                }
2131
            }
2132

    
2133
            if (c_min <= c_max) {
2134
                i = TEXTMODE_Y(c_min);
2135
                dpy_text_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2136
            }
2137
        }
2138

    
2139
        return;
2140
    case GMODE_GRAPH:
2141
        if (!full_update)
2142
            return;
2143

    
2144
        s->get_resolution(s, &width, &height);
2145
        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2146
                 width, height);
2147
        break;
2148
    case GMODE_BLANK:
2149
    default:
2150
        if (!full_update)
2151
            return;
2152

    
2153
        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2154
        break;
2155
    }
2156

    
2157
    /* Display a message */
2158
    s->last_width = 60;
2159
    s->last_height = height = 3;
2160
    dpy_text_cursor(s->ds, -1, -1);
2161
    dpy_text_resize(s->ds, s->last_width, height);
2162

    
2163
    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2164
        console_write_ch(dst ++, ' ');
2165

    
2166
    size = strlen(msg_buffer);
2167
    width = (s->last_width - size) / 2;
2168
    dst = chardata + s->last_width + width;
2169
    for (i = 0; i < size; i ++)
2170
        console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
2171

    
2172
    dpy_text_update(s->ds, 0, 0, s->last_width, height);
2173
}
2174

    
2175
static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2176
                             unsigned size)
2177
{
2178
    VGACommonState *s = opaque;
2179

    
2180
    return vga_mem_readb(s, addr);
2181
}
2182

    
2183
static void vga_mem_write(void *opaque, hwaddr addr,
2184
                          uint64_t data, unsigned size)
2185
{
2186
    VGACommonState *s = opaque;
2187

    
2188
    return vga_mem_writeb(s, addr, data);
2189
}
2190

    
2191
const MemoryRegionOps vga_mem_ops = {
2192
    .read = vga_mem_read,
2193
    .write = vga_mem_write,
2194
    .endianness = DEVICE_LITTLE_ENDIAN,
2195
    .impl = {
2196
        .min_access_size = 1,
2197
        .max_access_size = 1,
2198
    },
2199
};
2200

    
2201
static int vga_common_post_load(void *opaque, int version_id)
2202
{
2203
    VGACommonState *s = opaque;
2204

    
2205
    /* force refresh */
2206
    s->graphic_mode = -1;
2207
    return 0;
2208
}
2209

    
2210
const VMStateDescription vmstate_vga_common = {
2211
    .name = "vga",
2212
    .version_id = 2,
2213
    .minimum_version_id = 2,
2214
    .minimum_version_id_old = 2,
2215
    .post_load = vga_common_post_load,
2216
    .fields      = (VMStateField []) {
2217
        VMSTATE_UINT32(latch, VGACommonState),
2218
        VMSTATE_UINT8(sr_index, VGACommonState),
2219
        VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2220
        VMSTATE_UINT8(gr_index, VGACommonState),
2221
        VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2222
        VMSTATE_UINT8(ar_index, VGACommonState),
2223
        VMSTATE_BUFFER(ar, VGACommonState),
2224
        VMSTATE_INT32(ar_flip_flop, VGACommonState),
2225
        VMSTATE_UINT8(cr_index, VGACommonState),
2226
        VMSTATE_BUFFER(cr, VGACommonState),
2227
        VMSTATE_UINT8(msr, VGACommonState),
2228
        VMSTATE_UINT8(fcr, VGACommonState),
2229
        VMSTATE_UINT8(st00, VGACommonState),
2230
        VMSTATE_UINT8(st01, VGACommonState),
2231

    
2232
        VMSTATE_UINT8(dac_state, VGACommonState),
2233
        VMSTATE_UINT8(dac_sub_index, VGACommonState),
2234
        VMSTATE_UINT8(dac_read_index, VGACommonState),
2235
        VMSTATE_UINT8(dac_write_index, VGACommonState),
2236
        VMSTATE_BUFFER(dac_cache, VGACommonState),
2237
        VMSTATE_BUFFER(palette, VGACommonState),
2238

    
2239
        VMSTATE_INT32(bank_offset, VGACommonState),
2240
        VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2241
        VMSTATE_UINT16(vbe_index, VGACommonState),
2242
        VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2243
        VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2244
        VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2245
        VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2246
        VMSTATE_END_OF_LIST()
2247
    }
2248
};
2249

    
2250
void vga_common_init(VGACommonState *s)
2251
{
2252
    int i, j, v, b;
2253

    
2254
    for(i = 0;i < 256; i++) {
2255
        v = 0;
2256
        for(j = 0; j < 8; j++) {
2257
            v |= ((i >> j) & 1) << (j * 4);
2258
        }
2259
        expand4[i] = v;
2260

    
2261
        v = 0;
2262
        for(j = 0; j < 4; j++) {
2263
            v |= ((i >> (2 * j)) & 3) << (j * 4);
2264
        }
2265
        expand2[i] = v;
2266
    }
2267
    for(i = 0; i < 16; i++) {
2268
        v = 0;
2269
        for(j = 0; j < 4; j++) {
2270
            b = ((i >> j) & 1);
2271
            v |= b << (2 * j);
2272
            v |= b << (2 * j + 1);
2273
        }
2274
        expand4to8[i] = v;
2275
    }
2276

    
2277
    /* valid range: 1 MB -> 256 MB */
2278
    s->vram_size = 1024 * 1024;
2279
    while (s->vram_size < (s->vram_size_mb << 20) &&
2280
           s->vram_size < (256 << 20)) {
2281
        s->vram_size <<= 1;
2282
    }
2283
    s->vram_size_mb = s->vram_size >> 20;
2284

    
2285
    s->is_vbe_vmstate = 1;
2286
    memory_region_init_ram(&s->vram, "vga.vram", s->vram_size);
2287
    vmstate_register_ram_global(&s->vram);
2288
    xen_register_framebuffer(&s->vram);
2289
    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2290
    s->get_bpp = vga_get_bpp;
2291
    s->get_offsets = vga_get_offsets;
2292
    s->get_resolution = vga_get_resolution;
2293
    s->update = vga_update_display;
2294
    s->invalidate = vga_invalidate_display;
2295
    s->screen_dump = vga_screen_dump;
2296
    s->text_update = vga_update_text;
2297
    switch (vga_retrace_method) {
2298
    case VGA_RETRACE_DUMB:
2299
        s->retrace = vga_dumb_retrace;
2300
        s->update_retrace_info = vga_dumb_update_retrace_info;
2301
        break;
2302

    
2303
    case VGA_RETRACE_PRECISE:
2304
        s->retrace = vga_precise_retrace;
2305
        s->update_retrace_info = vga_precise_update_retrace_info;
2306
        break;
2307
    }
2308
    vga_dirty_log_start(s);
2309
}
2310

    
2311
static const MemoryRegionPortio vga_portio_list[] = {
2312
    { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2313
    { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2314
    { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2315
    { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2316
    { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2317
    PORTIO_END_OF_LIST(),
2318
};
2319

    
2320
static const MemoryRegionPortio vbe_portio_list[] = {
2321
    { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2322
# ifdef TARGET_I386
2323
    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2324
# endif
2325
    { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2326
    PORTIO_END_OF_LIST(),
2327
};
2328

    
2329
/* Used by both ISA and PCI */
2330
MemoryRegion *vga_init_io(VGACommonState *s,
2331
                          const MemoryRegionPortio **vga_ports,
2332
                          const MemoryRegionPortio **vbe_ports)
2333
{
2334
    MemoryRegion *vga_mem;
2335

    
2336
    *vga_ports = vga_portio_list;
2337
    *vbe_ports = vbe_portio_list;
2338

    
2339
    vga_mem = g_malloc(sizeof(*vga_mem));
2340
    memory_region_init_io(vga_mem, &vga_mem_ops, s,
2341
                          "vga-lowmem", 0x20000);
2342
    memory_region_set_flush_coalesced(vga_mem);
2343

    
2344
    return vga_mem;
2345
}
2346

    
2347
void vga_init(VGACommonState *s, MemoryRegion *address_space,
2348
              MemoryRegion *address_space_io, bool init_vga_ports)
2349
{
2350
    MemoryRegion *vga_io_memory;
2351
    const MemoryRegionPortio *vga_ports, *vbe_ports;
2352
    PortioList *vga_port_list = g_new(PortioList, 1);
2353
    PortioList *vbe_port_list = g_new(PortioList, 1);
2354

    
2355
    qemu_register_reset(vga_reset, s);
2356

    
2357
    s->bank_offset = 0;
2358

    
2359
    s->legacy_address_space = address_space;
2360

    
2361
    vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
2362
    memory_region_add_subregion_overlap(address_space,
2363
                                        isa_mem_base + 0x000a0000,
2364
                                        vga_io_memory,
2365
                                        1);
2366
    memory_region_set_coalescing(vga_io_memory);
2367
    if (init_vga_ports) {
2368
        portio_list_init(vga_port_list, vga_ports, s, "vga");
2369
        portio_list_add(vga_port_list, address_space_io, 0x3b0);
2370
    }
2371
    if (vbe_ports) {
2372
        portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
2373
        portio_list_add(vbe_port_list, address_space_io, 0x1ce);
2374
    }
2375
}
2376

    
2377
void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
2378
{
2379
    /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2380
     * so use an alias to avoid double-mapping the same region.
2381
     */
2382
    memory_region_init_alias(&s->vram_vbe, "vram.vbe",
2383
                             &s->vram, 0, memory_region_size(&s->vram));
2384
    /* XXX: use optimized standard vga accesses */
2385
    memory_region_add_subregion(system_memory,
2386
                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2387
                                &s->vram_vbe);
2388
    s->vbe_mapped = 1;
2389
}
2390
/********************************************************/
2391
/* vga screen dump */
2392

    
2393
void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
2394
{
2395
    int width = pixman_image_get_width(ds->image);
2396
    int height = pixman_image_get_height(ds->image);
2397
    FILE *f;
2398
    int y;
2399
    int ret;
2400
    pixman_image_t *linebuf;
2401

    
2402
    trace_ppm_save(filename, ds);
2403
    f = fopen(filename, "wb");
2404
    if (!f) {
2405
        error_setg(errp, "failed to open file '%s': %s", filename,
2406
                   strerror(errno));
2407
        return;
2408
    }
2409
    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
2410
    if (ret < 0) {
2411
        linebuf = NULL;
2412
        goto write_err;
2413
    }
2414
    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
2415
    for (y = 0; y < height; y++) {
2416
        qemu_pixman_linebuf_fill(linebuf, ds->image, width, y);
2417
        clearerr(f);
2418
        ret = fwrite(pixman_image_get_data(linebuf), 1,
2419
                     pixman_image_get_stride(linebuf), f);
2420
        (void)ret;
2421
        if (ferror(f)) {
2422
            goto write_err;
2423
        }
2424
    }
2425

    
2426
out:
2427
    qemu_pixman_image_unref(linebuf);
2428
    fclose(f);
2429
    return;
2430

    
2431
write_err:
2432
    error_setg(errp, "failed to write to file '%s': %s", filename,
2433
               strerror(errno));
2434
    unlink(filename);
2435
    goto out;
2436
}
2437

    
2438
/* save the vga display in a PPM image even if no display is
2439
   available */
2440
static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
2441
                            Error **errp)
2442
{
2443
    VGACommonState *s = opaque;
2444

    
2445
    if (cswitch) {
2446
        vga_invalidate_display(s);
2447
    }
2448
    vga_hw_update();
2449
    ppm_save(filename, s->ds->surface, errp);
2450
}