summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i8087.h
blob: 9344ca2e68e2aae5833bda8e651fb6b513d221cd (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:Philip Bennett, Carl

// SoftFloat 2 lacks an include guard
#ifndef softfloat_h
#define softfloat_h 1
#include "softfloat/milieu.h"
#include "softfloat/softfloat.h"
#endif

DECLARE_DEVICE_TYPE(I8087, i8087_device)

class i8087_device : public device_t
{
public:
	i8087_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
	template <class Object> void set_space_88(Object &&tag, int spacenum) { m_space.set_tag(std::forward<Object>(tag), spacenum); m_space.set_data_width(8); }
	template <class Object> void set_space_86(Object &&tag, int spacenum) { m_space.set_tag(std::forward<Object>(tag), spacenum); m_space.set_data_width(16); }
	auto irq() { return m_int_handler.bind(); }
	auto busy() { return m_busy_handler.bind(); }

	DECLARE_WRITE32_MEMBER(insn_w); // the real 8087 sniffs the bus watching for esc, can't do that here so provide a poke spot
	DECLARE_WRITE32_MEMBER(addr_w);

protected:
	i8087_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

private:
	address_space &space() { return *m_space; }

	typedef void (i8087_device::*x87_func)(u8 modrm);
	required_address_space m_space;
	devcb_write_line m_int_handler;
	devcb_write_line m_busy_handler;
	emu_timer *m_timer;
	floatx80 m_reg[8];

	u32 m_ea;
	u32 m_pc;
	u32 m_ppc;
	u16 m_opcode;
	u16 m_cw;
	u16 m_sw;
	u16 m_tw;
	int m_icount;

	x87_func m_opcode_table_d8[256];
	x87_func m_opcode_table_d9[256];
	x87_func m_opcode_table_da[256];
	x87_func m_opcode_table_db[256];
	x87_func m_opcode_table_dc[256];
	x87_func m_opcode_table_dd[256];
	x87_func m_opcode_table_de[256];
	x87_func m_opcode_table_df[256];

	void execute();
	void CYCLES(int cycles) {m_icount = cycles;}
	u8 FETCH();
	u8 READ8(offs_t ea);
	void WRITE8(offs_t ea, u8 data);
	u16 READ16(offs_t ea);
	void WRITE16(offs_t ea, u16 data);
	u32 READ32(offs_t ea);
	void WRITE32(offs_t ea, u32 data);
	u64 READ64(offs_t ea);
	void WRITE64(offs_t ea, u64 data);
	floatx80 READ80(offs_t);
	void WRITE80(offs_t ea, floatx80 t);
	void set_stack_top(int top);
	void set_tag(int reg, int tag);
	void write_stack(int i, floatx80 value, bool update_tag);
	void set_stack_underflow();
	void set_stack_overflow();
	int inc_stack();
	int dec_stack();
	int check_exceptions();
	void write_cw(u16 cw);
	floatx80 add(floatx80 a, floatx80 b);
	floatx80 sub(floatx80 a, floatx80 b);
	floatx80 mul(floatx80 a, floatx80 b);
	floatx80 div(floatx80 a, floatx80 b);
	void fadd_m32real(u8 modrm);
	void fadd_m64real(u8 modrm);
	void fadd_st_sti(u8 modrm);
	void fadd_sti_st(u8 modrm);
	void faddp(u8 modrm);
	void fiadd_m32int(u8 modrm);
	void fiadd_m16int(u8 modrm);
	void fsub_m32real(u8 modrm);
	void fsub_m64real(u8 modrm);
	void fsub_st_sti(u8 modrm);
	void fsub_sti_st(u8 modrm);
	void fsubp(u8 modrm);
	void fisub_m32int(u8 modrm);
	void fisub_m16int(u8 modrm);
	void fsubr_m32real(u8 modrm);
	void fsubr_m64real(u8 modrm);
	void fsubr_st_sti(u8 modrm);
	void fsubr_sti_st(u8 modrm);
	void fsubrp(u8 modrm);
	void fisubr_m32int(u8 modrm);
	void fisubr_m16int(u8 modrm);
	void fdiv_m32real(u8 modrm);
	void fdiv_m64real(u8 modrm);
	void fdiv_st_sti(u8 modrm);
	void fdiv_sti_st(u8 modrm);
	void fdivp(u8 modrm);
	void fidiv_m32int(u8 modrm);
	void fidiv_m16int(u8 modrm);
	void fdivr_m32real(u8 modrm);
	void fdivr_m64real(u8 modrm);
	void fdivr_st_sti(u8 modrm);
	void fdivr_sti_st(u8 modrm);
	void fdivrp(u8 modrm);
	void fidivr_m32int(u8 modrm);
	void fidivr_m16int(u8 modrm);
	void fmul_m32real(u8 modrm);
	void fmul_m64real(u8 modrm);
	void fmul_st_sti(u8 modrm);
	void fmul_sti_st(u8 modrm);
	void fmulp(u8 modrm);
	void fimul_m32int(u8 modrm);
	void fimul_m16int(u8 modrm);
	void fprem(u8 modrm);
	void fprem1(u8 modrm);
	void fsqrt(u8 modrm);
	void f2xm1(u8 modrm);
	void fyl2x(u8 modrm);
	void fyl2xp1(u8 modrm);
	void fptan(u8 modrm);
	void fpatan(u8 modrm);
	void fsin(u8 modrm);
	void fcos(u8 modrm);
	void fsincos(u8 modrm);
	void fld_m32real(u8 modrm);
	void fld_m64real(u8 modrm);
	void fld_m80real(u8 modrm);
	void fld_sti(u8 modrm);
	void fild_m16int(u8 modrm);
	void fild_m32int(u8 modrm);
	void fild_m64int(u8 modrm);
	void fbld(u8 modrm);
	void fst_m32real(u8 modrm);
	void fst_m64real(u8 modrm);
	void fst_sti(u8 modrm);
	void fstp_m32real(u8 modrm);
	void fstp_m64real(u8 modrm);
	void fstp_m80real(u8 modrm);
	void fstp_sti(u8 modrm);
	void fist_m16int(u8 modrm);
	void fist_m32int(u8 modrm);
	void fistp_m16int(u8 modrm);
	void fistp_m32int(u8 modrm);
	void fistp_m64int(u8 modrm);
	void fbstp(u8 modrm);
	void fld1(u8 modrm);
	void fldl2t(u8 modrm);
	void fldl2e(u8 modrm);
	void fldpi(u8 modrm);
	void fldlg2(u8 modrm);
	void fldln2(u8 modrm);
	void fldz(u8 modrm);
	void fnop(u8 modrm);
	void fchs(u8 modrm);
	void fabs(u8 modrm);
	void fscale(u8 modrm);
	void frndint(u8 modrm);
	void fxtract(u8 modrm);
	void ftst(u8 modrm);
	void fxam(u8 modrm);
	void ficom_m16int(u8 modrm);
	void ficom_m32int(u8 modrm);
	void ficomp_m16int(u8 modrm);
	void ficomp_m32int(u8 modrm);
	void fcom_m32real(u8 modrm);
	void fcom_m64real(u8 modrm);
	void fcom_sti(u8 modrm);
	void fcomp_m32real(u8 modrm);
	void fcomp_m64real(u8 modrm);
	void fcomp_sti(u8 modrm);
	void fcompp(u8 modrm);
	void fucom_sti(u8 modrm);
	void fucomp_sti(u8 modrm);
	void fucompp(u8 modrm);
	void fdecstp(u8 modrm);
	void fincstp(u8 modrm);
	void fclex(u8 modrm);
	void ffree(u8 modrm);
	void fdisi(u8 modrm);
	void feni(u8 modrm);
	void finit(u8 modrm);
	void fldcw(u8 modrm);
	void fstcw(u8 modrm);
	void fldenv(u8 modrm);
	void fstenv(u8 modrm);
	void fsave(u8 modrm);
	void frstor(u8 modrm);
	void fxch(u8 modrm);
	void fxch_sti(u8 modrm);
	void fstsw_ax(u8 modrm);
	void fstsw_m2byte(u8 modrm);
	void invalid(u8 modrm);
	void group_d8(u8 modrm);
	void group_d9(u8 modrm);
	void group_da(u8 modrm);
	void group_db(u8 modrm);
	void group_dc(u8 modrm);
	void group_dd(u8 modrm);
	void group_de(u8 modrm);
	void group_df(u8 modrm);
	void build_opcode_table_d8();
	void build_opcode_table_d9();
	void build_opcode_table_da();
	void build_opcode_table_db();
	void build_opcode_table_dc();
	void build_opcode_table_dd();
	void build_opcode_table_de();
	void build_opcode_table_df();
	void build_opcode_table();

};