aboutsummaryrefslogtreecommitdiff
path: root/hw/display
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-07-28 15:32:18 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2022-07-28 15:36:17 +0200
commit37e7b86766244b62a406747bb78e049390d0b528 (patch)
tree3e313037939504902220733f6726ecb6e3d42eae /hw/display
parentd82b11f69953cf15cee819bcf02dfd87325980a9 (diff)
vga: fix incorrect line height in 640x200x2 mode
When in CGA modes, QEMU wants to ignore the maximum scan field (bits 0..4) of the maximum scan length register in the CRTC. It is not clear why this is needed---for example, Bochs ignores bit 7 instead. The issue is that the CGA modes are not detected correctly, and in particular mode 6 results in multi_scan==3 according to how SeaBIOS programs it. The right way to check for CGA graphics modes is to check whether bit 13 of the address is special cased by the CRT controller to achieve line interleaving, i.e. whether bit 0 of the CRTC mode control register is clear. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1020 Reported-by: Korneliusz Osmenda <korneliuszo@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/display')
-rw-r--r--hw/display/vga.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 5dca2d1528..50ecb1ad02 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1514,9 +1514,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
force_shadow = true;
}
+ /* bits 5-6: 0 = 16-color mode, 1 = 4-color mode, 2 = 256-color mode. */
shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
- if (shift_control != 1) {
+ if (s->cr[VGA_CRTC_MODE] & 1) {
multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
- 1;
} else {