void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) { VGACommonState *s = opaque; if (s->vbe_index <= VBE_DISPI_INDEX_NB) { #ifdef DEBUG_BOCHS_VBE printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val); #endif switch(s->vbe_index) { case VBE_DISPI_INDEX_ID: if (val == VBE_DISPI_ID0 || val == VBE_DISPI_ID1 || val == VBE_DISPI_ID2 || val == VBE_DISPI_ID3 || val == VBE_DISPI_ID4) { s->vbe_regs[s->vbe_index] = val; } break; case VBE_DISPI_INDEX_XRES: case VBE_DISPI_INDEX_YRES: case VBE_DISPI_INDEX_BPP: case VBE_DISPI_INDEX_VIRT_WIDTH: case VBE_DISPI_INDEX_X_OFFSET: case VBE_DISPI_INDEX_Y_OFFSET: s->vbe_regs[s->vbe_index] = val; vbe_fixup_regs(s); break; case VBE_DISPI_INDEX_BANK: if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { val &= (s->vbe_bank_mask >> 2); } else { val &= s->vbe_bank_mask; } s->vbe_regs[s->vbe_index] = val; s->bank_offset = (val << 16); vga_update_memory_access(s); break; case VBE_DISPI_INDEX_ENABLE: if ((val & VBE_DISPI_ENABLED) && !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { int h, shift_control; s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED; vbe_fixup_regs(s); /* clear the screen */ if (!(val & VBE_DISPI_NOCLEARMEM)) { memset(s->vram_ptr, 0, s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); } /* we initialize the VGA graphic mode */ /* graphic mode + memory map 1 */ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | VGA_GR06_GRAPHICS_MODE; s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */ s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3; /* width */ s->cr[VGA_CRTC_H_DISP] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; /* height (only meaningful if < 1024) */ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; s->cr[VGA_CRTC_V_DISP_END] = h; s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) | ((h >> 7) & 0x02) | ((h >> 3) & 0x40); /* line compare to 1023 */ s->cr[VGA_CRTC_LINE_COMPARE] = 0xff; s->cr[VGA_CRTC_OVERFLOW] |= 0x10; s->cr[VGA_CRTC_MAX_SCAN] |= 0x40; if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { shift_control = 0; s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ } else { shift_control = 2; /* set chain 4 mode */ s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; /* activate all planes */ s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; } s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | (shift_control << 5); s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ } else { s->bank_offset = 0; } s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0; s->vbe_regs[s->vbe_index] = val; vga_update_memory_access(s); break; default: break; } } }