diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/bus/bus.mak | 14 | ||||
-rw-r--r-- | src/emu/bus/intv/ecs.c | 588 | ||||
-rw-r--r-- | src/emu/bus/intv/ecs.h | 145 | ||||
-rw-r--r-- | src/emu/bus/intv/rom.c | 50 | ||||
-rw-r--r-- | src/emu/bus/intv/rom.h | 82 | ||||
-rw-r--r-- | src/emu/bus/intv/slot.c | 572 | ||||
-rw-r--r-- | src/emu/bus/intv/slot.h | 184 | ||||
-rw-r--r-- | src/emu/bus/intv/voice.c | 122 | ||||
-rw-r--r-- | src/emu/bus/intv/voice.h | 76 | ||||
-rw-r--r-- | src/mess/drivers/intv.c | 570 | ||||
-rw-r--r-- | src/mess/includes/intv.h | 66 | ||||
-rw-r--r-- | src/mess/machine/intv.c | 475 | ||||
-rw-r--r-- | src/mess/mess.lst | 3 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 |
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 |