~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/vga.c

  • Committer: ths
  • Date: 2007-06-17 15:32:30 UTC
  • Revision ID: git-v1:ffb04fcf089865952592f1f8855c2848d4514a89
Allow relative paths for the interpreter prefix in linux-user emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2984 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * QEMU VGA Emulator.
3
 
 *
 
3
 * 
4
4
 * Copyright (c) 2003 Fabrice Bellard
5
 
 *
 
5
 * 
6
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
 * of this software and associated documentation files (the "Software"), to deal
8
8
 * in the Software without restriction, including without limitation the rights
21
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
 * THE SOFTWARE.
23
23
 */
24
 
#include "hw.h"
25
 
#include "console.h"
26
 
#include "pc.h"
27
 
#include "pci.h"
 
24
#include "vl.h"
28
25
#include "vga_int.h"
29
26
#include "pixel_ops.h"
30
 
#include "qemu-timer.h"
31
27
 
32
28
//#define DEBUG_VGA
33
29
//#define DEBUG_VGA_MEM
150
146
 
151
147
static void vga_screen_dump(void *opaque, const char *filename);
152
148
 
153
 
static void vga_dumb_update_retrace_info(VGAState *s)
154
 
{
155
 
    (void) s;
156
 
}
157
 
 
158
 
static void vga_precise_update_retrace_info(VGAState *s)
159
 
{
160
 
    int htotal_chars;
161
 
    int hretr_start_char;
162
 
    int hretr_skew_chars;
163
 
    int hretr_end_char;
164
 
 
165
 
    int vtotal_lines;
166
 
    int vretr_start_line;
167
 
    int vretr_end_line;
168
 
 
169
 
    int div2, sldiv2, dots;
170
 
    int clocking_mode;
171
 
    int clock_sel;
172
 
    const int hz[] = {25175000, 28322000, 25175000, 25175000};
173
 
    int64_t chars_per_sec;
174
 
    struct vga_precise_retrace *r = &s->retrace_info.precise;
175
 
 
176
 
    htotal_chars = s->cr[0x00] + 5;
177
 
    hretr_start_char = s->cr[0x04];
178
 
    hretr_skew_chars = (s->cr[0x05] >> 5) & 3;
179
 
    hretr_end_char = s->cr[0x05] & 0x1f;
180
 
 
181
 
    vtotal_lines = (s->cr[0x06]
182
 
                    | (((s->cr[0x07] & 1) | ((s->cr[0x07] >> 4) & 2)) << 8)) + 2
183
 
        ;
184
 
    vretr_start_line = s->cr[0x10]
185
 
        | ((((s->cr[0x07] >> 2) & 1) | ((s->cr[0x07] >> 6) & 2)) << 8)
186
 
        ;
187
 
    vretr_end_line = s->cr[0x11] & 0xf;
188
 
 
189
 
 
190
 
    div2 = (s->cr[0x17] >> 2) & 1;
191
 
    sldiv2 = (s->cr[0x17] >> 3) & 1;
192
 
 
193
 
    clocking_mode = (s->sr[0x01] >> 3) & 1;
194
 
    clock_sel = (s->msr >> 2) & 3;
195
 
    dots = (s->msr & 1) ? 8 : 9;
196
 
 
197
 
    chars_per_sec = hz[clock_sel] / dots;
198
 
 
199
 
    htotal_chars <<= clocking_mode;
200
 
 
201
 
    r->total_chars = vtotal_lines * htotal_chars;
202
 
    if (r->freq) {
203
 
        r->ticks_per_char = ticks_per_sec / (r->total_chars * r->freq);
204
 
    } else {
205
 
        r->ticks_per_char = ticks_per_sec / chars_per_sec;
206
 
    }
207
 
 
208
 
    r->vstart = vretr_start_line;
209
 
    r->vend = r->vstart + vretr_end_line + 1;
210
 
 
211
 
    r->hstart = hretr_start_char + hretr_skew_chars;
212
 
    r->hend = r->hstart + hretr_end_char + 1;
213
 
    r->htotal = htotal_chars;
214
 
 
215
 
#if 0
216
 
    printf (
217
 
        "hz=%f\n"
218
 
        "htotal = %d\n"
219
 
        "hretr_start = %d\n"
220
 
        "hretr_skew = %d\n"
221
 
        "hretr_end = %d\n"
222
 
        "vtotal = %d\n"
223
 
        "vretr_start = %d\n"
224
 
        "vretr_end = %d\n"
225
 
        "div2 = %d sldiv2 = %d\n"
226
 
        "clocking_mode = %d\n"
227
 
        "clock_sel = %d %d\n"
228
 
        "dots = %d\n"
229
 
        "ticks/char = %lld\n"
230
 
        "\n",
231
 
        (double) ticks_per_sec / (r->ticks_per_char * r->total_chars),
232
 
        htotal_chars,
233
 
        hretr_start_char,
234
 
        hretr_skew_chars,
235
 
        hretr_end_char,
236
 
        vtotal_lines,
237
 
        vretr_start_line,
238
 
        vretr_end_line,
239
 
        div2, sldiv2,
240
 
        clocking_mode,
241
 
        clock_sel,
242
 
        hz[clock_sel],
243
 
        dots,
244
 
        r->ticks_per_char
245
 
        );
246
 
#endif
247
 
}
248
 
 
249
 
static uint8_t vga_precise_retrace(VGAState *s)
250
 
