Merge pull request #968 from MooglyGuy/master

Make SPARC use only one memory map
This commit is contained in:
R. Belmont 2016-06-18 17:11:08 -04:00 committed by GitHub
commit a97891ef0b
4 changed files with 267 additions and 147 deletions

View File

@ -9,7 +9,9 @@
// compatible instruction set. // compatible instruction set.
// //
// To-Do: // To-Do:
// - Ops: FBFcc, LDF, STF, SPARCv8 ops // - Ops: FBFcc, LDF, STF
// - Test: SPARCv8 ops are untested
// - Test: Traps are untested
// - FPU support // - FPU support
// - Coprocessor support // - Coprocessor support
// //
@ -20,6 +22,8 @@
#include "sparc.h" #include "sparc.h"
#include "sparcdefs.h" #include "sparcdefs.h"
#define SPARCV8 (0)
CPU_DISASSEMBLE( sparc ); CPU_DISASSEMBLE( sparc );
const device_type MB86901 = &device_creator<mb86901_device>; const device_type MB86901 = &device_creator<mb86901_device>;
@ -32,10 +36,7 @@ const int mb86901_device::WINDOW_COUNT = 7;
mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, MB86901, "Fujitsu MB86901", tag, owner, clock, "mb86901", __FILE__) : cpu_device(mconfig, MB86901, "Fujitsu MB86901", tag, owner, clock, "mb86901", __FILE__)
, m_as8_config("user_insn", ENDIANNESS_BIG, 32, 32) , m_program_config("program", ENDIANNESS_BIG, 32, 32)
, m_as9_config("supr_insn", ENDIANNESS_BIG, 32, 32)
, m_as10_config("user_data", ENDIANNESS_BIG, 32, 32)
, m_as11_config("supr_data", ENDIANNESS_BIG, 32, 32)
{ {
} }
@ -77,20 +78,7 @@ void mb86901_device::device_start()
memset(m_dbgregs, 0, 24 * sizeof(UINT32)); memset(m_dbgregs, 0, 24 * sizeof(UINT32));
m_user_insn = &space(AS_USER_INSN); m_program = &space(AS_PROGRAM);
m_super_insn = &space(AS_SUPER_INSN);
m_user_data = &space(AS_USER_DATA);
m_super_data = &space(AS_SUPER_DATA);
for (int i = 0; i < 256; i++)
{
m_spaces[i] = m_super_insn;
}
m_spaces[0] = m_super_insn;
m_spaces[8] = m_user_insn;
m_spaces[9] = m_super_insn;
m_spaces[10] = m_user_data;
m_spaces[11] = m_super_data;
// register our state for the debugger // register our state for the debugger
state_add(STATE_GENPC, "GENPC", m_pc).noshow(); state_add(STATE_GENPC, "GENPC", m_pc).noshow();
@ -190,10 +178,10 @@ void mb86901_device::device_reset()
m_icc = 0; m_icc = 0;
m_ec = false; m_ec = false;
m_ef = false; m_ef = false;
m_pil = 0; // double-check this m_pil = 0;
m_s = true; m_s = true;
m_ps = true; // double-check this m_ps = true;
m_et = true; // double-check this m_et = false;
m_cwp = 0; m_cwp = 0;
m_insn_asi = 9; m_insn_asi = 9;
@ -218,18 +206,8 @@ const address_space_config *mb86901_device::memory_space_config(address_spacenum
{ {
switch (spacenum) switch (spacenum)
{ {
case AS_USER_INSN: case AS_PROGRAM:
return &m_as8_config; return &m_program_config;
break;
case AS_SUPER_INSN:
return &m_as9_config;
break;
case AS_USER_DATA:
return &m_as10_config;
break;
case AS_SUPER_DATA:
return &m_as11_config;
break;
default: default:
return nullptr; return nullptr;
} }
@ -243,72 +221,72 @@ const address_space_config *mb86901_device::memory_space_config(address_spacenum
UINT32 mb86901_device::read_byte(UINT8 asi, UINT32 address) UINT32 mb86901_device::read_byte(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: data_access_exception, data_access_error traps
// TODO: check for traps return m_program->read_byte(address);
return LOAD_UBA(asi, address);
} }
INT32 mb86901_device::read_signed_byte(UINT8 asi, UINT32 address) INT32 mb86901_device::read_signed_byte(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: check for traps // TODO: data_access_exception, data_access_error traps
return LOAD_SBA(asi, address); return (((INT32)m_program->read_byte(address) << 24) >> 24);
} }
UINT32 mb86901_device::read_half(UINT8 asi, UINT32 address) UINT32 mb86901_device::read_half(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: data_access_exception, data_access_error traps // TODO: data_access_exception, data_access_error traps
return LOAD_UHA(asi, address); return m_program->read_word(address);
} }
INT32 mb86901_device::read_signed_half(UINT8 asi, UINT32 address) INT32 mb86901_device::read_signed_half(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: data_access_exception, data_access_error traps // TODO: data_access_exception, data_access_error traps
return LOAD_SHA(asi, address); return (((INT32)m_program->read_word(address) << 16) >> 16);
} }
UINT32 mb86901_device::read_word(UINT8 asi, UINT32 address) UINT32 mb86901_device::read_word(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: data_access_exception, data_access_error traps // TODO: data_access_exception, data_access_error traps
return LOAD_WA(asi, address); return m_program->read_dword(address);
} }
UINT64 mb86901_device::read_doubleword(UINT8 asi, UINT32 address) UINT64 mb86901_device::read_doubleword(UINT8 asi, UINT32 address)
{ {
m_asi = asi; m_asi = asi;
// TODO: data_access_exception, data_access_error traps // TODO: data_access_exception, data_access_error traps
return LOAD_DA(asi, address); return (((UINT64)m_program->read_dword(address) << 32) | m_program->read_dword(address+4));
} }
void mb86901_device::write_byte(UINT8 asi, UINT32 address, UINT8 data) void mb86901_device::write_byte(UINT8 asi, UINT32 address, UINT8 data)
{ {
m_asi = asi; m_asi = asi;
// TODO: check for traps // TODO: data_access_exception, data_access_error traps
STORE_BA(asi, address, data); m_program->write_byte(address, data);
} }
void mb86901_device::write_half(UINT8 asi, UINT32 address, UINT16 data) void mb86901_device::write_half(UINT8 asi, UINT32 address, UINT16 data)
{ {
m_asi = asi; m_asi = asi;
// TODO: check for traps // TODO: data_access_exception, data_access_error traps
STORE_HA(asi, address, data); m_program->write_word(address, data);
} }
void mb86901_device::write_word(UINT8 asi, UINT32 address, UINT32 data) void mb86901_device::write_word(UINT8 asi, UINT32 address, UINT32 data)
{ {
m_asi = asi; m_asi = asi;
// TODO: check for traps // TODO: data_access_exception, data_access_error traps
STORE_WA(asi, address, data); m_program->write_dword(address, data);
} }
void mb86901_device::write_doubleword(UINT8 asi, UINT32 address, UINT64 data) void mb86901_device::write_doubleword(UINT8 asi, UINT32 address, UINT64 data)
{ {
m_asi = asi; m_asi = asi;
// TODO: check for traps // TODO: data_access_exception, data_access_error traps
STORE_DA(asi, address, data); m_program->write_dword(address, (UINT32)(data >> 32));
m_program->write_dword(address+4, (UINT32)data);
} }
@ -475,17 +453,62 @@ bool mb86901_device::execute_group2(UINT32 op)
case 8: // addx case 8: // addx
SET_RDREG(arg1 + arg2 + (ICC_C_SET ? 1 : 0)); SET_RDREG(arg1 + arg2 + (ICC_C_SET ? 1 : 0));
break; break;
#if SPARCV8
case 10: // umul, SPARCv8 case 10: // umul, SPARCv8
{
UINT64 result = (UINT64)arg1 * (UINT64)arg2;
Y = (UINT32)(result >> 32);
SET_RDREG((UINT32)result);
break; break;
}
case 11: // smul, SPARCv8 case 11: // smul, SPARCv8
{
INT64 result = (INT64)(INT32)arg1 * (INT64)(INT32)arg2;
Y = (UINT32)((UINT64)result >> 32);
SET_RDREG((UINT32)result);
break; break;
}
#endif
case 12: // subx case 12: // subx
SET_RDREG(arg1 - arg2 - (ICC_C_SET ? 1 : 0)); SET_RDREG(arg1 - arg2 - (ICC_C_SET ? 1 : 0));
break; break;
#if SPARCV8
case 14: // udiv, SPARCv8 case 14: // udiv, SPARCv8
{
UINT64 dividend = ((UINT64)Y << 32) || arg1;
UINT32 divisor = arg2;
UINT64 quotient = dividend / divisor;
if (quotient > (0xffffffffL + (divisor - 1)))
{
quotient = 0xffffffff;
}
SET_RDREG((UINT32)quotient);
break; break;
}
case 15: // sdiv, SPARCv8 case 15: // sdiv, SPARCv8
{
INT64 dividend = ((INT64)(INT32)Y << 32) || arg1;
INT32 divisor = arg2;
INT64 quotient = dividend / divisor;
if (quotient > 0)
{
INT32 absdivisor = (divisor < 0) ? -divisor : divisor;
if (quotient > (0x7fffffffL + (absdivisor - 1)))
{
quotient = 0x7fffffff;
}
}
else if (quotient < 0)
{
if (quotient < (INT64)0xffffffff80000000L)
{
quotient = 0x80000000;
}
}
SET_RDREG((UINT32)quotient);
break; break;
}
#endif
case 16: // addcc case 16: // addcc
{ {
UINT32 result = arg1 + arg2; UINT32 result = arg1 + arg2;
@ -563,10 +586,24 @@ bool mb86901_device::execute_group2(UINT32 op)
SET_RDREG(result); SET_RDREG(result);
break; break;
} }
#if SPARCV8
case 26: // umulcc, SPARCv8 case 26: // umulcc, SPARCv8
{
UINT64 result = (UINT64)arg1 * (UINT64)arg2;
Y = (UINT32)(result >> 32);
TEST_ICC_NZ(result);
SET_RDREG((UINT32)result);
break; break;
}
case 27: // smulcc, SPARCv8 case 27: // smulcc, SPARCv8
{
INT64 result = (INT64)(INT32)arg1 * (INT64)(INT32)arg2;
Y = (UINT32)((UINT64)result >> 32);
TEST_ICC_NZ(result);
SET_RDREG((UINT32)result);
break; break;
}
#endif
case 28: // subxcc case 28: // subxcc
{ {
UINT32 c = (ICC_C_SET ? 1 : 0); UINT32 c = (ICC_C_SET ? 1 : 0);
@ -580,10 +617,60 @@ bool mb86901_device::execute_group2(UINT32 op)
SET_RDREG(result); SET_RDREG(result);
break; break;
} }
#if SPARCV8
case 30: // udivcc, SPARCv8 case 30: // udivcc, SPARCv8
{
UINT64 dividend = ((UINT64)Y << 32) || arg1;
UINT32 divisor = arg2;
UINT64 quotient = dividend / divisor;
bool v = false;
if (quotient > (0xffffffffL + (divisor - 1)))
{
quotient = 0xffffffff;
v = true;
}
TEST_ICC_NZ((UINT32)quotient);
if (v)
ICC_V_SET;
SET_RDREG((UINT32)quotient);
break; break;
case 31: // sdivcc, SPARCv8 }
case 31: // sdiv, SPARCv8
{
INT64 dividend = ((INT64)(INT32)Y << 32) || arg1;
INT32 divisor = arg2;
INT64 quotient = dividend / divisor;
bool v = false;
if (quotient > 0)
{
INT32 absdivisor = (divisor < 0) ? -divisor : divisor;
if (quotient > (0x7fffffffL + (absdivisor - 1)))
{
quotient = 0x7fffffff;
v = true;
}
}
else if (quotient < 0)
{
if (quotient < (INT64)0xffffffff80000000L)
{
quotient = 0x80000000;
v = true;
}
}
if (v)
ICC_V_SET;
TEST_ICC_NZ((UINT32)quotient);
SET_RDREG((UINT32)quotient);
break; break;
}
#endif
case 32: // taddcc case 32: // taddcc
{ {
UINT32 result = arg1 + arg2; UINT32 result = arg1 + arg2;
@ -636,7 +723,7 @@ bool mb86901_device::execute_group2(UINT32 op)
TEST_ICC_NZ(result); TEST_ICC_NZ(result);
if (result > arg1) if (result > arg1)
SET_ICC_C_FLAG; SET_ICC_C_FLAG;
SET_RDREG(result); SET_RDREG(result);
} }
break; break;
} }
@ -694,50 +781,109 @@ bool mb86901_device::execute_group2(UINT32 op)
{ // rd y { // rd y
SET_RDREG(m_y); SET_RDREG(m_y);
} }
#if SPARCV8
else if (RS1 == 15 && RD == 0) else if (RS1 == 15 && RD == 0)
{ // stbar, SPARCv8 { // stbar, SPARCv8
// no-op, as this implementation assumes Total Store Ordering
} }
else else
{ // rd asr, SPARCv8 { // rd asr, SPARCv8
logerror("Unimplemented instruction: rd asr");
} }
#endif
break; break;
case 41: // rd psr case 41: // rd psr
// TODO: check privilege if (IS_USER)
SET_RDREG(m_psr); {
queue_trap(sparc_privileged_instruction);
}
else
{
SET_RDREG(m_psr);
}
break; break;
case 42: // rd wim case 42: // rd wim
// TODO: check privilege if (IS_USER)
SET_RDREG(m_wim); {
queue_trap(sparc_privileged_instruction);
}
else
{
SET_RDREG(m_wim);
}
break; break;
case 43: // rd tbr case 43: // rd tbr
// TODO: check privilege if (IS_USER)
SET_RDREG(m_tbr); {
queue_trap(sparc_privileged_instruction);
}
else
{
SET_RDREG(m_tbr);
}
break; break;
case 48: case 48:
if (RD == 0) if (RD == 0)
{ // wr y { // wr y
m_y = arg1 ^ arg2; m_y = arg1 ^ arg2;
} }
#if SPARCV8
else else
{ // wr asr, SPARCv8 { // wr asr, SPARCv8
logerror("Unimplemented instruction: wr asr");
} }
#endif
break; break;
case 49: // wr psr case 49: // wr psr
// TODO: check privilege if (IS_USER)
m_psr = (arg1 ^ arg2) & ~PSR_ZERO_MASK; {
BREAK_PSR; queue_trap(sparc_privileged_instruction);
}
else
{
UINT32 new_psr = (arg1 ^ arg2) & ~PSR_ZERO_MASK;
if ((new_psr & PSR_CWP_MASK) >= WINDOW_COUNT)
{
queue_trap(sparc_illegal_instruction);
}
else
{
m_psr = new_psr;
BREAK_PSR;
}
}
break; break;
case 50: // wr wim case 50: // wr wim
// TODO: check privilege if (IS_USER)
m_wim = (arg1 ^ arg2) & 0x7f; {
queue_trap(sparc_privileged_instruction);
}
else
{
m_wim = (arg1 ^ arg2) & 0x7f;
}
break; break;
case 51: // wr tbr case 51: // wr tbr
// TODO: check privilege if (IS_USER)
m_tbr = (arg1 ^ arg2) & 0xfffff000; {
queue_trap(sparc_privileged_instruction);
}
else
{
m_tbr = (arg1 ^ arg2) & 0xfffff000;
}
break; break;
case 52: // FPop1 case 52: // FPop1
if (FPU_DISABLED)
{
queue_trap(sparc_floating_point_disabled);
}
break; break;
case 53: // FPop2 case 53: // FPop2
if (FPU_DISABLED)
{
queue_trap(sparc_floating_point_disabled);
}
break; break;
case 56: // jmpl case 56: // jmpl
{ {
@ -793,6 +939,8 @@ bool mb86901_device::execute_group2(UINT32 op)
m_cwp = new_cwp; m_cwp = new_cwp;
m_s = m_ps; m_s = m_ps;
m_insn_asi = m_s ? 9 : 8;
m_data_asi = m_s ? 11 : 10;
m_et = true; m_et = true;
UINT32 target = arg1 + arg2; UINT32 target = arg1 + arg2;
@ -802,11 +950,14 @@ bool mb86901_device::execute_group2(UINT32 op)
} }
case 58: // ticc case 58: // ticc
return execute_ticc(op); return execute_ticc(op);
#if SPARCV8
case 59: case 59:
// SPARCv8
if (RD == 0) if (RD == 0)
{ // flush, SPARCv8 { // flush, SPARCv8
} }
break; break;
#endif
case 60: // save case 60: // save
{ {
UINT8 new_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT; UINT8 new_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT;
@ -834,6 +985,7 @@ bool mb86901_device::execute_group2(UINT32 op)
break; break;
} }
default: default:
queue_trap(sparc_illegal_instruction);
break; break;
} }
@ -900,46 +1052,46 @@ void mb86901_device::execute_group3(UINT32 op)
{ {
case 0: // ld case 0: // ld
check_main_traps(op, false, 3, 0, false); check_main_traps(op, false, 3, 0, false);
SET_RDREG(read_word(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_word(m_data_asi, ADDRESS));
break; break;
case 1: // ldub case 1: // ldub
SET_RDREG(read_byte(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_byte(m_data_asi, ADDRESS));
break; break;
case 2: // lduh case 2: // lduh
check_main_traps(op, false, 1, 0, false); check_main_traps(op, false, 1, 0, false);
SET_RDREG(read_half(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_half(m_data_asi, ADDRESS));
break; break;
case 3: // ldd case 3: // ldd
check_main_traps(op, false, 7, 1, false); check_main_traps(op, false, 7, 1, false);
SET_RDREG(read_word(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_word(m_data_asi, ADDRESS));
REG(RD+1) = read_word(m_s ? 10 : 11, ADDRESS+4); REG(RD+1) = read_word(m_data_asi, ADDRESS+4);
break; break;
case 4: // st case 4: // st
check_main_traps(op, false, 3, 0, false); check_main_traps(op, false, 3, 0, false);
write_word(m_s ? 10 : 11, ADDRESS, RDREG); write_word(m_data_asi, ADDRESS, RDREG);
break; break;
case 5: // stb case 5: // stb
write_byte(m_s ? 10 : 11, ADDRESS, UINT8(RDREG)); write_byte(m_data_asi, ADDRESS, UINT8(RDREG));
break; break;
case 6: // sth case 6: // sth
check_main_traps(op, false, 1, 0, false); check_main_traps(op, false, 1, 0, false);
write_word(m_s ? 10 : 11, ADDRESS, UINT16(RDREG)); write_word(m_data_asi, ADDRESS, UINT16(RDREG));
break; break;
case 7: // std case 7: // std
check_main_traps(op, false, 7, 1, false); check_main_traps(op, false, 7, 1, false);
write_word(m_s ? 10 : 11, ADDRESS, RDREG); write_word(m_data_asi, ADDRESS, RDREG);
write_word(m_s ? 10 : 11, ADDRESS, REG(RD+1)); write_word(m_data_asi, ADDRESS, REG(RD+1));
break; break;
case 9: // ldsb case 9: // ldsb
SET_RDREG(read_signed_byte(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_signed_byte(m_data_asi, ADDRESS));
break; break;
case 10: // lsdh case 10: // lsdh
check_main_traps(op, false, 1, 0, false); check_main_traps(op, false, 1, 0, false);
SET_RDREG(read_signed_half(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_signed_half(m_data_asi, ADDRESS));
break; break;
case 13: // ldstub case 13: // ldstub
SET_RDREG(read_byte(m_s ? 10 : 11, ADDRESS)); SET_RDREG(read_byte(m_data_asi, ADDRESS));
write_byte(m_s ? 10 : 11, ADDRESS, 0xff); write_byte(m_data_asi, ADDRESS, 0xff);
break; break;
case 15: // swap, SPARCv8 case 15: // swap, SPARCv8
break; break;
@ -1102,6 +1254,7 @@ bool mb86901_device::execute_ticc(UINT32 op)
UINT32 arg2 = USEIMM ? SIMM7 : RS2REG; UINT32 arg2 = USEIMM ? SIMM7 : RS2REG;
UINT8 tt = 128 + ((RS1REG + arg2) & 0x7f); UINT8 tt = 128 + ((RS1REG + arg2) & 0x7f);
queue_trap(sparc_trap_instruction, tt); queue_trap(sparc_trap_instruction, tt);
m_icount -= 3;
return false; return false;
} }
@ -1154,10 +1307,13 @@ bool mb86901_device::invoke_queued_traps()
m_ps = m_s; m_ps = m_s;
m_s = true; m_s = true;
m_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT; m_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT;
MAKE_PSR; MAKE_PSR;
update_gpr_pointers(); update_gpr_pointers();
REG(17) = PC; REG(17) = PC;
REG(18) = nPC; REG(18) = nPC;
m_tbr |= m_queued_tt << 4; m_tbr |= m_queued_tt << 4;
PC = m_tbr; PC = m_tbr;
@ -1201,8 +1357,10 @@ void mb86901_device::execute_run()
break; break;
case 6: // branch on floating-point condition codes case 6: // branch on floating-point condition codes
break; break;
#if SPARCV8
case 7: // branch on coprocessor condition codes, SPARCv8 case 7: // branch on coprocessor condition codes, SPARCv8
break; break;
#endif
default: default:
break; break;
} }

View File

@ -9,11 +9,6 @@
#ifndef __SPARC_H__ #ifndef __SPARC_H__
#define __SPARC_H__ #define __SPARC_H__
#define AS_USER_INSN AS_0
#define AS_SUPER_INSN AS_1
#define AS_USER_DATA AS_2
#define AS_SUPER_DATA AS_3
class mb86901_device : public cpu_device class mb86901_device : public cpu_device
{ {
public: public:
@ -42,7 +37,7 @@ public:
// device_state_interface overrides // device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
UINT8 fetch_asi() { return m_asi; } UINT8 get_asi() { return m_asi; }
UINT32 pc() { return m_pc; } UINT32 pc() { return m_pc; }
protected: protected:
@ -59,10 +54,7 @@ protected:
bool evaluate_condition(UINT32 op); bool evaluate_condition(UINT32 op);
// address spaces // address spaces
const address_space_config m_as8_config; const address_space_config m_program_config;
const address_space_config m_as9_config;
const address_space_config m_as10_config;
const address_space_config m_as11_config;
// memory access // memory access
UINT32 read_byte(UINT8 asi, UINT32 address); UINT32 read_byte(UINT8 asi, UINT32 address);
@ -117,11 +109,7 @@ protected:
UINT32 m_dbgregs[24]; UINT32 m_dbgregs[24];
// address spaces // address spaces
address_space *m_user_insn; address_space *m_program;
address_space *m_super_insn;
address_space *m_user_data;
address_space *m_super_data;
address_space *m_spaces[256];
// processor configuration // processor configuration
static const int WINDOW_COUNT; static const int WINDOW_COUNT;

View File

@ -12,29 +12,7 @@
#ifndef __MB86901_DEFS_H__ #ifndef __MB86901_DEFS_H__
#define __MB86901_DEFS_H__ #define __MB86901_DEFS_H__
#define GET_OPCODE 0; { m_asi = m_insn_asi; op = m_spaces[m_insn_asi]->read_dword(m_pc); } #define GET_OPCODE 0; { m_asi = m_insn_asi; op = m_program->read_dword(m_pc); }
#define LOAD_SBA(asi,addr) (((INT32)m_spaces[asi]->read_byte(addr) << 24) >> 24)
#define LOAD_UBA(asi,addr) m_spaces[asi]->read_byte(addr)
#define LOAD_SHA(asi,addr) (((INT32)m_spaces[asi]->read_word(addr) << 16) >> 16)
#define LOAD_UHA(asi,addr) m_spaces[asi]->read_word(addr)
#define LOAD_WA(asi,addr) m_spaces[asi]->read_dword(addr)
#define LOAD_DA(asi,addr) (((UINT64)m_spaces[asi]->read_dword(addr) << 32) | m_spaces[asi]->read_dword(addr+4))
#define STORE_BA(asi,addr,data) { m_spaces[asi]->write_byte(addr,data); }
#define STORE_HA(asi,addr,data) { m_spaces[asi]->write_word(addr,data); }
#define STORE_WA(asi,addr,data) { m_spaces[asi]->write_dword(addr,data); }
#define STORE_DA(asi,addr,data) { m_spaces[asi]->write_dword(addr,(UINT32)(data >> 32)); m_spaces[asi]->write_dword(addr+4,(UINT32)data); }
#define LOAD_SB(addr) { m_asi = m_data_asi; LOAD_SBA(m_data_asi,addr); }
#define LOAD_UB(addr) { m_asi = m_data_asi; LOAD_UBA(m_data_asi,addr); }
#define LOAD_SH(addr) { m_asi = m_data_asi; LOAD_SHA(m_data_asi,addr); }
#define LOAD_UH(addr) { m_asi = m_data_asi; LOAD_UHA(m_data_asi,addr); }
#define LOAD_W(addr) { m_asi = m_data_asi; LOAD_WA(m_data_asi,addr); }
#define LOAD_D(addr) { m_asi = m_data_asi; LOAD_DA(m_data_asi,addr); }
#define STORE_B(addr,data) { m_asi = m_data_asi; STORE_BA(m_data_asi,addr); }
#define STORE_H(addr,data) { m_asi = m_data_asi; STORE_HA(m_data_asi,addr); }
#define STORE_W(addr,data) { m_asi = m_data_asi; STORE_WA(m_data_asi,addr); }
#define STORE_D(addr,data) { m_asi = m_data_asi; STORE_DA(m_data_asi,addr); }
#define PSR_CWP_MASK 0x0000001f #define PSR_CWP_MASK 0x0000001f
#define PSR_ET_SHIFT 5 #define PSR_ET_SHIFT 5
@ -88,8 +66,8 @@
#define TEST_ICC_NZ(x) do { m_psr &= ~PSR_ICC_MASK; m_psr |= (x & 0x80000000) ? PSR_N_MASK : 0; m_psr |= (x == 0) ? PSR_Z_MASK : 0; } while (0); #define TEST_ICC_NZ(x) do { m_psr &= ~PSR_ICC_MASK; m_psr |= (x & 0x80000000) ? PSR_N_MASK : 0; m_psr |= (x == 0) ? PSR_Z_MASK : 0; } while (0);
#define MAKE_PSR do { m_psr = (m_impl << PSR_IMPL_SHIFT) | (m_ver << PSR_VER_SHIFT) | (m_icc << PSR_ICC_SHIFT) | (m_ec ? PSR_EC_MASK : 0) | (m_ef ? PSR_EF_MASK : 0) | (m_pil << PSR_PIL_SHIFT) | (m_s ? PSR_S_MASK : 0) | (m_ps ? PSR_PS_MASK : 0) | (m_et ? PSR_ET_MASK : 0) | m_cwp; } while(0); #define MAKE_PSR do { m_psr = (m_impl << PSR_IMPL_SHIFT) | (m_ver << PSR_VER_SHIFT) | (m_icc << PSR_ICC_SHIFT) | (m_ec ? PSR_EC_MASK : 0) | (m_ef ? PSR_EF_MASK : 0) | (m_pil << PSR_PIL_SHIFT) | (m_s ? PSR_S_MASK : 0) | (m_ps ? PSR_PS_MASK : 0) | (m_et ? PSR_ET_MASK : 0) | m_cwp; m_insn_asi = m_s ? 9 : 8; m_data_asi = m_s ? 11 : 10; } while(0);
#define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; } while(0); #define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; m_insn_asi = m_s ? 9 : 8; m_data_asi = m_s ? 11 : 10; } while(0);
#define MAKE_ICC do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; } while(0); #define MAKE_ICC do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; } while(0);
#define IS_SUPERVISOR (m_psr & PSR_S_MASK) #define IS_SUPERVISOR (m_psr & PSR_S_MASK)
@ -98,6 +76,9 @@
#define TRAPS_ENABLED (m_psr & PSR_ET_MASK) #define TRAPS_ENABLED (m_psr & PSR_ET_MASK)
#define TRAPS_DISABLED (!TRAPS_ENABLED) #define TRAPS_DISABLED (!TRAPS_ENABLED)
#define FPU_ENABLED (m_psr & PSR_EF_MASK)
#define FPU_DISABLED (!FPU_ENABLED)
#define OP (op >> 30) // gangnam style #define OP (op >> 30) // gangnam style
#define OP2 ((op >> 22) & 7) #define OP2 ((op >> 22) & 7)
#define OP3 ((op >> 19) & 63) #define OP3 ((op >> 19) & 63)
@ -131,6 +112,8 @@
#define PC m_pc #define PC m_pc
#define nPC m_npc #define nPC m_npc
#define Y m_y
enum sparc_trap_type enum sparc_trap_type
{ {
sparc_reset = 0, sparc_reset = 0,

View File

@ -423,7 +423,7 @@ protected:
READ32_MEMBER( sun4_state::sun4_mmu_r ) READ32_MEMBER( sun4_state::sun4_mmu_r )
{ {
UINT8 asi = m_maincpu->fetch_asi(); UINT8 asi = m_maincpu->get_asi();
if (asi == 2 && !space.debugger_access()) if (asi == 2 && !space.debugger_access())
{ {
@ -439,11 +439,11 @@ READ32_MEMBER( sun4_state::sun4_mmu_r )
return 0; return 0;
case 8: // (d-)cache tags case 8: // (d-)cache tags
printf("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc()); logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc());
return 0xffffffff; return 0xffffffff;
case 9: // (d-)cache data case 9: // (d-)cache data
printf("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc()); logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
return 0xffffffff; return 0xffffffff;
case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur. case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
@ -456,13 +456,17 @@ READ32_MEMBER( sun4_state::sun4_mmu_r )
{ {
return m_rom_ptr[offset & 0x1ffff]; return m_rom_ptr[offset & 0x1ffff];
} }
else if (asi < 8 || asi > 11)
{
logerror("sun4: read asi %d byte offset %x, PC = %x\n", asi, offset << 2, m_maincpu->pc());
}
return 0; return 0;
} }
WRITE32_MEMBER( sun4_state::sun4_mmu_w ) WRITE32_MEMBER( sun4_state::sun4_mmu_w )
{ {
UINT8 asi = m_maincpu->fetch_asi(); UINT8 asi = m_maincpu->get_asi();
if (asi == 2) if (asi == 2)
{ {
@ -476,12 +480,12 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w )
m_system_enable = (UINT8)data; m_system_enable = (UINT8)data;
return; return;
case 8: // cache tags3 case 8: // cache tags
printf("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc()); logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc());
return; return;
case 9: // cache data case 9: // cache data
printf("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc()); logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
return; return;
case 0: // IDPROM case 0: // IDPROM
@ -489,24 +493,14 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w )
return; return;
} }
} }
else if (asi < 8 || asi > 11)
{
logerror("sun4: %08x to asi %d byte offset %x, PC = %x\n", data, asi, offset << 2, m_maincpu->pc());
}
} }
static ADDRESS_MAP_START(sun4_asi8, AS_USER_INSN, 32, sun4_state) static ADDRESS_MAP_START(sun4_mem, AS_PROGRAM, 32, sun4_state)
AM_RANGE(0x00000000, 0xefffffff) AM_READWRITE( sun4_mmu_r, sun4_mmu_w ) AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE( sun4_mmu_r, sun4_mmu_w )
ADDRESS_MAP_END
static ADDRESS_MAP_START(sun4_asi9, AS_SUPER_INSN, 32, sun4_state)
AM_RANGE(0x00000000, 0xefffffff) AM_READWRITE( sun4_mmu_r, sun4_mmu_w )
AM_RANGE(0xffe80000, 0xffefffff) AM_ROM AM_REGION("user1", 0)
ADDRESS_MAP_END
static ADDRESS_MAP_START(sun4_asi10, AS_USER_DATA, 32, sun4_state)
AM_RANGE(0x00000000, 0xefffffff) AM_READWRITE( sun4_mmu_r, sun4_mmu_w )
ADDRESS_MAP_END
static ADDRESS_MAP_START(sun4_asi11, AS_SUPER_DATA, 32, sun4_state)
AM_RANGE(0x00000000, 0xefffffff) AM_READWRITE( sun4_mmu_r, sun4_mmu_w )
AM_RANGE(0xffe80000, 0xffefffff) AM_ROM AM_REGION("user1", 0)
ADDRESS_MAP_END ADDRESS_MAP_END
/* Input ports */ /* Input ports */
@ -526,10 +520,7 @@ void sun4_state::machine_start()
static MACHINE_CONFIG_START( sun4, sun4_state ) static MACHINE_CONFIG_START( sun4, sun4_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD("maincpu", MB86901, 16670000) MCFG_CPU_ADD("maincpu", MB86901, 16670000)
MCFG_DEVICE_ADDRESS_MAP(AS_USER_INSN, sun4_asi8) MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem)
MCFG_DEVICE_ADDRESS_MAP(AS_SUPER_INSN, sun4_asi9)
MCFG_DEVICE_ADDRESS_MAP(AS_USER_DATA, sun4_asi10)
MCFG_DEVICE_ADDRESS_MAP(AS_SUPER_DATA, sun4_asi11)
MACHINE_CONFIG_END MACHINE_CONFIG_END
/* /*