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,7 +82,6 @@ typedef struct VGAState { | ||
82 | uint8_t palette[768]; | 82 | uint8_t palette[768]; |
83 | 83 | ||
84 | /* display refresh support */ | 84 | /* display refresh support */ |
85 | - /* tell for each page if it has been updated since the last time */ | ||
86 | DisplayState *ds; | 85 | DisplayState *ds; |
87 | uint32_t font_offsets[2]; | 86 | uint32_t font_offsets[2]; |
88 | int graphic_mode; | 87 | int graphic_mode; |
@@ -94,6 +93,7 @@ typedef struct VGAState { | @@ -94,6 +93,7 @@ typedef struct VGAState { | ||
94 | uint32_t last_width, last_height; | 93 | uint32_t last_width, last_height; |
95 | uint8_t cursor_start, cursor_end; | 94 | uint8_t cursor_start, cursor_end; |
96 | uint32_t cursor_offset; | 95 | uint32_t cursor_offset; |
96 | + /* tell for each page if it has been updated since the last time */ | ||
97 | uint8_t vram_updated[VGA_RAM_SIZE / 4096]; | 97 | uint8_t vram_updated[VGA_RAM_SIZE / 4096]; |
98 | uint32_t last_palette[256]; | 98 | uint32_t last_palette[256]; |
99 | #define CH_ATTR_SIZE (132 * 60) | 99 | #define CH_ATTR_SIZE (132 * 60) |
@@ -763,13 +763,7 @@ static int update_basic_params(VGAState *s) | @@ -763,13 +763,7 @@ static int update_basic_params(VGAState *s) | ||
763 | v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ | 763 | v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ |
764 | line_offset = s->cr[0x13] | (v << 8); | 764 | line_offset = s->cr[0x13] | (v << 8); |
765 | line_offset <<= 3; | 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 | /* starting address */ | 767 | /* starting address */ |
774 | start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); | 768 | start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); |
775 | start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */ | 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,7 +911,7 @@ static void vga_draw_text(VGAState *s, int full_update) | ||
917 | s->cursor_start = s->cr[0xa]; | 911 | s->cursor_start = s->cr[0xa]; |
918 | s->cursor_end = s->cr[0xb]; | 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 | depth_index = get_depth_index(s->ds->depth); | 916 | depth_index = get_depth_index(s->ds->depth); |
923 | vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; | 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,18 +1029,17 @@ static vga_draw_line_func *vga_draw_line_table[4 * 6] = { | ||
1035 | */ | 1029 | */ |
1036 | static void vga_draw_graphic(VGAState *s, int full_update) | 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 | uint8_t *d; | 1034 | uint8_t *d; |
1041 | - uint32_t v, *palette, addr1, addr; | 1035 | + uint32_t v, addr1, addr; |
1042 | vga_draw_line_func *vga_draw_line; | 1036 | vga_draw_line_func *vga_draw_line; |
1043 | 1037 | ||
1044 | full_update |= update_palette16(s); | 1038 | full_update |= update_palette16(s); |
1045 | - palette = s->last_palette; | ||
1046 | 1039 | ||
1047 | full_update |= update_basic_params(s); | 1040 | full_update |= update_basic_params(s); |
1048 | 1041 | ||
1049 | - width = (s->cr[0x01] + 1); | 1042 | + width = (s->cr[0x01] + 1) * 8; |
1050 | height = s->cr[0x12] | | 1043 | height = s->cr[0x12] | |
1051 | ((s->cr[0x07] & 0x02) << 7) | | 1044 | ((s->cr[0x07] & 0x02) << 7) | |
1052 | ((s->cr[0x07] & 0x40) << 3); | 1045 | ((s->cr[0x07] & 0x40) << 3); |
@@ -1054,6 +1047,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1054,6 +1047,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1054 | 1047 | ||
1055 | if (width != s->last_width || | 1048 | if (width != s->last_width || |
1056 | height != s->last_height) { | 1049 | height != s->last_height) { |
1050 | + dpy_resize(s->ds, width, height); | ||
1057 | s->last_width = width; | 1051 | s->last_width = width; |
1058 | s->last_height = height; | 1052 | s->last_height = height; |
1059 | full_update = 1; | 1053 | full_update = 1; |
@@ -1066,44 +1060,52 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1066,44 +1060,52 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1066 | } | 1060 | } |
1067 | 1061 | ||
1068 | if (shift_control == 0) | 1062 | if (shift_control == 0) |
1069 | - v = 1; /* 4 bit/pxeil */ | 1063 | + v = 1; /* 4 bit/pixel */ |
1070 | else if (shift_control == 1) | 1064 | else if (shift_control == 1) |
1071 | v = 0; /* 2 bit/pixel */ | 1065 | v = 0; /* 2 bit/pixel */ |
1072 | else | 1066 | else |
1073 | v = 2; /* 8 bit/pixel */ | 1067 | v = 2; /* 8 bit/pixel */ |
1074 | - | ||
1075 | vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; | 1068 | vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; |
1076 | 1069 | ||
1077 | line_offset = s->line_offset; | 1070 | line_offset = s->line_offset; |
1078 | addr1 = (s->start_addr * 4); | 1071 | addr1 = (s->start_addr * 4); |
1079 | - y_min = height; | ||
1080 | - y_max = -1; | 1072 | + bwidth = width * 4; |
1073 | + y_start = -1; | ||
1081 | page_min = 0x7fffffff; | 1074 | page_min = 0x7fffffff; |
1082 | page_max = -1; | 1075 | page_max = -1; |
1083 | d = s->ds->data; | 1076 | d = s->ds->data; |
1084 | linesize = s->ds->linesize; | 1077 | linesize = s->ds->linesize; |
1085 | for(y = 0; y < height; y++) { | 1078 | for(y = 0; y < height; y++) { |
1086 | addr = addr1; | 1079 | addr = addr1; |
1087 | - if (s->cr[0x17] & 1) { | 1080 | + if (!(s->cr[0x17] & 1)) { |
1088 | /* CGA compatibility handling */ | 1081 | /* CGA compatibility handling */ |
1089 | addr = (addr & ~0x2000) | ((y & 1) << 13); | 1082 | addr = (addr & ~0x2000) | ((y & 1) << 13); |
1090 | } | 1083 | } |
1091 | - if (s->cr[0x17] & 2) { | 1084 | + if (!(s->cr[0x17] & 2)) { |
1092 | addr = (addr & ~0x4000) | ((y & 2) << 13); | 1085 | addr = (addr & ~0x4000) | ((y & 2) << 13); |
1093 | } | 1086 | } |
1094 | page0 = addr >> 12; | 1087 | page0 = addr >> 12; |
1095 | - page1 = (addr + width - 1) >> 12; | 1088 | + page1 = (addr + bwidth - 1) >> 12; |
1096 | update = full_update | s->vram_updated[page0] | s->vram_updated[page1]; | 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 | if (update) { | 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 | if (page0 < page_min) | 1097 | if (page0 < page_min) |
1103 | page_min = page0; | 1098 | page_min = page0; |
1104 | if (page1 > page_max) | 1099 | if (page1 > page_max) |
1105 | page_max = page1; | 1100 | page_max = page1; |
1106 | vga_draw_line(s, d, s->vram_ptr + addr, width); | 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 | if (y == s->line_compare) { | 1110 | if (y == s->line_compare) { |
1109 | addr1 = 0; | 1111 | addr1 = 0; |
@@ -1112,7 +1114,11 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1112,7 +1114,11 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
1112 | } | 1114 | } |
1113 | d += linesize; | 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 | /* reset modified pages */ | 1122 | /* reset modified pages */ |
1117 | if (page_max != -1) { | 1123 | if (page_max != -1) { |
1118 | memset(s->vram_updated + page_min, 0, page_max - page_min + 1); | 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,9 +84,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, | ||
84 | v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; | 84 | v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; |
85 | ((uint32_t *)d)[3] = v; | 85 | ((uint32_t *)d)[3] = v; |
86 | if (dup9) | 86 | if (dup9) |
87 | - *(uint8_t *)(d + 8) = v >> (24 * (1 - BIG)); | 87 | + ((uint8_t *)d)[8] = v >> (24 * (1 - BIG)); |
88 | else | 88 | else |
89 | - *(uint8_t *)(d + 8) = bgcol; | 89 | + ((uint8_t *)d)[8] = bgcol; |
90 | 90 | ||
91 | #elif BPP == 2 | 91 | #elif BPP == 2 |
92 | ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; | 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,9 +95,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, | ||
95 | v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; | 95 | v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; |
96 | ((uint32_t *)d)[3] = v; | 96 | ((uint32_t *)d)[3] = v; |
97 | if (dup9) | 97 | if (dup9) |
98 | - *(uint16_t *)(d + 8) = v >> (16 * (1 - BIG)); | 98 | + ((uint16_t *)d)[8] = v >> (16 * (1 - BIG)); |
99 | else | 99 | else |
100 | - *(uint16_t *)(d + 8) = bgcol; | 100 | + ((uint16_t *)d)[8] = bgcol; |
101 | #else | 101 | #else |
102 | ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol; | 102 | ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol; |
103 | ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol; | 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,9 +109,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, | ||
109 | v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol; | 109 | v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol; |
110 | ((uint32_t *)d)[7] = v; | 110 | ((uint32_t *)d)[7] = v; |
111 | if (dup9) | 111 | if (dup9) |
112 | - *(uint32_t *)(d + 8) = v; | 112 | + ((uint32_t *)d)[8] = v; |
113 | else | 113 | else |
114 | - *(uint32_t *)(d + 8) = bgcol; | 114 | + ((uint32_t *)d)[8] = bgcol; |
115 | #endif | 115 | #endif |
116 | font_ptr += 4; | 116 | font_ptr += 4; |
117 | d += linesize; | 117 | d += linesize; |