{
251
 
    struct vga_precise_retrace *r = &s->retrace_info.precise;
252
 
    uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
253
 
 
254
 
    if (r->total_chars) {
255
 
        int cur_line, cur_line_char, cur_char;
256
 
        int64_t cur_tick;
257
 
 
258
 
        cur_tick = qemu_get_clock(vm_clock);
259
 
 
260
 
        cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
261
 
        cur_line = cur_char / r->htotal;
262
 
 
263
 
        if (cur_line >= r->vstart && cur_line <= r->vend) {
264
 
            val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
265
 
        } else {
266
 
            cur_line_char = cur_char % r->htotal;
267
 
            if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
268
 
                val |= ST01_DISP_ENABLE;
269
 
            }
270
 
        }
271
 
 
272
 
        return val;
273
 
    } else {
274
 
        return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
275
 
    }
276
 
}
277
 
 
278
 
static uint8_t vga_dumb_retrace(VGAState *s)
279
 
{
280
 
    return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
281
 
}
282
 
 
283
149
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
284
150
{
285
151
    VGAState *s = opaque;
300
166
            break;
301
167
        case 0x3c1:
302
168
            index = s->ar_index & 0x1f;
303
 
            if (index < 21)
 
169
            if (index < 21) 
304
170
                val = s->ar[index];
305
171
            else
306
172
                val = 0;
359
225
        case 0x3ba:
360
226
        case 0x3da:
361
227
            /* just toggle to fool polling */
362
 
            val = s->st01 = s->retrace(s);
 
228
            s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
 
229
            val = s->st01;
363
230
            s->ar_flip_flop = 0;
364
231
            break;
365
232
        default:
421
288
        break;
422
289
    case 0x3c2:
423
290
        s->msr = val & ~0x10;
424
 
        s->update_retrace_info(s);
425
291
        break;
426
292
    case 0x3c4:
427
293
        s->sr_index = val & 7;
431
297
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
432
298
#endif
433
299
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
434
 
        if (s->sr_index == 1) s->update_retrace_info(s);
435
300
        break;
436
301
    case 0x3c7:
437
302
        s->dac_read_index = val;
489
354
            s->cr[s->cr_index] = val;
490
355
            break;
491
356
        }
492
 
 
493
 
        switch(s->cr_index) {
494
 
        case 0x00:
495
 
        case 0x04:
496
 
        case 0x05:
497
 
        case 0x06:
498
 
        case 0x07:
499
 
        case 0x11:
500
 
        case 0x17:
501
 
            s->update_retrace_info(s);
502
 
            break;
503
 
        }
504
357
        break;
505
358
    case 0x3ba:
506
359
    case 0x3da:
537
390
                val = VBE_DISPI_MAX_BPP;
538
391
                break;
539
392
            default:
540
 
                val = s->vbe_regs[s->vbe_index];
 
393
                val = s->vbe_regs[s->vbe_index]; 
541
394
                break;
542
395
            }
543
396
        } else {
544
 
            val = s->vbe_regs[s->vbe_index];
 
397
            val = s->vbe_regs[s->vbe_index]; 
545
398
        }
546
399
    } else {
547
400
        val = 0;
589
442
        case VBE_DISPI_INDEX_BPP:
590
443
            if (val == 0)
591
444
                val = 8;
592
 
            if (val == 4 || val == 8 || val == 15 ||
 
445
            if (val == 4 || val == 8 || val == 15 || 
593
446
                val == 16 || val == 24 || val == 32) {
594
447
                s->vbe_regs[s->vbe_index] = val;
595
448
            }
608
461
                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
609
462
                int h, shift_control;
610
463
 
611
 
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
 
464
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 
612
465
                    s->vbe_regs[VBE_DISPI_INDEX_XRES];
613
 
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
 
466
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = 
614
467
                    s->vbe_regs[VBE_DISPI_INDEX_YRES];
615
468
                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
616
469
                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
617
 
 
 
470
                
618
471
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
619
472
                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
620
473
                else
621
 
                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
 
474
                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * 
622
475
                        ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
623
476
                s->vbe_start_addr = 0;
624
477
 
625
478
                /* clear the screen (should be done in BIOS) */
626
479
                if (!(val & VBE_DISPI_NOCLEARMEM)) {
627
 
                    memset(s->vram_ptr, 0,
 
480
                    memset(s->vram_ptr, 0, 
628
481
                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
629
482
                }
630
 
 
 
483
                
631
484
                /* we initialize the VGA graphic mode (should be done
632
485
                   in BIOS) */
633
486
                s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
638
491
                /* height (only meaningful if < 1024) */
639
492
                h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
640
493
                s->cr[0x12] = h;
641
 
                s->cr[0x07] = (s->cr[0x07] & ~0x42) |
 
494
                s->cr[0x07] = (s->cr[0x07] & ~0x42) | 
642
495
                    ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
643
496
                /* line compare to 1023 */
644
497
                s->cr[0x18] = 0xff;
645
498
                s->cr[0x07] |= 0x10;
646
499
                s->cr[0x09] |= 0x40;
647
 
 
 
500
                
648
501
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
649
502
                    shift_control = 0;
650
503
                    s->sr[0x01] &= ~8; /* no double line */
709
562
    VGAState *s = opaque;
710
563
    int memory_map_mode, plane;
711
564
    uint32_t ret;
712
 
 
 
565
    
713
566
    /* convert to VGA memory offset */
714
567
    memory_map_mode = (s->gr[6] >> 2) & 3;
715
568
    addr &= 0x1ffff;
733
586
            return 0xff;
734
587
        break;
735
588
    }
736
 
 
 
589
    
737
590
    if (s->sr[4] & 0x08) {
738
591
        /* chain 4 mode : simplest access */
739
592
        ret = s->vram_ptr[addr];
823
676
            return;
824
677
        break;
825
678
    }
826
 
 
 
679
    
827
680
    if (s->sr[4] & 0x08) {
828
681
        /* chain 4 mode : simplest access */
829
682
        plane = addr & 3;
914
767
        mask = s->sr[2];
915
768
        s->plane_updated |= mask; /* only used to detect font change */
916
769
        write_mask = mask16[mask];
917
 
        ((uint32_t *)s->vram_ptr)[addr] =
918
 
            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
 
770
        ((uint32_t *)s->vram_ptr)[addr] = 
 
771
            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | 
919
772
            (val & write_mask);
920
773
#ifdef DEBUG_VGA_MEM
921
 
            printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
 
774
            printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n", 
922
775
                   addr * 4, write_mask, val);
923
776
#endif
924
777
            cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
955
808
                             const uint8_t *font_ptr, int h,
956
809
                             uint32_t fgcol, uint32_t bgcol);
957
810
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
958
 
                                  const uint8_t *font_ptr, int h,
 
811
                                  const uint8_t *font_ptr, int h, 
959
812
                                  uint32_t fgcol, uint32_t bgcol, int dup9);
960
 
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
 
813
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d, 
961
814
                                const uint8_t *s, int width);
