summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/pace/pace.h
blob: ed9cadf39b906fa7263c7c0cad67b9360b1b0755 (plain) (blame)
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
221
222
223
224
// license:BSD-3-Clause
// copyright-holders:AJR
/***************************************************************************

    National Semiconductor PACE/INS8900

****************************************************************************
                            _____________
                   D04   1 |             | 40  D05
                   D03   2 |             | 39  D06
                   D02   3 |             | 38  D07
                   D01   4 |             | 37  D08
                   D00   5 |             | 36  D09
                   IDS   6 |             | 35  D10
                   ODS   7 |             | 34  D11
                  NADS   8 |             | 33  D12
                 NHALT   9 |             | 32  D13
                CONTIN  10 |   IPC-16A   | 31  D14
                  JC14  11 |   INS8900   | 30  D15
                  JC15  12 |             | 29  Vgg/Vdd*
                  JC13  13 |             | 28  BPS
                  NIR5  14 |             | 27  EXTEND
                  NIR4  15 |             | 26  NINIT
                  NIR3  16 |             | 25  CLK/Vcc*
                  NIR2  17 |             | 24  NCLK/CLKX
                   F11  18 |             | 23  Vbb*
                   F12  19 |             | 22  F14
                  Vss*  20 |_____________| 21  F13

    * For PACE (IPC-16A): Vss = +5V, Vbb = +8V, Vgg = -12V
    * For INS8900: Vss = GND, Vbb = -8V, Vcc = +5V, Vdd = +12V

***************************************************************************/

#ifndef MAME_CPU_PACE_PACE_H
#define MAME_CPU_PACE_PACE_H

#pragma once


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> pace_device

class pace_device : public cpu_device
{
public:
	// register enumeration
	enum {
		PACE_PC,
		PACE_FR,
		PACE_AC0, PACE_AC1, PACE_AC2, PACE_AC3,
		PACE_STKD,
		PACE_STK0, PACE_STK1, PACE_STK2, PACE_STK3, PACE_STK4,
		PACE_STK5, PACE_STK6, PACE_STK7, PACE_STK8, PACE_STK9
	};

	// callback configuration
	auto jc13_callback() { return m_jc_callback[0].bind(); }
	auto jc14_callback() { return m_jc_callback[1].bind(); }
	auto jc15_callback() { return m_jc_callback[2].bind(); }
	auto f11_callback() { return m_flag_callback[0].bind(); }
	auto f12_callback() { return m_flag_callback[1].bind(); }
	auto f13_callback() { return m_flag_callback[2].bind(); }
	auto f14_callback() { return m_flag_callback[3].bind(); }

protected:
	// construction/destruction
	pace_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);

	// device_t implementation
	virtual void device_start() override;
	virtual void device_reset() override;

	// device_execute_interface implementation
	virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
	virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 4); }
	virtual void execute_run() override;
	virtual void execute_set_input(int irqline, int state) override;

	// device_disasm_interface implementation
	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

	// device_memory_interface implementation
	virtual space_config_vector memory_space_config() const override;

	// device_state_interface implementation
	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

private:
	enum class cycle : u8 {
		IFETCH_M1, LEA_M2, RDEA_M3,

		BOC_M4, BOC_M5,
		JMP_M4,
		JMP_IND_M4,
		JSR_M4, JSR_M5,
		JSR_IND_M4, JSR_IND_M5,
		RTS_M4, RTS_M5,
		RTI_M4, RTI_M5, RTI_M6,
		BRANCH,

		SKNE_M4, SKNE_M5,
		SKG_M4, SKG_M5, SKG_M6, SKG_M7,
		SKAZ_M4, SKAZ_M5,
		ISZ_M4, ISZ_M5, ISZ_M6, ISZ_M7,
		DSZ_M4, DSZ_M5, DSZ_M6, DSZ_M7,
		AISZ_M4, AISZ_M5,
		SKIP,

		LD_M4,
		LD_IND_M4, LD_IND_M5,
		ST_M4,
		ST_IND_M4,
		LSEX_M4,

		AND_M4,
		OR_M4,
		ADD_M4,
		SUBB_M4,
		DECA_M4, DECA_M5, DECA_M6, DECA_M7,

		LI_M4,
		RCPY_M4,
		RXCH_M4, RXCH_M5, RXCH_M6,
		XCHRS_M4, XCHRS_M5, XCHRS_M6,
		CFR_M4,
		CRF_M4,
		PUSH_M4,
		PULL_M4,
		PUSHF_M4,
		PULLF_M4,

		RADD_M4,
		RADC_M4,
		RAND_M4,
		RXOR_M4,
		CAI_M4, CAI_M5,

		SHL_M4, SHL_M5, SHL_M6, SHL_M7, SHL_M8,
		SHR_M4, SHR_M5, SHR_M6, SHR_M7, SHR_M8,
		ROL_M4, ROL_M5, ROL_M6, ROL_M7, ROL_M8,
		ROR_M4, ROR_M5, ROR_M6, ROR_M7, ROR_M8,

		HALT_M4,
		PFLG_M4, PFLG_M5, PFLG_M6,

		UNKNOWN
	};

	static const cycle s_decode[64];

	// flag and interrupt helpers
	void set_control_flag(u8 fc);
	void reset_control_flag(u8 fc);
	void set_fr(u16 r);

	// conditions and ALU helpers
	bool sign_bit(u16 r) const noexcept;
	bool equals_0(u16 r) const noexcept;
	bool poll_condition(u8 cc);
	static void sign_extend(u16 &r);
	void add(u16 &dr, u16 sr, bool c);
	void decimal_add(u16 &dr, u16 sr, unsigned stage);
	void prepare_shift();
	void shift_left(u16 &r, bool rotate);
	void shift_right(u16 &r, bool rotate);

	// stack helpers
	void stack_push(u16 r);
	u16 stack_pull();

	// execution helpers
	void read_instruction();
	u16 get_effective_address();
	void read_effective_address();
	void write_effective_address(u16 r);
	cycle execute_one();

	// address space and cache
	address_space_config m_space_config;
	memory_access<16, 1, -1, ENDIANNESS_LITTLE>::cache m_cache;
	memory_access<16, 1, -1, ENDIANNESS_LITTLE>::specific m_space;

	// callback objects
	devcb_read_line m_bps_callback;
	devcb_read_line::array<3> m_jc_callback;
	devcb_write_line::array<4> m_flag_callback;

	// core registers
	u16 m_fr;
	u16 m_pc;
	u16 m_mdr;
	u16 m_mar;
	u16 m_ac[4];

	// stack
	u8 m_stkp;
	u8 m_stack_depth;
	u16 m_stack[10];

	// execution state
	u16 m_ppc;
	u16 m_cir;
	bool m_shift_link;
	cycle m_cycle;
	s32 m_icount;
};

// ======================> ins8900_device

class ins8900_device : public pace_device
{
public:
	// device type constructor
	ins8900_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

// device type declarations
DECLARE_DEVICE_TYPE(INS8900, ins8900_device)

#endif // MAME_CPU_PACE_PACE_H