aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-11-07 22:57:20 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-11-07 22:57:20 +0000
commitf6c958c8652ad63f772f738a8b7776d975bcd787 (patch)
tree1a442ef8ca54e1275d38c14aaf19a91cc09fc42d /hw
parentCRTC register write protection fix (diff)
downloadqemu-kvm-f6c958c8652ad63f772f738a8b7776d975bcd787.tar.gz
qemu-kvm-f6c958c8652ad63f772f738a8b7776d975bcd787.tar.bz2
qemu-kvm-f6c958c8652ad63f772f738a8b7776d975bcd787.zip
CRTC register write protection fix - line_compare, multi_scan and double_scan fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1127 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r--hw/vga.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/hw/vga.c b/hw/vga.c
index 2660b0469..3d4312de2 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -344,7 +344,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
#endif
/* handle CR0-7 protection */
- if ((s->cr[11] & 0x80) && s->cr_index <= 7) {
+ if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
/* can always write bit 4 of CR7 */
if (s->cr_index == 7)
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
@@ -1346,11 +1346,13 @@ static void vga_draw_graphic(VGAState *s, int full_update)
disp_width = width;
shift_control = (s->gr[0x05] >> 5) & 3;
- double_scan = (s->cr[0x09] & 0x80);
- if (shift_control > 1) {
- multi_scan = (s->cr[0x09] & 0x1f);
+ double_scan = (s->cr[0x09] >> 7);
+ if (shift_control != 1) {
+ multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
} else {
- multi_scan = 0;
+ /* in CGA modes, multi_scan is ignored */
+ /* XXX: is it correct ? */
+ multi_scan = double_scan;
}
multi_run = multi_scan;
if (shift_control != s->shift_control ||
@@ -1417,7 +1419,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
line_offset = s->line_offset;
#if 0
- printf("w=%d h=%d v=%d line_offset=%d double_scan=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=%02x\n",
+ printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
#endif
addr1 = (s->start_addr * 4);
@@ -1468,21 +1470,17 @@ static void vga_draw_graphic(VGAState *s, int full_update)
}
}
if (!multi_run) {
- if (!double_scan || (y & 1) != 0) {
- if (y1 == s->line_compare) {
- addr1 = 0;
- } else {
- mask = (s->cr[0x17] & 3) ^ 3;
- if ((y1 & mask) == mask)
- addr1 += line_offset;
- }
- y1++;
- }
+ mask = (s->cr[0x17] & 3) ^ 3;
+ if ((y1 & mask) == mask)
+ addr1 += line_offset;
+ y1++;
multi_run = multi_scan;
} else {
multi_run--;
- y1++;
}
+ /* line compare acts on the displayed lines */
+ if (y == s->line_compare)
+ addr1 = 0;
d += linesize;
}
if (y_start >= 0) {