summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/smpc.h
blob: b62d13dc1d35646aad845547b19edf64c37cf662 (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
// license:LGPL-2.1+
// copyright-holders:Angelo Salese, R. Belmont
// TODO: make separate device when code is decoupled better
//void stv_SMPC_w(offs_t offset, uint8_t data);
//uint8_t stv_SMPC_r(offs_t offset);
//void saturn_SMPC_w(offs_t offset, uint8_t data);
//uint8_t saturn_SMPC_r(offs_t offset);

#ifndef MAME_MACHINE_SMPC_HLE_H
#define MAME_MACHINE_SMPC_HLE_H

#pragma once

#include "screen.h"
#include "bus/sat_ctrl/ctrl.h"
#include "machine/nvram.h"


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

// ======================> smpc_hle_device

class smpc_hle_device : public device_t,
						public device_memory_interface
{
public:
	// construction/destruction
	smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	// I/O operations
//  void io_map(address_map &map);
	uint8_t read(offs_t offset);
	void write(offs_t offset, uint8_t data);

	DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi_r );

	void m68k_reset_trigger();

	bool get_iosel(bool which);

	uint8_t get_ddr(bool which);

//  system delegation
	auto master_reset_handler() { return m_mshres.bind(); }

	auto master_nmi_handler() { return m_mshnmi.bind(); }

	auto slave_reset_handler() { return m_sshres.bind(); }

	auto sound_reset_handler() { return m_sndres.bind(); }

	auto system_reset_handler() { return m_sysres.bind(); }

	auto system_halt_handler() { return m_syshalt.bind(); }

	auto dot_select_handler() { return m_dotsel.bind(); }


//  PDR delegation
	auto pdr1_in_handler() { return m_pdr1_read.bind(); }

	auto pdr2_in_handler() { return m_pdr2_read.bind(); }

	auto pdr1_out_handler() { return m_pdr1_write.bind(); }

	auto pdr2_out_handler() { return m_pdr2_write.bind(); }

	// interrupt handler, doesn't work in Saturn driver???
	auto interrupt_handler() { return m_irq_line.bind(); }

	void set_region_code(uint8_t rgn) { m_region_code = rgn; }
	template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
	template <typename T, typename U> void set_control_port_tags(T &&tag1, U &&tag2)
	{
		m_ctrl1.set_tag(std::forward<T>(tag1));
		m_ctrl2.set_tag(std::forward<U>(tag2));
		// TODO: checking against nullptr still returns a device!?
		m_has_ctrl_ports = true;
	}

protected:
	// device-level overrides
//  virtual void device_validity_check(validity_checker &valid) const override;
	virtual void device_add_mconfig(machine_config &config) override;
	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;
	virtual space_config_vector memory_space_config() const override;

private:

	const address_space_config      m_space_config;
	enum {
		COMMAND_ID = 1,
		RTC_ID,
		INTBACK_ID,
		SNDRES_ID
	};

	emu_timer *m_cmd_timer;
	emu_timer *m_rtc_timer;
	emu_timer *m_intback_timer;
	emu_timer *m_sndres_timer;
	bool m_has_ctrl_ports;

	bool m_sf;
	bool m_cd_sf;
	uint8_t m_sr;
	uint8_t m_ddr1, m_ddr2;
	uint8_t m_pdr1_readback, m_pdr2_readback;
	bool m_iosel1, m_iosel2;
	bool m_exle1, m_exle2;
	uint8_t m_ireg[7];
	uint8_t m_intback_buf[3];
	uint8_t m_oreg[32];
	uint8_t m_rtc_data[7];
	uint8_t m_smem[5];
	uint8_t m_comreg;
	// in usec
	// timing table, from manual in usec
	const uint32_t m_cmd_table_timing[0x20] =
	{
		30, 30, // MASTER ON / OFF
		30, 30, // SLAVE ON / OFF
		10, 10, // <unknown>
		30, 30, // SOUND ON / OFF
		40, 40, // CD ON / OFF
		30, 30, 30, // NETLINK ON / OFF / <unknown>
		100*1000, 100*1000, 100*1000, // SYSTEM RESET / ClocK CHaNGe 352 / 320
		320*1000, // INTBACK
		30, 30, 30, 30, 30, // <unknown>
		70, 40, 30, 30, 30, // SETTIME / SETSMEM / NMIREQ / RESENAB / RESDISA
		30, 30, 30, 30 // <unknown>
	};
	bool m_command_in_progress;
	bool m_NMI_reset;
	bool m_cur_dotsel;

	void master_sh2_nmi();
	void irq_request();

	void resolve_intback();
	void intback_continue_request();
	void handle_rtc_increment();
	void read_saturn_ports();

	void sr_set(uint8_t data);
	void sr_ack();
	void sf_ack(bool cd_enable);
	void sf_set();
	int DectoBCD(int num);
	int m_intback_stage;
	int m_pmode;
	uint8_t m_region_code;

	required_device<nvram_device> m_mini_nvram;
	devcb_write_line m_mshres;
	devcb_write_line m_mshnmi;
	devcb_write_line m_sshres;
//  devcb_write_line m_sshnmi;
	devcb_write_line m_sndres;
	devcb_write_line m_sysres;
//  devcb_write_line m_cdres;
	devcb_write_line m_syshalt;
	devcb_write_line m_dotsel;
	devcb_read8 m_pdr1_read;
	devcb_read8 m_pdr2_read;
	devcb_write8 m_pdr1_write;
	devcb_write8 m_pdr2_write;
	devcb_write_line m_irq_line;
	optional_device<saturn_control_port_device> m_ctrl1;
	optional_device<saturn_control_port_device> m_ctrl2;

	required_device<screen_device> m_screen;

	void smpc_regs(address_map &map);

	void ireg_w(offs_t offset, uint8_t data);
	void command_register_w(uint8_t data);
	uint8_t oreg_r(offs_t offset);
	uint8_t status_register_r();
	void status_flag_w(uint8_t data);
	uint8_t status_flag_r();
	uint8_t pdr1_r();
	uint8_t pdr2_r();
	void pdr1_w(uint8_t data);
	void pdr2_w(uint8_t data);
	void ddr1_w(uint8_t data);
	void ddr2_w(uint8_t data);
	void iosel_w(uint8_t data);
	void exle_w(uint8_t data);
};


// device type definition
DECLARE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device)



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************


#endif // MAME_MACHINE_SMPC_HLE_H