From: Paolo Bonzini <bonzini@gnu.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 1/3] vga: mask addresses in non-VESA modes to 256k
Date: Sat, 8 Aug 2015 15:11:07 +0200 [thread overview]
Message-ID: <1439039469-438-2-git-send-email-bonzini@gnu.org> (raw)
In-Reply-To: <1439039469-438-1-git-send-email-bonzini@gnu.org>
This allows setting the start address to a high value, and reading the
bottom of the screen from the beginning of VRAM. Commander Keen 4
("Goodbye, Galaxy!") relies on this behavior.
Signed-off-by: Paolo Bonzini <bonzini@gnu.org>
---
hw/display/vga-helpers.h | 52 ++++++++++++++++++++++++++++++------------------
hw/display/vga.c | 7 +++++--
2 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h
index 94f6de2..ae61890 100644
--- a/hw/display/vga-helpers.h
+++ b/hw/display/vga-helpers.h
@@ -99,7 +99,7 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
* 4 color mode
*/
static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
uint32_t plane_mask, *palette, data, v;
int x;
@@ -108,6 +108,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
+ const uint8_t *s = s1->vram_ptr + (addr & (VGA_VRAM_SIZE - 1));
data = ((uint32_t *)s)[0];
data &= plane_mask;
v = expand2[GET_PLANE(data, 0)];
@@ -124,7 +125,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
- s += 4;
+ addr += 4;
}
}
@@ -135,7 +136,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
* 4 color mode, dup2 horizontal
*/
static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
uint32_t plane_mask, *palette, data, v;
int x;
@@ -144,6 +145,7 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
+ const uint8_t *s = s1->vram_ptr + (addr & (VGA_VRAM_SIZE - 1));
data = ((uint32_t *)s)[0];
data &= plane_mask;
v = expand2[GET_PLANE(data, 0)];
@@ -160,7 +162,7 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += 64;
- s += 4;
+ addr += 4;
}
}
@@ -168,7 +170,7 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
* 16 color mode
*/
static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
uint32_t plane_mask, data, v, *palette;
int x;
@@ -177,6 +179,7 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
+ const uint8_t *s = s1->vram_ptr + (addr & (VGA_VRAM_SIZE - 1));
data = ((uint32_t *)s)[0];
data &= plane_mask;
v = expand4[GET_PLANE(data, 0)];
@@ -192,7 +195,7 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
- s += 4;
+ addr += 4;
}
}
@@ -200,7 +203,7 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
* 16 color mode, dup2 horizontal
*/
static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
uint32_t plane_mask, data, v, *palette;
int x;
@@ -209,6 +212,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
+ const uint8_t *s = s1->vram_ptr + (addr & (VGA_VRAM_SIZE - 1));
data = ((uint32_t *)s)[0];
data &= plane_mask;
v = expand4[GET_PLANE(data, 0)];
@@ -224,7 +228,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += 64;
- s += 4;
+ addr += 4;
}
}
@@ -234,7 +238,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
* XXX: add plane_mask support (never used in standard VGA modes)
*/
static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
uint32_t *palette;
int x;
@@ -242,12 +246,13 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
palette = s1->last_palette;
width >>= 3;
for(x = 0; x < width; x++) {
+ const uint8_t *s = s1->vram_ptr + (addr & (VGA_VRAM_SIZE - 1));
PUT_PIXEL2(d, 0, palette[s[0]]);
PUT_PIXEL2(d, 1, palette[s[1]]);
PUT_PIXEL2(d, 2, palette[s[2]]);
PUT_PIXEL2(d, 3, palette[s[3]]);
d += 32;
- s += 4;
+ addr += 4;
}
}
@@ -257,8 +262,9 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
* XXX: add plane_mask support (never used in standard VGA modes)
*/
static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
uint32_t *palette;
int x;
@@ -282,8 +288,9 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
* 15 bit color
*/
static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t v, r, g, b;
@@ -300,8 +307,9 @@ static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
}
static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t v, r, g, b;
@@ -321,8 +329,9 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
* 16 bit color
*/
static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t v, r, g, b;
@@ -339,8 +348,9 @@ static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
}
static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t v, r, g, b;
@@ -360,8 +370,9 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
* 24 bit color
*/
static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t r, g, b;
@@ -377,8 +388,9 @@ static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
}
static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
int w;
uint32_t r, g, b;
@@ -397,8 +409,9 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
* 32 bit color
*/
static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
#ifndef HOST_WORDS_BIGENDIAN
memcpy(d, s, width * 4);
#else
@@ -418,8 +431,9 @@ static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
}
static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+ unsigned int addr, int width)
{
+ const uint8_t *s = s1->vram_ptr + addr;
#ifdef HOST_WORDS_BIGENDIAN
memcpy(d, s, width * 4);
#else
diff --git a/hw/display/vga.c b/hw/display/vga.c
index b35d523..5965ab2 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -41,6 +41,9 @@
/* 16 state changes per vertical frame @60 Hz */
#define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60)
+/* Address mask for non-VESA modes. */
+#define VGA_VRAM_SIZE 262144
+
/*
* Video Graphics Array (VGA)
*
@@ -978,7 +981,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
}
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width);
+ unsigned int s, int width);
#include "vga-helpers.h"
@@ -1629,7 +1632,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (page1 > page_max)
page_max = page1;
if (!(is_buffer_shared(surface))) {
- vga_draw_line(s, d, s->vram_ptr + addr, width);
+ vga_draw_line(s, d, addr, width);
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, y);
}
--
2.4.3
next prev parent reply other threads:[~2015-08-08 13:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-08 13:11 [Qemu-devel] [PATCH 0/3] vga: first round of hardware emulation fixes Paolo Bonzini
2015-08-08 13:11 ` Paolo Bonzini [this message]
2015-08-08 13:11 ` [Qemu-devel] [PATCH 2/3] vga: remove unused macros Paolo Bonzini
2015-08-08 13:11 ` [Qemu-devel] [PATCH 3/3] vga: fix CGA 640x200 mode Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1439039469-438-2-git-send-email-bonzini@gnu.org \
--to=bonzini@gnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).