summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/i960/i960.h
blob: 7251a091fd05da0bce01fa7b821f2f540da6bfde (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
// license:BSD-3-Clause
// copyright-holders:Farfetch'd, R. Belmont
#pragma once

#ifndef __I960_H__
#define __I960_H__


enum
{
	I960_PFP = 0,
	I960_SP  = 1,
	I960_RIP = 2,
	I960_FP  = 31,

	I960_R0 = 0,
	I960_R1 = 1,
	I960_R2 = 2,
	I960_R3 = 3,
	I960_R4 = 4,
	I960_R5 = 5,
	I960_R6 = 6,
	I960_R7 = 7,
	I960_R8 = 8,
	I960_R9 = 9,
	I960_R10 = 10,
	I960_R11 = 11,
	I960_R12 = 12,
	I960_R13 = 13,
	I960_R14 = 14,
	I960_R15 = 15,
	I960_G0 = 16,
	I960_G1 = 17,
	I960_G2 = 18,
	I960_G3 = 19,
	I960_G4 = 20,
	I960_G5 = 21,
	I960_G6 = 22,
	I960_G7 = 23,
	I960_G8 = 24,
	I960_G9 = 25,
	I960_G10 = 26,
	I960_G11 = 27,
	I960_G12 = 28,
	I960_G13 = 29,
	I960_G14 = 30,
	I960_G15 = 31,

	I960_SAT = 32,
	I960_PRCB = 33,
	I960_PC = 34,
	I960_AC = 35,
	I960_IP = 36,
	I960_PIP = 37
};

enum
{
	I960_IRQ0 = 0,
	I960_IRQ1 = 1,
	I960_IRQ2 = 2,
	I960_IRQ3 = 3
};


enum { I960_RCACHE_SIZE = 4 };


class i960_cpu_device :  public cpu_device
{
public:
	// construction/destruction
	i960_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	// call from any read/write handler for a memory area that can't be bursted
	// on the real hardware (e.g. Model 2's interrupt control registers)
	void i960_noburst() { m_bursting = 0; }

	void i960_stall() { m_IP = m_PIP; }

protected:
	// device-level overrides
	virtual void device_start();
	virtual void device_reset();

	// device_execute_interface overrides
	virtual UINT32 execute_min_cycles() const { return 1; } /* ???? TODO: Exact timing unknown */
	virtual UINT32 execute_max_cycles() const { return 1; } /* ???? TODO: Exact timing unknown */
	virtual UINT32 execute_input_lines() const { return 4; }
	virtual UINT32 execute_default_irq_vector() const { return 0xffffffff; }
	virtual void execute_run();
	virtual void execute_set_input(int inputnum, int state);

	// device_memory_interface overrides
	virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }

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

	// device_disasm_interface overrides
	virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
	virtual UINT32 disasm_max_opcode_bytes() const { return 8; }
	virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);

private:
	address_space_config m_program_config;

	UINT32 m_r[0x20];
	UINT32 m_rcache[I960_RCACHE_SIZE][0x10];
	UINT32 m_rcache_frame_addr[I960_RCACHE_SIZE];
	// rcache_pos = how deep in the stack we are.  0-(I960_RCACHE_SIZE-1) means in-cache.
	// I960_RCACHE_SIZE or greater means out of cache, must save to memory.
	INT32 m_rcache_pos;

	double m_fp[4];

	UINT32 m_SAT;
	UINT32 m_PRCB;
	UINT32 m_PC;
	UINT32 m_AC;
	UINT32 m_IP;
	UINT32 m_PIP;
	UINT32 m_ICR;
	int m_bursting;

	int m_immediate_irq;
	int m_immediate_vector;
	int  m_immediate_pri;

	address_space *m_program;
	direct_read_data *m_direct;

	int m_icount;

	UINT32 i960_read_dword_unaligned(UINT32 address);
	UINT16 i960_read_word_unaligned(UINT32 address);
	void i960_write_dword_unaligned(UINT32 address, UINT32 data);
	void i960_write_word_unaligned(UINT32 address, UINT16 data);
	void send_iac(UINT32 adr);
	UINT32 get_ea(UINT32 opcode);
	UINT32 get_1_ri(UINT32 opcode);
	UINT32 get_2_ri(UINT32 opcode);
	UINT64 get_2_ri64(UINT32 opcode);
	void set_ri(UINT32 opcode, UINT32 val);
	void set_ri2(UINT32 opcode, UINT32 val, UINT32 val2);
	void set_ri64(UINT32 opcode, UINT64 val);
	double get_1_rif(UINT32 opcode);
	double get_2_rif(UINT32 opcode);
	void set_rif(UINT32 opcode, double val);
	double get_1_rifl(UINT32 opcode);
	double get_2_rifl(UINT32 opcode);
	void set_rifl(UINT32 opcode, double val);
	UINT32 get_1_ci(UINT32 opcode);
	UINT32 get_2_ci(UINT32 opcode);
	UINT32 get_disp(UINT32 opcode);
	UINT32 get_disp_s(UINT32 opcode);
	void cmp_s(INT32 v1, INT32 v2);
	void cmp_u(UINT32 v1, UINT32 v2);
	void concmp_s(INT32 v1, INT32 v2);
	void concmp_u(UINT32 v1, UINT32 v2);
	void cmp_d(double v1, double v2);
	void bxx(UINT32 opcode, int mask);
	void bxx_s(UINT32 opcode, int mask);
	void test(UINT32 opcode, int mask);
	void execute_op(UINT32 opcode);
	void take_interrupt(int vector, int lvl);
	void check_irqs();
	void do_call(UINT32 adr, int type, UINT32 stack);
	void do_ret_0();
	void do_ret();
};


extern const device_type I960;


#endif /* __I960_H__ */