summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6805/m68hc05.h
blob: 5843a7df2f0ced8f9af9b0c8d3d20dcfb5928c81 (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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
#ifndef MAME_CPU_M6805_M68HC05_H
#define MAME_CPU_M6805_M68HC05_H

#pragma once

#include "m6805.h"

#include <array>


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

DECLARE_DEVICE_TYPE(M68HC05C4,   m68hc05c4_device)
DECLARE_DEVICE_TYPE(M68HC05C8,   m68hc05c8_device)
DECLARE_DEVICE_TYPE(M68HC705C4A, m68hc705c4a_device)
DECLARE_DEVICE_TYPE(M68HC705C8A, m68hc705c8a_device)
DECLARE_DEVICE_TYPE(M68HC705J1A, m68hc705j1a_device)
DECLARE_DEVICE_TYPE(M68HC05L9,   m68hc05l9_device)
DECLARE_DEVICE_TYPE(M68HC05L11,  m68hc05l11_device)


//**************************************************************************
//  TYPE DECLARATIONS
//**************************************************************************

// ======================> m68hc05_device

class m68hc05_device : public m6805_base_device
{
public:
	//  configuration helpers
	auto porta_r() { return m_port_cb_r[0].bind(); }
	auto portb_r() { return m_port_cb_r[1].bind(); }
	auto portc_r() { return m_port_cb_r[2].bind(); }
	auto portd_r() { return m_port_cb_r[3].bind(); }
	auto porta_w() { return m_port_cb_w[0].bind(); }
	auto portb_w() { return m_port_cb_w[1].bind(); }
	auto portc_w() { return m_port_cb_w[2].bind(); }
	auto portd_w() { return m_port_cb_w[3].bind(); }
	auto tcmp() { return m_tcmp_cb.bind(); }

protected:
	// state index constants
	enum
	{
		M68HC05_A = M6805_A,
		M68HC05_PC = M6805_PC,
		M68HC05_S = M6805_S,
		M68HC05_X = M6805_X,
		M68HC05_CC = M6805_CC,
		M68HC05_IRQ_STATE = M6805_IRQ_STATE,

		M68HC05_IRQLATCH = 0x10,

		M68HC05_LATCHA,
		M68HC05_LATCHB,
		M68HC05_LATCHC,
		M68HC05_LATCHD,
		M68HC05_DDRA,
		M68HC05_DDRB,
		M68HC05_DDRC,
		M68HC05_DDRD,

		M68HC05_TCR,
		M68HC05_TSR,
		M68HC05_ICR,
		M68HC05_OCR,
		M68HC05_PS,
		M68HC05_TR,

		M68HC05_COPRST,
		M68HC05_COPCR,
		M68HC05_PCOP,
		M68HC05_NCOPE,
		M68HC05_NCOP,

		M68HC705C8A_OPTION
	};

	enum { PORT_COUNT = 4 };

	m68hc05_device(
			machine_config const &mconfig,
			char const *tag,
			device_t *owner,
			const XTAL &clock,
			device_type type,
			u32 addr_width,
			u16 vector_mask,
			address_map_constructor internal_map);

	void set_port_bits(std::array<u8, PORT_COUNT> const &bits);
	void set_port_interrupt(std::array<u8, PORT_COUNT> const &interrupt);
	u8 port_read(offs_t offset);
	void port_latch_w(offs_t offset, u8 data);
	u8 port_ddr_r(offs_t offset);
	void port_ddr_w(offs_t offset, u8 data);

	u8 tcr_r();
	void tcr_w(u8 data);
	u8 tsr_r();
	u8 icr_r(offs_t offset);
	u8 ocr_r(offs_t offset);
	void ocr_w(offs_t offset, u8 data);
	u8 timer_r(offs_t offset);

	void set_ncope(bool state) { m_ncope = state ? 1 : 0; }
	void coprst_w(u8 data);
	u8 copcr_r();
	void copcr_w(u8 data);
	void copr_w(u8 data);

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

	virtual void execute_set_input(int inputnum, int state) override;
	virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override;
	virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override;

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

	virtual void interrupt() override;
	virtual bool test_il() override;
	virtual void burn_cycles(unsigned count) override;

	void add_port_state(std::array<bool, PORT_COUNT> const &ddr);
	void add_timer_state();
	void add_pcop_state();
	void add_ncop_state();

private:
	u8 port_value(unsigned offset) const;
	void update_port_irq();

	bool    tcr_icie() const    { return BIT(m_tcr, 7); }
	bool    tcr_ocie() const    { return BIT(m_tcr, 6); }
	bool    tcr_toie() const    { return BIT(m_tcr, 5); }
	bool    tcr_iedg() const    { return BIT(m_tcr, 1); }
	bool    tcr_olvl() const    { return BIT(m_tcr, 0); }

	bool    tsr_icf() const     { return BIT(m_tsr, 7); }
	bool    tsr_ocf() const     { return BIT(m_tsr, 6); }
	bool    tsr_tof() const     { return BIT(m_tsr, 5); }

	bool    copcr_copf() const  { return BIT(m_copcr, 4); }
	bool    copcr_cme() const   { return BIT(m_copcr, 3); }
	bool    copcr_pcope() const { return BIT(m_copcr, 2); }
	u8      copcr_cm() const    { return m_copcr & 0x03; }

	// digital I/O
	devcb_read8::array<PORT_COUNT> m_port_cb_r;
	devcb_write8::array<PORT_COUNT> m_port_cb_w;
	u8                  m_port_bits[PORT_COUNT];
	u8                  m_port_interrupt[PORT_COUNT];
	u8                  m_port_input[PORT_COUNT];
	u8                  m_port_latch[PORT_COUNT];
	u8                  m_port_ddr[PORT_COUNT];
	bool                m_port_irq_state, m_irq_line_state;
	u8                  m_irq_latch;

	// timer/counter
	devcb_write_line    m_tcmp_cb;
	bool                m_tcap_state;
	u8                  m_tcr;
	u8                  m_tsr, m_tsr_seen;
	u8                  m_prescaler;
	u16                 m_counter, m_icr, m_ocr;
	bool                m_inhibit_cap, m_inhibit_cmp;
	u8                  m_trl_buf[2];
	bool                m_trl_latched[2];

	// COP watchdogs
	u32                 m_pcop_cnt, m_ncop_cnt;
	u8                  m_coprst, m_copcr;
	u8                  m_ncope;
};


// ======================> m68hc705_device

class m68hc705_device : public m68hc05_device
{
protected:
	m68hc705_device(
			machine_config const &mconfig,
			char const *tag,
			device_t *owner,
			const XTAL &clock,
			device_type type,
			u32 addr_width,
			address_map_constructor internal_map);
};


// ======================> m68hc05c4_device

class m68hc05c4_device : public m68hc05_device
{
public:
	m68hc05c4_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void c4_map(address_map &map);

	virtual void device_start() override;

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};


// ======================> m68hc05c8_device

class m68hc05c8_device : public m68hc05_device
{
public:
	m68hc05c8_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void c8_map(address_map &map);

	virtual void device_start() override;

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};


// ======================> m68hc705c4a_device

class m68hc705c4a_device : public m68hc705_device
{
public:
	m68hc705c4a_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void c4a_map(address_map &map);

	virtual tiny_rom_entry const *device_rom_region() const override;

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

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

private:
	required_region_ptr<u8> m_rom;

	u8 m_option;
};


// ======================> m68hc705c8a_device

class m68hc705c8a_device : public m68hc705_device
{
public:
	m68hc705c8a_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void c8a_map(address_map &map);

	virtual tiny_rom_entry const *device_rom_region() const override;

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

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

private:
	required_region_ptr<u8> m_rom;

	u8 ram0_r(offs_t offset);
	void ram0_w(offs_t offset, u8 data);
	u8 ram1_r(offs_t offset);
	void ram1_w(offs_t offset, u8 data);

	u8 m_ram[0x80];
	u8 m_option;
};


// ======================> m68hc705j1a_device

class m68hc705j1a_device : public m68hc705_device
{
public:
	m68hc705j1a_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void j1a_map(address_map &map);

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

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};


// ======================> m68hc05l9_device

class m68hc05l9_device : public m68hc05_device
{
public:
	m68hc05l9_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void l9_map(address_map &map);

	virtual void device_start() override;

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};


// ======================> m68hc05l11_device

class m68hc05l11_device : public m68hc05_device
{
public:
	m68hc05l11_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);

protected:
	void l11_map(address_map &map);

	virtual void device_start() override;

	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};


/****************************************************************************
 * 68HC05 section
 ****************************************************************************/

#define M68HC05_IRQ_LINE            (M6805_IRQ_LINE + 0)
#define M68HC05_TCAP_LINE           (M6805_IRQ_LINE + 1)

#endif // MAME_CPU_M6805_M68HC05_H