1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 
4 #ifndef MAME_CPU_M6800_M6801_H
5 #define MAME_CPU_M6800_M6801_H
6 
7 #pragma once
8 
9 #include "cpu/m6800/m6800.h"
10 
11 
12 enum
13 {
14 	M6801_IRQ_LINE = M6800_IRQ_LINE,
15 	M6801_TIN_LINE, // P20/Tin Input Capture line (edge sense). Active edge is selectable by internal reg.
16 	M6801_SC1_LINE
17 };
18 
19 enum
20 {
21 	M6803_IRQ_LINE = M6800_IRQ_LINE
22 };
23 
24 enum
25 {
26 	HD6301_IRQ_LINE = M6800_IRQ_LINE
27 };
28 
29 enum
30 {
31 	M6801_MODE_0 = 0,
32 	M6801_MODE_1,
33 	M6801_MODE_2,
34 	M6801_MODE_3,
35 	M6801_MODE_4,
36 	M6801_MODE_5,
37 	M6801_MODE_6,
38 	M6801_MODE_7
39 };
40 
41 
42 class m6801_cpu_device : public m6800_cpu_device
43 {
44 public:
45 	m6801_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
46 
in_p1_cb()47 	auto in_p1_cb() { return m_in_port_func[0].bind(); }
out_p1_cb()48 	auto out_p1_cb() { return m_out_port_func[0].bind(); }
in_p2_cb()49 	auto in_p2_cb() { return m_in_port_func[1].bind(); }
out_p2_cb()50 	auto out_p2_cb() { return m_out_port_func[1].bind(); }
in_p3_cb()51 	auto in_p3_cb() { return m_in_port_func[2].bind(); }
out_p3_cb()52 	auto out_p3_cb() { return m_out_port_func[2].bind(); }
in_p4_cb()53 	auto in_p4_cb() { return m_in_port_func[3].bind(); }
out_p4_cb()54 	auto out_p4_cb() { return m_out_port_func[3].bind(); }
55 
out_sc2_cb()56 	auto out_sc2_cb() { return m_out_sc2_func.bind(); }
out_ser_tx_cb()57 	auto out_ser_tx_cb() { return m_out_sertx_func.bind(); }
58 
59 	void m6801_io(address_map &map); // FIXME: privatize this
60 
61 	void m6801_clock_serial();
62 
63 protected:
64 	m6801_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal = address_map_constructor());
65 
66 	// device-level overrides
67 	virtual void device_resolve_objects() override;
68 	virtual void device_start() override;
69 	virtual void device_reset() override;
70 
71 	// device_execute_interface overrides
execute_clocks_to_cycles(uint64_t clocks)72 	virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
execute_cycles_to_clocks(uint64_t cycles)73 	virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
74 	virtual void execute_set_input(int inputnum, int state) override;
75 
76 	// device_disasm_interface overrides
77 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
78 
79 	void p1_ddr_w(uint8_t data);
80 	uint8_t p1_data_r();
81 	void p1_data_w(uint8_t data);
82 	void p2_ddr_w(uint8_t data);
83 	uint8_t p2_data_r();
84 	void p2_data_w(uint8_t data);
85 	void p3_ddr_w(uint8_t data);
86 	uint8_t p3_data_r();
87 	void p3_data_w(uint8_t data);
88 	uint8_t p3_csr_r();
89 	void p3_csr_w(uint8_t data);
90 	void p4_ddr_w(uint8_t data);
91 	uint8_t p4_data_r();
92 	void p4_data_w(uint8_t data);
93 
94 protected:
95 	uint8_t tcsr_r();
96 	void tcsr_w(uint8_t data);
97 	uint8_t ch_r();
98 	uint8_t cl_r();
99 	void ch_w(uint8_t data);
100 	void cl_w(uint8_t data);
101 	uint8_t ocrh_r();
102 	uint8_t ocrl_r();
103 	void ocrh_w(uint8_t data);
104 	void ocrl_w(uint8_t data);
105 	uint8_t icrh_r();
106 	uint8_t icrl_r();
107 
108 	uint8_t sci_rmcr_r();
109 	void sci_rmcr_w(uint8_t data);
110 	uint8_t sci_trcsr_r();
111 	void sci_trcsr_w(uint8_t data);
112 	uint8_t sci_rdr_r();
113 	void sci_tdr_w(uint8_t data);
114 
115 	uint8_t rcr_r();
116 	void rcr_w(uint8_t data);
117 	uint8_t ff_r();
118 
119 	void m6803_mem(address_map &map);
120 
121 	devcb_read8::array<4> m_in_port_func;
122 	devcb_write8::array<4> m_out_port_func;
123 
124 	devcb_write_line m_out_sc2_func;
125 	devcb_write_line m_out_sertx_func;
126 
127 	/* internal registers */
128 	uint8_t   m_port_ddr[4];
129 	uint8_t   m_port_data[4];
130 	uint8_t   m_p3csr;          // Port 3 Control/Status Register
131 	uint8_t   m_tcsr;           /* Timer Control and Status Register */
132 	uint8_t   m_pending_tcsr;   /* pending IRQ flag for clear IRQflag process */
133 	uint8_t   m_irq2;           /* IRQ2 flags */
134 	uint8_t   m_ram_ctrl;
135 	PAIR    m_counter;        /* free running counter */
136 	PAIR    m_output_compare; /* output compare       */
137 	uint16_t  m_input_capture;  /* input capture        */
138 	int     m_p3csr_is3_flag_read;
139 	int     m_port3_latched;
140 
141 	uint8_t   m_trcsr, m_rmcr, m_rdr, m_tdr, m_rsr, m_tsr;
142 	int     m_rxbits, m_txbits, m_txstate, m_trcsr_read_tdre, m_trcsr_read_orfe, m_trcsr_read_rdrf, m_tx, m_ext_serclock;
143 	bool    m_use_ext_serclock;
144 	bool    m_port2_written;
145 
146 	int     m_latch09;
147 
148 	PAIR    m_timer_over;
149 	emu_timer *m_sci_timer;
150 
151 	/* point of next timer event */
152 	uint32_t m_timer_next;
153 
154 	int     m_sc1_state;
155 
156 	static const uint8_t cycles_6803[256];
157 	static const uint8_t cycles_63701[256];
158 	static const op_func m6803_insn[256];
159 	static const op_func hd63701_insn[256];
160 
161 	virtual void m6800_check_irq2() override;
162 	virtual void increment_counter(int amount) override;
163 	virtual void EAT_CYCLES() override;
164 	virtual void CLEANUP_COUNTERS() override;
165 
166 	virtual void modified_tcsr();
167 	virtual void set_timer_event();
168 	virtual void modified_counters();
169 	virtual void check_timer_event();
170 	void set_rmcr(uint8_t data);
171 	virtual void write_port2();
172 	int m6800_rx();
173 	void serial_transmit();
174 	void serial_receive();
175 	TIMER_CALLBACK_MEMBER( sci_tick );
176 	void set_os3(int state);
177 };
178 
179 
180 class m6803_cpu_device : public m6801_cpu_device
181 {
182 public:
183 	m6803_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
184 
185 protected:
186 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
187 };
188 
189 
190 class m6803e_cpu_device : public m6801_cpu_device
191 {
192 public:
193 	m6803e_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
194 
195 protected:
execute_clocks_to_cycles(uint64_t clocks)196 	virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return clocks; }
execute_cycles_to_clocks(uint64_t cycles)197 	virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return cycles; }
198 
199 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
200 };
201 
202 
203 class hd6301_cpu_device : public m6801_cpu_device
204 {
205 protected:
206 	hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
207 
208 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
209 
210 	virtual void TAKE_TRAP() override;
211 };
212 
213 
214 // DP-40 package: HD6301V1P,  HD63A01V1P,  HD63B01V1P
215 // FP-54 package: HD6301V1F,  HD63A01V1F,  HD63B01V1F
216 // CG-40 package: HD6301V1CG, HD63A01V1CG, HD63B01V1CG
217 // CP-52 package: HD6301V1CP, HD63A01V1CP, HD63B01V1CP
218 // CP-44 package: HD6301V1L,  HD63A01V1L,  HD63B01V1L
219 // Not fully emulated yet
220 class hd6301v1_cpu_device : public hd6301_cpu_device
221 {
222 public:
223 	hd6301v1_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
224 };
225 
226 
227 // DC-40 package: HD63701V0C, HD63A701V0C, HD63B701V0C
228 // Not fully emulated yet
229 class hd63701v0_cpu_device : public hd6301_cpu_device
230 {
231 public:
232 	hd63701v0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
233 };
234 
235 
236 // DP-40 package: HD6303RP,  HD63A03RP,  HD63B03RP
237 // FP-54 package: HD6303RF,  HD63A03RF,  HD63B03RF
238 // CG-40 package: HD6303RCG, HD63A03RCG, HD63B03RCG
239 // Not fully emulated yet
240 class hd6303r_cpu_device : public hd6301_cpu_device
241 {
242 public:
243 	hd6303r_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
244 };
245 
246 
247 class hd6301x_cpu_device : public hd6301_cpu_device
248 {
249 public:
in_p5_cb()250 	auto in_p5_cb() { return m_in_portx_func[0].bind(); }
out_p5_cb()251 	auto out_p5_cb() { return m_out_portx_func[0].bind(); }
in_p6_cb()252 	auto in_p6_cb() { return m_in_portx_func[1].bind(); }
out_p6_cb()253 	auto out_p6_cb() { return m_out_portx_func[1].bind(); }
out_p7_cb()254 	auto out_p7_cb() { return m_out_portx_func[2].bind(); }
255 
256 	// TODO: privatize eventually
257 	void hd6301x_io(address_map &map);
258 
259 protected:
260 	hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
261 
262 	// device-level overrides
263 	virtual void device_resolve_objects() override;
264 	virtual void device_start() override;
265 	virtual void device_reset() override;
266 
267 	virtual void write_port2() override;
268 
269 	void p2_ddr_2bit_w(uint8_t data);
270 	uint8_t p5_data_r();
271 	void p6_ddr_w(uint8_t data);
272 	uint8_t p6_data_r();
273 	void p6_data_w(uint8_t data);
274 	uint8_t p7_data_r();
275 	void p7_data_w(uint8_t data);
276 
277 	uint8_t tcsr2_r();
278 	void tcsr2_w(uint8_t data);
279 	uint8_t ocr2h_r();
280 	void ocr2h_w(uint8_t data);
281 	uint8_t ocr2l_r();
282 	void ocr2l_w(uint8_t data);
283 
284 	virtual void m6800_check_irq2() override;
285 	virtual void modified_tcsr() override;
286 	virtual void set_timer_event() override;
287 	virtual void modified_counters() override;
288 	virtual void check_timer_event() override;
289 	virtual void CLEANUP_COUNTERS() override;
290 
291 	devcb_read8::array<2> m_in_portx_func;
292 	devcb_write8::array<3> m_out_portx_func;
293 
294 	uint8_t m_portx_ddr[2];
295 	uint8_t m_portx_data[3];
296 
297 	uint8_t m_tcsr2;
298 	uint8_t m_pending_tcsr2;
299 	PAIR    m_output_compare2;
300 };
301 
302 
303 // DP-64S package: HD6301X0P,  HD63A01X0P,  HD63B01X0P
304 // FP-80  package: HD6301X0F,  HD63A01X0F,  HD63B01X0F
305 // CP-68  package: HD6301X0CP, HD63A01X0CP, HD63B01X0CP
306 // Not fully emulated yet
307 class hd6301x0_cpu_device : public hd6301x_cpu_device
308 {
309 public:
310 	hd6301x0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
311 };
312 
313 
314 // DC-64S package: HD63701X0C, HD63A701X0C, HD63B701X0C
315 // Not fully emulated yet
316 class hd63701x0_cpu_device : public hd6301x_cpu_device
317 {
318 public:
319 	hd63701x0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
320 };
321 
322 
323 // DP-64S package: HD6303XP,  HD63A03XP,  HD63B03XP
324 // FP-80  package: HD6303XF,  HD63A03XF,  HD63B03XF
325 // CP-68  package: HD6303XCP, HD63A03XCP, HD63B03XCP
326 // Not fully emulated yet
327 class hd6303x_cpu_device : public hd6301x_cpu_device
328 {
329 public:
330 	hd6303x_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
331 };
332 
333 
334 class hd6301y_cpu_device : public hd6301x_cpu_device
335 {
336 public:
337 	// TODO: privatize eventually
338 	void hd6301y_io(address_map &map);
339 
340 protected:
341 	hd6301y_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
342 
343 	void p5_ddr_w(uint8_t data);
344 	void p5_data_w(uint8_t data);
345 };
346 
347 
348 // DP-64S package: HD6301Y0P,  HD63A01Y0P,  HD63B01Y0P,  HD63C01Y0P
349 // FP-64  package: HD6301Y0F,  HD63A01Y0F,  HD63B01Y0F,  HD63C01Y0F
350 // FP-64A package: HD6301Y0H,  HD63A01Y0H,  HD63B01Y0H,  HD63C01Y0H
351 // CP-68  package: HD6301Y0CP, HD63A01Y0CP, HD63B01Y0CP, HD63C01Y0CP
352 // Not fully emulated yet
353 class hd6301y0_cpu_device : public hd6301y_cpu_device
354 {
355 public:
356 	hd6301y0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
357 };
358 
359 
360 // DC-64S package: HD63701Y0C, HD63A701Y0C, HD63B701Y0C, HD63C701Y0C
361 // Not fully emulated yet
362 class hd63701y0_cpu_device : public hd6301y_cpu_device
363 {
364 public:
365 	hd63701y0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
366 };
367 
368 
369 // DP-64S package: HD6303YP,  HD63A03YP,  HD63B03YP,  HD63C03YP
370 // FP-64  package: HD6303YF,  HD63A03YF,  HD63B03YF,  HD63C03YF
371 // FP-64A package: HD6303YH,  HD63A03YH,  HD63B03YH,  HD63C03YH
372 // CP-68  package: HD6303YCP, HD63A03YCP, HD63B03YCP, HD63C03YCP
373 // Not fully emulated yet
374 class hd6303y_cpu_device : public hd6301y_cpu_device
375 {
376 public:
377 	hd6303y_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
378 };
379 
380 
381 DECLARE_DEVICE_TYPE(M6801, m6801_cpu_device)
382 DECLARE_DEVICE_TYPE(M6803, m6803_cpu_device)
383 DECLARE_DEVICE_TYPE(M6803E, m6803e_cpu_device)
384 DECLARE_DEVICE_TYPE(HD6301V1, hd6301v1_cpu_device)
385 DECLARE_DEVICE_TYPE(HD6301X0, hd6301x0_cpu_device)
386 DECLARE_DEVICE_TYPE(HD6301Y0, hd6301y0_cpu_device)
387 DECLARE_DEVICE_TYPE(HD63701V0, hd63701v0_cpu_device)
388 DECLARE_DEVICE_TYPE(HD63701X0, hd63701x0_cpu_device)
389 DECLARE_DEVICE_TYPE(HD63701Y0, hd63701y0_cpu_device)
390 DECLARE_DEVICE_TYPE(HD6303R, hd6303r_cpu_device)
391 DECLARE_DEVICE_TYPE(HD6303X, hd6303x_cpu_device)
392 DECLARE_DEVICE_TYPE(HD6303Y, hd6303y_cpu_device)
393 
394 #endif // MAME_CPU_M6800_M6801_H
395