Commit 39cf7803273871207ec06a0d162e181998ccc384

Authored by bellard
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;