962
815
 
963
816
#define DEPTH 8
1056
909
        else
1057
910
            v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
1058
911
        v = v * 3;
1059
 
        col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1060
 
                              c6_to_8(s->palette[v + 1]),
 
912
        col = s->rgb_to_pixel(c6_to_8(s->palette[v]), 
 
913
                              c6_to_8(s->palette[v + 1]), 
1061
914
                              c6_to_8(s->palette[v + 2]));
1062
915
        if (col != palette[i]) {
1063
916
            full_update = 1;
1078
931
    v = 0;
1079
932
    for(i = 0; i < 256; i++) {
1080
933
        if (s->dac_8bit) {
1081
 
          col = s->rgb_to_pixel(s->palette[v],
1082
 
                                s->palette[v + 1],
 
934
          col = s->rgb_to_pixel(s->palette[v], 
 
935
                                s->palette[v + 1], 
1083
936
                                s->palette[v + 2]);
1084
937
        } else {
1085
 
          col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1086
 
                                c6_to_8(s->palette[v + 1]),
 
938
          col = s->rgb_to_pixel(c6_to_8(s->palette[v]), 
 
939
                                c6_to_8(s->palette[v + 1]), 
1087
940
                                c6_to_8(s->palette[v + 2]));
1088
941
        }
1089
942
        if (col != palette[i]) {
1095
948
    return full_update;
1096
949
}
1097
950
 
1098
 
static void vga_get_offsets(VGAState *s,
1099
 
                            uint32_t *pline_offset,
 
951
static void vga_get_offsets(VGAState *s, 
 
952
                            uint32_t *pline_offset, 
1100
953
                            uint32_t *pstart_addr,
1101
954
                            uint32_t *pline_compare)
1102
955
{
1108
961
        line_compare = 65535;
1109
962
    } else
1110
963
#endif
1111
 
    {
 
964
    {  
1112
965
        /* compute line_offset in bytes */
1113
966
        line_offset = s->cr[0x13];
1114
967
        line_offset <<= 3;
1117
970
        start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
1118
971
 
1119
972
        /* line compare */
1120
 
        line_compare = s->cr[0x18] |
 
973
        line_compare = s->cr[0x18] | 
1121
974
            ((s->cr[0x07] & 0x10) << 4) |
1122
975
            ((s->cr[0x09] & 0x40) << 3);
1123
976
    }
1131
984
{
1132
985
    int full_update;
1133
986
    uint32_t start_addr, line_offset, line_compare;
1134
 
 
 
987
    
1135
988
    full_update = 0;
1136
989
 
1137
990
    s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1202
1055
    vga_draw_glyph9_16,
1203
1056
    vga_draw_glyph9_16,
1204
1057
};
1205
 
 
 
1058
    
1206
1059
static const uint8_t cursor_glyph[32 * 4] = {
1207
1060
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1208
1061
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1220
1073
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1221
1074
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1222
1075
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1223
 
};
 
1076
};    
1224
1077
 
1225
 
/*
1226
 
 * Text mode update
 
1078
/* 
 
1079
 * Text mode update 
1227
1080
 * Missing:
1228
1081
 * - double scan
1229
 
 * - double width
 
1082
 * - double width 
1230
1083
 * - underline
1231
1084
 * - flashing
1232
1085
 */
1245
1098
 
1246
1099
    full_update |= update_palette16(s);
1247
1100
    palette = s->last_palette;
1248
 
 
 
1101
    
1249
1102
    /* compute font data address (in plane 2) */
1250
1103
    v = s->sr[3];
1251
1104
    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1285
1138
        /* ugly hack for CGA 160x100x16 - explain me the logic */
1286
1139
        height = 100;
1287
1140
    } else {
1288
 
        height = s->cr[0x12] |
1289
 
            ((s->cr[0x07] & 0x02) << 7) |
 
1141
        height = s->cr[0x12] | 
 
1142
            ((s->cr[0x07] & 0x02) << 7) | 
1290
1143
            ((s->cr[0x07] & 0x40) << 3);
1291
1144
        height = (height + 1) / cheight;
1292
1145
    }
1299
1152
        cw != s->last_cw || cheight != s->last_ch) {
1300
1153
        s->last_scr_width = width * cw;
1301
1154
        s->last_scr_height = height * cheight;
1302
 
        qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height);
 
1155
        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
1303
1156
        s->last_width = width;
1304
1157
        s->last_height = height;
1305
1158
        s->last_ch = cheight;
1321
1174
        s->cursor_end = s->cr[0xb];
1322
1175
    }
1323
1176
    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1324
 
 
 
1177
    
1325
1178
    depth_index = get_depth_index(s->ds);
1326
1179
    if (cw == 16)
1327
1180
        vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
1328
1181
    else
1329
1182
        vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
1330
1183
    vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
1331
 
 
 
1184
    
1332
1185
    dest = s->ds->data;
1333
1186
    linesize = s->ds->linesize;
1334
1187
    ch_attr_ptr = s->last_ch_attr;
1357
1210
                bgcol = palette[cattr >> 4];
1358
1211
                fgcol = palette[cattr & 0x0f];
1359
1212
                if (cw != 9) {
1360
 
                    vga_draw_glyph8(d1, linesize,
 
1213
                    vga_draw_glyph8(d1, linesize, 
1361
1214
                                    font_ptr, cheight, fgcol, bgcol);
1362
1215
                } else {
1363
1216
                    dup9 = 0;
1364
1217
                    if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
1365
1218
                        dup9 = 1;
1366
 
                    vga_draw_glyph9(d1, linesize,
 
1219
                    vga_draw_glyph9(d1, linesize, 
1367
1220
                                    font_ptr, cheight, fgcol, bgcol, dup9);
1368
1221
                }
1369
1222
                if (src == cursor_ptr &&
1379
1232
                        h = line_last - line_start + 1;
1380
1233
                        d = d1 + linesize * line_start;
1381
1234
                        if (cw != 9) {
1382
 
                            vga_draw_glyph8(d, linesize,
 
1235
                            vga_draw_glyph8(d, linesize, 
1383
1236
                                            cursor_glyph, h, fgcol, bgcol);
1384
1237
                        } else {
1385
 
                            vga_draw_glyph9(d, linesize,
 
1238
                            vga_draw_glyph9(d, linesize, 
1386
1239
                                            cursor_glyph, h, fgcol, bgcol, 1);
1387
1240
                        }
1388
1241
                    }
1393
1246
            ch_attr_ptr++;
1394
1247
        }
1395
1248
        if (cx_max != -1) {
1396
 
            dpy_update(s->ds, cx_min * cw, cy * cheight,
 
1249
            dpy_update(s->ds, cx_min * cw, cy * cheight, 
1397
1250
                       (cx_max - cx_min + 1) * cw, cheight);
1398
1251
        }
1399
1252
        dest += linesize * cheight;
1515
1368
#ifdef CONFIG_BOCHS_VBE
1516
1369
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1517
1370
        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1518
 
    } else
 
1371
    } else 
1519
1372
#endif
1520
1373
    {
1521
1374
        ret = 0;
1526
1379
static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
1527
1380
{
1528
1381
    int width, height;
1529
 
 
 
1382
    
1530
1383
#ifdef CONFIG_BOCHS_VBE
1531
1384
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1532
1385
        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1533
1386
        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1534
 
    } else
 
1387
    } else 
1535
1388
#endif
1536
1389
    {
1537
1390
        width = (s->cr[0x01] + 1) * 8;
1538
 
        height = s->cr[0x12] |
1539
 
            ((s->cr[0x07] & 0x02) << 7) |
 
1391
        height = s->cr[0x12] | 
 
1392
            ((s->cr[0x07] & 0x02) << 7) | 
1540
1393
            ((s->cr[0x07] & 0x40) << 3);
1541
1394
        height = (height + 1);
1542
1395
    }
1556
1409
    }
1557
1410
}
1558
1411
 
1559
 
/*
 
1412
/* 
1560
1413
 * graphic modes
1561
1414
 */
1562
1415
static void vga_draw_graphic(VGAState *s, int full_update)
1563
1416
{
1564
1417
    int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
1565
 
    int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
 
1418
    int width, height, shift_control, line_offset, page0, page1, bwidth;
1566
1419
    int disp_width, multi_scan, multi_run;
1567
1420
    uint8_t *d;
1568
1421
    uint32_t v, addr1, addr;
1569
1422
    vga_draw_line_func *vga_draw_line;
1570
 
 
 
1423
    
1571
1424
    full_update |= update_basic_params(s);
1572
1425
 
1573
1426
    s->get_resolution(s, &width, &height);
1589
1442
        s->shift_control = shift_control;
1590
1443
        s->double_scan = double_scan;
1591
1444
    }
1592
 
 
 
1445
    
1593
1446
    if (shift_control == 0) {
1594
1447
        full_update |= update_palette16(s);
1595
1448
        if (s->sr[0x01] & 8) {
1598
1451
        } else {
1599
1452
            v = VGA_DRAW_LINE4;
1600
1453
        }
1601
 
        bits = 4;
1602
1454
    } else if (shift_control == 1) {
1603
1455
        full_update |= update_palette16(s);
1604
1456
        if (s->sr[0x01] & 8) {
1607
1459
        } else {
1608
1460
            v = VGA_DRAW_LINE2;
1609
1461
        }
1610
 
        bits = 4;
1611
1462
    } else {
1612
1463
        switch(s->get_bpp(s)) {
1613
1464
        default:
1614
1465
        case 0:
1615
1466
            full_update |= update_palette256(s);
1616
1467
            v = VGA_DRAW_LINE8D2;
1617
 
            bits = 4;
1618
1468
            break;
1619
1469
        case 8:
1620
1470
            full_update |= update_palette256(s);
1621
1471
            v = VGA_DRAW_LINE8;
1622
 
            bits = 8;
1623
1472
            break;
1624
1473
        case 15:
1625
1474
            v = VGA_DRAW_LINE15;
1626
 
            bits = 16;
1627
1475
            break;
1628
1476
        case 16:
1629
1477
            v = VGA_DRAW_LINE16;
1630
 
            bits = 16;
1631
1478
            break;
1632
1479
        case 24:
1633
1480
            v = VGA_DRAW_LINE24;
1634
 
            bits = 24;
1635
1481
            break;
1636
1482
        case 32:
1637
1483
            v = VGA_DRAW_LINE32;
1638
 
            bits = 32;
1639
1484
            break;
1640
1485
        }
1641
1486
    }
1643
1488
 
1644
1489
    if (disp_width != s->last_width ||
1645
1490
        height != s->last_height) {
1646
 
        qemu_console_resize(s->console, disp_width, height);
 
1491
        dpy_resize(s->ds, disp_width, height);
1647
1492
        s->last_scr_width = disp_width;
1648
1493
        s->last_scr_height = height;
1649
1494
        s->last_width = disp_width;
1652
1497
    }
1653
1498
    if (s->cursor_invalidate)
1654
1499
        s->cursor_invalidate(s);
1655
 
 
 
1500
    
1656
1501
    line_offset = s->line_offset;
1657
1502
#if 0
1658
1503
    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",
1659
1504
           width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
1660
1505
#endif
1661
1506
    addr1 = (s->start_addr * 4);
1662
 
    bwidth = (width * bits + 7) / 8;
 
1507
    bwidth = width * 4;
1663
1508
    y_start = -1;
1664
1509
    page_min = 0x7fffffff;
1665
1510
    page_max = -1;
1679
1524
        }
