1 // license:LGPL-2.1+
2 // copyright-holders:Angelo Salese, R. Belmont
3 // TODO: make separate device when code is decoupled better
4 //void stv_SMPC_w(offs_t offset, uint8_t data);
5 //uint8_t stv_SMPC_r(offs_t offset);
6 //void saturn_SMPC_w(offs_t offset, uint8_t data);
7 //uint8_t saturn_SMPC_r(offs_t offset);
8 
9 #ifndef MAME_MACHINE_SMPC_HLE_H
10 #define MAME_MACHINE_SMPC_HLE_H
11 
12 #pragma once
13 
14 #include "screen.h"
15 #include "bus/sat_ctrl/ctrl.h"
16 #include "machine/nvram.h"
17 
18 
19 //**************************************************************************
20 //  TYPE DEFINITIONS
21 //**************************************************************************
22 
23 // ======================> smpc_hle_device
24 
25 class smpc_hle_device : public device_t,
26 						public device_memory_interface
27 {
28 public:
29 	// construction/destruction
30 	smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
31 
32 	// I/O operations
33 //  void io_map(address_map &map);
34 	uint8_t read(offs_t offset);
35 	void write(offs_t offset, uint8_t data);
36 
37 	DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi_r );
38 
39 	void m68k_reset_trigger();
40 
41 	bool get_iosel(bool which);
42 
43 	uint8_t get_ddr(bool which);
44 
45 //  system delegation
master_reset_handler()46 	auto master_reset_handler() { return m_mshres.bind(); }
47 
master_nmi_handler()48 	auto master_nmi_handler() { return m_mshnmi.bind(); }
49 
slave_reset_handler()50 	auto slave_reset_handler() { return m_sshres.bind(); }
51 
sound_reset_handler()52 	auto sound_reset_handler() { return m_sndres.bind(); }
53 
system_reset_handler()54 	auto system_reset_handler() { return m_sysres.bind(); }
55 
system_halt_handler()56 	auto system_halt_handler() { return m_syshalt.bind(); }
57 
dot_select_handler()58 	auto dot_select_handler() { return m_dotsel.bind(); }
59 
60 
61 //  PDR delegation
pdr1_in_handler()62 	auto pdr1_in_handler() { return m_pdr1_read.bind(); }
63 
pdr2_in_handler()64 	auto pdr2_in_handler() { return m_pdr2_read.bind(); }
65 
pdr1_out_handler()66 	auto pdr1_out_handler() { return m_pdr1_write.bind(); }
67 
pdr2_out_handler()68 	auto pdr2_out_handler() { return m_pdr2_write.bind(); }
69 
70 	// interrupt handler, doesn't work in Saturn driver???
interrupt_handler()71 	auto interrupt_handler() { return m_irq_line.bind(); }
72 
set_region_code(uint8_t rgn)73 	void set_region_code(uint8_t rgn) { m_region_code = rgn; }
set_screen_tag(T && tag)74 	template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
set_control_port_tags(T && tag1,U && tag2)75 	template <typename T, typename U> void set_control_port_tags(T &&tag1, U &&tag2)
76 	{
77 		m_ctrl1.set_tag(std::forward<T>(tag1));
78 		m_ctrl2.set_tag(std::forward<U>(tag2));
79 		// TODO: checking against nullptr still returns a device!?
80 		m_has_ctrl_ports = true;
81 	}
82 
83 protected:
84 	// device-level overrides
85 //  virtual void device_validity_check(validity_checker &valid) const override;
86 	virtual void device_add_mconfig(machine_config &config) override;
87 	virtual void device_start() override;
88 	virtual void device_reset() override;
89 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
90 	virtual space_config_vector memory_space_config() const override;
91 
92 private:
93 
94 	const address_space_config      m_space_config;
95 	enum {
96 		COMMAND_ID = 1,
97 		RTC_ID,
98 		INTBACK_ID,
99 		SNDRES_ID
100 	};
101 
102 	emu_timer *m_cmd_timer;
103 	emu_timer *m_rtc_timer;
104 	emu_timer *m_intback_timer;
105 	emu_timer *m_sndres_timer;
106 	bool m_has_ctrl_ports;
107 
108 	bool m_sf;
109 	bool m_cd_sf;
110 	uint8_t m_sr;
111 	uint8_t m_ddr1, m_ddr2;
112 	uint8_t m_pdr1_readback, m_pdr2_readback;
113 	bool m_iosel1, m_iosel2;
114 	bool m_exle1, m_exle2;
115 	uint8_t m_ireg[7];
116 	uint8_t m_intback_buf[3];
117 	uint8_t m_oreg[32];
118 	uint8_t m_rtc_data[7];
119 	uint8_t m_smem[5];
120 	uint8_t m_comreg;
121 	// in usec
122 	// timing table, from manual in usec
123 	const uint32_t m_cmd_table_timing[0x20] =
124 	{
125 		30, 30, // MASTER ON / OFF
126 		30, 30, // SLAVE ON / OFF
127 		10, 10, // <unknown>
128 		30, 30, // SOUND ON / OFF
129 		40, 40, // CD ON / OFF
130 		30, 30, 30, // NETLINK ON / OFF / <unknown>
131 		100*1000, 100*1000, 100*1000, // SYSTEM RESET / ClocK CHaNGe 352 / 320
132 		320*1000, // INTBACK
133 		30, 30, 30, 30, 30, // <unknown>
134 		70, 40, 30, 30, 30, // SETTIME / SETSMEM / NMIREQ / RESENAB / RESDISA
135 		30, 30, 30, 30 // <unknown>
136 	};
137 	bool m_command_in_progress;
138 	bool m_NMI_reset;
139 	bool m_cur_dotsel;
140 
141 	void master_sh2_nmi();
142 	void irq_request();
143 
144 	void resolve_intback();
145 	void intback_continue_request();
146 	void handle_rtc_increment();
147 	void read_saturn_ports();
148 
149 	void sr_set(uint8_t data);
150 	void sr_ack();
151 	void sf_ack(bool cd_enable);
152 	void sf_set();
153 	int DectoBCD(int num);
154 	int m_intback_stage;
155 	int m_pmode;
156 	uint8_t m_region_code;
157 
158 	required_device<nvram_device> m_mini_nvram;
159 	devcb_write_line m_mshres;
160 	devcb_write_line m_mshnmi;
161 	devcb_write_line m_sshres;
162 //  devcb_write_line m_sshnmi;
163 	devcb_write_line m_sndres;
164 	devcb_write_line m_sysres;
165 //  devcb_write_line m_cdres;
166 	devcb_write_line m_syshalt;
167 	devcb_write_line m_dotsel;
168 	devcb_read8 m_pdr1_read;
169 	devcb_read8 m_pdr2_read;
170 	devcb_write8 m_pdr1_write;
171 	devcb_write8 m_pdr2_write;
172 	devcb_write_line m_irq_line;
173 	optional_device<saturn_control_port_device> m_ctrl1;
174 	optional_device<saturn_control_port_device> m_ctrl2;
175 
176 	required_device<screen_device> m_screen;
177 
178 	void smpc_regs(address_map &map);
179 
180 	void ireg_w(offs_t offset, uint8_t data);
181 	void command_register_w(uint8_t data);
182 	uint8_t oreg_r(offs_t offset);
183 	uint8_t status_register_r();
184 	void status_flag_w(uint8_t data);
185 	uint8_t status_flag_r();
186 	uint8_t pdr1_r();
187 	uint8_t pdr2_r();
188 	void pdr1_w(uint8_t data);
189 	void pdr2_w(uint8_t data);
190 	void ddr1_w(uint8_t data);
191 	void ddr2_w(uint8_t data);
192 	void iosel_w(uint8_t data);
193 	void exle_w(uint8_t data);
194 };
195 
196 
197 // device type definition
198 DECLARE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device)
199 
200 
201 
202 //**************************************************************************
203 //  GLOBAL VARIABLES
204 //**************************************************************************
205 
206 
207 #endif // MAME_MACHINE_SMPC_HLE_H
208 
209