diff options
author | Angelo Salese <angelosa@users.noreply.github.com> | 2012-01-03 03:13:01 +0000 |
---|---|---|
committer | Angelo Salese <angelosa@users.noreply.github.com> | 2012-01-03 03:13:01 +0000 |
commit | 0e077609df4b295e6d101c408357571bedccf284 (patch) | |
tree | b32136bbdbccd47c63a6754e8d57e7cee42a84dc | |
parent | 85f5960fb3e9a15bff96c72902488507b2a7fb88 (diff) |
Hooked up Voodoo, and another batch of x87. It fails due of the color DAC
-rw-r--r-- | src/emu/cpu/i386/x87ops.c | 153 | ||||
-rw-r--r-- | src/mame/drivers/funkball.c | 9 |
2 files changed, 154 insertions, 8 deletions
diff --git a/src/emu/cpu/i386/x87ops.c b/src/emu/cpu/i386/x87ops.c index 01824026b75..16ef64d1ece 100644 --- a/src/emu/cpu/i386/x87ops.c +++ b/src/emu/cpu/i386/x87ops.c @@ -647,7 +647,18 @@ static void I386OP(fpu_group_db)(i386_state *cpustate) // Opcode 0xdb t.f=(INT32)READ32(cpustate,ea); FPU_PUSH(cpustate,t); - CYCLES(cpustate,1); // TODO + CYCLES(cpustate,9); + break; + } + + case 3: // FISTP + { + X87_REG t; + + t = X87_FROUND(cpustate,ST(0)); + WRITE32(cpustate,ea,(INT32)t.i); + FPU_POP(cpustate); + CYCLES(cpustate,28); break; } @@ -702,6 +713,24 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc switch ((modrm >> 3) & 0x7) { + case 0: /* FADD double */ + { + X87_REG t; + t.i = READ64(cpustate,ea); + ST(0).f += t.f; + CYCLES(cpustate,8); + break; + } + + case 1: /* FMUL double */ + { + X87_REG t; + t.i = READ64(cpustate,ea); + ST(0).f *= t.f; + CYCLES(cpustate,14); + break; + } + case 2: /* FCOM double */ { X87_REG t; @@ -715,6 +744,7 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc CYCLES(cpustate,4); break; } + case 3: /* FCOMP double */ { X87_REG t; @@ -729,6 +759,25 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc CYCLES(cpustate,4); break; } + + case 4: /* FSUB double */ + { + X87_REG t; + t.i = READ64(cpustate,ea); + ST(0).f -= t.f; + CYCLES(cpustate,8); + break; + } + + case 5: /* FSUBR double */ + { + X87_REG t; + t.i = READ64(cpustate,ea); + ST(0).f = t.f - ST(0).f; + CYCLES(cpustate,8); + break; + } + case 6: /* FDIV double */ { X87_REG t; @@ -742,6 +791,19 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc break; } + case 7: /* FDIV double */ + { + X87_REG t; + t.i = READ64(cpustate,ea); + if(ST(0).f) + ST(0).f = t.f / ST(0).f; + else + fatalerror("FPU Op DC 6 Divide by zero unhandled exception"); + + CYCLES(cpustate,73); + break; + } + default: fatalerror("I386: FPU Op DC %02X at %08X", (modrm >> 3) & 0x7, cpustate->pc-2); } @@ -750,6 +812,34 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc { switch (modrm & 0x3f) { + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // FADD + { + ST(modrm & 7).f += ST(0).f; + CYCLES(cpustate,8); + break; + } + + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: // FMUL + { + ST(modrm & 7).f *= ST(0).f; + CYCLES(cpustate,8); + break; + } + + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // FSUBR + { + ST(modrm & 7).f = ST(0).f - ST(modrm & 7).f; + CYCLES(cpustate,8); + break; + } + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: // FSUB + { + ST(modrm & 7).f -= ST(0).f; + CYCLES(cpustate,8); + break; + } + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: { // FDIVR @@ -907,6 +997,42 @@ static void I386OP(fpu_group_de)(i386_state *cpustate) // Opcode 0xde break; } + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // FSUBRP + { + ST(modrm & 7).f = ST(0).f - ST(modrm & 7).f; + FPU_POP(cpustate); + CYCLES(cpustate,8); + break; + } + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: // FSUBP + { + ST(modrm & 7).f -= ST(cpustate->fpu_top).f; + FPU_POP(cpustate); + CYCLES(cpustate,8); + break; + } + + // FDIVRP + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + { + if ((ST(modrm & 7).i & U64(0x7fffffffffffffff)) == 0) + { + // set result as infinity if zero divide is masked + if (cpustate->fpu_control_word & FPU_MASK_ZERO_DIVIDE) + { + ST(modrm & 7).i |= FPU_INFINITY_DOUBLE; + } + } + else + { + ST(modrm & 7).f = ST(0).f / ST(modrm & 7).f; + } + FPU_POP(cpustate); + CYCLES(cpustate,73); + break; + } + // FDIVP case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: { @@ -923,7 +1049,7 @@ static void I386OP(fpu_group_de)(i386_state *cpustate) // Opcode 0xde ST(modrm & 7).f = ST(modrm & 7).f / ST(0).f; } FPU_POP(cpustate); - CYCLES(cpustate,1); // TODO + CYCLES(cpustate,73); break; } @@ -943,7 +1069,28 @@ static void I386OP(fpu_group_df)(i386_state *cpustate) // Opcode 0xdf switch ((modrm >> 3) & 0x7) { - case 5: // FILD + case 0: // FILD short + { + X87_REG t; + + t.f=(INT16)READ16(cpustate,ea); + FPU_PUSH(cpustate,t); + CYCLES(cpustate,13); + break; + } + + case 3: // FISTP short + { + X87_REG t; + + t = X87_FROUND(cpustate,ST(0)); + WRITE16(cpustate,ea,(INT16)t.i); + FPU_POP(cpustate); + CYCLES(cpustate,29); + break; + } + + case 5: // FILD long { X87_REG t; diff --git a/src/mame/drivers/funkball.c b/src/mame/drivers/funkball.c index 72e841d5202..f6fbdfc2028 100644 --- a/src/mame/drivers/funkball.c +++ b/src/mame/drivers/funkball.c @@ -4,11 +4,9 @@ /*************************************************************************** Notes: -- Voodoo currently fails to init DAC regs, sub-routine is at 0x182a3. - It does: mov [ebx],ecx in there, where ebx is 0xfffxxxxx, but only lower - 16 bits are used so it ends up in reading at conventional work RAM. - CPU core bug? -bp 0x182a8,ax = 1;bp 0x18390,ax = 1;bp 0x183a2,ax = 1;bp 0x1b578,ax = 1 +- currently fails DAC r/w in Voodoo registers; +(note: some of those are redundant) +bp 0x182a8,ax = 1;bp 0x18390,ax = 1;bp 0x183a2,ax = 1;bp 0x1b578,ax = 1;bp 0x1b5cb,ax = 1; Funky Ball dgPIX, 1998 @@ -580,6 +578,7 @@ static ADDRESS_MAP_START(funkball_map, AS_PROGRAM, 32, funkball_state) // AM_RANGE(0x08000000, 0x0fffffff) AM_NOP AM_RANGE(0x40008000, 0x400080ff) AM_READWRITE_LEGACY(biu_ctrl_r, biu_ctrl_w) AM_RANGE(0x40010e00, 0x40010eff) AM_RAM AM_BASE(m_unk_ram) + AM_RANGE(0xff000000, 0xffffdfff) AM_DEVREADWRITE_LEGACY("voodoo_0", voodoo_r, voodoo_w) AM_RANGE(0xfffe0000, 0xffffffff) AM_ROM AM_REGION("bios", 0) /* System BIOS */ ADDRESS_MAP_END |