Revision 5fafdf24 hw/vga.c
b/hw/vga.c | ||
---|---|---|
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 |
... | ... | |
166 | 166 |
break; |
167 | 167 |
case 0x3c1: |
168 | 168 |
index = s->ar_index & 0x1f; |
169 |
if (index < 21)
|
|
169 |
if (index < 21) |
|
170 | 170 |
val = s->ar[index]; |
171 | 171 |
else |
172 | 172 |
val = 0; |
... | ... | |
390 | 390 |
val = VBE_DISPI_MAX_BPP; |
391 | 391 |
break; |
392 | 392 |
default: |
393 |
val = s->vbe_regs[s->vbe_index];
|
|
393 |
val = s->vbe_regs[s->vbe_index]; |
|
394 | 394 |
break; |
395 | 395 |
} |
396 | 396 |
} else { |
397 |
val = s->vbe_regs[s->vbe_index];
|
|
397 |
val = s->vbe_regs[s->vbe_index]; |
|
398 | 398 |
} |
399 | 399 |
} else { |
400 | 400 |
val = 0; |
... | ... | |
442 | 442 |
case VBE_DISPI_INDEX_BPP: |
443 | 443 |
if (val == 0) |
444 | 444 |
val = 8; |
445 |
if (val == 4 || val == 8 || val == 15 ||
|
|
445 |
if (val == 4 || val == 8 || val == 15 || |
|
446 | 446 |
val == 16 || val == 24 || val == 32) { |
447 | 447 |
s->vbe_regs[s->vbe_index] = val; |
448 | 448 |
} |
... | ... | |
461 | 461 |
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { |
462 | 462 |
int h, shift_control; |
463 | 463 |
|
464 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
|
|
464 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = |
|
465 | 465 |
s->vbe_regs[VBE_DISPI_INDEX_XRES]; |
466 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
|
|
466 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = |
|
467 | 467 |
s->vbe_regs[VBE_DISPI_INDEX_YRES]; |
468 | 468 |
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; |
469 | 469 |
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; |
470 |
|
|
470 |
|
|
471 | 471 |
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) |
472 | 472 |
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1; |
473 | 473 |
else |
474 |
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
|
|
474 |
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * |
|
475 | 475 |
((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); |
476 | 476 |
s->vbe_start_addr = 0; |
477 | 477 |
|
478 | 478 |
/* clear the screen (should be done in BIOS) */ |
479 | 479 |
if (!(val & VBE_DISPI_NOCLEARMEM)) { |
480 |
memset(s->vram_ptr, 0,
|
|
480 |
memset(s->vram_ptr, 0, |
|
481 | 481 |
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); |
482 | 482 |
} |
483 |
|
|
483 |
|
|
484 | 484 |
/* we initialize the VGA graphic mode (should be done |
485 | 485 |
in BIOS) */ |
486 | 486 |
s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */ |
... | ... | |
491 | 491 |
/* height (only meaningful if < 1024) */ |
492 | 492 |
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; |
493 | 493 |
s->cr[0x12] = h; |
494 |
s->cr[0x07] = (s->cr[0x07] & ~0x42) |
|
|
494 |
s->cr[0x07] = (s->cr[0x07] & ~0x42) | |
|
495 | 495 |
((h >> 7) & 0x02) | ((h >> 3) & 0x40); |
496 | 496 |
/* line compare to 1023 */ |
497 | 497 |
s->cr[0x18] = 0xff; |
498 | 498 |
s->cr[0x07] |= 0x10; |
499 | 499 |
s->cr[0x09] |= 0x40; |
500 |
|
|
500 |
|
|
501 | 501 |
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { |
502 | 502 |
shift_control = 0; |
503 | 503 |
s->sr[0x01] &= ~8; /* no double line */ |
... | ... | |
562 | 562 |
VGAState *s = opaque; |
563 | 563 |
int memory_map_mode, plane; |
564 | 564 |
uint32_t ret; |
565 |
|
|
565 |
|
|
566 | 566 |
/* convert to VGA memory offset */ |
567 | 567 |
memory_map_mode = (s->gr[6] >> 2) & 3; |
568 | 568 |
addr &= 0x1ffff; |
... | ... | |
586 | 586 |
return 0xff; |
587 | 587 |
break; |
588 | 588 |
} |
589 |
|
|
589 |
|
|
590 | 590 |
if (s->sr[4] & 0x08) { |
591 | 591 |
/* chain 4 mode : simplest access */ |
592 | 592 |
ret = s->vram_ptr[addr]; |
... | ... | |
676 | 676 |
return; |
677 | 677 |
break; |
678 | 678 |
} |
679 |
|
|
679 |
|
|
680 | 680 |
if (s->sr[4] & 0x08) { |
681 | 681 |
/* chain 4 mode : simplest access */ |
682 | 682 |
plane = addr & 3; |
... | ... | |
767 | 767 |
mask = s->sr[2]; |
768 | 768 |
s->plane_updated |= mask; /* only used to detect font change */ |
769 | 769 |
write_mask = mask16[mask]; |
770 |
((uint32_t *)s->vram_ptr)[addr] =
|
|
771 |
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
|
|
770 |
((uint32_t *)s->vram_ptr)[addr] = |
|
771 |
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | |
|
772 | 772 |
(val & write_mask); |
773 | 773 |
#ifdef DEBUG_VGA_MEM |
774 |
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", |
|
775 | 775 |
addr * 4, write_mask, val); |
776 | 776 |
#endif |
777 | 777 |
cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2)); |
... | ... | |
808 | 808 |
const uint8_t *font_ptr, int h, |
809 | 809 |
uint32_t fgcol, uint32_t bgcol); |
810 | 810 |
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize, |
811 |
const uint8_t *font_ptr, int h,
|
|
811 |
const uint8_t *font_ptr, int h, |
|
812 | 812 |
uint32_t fgcol, uint32_t bgcol, int dup9); |
813 |
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
|
|
813 |
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d, |
|
814 | 814 |
const uint8_t *s, int width); |
815 | 815 |
|
816 | 816 |
#define DEPTH 8 |
... | ... | |
909 | 909 |
else |
910 | 910 |
v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f); |
911 | 911 |
v = v * 3; |
912 |
col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
|
|
913 |
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]), |
|
914 | 914 |
c6_to_8(s->palette[v + 2])); |
915 | 915 |
if (col != palette[i]) { |
916 | 916 |
full_update = 1; |
... | ... | |
931 | 931 |
v = 0; |
932 | 932 |
for(i = 0; i < 256; i++) { |
933 | 933 |
if (s->dac_8bit) { |
934 |
col = s->rgb_to_pixel(s->palette[v],
|
|
935 |
s->palette[v + 1],
|
|
934 |
col = s->rgb_to_pixel(s->palette[v], |
|
935 |
s->palette[v + 1], |
|
936 | 936 |
s->palette[v + 2]); |
937 | 937 |
} else { |
938 |
col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
|
|
939 |
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]), |
|
940 | 940 |
c6_to_8(s->palette[v + 2])); |
941 | 941 |
} |
942 | 942 |
if (col != palette[i]) { |
... | ... | |
948 | 948 |
return full_update; |
949 | 949 |
} |
950 | 950 |
|
951 |
static void vga_get_offsets(VGAState *s,
|
|
952 |
uint32_t *pline_offset,
|
|
951 |
static void vga_get_offsets(VGAState *s, |
|
952 |
uint32_t *pline_offset, |
|
953 | 953 |
uint32_t *pstart_addr, |
954 | 954 |
uint32_t *pline_compare) |
955 | 955 |
{ |
... | ... | |
961 | 961 |
line_compare = 65535; |
962 | 962 |
} else |
963 | 963 |
#endif |
964 |
{
|
|
964 |
{ |
|
965 | 965 |
/* compute line_offset in bytes */ |
966 | 966 |
line_offset = s->cr[0x13]; |
967 | 967 |
line_offset <<= 3; |
... | ... | |
970 | 970 |
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); |
971 | 971 |
|
972 | 972 |
/* line compare */ |
973 |
line_compare = s->cr[0x18] |
|
|
973 |
line_compare = s->cr[0x18] | |
|
974 | 974 |
((s->cr[0x07] & 0x10) << 4) | |
975 | 975 |
((s->cr[0x09] & 0x40) << 3); |
976 | 976 |
} |
... | ... | |
984 | 984 |
{ |
985 | 985 |
int full_update; |
986 | 986 |
uint32_t start_addr, line_offset, line_compare; |
987 |
|
|
987 |
|
|
988 | 988 |
full_update = 0; |
989 | 989 |
|
990 | 990 |
s->get_offsets(s, &line_offset, &start_addr, &line_compare); |
... | ... | |
1055 | 1055 |
vga_draw_glyph9_16, |
1056 | 1056 |
vga_draw_glyph9_16, |
1057 | 1057 |
}; |
1058 |
|
|
1058 |
|
|
1059 | 1059 |
static const uint8_t cursor_glyph[32 * 4] = { |
1060 | 1060 |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
1061 | 1061 |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
... | ... | |
1073 | 1073 |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
1074 | 1074 |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
1075 | 1075 |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
1076 |
};
|
|
1076 |
}; |
|
1077 | 1077 |
|
1078 |
/*
|
|
1079 |
* Text mode update
|
|
1078 |
/* |
|
1079 |
* Text mode update |
|
1080 | 1080 |
* Missing: |
1081 | 1081 |
* - double scan |
1082 |
* - double width
|
|
1082 |
* - double width |
|
1083 | 1083 |
* - underline |
1084 | 1084 |
* - flashing |
1085 | 1085 |
*/ |
... | ... | |
1098 | 1098 |
|
1099 | 1099 |
full_update |= update_palette16(s); |
1100 | 1100 |
palette = s->last_palette; |
1101 |
|
|
1101 |
|
|
1102 | 1102 |
/* compute font data address (in plane 2) */ |
1103 | 1103 |
v = s->sr[3]; |
1104 | 1104 |
offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; |
... | ... | |
1138 | 1138 |
/* ugly hack for CGA 160x100x16 - explain me the logic */ |
1139 | 1139 |
height = 100; |
1140 | 1140 |
} else { |
1141 |
height = s->cr[0x12] |
|
|
1142 |
((s->cr[0x07] & 0x02) << 7) |
|
|
1141 |
height = s->cr[0x12] | |
|
1142 |
((s->cr[0x07] & 0x02) << 7) | |
|
1143 | 1143 |
((s->cr[0x07] & 0x40) << 3); |
1144 | 1144 |
height = (height + 1) / cheight; |
1145 | 1145 |
} |
... | ... | |
1174 | 1174 |
s->cursor_end = s->cr[0xb]; |
1175 | 1175 |
} |
1176 | 1176 |
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4; |
1177 |
|
|
1177 |
|
|
1178 | 1178 |
depth_index = get_depth_index(s->ds); |
1179 | 1179 |
if (cw == 16) |
1180 | 1180 |
vga_draw_glyph8 = vga_draw_glyph16_table[depth_index]; |
1181 | 1181 |
else |
1182 | 1182 |
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; |
1183 | 1183 |
vga_draw_glyph9 = vga_draw_glyph9_table[depth_index]; |
1184 |
|
|
1184 |
|
|
1185 | 1185 |
dest = s->ds->data; |
1186 | 1186 |
linesize = s->ds->linesize; |
1187 | 1187 |
ch_attr_ptr = s->last_ch_attr; |
... | ... | |
1210 | 1210 |
bgcol = palette[cattr >> 4]; |
1211 | 1211 |
fgcol = palette[cattr & 0x0f]; |
1212 | 1212 |
if (cw != 9) { |
1213 |
vga_draw_glyph8(d1, linesize,
|
|
1213 |
vga_draw_glyph8(d1, linesize, |
|
1214 | 1214 |
font_ptr, cheight, fgcol, bgcol); |
1215 | 1215 |
} else { |
1216 | 1216 |
dup9 = 0; |
1217 | 1217 |
if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04)) |
1218 | 1218 |
dup9 = 1; |
1219 |
vga_draw_glyph9(d1, linesize,
|
|
1219 |
vga_draw_glyph9(d1, linesize, |
|
1220 | 1220 |
font_ptr, cheight, fgcol, bgcol, dup9); |
1221 | 1221 |
} |
1222 | 1222 |
if (src == cursor_ptr && |
... | ... | |
1232 | 1232 |
h = line_last - line_start + 1; |
1233 | 1233 |
d = d1 + linesize * line_start; |
1234 | 1234 |
if (cw != 9) { |
1235 |
vga_draw_glyph8(d, linesize,
|
|
1235 |
vga_draw_glyph8(d, linesize, |
|
1236 | 1236 |
cursor_glyph, h, fgcol, bgcol); |
1237 | 1237 |
} else { |
1238 |
vga_draw_glyph9(d, linesize,
|
|
1238 |
vga_draw_glyph9(d, linesize, |
|
1239 | 1239 |
cursor_glyph, h, fgcol, bgcol, 1); |
1240 | 1240 |
} |
1241 | 1241 |
} |
... | ... | |
1246 | 1246 |
ch_attr_ptr++; |
1247 | 1247 |
} |
1248 | 1248 |
if (cx_max != -1) { |
1249 |
dpy_update(s->ds, cx_min * cw, cy * cheight,
|
|
1249 |
dpy_update(s->ds, cx_min * cw, cy * cheight, |
|
1250 | 1250 |
(cx_max - cx_min + 1) * cw, cheight); |
1251 | 1251 |
} |
1252 | 1252 |
dest += linesize * cheight; |
... | ... | |
1368 | 1368 |
#ifdef CONFIG_BOCHS_VBE |
1369 | 1369 |
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { |
1370 | 1370 |
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP]; |
1371 |
} else
|
|
1371 |
} else |
|
1372 | 1372 |
#endif |
1373 | 1373 |
{ |
1374 | 1374 |
ret = 0; |
... | ... | |
1379 | 1379 |
static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight) |
1380 | 1380 |
{ |
1381 | 1381 |
int width, height; |
1382 |
|
|
1382 |
|
|
1383 | 1383 |
#ifdef CONFIG_BOCHS_VBE |
1384 | 1384 |
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { |
1385 | 1385 |
width = s->vbe_regs[VBE_DISPI_INDEX_XRES]; |
1386 | 1386 |
height = s->vbe_regs[VBE_DISPI_INDEX_YRES]; |
1387 |
} else
|
|
1387 |
} else |
|
1388 | 1388 |
#endif |
1389 | 1389 |
{ |
1390 | 1390 |
width = (s->cr[0x01] + 1) * 8; |
1391 |
height = s->cr[0x12] |
|
|
1392 |
((s->cr[0x07] & 0x02) << 7) |
|
|
1391 |
height = s->cr[0x12] | |
|
1392 |
((s->cr[0x07] & 0x02) << 7) | |
|
1393 | 1393 |
((s->cr[0x07] & 0x40) << 3); |
1394 | 1394 |
height = (height + 1); |
1395 | 1395 |
} |
... | ... | |
1409 | 1409 |
} |
1410 | 1410 |
} |
1411 | 1411 |
|
1412 |
/*
|
|
1412 |
/* |
|
1413 | 1413 |
* graphic modes |
1414 | 1414 |
*/ |
1415 | 1415 |
static void vga_draw_graphic(VGAState *s, int full_update) |
... | ... | |
1420 | 1420 |
uint8_t *d; |
1421 | 1421 |
uint32_t v, addr1, addr; |
1422 | 1422 |
vga_draw_line_func *vga_draw_line; |
1423 |
|
|
1423 |
|
|
1424 | 1424 |
full_update |= update_basic_params(s); |
1425 | 1425 |
|
1426 | 1426 |
s->get_resolution(s, &width, &height); |
... | ... | |
1442 | 1442 |
s->shift_control = shift_control; |
1443 | 1443 |
s->double_scan = double_scan; |
1444 | 1444 |
} |
1445 |
|
|
1445 |
|
|
1446 | 1446 |
if (shift_control == 0) { |
1447 | 1447 |
full_update |= update_palette16(s); |
1448 | 1448 |
if (s->sr[0x01] & 8) { |
... | ... | |
1497 | 1497 |
} |
1498 | 1498 |
if (s->cursor_invalidate) |
1499 | 1499 |
s->cursor_invalidate(s); |
1500 |
|
|
1500 |
|
|
1501 | 1501 |
line_offset = s->line_offset; |
1502 | 1502 |
#if 0 |
1503 | 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", |
... | ... | |
1524 | 1524 |
} |
1525 | 1525 |
page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); |
1526 | 1526 |
page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); |
1527 |
update = full_update |
|
|
1527 |
update = full_update | |
|
1528 | 1528 |
cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | |
1529 | 1529 |
cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); |
1530 | 1530 |
if ((page1 - page0) > TARGET_PAGE_SIZE) { |
1531 | 1531 |
/* if wide line, can use another page */ |
1532 |
update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
|
|
1532 |
update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, |
|
1533 | 1533 |
VGA_DIRTY_FLAG); |
1534 | 1534 |
} |
1535 | 1535 |
/* explicit invalidation for the hardware cursor */ |
... | ... | |
1547 | 1547 |
} else { |
1548 | 1548 |
if (y_start >= 0) { |
1549 | 1549 |
/* flush to display */ |
1550 |
dpy_update(s->ds, 0, y_start,
|
|
1550 |
dpy_update(s->ds, 0, y_start, |
|
1551 | 1551 |
disp_width, y - y_start); |
1552 | 1552 |
y_start = -1; |
1553 | 1553 |
} |
... | ... | |
1568 | 1568 |
} |
1569 | 1569 |
if (y_start >= 0) { |
1570 | 1570 |
/* flush to display */ |
1571 |
dpy_update(s->ds, 0, y_start,
|
|
1571 |
dpy_update(s->ds, 0, y_start, |
|
1572 | 1572 |
disp_width, y - y_start); |
1573 | 1573 |
} |
1574 | 1574 |
/* reset modified pages */ |
... | ... | |
1588 | 1588 |
return; |
1589 | 1589 |
if (s->last_scr_width <= 0 || s->last_scr_height <= 0) |
1590 | 1590 |
return; |
1591 |
if (s->ds->depth == 8)
|
|
1591 |
if (s->ds->depth == 8) |
|
1592 | 1592 |
val = s->rgb_to_pixel(0, 0, 0); |
1593 | 1593 |
else |
1594 | 1594 |
val = 0; |
... | ... | |
1598 | 1598 |
memset(d, val, w); |
1599 | 1599 |
d += s->ds->linesize; |
1600 | 1600 |
} |
1601 |
dpy_update(s->ds, 0, 0,
|
|
1601 |
dpy_update(s->ds, 0, 0, |
|
1602 | 1602 |
s->last_scr_width, s->last_scr_height); |
1603 | 1603 |
} |
1604 | 1604 |
|
1605 | 1605 |
#define GMODE_TEXT 0 |
1606 | 1606 |
#define GMODE_GRAPH 1 |
1607 |
#define GMODE_BLANK 2
|
|
1607 |
#define GMODE_BLANK 2 |
|
1608 | 1608 |
|
1609 | 1609 |
static void vga_update_display(void *opaque) |
1610 | 1610 |
{ |
... | ... | |
1614 | 1614 |
if (s->ds->depth == 0) { |
1615 | 1615 |
/* nothing to do */ |
1616 | 1616 |
} else { |
1617 |
s->rgb_to_pixel =
|
|
1617 |
s->rgb_to_pixel = |
|
1618 | 1618 |
rgb_to_pixel_dup_table[get_depth_index(s->ds)]; |
1619 |
|
|
1619 |
|
|
1620 | 1620 |
full_update = 0; |
1621 | 1621 |
if (!(s->ar_index & 0x20)) { |
1622 | 1622 |
graphic_mode = GMODE_BLANK; |
... | ... | |
1646 | 1646 |
static void vga_invalidate_display(void *opaque) |
1647 | 1647 |
{ |
1648 | 1648 |
VGAState *s = (VGAState *)opaque; |
1649 |
|
|
1649 |
|
|
1650 | 1650 |
s->last_width = -1; |
1651 | 1651 |
s->last_height = -1; |
1652 | 1652 |
} |
... | ... | |
1775 | 1775 |
VGAState vga_state; |
1776 | 1776 |
} PCIVGAState; |
1777 | 1777 |
|
1778 |
static void vga_map(PCIDevice *pci_dev, int region_num,
|
|
1778 |
static void vga_map(PCIDevice *pci_dev, int region_num, |
|
1779 | 1779 |
uint32_t addr, uint32_t size, int type) |
1780 | 1780 |
{ |
1781 | 1781 |
PCIVGAState *d = (PCIVGAState *)pci_dev; |
... | ... | |
1787 | 1787 |
} |
1788 | 1788 |
} |
1789 | 1789 |
|
1790 |
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, |
|
1791 | 1791 |
unsigned long vga_ram_offset, int vga_ram_size) |
1792 | 1792 |
{ |
1793 | 1793 |
int i, j, v, b; |
... | ... | |
1866 | 1866 |
register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s); |
1867 | 1867 |
|
1868 | 1868 |
register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s); |
1869 |
register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
|
|
1869 |
register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s); |
|
1870 | 1870 |
#else |
1871 | 1871 |
register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s); |
1872 | 1872 |
register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s); |
... | ... | |
1877 | 1877 |
#endif /* CONFIG_BOCHS_VBE */ |
1878 | 1878 |
|
1879 | 1879 |
vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s); |
1880 |
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
|
|
1880 |
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, |
|
1881 | 1881 |
vga_io_memory); |
1882 | 1882 |
} |
1883 | 1883 |
|
... | ... | |
1956 | 1956 |
cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory); |
1957 | 1957 |
} |
1958 | 1958 |
|
1959 |
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
|
|
1959 |
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, |
|
1960 | 1960 |
unsigned long vga_ram_offset, int vga_ram_size) |
1961 | 1961 |
{ |
1962 | 1962 |
VGAState *s; |
... | ... | |
1972 | 1972 |
|
1973 | 1973 |
#ifdef CONFIG_BOCHS_VBE |
1974 | 1974 |
/* XXX: use optimized standard vga accesses */ |
1975 |
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
|
|
1975 |
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, |
|
1976 | 1976 |
vga_ram_size, vga_ram_offset); |
1977 | 1977 |
#endif |
1978 | 1978 |
return 0; |
... | ... | |
2002 | 2002 |
return 0; |
2003 | 2003 |
} |
2004 | 2004 |
|
2005 |
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, |
|
2006 | 2006 |
unsigned long vga_ram_offset, int vga_ram_size, |
2007 | 2007 |
unsigned long vga_bios_offset, int vga_bios_size) |
2008 | 2008 |
{ |
2009 | 2009 |
PCIVGAState *d; |
2010 | 2010 |
VGAState *s; |
2011 | 2011 |
uint8_t *pci_conf; |
2012 |
|
|
2013 |
d = (PCIVGAState *)pci_register_device(bus, "VGA",
|
|
2012 |
|
|
2013 |
d = (PCIVGAState *)pci_register_device(bus, "VGA", |
|
2014 | 2014 |
sizeof(PCIVGAState), |
2015 | 2015 |
-1, NULL, NULL); |
2016 | 2016 |
if (!d) |
2017 | 2017 |
return -1; |
2018 | 2018 |
s = &d->vga_state; |
2019 |
|
|
2019 |
|
|
2020 | 2020 |
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
2021 | 2021 |
vga_init(s); |
2022 | 2022 |
|
2023 | 2023 |
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s); |
2024 | 2024 |
|
2025 | 2025 |
s->pci_dev = &d->dev; |
2026 |
|
|
2026 |
|
|
2027 | 2027 |
pci_conf = d->dev.config; |
2028 | 2028 |
pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID) |
2029 | 2029 |
pci_conf[0x01] = 0x12; |
2030 | 2030 |
pci_conf[0x02] = 0x11; |
2031 | 2031 |
pci_conf[0x03] = 0x11; |
2032 |
pci_conf[0x0a] = 0x00; // VGA controller
|
|
2032 |
pci_conf[0x0a] = 0x00; // VGA controller |
|
2033 | 2033 |
pci_conf[0x0b] = 0x03; |
2034 | 2034 |
pci_conf[0x0e] = 0x00; // header_type |
2035 |
|
|
2035 |
|
|
2036 | 2036 |
/* XXX: vga_ram_size must be a power of two */ |
2037 |
pci_register_io_region(&d->dev, 0, vga_ram_size,
|
|
2037 |
pci_register_io_region(&d->dev, 0, vga_ram_size, |
|
2038 | 2038 |
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); |
2039 | 2039 |
if (vga_bios_size != 0) { |
2040 | 2040 |
unsigned int bios_total_size; |
... | ... | |
2044 | 2044 |
bios_total_size = 1; |
2045 | 2045 |
while (bios_total_size < vga_bios_size) |
2046 | 2046 |
bios_total_size <<= 1; |
2047 |
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, |
|
2048 | 2048 |
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); |
2049 | 2049 |
} |
2050 | 2050 |
return 0; |
... | ... | |
2055 | 2055 |
|
2056 | 2056 |
static int vga_save_w, vga_save_h; |
2057 | 2057 |
|
2058 |
static void vga_save_dpy_update(DisplayState *s,
|
|
2058 |
static void vga_save_dpy_update(DisplayState *s, |
|
2059 | 2059 |
int x, int y, int w, int h) |
2060 | 2060 |
{ |
2061 | 2061 |
} |
... | ... | |
2072 | 2072 |
{ |
2073 | 2073 |
} |
2074 | 2074 |
|
2075 |
int ppm_save(const char *filename, uint8_t *data,
|
|
2075 |
int ppm_save(const char *filename, uint8_t *data, |
|
2076 | 2076 |
int w, int h, int linesize) |
2077 | 2077 |
{ |
2078 | 2078 |
FILE *f; |
... | ... | |
2107 | 2107 |
{ |
2108 | 2108 |
VGAState *s = (VGAState *)opaque; |
2109 | 2109 |
DisplayState *saved_ds, ds1, *ds = &ds1; |
2110 |
|
|
2110 |
|
|
2111 | 2111 |
/* XXX: this is a little hackish */ |
2112 | 2112 |
vga_invalidate_display(s); |
2113 | 2113 |
saved_ds = s->ds; |
... | ... | |
2121 | 2121 |
s->ds = ds; |
2122 | 2122 |
s->graphic_mode = -1; |
2123 | 2123 |
vga_update_display(s); |
2124 |
|
|
2124 |
|
|
2125 | 2125 |
if (ds->data) { |
2126 |
ppm_save(filename, ds->data, vga_save_w, vga_save_h,
|
|
2126 |
ppm_save(filename, ds->data, vga_save_w, vga_save_h, |
|
2127 | 2127 |
s->ds->linesize); |
2128 | 2128 |
qemu_free(ds->data); |
2129 | 2129 |
} |
Also available in: Unified diff