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, | ... | ... |