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
This commit is contained in:
		
							parent
							
								
									9bb34eac8b
								
							
						
					
					
						commit
						f6c958c865
					
				
							
								
								
									
										24
									
								
								hw/vga.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								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);
 | 
					        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        /* handle CR0-7 protection */
 | 
					        /* 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 */
 | 
					            /* can always write bit 4 of CR7 */
 | 
				
			||||||
            if (s->cr_index == 7)
 | 
					            if (s->cr_index == 7)
 | 
				
			||||||
                s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
 | 
					                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;
 | 
					    disp_width = width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shift_control = (s->gr[0x05] >> 5) & 3;
 | 
					    shift_control = (s->gr[0x05] >> 5) & 3;
 | 
				
			||||||
    double_scan = (s->cr[0x09] & 0x80);
 | 
					    double_scan = (s->cr[0x09] >> 7);
 | 
				
			||||||
    if (shift_control > 1) {
 | 
					    if (shift_control != 1) {
 | 
				
			||||||
        multi_scan = (s->cr[0x09] & 0x1f);
 | 
					        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        multi_scan = 0;
 | 
					        /* in CGA modes, multi_scan is ignored */
 | 
				
			||||||
 | 
					        /* XXX: is it correct ? */
 | 
				
			||||||
 | 
					        multi_scan = double_scan;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    multi_run = multi_scan;
 | 
					    multi_run = multi_scan;
 | 
				
			||||||
    if (shift_control != s->shift_control ||
 | 
					    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;
 | 
					    line_offset = s->line_offset;
 | 
				
			||||||
#if 0
 | 
					#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]);
 | 
					           width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    addr1 = (s->start_addr * 4);
 | 
					    addr1 = (s->start_addr * 4);
 | 
				
			||||||
@ -1468,21 +1470,17 @@ static void vga_draw_graphic(VGAState *s, int full_update)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!multi_run) {
 | 
					        if (!multi_run) {
 | 
				
			||||||
            if (!double_scan || (y & 1) != 0) {
 | 
					 | 
				
			||||||
                if (y1 == s->line_compare) {
 | 
					 | 
				
			||||||
                    addr1 = 0;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
            mask = (s->cr[0x17] & 3) ^ 3;
 | 
					            mask = (s->cr[0x17] & 3) ^ 3;
 | 
				
			||||||
            if ((y1 & mask) == mask)
 | 
					            if ((y1 & mask) == mask)
 | 
				
			||||||
                addr1 += line_offset;
 | 
					                addr1 += line_offset;
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            y1++;
 | 
					            y1++;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            multi_run = multi_scan;
 | 
					            multi_run = multi_scan;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            multi_run--;
 | 
					            multi_run--;
 | 
				
			||||||
            y1++;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        /* line compare acts on the displayed lines */
 | 
				
			||||||
 | 
					        if (y == s->line_compare)
 | 
				
			||||||
 | 
					            addr1 = 0;
 | 
				
			||||||
        d += linesize;
 | 
					        d += linesize;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (y_start >= 0) {
 | 
					    if (y_start >= 0) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user