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