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 | 4 | * Copyright (c) 2003 Fabrice Bellard |
| 5 | 5 | * |
| ... | ... | @@ -53,6 +53,8 @@ |
| 53 | 53 | //#define DEBUG_VGA_REG |
| 54 | 54 | |
| 55 | 55 | //#define DEBUG_S3 |
| 56 | +//#define DEBUG_BOCHS_VBE | |
| 57 | + | |
| 56 | 58 | #define CONFIG_S3VGA |
| 57 | 59 | |
| 58 | 60 | #define MSR_COLOR_EMULATION 0x01 |
| ... | ... | @@ -61,6 +63,35 @@ |
| 61 | 63 | #define ST01_V_RETRACE 0x08 |
| 62 | 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 | 95 | typedef struct VGAState { |
| 65 | 96 | uint8_t *vram_ptr; |
| 66 | 97 | unsigned long vram_offset; |
| ... | ... | @@ -85,7 +116,12 @@ typedef struct VGAState { |
| 85 | 116 | uint8_t dac_write_index; |
| 86 | 117 | uint8_t dac_cache[3]; /* used when writing */ |
| 87 | 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 | 125 | /* display refresh support */ |
| 90 | 126 | DisplayState *ds; |
| 91 | 127 | uint32_t font_offsets[2]; |
| ... | ... | @@ -101,7 +137,6 @@ typedef struct VGAState { |
| 101 | 137 | uint32_t cursor_offset; |
| 102 | 138 | unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned b); |
| 103 | 139 | /* tell for each page if it has been updated since the last time */ |
| 104 | - uint8_t vram_updated[VGA_RAM_SIZE / 4096]; | |
| 105 | 140 | uint32_t last_palette[256]; |
| 106 | 141 | #define CH_ATTR_SIZE (160 * 100) |
| 107 | 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 | 348 | break; |
| 314 | 349 | } |
| 315 | 350 | } |
| 316 | -#ifdef DEBUG_VGA | |
| 351 | +#if defined(DEBUG_VGA) | |
| 317 | 352 | printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); |
| 318 | 353 | #endif |
| 319 | 354 | return 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 | 622 | /* called for accesses between 0xa0000 and 0xc0000 */ |
| 472 | 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 | 695 | } |
| 545 | 696 | |
| 546 | 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 | 700 | VGAState *s = &vga_state; |
| 550 | 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 | 736 | #ifdef DEBUG_VGA_MEM |
| 586 | 737 | printf("vga: chain4: [0x%x]\n", addr); |
| 587 | 738 | #endif |
| 588 | - s->vram_updated[addr >> 12] = 1; | |
| 739 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); | |
| 589 | 740 | } |
| 590 | 741 | } else if (s->gr[5] & 0x10) { |
| 591 | 742 | /* odd/even mode (aka text mode mapping) */ |
| ... | ... | @@ -596,7 +747,7 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) |
| 596 | 747 | #ifdef DEBUG_VGA_MEM |
| 597 | 748 | printf("vga: odd/even: [0x%x]\n", addr); |
| 598 | 749 | #endif |
| 599 | - s->vram_updated[addr >> 12] = 1; | |
| 750 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); | |
| 600 | 751 | } |
| 601 | 752 | } else { |
| 602 | 753 | /* standard VGA latched access */ |
| ... | ... | @@ -668,22 +819,22 @@ void vga_mem_writeb(uint32_t addr, uint32_t val) |
| 668 | 819 | printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n", |
| 669 | 820 | addr * 4, write_mask, val); |
| 670 | 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 | 840 | typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, |
| ... | ... | @@ -823,22 +974,31 @@ static int update_basic_params(VGAState *s) |
| 823 | 974 | uint32_t start_addr, line_offset, line_compare, v; |
| 824 | 975 | |
| 825 | 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 | 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 | 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 | 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 | 999 | #endif |
| 841 | - | |
| 1000 | + } | |
| 1001 | + | |
| 842 | 1002 | /* line compare */ |
| 843 | 1003 | line_compare = s->cr[0x18] | |
| 844 | 1004 | ((s->cr[0x07] & 0x10) << 4) | |
| ... | ... | @@ -1086,6 +1246,7 @@ enum { |
| 1086 | 1246 | VGA_DRAW_LINE8, |
| 1087 | 1247 | VGA_DRAW_LINE15, |
| 1088 | 1248 | VGA_DRAW_LINE16, |
| 1249 | + VGA_DRAW_LINE24, | |
| 1089 | 1250 | VGA_DRAW_LINE32, |
| 1090 | 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 | 1292 | vga_draw_line16_16, |
| 1132 | 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 | 1300 | vga_draw_line32_8, |
| 1135 | 1301 | vga_draw_line32_15, |
| 1136 | 1302 | vga_draw_line32_16, |
| ... | ... | @@ -1193,8 +1359,33 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1193 | 1359 | v = VGA_DRAW_LINE2; |
| 1194 | 1360 | } |
| 1195 | 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 | 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 | 1421 | if (!(s->cr[0x17] & 2)) { |
| 1231 | 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 | 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 | 1432 | if (update) { |
| 1241 | 1433 | if (y_start < 0) |
| ... | ... | @@ -1278,7 +1470,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1278 | 1470 | } |
| 1279 | 1471 | /* reset modified pages */ |
| 1280 | 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 | 1612 | register_ioport_read(0x3ba, 1, vga_ioport_read, 1); |
| 1421 | 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 | 1624 | vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write); |
| 1424 | 1625 | #if defined (TARGET_I386) |
| 1425 | 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 | 1632 | #elif defined (TARGET_PPC) |
| 1427 | 1633 | cpu_register_physical_memory(0xf00a0000, 0x20000, vga_io_memory); |
| 1428 | 1634 | #endif | ... | ... |
hw/vga_template.h
| ... | ... | @@ -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 | 414 | * 32 bit color |
| 395 | 415 | */ |
| 396 | 416 | static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, | ... | ... |