1680
1525
        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
1681
1526
        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
1682
 
        update = full_update |
 
1527
        update = full_update | 
1683
1528
            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
1684
1529
            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
1685
1530
        if ((page1 - page0) > TARGET_PAGE_SIZE) {
1686
1531
            /* if wide line, can use another page */
1687
 
            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
 
1532
            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, 
1688
1533
                                                    VGA_DIRTY_FLAG);
1689
1534
        }
1690
1535
        /* explicit invalidation for the hardware cursor */
1702
1547
        } else {
1703
1548
            if (y_start >= 0) {
1704
1549
                /* flush to display */
1705
 
                dpy_update(s->ds, 0, y_start,
 
1550
                dpy_update(s->ds, 0, y_start, 
1706
1551
                           disp_width, y - y_start);
1707
1552
                y_start = -1;
1708
1553
            }
1723
1568
    }
1724
1569
    if (y_start >= 0) {
1725
1570
        /* flush to display */
1726
 
        dpy_update(s->ds, 0, y_start,
 
1571
        dpy_update(s->ds, 0, y_start, 
1727
1572
                   disp_width, y - y_start);
1728
1573
    }
1729
1574
    /* reset modified pages */
1743
1588
        return;
1744
1589
    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1745
1590
        return;
1746
 
    if (s->ds->depth == 8)
 
1591
    if (s->ds->depth == 8) 
1747
1592
        val = s->rgb_to_pixel(0, 0, 0);
1748
1593
    else
1749
1594
        val = 0;
1753
1598
        memset(d, val, w);
1754
1599
        d += s->ds->linesize;
1755
1600
    }
1756
 
    dpy_update(s->ds, 0, 0,
 
1601
    dpy_update(s->ds, 0, 0, 
1757
1602
               s->last_scr_width, s->last_scr_height);
1758
1603
}
1759
1604
 
1760
1605
#define GMODE_TEXT     0
1761
1606
#define GMODE_GRAPH    1
1762
 
#define GMODE_BLANK 2
 
1607
#define GMODE_BLANK 2 
1763
1608
 
1764
1609
static void vga_update_display(void *opaque)
1765
1610
{
1769
1614
    if (s->ds->depth == 0) {
1770
1615
        /* nothing to do */
1771
1616
    } else {
1772
 
        s->rgb_to_pixel =
 
1617
        s->rgb_to_pixel = 
1773
1618
            rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1774
 
 
 
1619
        
1775
1620
        full_update = 0;
1776
1621
        if (!(s->ar_index & 0x20)) {
1777
1622
            graphic_mode = GMODE_BLANK;
1801
1646
static void vga_invalidate_display(void *opaque)
1802
1647
{
1803
1648
    VGAState *s = (VGAState *)opaque;
1804
 
 
 
1649
    
1805
1650
    s->last_width = -1;
1806
1651
    s->last_height = -1;
1807
1652
}
1812
1657
    s->graphic_mode = -1; /* force full update */
1813
1658
}
1814
1659
 
1815
 
#define TEXTMODE_X(x)   ((x) % width)
1816
 
#define TEXTMODE_Y(x)   ((x) / width)
1817
 
#define VMEM2CHTYPE(v)  ((v & 0xff0007ff) | \
1818
 
        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1819
 
/* relay text rendering to the display driver
1820
 
 * instead of doing a full vga_update_display() */
1821
 
static void vga_update_text(void *opaque, console_ch_t *chardata)
1822
 
{
1823
 
    VGAState *s = (VGAState *) opaque;
1824
 
    int graphic_mode, i, cursor_offset, cursor_visible;
1825
 
    int cw, cheight, width, height, size, c_min, c_max;
1826
 
    uint32_t *src;
1827
 
    console_ch_t *dst, val;
1828
 
    char msg_buffer[80];
1829
 
    int full_update = 0;
1830
 
 
1831
 
    if (!(s->ar_index & 0x20)) {
1832
 
        graphic_mode = GMODE_BLANK;
1833
 
    } else {
1834
 
        graphic_mode = s->gr[6] & 1;
1835
 
    }
1836
 
    if (graphic_mode != s->graphic_mode) {
1837
 
        s->graphic_mode = graphic_mode;
1838
 
        full_update = 1;
1839
 
    }
1840
 
    if (s->last_width == -1) {
1841
 
        s->last_width = 0;
1842
 
        full_update = 1;
1843
 
    }
1844
 
 
1845
 
    switch (graphic_mode) {
1846
 
    case GMODE_TEXT:
1847
 
        /* TODO: update palette */
1848
 
        full_update |= update_basic_params(s);
1849
 
 
1850
 
        /* total width & height */
1851
 
        cheight = (s->cr[9] & 0x1f) + 1;
1852
 
        cw = 8;
1853
 
        if (!(s->sr[1] & 0x01))
1854
 
            cw = 9;
1855
 
        if (s->sr[1] & 0x08)
1856
 
            cw = 16; /* NOTE: no 18 pixel wide */
1857
 
        width = (s->cr[0x01] + 1);
1858
 
        if (s->cr[0x06] == 100) {
1859
 
            /* ugly hack for CGA 160x100x16 - explain me the logic */
1860
 
            height = 100;
1861
 
        } else {
1862
 
            height = s->cr[0x12] | 
1863
 
                ((s->cr[0x07] & 0x02) << 7) | 
1864
 
                ((s->cr[0x07] & 0x40) << 3);
1865
 
            height = (height + 1) / cheight;
1866
 
        }
1867
 
 
1868
 
        size = (height * width);
1869
 
        if (size > CH_ATTR_SIZE) {
1870
 
            if (!full_update)
1871
 
                return;
1872
 
 
1873
 
            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1874
 
                     width, height);
1875
 
            break;
1876
 
        }
1877
 
 
1878
 
        if (width != s->last_width || height != s->last_height ||
1879
 
            cw != s->last_cw || cheight != s->last_ch) {
1880
 
            s->last_scr_width = width * cw;
1881
 
            s->last_scr_height = height * cheight;
1882
 
            qemu_console_resize(s->console, width, height);
1883
 
            s->last_width = width;
1884
 
            s->last_height = height;
1885
 
            s->last_ch = cheight;
1886
 
            s->last_cw = cw;
1887
 
            full_update = 1;
1888
 
        }
1889
 
 
1890
 
        /* Update "hardware" cursor */
1891
 
        cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
1892
 
        if (cursor_offset != s->cursor_offset ||
1893
 
            s->cr[0xa] != s->cursor_start ||
1894
 
            s->cr[0xb] != s->cursor_end || full_update) {
1895
 
            cursor_visible = !(s->cr[0xa] & 0x20);
1896
 
            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1897
 
                dpy_cursor(s->ds,
1898
 
                           TEXTMODE_X(cursor_offset),
1899
 
                           TEXTMODE_Y(cursor_offset));
1900
 
            else
1901
 
                dpy_cursor(s->ds, -1, -1);
1902
 
            s->cursor_offset = cursor_offset;
1903
 
            s->cursor_start = s->cr[0xa];
1904
 
            s->cursor_end = s->cr[0xb];
1905
 
        }
1906
 
 
1907
 
        src = (uint32_t *) s->vram_ptr + s->start_addr;
1908
 
        dst = chardata;
1909
 
 
1910
 
        if (full_update) {
1911
 
            for (i = 0; i < size; src ++, dst ++, i ++)
1912
 
                console_write_ch(dst, VMEM2CHTYPE(*src));
1913
 
 
1914
 
            dpy_update(s->ds, 0, 0, width, height);
1915
 
        } else {
1916
 
            c_max = 0;
1917
 
 
1918
 
            for (i = 0; i < size; src ++, dst ++, i ++) {
1919
 
                console_write_ch(&val, VMEM2CHTYPE(*src));
1920
 
                if (*dst != val) {
1921
 
                    *dst = val;
1922
 
                    c_max = i;
1923
 
                    break;
1924
 
                }
1925
 
            }
1926
 
            c_min = i;
1927
 
            for (; i < size; src ++, dst ++, i ++) {
1928
 
                console_write_ch(&val, VMEM2CHTYPE(*src));
1929
 
                if (*dst != val) {
1930
 
                    *dst = val;
1931
 
                    c_max = i;
1932
 
                }
1933
 
            }
1934
 
 
1935
 
            if (c_min <= c_max) {
1936
 
                i = TEXTMODE_Y(c_min);
1937
 
                dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
1938
 
            }
1939
 
        }
1940
 
 
1941
 
        return;
1942
 
    case GMODE_GRAPH:
1943
 
        if (!full_update)
1944
 
            return;
1945
 
 
1946
 
        s->get_resolution(s, &width, &height);
1947
 
        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
1948
 
                 width, height);
1949
 
        break;
1950
 
    case GMODE_BLANK:
1951
 
    default:
1952
 
        if (!full_update)
1953
 
            return;
1954
 
 
1955
 
        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
1956
 
        break;
1957
 
    }
1958
 
 
1959
 
    /* Display a message */
1960
 
    s->last_width = 60;
1961
 
    s->last_height = height = 3;
1962
 
    dpy_cursor(s->ds, -1, -1);
1963
 
    qemu_console_resize(s->console, s->last_width, height);
1964
 
 
1965
 
    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
1966
 
        console_write_ch(dst ++, ' ');
1967
 
 
1968
 
    size = strlen(msg_buffer);
1969
 
    width = (s->last_width - size) / 2;
1970
 
    dst = chardata + s->last_width + width;
1971
 
    for (i = 0; i < size; i ++)
1972
 
        console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
1973
 
 
1974
 
    dpy_update(s->ds, 0, 0, s->last_width, height);
1975
 
}
1976
 
 
1977
1660
static CPUReadMemoryFunc *vga_mem_read[3] = {
1978
1661
    vga_mem_readb,
1979
1662
    vga_mem_readw,
2001
1684
    qemu_put_buffer(f, s->gr, 16);
2002
1685
    qemu_put_8s(f, &s->ar_index);
2003
1686
    qemu_put_buffer(f, s->ar, 21);
2004
 
    qemu_put_be32(f, s->ar_flip_flop);
 
1687
    qemu_put_be32s(f, &s->ar_flip_flop);
2005
1688
    qemu_put_8s(f, &s->cr_index);
2006
1689
    qemu_put_buffer(f, s->cr, 256);
2007
1690
    qemu_put_8s(f, &s->msr);
2008
1691
    qemu_put_8s(f, &s->fcr);
2009
 
    qemu_put_byte(f, s->st00);
 
1692
    qemu_put_8s(f, &s->st00);
2010
1693
    qemu_put_8s(f, &s->st01);
2011
1694
 
2012
1695
    qemu_put_8s(f, &s->dac_state);
2016
1699
    qemu_put_buffer(f, s->dac_cache, 3);
2017
1700
    qemu_put_buffer(f, s->palette, 768);
2018
1701
 
2019
 
    qemu_put_be32(f, s->bank_offset);
 
1702
    qemu_put_be32s(f, &s->bank_offset);
2020
1703
#ifdef CONFIG_BOCHS_VBE
2021
1704
    qemu_put_byte(f, 1);
2022
1705
    qemu_put_be16s(f, &s->vbe_index);
2051
1734
    qemu_get_buffer(f, s->gr, 16);
2052
1735
    qemu_get_8s(f, &s->ar_index);
2053
1736
    qemu_get_buffer(f, s->ar, 21);
2054
 
    s->ar_flip_flop=qemu_get_be32(f);
 
1737
    qemu_get_be32s(f, &s->ar_flip_flop);
2055
1738
    qemu_get_8s(f, &s->cr_index);
2056
1739
    qemu_get_buffer(f, s->cr, 256);
2057
1740
    qemu_get_8s(f, &s->msr);
2066
1749
    qemu_get_buffer(f, s->dac_cache, 3);
2067
1750
    qemu_get_buffer(f, s->palette, 768);
2068
1751
 
2069
 
    s->bank_offset=qemu_get_be32(f);
 
1752
    qemu_get_be32s(f, &s->bank_offset);
2070
1753
    is_vbe = qemu_get_byte(f);
2071
1754
#ifdef CONFIG_BOCHS_VBE
2072
1755
    if (!is_vbe)
2092
1775
    VGAState vga_state;
2093
1776
} PCIVGAState;
2094
1777
 
2095
 
static void vga_map(PCIDevice *pci_dev, int region_num,
 
1778
static void vga_map(PCIDevice *pci_dev, int region_num, 
2096
1779
                    uint32_t addr, uint32_t size, int type)
2097
1780
{
2098
1781
    PCIVGAState *d = (PCIVGAState *)pci_dev;
2104
1787
    }
2105
1788
}
2106
1789
 
2107
 
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
 
1790
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
2108
1791
                     unsigned long vga_ram_offset, int vga_ram_size)
