bochs vbe: virtual screen support and bank switch (untested)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@605 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									6411cfb6f3
								
							
						
					
					
						commit
						cae61cef89
					
				
							
								
								
									
										87
									
								
								hw/vga.c
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								hw/vga.c
									
									
									
									
									
								
							@ -116,11 +116,13 @@ typedef struct VGAState {
 | 
				
			|||||||
    uint8_t dac_write_index;
 | 
					    uint8_t dac_write_index;
 | 
				
			||||||
    uint8_t dac_cache[3]; /* used when writing */
 | 
					    uint8_t dac_cache[3]; /* used when writing */
 | 
				
			||||||
    uint8_t palette[768];
 | 
					    uint8_t palette[768];
 | 
				
			||||||
 | 
					    uint32_t bank_offset;
 | 
				
			||||||
#ifdef CONFIG_BOCHS_VBE
 | 
					#ifdef CONFIG_BOCHS_VBE
 | 
				
			||||||
    uint16_t vbe_index;
 | 
					    uint16_t vbe_index;
 | 
				
			||||||
    uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
 | 
					    uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
 | 
				
			||||||
    uint32_t vbe_start_addr;
 | 
					    uint32_t vbe_start_addr;
 | 
				
			||||||
    uint32_t vbe_line_offset;
 | 
					    uint32_t vbe_line_offset;
 | 
				
			||||||
 | 
					    uint32_t vbe_bank_mask;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    /* display refresh support */
 | 
					    /* display refresh support */
 | 
				
			||||||
    DisplayState *ds;
 | 
					    DisplayState *ds;
 | 
				
			||||||
@ -537,28 +539,34 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
        switch(s->vbe_index) {
 | 
					        switch(s->vbe_index) {
 | 
				
			||||||
        case VBE_DISPI_INDEX_ID:
 | 
					        case VBE_DISPI_INDEX_ID:
 | 
				
			||||||
            if (val != VBE_DISPI_ID0 &&
 | 
					            if (val == VBE_DISPI_ID0 ||
 | 
				
			||||||
                val != VBE_DISPI_ID1 &&
 | 
					                val == VBE_DISPI_ID1 ||
 | 
				
			||||||
                val != VBE_DISPI_ID2)
 | 
					                val == VBE_DISPI_ID2) {
 | 
				
			||||||
                return;
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_XRES:
 | 
					        case VBE_DISPI_INDEX_XRES:
 | 
				
			||||||
            if ((val > VBE_DISPI_MAX_XRES) || ((val & 7) != 0))
 | 
					            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
 | 
				
			||||||
                return;
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_YRES:
 | 
					        case VBE_DISPI_INDEX_YRES:
 | 
				
			||||||
            if (val > VBE_DISPI_MAX_YRES)
 | 
					            if (val <= VBE_DISPI_MAX_YRES) {
 | 
				
			||||||
                return;
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_BPP:
 | 
					        case VBE_DISPI_INDEX_BPP:
 | 
				
			||||||
            if (val == 0)
 | 
					            if (val == 0)
 | 
				
			||||||
                val = 8;
 | 
					                val = 8;
 | 
				
			||||||
            if (val != 4 && val != 8 && val != 15 && 
 | 
					            if (val == 4 || val == 8 || val == 15 || 
 | 
				
			||||||
                val != 16 && val != 24 && val != 32)
 | 
					                val == 16 || val == 24 || val == 32) {
 | 
				
			||||||
                return;
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_BANK:
 | 
					        case VBE_DISPI_INDEX_BANK:
 | 
				
			||||||
            val &= 0xff;
 | 
					            val &= s->vbe_bank_mask;
 | 
				
			||||||
 | 
					            s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            s->bank_offset = (val << 16) - 0xa0000;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_ENABLE:
 | 
					        case VBE_DISPI_INDEX_ENABLE:
 | 
				
			||||||
            if (val & VBE_DISPI_ENABLED) {
 | 
					            if (val & VBE_DISPI_ENABLED) {
 | 
				
			||||||
@ -584,9 +592,9 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
 | 
				
			|||||||
                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 | 
					                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                /* we initialize graphic mode force graphic mode
 | 
					                /* we initialize the VGA graphic mode (should be done
 | 
				
			||||||
                   (should be done in BIOS) */
 | 
					                   in BIOS) */
 | 
				
			||||||
                s->gr[6] |= 1;
 | 
					                s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
 | 
				
			||||||
                s->cr[0x17] |= 3; /* no CGA modes */
 | 
					                s->cr[0x17] |= 3; /* no CGA modes */
 | 
				
			||||||
                s->cr[0x13] = s->vbe_line_offset >> 3;
 | 
					                s->cr[0x13] = s->vbe_line_offset >> 3;
 | 
				
			||||||
                /* width */
 | 
					                /* width */
 | 
				
			||||||
@ -609,12 +617,49 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
 | 
					                s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
 | 
				
			||||||
                s->cr[0x09] &= ~0x9f; /* no double scan */
 | 
					                s->cr[0x09] &= ~0x9f; /* no double scan */
 | 
				
			||||||
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                /* XXX: the bios should do that */
 | 
				
			||||||
 | 
					                s->bank_offset = -0xa0000;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case VBE_DISPI_INDEX_VIRT_WIDTH:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int w, h, line_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                w = val;
 | 
				
			||||||
 | 
					                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
 | 
				
			||||||
 | 
					                    line_offset = w >> 1;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
 | 
				
			||||||
 | 
					                h = s->vram_size / line_offset;
 | 
				
			||||||
 | 
					                /* XXX: support weird bochs semantics ? */
 | 
				
			||||||
 | 
					                if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
 | 
				
			||||||
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
 | 
				
			||||||
 | 
					                s->vbe_line_offset = line_offset;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case VBE_DISPI_INDEX_X_OFFSET:
 | 
				
			||||||
 | 
					        case VBE_DISPI_INDEX_Y_OFFSET:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int x;
 | 
				
			||||||
 | 
					                s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
 | 
					                s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
 | 
				
			||||||
 | 
					                x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
 | 
				
			||||||
 | 
					                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
 | 
				
			||||||
 | 
					                    s->vbe_start_addr += x >> 1;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
 | 
				
			||||||
 | 
					                s->vbe_start_addr >>= 2;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        s->vbe_regs[s->vbe_index] = val;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -633,9 +678,9 @@ static uint32_t vga_mem_readb(uint32_t addr)
 | 
				
			|||||||
        addr -= 0xa0000;
 | 
					        addr -= 0xa0000;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        addr -= 0xa0000;
 | 
					        if (addr >= 0xb0000)
 | 
				
			||||||
        if (addr >= 0x10000)
 | 
					 | 
				
			||||||
            return 0xff;
 | 
					            return 0xff;
 | 
				
			||||||
 | 
					        addr += s->bank_offset;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 2:
 | 
					    case 2:
 | 
				
			||||||
        addr -= 0xb0000;
 | 
					        addr -= 0xb0000;
 | 
				
			||||||
@ -711,9 +756,9 @@ void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
 | 
				
			|||||||
        addr -= 0xa0000;
 | 
					        addr -= 0xa0000;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        addr -= 0xa0000;
 | 
					        if (addr >= 0xb0000)
 | 
				
			||||||
        if (addr >= 0x10000)
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					        addr += s->bank_offset;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 2:
 | 
					    case 2:
 | 
				
			||||||
        addr -= 0xb0000;
 | 
					        addr -= 0xb0000;
 | 
				
			||||||
@ -1611,9 +1656,11 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base,
 | 
				
			|||||||
    register_ioport_read(0x3d4, 2, vga_ioport_read, 1);
 | 
					    register_ioport_read(0x3d4, 2, vga_ioport_read, 1);
 | 
				
			||||||
    register_ioport_read(0x3ba, 1, vga_ioport_read, 1);
 | 
					    register_ioport_read(0x3ba, 1, vga_ioport_read, 1);
 | 
				
			||||||
    register_ioport_read(0x3da, 1, vga_ioport_read, 1);
 | 
					    register_ioport_read(0x3da, 1, vga_ioport_read, 1);
 | 
				
			||||||
 | 
					    s->bank_offset = -0xa0000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_BOCHS_VBE
 | 
					#ifdef CONFIG_BOCHS_VBE
 | 
				
			||||||
    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
 | 
					    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
 | 
				
			||||||
 | 
					    s->vbe_bank_mask = ((s->vram_size >> 16) - 1);
 | 
				
			||||||
    register_ioport_read(0x1ce, 1, vbe_ioport_read, 2);
 | 
					    register_ioport_read(0x1ce, 1, vbe_ioport_read, 2);
 | 
				
			||||||
    register_ioport_read(0x1cf, 1, vbe_ioport_read, 2);
 | 
					    register_ioport_read(0x1cf, 1, vbe_ioport_read, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user