1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     IBM 5150 83-key keyboard emulation
6 
7 *********************************************************************/
8 
9 #include "emu.h"
10 #include "pc83.h"
11 
12 
13 
14 //**************************************************************************
15 //  MACROS / CONSTANTS
16 //**************************************************************************
17 
18 #define I8048_TAG       "u1"
19 
20 
21 
22 //**************************************************************************
23 //  DEVICE DEFINITIONS
24 //**************************************************************************
25 
26 DEFINE_DEVICE_TYPE(PC_KBD_IBM_PC_83, ibm_pc_83_keyboard_device, "kb_pc83", "IBM PC Keyboard")
27 
28 
29 //-------------------------------------------------
30 //  ROM( ibm_pc_83_keyboard )
31 //-------------------------------------------------
32 
ROM_START(ibm_pc_83_keyboard)33 ROM_START( ibm_pc_83_keyboard )
34 	ROM_REGION( 0x400, I8048_TAG, 0 )
35 	ROM_LOAD( "8048.u1", 0x000, 0x400, NO_DUMP )
36 ROM_END
37 
38 
39 //-------------------------------------------------
40 //  rom_region - device-specific ROM region
41 //-------------------------------------------------
42 
43 const tiny_rom_entry *ibm_pc_83_keyboard_device::device_rom_region() const
44 {
45 	return ROM_NAME( ibm_pc_83_keyboard );
46 }
47 
48 
49 //-------------------------------------------------
50 //  device_add_mconfig - add device configuration
51 //-------------------------------------------------
52 
device_add_mconfig(machine_config & config)53 void ibm_pc_83_keyboard_device::device_add_mconfig(machine_config &config)
54 {
55 	I8048(config, m_maincpu, MCS48_LC_CLOCK(IND_U(47), CAP_P(20)));
56 	m_maincpu->bus_out_cb().set(FUNC(ibm_pc_83_keyboard_device::bus_w));
57 	m_maincpu->p1_in_cb().set(FUNC(ibm_pc_83_keyboard_device::p1_r));
58 	m_maincpu->p2_out_cb().set(FUNC(ibm_pc_83_keyboard_device::p2_w));
59 	m_maincpu->t0_in_cb().set(FUNC(ibm_pc_83_keyboard_device::t0_r));
60 }
61 
62 
63 //-------------------------------------------------
64 //  INPUT_PORTS( ibm_pc_83_keyboard )
65 //-------------------------------------------------
66 
67 INPUT_PORTS_START( ibm_pc_83_keyboard )
68 	PORT_START("DR00")
69 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
70 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
71 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
72 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
73 
74 	PORT_START("DR01")
75 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
76 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
77 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
78 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
79 
80 	PORT_START("DR02")
81 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
82 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
83 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
84 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
85 
86 	PORT_START("DR03")
87 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
88 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
89 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
90 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
91 
92 	PORT_START("DR04")
93 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
94 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
95 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
96 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
97 
98 	PORT_START("DR05")
99 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
100 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
101 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
102 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
103 
104 	PORT_START("DR06")
105 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
106 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
107 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
108 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
109 
110 	PORT_START("DR07")
111 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
112 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
113 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
114 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
115 
116 	PORT_START("DR08")
117 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
118 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
119 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
120 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
121 
122 	PORT_START("DR09")
123 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
124 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
125 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
126 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
127 
128 	PORT_START("DR10")
129 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
130 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
131 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
132 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
133 
134 	PORT_START("DR11")
135 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
136 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
137 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
138 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
139 
140 	PORT_START("DR12")
141 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
142 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
143 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
144 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
145 
146 	PORT_START("DR13")
147 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
148 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
149 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
150 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
151 
152 	PORT_START("DR14")
153 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
154 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
155 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
156 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
157 
158 	PORT_START("DR15")
159 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
160 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
161 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
162 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
163 
164 	PORT_START("DR16")
165 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
166 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
167 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
168 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
169 
170 	PORT_START("DR17")
171 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
172 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
173 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
174 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
175 
176 	PORT_START("DR18")
177 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
178 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
179 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
180 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
181 
182 	PORT_START("DR19")
183 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
184 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
185 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
186 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
187 
188 	PORT_START("DR20")
189 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
190 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
191 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
192 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
193 
194 	PORT_START("DR21")
195 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
196 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
197 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
198 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
199 
200 	PORT_START("DR22")
201 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
202 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
203 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
204 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
205 
206 	PORT_START("DR23")
207 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
208 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
209 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
210 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
211 INPUT_PORTS_END
212 
213 
214 //-------------------------------------------------
215 //  input_ports - device-specific input ports
216 //-------------------------------------------------
217 
device_input_ports() const218 ioport_constructor ibm_pc_83_keyboard_device::device_input_ports() const
219 {
220 	return INPUT_PORTS_NAME( ibm_pc_83_keyboard );
221 }
222 
223 
224 
225 //**************************************************************************
226 //  LIVE DEVICE
227 //**************************************************************************
228 
229 //-------------------------------------------------
230 //  ibm_pc_83_keyboard_device - constructor
231 //-------------------------------------------------
232 
ibm_pc_83_keyboard_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)233 ibm_pc_83_keyboard_device::ibm_pc_83_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
234 	device_t(mconfig, PC_KBD_IBM_PC_83, tag, owner, clock),
235 	device_pc_kbd_interface(mconfig, *this),
236 	m_maincpu(*this, I8048_TAG),
237 	m_dr(*this, "DR%02u", 0),
238 	m_cnt(0)
239 {
240 }
241 
242 
243 //-------------------------------------------------
244 //  device_start - device-specific startup
245 //-------------------------------------------------
246 
device_start()247 void ibm_pc_83_keyboard_device::device_start()
248 {
249 	// state saving
250 	save_item(NAME(m_cnt));
251 }
252 
253 
254 //-------------------------------------------------
255 //  device_reset - device-specific reset
256 //-------------------------------------------------
257 
device_reset()258 void ibm_pc_83_keyboard_device::device_reset()
259 {
260 	m_maincpu->reset();
261 }
262 
263 
264 //-------------------------------------------------
265 //  bus_w -
266 //-------------------------------------------------
267 
bus_w(uint8_t data)268 void ibm_pc_83_keyboard_device::bus_w(uint8_t data)
269 {
270 	/*
271 
272 	    bit     description
273 
274 	    0       CNT 1
275 	    1       CNT 2
276 	    2       CNT 4
277 	    3       CNT 8
278 	    4       CNT 16
279 	    5       CNT 32
280 	    6       CNT 64
281 	    7
282 
283 	*/
284 
285 	m_cnt = data & 0x7f;
286 }
287 
288 
289 //-------------------------------------------------
290 //  p1_r -
291 //-------------------------------------------------
292 
p1_r()293 uint8_t ibm_pc_83_keyboard_device::p1_r()
294 {
295 	/*
296 
297 	    bit     description
298 
299 	    0       -REQ IN
300 	    1       DATA IN
301 	    2
302 	    3
303 	    4
304 	    5
305 	    6
306 	    7
307 
308 	*/
309 
310 	uint8_t data = 0;
311 
312 	data |= clock_signal();
313 	data |= data_signal() << 1;
314 
315 	return data;
316 }
317 
318 
319 //-------------------------------------------------
320 //  p2_w -
321 //-------------------------------------------------
322 
p2_w(uint8_t data)323 void ibm_pc_83_keyboard_device::p2_w(uint8_t data)
324 {
325 	/*
326 
327 	    bit     description
328 
329 	    0       -MATRIX STROBE
330 	    1       CLOCK OUT
331 	    2       DATA OUT
332 	    3
333 	    4
334 	    5
335 	    6
336 	    7
337 
338 	*/
339 
340 	m_pc_kbdc->clock_write_from_kb(BIT(data, 1));
341 	m_pc_kbdc->data_write_from_kb(BIT(data, 2));
342 }
343 
344 
345 //-------------------------------------------------
346 //  t0_r -
347 //-------------------------------------------------
348 
READ_LINE_MEMBER(ibm_pc_83_keyboard_device::t0_r)349 READ_LINE_MEMBER( ibm_pc_83_keyboard_device::t0_r )
350 {
351 	uint8_t data = 0xff;
352 
353 	int keylatch = m_cnt >> 2;
354 
355 	if (keylatch < 24)
356 	{
357 		data = m_dr[keylatch]->read();
358 	}
359 
360 	int sense = m_cnt & 0x03;
361 
362 	return BIT(data, sense);
363 }
364