48
49
enum { VGA_MODE, EXT_MODE };
50
51
+static void ati_vga_set_offset(VGACommonState *vga, uint32_t offs)
52
+{
53
+ int bypp = DIV_ROUND_UP(vga->vbe_regs[VBE_DISPI_INDEX_BPP], BITS_PER_BYTE);
54
+
55
+ if (!bypp ||
56
+ vga->vbe_regs[VBE_DISPI_INDEX_YRES] *
57
+ vga->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * bypp + offs >
58
+ vga->vbe_size) {
59
+ return;
60
+ }
61
+ vga->vbe_start_addr = offs / 4;
62
+}
63
+
64
static void ati_vga_switch_mode(ATIVGAState *s)
65
{
66
DPRINTF("%d -> %d\n",
122
vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED |
123
VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM |
124
(s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
112
- /* now set offset and stride after enable as that resets these */
125
+ /* now set offset and stride because enable resets these */
126
if (stride) {
114
- int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE);
115
-
127
vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
128
vbe_ioport_write_data(&s->vga, 0, stride);
118
- stride *= bypp;
119
- if (offs % stride) {
120
- DPRINTF("CRTC offset is not multiple of pitch\n");
121
- vbe_ioport_write_index(&s->vga, 0,
122
- VBE_DISPI_INDEX_X_OFFSET);
123
- vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp);
124
- }
125
- vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
126
- vbe_ioport_write_data(&s->vga, 0, offs / stride);
127
- DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n",
128
- s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET],
129
- s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET],
130
- s->vga.vbe_start_addr);
129
}
130
+ ati_vga_set_offset(&s->vga, offs);
131
}
132
} else {
133
/* VGA mode enabled */
736
s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff;
737
break;
738
case CRTC_OFFSET:
740
- s->regs.crtc_offset = data & 0xc7ffffff;
739
+ s->regs.crtc_offset = data & 0x87fffff8;
740
+ ati_vga_set_offset(&s->vga, s->regs.crtc_offset & 0x07ffffff);
741
break;
742
case CRTC_OFFSET_CNTL:
743
s->regs.crtc_offset_cntl = data; /* FIXME */