ns32000: initial cpu emulation

* implemented most instructions
* preliminary interrupt/trap support
* no fpu or mmu yet
* took over copyright with permission
* minor disassembler improvements
This commit is contained in:
Patrick Mackinlay 2020-09-08 19:13:18 +07:00
parent 21998119ac
commit d54e5e79b2
3 changed files with 2192 additions and 174 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,21 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/*****************************************************************************
*
* ns32000.h
*
* NS32000 CPU family
*
*****************************************************************************/
// copyright-holders:Patrick Mackinlay
#ifndef MAME_CPU_NS32016_NS32016_H
#define MAME_CPU_NS32016_NS32016_H
#ifndef MAME_CPU_NS32000_NS32000_H
#define MAME_CPU_NS32000_NS32000_H
#pragma once
/***********************************************************************
CONSTANTS
***********************************************************************/
/***********************************************************************
TYPE DEFINITIONS
***********************************************************************/
class ns32000_cpu_device : public cpu_device
class ns32000_device : public cpu_device
{
public:
// construction/destruction
ns32000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
protected:
ns32000_cpu_device(const machine_config &mconfig, device_type type, const char *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, int databits, int addrbits);
// device-level overrides
// device_t overrides
virtual void device_start() override;
virtual void device_reset() override;
@ -45,105 +27,106 @@ protected:
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; }
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
// device_state_interface overrides
virtual void state_string_export(device_state_entry const &entry, std::string &str) const override;
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
// addressing modes
enum
{
ADDRESSING_MODE_REGISTER_0 = 0,
ADDRESSING_MODE_REGISTER_1,
ADDRESSING_MODE_REGISTER_2,
ADDRESSING_MODE_REGISTER_3,
ADDRESSING_MODE_REGISTER_4,
ADDRESSING_MODE_REGISTER_5,
ADDRESSING_MODE_REGISTER_6,
ADDRESSING_MODE_REGISTER_7,
ADDRESSING_MODE_REGISTER_0_RELATIVE,
ADDRESSING_MODE_REGISTER_1_RELATIVE,
ADDRESSING_MODE_REGISTER_2_RELATIVE,
ADDRESSING_MODE_REGISTER_3_RELATIVE,
ADDRESSING_MODE_REGISTER_4_RELATIVE,
ADDRESSING_MODE_REGISTER_5_RELATIVE,
ADDRESSING_MODE_REGISTER_6_RELATIVE,
ADDRESSING_MODE_REGISTER_7_RELATIVE,
ADDRESSING_MODE_FRAME_MEMORY_RELATIVE,
ADDRESSING_MODE_STACK_MEMORY_RELATIVE,
ADDRESSING_MODE_STATIC_MEMORY_RELATIVE,
ADDRESSING_MODE_RESERVED,
ADDRESSING_MODE_IMMEDIATE,
ADDRESSING_MODE_ABSOLUTE,
ADDRESSING_MODE_EXTERNAL,
ADDRESSING_MODE_TOP_OF_STACK,
ADDRESSING_MODE_FRAME_MEMORY,
ADDRESSING_MODE_STACK_MEMORY,
ADDRESSING_MODE_STATIC_MEMORY,
ADDRESSING_MODE_PROGRAM_MEMORY,
ADDRESSING_MODE_INDEX_BYTES,
ADDRESSING_MODE_INDEX_WORDS,
ADDRESSING_MODE_INDEX_DOUBLE_WORDS,
ADDRESSING_MODE_INDEX_QUAD_WORDS,
};
// registers
enum
{
NS32000_PC = 1,
NS32000_SB, NS32000_FP, NS32000_SP1, NS32000_SP0, NS32000_INTBASE, NS32000_PSR, NS32000_MOD,
NS32000_R0, NS32000_R1, NS32000_R2, NS32000_R3, NS32000_R4, NS32000_R5, NS32000_R6, NS32000_R7,
};
private:
enum addr_mode_type : unsigned
{
IMM,
REG,
MEM,
IND,
EXT,
TOS,
};
struct addr_mode
{
addr_mode(unsigned gen)
: gen(gen)
, base(0)
, disp(0)
{};
void rmw() { if (type == TOS) type = MEM; }
void addr() { if (type == TOS) type = MEM; }
void regaddr() { if (type == TOS) type = MEM; }
unsigned gen;
addr_mode_type type;
u32 base;
u32 disp;
};
// instruction decoding helpers
s32 displacement(unsigned &bytes);
void decode(addr_mode *mode, unsigned size, unsigned &bytes);
// operand read/write helpers
u32 ea(addr_mode const mode);
u32 gen_read(addr_mode mode, unsigned size);
s32 gen_read_sx(addr_mode mode, unsigned size);
void gen_write(addr_mode mode, unsigned size, u64 data);
// other execution helpers
bool condition(unsigned const cc);
void flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction);
void interrupt(unsigned const vector, u32 const return_address, bool const trap = true);
// configuration
address_space_config m_program_config;
address_space_config m_interrupt_config;
// emulation state
int m_icount;
u32 m_pc;
u32 m_sb;
u32 m_fp;
u32 m_sp1;
u32 m_sp0;
u32 m_intbase;
u32 m_psr;
u32 m_mod;
memory_access<24, 1, 0, ENDIANNESS_LITTLE>::cache m_bus[16];
u32 m_pc; // program counter
u32 m_sb; // static base
u32 m_fp; // frame pointer
u32 m_sp1; // user stack pointer
u32 m_sp0; // interrupt stack pointer
u32 m_intbase; // interrupt base
u16 m_psr; // processor status
u16 m_mod; // module
u8 m_cfg; // configuration
u32 m_r[8];
u32 m_f[8];
u8 m_irq_line;
u8 m_nmi_line;
bool m_nmi_line;
bool m_int_line;
bool m_wait;
};
class ns32008_cpu_device : public ns32000_cpu_device
class ns32008_device : public ns32000_device
{
public:
ns32008_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
ns32008_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
};
class ns32016_cpu_device : public ns32000_cpu_device
class ns32016_device : public ns32000_device
{
public:
ns32016_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
ns32016_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
};
class ns32032_cpu_device : public ns32000_cpu_device
class ns32032_device : public ns32000_device
{
public:
ns32032_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
ns32032_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
};
/***********************************************************************
DEVICE TYPE DECLARATIONS
***********************************************************************/
DECLARE_DEVICE_TYPE(NS32008, ns32008_device)
DECLARE_DEVICE_TYPE(NS32016, ns32016_device)
DECLARE_DEVICE_TYPE(NS32032, ns32032_device)
DECLARE_DEVICE_TYPE(NS32008, ns32008_cpu_device)
DECLARE_DEVICE_TYPE(NS32016, ns32016_cpu_device)
DECLARE_DEVICE_TYPE(NS32032, ns32032_cpu_device)
#endif // MAME_CPU_NS32016_NS32016_H
#endif // MAME_CPU_NS32000_NS32000_H

