提交 39cf7803 编写于 作者: B bellard

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
上级 e89f66ec
...@@ -82,7 +82,6 @@ typedef struct VGAState { ...@@ -82,7 +82,6 @@ typedef struct VGAState {
uint8_t palette[768]; uint8_t palette[768];
/* display refresh support */ /* display refresh support */
/* tell for each page if it has been updated since the last time */
DisplayState *ds; DisplayState *ds;
uint32_t font_offsets[2]; uint32_t font_offsets[2];
int graphic_mode; int graphic_mode;
...@@ -94,6 +93,7 @@ typedef struct VGAState { ...@@ -94,6 +93,7 @@ typedef struct VGAState {
uint32_t last_width, last_height; uint32_t last_width, last_height;
uint8_t cursor_start, cursor_end; uint8_t cursor_start, cursor_end;
uint32_t cursor_offset; uint32_t cursor_offset;
/* tell for each page if it has been updated since the last time */
uint8_t vram_updated[VGA_RAM_SIZE / 4096]; uint8_t vram_updated[VGA_RAM_SIZE / 4096];
uint32_t last_palette[256]; uint32_t last_palette[256];
#define CH_ATTR_SIZE (132 * 60) #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)
v = (s->cr[0x43] >> 2) & 1; /* S3 extension */ v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
line_offset = s->cr[0x13] | (v << 8); line_offset = s->cr[0x13] | (v << 8);
line_offset <<= 3; line_offset <<= 3;
#if 0
/* XXX: check this - inconsistent with some VGA docs */
if (s->cr[0x14] & 0x40)
line_offset <<= 2;
else if (!(s->cr[0x17] & 0x40))
line_offset <<= 1;
#endif
/* starting address */ /* starting address */
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8); start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */ 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)
s->cursor_start = s->cr[0xa]; s->cursor_start = s->cr[0xa];
s->cursor_end = s->cr[0xb]; s->cursor_end = s->cr[0xb];
} }
cursor_ptr = s->vram_ptr + cursor_offset * 4; cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
depth_index = get_depth_index(s->ds->depth); depth_index = get_depth_index(s->ds->depth);
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; 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] = {
*/ */
static void vga_draw_graphic(VGAState *s, int full_update) static void vga_draw_graphic(VGAState *s, int full_update)
{ {
int y, update, y_min, y_max, page_min, page_max, linesize; int y, update, page_min, page_max, linesize, y_start;
int width, height, shift_control, line_offset, page0, page1; int width, height, shift_control, line_offset, page0, page1, bwidth;
uint8_t *d; uint8_t *d;
uint32_t v, *palette, addr1, addr; uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line; vga_draw_line_func *vga_draw_line;
full_update |= update_palette16(s); full_update |= update_palette16(s);
palette = s->last_palette;
full_update |= update_basic_params(s); full_update |= update_basic_params(s);
width = (s->cr[0x01] + 1); width = (s->cr[0x01] + 1) * 8;
height = s->cr[0x12] | height = s->cr[0x12] |
((s->cr[0x07] & 0x02) << 7) | ((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3); ((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)
if (width != s->last_width || if (width != s->last_width ||
height != s->last_height) { height != s->last_height) {
dpy_resize(s->ds, width, height);
s->last_width = width; s->last_width = width;
s->last_height = height; s->last_height = height;
full_update = 1; 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)
} }
if (shift_control == 0) if (shift_control == 0)
v = 1; /* 4 bit/pxeil */ v = 1; /* 4 bit/pixel */
else if (shift_control == 1) else if (shift_control == 1)
v = 0; /* 2 bit/pixel */ v = 0; /* 2 bit/pixel */
else else
v = 2; /* 8 bit/pixel */ v = 2; /* 8 bit/pixel */
vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
line_offset = s->line_offset; line_offset = s->line_offset;
addr1 = (s->start_addr * 4); addr1 = (s->start_addr * 4);
y_min = height; bwidth = width * 4;
y_max = -1; y_start = -1;
page_min = 0x7fffffff; page_min = 0x7fffffff;
page_max = -1; page_max = -1;
d = s->ds->data; d = s->ds->data;
linesize = s->ds->linesize; linesize = s->ds->linesize;
for(y = 0; y < height; y++) { for(y = 0; y < height; y++) {
addr = addr1; addr = addr1;
if (s->cr[0x17] & 1) { if (!(s->cr[0x17] & 1)) {
/* CGA compatibility handling */ /* CGA compatibility handling */
addr = (addr & ~0x2000) | ((y & 1) << 13); addr = (addr & ~0x2000) | ((y & 1) << 13);
} }
if (s->cr[0x17] & 2) { if (!(s->cr[0x17] & 2)) {
addr = (addr & ~0x4000) | ((y & 2) << 13); addr = (addr & ~0x4000) | ((y & 2) << 13);
} }
page0 = addr >> 12; page0 = addr >> 12;
page1 = (addr + width - 1) >> 12; page1 = (addr + bwidth - 1) >> 12;
update = full_update | s->vram_updated[page0] | s->vram_updated[page1]; update = full_update | s->vram_updated[page0] | s->vram_updated[page1];
if ((page1 - page0) > 1) {
/* if wide line, can use another page */
update |= s->vram_updated[page0 + 1];
}
if (update) { if (update) {
if (y < y_min) if (y_start < 0)
y_min = y; y_start = y;
if (y > y_max)
y_max = y;
if (page0 < page_min) if (page0 < page_min)
page_min = page0; page_min = page0;
if (page1 > page_max) if (page1 > page_max)
page_max = page1; page_max = page1;
vga_draw_line(s, d, s->vram_ptr + addr, width); vga_draw_line(s, d, s->vram_ptr + addr, width);
} else {
if (y_start >= 0) {
/* flush to display */
dpy_update(s->ds, 0, y_start,
width, y - y_start);
y_start = -1;
}
} }
if (y == s->line_compare) { if (y == s->line_compare) {
addr1 = 0; 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)
} }
d += linesize; d += linesize;
} }
if (y_start >= 0) {
/* flush to display */
dpy_update(s->ds, 0, y_start,
width, y - y_start);
}
/* reset modified pages */ /* reset modified pages */
if (page_max != -1) { if (page_max != -1) {
memset(s->vram_updated + page_min, 0, page_max - page_min + 1); memset(s->vram_updated + page_min, 0, page_max - page_min + 1);
......
...@@ -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,
v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
((uint32_t *)d)[3] = v; ((uint32_t *)d)[3] = v;
if (dup9) if (dup9)
*(uint8_t *)(d + 8) = v >> (24 * (1 - BIG)); ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
else else
*(uint8_t *)(d + 8) = bgcol; ((uint8_t *)d)[8] = bgcol;
#elif BPP == 2 #elif BPP == 2
((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; ((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,
v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
((uint32_t *)d)[3] = v; ((uint32_t *)d)[3] = v;
if (dup9) if (dup9)
*(uint16_t *)(d + 8) = v >> (16 * (1 - BIG)); ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
else else
*(uint16_t *)(d + 8) = bgcol; ((uint16_t *)d)[8] = bgcol;
#else #else
((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol; ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol;
((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol; ((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,
v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol; v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[7] = v; ((uint32_t *)d)[7] = v;
if (dup9) if (dup9)
*(uint32_t *)(d + 8) = v; ((uint32_t *)d)[8] = v;
else else
*(uint32_t *)(d + 8) = bgcol; ((uint32_t *)d)[8] = bgcol;
#endif #endif
font_ptr += 4; font_ptr += 4;
d += linesize; d += linesize;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册