summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh/sh7604.h
blob: bc0bfcc33308e115da7b0ad1e8b05c639eff7690 (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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller, R. Belmont

// sh7604, sh2 variant

#ifndef MAME_CPU_SH_SH7604_H
#define MAME_CPU_SH_SH7604_H

#pragma once

#include "sh2.h"

#define SH2_DMA_KLUDGE_CB(name)  int name(uint32_t src, uint32_t dst, uint32_t data, int size)
#define SH2_DMA_FIFO_DATA_AVAILABLE_CB(name)  int name(uint32_t src, uint32_t dst, uint32_t data, int size)
#define SH2_FTCSR_READ_CB(name)  void name(uint32_t data)


class sh7604_device : public sh2_device
{
public:
	typedef device_delegate<int (uint32_t src, uint32_t dst, uint32_t data, int size)> dma_kludge_delegate;
	typedef device_delegate<int (uint32_t src, uint32_t dst, uint32_t data, int size)> dma_fifo_data_available_delegate;
	typedef device_delegate<void (uint32_t data)> ftcsr_read_delegate;

	sh7604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_is_slave(int slave) { m_is_slave = slave; }

	template <typename... T> void set_dma_kludge_callback(T &&... args) { m_dma_kludge_cb.set(std::forward<T>(args)...); }

	template <typename... T> void set_dma_fifo_data_available_callback(T &&... args) { m_dma_fifo_data_available_cb.set(std::forward<T>(args)...); }

	template <typename... T> void set_ftcsr_read_callback(T &&... args) { m_ftcsr_read_cb.set(std::forward<T>(args)...); }

	void sh2_notify_dma_data_available();

protected:
	sh7604_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines);

	virtual void device_start() override ATTR_COLD;
	virtual void device_reset() override ATTR_COLD;

	virtual void sh2_exception(const char *message, int irqline) override;

	uint32_t m_test_irq;
	int m_internal_irq_vector;

private:
	enum
	{
		ICF  = 0x80,
		OCFA = 0x08,
		OCFB = 0x04,
		OVF  = 0x02,
		CCLRA = 0x01
	};

	void sh7604_map(address_map &map) ATTR_COLD;

	uint32_t sh2_internal_a5();

	// SCI
	uint8_t smr_r();
	void smr_w(uint8_t data);
	uint8_t brr_r();
	void brr_w(uint8_t data);
	uint8_t scr_r();
	void scr_w(uint8_t data);
	uint8_t tdr_r();
	void tdr_w(uint8_t data);
	uint8_t ssr_r();
	void ssr_w(uint8_t data);
	uint8_t rdr_r();

	// FRT / FRC
	uint8_t tier_r();
	void tier_w(uint8_t data);
	uint16_t frc_r();
	void frc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint8_t ftcsr_r();
	void ftcsr_w(uint8_t data);
	uint16_t ocra_b_r();
	void ocra_b_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint8_t frc_tcr_r();
	void frc_tcr_w(uint8_t data);
	uint8_t tocr_r();
	void tocr_w(uint8_t data);
	uint16_t frc_icr_r();

	// INTC
	uint16_t ipra_r();
	void ipra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t iprb_r();
	void iprb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t vcra_r();
	void vcra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t vcrb_r();
	void vcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t vcrc_r();
	void vcrc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t vcrd_r();
	void vcrd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t vcrwdt_r();
	void vcrwdt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint32_t vcrdiv_r();
	void vcrdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint16_t intc_icr_r();
	void intc_icr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);

	// DIVU
	uint32_t dvsr_r();
	void dvsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t dvdnt_r();
	void dvdnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t dvdnth_r();
	void dvdnth_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t dvdntl_r();
	void dvdntl_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	uint32_t dvcr_r();
	void dvcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	// DMAC
	template <int Channel> uint32_t vcrdma_r();
	template <int Channel> void vcrdma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	template <int Channel> uint8_t drcr_r();
	template <int Channel> void drcr_w(uint8_t data);
	template <int Channel> uint32_t sar_r();
	template <int Channel> void sar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	template <int Channel> uint32_t dar_r();
	template <int Channel> void dar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	template <int Channel> uint32_t dmac_tcr_r();
	template <int Channel> void dmac_tcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	template <int Channel> uint32_t chcr_r();
	template <int Channel> void chcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t dmaor_r();
	void dmaor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	// WTC
	uint16_t wtcnt_r();
	void wtcnt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint16_t rstcsr_r();
	void rstcsr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);

	// misc
	uint16_t fmr_sbycr_r();
	void fmr_sbycr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
	uint8_t ccr_r();
	void ccr_w(uint8_t data);

	// BSC
	uint32_t bcr1_r();
	void bcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t bcr2_r();
	void bcr2_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t wcr_r();
	void wcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t mcr_r();
	void mcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t rtcsr_r();
	void rtcsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t rtcor_r();
	void rtcor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t rtcnt_r();
	void rtcnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	virtual void set_frt_input(int state) override;

	// SCI
	uint8_t m_smr, m_brr, m_scr, m_tdr, m_ssr;

	// FRT / FRC
	uint8_t m_tier, m_ftcsr, m_frc_tcr, m_tocr;
	uint16_t m_frc;
	uint16_t m_ocra, m_ocrb, m_frc_icr;

	// INTC
	struct
	{
		uint8_t frc;
		uint8_t sci;
		uint8_t divu;
		uint8_t dmac;
		uint8_t wdt;
	} m_irq_level;

	struct
	{
		uint8_t fic;
		uint8_t foc;
		uint8_t fov;
		uint8_t divu;
		uint8_t dmac[2];
	} m_irq_vector;

	uint16_t m_ipra, m_iprb;
	uint16_t m_vcra, m_vcrb, m_vcrc, m_vcrd, m_vcrwdt, m_vcrdiv, m_intc_icr, m_vcrdma[2];
	bool m_vecmd, m_nmie;

	// DIVU
	bool m_divu_ovf, m_divu_ovfie;
	uint32_t m_dvsr, m_dvdntl, m_dvdnth;

	// WTC
	uint8_t m_wtcnt, m_wtcsr;
	uint8_t m_rstcsr;
	uint16_t m_wtcw[2];

	// DMAC
	struct
	{
		uint8_t drcr;
		uint32_t sar;
		uint32_t dar;
		uint32_t tcr;
		uint32_t chcr;
	} m_dmac[2];
	uint8_t m_dmaor;

	// misc
	uint8_t m_sbycr, m_ccr;

	// BSC
	uint32_t m_bcr1, m_bcr2, m_wcr, m_mcr, m_rtcsr, m_rtcor, m_rtcnt;

	uint64_t m_frc_base;

	int m_frt_input;

	emu_timer *m_timer;
	emu_timer *m_wdtimer;
	emu_timer *m_dma_current_active_timer[2];
	int m_dma_timer_active[2];
	uint8_t m_dma_irq[2];

	int m_active_dma_incs[2];
	int m_active_dma_incd[2];
	int m_active_dma_size[2];
	int m_active_dma_steal[2];
	uint32_t m_active_dma_src[2];
	uint32_t m_active_dma_dst[2];
	uint32_t m_active_dma_count[2];

	int m_is_slave;

	dma_kludge_delegate              m_dma_kludge_cb;
	dma_fifo_data_available_delegate m_dma_fifo_data_available_cb;
	ftcsr_read_delegate              m_ftcsr_read_cb;

	TIMER_CALLBACK_MEMBER(sh2_timer_callback);
	TIMER_CALLBACK_MEMBER(sh2_wdtimer_callback);
	TIMER_CALLBACK_MEMBER(sh2_dma_current_active_callback);
	void sh2_timer_resync();
	void sh2_timer_activate();
	void sh2_wtcnt_recalc();
	void sh2_wdt_activate();
	void sh2_do_dma(int dmach);
	void sh2_dmac_check(int dma);
	void sh2_recalc_irq();
};

DECLARE_DEVICE_TYPE(SH7604, sh7604_device)

#endif // MAME_CPU_SH_SH7604_H