View File

@ -272,7 +272,7 @@ const char *const ns32000_disassembler::Format2[] =
};
const char *const ns32000_disassembler::Format3[] =
{
"CXPD", "Trap (UND)", "BICPSR", "Trap (UND)", "JUMP", "Trap (UND)", "BISPSR", "Trap (UND)", "Trap (UND)", "Trap (UND)", "ADJSPi", "Trap (UND)", "JSR", "Trap (UND)", "CASEi", "Trap (UND)"
"CXPD", "Trap (UND)", "BICPSRi", "Trap (UND)", "JUMP", "Trap (UND)", "BISPSRi", "Trap (UND)", "Trap (UND)", "Trap (UND)", "ADJSPi", "Trap (UND)", "JSR", "Trap (UND)", "CASEi", "Trap (UND)"
};
const char *const ns32000_disassembler::Format4[] =
{
@ -569,7 +569,10 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l
/* External */
disp1 = get_disp(pc, opcodes);
disp2 = get_disp(pc, opcodes);
util::stream_format(stream, "EXT(%d)+%d", disp1, disp2);
if (disp2)
util::stream_format(stream, "EXT(%d)+%d", disp1, disp2);
else
util::stream_format(stream, "EXT(%d)", disp1);
break;
case 0x17:
/* Top Of Stack */