1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 /***************************************************************************
4
5 Applix 1616 computer
6
7 See for docs: http://psiphi.server101.com/applix/
8
9 First revealed to the world in December 1986 issue of Electronics Today
10 International (ETI) an Australian electronics magazine which is now defunct.
11
12 The main articles appeared in ETI February/March/April 1987, followed by
13 other articles in various issues after that.
14
15 Current Status:
16 After 60 seconds, boots to the ramdisk. You can enter commands.
17 If you have a floppy mounted, it will boot from the disk.
18
19 The system could support 1 or 2 5.25 or 3.5 floppy drives, although 3.5
20 was the recommended hardware. Format is similar to the PC 720kb, except
21 it has 5 sectors of 1024 bytes, giving 800kb total. We only support the
22 3.5-sized disks.
23
24 TODO:
25 - Cassette interface (coded but not working)
26 - Use kbtro device (tried and failed)
27 - Optional SCSI controller NCR5380 and hard drive (max 40mb)
28 - Joystick
29 - Audio: it could be better
30 - DAC output is used to compare against analog inputs; core doesn't permit
31 audio outputs to be used for non-speaker purposes.
32 - Bios 5 crashes MAME after scrolling about half a screen
33
34 ****************************************************************************/
35
36 #include "emu.h"
37
38 #include "bus/centronics/ctronics.h"
39 #include "bus/rs232/rs232.h"
40 #include "cpu/m68000/m68000.h"
41 #include "cpu/mcs51/mcs51.h"
42 #include "cpu/z80/z80.h"
43 #include "imagedev/cassette.h"
44 #include "imagedev/floppy.h"
45 #include "machine/6522via.h"
46 #include "machine/timer.h"
47 #include "machine/wd_fdc.h"
48 #include "machine/z80scc.h"
49 #include "sound/dac.h"
50 #include "video/mc6845.h"
51
52 #include "emupal.h"
53 #include "screen.h"
54 #include "speaker.h"
55
56 #include "formats/applix_dsk.h"
57
58
59
60 class applix_state : public driver_device
61 {
62 public:
applix_state(const machine_config & mconfig,device_type type,const char * tag)63 applix_state(const machine_config &mconfig, device_type type, const char *tag)
64 : driver_device(mconfig, type, tag)
65 , m_base(*this, "base")
66 , m_maincpu(*this, "maincpu")
67 , m_crtc(*this, "crtc")
68 , m_via(*this, "via6522")
69 , m_centronics(*this, "centronics")
70 , m_cent_data_out(*this, "cent_data_out")
71 , m_fdc(*this, "fdc")
72 , m_floppy0(*this, "fdc:0")
73 , m_floppy1(*this, "fdc:1")
74 , m_ldac(*this, "ldac")
75 , m_rdac(*this, "rdac")
76 , m_cass(*this, "cassette")
77 , m_io_dsw(*this, "DSW")
78 , m_io_fdc(*this, "FDC")
79 , m_io_k0f(*this, "K0f")
80 , m_io_k300(*this, "K30_0")
81 , m_io_k301(*this, "K30_1")
82 , m_io_k310(*this, "K31_0")
83 , m_io_k311(*this, "K31_1")
84 , m_io_k320(*this, "K32_0")
85 , m_io_k321(*this, "K32_1")
86 , m_io_k330(*this, "K33_0")
87 , m_io_k331(*this, "K33_1")
88 , m_io_k340(*this, "K34_0")
89 , m_io_k341(*this, "K34_1")
90 , m_io_k350(*this, "K35_0")
91 , m_io_k351(*this, "K35_1")
92 , m_io_k360(*this, "K36_0")
93 , m_io_k361(*this, "K36_1")
94 , m_io_k370(*this, "K37_0")
95 , m_io_k371(*this, "K37_1")
96 , m_io_k380(*this, "K38_0")
97 , m_io_k390(*this, "K39_0")
98 , m_io_k3a0(*this, "K3a_0")
99 , m_io_k3b0(*this, "K3b_0")
100 , m_io_k0b(*this, "K0b")
101 , m_expansion(*this, "expansion")
102 , m_palette(*this, "palette")
103 { }
104
105 void applix(machine_config &config);
106
107 void init_applix();
108
109 private:
110 virtual void machine_reset() override;
111 virtual void machine_start() override;
112 u16 applix_inputs_r();
113 void palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
114 void analog_latch_w(u16 data);
115 void dac_latch_w(u16 data);
116 void video_latch_w(offs_t offset, u16 data, u16 mem_mask = ~0);
117 u8 applix_pb_r();
118 void applix_pa_w(u8 data);
119 void applix_pb_w(u8 data);
120 DECLARE_WRITE_LINE_MEMBER(vsync_w);
121 u8 port00_r();
122 u8 port08_r();
123 u8 port10_r();
124 u8 port18_r();
125 u8 port20_r();
126 u8 port60_r();
127 void port08_w(u8 data);
128 void port10_w(u8 data);
129 void port18_w(offs_t offset, u8 data);
130 void port20_w(u8 data);
131 void port60_w(u8 data);
132 u16 fdc_data_r();
133 u16 fdc_stat_r(offs_t offset);
134 void fdc_data_w(u16 data);
135 void fdc_cmd_w(u16 data);
136 DECLARE_FLOPPY_FORMATS(floppy_formats);
137 u8 internal_data_read(offs_t offset);
138 void internal_data_write(offs_t offset, u8 data);
139 u8 p1_read();
140 void p1_write(u8 data);
141 u8 p2_read();
142 void p2_write(u8 data);
143 u8 p3_read();
144 void p3_write(u8 data);
145 TIMER_DEVICE_CALLBACK_MEMBER(cass_timer);
146
147 MC6845_UPDATE_ROW(crtc_update_row);
148 MC6845_BEGIN_UPDATE(crtc_update_border);
149 void applix_palette(palette_device &palette) const;
150
151 u8 m_video_latch;
152 u8 m_pa;
153 u8 m_palette_latch[4];
154 required_shared_ptr<u16> m_base;
155
156 void main_mem(address_map &map);
157 void keytronic_pc3270_io(address_map &map);
158 void keytronic_pc3270_program(address_map &map);
159 void sub_io(address_map &map);
160 void sub_mem(address_map &map);
161
162 u8 m_pb;
163 u8 m_analog_latch;
164 u8 m_dac_latch;
165 u8 m_port08;
166 u8 m_data_to_fdc;
167 u8 m_data_from_fdc;
168 bool m_data;
169 bool m_data_or_cmd;
170 bool m_buffer_empty;
171 bool m_fdc_cmd;
172 u8 m_clock_count;
173 bool m_cp;
174 u8 m_p1;
175 u8 m_p1_data;
176 u8 m_p2;
177 u8 m_p3;
178 u16 m_last_write_addr;
179 u8 m_cass_data[4];
180 required_device<cpu_device> m_maincpu;
181 required_device<mc6845_device> m_crtc;
182 required_device<via6522_device> m_via;
183 required_device<centronics_device> m_centronics;
184 required_device<output_latch_device> m_cent_data_out;
185 required_device<wd1772_device> m_fdc;
186 required_device<floppy_connector> m_floppy0;
187 required_device<floppy_connector> m_floppy1;
188 required_device<dac_byte_interface> m_ldac;
189 required_device<dac_byte_interface> m_rdac;
190 required_device<cassette_image_device> m_cass;
191 required_ioport m_io_dsw;
192 required_ioport m_io_fdc;
193 required_ioport m_io_k0f;
194 required_ioport m_io_k300;
195 required_ioport m_io_k301;
196 required_ioport m_io_k310;
197 required_ioport m_io_k311;
198 required_ioport m_io_k320;
199 required_ioport m_io_k321;
200 required_ioport m_io_k330;
201 required_ioport m_io_k331;
202 required_ioport m_io_k340;
203 required_ioport m_io_k341;
204 required_ioport m_io_k350;
205 required_ioport m_io_k351;
206 required_ioport m_io_k360;
207 required_ioport m_io_k361;
208 required_ioport m_io_k370;
209 required_ioport m_io_k371;
210 required_ioport m_io_k380;
211 required_ioport m_io_k390;
212 required_ioport m_io_k3a0;
213 required_ioport m_io_k3b0;
214 required_ioport m_io_k0b;
215 required_shared_ptr<u16> m_expansion;
216
217 required_device<palette_device> m_palette;
218 };
219
220 /*
221 d0,1,2 = joystick
222 d3 = cassette LED, low=on
223 d4,5,6 = audio select
224 d7 = cassette relay, low=on
225 */
analog_latch_w(u16 data)226 void applix_state::analog_latch_w(u16 data)
227 {
228 data &= 0xff;
229 if (data != m_analog_latch)
230 {
231 m_cass->change_state(
232 (BIT(data,7)) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
233
234 m_analog_latch = data;
235 }
236 }
237
dac_latch_w(u16 data)238 void applix_state::dac_latch_w(u16 data)
239 {
240 data &= 0xff;
241 m_dac_latch = data;
242
243 if ((m_analog_latch & 0x70) == 0) // right
244 m_rdac->write(m_dac_latch);
245 else
246 if ((m_analog_latch & 0x70) == 0x10) // left
247 m_ldac->write(m_dac_latch);
248 }
249
250 //cent = odd, video = even
palette_w(offs_t offset,u16 data,u16 mem_mask)251 void applix_state::palette_w(offs_t offset, u16 data, u16 mem_mask)
252 {
253 offset >>= 4;
254 if (ACCESSING_BITS_0_7)
255 {
256 m_cent_data_out->write(data);
257 }
258 else
259 m_palette_latch[offset] = (data >> 8) & 15;
260 }
261
video_latch_w(offs_t offset,u16 data,u16 mem_mask)262 void applix_state::video_latch_w(offs_t offset, u16 data, u16 mem_mask)
263 {
264 if (ACCESSING_BITS_0_7)
265 m_video_latch = data;
266 }
267
268 /*
269 d0 = dac output + external signal = analog input
270 d1 = cassette in
271 d2,3 = joystick in
272 d4-7 = SW2 dipswitch block
273 */
applix_inputs_r()274 u16 applix_state::applix_inputs_r()
275 {
276 return m_io_dsw->read() | m_cass_data[2];
277 }
278
applix_pb_r()279 u8 applix_state::applix_pb_r()
280 {
281 return m_pb;
282 }
283
284 /*
285 d0 = /(in) printer busy signal
286 d1 = /(out) printer strobe
287 d2 = /(out) enable cassette write IRQ
288 d3 = (out) H = 640 video mode
289 d4 = /(out) enable cassette read IRQ
290 d5 = /(out) clear cass IRQ and output line
291 d6 = /(out) reset keyboard by pulling kbd clock low
292 d7 = /(out) reset keyboard flipflop
293 */
applix_pa_w(u8 data)294 void applix_state::applix_pa_w(u8 data)
295 {
296 // Reset flipflop counter
297 if (!BIT(data, 7))
298 m_clock_count = 0;
299
300 // Reset keyboard
301 if (!BIT(data, 6))
302 {
303 m_p3 = 0xff;
304 m_last_write_addr = 0;
305 }
306 m_cass->output(BIT(data, 5) ? -1.0 : +1.0);
307
308 // high-to-low of PA5 when reading cassette - /PRE on IC32b
309 if (BIT(m_pa, 5) && !BIT(data, 5) && !BIT(data, 4))
310 m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE);
311
312 // low-to-high of PA2 when writing cassette - /PRE on IC49
313 if (!BIT(m_pa, 2) && BIT(data, 2))
314 m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE);
315
316 m_centronics->write_strobe(BIT(data, 1));
317
318 m_pa = data;
319 }
320
321 /*
322 d0-6 = user
323 d7 = square wave output for cassette IRQ
324 */
applix_pb_w(u8 data)325 void applix_state::applix_pb_w(u8 data)
326 {
327 // low-to-high of PB7 when writing cassette - CLK on IC49
328 if (!BIT(m_pb, 7) && BIT(data, 7))
329 if (!BIT(m_pa, 2))
330 m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE);
331
332 m_pb = data;
333 }
334
335 /*
336 d0 = H if 68000 sent a command
337 d1 = H if 68000 sent a byte
338 d2 = H if 68000 has read last byte
339 d3 = test switch
340 */
port00_r()341 u8 applix_state::port00_r()
342 {
343 return (u8)m_data_or_cmd | ((u8)m_data << 1) | ((u8)m_buffer_empty << 2) | m_io_fdc->read();
344 }
345
346 /*
347 d0 = /RDY
348 d1 = /DISC CHANGE
349 d2 = DS0
350 d3 = DS1
351 d4 = MOTORON
352 d5 = SIDE
353 d6 = BANK
354 d7 = MAP
355 */
port08_r()356 u8 applix_state::port08_r()
357 {
358 return m_port08 | 3;
359 }
360
361 /*
362 d0 = /INUSE
363 d1 = /EJECT
364 d2-7 same as for port08_r
365 */
port08_w(u8 data)366 void applix_state::port08_w(u8 data)
367 {
368 m_port08 = data;
369 membank("bank1")->set_entry(BIT(data, 6));
370
371 floppy_image_device *floppy = nullptr;
372 if (BIT(data, 2)) floppy = m_floppy0->get_device();
373 if (BIT(data, 3)) floppy = m_floppy1->get_device();
374
375 m_fdc->set_floppy(floppy);
376
377 if (floppy)
378 {
379 floppy->mon_w(0);
380 floppy->ss_w(BIT(data, 5));
381 }
382 }
383
port10_r()384 u8 applix_state::port10_r()
385 {
386 return 0;
387 }
388
port10_w(u8 data)389 void applix_state::port10_w(u8 data)
390 {
391 }
392
port18_r()393 u8 applix_state::port18_r()
394 {
395 m_data = 0;
396 return m_data_to_fdc;
397 }
398
port18_w(offs_t offset,u8 data)399 void applix_state::port18_w(offs_t offset, u8 data)
400 {
401 m_data_from_fdc = data;
402 m_buffer_empty = 0;
403 m_fdc_cmd = BIT(offset, 2);
404 }
405
port20_r()406 u8 applix_state::port20_r()
407 {
408 return 0;
409 }
410
port20_w(u8 data)411 void applix_state::port20_w(u8 data)
412 {
413 }
414
port60_r()415 u8 applix_state::port60_r()
416 {
417 return 0;
418 }
419
port60_w(u8 data)420 void applix_state::port60_w(u8 data)
421 {
422 }
423
fdc_stat_r(offs_t offset)424 u16 applix_state::fdc_stat_r(offs_t offset)
425 {
426 u8 data = 0;
427 switch (offset)
428 {
429 case 0: data = (u8)m_buffer_empty^1; break;
430 case 1: data = (u8)m_data^1; break;
431 default: data = (u8)m_fdc_cmd; // case 2
432 }
433 return data << 7;
434 }
435
fdc_data_r()436 u16 applix_state::fdc_data_r()
437 {
438 m_buffer_empty = 1;
439 return m_data_from_fdc;
440 }
441
fdc_data_w(u16 data)442 void applix_state::fdc_data_w(u16 data)
443 {
444 m_data_to_fdc = data;
445 m_data = 1;
446 m_data_or_cmd = 0;
447 }
448
fdc_cmd_w(u16 data)449 void applix_state::fdc_cmd_w(u16 data)
450 {
451 m_data_to_fdc = data;
452 m_data = 1;
453 m_data_or_cmd = 1;
454 }
455
main_mem(address_map & map)456 void applix_state::main_mem(address_map &map)
457 {
458 map.unmap_value_high();
459 map.global_mask(0xffffff);
460 map(0x000000, 0x3fffff).ram().share("expansion"); // Expansion
461 map(0x400000, 0x47ffff).ram().mirror(0x80000).share("base"); // Main ram
462 map(0x500000, 0x51ffff).rom().region("maincpu", 0);
463 map(0x600000, 0x60007f).w(FUNC(applix_state::palette_w));
464 map(0x600080, 0x6000ff).w(FUNC(applix_state::dac_latch_w));
465 map(0x600100, 0x60017f).w(FUNC(applix_state::video_latch_w)); //video latch (=border colour, high nibble; video base, low nibble) (odd)
466 map(0x600180, 0x6001ff).w(FUNC(applix_state::analog_latch_w));
467 map(0x700000, 0x700007).mirror(0x78).rw("scc", FUNC(scc8530_device::ab_dc_r), FUNC(scc8530_device::ab_dc_w)).umask16(0xff00).cswidth(16);
468 map(0x700080, 0x7000ff).r(FUNC(applix_state::applix_inputs_r));
469 map(0x700100, 0x70011f).mirror(0x60).m(m_via, FUNC(via6522_device::map)).umask16(0xff00).cswidth(16);
470 map(0x700180, 0x700180).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)).cswidth(16);
471 map(0x700182, 0x700182).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)).cswidth(16);
472 map(0xffffc0, 0xffffc1).rw(FUNC(applix_state::fdc_data_r), FUNC(applix_state::fdc_data_w));
473 //map(0xffffc2, 0xffffc3).rw(FUNC(applix_state::fdc_int_r) , FUNC(applix_state::fdc_int_w)); // optional
474 map(0xffffc8, 0xffffcd).r(FUNC(applix_state::fdc_stat_r));
475 map(0xffffd0, 0xffffd1).w(FUNC(applix_state::fdc_cmd_w));
476 //600000, 6FFFFF io ports and latches
477 //700000, 7FFFFF peripheral chips and devices
478 //800000, FFC000 optional roms
479 //FFFFC0, FFFFFF disk controller board
480 }
481
sub_mem(address_map & map)482 void applix_state::sub_mem(address_map &map)
483 {
484 map(0x0000, 0x5fff).rom();
485 map(0x6000, 0x7fff).ram();
486 map(0x8000, 0xffff).bankrw("bank1");
487 }
488
sub_io(address_map & map)489 void applix_state::sub_io(address_map &map)
490 {
491 map.global_mask(0xff);
492 map(0x00, 0x07).r(FUNC(applix_state::port00_r)); //PORTR
493 map(0x08, 0x0f).rw(FUNC(applix_state::port08_r), FUNC(applix_state::port08_w)); //Disk select
494 map(0x10, 0x17).rw(FUNC(applix_state::port10_r), FUNC(applix_state::port10_w)); //IRQ
495 map(0x18, 0x1f).rw(FUNC(applix_state::port18_r), FUNC(applix_state::port18_w)); //data&command
496 map(0x20, 0x27).mirror(0x18).rw(FUNC(applix_state::port20_r), FUNC(applix_state::port20_w)); //SCSI NCR5380
497 map(0x40, 0x43).mirror(0x1c).rw(m_fdc, FUNC(wd1772_device::read), FUNC(wd1772_device::write)); //FDC
498 map(0x60, 0x63).mirror(0x1c).rw(FUNC(applix_state::port60_r), FUNC(applix_state::port60_w)); //anotherZ80SCC
499 }
500
keytronic_pc3270_program(address_map & map)501 void applix_state::keytronic_pc3270_program(address_map &map)
502 {
503 map(0x0000, 0x0fff).rom().region("kbdcpu", 0);
504 }
505
keytronic_pc3270_io(address_map & map)506 void applix_state::keytronic_pc3270_io(address_map &map)
507 {
508 map(0x0000, 0xffff).rw(FUNC(applix_state::internal_data_read), FUNC(applix_state::internal_data_write));
509 }
510
511 // io priorities:
512 // 4 cassette
513 // 3 scc
514 // 2 via
515
516 /* Input ports */
517 static INPUT_PORTS_START( applix )
518 PORT_START( "K0f" )
PORT_CODE(KEYCODE_5)519 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') /* 06 */
520 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') /* 05 */
521 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') /* 14 */
522 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') /* 13 */
523 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') /* 22 */
524 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') /* 21 */
525 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7 (IRMA)") /* 41 */
526 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6a?") /* 6a */
527
528 PORT_START( "K30_0" )
529 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') /* 31 */
530 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') /* 32 */
531 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') /* 30 */
532 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') /* 2f */
533 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') /* 2e */
534 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') /* 33 */
535 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
536
537 PORT_START( "K30_1" )
538 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) /* 58 */
539 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) /* 59 */
540 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) /* 5a */
541 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) /* 5b */
542 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) /* 5c */
543 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) /* 5d */
544 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6b?") /* 6b */
545 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8 (IRMA)") /* 42 */
546
547 PORT_START( "K31_0" )
548 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') /* 07 */
549 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') /* 08 */
550 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') /* 15 */
551 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') /* 16 */
552 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') /* 23 */
553 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') /* 24 */
554 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
555
556 PORT_START( "K31_1" )
557 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) /* 37 */
558 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) /* 5f */
559 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("LShift") PORT_CHAR(UCHAR_SHIFT_1) /* 2a */
560 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("<") /* 70 */
561 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') /* 2c */
562 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') /* 2d */
563 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6c?") /* 6c */
564 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9 (IRMA)") /* 43 */
565
566 PORT_START( "K32_0" )
567 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') /* 0a */
568 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') /* 09 */
569 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') /* 18 */
570 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') /* 17 */
571 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') /* 26 */
572 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') /* 25 */
573 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
574
575 PORT_START( "K32_1" )
576 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) /* 57 */
577 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) /* 1d */
578 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) /* 71 */
579 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LALT) PORT_NAME("LAlt") /* 38 */
580 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') /* 39 */
581 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RALT) PORT_NAME("RAlt") /* 38 */
582 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?69?") /* 69 */
583 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6 (IRMA)") /* 40 */
584
585 PORT_START( "K33_0" )
586 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("KP 2") /* 50 */
587 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_END) PORT_NAME("KP 1") /* 4f */
588 PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
589 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Down") /* 55 */
590 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Enter") /* 75 */
591 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
592
593 PORT_START( "K33_1" )
594 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') /* 02 */
595 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') /* 29 */
596 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') /* 10 */
597 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) /* 0f */
598 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') /* 1e */
599 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps") /* 3a */
600 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?68?") /* 68 */
601 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5 (IRMA)") /* 3f */
602
603 PORT_START( "K34_0" )
604 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
605 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') /* 35 */
606 PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) /* 36 */
607 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left") /* 56 */
608 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') /* 34 */
609 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
610
611 PORT_START( "K34_1" )
612 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') /* 02 */
613 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') /* 03 */
614 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') /* 11 */
615 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') /* 12 */
616 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') /* 1f */
617 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') /* 20 */
618 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?67?") /* 67 */
619 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4 (IRMA)") /* 3e */
620
621 PORT_START( "K35_0" )
622 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') /* 0b */
623 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') /* 0c */
624 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') /* 19 */
625 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') /* 1a */
626 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') /* 27 */
627 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') /* 28 */
628 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
629
630 PORT_START( "K35_1" )
631 PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
632 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?66?") /* 66 */
633 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3 (IRMA)") /* 3d */
634
635 PORT_START( "K36_0" )
636 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) /* 0e */
637 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') /* 0d */
638 PORT_BIT( 0x14, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) /* 1c */
639 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') /* 2b */
640 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') /* 1b */
641 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
642
643 PORT_START( "K36_1" )
644 PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED )
645 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2 (IRMA)") /* 3c */
646
647 PORT_START( "K37_0" )
648 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA1") /* 7b */
649 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("|<--") /* 7e */
650 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a\\") /* 7a */
651 PORT_BIT( 0x30, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("KP +") /* 4e */
652 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
653
654 PORT_START( "K37_1" )
655 PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
656 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?64?") /* 64 */
657 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1 (IRMA)") /* 3b */
658
659 PORT_START( "K38_0" )
660 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SysReq") /* 54 */
661 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) /*PORT_CODE(KEYCODE_SCRLOCK)*/ PORT_NAME("ScrLock") /* 46 */
662 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("-->|") /* 7c */
663 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("KP 9") /* 49 */
664 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("KP -") /* 4a */
665 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("KP 6") /* 4d */
666 PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
667
668 PORT_START( "K39_0" )
669 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") /* 01 */
670 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_NAME("NumLock") /* 45 */
671 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_HOME) PORT_NAME("KP 7") /* 47 */
672 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_NAME("KP 8") /* 48 */
673 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("KP 4") /* 4b */
674 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("KP 5") /* 4c */
675 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?76?") /* 76 */
676 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?63?") /* 63 */
677
678 PORT_START( "K3a_0" )
679 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PrtSc *") /* 6f */
680 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA2") /* 7f */
681 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right") /* 7d */
682 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a") /* 79 */
683 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Center") /* 77 */
684 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
685 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6e?") /* 6e */
686 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?62?") /* 62 */
687
688 PORT_START( "K3b_0" )
689 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("KP 3") /* 51 */
690 PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("KP 0") /* 52 */
691 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("KP .") /* 53 */
692 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
693 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Up") /* 78 */
694 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6d?") /* 6d */
695 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10 (IRMA)") /* 44 */
696
697 PORT_START( "K0b" )
698 PORT_DIPNAME( 0x01, 0x01, "Protocol selection" )
699 PORT_DIPSETTING( 0x00, "Enhanced XT, AT and PS/2 models" )
700 PORT_DIPSETTING( 0x01, "Standard PC and XT" )
701 PORT_DIPNAME( 0x02, 0x00, "IRMA/Native scan code set" )
702 PORT_DIPSETTING( 0x00, "Native scan code set" )
703 PORT_DIPSETTING( 0x02, "IRMA Emulation" )
704 PORT_DIPNAME( 0x04, 0x04, "Enhanced 101/Native scan code set" )
705 PORT_DIPSETTING( 0x00, "Native scan code set" )
706 PORT_DIPSETTING( 0x04, "Enhanced 101 scan code set" )
707 PORT_DIPNAME( 0x08, 0x08, "Enable E0" )
708 PORT_DIPSETTING( 0x00, "Enable E0" )
709 PORT_DIPSETTING( 0x08, "Disable E0" )
710 PORT_DIPNAME( 0x10, 0x10, "Code tables" )
711 PORT_DIPSETTING( 0x00, "U.S. code tables" )
712 PORT_DIPSETTING( 0x10, "International code tables" )
713 PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_UNUSED )
714 PORT_DIPNAME( 0x80, 0x80, "Key click" )
715 PORT_DIPSETTING( 0x00, "No key click" )
716 PORT_DIPSETTING( 0x80, "Key click" )
717
718 PORT_START("DSW")
719 PORT_BIT( 0xf, 0, IPT_UNUSED )
720 PORT_DIPNAME( 0x10, 0x00, "Switch 0") PORT_DIPLOCATION("SW2:1")
721 PORT_DIPSETTING( 0x10, DEF_STR(Off))
722 PORT_DIPSETTING( 0x00, DEF_STR(On))
723 PORT_DIPNAME( 0x20, 0x00, "Switch 1") PORT_DIPLOCATION("SW2:2")
724 PORT_DIPSETTING( 0x20, DEF_STR(Off))
725 PORT_DIPSETTING( 0x00, DEF_STR(On))
726 PORT_DIPNAME( 0x40, 0x00, "Switch 2") PORT_DIPLOCATION("SW2:3")
727 PORT_DIPSETTING( 0x40, DEF_STR(Off))
728 PORT_DIPSETTING( 0x00, DEF_STR(On))
729 PORT_DIPNAME( 0x80, 0x80, "Switch 3") PORT_DIPLOCATION("SW2:4")
730 PORT_DIPSETTING( 0x80, DEF_STR(Off))
731 PORT_DIPSETTING( 0x00, DEF_STR(On))
732
733 PORT_START("FDC")
734 PORT_BIT( 0xf7, 0, IPT_UNUSED )
735 PORT_DIPNAME( 0x08, 0x08, "FDC Test") PORT_DIPLOCATION("SW3:1")
736 PORT_DIPSETTING( 0x08, DEF_STR(Off))
737 PORT_DIPSETTING( 0x00, DEF_STR(On))
738 INPUT_PORTS_END
739
740
741 void applix_state::machine_reset()
742 {
743 u8* ROM = memregion("maincpu")->base();
744 memcpy(m_expansion, ROM, 8);
745 membank("bank1")->set_entry(0);
746 m_p3 = 0xff;
747 m_last_write_addr = 0;
748 m_maincpu->reset();
749 }
750
FLOPPY_FORMATS_MEMBER(applix_state::floppy_formats)751 FLOPPY_FORMATS_MEMBER( applix_state::floppy_formats )
752 FLOPPY_APPLIX_FORMAT
753 FLOPPY_FORMATS_END
754
755 static void applix_floppies(device_slot_interface &device)
756 {
757 device.option_add("35dd", FLOPPY_35_DD);
758 }
759
760
applix_palette(palette_device & palette) const761 void applix_state::applix_palette(palette_device &palette) const
762 {
763 // shades need to be verified - the names on the right are from the manual
764 constexpr rgb_t colors[16] = {
765 { 0x00, 0x00, 0x00 }, // 0 Black
766 { 0x40, 0x40, 0x40 }, // 1 Dark Grey
767 { 0x00, 0x00, 0x80 }, // 2 Dark Blue
768 { 0x00, 0x00, 0xff }, // 3 Mid Blue
769 { 0x00, 0x80, 0x00 }, // 4 Dark Green
770 { 0x00, 0xff, 0x00 }, // 5 Green
771 { 0x00, 0xff, 0xff }, // 6 Blue Grey
772 { 0x00, 0x7f, 0x7f }, // 7 Light Blue
773 { 0x7f, 0x00, 0x00 }, // 8 Dark Red
774 { 0xff, 0x00, 0x00 }, // 9 Red
775 { 0x7f, 0x00, 0x7f }, // 10 Dark Violet
776 { 0xff, 0x00, 0xff }, // 11 Violet
777 { 0x7f, 0x7f, 0x00 }, // 12 Brown
778 { 0xff, 0xff, 0x00 }, // 13 Yellow
779 { 0xbf, 0xbf, 0xbf }, // 14 Light Grey
780 { 0xff, 0xff, 0xff } }; // 15 White
781
782 palette.set_pen_colors(0, colors);
783 }
784
785
machine_start()786 void applix_state::machine_start()
787 {
788 save_item(NAME(m_video_latch));
789 save_item(NAME(m_pa));
790 save_item(NAME(m_palette_latch));
791 save_item(NAME(m_pb));
792 save_item(NAME(m_analog_latch));
793 save_item(NAME(m_dac_latch));
794 save_item(NAME(m_port08));
795 save_item(NAME(m_data_to_fdc));
796 save_item(NAME(m_data_from_fdc));
797 save_item(NAME(m_data));
798 save_item(NAME(m_data_or_cmd));
799 save_item(NAME(m_buffer_empty));
800 save_item(NAME(m_fdc_cmd));
801 save_item(NAME(m_clock_count));
802 save_item(NAME(m_cp));
803 save_item(NAME(m_p1));
804 save_item(NAME(m_p1_data));
805 save_item(NAME(m_p2));
806 save_item(NAME(m_p3));
807 save_item(NAME(m_last_write_addr));
808 save_item(NAME(m_cass_data));
809 }
810
MC6845_UPDATE_ROW(applix_state::crtc_update_row)811 MC6845_UPDATE_ROW( applix_state::crtc_update_row )
812 {
813 if (!de)
814 return;
815 // The display is bitmapped. 2 modes are supported here, 320x200x16 and 640x200x4.
816 // There is a monochrome mode, but no info found as yet.
817 // The 6845 cursor signal is not used at all.
818 rgb_t const *const palette = m_palette->palette()->entry_list_raw();
819 u32 const vidbase = (m_video_latch & 15) << 14 | (ra & 7) << 12;
820 u32 *p = &bitmap.pix(y + vbp, hbp);
821
822 for (u16 x = 0; x < x_count; x++)
823 {
824 u32 const mem = vidbase | ((ma + x) & 0xfff);
825 u16 chr = m_base[mem];
826
827 if (BIT(m_pa, 3))
828 {
829 // 640 x 200 x 4of16 mode
830 for (int i = 0; i < 8; i++)
831 {
832 *p++ = palette[m_palette_latch[chr>>14]];
833 chr <<= 2;
834 }
835 }
836 else
837 {
838 // 320 x 200 x 16 mode
839 for (int i = 0; i < 4; i++)
840 {
841 *p++ = palette[chr>>12];
842 *p++ = palette[chr>>12];
843 chr <<= 4;
844 }
845 }
846 }
847 }
848
MC6845_BEGIN_UPDATE(applix_state::crtc_update_border)849 MC6845_BEGIN_UPDATE( applix_state::crtc_update_border )
850 {
851 bitmap.fill(m_palette->pen(m_video_latch >> 4), cliprect);
852 }
853
WRITE_LINE_MEMBER(applix_state::vsync_w)854 WRITE_LINE_MEMBER( applix_state::vsync_w )
855 {
856 m_via->write_ca2(state);
857 }
858
TIMER_DEVICE_CALLBACK_MEMBER(applix_state::cass_timer)859 TIMER_DEVICE_CALLBACK_MEMBER(applix_state::cass_timer)
860 {
861 /* cassette - turn 2500/5000Hz to a bit */
862 m_cass_data[1]++;
863 u8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0;
864
865 if (cass_ws != m_cass_data[0])
866 {
867 m_cass_data[0] = cass_ws;
868 m_cass_data[2] = ((m_cass_data[1] < 12) ? 2 : 0);
869 m_cass_data[1] = 0;
870 // low-to-high transition when reading cassette - CLK on IC32b
871 if ((cass_ws) && !BIT(m_pa, 4))
872 m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE);
873 }
874 }
875
applix(machine_config & config)876 void applix_state::applix(machine_config &config)
877 {
878 /* basic machine hardware */
879 M68000(config, m_maincpu, 30_MHz_XTAL / 4); // MC68000-P10 @ 7.5 MHz
880 m_maincpu->set_addrmap(AS_PROGRAM, &applix_state::main_mem);
881
882 z80_device &subcpu(Z80(config, "subcpu", 16_MHz_XTAL / 2)); // Z80H
883 subcpu.set_addrmap(AS_PROGRAM, &applix_state::sub_mem);
884 subcpu.set_addrmap(AS_IO, &applix_state::sub_io);
885
886 i8051_device &kbdcpu(I8051(config, "kbdcpu", 11060250));
887 kbdcpu.set_addrmap(AS_PROGRAM, &applix_state::keytronic_pc3270_program);
888 kbdcpu.set_addrmap(AS_IO, &applix_state::keytronic_pc3270_io);
889 kbdcpu.port_in_cb<1>().set(FUNC(applix_state::p1_read));
890 kbdcpu.port_out_cb<1>().set(FUNC(applix_state::p1_write));
891 kbdcpu.port_in_cb<2>().set(FUNC(applix_state::p2_read));
892 kbdcpu.port_out_cb<2>().set(FUNC(applix_state::p2_write));
893 kbdcpu.port_in_cb<3>().set(FUNC(applix_state::p3_read));
894 kbdcpu.port_out_cb<3>().set(FUNC(applix_state::p3_write));
895
896 /* video hardware */
897 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
898 screen.set_refresh_hz(50);
899 screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
900 screen.set_size(640, 200);
901 screen.set_visarea_full();
902 screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update));
903 PALETTE(config, m_palette, FUNC(applix_state::applix_palette), 16);
904
905 /* sound hardware */
906 SPEAKER(config, "lspeaker").front_left();
907 SPEAKER(config, "rspeaker").front_right();
908 DAC0800(config, "ldac", 0).add_route(ALL_OUTPUTS, "lspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23
909 DAC0800(config, "rdac", 0).add_route(ALL_OUTPUTS, "rspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23
910
911 /* Devices */
912 MC6845(config, m_crtc, 30_MHz_XTAL / 16); // MC6545 @ 1.875 MHz
913 m_crtc->set_screen("screen");
914 m_crtc->set_show_border_area(true);
915 m_crtc->set_char_width(8);
916 m_crtc->set_update_row_callback(FUNC(applix_state::crtc_update_row));
917 m_crtc->set_begin_update_callback(FUNC(applix_state::crtc_update_border));
918 m_crtc->out_vsync_callback().set(FUNC(applix_state::vsync_w));
919
920 VIA6522(config, m_via, 30_MHz_XTAL / 4 / 10); // VIA uses 68000 E clock
921 m_via->readpb_handler().set(FUNC(applix_state::applix_pb_r));
922 // in CB1 kbd clk
923 // in CA2 vsync
924 // in CB2 kdb data
925 m_via->writepa_handler().set(FUNC(applix_state::applix_pa_w));
926 m_via->writepb_handler().set(FUNC(applix_state::applix_pb_w));
927 m_via->irq_handler().set_inputline("maincpu", M68K_IRQ_2);
928
929 CENTRONICS(config, m_centronics, centronics_devices, "printer");
930 m_centronics->ack_handler().set(m_via, FUNC(via6522_device::write_ca1));
931 m_centronics->busy_handler().set(m_via, FUNC(via6522_device::write_pa0));
932
933 OUTPUT_LATCH(config, m_cent_data_out);
934 m_centronics->set_output_latch(*m_cent_data_out);
935
936 CASSETTE(config, m_cass);
937 m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
938 m_cass->add_route(ALL_OUTPUTS, "lspeaker", 0.10);
939
940 WD1772(config, m_fdc, 16_MHz_XTAL / 2); //connected to Z80H clock pin
941 FLOPPY_CONNECTOR(config, "fdc:0", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true);
942 FLOPPY_CONNECTOR(config, "fdc:1", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true);
943 TIMER(config, "applix_c").configure_periodic(FUNC(applix_state::cass_timer), attotime::from_hz(100000));
944
945 scc8530_device &scc(SCC8530N(config, "scc", 30_MHz_XTAL / 8));
946 scc.out_txda_callback().set("serial_a", FUNC(rs232_port_device::write_txd));
947 scc.out_rtsa_callback().set("serial_a", FUNC(rs232_port_device::write_rts));
948 scc.out_dtra_callback().set("serial_a", FUNC(rs232_port_device::write_dtr));
949 scc.out_txdb_callback().set("serial_b", FUNC(rs232_port_device::write_txd));
950 scc.out_rtsb_callback().set("serial_b", FUNC(rs232_port_device::write_rts));
951 scc.out_dtrb_callback().set("serial_b", FUNC(rs232_port_device::write_dtr));
952 scc.out_int_callback().set_inputline("maincpu", M68K_IRQ_3);
953
954 rs232_port_device &serial_a(RS232_PORT(config, "serial_a", default_rs232_devices, nullptr));
955 serial_a.rxd_handler().set("scc", FUNC(scc8530_device::rxa_w));
956 serial_a.cts_handler().set("scc", FUNC(scc8530_device::ctsa_w));
957 serial_a.cts_handler().set("scc", FUNC(scc8530_device::dcda_w));
958
959 rs232_port_device &serial_b(RS232_PORT(config, "serial_b", default_rs232_devices, nullptr));
960 serial_b.rxd_handler().set("scc", FUNC(scc8530_device::rxb_w));
961 serial_b.cts_handler().set("scc", FUNC(scc8530_device::ctsb_w));
962 serial_b.cts_handler().set("scc", FUNC(scc8530_device::dcdb_w));
963
964 SOFTWARE_LIST(config, "flop_list").set_original("applix_flop");
965 }
966
967 /* ROM definition */
968 ROM_START( applix )
969 ROM_REGION16_BE(0x20000, "maincpu", 0)
970 ROM_SYSTEM_BIOS(0, "v4.5a", "V4.5a")
971 ROMX_LOAD( "1616osl.45a", 0x00000, 0x10000, CRC(9dfb3224) SHA1(5223833a357f90b147f25826c01713269fc1945f), ROM_SKIP(1) | ROM_BIOS(0) )
972 ROMX_LOAD( "1616osh.45a", 0x00001, 0x10000, CRC(951bd441) SHA1(e0a38c8d0d38d84955c1de3f6a7d56ce06b063f6), ROM_SKIP(1) | ROM_BIOS(0) )
973 ROM_SYSTEM_BIOS(1, "v4.4a", "V4.4a")
974 ROMX_LOAD( "1616osl.44a", 0x00000, 0x10000, CRC(4a1a90d3) SHA1(4df504bbf6fc5dad76c29e9657bfa556500420a6), ROM_SKIP(1) | ROM_BIOS(1) )
CRC(ef619994)975 ROMX_LOAD( "1616osh.44a", 0x00001, 0x10000, CRC(ef619994) SHA1(ff16fe9e2c99a1ffc855baf89278a97a2a2e881a), ROM_SKIP(1) | ROM_BIOS(1) )
976 ROM_SYSTEM_BIOS(2, "v4.3a", "V4.3a")
977 ROMX_LOAD( "1616osl.43a", 0x00000, 0x10000, CRC(c09b9ff8) SHA1(c46f2a98470d2d09cf9f9eec0f4096ab762407b5), ROM_SKIP(1) | ROM_BIOS(2) )
978 ROMX_LOAD( "1616osh.43a", 0x00001, 0x10000, CRC(071a2505) SHA1(42c4cc6e3e78b6a5320f9d9c858fc9f4e6220857), ROM_SKIP(1) | ROM_BIOS(2) )
979 ROM_SYSTEM_BIOS(3, "v4.0c", "V4.0c")
980 ROMX_LOAD( "1616osl.40c", 0x00000, 0x10000, CRC(6a517b5d) SHA1(e0f4eba0cb8d273ba681b9d2c6d4b1beff9ef325), ROM_SKIP(1) | ROM_BIOS(3) )
981 ROMX_LOAD( "1616osh.40c", 0x00001, 0x10000, CRC(7851651f) SHA1(d7d329aa7fe9f4418de0cdf813b61e70243e0e77), ROM_SKIP(1) | ROM_BIOS(3) )
982 ROM_SYSTEM_BIOS(4, "v3.0b", "V3.0b")
983 ROMX_LOAD( "1616osl.30b", 0x00000, 0x10000, CRC(fb9198c3) SHA1(e0e7a1dd176c1cbed063df1c405821c261d48f3a), ROM_SKIP(1) | ROM_BIOS(4) )
984 ROMX_LOAD( "1616osh.30b", 0x00001, 0x10000, CRC(a279e1d7) SHA1(3451b2cae87a9ccee5f579fd1d49cf52d9f97b83), ROM_SKIP(1) | ROM_BIOS(4) )
985 ROM_SYSTEM_BIOS(5, "v2.4a", "V2.4a")
986 ROMX_LOAD( "1616osl.24a", 0x00000, 0x08000, CRC(b155830b) SHA1(b32db6a06c8a3c544210ba9faba7c49497c504fb), ROM_SKIP(1) | ROM_BIOS(5) )
987 ROMX_LOAD( "1616osh.24a", 0x00001, 0x08000, CRC(6d9fc0e0) SHA1(07111f46386494ed3f426c1e50308f0209587f06), ROM_SKIP(1) | ROM_BIOS(5) )
988
989 ROM_REGION(0x18000, "subcpu", 0)
990 ROM_LOAD( "1616ssdv.022", 0x0000, 0x8000, CRC(6d8e413a) SHA1(fc27d92c34f231345a387b06670f36f8c1705856) )
991
992 ROM_REGION(0x20000, "user1", 0)
993 ROM_LOAD( "ssdcromv.22", 0x0000, 0x8000, CRC(c85c47fb) SHA1(6f0bb3753fc0d74ee5901d71d05a74ec6a4a1d05) )
994 ROM_LOAD( "ssddromv.14a", 0x8000, 0x8000, CRC(8fe2db78) SHA1(487484003aba4d8960101ced6a689dc81676235d) )
995
996 ROM_REGION(0x2000, "kbdcpu", 0)
997 ROM_LOAD( "14166.bin", 0x0000, 0x2000, CRC(1aea1b53) SHA1(b75b6d4509036406052157bc34159f7039cdc72e) )
998 ROM_END
999
1000
1001 void applix_state::init_applix()
1002 {
1003 u8 *RAM = memregion("subcpu")->base();
1004 membank("bank1")->configure_entries(0, 2, &RAM[0x8000], 0x8000);
1005 }
1006
1007
1008 /* Driver */
1009
1010 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
1011 COMP( 1986, applix, 0, 0, applix, applix, applix_state, init_applix, "Applix Pty Ltd", "Applix 1616", MACHINE_SUPPORTS_SAVE )
1012
1013
1014
1015 /**************************************************** KEYBOARD MODULE *****************************************/
1016
internal_data_read(offs_t offset)1017 u8 applix_state::internal_data_read(offs_t offset)
1018 {
1019 m_via->write_cb2( BIT(offset, 8) ); // data
1020 bool cp = !BIT(offset, 9); // clock pulses //TODO tidy this up with real flipflops
1021 if (cp != m_cp)
1022 {
1023 m_cp = cp;
1024 if (cp)
1025 m_clock_count++;
1026 }
1027 if (m_clock_count > 1)
1028 m_via->write_cb1( cp );
1029
1030 return 0xff;
1031 }
1032
1033
internal_data_write(offs_t offset,u8 data)1034 void applix_state::internal_data_write(offs_t offset, u8 data)
1035 {
1036 /* Check for low->high transition on AD8 */
1037 if ( ! ( m_last_write_addr & 0x0100 ) && ( offset & 0x0100 ) )
1038 {
1039 switch (m_p1)
1040 {
1041 case 0x0e:
1042 break;
1043 case 0x0f:
1044 m_p1_data = m_io_k0f->read();
1045 break;
1046 case 0x30:
1047 m_p1_data = m_io_k300->read();
1048 break;
1049 case 0x31:
1050 m_p1_data = m_io_k310->read();
1051 break;
1052 case 0x32:
1053 m_p1_data = m_io_k320->read();
1054 break;
1055 case 0x33:
1056 m_p1_data = m_io_k330->read();
1057 break;
1058 case 0x34:
1059 m_p1_data = m_io_k340->read();
1060 break;
1061 case 0x35:
1062 m_p1_data = m_io_k350->read();
1063 break;
1064 case 0x36:
1065 m_p1_data = m_io_k360->read();
1066 break;
1067 case 0x37:
1068 m_p1_data = m_io_k370->read() | (m_io_k360->read() & 0x01);
1069 break;
1070 case 0x38:
1071 m_p1_data = m_io_k380->read();
1072 break;
1073 case 0x39:
1074 m_p1_data = m_io_k390->read();
1075 break;
1076 case 0x3a:
1077 m_p1_data = m_io_k3a0->read();
1078 break;
1079 case 0x3b:
1080 m_p1_data = m_io_k3b0->read();
1081 break;
1082 }
1083 }
1084
1085 /* Check for low->high transition on AD9 */
1086 if ( ! ( m_last_write_addr & 0x0200 ) && ( offset & 0x0200 ) )
1087 {
1088 switch (m_p1)
1089 {
1090 case 0x0b:
1091 m_p1_data = m_io_k0b->read();
1092 break;
1093 case 0x30:
1094 m_p1_data = m_io_k301->read();
1095 break;
1096 case 0x31:
1097 m_p1_data = m_io_k311->read();
1098 break;
1099 case 0x32:
1100 m_p1_data = m_io_k321->read();
1101 break;
1102 case 0x33:
1103 m_p1_data = m_io_k331->read();
1104 break;
1105 case 0x34:
1106 m_p1_data = m_io_k341->read();
1107 break;
1108 case 0x35:
1109 m_p1_data = m_io_k351->read();
1110 break;
1111 case 0x36:
1112 m_p1_data = m_io_k361->read();
1113 break;
1114 case 0x37:
1115 m_p1_data = m_io_k371->read();
1116 break;
1117 case 0x38:
1118 m_p1_data = 0xff;
1119 break;
1120 case 0x39:
1121 m_p1_data = 0xff;
1122 break;
1123 case 0x3a:
1124 m_p1_data = 0xff;
1125 break;
1126 }
1127 }
1128
1129 m_last_write_addr = offset;
1130 }
1131
1132
p1_read()1133 u8 applix_state::p1_read()
1134 {
1135 return m_p1 & m_p1_data;
1136 }
1137
1138
p1_write(u8 data)1139 void applix_state::p1_write(u8 data)
1140 {
1141 m_p1 = data;
1142 }
1143
1144
p2_read()1145 u8 applix_state::p2_read()
1146 {
1147 return m_p2;
1148 }
1149
1150
p2_write(u8 data)1151 void applix_state::p2_write(u8 data)
1152 {
1153 m_p2 = data;
1154 }
1155
1156
p3_read()1157 u8 applix_state::p3_read()
1158 {
1159 u8 data = m_p3;
1160
1161 data &= ~0x14;
1162
1163 /* -INT0 signal */
1164 data |= 4;
1165
1166 /* T0 signal */
1167 data |= 0;
1168
1169 return data;
1170 }
1171
1172
p3_write(u8 data)1173 void applix_state::p3_write(u8 data)
1174 {
1175 m_p3 = data;
1176 }
1177