mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-14 14:13:06 +00:00
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:
parent
e89f66eca9
commit
39cf780327
58
hw/vga.c
58
hw/vga.c
@ -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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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] = {
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user