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