summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/6532riot.h
blob: f51aa8766f5f0253e1904a6e5f0be2c34f197925 (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
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

  RIOT 6532 emulation

***************************************************************************/

#pragma once

#ifndef __RIOT6532_H__
#define __RIOT6532_H__



//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_RIOT6532_IN_PA_CB(_devcb) \
	devcb = &downcast<riot6532_device &>(*device).set_in_pa_callback(DEVCB_##_devcb);

#define MCFG_RIOT6532_OUT_PA_CB(_devcb) \
	devcb = &downcast<riot6532_device &>(*device).set_out_pa_callback(DEVCB_##_devcb);

#define MCFG_RIOT6532_IN_PB_CB(_devcb) \
	devcb = &downcast<riot6532_device &>(*device).set_in_pb_callback(DEVCB_##_devcb);

#define MCFG_RIOT6532_OUT_PB_CB(_devcb) \
	devcb = &downcast<riot6532_device &>(*device).set_out_pb_callback(DEVCB_##_devcb);

#define MCFG_RIOT6532_IRQ_CB(_devcb) \
	devcb = &downcast<riot6532_device &>(*device).set_irq_callback(DEVCB_##_devcb);


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


// ======================> riot6532_device

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

	template <class Object> devcb_base &set_in_pa_callback(Object &&cb) { return m_in_pa_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_pa_callback(Object &&cb) { return m_out_pa_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_pb_callback(Object &&cb) { return m_in_pb_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_pb_callback(Object &&cb) { return m_out_pb_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );

	uint8_t reg_r(uint8_t offset, bool debugger_access = false);
	void reg_w(uint8_t offset, uint8_t data);

	void porta_in_set(uint8_t data, uint8_t mask);
	void portb_in_set(uint8_t data, uint8_t mask);

	DECLARE_WRITE_LINE_MEMBER(pa0_w);
	DECLARE_WRITE_LINE_MEMBER(pa1_w);
	DECLARE_WRITE_LINE_MEMBER(pa2_w);
	DECLARE_WRITE_LINE_MEMBER(pa3_w);
	DECLARE_WRITE_LINE_MEMBER(pa4_w);
	DECLARE_WRITE_LINE_MEMBER(pa5_w);
	DECLARE_WRITE_LINE_MEMBER(pa6_w);
	DECLARE_WRITE_LINE_MEMBER(pa7_w);
	DECLARE_WRITE_LINE_MEMBER(pb0_w);
	DECLARE_WRITE_LINE_MEMBER(pb1_w);
	DECLARE_WRITE_LINE_MEMBER(pb2_w);
	DECLARE_WRITE_LINE_MEMBER(pb3_w);
	DECLARE_WRITE_LINE_MEMBER(pb4_w);
	DECLARE_WRITE_LINE_MEMBER(pb5_w);
	DECLARE_WRITE_LINE_MEMBER(pb6_w);
	DECLARE_WRITE_LINE_MEMBER(pb7_w);

	uint8_t porta_in_get();
	uint8_t portb_in_get();

	uint8_t porta_out_get();
	uint8_t portb_out_get();

	void timer_end();

protected:
	class riot6532_port
	{
	public:
		uint8_t                   m_in;
		uint8_t                   m_out;
		uint8_t                   m_ddr;
		devcb_read8             *m_in_cb;
		devcb_write8            *m_out_cb;
	};

	// device-level overrides
	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 void device_post_load() override { }
	virtual void device_clock_changed() override { }


private:
	void update_irqstate();
	uint8_t apply_ddr(const riot6532_port *port);
	void update_pa7_state();
	uint8_t get_timer();

	riot6532_port   m_port[2];

	devcb_read8         m_in_pa_cb;
	devcb_write8        m_out_pa_cb;
	devcb_read8         m_in_pb_cb;
	devcb_write8        m_out_pb_cb;
	devcb_write_line    m_irq_cb;

	uint8_t           m_irqstate;
	uint8_t           m_irqenable;
	int             m_irq;

	uint8_t           m_pa7dir;     /* 0x80 = high-to-low, 0x00 = low-to-high */
	uint8_t           m_pa7prev;

	uint8_t           m_timershift;
	uint8_t           m_timerstate;
	emu_timer *     m_timer;

	enum
	{
		TIMER_END_CB
	};
};


// device type definition
DECLARE_DEVICE_TYPE(RIOT6532, riot6532_device)

#endif