summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/z80ctc.h
blob: 405ddd0ed026f3f8be285293b94f466d27be2930 (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
/***************************************************************************

    Z80 CTC (Z8430) implementation

    Copyright Nicola Salmoria and the MAME Team.
    Visit http://mamedev.org for licensing and usage restrictions.

****************************************************************************
                            _____   _____
                    D4   1 |*    \_/     | 28  D3
                    D5   2 |             | 27  D2
                    D6   3 |             | 26  D1
                    D7   4 |             | 25  D0
                   GND   5 |             | 24  +5V
                   _RD   6 |             | 23  CLK/TRG0
                ZC/TOO   7 |   Z80-CTC   | 22  CLK/TRG1
                ZC/TO1   8 |             | 21  CLK/TRG2
                ZC/TO2   9 |             | 20  CLK/TRG3
                 _IORQ  10 |             | 19  CS1
                   IEO  11 |             | 18  CS0
                  _INT  12 |             | 17  _RESET
                   IEI  13 |             | 16  _CE
                   _M1  14 |_____________| 15  CLK

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

#ifndef __Z80CTC_H__
#define __Z80CTC_H__

#include "cpu/z80/z80daisy.h"


//**************************************************************************
//  CONSTANTS
//**************************************************************************

const int NOTIMER_0 = (1<<0);
const int NOTIMER_1 = (1<<1);
const int NOTIMER_2 = (1<<2);
const int NOTIMER_3 = (1<<3);



//**************************************************************************
//  DEVICE CONFIGURATION MACROS
//**************************************************************************

#define Z80CTC_INTERFACE(name) \
	const z80ctc_interface (name)=


#define MDRV_Z80CTC_ADD(_tag, _clock, _intrf) \
	MDRV_DEVICE_ADD(_tag, Z80CTC, _clock) \
	MDRV_DEVICE_CONFIG(_intrf)



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


// ======================> z80ctc_interface

struct z80ctc_interface
{
	UINT8				m_notimer;	// timer disabler mask
	devcb_write_line	m_intr;		// callback when change interrupt status
	devcb_write_line	m_zc0;		// ZC/TO0 callback
	devcb_write_line	m_zc1;		// ZC/TO1 callback
	devcb_write_line	m_zc2;		// ZC/TO2 callback
};



// ======================> z80ctc_device_config

class z80ctc_device_config :	public device_config,
								public device_config_z80daisy_interface,
								public z80ctc_interface
{
	friend class z80ctc_device;

	// construction/destruction
	z80ctc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);

public:
	// allocators
	static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
	virtual device_t *alloc_device(running_machine &machine) const;

protected:
	// device_config overrides
	virtual void device_config_complete();
};



// ======================> z80ctc_device

class z80ctc_device :	public device_t,
						public device_z80daisy_interface
{
	friend class z80ctc_device_config;

	// construction/destruction
	z80ctc_device(running_machine &_machine, const z80ctc_device_config &_config);

public:
	// state getters
	attotime period(int ch) const { return m_channel[ch].period(); }

	// I/O operations
	UINT8 read(int ch) { return m_channel[ch].read(); }
	void write(int ch, UINT8 data) { m_channel[ch].write(data); }
	void trigger(int ch, UINT8 data) { m_channel[ch].trigger(data); }

private:
	// device-level overrides
	virtual void device_start();
	virtual void device_reset();

	// z80daisy_interface overrides
	virtual int z80daisy_irq_state();
	virtual int z80daisy_irq_ack();
	virtual void z80daisy_irq_reti();

	// internal helpers
	void interrupt_check();
	void timercallback(int chanindex);

	// a single channel within the CTC
	class ctc_channel
	{
	public:
		ctc_channel();

		void start(z80ctc_device *device, int index, bool notimer, const devcb_write_line *write_line);
		void reset();

		UINT8 read();
		void write(UINT8 data);

		attotime period() const;
		void trigger(UINT8 data);
		void timer_callback();

		z80ctc_device *	m_device;				// pointer back to our device
		int				m_index;				// our channel index
		devcb_resolved_write_line m_zc;			// zero crossing callbacks
		bool			m_notimer;				// timer disabled?
		UINT16			m_mode;					// current mode
		UINT16			m_tconst;				// time constant
		UINT16			m_down;					// down counter (clock mode only)
		UINT8			m_extclk;				// current signal from the external clock
		emu_timer *		m_timer;				// array of active timers
		UINT8			m_int_state;			// interrupt status (for daisy chain)

	private:
		static TIMER_CALLBACK( static_timer_callback ) { reinterpret_cast<z80ctc_device::ctc_channel *>(ptr)->timer_callback(); }
	};

	// internal state
	const z80ctc_device_config &m_config;
	devcb_resolved_write_line m_intr;			// interrupt callback

	UINT8				m_vector;				// interrupt vector
	attotime			m_period16;				// 16/system clock
	attotime			m_period256;			// 256/system clock
	ctc_channel			m_channel[4];			// data for each channel
};


// device type definition
extern const device_type Z80CTC;



//**************************************************************************
//  READ/WRITE HANDLERS
//**************************************************************************

WRITE8_DEVICE_HANDLER( z80ctc_w );
READ8_DEVICE_HANDLER( z80ctc_r );

WRITE_LINE_DEVICE_HANDLER( z80ctc_trg0_w );
WRITE_LINE_DEVICE_HANDLER( z80ctc_trg1_w );
WRITE_LINE_DEVICE_HANDLER( z80ctc_trg2_w );
WRITE_LINE_DEVICE_HANDLER( z80ctc_trg3_w );


#endif