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
|
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
#ifndef MAME_MACHINE_WTL3132_H
#define MAME_MACHINE_WTL3132_H
#pragma once
#include "softfloat3/source/include/softfloat.h"
class wtl3132_device : public device_t
{
public:
wtl3132_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
// output lines
auto out_fpcn() { return m_fpcn_cb.bind(); }
auto out_fpex() { return m_fpex_cb.bind(); }
auto out_zero() { return m_zero_cb.bind(); }
auto out_port_x() { return m_port_x_cb.bind(); }
// code and data ports
void c_port_w(u64 data) { m_c_port = data; }
u32 x_port_r() { return m_x_port.v; }
void x_port_w(u32 data) { m_x_port.v = data; }
// input lines
void abort_w(int state) { m_abort = state; }
void clk_w(int state);
void neut_w(int state) { m_neut = state; }
void stall_w(int state) { m_stall = state; }
// disassembly helpers
static std::string disassemble(u64 const code);
static std::string reg(unsigned const reg);
static std::string mbin(u64 const code);
static std::string abin(u64 const code);
static std::string adst(u64 const code);
void state_add(device_state_interface &parent, unsigned base = 0)
{
parent.state_add(base + 0, "MODE", m_mode).formatstr("%04X");
parent.state_add(base + 1, "T1", m_t1.v).formatstr("%08X");
parent.state_add(base + 2, "T2", m_t2.v).formatstr("%08X");
parent.state_add(base + 3, "T3", m_t3.v).formatstr("%08X");
for (unsigned i = 0; i < 32; i++)
parent.state_add(base + i + 4, util::string_format("F%d", i).c_str(), m_f[i].v).formatstr("%08X");
}
enum code_mask : u64
{
// opcode is 34 bits wide
M_ENCN = 0x0'00000003, // condition output select
M_MBIN = 0x0'00000004, // mbin input select
M_ADST = 0x0'00000018, // alu destination select
M_ABIN = 0x0'000000e0, // abin input select
M_DADD = 0x0'00001f00, // d port register address
M_IOCT = 0x0'00006000, // i/o control
M_CWEN = 0x0'00008000, // c port write enable (active low)
M_CADD = 0x0'001f0000, // c port register address
M_BADD = 0x0'03e00000, // b port register address
M_AADD = 0x0'7c000000, // a port register address
M_F = 0x3'80000000, // function code
// internal pipeline control flag
M_CANCEL = 0x80000000'00000000, // cancelled
};
enum code_shift : unsigned
{
S_ENCN = 0, // condition output select
S_MBIN = 2, // mbin input select
S_ADST = 3, // alu destination select
S_ABIN = 5, // abin input select
S_DADD = 8, // d port register address
S_IOCT = 13, // i/o control
S_CWEN = 15, // c port write enable (active low)
S_CADD = 16, // c port register address
S_BADD = 21, // b port register address
S_AADD = 26, // a port register address
S_F = 31, // function code
};
enum function_code : unsigned
{
F_MISC = 0, // miscellaneous
F_FSUBR = 1, // negate and add
F_FSUB = 2, // subtract
F_FADD = 3, // add
F_FMNA = 5, // multiply, negate and add
F_FMNS = 6, // multiply, negate and subtract
F_FMAC = 7, // multiply and accumulate
};
enum misc_code : unsigned
{
MF_FCLSR = 0, // clear status register
MF_FSTSR = 1, // read status register
MF_FMODE = 3, // load mode register
MF_FABS = 4, // absolute value
MF_FLOAT = 5, // fixed-to-float
MF_FIX = 6, // float-to-fixed
MF_FLUT = 7, // lookup operation
};
enum mode_mask : u16
{
MODE_IBA = 0x0001, // internal bypass A enable
MODE_RTN = 0x0002, // round to nearest
MODE_IBP = 0x0008, // input bypass enable
MODE_OBP = 0x0010, // output bypass enable
MODE_FXO = 0x0020, // fpex overflow enable
MODE_CPL = 0x0040, // coprocessor load enable
MODE_FXH = 0x0100, // fpex active high
MODE_DBP = 0x0200, // double pump enable (3332 only)
MODE_IBB = 0x0800, // internal bypass B enable
MODE_YLI = 0x1000, // Y late input enable (3332 only)
};
protected:
virtual void device_start() override;
virtual void device_reset() override;
void stage1(unsigned const index);
void stage2(unsigned const index);
void stage3(unsigned const index);
void stage4(unsigned const index);
private:
devcb_write_line m_fpcn_cb;
devcb_write_line m_fpex_cb;
devcb_write_line m_zero_cb;
devcb_write32 m_port_x_cb;
// output line state
bool m_fpcn_state;
bool m_fpex_state;
bool m_zero_state;
// port state
u64 m_c_port;
float32_t m_x_port;
float32_t m_x_in;
float32_t m_x_out;
// input line state
int m_abort;
int m_neut;
int m_stall;
// pipeline state
u64 m_slot[4];
unsigned m_head;
// registers
u16 m_mode;
float32_t m_f[32];
float32_t m_t1;
float32_t m_t2;
float32_t m_t3;
bool m_cr;
bool m_sr;
bool m_zr;
// C bus
float32_t m_c_bus_data;
unsigned m_c_bus_addr;
bool m_c_bus_cwen;
// multiplier inputs and output
float32_t m_ma_in;
float32_t m_mb_in;
float32_t m_m_out;
// accumulator buffers, inputs and output
float32_t m_aa_in[2];
float32_t m_ab_in[2];
float32_t m_a_out;
};
DECLARE_DEVICE_TYPE(WTL3132, wtl3132_device)
#endif // MAME_MACHINE_WTL3132_H
|