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

    MM74C922/MM74C923 16/20-Key Encoder emulation

**********************************************************************
                            _____   _____
                ROW Y1   1 |*    \_/     | 18  Vcc
                ROW Y2   2 |             | 17  DATA OUT A
                ROW Y3   3 |             | 16  DATA OUT B
                ROW Y4   4 |             | 15  DATA OUT C
            OSCILLATOR   5 |  MM74C922   | 14  DATA OUT D
        KEYBOUNCE MASK   6 |             | 13  _OUTPUT ENABLE
             COLUMN X4   7 |             | 12  DATA AVAILABLE
             COLUMN X3   8 |             | 11  COLUMN X1
                   GND   9 |_____________| 10  COLUMN X2

                            _____   _____
                ROW Y1   1 |*    \_/     | 20  Vcc
                ROW Y2   2 |             | 19  DATA OUT A
                ROW Y3   3 |             | 18  DATA OUT B
                ROW Y4   4 |             | 17  DATA OUT C
                ROW Y5   5 |  MM74C923   | 16  DATA OUT D
            OSCILLATOR   6 |             | 15  DATA OUT E
        KEYBOUNCE MASK   7 |             | 14  _OUTPUT ENABLE
             COLUMN X4   8 |             | 13  DATA AVAILABLE
             COLUMN X3   9 |             | 12  COLUMN X1
                   GND  10 |_____________| 11  COLUMN X2

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

#pragma once

#ifndef __MM74C922__
#define __MM74C922__

#include "emu.h"



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

#define MCFG_MM74C922_OSC(_value) \
	mm74c922_device::static_set_cap_osc(*device, _value);

#define MCFG_MM74C922_DEBOUNCE(_value) \
	mm74c922_device::static_set_cap_debounce(*device, _value);

#define MCFG_MM74C922_DA_CALLBACK(_write) \
	devcb = &mm74c922_device::set_da_wr_callback(*device, DEVCB_##_write);

#define MCFG_MM74C922_X1_CALLBACK(_read) \
	devcb = &mm74c922_device::set_x1_rd_callback(*device, DEVCB_##_read);

#define MCFG_MM74C922_X2_CALLBACK(_read) \
	devcb = &mm74c922_device::set_x2_rd_callback(*device, DEVCB_##_read);

#define MCFG_MM74C922_X3_CALLBACK(_read) \
	devcb = &mm74c922_device::set_x3_rd_callback(*device, DEVCB_##_read);

#define MCFG_MM74C922_X4_CALLBACK(_read) \
	devcb = &mm74c922_device::set_x4_rd_callback(*device, DEVCB_##_read);

#define MCFG_MM74C922_X5_CALLBACK(_read) \
	devcb = &mm74c922_device::set_x5_rd_callback(*device, DEVCB_##_read);



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

// ======================> mm74c922_device

class mm74c922_device :  public device_t
{
public:
	// construction/destruction
	mm74c922_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock);

	static void static_set_cap_osc(device_t &device, double value) { downcast<mm74c922_device &>(device).m_cap_osc = value; }
	static void static_set_cap_debounce(device_t &device, double value) { downcast<mm74c922_device &>(device).m_cap_debounce = value; }

	template<class _Object> static devcb_base &set_da_wr_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_write_da.set_callback(object); }
	template<class _Object> static devcb_base &set_x1_rd_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_read_x1.set_callback(object); }
	template<class _Object> static devcb_base &set_x2_rd_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_read_x2.set_callback(object); }
	template<class _Object> static devcb_base &set_x3_rd_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_read_x3.set_callback(object); }
	template<class _Object> static devcb_base &set_x4_rd_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_read_x4.set_callback(object); }
	template<class _Object> static devcb_base &set_x5_rd_callback(device_t &device, _Object object) { return downcast<mm74c922_device &>(device).m_read_x5.set_callback(object); }

	UINT8 read();

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

private:
	void change_output_lines();
	void clock_scan_counters();
	void detect_keypress();

	devcb_write_line   m_write_da;
	devcb_read8        m_read_x1;
	devcb_read8        m_read_x2;
	devcb_read8        m_read_x3;
	devcb_read8        m_read_x4;
	devcb_read8        m_read_x5;

	double              m_cap_osc;
	double              m_cap_debounce;

	int m_max_y;

	int m_inhibit;              // scan counter clock inhibit
	int m_x;                    // currently scanned column
	int m_y;                    // latched row

	UINT8 m_data;               // data latch

	int m_da;                   // data available flag
	int m_next_da;              // next value of data available flag

	// timers
	emu_timer *m_scan_timer;    // keyboard scan timer
};


// device type definition
extern const device_type MM74C922;
extern const device_type MM74C923;



#endif