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