summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit0e077609df4b295e6d101c408357571bedccf284 (patch)
treeb32136bbdbccd47c63a6754e8d57e7cee42a84dc
parent85f5960fb3e9a15bff96c72902488507b2a7fb88 (diff)
Hooked up Voodoo, and another batch of x87. It fails due of the color DAC
-rw-r--r--src/emu/cpu/i386/x87ops.c153
-rw-r--r--src/mame/drivers/funkball.c9
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