2109
1792
{
2110
1793
    int i, j, v, b;
2144
1827
    s->update = vga_update_display;
2145
1828
    s->invalidate = vga_invalidate_display;
2146
1829
    s->screen_dump = vga_screen_dump;
2147
 
    s->text_update = vga_update_text;
2148
 
    switch (vga_retrace_method) {
2149
 
    case VGA_RETRACE_DUMB:
2150
 
        s->retrace = vga_dumb_retrace;
2151
 
        s->update_retrace_info = vga_dumb_update_retrace_info;
2152
 
        break;
2153
 
 
2154
 
    case VGA_RETRACE_PRECISE:
2155
 
        s->retrace = vga_precise_retrace;
2156
 
        s->update_retrace_info = vga_precise_update_retrace_info;
2157
 
        memset(&s->retrace_info, 0, sizeof (s->retrace_info));
2158
 
        break;
2159
 
    }
2160
1830
}
2161
1831
 
2162
1832
/* used by both ISA and PCI */
2196
1866
    register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
2197
1867
 
2198
1868
    register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
2199
 
    register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
 
1869
    register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s); 
2200
1870
#else
2201
1871
    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
2202
1872
    register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
2207
1877
#endif /* CONFIG_BOCHS_VBE */
2208
1878
 
2209
1879
    vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
