summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/bus/bus.mak14
-rw-r--r--src/emu/bus/intv/ecs.c588
-rw-r--r--src/emu/bus/intv/ecs.h145
-rw-r--r--src/emu/bus/intv/rom.c50
-rw-r--r--src/emu/bus/intv/rom.h82
-rw-r--r--src/emu/bus/intv/slot.c572
-rw-r--r--src/emu/bus/intv/slot.h184
-rw-r--r--src/emu/bus/intv/voice.c122
-rw-r--r--src/emu/bus/intv/voice.h76
-rw-r--r--src/mess/drivers/intv.c570
-rw-r--r--src/mess/includes/intv.h66
-rw-r--r--src/mess/machine/intv.c475
-rw-r--r--src/mess/mess.lst3
-rw-r--r--src/mess/mess.mak1
14 files changed, 2064 insertions, 884 deletions
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak
index a6cd026c0a8..3baeace9b15 100644
--- a/src/emu/bus/bus.mak
+++ b/src/emu/bus/bus.mak
@@ -415,6 +415,20 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/intv/slot.h,BUSES += INTV
+#-------------------------------------------------
+
+ifneq ($(filter INTV,$(BUSES)),)
+OBJDIRS += $(BUSOBJ)/intv
+BUSOBJS += $(BUSOBJ)/intv/slot.o
+BUSOBJS += $(BUSOBJ)/intv/rom.o
+BUSOBJS += $(BUSOBJ)/intv/voice.o
+BUSOBJS += $(BUSOBJ)/intv/ecs.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/isa/isa.h,BUSES += ISA
#-------------------------------------------------
diff --git a/src/emu/bus/intv/ecs.c b/src/emu/bus/intv/ecs.c
new file mode 100644
index 00000000000..6b42f004bab
--- /dev/null
+++ b/src/emu/bus/intv/ecs.c
@@ -0,0 +1,588 @@
+/***********************************************************************************************************
+
+
+ Mattel Intellivision Entertainment Computer System expansion emulation
+
+ TODO:
+ - Make paged rom emulation more accurate (according to
+ http://spatula-city.org/~im14u2c/intv/tech/ecs.html
+ writes to $xa5y should be available for every x and every y, i.e. we shall
+ have writes to every 4K chunk of the memory map, and there shall be 16 pages
+ for each)
+ Current emulation is instead tailored around the minimal usage necessary to
+ make the main expansion and World Series Major League Baseball happy
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "ecs.h"
+
+
+//-------------------------------------------------
+// intv_ecs_device - constructor
+//-------------------------------------------------
+
+const device_type INTV_ROM_ECS = &device_creator<intv_ecs_device>;
+
+intv_ecs_device::intv_ecs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : 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)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intv_ecs_device::device_start()
+{
+ // if the ECS is mounted directly in the system, use device rom and alloc RAM
+ if (m_rom == NULL)
+ {
+ astring region_tag;
+ m_rom = memregion(region_tag.cpy(tag()).cat(":ecs"))->base();
+ }
+ if (!m_ram.count())
+ {
+ m_ram.resize(0x800);
+ }
+
+ save_item(NAME(m_bank_base));
+ save_item(NAME(m_psg_porta));
+}
+
+void intv_ecs_device::device_reset()
+{
+ memset(m_bank_base, 0, sizeof(m_bank_base));
+}
+
+void intv_ecs_device::late_subslot_setup()
+{
+ switch (m_subslot->get_type())
+ {
+ case INTV_RAM:
+ m_ramd0_enabled = true;
+ break;
+ case INTV_GFACT:
+ m_ram88_enabled = true;
+ break;
+ case INTV_VOICE:
+ m_voice_enabled = true;
+ m_subslot->late_subslot_setup();
+ break;
+ case INTV_ECS:
+ printf("WARNING: You cannot connect serially multiple ECS units.\n");
+ printf("WARNING: Emulation will likely misbehave.\n");
+ break;
+ case INTV_KEYCOMP:
+ printf("WARNING: You cannot connect the Keyboard component to the ECS unit.\n");
+ printf("WARNING: Emulation will likely misbehave.\n");
+ break;
+ }
+}
+
+//-------------------------------------------------
+// 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];
+ }
+ }
+
+ switch ((m_options->read() >> hand) & 4)
+ {
+ case 0: /* disc == digital */
+ default:
+
+ x = m_disc[hand]->read();
+ for (y = 0; y < 16; y++)
+ {
+ if (x & (1 << y))
+ {
+ val &= disc_table[y];
+ }
+ }
+ break;
+
+ case 1: /* 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_SOUND_ROUTE(ALL_OUTPUTS, "mono_ecs", 0.33)
+
+ MCFG_INTV_CARTRIDGE_ADD("subslot", intv_cart, NULL)
+MACHINE_CONFIG_END
+
+
+machine_config_constructor intv_ecs_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sub_slot );
+}
+
+
+ROM_START( ecs )
+ ROM_REGION( 0x20000, "ecs", ROMREGION_ERASEFF )
+ ROM_LOAD16_WORD_SWAP( "ecs_rom.20", 0x04000, 0x2000, CRC(5f9d05e5) SHA1(083a3e7405b8f8b4b8a5003ca9c31b8d824b535c))
+ ROM_LOAD16_WORD_SWAP( "ecs_rom.70", 0x0e000, 0x2000, CRC(46bb1f48) SHA1(eda44a8476fdada1ae90fba0d0287611e2efa074))
+ ROM_LOAD16_WORD_SWAP( "ecs_rom.e0", 0x1c000, 0x2000, CRC(c2ebcd90) SHA1(b3c14955f56c57e6f0d8fbb695771946cfcf6582))
+ROM_END
+
+const rom_entry *intv_ecs_device::device_rom_region() const
+{
+ return ROM_NAME( ecs );
+}
+
+
+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("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P3/Right") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P3/Down") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P3/Left") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+
+ 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("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+
+ 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("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+
+ // 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("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P4/Right") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P4/Down") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P4/Left") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+
+ 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("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+
+ 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("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+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( 0x04, 0x00, "ECS_P3 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_CONFSETTING( 0x00, "Digital" )
+ PORT_CONFSETTING( 0x04, "Analog" )
+ PORT_CONFNAME( 0x08, 0x00, "ECS_P4 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
+ PORT_CONFSETTING( 0x00, "Digital" )
+ PORT_CONFSETTING( 0x08, "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
+ -------------------------------------------------*/
+
+READ16_MEMBER(intv_ecs_device::read_rom20)
+{
+ if (m_bank_base[2])
+ return INTV_ROM16_READ(offset + 0x2000);
+ else
+ return 0xffff;
+}
+
+READ16_MEMBER(intv_ecs_device::read_rom70)
+{
+ if (m_bank_base[7])
+ return 0xffff;
+ else
+ return INTV_ROM16_READ(offset + 0x7000);
+}
+
+READ16_MEMBER(intv_ecs_device::read_rome0)
+{
+ if (m_bank_base[14])
+ return INTV_ROM16_READ(offset + 0xe000);
+ else // if WSMLB is loaded, it shall go here, otherwise 0xffff
+ return m_subslot->read_rome0(space, offset, mem_mask);
+}
+
+READ16_MEMBER(intv_ecs_device::read_romf0)
+{
+ // only WSMLB should come here with bank_base = 1
+ if (m_bank_base[15])
+ return m_subslot->read_romf0(space, offset + 0x1000, mem_mask);
+ else
+ return m_subslot->read_romf0(space, offset, mem_mask);
+}
+
+
+/*-------------------------------------------------
+ read_audio
+ -------------------------------------------------*/
+
+READ16_MEMBER(intv_ecs_device::read_ay)
+{
+ if (ACCESSING_BITS_0_7)
+ return m_snd->read(space, offset, mem_mask);
+ else
+ return 0xffff;
+}
+
+/*-------------------------------------------------
+ write_audio
+ -------------------------------------------------*/
+
+WRITE16_MEMBER(intv_ecs_device::write_ay)
+{
+ if (ACCESSING_BITS_0_7)
+ return m_snd->write(space, offset, data, mem_mask);
+}
+
diff --git a/src/emu/bus/intv/ecs.h b/src/emu/bus/intv/ecs.h
new file mode 100644
index 00000000000..6db3609c7ce
--- /dev/null
+++ b/src/emu/bus/intv/ecs.h
@@ -0,0 +1,145 @@
+#ifndef __INTV_ECS_H
+#define __INTV_ECS_H
+
+#include "slot.h"
+#include "rom.h"
+#include "sound/ay8910.h"
+
+
+
+// ======================> intv_ecs_device
+
+class intv_ecs_device : public intv_rom_device
+{
+public:
+ // construction/destruction
+ intv_ecs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+ virtual const rom_entry *device_rom_region() const;
+
+ // reading and writing
+
+ // actual ECS accesses
+ // paged ROMs
+ virtual DECLARE_READ16_MEMBER(read_rom20);
+ virtual DECLARE_READ16_MEMBER(read_rom70);
+ virtual DECLARE_READ16_MEMBER(read_rome0);
+ virtual DECLARE_READ16_MEMBER(read_romf0);
+ // RAM
+ virtual DECLARE_READ16_MEMBER(read_ram) { return (int)m_ram[offset & (m_ram.count() - 1)]; }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) { m_ram[offset & (m_ram.count() - 1)] = data & 0xff; }
+ // AY8914
+ virtual DECLARE_READ16_MEMBER(read_ay);
+ virtual DECLARE_WRITE16_MEMBER(write_ay);
+ 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) { return m_subslot->read_rom04(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom40) { return m_subslot->read_rom40(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom48) { return m_subslot->read_rom48(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom50) { return m_subslot->read_rom50(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom60) { return m_subslot->read_rom60(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom80)
+ {
+ if (m_ram88_enabled && offset >= 0x800)
+ return m_subslot->read_ram(space, offset & 0x7ff, mem_mask);
+ else
+ return m_subslot->read_rom80(space, offset, mem_mask);
+ }
+ virtual DECLARE_READ16_MEMBER(read_rom90) { return m_subslot->read_rom90(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_roma0) { return m_subslot->read_roma0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romb0) { return m_subslot->read_romb0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romc0) { return m_subslot->read_romc0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romd0)
+ {
+ if (m_ramd0_enabled && offset < 0x800)
+ return m_subslot->read_ram(space, offset, mem_mask);
+ else
+ return m_subslot->read_romd0(space, offset, mem_mask);
+ }
+
+ // paged ROM banking
+ virtual DECLARE_WRITE16_MEMBER(write_rom20)
+ {
+ if (offset == 0xfff)
+ {
+ if (data == 0x2a50)
+ m_bank_base[2] = 0;
+ else if (data == 0x2a51)
+ m_bank_base[2] = 1;
+ }
+ }
+ virtual DECLARE_WRITE16_MEMBER(write_rom70)
+ {
+ if (offset == 0xfff)
+ {
+ if (data == 0x7a50)
+ m_bank_base[7] = 0;
+ else if (data == 0x7a51)
+ m_bank_base[7] = 1;
+ }
+ }
+ virtual DECLARE_WRITE16_MEMBER(write_rome0)
+ {
+ if (offset == 0xfff)
+ {
+ if (data == 0xea50)
+ m_bank_base[14] = 0;
+ else if (data == 0xea51)
+ m_bank_base[14] = 1;
+ }
+ }
+ virtual DECLARE_WRITE16_MEMBER(write_romf0)
+ {
+ if (offset == 0xfff)
+ {
+ if (data == 0xfa50)
+ m_bank_base[15] = 0;
+ else if (data == 0xfa51)
+ m_bank_base[15] = 1;
+ }
+ }
+ // RAM passthru write
+ virtual DECLARE_WRITE16_MEMBER(write_88) { if (m_ram88_enabled) m_subslot->write_ram(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_d0) { if (m_ramd0_enabled) m_subslot->write_ram(space, offset, data, mem_mask); }
+ // IntelliVoice passthru
+ virtual DECLARE_READ16_MEMBER(read_speech) { if (m_voice_enabled) return m_subslot->read_speech(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_WRITE16_MEMBER(write_speech) { if (m_voice_enabled) m_subslot->write_speech(space, offset, data, mem_mask); }
+
+ virtual void late_subslot_setup();
+
+ 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;
+
+#endif
diff --git a/src/emu/bus/intv/rom.c b/src/emu/bus/intv/rom.c
new file mode 100644
index 00000000000..6bc190f4a83
--- /dev/null
+++ b/src/emu/bus/intv/rom.c
@@ -0,0 +1,50 @@
+/***********************************************************************************************************
+
+
+ Mattel Intellivision cart emulation
+
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "rom.h"
+
+
+//-------------------------------------------------
+// intv_rom_device - constructor
+//-------------------------------------------------
+
+const device_type INTV_ROM_STD = &device_creator<intv_rom_device>;
+const device_type INTV_ROM_RAM = &device_creator<intv_ram_device>;
+const device_type INTV_ROM_GFACT = &device_creator<intv_gfact_device>;
+const device_type INTV_ROM_WSMLB = &device_creator<intv_wsmlb_device>;
+
+
+intv_rom_device::intv_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_intv_cart_interface( mconfig, *this )
+{
+}
+
+intv_rom_device::intv_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, INTV_ROM_STD, "Intellivision Standard Carts", tag, owner, clock, "intv_rom", __FILE__),
+ device_intv_cart_interface( mconfig, *this )
+{
+}
+
+intv_ram_device::intv_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : intv_rom_device(mconfig, INTV_ROM_RAM, "Intellivision Carts w/RAM", tag, owner, clock, "intv_ram", __FILE__)
+{
+}
+
+intv_gfact_device::intv_gfact_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : intv_rom_device(mconfig, INTV_ROM_GFACT, "Intellivision Game Factory Cart", tag, owner, clock, "intv_gfact", __FILE__)
+{
+}
+
+intv_wsmlb_device::intv_wsmlb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : intv_rom_device(mconfig, INTV_ROM_WSMLB, "Intellivision World Series Baseball Cart", tag, owner, clock, "intv_wsmlb", __FILE__)
+{
+}
+
diff --git a/src/emu/bus/intv/rom.h b/src/emu/bus/intv/rom.h
new file mode 100644
index 00000000000..2eb13cc5c76
--- /dev/null
+++ b/src/emu/bus/intv/rom.h
@@ -0,0 +1,82 @@
+#ifndef __INTV_ROM_H
+#define __INTV_ROM_H
+
+#include "slot.h"
+
+
+// ======================> intv_rom_device
+
+class intv_rom_device : public device_t,
+ public device_intv_cart_interface
+{
+public:
+ // construction/destruction
+ intv_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+ intv_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read_rom04) { return INTV_ROM16_READ(offset + 0x0400); }
+ virtual DECLARE_READ16_MEMBER(read_rom20) { return INTV_ROM16_READ(offset + 0x2000); }
+ virtual DECLARE_READ16_MEMBER(read_rom40) { return INTV_ROM16_READ(offset + 0x4000); }
+ virtual DECLARE_READ16_MEMBER(read_rom48) { return INTV_ROM16_READ(offset + 0x4800); }
+ virtual DECLARE_READ16_MEMBER(read_rom50) { return INTV_ROM16_READ(offset + 0x5000); }
+ virtual DECLARE_READ16_MEMBER(read_rom60) { return INTV_ROM16_READ(offset + 0x6000); }
+ virtual DECLARE_READ16_MEMBER(read_rom70) { return INTV_ROM16_READ(offset + 0x7000); }
+ virtual DECLARE_READ16_MEMBER(read_rom80) { return INTV_ROM16_READ(offset + 0x8000); }
+ virtual DECLARE_READ16_MEMBER(read_rom90) { return INTV_ROM16_READ(offset + 0x9000); }
+ virtual DECLARE_READ16_MEMBER(read_roma0) { return INTV_ROM16_READ(offset + 0xa000); }
+ virtual DECLARE_READ16_MEMBER(read_romb0) { return INTV_ROM16_READ(offset + 0xb000); }
+ virtual DECLARE_READ16_MEMBER(read_romc0) { return INTV_ROM16_READ(offset + 0xc000); }
+ virtual DECLARE_READ16_MEMBER(read_romd0) { return INTV_ROM16_READ(offset + 0xd000); }
+ virtual DECLARE_READ16_MEMBER(read_rome0) { return INTV_ROM16_READ(offset + 0xe000); }
+ virtual DECLARE_READ16_MEMBER(read_romf0) { return INTV_ROM16_READ(offset + 0xf000); }
+
+ // device-level overrides
+ virtual void device_start() {}
+ virtual void device_reset() {}
+};
+
+// ======================> intv_ram_device
+
+class intv_ram_device : public intv_rom_device
+{
+public:
+ // construction/destruction
+ intv_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read_ram) { return (int)m_ram[offset & (m_ram.count() - 1)]; }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) { m_ram[offset & (m_ram.count() - 1)] = data & 0xff; }
+};
+
+// ======================> intv_gfact_device
+
+class intv_gfact_device : public intv_rom_device
+{
+public:
+ // construction/destruction
+ intv_gfact_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read_ram) { return (int)m_ram[offset & (m_ram.count() - 1)]; }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) { m_ram[offset & (m_ram.count() - 1)] = data & 0xff; }
+};
+
+// ======================> intv_wsmlb_device
+
+class intv_wsmlb_device : public intv_rom_device
+{
+public:
+ // construction/destruction
+ intv_wsmlb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+
+// device type definition
+extern const device_type INTV_ROM_STD;
+extern const device_type INTV_ROM_RAM;
+extern const device_type INTV_ROM_GFACT;
+extern const device_type INTV_ROM_WSMLB;
+
+#endif
diff --git a/src/emu/bus/intv/slot.c b/src/emu/bus/intv/slot.c
new file mode 100644
index 00000000000..df50465b1c0
--- /dev/null
+++ b/src/emu/bus/intv/slot.c
@@ -0,0 +1,572 @@
+/***********************************************************************************************************
+
+ Mattel Intellivision cart emulation
+ (through slot devices)
+
+
+ This is a strange beast, because INTV carts had potentially access to
+ a *LOT* of memory ranges!
+ Quoting Joe Zbiciak's documentation for his emu (jzIntv):
+
+
+ The Intellivision leaves many addresses available to cartridges. However,
+ several address ranges come with caveats, such as interactions with other
+ devices in the system, or incompatibilities with various peripherals.
+
+ Below is a summary.
+
+ ADDRESSES NOTES
+ -------------- --------------------------------------------------------------
+ $0400 - $04FF RAM/ROM ok on all but Intellivision 2.
+ $0500 - $06FF RAM/ROM ok.
+ $0700 - $0CFF RAM/ROM ok if no Intellivoice.
+ $0D00 - $0FFF RAM/ROM ok.
+ $2000 - $2FFF RAM/ROM ok if no ECS.
+ $4000 - $47FF RAM/ROM ok if no ECS.
+ $4800 ROM ok. RAM ok only if boot ROM at $7000.
+ $4801 - $4FFF RAM/ROM ok.
+ $5000 - $5014 ROM ok. RAM ok only if boot ROM at $7000 or $4800.
+ $5015 - $6FFF RAM/ROM ok.
+ $7000 ROM ok if no ECS. RAM at $7000 confuses EXEC boot sequence.
+ $7001 - $77FF RAM/ROM ok if no ECS.
+ $7800 - $7FFF ROM ok if no ECS. Do not map RAM here due to GRAM alias.
+ $8000 - $8FFF RAM/ROM ok. Avoid STIC alias at $8000 - $803F.
+ $9000 - $B7FF RAM/ROM ok.
+ $B800 - $BFFF ROM ok. Do not map RAM here due to GRAM alias.
+ $C000 - $CFFF RAM/ROM ok. Avoid STIC alias at $C000 - $C03F.
+ $D000 - $DFFF RAM/ROM ok.
+ $E000 - $EFFF RAM/ROM ok if no ECS.
+ $F000 - $F7FF RAM/ROM ok.
+ $F800 - $FFFF ROM ok. Do not map RAM here due to GRAM alias.
+
+
+ We handle this, by always creating a 0x10000 wide ROM region to load the
+ cart image and exposing the following (long list of) read handlers:
+ read_rom04
+ read_rom20
+ read_rom40
+ read_rom48
+ read_rom50
+ read_rom60
+ read_rom70
+ read_rom80
+ read_rom90
+ read_roma0
+ read_romb0
+ read_romc0
+ read_romd0
+ read_rome0
+ read_romf0
+ Each pcb types will then use the correct ones for its wiring setup.
+
+ The BIN+CFG format introduced by INTVPC emulator includes metadata about where to
+ load ROM into memory in the CFG file, but we don't support it (because we don't parse
+ the CFG at all) and we rely instead on the intv.hsi metadata for fullpath loading of
+ these.
+ Alternatively, we support the .ROM format used by jzIntv.
+
+
+ TODO:
+ - Convert also the keyboard component to be a passthru slot device
+ - Merge some of the ROM accessor above, once it is clear which ones can be merged
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "slot.h"
+#include "hashfile.h"
+
+#define INTELLIVOICE_MASK 0x02
+#define ECS_MASK 0x01
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type INTV_CART_SLOT = &device_creator<intv_cart_slot_device>;
+
+//**************************************************************************
+// Intellivision Cartridges Interface
+//**************************************************************************
+
+//-------------------------------------------------
+// device_intv_cart_interface - constructor
+//-------------------------------------------------
+
+device_intv_cart_interface::device_intv_cart_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_rom_size(0)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_intv_cart_interface - destructor
+//-------------------------------------------------
+
+device_intv_cart_interface::~device_intv_cart_interface()
+{
+}
+
+//-------------------------------------------------
+// rom_alloc - alloc the space for the cart
+//-------------------------------------------------
+
+void device_intv_cart_interface::rom_alloc(UINT32 size, const char *tag)
+{
+ if (m_rom == NULL)
+ {
+ astring tempstring(tag);
+ tempstring.cat(INTVSLOT_ROM_REGION_TAG);
+ m_rom = device().machine().memory().region_alloc(tempstring, size, 1, ENDIANNESS_LITTLE)->base();
+ memset(m_rom, 0xff, size);
+ m_rom_size = size;
+ }
+}
+
+
+//-------------------------------------------------
+// ram_alloc - alloc the space for the ram
+//-------------------------------------------------
+
+void device_intv_cart_interface::ram_alloc(UINT32 size)
+{
+ m_ram.resize(size);
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// intv_cart_slot_device - constructor
+//-------------------------------------------------
+intv_cart_slot_device::intv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, INTV_CART_SLOT, "Intellivision Cartridge Slot", tag, owner, clock, "intv_cart_slot", __FILE__),
+ device_image_interface(mconfig, *this),
+ device_slot_interface(mconfig, *this),
+ m_type(INTV_STD)
+{
+}
+
+
+//-------------------------------------------------
+// intv_cart_slot_device - destructor
+//-------------------------------------------------
+
+intv_cart_slot_device::~intv_cart_slot_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intv_cart_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_intv_cart_interface *>(get_card_device());
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void intv_cart_slot_device::device_config_complete()
+{
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// INTV PCB
+//-------------------------------------------------
+
+struct intv_slot
+{
+ int pcb_id;
+ const char *slot_option;
+};
+
+// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
+static const intv_slot slot_list[] =
+{
+ { INTV_STD, "intv_rom" },
+ { INTV_RAM, "intv_ram" },
+ { INTV_GFACT, "intv_gfact" },
+ { INTV_WSMLB, "intv_wsmlb" },
+ { INTV_VOICE, "intv_voice" },
+ { INTV_ECS, "intv_ecs" },
+ { INTV_KEYCOMP, "intv_keycomp" }
+};
+
+static int intv_get_pcb_id(const char *slot)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (!core_stricmp(slot_list[i].slot_option, slot))
+ return slot_list[i].pcb_id;
+ }
+
+ return 0;
+}
+
+#if 1
+static const char *intv_get_slot(int type)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (slot_list[i].pcb_id == type)
+ return slot_list[i].slot_option;
+ }
+
+ return "intv_rom";
+}
+#endif
+
+/*-------------------------------------------------
+ call load
+ -------------------------------------------------*/
+
+int intv_cart_slot_device::load_fullpath()
+{
+ UINT8 temp;
+ UINT8 num_segments;
+ UINT8 start_seg;
+ UINT8 end_seg;
+
+ UINT32 current_address;
+ UINT32 end_address;
+
+ UINT8 high_byte;
+ UINT8 low_byte;
+
+ UINT8 *ROM;
+ const char *file_type = filetype();
+
+ /* if it is in .rom format, we enter here */
+ if (!core_stricmp (file_type, "rom"))
+ {
+ // header
+ fread(&temp, 1);
+ if (temp != 0xa8)
+ return IMAGE_INIT_FAIL;
+
+ fread(&num_segments, 1);
+
+ fread(&temp, 1);
+ if (temp != (num_segments ^ 0xff))
+ return IMAGE_INIT_FAIL;
+
+ m_cart->rom_alloc(0x10000, tag());
+ ROM = (UINT8 *)m_cart->get_rom_base();
+
+ for (int i = 0; i < num_segments; i++)
+ {
+ fread(&start_seg, 1);
+ current_address = start_seg * 0x100;
+
+ fread(&end_seg, 1);
+ end_address = end_seg * 0x100 + 0xff;
+
+ while (current_address <= end_address)
+ {
+ fread(&low_byte, 1);
+ ROM[(current_address << 1) + 1] = low_byte;
+ fread(&high_byte, 1);
+ ROM[current_address << 1] = high_byte;
+ current_address++;
+ }
+
+ // Here we should calculate and compare the CRC16...
+ fread(&temp, 1);
+ fread(&temp, 1);
+ }
+
+ // Access tables and fine address restriction tables are not supported ATM
+ for (int i = 0; i < (16 + 32 + 2); i++)
+ {
+ fread(&temp, 1);
+ }
+ return IMAGE_INIT_PASS;
+ }
+ /* otherwise, we load it as a .bin file, using extrainfo from intv.hsi in place of .cfg */
+ else
+ {
+ // This code is a blatant hack, due to impossibility to load a separate .cfg file in MESS.
+ // It shall be eventually replaced by the .xml loading
+
+ // extrainfo format
+ // 1. mapper number (to deal with bankswitch). no bankswitch is mapper 0 (most games).
+ // 2.->5. current images have at most 4 chunks of data. we store here block size and location to load
+ // (value & 0xf0) >> 4 is the location / 0x1000
+ // (value & 0x0f) is the size / 0x800
+ // 6. some images have a ram chunk. as above we store location and size in 8 bits
+ // 7. extra = 1 ECS, 2 Intellivoice
+ int start, size;
+ int mapper, rom[5], ram, extra;
+ astring extrainfo;
+
+ m_cart->rom_alloc(0x10000, tag());
+ ROM = (UINT8 *)m_cart->get_rom_base();
+
+ if (!hashfile_extrainfo(*this, extrainfo))
+ {
+ // If no extrainfo, we assume a single 0x2000 chunk at 0x5000
+ for (int i = 0; i < 0x2000; i++ )
+ {
+ fread(&low_byte, 1);
+ ROM[((0x5000 + i) << 1) + 1] = low_byte;
+ fread(&high_byte, 1);
+ ROM[(0x5000 + i) << 1] = high_byte;
+ }
+ }
+ else
+ {
+ sscanf(extrainfo.cstr() ,"%d %d %d %d %d %d %d", &mapper, &rom[0], &rom[1], &rom[2],
+ &rom[3], &ram, &extra);
+ //printf("extrainfo: %d %d %d %d %d %d %d \n", mapper, rom[0], rom[1], rom[2], rom[3], ram, extra);
+
+ if (mapper)
+ logerror("Bankswitch not yet implemented!\n");
+
+ if (ram)
+ {
+ start = ((ram & 0xf0) >> 4) * 0x1000;
+ size = (ram & 0x0f) * 0x800;
+
+ if (start == 0xd000 && size == 0x800)
+ {
+ m_type = INTV_RAM;
+ m_cart->ram_alloc(0x800);
+ }
+ else if (start == 0x8800 && size == 0x800)
+ {
+ m_type = INTV_GFACT;
+ m_cart->ram_alloc(0x800);
+ }
+ else
+ printf("Unrecognized RAM setup [Start 0x%X - End 0x%X]. Please contact MESSdevs.\n", start, start + size);
+ }
+ if (extra & INTELLIVOICE_MASK)
+ {
+ printf("WARNING: This game requires emulation of the IntelliVoice module.\n");
+ }
+
+ if (extra & ECS_MASK)
+ {
+ printf("WARNING: This game requires emulation of the ECS module.\n");
+ }
+
+ for (int j = 0; j < 4; j++)
+ {
+ start = ((rom[j] & 0xf0) >> 4) * 0x1000;
+ size = (rom[j] & 0x0f) * 0x800;
+
+ // some cart has to be loaded to 0x4800, but none of the available ones goes to 0x4000.
+ // Hence, we use 0x04 << 4 in extrainfo (to reduce the stored values) and fix the value here.
+ if (start == 0x4000) start += 0x800;
+
+// logerror("step %d: %d %d \n", j, start / 0x1000, size / 0x1000);
+
+ for (int i = 0; i < size; i++)
+ {
+ fread(&low_byte, 1);
+ ROM[((start + i) << 1) + 1] = low_byte;
+ fread(&high_byte, 1);
+ ROM[(start + i) << 1] = high_byte;
+ }
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+ }
+}
+
+bool intv_cart_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ if (software_entry() == NULL)
+ return load_fullpath();
+ else
+ {
+ UINT16 offset[] = { 0x400, 0x2000, 0x4000, 0x4800, 0x5000, 0x6000, 0x7000, 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000};
+ const char* region_name[] = {"0400", "2000", "4000", "4800", "5000", "6000", "7000", "8000", "9000", "A000", "B000", "C000", "D000", "E000", "F000"};
+ const char *pcb_name = get_feature("slot");
+ bool extra_bank = false;
+
+ if (pcb_name)
+ m_type = intv_get_pcb_id(pcb_name);
+
+ // these two carts have paged roms, which does not work well with our 0x10000 rom region
+ // so if we are loading one of these, we allocate additional 0x2000 bytes for the paged bank
+ if (m_type == INTV_WSMLB)
+ extra_bank = true;
+
+ UINT32 size = 0;
+ UINT16 address = 0;
+ UINT8 *ROM, *region;
+
+ m_cart->rom_alloc(extra_bank ? 0x22000 : 0x20000, tag());
+ ROM = m_cart->get_rom_base();
+
+ for (int i = 0; i < 15; i++)
+ {
+ address = offset[i];
+ size = get_software_region_length(region_name[i]);
+ if (size)
+ {
+ region = get_software_region(region_name[i]);
+
+ for (int j = 0; j < size / 2; j++)
+ {
+ ROM[((address + j) << 1) + 1] = region[2 * j];
+ ROM[(address + j) << 1] = region[2 * j + 1];
+ }
+ }
+ }
+
+ if (m_type == INTV_RAM || m_type == INTV_GFACT || m_type == INTV_ECS)
+ m_cart->ram_alloc(get_software_region_length("ram"));
+
+ //printf("Type: %s\n", intv_get_slot(m_type));
+ return IMAGE_INIT_PASS;
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+/*-------------------------------------------------
+ call softlist load
+ -------------------------------------------------*/
+
+bool intv_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
+{
+ load_software_part_region(*this, swlist, swname, start_entry);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------
+ get default card software
+ -------------------------------------------------*/
+
+void intv_cart_slot_device::get_default_card_software(astring &result)
+{
+ if (open_image_file(mconfig().options()))
+ {
+ const char *slot_string = "intv_rom";
+ UINT32 len = core_fsize(m_file);
+ dynamic_buffer rom(len);
+ int type = INTV_STD;
+
+ core_fread(m_file, rom, len);
+
+ if (rom[0] == 0xa8 && (rom[1] == rom[2] ^ 0xff ))
+ {
+ // it's .ROM file, so that we don't have currently any way to distinguish RAM-equipped carts
+ }
+ else
+ {
+ // assume it's .BIN and try to use .hsi file to determine type (just RAM)
+ int start;
+ int mapper, rom[5], ram, extra;
+ astring extrainfo;
+
+ if (hashfile_extrainfo(*this, extrainfo))
+ {
+ sscanf(extrainfo.cstr() ,"%d %d %d %d %d %d %d", &mapper, &rom[0], &rom[1], &rom[2],
+ &rom[3], &ram, &extra);
+
+ if (ram)
+ {
+ start = ((ram & 0xf0) >> 4) * 0x1000;
+ if (start == 0xd000)
+ type = INTV_RAM;
+ if (start == 0x8800)
+ type = INTV_GFACT;
+ }
+ }
+
+ }
+
+ slot_string = intv_get_slot(type);
+
+ //printf("type: %s\n", slot_string);
+ clear();
+
+ result.cpy(slot_string);
+ return;
+ }
+ software_get_default_slot(result, "intv_rom");
+}
+
+/*-------------------------------------------------
+ read_ay
+ -------------------------------------------------*/
+
+READ16_MEMBER(intv_cart_slot_device::read_ay)
+{
+ if (m_cart)
+ return m_cart->read_ay(space, offset, mem_mask);
+ else
+ return 0xffff;
+}
+
+/*-------------------------------------------------
+ write_ay
+ -------------------------------------------------*/
+
+WRITE16_MEMBER(intv_cart_slot_device::write_ay)
+{
+ if (m_cart)
+ m_cart->write_ay(space, offset, data, mem_mask);
+}
+
+/*-------------------------------------------------
+ read_speech
+ -------------------------------------------------*/
+
+READ16_MEMBER(intv_cart_slot_device::read_speech)
+{
+ if (m_cart)
+ return m_cart->read_speech(space, offset, mem_mask);
+ else
+ return 0xffff;
+}
+
+/*-------------------------------------------------
+ write_speech
+ -------------------------------------------------*/
+
+WRITE16_MEMBER(intv_cart_slot_device::write_speech)
+{
+ if (m_cart)
+ m_cart->write_speech(space, offset, data, mem_mask);
+}
+
+
+
+#include "bus/intv/rom.h"
+#include "bus/intv/ecs.h"
+//#include "bus/intv/keycomp.h"
+#include "bus/intv/voice.h"
+
+SLOT_INTERFACE_START(intv_cart)
+ SLOT_INTERFACE_INTERNAL("intv_rom", INTV_ROM_STD)
+ SLOT_INTERFACE_INTERNAL("intv_ram", INTV_ROM_RAM)
+ SLOT_INTERFACE_INTERNAL("intv_gfact", INTV_ROM_GFACT)
+ SLOT_INTERFACE_INTERNAL("intv_wsmlb", INTV_ROM_WSMLB)
+ SLOT_INTERFACE_INTERNAL("intv_voice", INTV_ROM_VOICE)
+ SLOT_INTERFACE_INTERNAL("intv_ecs", INTV_ROM_ECS)
+// SLOT_INTERFACE_INTERNAL("intv_keycomp", INTV_ROM_KEYCOMP)
+SLOT_INTERFACE_END
+
diff --git a/src/emu/bus/intv/slot.h b/src/emu/bus/intv/slot.h
new file mode 100644
index 00000000000..e14243f190f
--- /dev/null
+++ b/src/emu/bus/intv/slot.h
@@ -0,0 +1,184 @@
+#ifndef __INTV_SLOT_H
+#define __INTV_SLOT_H
+
+/***************************************************************************
+ TYPE DEFINITIONS
+ ***************************************************************************/
+
+
+/* PCB */
+enum
+{
+ INTV_STD = 0,
+ INTV_RAM,
+ INTV_GFACT, // has RAM too but at diff offset
+ INTV_WSMLB,
+ INTV_VOICE,
+ INTV_ECS,
+ INTV_KEYCOMP
+};
+
+
+#define INTV_ROM16_READ(addr) \
+ (UINT16) (m_rom[(addr) << 1] | (m_rom[((addr) << 1) + 1] << 8))
+
+
+// ======================> device_intv_cart_interface
+
+class device_intv_cart_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_intv_cart_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_intv_cart_interface();
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read_rom04) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom20) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom40) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom48) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom50) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom60) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom70) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom80) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom90) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_roma0) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romb0) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romc0) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romd0) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rome0) { return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romf0) { return 0xffff; }
+
+ virtual DECLARE_READ16_MEMBER(read_ram) { return 0xffff; }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) {}
+
+ // Used by IntelliVoice & ECS
+ virtual DECLARE_READ16_MEMBER(read_ay) { return 0xffff; }
+ virtual DECLARE_WRITE16_MEMBER(write_ay) {}
+ virtual DECLARE_READ16_MEMBER(read_speech) { return 0xffff; }
+ virtual DECLARE_WRITE16_MEMBER(write_speech) {}
+ virtual DECLARE_WRITE16_MEMBER(write_d0) {}
+ virtual DECLARE_WRITE16_MEMBER(write_88) {}
+ virtual DECLARE_WRITE16_MEMBER(write_rom20) {}
+ virtual DECLARE_WRITE16_MEMBER(write_rom70) {}
+ virtual DECLARE_WRITE16_MEMBER(write_rome0) {}
+ virtual DECLARE_WRITE16_MEMBER(write_romf0) {}
+
+ void rom_alloc(UINT32 size, const char *tag);
+ void ram_alloc(UINT32 size);
+ UINT8* get_rom_base() { return m_rom; }
+ UINT8* get_ram_base() { return m_ram; }
+ UINT32 get_rom_size() { return m_rom_size; }
+ UINT32 get_ram_size() { return m_ram.count(); }
+
+ void save_ram() { device().save_item(NAME(m_ram)); }
+ virtual void late_subslot_setup() {}
+
+protected:
+ // internal state
+ UINT8 *m_rom;
+ UINT32 m_rom_size;
+ dynamic_buffer m_ram;
+};
+
+
+// ======================> intv_cart_slot_device
+
+class intv_cart_slot_device : public device_t,
+ public device_image_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ intv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~intv_cart_slot_device();
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_config_complete();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual void call_unload() {}
+ virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
+
+ int get_type() { return m_type; }
+ int load_fullpath();
+
+ void save_ram() { if (m_cart && m_cart->get_ram_size()) m_cart->save_ram(); }
+
+ virtual iodevice_t image_type() const { return IO_CARTSLOT; }
+ virtual bool is_readable() const { return 1; }
+ virtual bool is_writeable() const { return 0; }
+ virtual bool is_creatable() const { return 0; }
+ virtual bool must_be_loaded() const { return 0; }
+ virtual bool is_reset_on_load() const { return 1; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+ virtual const char *image_interface() const { return "intv_cart"; }
+ virtual const char *file_extensions() const { return "bin,int,rom,itv"; }
+
+ // slot interface overrides
+ virtual void get_default_card_software(astring &result);
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read_rom04) { if (m_cart) return m_cart->read_rom04(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom20) { if (m_cart) return m_cart->read_rom20(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom40) { if (m_cart) return m_cart->read_rom40(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom48) { if (m_cart) return m_cart->read_rom48(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom50) { if (m_cart) return m_cart->read_rom50(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom60) { if (m_cart) return m_cart->read_rom60(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom70) { if (m_cart) return m_cart->read_rom70(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom80) { if (m_cart) return m_cart->read_rom80(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rom90) { if (m_cart) return m_cart->read_rom90(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_roma0) { if (m_cart) return m_cart->read_roma0(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romb0) { if (m_cart) return m_cart->read_romb0(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romc0) { if (m_cart) return m_cart->read_romc0(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romd0) { if (m_cart) return m_cart->read_romd0(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_rome0) { if (m_cart) return m_cart->read_rome0(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_READ16_MEMBER(read_romf0) { if (m_cart) return m_cart->read_romf0(space, offset, mem_mask); else return 0xffff; }
+
+ virtual DECLARE_READ16_MEMBER(read_ay);
+ virtual DECLARE_WRITE16_MEMBER(write_ay);
+ virtual DECLARE_READ16_MEMBER(read_speech);
+ virtual DECLARE_WRITE16_MEMBER(write_speech);
+ virtual DECLARE_READ16_MEMBER(read_ram) { if (m_cart) return m_cart->read_ram(space, offset, mem_mask); else return 0xffff; }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) { if (m_cart) m_cart->write_ram(space, offset, data, mem_mask); }
+
+ virtual void late_subslot_setup() { if (m_cart) return m_cart->late_subslot_setup(); }
+
+ // these RAM accessors are needed to deal with IntelliVoice and ECS mounting RAM-equipped carts
+ virtual DECLARE_WRITE16_MEMBER(write_d0) { if (m_cart) m_cart->write_d0(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_88) { if (m_cart) m_cart->write_88(space, offset, data, mem_mask); }
+
+ // ECS paged roms need these
+ virtual DECLARE_WRITE16_MEMBER(write_rom20) { if (m_cart) m_cart->write_rom20(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_rom70) { if (m_cart) m_cart->write_rom70(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_rome0) { if (m_cart) m_cart->write_rome0(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_romf0) { if (m_cart) m_cart->write_romf0(space, offset, data, mem_mask); }
+
+//protected:
+
+ int m_type;
+ device_intv_cart_interface* m_cart;
+};
+
+
+
+// device type definition
+extern const device_type INTV_CART_SLOT;
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+ ***************************************************************************/
+
+#define INTVSLOT_ROM_REGION_TAG ":cart:rom"
+
+#define MCFG_INTV_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
+ MCFG_DEVICE_ADD(_tag, INTV_CART_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+
+
+SLOT_INTERFACE_EXTERN(intv_cart);
+
+#endif
diff --git a/src/emu/bus/intv/voice.c b/src/emu/bus/intv/voice.c
new file mode 100644
index 00000000000..ac5bc8cdc5b
--- /dev/null
+++ b/src/emu/bus/intv/voice.c
@@ -0,0 +1,122 @@
+/***********************************************************************************************************
+
+
+ Mattel Intellivoice cart emulation
+
+ TODO:
+ - speech ROM shall be loaded from softlist
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "voice.h"
+
+
+//-------------------------------------------------
+// intv_voice_device - constructor
+//-------------------------------------------------
+
+const device_type INTV_ROM_VOICE = &device_creator<intv_voice_device>;
+
+intv_voice_device::intv_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : intv_rom_device(mconfig, INTV_ROM_VOICE, "Intellivision Intellivoice Expansion", tag, owner, clock, "intv_voice", __FILE__),
+ m_speech(*this, "sp0256_speech"),
+ m_subslot(*this, "subslot"),
+ m_ramd0_enabled(false),
+ m_ram88_enabled(false)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void intv_voice_device::device_start()
+{
+}
+
+void intv_voice_device::late_subslot_setup()
+{
+ switch (m_subslot->get_type())
+ {
+ case INTV_RAM:
+ m_ramd0_enabled = true;
+ break;
+ case INTV_GFACT:
+ m_ram88_enabled = true;
+ break;
+ case INTV_VOICE:
+ printf("WARNING: You cannot connect serially multiple IntelliVoice units.\n");
+ printf("WARNING: Emulation will likely misbehave.\n");
+ break;
+ case INTV_ECS:
+ printf("WARNING: You cannot connect ECS to IntelliVoice in this manner.\n");
+ printf("WARNING: Emulation will likely misbehave.\n");
+ break;
+ case INTV_KEYCOMP:
+ printf("WARNING: You cannot connect the Keyboard component to the IntelliVoice unit.\n");
+ printf("WARNING: Emulation will likely misbehave.\n");
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( intellivoice )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( intellivoice )
+ MCFG_SPEAKER_STANDARD_MONO("mono_voice")
+
+ MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
+ /* The Intellivoice uses a speaker with its own volume control so the relative volumes to use are subjective */
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono_voice", 1.00)
+
+ MCFG_INTV_CARTRIDGE_ADD("subslot", intv_cart, NULL)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor intv_voice_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( intellivoice );
+}
+
+
+ROM_START( intellivoice )
+ ROM_REGION( 0x10000, "sp0256_speech", 0 )
+ /* SP0256-012 Speech chip w/2KiB mask rom */
+ ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) )
+ROM_END
+
+const rom_entry *intv_voice_device::device_rom_region() const
+{
+ return ROM_NAME( intellivoice );
+}
+
+/*-------------------------------------------------
+ read_audio
+ -------------------------------------------------*/
+
+READ16_MEMBER(intv_voice_device::read_speech)
+{
+ if (ACCESSING_BITS_0_7)
+ return m_speech->spb640_r(space, offset, mem_mask);
+ else
+ return 0xff;
+}
+
+/*-------------------------------------------------
+ write_audio
+ -------------------------------------------------*/
+
+WRITE16_MEMBER(intv_voice_device::write_speech)
+{
+ if (ACCESSING_BITS_0_7)
+ return m_speech->spb640_w(space, offset, data, mem_mask);
+}
diff --git a/src/emu/bus/intv/voice.h b/src/emu/bus/intv/voice.h
new file mode 100644
index 00000000000..9ba16aef358
--- /dev/null
+++ b/src/emu/bus/intv/voice.h
@@ -0,0 +1,76 @@
+#ifndef __INTV_VOICE_H
+#define __INTV_VOICE_H
+
+#include "slot.h"
+#include "rom.h"
+#include "sound/sp0256.h"
+
+
+// ======================> intv_voice_device
+
+class intv_voice_device : public intv_rom_device
+{
+public:
+ // construction/destruction
+ intv_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual const rom_entry *device_rom_region() const;
+
+ // reading and writing
+ // actual IntelliVoice access
+ virtual DECLARE_READ16_MEMBER(read_speech);
+ virtual DECLARE_WRITE16_MEMBER(write_speech);
+
+ // passthru access
+ virtual DECLARE_READ16_MEMBER(read_rom04) { return m_subslot->read_rom04(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom20) { return m_subslot->read_rom20(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom40) { return m_subslot->read_rom40(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom48) { return m_subslot->read_rom48(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom50) { return m_subslot->read_rom50(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom60) { return m_subslot->read_rom60(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom70) { return m_subslot->read_rom70(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_rom80)
+ {
+ if (m_ram88_enabled && offset >= 0x800)
+ return m_subslot->read_ram(space, offset & 0x7ff, mem_mask);
+ else
+ return m_subslot->read_rom80(space, offset, mem_mask);
+ }
+ virtual DECLARE_READ16_MEMBER(read_rom90) { return m_subslot->read_rom90(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_roma0) { return m_subslot->read_roma0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romb0) { return m_subslot->read_romb0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romc0) { return m_subslot->read_romc0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romd0)
+ {
+ if (m_ramd0_enabled && offset < 0x800)
+ return m_subslot->read_ram(space, offset, mem_mask);
+ else
+ return m_subslot->read_romd0(space, offset, mem_mask);
+ }
+ virtual DECLARE_READ16_MEMBER(read_rome0) { return m_subslot->read_rome0(space, offset, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_romf0) { return m_subslot->read_romf0(space, offset, mem_mask); }
+
+ // RAM passthru write
+ virtual DECLARE_WRITE16_MEMBER(write_88) { if (m_ram88_enabled) m_subslot->write_ram(space, offset, data, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_d0) { if (m_ramd0_enabled) m_subslot->write_ram(space, offset, data, mem_mask); }
+ virtual DECLARE_READ16_MEMBER(read_ram) { return m_subslot->read_ram(space, offset, mem_mask); }
+ virtual DECLARE_WRITE16_MEMBER(write_ram) { m_subslot->write_ram(space, offset, data, mem_mask); }
+
+ virtual void late_subslot_setup();
+
+private:
+ required_device<sp0256_device> m_speech;
+ required_device<intv_cart_slot_device> m_subslot;
+ bool m_ramd0_enabled, m_ram88_enabled;
+};
+
+
+
+
+// device type definition
+extern const device_type INTV_ROM_VOICE;
+
+#endif
diff --git a/src/mess/drivers/intv.c b/src/mess/drivers/intv.c
index 0e62702dc71..905f99787a1 100644
--- a/src/mess/drivers/intv.c
+++ b/src/mess/drivers/intv.c
@@ -52,7 +52,6 @@ RO-3-9506 = 8KiB (4Kiw) self decoding address mask rom with external address dec
#include "cpu/m6502/m6502.h"
#include "cpu/cp1610/cp1610.h"
#include "includes/intv.h"
-#include "imagedev/cartslot.h"
#include "sound/ay8910.h"
#ifndef VERBOSE
@@ -136,7 +135,8 @@ GFXDECODE_END
static INPUT_PORTS_START( intv )
- PORT_START("KEYPAD1") /* Left Player Controller Starts Here */
+ /* 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)
@@ -178,7 +178,8 @@ static INPUT_PORTS_START( intv )
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)
- PORT_START("KEYPAD2") /* Right Player Controller Starts Here */
+ /* 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")
@@ -229,286 +230,6 @@ static INPUT_PORTS_START( intv )
PORT_CONFSETTING( 0x02, "Analog" )
INPUT_PORTS_END
-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("ECS_ROW0")
- 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("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CONDITION("ECS_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("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW1")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW2")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('-') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW3")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW4")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW5")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CONDITION("ECS_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("ECS_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("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('=') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CONDITION("ECS_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("ECS_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("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x02)
-
- PORT_START("ECS_ROW6")
- 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("ECS_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("ECS_SYNTH_ROW0")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW1")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW2")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW3")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW4")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW5")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x01)
-
- PORT_START("ECS_SYNTH_ROW6")
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6") PORT_CONDITION("ECS_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("KEYPAD3")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/1") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/6") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/7") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/8") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/9") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/Clear") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/0") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/Enter") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3/Upper") PORT_PLAYER(3) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3/Lower-Left") PORT_PLAYER(3) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P3/Lower-Right") PORT_PLAYER(3) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC3")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P3/Up") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P3/Right") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P3/Down") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P3/Left") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-
- PORT_START("DISCX3")
- 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("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-
- PORT_START("DISCY3")
- 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("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-
-// Second ECS Hand Controller
- PORT_START("KEYPAD4")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/1") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/2") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/3") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/4") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/5") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/6") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/7") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/8") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/9") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/Clear") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/0") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/Enter") PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4/Upper") PORT_PLAYER(4) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4/Lower-Left") PORT_PLAYER(4) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P4/Lower-Right") PORT_PLAYER(4) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
-
- PORT_START("DISC4")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P4/Up") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P4/Right") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P4/Down") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P4/Left") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
- PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-
- PORT_START("DISCX4")
- 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(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-
- PORT_START("DISCY4")
- 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(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("ECS_CNTRLSEL",0x0f,EQUALS,0x00)
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( intvecs )
- PORT_INCLUDE( intv )
- PORT_INCLUDE( intv_ecs_pads )
- PORT_INCLUDE( intv_ecs_synth )
- PORT_INCLUDE( intv_ecs_kbd )
-
- PORT_MODIFY("OPTIONS")
- PORT_CONFNAME( 0x04, 0x00, "ECS_P3 Disc" )
- PORT_CONFSETTING( 0x00, "Digital" )
- PORT_CONFSETTING( 0x04, "Analog" )
- PORT_CONFNAME( 0x08, 0x00, "ECS_P4 Disc" )
- PORT_CONFSETTING( 0x00, "Digital" )
- PORT_CONFSETTING( 0x08, "Analog" )
-
- PORT_START("ECS_CNTRLSEL")
- PORT_CONFNAME( 0x0F, 0x02, "ECS Controller")
- PORT_CONFSETTING( 0x00, "Gamepads" )
- PORT_CONFSETTING( 0x01, "Piano" )
- PORT_CONFSETTING( 0x02, "Keyboard" )
-INPUT_PORTS_END
/*
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
@@ -653,87 +374,145 @@ static INPUT_PORTS_START( intvkbd )
PORT_INCLUDE( intv )
INPUT_PORTS_END
-static ADDRESS_MAP_START(intv_mem, AS_PROGRAM, 16, intv_state)
- AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
- AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
- AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
- AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
- AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
- AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000<<1) /* Exec ROM, 10-bits wide */
- AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) /* GROM, 8-bits wide */
- AM_RANGE(0x3800, 0x39ff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM, 8-bits wide */
- AM_RANGE(0x3a00, 0x3bff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM Alias, 8-bits wide */
- AM_RANGE(0x4800, 0x7fff) AM_ROM AM_REGION("maincpu", 0x4800<<1)
- AM_RANGE(0x9000, 0xBfff) AM_ROM AM_REGION("maincpu", 0x9000<<1)
- AM_RANGE(0xC000, 0xCfff) AM_ROM AM_REGION("maincpu", 0xC000<<1)
- AM_RANGE(0xD000, 0xDfff) AM_ROM AM_REGION("maincpu", 0xD000<<1)
- AM_RANGE(0xE000, 0xFfff) AM_ROM AM_REGION("maincpu", 0xE000<<1)
+static ADDRESS_MAP_START( intv_mem, AS_PROGRAM, 16, intv_state )
+ AM_RANGE(0x0000, 0x003f) AM_READWRITE(intv_stic_r, intv_stic_w)
+ AM_RANGE(0x0100, 0x01ef) AM_READWRITE(intv_ram8_r, intv_ram8_w)
+ AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914", ay8914_device, read, write, 0x00ff)
+ AM_RANGE(0x0200, 0x035f) AM_READWRITE(intv_ram16_r, intv_ram16_w)
+ AM_RANGE(0x0400, 0x04ff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom04)
+ AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000 << 1) // Exec ROM, 10-bits wide
+ AM_RANGE(0x2000, 0x2fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom20)
+ AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) // GROM, 8-bits wide
+ AM_RANGE(0x3800, 0x39ff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM, 8-bits wide
+ AM_RANGE(0x3a00, 0x3bff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM Alias, 8-bits wide
+ AM_RANGE(0x4000, 0x47ff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom40)
+ AM_RANGE(0x4800, 0x4fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom48)
+ AM_RANGE(0x5000, 0x5fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom50)
+ AM_RANGE(0x6000, 0x6fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom60)
+ AM_RANGE(0x7000, 0x7fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom70)
+ AM_RANGE(0x8000, 0x8fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom80)
+ AM_RANGE(0x9000, 0x9fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom90)
+ AM_RANGE(0xa000, 0xafff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_roma0)
+ AM_RANGE(0xb000, 0xbfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romb0)
+ AM_RANGE(0xc000, 0xcfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romc0)
+ AM_RANGE(0xd000, 0xdfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romd0)
+ AM_RANGE(0xe000, 0xefff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rome0)
+ AM_RANGE(0xf000, 0xffff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romf0)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( intv2_mem , AS_PROGRAM, 16, intv_state)
- AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
- AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
- AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
- AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
- AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
- AM_RANGE(0x0400, 0x04ff) AM_ROM AM_REGION("maincpu", 0x400<<1) /* Exec ROM, 10-bits wide */
- AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000<<1) /* Exec ROM, 10-bits wide */
- AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) /* GROM, 8-bits wide */
- AM_RANGE(0x3800, 0x39ff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM, 8-bits wide */
- AM_RANGE(0x3a00, 0x3bff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM Alias, 8-bits wide */
- AM_RANGE(0x4800, 0x7fff) AM_ROM AM_REGION("maincpu", 0x4800<<1)
- AM_RANGE(0x9000, 0xBfff) AM_ROM AM_REGION("maincpu", 0x9000<<1)
- AM_RANGE(0xC000, 0xCfff) AM_ROM AM_REGION("maincpu", 0xC000<<1)
- AM_RANGE(0xD000, 0xDfff) AM_ROM AM_REGION("maincpu", 0xD000<<1)
- AM_RANGE(0xE000, 0xFfff) AM_ROM AM_REGION("maincpu", 0xE000<<1)
+static ADDRESS_MAP_START( intvoice_mem, AS_PROGRAM, 16, intv_state )
+ AM_RANGE(0x0000, 0x003f) AM_READWRITE(intv_stic_r, intv_stic_w)
+ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("voice", intv_voice_device, read_speech, write_speech) // Intellivoice
+ AM_RANGE(0x0100, 0x01ef) AM_READWRITE(intv_ram8_r, intv_ram8_w)
+ AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914", ay8914_device, read, write, 0x00ff)
+ AM_RANGE(0x0200, 0x035f) AM_READWRITE(intv_ram16_r, intv_ram16_w)
+ AM_RANGE(0x0400, 0x04ff) AM_DEVREAD("voice", intv_voice_device, read_rom04)
+ AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000 << 1) // Exec ROM, 10-bits wide
+ AM_RANGE(0x2000, 0x2fff) AM_DEVREAD("voice", intv_voice_device, read_rom20)
+ AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) // GROM, 8-bits wide
+ AM_RANGE(0x3800, 0x39ff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM, 8-bits wide
+ AM_RANGE(0x3a00, 0x3bff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM Alias, 8-bits wide
+ AM_RANGE(0x4000, 0x47ff) AM_DEVREAD("voice", intv_voice_device, read_rom40)
+ AM_RANGE(0x4800, 0x4fff) AM_DEVREAD("voice", intv_voice_device, read_rom48)
+ AM_RANGE(0x5000, 0x5fff) AM_DEVREAD("voice", intv_voice_device, read_rom50)
+ AM_RANGE(0x6000, 0x6fff) AM_DEVREAD("voice", intv_voice_device, read_rom60)
+ AM_RANGE(0x7000, 0x7fff) AM_DEVREAD("voice", intv_voice_device, read_rom70)
+ AM_RANGE(0x8000, 0x8fff) AM_DEVREAD("voice", intv_voice_device, read_rom80)
+ AM_RANGE(0x9000, 0x9fff) AM_DEVREAD("voice", intv_voice_device, read_rom90)
+ AM_RANGE(0xa000, 0xafff) AM_DEVREAD("voice", intv_voice_device, read_roma0)
+ AM_RANGE(0xb000, 0xbfff) AM_DEVREAD("voice", intv_voice_device, read_romb0)
+ AM_RANGE(0xc000, 0xcfff) AM_DEVREAD("voice", intv_voice_device, read_romc0)
+ AM_RANGE(0xd000, 0xdfff) AM_DEVREAD("voice", intv_voice_device, read_romd0)
+ AM_RANGE(0xe000, 0xefff) AM_DEVREAD("voice", intv_voice_device, read_rome0)
+ AM_RANGE(0xf000, 0xffff) AM_DEVREAD("voice", intv_voice_device, read_romf0)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( intv2_mem , AS_PROGRAM, 16, intv_state )
+ AM_RANGE(0x0000, 0x003f) AM_READWRITE(intv_stic_r, intv_stic_w)
+ AM_RANGE(0x0100, 0x01ef) AM_READWRITE(intv_ram8_r, intv_ram8_w)
+ AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914", ay8914_device, read, write, 0x00ff)
+ AM_RANGE(0x0200, 0x035f) AM_READWRITE(intv_ram16_r, intv_ram16_w)
+ AM_RANGE(0x0400, 0x04ff) AM_ROM AM_REGION("maincpu", 0x400 << 1) // Exec ROM, 10-bits wide
+ AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000 << 1) // Exec ROM, 10-bits wide
+ AM_RANGE(0x2000, 0x2fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom20)
+ AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) // GROM, 8-bits wide
+ AM_RANGE(0x3800, 0x39ff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM, 8-bits wide
+ AM_RANGE(0x3a00, 0x3bff) AM_READWRITE(intv_gram_r, intv_gram_w) // GRAM Alias, 8-bits wide
+ AM_RANGE(0x4000, 0x47ff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom40)
+ AM_RANGE(0x4800, 0x4fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom48)
+ AM_RANGE(0x5000, 0x5fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom50)
+ AM_RANGE(0x6000, 0x6fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom60)
+ AM_RANGE(0x7000, 0x7fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom70)
+ AM_RANGE(0x8000, 0x8fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom80)
+ AM_RANGE(0x9000, 0x9fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom90)
+ AM_RANGE(0xa000, 0xafff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_roma0)
+ AM_RANGE(0xb000, 0xbfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romb0)
+ AM_RANGE(0xc000, 0xcfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romc0)
+ AM_RANGE(0xd000, 0xdfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romd0)
+ AM_RANGE(0xe000, 0xefff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rome0)
+ AM_RANGE(0xf000, 0xffff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romf0)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( intvecs_mem , AS_PROGRAM, 16, intv_state)
- AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
- AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
+static ADDRESS_MAP_START( intvecs_mem , AS_PROGRAM, 16, intv_state )
+ AM_RANGE(0x0000, 0x003f) AM_READWRITE(intv_stic_r, intv_stic_w)
+ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
// AM_RANGE(0x00E0, 0x00E3) AM_READWRITE( intv_ecs_uart_r, intv_ecs_uart_w )
- AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE8("ay8914.2", ay8914_device, read, write, 0x00ff ) /* ecs psg */
- AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
- AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
- AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
+ AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_ay, write_ay) /* ecs psg */
+ AM_RANGE(0x0100, 0x01ef) AM_READWRITE(intv_ram8_r, intv_ram8_w)
+ AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914", ay8914_device, read, write, 0x00ff)
+ AM_RANGE(0x0200, 0x035f) AM_READWRITE(intv_ram16_r, intv_ram16_w)
+ AM_RANGE(0x0400, 0x04ff) AM_DEVREAD("ecs", intv_ecs_device, read_rom04)
AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000<<1) /* Exec ROM, 10-bits wide */
- AM_RANGE(0x2000, 0x2fff) AM_READ_BANK("bank1") AM_WRITE( ecs_bank1_page_select );
+ AM_RANGE(0x2000, 0x2fff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_rom20, write_rom20)
AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) /* GROM, 8-bits wide */
- AM_RANGE(0x3800, 0x39ff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM, 8-bits wide */
- AM_RANGE(0x3a00, 0x3bff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM Alias, 8-bits wide */
- AM_RANGE(0x4000, 0x47ff) AM_READWRITE( intv_ecs_ram8_r, intv_ecs_ram8_w )
- AM_RANGE(0x4800, 0x6fff) AM_ROM AM_REGION("maincpu", 0x4800<<1)
- AM_RANGE(0x7000, 0x7fff) AM_READ_BANK("bank2") AM_WRITE( ecs_bank2_page_select );
- //AM_RANGE(0x8800, 0x8fff) AM_RAM_BANK("bank5") // cart rom / game factory ram
- AM_RANGE(0x9000, 0xBfff) AM_ROM AM_REGION("maincpu", 0x9000<<1)
- AM_RANGE(0xC000, 0xCfff) AM_ROM AM_REGION("maincpu", 0xC000<<1)
- AM_RANGE(0xD000, 0xDfff) AM_ROM AM_REGION("maincpu", 0xD000<<1)
- AM_RANGE(0xE000, 0xEfff) AM_READ_BANK("bank3") AM_WRITE( ecs_bank3_page_select );
- AM_RANGE(0xF000, 0xFfff) AM_READ_BANK("bank4") AM_WRITE( wsmlb_bank_page_select ); // World Series Major League Baseball Banking
+ AM_RANGE(0x3800, 0x39ff) AM_READWRITE(intv_gram_r, intv_gram_w) /* GRAM, 8-bits wide */
+ AM_RANGE(0x3a00, 0x3bff) AM_READWRITE(intv_gram_r, intv_gram_w) /* GRAM Alias, 8-bits wide */
+ AM_RANGE(0x4000, 0x47ff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_ram, write_ram)
+ AM_RANGE(0x4800, 0x4fff) AM_DEVREAD("ecs", intv_ecs_device, read_rom48)
+ AM_RANGE(0x5000, 0x5fff) AM_DEVREAD("ecs", intv_ecs_device, read_rom50)
+ AM_RANGE(0x6000, 0x6fff) AM_DEVREAD("ecs", intv_ecs_device, read_rom60)
+ AM_RANGE(0x7000, 0x7fff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_rom70, write_rom70)
+ AM_RANGE(0x8000, 0x8fff) AM_DEVREAD("ecs", intv_ecs_device, read_rom80)
+ AM_RANGE(0x9000, 0x9fff) AM_DEVREAD("ecs", intv_ecs_device, read_rom90)
+ AM_RANGE(0xa000, 0xafff) AM_DEVREAD("ecs", intv_ecs_device, read_roma0)
+ AM_RANGE(0xb000, 0xbfff) AM_DEVREAD("ecs", intv_ecs_device, read_romb0)
+ AM_RANGE(0xc000, 0xcfff) AM_DEVREAD("ecs", intv_ecs_device, read_romc0)
+ AM_RANGE(0xd000, 0xdfff) AM_DEVREAD("ecs", intv_ecs_device, read_romd0)
+ AM_RANGE(0xe000, 0xefff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_rome0, write_rome0)
+ AM_RANGE(0xf000, 0xffff) AM_DEVREADWRITE("ecs", intv_ecs_device, read_romf0, write_romf0)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( intvkbd_mem , AS_PROGRAM, 16, intv_state)
- AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
- AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
- AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
- AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
- AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
+static ADDRESS_MAP_START( intvkbd_mem , AS_PROGRAM, 16, intv_state )
+ AM_RANGE(0x0000, 0x003f) AM_READWRITE(intv_stic_r, intv_stic_w)
+ AM_RANGE(0x0100, 0x01ef) AM_READWRITE(intv_ram8_r, intv_ram8_w)
+ AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914", ay8914_device, read, write, 0x00ff)
+ AM_RANGE(0x0200, 0x035f) AM_READWRITE(intv_ram16_r, intv_ram16_w)
+ AM_RANGE(0x0400, 0x04ff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom04)
AM_RANGE(0x1000, 0x1fff) AM_ROM AM_REGION("maincpu", 0x1000<<1) /* Exec ROM, 10-bits wide */
+ AM_RANGE(0x2000, 0x2fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom20)
AM_RANGE(0x3000, 0x37ff) AM_DEVREAD("stic", stic_device, grom_read) /* GROM, 8-bits wide */
- AM_RANGE(0x3800, 0x39ff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM, 8-bits wide */
- AM_RANGE(0x3a00, 0x3bff) AM_READWRITE( intv_gram_r, intv_gram_w ) /* GRAM Alias, 8-bits wide */
- AM_RANGE(0x4800, 0x6fff) AM_ROM /* Cartridges? */
+ AM_RANGE(0x3800, 0x39ff) AM_READWRITE(intv_gram_r, intv_gram_w) /* GRAM, 8-bits wide */
+ AM_RANGE(0x3a00, 0x3bff) AM_READWRITE(intv_gram_r, intv_gram_w) /* GRAM Alias, 8-bits wide */
+ AM_RANGE(0x4000, 0x47ff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom40)
+ AM_RANGE(0x4800, 0x4fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom48)
+ AM_RANGE(0x5000, 0x5fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom50)
+ AM_RANGE(0x6000, 0x6fff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rom60)
AM_RANGE(0x7000, 0x7fff) AM_ROM AM_REGION("maincpu", 0x7000<<1) /* Keyboard ROM */
- AM_RANGE(0x8000, 0xbfff) AM_RAM_WRITE( intvkbd_dualport16_w ) AM_SHARE("dualport_ram") /* Dual-port RAM */
+ AM_RANGE(0x8000, 0xbfff) AM_RAM_WRITE(intvkbd_dualport16_w) AM_SHARE("dualport_ram") /* Dual-port RAM */
+ AM_RANGE(0xc000, 0xcfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romc0)
+ AM_RANGE(0xd000, 0xdfff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romd0)
+ AM_RANGE(0xe000, 0xefff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_rome0)
+ AM_RANGE(0xf000, 0xffff) AM_DEVREAD("cartslot", intv_cart_slot_device, read_romf0)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( intvkbd2_mem , AS_PROGRAM, 8, intv_state)
+static ADDRESS_MAP_START( intvkbd2_mem , AS_PROGRAM, 8, intv_state )
ADDRESS_MAP_UNMAP_HIGH /* Required because of probing */
- AM_RANGE( 0x0000, 0x3fff) AM_READWRITE( intvkbd_dualport8_lsb_r, intvkbd_dualport8_lsb_w ) /* Dual-port RAM */
- AM_RANGE( 0x4000, 0x7fff) AM_READWRITE( intvkbd_dualport8_msb_r, intvkbd_dualport8_msb_w ) /* Dual-port RAM */
- AM_RANGE( 0xb7f8, 0xb7ff) AM_RAM /* ??? */
- AM_RANGE( 0xb800, 0xbfff) AM_RAM AM_SHARE("videoram") /* Text Display */
- AM_RANGE( 0xc000, 0xffff) AM_ROM
+ AM_RANGE(0x0000, 0x3fff) AM_READWRITE(intvkbd_dualport8_lsb_r, intvkbd_dualport8_lsb_w) /* Dual-port RAM */
+ AM_RANGE(0x4000, 0x7fff) AM_READWRITE(intvkbd_dualport8_msb_r, intvkbd_dualport8_msb_w) /* Dual-port RAM */
+ AM_RANGE(0xb7f8, 0xb7ff) AM_RAM /* ??? */
+ AM_RANGE(0xb800, 0xbfff) AM_RAM AM_SHARE("videoram") /* Text Display */
+ AM_RANGE(0xc000, 0xdfff) AM_ROM
+ AM_RANGE(0xe000, 0xffff) AM_READ(intvkb_iocart_r)
ADDRESS_MAP_END
void intv_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@@ -769,6 +548,7 @@ 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 */
@@ -793,22 +573,17 @@ static MACHINE_CONFIG_START( intv, intv_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
- MCFG_SOUND_ADD("ay8914.1", AY8914, XTAL_3_579545MHz/2)
+ 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_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33)
- MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
- /* The Intellivoice uses a speaker with its own volume control so the relative volumes to use are subjective */
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
-
/* cartridge */
- MCFG_CARTSLOT_ADD("cart")
- MCFG_CARTSLOT_EXTENSION_LIST("int,rom,bin,itv")
- MCFG_CARTSLOT_LOAD(intv_state,intv_cart)
- MCFG_CARTSLOT_INTERFACE("intv_cart")
+ MCFG_INTV_CARTRIDGE_ADD("cartslot", intv_cart, NULL)
+
/* software lists */
- MCFG_SOFTWARE_LIST_ADD("cart_list","intv")
+ MCFG_SOFTWARE_LIST_ADD("cart_list", "intv")
+ MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("ecs_list", "intvecs")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( intv2, intv )
@@ -816,20 +591,33 @@ static MACHINE_CONFIG_DERIVED( intv2, intv )
MCFG_CPU_PROGRAM_MAP(intv2_mem)
MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( intvoice, intv )
+ MCFG_CPU_MODIFY( "maincpu" )
+ MCFG_CPU_PROGRAM_MAP(intvoice_mem)
+
+ MCFG_DEVICE_REMOVE("cartslot")
+ MCFG_DEVICE_ADD("voice", INTV_ROM_VOICE, 0)
+MACHINE_CONFIG_END
+
static MACHINE_CONFIG_DERIVED( intvecs, intv )
MCFG_CPU_MODIFY( "maincpu" )
MCFG_CPU_PROGRAM_MAP(intvecs_mem)
- MCFG_SOFTWARE_LIST_ADD("cart_list_ecs","intvecs")
- MCFG_SOUND_ADD("ay8914.2", AY8914, XTAL_3_579545MHz/2)
- MCFG_AY8910_PORT_A_READ_CB(READ8(intv_state, intv_ecs_porta_r))
- MCFG_AY8910_PORT_B_READ_CB(READ8(intv_state, intv_ecs_portb_r))
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(intv_state, intv_ecs_porta_w))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33)
+ MCFG_DEVICE_REMOVE("cartslot")
+ MCFG_DEVICE_ADD("ecs", INTV_ROM_ECS, 0)
+
+ MCFG_SOUND_ADD("speech", SP0256, 3120000)
+ /* The Intellivoice uses a speaker with its own volume control so the relative volumes to use are subjective */
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
/* cassette */
//MCFG_CASSETTE_ADD( "cassette" )
+ /* software lists */
+ MCFG_DEVICE_REMOVE("cart_list")
+ MCFG_DEVICE_REMOVE("ecs_list")
+ MCFG_SOFTWARE_LIST_ADD("cart_list", "intvecs")
+ MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("intv_list", "intv")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( intvkbd, intv )
@@ -852,62 +640,37 @@ static MACHINE_CONFIG_DERIVED( intvkbd, intv )
MCFG_SCREEN_VISIBLE_AREA(0, (STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTVKBD_X_SCALE-1, 0, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTVKBD_Y_SCALE-1)
MCFG_SCREEN_UPDATE_DRIVER(intv_state, screen_update_intvkbd)
- /* cartridge */
- MCFG_DEVICE_REMOVE("cart")
- MCFG_CARTSLOT_ADD("cart1")
- MCFG_CARTSLOT_EXTENSION_LIST("int,rom,bin,itv")
- MCFG_CARTSLOT_NOT_MANDATORY
- MCFG_CARTSLOT_LOAD(intv_state,intvkbd_cart)
- MCFG_CARTSLOT_INTERFACE("intv_cart")
-
- MCFG_CARTSLOT_ADD("cart2")
- MCFG_CARTSLOT_EXTENSION_LIST("int,rom,bin,itv")
- MCFG_CARTSLOT_NOT_MANDATORY
- MCFG_CARTSLOT_LOAD(intv_state,intvkbd_cart)
- MCFG_CARTSLOT_INTERFACE("intv_cart")
+ /* I/O cartslots for BASIC */
+ MCFG_GENERIC_CARTSLOT_ADD("ioslot1", generic_plain_slot, "intbasic_cart")
+ MCFG_GENERIC_CARTSLOT_ADD("ioslot2", generic_plain_slot, "intbasic_cart")
MACHINE_CONFIG_END
ROM_START(intv) // the intv1 exec rom should be two roms: RO-3-9502-011.U5 and RO-3-9504-021.U6
ROM_REGION(0x10000<<1,"maincpu", ROMREGION_ERASEFF)
ROM_LOAD16_WORD( "exec.bin", (0x1000<<1)+0, 0x2000, CRC(cbce86f7) SHA1(5a65b922b562cb1f57dab51b73151283f0e20c7a))
-
- ROM_REGION( 0x10000<<1, "sp0256_speech", 0 )
- /* SP0256-012 Speech chip w/2KiB mask rom */
- ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) )
ROM_END
+#define rom_intvoice rom_intv
+
// the later intellivision 2's exec rom is a single ro-3-9506-010 at location ic6 holding 8k plus 512 bytes; the 1st 512 bytes are at 0x400 and the 8k at 0x1000
ROM_START(intv2)
ROM_REGION(0x10000<<1,"maincpu", ROMREGION_ERASEFF)
ROM_LOAD16_WORD_SWAP( "ro-3-9506-010.ic6", (0x400<<1)+0, 0x200, CRC(DD7E1237) SHA1(FB821A643B7714ED4C812553CD3F668766FD44AB))
ROM_CONTINUE( (0x1000<<1)+0, 0x2000 )
-
- ROM_REGION( 0x10000<<1, "sp0256_speech", 0 )
- /* SP0256-012 Speech chip w/2KiB mask rom */
- ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) )
ROM_END
ROM_START(intvsrs) // the intv1 sears exec rom should be two roms: RO-3-9502-???.U5 and RO-3-9504-???.U6 but the correct names are unknown as of yet
ROM_REGION(0x10000<<1,"maincpu", ROMREGION_ERASEFF)
ROM_LOAD16_WORD( "searsexc.bin", (0x1000<<1)+0, 0x2000, CRC(ea552a22) SHA1(834339de056d42a35571cae7fd5b04d1344001e9))
-
- ROM_REGION( 0x10000<<1, "sp0256_speech", 0 )
- /* SP0256-012 Speech chip w/2KiB mask rom */
- ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) )
ROM_END
ROM_START(intvecs) // the intv1 exec rom should be two roms: RO-3-9502-011.U5 and RO-3-9504-021.U6
ROM_REGION(0x10000<<1,"maincpu", ROMREGION_ERASEFF)
ROM_LOAD16_WORD( "exec.bin", (0x1000<<1)+0, 0x2000, CRC(cbce86f7) SHA1(5a65b922b562cb1f57dab51b73151283f0e20c7a))
- ROM_REGION( 0x10000<<1, "sp0256_speech", 0 )
+ ROM_REGION( 0x10000<<1, "speech", 0 )
/* SP0256-012 Speech chip w/2KiB mask rom */
ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) )
-
- ROM_REGION( 0x10000<<1, "ecs_rom", ROMREGION_ERASEFF)
- ROM_LOAD16_WORD_SWAP( "ecs_rom.bin", 0x2000<<1, 0x2000, CRC(ea790a06) SHA1(b7ccb38b881d7f8426cd6f1f8a7aabbd31784fc5))
- ROM_CONTINUE( 0x7000<<1, 0x2000 )
- ROM_CONTINUE( 0xE000<<1, 0x2000 )
ROM_END
ROM_START(intvkbd) // the intv1 exec rom should be two roms: RO-3-9502-011.U5 and RO-3-9504-021.U6
@@ -932,7 +695,6 @@ DRIVER_INIT_MEMBER(intv_state,intv)
m_stic->set_x_scale(INTV_X_SCALE);
m_stic->set_y_scale(INTV_Y_SCALE);
m_is_keybd = 0;
- m_is_ecs = 0;
}
DRIVER_INIT_MEMBER(intv_state,intvkbd)
@@ -940,15 +702,6 @@ DRIVER_INIT_MEMBER(intv_state,intvkbd)
m_stic->set_x_scale(INTVKBD_X_SCALE);
m_stic->set_y_scale(INTVKBD_Y_SCALE);
m_is_keybd = 1;
- m_is_ecs = 0;
-}
-
-DRIVER_INIT_MEMBER(intv_state,intvecs)
-{
- m_stic->set_x_scale(INTV_X_SCALE);
- m_stic->set_y_scale(INTV_Y_SCALE);
- m_is_keybd = 0;
- m_is_ecs = 1;
}
@@ -963,4 +716,7 @@ CONS( 1979, intv, 0, 0, intv, intv, intv_state, i
CONS( 1981, intvsrs, intv, 0, intv, intv, intv_state, intv, "Sears", "Super Video Arcade", GAME_SUPPORTS_SAVE )
COMP( 1981, intvkbd, intv, 0, intvkbd, intvkbd, intv_state, intvkbd, "Mattel", "Intellivision Keyboard Component (Unreleased)", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
CONS( 1982, intv2, intv, 0, intv2, intv, intv_state, intv, "Mattel", "Intellivision II", GAME_SUPPORTS_SAVE )
-COMP( 1983, intvecs, intv, 0, intvecs, intvecs, intv_state, intvecs, "Mattel", "Intellivision Entertainment Computer System", GAME_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", GAME_SUPPORTS_SAVE )
+COMP( 1983, intvecs, intv, 0, intvecs, intv, intv_state, intv, "Mattel", "Intellivision w/Entertainment Computer System + Intellivoice expansions", GAME_SUPPORTS_SAVE )
diff --git a/src/mess/includes/intv.h b/src/mess/includes/intv.h
index 8355595b483..44e08f823ca 100644
--- a/src/mess/includes/intv.h
+++ b/src/mess/includes/intv.h
@@ -8,8 +8,11 @@
#define INTV_H_
#include "sound/ay8910.h"
-#include "sound/sp0256.h"
#include "video/stic.h"
+#include "bus/intv/slot.h"
+#include "bus/intv/voice.h"
+#include "bus/intv/ecs.h"
+#include "bus/intv/keycomp.h"
class intv_state : public driver_device
{
@@ -24,31 +27,26 @@ public:
intv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
- m_intellivoice(*this, "sp0256_speech"),
- m_sound(*this, "ay8914.1"),
- m_ecs_sound(*this, "ay8914.2"),
+ m_sound(*this, "ay8914"),
m_stic(*this, "stic"),
+ m_cart(*this, "cartslot"),
m_intvkbd_dualport_ram(*this, "dualport_ram"),
m_videoram(*this, "videoram"),
m_keyboard(*this, "keyboard"),
+ m_iocart1(*this, "ioslot1"),
+ m_iocart2(*this, "ioslot2"),
m_region_maincpu(*this, "maincpu"),
- m_region_ecs_rom(*this, "ecs_rom"),
m_region_keyboard(*this, "keyboard"),
- m_bank1(*this, "bank1"),
- m_bank2(*this, "bank2"),
- m_bank3(*this, "bank3"),
- m_bank4(*this, "bank4"),
m_io_options(*this, "OPTIONS"),
- m_io_ecs_cntrlsel(*this, "ECS_CNTRLSEL"),
m_io_test(*this, "TEST"),
m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette") { }
+ m_palette(*this, "palette")
+ { }
required_device<cpu_device> m_maincpu;
- required_device<sp0256_device> m_intellivoice;
required_device<ay8914_device> m_sound;
- optional_device<ay8914_device> m_ecs_sound;
required_device<stic_device> m_stic;
+ optional_device<intv_cart_slot_device> m_cart;
optional_shared_ptr<UINT16> m_intvkbd_dualport_ram;
optional_shared_ptr<UINT8> m_videoram;
@@ -60,35 +58,16 @@ public:
DECLARE_WRITE16_MEMBER(intv_ram8_w);
DECLARE_READ16_MEMBER(intv_ram16_r);
DECLARE_WRITE16_MEMBER(intv_ram16_w);
+ DECLARE_READ8_MEMBER(intvkb_iocart_r);
- DECLARE_READ16_MEMBER(intv_cart_ram8_r);
- DECLARE_WRITE16_MEMBER(intv_cart_ram8_w);
-
- DECLARE_READ8_MEMBER( intv_right_control_r );
- DECLARE_READ8_MEMBER( intv_left_control_r );
-
+ DECLARE_READ8_MEMBER(intv_right_control_r);
+ DECLARE_READ8_MEMBER(intv_left_control_r);
+
UINT8 m_bus_copy_mode;
UINT8 m_backtab_row;
UINT16 m_ram16[0x160];
int m_sr1_int_pending;
UINT8 m_ram8[256];
- UINT8 m_cart_ram8[2048];
-
- // ecs
- DECLARE_WRITE16_MEMBER(ecs_bank1_page_select);
- DECLARE_WRITE16_MEMBER(ecs_bank2_page_select);
- DECLARE_WRITE16_MEMBER(ecs_bank3_page_select);
- DECLARE_WRITE16_MEMBER(wsmlb_bank_page_select);
- DECLARE_READ16_MEMBER(intv_ecs_ram8_r);
- DECLARE_WRITE16_MEMBER(intv_ecs_ram8_w);
-
- DECLARE_READ8_MEMBER(intv_ecs_porta_r);
- DECLARE_WRITE8_MEMBER(intv_ecs_porta_w);
- DECLARE_READ8_MEMBER(intv_ecs_portb_r);
-
- UINT8 m_ecs_ram8[2048];
- UINT8 m_ecs_psg_porta;
- int m_ecs_bank_src[4];
// Keyboard Component
DECLARE_READ8_MEMBER(intvkbd_tms9927_r);
@@ -125,22 +104,16 @@ public:
TIMER_CALLBACK_MEMBER(intv_interrupt2_complete);
TIMER_CALLBACK_MEMBER(intv_interrupt_complete);
TIMER_CALLBACK_MEMBER(intv_btb_fill);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(intv_cart);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(intvkbd_cart);
protected:
- int m_is_keybd, m_is_ecs;
+ int m_is_keybd;
optional_device<cpu_device> m_keyboard;
+ optional_device<generic_slot_device> m_iocart1;
+ optional_device<generic_slot_device> m_iocart2;
required_memory_region m_region_maincpu;
- optional_memory_region m_region_ecs_rom;
optional_memory_region m_region_keyboard;
- optional_memory_bank m_bank1;
- optional_memory_bank m_bank2;
- optional_memory_bank m_bank3;
- optional_memory_bank m_bank4;
required_ioport m_io_options;
- optional_ioport m_io_ecs_cntrlsel;
optional_ioport m_io_test;
optional_device<gfxdecode_device> m_gfxdecode;
@@ -151,9 +124,6 @@ protected:
ioport_port *m_discx[4];
ioport_port *m_discy[4];
ioport_port *m_intv_keyboard[10];
- ioport_port *m_ecs_keyboard[7];
- ioport_port *m_ecs_synth[7];
- UINT8 *m_bank_base[2];
int intv_load_rom_file(device_image_interface &image);
UINT8 intv_control_r(int hand);
diff --git a/src/mess/machine/intv.c b/src/mess/machine/intv.c
index d35c7a95782..f3c0bbc6d9d 100644
--- a/src/mess/machine/intv.c
+++ b/src/mess/machine/intv.c
@@ -2,10 +2,7 @@
#include "video/stic.h"
#include "includes/intv.h"
#include "cpu/cp1610/cp1610.h"
-#include "hashfile.h"
-#define INTELLIVOICE_MASK 0x02
-#define ECS_MASK 0x01
WRITE16_MEMBER( intv_state::intvkbd_dualport16_w )
@@ -288,25 +285,6 @@ WRITE16_MEMBER( intv_state::intv_ram8_w )
m_ram8[offset] = data&0xff;
}
-READ16_MEMBER( intv_state::intv_ecs_ram8_r )
-{
- return (int)m_ecs_ram8[offset];
-}
-
-WRITE16_MEMBER( intv_state::intv_ecs_ram8_w )
-{
- m_ecs_ram8[offset] = data&0xff;
-}
-
-READ16_MEMBER( intv_state::intv_cart_ram8_r )
-{
- return (int)m_cart_ram8[offset];
-}
-WRITE16_MEMBER( intv_state::intv_cart_ram8_w )
-{
- m_cart_ram8[offset] = data&0xff;
-}
-
READ16_MEMBER( intv_state::intv_ram16_r )
{
//logerror("%x = ram16_r(%x)\n",state->m_ram16[offset],offset);
@@ -320,289 +298,16 @@ WRITE16_MEMBER( intv_state::intv_ram16_w )
m_ram16[offset] = data & 0xffff;
}
-// ECS and Wsmlb bank switching register handlers
-WRITE16_MEMBER( intv_state::ecs_bank1_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0x2a50)
- {
- m_ecs_bank_src[0] = 0;
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- }
- else if (data == 0x2a51)
- {
- m_ecs_bank_src[0] = 1;
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::ecs_bank2_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0x7a50)
- {
- m_ecs_bank_src[1] = 1;
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1)); // ECS ROM at 0x7000 is on page 1
- }
- else if (data == 0x7a51 )
- {
- m_ecs_bank_src[1] = 0;
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::ecs_bank3_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0xea50)
- {
- m_ecs_bank_src[2] = 0;
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- }
- else if (data == 0xea51)
- {
- m_ecs_bank_src[2] = 1;
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::wsmlb_bank_page_select )
-{
- logerror("offset %x data %x\n", offset, data);
- if (offset == 0xfff)
- {
- if (data == 0xfa50)
- {
- m_ecs_bank_src[3] = 0;
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
- else if (data == 0xfa51)
- {
- m_ecs_bank_src[3] = 1;
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
- }
-}
-
-int intv_state::intv_load_rom_file(device_image_interface &image)
+READ8_MEMBER( intv_state::intvkb_iocart_r )
{
- int i,j;
-
- UINT8 temp;
- UINT8 num_segments;
- UINT8 start_seg;
- UINT8 end_seg;
-
- UINT32 current_address;
- UINT32 end_address;
-
- UINT8 high_byte;
- UINT8 low_byte;
-
- UINT8 *memory = m_region_maincpu->base();
- address_space &program = m_maincpu->space(AS_PROGRAM);
- const char *filetype = image.filetype();
-
- /* if it is in .rom format, we enter here */
- if (!core_stricmp (filetype, "rom"))
- {
- image.fread( &temp, 1); /* header */
- if (temp != 0xa8)
- {
- return IMAGE_INIT_FAIL;
- }
-
- image.fread( &num_segments, 1);
-
- image.fread( &temp, 1);
- if (temp != (num_segments ^ 0xff))
- {
- return IMAGE_INIT_FAIL;
- }
-
- for (i = 0; i < num_segments; i++)
- {
- image.fread( &start_seg, 1);
- current_address = start_seg * 0x100;
-
- image.fread( &end_seg, 1);
- end_address = end_seg * 0x100 + 0xff;
-
- while (current_address <= end_address)
- {
- image.fread( &low_byte, 1);
- memory[(current_address << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[current_address << 1] = high_byte;
- current_address++;
- }
-
- /* Here we should calculate and compare the CRC16... */
- image.fread( &temp, 1);
- image.fread( &temp, 1);
- }
-
- /* Access tables and fine address restriction tables are not supported ATM */
- for (i = 0; i < (16 + 32 + 2); i++)
- {
- image.fread( &temp, 1);
- }
- return IMAGE_INIT_PASS;
- }
- /* otherwise, we load it as a .bin file, using extrainfo from intv.hsi in place of .cfg */
+ if (m_iocart1->exists())
+ return m_iocart1->read_rom(space, offset, mem_mask);
+ else if (m_iocart2->exists())
+ return m_iocart2->read_rom(space, offset, mem_mask);
else
- {
- /* This code is a blatant hack, due to impossibility to load a separate .cfg file in MESS. */
- /* It shall be eventually replaced by the .xml loading */
-
- /* extrainfo format */
- // 1. mapper number (to deal with bankswitch). no bankswitch is mapper 0 (most games).
- // 2.->5. current images have at most 4 chunks of data. we store here block size and location to load
- // (value & 0xf0) >> 4 is the location / 0x1000
- // (value & 0x0f) is the size / 0x800
- // 6. some images have a ram chunk. as above we store location and size in 8 bits
- // 7. extra = 1 ECS, 2 Intellivoice
- int start, size;
- int mapper, rom[5], ram, extra;
- astring extrainfo;
- if (!hashfile_extrainfo(image, extrainfo))
- {
- /* If no extrainfo, we assume a single 0x2000 chunk at 0x5000 */
- for (i = 0; i < 0x2000; i++ )
- {
- image.fread( &low_byte, 1);
- memory[((0x5000 + i) << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[(0x5000 + i) << 1] = high_byte;
- }
- }
- else
- {
- sscanf(extrainfo.cstr() ,"%d %d %d %d %d %d %d", &mapper, &rom[0], &rom[1], &rom[2],
- &rom[3], &ram, &extra);
-
-// logerror("extrainfo: %d %d %d %d %d %d %d \n", mapper, rom[0], rom[1], rom[2],
-// rom[3], ram, extra);
-
- if (mapper)
- {
- logerror("Bankswitch not yet implemented! \n");
- }
-
- if (ram)
- {
- start = (( ram & 0xf0 ) >> 4) * 0x1000;
- size = ( ram & 0x0f ) * 0x800;
-
- program.install_readwrite_handler(start, start + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
- /* For now intellivoice always active
- if (extra & INTELLIVOICE_MASK)
- {
- // tbd
- }
- */
-
- if (extra & ECS_MASK)
- {
- logerror("Requires ECS Module\n");
- }
-
- for (j = 0; j < 4; j++)
- {
- start = (( rom[j] & 0xf0 ) >> 4) * 0x1000;
- size = ( rom[j] & 0x0f ) * 0x800;
-
- /* some cart has to be loaded to 0x4800, but none goes to 0x4000. Hence, we use */
- /* 0x04 << 4 in extrainfo (to reduce the stored values) and fix the value here. */
- if (start == 0x4000) start += 0x800;
-
-// logerror("step %d: %d %d \n", j, start / 0x1000, size / 0x1000);
-
- for (i = 0; i < size; i++ )
- {
- image.fread( &low_byte, 1);
- memory[((start + i) << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[(start + i) << 1] = high_byte;
- }
- }
- }
-
- return IMAGE_INIT_PASS;
- }
+ return m_region_keyboard->u8(offset + 0xe000);
}
-DEVICE_IMAGE_LOAD_MEMBER( intv_state, intv_cart )
-{
- if (image.software_entry() == NULL)
- return intv_load_rom_file(image);
- else
- {
- UINT16 offset[] = {0x4800, 0x5000, 0x6000, 0x7000, 0x9000, 0xa000, 0xc000, 0xd000, 0xf000};
- const char* region_name[] = {"4800", "5000", "6000", "7000", "9000", "A000", "C000", "D000", "F000"};
- UINT8 *memory = m_region_maincpu->base();
- address_space &program = m_maincpu->space(AS_PROGRAM);
-
- UINT32 size=0;
- UINT16 address = 0;
- UINT8 *region;
- for(int i = 0; i < 9; i++)
- {
- address = offset[i];
- size = image.get_software_region_length(region_name[i]);
- if (size)
- {
- region = image.get_software_region(region_name[i]);
- for (int j = 0; j < (size>>1); j++)
- {
- memory[((address + j) << 1) + 1] = region[2*j];
- memory[(address + j) << 1] = region[2*j+1];
- }
- }
- }
- // deal with wsmlb paged rom
-
- size = image.get_software_region_length("F000_bank1");
- if (size && m_region_ecs_rom) // only load if ecs is plugged in (should probably be done a different way)
- {
- UINT8 *ecs_rom_region = m_region_ecs_rom->base();
-
- region = image.get_software_region("F000_bank1");
- for (int j = 0; j < (size>>1); j++)
- {
- ecs_rom_region[((address + j) << 1) + 1] = region[2*j];
- ecs_rom_region[(address + j) << 1] = region[2*j+1];
- }
- }
-
- // Cartridge 8bit ram support
- size = image.get_software_region_length("D000_RAM8");
- if (size)
- {
- program.install_readwrite_handler(0xD000, 0xD000 + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
-
- size = image.get_software_region_length("8800_RAM8");
- if (size)
- {
- program.install_readwrite_handler(0x8800, 0x8800 + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
- return IMAGE_INIT_PASS;
- }
-}
/* Set Reset and INTR/INTRM Vector */
void intv_state::machine_reset()
@@ -615,21 +320,6 @@ void intv_state::machine_reset()
/* Set initial PC */
m_maincpu->set_state_int(CP1610_R7, 0x1000);
-
- if (m_is_ecs)
- {
- // ECS can switch between the maincpu and the ecs roms
- m_ecs_bank_src[0] = 0; // CPU
- m_ecs_bank_src[1] = 1; // ECS
- m_ecs_bank_src[2] = 0; // CPU
- m_ecs_bank_src[3] = 0; // CPU
- m_bank_base[0] = m_region_maincpu->base();
- m_bank_base[1] = m_region_ecs_rom->base();
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
}
void intv_state::machine_start()
@@ -661,30 +351,7 @@ void intv_state::machine_start()
save_item(NAME(m_ram16));
save_item(NAME(m_sr1_int_pending));
save_item(NAME(m_ram8));
- save_item(NAME(m_cart_ram8));
-
- // ecs
- if (m_is_ecs)
- {
- for (int i = 0; i < 7; i++)
- {
- char str[9];
- sprintf(str, "ECS_ROW%i", i);
- m_ecs_keyboard[i] = ioport(str);
- }
- for (int i = 0; i < 7; i++)
- {
- char str[15];
- sprintf(str, "ECS_SYNTH_ROW%i", i);
- m_ecs_synth[i] = ioport(str);
- }
-
- save_item(NAME(m_ecs_ram8));
- save_item(NAME(m_ecs_psg_porta));
- save_item(NAME(m_ecs_bank_src));
- machine().save().register_postload(save_prepost_delegate(FUNC(intv_state::ecs_banks_restore), this));
- }
-
+
// intvkbd
if (m_is_keybd)
{
@@ -706,14 +373,47 @@ void intv_state::machine_start()
save_item(NAME(m_tms9927_cursor_row));
save_item(NAME(m_tms9927_last_row));
}
-}
-void intv_state::ecs_banks_restore()
-{
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
+ if (m_cart && m_cart->exists())
+ {
+ // RAM
+ switch (m_cart->get_type())
+ {
+ case INTV_RAM:
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xd000, 0xd7ff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_GFACT:
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x8800, 0x8fff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_VOICE:
+ m_cart->late_subslot_setup();
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0080, 0x0081, read16_delegate(FUNC(intv_cart_slot_device::read_speech),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_speech),(intv_cart_slot_device*)m_cart));
+
+ // passthru for RAM-equipped carts
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x8800, 0x8fff, write16_delegate(FUNC(intv_cart_slot_device::write_88),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000, 0xd7ff, write16_delegate(FUNC(intv_cart_slot_device::write_d0),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_ECS:
+ m_cart->late_subslot_setup();
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x00f0, 0x00ff, read16_delegate(FUNC(intv_cart_slot_device::read_ay),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ay),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x4000, 0x47ff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x2000, 0x2fff, write16_delegate(FUNC(intv_cart_slot_device::write_rom20),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x7000, 0x7fff, write16_delegate(FUNC(intv_cart_slot_device::write_rom70),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xe000, 0xefff, write16_delegate(FUNC(intv_cart_slot_device::write_rome0),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xf000, 0xffff, write16_delegate(FUNC(intv_cart_slot_device::write_romf0),(intv_cart_slot_device*)m_cart));
+
+ // passthru for Intellivoice expansion
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0080, 0x0081, read16_delegate(FUNC(intv_cart_slot_device::read_speech),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_speech),(intv_cart_slot_device*)m_cart));
+
+ // passthru for RAM-equipped carts
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x8800, 0x8fff, write16_delegate(FUNC(intv_cart_slot_device::write_88),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000, 0xd7ff, write16_delegate(FUNC(intv_cart_slot_device::write_d0),(intv_cart_slot_device*)m_cart));
+ break;
+ }
+
+ m_cart->save_ram();
+ }
}
@@ -828,84 +528,3 @@ READ8_MEMBER( intv_state::intv_right_control_r )
{
return intv_control_r(1);
}
-
-READ8_MEMBER( intv_state::intv_ecs_porta_r )
-{
- if (m_io_ecs_cntrlsel->read() == 0)
- return intv_control_r(2);
- else
- return 0xff; // not sure what to return here, maybe it should be last output?
-}
-
-READ8_MEMBER( intv_state::intv_ecs_portb_r )
-{
- switch (m_io_ecs_cntrlsel->read())
- {
- case 0x00: // hand controller
- {
- return intv_control_r(3);
- }
- case 0x01: // synthesizer keyboard
- {
- UINT8 rv = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_ecs_psg_porta, i))
- rv &= m_ecs_synth[i]->read();
- }
- return rv;
- }
- case 0x02: // ecs keyboard
- {
- UINT8 rv = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_ecs_psg_porta, i))
- rv &= m_ecs_keyboard[i]->read();
- }
- return rv;
- }
- default:
- return 0xff;
- }
-}
-
-WRITE8_MEMBER( intv_state::intv_ecs_porta_w )
-{
- m_ecs_psg_porta = (~data) & 0xff;
-}
-
-/* Intellivision console + keyboard component */
-
-DEVICE_IMAGE_LOAD_MEMBER( intv_state,intvkbd_cart )
-{
- if (strcmp(image.device().tag(),":cart1") == 0) /* Legacy cartridge slot */
- {
- /* First, initialize these as empty so that the intellivision
- * will think that the playcable is not attached */
- UINT8 *memory = m_region_maincpu->base();
-
- /* assume playcable is absent */
- memory[0x4800 << 1] = 0xff;
- memory[(0x4800 << 1) + 1] = 0xff;
-
- if (image.software_entry() == NULL)
- {
- return intv_load_rom_file(image);
- }
- // Shouldn't we report failure here???
- }
-
- if (strcmp(image.device().tag(),":cart2") == 0) /* Keyboard component cartridge slot */
- {
- UINT8 *memory = m_region_keyboard->base();
-
- /* Assume an 8K cart, like BASIC */
- image.fread(&memory[0xe000], 0x2000);
- }
-
- return IMAGE_INIT_PASS;
-
-}
diff --git a/src/mess/mess.lst b/src/mess/mess.lst
index e7f03faadc5..ffc717b6ee3 100644
--- a/src/mess/mess.lst
+++ b/src/mess/mess.lst
@@ -293,6 +293,7 @@ vectrex // General Consumer Electric Vectrex - 1982-1984
intv // Mattel Intellivision - 1979 AKA INTV
intv2 // Mattel Intellivision II- 1982?
intvsrs // Intellivision (Sears License) - 19??
+intvoice // Mattel Intellivision + IntelliVoice expansion - 1982
// Milton Bradley
microvsn // MicroVision - 1979
@@ -1637,7 +1638,7 @@ rs128 // 1984 Memotech RS 128
// Mattel
intvkbd // 1981 - Mattel Intellivision Keyboard Component
// (Test marketed, later recalled)
-intvecs // 1983 - Mattel Intellivision ECS
+intvecs // 1983 - Mattel Intellivision w/ECS and IntelliVoice expansions
aquarius // 1983 Aquarius
//aquariu2 // 1984 Aquarius II
juicebox
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index 9495461e505..98f77760508 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -592,6 +592,7 @@ BUSES += GBA
BUSES += GENERIC
BUSES += IEEE488
BUSES += IMI7000
+BUSES += INTV
BUSES += IQ151
BUSES += ISA
BUSES += ISBX