Commit 4fa0f5d292add0d53554eb02351a78b18af8985d
1 parent
1ccde1cb
added bochs VBE support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@602 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
263 additions
and
37 deletions
hw/vga.c
1 | /* | 1 | /* |
2 | - * QEMU VGA Emulator. An S3 86c968 is emulated | 2 | + * QEMU VGA Emulator. |
3 | * | 3 | * |
4 | * Copyright (c) 2003 Fabrice Bellard | 4 | * Copyright (c) 2003 Fabrice Bellard |
5 | * | 5 | * |
@@ -53,6 +53,8 @@ | @@ -53,6 +53,8 @@ | ||
53 | //#define DEBUG_VGA_REG | 53 | //#define DEBUG_VGA_REG |
54 | 54 | ||
55 | //#define DEBUG_S3 | 55 | //#define DEBUG_S3 |
56 | +//#define DEBUG_BOCHS_VBE | ||
57 | + | ||
56 | #define CONFIG_S3VGA | 58 | #define CONFIG_S3VGA |
57 | 59 | ||
58 | #define MSR_COLOR_EMULATION 0x01 | 60 | #define MSR_COLOR_EMULATION 0x01 |
@@ -61,6 +63,35 @@ | @@ -61,6 +63,35 @@ | ||
61 | #define ST01_V_RETRACE 0x08 | 63 | #define ST01_V_RETRACE 0x08 |
62 | #define ST01_DISP_ENABLE 0x01 | 64 | #define ST01_DISP_ENABLE 0x01 |
63 | 65 | ||
66 | +/* bochs VBE support */ | ||
67 | +#define CONFIG_BOCHS_VBE | ||
68 | + | ||
69 | +#define VBE_DISPI_MAX_XRES 1024 | ||
70 | +#define VBE_DISPI_MAX_YRES 768 | ||
71 | + | ||
72 | +#define VBE_DISPI_INDEX_ID 0x0 | ||
73 | +#define VBE_DISPI_INDEX_XRES 0x1 | ||
74 | +#define VBE_DISPI_INDEX_YRES 0x2 | ||
75 | +#define VBE_DISPI_INDEX_BPP 0x3 | ||
76 | +#define VBE_DISPI_INDEX_ENABLE 0x4 | ||
77 | +#define VBE_DISPI_INDEX_BANK 0x5 | ||
78 | +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 | ||
79 | +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 | ||
80 | +#define VBE_DISPI_INDEX_X_OFFSET 0x8 | ||
81 | +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 | ||
82 | +#define VBE_DISPI_INDEX_NB 0xa | ||
83 | + | ||
84 | +#define VBE_DISPI_ID0 0xB0C0 | ||
85 | +#define VBE_DISPI_ID1 0xB0C1 | ||
86 | +#define VBE_DISPI_ID2 0xB0C2 | ||
87 | + | ||
88 | +#define VBE_DISPI_DISABLED 0x00 | ||
89 | +#define VBE_DISPI_ENABLED 0x01 | ||
90 | +#define VBE_DISPI_LFB_ENABLED 0x40 | ||
91 | +#define VBE_DISPI_NOCLEARMEM 0x80 | ||
92 | + | ||
93 | +#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 | ||
94 | + | ||
64 | typedef struct VGAState { | 95 | typedef struct VGAState { |
65 | uint8_t *vram_ptr; | 96 | uint8_t *vram_ptr; |
66 | unsigned long vram_offset; | 97 | unsigned long vram_offset; |
@@ -85,7 +116,12 @@ typedef struct VGAState { | @@ -85,7 +116,12 @@ typedef struct VGAState { | ||
85 | uint8_t dac_write_index; | 116 | uint8_t dac_write_index; |
86 | uint8_t dac_cache[3]; /* used when writing */ | 117 | uint8_t dac_cache[3]; /* used when writing */ |
87 | uint8_t palette[768]; | 118 | uint8_t palette[768]; |
88 | - | 119 | +#ifdef CONFIG_BOCHS_VBE |
120 | + uint16_t vbe_index; | ||
121 | + uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; | ||
122 | + uint32_t vbe_start_addr; | ||
123 | + uint32_t vbe_line_offset; | ||
124 | +#endif | ||
89 | /* display refresh support */ | 125 | /* display refresh support */ |
90 | DisplayState *ds; | 126 | DisplayState *ds; |
91 | uint32_t font_offsets[2]; | 127 | uint32_t font_offsets[2]; |
@@ -101,7 +137,6 @@ typedef struct VGAState { | @@ -101,7 +137,6 @@ typedef struct VGAState { | ||
101 | uint32_t cursor_offset; | 137 | uint32_t cursor_offset; |
102 | unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned b); | 138 | unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned b); |
103 | /* tell for each page if it has been updated since the last time */ | 139 | /* tell for each page if it has been updated since the last time */ |
104 | - uint8_t vram_updated[VGA_RAM_SIZE / 4096]; | ||
105 | uint32_t last_palette[256]; | 140 | uint32_t last_palette[256]; |
106 | #define CH_ATTR_SIZE (160 * 100) | 141 | #define CH_ATTR_SIZE (160 * 100) |
107 | uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ | 142 | uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ |
@@ -313,7 +348,7 @@ static uint32_t vga_ioport_read(CPUState *env, uint32_t addr) | @@ -313,7 +348,7 @@ static uint32_t vga_ioport_read(CPUState *env, uint32_t addr) | ||
313 | break; | 348 | break; |
314 | } | 349 | } |
315 | } | 350 | } |
316 | -#ifdef DEBUG_VGA | 351 | +#if defined(DEBUG_VGA) |
317 | printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); | 352 | printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); |
318 | #endif | 353 | #endif |
319 | return val; | 354 | return val; |
@@ -468,6 +503,122 @@ static void vga_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -468,6 +503,122 @@ static void vga_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | ||
468 | } | 503 | } |
469 | } | 504 | } |
470 | 505 | ||
506 | +#ifdef CONFIG_BOCHS_VBE | ||
507 | +static uint32_t vbe_ioport_read(CPUState *env, uint32_t addr) | ||
508 | +{ | ||
509 | + VGAState *s = &vga_state; | ||
510 | + uint32_t val; | ||
511 | + | ||
512 | + addr &= 1; | ||
513 | + if (addr == 0) { | ||
514 | + val = s->vbe_index; | ||
515 | + } else { | ||
516 | + if (s->vbe_index <= VBE_DISPI_INDEX_NB) | ||
517 | + val = s->vbe_regs[s->vbe_index]; | ||
518 | + else | ||
519 | + val = 0; | ||
520 | +#ifdef DEBUG_BOCHS_VBE | ||
521 | + printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val); | ||
522 | +#endif | ||
523 | + } | ||
524 | + return val; | ||
525 | +} | ||
526 | + | ||
527 | +static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | ||
528 | +{ | ||
529 | + VGAState *s = &vga_state; | ||
530 | + | ||
531 | + addr &= 1; | ||
532 | + if (addr == 0) { | ||
533 | + s->vbe_index = val; | ||
534 | + } else if (s->vbe_index <= VBE_DISPI_INDEX_NB) { | ||
535 | +#ifdef DEBUG_BOCHS_VBE | ||
536 | + printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val); | ||
537 | +#endif | ||
538 | + switch(s->vbe_index) { | ||
539 | + case VBE_DISPI_INDEX_ID: | ||
540 | + if (val != VBE_DISPI_ID0 && | ||
541 | + val != VBE_DISPI_ID1 && | ||
542 | + val != VBE_DISPI_ID2) | ||
543 | + return; | ||
544 | + break; | ||
545 | + case VBE_DISPI_INDEX_XRES: | ||
546 | + if ((val > VBE_DISPI_MAX_XRES) || ((val & 7) != 0)) | ||
547 | + return; | ||
548 | + break; | ||
549 | + case VBE_DISPI_INDEX_YRES: | ||
550 | + if (val > VBE_DISPI_MAX_YRES) | ||
551 | + return; | ||
552 | + break; | ||
553 | + case VBE_DISPI_INDEX_BPP: | ||
554 | + if (val == 0) | ||
555 | + val = 8; | ||
556 | + if (val != 4 && val != 8 && val != 15 && | ||
557 | + val != 16 && val != 24 && val != 32) | ||
558 | + return; | ||
559 | + break; | ||
560 | + case VBE_DISPI_INDEX_BANK: | ||
561 | + val &= 0xff; | ||
562 | + break; | ||
563 | + case VBE_DISPI_INDEX_ENABLE: | ||
564 | + if (val & VBE_DISPI_ENABLED) { | ||
565 | + int h, shift_control; | ||
566 | + | ||
567 | + s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = | ||
568 | + s->vbe_regs[VBE_DISPI_INDEX_XRES]; | ||
569 | + s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = | ||
570 | + s->vbe_regs[VBE_DISPI_INDEX_YRES]; | ||
571 | + s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; | ||
572 | + s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; | ||
573 | + | ||
574 | + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) | ||
575 | + s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1; | ||
576 | + else | ||
577 | + s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * | ||
578 | + ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); | ||
579 | + s->vbe_start_addr = 0; | ||
580 | + | ||
581 | + /* clear the screen (should be done in BIOS) */ | ||
582 | + if (!(val & VBE_DISPI_NOCLEARMEM)) { | ||
583 | + memset(s->vram_ptr, 0, | ||
584 | + s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); | ||
585 | + } | ||
586 | + | ||
587 | + /* we initialize graphic mode force graphic mode | ||
588 | + (should be done in BIOS) */ | ||
589 | + s->gr[6] |= 1; | ||
590 | + s->cr[0x17] |= 3; /* no CGA modes */ | ||
591 | + s->cr[0x13] = s->vbe_line_offset >> 3; | ||
592 | + /* width */ | ||
593 | + s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; | ||
594 | + /* height */ | ||
595 | + h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; | ||
596 | + s->cr[0x12] = h; | ||
597 | + s->cr[0x07] = (s->cr[0x07] & ~0x42) | | ||
598 | + ((h >> 7) & 0x02) | ((h >> 3) & 0x40); | ||
599 | + /* line compare to 1023 */ | ||
600 | + s->cr[0x18] = 0xff; | ||
601 | + s->cr[0x07] |= 0x10; | ||
602 | + s->cr[0x09] |= 0x40; | ||
603 | + | ||
604 | + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { | ||
605 | + shift_control = 0; | ||
606 | + s->sr[0x01] &= ~8; /* no double line */ | ||
607 | + } else { | ||
608 | + shift_control = 2; | ||
609 | + } | ||
610 | + s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5); | ||
611 | + s->cr[0x09] &= ~0x9f; /* no double scan */ | ||
612 | + } | ||
613 | + break; | ||
614 | + default: | ||
615 | + break; | ||
616 | + } | ||
617 | + s->vbe_regs[s->vbe_index] = val; | ||
618 | + } | ||
619 | +} | ||
620 | +#endif | ||
621 | + | ||
471 | /* called for accesses between 0xa0000 and 0xc0000 */ | 622 | /* called for accesses between 0xa0000 and 0xc0000 */ |
472 | static uint32_t vga_mem_readb(uint32_t addr) | 623 | static uint32_t vga_mem_readb(uint32_t addr) |
473 | { | 624 | { |
@@ -544,7 +695,7 @@ static uint32_t vga_mem_readl(uint32_t addr) | @@ -544,7 +695,7 @@ static uint32_t vga_mem_readl(uint32_t addr) | ||
544 | } | 695 | } |
545 | 696 | ||
546 | /* called for accesses between 0xa0000 and 0xc0000 */ | 697 | /* called for accesses between 0xa0000 and 0xc0000 */ |
547 | -void vga_mem_writeb(uint32_t addr, uint32_t val) | 698 | +void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) |
548 | { | 699 | { |
549 | VGAState *s = &vga_state; | 700 | VGAState *s = &vga_state; |
550 | int memory_map_mode, plane, write_mode, b, func_select; | 701 | int memory_map_mode, plane, write_mode, b, func_select; |
@@ -585,7 +736,7 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | @@ -585,7 +736,7 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | ||
585 | #ifdef DEBUG_VGA_MEM | 736 | #ifdef DEBUG_VGA_MEM |
586 | printf("vga: chain4: [0x%x]\n", addr); | 737 | printf("vga: chain4: [0x%x]\n", addr); |
587 | #endif | 738 | #endif |
588 | - s->vram_updated[addr >> 12] = 1; | 739 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); |
589 | } | 740 | } |
590 | } else if (s->gr[5] & 0x10) { | 741 | } else if (s->gr[5] & 0x10) { |
591 | /* odd/even mode (aka text mode mapping) */ | 742 | /* odd/even mode (aka text mode mapping) */ |
@@ -596,7 +747,7 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | @@ -596,7 +747,7 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | ||
596 | #ifdef DEBUG_VGA_MEM | 747 | #ifdef DEBUG_VGA_MEM |
597 | printf("vga: odd/even: [0x%x]\n", addr); | 748 | printf("vga: odd/even: [0x%x]\n", addr); |
598 | #endif | 749 | #endif |
599 | - s->vram_updated[addr >> 12] = 1; | 750 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); |
600 | } | 751 | } |
601 | } else { | 752 | } else { |
602 | /* standard VGA latched access */ | 753 | /* standard VGA latched access */ |
@@ -668,22 +819,22 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | @@ -668,22 +819,22 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) | ||
668 | printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n", | 819 | printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n", |
669 | addr * 4, write_mask, val); | 820 | addr * 4, write_mask, val); |
670 | #endif | 821 | #endif |
671 | - s->vram_updated[addr >> 10] = 1; | 822 | + cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2)); |
672 | } | 823 | } |
673 | } | 824 | } |
674 | 825 | ||
675 | -void vga_mem_writew(uint32_t addr, uint32_t val) | 826 | +void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr) |
676 | { | 827 | { |
677 | - vga_mem_writeb(addr, val & 0xff); | ||
678 | - vga_mem_writeb(addr + 1, (val >> 8) & 0xff); | 828 | + vga_mem_writeb(addr, val & 0xff, vaddr); |
829 | + vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); | ||
679 | } | 830 | } |
680 | 831 | ||
681 | -void vga_mem_writel(uint32_t addr, uint32_t val) | 832 | +void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr) |
682 | { | 833 | { |
683 | - vga_mem_writeb(addr, val & 0xff); | ||
684 | - vga_mem_writeb(addr + 1, (val >> 8) & 0xff); | ||
685 | - vga_mem_writeb(addr + 2, (val >> 16) & 0xff); | ||
686 | - vga_mem_writeb(addr + 3, (val >> 24) & 0xff); | 834 | + vga_mem_writeb(addr, val & 0xff, vaddr); |
835 | + vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); | ||
836 | + vga_mem_writeb(addr + 2, (val >> 16) & 0xff, vaddr); | ||
837 | + vga_mem_writeb(addr + 3, (val >> 24) & 0xff, vaddr); | ||
687 | } | 838 | } |
688 | 839 | ||
689 | typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, | 840 | typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, |
@@ -823,22 +974,31 @@ static int update_basic_params(VGAState *s) | @@ -823,22 +974,31 @@ static int update_basic_params(VGAState *s) | ||
823 | uint32_t start_addr, line_offset, line_compare, v; | 974 | uint32_t start_addr, line_offset, line_compare, v; |
824 | 975 | ||
825 | full_update = 0; | 976 | full_update = 0; |
826 | - /* compute line_offset in bytes */ | ||
827 | - line_offset = s->cr[0x13]; | 977 | + |
978 | +#ifdef CONFIG_BOCHS_VBE | ||
979 | + if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { | ||
980 | + line_offset = s->vbe_line_offset; | ||
981 | + start_addr = s->vbe_start_addr; | ||
982 | + } else | ||
983 | +#endif | ||
984 | + { | ||
985 | + /* compute line_offset in bytes */ | ||
986 | + line_offset = s->cr[0x13]; | ||
828 | #ifdef CONFIG_S3VGA | 987 | #ifdef CONFIG_S3VGA |
829 | - v = (s->cr[0x51] >> 4) & 3; /* S3 extension */ | ||
830 | - if (v == 0) | ||
831 | - v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ | ||
832 | - line_offset |= (v << 8); | 988 | + v = (s->cr[0x51] >> 4) & 3; /* S3 extension */ |
989 | + if (v == 0) | ||
990 | + v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ | ||
991 | + line_offset |= (v << 8); | ||
833 | #endif | 992 | #endif |
834 | - line_offset <<= 3; | ||
835 | - | ||
836 | - /* starting address */ | ||
837 | - start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); | 993 | + line_offset <<= 3; |
994 | + | ||
995 | + /* starting address */ | ||
996 | + start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); | ||
838 | #ifdef CONFIG_S3VGA | 997 | #ifdef CONFIG_S3VGA |
839 | - start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */ | 998 | + start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */ |
840 | #endif | 999 | #endif |
841 | - | 1000 | + } |
1001 | + | ||
842 | /* line compare */ | 1002 | /* line compare */ |
843 | line_compare = s->cr[0x18] | | 1003 | line_compare = s->cr[0x18] | |
844 | ((s->cr[0x07] & 0x10) << 4) | | 1004 | ((s->cr[0x07] & 0x10) << 4) | |
@@ -1086,6 +1246,7 @@ enum { | @@ -1086,6 +1246,7 @@ enum { | ||
1086 | VGA_DRAW_LINE8, | 1246 | VGA_DRAW_LINE8, |
1087 | VGA_DRAW_LINE15, | 1247 | VGA_DRAW_LINE15, |
1088 | VGA_DRAW_LINE16, | 1248 | VGA_DRAW_LINE16, |
1249 | + VGA_DRAW_LINE24, | ||
1089 | VGA_DRAW_LINE32, | 1250 | VGA_DRAW_LINE32, |
1090 | VGA_DRAW_LINE_NB, | 1251 | VGA_DRAW_LINE_NB, |
1091 | }; | 1252 | }; |
@@ -1131,6 +1292,11 @@ static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = { | @@ -1131,6 +1292,11 @@ static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = { | ||
1131 | vga_draw_line16_16, | 1292 | vga_draw_line16_16, |
1132 | vga_draw_line16_32, | 1293 | vga_draw_line16_32, |
1133 | 1294 | ||
1295 | + vga_draw_line24_8, | ||
1296 | + vga_draw_line24_15, | ||
1297 | + vga_draw_line24_16, | ||
1298 | + vga_draw_line24_32, | ||
1299 | + | ||
1134 | vga_draw_line32_8, | 1300 | vga_draw_line32_8, |
1135 | vga_draw_line32_15, | 1301 | vga_draw_line32_15, |
1136 | vga_draw_line32_16, | 1302 | vga_draw_line32_16, |
@@ -1193,8 +1359,33 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1193,8 +1359,33 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1193 | v = VGA_DRAW_LINE2; | 1359 | v = VGA_DRAW_LINE2; |
1194 | } | 1360 | } |
1195 | } else { | 1361 | } else { |
1196 | - full_update |= update_palette256(s); | ||
1197 | - v = VGA_DRAW_LINE8D2; | 1362 | +#ifdef CONFIG_BOCHS_VBE |
1363 | + if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { | ||
1364 | + switch(s->vbe_regs[VBE_DISPI_INDEX_BPP]) { | ||
1365 | + default: | ||
1366 | + case 8: | ||
1367 | + full_update |= update_palette256(s); | ||
1368 | + v = VGA_DRAW_LINE8; | ||
1369 | + break; | ||
1370 | + case 15: | ||
1371 | + v = VGA_DRAW_LINE15; | ||
1372 | + break; | ||
1373 | + case 16: | ||
1374 | + v = VGA_DRAW_LINE16; | ||
1375 | + break; | ||
1376 | + case 24: | ||
1377 | + v = VGA_DRAW_LINE24; | ||
1378 | + break; | ||
1379 | + case 32: | ||
1380 | + v = VGA_DRAW_LINE32; | ||
1381 | + break; | ||
1382 | + } | ||
1383 | + } else | ||
1384 | +#endif | ||
1385 | + { | ||
1386 | + full_update |= update_palette256(s); | ||
1387 | + v = VGA_DRAW_LINE8D2; | ||
1388 | + } | ||
1198 | } | 1389 | } |
1199 | vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; | 1390 | vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; |
1200 | 1391 | ||
@@ -1230,12 +1421,13 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1230,12 +1421,13 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1230 | if (!(s->cr[0x17] & 2)) { | 1421 | if (!(s->cr[0x17] & 2)) { |
1231 | addr = (addr & ~0x8000) | ((y1 & 2) << 14); | 1422 | addr = (addr & ~0x8000) | ((y1 & 2) << 14); |
1232 | } | 1423 | } |
1233 | - page0 = addr >> 12; | ||
1234 | - page1 = (addr + bwidth - 1) >> 12; | ||
1235 | - update = full_update | s->vram_updated[page0] | s->vram_updated[page1]; | ||
1236 | - if ((page1 - page0) > 1) { | 1424 | + page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); |
1425 | + page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); | ||
1426 | + update = full_update | cpu_physical_memory_is_dirty(page0) | | ||
1427 | + cpu_physical_memory_is_dirty(page1); | ||
1428 | + if ((page1 - page0) > TARGET_PAGE_SIZE) { | ||
1237 | /* if wide line, can use another page */ | 1429 | /* if wide line, can use another page */ |
1238 | - update |= s->vram_updated[page0 + 1]; | 1430 | + update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE); |
1239 | } | 1431 | } |
1240 | if (update) { | 1432 | if (update) { |
1241 | if (y_start < 0) | 1433 | if (y_start < 0) |
@@ -1278,7 +1470,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1278,7 +1470,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1278 | } | 1470 | } |
1279 | /* reset modified pages */ | 1471 | /* reset modified pages */ |
1280 | if (page_max != -1) { | 1472 | if (page_max != -1) { |
1281 | - memset(s->vram_updated + page_min, 0, page_max - page_min + 1); | 1473 | + cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); |
1282 | } | 1474 | } |
1283 | } | 1475 | } |
1284 | 1476 | ||
@@ -1420,9 +1612,23 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | @@ -1420,9 +1612,23 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | ||
1420 | register_ioport_read(0x3ba, 1, vga_ioport_read, 1); | 1612 | register_ioport_read(0x3ba, 1, vga_ioport_read, 1); |
1421 | register_ioport_read(0x3da, 1, vga_ioport_read, 1); | 1613 | register_ioport_read(0x3da, 1, vga_ioport_read, 1); |
1422 | 1614 | ||
1615 | +#ifdef CONFIG_BOCHS_VBE | ||
1616 | + s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0; | ||
1617 | + register_ioport_read(0x1ce, 1, vbe_ioport_read, 2); | ||
1618 | + register_ioport_read(0x1cf, 1, vbe_ioport_read, 2); | ||
1619 | + | ||
1620 | + register_ioport_write(0x1ce, 1, vbe_ioport_write, 2); | ||
1621 | + register_ioport_write(0x1cf, 1, vbe_ioport_write, 2); | ||
1622 | +#endif | ||
1623 | + | ||
1423 | vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write); | 1624 | vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write); |
1424 | #if defined (TARGET_I386) | 1625 | #if defined (TARGET_I386) |
1425 | cpu_register_physical_memory(0x000a0000, 0x20000, vga_io_memory); | 1626 | cpu_register_physical_memory(0x000a0000, 0x20000, vga_io_memory); |
1627 | +#ifdef CONFIG_BOCHS_VBE | ||
1628 | + /* XXX: use optimized standard vga accesses */ | ||
1629 | + cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, | ||
1630 | + vga_ram_size, vga_ram_offset); | ||
1631 | +#endif | ||
1426 | #elif defined (TARGET_PPC) | 1632 | #elif defined (TARGET_PPC) |
1427 | cpu_register_physical_memory(0xf00a0000, 0x20000, vga_io_memory); | 1633 | cpu_register_physical_memory(0xf00a0000, 0x20000, vga_io_memory); |
1428 | #endif | 1634 | #endif |
hw/vga_template.h
@@ -391,6 +391,26 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, | @@ -391,6 +391,26 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, | ||
391 | } | 391 | } |
392 | 392 | ||
393 | /* | 393 | /* |
394 | + * 24 bit color | ||
395 | + */ | ||
396 | +static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, | ||
397 | + const uint8_t *s, int width) | ||
398 | +{ | ||
399 | + int w; | ||
400 | + uint32_t r, g, b; | ||
401 | + | ||
402 | + w = width; | ||
403 | + do { | ||
404 | + b = s[0]; | ||
405 | + g = s[1]; | ||
406 | + r = s[2]; | ||
407 | + ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b); | ||
408 | + s += 3; | ||
409 | + d += BPP; | ||
410 | + } while (--w != 0); | ||
411 | +} | ||
412 | + | ||
413 | +/* | ||
394 | * 32 bit color | 414 | * 32 bit color |
395 | */ | 415 | */ |
396 | static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, | 416 | static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, |
vl.h
@@ -72,7 +72,7 @@ struct cow_header_v2 { | @@ -72,7 +72,7 @@ struct cow_header_v2 { | ||
72 | 72 | ||
73 | /* vga.c */ | 73 | /* vga.c */ |
74 | 74 | ||
75 | -#define VGA_RAM_SIZE (8192 * 1024) | 75 | +#define VGA_RAM_SIZE (4096 * 1024) |
76 | 76 | ||
77 | typedef struct DisplayState { | 77 | typedef struct DisplayState { |
78 | uint8_t *data; | 78 | uint8_t *data; |