diff options
Diffstat (limited to 'src/mame/drivers/intv.c')
-rw-r--r-- | src/mame/drivers/intv.c | 752 |
1 files changed, 752 insertions, 0 deletions
diff --git a/src/mame/drivers/intv.c b/src/mame/drivers/intv.c new file mode 100644 index 00000000000..023cd6fcc36 --- /dev/null +++ b/src/mame/drivers/intv.c @@ -0,0 +1,752 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods,Frank Palazzolo +/************************************************************************ + * Mattel Intellivision + Keyboard Component Drivers + * + * Frank Palazzolo + * Kyle Davis + * + * TBD: + * Add tape support (intvkbd) + * Add runtime tape loading + * Fix memory system workaround + * (memory handler stuff in CP1610, debugger, and shared mem) + * STIC + * reenable dirty support + * Cleanup + * Separate stic & video better, get rid of *2 for kbd comp + * Add better runtime cart loading + * Switch to tilemap system + * Note from kevtris about IntelliVoice Hookup: +<kevtris> the intv uses a special chip +<kevtris> called the SPB640 +<kevtris> it is really cool and lame at the same time +<kevtris> it holds 64 10 bit words, which it simply serializes and sends to the SP0256 +<kevtris> the SP0256-012 just blindly jumps to 02000h or something when you try to play one of the samples +<kevtris> the SPB640 sits at 2000h and when it sees that address come up, it will send out the 640 bits to the '256 +<kevtris> this means you cannot use any gotos/gosubs in your speech data, but that is OK +<kevtris> it's just a single serial stream. the intv simply watches the buffer state and refills it periodically. there's enough buffer to keep it full for 1 frame +<kevtris> that's about it +<kevtris> the samples are stored in the game ROMs, and are easy to extract + +9502, 9503 and 9504 are the chips used in the intv1 (the sears one may use different chips) +9505 is used in some carts +9503 and 9506 are the chips used in the intv2 + +Known roms so far: +RO-3-9502-011 = 4KiB(2Kiw) self-decoding mask rom with decoder & bus, (DIP40 containing 1/2 of EXEC, maps at words 0000-0fff or 1000-1fff [unclear which, guess is 0000], i/o maps at ?), located at U5 on intv1 +RO-3-9503-003 = 2KiB(1Kiw) self-decoding mask rom with decoder & bus, (DIP40 containing GROM, maps at words 0x3000-0x37FF, i/o maps at ?), located at U21 in intv1, U5 in intv2 +RO-3-9504-021 = 4KiB(2Kiw) self-decoding mask rom without decoder or bus, (DIP28 containing 1/2 of EXEC, maps at words 0000-0fff or 1000-1fff [unclear which, guess is 1000]), located at U6 in intv1 +RO-3-9506-010 = 8KiB(4Kiw)+512B(256W) self-decoding mask rom with decoder & bus, (DIP40 containing EXEC2, maps at words 0000-1fff and 0400-04FF, i/o maps at ?) located at U6 in intv2 + +rom types (suspected, not proven yet): +RO-3-9502 = 4KiB (2Kiw) self decoding address mask rom with external address decoder & bus (DIP40) +RO-3-9503 = 2KiB (1Kiw) self decoding address mask rom with external address decoder & bus (DIP40) +RO-3-9504 = 4KiB (2Kiw) self decoding address mask rom without external address decoder or bus (DIP28) +RO-3-9505 = 8KiB (4Kiw) self decoding address mask rom without external address decoder or bus (DIP28) +RO-3-9506 = 8KiB (4Kiw) self decoding address mask rom with external address decoder & bus (DIP40) + + * + ************************************************************************/ + + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "cpu/cp1610/cp1610.h" +#include "includes/intv.h" +#include "sound/ay8910.h" + +#ifndef VERBOSE +#ifdef MAME_DEBUG +#define VERBOSE 1 +#else +#define VERBOSE 0 +#endif +#endif + +static const unsigned char intv_colors[] = +{ + 0x00, 0x00, 0x00, /* BLACK */ + 0x00, 0x2D, 0xFF, /* BLUE */ + 0xFF, 0x3D, 0x10, /* RED */ + 0xC9, 0xCF, 0xAB, /* TAN */ + 0x38, 0x6B, 0x3F, /* DARK GREEN */ + 0x00, 0xA7, 0x56, /* GREEN */ + 0xFA, 0xEA, 0x50, /* YELLOW */ + 0xFF, 0xFC, 0xFF, /* WHITE */ + 0xBD, 0xAC, 0xC8, /* GRAY */ + 0x24, 0xB8, 0xFF, /* CYAN */ + 0xFF, 0xB4, 0x1F, /* ORANGE */ + 0x54, 0x6E, 0x00, /* BROWN */ + 0xFF, 0x4E, 0x57, /* PINK */ + 0xA4, 0x96, 0xFF, /* LIGHT BLUE */ + 0x75, 0xCC, 0x80, /* YELLOW GREEN */ + 0xB5, 0x1A, 0x58 /* PURPLE */ +}; + +PALETTE_INIT_MEMBER(intv_state, intv) +{ + int k = 0; + UINT8 r, g, b; + /* Two copies of everything (why?) */ + + for (int i = 0; i < 16; i++) + { + r = intv_colors[i * 3 + 0]; + g = intv_colors[i * 3 + 1]; + b = intv_colors[i * 3 + 2]; + palette.set_indirect_color(i, rgb_t(r, g, b)); + palette.set_indirect_color(i + 16, rgb_t(r, g, b)); + } + + for (int i = 0; i < 16; i++) + { + for (int j = 0; j < 16; j++) + { + palette.set_pen_indirect(k++, i); + palette.set_pen_indirect(k++, j); + } + } + + for (int i = 0; i < 16; i++) + { + for (int j = 16; j < 32; j++) + { + palette.set_pen_indirect(k++, i); + palette.set_pen_indirect(k++, j); + } + } +} + +/* graphics output */ + +static const gfx_layout intvkbd_charlayout = +{ + 8, 8, + 256, + 1, + { 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, + 8 * 8 +}; + +static GFXDECODE_START( intvkbd ) + GFXDECODE_ENTRY( "gfx1", 0x0000, intvkbd_charlayout, 0, 256 ) +GFXDECODE_END + +static INPUT_PORTS_START( intv ) + + /* Left Player Controller */ + PORT_START("KEYPAD1") + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/3") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/5") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/6") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/7") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/8") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/9") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/Clear") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Left/Enter") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Left/Upper") PORT_PLAYER(1) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Left/Lower-Left") PORT_PLAYER(1) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Left/Lower-Right") PORT_PLAYER(1) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("DISC1") + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Left/Up") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Right-Up-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("Left/Right") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Right-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Down-Right") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("Left/Down") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Left-Down-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("Left/Left") PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Left-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left/Up-Up-Left") PORT_CONDITION("OPTIONS",0x01,EQUALS,0x00) + + PORT_START("DISCX1") + PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("Left/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01) + + PORT_START("DISCY1") + PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("Left/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_PLAYER(1) PORT_CONDITION("OPTIONS",0x01,EQUALS,0x01) + + /* Right Player Controller */ + PORT_START("KEYPAD2") + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/1") + PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/2") + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/3") + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/4") + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/5") + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/6") + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/7") + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/8") + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/9") + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/Clear") + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/0") + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Right/Enter") + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Right/Upper") PORT_PLAYER(2) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Right/Lower-Left") PORT_PLAYER(2) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Right/Lower-Right") PORT_PLAYER(2) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("DISC2") + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Right/Up") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Right-Up-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("Right/Right") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Right-Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Down-Right") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("Right/Down") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Left-Down-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("Right/Left") PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Left-Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right/Up-Up-Left") PORT_CONDITION("OPTIONS",0x02,EQUALS,0x00) + + PORT_START("DISCX2") + PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("Right/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_D) PORT_CODE_INC(KEYCODE_G) PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x02) + + PORT_START("DISCY2") + PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("Right/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_R) PORT_CODE_INC(KEYCODE_F) PORT_PLAYER(2) PORT_CONDITION("OPTIONS",0x02,EQUALS,0x02) + + PORT_START("OPTIONS") + PORT_CONFNAME( 0x01, 0x00, "Left Disc" ) + PORT_CONFSETTING( 0x00, "Digital" ) + PORT_CONFSETTING( 0x01, "Analog" ) + PORT_CONFNAME( 0x02, 0x00, "Right Disc" ) + PORT_CONFSETTING( 0x00, "Digital" ) + PORT_CONFSETTING( 0x02, "Analog" ) +INPUT_PORTS_END + + +/* + Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 + + Row 0 NC NC NC NC NC NC CTRL SHIFT + Row 1 NC NC NC NC NC NC RPT LOCK + Row 2 NC / , N V X NC SPC + Row 3 (right) . M B C Z NC CLS + Row 4 (down) ; K H F S NC TAB + Row 5 ] P I Y R W NC Q + Row 6 (up) - 9 7 5 3 NC 1 + Row 7 = 0 8 6 4 2 NC [ + Row 8 (return)(left) O U T E NC ESC + Row 9 DEL ' L J G D NC A + +2008-05 FP: +The keyboard layout is quite strange, with '[' and ']' at the two ends of the 1st row, +'Esc' in the 2nd row (between 'Tab' and 'Q'), and with Cursor keys and 'Enter' where +you would expect the braces. Moreover, Shift + Cursor keys produce characters. +The emulated layout moves 'Esc', '[' and ']' to their usual position. + +Moreover, a small note on natural keyboard support: currently +- "Clear Screen" is mapped to 'Left Alt' +- "Repeat" is mapped to 'F1' +- "Lock" is mapped to 'F2' +*/ + +static INPUT_PORTS_START( intvkbd ) + PORT_START("ROW0") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + + PORT_START("ROW1") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPEAT") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(F2)) + + PORT_START("ROW2") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("ROW3") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR('>') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Clear Screen") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) + + PORT_START("ROW4") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR('\\') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') + + PORT_START("ROW5") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + + PORT_START("ROW6") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR('|') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('_') PORT_CHAR('-') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + + PORT_START("ROW7") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('O') PORT_CHAR(')') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('\xA2') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') // this one would be 1st row, 1st key (at 'Esc' position) + + PORT_START("ROW8") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR('<') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) // this one would be 2nd row, 2nd key (between 'Tab' and 'Q') + + PORT_START("ROW9") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + + PORT_START("TEST") /* For tape drive testing... */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) + + /* 2008-05 FP: I include here the controller inputs to make happy the read_handler. + Please remove this (and re-tag accordingly the inputs above) if intv_right_control_r + is supposed to scan the keyboard inputs when the Keyboard Component is connected */ + PORT_INCLUDE( intv ) +INPUT_PORTS_END + +static ADDRESS_MAP_START( intv_mem, AS_PROGRAM, 16, intv_state ) + 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( 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("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_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_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_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(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_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(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 ) + 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, 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) +{ + switch (id) + { + case TIMER_INTV_INTERRUPT2_COMPLETE: + intv_interrupt2_complete(ptr, param); + break; + case TIMER_INTV_INTERRUPT_COMPLETE: + intv_interrupt_complete(ptr, param); + break; + case TIMER_INTV_BTB_FILL: + intv_btb_fill(ptr, param); + break; + default: + assert_always(FALSE, "Unknown id in intv_state::device_timer"); + } +} + + +/* This is needed because MAME core does not allow PULSE_LINE. + The time interval is not critical, although it should be below 1000. */ + +TIMER_CALLBACK_MEMBER(intv_state::intv_interrupt2_complete) +{ + m_keyboard->set_input_line(0, CLEAR_LINE); +} + +INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt2) +{ + m_keyboard->set_input_line(0, ASSERT_LINE); + 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 */ + MCFG_CPU_PROGRAM_MAP(intv_mem) + MCFG_CPU_VBLANK_INT_DRIVER("screen", intv_state, intv_interrupt) + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + + /* video hardware */ + MCFG_STIC_ADD("stic") + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(59.92) + //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2400)) /* not accurate */ + MCFG_SCREEN_UPDATE_DRIVER(intv_state, screen_update_intv) + MCFG_SCREEN_SIZE((STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTV_X_SCALE, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTV_Y_SCALE) + MCFG_SCREEN_VISIBLE_AREA(0, (STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTV_X_SCALE-1, 0, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTV_Y_SCALE-1) + MCFG_SCREEN_PALETTE("palette") + + MCFG_PALETTE_ADD("palette", 0x400) + MCFG_PALETTE_INDIRECT_ENTRIES(32) + MCFG_PALETTE_INIT_OWNER(intv_state, intv) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("ay8914", AY8914, XTAL_3_579545MHz/2) + MCFG_AY8910_PORT_A_READ_CB(READ8(intv_state, intv_right_control_r)) + MCFG_AY8910_PORT_B_READ_CB(READ8(intv_state, intv_left_control_r)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33) + + /* cartridge */ + MCFG_INTV_CARTRIDGE_ADD("cartslot", intv_cart, NULL) + + /* software lists */ + MCFG_SOFTWARE_LIST_ADD("cart_list", "intv") + MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("ecs_list", "intvecs") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( intv2, intv ) + MCFG_CPU_MODIFY( "maincpu" ) + 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_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 ) + MCFG_CPU_MODIFY( "maincpu" ) + MCFG_CPU_PROGRAM_MAP(intvkbd_mem) + + MCFG_CPU_ADD("keyboard", M6502, XTAL_3_579545MHz/2) /* Colorburst/2 */ + MCFG_CPU_PROGRAM_MAP(intvkbd2_mem) + MCFG_CPU_VBLANK_INT_DRIVER("screen", intv_state, intv_interrupt2) + + MCFG_QUANTUM_TIME(attotime::from_hz(6000)) + + /* video hardware */ + MCFG_GFXDECODE_ADD("gfxdecode", "palette", intvkbd) + MCFG_PALETTE_MODIFY("palette") + MCFG_PALETTE_INIT_OWNER(intv_state, intv) + + MCFG_SCREEN_MODIFY("screen") + MCFG_SCREEN_SIZE((STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTVKBD_X_SCALE, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTVKBD_Y_SCALE) + 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) + + /* 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_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_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_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, "speech", 0 ) + /* SP0256-012 Speech chip w/2KiB mask rom */ + ROM_LOAD( "sp0256-012.bin", 0x1000, 0x0800, CRC(0de7579d) SHA1(618563e512ff5665183664f52270fa9606c9d289) ) +ROM_END + +/* +Intellivision Keyboard Component - Prototype +------------------------------------------------------------- + +GI 9333B-0104 0104.U20 4Kx8 Mask ROM, 6502 code +Intel 2732 "CPU 2D" CPU2D.U21 4Kx8 EPROM, 6502 code + +TI 8S030N 1149-0360 0360.U58 32x8 Timing prom? +TI 8S030N 1149-0370 0370.U74 32x8 Timing prom? + +GI RO-3-9502-024 024.U60 2Kx10 Mask ROM+Addr Decoder, CP1600 code +GI 9316B-4D72 4D72.U62 2Kx8 Mask ROM, CP1600 code (upper) +GI 9316B-4D71 4D71.U63 2Kx8 Mask ROM, CP1600 code (lower) +GI 9316B-4C52 4C52.U34 2Kx8 Mask ROM, Alphanumerics + +Main board also includes: + + 2 2114 DRAMS 1Kx4 Character memory + 10 MM5290J DRAMS 16Kx10 CP1600 memory? + 1 6502 + 1 Mystery 40-pin chip (under heat sink) + (actually a SMC CRT5027 aka TI TMS9927 CRT controller) +*/ + +ROM_START(intvkbd) // 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, 0x2000, CRC(cbce86f7) SHA1(5a65b922b562cb1f57dab51b73151283f0e20c7a)) + ROM_LOAD16_WORD( "024.u60", 0x7000<<1, 0x1000, CRC(4f7998ec) SHA1(ec006d0ae9002e9d56d83a71f5f2eddd6a456a40)) + ROM_LOAD16_BYTE( "4d72.u62", 0x7800<<1, 0x0800, CRC(aa57c594) SHA1(741860d489d90f5882ca53daa3169b6abacdf130)) + ROM_LOAD16_BYTE( "4d71.u63", (0x7800<<1)+1, 0x0800, CRC(069b2f0b) SHA1(070850bb32f8474107cc52c5183cfaa32d640f9a)) + + ROM_REGION(0x10000,"keyboard",0) + ROM_LOAD( "0104.u20", 0xc000, 0x1000, CRC(5c6f1256) SHA1(271931fb354dfae6a1a5697ee888924a89a15ca8)) + ROM_RELOAD( 0xe000, 0x1000 ) + ROM_LOAD("cpu2d.u21", 0xd000, 0x1000, CRC(2c2dba33) SHA1(0db5d177fec3f8ae89abeef2e6900ad4f3460266)) + ROM_RELOAD( 0xf000, 0x1000 ) + + ROM_REGION(0x00800,"gfx1",0) + ROM_LOAD( "4c52.u34", 0x0000, 0x0800, CRC(cbeb2e96) SHA1(f0e17adcd278fb376c9f90833c7fbbb60193dbe3)) + + ROM_REGION(0x0100,"proms",0) + ROM_LOAD( "0360.u58", 0x00, 0x20, CRC(1295528a) SHA1(b35e598891f1185e02cbacb4811d2334357abd79)) + ROM_LOAD( "0370.u74", 0x20, 0x20, CRC(19da5096) SHA1(76af50e4fd29649fc4837120c245321a8fc84cd3)) +ROM_END + +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; +} + +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; +} + + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ +CONS( 1979, intv, 0, 0, intv, intv, intv_state, intv, "Mattel", "Intellivision", MACHINE_SUPPORTS_SAVE ) +CONS( 1981, intvsrs, intv, 0, intv, intv, intv_state, intv, "Sears", "Super Video Arcade", MACHINE_SUPPORTS_SAVE ) +COMP( 1981, intvkbd, intv, 0, intvkbd, intvkbd, intv_state, intvkbd, "Mattel", "Intellivision Keyboard Component (Unreleased)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +CONS( 1982, intv2, intv, 0, intv2, intv, intv_state, intv, "Mattel", "Intellivision II", MACHINE_SUPPORTS_SAVE ) + +// made up, user friendlier machines with pre-mounted passthu expansions +COMP( 1982, intvoice, intv, 0, intvoice, intv, intv_state, intv, "Mattel", "Intellivision w/IntelliVoice expansion", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, intvecs, intv, 0, intvecs, intv, intv_state, intv, "Mattel", "Intellivision w/Entertainment Computer System + Intellivoice expansions", MACHINE_SUPPORTS_SAVE ) |