summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/amigakbd.h
blob: 9c974238e3a7d2e19cfced1df59ff6552ce72d77 (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
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************

    Amiga Keyboard

    We currently emulate the Amiga 500 keyboard controller, which was
    also used in later Amiga 2000 keyboards.

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

#pragma once

#ifndef __AMIGAKBD_H__
#define __AMIGAKBD_H__

#include "emu.h"
#include "cpu/m6502/m6502.h"


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

#define MCFG_AMIGA_KEYBOARD_KCLK_CALLBACK(_write) \
	devcb = &amigakbd_device::set_kclk_wr_callback(*device, DEVCB_##_write);

#define MCFG_AMIGA_KEYBOARD_KDAT_CALLBACK(_write) \
	devcb = &amigakbd_device::set_kdat_wr_callback(*device, DEVCB_##_write);

#define MCFG_AMIGA_KEYBOARD_KRST_CALLBACK(_write) \
	devcb = &amigakbd_device::set_krst_wr_callback(*device, DEVCB_##_write);


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

// ======================> amigakbd_device

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

	template<class _Object> static devcb_base &set_kclk_wr_callback(device_t &device, _Object object)
		{ return downcast<amigakbd_device &>(device).m_write_kclk.set_callback(object); }
	template<class _Object> static devcb_base &set_kdat_wr_callback(device_t &device, _Object object)
		{ return downcast<amigakbd_device &>(device).m_write_kdat.set_callback(object); }
	template<class _Object> static devcb_base &set_krst_wr_callback(device_t &device, _Object object)
		{ return downcast<amigakbd_device &>(device).m_write_krst.set_callback(object); }

	DECLARE_WRITE_LINE_MEMBER( kdat_w );

	// 6500/1 internal
	DECLARE_READ8_MEMBER( port_a_r );
	DECLARE_WRITE8_MEMBER( port_a_w );
	DECLARE_READ8_MEMBER( port_b_r );
	DECLARE_WRITE8_MEMBER( port_b_w );
	DECLARE_WRITE8_MEMBER( port_c_w );
	DECLARE_WRITE8_MEMBER( port_d_w );
	DECLARE_WRITE8_MEMBER( latch_w );
	DECLARE_READ8_MEMBER( counter_r );
	DECLARE_WRITE8_MEMBER( transfer_latch_w );
	DECLARE_WRITE8_MEMBER( clear_pa0_detect );
	DECLARE_WRITE8_MEMBER( clear_pa1_detect );
	DECLARE_READ8_MEMBER( control_r );
	DECLARE_WRITE8_MEMBER( control_w );

	DECLARE_INPUT_CHANGED_MEMBER( check_reset );

protected:
	// device-level overrides
	virtual const rom_entry *device_rom_region() const override;
	virtual machine_config_constructor device_mconfig_additions() const override;
	virtual ioport_constructor device_input_ports() const override;
	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;

private:
	enum
	{
		// counter modes
		COUNTER_INTERVAL = 0x00,
		COUNTER_PULSE = 0x01,
		COUNTER_EVENT = 0x02,
		COUNTER_PWM = 0x03,

		// interrupt enables
		PA1_INT_ENABLED     = 0x04,
		PA0_INT_ENABLED     = 0x08,
		COUNTER_INT_ENABLED = 0x10,

		// status
		PA1_NEGATIVE_EDGE = 0x20,
		PA0_POSITIVE_EDGE = 0x40,
		COUNTER_OVERFLOW  = 0x80
	};

	void update_irqs();

	devcb_write_line m_write_kclk;
	devcb_write_line m_write_kdat;
	devcb_write_line m_write_krst;

	required_device<m6502_device> m_mpu;

	required_ioport m_special;
	required_ioport m_row_d6;
	required_ioport m_row_d5;
	required_ioport m_row_d4;
	required_ioport m_row_d3;
	required_ioport m_row_d2;
	required_ioport m_row_d1;
	required_ioport m_row_d0;
	required_ioport m_row_c7;
	required_ioport m_row_c6;
	required_ioport m_row_c5;
	required_ioport m_row_c4;
	required_ioport m_row_c3;
	required_ioport m_row_c2;
	required_ioport m_row_c1;
	required_ioport m_row_c0;

	emu_timer *m_timer;
	emu_timer *m_watchdog;
	emu_timer *m_reset;

	int m_kdat;
	int m_kclk;

	UINT8 m_port_c;
	UINT8 m_port_d;
	UINT16 m_latch;
	UINT16 m_counter;
	UINT8 m_control;
};

// device type definition
extern const device_type AMIGAKBD;

#endif // __AMIGAKBD_H__