mirror of
https://github.com/holub/mame
synced 2025-04-27 02:33:13 +03:00
ns32000: add support for ns32532
* refactor slave interfaces * add crude /rdy emulation
This commit is contained in:
parent
61870af881
commit
d779f98bcb
@ -6,6 +6,64 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace ns32000
|
||||||
|
{
|
||||||
|
enum st_mask : unsigned
|
||||||
|
{
|
||||||
|
ST_ICI = 0x0, // bus idle (CPU busy)
|
||||||
|
ST_ICW = 0x1, // bus idle (CPU wait)
|
||||||
|
ST_ISE = 0x3, // bus idle (slave execution)
|
||||||
|
ST_IAM = 0x4, // interrupt acknowledge, master
|
||||||
|
ST_IAC = 0x5, // interrupt acknowledge, cascaded
|
||||||
|
ST_EIM = 0x6, // end of interrupt, master
|
||||||
|
ST_EIC = 0x7, // end of interrupt, cascaded
|
||||||
|
ST_SIF = 0x8, // sequential instruction fetch
|
||||||
|
ST_NIF = 0x9, // non-sequential instruction fetch
|
||||||
|
ST_ODT = 0xa, // operand data transfer
|
||||||
|
ST_RMW = 0xb, // read RMW operand
|
||||||
|
ST_EAR = 0xc, // effective address read
|
||||||
|
ST_SOP = 0xd, // slave operand
|
||||||
|
ST_SST = 0xe, // slave status
|
||||||
|
ST_SID = 0xf, // slave ID
|
||||||
|
|
||||||
|
ST_PT1 = 0xd, // access pte1 by MMU (32532)
|
||||||
|
ST_PT2 = 0xe, // access pte2 by MMU (32532)
|
||||||
|
ST_SLV = 0x10, // slave access ST4 (32532)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class ns32000_state_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void state_add(device_state_interface &parent, int &index) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ns32000_fpu_interface
|
||||||
|
: public device_interface
|
||||||
|
, public ns32000_state_interface
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ns32000_fpu_interface(machine_config const &mconfig, device_t &device)
|
||||||
|
: device_interface(device, "ns32000_fpu")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ns32000_mmu_interface
|
||||||
|
: public device_interface
|
||||||
|
, public ns32000_state_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
|
||||||
|
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool flag = false, bool suppress = false) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
|
||||||
|
: device_interface(device, "ns32000_mmu")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ns32000_slave_interface : public device_interface
|
class ns32000_slave_interface : public device_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -19,14 +77,15 @@ public:
|
|||||||
|
|
||||||
enum slave_status : u16
|
enum slave_status : u16
|
||||||
{
|
{
|
||||||
SLAVE_Q = 0x0001,
|
SLAVE_Q = 0x0001, // quit (1=error)
|
||||||
SLAVE_L = 0x0004,
|
SLAVE_L = 0x0004,
|
||||||
SLAVE_F = 0x0020,
|
SLAVE_F = 0x0020,
|
||||||
SLAVE_Z = 0x0040,
|
SLAVE_Z = 0x0040,
|
||||||
SLAVE_N = 0x0080,
|
SLAVE_N = 0x0080,
|
||||||
};
|
SLAVE_TS = 0x8000, // trap status (1=UND, 0=FPU)
|
||||||
|
|
||||||
virtual void state_add(device_state_interface &parent, int &index) = 0;
|
SLAVE_OK = 0,
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ns32000_slave_interface(machine_config const &mconfig, device_t &device, char const *type)
|
ns32000_slave_interface(machine_config const &mconfig, device_t &device, char const *type)
|
||||||
@ -38,19 +97,6 @@ protected:
|
|||||||
devcb_write_line m_out_scb;
|
devcb_write_line m_out_scb;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ns32000_mmu_interface : public ns32000_slave_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
|
|
||||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool debug = false) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
|
|
||||||
: ns32000_slave_interface(mconfig, device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ns32000_slow_slave_interface : public ns32000_slave_interface
|
class ns32000_slow_slave_interface : public ns32000_slave_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -69,7 +115,7 @@ protected:
|
|||||||
class ns32000_fast_slave_interface : public ns32000_slave_interface
|
class ns32000_fast_slave_interface : public ns32000_slave_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual u32 read_st(int *icount = nullptr) = 0;
|
virtual u32 read_st32(int *icount = nullptr) = 0;
|
||||||
virtual u32 read() = 0;
|
virtual u32 read() = 0;
|
||||||
virtual void write(u32 data) = 0;
|
virtual void write(u32 data) = 0;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,24 +8,23 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
template <int Width>
|
template <int HighBits, int Width>
|
||||||
class ns32000_device : public cpu_device
|
class ns32000_device : public cpu_device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T> void set_fpu(T &&tag) { m_fpu.set_tag(std::forward<T>(tag)); }
|
template <typename T> void set_fpu(T &&tag) { m_fpu.set_tag(std::forward<T>(tag)); }
|
||||||
template <typename T> void set_mmu(T &&tag) { m_mmu.set_tag(std::forward<T>(tag)); }
|
template <typename T> void set_mmu(T &&tag) { m_mmu.set_tag(std::forward<T>(tag)); }
|
||||||
|
|
||||||
// construction/destruction
|
void rdy_w(int state) { m_ready = !state; }
|
||||||
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, int databits, int addrbits);
|
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
// device_t overrides
|
// device_t implementation
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
// device_execute_interface overrides
|
// device_execute_interface implementation
|
||||||
virtual u32 execute_min_cycles() const noexcept override { return 1; }
|
virtual u32 execute_min_cycles() const noexcept override { return 1; }
|
||||||
virtual u32 execute_max_cycles() const noexcept override { return 6; }
|
virtual u32 execute_max_cycles() const noexcept override { return 6; }
|
||||||
virtual u32 execute_input_lines() const noexcept override { return 2; }
|
virtual u32 execute_input_lines() const noexcept override { return 2; }
|
||||||
@ -33,14 +32,14 @@ protected:
|
|||||||
virtual void execute_set_input(int inputnum, int state) override;
|
virtual void execute_set_input(int inputnum, int state) override;
|
||||||
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
|
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
|
||||||
|
|
||||||
// device_memory_interface overrides
|
// device_memory_interface implementation
|
||||||
virtual space_config_vector memory_space_config() const override;
|
virtual space_config_vector memory_space_config() const override;
|
||||||
virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
|
virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
|
||||||
|
|
||||||
// device_state_interface overrides
|
// device_state_interface implementation
|
||||||
virtual void state_string_export(device_state_entry const &entry, std::string &str) const override;
|
virtual void state_string_export(device_state_entry const &entry, std::string &str) const override;
|
||||||
|
|
||||||
// device_disasm_interface overrides
|
// device_disasm_interface implementation
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||||
|
|
||||||
enum addr_mode_type : unsigned
|
enum addr_mode_type : unsigned
|
||||||
@ -133,16 +132,27 @@ protected:
|
|||||||
s64 gen_read_sx(addr_mode mode);
|
s64 gen_read_sx(addr_mode mode);
|
||||||
void gen_write(addr_mode mode, u64 data);
|
void gen_write(addr_mode mode, u64 data);
|
||||||
|
|
||||||
|
// register helpers
|
||||||
|
u32 &SP();
|
||||||
|
u32 &SP(bool user);
|
||||||
|
virtual u32 const PSR_MSK() { return 0x0fe7; }
|
||||||
|
|
||||||
// other execution helpers
|
// other execution helpers
|
||||||
bool condition(unsigned const cc);
|
bool condition(unsigned const cc);
|
||||||
void flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction);
|
void flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction);
|
||||||
void interrupt(unsigned const type, u32 const return_address);
|
void interrupt(unsigned const type);
|
||||||
|
virtual void lpr(unsigned reg, addr_mode const mode, bool user, unsigned &tex);
|
||||||
|
virtual void spr(unsigned reg, addr_mode const mode, bool user, unsigned &tex);
|
||||||
|
|
||||||
// slave protocol helpers
|
// slave protocol helpers
|
||||||
u16 slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
virtual u16 slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
||||||
u16 slave_slow(ns32000_slow_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
u16 slave_slow(ns32000_slow_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
||||||
u16 slave_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
u16 slave_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
|
||||||
|
|
||||||
|
u32 m_cfg; // configuration register
|
||||||
|
|
||||||
|
typename memory_access<HighBits, Width, 0, ENDIANNESS_LITTLE>::specific m_bus[16];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 const m_address_mask;
|
u32 const m_address_mask;
|
||||||
|
|
||||||
@ -158,14 +168,12 @@ private:
|
|||||||
address_space_config m_rmw_config;
|
address_space_config m_rmw_config;
|
||||||
address_space_config m_ear_config;
|
address_space_config m_ear_config;
|
||||||
|
|
||||||
optional_device<ns32000_slave_interface> m_fpu;
|
optional_device<ns32000_fpu_interface> m_fpu;
|
||||||
optional_device<ns32000_mmu_interface> m_mmu;
|
optional_device<ns32000_mmu_interface> m_mmu;
|
||||||
|
|
||||||
// emulation state
|
// emulation state
|
||||||
int m_icount;
|
int m_icount;
|
||||||
|
|
||||||
typename memory_access<24, Width, 0, ENDIANNESS_LITTLE>::specific m_bus[16];
|
|
||||||
|
|
||||||
u32 m_ssp; // saved stack pointer
|
u32 m_ssp; // saved stack pointer
|
||||||
u16 m_sps; // saved program status
|
u16 m_sps; // saved program status
|
||||||
|
|
||||||
@ -177,44 +185,85 @@ private:
|
|||||||
u32 m_intbase; // interrupt base
|
u32 m_intbase; // interrupt base
|
||||||
u16 m_psr; // processor status
|
u16 m_psr; // processor status
|
||||||
u16 m_mod; // module
|
u16 m_mod; // module
|
||||||
u8 m_cfg; // configuration
|
|
||||||
|
|
||||||
u32 m_r[8];
|
u32 m_r[8];
|
||||||
u32 m_f[8];
|
|
||||||
|
|
||||||
bool m_nmi_line;
|
bool m_nmi_line;
|
||||||
bool m_int_line;
|
bool m_int_line;
|
||||||
bool m_wait;
|
bool m_wait;
|
||||||
bool m_sequential;
|
bool m_sequential;
|
||||||
|
bool m_ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ns32008_device : public ns32000_device<0>
|
class ns32008_device : public ns32000_device<24, 0>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ns32008_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
ns32008_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ns32016_device : public ns32000_device<1>
|
class ns32016_device : public ns32000_device<24, 1>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ns32016_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
ns32016_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ns32032_device : public ns32000_device<2>
|
class ns32032_device : public ns32000_device<24, 2>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ns32032_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
ns32032_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ns32332_device : public ns32000_device<2>
|
class ns32332_device : public ns32000_device<32, 2>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ns32332_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
ns32332_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ns32532_device
|
||||||
|
: public ns32000_device<32, 2>
|
||||||
|
, public ns32000_mmu_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ns32532_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
|
// ns32000_mmu_interface implementation
|
||||||
|
virtual void state_add(device_state_interface &parent, int &index) override;
|
||||||
|
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool rdwrval = false, bool suppress = false) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device_t implementation
|
||||||
|
virtual void device_add_mconfig(machine_config &config) override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
// device_memory_interface implementation
|
||||||
|
virtual space_config_vector memory_space_config() const override;
|
||||||
|
|
||||||
|
virtual u32 const PSR_MSK() override { return 0x0ff7; }
|
||||||
|
virtual void lpr(unsigned reg, addr_mode const mode, bool user, unsigned &tex) override;
|
||||||
|
virtual void spr(unsigned reg, addr_mode const mode, bool user, unsigned &tex) override;
|
||||||
|
virtual u16 slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
address_space_config m_pt1_config;
|
||||||
|
address_space_config m_pt2_config;
|
||||||
|
|
||||||
|
// memory management registers
|
||||||
|
u32 m_ptb[2]; // page table base pointer
|
||||||
|
u32 m_tear; // translation exception address
|
||||||
|
u32 m_mcr; // memory management control
|
||||||
|
u32 m_msr; // memory management status
|
||||||
|
|
||||||
|
// debug registers
|
||||||
|
u32 m_dcr; // debug condition
|
||||||
|
u32 m_dsr; // debug status
|
||||||
|
u32 m_car; // compare address
|
||||||
|
u32 m_bpc; // breakpoint program counter
|
||||||
|
};
|
||||||
|
|
||||||
DECLARE_DEVICE_TYPE(NS32008, ns32008_device)
|
DECLARE_DEVICE_TYPE(NS32008, ns32008_device)
|
||||||
DECLARE_DEVICE_TYPE(NS32016, ns32016_device)
|
DECLARE_DEVICE_TYPE(NS32016, ns32016_device)
|
||||||
DECLARE_DEVICE_TYPE(NS32032, ns32032_device)
|
DECLARE_DEVICE_TYPE(NS32032, ns32032_device)
|
||||||
DECLARE_DEVICE_TYPE(NS32332, ns32332_device)
|
DECLARE_DEVICE_TYPE(NS32332, ns32332_device)
|
||||||
|
DECLARE_DEVICE_TYPE(NS32532, ns32532_device)
|
||||||
|
|
||||||
#endif // MAME_CPU_NS32000_NS32000_H
|
#endif // MAME_CPU_NS32000_NS32000_H
|
||||||
|
@ -21,19 +21,19 @@ s32 ns32000_disassembler::displacement(offs_t pc, data_buffer const &opcodes, un
|
|||||||
u32 const byte2 = opcodes.r8(pc + bytes++);
|
u32 const byte2 = opcodes.r8(pc + bytes++);
|
||||||
u32 const byte3 = opcodes.r8(pc + bytes++);
|
u32 const byte3 = opcodes.r8(pc + bytes++);
|
||||||
|
|
||||||
return (s32((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 2) >> 2;
|
return util::sext((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3, 30);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// word displacement
|
// word displacement
|
||||||
u8 const byte1 = opcodes.r8(pc + bytes++);
|
u8 const byte1 = opcodes.r8(pc + bytes++);
|
||||||
|
|
||||||
return s16(((byte0 << 8) | byte1) << 2) >> 2;
|
return util::sext((byte0 << 8) | byte1, 14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// byte displacement
|
// byte displacement
|
||||||
return s8(byte0 << 1) >> 1;
|
return util::sext(byte0, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ns32000_disassembler::displacement_string(offs_t pc, data_buffer const &opcodes, unsigned &bytes, std::string const zero)
|
std::string ns32000_disassembler::displacement_string(offs_t pc, data_buffer const &opcodes, unsigned &bytes, std::string const zero)
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// copyright-holders:Patrick Mackinlay
|
// copyright-holders:Patrick Mackinlay
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* National Semiconductor 32081 Floating-Point Unit.
|
* National Semiconductor NS32081 Floating-Point Unit.
|
||||||
*
|
*
|
||||||
* Sources:
|
* Sources:
|
||||||
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
|
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - testing
|
* - NS32381
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(NS32081, ns32081_device, "ns32081", "National Semiconductor 32081 Floating-Point Unit")
|
DEFINE_DEVICE_TYPE(NS32081, ns32081_device, "ns32081", "National Semiconductor NS32081 Floating-Point Unit")
|
||||||
|
|
||||||
enum fsr_mask : u32
|
enum fsr_mask : u32
|
||||||
{
|
{
|
||||||
@ -83,6 +83,7 @@ enum size_code : unsigned
|
|||||||
ns32081_device::ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
ns32081_device::ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||||
: device_t(mconfig, NS32081, tag, owner, clock)
|
: device_t(mconfig, NS32081, tag, owner, clock)
|
||||||
, ns32000_slow_slave_interface(mconfig, *this)
|
, ns32000_slow_slave_interface(mconfig, *this)
|
||||||
|
, ns32000_fpu_interface(mconfig, *this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
class ns32081_device
|
class ns32081_device
|
||||||
: public device_t
|
: public device_t
|
||||||
, public ns32000_slow_slave_interface
|
, public ns32000_slow_slave_interface
|
||||||
|
, public ns32000_fpu_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||||
@ -24,7 +25,7 @@ public:
|
|||||||
virtual void write_op(u16 data) override;
|
virtual void write_op(u16 data) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device_t overrides
|
// device_t implementation
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// copyright-holders:Patrick Mackinlay
|
// copyright-holders:Patrick Mackinlay
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* National Semiconductor 32082 Memory Management Unit.
|
* National Semiconductor NS32082 Memory Management Unit.
|
||||||
*
|
*
|
||||||
* Sources:
|
* Sources:
|
||||||
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
|
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(NS32082, ns32082_device, "ns32082", "National Semiconductor 32082 Memory Management Unit")
|
DEFINE_DEVICE_TYPE(NS32082, ns32082_device, "ns32082", "National Semiconductor NS32082 Memory Management Unit")
|
||||||
|
|
||||||
enum state : unsigned
|
enum state : unsigned
|
||||||
{
|
{
|
||||||
@ -125,25 +125,6 @@ enum eia_mask : u32
|
|||||||
EIA_AS = 0x80000000, // address space
|
EIA_AS = 0x80000000, // address space
|
||||||
};
|
};
|
||||||
|
|
||||||
enum st_mask : unsigned
|
|
||||||
{
|
|
||||||
ST_ICI = 0x0, // bus idle (CPU busy)
|
|
||||||
ST_ICW = 0x1, // bus idle (CPU wait)
|
|
||||||
ST_ISE = 0x3, // bus idle (slave execution)
|
|
||||||
ST_IAM = 0x4, // interrupt acknowledge, master
|
|
||||||
ST_IAC = 0x5, // interrupt acknowledge, cascaded
|
|
||||||
ST_EIM = 0x6, // end of interrupt, master
|
|
||||||
ST_EIC = 0x7, // end of interrupt, cascaded
|
|
||||||
ST_SIF = 0x8, // sequential instruction fetch
|
|
||||||
ST_NIF = 0x9, // non-sequential instruction fetch
|
|
||||||
ST_ODT = 0xa, // operand data transfer
|
|
||||||
ST_RMW = 0xb, // read RMW operand
|
|
||||||
ST_EAR = 0xc, // effective address read
|
|
||||||
ST_SOP = 0xd, // slave operand
|
|
||||||
ST_SST = 0xe, // slave status
|
|
||||||
ST_SID = 0xf, // slave ID
|
|
||||||
};
|
|
||||||
|
|
||||||
ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||||
: device_t(mconfig, NS32082, tag, owner, clock)
|
: device_t(mconfig, NS32082, tag, owner, clock)
|
||||||
, ns32000_slow_slave_interface(mconfig, *this)
|
, ns32000_slow_slave_interface(mconfig, *this)
|
||||||
@ -402,12 +383,12 @@ void ns32082_device::set_msr(u32 data)
|
|||||||
m_msr = (m_msr & ~MSR_WM) | (data & MSR_WM);
|
m_msr = (m_msr & ~MSR_WM) | (data & MSR_WM);
|
||||||
}
|
}
|
||||||
|
|
||||||
ns32082_device::translate_result ns32082_device::translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs, bool debug)
|
ns32082_device::translate_result ns32082_device::translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs, bool suppress)
|
||||||
{
|
{
|
||||||
// update program flow trace state
|
// update program flow trace state
|
||||||
if (pfs && (m_msr & MSR_FT))
|
if (pfs && (m_msr & MSR_FT))
|
||||||
{
|
{
|
||||||
if (st == ST_NIF)
|
if (st == ns32000::ST_NIF)
|
||||||
{
|
{
|
||||||
m_pf[1] = m_pf[0];
|
m_pf[1] = m_pf[0];
|
||||||
m_pf[0] = address;
|
m_pf[0] = address;
|
||||||
@ -427,7 +408,7 @@ ns32082_device::translate_result ns32082_device::translate(address_space &space,
|
|||||||
|
|
||||||
bool const address_space = (m_msr & MSR_DS) && user;
|
bool const address_space = (m_msr & MSR_DS) && user;
|
||||||
unsigned const access_level = (user && !(m_msr & MSR_AO))
|
unsigned const access_level = (user && !(m_msr & MSR_AO))
|
||||||
? ((write || st == ST_RMW) ? PL_URW : PL_URO) : ((write || st == ST_RMW) ? PL_SRW : PL_SRO);
|
? ((write || st == ns32000::ST_RMW) ? PL_URW : PL_URO) : ((write || st == ns32000::ST_RMW) ? PL_SRW : PL_SRO);
|
||||||
|
|
||||||
u32 const ptb = ((m_ptb[address_space] & PTB_MS) >> 7) | (m_ptb[address_space] & PTB_AB);
|
u32 const ptb = ((m_ptb[address_space] & PTB_MS) >> 7) | (m_ptb[address_space] & PTB_AB);
|
||||||
|
|
||||||
@ -440,7 +421,7 @@ ns32082_device::translate_result ns32082_device::translate(address_space &space,
|
|||||||
|
|
||||||
if (access_level > (pte1 & PTE_PL) || !(pte1 & PTE_V))
|
if (access_level > (pte1 & PTE_PL) || !(pte1 & PTE_V))
|
||||||
{
|
{
|
||||||
if (m_state == IDLE && !debug)
|
if (m_state == IDLE && !suppress)
|
||||||
{
|
{
|
||||||
// reset error status
|
// reset error status
|
||||||
m_msr &= ~(MSR_EST | MSR_ED | MSR_TET | MSR_TE);
|
m_msr &= ~(MSR_EST | MSR_ED | MSR_TET | MSR_TE);
|
||||||
@ -472,7 +453,7 @@ ns32082_device::translate_result ns32082_device::translate(address_space &space,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set referenced
|
// set referenced
|
||||||
if (!(pte1 & PTE_R) && !debug)
|
if (!(pte1 & PTE_R) && !suppress)
|
||||||
space.write_word(pte1_address, u16(pte1 | PTE_R));
|
space.write_word(pte1_address, u16(pte1 | PTE_R));
|
||||||
|
|
||||||
// read level 2 page table entry
|
// read level 2 page table entry
|
||||||
@ -482,7 +463,7 @@ ns32082_device::translate_result ns32082_device::translate(address_space &space,
|
|||||||
|
|
||||||
if (access_level > (pte2 & PTE_PL) || !(pte2 & PTE_V))
|
if (access_level > (pte2 & PTE_PL) || !(pte2 & PTE_V))
|
||||||
{
|
{
|
||||||
if (m_state == IDLE && !debug)
|
if (m_state == IDLE && !suppress)
|
||||||
{
|
{
|
||||||
// reset error status
|
// reset error status
|
||||||
m_msr &= ~(MSR_EST | MSR_ED | MSR_TET | MSR_TE);
|
m_msr &= ~(MSR_EST | MSR_ED | MSR_TET | MSR_TE);
|
||||||
@ -512,7 +493,7 @@ ns32082_device::translate_result ns32082_device::translate(address_space &space,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set modified and referenced
|
// set modified and referenced
|
||||||
if ((!(pte2 & PTE_R) || (write && !(pte2 & PTE_M))) && !debug)
|
if ((!(pte2 & PTE_R) || (write && !(pte2 & PTE_M))) && !suppress)
|
||||||
space.write_word(pte2_address, u16(pte2 | (write ? PTE_M : 0) | PTE_R));
|
space.write_word(pte2_address, u16(pte2 | (write ? PTE_M : 0) | PTE_R));
|
||||||
|
|
||||||
address = ((pte1 & PTE_MS) >> 7) | (pte2 & PTE_PFN) | (address & VA_OFFSET);
|
address = ((pte1 & PTE_MS) >> 7) | (pte2 & PTE_PFN) | (address & VA_OFFSET);
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
virtual void write_id(u16 data) override;
|
virtual void write_id(u16 data) override;
|
||||||
virtual void write_op(u16 data) override;
|
virtual void write_op(u16 data) override;
|
||||||
|
|
||||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool debug = false) override;
|
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool suppress = false) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device_t overrides
|
// device_t overrides
|
||||||
|
@ -123,25 +123,6 @@ enum va_mask : u32
|
|||||||
VA_OFFSET = 0x00000fff,
|
VA_OFFSET = 0x00000fff,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum st_mask : unsigned
|
|
||||||
{
|
|
||||||
ST_ICI = 0x0, // bus idle (CPU busy)
|
|
||||||
ST_ICW = 0x1, // bus idle (CPU wait)
|
|
||||||
ST_ISE = 0x3, // bus idle (slave execution)
|
|
||||||
ST_IAM = 0x4, // interrupt acknowledge, master
|
|
||||||
ST_IAC = 0x5, // interrupt acknowledge, cascaded
|
|
||||||
ST_EIM = 0x6, // end of interrupt, master
|
|
||||||
ST_EIC = 0x7, // end of interrupt, cascaded
|
|
||||||
ST_SIF = 0x8, // sequential instruction fetch
|
|
||||||
ST_NIF = 0x9, // non-sequential instruction fetch
|
|
||||||
ST_ODT = 0xa, // operand data transfer
|
|
||||||
ST_RMW = 0xb, // read RMW operand
|
|
||||||
ST_EAR = 0xc, // effective address read
|
|
||||||
ST_SOP = 0xd, // slave operand
|
|
||||||
ST_SST = 0xe, // slave status
|
|
||||||
ST_SID = 0xf, // slave ID
|
|
||||||
};
|
|
||||||
|
|
||||||
ns32382_device::ns32382_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
ns32382_device::ns32382_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||||
: device_t(mconfig, NS32382, tag, owner, clock)
|
: device_t(mconfig, NS32382, tag, owner, clock)
|
||||||
, ns32000_fast_slave_interface(mconfig, *this)
|
, ns32000_fast_slave_interface(mconfig, *this)
|
||||||
@ -184,7 +165,7 @@ void ns32382_device::state_add(device_state_interface &parent, int &index)
|
|||||||
parent.state_add(index++, "MSR", m_msr).formatstr("%08X");
|
parent.state_add(index++, "MSR", m_msr).formatstr("%08X");
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ns32382_device::read_st(int *icount)
|
u32 ns32382_device::read_st32(int *icount)
|
||||||
{
|
{
|
||||||
if (m_state == STATUS)
|
if (m_state == STATUS)
|
||||||
{
|
{
|
||||||
@ -363,7 +344,7 @@ ns32382_device::translate_result ns32382_device::translate(address_space &space,
|
|||||||
|
|
||||||
bool const address_space = (m_mcr & MCR_DS) && user;
|
bool const address_space = (m_mcr & MCR_DS) && user;
|
||||||
unsigned const access_level = (user && !(m_mcr & MCR_AO))
|
unsigned const access_level = (user && !(m_mcr & MCR_AO))
|
||||||
? ((write || st == ST_RMW) ? PL_URW : PL_URO) : ((write || st == ST_RMW) ? PL_SRW : PL_SRO);
|
? ((write || st == ns32000::ST_RMW) ? PL_URW : PL_URO) : ((write || st == ns32000::ST_RMW) ? PL_SRW : PL_SRO);
|
||||||
|
|
||||||
if (m_state == IDLE && !debug)
|
if (m_state == IDLE && !debug)
|
||||||
m_msr &= ~(MSR_STT | MSR_UST | MSR_DDT | MSR_TEX);
|
m_msr &= ~(MSR_STT | MSR_UST | MSR_DDT | MSR_TEX);
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
virtual void state_add(device_state_interface &parent, int &index) override;
|
virtual void state_add(device_state_interface &parent, int &index) override;
|
||||||
|
|
||||||
// ns32000_fast_slave_interface overrides
|
// ns32000_fast_slave_interface overrides
|
||||||
virtual u32 read_st(int *icount = nullptr) override;
|
virtual u32 read_st32(int *icount = nullptr) override;
|
||||||
virtual void write(u32 data) override;
|
virtual void write(u32 data) override;
|
||||||
virtual u32 read() override;
|
virtual u32 read() override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user