* [PATCH 1/2] ati-vga: Fix setting CRTC_OFFSET
2026-04-03 14:59 [PATCH 0/2] More ati-vga fixes for 11.0 BALATON Zoltan
@ 2026-04-03 14:59 ` BALATON Zoltan
2026-04-06 15:43 ` Chad Jablonski
2026-04-03 14:59 ` [PATCH 2/2] ati-vga: Update mode on CRTC_PITCH change BALATON Zoltan
1 sibling, 1 reply; 5+ messages in thread
From: BALATON Zoltan @ 2026-04-03 14:59 UTC (permalink / raw)
To: qemu-devel
Cc: Gerd Hoffmann, marcandre.lureau, Chad Jablonski,
Philippe Mathieu-Daudé, Peter Maydell
Offset (display start address) should also be updated when changing
the register value not only on mode change. Fix the register write
mask to hard code bits 0:2 to 0 as the chip docs say and update the
start address on register write. This fixes virtual screen panning for
screens larger than displayed resolution.
As this register allows values that cannot be handled by the VBE_DISPI
X and Y offsets (which is restricted by line length) we add a function
to set it directly not through the VBE offsets.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/display/ati.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index eb00382902..3976f5f01c 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -48,6 +48,19 @@ static const struct {
enum { VGA_MODE, EXT_MODE };
+static void ati_vga_set_offset(VGACommonState *vga, uint32_t offs)
+{
+ int bypp = DIV_ROUND_UP(vga->vbe_regs[VBE_DISPI_INDEX_BPP], BITS_PER_BYTE);
+
+ if (!bypp ||
+ vga->vbe_regs[VBE_DISPI_INDEX_YRES] *
+ vga->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * bypp + offs >
+ vga->vbe_size) {
+ return;
+ }
+ vga->vbe_start_addr = offs / 4;
+}
+
static void ati_vga_switch_mode(ATIVGAState *s)
{
DPRINTF("%d -> %d\n",
@@ -110,26 +123,12 @@ static void ati_vga_switch_mode(ATIVGAState *s)
vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED |
VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM |
(s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
- /* now set offset and stride after enable as that resets these */
+ /* now set offset and stride because enable resets these */
if (stride) {
- int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE);
-
vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
vbe_ioport_write_data(&s->vga, 0, stride);
- stride *= bypp;
- if (offs % stride) {
- DPRINTF("CRTC offset is not multiple of pitch\n");
- vbe_ioport_write_index(&s->vga, 0,
- VBE_DISPI_INDEX_X_OFFSET);
- vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp);
- }
- vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
- vbe_ioport_write_data(&s->vga, 0, offs / stride);
- DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n",
- s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET],
- s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET],
- s->vga.vbe_start_addr);
}
+ ati_vga_set_offset(&s->vga, offs);
}
} else {
/* VGA mode enabled */
@@ -752,7 +751,8 @@ static void ati_mm_write(void *opaque, hwaddr addr,
s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff;
break;
case CRTC_OFFSET:
- s->regs.crtc_offset = data & 0xc7ffffff;
+ s->regs.crtc_offset = data & 0x87fffff8;
+ ati_vga_set_offset(&s->vga, s->regs.crtc_offset & 0x07ffffff);
break;
case CRTC_OFFSET_CNTL:
s->regs.crtc_offset_cntl = data; /* FIXME */
--
2.41.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/2] ati-vga: Update mode on CRTC_PITCH change
2026-04-03 14:59 [PATCH 0/2] More ati-vga fixes for 11.0 BALATON Zoltan
2026-04-03 14:59 ` [PATCH 1/2] ati-vga: Fix setting CRTC_OFFSET BALATON Zoltan
@ 2026-04-03 14:59 ` BALATON Zoltan
2026-04-06 15:43 ` Chad Jablonski
1 sibling, 1 reply; 5+ messages in thread
From: BALATON Zoltan @ 2026-04-03 14:59 UTC (permalink / raw)
To: qemu-devel
Cc: Gerd Hoffmann, marcandre.lureau, Chad Jablonski,
Philippe Mathieu-Daudé, Peter Maydell
When changing line length we need to update display parameters so call
mode change when changing CRTC_PITCH if the value has changed.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/display/ati.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 3976f5f01c..07c0961b61 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -758,7 +758,11 @@ static void ati_mm_write(void *opaque, hwaddr addr,
s->regs.crtc_offset_cntl = data; /* FIXME */
break;
case CRTC_PITCH:
- s->regs.crtc_pitch = data & 0x07ff07ff;
+ data &= 0x07ff07ff;
+ if (s->regs.crtc_pitch != data) {
+ s->regs.crtc_pitch = data;
+ ati_vga_switch_mode(s);
+ }
break;
case 0xf00 ... 0xfff:
/* read-only copy of PCI config space so ignore writes */
--
2.41.3
^ permalink raw reply related [flat|nested] 5+ messages in thread