summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/a2kbd/a2kbd.h
blob: a2a57420b260293c8a7a27fc5ee8b2e133be5e63 (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
// license:BSD-3-Clause
// copyright-holders:AJR
/*********************************************************************

    Apple II Keyboard Connector

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

#ifndef MAME_BUS_A2KBD_A2KBD_H
#define MAME_BUS_A2KBD_A2KBD_H

#pragma once


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

// forward declaration
class device_a2kbd_interface;

// ======================> a2kbd_connector_device

class a2kbd_connector_device : public device_t, public device_single_card_slot_interface<device_a2kbd_interface>
{
	friend class device_a2kbd_interface;

public:
	// construction/destruction
	a2kbd_connector_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);

	template <typename T>
	a2kbd_connector_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt)
		: a2kbd_connector_device(mconfig, tag, owner, 0U)
	{
		set_options(std::forward<T>(opts), dflt, false);
	}

	// standard options
	static void default_options(device_slot_interface &slot);

	// output callback configuration
	auto b_callback() { return m_b_callback.bind(); }
	auto strobe_callback() { return m_strobe_callback.bind(); }
	auto reset_callback() { return m_reset_callback.bind(); }
	auto mode_callback() { return m_mode_callback.bind(); }

	// shift and control key inputs (modification)
	int shift_r();
	int control_r();

	// outputs to keyboard (modification)
	void ack_w(int state);
	void an3_w(int state);

protected:
	// device_t implementation
	virtual void device_config_complete() override ATTR_COLD;
	virtual void device_resolve_objects() override ATTR_COLD;
	virtual void device_start() override ATTR_COLD;

private:
	// callback objects
	devcb_write8 m_b_callback;
	devcb_write_line m_strobe_callback;
	devcb_write_line m_reset_callback;
	devcb_write_line m_mode_callback;

	// selected device
	device_a2kbd_interface *m_intf;
};

// ======================> device_a2kbd_interface

class device_a2kbd_interface : public device_interface
{
	friend class a2kbd_connector_device;

public:
	virtual ~device_a2kbd_interface();

protected:
	// construction/destruction
	device_a2kbd_interface(const machine_config &mconfig, device_t &device);

	// dedicated inputs from keyboard
	virtual int shift_r() { return 0; }
	virtual int control_r() { return 0; }

	// optional outputs to keyboard
	virtual void ack_w(int state) { }
	virtual void an3_w(int state) { }

	void b_w(u8 data) { m_connector->m_b_callback(data & 0x7f); }
	void strobe_w(int state) { m_connector->m_strobe_callback(state); }
	void reset_w(int state) { m_connector->m_reset_callback(state); }
	void mode_w(int state) { m_connector->m_mode_callback(state); }

private:
	a2kbd_connector_device *m_connector;
};

// device type declaration
DECLARE_DEVICE_TYPE(A2KBD_CONNECTOR, a2kbd_connector_device)

//**************************************************************************
//  INLINE FUNCTIONS
//**************************************************************************

inline int a2kbd_connector_device::shift_r()
{
	// Poll shift key(s) (0 = pressed, 1 = not pressed)
	return (m_intf != nullptr) ? m_intf->shift_r() : 0;
}

inline int a2kbd_connector_device::control_r()
{
	// Poll control key(s) (0 = pressed, 1 = not pressed)
	return (m_intf != nullptr) ? m_intf->control_r() : 1;
}

inline void a2kbd_connector_device::ack_w(int state)
{
	if (m_intf != nullptr)
		m_intf->ack_w(state);
}

inline void a2kbd_connector_device::an3_w(int state)
{
	if (m_intf != nullptr)
		m_intf->an3_w(state);
}

#endif // MAME_BUS_A2KBD_A2KBD_H