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]
This commit is contained in:
Miodrag Milanovic 2012-02-18 10:58:12 +00:00
parent c19f1f8c49
commit f47c0750ce
5 changed files with 117 additions and 13 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

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