vga: implement horizontal pel panning in graphics modes
This implements smooth scrolling, as used for example by Commander Keen and Second Reality. Unfortunately, this is not enough to avoid tearing in Commander Keen, because sometimes the wrong start address is used for a frame. On real EGA, the panning register is sampled on every line, while the display start is latched for the next frame at the start of the vertical retrace. On real VGA, the panning register is also latched, but at the end of the vertical retrace. It looks like Keen exploits this by only waiting for horizontal retrace when setting the display start, but implementing it breaks the 256-color Keen games... Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9b53b95a1c
commit
973a724eb0
@ -43,6 +43,7 @@
|
|||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "ui/pixel_ops.h"
|
#include "ui/pixel_ops.h"
|
||||||
|
#include "vga_regs.h"
|
||||||
#include "cirrus_vga_internal.h"
|
#include "cirrus_vga_internal.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
@ -1121,6 +1122,9 @@ static void cirrus_get_params(VGACommonState *s1,
|
|||||||
params->line_compare = s->vga.cr[0x18] |
|
params->line_compare = s->vga.cr[0x18] |
|
||||||
((s->vga.cr[0x07] & 0x10) << 4) |
|
((s->vga.cr[0x07] & 0x10) << 4) |
|
||||||
((s->vga.cr[0x09] & 0x40) << 3);
|
((s->vga.cr[0x09] & 0x40) << 3);
|
||||||
|
|
||||||
|
params->hpel = s->vga.ar[VGA_ATC_PEL];
|
||||||
|
params->hpel_split = s->vga.ar[VGA_ATC_MODE] & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
|
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
|
||||||
|
@ -98,14 +98,19 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
|
|||||||
/*
|
/*
|
||||||
* 4 color mode
|
* 4 color mode
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line2(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t plane_mask, *palette, data, v;
|
uint32_t plane_mask, *palette, data, v;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||||
|
hpel &= 7;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
||||||
@ -126,6 +131,7 @@ static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 32;
|
d += 32;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 4 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PUT_PIXEL2(d, n, v) \
|
#define PUT_PIXEL2(d, n, v) \
|
||||||
@ -134,14 +140,19 @@ static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
|
|||||||
/*
|
/*
|
||||||
* 4 color mode, dup2 horizontal
|
* 4 color mode, dup2 horizontal
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t plane_mask, *palette, data, v;
|
uint32_t plane_mask, *palette, data, v;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||||
|
hpel &= 7;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
||||||
@ -162,19 +173,25 @@ static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 64;
|
d += 64;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 8 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 16 color mode
|
* 16 color mode
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line4(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t plane_mask, data, v, *palette;
|
uint32_t plane_mask, data, v, *palette;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||||
|
hpel &= 7;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
||||||
@ -194,19 +211,25 @@ static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 32;
|
d += 32;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 4 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 16 color mode, dup2 horizontal
|
* 16 color mode, dup2 horizontal
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t plane_mask, data, v, *palette;
|
uint32_t plane_mask, data, v, *palette;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||||
|
hpel &= 7;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
|
||||||
@ -226,6 +249,7 @@ static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 64;
|
d += 64;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 8 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -233,13 +257,18 @@ static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
|
|||||||
*
|
*
|
||||||
* XXX: add plane_mask support (never used in standard VGA modes)
|
* XXX: add plane_mask support (never used in standard VGA modes)
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t *palette;
|
uint32_t *palette;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
|
hpel = (hpel >> 1) & 3;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
addr &= VGA_VRAM_SIZE - 1;
|
addr &= VGA_VRAM_SIZE - 1;
|
||||||
@ -250,6 +279,7 @@ static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 32;
|
d += 32;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 8 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -257,13 +287,18 @@ static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
|
|||||||
*
|
*
|
||||||
* XXX: add plane_mask support (never used in standard VGA modes)
|
* XXX: add plane_mask support (never used in standard VGA modes)
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line8(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
uint32_t *palette;
|
uint32_t *palette;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
palette = vga->last_palette;
|
palette = vga->last_palette;
|
||||||
|
hpel = (hpel >> 1) & 3;
|
||||||
|
if (hpel) {
|
||||||
|
width += 8;
|
||||||
|
d = vga->panning_buf;
|
||||||
|
}
|
||||||
width >>= 3;
|
width >>= 3;
|
||||||
for(x = 0; x < width; x++) {
|
for(x = 0; x < width; x++) {
|
||||||
((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
|
((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
|
||||||
@ -277,13 +312,14 @@ static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
|
|||||||
d += 32;
|
d += 32;
|
||||||
addr += 8;
|
addr += 8;
|
||||||
}
|
}
|
||||||
|
return hpel ? vga->panning_buf + 4 * hpel : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 15 bit color
|
* 15 bit color
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t v, r, g, b;
|
uint32_t v, r, g, b;
|
||||||
@ -298,10 +334,11 @@ static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 2;
|
addr += 2;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t v, r, g, b;
|
uint32_t v, r, g, b;
|
||||||
@ -316,13 +353,14 @@ static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 2;
|
addr += 2;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 16 bit color
|
* 16 bit color
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t v, r, g, b;
|
uint32_t v, r, g, b;
|
||||||
@ -337,10 +375,11 @@ static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 2;
|
addr += 2;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t v, r, g, b;
|
uint32_t v, r, g, b;
|
||||||
@ -355,13 +394,14 @@ static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 2;
|
addr += 2;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 24 bit color
|
* 24 bit color
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t r, g, b;
|
uint32_t r, g, b;
|
||||||
@ -375,10 +415,11 @@ static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 3;
|
addr += 3;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t r, g, b;
|
uint32_t r, g, b;
|
||||||
@ -392,13 +433,14 @@ static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 3;
|
addr += 3;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 32 bit color
|
* 32 bit color
|
||||||
*/
|
*/
|
||||||
static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t r, g, b;
|
uint32_t r, g, b;
|
||||||
@ -412,10 +454,11 @@ static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 4;
|
addr += 4;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
|
static void *vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
|
||||||
uint32_t addr, int width)
|
uint32_t addr, int width, int hpel)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
uint32_t r, g, b;
|
uint32_t r, g, b;
|
||||||
@ -429,4 +472,5 @@ static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
|
|||||||
addr += 4;
|
addr += 4;
|
||||||
d += 4;
|
d += 4;
|
||||||
} while (--w != 0);
|
} while (--w != 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,13 @@ bool have_vga = true;
|
|||||||
/* Address mask for non-VESA modes. */
|
/* Address mask for non-VESA modes. */
|
||||||
#define VGA_VRAM_SIZE (256 * KiB)
|
#define VGA_VRAM_SIZE (256 * KiB)
|
||||||
|
|
||||||
|
/* This value corresponds to a shift of zero pixels
|
||||||
|
* in 9-dot text mode. In other modes, bit 3 is undefined;
|
||||||
|
* we just ignore it, so that 8 corresponds to zero pixels
|
||||||
|
* in all modes.
|
||||||
|
*/
|
||||||
|
#define VGA_HPEL_NEUTRAL 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Video Graphics Array (VGA)
|
* Video Graphics Array (VGA)
|
||||||
*
|
*
|
||||||
@ -984,8 +991,8 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
|
typedef void *vga_draw_line_func(VGACommonState *s1, uint8_t *d,
|
||||||
uint32_t srcaddr, int width);
|
uint32_t srcaddr, int width, int hpel);
|
||||||
|
|
||||||
#include "vga-access.h"
|
#include "vga-access.h"
|
||||||
#include "vga-helpers.h"
|
#include "vga-helpers.h"
|
||||||
@ -1052,6 +1059,8 @@ static void vga_get_params(VGACommonState *s,
|
|||||||
params->line_offset = s->vbe_line_offset;
|
params->line_offset = s->vbe_line_offset;
|
||||||
params->start_addr = s->vbe_start_addr;
|
params->start_addr = s->vbe_start_addr;
|
||||||
params->line_compare = 65535;
|
params->line_compare = 65535;
|
||||||
|
params->hpel = VGA_HPEL_NEUTRAL;
|
||||||
|
params->hpel_split = false;
|
||||||
} else {
|
} else {
|
||||||
/* compute line_offset in bytes */
|
/* compute line_offset in bytes */
|
||||||
params->line_offset = s->cr[VGA_CRTC_OFFSET] << 3;
|
params->line_offset = s->cr[VGA_CRTC_OFFSET] << 3;
|
||||||
@ -1064,6 +1073,9 @@ static void vga_get_params(VGACommonState *s,
|
|||||||
params->line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
|
params->line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
|
||||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
|
((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
|
||||||
((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
|
((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
|
||||||
|
|
||||||
|
params->hpel = s->ar[VGA_ATC_PEL];
|
||||||
|
params->hpel_split = s->ar[VGA_ATC_MODE] & 0x20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1435,6 +1447,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||||||
ram_addr_t page0, page1, region_start, region_end;
|
ram_addr_t page0, page1, region_start, region_end;
|
||||||
DirtyBitmapSnapshot *snap = NULL;
|
DirtyBitmapSnapshot *snap = NULL;
|
||||||
int disp_width, multi_scan, multi_run;
|
int disp_width, multi_scan, multi_run;
|
||||||
|
int hpel;
|
||||||
uint8_t *d;
|
uint8_t *d;
|
||||||
uint32_t v, addr1, addr;
|
uint32_t v, addr1, addr;
|
||||||
vga_draw_line_func *vga_draw_line = NULL;
|
vga_draw_line_func *vga_draw_line = NULL;
|
||||||
@ -1534,6 +1547,9 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||||||
s->last_line_offset = s->params.line_offset;
|
s->last_line_offset = s->params.line_offset;
|
||||||
s->last_depth = depth;
|
s->last_depth = depth;
|
||||||
s->last_byteswap = byteswap;
|
s->last_byteswap = byteswap;
|
||||||
|
/* 16 extra pixels are needed for double-width planar modes. */
|
||||||
|
s->panning_buf = g_realloc(s->panning_buf,
|
||||||
|
(disp_width + 16) * sizeof(uint32_t));
|
||||||
full_update = 1;
|
full_update = 1;
|
||||||
}
|
}
|
||||||
if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4)
|
if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4)
|
||||||
@ -1613,8 +1629,12 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||||||
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
|
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
|
||||||
s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
|
s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
|
||||||
#endif
|
#endif
|
||||||
|
hpel = bits <= 8 ? s->params.hpel : 0;
|
||||||
addr1 = (s->params.start_addr * 4);
|
addr1 = (s->params.start_addr * 4);
|
||||||
bwidth = DIV_ROUND_UP(width * bits, 8);
|
bwidth = DIV_ROUND_UP(width * bits, 8);
|
||||||
|
if (hpel) {
|
||||||
|
bwidth += 4;
|
||||||
|
}
|
||||||
y_start = -1;
|
y_start = -1;
|
||||||
d = surface_data(surface);
|
d = surface_data(surface);
|
||||||
linesize = surface_stride(surface);
|
linesize = surface_stride(surface);
|
||||||
@ -1662,7 +1682,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||||||
if (y_start < 0)
|
if (y_start < 0)
|
||||||
y_start = y;
|
y_start = y;
|
||||||
if (!(is_buffer_shared(surface))) {
|
if (!(is_buffer_shared(surface))) {
|
||||||
vga_draw_line(s, d, addr, width);
|
uint8_t *p;
|
||||||
|
p = vga_draw_line(s, d, addr, width, hpel);
|
||||||
|
if (p) {
|
||||||
|
memcpy(d, p, disp_width * sizeof(uint32_t));
|
||||||
|
}
|
||||||
if (s->cursor_draw_line)
|
if (s->cursor_draw_line)
|
||||||
s->cursor_draw_line(s, d, y);
|
s->cursor_draw_line(s, d, y);
|
||||||
}
|
}
|
||||||
@ -1684,8 +1708,12 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||||||
multi_run--;
|
multi_run--;
|
||||||
}
|
}
|
||||||
/* line compare acts on the displayed lines */
|
/* line compare acts on the displayed lines */
|
||||||
if (y == s->params.line_compare)
|
if (y == s->params.line_compare) {
|
||||||
|
if (s->params.hpel_split) {
|
||||||
|
hpel = VGA_HPEL_NEUTRAL;
|
||||||
|
}
|
||||||
addr1 = 0;
|
addr1 = 0;
|
||||||
|
}
|
||||||
d += linesize;
|
d += linesize;
|
||||||
}
|
}
|
||||||
if (y_start >= 0) {
|
if (y_start >= 0) {
|
||||||
|
@ -60,6 +60,8 @@ typedef struct VGADisplayParams {
|
|||||||
uint32_t line_offset;
|
uint32_t line_offset;
|
||||||
uint32_t start_addr;
|
uint32_t start_addr;
|
||||||
uint32_t line_compare;
|
uint32_t line_compare;
|
||||||
|
uint8_t hpel;
|
||||||
|
bool hpel_split;
|
||||||
} VGADisplayParams;
|
} VGADisplayParams;
|
||||||
|
|
||||||
typedef struct VGACommonState {
|
typedef struct VGACommonState {
|
||||||
@ -111,6 +113,7 @@ typedef struct VGACommonState {
|
|||||||
/* display refresh support */
|
/* display refresh support */
|
||||||
QemuConsole *con;
|
QemuConsole *con;
|
||||||
uint32_t font_offsets[2];
|
uint32_t font_offsets[2];
|
||||||
|
uint8_t *panning_buf;
|
||||||
int graphic_mode;
|
int graphic_mode;
|
||||||
uint8_t shift_control;
|
uint8_t shift_control;
|
||||||
uint8_t double_scan;
|
uint8_t double_scan;
|
||||||
|
Loading…
Reference in New Issue
Block a user