summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2012-02-18 10:58:12 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2012-02-18 10:58:12 +0000
commitf47c0750ce4e66ae6c5b611370abe47700be526a (patch)
tree4f2dd88276031da3a78290be0d5d2d6480d1cf93 /src
parentc19f1f8c49b0d99be08b28052aa7df3aecd1e8bf (diff)
dma8237: fix uninitialized variable [Hans Ostermeyer]
mc146818: remove previous Apollo hack, fix 32768 Hz. updates [Hans Ostermeyer] m68k: fix FSGLMUL/FSGLDIV plus some minor MMU improvements [Hans Ostermeyer] m68k: slightly less stubby CINV [Hans Ostermeyer]
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/m68000/m68k_in.c13
-rw-r--r--src/emu/cpu/m68000/m68kfpu.c75
-rw-r--r--src/emu/cpu/m68000/m68kmmu.h31
-rw-r--r--src/emu/machine/8237dma.c1
-rw-r--r--src/emu/machine/mc146818.c10
5 files changed, 117 insertions, 13 deletions
diff --git a/src/emu/cpu/m68000/m68k_in.c b/src/emu/cpu/m68000/m68k_in.c
index 0775cb62aea..fd5e742a55d 100644
--- a/src/emu/cpu/m68000/m68k_in.c
+++ b/src/emu/cpu/m68000/m68k_in.c
@@ -10483,8 +10483,17 @@ M68KMAKE_OP(cinv, 32, ., .)
{
if(CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type))
{
- logerror("%s at %08x: called unimplemented instruction %04x (cinv)\n",
- (mc68kcpu)->device->tag(), REG_PC(mc68kcpu) - 2, (mc68kcpu)->ir);
+ UINT16 ir = mc68kcpu->ir;
+ UINT8 cache = (ir >> 6) & 3;
+// UINT8 scope = (ir >> 3) & 3;
+// logerror("68040 %s: pc=%08x ir=%04x cache=%d scope=%d register=%d\n", ir & 0x0020 ? "cpush" : "cinv", REG_PPC(mc68kcpu), ir, cache, scope, ir & 7);
+ switch (cache)
+ {
+ case 2:
+ case 3:
+ // we invalidate/push the whole instruction cache
+ m68ki_ic_clear(mc68kcpu);
+ }
return;
}
m68ki_exception_1111(mc68kcpu);
diff --git a/src/emu/cpu/m68000/m68kfpu.c b/src/emu/cpu/m68000/m68kfpu.c
index c0abca10a39..b07ace6fa89 100644
--- a/src/emu/cpu/m68000/m68kfpu.c
+++ b/src/emu/cpu/m68000/m68kfpu.c
@@ -5,6 +5,9 @@
#define FPCC_I 0x02000000
#define FPCC_NAN 0x01000000
+#define FPES_OE 0x00002000
+#define FPAE_IOP 0x00000080
+
#define DOUBLE_INFINITY U64(0x7ff0000000000000)
#define DOUBLE_EXPONENT U64(0x7ff0000000000000)
#define DOUBLE_MANTISSA U64(0x000fffffffffffff)
@@ -1390,7 +1393,9 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
}
case 0x24: // FSGLDIV
{
- REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
+ float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
+ float32 b = floatx80_to_float32( source );
+ REG_FP(m68k)[dst] = float32_to_floatx80( float32_div(a, b) );
m68k->remaining_cycles -= 43; // // ? (value is from FDIV)
break;
}
@@ -1403,7 +1408,9 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
}
case 0x27: // FSGLMUL
{
- REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
+ float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
+ float32 b = floatx80_to_float32( source );
+ REG_FP(m68k)[dst] = float32_to_floatx80( float32_mul(a, b) );
SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
m68k->remaining_cycles -= 11; // ? (value is from FMUL)
break;
@@ -1471,7 +1478,12 @@ static void fmove_reg_mem(m68ki_cpu_core *m68k, UINT16 w2)
}
case 4: // Word Integer
{
- WRITE_EA_16(m68k, ea, (INT16)floatx80_to_int32(REG_FP(m68k)[src]));
+ int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
+ if (value > 0x7fff || value < -0x8000 )
+ {
+ REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
+ }
+ WRITE_EA_16(m68k, ea, (INT16)value);
break;
}
case 5: // Double-precision Real
@@ -1485,7 +1497,12 @@ static void fmove_reg_mem(m68ki_cpu_core *m68k, UINT16 w2)
}
case 6: // Byte Integer
{
- WRITE_EA_8(m68k, ea, (INT8)floatx80_to_int32(REG_FP(m68k)[src]));
+ int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
+ if (value > 127 || value < -128)
+ {
+ REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
+ }
+ WRITE_EA_8(m68k, ea, (INT8) value);
break;
}
case 7: // Packed-decimal Real with Dynamic K-factor
@@ -1547,6 +1564,56 @@ static void fmove_fpcr(m68ki_cpu_core *m68k, UINT16 w2)
}
}
+#if 0
+ // FIXME: (2011-12-18 ost)
+ // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
+ // but: with this code on Apollo the following programs in /systest/fptest will fail:
+ // 1. Single Precision Whetstone will return wrong results never the less
+ // 2. Vector Test will fault with 00040004: reference to illegal address
+
+ if ((regsel & 4) && dir == 0)
+ {
+ int rnd = (REG_FPCR(m68k) >> 4) & 3;
+ int prec = (REG_FPCR(m68k) >> 6) & 3;
+
+ logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", REG_FPCR(m68k), prec, rnd);
+
+#ifdef FLOATX80
+ switch (prec)
+ {
+ case 0: // Extend (X)
+ floatx80_rounding_precision = 80;
+ break;
+ case 1: // Single (S)
+ floatx80_rounding_precision = 32;
+ break;
+ case 2: // Double (D)
+ floatx80_rounding_precision = 64;
+ break;
+ case 3: // Undefined
+ floatx80_rounding_precision = 80;
+ break;
+ }
+#endif
+
+ switch (rnd)
+ {
+ case 0: // To Nearest (RN)
+ float_rounding_mode = float_round_nearest_even;
+ break;
+ case 1: // To Zero (RZ)
+ float_rounding_mode = float_round_to_zero;
+ break;
+ case 2: // To Minus Infinitiy (RM)
+ float_rounding_mode = float_round_down;
+ break;
+ case 3: // To Plus Infinitiy (RP)
+ float_rounding_mode = float_round_up;
+ break;
+ }
+ }
+#endif
+
m68k->remaining_cycles -= 10;
}
diff --git a/src/emu/cpu/m68000/m68kmmu.h b/src/emu/cpu/m68000/m68kmmu.h
index 23b3b11f0c4..19e7442b4c5 100644
--- a/src/emu/cpu/m68000/m68kmmu.h
+++ b/src/emu/cpu/m68000/m68kmmu.h
@@ -260,6 +260,18 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U
}
}
+ if (m68k->mmu_tt1 & 0x8000)
+ {
+ // transparent translation register 1 enabled
+ UINT32 address_base = m68k->mmu_tt1 & 0xff000000;
+ UINT32 address_mask = ((m68k->mmu_tt1 << 8) & 0xff000000) ^ 0xff000000;
+ if ((addr_in & address_mask) == address_base)
+ {
+// printf("PMMU: pc=%x TT1 fc=%x addr_in=%08x address_mask=%08x address_base=%08x\n", m68k->ppc, fc, addr_in, address_mask, address_base);
+ return addr_in;
+ }
+ }
+
// if ((++pmmu_access_count % 10000000) == 0) {
// printf("pmmu_translate_addr_with_fc: atc usage = %d%%\n", pmmu_atc_count*100/pmmu_access_count);
// pmmu_atc_count = pmmu_access_count = 0;
@@ -777,6 +789,11 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k)
printf("680x0: unhandled PBcc\n");
return;
}
+ else if ((m68k->ir & 0xffe0) == 0xf500)
+ {
+// logerror("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", REG_PPC(m68k), m68k->ir, (m68k->ir >> 3) & 3, m68k->ir & 7);
+ pmmu_atc_flush(m68k);
+ }
else // the rest are 1111000xxxXXXXXX where xxx is the instruction family
{
switch ((m68k->ir>>9) & 0x7)
@@ -972,6 +989,20 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k)
}
break;
+ case 7: // MC68851 Access Control Register
+ if (m68k->cpu_type == CPU_TYPE_020)
+ {
+ // DomainOS on Apollo DN3000 will only reset this to 0
+ UINT16 mmu_ac = READ_EA_16(m68k, ea);
+ if (mmu_ac != 0)
+ {
+ printf("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
+ m68k->ppc, mmu_ac);
+ }
+ break;
+ }
+ // fall through; unknown PMOVE mode unless MC68020 with MC68851
+
default:
printf("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, m68k->pc);
break;
diff --git a/src/emu/machine/8237dma.c b/src/emu/machine/8237dma.c
index c49650987e7..d923fade9a7 100644
--- a/src/emu/machine/8237dma.c
+++ b/src/emu/machine/8237dma.c
@@ -131,6 +131,7 @@ void i8237_device::device_reset()
m_eop = 1;
m_state = DMA8237_SI;
m_last_service_channel = 3;
+ m_service_channel = 0;
m_command = 0;
m_drq = 0;
diff --git a/src/emu/machine/mc146818.c b/src/emu/machine/mc146818.c
index 7060cd2a19b..606eb816b3e 100644
--- a/src/emu/machine/mc146818.c
+++ b/src/emu/machine/mc146818.c
@@ -147,12 +147,7 @@ void mc146818_device::device_start()
memset(m_data, 0, sizeof(m_data));
- if (m_type == MC146818_UTC) {
- // hack: for apollo we increase the update frequency to stay in sync with real time
- m_clock_timer->adjust(attotime::from_hz(2), 0, attotime::from_hz(2));
- } else {
- m_clock_timer->adjust(attotime::from_hz(1), 0, attotime::from_hz(1));
- }
+ m_clock_timer->adjust(attotime::from_hz(1), 0, attotime::from_hz(1));
m_periodic_timer->adjust(attotime::never);
m_period = attotime::never;
@@ -422,7 +417,8 @@ READ8_MEMBER( mc146818_device::read )
switch (m_index % MC146818_DATA_SIZE) {
case 0xa:
data = m_data[m_index % MC146818_DATA_SIZE];
- if ((space.machine().time() - m_last_refresh) < attotime::from_hz(32768))
+ // Update In Progress (UIP) time for 32768 Hz is 244+1984usec
+ if ((space.machine().time() - m_last_refresh) < attotime::from_usec(244+1984))
data |= 0x80;
#if 0
/* for pc1512 bios realtime clock test */