summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author etabeta78 <doge.fabio@gmail.com>2016-04-10 17:54:51 +0200
committer etabeta78 <doge.fabio@gmail.com>2016-04-10 17:54:51 +0200
commit465de1588565a8a6bee0434f53e0b6db67f297e5 (patch)
tree6b82c9afdb70752bde3eb505f65cd52921a9a96c /src
parent19397471c1141d0d8b42ea10b28003afcb01d581 (diff)
intv: Converted controller inputs to be slot devices. [Fabio Priuli]
intvecs: Converted hand controllers, keyboard and synth to be slot devices, by using a temporary hack to workaround the impossibility to plug the same device into 2 different slots as these keyboard require. [Fabio Priuli] out of whatsnew: in the long term we need to come up with a core solution for these devices that occupy multiple slot devices at once (another one is the VCS Compumate which plugs into both VCS control ports), because the hack I used (a "fake" control port which acts as a passthru for the two real control ports) is not really satisfactory. However, current solution is better than the selectable controllers we had, which were (ab)using PORT_CONDITIONs...
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/intv/ecs.cpp424
-rw-r--r--src/devices/bus/intv/ecs.h20
-rw-r--r--src/devices/bus/intv_ctrl/ctrl.cpp95
-rw-r--r--src/devices/bus/intv_ctrl/ctrl.h76
-rw-r--r--src/devices/bus/intv_ctrl/ecs_ctrl.cpp448
-rw-r--r--src/devices/bus/intv_ctrl/ecs_ctrl.h171
-rw-r--r--src/devices/bus/intv_ctrl/handctrl.cpp179
-rw-r--r--src/devices/bus/intv_ctrl/handctrl.h55
-rw-r--r--src/mame/drivers/intv.cpp120
-rw-r--r--src/mame/includes/intv.h10
-rw-r--r--src/mame/machine/intv.cpp93
11 files changed, 1042 insertions, 649 deletions
diff --git a/src/devices/bus/intv/ecs.cpp b/src/devices/bus/intv/ecs.cpp
index b9da2d9803b..bbee4f3074b 100644
--- a/src/devices/bus/intv/ecs.cpp
+++ b/src/devices/bus/intv/ecs.cpp
@@ -31,15 +31,6 @@ intv_ecs_device::intv_ecs_device(const machine_config &mconfig, const char *tag,
: intv_rom_device(mconfig, INTV_ROM_ECS, "Intellivision ECS Expansion", tag, owner, clock, "intv_ecs", __FILE__),
m_snd(*this, "ay8914"),
m_subslot(*this, "subslot"),
- m_keybd(*this, "ROW"),
- m_synth(*this, "SYNTH"),
- m_cntrlsel(*this, "CNTRLSEL"),
- m_options(*this, "OPTIONS"),
- m_keypad(*this, "KEYPAD"),
- m_disc(*this, "DISC"),
- m_discx(*this, "DISCX"),
- m_discy(*this, "DISCY"),
- m_psg_porta(0),
m_voice_enabled(false),
m_ramd0_enabled(false),
m_ram88_enabled(false)
@@ -65,7 +56,6 @@ void intv_ecs_device::device_start()
}
save_item(NAME(m_bank_base));
- save_item(NAME(m_psg_porta));
}
void intv_ecs_device::device_reset()
@@ -102,135 +92,17 @@ void intv_ecs_device::late_subslot_setup()
// MACHINE_CONFIG_FRAGMENT( sub_slot )
//-------------------------------------------------
-UINT8 intv_ecs_device::intv_control_r(int hand)
-{
- static const UINT8 keypad_table[] =
- {
- 0xFF, 0x3F, 0x9F, 0x5F, 0xD7, 0xB7, 0x77, 0xDB,
- 0xBB, 0x7B, 0xDD, 0xBD, 0x7D, 0xDE, 0xBE, 0x7E
- };
-
- static const UINT8 disc_table[] =
- {
- 0xF3, 0xE3, 0xE7, 0xF7, 0xF6, 0xE6, 0xEE, 0xFE,
- 0xFC, 0xEC, 0xED, 0xFD, 0xF9, 0xE9, 0xEB, 0xFB
- };
-
- static const UINT8 discyx_table[5][5] =
- {
- { 0xE3, 0xF3, 0xFB, 0xEB, 0xE9 },
- { 0xE7, 0xE3, 0xFB, 0xE9, 0xF9 },
- { 0xF7, 0xF7, 0xFF, 0xFD, 0xFD },
- { 0xF6, 0xE6, 0xFE, 0xEC, 0xED },
- { 0xE6, 0xEE, 0xFE, 0xFC, 0xEC }
- };
-
- int x, y;
- UINT8 val = 0xff;
-
- /* keypad */
- x = m_keypad[hand]->read();
- for (y = 0; y < 16; y++)
- {
- if (x & (1 << y))
- {
- val &= keypad_table[y];
- }
- }
-
- y = (m_options->read() >> ((hand + 2) * 2)) & 3;
- switch (y)
- {
- case 0: /* disc == digital 8-way */
- case 1: /* disc == digital 16-way */
- default:
-
- x = m_disc[hand]->read();
- if (!!x && (!y || !(x & 0x7777)))
- {
- // merge cardinals to form true diagonals
- y = ((x >> 2) & (x << 2)) | ((x >> (16 - 2)) & (x >> 2));
- x = y | (x & ~((y << 2) | (y >> 2) | (y << (16 - 2))));
- }
-
- // only one disc direction is allowed
- x &= -x;
-
- for (y = 0; y < 16; y++)
- {
- if (x & (1 << y))
- {
- val &= disc_table[y];
- }
- }
- break;
-
- case 2: /* disc == _fake_ analog */
-
- x = m_discx[hand]->read();
- y = m_discy[hand]->read();
- val &= discyx_table[y / 32][x / 32];
- }
-
- return val;
-}
-
-READ8_MEMBER( intv_ecs_device::ay_porta_r )
-{
- if (m_cntrlsel->read() == 0)
- return intv_control_r(0);
- else
- return 0xff; // not sure what to return here, maybe it should be last output?
-}
-
-READ8_MEMBER( intv_ecs_device::ay_portb_r )
-{
- switch (m_cntrlsel->read())
- {
- case 0x00: // hand controller
- return intv_control_r(1);
-
- case 0x01: // synthesizer keyboard
- {
- UINT8 val = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_psg_porta, i))
- val &= m_synth[i]->read();
- }
- return val;
- }
- case 0x02: // ecs keyboard
- {
- UINT8 val = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_psg_porta, i))
- val &= m_keybd[i]->read();
- }
- return val;
- }
- default:
- return 0xff;
- }
-}
-
-WRITE8_MEMBER( intv_ecs_device::ay_porta_w )
-{
- m_psg_porta = (~data) & 0xff;
-}
static MACHINE_CONFIG_FRAGMENT( sub_slot )
MCFG_SPEAKER_STANDARD_MONO("mono_ecs")
MCFG_SOUND_ADD("ay8914", AY8914, XTAL_3_579545MHz/2)
- MCFG_AY8910_PORT_A_READ_CB(READ8(intv_ecs_device, ay_porta_r))
- MCFG_AY8910_PORT_B_READ_CB(READ8(intv_ecs_device, ay_portb_r))
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(intv_ecs_device, ay_porta_w))
+ MCFG_AY8910_PORT_A_READ_CB(DEVREAD8("ctrl_port", intvecs_control_port_device, portA_r))
+ MCFG_AY8910_PORT_B_READ_CB(DEVREAD8("ctrl_port", intvecs_control_port_device, portB_r))
+ MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("ctrl_port", intvecs_control_port_device, portA_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono_ecs", 0.33)
+ MCFG_INTVECS_CONTROL_PORT_ADD("ctrl_port", intvecs_control_port_devices, "keybd")
MCFG_INTV_CARTRIDGE_ADD("subslot", intv_cart, nullptr)
MACHINE_CONFIG_END
@@ -254,294 +126,6 @@ const rom_entry *intv_ecs_device::device_rom_region() const
}
-static INPUT_PORTS_START( intv_ecs_kbd )
-/*
- ECS matrix scanned by setting 0xFE bits to output and reading 0xFF
- ECS Keyboard Layout:
- FF\FE Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
- Bit 0 NC RTN 0 ESC P ; . (left)
- Bit 1 L O 8 9 I K M ,
- Bit 2 J U 6 7 Y H B N
- Bit 3 G T 4 5 R F C V
- Bit 4 D E 2 3 W S Z X
- Bit 5 A CTL (right) 1 Q (up) (down) (space)
- Bit 6 SHIFT NC NC NC NC NC NC NC
-
- Shifted keys that differ from pc:
- Key : 1 2 5 6 7 (left) (right) (up) (down)
- Shift + key: = " + - / % ' ^ ?
- */
-
- PORT_START("ROW.0")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RTN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR('%') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.1")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.2")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('-') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.3")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.4")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.5")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTL") PORT_CODE(KEYCODE_RCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR('\'') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('=') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR('^') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR('?') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ROW.6")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( intv_ecs_synth )
-/*
- ECS Synthesizer Layout:
- FF\FE Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
- Bit 0 G2 Gb2 F2 E2 Eb2 D2 Db2 C2
- Bit 1 Eb3 D3 Db3 C3 B2 Bb2 A2 Ab2
- Bit 2 B3 Bb3 A3 Ab3 G3 Gb3 F3 E3
- Bit 3 G4 Gb4 F4 E4 Eb4 D4 Db4 C4
- Bit 4 Eb5 D5 Db5 C5 B4 Bb4 A4 Ab4
- Bit 5 B5 Bb5 A5 Ab5 G5 Gb5 F5 E5
- Bit 6 C6 NC NC NC NC NC NC NC
- */
- PORT_START("SYNTH.0")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.1")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.2")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.3")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.4")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.5")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("SYNTH.6")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( intv_ecs_pads )
- // First ECS Hand Controller
- PORT_START("KEYPAD.0")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 1") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 6") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 7") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 8") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 9") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 Clear") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 0") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3 Enter") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 Upper") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 Lower-Left") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P3 Lower-Right") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC.0")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P3 Up") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,NOTEQUALS,0x20)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Up-Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Right-Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P3 Right") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,NOTEQUALS,0x20)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Right-Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Down-Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P3 Down") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,NOTEQUALS,0x20)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Down-Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Left-Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P3 Left") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,NOTEQUALS,0x20)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Left-Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Up-Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x10)
-
- PORT_START("DISCX.0")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("P3 X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x20)
-
- PORT_START("DISCY.0")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("P3 Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0x30,EQUALS,0x20)
-
- // Second ECS Hand Controller
- PORT_START("KEYPAD.1")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 1") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 6") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 7") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 8") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 9") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 Clear") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 0") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4 Enter") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 Upper") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 Lower-Left") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P4 Lower-Right") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC.1")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P4 Up") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,NOTEQUALS,0x80)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Up-Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Right-Up-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P4 Right") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,NOTEQUALS,0x80)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Right-Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Down-Down-Right") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P4 Down") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,NOTEQUALS,0x80)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Down-Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Left-Down-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P4 Left") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,NOTEQUALS,0x80)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Left-Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Up-Up-Left") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x40)
-
- PORT_START("DISCX.1")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("P4 X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_D) PORT_CODE_INC(KEYCODE_G) PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x80)
-
- PORT_START("DISCY.1")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("P4 Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_R) PORT_CODE_INC(KEYCODE_F) PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00) PORT_CONDITION("OPTIONS",0xC0,EQUALS,0x80)
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( intv_ecs )
- PORT_INCLUDE( intv_ecs_pads )
- PORT_INCLUDE( intv_ecs_synth )
- PORT_INCLUDE( intv_ecs_kbd )
-
- PORT_START("OPTIONS")
- PORT_CONFNAME( 0x30, 0x00, "ECS P3 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_CONFSETTING( 0x00, "Digital 8-way" )
- PORT_CONFSETTING( 0x10, "Digital 16-way" )
- PORT_CONFSETTING( 0x20, "Analog" )
- PORT_CONFNAME( 0xC0, 0x00, "ECS P4 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_CONFSETTING( 0x00, "Digital 8-way" )
- PORT_CONFSETTING( 0x40, "Digital 16-way" )
- PORT_CONFSETTING( 0x80, "Analog" )
-
- PORT_START("CNTRLSEL")
- PORT_CONFNAME( 0x0F, 0x02, "ECS Controller")
- PORT_CONFSETTING( 0x00, "Gamepads" )
- PORT_CONFSETTING( 0x01, "Piano" )
- PORT_CONFSETTING( 0x02, "Keyboard" )
-INPUT_PORTS_END
-
-ioport_constructor intv_ecs_device::device_input_ports() const
-{
- return INPUT_PORTS_NAME( intv_ecs );
-}
-
-
/*-------------------------------------------------
Paged ROM handling
-------------------------------------------------*/
diff --git a/src/devices/bus/intv/ecs.h b/src/devices/bus/intv/ecs.h
index 3dc2f37e7b6..ce22d4f7481 100644
--- a/src/devices/bus/intv/ecs.h
+++ b/src/devices/bus/intv/ecs.h
@@ -6,7 +6,7 @@
#include "slot.h"
#include "rom.h"
#include "sound/ay8910.h"
-
+#include "bus/intv_ctrl/ecs_ctrl.h"
// ======================> intv_ecs_device
@@ -21,7 +21,6 @@ public:
virtual void device_start() override;
virtual void device_reset() override;
virtual machine_config_constructor device_mconfig_additions() const override;
- virtual ioport_constructor device_input_ports() const override;
virtual const rom_entry *device_rom_region() const override;
// reading and writing
@@ -38,9 +37,6 @@ public:
// AY8914
virtual DECLARE_READ16_MEMBER(read_ay) override;
virtual DECLARE_WRITE16_MEMBER(write_ay) override;
- DECLARE_READ8_MEMBER(ay_porta_r);
- DECLARE_READ8_MEMBER(ay_portb_r);
- DECLARE_WRITE8_MEMBER(ay_porta_w);
// passthru accesses
virtual DECLARE_READ16_MEMBER(read_rom04) override { return m_subslot->read_rom04(space, offset, mem_mask); }
@@ -117,30 +113,16 @@ public:
virtual void late_subslot_setup() override;
- UINT8 intv_control_r(int hand);
-
private:
required_device<ay8914_device> m_snd;
required_device<intv_cart_slot_device> m_subslot;
- required_ioport_array<7> m_keybd;
- required_ioport_array<7> m_synth;
- required_ioport m_cntrlsel;
- required_ioport m_options;
- required_ioport_array<2> m_keypad;
- required_ioport_array<2> m_disc;
- required_ioport_array<2> m_discx;
- required_ioport_array<2> m_discy;
int m_bank_base[0x10];
- UINT8 m_psg_porta;
bool m_voice_enabled, m_ramd0_enabled, m_ram88_enabled;
};
-
-
-
// device type definition
extern const device_type INTV_ROM_ECS;
diff --git a/src/devices/bus/intv_ctrl/ctrl.cpp b/src/devices/bus/intv_ctrl/ctrl.cpp
new file mode 100644
index 00000000000..4d57c558d0e
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/ctrl.cpp
@@ -0,0 +1,95 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision controller port emulation
+
+**********************************************************************/
+
+#include "ctrl.h"
+// slot devices
+#include "handctrl.h"
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type INTV_CONTROL_PORT = &device_creator<intv_control_port_device>;
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_intv_control_port_interface - constructor
+//-------------------------------------------------
+
+device_intv_control_port_interface::device_intv_control_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_port = dynamic_cast<intv_control_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_intv_control_port_interface - destructor
+//-------------------------------------------------
+
+device_intv_control_port_interface::~device_intv_control_port_interface()
+{
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// intv_control_port_device - constructor
+//-------------------------------------------------
+
+intv_control_port_device::intv_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, INTV_CONTROL_PORT, "Mattel Intellivision control port", tag, owner, clock, "intv_control_port", __FILE__),
+ device_slot_interface(mconfig, *this), m_device(nullptr)
+{
+}
+
+
+//-------------------------------------------------
+// intv_control_port_device - destructor
+//-------------------------------------------------
+
+intv_control_port_device::~intv_control_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intv_control_port_device::device_start()
+{
+ m_device = dynamic_cast<device_intv_control_port_interface *>(get_card_device());
+}
+
+
+UINT8 intv_control_port_device::read_ctrl()
+{
+ UINT8 data = 0;
+ if (m_device)
+ data |= m_device->read_ctrl();
+ return data;
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( intv_control_port_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( intv_control_port_devices )
+ SLOT_INTERFACE("handctrl", INTV_HANDCTRL)
+SLOT_INTERFACE_END
+
diff --git a/src/devices/bus/intv_ctrl/ctrl.h b/src/devices/bus/intv_ctrl/ctrl.h
new file mode 100644
index 00000000000..b29891efe87
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/ctrl.h
@@ -0,0 +1,76 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision controller port emulation
+
+**********************************************************************/
+
+
+#pragma once
+
+#ifndef __INTV_CONTROL_PORT__
+#define __INTV_CONTROL_PORT__
+
+#include "emu.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class intv_control_port_device;
+
+// ======================> device_intv_control_port_interface
+
+class device_intv_control_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_intv_control_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_intv_control_port_interface();
+
+ virtual UINT8 read_ctrl() { return 0; };
+
+protected:
+ intv_control_port_device *m_port;
+};
+
+// ======================> intv_control_port_device
+
+class intv_control_port_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ intv_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~intv_control_port_device();
+
+ DECLARE_READ8_MEMBER( ctrl_r ) { return read_ctrl(); }
+ UINT8 read_ctrl();
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ device_intv_control_port_interface *m_device;
+};
+
+
+// device type definition
+extern const device_type INTV_CONTROL_PORT;
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_INTV_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, INTV_CONTROL_PORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+SLOT_INTERFACE_EXTERN( intv_control_port_devices );
+
+
+#endif
diff --git a/src/devices/bus/intv_ctrl/ecs_ctrl.cpp b/src/devices/bus/intv_ctrl/ecs_ctrl.cpp
new file mode 100644
index 00000000000..19bc059531a
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/ecs_ctrl.cpp
@@ -0,0 +1,448 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision ECS hack for controller port emulation
+
+ FIXME: This device is the best I could come up with to emulate
+ the fact that Keyboard and Synth controllers for the ECS should be
+ plugged in both ECS control ports, while the 3rd and 4th additional
+ hand controller should only be plugged in a single port.
+ Since the core currently does not allow a single device mounted
+ in more than a slot, this has been worked around with this device
+ which supports as options
+ - ECS keyboard
+ - ECS synth
+ - a pair of Intellivision controller
+
+ All the code for both the controller port and the slot devices has
+ been included in this single source file to make easier to clean
+ them up once we extend the core to support this kind of setup
+ (necessary for Atari 2600 Compumate as well)
+
+**********************************************************************/
+
+#include "ecs_ctrl.h"
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type INTVECS_CONTROL_PORT = &device_creator<intvecs_control_port_device>;
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_intvecs_control_port_interface - constructor
+//-------------------------------------------------
+
+device_intvecs_control_port_interface::device_intvecs_control_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_port = dynamic_cast<intvecs_control_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_intvecs_control_port_interface - destructor
+//-------------------------------------------------
+
+device_intvecs_control_port_interface::~device_intvecs_control_port_interface()
+{
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// intvecs_control_port_device - constructor
+//-------------------------------------------------
+
+intvecs_control_port_device::intvecs_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, INTVECS_CONTROL_PORT, "Mattel Intellivision ECS control port (HACK)", tag, owner, clock, "intvecs_control_port", __FILE__),
+ device_slot_interface(mconfig, *this), m_device(nullptr)
+{
+}
+
+
+//-------------------------------------------------
+// intvecs_control_port_device - destructor
+//-------------------------------------------------
+
+intvecs_control_port_device::~intvecs_control_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intvecs_control_port_device::device_start()
+{
+ m_device = dynamic_cast<device_intvecs_control_port_interface *>(get_card_device());
+}
+
+
+UINT8 intvecs_control_port_device::read_portA()
+{
+ UINT8 data = 0;
+ if (m_device)
+ data |= m_device->read_portA();
+ return data;
+}
+
+UINT8 intvecs_control_port_device::read_portB()
+{
+ UINT8 data = 0;
+ if (m_device)
+ data |= m_device->read_portB();
+ return data;
+}
+
+void intvecs_control_port_device::write_portA(UINT8 data)
+{
+ if (m_device)
+ m_device->write_portA(data);
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( intvecs_control_port_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( intvecs_control_port_devices )
+ SLOT_INTERFACE("ctrls", ECS_CTRLS)
+ SLOT_INTERFACE("keybd", ECS_KEYBD)
+ SLOT_INTERFACE("synth", ECS_SYNTH)
+SLOT_INTERFACE_END
+
+
+
+
+
+//**************************************************************************
+// ACTUAL SLOT DEVICES - included here until core issues are solved...
+//**************************************************************************
+
+
+//-------------------------------------------------
+// ECS_CTRLS - A pair of hand controllers
+//-------------------------------------------------
+
+const device_type ECS_CTRLS = &device_creator<intvecs_ctrls_device>;
+
+static SLOT_INTERFACE_START( intvecs_controller )
+ SLOT_INTERFACE("handctrl", INTV_HANDCTRL)
+SLOT_INTERFACE_END
+
+static MACHINE_CONFIG_FRAGMENT( intvecs_ctrls )
+ MCFG_INTV_CONTROL_PORT_ADD("port1", intvecs_controller, "handctrl")
+ MCFG_INTV_CONTROL_PORT_ADD("port2", intvecs_controller, "handctrl")
+MACHINE_CONFIG_END
+
+
+machine_config_constructor intvecs_ctrls_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( intvecs_ctrls );
+}
+
+intvecs_ctrls_device::intvecs_ctrls_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECS_CTRLS, "Mattel Intellivision ECS Hand Controller x2 (HACK)", tag, owner, clock, "intvecs_ctrls", __FILE__),
+ device_intvecs_control_port_interface(mconfig, *this),
+ m_hand1(*this, "port1"),
+ m_hand2(*this, "port2")
+{
+}
+
+void intvecs_ctrls_device::device_start()
+{
+}
+
+void intvecs_ctrls_device::device_reset()
+{
+}
+
+UINT8 intvecs_ctrls_device::read_portA()
+{
+ return m_hand1->read_ctrl();
+}
+
+UINT8 intvecs_ctrls_device::read_portB()
+{
+ return m_hand2->read_ctrl();
+}
+
+//-------------------------------------------------
+// ECS_KEYBD - Keyboard
+//-------------------------------------------------
+
+const device_type ECS_KEYBD = &device_creator<intvecs_keybd_device>;
+
+static INPUT_PORTS_START( intvecs_keybd )
+/*
+ ECS matrix scanned by setting 0xFE bits to output and reading 0xFF
+ ECS Keyboard Layout:
+ FF\FE Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
+ Bit 0 NC RTN 0 ESC P ; . (left)
+ Bit 1 L O 8 9 I K M ,
+ Bit 2 J U 6 7 Y H B N
+ Bit 3 G T 4 5 R F C V
+ Bit 4 D E 2 3 W S Z X
+ Bit 5 A CTL (right) 1 Q (up) (down) (space)
+ Bit 6 SHIFT NC NC NC NC NC NC NC
+
+ Shifted keys that differ from pc:
+ Key : 1 2 5 6 7 (left) (right) (up) (down)
+ Shift + key: = " + - / % ' ^ ?
+ */
+
+ PORT_START("ROW.0")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RTN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR('%')
+
+ PORT_START("ROW.1")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
+
+ PORT_START("ROW.2")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('-')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
+
+ PORT_START("ROW.3")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
+
+ PORT_START("ROW.4")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+
+ PORT_START("ROW.5")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTL") PORT_CODE(KEYCODE_RCONTROL) PORT_CODE(KEYCODE_LCONTROL)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR('\'')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('=')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR('^')
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR('?')
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+
+ PORT_START("ROW.6")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+INPUT_PORTS_END
+
+ioport_constructor intvecs_keybd_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( intvecs_keybd );
+}
+
+intvecs_keybd_device::intvecs_keybd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECS_KEYBD, "Mattel Intellivision ECS Keyboard", tag, owner, clock, "intvecs_keybd", __FILE__),
+ device_intvecs_control_port_interface(mconfig, *this),
+ m_keybd(*this, "ROW")
+{
+}
+
+void intvecs_keybd_device::device_start()
+{
+ save_item(NAME(m_psg_portA));
+}
+
+void intvecs_keybd_device::device_reset()
+{
+ m_psg_portA = 0;
+}
+
+UINT8 intvecs_keybd_device::read_portB()
+{
+ UINT8 val = 0xff;
+ // return correct result if more than one bit of 0xFE is set
+ for (int i = 0; i < 7; i++)
+ {
+ if (BIT(m_psg_portA, i))
+ val &= m_keybd[i]->read();
+ }
+ return val;
+}
+
+void intvecs_keybd_device::write_portA(UINT8 data)
+{
+ m_psg_portA = (~data) & 0xff;
+}
+
+
+
+//-------------------------------------------------
+// ECS_SYNTH - Synth
+//-------------------------------------------------
+
+const device_type ECS_SYNTH = &device_creator<intvecs_synth_device>;
+
+
+static INPUT_PORTS_START( intvecs_synth )
+/*
+ ECS Synthesizer Layout:
+ FF\FE Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
+ Bit 0 G2 Gb2 F2 E2 Eb2 D2 Db2 C2
+ Bit 1 Eb3 D3 Db3 C3 B2 Bb2 A2 Ab2
+ Bit 2 B3 Bb3 A3 Ab3 G3 Gb3 F3 E3
+ Bit 3 G4 Gb4 F4 E4 Eb4 D4 Db4 C4
+ Bit 4 Eb5 D5 Db5 C5 B4 Bb4 A4 Ab4
+ Bit 5 B5 Bb5 A5 Ab5 G5 Gb5 F5 E5
+ Bit 6 C6 NC NC NC NC NC NC NC
+ */
+ PORT_START("SYNTH.0")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb2")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E2")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb2")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2")
+
+ PORT_START("SYNTH.1")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb3")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db3")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B2")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb2")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab2")
+
+ PORT_START("SYNTH.2")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B3")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb3")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab3")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb3")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E3")
+
+ PORT_START("SYNTH.3")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb4")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E4")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb4")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db4")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4")
+
+ PORT_START("SYNTH.4")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb5")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db5")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb4")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab4")
+
+ PORT_START("SYNTH.5")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B5")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb5")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab5")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb5")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E5")
+
+ PORT_START("SYNTH.6")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+INPUT_PORTS_END
+
+
+ioport_constructor intvecs_synth_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( intvecs_synth );
+}
+
+
+intvecs_synth_device::intvecs_synth_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECS_SYNTH, "Mattel Intellivision ECS Synthetizer", tag, owner, clock, "intvecs_synth", __FILE__),
+ device_intvecs_control_port_interface(mconfig, *this),
+ m_synth(*this, "SYNTH")
+{
+}
+
+void intvecs_synth_device::device_start()
+{
+ save_item(NAME(m_psg_portA));
+}
+
+void intvecs_synth_device::device_reset()
+{
+ m_psg_portA = 0;
+}
+
+UINT8 intvecs_synth_device::read_portB()
+{
+ UINT8 val = 0xff;
+ // return correct result if more than one bit of 0xFE is set
+ for (int i = 0; i < 7; i++)
+ {
+ if (BIT(m_psg_portA, i))
+ val &= m_synth[i]->read();
+ }
+ return val;
+}
+
+void intvecs_synth_device::write_portA(UINT8 data)
+{
+ m_psg_portA = (~data) & 0xff;
+}
+
diff --git a/src/devices/bus/intv_ctrl/ecs_ctrl.h b/src/devices/bus/intv_ctrl/ecs_ctrl.h
new file mode 100644
index 00000000000..40d94ca5d1b
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/ecs_ctrl.h
@@ -0,0 +1,171 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision ECS hack for controller port emulation
+
+**********************************************************************/
+
+
+#pragma once
+
+#ifndef __INTVECS_CONTROL_PORT__
+#define __INTVECS_CONTROL_PORT__
+
+#include "emu.h"
+#include "bus/intv_ctrl/ctrl.h"
+#include "bus/intv_ctrl/handctrl.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class intvecs_control_port_device;
+
+// ======================> device_intvecs_control_port_interface
+
+class device_intvecs_control_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_intvecs_control_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_intvecs_control_port_interface();
+
+ virtual UINT8 read_portA() { return 0xff; };
+ virtual UINT8 read_portB() { return 0xff; };
+ virtual void write_portA(UINT8 data) { };
+
+protected:
+ intvecs_control_port_device *m_port;
+};
+
+// ======================> intvecs_control_port_device
+
+class intvecs_control_port_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ intvecs_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~intvecs_control_port_device();
+
+ DECLARE_READ8_MEMBER( portA_r ) { return read_portA(); }
+ DECLARE_READ8_MEMBER( portB_r ) { return read_portB(); }
+ DECLARE_WRITE8_MEMBER( portA_w ) { return write_portA(data); }
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ UINT8 read_portA();
+ UINT8 read_portB();
+ void write_portA(UINT8 data);
+
+ device_intvecs_control_port_interface *m_device;
+};
+
+
+// device type definition
+extern const device_type INTVECS_CONTROL_PORT;
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_INTVECS_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, INTVECS_CONTROL_PORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+SLOT_INTERFACE_EXTERN( intvecs_control_port_devices );
+
+
+//**************************************************************************
+// ACTUAL SLOT DEVICES - included here until core issues are solved...
+//**************************************************************************
+
+// ======================> intvecs_ctrls_device
+
+class intvecs_ctrls_device : public device_t,
+ public device_intvecs_control_port_interface
+{
+public:
+ // construction/destruction
+ intvecs_ctrls_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual UINT8 read_portA() override;
+ virtual UINT8 read_portB() override;
+
+private:
+ required_device<intv_control_port_device> m_hand1;
+ required_device<intv_control_port_device> m_hand2;
+};
+
+// ======================> intvecs_keybd_device
+
+class intvecs_keybd_device : public device_t,
+ public device_intvecs_control_port_interface
+{
+public:
+ // construction/destruction
+ intvecs_keybd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual UINT8 read_portB() override;
+ virtual void write_portA(UINT8 data) override;
+
+private:
+ UINT8 m_psg_portA;
+ required_ioport_array<7> m_keybd;
+};
+
+// ======================> intvecs_synth_device
+
+class intvecs_synth_device : public device_t,
+ public device_intvecs_control_port_interface
+{
+public:
+ // construction/destruction
+ intvecs_synth_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual UINT8 read_portB() override;
+ virtual void write_portA(UINT8 data) override;
+
+private:
+ UINT8 m_psg_portA;
+ required_ioport_array<7> m_synth;
+};
+
+
+// device type definition
+extern const device_type ECS_CTRLS;
+extern const device_type ECS_KEYBD;
+extern const device_type ECS_SYNTH;
+
+
+
+#endif
diff --git a/src/devices/bus/intv_ctrl/handctrl.cpp b/src/devices/bus/intv_ctrl/handctrl.cpp
new file mode 100644
index 00000000000..512f9f32adc
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/handctrl.cpp
@@ -0,0 +1,179 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision Hand Controllers
+
+**********************************************************************/
+
+#include "handctrl.h"
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type INTV_HANDCTRL = &device_creator<intv_handctrl_device>;
+
+
+static INPUT_PORTS_START( intv_handctrl )
+ PORT_START("KEYPAD")
+ PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("3") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("7") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("8") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("9") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Clear") PORT_CODE(KEYCODE_DEL_PAD)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD)
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Upper") PORT_PLAYER(1)
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Lower-Left") PORT_PLAYER(1)
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Lower-Right") PORT_PLAYER(1)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("DISC_DG")
+ PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Up") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Up-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("Right") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Down-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("Down") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Down-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("Left") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Up-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
+
+ PORT_START("DISC_AN_X")
+ PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01)
+
+ PORT_START("DISC_AN_Y")
+ PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01)
+
+
+ PORT_START("OPTIONS")
+ PORT_CONFNAME( 0x01, 0x01, "Controller Disc Emulation" )
+ PORT_CONFSETTING( 0x00, "Digital" )
+ PORT_CONFSETTING( 0x01, "Analog" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor intv_handctrl_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( intv_handctrl );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// intv_handctrl_device - constructor
+//-------------------------------------------------
+
+intv_handctrl_device::intv_handctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, INTV_HANDCTRL, "Mattel Intellivision Hand Controller", tag, owner, clock, "intv_hand", __FILE__),
+ device_intv_control_port_interface(mconfig, *this),
+ m_cfg(*this, "OPTIONS"),
+ m_keypad(*this, "KEYPAD"),
+ m_disc_dig(*this, "DISC_DG"),
+ m_disc_anx(*this, "DISC_AN_X"),
+ m_disc_any(*this, "DISC_AN_Y")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intv_handctrl_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void intv_handctrl_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// read_ctrl
+//-------------------------------------------------
+
+UINT8 intv_handctrl_device::read_ctrl()
+{
+ static const UINT8 keypad_table[] =
+ {
+ 0xff, 0x3f, 0x9f, 0x5f, 0xd7, 0xb7, 0x77, 0xdb,
+ 0xbb, 0x7b, 0xdd, 0xbd, 0x7d, 0xde, 0xbe, 0x7e
+ };
+
+ static const UINT8 disc_table[] =
+ {
+ 0xf3, 0xe3, 0xe7, 0xf7, 0xf6, 0xe6, 0xee, 0xfe,
+ 0xfc, 0xec, 0xed, 0xfd, 0xf9, 0xe9, 0xeb, 0xfb
+ };
+
+ static const UINT8 discyx_table[5][5] =
+ {
+ { 0xe3, 0xf3, 0xfb, 0xeb, 0xe9 },
+ { 0xe7, 0xe3, 0xfb, 0xe9, 0xf9 },
+ { 0xf7, 0xf7, 0xff, 0xfd, 0xfd },
+ { 0xf6, 0xe6, 0xfe, 0xec, 0xed },
+ { 0xe6, 0xee, 0xfe, 0xfc, 0xec }
+ };
+
+ int x, y;
+ UINT8 res = 0xff;
+
+ /* keypad */
+ x = m_keypad->read();
+ for (int i = 0; i < 16; i++)
+ {
+ if (BIT(x, i))
+ res &= keypad_table[i];
+ }
+
+ switch (m_cfg->read() & 1)
+ {
+ /* disc == digital */
+ case 0:
+ default:
+ x = m_disc_dig->read();
+ for (int i = 0; i < 16; i++)
+ {
+ if (BIT(x, i))
+ res &= disc_table[i];
+ }
+ break;
+
+ /* disc == _fake_ analog */
+ case 1:
+ x = m_disc_anx->read();
+ y = m_disc_any->read();
+ res &= discyx_table[y / 32][x / 32];
+ break;
+ }
+
+ return res;
+}
+
diff --git a/src/devices/bus/intv_ctrl/handctrl.h b/src/devices/bus/intv_ctrl/handctrl.h
new file mode 100644
index 00000000000..5b6fc4a3fb9
--- /dev/null
+++ b/src/devices/bus/intv_ctrl/handctrl.h
@@ -0,0 +1,55 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli
+/**********************************************************************
+
+ Mattel Intellivision Hand Controller
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __INTV_HANDCTRL__
+#define __INTV_HANDCTRL__
+
+
+#include "emu.h"
+#include "ctrl.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> intv_handctrl_device
+
+class intv_handctrl_device : public device_t,
+ public device_intv_control_port_interface
+{
+public:
+ // construction/destruction
+ intv_handctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_intv_control_port_interface overrides
+ virtual UINT8 read_ctrl() override;
+
+private:
+ required_ioport m_cfg;
+ required_ioport m_keypad;
+ required_ioport m_disc_dig;
+ required_ioport m_disc_anx;
+ required_ioport m_disc_any;
+};
+
+
+// device type definition
+extern const device_type INTV_HANDCTRL;
+
+
+#endif
diff --git a/src/mame/drivers/intv.cpp b/src/mame/drivers/intv.cpp
index d1d6f8eab6b..084d7b492ba 100644
--- a/src/mame/drivers/intv.cpp
+++ b/src/mame/drivers/intv.cpp
@@ -136,103 +136,6 @@ static GFXDECODE_START( intvkbd )
GFXDECODE_ENTRY( "gfx1", 0x0000, intvkbd_charlayout, 0, 256 )
GFXDECODE_END
-static INPUT_PORTS_START( intv )
-
- /* Left Player Controller */
- PORT_START("KEYPAD1")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/1") PORT_CODE(KEYCODE_1_PAD)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/2") PORT_CODE(KEYCODE_2_PAD)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/3") PORT_CODE(KEYCODE_3_PAD)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/4") PORT_CODE(KEYCODE_4_PAD)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/5") PORT_CODE(KEYCODE_5_PAD)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/6") PORT_CODE(KEYCODE_6_PAD)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/7") PORT_CODE(KEYCODE_7_PAD)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/8") PORT_CODE(KEYCODE_8_PAD)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/9") PORT_CODE(KEYCODE_9_PAD)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/Clear") PORT_CODE(KEYCODE_DEL_PAD)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/0") PORT_CODE(KEYCODE_0_PAD)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/Enter") PORT_CODE(KEYCODE_ENTER_PAD)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Left/Upper") PORT_PLAYER(1)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Left/Lower-Left") PORT_PLAYER(1)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Left/Lower-Right") PORT_PLAYER(1)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC1")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Left/Up") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Right-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("Left/Right") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Right-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("Left/Down") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Left-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("Left/Left") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Left-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00)
-
- PORT_START("DISCX1")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("Left/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01)
-
- PORT_START("DISCY1")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("Left/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01)
-
- /* Right Player Controller */
- PORT_START("KEYPAD2")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/1")
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/2")
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/3")
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/4")
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/5")
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/6")
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/7")
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/8")
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/9")
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/Clear")
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/0")
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/Enter")
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Right/Upper") PORT_PLAYER(2)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Right/Lower-Left") PORT_PLAYER(2)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Right/Lower-Right") PORT_PLAYER(2)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC2")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Right/Up") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Right-Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("Right/Right") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Right-Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("Right/Down") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Left-Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("Right/Left") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Left-Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00)
-
- PORT_START("DISCX2")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("Right/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_D) PORT_CODE_INC(KEYCODE_G) PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x02)
-
- PORT_START("DISCY2")
- PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("Right/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_R) PORT_CODE_INC(KEYCODE_F) PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x02)
-
- PORT_START("OPTIONS")
- PORT_CONFNAME( 0x01, 0x00, "Left Disc" )
- PORT_CONFSETTING( 0x00, "Digital" )
- PORT_CONFSETTING( 0x01, "Analog" )
- PORT_CONFNAME( 0x02, 0x00, "Right Disc" )
- PORT_CONFSETTING( 0x00, "Digital" )
- PORT_CONFSETTING( 0x02, "Analog" )
-INPUT_PORTS_END
-
/*
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
@@ -370,11 +273,6 @@ static INPUT_PORTS_START( intvkbd )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD)
-
- /* 2008-05 FP: I include here the controller inputs to make happy the read_handler.
- Please remove this (and re-tag accordingly the inputs above) if intv_right_control_r
- is supposed to scan the keyboard inputs when the Keyboard Component is connected */
- PORT_INCLUDE( intv )
INPUT_PORTS_END
static ADDRESS_MAP_START( intv_mem, AS_PROGRAM, 16, intv_state )
@@ -551,7 +449,6 @@ INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt2)
timer_set(m_keyboard->cycles_to_attotime(100), TIMER_INTV_INTERRUPT2_COMPLETE);
}
-
static MACHINE_CONFIG_START( intv, intv_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", CP1610, XTAL_3_579545MHz/4) /* Colorburst/4 */
@@ -574,11 +471,14 @@ static MACHINE_CONFIG_START( intv, intv_state )
MCFG_PALETTE_INDIRECT_ENTRIES(32)
MCFG_PALETTE_INIT_OWNER(intv_state, intv)
+ MCFG_INTV_CONTROL_PORT_ADD("iopt_right_ctrl", intv_control_port_devices, "handctrl")
+ MCFG_INTV_CONTROL_PORT_ADD("iopt_left_ctrl", intv_control_port_devices, "handctrl")
+
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ay8914", AY8914, XTAL_3_579545MHz/2)
- MCFG_AY8910_PORT_A_READ_CB(READ8(intv_state, intv_right_control_r))
- MCFG_AY8910_PORT_B_READ_CB(READ8(intv_state, intv_left_control_r))
+ MCFG_AY8910_PORT_A_READ_CB(DEVREAD8("iopt_right_ctrl", intv_control_port_device, ctrl_r))
+ MCFG_AY8910_PORT_B_READ_CB(DEVREAD8("iopt_left_ctrl", intv_control_port_device, ctrl_r))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33)
/* cartridge */
@@ -743,11 +643,11 @@ DRIVER_INIT_MEMBER(intv_state,intvkbd)
***************************************************************************/
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
-CONS( 1979, intv, 0, 0, intv, intv, intv_state, intv, "Mattel", "Intellivision", MACHINE_SUPPORTS_SAVE )
-CONS( 1981, intvsrs, intv, 0, intv, intv, intv_state, intv, "Sears", "Super Video Arcade", MACHINE_SUPPORTS_SAVE )
+CONS( 1979, intv, 0, 0, intv, 0, intv_state, intv, "Mattel", "Intellivision", MACHINE_SUPPORTS_SAVE )
+CONS( 1981, intvsrs, intv, 0, intv, 0, intv_state, intv, "Sears", "Super Video Arcade", MACHINE_SUPPORTS_SAVE )
COMP( 1981, intvkbd, intv, 0, intvkbd, intvkbd, intv_state, intvkbd, "Mattel", "Intellivision Keyboard Component (Unreleased)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
-CONS( 1982, intv2, intv, 0, intv2, intv, intv_state, intv, "Mattel", "Intellivision II", MACHINE_SUPPORTS_SAVE )
+CONS( 1982, intv2, intv, 0, intv2, 0, intv_state, intv, "Mattel", "Intellivision II", MACHINE_SUPPORTS_SAVE )
// made up, user friendlier machines with pre-mounted passthu expansions
-COMP( 1982, intvoice, intv, 0, intvoice, intv, intv_state, intv, "Mattel", "Intellivision w/IntelliVoice expansion", MACHINE_SUPPORTS_SAVE )
-COMP( 1983, intvecs, intv, 0, intvecs, intv, intv_state, intv, "Mattel", "Intellivision w/Entertainment Computer System + Intellivoice expansions", MACHINE_SUPPORTS_SAVE )
+COMP( 1982, intvoice, intv, 0, intvoice, 0, intv_state, intv, "Mattel", "Intellivision w/IntelliVoice expansion", MACHINE_SUPPORTS_SAVE )
+COMP( 1983, intvecs, intv, 0, intvecs, 0, intv_state, intv, "Mattel", "Intellivision w/Entertainment Computer System + Intellivoice expansions", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/includes/intv.h b/src/mame/includes/intv.h
index 7f14c7fb55a..4155499db7d 100644
--- a/src/mame/includes/intv.h
+++ b/src/mame/includes/intv.h
@@ -16,6 +16,9 @@
#include "bus/intv/ecs.h"
//#include "bus/intv/keycomp.h"
+#include "bus/intv_ctrl/ctrl.h"
+#include "bus/intv_ctrl/handctrl.h"
+
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
@@ -43,7 +46,6 @@ public:
m_iocart2(*this, "ioslot2"),
m_region_maincpu(*this, "maincpu"),
m_region_keyboard(*this, "keyboard"),
- m_io_options(*this, "OPTIONS"),
m_io_test(*this, "TEST"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
@@ -118,19 +120,13 @@ protected:
optional_device<generic_slot_device> m_iocart2;
required_memory_region m_region_maincpu;
optional_memory_region m_region_keyboard;
- required_ioport m_io_options;
optional_ioport m_io_test;
optional_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
- ioport_port *m_keypad[4];
- ioport_port *m_disc[4];
- ioport_port *m_discx[4];
- ioport_port *m_discy[4];
ioport_port *m_intv_keyboard[10];
- UINT8 intv_control_r(int hand);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
};
diff --git a/src/mame/machine/intv.cpp b/src/mame/machine/intv.cpp
index 391abbd4150..55915b00254 100644
--- a/src/mame/machine/intv.cpp
+++ b/src/mame/machine/intv.cpp
@@ -326,28 +326,6 @@ void intv_state::machine_reset()
void intv_state::machine_start()
{
- // TODO: split these for intvkbd & intvecs??
- for (int i = 0; i < 4; i++)
- {
- char str[8];
- sprintf(str, "KEYPAD%i", i + 1);
- m_keypad[i] = ioport(str);
- }
- for (int i = 0; i < 4; i++)
- {
- char str[6];
- sprintf(str, "DISC%i", i + 1);
- m_disc[i] = ioport(str);
- }
- for (int i = 0; i < 4; i++)
- {
- char str[7];
- sprintf(str, "DISCX%i", i + 1);
- m_discx[i] = ioport(str);
- sprintf(str, "DISCY%i", i + 1);
- m_discy[i] = ioport(str);
- }
-
save_item(NAME(m_bus_copy_mode));
save_item(NAME(m_backtab_row));
save_item(NAME(m_ram16));
@@ -459,74 +437,3 @@ INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt)
m_stic->screenrefresh();
}
-/* hand 0 == left, 1 == right, 2 == ECS hand controller 1, 3 == ECS hand controller 2 */
-UINT8 intv_state::intv_control_r(int hand)
-{
- static const UINT8 keypad_table[] =
- {
- 0xFF, 0x3F, 0x9F, 0x5F, 0xD7, 0xB7, 0x77, 0xDB,
- 0xBB, 0x7B, 0xDD, 0xBD, 0x7D, 0xDE, 0xBE, 0x7E
- };
-
- static const UINT8 disc_table[] =
- {
- 0xF3, 0xE3, 0xE7, 0xF7, 0xF6, 0xE6, 0xEE, 0xFE,
- 0xFC, 0xEC, 0xED, 0xFD, 0xF9, 0xE9, 0xEB, 0xFB
- };
-
- static const UINT8 discyx_table[5][5] =
- {
- { 0xE3, 0xF3, 0xFB, 0xEB, 0xE9 },
- { 0xE7, 0xE3, 0xFB, 0xE9, 0xF9 },
- { 0xF7, 0xF7, 0xFF, 0xFD, 0xFD },
- { 0xF6, 0xE6, 0xFE, 0xEC, 0xED },
- { 0xE6, 0xEE, 0xFE, 0xFC, 0xEC }
- };
-
- int x, y;
- UINT8 rv = 0xFF;
-
- /* keypad */
- x = m_keypad[hand]->read();
- for (y = 0; y < 16; y++)
- {
- if (x & (1 << y))
- {
- rv &= keypad_table[y];
- }
- }
-
- switch ((m_io_options->read() >> hand) & 1)
- {
- case 0: /* disc == digital */
- default:
-
- x = m_disc[hand]->read();
- for (y = 0; y < 16; y++)
- {
- if (x & (1 << y))
- {
- rv &= disc_table[y];
- }
- }
- break;
-
- case 1: /* disc == _fake_ analog */
-
- x = m_discx[hand]->read();
- y = m_discy[hand]->read();
- rv &= discyx_table[y / 32][x / 32];
- }
-
- return rv;
-}
-
-READ8_MEMBER( intv_state::intv_left_control_r )
-{
- return intv_control_r(0);
-}
-
-READ8_MEMBER( intv_state::intv_right_control_r )
-{
- return intv_control_r(1);
-}