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 */