Commit f6c958c8652ad63f772f738a8b7776d975bcd787

Authored by bellard
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,7 +344,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
344 printf("vga: write CR%x = 0x%02x\n", s->cr_index, val); 344 printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
345 #endif 345 #endif
346 /* handle CR0-7 protection */ 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 /* can always write bit 4 of CR7 */ 348 /* can always write bit 4 of CR7 */
349 if (s->cr_index == 7) 349 if (s->cr_index == 7)
350 s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10); 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,11 +1346,13 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1346 disp_width = width; 1346 disp_width = width;
1347 1347
1348 shift_control = (s->gr[0x05] >> 5) & 3; 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 } else { 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 multi_run = multi_scan; 1357 multi_run = multi_scan;
1356 if (shift_control != s->shift_control || 1358 if (shift_control != s->shift_control ||
@@ -1417,7 +1419,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) @@ -1417,7 +1419,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1417 1419
1418 line_offset = s->line_offset; 1420 line_offset = s->line_offset;
1419 #if 0 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 width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]); 1423 width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
1422 #endif 1424 #endif
1423 addr1 = (s->start_addr * 4); 1425 addr1 = (s->start_addr * 4);
@@ -1468,21 +1470,17 @@ static void vga_draw_graphic(VGAState *s, int full_update) @@ -1468,21 +1470,17 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1468 } 1470 }
1469 } 1471 }
1470 if (!multi_run) { 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 multi_run = multi_scan; 1477 multi_run = multi_scan;
1482 } else { 1478 } else {
1483 multi_run--; 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 d += linesize; 1484 d += linesize;
1487 } 1485 }
1488 if (y_start >= 0) { 1486 if (y_start >= 0) {