diff mbox series

ati-vga: Attempt to handle CRTC offset not exact multiple of stride

Message ID e626b64a89116e519e6c307c83dc8624616cf309.1564068311.git.balaton@eik.bme.hu
State New
Headers show
Series ati-vga: Attempt to handle CRTC offset not exact multiple of stride | expand

Commit Message

BALATON Zoltan July 25, 2019, 3:25 p.m. UTC
MacOS seems to need this and the resulting vbe_start_addr seems
correct but I'm not sure this is how it should work (picture is still
broken with MacOS but probably due to firmware problems now).

It also occured to me that these CRTC regs are also present in VGA so
I wonder if they should be shared in case some drivers try to poke
them via VGA regs. Added a comment noting this although in practice
drivers I've tried so far program the card accessing ati regs so I did
not attempt to change it.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 hw/display/ati.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/hw/display/ati.c b/hw/display/ati.c
index b849f5d510..d1db07dd2f 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -50,6 +50,7 @@  static void ati_vga_switch_mode(ATIVGAState *s)
         s->mode = EXT_MODE;
         if (s->regs.crtc_gen_cntl & CRTC2_EN) {
             /* CRT controller enabled, use CRTC values */
+            /* FIXME Should these be the same as VGA CRTC regs? */
             uint32_t offs = s->regs.crtc_offset & 0x07ffffff;
             int stride = (s->regs.crtc_pitch & 0x7ff) * 8;
             int bpp = 0;
@@ -103,14 +104,20 @@  static void ati_vga_switch_mode(ATIVGAState *s)
             if (stride) {
                 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
                 vbe_ioport_write_data(&s->vga, 0, stride);
-                if (offs % stride == 0) {
-                    vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
-                    vbe_ioport_write_data(&s->vga, 0, offs / stride);
-                } else {
-                    /* FIXME what to do with this? */
-                    error_report("VGA offset is not multiple of pitch, "
-                                 "expect bad picture");
+                if (offs % stride) {
+                    /* FIXME Is this correct? */
+                    warn_report("CRTC offset is not multiple of pitch");
+                    vbe_ioport_write_index(&s->vga, 0,
+                                           VBE_DISPI_INDEX_X_OFFSET);
+                    vbe_ioport_write_data(&s->vga, 0,
+                                          offs % stride / (bpp / 8));
                 }
+                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);
             }
         }
     } else {