@samitouri / QOSamiQemu / commits / 28df2e5469

ati-vga: Simplify pointer image handling

Rewrite reading of mouse pointer image. I am not sure this is entirely correct but appears to work at least on little endian host with PPC guests using little or big endian frame buffer (MorphOS and MacOS) but still produces broken pointer image with Linux where I am not sure if it is a guest driver bug or still missing something. Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Message-ID: <b9de530074b954d661a0eb9b8b4ad82a66085456.1774110169.git.balaton@eik.bme.hu> [PMD: Replaced BIT() -> BIT_ULL() in ati_cursor_draw_line()] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

BALATON Zoltan committed Mar 21, 2026 at 17:30 UTC 28df2e5469f07379f2506a4c3966ebc4c8d92bc3
1 file changed +24 -29
hw/display/ati.c
+24 -29
@@ -141,27 +141,24 @@ static void ati_vga_switch_mode(ATIVGAState *s)
141 /* Used by host side hardware cursor */
142 static void ati_cursor_define(ATIVGAState *s)
143 {
144 - uint8_t data[1024];
144 + uint64_t data[128];
145 uint32_t srcoff;
146 - int i, j, idx = 0;
146
147 if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) {
148 return; /* Do not update cursor if locked or rendered by guest */
149 }
150 /* FIXME handle cur_hv_offs correctly */
152 - srcoff = s->regs.cur_offset -
153 - (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16;
154 - for (i = 0; i < 64; i++) {
155 - for (j = 0; j < 8; j++, idx++) {
156 - data[idx] = vga_read_byte(&s->vga, srcoff + i * 16 + j);
157 - data[512 + idx] = vga_read_byte(&s->vga, srcoff + i * 16 + j + 8);
158 - }
151 + srcoff = s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
152 + (s->regs.cur_hv_offs & 0xffff) * 16;
153 + for (int i = 0; i < 64; i++, srcoff += 16) {
154 + data[i] = ldq_le_p(&s->vga.vram_ptr[srcoff]);
155 + data[i + 64] = ldq_le_p(&s->vga.vram_ptr[srcoff + 8]);
156 }
157 if (!s->cursor) {
158 s->cursor = cursor_alloc(64, 64);
159 }
160 cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0,
164 - &data[512], 1, &data[0]);
161 + (uint8_t *)&data[64], 1, (uint8_t *)&data[0]);
162 dpy_cursor_define(s->vga.con, s->cursor);
163 }
164
@@ -196,9 +193,9 @@ static void ati_cursor_invalidate(VGACommonState *vga)
193 static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
194 {
195 ATIVGAState *s = container_of(vga, ATIVGAState, vga);
199 - uint32_t srcoff;
196 + uint32_t h, srcoff, color;
197 + uint64_t abits, xbits, mask;
198 uint32_t *dp = (uint32_t *)d;
201 - int i, j, h, idx = 0;
199
200 if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
201 scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
@@ -209,26 +206,24 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
206 srcoff = s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
207 dp = &dp[vga->hw_cursor_x];
208 h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
212 - for (i = 0; i < 8; i++) {
213 - uint32_t color;
214 - uint8_t abits = vga_read_byte(vga, srcoff + i);
215 - uint8_t xbits = vga_read_byte(vga, srcoff + i + 8);
216 - for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1, idx++) {
217 - if (vga->hw_cursor_x + idx >= h) {
218 - return; /* end of screen, don't span to next line */
219 - }
220 - if (abits & BIT(7)) {
221 - if (xbits & BIT(7)) {
222 - color = dp[idx] ^ 0xffffffff; /* complement */
223 - } else {
224 - continue; /* transparent, no change */
225 - }
209 + abits = ldq_be_p(&vga->vram_ptr[srcoff]);
210 + xbits = ldq_be_p(&vga->vram_ptr[srcoff + 8]);
211 + mask = BIT_ULL(63);
212 + for (int i = 0; i < 64; i++, mask >>= 1) {
213 + if (vga->hw_cursor_x + i >= h) {
214 + return; /* end of screen, don't span to next line */
215 + }
216 + if (abits & mask) {
217 + if (xbits & mask) {
218 + color = dp[i] ^ 0xffffffff; /* complement */
219 } else {
227 - color = (xbits & BIT(7) ? s->regs.cur_color1 :
228 - s->regs.cur_color0) | 0xff000000;
220 + continue; /* transparent, no change */
221 }
230 - dp[idx] = color;
222 + } else {
223 + color = (xbits & mask ? s->regs.cur_color1 :
224 + s->regs.cur_color0) | 0xff000000;
225 }
226 + dp[i] = color;
227 }
228 }
229