2210
 
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
 
1880
    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
2211
1881
                                 vga_io_memory);
2212
1882
}
2213
1883
 
2286
1956
    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
2287
1957
}
2288
1958
 
2289
 
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
 
1959
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
2290
1960
                 unsigned long vga_ram_offset, int vga_ram_size)
2291
1961
{
2292
1962
    VGAState *s;
2298
1968
    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2299
1969
    vga_init(s);
2300
1970
 
2301
 
    s->console = graphic_console_init(s->ds, s->update, s->invalidate,
2302
 
                                      s->screen_dump, s->text_update, s);
 
1971
    graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
2303
1972
 
2304
1973
#ifdef CONFIG_BOCHS_VBE
2305
1974
    /* XXX: use optimized standard vga accesses */
2306
 
    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
 
1975
    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 
2307
1976
                                 vga_ram_size, vga_ram_offset);
2308
1977
#endif
2309
1978
    return 0;
2323
1992
    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2324
1993
    vga_mm_init(s, vram_base, ctrl_base, it_shift);
2325
1994
 
2326
 
    s->console = graphic_console_init(s->ds, s->update, s->invalidate,
2327
 
                                      s->screen_dump, s->text_update, s);
 
1995
    graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
2328
1996
 
2329
1997
#ifdef CONFIG_BOCHS_VBE
2330
1998
    /* XXX: use optimized standard vga accesses */
