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
This commit is contained in:
bellard 2003-08-05 23:06:22 +00:00
parent e89f66eca9
commit 39cf780327
2 changed files with 38 additions and 32 deletions

View File

@ -82,7 +82,6 @@ typedef struct VGAState {
uint8_t palette[768];
/* display refresh support */
/* tell for each page if it has been updated since the last time */
DisplayState *ds;
uint32_t font_offsets[2];
int graphic_mode;
@ -94,6 +93,7 @@ typedef struct VGAState {
uint32_t last_width, last_height;
uint8_t cursor_start, cursor_end;
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];
uint32_t last_palette[256];
#define CH_ATTR_SIZE (132 * 60)
@ -763,13 +763,7 @@ static int update_basic_params(VGAState *s)
v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
line_offset = s->cr[0x13] | (v << 8);
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 */
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
@ -917,7 +911,7 @@ static void vga_draw_text(VGAState *s, int full_update)
s->cursor_start = s->cr[0xa];
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);
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
@ -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)
{
int y, update, y_min, y_max, page_min, page_max, linesize;
int width, height, shift_control, line_offset, page0, page1;
int y, update, page_min, page_max, linesize, y_start;
int width, height, shift_control, line_offset, page0, page1, bwidth;
uint8_t *d;
uint32_t v, *palette, addr1, addr;
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
full_update |= update_palette16(s);
palette = s->last_palette;
full_update |= update_basic_params(s);
width = (s->cr[0x01] + 1);
width = (s->cr[0x01] + 1) * 8;
height = s->cr[0x12] |
((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3);
@ -1054,6 +1047,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
if (width != s->last_width ||
height != s->last_height) {
dpy_resize(s->ds, width, height);
s->last_width = width;
s->last_height = height;
full_update = 1;
@ -1066,44 +1060,52 @@ static void vga_draw_graphic(VGAState *s, int full_update)
}
if (shift_control == 0)
v = 1; /* 4 bit/pxeil */
v = 1; /* 4 bit/pixel */
else if (shift_control == 1)
v = 0; /* 2 bit/pixel */
else
v = 2; /* 8 bit/pixel */
vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
line_offset = s->line_offset;
addr1 = (s->start_addr * 4);
y_min = height;
y_max = -1;
bwidth = width * 4;
y_start = -1;
page_min = 0x7fffffff;
page_max = -1;
d = s->ds->data;
linesize = s->ds->linesize;
for(y = 0; y < height; y++) {
addr = addr1;
if (s->cr[0x17] & 1) {
if (!(s->cr[0x17] & 1)) {
/* CGA compatibility handling */
addr = (addr & ~0x2000) | ((y & 1) << 13);
}
if (s->cr[0x17] & 2) {
if (!(s->cr[0x17] & 2)) {
addr = (addr & ~0x4000) | ((y & 2) << 13);
}
page0 = addr >> 12;
page1 = (addr + width - 1) >> 12;
page1 = (addr + bwidth - 1) >> 12;
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 (y < y_min)
y_min = y;
if (y > y_max)
y_max = y;
if (y_start < 0)
y_start = y;
if (page0 < page_min)
page_min = page0;
if (page1 > page_max)
page_max = page1;
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) {
addr1 = 0;
@ -1112,7 +1114,11 @@ static void vga_draw_graphic(VGAState *s, int full_update)
}
d += linesize;
}
if (y_start >= 0) {
/* flush to display */
dpy_update(s->ds, 0, y_start,
width, y - y_start);
}
/* reset modified pages */
if (page_max != -1) {
memset(s->vram_updated + page_min, 0, page_max - page_min + 1);

View File

@ -84,9 +84,9 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
((uint32_t *)d)[3] = v;
if (dup9)
*(uint8_t *)(d + 8) = v >> (24 * (1 - BIG));
((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
else
*(uint8_t *)(d + 8) = bgcol;
((uint8_t *)d)[8] = bgcol;
#elif BPP == 2
((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,
v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
((uint32_t *)d)[3] = v;
if (dup9)
*(uint16_t *)(d + 8) = v >> (16 * (1 - BIG));
((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
else
*(uint16_t *)(d + 8) = bgcol;
((uint16_t *)d)[8] = bgcol;
#else
((uint32_t *)d)[0] = ((-(font_data >> 7)) & 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,
v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[7] = v;
if (dup9)
*(uint32_t *)(d + 8) = v;
((uint32_t *)d)[8] = v;
else
*(uint32_t *)(d + 8) = bgcol;
((uint32_t *)d)[8] = bgcol;
#endif
font_ptr += 4;
d += linesize;