summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i8255.h
blob: 2677a2f54a36dbda4a81f78b8b6a6e9940fc11bd (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
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Intel 8255(A) Programmable Peripheral Interface emulation

**********************************************************************
                            _____   _____
                   PA3   1 |*    \_/     | 40  PA4
                   PA2   2 |             | 39  PA5
                   PA1   3 |             | 38  PA6
                   PA0   4 |             | 37  PA7
                   _RD   5 |             | 36  WR
                   _CS   6 |             | 35  RESET
                   GND   7 |             | 34  D0
                    A1   8 |             | 33  D1
                    A0   9 |             | 32  D2
                   PC7  10 |    8255     | 31  D3
                   PC6  11 |    8255A    | 30  D4
                   PC5  12 |             | 29  D5
                   PC4  13 |             | 28  D6
                   PC0  14 |             | 27  D7
                   PC1  15 |             | 26  Vcc
                   PC2  16 |             | 25  PB7
                   PC3  17 |             | 24  PB6
                   PB0  18 |             | 23  PB5
                   PB1  19 |             | 22  PB4
                   PB2  20 |_____________| 21  PB3

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

#pragma once

#ifndef __I8255__
#define __I8255__


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

#define MCFG_I8255_IN_PORTA_CB(_devcb) \
	devcb = &i8255_device::set_in_pa_callback(*device, DEVCB_##_devcb);

#define MCFG_I8255_IN_PORTB_CB(_devcb) \
	devcb = &i8255_device::set_in_pb_callback(*device, DEVCB_##_devcb);

#define MCFG_I8255_IN_PORTC_CB(_devcb) \
	devcb = &i8255_device::set_in_pc_callback(*device, DEVCB_##_devcb);

#define MCFG_I8255_OUT_PORTA_CB(_devcb) \
	devcb = &i8255_device::set_out_pa_callback(*device, DEVCB_##_devcb);

#define MCFG_I8255_OUT_PORTB_CB(_devcb) \
	devcb = &i8255_device::set_out_pb_callback(*device, DEVCB_##_devcb);

#define MCFG_I8255_OUT_PORTC_CB(_devcb) \
	devcb = &i8255_device::set_out_pc_callback(*device, DEVCB_##_devcb);

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

// ======================> i8255_device

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

	template<class _Object> static devcb_base &set_in_pa_callback(device_t &device, _Object object)  { return downcast<i8255_device &>(device).m_in_pa_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_in_pb_callback(device_t &device, _Object object)  { return downcast<i8255_device &>(device).m_in_pb_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_in_pc_callback(device_t &device, _Object object)  { return downcast<i8255_device &>(device).m_in_pc_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_pa_callback(device_t &device, _Object object) { return downcast<i8255_device &>(device).m_out_pa_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_pb_callback(device_t &device, _Object object) { return downcast<i8255_device &>(device).m_out_pb_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_pc_callback(device_t &device, _Object object) { return downcast<i8255_device &>(device).m_out_pc_cb.set_callback(object); }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );

	DECLARE_READ8_MEMBER( pa_r );
	uint8_t pa_r();

	DECLARE_READ8_MEMBER( pb_r );
	uint8_t pb_r();

	DECLARE_WRITE_LINE_MEMBER( pc2_w );
	DECLARE_WRITE_LINE_MEMBER( pc4_w );
	DECLARE_WRITE_LINE_MEMBER( pc6_w );

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

private:
	inline void check_interrupt(int port);
	inline void set_ibf(int port, int state);
	inline void set_obf(int port, int state);
	inline void set_inte(int port, int state);
	inline void set_inte1(int state);
	inline void set_inte2(int state);
	inline void set_intr(int port, int state);
	inline int group_mode(int group);
	inline int port_mode(int port);
	inline int port_c_lower_mode();
	inline int port_c_upper_mode();

	uint8_t read_mode0(int port);
	uint8_t read_mode1(int port);
	uint8_t read_mode2();
	uint8_t read_pc();
	void write_mode0(int port, uint8_t data);
	void write_mode1(int port, uint8_t data);
	void write_mode2(uint8_t data);
	void output_pc();
	void set_mode(uint8_t data);
	void set_pc_bit(int bit, int state);

	devcb_read8        m_in_pa_cb;
	devcb_read8        m_in_pb_cb;
	devcb_read8        m_in_pc_cb;

	devcb_write8       m_out_pa_cb;
	devcb_write8       m_out_pb_cb;
	devcb_write8       m_out_pc_cb;

	uint8_t m_control;            // mode control word
	uint8_t m_output[3];          // output latch
	uint8_t m_input[3];           // input latch

	int m_ibf[2];               // input buffer full flag
	int m_obf[2];               // output buffer full flag, negative logic
	int m_inte[2];              // interrupt enable
	int m_inte1;                // interrupt enable
	int m_inte2;                // interrupt enable
	int m_intr[2];              // interrupt
};


// device type definition
extern const device_type I8255;
extern const device_type I8255A;


#endif