2334
2002
    return 0;
2335
2003
}
2336
2004
 
2337
 
int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
 
2005
int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
2338
2006
                 unsigned long vga_ram_offset, int vga_ram_size,
2339
2007
                 unsigned long vga_bios_offset, int vga_bios_size)
2340
2008
{
2341
2009
    PCIVGAState *d;
2342
2010
    VGAState *s;
2343
2011
    uint8_t *pci_conf;
2344
 
 
2345
 
    d = (PCIVGAState *)pci_register_device(bus, "VGA",
 
2012
    
 
2013
    d = (PCIVGAState *)pci_register_device(bus, "VGA", 
2346
2014
                                           sizeof(PCIVGAState),
2347
2015
                                           -1, NULL, NULL);
2348
2016
    if (!d)
2349
2017
        return -1;
2350
2018
    s = &d->vga_state;
2351
 
 
 
2019
    
2352
2020
    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2353
2021
    vga_init(s);
2354
2022
 
2355
 
    s->console = graphic_console_init(s->ds, s->update, s->invalidate,
2356
 
                                      s->screen_dump, s->text_update, s);
 
2023
    graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
2357
2024
 
2358
2025
    s->pci_dev = &d->dev;
2359
 
 
 
2026
    
2360
2027
    pci_conf = d->dev.config;
2361
2028
    pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
2362
2029
    pci_conf[0x01] = 0x12;
2363
2030
    pci_conf[0x02] = 0x11;
2364
2031
    pci_conf[0x03] = 0x11;
2365
 
    pci_conf[0x0a] = 0x00; // VGA controller
 
2032
    pci_conf[0x0a] = 0x00; // VGA controller 
2366
2033
    pci_conf[0x0b] = 0x03;
2367
2034
    pci_conf[0x0e] = 0x00; // header_type
2368
 
 
 
2035
    
2369
2036
    /* XXX: vga_ram_size must be a power of two */
2370
 
    pci_register_io_region(&d->dev, 0, vga_ram_size,
 
2037
    pci_register_io_region(&d->dev, 0, vga_ram_size, 
2371
2038
                           PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
2372
2039
    if (vga_bios_size != 0) {
2373
2040
        unsigned int bios_total_size;
2377
2044
        bios_total_size = 1;
2378
2045
        while (bios_total_size < vga_bios_size)
2379
2046
            bios_total_size <<= 1;
2380
 
        pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size,
 
2047
        pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size, 
2381
2048
                               PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
2382
2049
    }
2383
2050
    return 0;
2388
2055
 
2389
2056
static int vga_save_w, vga_save_h;
2390
2057
 
2391
 
static void vga_save_dpy_update(DisplayState *s,
 
2058
static void vga_save_dpy_update(DisplayState *s, 
2392
2059
                                int x, int y, int w, int h)
2393
2060
{
2394
2061
}
2405
2072
{
2406
2073
}
2407
2074
 
2408
 
int ppm_save(const char *filename, uint8_t *data,
 
2075
int ppm_save(const char *filename, uint8_t *data, 
2409
2076
             int w, int h, int linesize)
2410
2077
{
2411
2078
    FILE *f;
2440
2107
{
2441
2108
    VGAState *s = (VGAState *)opaque;
2442
2109
    DisplayState *saved_ds, ds1, *ds = &ds1;
2443
 
 
 
2110
    
2444
2111
    /* XXX: this is a little hackish */
2445
2112
    vga_invalidate_display(s);
2446
2113
    saved_ds = s->ds;
2454
2121
    s->ds = ds;
2455
2122
    s->graphic_mode = -1;
2456
2123
    vga_update_display(s);
2457
 
 
 
2124
    
2458
2125
    if (ds->data) {
2459
 
        ppm_save(filename, ds->data, vga_save_w, vga_save_h,
 
2126
        ppm_save(filename, ds->data, vga_save_w, vga_save_h, 
2460
2127
                 s->ds->linesize);
2461
2128
        qemu_free(ds->data);
2462
2129
    }