Previous 199869 Revisions Next

r32058 Wednesday 10th September, 2014 at 19:12:16 UTC by Dirk Best
Amiga: Implement the Amiga 500 low-level keyboard controller using the
newly dumped internal ROM. Remove existing keyboard HLE.
[src/emu/machine]mos6526.c
[src/mess/machine]amigakbd.c amigakbd.h

trunk/src/emu/machine/mos6526.c
r32057r32058
184184      m_ta_pb6 = 1;
185185   }
186186
187   // switching to serial output mode with a one-shot timer causes a pulse?
188   if (!CRA_SPMODE && BIT(data, 6) && CRA_RUNMODE)
187   // switching to serial output mode causes sp to go high?
188   if (!CRA_SPMODE && BIT(data, 6))
189   {
190      m_bits = 0;
189191      m_write_sp(1);
192   }
190193
191194   // lower sp again when switching back to input?
192   if (CRA_SPMODE && !BIT(data, 6) && CRA_RUNMODE)
195   if (CRA_SPMODE && !BIT(data, 6))
196   {
197      m_bits = 0;
193198      m_write_sp(0);
199   }
194200
195201   m_cra = data;
196202   update_pb();
trunk/src/mess/machine/amigakbd.c
r32057r32058
11/***************************************************************************
22
3    Amiga keyboard controller emulation
3    Amiga Keyboard
44
5    license: MAME, GPL-2.0+
6    copyright-holders: Dirk Best
7
8    We currently emulate the Amiga 500 keyboard controller, which was
9    also used in later Amiga 2000 keyboards.
10
11   TODO: - Natural keyboard mode doesn't work with shifted characters,
12           they get sent in the wrong order (core bug?)
13         - Move 6500/1 to its own CPU core so that it can be shared with
14           other systems
15         - Add support for more keyboard controllers (pending on them
16           getting dumped)
17
518***************************************************************************/
619
7
8#include "emu.h"
9#include "includes/amiga.h"
1020#include "amigakbd.h"
1121
12#define KEYBOARD_BUFFER_SIZE    256
1322
23//**************************************************************************
24//  DEVICE DEFINITIONS
25//**************************************************************************
26
1427const device_type AMIGAKBD = &device_creator<amigakbd_device>;
1528
1629//-------------------------------------------------
30//  machine_config_additions - device-specific
31//  machine configurations
32//-------------------------------------------------
33
34static ADDRESS_MAP_START( mpu6500_map, AS_PROGRAM, 8, amigakbd_device )
35   ADDRESS_MAP_GLOBAL_MASK(0xfff)
36   AM_RANGE(0x000, 0x03f) AM_RAM
37   AM_RANGE(0x080, 0x080) AM_READWRITE(port_a_r, port_a_w)
38   AM_RANGE(0x081, 0x081) AM_READ_PORT("special") AM_WRITE(port_b_w)
39   AM_RANGE(0x082, 0x082) AM_WRITE(port_c_w)
40   AM_RANGE(0x083, 0x083) AM_WRITE(port_d_w)
41   AM_RANGE(0x084, 0x085) AM_WRITE(latch_w)
42   AM_RANGE(0x086, 0x087) AM_READ(counter_r)
43   AM_RANGE(0x088, 0x088) AM_WRITE(transfer_latch_w)
44   AM_RANGE(0x089, 0x089) AM_WRITE(clear_pa0_detect)
45   AM_RANGE(0x08a, 0x08a) AM_WRITE(clear_pa1_detect)
46   AM_RANGE(0x08f, 0x08f) AM_READWRITE(control_r, control_w)
47   AM_RANGE(0x800, 0xfff) AM_ROM AM_REGION("mos6570_036", 0)
48ADDRESS_MAP_END
49
50static MACHINE_CONFIG_FRAGMENT( a500_keyboard )
51   MCFG_CPU_ADD("mos6570_036", M6502, XTAL_3MHz / 2)
52   MCFG_CPU_PROGRAM_MAP(mpu6500_map)
53MACHINE_CONFIG_END
54
55machine_config_constructor amigakbd_device::device_mconfig_additions() const
56{
57   return MACHINE_CONFIG_NAME( a500_keyboard );
58}
59
60//-------------------------------------------------
61//  rom_region - device-specific ROM region
62//-------------------------------------------------
63
64ROM_START( mos6570_036 )
65   ROM_REGION(0x800, "mos6570_036", 0)
66   ROM_LOAD("328191-01.ic1", 0x000, 0x800, CRC(4a3fc332) SHA1(83b21d0c8b93fc9b9b3b287fde4ec8f3badac5a2))
67ROM_END
68
69const rom_entry *amigakbd_device::device_rom_region() const
70{
71   return ROM_NAME( mos6570_036 );
72}
73
74//-------------------------------------------------
75//  input_ports - device-specific input ports
76//-------------------------------------------------
77
78static INPUT_PORTS_START( a500_us_keyboard )
79   PORT_START("special")
80   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED)
81   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LWIN)      PORT_CHAR(UCHAR_MAMEKEY(LWIN))      PORT_NAME("Left Amiga")
82   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT)      PORT_CHAR(UCHAR_MAMEKEY(LALT))
83   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT)    PORT_CHAR(UCHAR_SHIFT_1)
84   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)  PORT_CHAR(UCHAR_SHIFT_2)            PORT_NAME("Ctrl")
85   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RWIN)      PORT_CHAR(UCHAR_MAMEKEY(RWIN))      PORT_NAME("Right Amiga")
86   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT)      PORT_CHAR(UCHAR_MAMEKEY(RALT))
87   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT)    PORT_CHAR(UCHAR_SHIFT_1)
88
89   PORT_START("row_d6")
90   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK)   PORT_CHAR(UCHAR_MAMEKEY(ASTERISK))
91   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_END)                                           PORT_NAME("Unused")
92   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK)   PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_NAME("Caps Lock")
93   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB)        PORT_CHAR(9)
94   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE)      PORT_CHAR('`') PORT_CHAR('~')
95   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC)        PORT_CHAR(UCHAR_MAMEKEY(ESC))
96   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
97   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
98
99   PORT_START("row_d5")
100   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD)   PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
101   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z)          PORT_CHAR('z') PORT_CHAR('Z')
102   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A)          PORT_CHAR('a') PORT_CHAR('A')
103   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q)          PORT_CHAR('q') PORT_CHAR('Q')
104   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1)          PORT_CHAR('1') PORT_CHAR('!')
105   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME)                                          PORT_NAME("(")
106   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
107   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
108
109   PORT_START("row_d4")
110   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD)      PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
111   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X)          PORT_CHAR('x') PORT_CHAR('X')
112   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S)          PORT_CHAR('s') PORT_CHAR('S')
113   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W)          PORT_CHAR('w') PORT_CHAR('W')
114   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2)          PORT_CHAR('2') PORT_CHAR('@')
115   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1)         PORT_CHAR(UCHAR_MAMEKEY(F1))
116   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
117   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
118
119   PORT_START("row_d3")
120   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD)      PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
121   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C)          PORT_CHAR('c') PORT_CHAR('C')
122   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D)          PORT_CHAR('d') PORT_CHAR('D')
123   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E)          PORT_CHAR('e') PORT_CHAR('E')
124   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3)          PORT_CHAR('3') PORT_CHAR('#')
125   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2)         PORT_CHAR(UCHAR_MAMEKEY(F2))
126   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
127   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
128
129   PORT_START("row_d2")
130   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD)      PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
131   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V)          PORT_CHAR('v') PORT_CHAR('V')
132   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F)          PORT_CHAR('f') PORT_CHAR('F')
133   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R)          PORT_CHAR('r') PORT_CHAR('R')
134   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4)          PORT_CHAR('4') PORT_CHAR('$')
135   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3)         PORT_CHAR(UCHAR_MAMEKEY(F3))
136   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
137   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
138
139   PORT_START("row_d1")
140   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD)    PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
141   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B)          PORT_CHAR('b') PORT_CHAR('B')
142   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G)          PORT_CHAR('g') PORT_CHAR('G')
143   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T)          PORT_CHAR('t') PORT_CHAR('T')
144   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5)          PORT_CHAR('5') PORT_CHAR('%')
145   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4)         PORT_CHAR(UCHAR_MAMEKEY(F4))
146   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
147   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
148
149   PORT_START("row_d0")
150   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD)      PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
151   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N)          PORT_CHAR('n') PORT_CHAR('N')
152   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H)          PORT_CHAR('h') PORT_CHAR('H')
153   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y)          PORT_CHAR('y') PORT_CHAR('Y')
154   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6)          PORT_CHAR('6') PORT_CHAR('^')
155   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5)         PORT_CHAR(UCHAR_MAMEKEY(F5))
156   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
157   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
158
159   PORT_START("row_c7")
160   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD)      PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
161   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M)          PORT_CHAR('m') PORT_CHAR('M')
162   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J)          PORT_CHAR('j') PORT_CHAR('J')
163   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U)          PORT_CHAR('u') PORT_CHAR('U')
164   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7)          PORT_CHAR('7') PORT_CHAR('&')
165   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP)                                          PORT_NAME(")")
166   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
167   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
168
169   PORT_START("row_c6")
170   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD)      PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
171   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA)      PORT_CHAR(',') PORT_CHAR('<')
172   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K)          PORT_CHAR('k') PORT_CHAR('K')
173   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I)          PORT_CHAR('i') PORT_CHAR('I')
174   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8)          PORT_CHAR('8') PORT_CHAR('*')
175   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6)         PORT_CHAR(UCHAR_MAMEKEY(F6))
176   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
177   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
178
179   PORT_START("row_c5")
180   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD)  PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))
181   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP)       PORT_CHAR('.') PORT_CHAR('>')
182   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L)          PORT_CHAR('l') PORT_CHAR('L')
183   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O)          PORT_CHAR('o') PORT_CHAR('O')
184   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9)          PORT_CHAR('9') PORT_CHAR('(')
185   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD)  PORT_CHAR('/')
186   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
187   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
188
189   PORT_START("row_c4")
190   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD)      PORT_CHAR('7') PORT_CHAR('&')
191   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH)      PORT_CHAR('/') PORT_CHAR('?')
192   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON)      PORT_CHAR(';') PORT_CHAR(':')
193   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P)          PORT_CHAR('p') PORT_CHAR('P')
194   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0)          PORT_CHAR('0') PORT_CHAR(')')
195   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7)         PORT_CHAR(UCHAR_MAMEKEY(F7))
196   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
197   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
198
199   PORT_START("row_c3")
200   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD)      PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
201   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED)
202   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE)      PORT_CHAR('\'') PORT_CHAR('"')
203   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE)  PORT_CHAR('[')  PORT_CHAR('{')
204   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS)      PORT_CHAR('-')  PORT_CHAR('_')
205   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8)         PORT_CHAR(UCHAR_MAMEKEY(F8))
206   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
207   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
208
209   PORT_START("row_c2")
210   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD)      PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
211   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE)      PORT_CHAR(' ')
212   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN)                                          PORT_NAME("Unused")
213   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
214   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS)     PORT_CHAR('=') PORT_CHAR('+')
215   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9)         PORT_CHAR(UCHAR_MAMEKEY(F9))
216   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
217   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
218
219   PORT_START("row_c1")
220   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD)     PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
221   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
222   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL)       PORT_CHAR(UCHAR_MAMEKEY(DEL))
223   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER)     PORT_CHAR(13)
224   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
225   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10)       PORT_CHAR(UCHAR_MAMEKEY(F10))
226   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
227   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
228
229   PORT_START("row_c0")
230   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
231   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN)      PORT_CHAR(UCHAR_MAMEKEY(DOWN))
232   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT)     PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
233   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT)      PORT_CHAR(UCHAR_MAMEKEY(LEFT))
234   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP)        PORT_CHAR(UCHAR_MAMEKEY(UP))
235   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11)                                           PORT_NAME("Help")
236   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
237   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
238INPUT_PORTS_END
239
240ioport_constructor amigakbd_device::device_input_ports() const
241{
242   return INPUT_PORTS_NAME( a500_us_keyboard );
243}
244
245
246//**************************************************************************
247//  LIVE DEVICE
248//**************************************************************************
249
250//-------------------------------------------------
17251//  amigakbd_device - constructor
18252//-------------------------------------------------
19253
20254amigakbd_device::amigakbd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
21   : device_t(mconfig, AMIGAKBD, "Amiga Keyboard", tag, owner, clock, "amigakbd", __FILE__),
255   : device_t(mconfig, AMIGAKBD, "Amiga 500 Keyboard with 6570-036 MPU", tag, owner, clock, "amigakbd", __FILE__),
22256   m_write_kclk(*this),
23257   m_write_kdat(*this),
24   m_buf(NULL),
25   m_buf_pos(0),
26   m_cur_pos(0),
27   m_timer(NULL)
258   m_mpu(*this, "mos6570_036"),
259   m_row_d6(*this, "row_d6"),
260   m_row_d5(*this, "row_d5"),
261   m_row_d4(*this, "row_d4"),
262   m_row_d3(*this, "row_d3"),
263   m_row_d2(*this, "row_d2"),
264   m_row_d1(*this, "row_d1"),
265   m_row_d0(*this, "row_d0"),
266   m_row_c7(*this, "row_c7"),
267   m_row_c6(*this, "row_c6"),
268   m_row_c5(*this, "row_c5"),
269   m_row_c4(*this, "row_c4"),
270   m_row_c3(*this, "row_c3"),
271   m_row_c2(*this, "row_c2"),
272   m_row_c1(*this, "row_c1"),
273   m_row_c0(*this, "row_c0"),
274   m_timer(NULL),
275   m_watchdog(NULL),
276   m_kdat(1),
277   m_kclk(1),
278   m_port_c(0xff),
279   m_port_d(0xff),
280   m_latch(0xffff),
281   m_counter(0xffff),
282   m_control(0x00)
28283{
29284}
30285
r32057r32058
36291{
37292   m_write_kclk.resolve_safe();
38293   m_write_kdat.resolve_safe();
294   m_timer = timer_alloc(0, NULL);
295   m_watchdog = timer_alloc(1, NULL);
296}
39297
40   /* allocate a keyboard buffer */
41   m_buf = auto_alloc_array(machine(), UINT8, KEYBOARD_BUFFER_SIZE);
42   m_timer = timer_alloc(0);
43   m_timer->reset();
298//-------------------------------------------------
299//  device_reset - device-specific reset
300//-------------------------------------------------
301
302void amigakbd_device::device_reset()
303{
304   // stack starts 0
305   m_mpu->set_state_int(M6502_S, 0);
306
307   m_kdat = 1;
308   m_kclk = 1;
309   m_port_c = 0xff;
310   m_port_d = 0xff;
311   m_latch = 0xffff;   // not initialized by hardware
312   m_counter = 0xffff;   // not initialized by hardware
313   m_control = 0x00;
314
315   m_timer->adjust(attotime::zero, 0, attotime::from_hz(XTAL_3MHz / 2));
316   m_watchdog->adjust(attotime::from_msec(54));
44317}
45318
46void amigakbd_device::kbd_sendscancode(UINT8 scancode )
319void amigakbd_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
47320{
48   // send over to the cia
49   for(int j = 0; j < 8; j++)
321   switch (tid)
50322   {
51      m_write_kclk(0);    /* lower cnt */
52      m_write_kdat(BIT(scancode << j, 7)); /* set the serial data */
53      m_write_kclk(1);    /* raise cnt */
323   case 0:
324      switch (m_control & 0x03)
325      {
326      // interval timer, pulse width measurement (connected to gnd here)
327      case 0:
328      case 3:
329         if (m_counter-- == 0)
330         {
331            // counter overflow
332            m_control |= COUNTER_OVERFLOW;
333            m_counter = m_latch;
334
335            // generate interrupt?
336            update_irqs();
337         }
338         break;
339
340      // pulse generator
341      case 1:
342         break;
343
344      // event counter
345      case 2:
346         break;
347      }
348      break;
349
350   case 1:
351      m_mpu->reset();
352      m_watchdog->adjust(attotime::from_msec(54));
353      break;
54354   }
55355}
56356
57//-------------------------------------------------
58//  device_timer - handler timer events
59//-------------------------------------------------
60357
61void amigakbd_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
358//**************************************************************************
359//  IMPLEMENTATION
360//**************************************************************************
361
362void amigakbd_device::update_irqs()
62363{
63   UINT8   scancode;
364   if ((m_control & PA1_INT_ENABLED) && (m_control & PA1_NEGATIVE_EDGE))
365      m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
64366
65   (void)param;
367   else if ((m_control & PA0_INT_ENABLED) && (m_control & PA0_POSITIVE_EDGE))
368      m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
66369
67   /* if we don't have pending data, bail */
370   else if ((m_control & COUNTER_INT_ENABLED) && (m_control & COUNTER_OVERFLOW))
371      m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
68372
69   if ( m_buf_pos == m_cur_pos )
70      return;
373   else
374      m_mpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
375}
71376
72   /* fetch the next scan code and send it to the Amiga */
73   scancode = m_buf[m_cur_pos++];
74   m_cur_pos %= KEYBOARD_BUFFER_SIZE;
75   kbd_sendscancode(scancode);
377READ8_MEMBER( amigakbd_device::port_a_r )
378{
379   UINT8 data = 0xfc;
76380
77   /* if we still have more data, schedule another update */
78   if ( m_buf_pos != m_cur_pos )
381   // kdat & kclk
382   data |= m_kdat << 0;
383   data |= m_kclk << 1;
384
385   // port d rows
386   if (!BIT(m_port_d, 6)) data &= m_row_d6->read();
387   if (!BIT(m_port_d, 5)) data &= m_row_d5->read();
388   if (!BIT(m_port_d, 4)) data &= m_row_d4->read();
389   if (!BIT(m_port_d, 3)) data &= m_row_d3->read();
390   if (!BIT(m_port_d, 2)) data &= m_row_d2->read();
391   if (!BIT(m_port_d, 1)) data &= m_row_d1->read();
392   if (!BIT(m_port_d, 0)) data &= m_row_d0->read();
393
394   // port c rows
395   if (!BIT(m_port_c, 7)) data &= m_row_c7->read();
396   if (!BIT(m_port_c, 6)) data &= m_row_c6->read();
397   if (!BIT(m_port_c, 5)) data &= m_row_c5->read();
398   if (!BIT(m_port_c, 4)) data &= m_row_c4->read();
399   if (!BIT(m_port_c, 3)) data &= m_row_c3->read();
400   if (!BIT(m_port_c, 2)) data &= m_row_c2->read();
401   if (!BIT(m_port_c, 1)) data &= m_row_c1->read();
402   if (!BIT(m_port_c, 0)) data &= m_row_c0->read();
403
404   return data;
405}
406
407WRITE8_MEMBER( amigakbd_device::port_a_w )
408{
409   // look for pa0 edge
410   if (!m_kdat && BIT(data, 0))
79411   {
80      m_timer->adjust(machine().first_screen()->frame_period() / 4);
412      m_control |= PA0_POSITIVE_EDGE;
413      update_irqs();
81414   }
415
416   // and pa1 edge
417   if (m_kclk && !BIT(data, 1))
418   {
419      m_control |= PA1_NEGATIVE_EDGE;
420      update_irqs();
421   }
422
423   // update with new values and output
424   if (m_kdat != BIT(data, 0))
425   {
426      m_kdat = BIT(data, 0);
427      m_write_kdat(m_kdat);
428   }
429
430   if (m_kclk != BIT(data, 1))
431   {
432      m_kclk = BIT(data, 1);
433      m_write_kclk(m_kclk);
434   }
82435}
83436
84WRITE_LINE_MEMBER( amigakbd_device::kdat_w )
437WRITE8_MEMBER( amigakbd_device::port_b_w )
85438{
86   // todo: do something with the handshake
87   // the real keyboard times out if it doesn't receive a handshake
88   // after a key and goes into resync mode
439   // caps lock led
440   output_set_value("led0", BIT(data, 7));
89441}
90442
91INPUT_CHANGED_MEMBER( amigakbd_device::kbd_update )
443WRITE8_MEMBER( amigakbd_device::port_c_w )
92444{
93   int index = (int)(FPTR)param, i;
94   UINT32  oldvalue = oldval * field.mask(), newvalue = newval * field.mask();
95   UINT32  delta = oldvalue ^ newvalue;
445   m_port_c = data;
446}
96447
97   int key_buf_was_empty = ( m_buf_pos == m_cur_pos ) ? 1 : 0;
448WRITE8_MEMBER( amigakbd_device::port_d_w )
449{
450   // reset watchdog on 0 -> 1 transition
451   if (!BIT(m_port_d, 7) && BIT(data, 7))
452      m_watchdog->adjust(attotime::from_msec(54));
98453
99   for( i = 0; i < 32; i++ )
454   m_port_d = data;
455}
456
457WRITE8_MEMBER( amigakbd_device::latch_w )
458{
459   if (offset == 0)
100460   {
101      if ( delta & ( 1 << i ) )
102      {
103         int down = ( newvalue & ( 1 << i ) ) ? 0 : 1;
104         int scancode = ( ( (index*32)+i ) << 1 ) | down;
105         int amigacode = ~scancode;
106
107         /* add the keycode to the buffer */
108         m_buf[m_buf_pos++] = amigacode & 0xff;
109         m_buf_pos %= KEYBOARD_BUFFER_SIZE;
110      }
461      m_latch &= 0x00ff;
462      m_latch |= data << 8;
111463   }
112
113   /* if the buffer was empty and we have new data, start a timer to send the keystrokes */
114   if ( key_buf_was_empty && ( m_buf_pos != m_cur_pos ) )
464   else
115465   {
116      m_timer->adjust(machine().first_screen()->frame_period() / 4);
466      m_latch &= 0xff00;
467      m_latch |= data << 0;
117468   }
118469}
119470
120/*********************************************************************************************/
471READ8_MEMBER( amigakbd_device::counter_r )
472{
473   if (!space.debugger_access())
474   {
475      m_control &= ~COUNTER_OVERFLOW;
476      update_irqs();
477   }
121478
122/* Layout is for the US A500 keyboard */
479   if (offset == 0)
480      return m_counter >> 8;
481   else
482      return m_counter >> 0;
483}
123484
124INPUT_PORTS_START( amiga_us_keyboard )
125   PORT_START("amiga_keyboard_0")
126   PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')     // 00
127   PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')         // 01
128   PORT_BIT( 0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')         // 02
129   PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')         // 03
130   PORT_BIT( 0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')         // 04
131   PORT_BIT( 0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')         // 05
132   PORT_BIT( 0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')         // 06
133   PORT_BIT( 0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')         // 07
134   PORT_BIT( 0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')         // 08
135   PORT_BIT( 0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')         // 09
136   PORT_BIT( 0x00000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')         // 0A
137   PORT_BIT( 0x00000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')     // 0B
138   PORT_BIT( 0x00001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')        // 0C
139   PORT_BIT( 0x00002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('\\') PORT_CHAR('\xA6')    // 0D
140   PORT_BIT( 0x00004000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0)                                  // 0E
141   PORT_BIT( 0x00008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))   // 0F
142   PORT_BIT( 0x00010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')         // 10
143   PORT_BIT( 0x00020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')         // 11
144   PORT_BIT( 0x00040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')         // 12
145   PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')         // 13
146   PORT_BIT( 0x00100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')         // 14
147   PORT_BIT( 0x00200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')         // 15
148   PORT_BIT( 0x00400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')         // 16
149   PORT_BIT( 0x00800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')         // 17
150   PORT_BIT( 0x01000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')         // 18
151   PORT_BIT( 0x02000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')         // 19
152   PORT_BIT( 0x04000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') // 1A
153   PORT_BIT( 0x08000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')    // 1B
154   PORT_BIT( 0x10000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0)                                  // 1C
155   PORT_BIT( 0x20000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))   // 1D
156   PORT_BIT( 0x40000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))   // 1E
157   PORT_BIT( 0x80000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 0) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))   // 1F
485WRITE8_MEMBER( amigakbd_device::transfer_latch_w )
486{
487   m_control &= ~COUNTER_OVERFLOW;
488   update_irqs();
158489
159   PORT_START("amiga_keyboard_1")
160   PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')         // 20
161   PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')         // 21
162   PORT_BIT( 0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')         // 22
163   PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')         // 23
164   PORT_BIT( 0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')         // 24
165   PORT_BIT( 0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')         // 25
166   PORT_BIT( 0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')         // 26
167   PORT_BIT( 0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')         // 27
168   PORT_BIT( 0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')         // 28
169   PORT_BIT( 0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')     // 29
170   PORT_BIT( 0x00000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')        // 2A
171   PORT_BIT( 0x00000800, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1)                                  // 2B
172   PORT_BIT( 0x00001000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1)                                  // 2C
173   PORT_BIT( 0x00002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))   // 2D
174   PORT_BIT( 0x00004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))   // 2E
175   PORT_BIT( 0x00008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))   // 2F
176   PORT_BIT( 0x00010000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1)                                  // 30
177   PORT_BIT( 0x00020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')         // 31
178   PORT_BIT( 0x00040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')         // 32
179   PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')         // 33
180   PORT_BIT( 0x00100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')         // 34
181   PORT_BIT( 0x00200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')         // 35
182   PORT_BIT( 0x00400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')         // 36
183   PORT_BIT( 0x00800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')         // 37
184   PORT_BIT( 0x01000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')     // 38
185   PORT_BIT( 0x02000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_STOP)     PORT_CHAR('.') PORT_CHAR('>')      // 39
186   PORT_BIT( 0x04000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')     // 3A
187   PORT_BIT( 0x08000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1)                                  // 3B
188   PORT_BIT( 0x10000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))// 3C
189   PORT_BIT( 0x20000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))   // 3D
190   PORT_BIT( 0x40000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))   // 3E
191   PORT_BIT( 0x80000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 1) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))   // 3F
490   m_latch &= 0x00ff;
491   m_latch |= data << 8;
192492
193   PORT_START("amiga_keyboard_2")
194   PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')                        // 40
195   PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)                  // 41
196   PORT_BIT( 0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')                     // 42
197   PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))   // 43
198   PORT_BIT( 0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)                     // 44
199   PORT_BIT( 0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))       // 45
200   PORT_BIT( 0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))       // 46
201   PORT_BIT( 0x00000080, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 47
202   PORT_BIT( 0x00000100, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 48
203   PORT_BIT( 0x00000200, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 49
204   PORT_BIT( 0x00000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))   // 4A
205   PORT_BIT( 0x00000800, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 4B
206   PORT_BIT( 0x00001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))         // 4C
207   PORT_BIT( 0x00002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))     // 4D
208   PORT_BIT( 0x00004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))   // 4E
209   PORT_BIT( 0x00008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))     // 4F
210   PORT_BIT( 0x00010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))         // 50
211   PORT_BIT( 0x00020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))         // 51
212   PORT_BIT( 0x00040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))         // 52
213   PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))         // 53
214   PORT_BIT( 0x00100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5))         // 54
215   PORT_BIT( 0x00200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))         // 55
216   PORT_BIT( 0x00400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))         // 56
217   PORT_BIT( 0x00800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))         // 57
218   PORT_BIT( 0x01000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9))         // 58
219   PORT_BIT( 0x02000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10))       // 59
220   PORT_BIT( 0x04000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 5A
221   PORT_BIT( 0x08000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2)                                  // 5B
222   PORT_BIT( 0x10000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD))   // 5C
223   PORT_BIT( 0x20000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) // 5D
224   PORT_BIT( 0x40000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) // 5E
225   PORT_BIT( 0x80000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 2) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) // 5F
493   m_counter = m_latch;
494}
226495
227   PORT_START("amiga_keyboard_3")
228   PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Shift (Left)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)   // 60
229   PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Shift (Right)") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)  // 61
230   PORT_BIT( 0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK)         // 62
231   PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))// 63
232   PORT_BIT( 0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Alt (Left)") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) // 64
233   PORT_BIT( 0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Alt (Right)") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT))    // 65
234   PORT_BIT( 0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Amiga A (Left)") PORT_CODE(KEYCODE_LWIN)                // 66
235   PORT_BIT( 0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3) PORT_NAME("Amiga A (Right)")  PORT_CODE(KEYCODE_RWIN)          // 67
236   PORT_BIT( 0x00000100, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 68
237   PORT_BIT( 0x00000200, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 69
238   PORT_BIT( 0x00000400, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6A
239   PORT_BIT( 0x00000800, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6B
240   PORT_BIT( 0x00001000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6C
241   PORT_BIT( 0x00002000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6D
242   PORT_BIT( 0x00004000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6E
243   PORT_BIT( 0x00008000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 6F
244   PORT_BIT( 0x00010000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 70
245   PORT_BIT( 0x00020000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 71
246   PORT_BIT( 0x00040000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 72
247   PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 73
248   PORT_BIT( 0x00100000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 74
249   PORT_BIT( 0x00200000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 75
250   PORT_BIT( 0x00400000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 76
251   PORT_BIT( 0x00800000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 77
252   PORT_BIT( 0x01000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 78
253   PORT_BIT( 0x02000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 79
254   PORT_BIT( 0x04000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 7A
255   PORT_BIT( 0x08000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 7B
256   PORT_BIT( 0x10000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 7C
257   PORT_BIT( 0x20000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 7D
258   PORT_BIT( 0x40000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)                                  // 7E
259   PORT_BIT( 0x80000000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, amigakbd_device, kbd_update, 3)    PORT_CODE(KEYCODE_PGUP)         // 7F NMI button
260INPUT_PORTS_END
496WRITE8_MEMBER( amigakbd_device::clear_pa0_detect )
497{
498   m_control &= ~PA0_POSITIVE_EDGE;
499   update_irqs();
500}
261501
262//-------------------------------------------------
263//  input_ports - device-specific input ports
264//-------------------------------------------------
502WRITE8_MEMBER( amigakbd_device::clear_pa1_detect )
503{
504   m_control &= ~PA1_NEGATIVE_EDGE;
505   update_irqs();
506}
265507
266ioport_constructor amigakbd_device::device_input_ports() const
508READ8_MEMBER( amigakbd_device::control_r )
267509{
268   return INPUT_PORTS_NAME( amiga_us_keyboard );
510   return m_control;
269511}
270512
271//-------------------------------------------------
272//  rom_region - device-specific ROM region
273//-------------------------------------------------
513WRITE8_MEMBER( amigakbd_device::control_w )
514{
515   m_control = data;
516   update_irqs();
517}
274518
275ROM_START( keyboard_mpu )
276   ROM_REGION(0x800, "keyboard", 0)
277   ROM_LOAD("328191-01.ic1", 0x000, 0x800, NO_DUMP)
278ROM_END
519WRITE_LINE_MEMBER( amigakbd_device::kdat_w )
520{
521   // detect positive edge
522   if (state && !m_kdat)
523   {
524      m_control |= PA0_POSITIVE_EDGE;
525      update_irqs();
526   }
279527
280const rom_entry *amigakbd_device::device_rom_region() const
281{
282   return ROM_NAME( keyboard_mpu );
528   m_kdat = state;
283529}
trunk/src/mess/machine/amigakbd.h
r32057r32058
1#ifndef AMIGAKBD_H
2#define AMIGAKBD_H
1/***************************************************************************
32
3    Amiga Keyboard
44
5    license: MAME, GPL-2.0+
6    copyright-holders: Dirk Best
7
8    We currently emulate the Amiga 500 keyboard controller, which was
9    also used in later Amiga 2000 keyboards.
10
11***************************************************************************/
12
13#pragma once
14
15#ifndef __AMIGAKBD_H__
16#define __AMIGAKBD_H__
17
18#include "emu.h"
19#include "cpu/m6502/m6502.h"
20
21
522//**************************************************************************
623//  INTERFACE CONFIGURATION MACROS
724//**************************************************************************
r32057r32058
1936
2037// ======================> amigakbd_device
2138
22class amigakbd_device : public device_t
39class amigakbd_device : public device_t
2340{
2441public:
2542   // construction/destruction
2643   amigakbd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2744
28   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); }
29   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); }
45   template<class _Object> static devcb_base &set_kclk_wr_callback(device_t &device, _Object object)
46      { return downcast<amigakbd_device &>(device).m_write_kclk.set_callback(object); }
47   template<class _Object> static devcb_base &set_kdat_wr_callback(device_t &device, _Object object)
48      { return downcast<amigakbd_device &>(device).m_write_kdat.set_callback(object); }
3049
31   // optional information overrides
32   virtual ioport_constructor device_input_ports() const;
33   virtual const rom_entry *device_rom_region() const;
50   DECLARE_WRITE_LINE_MEMBER( kdat_w );
3451
35   DECLARE_INPUT_CHANGED_MEMBER( kbd_update );
52   // 6500/1 internal
53   DECLARE_READ8_MEMBER( port_a_r );
54   DECLARE_WRITE8_MEMBER( port_a_w );
55   DECLARE_READ8_MEMBER( port_b_r );
56   DECLARE_WRITE8_MEMBER( port_b_w );
57   DECLARE_WRITE8_MEMBER( port_c_w );
58   DECLARE_WRITE8_MEMBER( port_d_w );
59   DECLARE_WRITE8_MEMBER( latch_w );
60   DECLARE_READ8_MEMBER( counter_r );
61   DECLARE_WRITE8_MEMBER( transfer_latch_w );
62   DECLARE_WRITE8_MEMBER( clear_pa0_detect );
63   DECLARE_WRITE8_MEMBER( clear_pa1_detect );
64   DECLARE_READ8_MEMBER( control_r );
65   DECLARE_WRITE8_MEMBER( control_w );
3666
37   DECLARE_WRITE_LINE_MEMBER( kdat_w );
38
3967protected:
4068   // device-level overrides
69   virtual const rom_entry *device_rom_region() const;
70   virtual machine_config_constructor device_mconfig_additions() const;
71   virtual ioport_constructor device_input_ports() const;
4172   virtual void device_start();
73   virtual void device_reset();
4274   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
4375
44   void kbd_sendscancode(UINT8 scancode );
76private:
77   enum
78   {
79      // counter modes
80      COUNTER_INTERVAL = 0x00,
81      COUNTER_PULSE = 0x01,
82      COUNTER_EVENT = 0x02,
83      COUNTER_PWM = 0x03,
4584
46private:
85      // interrupt enables
86      PA1_INT_ENABLED     = 0x04,
87      PA0_INT_ENABLED     = 0x08,
88      COUNTER_INT_ENABLED = 0x10,
89
90      // status
91      PA1_NEGATIVE_EDGE = 0x20,
92      PA0_POSITIVE_EDGE = 0x40,
93      COUNTER_OVERFLOW  = 0x80
94   };
95
96   void update_irqs();
97
4798   devcb_write_line m_write_kclk;
4899   devcb_write_line m_write_kdat;
49100
50   UINT8 *m_buf;
51   int m_buf_pos;
52   int m_cur_pos;
101   required_device<m6502_device> m_mpu;
102
103   required_ioport m_row_d6;
104   required_ioport m_row_d5;
105   required_ioport m_row_d4;
106   required_ioport m_row_d3;
107   required_ioport m_row_d2;
108   required_ioport m_row_d1;
109   required_ioport m_row_d0;
110   required_ioport m_row_c7;
111   required_ioport m_row_c6;
112   required_ioport m_row_c5;
113   required_ioport m_row_c4;
114   required_ioport m_row_c3;
115   required_ioport m_row_c2;
116   required_ioport m_row_c1;
117   required_ioport m_row_c0;
118
53119   emu_timer *m_timer;
120   emu_timer *m_watchdog;
121
122   int m_kdat;
123   int m_kclk;
124
125   UINT8 m_port_c;
126   UINT8 m_port_d;
127   UINT16 m_latch;
128   UINT16 m_counter;
129   UINT8 m_control;
54130};
55131
56132// device type definition
57133extern const device_type AMIGAKBD;
58134
59#endif // AMIGAKBD_H
135#endif // __AMIGAKBD_H__

Previous 199869 Revisions Next


© 1997-2024 The MAME Team