1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
#ifndef MAME_CPU_NS32000_NS32000_H
#define MAME_CPU_NS32000_NS32000_H
#pragma once
#include "slave.h"
template <int Width>
class ns32000_device : public cpu_device
{
public:
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)); }
// construction/destruction
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, const XTAL &clock);
protected:
ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, const XTAL &clock, int databits, int addrbits);
// device_t overrides
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual u32 execute_min_cycles() const noexcept override { return 1; }
virtual u32 execute_max_cycles() const noexcept override { return 6; }
virtual u32 execute_input_lines() const noexcept override { return 2; }
virtual void execute_run() 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; }
// 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;
enum addr_mode_type : unsigned
{
IMM, // immediate
REG, // register
MEM, // memory space
REL, // memory relative
EXT, // external
TOS, // top of stack
};
enum access_class : unsigned
{
NONE,
READ,
WRITE,
RMW,
ADDR,
REGADDR,
};
enum size_code : unsigned
{
SIZE_B = 0,
SIZE_W = 1,
SIZE_D = 3,
SIZE_Q = 7,
};
// time needed to read or write a memory operand
unsigned top(size_code const size, u32 const address = 0) const
{
unsigned const tmmu = m_mmu ? 1 : 0;
switch (size)
{
case SIZE_B: return 3 + tmmu;
case SIZE_W: return (address & 1) ? 7 + 2 * tmmu : 3 + tmmu;
case SIZE_D: return (address & 1) ? 11 + 3 * tmmu : 7 + 2 * tmmu;
case SIZE_Q: return (address & 1) ? 19 + 5 * tmmu : 15 + 4 * tmmu;
}
// can't happen
return 0;
}
struct addr_mode
{
addr_mode(unsigned gen)
: gen(gen)
, access(NONE)
, slave(false)
, base(0)
, disp(0)
, imm(0)
, tea(0)
{};
void read_i(size_code code) { access = READ; size = code; }
void read_f(size_code code) { access = READ; size = code; slave = true; }
void write_i(size_code code) { access = WRITE; size = code; }
void write_f(size_code code) { access = WRITE; size = code; slave = true; }
void rmw_i(size_code code) { access = RMW; size = code; }
void rmw_f(size_code code) { access = RMW; size = code; slave = true; }
void addr() { access = ADDR; size = SIZE_D; }
void regaddr() { access = REGADDR; size = SIZE_D; }
unsigned gen;
addr_mode_type type;
access_class access;
size_code size;
bool slave;
u32 base;
u32 disp;
u64 imm;
unsigned tea;
};
// memory accessors
template <typename T> T mem_read(unsigned st, u32 address, bool user = false, bool pfs = false);
template <typename T> void mem_write(unsigned st, u32 address, u64 data, bool user = false);
// instruction fetch/decode helpers
template <typename T> T fetch(unsigned &bytes);
s32 displacement(unsigned &bytes);
void decode(addr_mode *mode, unsigned &bytes);
// operand read/write helpers
u32 ea(addr_mode const mode);
u64 gen_read(addr_mode mode);
s64 gen_read_sx(addr_mode mode);
void gen_write(addr_mode mode, 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 type, u32 const return_address);
// slave protocol helpers
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_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2);
private:
u32 const m_address_mask;
// configuration
address_space_config m_program_config;
address_space_config m_iam_config;
address_space_config m_iac_config;
address_space_config m_eim_config;
address_space_config m_eic_config;
address_space_config m_sif_config;
address_space_config m_nif_config;
address_space_config m_odt_config;
address_space_config m_rmw_config;
address_space_config m_ear_config;
optional_device<ns32000_slave_interface> m_fpu;
optional_device<ns32000_mmu_interface> m_mmu;
// emulation state
int m_icount;
typename memory_access<24, Width, 0, ENDIANNESS_LITTLE>::specific m_bus[16];
u32 m_ssp; // saved stack pointer
u16 m_sps; // saved program status
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];
bool m_nmi_line;
bool m_int_line;
bool m_wait;
bool m_sequential;
};
class ns32008_device : public ns32000_device<0>
{
public:
ns32008_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
};
class ns32016_device : public ns32000_device<1>
{
public:
ns32016_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
};
class ns32032_device : public ns32000_device<2>
{
public:
ns32032_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
};
class ns32332_device : public ns32000_device<2>
{
public:
ns32332_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
};
DECLARE_DEVICE_TYPE(NS32008, ns32008_device)
DECLARE_DEVICE_TYPE(NS32016, ns32016_device)
DECLARE_DEVICE_TYPE(NS32032, ns32032_device)
DECLARE_DEVICE_TYPE(NS32332, ns32332_device)
#endif // MAME_CPU_NS32000_NS32000_H
|