Commit 39cf7803273871207ec06a0d162e181998ccc384
1 parent
e89f66ec
fixed graphical VGA 16 color mode - fixed 9 pixel wide text mode
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@345 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
38 additions
and
32 deletions
hw/vga.c
| ... | ... | @@ -82,7 +82,6 @@ typedef struct VGAState { |
| 82 | 82 | uint8_t palette[768]; |
| 83 | 83 | |
| 84 | 84 | /* display refresh support */ |
| 85 | - /* tell for each page if it has been updated since the last time */ | |
| 86 | 85 | DisplayState *ds; |
| 87 | 86 | uint32_t font_offsets[2]; |
| 88 | 87 | int graphic_mode; |
| ... | ... | @@ -94,6 +93,7 @@ typedef struct VGAState { |
| 94 | 93 | uint32_t last_width, last_height; |
| 95 | 94 | uint8_t cursor_start, cursor_end; |
| 96 | 95 | uint32_t cursor_offset; |
| 96 | + /* tell for each page if it has been updated since the last time */ | |
| 97 | 97 | uint8_t vram_updated[VGA_RAM_SIZE / 4096]; |
| 98 | 98 | uint32_t last_palette[256]; |
| 99 | 99 | #define CH_ATTR_SIZE (132 * 60) |
| ... | ... | @@ -763,13 +763,7 @@ static int update_basic_params(VGAState *s) |
| 763 | 763 | v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ |
| 764 | 764 | line_offset = s->cr[0x13] | (v << 8); |
| 765 | 765 | line_offset <<= 3; |
| 766 | -#if 0 | |
| 767 | - /* XXX: check this - inconsistent with some VGA docs */ | |
| 768 | - if (s->cr[0x14] & 0x40) | |
| 769 | - line_offset <<= 2; | |
| 770 | - else if (!(s->cr[0x17] & 0x40)) | |
| 771 | - line_offset <<= 1; | |
| 772 | -#endif | |
| 766 | + | |
| 773 | 767 | /* starting address */ |
| 774 | 768 | start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); |
| 775 | 769 | start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */ |
| ... | ... | @@ -917,7 +911,7 @@ static void vga_draw_text(VGAState *s, int full_update) |
| 917 | 911 | s->cursor_start = s->cr[0xa]; |
| 918 | 912 | s->cursor_end = s->cr[0xb]; |
| 919 | 913 | } |
| 920 | - cursor_ptr = s->vram_ptr + cursor_offset * 4; | |
| 914 | + cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4; | |
| 921 | 915 | |
| 922 | 916 | depth_index = get_depth_index(s->ds->depth); |
| 923 | 917 | vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; |
| ... | ... | @@ -1035,18 +1029,17 @@ static vga_draw_line_func *vga_draw_line_table[4 * 6] = { |
| 1035 | 1029 | */ |
| 1036 | 1030 | static void vga_draw_graphic(VGAState *s, int full_update) |
| 1037 | 1031 | { |
| 1038 | - int y, update, y_min, y_max, page_min, page_max, linesize; | |
| 1039 | - int width, height, shift_control, line_offset, page0, page1; | |
| 1032 | + int y, update, page_min, page_max, linesize, y_start; | |
| 1033 | + int width, height, shift_control, line_offset, page0, page1, bwidth; | |
| 1040 | 1034 | uint8_t *d; |
| 1041 | - uint32_t v, *palette, addr1, addr; | |
| 1035 | + uint32_t v, addr1, addr; | |
| 1042 | 1036 | vga_draw_line_func *vga_draw_line; |
| 1043 | 1037 | |
| 1044 | 1038 | full_update |= update_palette16(s); |
| 1045 | - palette = s->last_palette; | |
| 1046 | 1039 | |
| 1047 | 1040 | full_update |= update_basic_params(s); |
| 1048 | 1041 | |
| 1049 | - width = (s->cr[0x01] + 1); | |
| 1042 | + width = (s->cr[0x01] + 1) * 8; | |
| 1050 | 1043 | height = s->cr[0x12] | |
| 1051 | 1044 | ((s->cr[0x07] & 0x02) << 7) | |
| 1052 | 1045 | ((s->cr[0x07] & 0x40) << 3); |
| ... | ... | @@ -1054,6 +1047,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1054 | 1047 | |
| 1055 | 1048 | if (width != s->last_width || |
| 1056 | 1049 | height != s->last_height) { |
| 1050 | + dpy_resize(s->ds, width, height); | |
| 1057 | 1051 | s->last_width = width; |
| 1058 | 1052 | s->last_height = height; |
| 1059 | 1053 | full_update = 1; |
| ... | ... | @@ -1066,44 +1060,52 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1066 | 1060 | } |
| 1067 | 1061 | |
| 1068 | 1062 | if (shift_control == 0) |
| 1069 | - v = 1; /* 4 bit/pxeil */ | |
| 1063 | + v = 1; /* 4 bit/pixel */ | |
| 1070 | 1064 | else if (shift_control == 1) |
| 1071 | 1065 | v = 0; /* 2 bit/pixel */ |
| 1072 | 1066 | else |
| 1073 | 1067 | v = 2; /* 8 bit/pixel */ |
| 1074 | - | |
| 1075 | 1068 | vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; |
| 1076 | 1069 | |
| 1077 | 1070 | line_offset = s->line_offset; |
| 1078 | 1071 | addr1 = (s->start_addr * 4); |
| 1079 | - y_min = height; | |
| 1080 | - y_max = -1; | |
| 1072 | + bwidth = width * 4; | |
| 1073 | + y_start = -1; | |
| 1081 | 1074 | page_min = 0x7fffffff; |
| 1082 | 1075 | page_max = -1; |
| 1083 | 1076 | d = s->ds->data; |
| 1084 | 1077 | linesize = s->ds->linesize; |
| 1085 | 1078 | for(y = 0; y < height; y++) { |
| 1086 | 1079 | addr = addr1; |
| 1087 | - if (s->cr[0x17] & 1) { | |
| 1080 | + if (!(s->cr[0x17] & 1)) { | |
| 1088 | 1081 | /* CGA compatibility handling */ |
| 1089 | 1082 | addr = (addr & ~0x2000) | ((y & 1) << 13); |
| 1090 | 1083 | } |
| 1091 | - if (s->cr[0x17] & 2) { | |
| 1084 | + if (!(s->cr[0x17] & 2)) { | |
| 1092 | 1085 | addr = (addr & ~0x4000) | ((y & 2) << 13); |
| 1093 | 1086 | } |
| 1094 | 1087 | page0 = addr >> 12; |
| 1095 | - page1 = (addr + width - 1) >> 12; | |
| 1088 | + page1 = (addr + bwidth - 1) >> 12; | |
| 1096 | 1089 | update = full_update | s->vram_updated[page0] | s->vram_updated[page1]; |
| 1090 | + if ((page1 - page0) > 1) { | |
| 1091 | + /* if wide line, can use another page */ | |
| 1092 | + update |= s->vram_updated[page0 + 1]; | |
| 1093 | + } | |
| 1097 | 1094 | if (update) { |
| 1098 | - if (y < y_min) | |
| 1099 | - y_min = y; | |
| 1100 | - if (y > y_max) | |
| 1101 | - y_max = y; | |
| 1095 | + if (y_start < 0) | |
| 1096 | + y_start = y; | |
| 1102 | 1097 | if (page0 < page_min) |
| 1103 | 1098 | page_min = page0; |
| 1104 | 1099 | if (page1 > page_max) |
| 1105 | 1100 | page_max = page1; |
| 1106 | 1101 | vga_draw_line(s, d, s->vram_ptr + addr, width); |
| 1102 | + } else { | |
| 1103 | + if (y_start >= 0) { | |
| 1104 | + /* flush to display */ | |
| 1105 | + dpy_update(s->ds, 0, y_start, | |
| 1106 | + width, y - y_start); | |
| 1107 | + y_start = -1; | |
| 1108 | + } | |
| 1107 | 1109 | } |
| 1108 | 1110 | if (y == s->line_compare) { |
| 1109 | 1111 | addr1 = 0; |
| ... | ... | @@ -1112,7 +1114,11 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1112 | 1114 | } |
| 1113 | 1115 | d += linesize; |
| 1114 | 1116 | } |
| 1115 | - | |
| 1117 | + if (y_start >= 0) { | |
| 1118 | + /* flush to display */ | |
| 1119 | + dpy_update(s->ds, 0, y_start, | |
| 1120 | + width, y - y_start); | |
| 1121 | + } | |
| 1116 | 1122 | /* reset modified pages */ |
| 1117 | 1123 | if (page_max != -1) { |
| 1118 | 1124 | memset(s->vram_updated + page_min, 0, page_max - page_min + 1); | ... | ... |
hw/vga_template.h
| ... | ... | @@ -84,9 +84,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, |
| 84 | 84 | v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; |
| 85 | 85 | ((uint32_t *)d)[3] = v; |
| 86 | 86 | if (dup9) |
| 87 | - *(uint8_t *)(d + 8) = v >> (24 * (1 - BIG)); | |
| 87 | + ((uint8_t *)d)[8] = v >> (24 * (1 - BIG)); | |
| 88 | 88 | else |
| 89 | - *(uint8_t *)(d + 8) = bgcol; | |
| 89 | + ((uint8_t *)d)[8] = bgcol; | |
| 90 | 90 | |
| 91 | 91 | #elif BPP == 2 |
| 92 | 92 | ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; |
| ... | ... | @@ -95,9 +95,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, |
| 95 | 95 | v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; |
| 96 | 96 | ((uint32_t *)d)[3] = v; |
| 97 | 97 | if (dup9) |
| 98 | - *(uint16_t *)(d + 8) = v >> (16 * (1 - BIG)); | |
| 98 | + ((uint16_t *)d)[8] = v >> (16 * (1 - BIG)); | |
| 99 | 99 | else |
| 100 | - *(uint16_t *)(d + 8) = bgcol; | |
| 100 | + ((uint16_t *)d)[8] = bgcol; | |
| 101 | 101 | #else |
| 102 | 102 | ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol; |
| 103 | 103 | ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol; |
| ... | ... | @@ -109,9 +109,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, |
| 109 | 109 | v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol; |
| 110 | 110 | ((uint32_t *)d)[7] = v; |
| 111 | 111 | if (dup9) |
| 112 | - *(uint32_t *)(d + 8) = v; | |
| 112 | + ((uint32_t *)d)[8] = v; | |
| 113 | 113 | else |
| 114 | - *(uint32_t *)(d + 8) = bgcol; | |
| 114 | + ((uint32_t *)d)[8] = bgcol; | |
| 115 | 115 | #endif |
| 116 | 116 | font_ptr += 4; |
| 117 | 117 | d += linesize; | ... | ... |