Commit f6c958c8652ad63f772f738a8b7776d975bcd787
1 parent
9bb34eac
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
Showing
1 changed file
with
15 additions
and
17 deletions
hw/vga.c
... | ... | @@ -344,7 +344,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
344 | 344 | printf("vga: write CR%x = 0x%02x\n", s->cr_index, val); |
345 | 345 | #endif |
346 | 346 | /* handle CR0-7 protection */ |
347 | - if ((s->cr[11] & 0x80) && s->cr_index <= 7) { | |
347 | + if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) { | |
348 | 348 | /* can always write bit 4 of CR7 */ |
349 | 349 | if (s->cr_index == 7) |
350 | 350 | s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10); |
... | ... | @@ -1346,11 +1346,13 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
1346 | 1346 | disp_width = width; |
1347 | 1347 | |
1348 | 1348 | shift_control = (s->gr[0x05] >> 5) & 3; |
1349 | - double_scan = (s->cr[0x09] & 0x80); | |
1350 | - if (shift_control > 1) { | |
1351 | - multi_scan = (s->cr[0x09] & 0x1f); | |
1349 | + double_scan = (s->cr[0x09] >> 7); | |
1350 | + if (shift_control != 1) { | |
1351 | + multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1; | |
1352 | 1352 | } else { |
1353 | - multi_scan = 0; | |
1353 | + /* in CGA modes, multi_scan is ignored */ | |
1354 | + /* XXX: is it correct ? */ | |
1355 | + multi_scan = double_scan; | |
1354 | 1356 | } |
1355 | 1357 | multi_run = multi_scan; |
1356 | 1358 | if (shift_control != s->shift_control || |
... | ... | @@ -1417,7 +1419,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
1417 | 1419 | |
1418 | 1420 | line_offset = s->line_offset; |
1419 | 1421 | #if 0 |
1420 | - printf("w=%d h=%d v=%d line_offset=%d double_scan=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=%02x\n", | |
1422 | + 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", | |
1421 | 1423 | width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]); |
1422 | 1424 | #endif |
1423 | 1425 | addr1 = (s->start_addr * 4); |
... | ... | @@ -1468,21 +1470,17 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
1468 | 1470 | } |
1469 | 1471 | } |
1470 | 1472 | if (!multi_run) { |
1471 | - if (!double_scan || (y & 1) != 0) { | |
1472 | - if (y1 == s->line_compare) { | |
1473 | - addr1 = 0; | |
1474 | - } else { | |
1475 | - mask = (s->cr[0x17] & 3) ^ 3; | |
1476 | - if ((y1 & mask) == mask) | |
1477 | - addr1 += line_offset; | |
1478 | - } | |
1479 | - y1++; | |
1480 | - } | |
1473 | + mask = (s->cr[0x17] & 3) ^ 3; | |
1474 | + if ((y1 & mask) == mask) | |
1475 | + addr1 += line_offset; | |
1476 | + y1++; | |
1481 | 1477 | multi_run = multi_scan; |
1482 | 1478 | } else { |
1483 | 1479 | multi_run--; |
1484 | - y1++; | |
1485 | 1480 | } |
1481 | + /* line compare acts on the displayed lines */ | |
1482 | + if (y == s->line_compare) | |
1483 | + addr1 = 0; | |
1486 | 1484 | d += linesize; |
1487 | 1485 | } |
1488 | 1486 | if (y_start >= 0) { | ... | ... |