diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index b5e3ed6d1..bbc7d2537 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -1733,10 +1733,44 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & FBZ_CHROMAKEY)) { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); + switch (_rgb_sel) + { + case CC_LOCALSELECT_ITER_RGB: + addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x87); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM0, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe0); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case CC_LOCALSELECT_COLOR1: + addbyte(0x8b); /*MOV EAX, params->color1[RSI]*/ + addbyte(0x86); + addlong(offsetof(voodoo_params_t, color1)); + break; + case CC_LOCALSELECT_TEX: + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + } addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, chromaKey)); diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index a9f2c5533..6e8c891c1 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -1668,10 +1668,44 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & FBZ_CHROMAKEY)) { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); + switch (_rgb_sel) + { + case CC_LOCALSELECT_ITER_RGB: + addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x87); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM0, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe0); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case CC_LOCALSELECT_COLOR1: + addbyte(0x8b); /*MOV EAX, params->color1[ESI]*/ + addbyte(0x86); + addlong(offsetof(voodoo_params_t, color1)); + break; + case CC_LOCALSELECT_TEX: + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + } addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, chromaKey)); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index b1a1c8222..5dcca426a 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -401,7 +401,7 @@ ati28800_recalctimings(svga_t *svga) case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; break; case 0x0A: svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; break; case 0x0B: svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; break; - case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; case 0x0D: svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; break; case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; @@ -423,14 +423,6 @@ ati28800_recalctimings(svga_t *svga) svga->rowoffset <<= 1; } - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) { /* Extended 256 colour modes */ switch (svga->bpp) { case 8: diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index ba4964a09..932fb9ee6 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -660,7 +660,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_hwCurPatAddr: banshee->hwCurPatAddr = val; - svga->hwcursor.addr = val & 0xfffff0; + svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); break; case Video_hwCurLoc: banshee->hwCurLoc = val; @@ -673,6 +673,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) } else svga->hwcursor.yoff = 0; + svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); svga->hwcursor.xsize = 64; svga->hwcursor.ysize = 64; // banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); @@ -1381,6 +1382,9 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 1) + return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8); + sub_cycles(voodoo->read_time); addr &= svga->decode_mask; @@ -1412,6 +1416,9 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 3) + return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16); + sub_cycles(voodoo->read_time); addr &= svga->decode_mask; @@ -1475,6 +1482,13 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 1) + { + banshee_write_linear(addr, val, p); + banshee_write_linear(addr + 1, val >> 8, p); + return; + } + sub_cycles(voodoo->write_time); // banshee_log("write_linear: addr=%08x val=%02x\n", addr, val); @@ -1508,6 +1522,13 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) svga_t *svga = &banshee->svga; int timing; + if (addr & 3) + { + banshee_write_linear_w(addr, val, p); + banshee_write_linear_w(addr + 2, val >> 16, p); + return; + } + if (addr == voodoo->last_write_addr+4) timing = voodoo->burst_time; else