diff options
Diffstat (limited to 'src/emu')
62 files changed, 10520 insertions, 0 deletions
diff --git a/src/emu/bus/abckb/abc77.c b/src/emu/bus/abckb/abc77.c new file mode 100644 index 00000000000..8d1ad08d1d9 --- /dev/null +++ b/src/emu/bus/abckb/abc77.c @@ -0,0 +1,659 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-55/77 keyboard emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +/* + +PCB Layout +---------- + +KTC A65-02486-232 + +|-----------------------------------------------------------------------| +| SW1 CN1 LS393 | +| 4020 7406 LS132 7407 LS02 7407 NE556 LS1 | +| | +| 22-950-3B XTAL CPU ROM0 ROM1 LS373 LS240 22-908-03 | +| | +| | +| | +| | +| | +| | +| | +|-----------------------------------------------------------------------| + +Notes: + All IC's shown. + + CPU - Signetics SCN8035A 8035 CPU + ROM0 - NEC D2716D 2Kx8 ROM "-78" + ROM1 - not populated + 22-950-3B - Exar Semiconductor XR22-950-3B keyboard matrix row driver with 4 to 12 decoder/demultiplexer + 22-908-03 - Exar Semiconductor XR22-908-03 keyboard matrix capacitive readout latch + CN1 - 1x12 PCB header + LS1 - loudspeaker + SW1 - reset switch + +*/ + +#include "abc77.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define I8035_TAG "z16" +#define DISCRETE_TAG "discrete" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type ABC77 = &device_creator<abc77_device>; +const device_type ABC55 = &device_creator<abc55_device>; + + +//------------------------------------------------- +// ROM( abc77 ) +//------------------------------------------------- + +ROM_START( abc77 ) + ROM_REGION( 0x1000, I8035_TAG, 0 ) + ROM_LOAD( "-78.z10", 0x000, 0x800, CRC(635986ce) SHA1(04a30141ac611d0544bbb786061515040c23480c) ) +// ROM_LOAD( "keyboard.z14", 0x0800, 0x0800, NO_DUMP ) // non-Swedish keyboard encoding ROM +ROM_END + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *abc77_device::device_rom_region() const +{ + return ROM_NAME( abc77 ); +} + + +//------------------------------------------------- +// ADDRESS_MAP( abc77_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc77_map, AS_PROGRAM, 8, abc77_device ) + AM_RANGE(0x000, 0xfff) AM_ROM AM_REGION("z16", 0) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( abc77_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc77_io, AS_IO, 8, abc77_device ) + AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_WRITE(j3_w) + AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_READ_PORT("DSW") + AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READ(p1_r) + AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(p2_w) + AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r) + AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_WRITE(prog_w) +ADDRESS_MAP_END + + +//------------------------------------------------- +// DISCRETE_SOUND( abc77 ) +//------------------------------------------------- + +static const discrete_555_desc abc77_ne556_a = +{ + DISC_555_OUT_SQW | DISC_555_OUT_DC, + 5, // B+ voltage of 555 + DEFAULT_555_VALUES +}; + + +static DISCRETE_SOUND_START( abc77 ) + DISCRETE_INPUT_LOGIC(NODE_01) + DISCRETE_555_ASTABLE(NODE_02, NODE_01, RES_K(2.7), RES_K(15), CAP_N(22), &abc77_ne556_a) + DISCRETE_OUTPUT(NODE_02, 5000) +DISCRETE_SOUND_END + + +//------------------------------------------------- +// MACHINE_DRIVER( abc77 ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( abc77 ) + // keyboard cpu + MCFG_CPU_ADD(I8035_TAG, I8035, XTAL_4_608MHz) + MCFG_CPU_PROGRAM_MAP(abc77_map) + MCFG_CPU_IO_MAP(abc77_io) + + // watchdog + MCFG_WATCHDOG_TIME_INIT(attotime::from_hz(XTAL_4_608MHz/3/5/4096)) + + // discrete sound + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD(DISCRETE_TAG, DISCRETE, 0) + MCFG_SOUND_CONFIG_DISCRETE(abc77) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor abc77_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( abc77 ); +} + + +//------------------------------------------------- +// INPUT_CHANGED_MEMBER( keyboard_reset ) +//------------------------------------------------- + +INPUT_CHANGED_MEMBER( abc77_device::keyboard_reset ) +{ + if (oldval && !newval) + { + device_reset(); + } +} + + +//------------------------------------------------- +// INPUT_PORTS( abc55 ) +//------------------------------------------------- + +INPUT_PORTS_START( abc55 ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RIGHT SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LEFT SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\r') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(0x00E9) PORT_CHAR(0x00C9) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_CHAR('?') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00E5) PORT_CHAR(0x00C5) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(0x00FC) PORT_CHAR(0x00DC) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x00E4) PORT_CHAR(0x00C4) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\'') PORT_CHAR('*') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("X4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(0x00F6) PORT_CHAR(0x00D6) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('-') PORT_CHAR('_') + + PORT_START("X5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') + + PORT_START("X6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x02, 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_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + + PORT_START("X7") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("4 \xC2\xA4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR(0x00A4) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + + PORT_START("X8") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + + PORT_START("X9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X11") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + + PORT_START("DSW") + PORT_DIPNAME( 0x01, 0x01, "Keyboard Program" ) + PORT_DIPSETTING( 0x00, "Internal (8048)" ) + PORT_DIPSETTING( 0x01, "External PROM" ) // @ Z10 + PORT_DIPNAME( 0x02, 0x02, "Character Set" ) + PORT_DIPSETTING( 0x02, "Swedish" ) + PORT_DIPSETTING( 0x00, "US ASCII" ) + PORT_DIPNAME( 0x04, 0x04, "External Encoding PROM" ) // @ Z14 + PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x18, 0x18, "Keyboard Language" ) PORT_CONDITION("DSW", 0x04, EQUALS, 0x00) + PORT_DIPSETTING( 0x00, "Danish" ) + PORT_DIPSETTING( 0x10, DEF_STR( French ) ) + PORT_DIPSETTING( 0x08, DEF_STR( German ) ) + PORT_DIPSETTING( 0x18, DEF_STR( Spanish ) ) + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("SW1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_NAME("Keyboard Reset") PORT_CHANGED_MEMBER(DEVICE_SELF, abc77_device, keyboard_reset, 0) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor abc55_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( abc55 ); +} + + +//------------------------------------------------- +// INPUT_PORTS( abc77 ) +//------------------------------------------------- + +INPUT_PORTS_START( abc77 ) + PORT_INCLUDE( abc55 ) + + PORT_MODIFY("X9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad RETURN") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_MODIFY("X10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor abc77_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( abc77 ); +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// serial_output - +//------------------------------------------------- + +inline void abc77_device::serial_output(int state) +{ + if (m_txd != state) + { + m_txd = state; + + m_slot->write_rx(m_txd); + } +} + + +//------------------------------------------------- +// serial_clock - +//------------------------------------------------- + +inline void abc77_device::serial_clock() +{ + m_clock = !m_clock; + + m_slot->trxc_w(!m_clock); +} + + +//------------------------------------------------- +// keydown - +//------------------------------------------------- + +inline void abc77_device::key_down(int state) +{ + if (m_keydown != state) + { + m_slot->keydown_w(state); + m_keydown = state; + } +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// abc77_device - constructor +//------------------------------------------------- + +abc77_device::abc77_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ABC77, "Luxor ABC 77", tag, owner, clock, "abc77", __FILE__), + abc_keyboard_interface(mconfig, *this), + m_maincpu(*this, I8035_TAG), + m_discrete(*this, DISCRETE_TAG), + m_x0(*this, "X0"), + m_x1(*this, "X1"), + m_x2(*this, "X2"), + m_x3(*this, "X3"), + m_x4(*this, "X4"), + m_x5(*this, "X5"), + m_x6(*this, "X6"), + m_x7(*this, "X7"), + m_x8(*this, "X8"), + m_x9(*this, "X9"), + m_x10(*this, "X10"), + m_x11(*this, "X11"), + m_dsw(*this, "DSW"), + m_txd(1), + m_keydown(1), + m_clock(0), + m_stb(1) +{ +} + +abc77_device::abc77_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), + abc_keyboard_interface(mconfig, *this), + m_maincpu(*this, I8035_TAG), + m_discrete(*this, DISCRETE_TAG), + m_x0(*this, "X0"), + m_x1(*this, "X1"), + m_x2(*this, "X2"), + m_x3(*this, "X3"), + m_x4(*this, "X4"), + m_x5(*this, "X5"), + m_x6(*this, "X6"), + m_x7(*this, "X7"), + m_x8(*this, "X8"), + m_x9(*this, "X9"), + m_x10(*this, "X10"), + m_x11(*this, "X11"), + m_dsw(*this, "DSW"), + m_txd(1), + m_keydown(1), + m_clock(0), + m_stb(1) +{ +} + +abc55_device::abc55_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : abc77_device(mconfig, ABC55, "Luxor ABC 55", tag, owner, clock, "abc55", __FILE__) { } + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void abc77_device::device_start() +{ + // allocate timers + m_serial_timer = timer_alloc(TIMER_SERIAL); + m_serial_timer->adjust(attotime::from_hz(19200), 0, attotime::from_hz(19200)); // ALE/32 + + m_reset_timer = timer_alloc(TIMER_RESET); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void abc77_device::device_reset() +{ + int t = 1.1 * RES_K(100) * CAP_N(100) * 1000; // t = 1.1 * R1 * C1 + int ea = BIT(m_dsw->read(), 7); + + // trigger reset + m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_reset_timer->adjust(attotime::from_msec(t)); + + m_maincpu->set_input_line(MCS48_INPUT_EA, ea ? CLEAR_LINE : ASSERT_LINE); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void abc77_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_SERIAL: + serial_clock(); + break; + + case TIMER_RESET: + m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + break; + } +} + + +//------------------------------------------------- +// txd_w - +//------------------------------------------------- + +void abc77_device::txd_w(int state) +{ + m_maincpu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); +} + + +//------------------------------------------------- +// p1_r - +//------------------------------------------------- + +READ8_MEMBER( abc77_device::p1_r ) +{ + /* + + bit description + + P10 Z17 Y0 + P11 Z17 Y1 + P12 Z17 Y2 + P13 Z17 Y3 + P14 Z17 Y4 + P15 Z17 Y5 + P16 Z17 Y6 + P17 Z17 Y7 + + */ + + UINT8 data = 0xff; + + if (m_stb) + { + switch (m_keylatch) + { + case 0: data = m_x0->read(); break; + case 1: data = m_x1->read(); break; + case 2: data = m_x2->read(); break; + case 3: data = m_x3->read(); break; + case 4: data = m_x4->read(); break; + case 5: data = m_x5->read(); break; + case 6: data = m_x6->read(); break; + case 7: data = m_x7->read(); break; + case 8: data = m_x8->read(); break; + case 9: data = m_x9->read(); break; + case 10: data = m_x10->read(); break; + case 11: data = m_x11->read(); break; + } + } + + return data; +} + + +//------------------------------------------------- +// p2_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc77_device::p2_w ) +{ + /* + + bit description + + P20 Z2 A0 + P21 Z2 A1 + P22 Z2 A2 + P23 Z2 A3 + P24 NE556 2,6 + P25 TxD + P26 _KEYDOWN + P27 Z17 HYS + + */ + + if (!m_stb) + { + m_keylatch = data & 0x0f; + + if (m_keylatch == 1) + { + machine().watchdog_reset(); + } + } + + // beep + discrete_sound_w(m_discrete, space, NODE_01, BIT(data, 4)); + + // transmit data + serial_output(BIT(data, 5)); + + // key down + key_down(BIT(data, 6)); + + // hysteresis + m_hys = BIT(data, 7); +} + + +//------------------------------------------------- +// t1_r - +//------------------------------------------------- + +READ8_MEMBER( abc77_device::t1_r ) +{ + return m_clock; +} + + +//------------------------------------------------- +// prog_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc77_device::prog_w ) +{ + m_stb = BIT(data, 0); +} + + +//------------------------------------------------- +// j3_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc77_device::j3_w ) +{ + m_j3 = data; +} diff --git a/src/emu/bus/abckb/abc77.h b/src/emu/bus/abckb/abc77.h new file mode 100644 index 00000000000..71fc368fd84 --- /dev/null +++ b/src/emu/bus/abckb/abc77.h @@ -0,0 +1,119 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-55/77 keyboard emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +#pragma once + +#ifndef __ABC77__ +#define __ABC77__ + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "abckb.h" +#include "sound/discrete.h" +#include "sound/speaker.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> abc77_device + +class abc77_device : public device_t, + public abc_keyboard_interface +{ +public: + // construction/destruction + abc77_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); + abc77_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + virtual ioport_constructor device_input_ports() const; + + // abc_keyboard_interface overrides + virtual void txd_w(int state); + + DECLARE_INPUT_CHANGED_MEMBER( keyboard_reset ); + + DECLARE_READ8_MEMBER( p1_r ); + DECLARE_WRITE8_MEMBER( p2_w ); + DECLARE_READ8_MEMBER( t1_r ); + DECLARE_WRITE8_MEMBER( prog_w ); + DECLARE_WRITE8_MEMBER( j3_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + enum + { + TIMER_SERIAL, + TIMER_RESET + }; + + inline void serial_output(int state); + inline void serial_clock(); + inline void key_down(int state); + + required_device<cpu_device> m_maincpu; + required_device<discrete_sound_device> m_discrete; + required_ioport m_x0; + required_ioport m_x1; + required_ioport m_x2; + required_ioport m_x3; + required_ioport m_x4; + required_ioport m_x5; + required_ioport m_x6; + required_ioport m_x7; + required_ioport m_x8; + required_ioport m_x9; + required_ioport m_x10; + required_ioport m_x11; + required_ioport m_dsw; + + int m_txd; // transmit data + int m_keylatch; // keyboard row latch + int m_keydown; // key down + int m_clock; // transmit clock + int m_hys; // hysteresis + int m_reset; // reset + int m_stb; // strobe + UINT8 m_j3; + + // timers + emu_timer *m_serial_timer; + emu_timer *m_reset_timer; +}; + + +class abc55_device : public abc77_device +{ +public: + // construction/destruction + abc55_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual ioport_constructor device_input_ports() const; +}; + + +// device type definition +extern const device_type ABC77; +extern const device_type ABC55; + + + +#endif diff --git a/src/emu/bus/abckb/abc800kb.c b/src/emu/bus/abckb/abc800kb.c new file mode 100644 index 00000000000..55a18604f86 --- /dev/null +++ b/src/emu/bus/abckb/abc800kb.c @@ -0,0 +1,510 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-800 keyboard emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +/* + +PCB Layout +---------- + +KTC A65-02201-201K + + |---------------| +|---| CN1 |---------------------------------------------------| +| | +| LS193 LS374 8048 22-008-03 | +| LS13 LS193 22-050-3B 5.9904MHz | +| | +| | +| | +| | +| | +| | +| | +| | +|-----------------------------------------------------------------------| + +Notes: + All IC's shown. + + 8048 - National Semiconductor INS8048 MCU "8048-132" + 22-008-03 - Exar Semiconductor XR22-008-03 keyboard matrix capacitive readout latch + 22-050-3B - Exar Semiconductor XR22-050-3B keyboard matrix row driver with 4 to 12 decoder/demultiplexer + CN1 - keyboard data connector + + +XR22-008-03 Pinout +------------------ + _____ _____ + D0 1 |* \_/ | 20 Vcc + D1 2 | | 19 _CLR + D2 3 | | 18 Q0 + D3 4 | | 17 Q1 + HYS 5 | 22-008-03 | 16 Q2 + D4 6 | | 15 Q3 + D5 7 | | 14 Q4 + D6 8 | | 13 Q5 + D7 9 | | 12 Q6 + GND 10 |_____________| 11 Q7 + + +XR22-050-3B Pinout +------------------ + _____ _____ + Y8 1 |* \_/ | 20 Vcc + Y9 2 | | 19 Y7 + Y10 3 | | 18 Y6 + Y11 4 | | 17 Y5 + _STB 5 | 22-050-3B | 16 Y4 + A0 6 | | 15 Y3 + A1 7 | | 14 Y2 + A2 8 | | 13 Y1 + A3 9 | | 12 Y0 + GND 10 |_____________| 11 OE? + +*/ + +#include "abc800kb.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define I8048_TAG "i8048" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type ABC800_KEYBOARD = &device_creator<abc800_keyboard_device>; + + +//------------------------------------------------- +// ROM( abc800_keyboard ) +//------------------------------------------------- + +ROM_START( abc800_keyboard ) + ROM_REGION( 0x400, I8048_TAG, 0 ) + ROM_LOAD( "8048-132.z9", 0x0000, 0x0400, CRC(05c4dce5) SHA1(1824c5d304bbd09f97056cfa408e1b18b5219ba2) ) +ROM_END + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *abc800_keyboard_device::device_rom_region() const +{ + return ROM_NAME( abc800_keyboard ); +} + + +//------------------------------------------------- +// ADDRESS_MAP( abc800_keyboard_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc800_keyboard_io, AS_IO, 8, abc800_keyboard_device ) + AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(kb_p1_r, kb_p1_w) + AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(kb_p2_w) + AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(kb_t1_r) +ADDRESS_MAP_END + + +//------------------------------------------------- +// MACHINE_DRIVER( abc800_keyboard ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( abc800_keyboard ) + MCFG_CPU_ADD(I8048_TAG, I8048, XTAL_5_9904MHz) + MCFG_CPU_IO_MAP(abc800_keyboard_io) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor abc800_keyboard_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( abc800_keyboard ); +} + + +//------------------------------------------------- +// INPUT_PORTS( abc800_keyboard ) +//------------------------------------------------- + +INPUT_PORTS_START( abc800_keyboard ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // 80 + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // 81 + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // 82 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 83 + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad RETURN") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // 84 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 85 + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // 18 + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 86 + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("4 \xC2\xA4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR(0x00A4) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("X4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("X5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + + PORT_START("X6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + + PORT_START("X7") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\r') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PF7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + + PORT_START("X8") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u_UMLAUT " " U_UMLAUT) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(0x00FC) PORT_CHAR(0x00DC) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('\'') PORT_CHAR('*') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(TAB)) + + PORT_START("X9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(e_ACUTE " " E_ACUTE) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(0x00E9) PORT_CHAR(0x00C9) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(a_RING " " A_RING) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00E5) PORT_CHAR(0x00C5) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(a_UMLAUT " " A_UMLAUT) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x00E4) PORT_CHAR(0x00C4) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT) + + PORT_START("X10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_CHAR('?') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(o_UMLAUT " " O_UMLAUT) PORT_CODE(KEYCODE_COLON) PORT_CHAR(0x00F6) PORT_CHAR(0x00D6) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // 87 + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // 88 + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // 89 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 8a + + PORT_START("X11") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) // 03 + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) // 23 + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) // 96 + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) // 8b + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // 8c + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // 8d + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // 8e + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 8f +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor abc800_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( abc800_keyboard ); +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// serial_output - +//------------------------------------------------- + +inline void abc800_keyboard_device::serial_output(int state) +{ + if (m_txd != state) + { + m_txd = state; + + m_slot->write_rx(m_txd); + } +} + + +//------------------------------------------------- +// serial_clock - +//------------------------------------------------- + +inline void abc800_keyboard_device::serial_clock() +{ + m_clk = !m_clk; + + m_slot->trxc_w(!m_clk); +} + + +//------------------------------------------------- +// keydown - +//------------------------------------------------- + +inline void abc800_keyboard_device::key_down(int state) +{ + if (m_keydown != state) + { + m_keydown = state; + + m_slot->keydown_w(state); + } +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// abc800_keyboard_device - constructor +//------------------------------------------------- + +abc800_keyboard_device::abc800_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ABC800_KEYBOARD, "ABC-800 Keyboard", tag, owner, clock, "abc800kb", __FILE__), + abc_keyboard_interface(mconfig, *this), + m_maincpu(*this, I8048_TAG), + m_x0(*this, "X0"), + m_x1(*this, "X1"), + m_x2(*this, "X2"), + m_x3(*this, "X3"), + m_x4(*this, "X4"), + m_x5(*this, "X5"), + m_x6(*this, "X6"), + m_x7(*this, "X7"), + m_x8(*this, "X8"), + m_x9(*this, "X9"), + m_x10(*this, "X10"), + m_x11(*this, "X11"), + m_row(0), + m_txd(1), + m_clk(0), + m_stb(1), + m_keydown(1) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void abc800_keyboard_device::device_start() +{ + // allocate timers + m_serial_timer = timer_alloc(); + m_serial_timer->adjust(attotime::from_hz(XTAL_5_9904MHz/(3*5)/20), 0, attotime::from_hz(XTAL_5_9904MHz/(3*5)/20)); // ??? + + // state saving + save_item(NAME(m_row)); + save_item(NAME(m_clk)); + save_item(NAME(m_txd)); + save_item(NAME(m_stb)); + save_item(NAME(m_keydown)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void abc800_keyboard_device::device_reset() +{ +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void abc800_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + serial_clock(); +} + + +//------------------------------------------------- +// txd_w - +//------------------------------------------------- + +void abc800_keyboard_device::txd_w(int state) +{ + m_maincpu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); +} + + +//------------------------------------------------- +// kb_p1_r - keyboard column data read +//------------------------------------------------- + +READ8_MEMBER( abc800_keyboard_device::kb_p1_r ) +{ + UINT8 data = 0xff; + + if (m_stb) + { + switch (m_row) + { + case 0: data = m_x0->read(); break; + case 1: data = m_x1->read(); break; + case 2: data = m_x2->read(); break; + case 3: data = m_x3->read(); break; + case 4: data = m_x4->read(); break; + case 5: data = m_x5->read(); break; + case 6: data = m_x6->read(); break; + case 7: data = m_x7->read(); break; + case 8: data = m_x8->read(); break; + case 9: data = m_x9->read(); break; + case 10: data = m_x10->read(); break; + case 11: data = m_x11->read(); break; + } + } + + return data; +} + + +//------------------------------------------------- +// kb_p1_w - keyboard row write +//------------------------------------------------- + +WRITE8_MEMBER( abc800_keyboard_device::kb_p1_w ) +{ + /* + + bit description + + 0 A0 + 1 A1 + 2 A2 + 3 A3 + 4 ? + 5 ? + 6 + 7 + + */ + + // keyboard row + if (!m_stb) + { + m_row = data & 0x0f; + } +} + + +//------------------------------------------------- +// kb_p2_w - keyboard control write +//------------------------------------------------- + +WRITE8_MEMBER( abc800_keyboard_device::kb_p2_w ) +{ + /* + + bit description + + 0 + 1 + 2 + 3 + 4 TxD + 5 ? + 6 22-008-03 CLR, 22-050-3B STB + 7 22-008-03 HYS + + */ + + // TxD + serial_output(!BIT(data, 4)); + + // keydown + key_down(!BIT(data, 5)); + + // strobe + m_stb = BIT(data, 6); +} + + +//------------------------------------------------- +// kb_t1_r - keyboard T1 timer read +//------------------------------------------------- + +READ8_MEMBER( abc800_keyboard_device::kb_t1_r ) +{ + return m_clk; +} diff --git a/src/emu/bus/abckb/abc800kb.h b/src/emu/bus/abckb/abc800kb.h new file mode 100644 index 00000000000..6428f332f6e --- /dev/null +++ b/src/emu/bus/abckb/abc800kb.h @@ -0,0 +1,93 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-800 keyboard emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __ABC800_KEYBOARD__ +#define __ABC800_KEYBOARD__ + + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "abckb.h" +#include "sound/discrete.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> abc800_keyboard_device + +class abc800_keyboard_device : public device_t, + public abc_keyboard_interface +{ +public: + // construction/destruction + abc800_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + virtual ioport_constructor device_input_ports() const; + + // abc_keyboard_interface overrides + virtual void txd_w(int state); + + // not really public + DECLARE_READ8_MEMBER( kb_p1_r ); + DECLARE_WRITE8_MEMBER( kb_p1_w ); + DECLARE_WRITE8_MEMBER( kb_p2_w ); + DECLARE_READ8_MEMBER( kb_t1_r ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +private: + inline void serial_output(int state); + inline void serial_clock(); + inline void key_down(int state); + + required_device<cpu_device> m_maincpu; + required_ioport m_x0; + required_ioport m_x1; + required_ioport m_x2; + required_ioport m_x3; + required_ioport m_x4; + required_ioport m_x5; + required_ioport m_x6; + required_ioport m_x7; + required_ioport m_x8; + required_ioport m_x9; + required_ioport m_x10; + required_ioport m_x11; + + int m_row; + int m_txd; + int m_clk; + int m_stb; + int m_keydown; + + // timers + emu_timer *m_serial_timer; +}; + + +// device type definition +extern const device_type ABC800_KEYBOARD; + + + +#endif diff --git a/src/emu/bus/abckb/abc99.c b/src/emu/bus/abckb/abc99.c new file mode 100644 index 00000000000..a4272a52213 --- /dev/null +++ b/src/emu/bus/abckb/abc99.c @@ -0,0 +1,783 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-99 keyboard and mouse emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +/* + +Keyboard PCB Layout +------------------- + +|-----------------------------------------------------------------------| +| CN1 CN2 CPU1 ROM1 SW1 | +| | +| 6MHz CPU0 ROM0 GI | +| | +| | +| | +| | +| | +| | +| | +| | +|-----------------------------------------------------------------------| + +Notes: + Relevant IC's shown. + + CPU0 - STMicro ET8035N-6 8035 CPU + CPU1 - STMicro ET8035N-6 8035 CPU + ROM0 - Texas Instruments TMS2516JL-16 2Kx8 ROM "107268-16" + ROM1 - STMicro ET2716Q-1 2Kx8 ROM "107268-17" + GI - General Instruments 321239007 keyboard chip "4=7" + CN1 - DB15 connector, Luxor ABC R8 (3 button mouse) + CN2 - 12 pin PCB header, keyboard data cable + SW1 - reset switch? + +*/ + +/* + + TODO: + + - verify cursor keys + - language DIP + - mouse + - investigate unknown ROMs + - MCS-48 PC:01DC - Unimplemented opcode = 75 + - 75 = ENT0 CLK : enable CLK (unscaled_clock/3) output on T0 + - halt Z2 when Z5 is reset, resume Z2 when Z5 executes ENT0 CLK instruction + +*/ + +#include "abc99.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define I8035_Z2_TAG "z2" +#define I8035_Z5_TAG "z5" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type ABC99 = &device_creator<abc99_device>; + + +//------------------------------------------------- +// ROM( abc99 ) +//------------------------------------------------- + +ROM_START( abc99 ) + ROM_REGION( 0x800, I8035_Z2_TAG, 0 ) + ROM_LOAD( "107268-17.z3", 0x000, 0x800, CRC(2f60cc35) SHA1(ebc6af9cd0a49a0d01698589370e628eebb6221c) ) + + ROM_REGION( 0x800, I8035_Z5_TAG, 0 ) + ROM_LOAD( "107268-16.z6", 0x000, 0x800, CRC(785ec0c6) SHA1(0b261beae20dbc06fdfccc50b19ea48b5b6e22eb) ) + + ROM_REGION( 0x1800, "unknown", 0) + ROM_LOAD( "106819-09.bin", 0x0000, 0x1000, CRC(ffe32a71) SHA1(fa2ce8e0216a433f9bbad0bdd6e3dc0b540f03b7) ) + ROM_LOAD( "107268-64.bin", 0x1000, 0x0800, CRC(e33683ae) SHA1(0c1d9e320f82df05f4804992ef6f6f6cd20623f3) ) +ROM_END + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *abc99_device::device_rom_region() const +{ + return ROM_NAME( abc99 ); +} + + +//------------------------------------------------- +// ADDRESS_MAP( abc99_z2_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc99_z2_mem, AS_PROGRAM, 8, abc99_device ) + AM_RANGE(0x0000, 0x07ff) AM_ROM AM_REGION(I8035_Z2_TAG, 0) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( abc99_z2_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc99_z2_io, AS_IO, 8, abc99_device ) + AM_RANGE(0x21, 0x21) AM_WRITE(z2_led_w) + AM_RANGE(0x30, 0x30) AM_READ_PORT("X0") AM_WRITENOP + AM_RANGE(0x31, 0x31) AM_READ_PORT("X1") AM_WRITENOP + AM_RANGE(0x32, 0x32) AM_READ_PORT("X2") AM_WRITENOP + AM_RANGE(0x33, 0x33) AM_READ_PORT("X3") AM_WRITENOP + AM_RANGE(0x34, 0x34) AM_READ_PORT("X4") AM_WRITENOP + AM_RANGE(0x35, 0x35) AM_READ_PORT("X5") AM_WRITENOP + AM_RANGE(0x36, 0x36) AM_READ_PORT("X6") AM_WRITENOP + AM_RANGE(0x37, 0x37) AM_READ_PORT("X7") AM_WRITENOP + AM_RANGE(0x38, 0x38) AM_READ_PORT("X8") AM_WRITENOP + AM_RANGE(0x39, 0x39) AM_READ_PORT("X9") AM_WRITENOP + AM_RANGE(0x3a, 0x3a) AM_READ_PORT("X10") AM_WRITENOP + AM_RANGE(0x3b, 0x3b) AM_READ_PORT("X11") AM_WRITENOP + AM_RANGE(0x3c, 0x3c) AM_READ_PORT("X12") AM_WRITENOP + AM_RANGE(0x3d, 0x3d) AM_READ_PORT("X13") AM_WRITENOP + AM_RANGE(0x3e, 0x3e) AM_READ_PORT("X14") AM_WRITENOP + AM_RANGE(0x3f, 0x3f) AM_READ_PORT("X15") AM_WRITENOP + AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(z2_p1_w) + AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READ(z2_p2_r) + AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(z2_t0_r) + AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(z2_t1_r) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( abc99_z5_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc99_z5_mem, AS_PROGRAM, 8, abc99_device ) + AM_RANGE(0x0000, 0x07ff) AM_ROM AM_REGION(I8035_Z5_TAG, 0) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( abc99_z5_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc99_z5_io, AS_IO, 8, abc99_device ) +/* AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READ(z5_p1_r) + AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(z5_p2_w) + AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_WRITENOP // Z2 CLK + AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(z5_t1_r)*/ +ADDRESS_MAP_END + + +//------------------------------------------------- +// MACHINE_DRIVER( abc99 ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( abc99 ) + // keyboard CPU + MCFG_CPU_ADD(I8035_Z2_TAG, I8035, XTAL_6MHz/3) // from Z5 T0 output + MCFG_CPU_PROGRAM_MAP(abc99_z2_mem) + MCFG_CPU_IO_MAP(abc99_z2_io) + + // mouse CPU + MCFG_CPU_ADD(I8035_Z5_TAG, I8035, XTAL_6MHz) + MCFG_CPU_PROGRAM_MAP(abc99_z5_mem) + MCFG_CPU_IO_MAP(abc99_z5_io) + MCFG_DEVICE_DISABLE() // HACK fix for broken serial I/O + + // sound hardware + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor abc99_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( abc99 ); +} + + +//------------------------------------------------- +// INPUT_CHANGED_MEMBER( keyboard_reset ) +//------------------------------------------------- + +INPUT_CHANGED_MEMBER( abc99_device::keyboard_reset ) +{ + if (newval) + { + m_mousecpu->reset(); + } +} + + +//------------------------------------------------- +// INPUT_PORTS( abc99 ) +//------------------------------------------------- + +INPUT_PORTS_START( abc99 ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF13") PORT_CODE(KEYCODE_PRTSCR) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT"|") PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\r') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LF") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad CE") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad RETURN") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PRINT") PORT_CODE(KEYCODE_PGUP) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("HELP") PORT_CODE(KEYCODE_HOME) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("X4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF15") PORT_CODE(KEYCODE_PAUSE) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) // cursor B + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) // cursor D + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("X5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF12") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(0x00FC) PORT_CHAR(0x00DC) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\'') PORT_CHAR('*') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + + PORT_START("X6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF14") PORT_CODE(KEYCODE_SCRLOCK) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) // cursor A + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) // cursor C + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + + PORT_START("X7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF11") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(0x00E9) PORT_CHAR(0x00C9) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00E5) PORT_CHAR(0x00C5) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x00E4) PORT_CHAR(0x00C4) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + + PORT_START("X8") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("STOP") PORT_CODE(KEYCODE_END) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("|"UTF8_LEFT) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) + + PORT_START("X9") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_CHAR('?') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(0x00F6) PORT_CHAR(0x00D6) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + + PORT_START("X10") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) + + PORT_START("X11") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + + PORT_START("X12") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("X13") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 \xC2\xA4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR(0x00A4) + + PORT_START("X14") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + + PORT_START("X15") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + + PORT_START("Z14") + PORT_DIPNAME( 0x07, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("Z14:1,2,3") + PORT_DIPSETTING( 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x03, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x05, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x06, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x07, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x08, 0x08, "Keyboard Program" ) PORT_DIPLOCATION("Z14:4") + PORT_DIPSETTING( 0x00, "Internal (8048)" ) + PORT_DIPSETTING( 0x08, "External PROM" ) + + PORT_START("MOUSEB") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_NAME("Left Mouse Button") PORT_CODE(MOUSECODE_BUTTON1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_NAME("Middle Mouse Button") PORT_CODE(MOUSECODE_BUTTON3) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_NAME("Right Mouse Button") PORT_CODE(MOUSECODE_BUTTON2) + + PORT_START("MOUSEX") + PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) + + PORT_START("MOUSEY") + PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) + + PORT_START("J4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_NAME("Keyboard Reset") PORT_CHANGED_MEMBER(DEVICE_SELF, abc99_device, keyboard_reset, 0) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor abc99_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( abc99 ); +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// serial_input - +//------------------------------------------------- + +inline void abc99_device::serial_input() +{ + m_maincpu->set_input_line(MCS48_INPUT_IRQ, (m_si || m_si_en) ? CLEAR_LINE : ASSERT_LINE); + m_mousecpu->set_input_line(MCS48_INPUT_IRQ, m_si ? CLEAR_LINE : ASSERT_LINE); +} + + +//------------------------------------------------- +// serial_output - +//------------------------------------------------- + +inline void abc99_device::serial_output(int state) +{ + if (m_txd != state) + { + m_txd = state; + + m_slot->write_rx(m_txd); + } +} + + +//------------------------------------------------- +// serial_clock - +//------------------------------------------------- + +inline void abc99_device::serial_clock() +{ + m_slot->trxc_w(1); + m_slot->trxc_w(0); +} + + +//------------------------------------------------- +// keydown - +//------------------------------------------------- + +inline void abc99_device::key_down(int state) +{ + if (m_keydown != state) + { + m_slot->keydown_w(state); + m_keydown = state; + } +} + + +//------------------------------------------------- +// scan_mouse - +//------------------------------------------------- + +inline void abc99_device::scan_mouse() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// abc99_device - constructor +//------------------------------------------------- + +abc99_device::abc99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ABC99, "Luxor ABC 99", tag, owner, clock, "abc99", __FILE__), + abc_keyboard_interface(mconfig, *this), + m_maincpu(*this, I8035_Z2_TAG), + m_mousecpu(*this, I8035_Z5_TAG), + m_speaker(*this, "speaker"), + m_z14(*this, "Z14"), + m_mouseb(*this, "MOUSEB"), + m_si(1), + m_si_en(1), + m_so_z2(1), + m_so_z5(1), + m_keydown(0), + m_t1_z2(0), + m_t1_z5(0), + m_led_en(0), + m_reset(1), + m_txd(1) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void abc99_device::device_start() +{ + // allocate timers + m_serial_timer = timer_alloc(TIMER_SERIAL); + m_serial_timer->adjust(MCS48_ALE_CLOCK(XTAL_6MHz/3), 0, MCS48_ALE_CLOCK(XTAL_6MHz/3)); + + m_mouse_timer = timer_alloc(TIMER_MOUSE); + + // state saving + save_item(NAME(m_si)); + save_item(NAME(m_si_en)); + save_item(NAME(m_so_z2)); + save_item(NAME(m_so_z5)); + save_item(NAME(m_keydown)); + save_item(NAME(m_t1_z2)); + save_item(NAME(m_t1_z5)); + save_item(NAME(m_led_en)); + save_item(NAME(m_reset)); + save_item(NAME(m_txd)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void abc99_device::device_reset() +{ + // set EA lines + m_maincpu->set_input_line(MCS48_INPUT_EA, ASSERT_LINE); + m_mousecpu->set_input_line(MCS48_INPUT_EA, ASSERT_LINE); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void abc99_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_SERIAL: + serial_clock(); + break; + + case TIMER_MOUSE: + scan_mouse(); + break; + } +} + + +//------------------------------------------------- +// txd_w - +//------------------------------------------------- + +void abc99_device::txd_w(int state) +{ + if (m_si != state) + { + m_si = state; + serial_input(); + } +} + + +//------------------------------------------------- +// z2_bus_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc99_device::z2_led_w ) +{ + if (m_led_en) return; + + output_set_led_value(LED_1, BIT(data, 0)); + output_set_led_value(LED_2, BIT(data, 1)); + output_set_led_value(LED_3, BIT(data, 2)); + output_set_led_value(LED_4, BIT(data, 3)); + output_set_led_value(LED_5, BIT(data, 4)); + output_set_led_value(LED_6, BIT(data, 5)); + output_set_led_value(LED_7, BIT(data, 6)); + output_set_led_value(LED_8, BIT(data, 7)); +} + + +//------------------------------------------------- +// z2_p1_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc99_device::z2_p1_w ) +{ + /* + + bit description + + P10 serial output + P11 KEY DOWN + P12 transmit -> Z5 T1 + P13 INS led + P14 ALT led + P15 CAPS LOCK led + P16 speaker output + P17 Z8 enable + + */ + + // serial output + m_so_z2 = BIT(data, 0); + serial_output(m_so_z2 && m_so_z5); + + // key down + key_down(!BIT(data, 1)); + + // master T1 + m_t1_z5 = BIT(data, 2); + + // key LEDs + output_set_led_value(LED_INS, BIT(data, 3)); + output_set_led_value(LED_ALT, BIT(data, 4)); + output_set_led_value(LED_CAPS_LOCK, BIT(data, 5)); + + // speaker output + m_speaker->level_w(!BIT(data, 6)); + + // Z8 enable + m_led_en = BIT(data, 7); +} + + +//------------------------------------------------- +// z2_p2_r - +//------------------------------------------------- + +READ8_MEMBER( abc99_device::z2_p2_r ) +{ + /* + + bit description + + P20 + P21 + P22 + P23 + P24 + P25 DIP0 + P26 DIP1 + P27 DIP2 + + */ + + UINT8 data = m_z14->read() << 5; + + return data; +} + + +//------------------------------------------------- +// z2_t0_r - +//------------------------------------------------- + +READ8_MEMBER( abc99_device::z2_t0_r ) +{ + return 1; // 0=mouse connected, 1=no mouse +} + + +//------------------------------------------------- +// z2_t1_r - +//------------------------------------------------- + +READ8_MEMBER( abc99_device::z2_t1_r ) +{ + return m_t1_z2; +} + + +//------------------------------------------------- +// z5_p1_r - +//------------------------------------------------- + +READ8_MEMBER( abc99_device::z5_p1_r ) +{ + /* + + bit description + + P10 XA + P11 XB + P12 YA + P13 YB + P14 LB + P15 MB + P16 RB + P17 input from host + + */ + + UINT8 data = 0; + + // mouse buttons + data |= (m_mouseb->read() & 0x07) << 4; + + // serial input + data |= m_si << 7; + + return data; +} + + +//------------------------------------------------- +// z5_p2_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc99_device::z5_p2_w ) +{ + /* + + bit description + + P20 + P21 + P22 + P23 + P24 Z2 serial input enable + P25 Z2 RESET + P26 serial output + P27 Z2 T1 + + */ + + // serial input enable + int si_en = BIT(data, 4); + + if (m_si_en != si_en) + { + m_si_en = si_en; + serial_input(); + } + + // Z2 reset + int reset = BIT(data, 5); + + if (!m_reset && reset) + { + m_maincpu->reset(); + } + + m_reset = reset; + + // serial output + m_so_z5 = BIT(data, 6); + serial_output(m_so_z2 && m_so_z5); + + // keyboard CPU T1 + m_t1_z2 = BIT(data, 7); +} + + +//------------------------------------------------- +// z5_t1_r - +//------------------------------------------------- + +READ8_MEMBER( abc99_device::z5_t1_r ) +{ + return m_t1_z5; +} diff --git a/src/emu/bus/abckb/abc99.h b/src/emu/bus/abckb/abc99.h new file mode 100644 index 00000000000..e7b01331517 --- /dev/null +++ b/src/emu/bus/abckb/abc99.h @@ -0,0 +1,117 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC-99 keyboard and mouse emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +#pragma once + +#ifndef __ABC99__ +#define __ABC99__ + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "abckb.h" +#include "sound/speaker.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> abc99_device + +class abc99_device : public device_t, + public abc_keyboard_interface +{ +public: + // construction/destruction + abc99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + virtual ioport_constructor device_input_ports() const; + + // abc_keyboard_interface overrides + virtual void txd_w(int state); + + DECLARE_INPUT_CHANGED_MEMBER( keyboard_reset ); + + DECLARE_WRITE8_MEMBER( z2_led_w ); + DECLARE_WRITE8_MEMBER( z2_p1_w ); + DECLARE_READ8_MEMBER( z2_p2_r ); + DECLARE_READ8_MEMBER( z2_t0_r ); + DECLARE_READ8_MEMBER( z2_t1_r ); + DECLARE_READ8_MEMBER( z5_p1_r ); + DECLARE_WRITE8_MEMBER( z5_p2_w ); + DECLARE_READ8_MEMBER( z5_t1_r ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +private: + enum + { + TIMER_SERIAL, + TIMER_MOUSE + }; + + enum + { + LED_1 = 0, + LED_2, + LED_3, + LED_4, + LED_5, + LED_6, + LED_7, + LED_8, + LED_INS, + LED_ALT, + LED_CAPS_LOCK + }; + + inline void serial_input(); + inline void serial_output(int state); + inline void serial_clock(); + inline void key_down(int state); + inline void scan_mouse(); + + emu_timer *m_serial_timer; + emu_timer *m_mouse_timer; + + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_mousecpu; + required_device<speaker_sound_device> m_speaker; + required_ioport m_z14; + required_ioport m_mouseb; + + int m_si; + int m_si_en; + int m_so_z2; + int m_so_z5; + int m_keydown; + int m_t1_z2; + int m_t1_z5; + int m_led_en; + int m_reset; + int m_txd; +}; + + +// device type definition +extern const device_type ABC99; + + + +#endif diff --git a/src/emu/bus/abckb/abckb.c b/src/emu/bus/abckb/abckb.c new file mode 100644 index 00000000000..6cdf605aaf1 --- /dev/null +++ b/src/emu/bus/abckb/abckb.c @@ -0,0 +1,139 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC 800/802/806/1600 keyboard port emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "abckb.h" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +// device type definition +const device_type ABC_KEYBOARD_PORT = &device_creator<abc_keyboard_port_device>; + + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// abc_keyboard_interface - constructor +//------------------------------------------------- + +abc_keyboard_interface::abc_keyboard_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig,device) +{ + m_slot = dynamic_cast<abc_keyboard_port_device *>(device.owner()); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// abc_keyboard_port_device - constructor +//------------------------------------------------- + +abc_keyboard_port_device::abc_keyboard_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, ABC_KEYBOARD_PORT, "Luxor ABC keyboard port", tag, owner, clock, "abc_keyboard_port", __FILE__), + device_slot_interface(mconfig, *this), + m_out_rx_handler(*this), + m_out_trxc_handler(*this), + m_out_keydown_handler(*this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void abc_keyboard_port_device::device_start() +{ + m_card = dynamic_cast<abc_keyboard_interface *>(get_card_device()); + + // resolve callbacks + m_out_rx_handler.resolve_safe(); + m_out_trxc_handler.resolve_safe(); + m_out_keydown_handler.resolve_safe(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void abc_keyboard_port_device::device_reset() +{ + if (m_card != NULL) + get_card_device()->reset(); +} + + +//------------------------------------------------- +// write_rx - +//------------------------------------------------- + +WRITE_LINE_MEMBER( abc_keyboard_port_device::write_rx ) +{ + m_out_rx_handler(state); +} + + +//------------------------------------------------- +// txd_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( abc_keyboard_port_device::txd_w ) +{ + if (m_card != NULL) + m_card->txd_w(state); +} + + +//------------------------------------------------- +// trxc_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( abc_keyboard_port_device::trxc_w ) +{ + m_out_trxc_handler(state); +} + + +//------------------------------------------------- +// keydown_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( abc_keyboard_port_device::keydown_w ) +{ + m_out_keydown_handler(state); +} + + + +//************************************************************************** +// SLOT INTERFACE +//************************************************************************** + +#include "abc800kb.h" +#include "abc77.h" +#include "abc99.h" + +SLOT_INTERFACE_START( abc_keyboard_devices ) + SLOT_INTERFACE("abc800", ABC800_KEYBOARD) + SLOT_INTERFACE("abc55", ABC55) + SLOT_INTERFACE("abc77", ABC77) + SLOT_INTERFACE("abc99", ABC99) +SLOT_INTERFACE_END diff --git a/src/emu/bus/abckb/abckb.h b/src/emu/bus/abckb/abckb.h new file mode 100644 index 00000000000..f9c050b11ed --- /dev/null +++ b/src/emu/bus/abckb/abckb.h @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Luxor ABC 800/802/806/1600 keyboard port emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __ABC_KEYBOARD_PORT__ +#define __ABC_KEYBOARD_PORT__ + +#include "emu.h" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_ABC_KEYBOARD_PORT_ADD(_tag, _def_slot) \ + MCFG_DEVICE_ADD(_tag, ABC_KEYBOARD_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(abc_keyboard_devices, _def_slot, false) + +#define MCFG_ABC_KEYBOARD_OUT_RX_HANDLER(_devcb) \ + devcb = &abc_keyboard_port_device::set_out_rx_handler(*device, DEVCB2_##_devcb); + +#define MCFG_ABC_KEYBOARD_OUT_TRXC_HANDLER(_devcb) \ + devcb = &abc_keyboard_port_device::set_out_trxc_handler(*device, DEVCB2_##_devcb); + +#define MCFG_ABC_KEYBOARD_OUT_KEYDOWN_HANDLER(_devcb) \ + devcb = &abc_keyboard_port_device::set_out_keydown_handler(*device, DEVCB2_##_devcb); + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class abc_keyboard_interface; + +class abc_keyboard_port_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + abc_keyboard_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + template<class _Object> static devcb2_base &set_out_rx_handler(device_t &device, _Object object) { return downcast<abc_keyboard_port_device &>(device).m_out_rx_handler.set_callback(object); } + template<class _Object> static devcb2_base &set_out_trxc_handler(device_t &device, _Object object) { return downcast<abc_keyboard_port_device &>(device).m_out_trxc_handler.set_callback(object); } + template<class _Object> static devcb2_base &set_out_keydown_handler(device_t &device, _Object object) { return downcast<abc_keyboard_port_device &>(device).m_out_keydown_handler.set_callback(object); } + + // computer interface + DECLARE_WRITE_LINE_MEMBER( txd_w ); + + // peripheral interface + DECLARE_WRITE_LINE_MEMBER( write_rx ); + DECLARE_WRITE_LINE_MEMBER( trxc_w ); + DECLARE_WRITE_LINE_MEMBER( keydown_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + devcb2_write_line m_out_rx_handler; + devcb2_write_line m_out_trxc_handler; + devcb2_write_line m_out_keydown_handler; + + abc_keyboard_interface *m_card; +}; + + +class abc_keyboard_interface : public device_slot_card_interface +{ +public: + // construction/destruction + abc_keyboard_interface(const machine_config &mconfig, device_t &device); + + virtual void txd_w(int state) { }; + +protected: + abc_keyboard_port_device *m_slot; +}; + + +// device type definition +extern const device_type ABC_KEYBOARD_PORT; + + +// supported devices +SLOT_INTERFACE_EXTERN( abc_keyboard_devices ); + + + +#endif diff --git a/src/emu/bus/bml3/bml3bus.c b/src/emu/bus/bml3/bml3bus.c new file mode 100644 index 00000000000..d864f2e4f1f --- /dev/null +++ b/src/emu/bus/bml3/bml3bus.c @@ -0,0 +1,257 @@ +/*************************************************************************** + + bml3bus.c - Hitachi MB-6890 slot bus and card emulation + + Adapted from a2bus by Jonathan Edwards + + Pinout (/ indicates an inverted signal, ie, one that would have a bar over it + on a schematic diagram) + + out <-> CPU CPU <-> out + ---------- ----------- + +5V <-- 1 2 <-> GND + D0 <-> 3 4 <-> D1 + D2 <-> 5 6 <-> D3 + D4 <-> 7 8 <-> D5 + D6 <-> 9 10 <-> D7 + A0 <-> 11 12 <-> A1 + A2 <-> 13 14 <-> A3 + A4 <-> 15 16 <-> A5 + A6 <-> 17 18 <-> A7 + A8 <-> 19 20 <-> A9 + A10 <-> 21 22 <-> A11 + A12 <-> 23 24 <-> A13 + A14 <-> 25 26 <-> A15 + BA <-- 27 28 --> BS + /ROM-KIL --> 29 30 --> EXROM-KIL + R/W IN --> 31 32 --> /EX-I/O + R/W OUT <-- 33 34 --> VMA OUT + E <-- 35 36 --> Q + /RES <-- 37 38 <-- /NMI + /IRQ --> 39 40 <-- /FIRQ + /HALT --> 41 42 <-- /VMA CTRL + /DMA --> 43 44 --> /BANK-SW + HALT ACK <-- 45 46 <-- SOUND IN + 16MCK <-- 47 48 <-> GND + 2MCK <-- 49 50 <-> GND + -5V <-- 51 52 --> /EX-I/O2 + -12V <-- 53 54 --> +12V + GND <-> 55 56 --> +5V + +***************************************************************************/ + +#include "emu.h" +#include "emuopts.h" +#include "bml3bus.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type BML3BUS_SLOT = &device_creator<bml3bus_slot_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bml3bus_slot_device - constructor +//------------------------------------------------- +bml3bus_slot_device::bml3bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, BML3BUS_SLOT, "Hitachi MB-6890 Slot", tag, owner, clock, "bml3bus_slot", __FILE__), + device_slot_interface(mconfig, *this) +{ +} + +bml3bus_slot_device::bml3bus_slot_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_slot_interface(mconfig, *this) +{ +} + +void bml3bus_slot_device::static_set_bml3bus_slot(device_t &device, const char *tag, const char *slottag) +{ + bml3bus_slot_device &bml3bus_card = dynamic_cast<bml3bus_slot_device &>(device); + bml3bus_card.m_bml3bus_tag = tag; + bml3bus_card.m_bml3bus_slottag = slottag; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bml3bus_slot_device::device_start() +{ + device_bml3bus_card_interface *dev = dynamic_cast<device_bml3bus_card_interface *>(get_card_device()); + + if (dev) device_bml3bus_card_interface::static_set_bml3bus_tag(*dev, m_bml3bus_tag, m_bml3bus_slottag); +} + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type BML3BUS = &device_creator<bml3bus_device>; + +void bml3bus_device::static_set_cputag(device_t &device, const char *tag) +{ + bml3bus_device &bml3bus = downcast<bml3bus_device &>(device); + bml3bus.m_cputag = tag; +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void bml3bus_device::device_config_complete() +{ + // inherit a copy of the static data + const bml3bus_interface *intf = reinterpret_cast<const bml3bus_interface *>(static_config()); + if (intf != NULL) + { + *static_cast<bml3bus_interface *>(this) = *intf; + } + + // or initialize to defaults if none provided + else + { + memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb)); + memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb)); + memset(&m_out_firq_cb, 0, sizeof(m_out_firq_cb)); + } +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bml3bus_device - constructor +//------------------------------------------------- + +bml3bus_device::bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, BML3BUS, "Hitachi MB-6890 Bus", tag, owner, clock, "bml3bus", __FILE__) +{ +} + +bml3bus_device::bml3bus_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_start - device-specific startup +//------------------------------------------------- + +void bml3bus_device::device_start() +{ + m_maincpu = machine().device<cpu_device>(m_cputag); + + // resolve callbacks + m_out_nmi_func.resolve(m_out_nmi_cb, *this); + m_out_irq_func.resolve(m_out_irq_cb, *this); + m_out_firq_func.resolve(m_out_firq_cb, *this); + + // clear slots + for (int i = 0; i < BML3BUS_MAX_SLOTS; i++) + { + m_device_list[i] = NULL; + } +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void bml3bus_device::device_reset() +{ +} + +device_bml3bus_card_interface *bml3bus_device::get_bml3bus_card(int slot) +{ + if (slot < 0) + { + return NULL; + } + + return m_device_list[slot]; +} + +void bml3bus_device::add_bml3bus_card(int slot, device_bml3bus_card_interface *card) +{ + m_device_list[slot] = card; +} + +void bml3bus_device::set_nmi_line(int state) +{ + m_out_nmi_func(state); +} + +void bml3bus_device::set_irq_line(int state) +{ + m_out_irq_func(state); +} + +void bml3bus_device::set_firq_line(int state) +{ + m_out_firq_func(state); +} + +// interrupt request from bml3bus card +WRITE_LINE_MEMBER( bml3bus_device::nmi_w ) { m_out_nmi_func(state); } +WRITE_LINE_MEMBER( bml3bus_device::irq_w ) { m_out_irq_func(state); } +WRITE_LINE_MEMBER( bml3bus_device::firq_w ) { m_out_firq_func(state); } + +//************************************************************************** +// DEVICE CONFIG BML3BUS CARD INTERFACE +//************************************************************************** + + +//************************************************************************** +// DEVICE BML3BUS CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_bml3bus_card_interface - constructor +//------------------------------------------------- + +device_bml3bus_card_interface::device_bml3bus_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_bml3bus(NULL), + m_bml3bus_tag(NULL) +{ +} + + +//------------------------------------------------- +// ~device_bml3bus_card_interface - destructor +//------------------------------------------------- + +device_bml3bus_card_interface::~device_bml3bus_card_interface() +{ +} + +void device_bml3bus_card_interface::static_set_bml3bus_tag(device_t &device, const char *tag, const char *slottag) +{ + device_bml3bus_card_interface &bml3bus_card = dynamic_cast<device_bml3bus_card_interface &>(device); + bml3bus_card.m_bml3bus_tag = tag; + bml3bus_card.m_bml3bus_slottag = slottag; +} + +void device_bml3bus_card_interface::set_bml3bus_device() +{ + // extract the slot number from the last digit of the slot tag + int tlen = strlen(m_bml3bus_slottag); + + m_slot = (m_bml3bus_slottag[tlen-1] - '1'); + + if (m_slot < 0 || m_slot >= BML3BUS_MAX_SLOTS) + { + fatalerror("Slot %x out of range for Hitachi MB-6890 Bus\n", m_slot); + } + + m_bml3bus = dynamic_cast<bml3bus_device *>(device().machine().device(m_bml3bus_tag)); + m_bml3bus->add_bml3bus_card(m_slot, this); +} diff --git a/src/emu/bus/bml3/bml3bus.h b/src/emu/bus/bml3/bml3bus.h new file mode 100644 index 00000000000..66a5660bbd2 --- /dev/null +++ b/src/emu/bus/bml3/bml3bus.h @@ -0,0 +1,151 @@ +/*************************************************************************** + + bml3bus.h - Hitachi MB-6890 slot bus and card emulation + + Adapted from a2bus by Jonathan Edwards + +***************************************************************************/ + +#pragma once + +#ifndef __BML3BUS_H__ +#define __BML3BUS_H__ + +#include "emu.h" + +#define BML3BUS_MAX_SLOTS 6 + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_BML3BUS_BUS_ADD(_tag, _cputag, _config) \ + MCFG_DEVICE_ADD(_tag, BML3BUS, 0) \ + MCFG_DEVICE_CONFIG(_config) \ + bml3bus_device::static_set_cputag(*device, _cputag); +#define MCFG_BML3BUS_SLOT_ADD(_nbtag, _tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, BML3BUS_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \ + bml3bus_slot_device::static_set_bml3bus_slot(*device, _nbtag, _tag); +#define MCFG_BML3BUS_SLOT_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +#define MCFG_BML3BUS_ONBOARD_ADD(_nbtag, _tag, _dev_type) \ + MCFG_DEVICE_ADD(_tag, _dev_type, 0) \ + device_bml3bus_card_interface::static_set_bml3bus_tag(*device, _nbtag, _tag); + +#define MCFG_BML3BUS_BUS_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bml3bus_device; + +class bml3bus_slot_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + bml3bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + bml3bus_slot_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-level overrides + virtual void device_start(); + + // inline configuration + static void static_set_bml3bus_slot(device_t &device, const char *tag, const char *slottag); +protected: + // configuration + const char *m_bml3bus_tag, *m_bml3bus_slottag; +}; + +// device type definition +extern const device_type BML3BUS_SLOT; + +// ======================> bml3bus_interface + +struct bml3bus_interface +{ + devcb_write_line m_out_nmi_cb; + devcb_write_line m_out_irq_cb; + devcb_write_line m_out_firq_cb; +}; + +class device_bml3bus_card_interface; +// ======================> bml3bus_device +class bml3bus_device : public device_t, + public bml3bus_interface +{ +public: + // construction/destruction + bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + bml3bus_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); + // inline configuration + static void static_set_cputag(device_t &device, const char *tag); + + void add_bml3bus_card(int slot, device_bml3bus_card_interface *card); + device_bml3bus_card_interface *get_bml3bus_card(int slot); + + void set_nmi_line(int state); + void set_irq_line(int state); + void set_firq_line(int state); + + DECLARE_WRITE_LINE_MEMBER( nmi_w ); + DECLARE_WRITE_LINE_MEMBER( irq_w ); + DECLARE_WRITE_LINE_MEMBER( firq_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_config_complete(); + + // internal state + cpu_device *m_maincpu; + + devcb_resolved_write_line m_out_nmi_func; + devcb_resolved_write_line m_out_irq_func; + devcb_resolved_write_line m_out_firq_func; + + device_bml3bus_card_interface *m_device_list[BML3BUS_MAX_SLOTS]; + const char *m_cputag; +}; + + +// device type definition +extern const device_type BML3BUS; + +// ======================> device_bml3bus_card_interface + +// class representing interface-specific live bml3bus card +class device_bml3bus_card_interface : public device_slot_card_interface +{ + friend class bml3bus_device; +public: + // construction/destruction + device_bml3bus_card_interface(const machine_config &mconfig, device_t &device); + virtual ~device_bml3bus_card_interface(); + + device_bml3bus_card_interface *next() const { return m_next; } + + void set_bml3bus_device(); + + void raise_slot_nmi() { m_bml3bus->set_nmi_line(ASSERT_LINE); } + void lower_slot_nmi() { m_bml3bus->set_nmi_line(CLEAR_LINE); } + void raise_slot_irq() { m_bml3bus->set_irq_line(ASSERT_LINE); } + void lower_slot_irq() { m_bml3bus->set_irq_line(CLEAR_LINE); } + void raise_slot_firq() { m_bml3bus->set_firq_line(ASSERT_LINE); } + void lower_slot_firq() { m_bml3bus->set_firq_line(CLEAR_LINE); } + + // inline configuration + static void static_set_bml3bus_tag(device_t &device, const char *tag, const char *slottag); +public: + bml3bus_device *m_bml3bus; + const char *m_bml3bus_tag, *m_bml3bus_slottag; + int m_slot; + device_bml3bus_card_interface *m_next; +}; + +#endif /* __BML3BUS_H__ */ diff --git a/src/emu/bus/bml3/bml3kanji.c b/src/emu/bus/bml3/bml3kanji.c new file mode 100644 index 00000000000..e13f07e28ff --- /dev/null +++ b/src/emu/bus/bml3/bml3kanji.c @@ -0,0 +1,99 @@ +/********************************************************************* + + bml3kanji.c + + Hitachi MP-9740 (?) kanji character ROM for the MB-689x + +*********************************************************************/ + +#include "emu.h" +#include "bml3kanji.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type BML3BUS_KANJI = &device_creator<bml3bus_kanji_device>; + +#define KANJI_ROM_REGION "kanji_rom" + +ROM_START( kanji ) + ROM_REGION( 0x20000, KANJI_ROM_REGION, ROMREGION_ERASEFF ) + ROM_LOAD("kanji.rom", 0x00000, 0x20000, BAD_DUMP CRC(de99a726) SHA1(65fead5d0d779b242f6e0ac25fcc9899dc343101)) +ROM_END + +MACHINE_CONFIG_FRAGMENT( kanji ) + // nothing to add +MACHINE_CONFIG_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor bml3bus_kanji_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( kanji ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *bml3bus_kanji_device::device_rom_region() const +{ + return ROM_NAME( kanji ); +} + +READ8_MEMBER( bml3bus_kanji_device::bml3_kanji_r ) +{ + return m_rom[((UINT32)m_kanji_addr << 1) + offset]; +} + +WRITE8_MEMBER( bml3bus_kanji_device::bml3_kanji_w ) +{ + m_kanji_addr &= (0xff << (offset*8)); + m_kanji_addr |= (data << ((offset^1)*8)); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +bml3bus_kanji_device::bml3bus_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, BML3BUS_KANJI, "Hitachi MP-9740 Kanji Character ROM Card", tag, owner, clock, "bml3kanji", __FILE__), + device_bml3bus_card_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bml3bus_kanji_device::device_start() +{ + // set_bml3bus_device makes m_slot valid + set_bml3bus_device(); + + m_rom = memregion(KANJI_ROM_REGION)->base(); + + // install into memory + address_space &space_prg = machine().firstcpu->space(AS_PROGRAM); + space_prg.install_readwrite_handler(0xff75, 0xff76, read8_delegate( FUNC(bml3bus_kanji_device::bml3_kanji_r), this), write8_delegate(FUNC(bml3bus_kanji_device::bml3_kanji_w), this) ); +} + +void bml3bus_kanji_device::device_reset() +{ + m_kanji_addr = 0; +} diff --git a/src/emu/bus/bml3/bml3kanji.h b/src/emu/bus/bml3/bml3kanji.h new file mode 100644 index 00000000000..91353e001f9 --- /dev/null +++ b/src/emu/bus/bml3/bml3kanji.h @@ -0,0 +1,47 @@ +/********************************************************************* + + bml3kanji.h + + Hitachi MP-9740 (?) kanji character ROM for the MB-689x + +*********************************************************************/ + +#ifndef __BML3BUS_KANJI__ +#define __BML3BUS_KANJI__ + +#include "emu.h" +#include "bml3bus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bml3bus_kanji_device: + public device_t, + public device_bml3bus_card_interface +{ +public: + // construction/destruction + bml3bus_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + DECLARE_READ8_MEMBER(bml3_kanji_r); + DECLARE_WRITE8_MEMBER(bml3_kanji_w); + +protected: + virtual void device_start(); + virtual void device_reset(); + + UINT16 m_kanji_addr; + +private: + UINT8 *m_rom; +}; + +// device type definition +extern const device_type BML3BUS_KANJI; + +#endif /* __BML3BUS_KANJI__ */ diff --git a/src/emu/bus/bml3/bml3mp1802.c b/src/emu/bus/bml3/bml3mp1802.c new file mode 100644 index 00000000000..3d20f77f122 --- /dev/null +++ b/src/emu/bus/bml3/bml3mp1802.c @@ -0,0 +1,155 @@ +/********************************************************************* + + bml3mp1802.c + + Hitachi MP-1802 floppy disk controller card for the MB-6890 + Hitachi MP-3550 floppy drive is attached + +*********************************************************************/ + +#include "emu.h" +#include "bml3mp1802.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type BML3BUS_MP1802 = &device_creator<bml3bus_mp1802_device>; + +static const floppy_interface bml3_mp1802_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_5_25_DSDD, + LEGACY_FLOPPY_OPTIONS_NAME(default), + NULL +}; + +WRITE_LINE_MEMBER( bml3bus_mp1802_device::bml3_wd17xx_intrq_w ) +{ + if (state) { + m_bml3bus->set_nmi_line(PULSE_LINE); + } +} + +const wd17xx_interface bml3_wd17xx_interface = +{ + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, bml3bus_mp1802_device, bml3_wd17xx_intrq_w), + DEVCB_NULL, + {FLOPPY_0, FLOPPY_1} +}; + + +#define MP1802_ROM_REGION "mp1802_rom" + +ROM_START( mp1802 ) + ROM_REGION(0x10000, MP1802_ROM_REGION, 0) + // MP-1802 disk controller ROM, which replaces part of the system ROM + ROM_LOAD( "mp1802.rom", 0xf800, 0x800, BAD_DUMP CRC(8d0dc101) SHA1(92f7d1cebecafa7472e45c4999520de5c01c6dbc)) +ROM_END + +MACHINE_CONFIG_FRAGMENT( mp1802 ) + MCFG_MB8866_ADD("wd17xx", bml3_wd17xx_interface ) + MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(bml3_mp1802_floppy_interface) +MACHINE_CONFIG_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor bml3bus_mp1802_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( mp1802 ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *bml3bus_mp1802_device::device_rom_region() const +{ + return ROM_NAME( mp1802 ); +} + +READ8_MEMBER( bml3bus_mp1802_device::bml3_mp1802_r) +{ + return wd17xx_drq_r(m_wd17xx) ? 0x00 : 0x80; +} + +WRITE8_MEMBER( bml3bus_mp1802_device::bml3_mp1802_w) +{ + int drive = data & 0x03; + int side = BIT(data, 4); + int motor = BIT(data, 3); + const char *floppy_name = NULL; + switch (drive) { + case 0: + floppy_name = FLOPPY_0; + break; + case 1: + floppy_name = FLOPPY_1; + break; + case 2: + floppy_name = FLOPPY_2; + break; + case 3: + floppy_name = FLOPPY_3; + break; + } + device_t *floppy = subdevice(floppy_name); + wd17xx_set_drive(m_wd17xx,drive); + floppy_mon_w(floppy, !motor); + floppy_drive_set_ready_state(floppy, ASSERT_LINE, 0); + wd17xx_set_side(m_wd17xx,side); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +bml3bus_mp1802_device::bml3bus_mp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, BML3BUS_MP1802, "Hitachi MP-1802 Floppy Controller Card", tag, owner, clock, "bml3mp1802", __FILE__), + device_bml3bus_card_interface(mconfig, *this), + m_wd17xx(*this, "wd17xx") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bml3bus_mp1802_device::device_start() +{ + // set_bml3bus_device makes m_slot valid + set_bml3bus_device(); + + m_rom = memregion(MP1802_ROM_REGION)->base(); + + // install into memory + address_space &space_prg = machine().firstcpu->space(AS_PROGRAM); + space_prg.install_legacy_readwrite_handler(m_wd17xx, 0xff00, 0xff03, FUNC(wd17xx_r), FUNC(wd17xx_w)); + space_prg.install_readwrite_handler(0xff04, 0xff04, read8_delegate( FUNC(bml3bus_mp1802_device::bml3_mp1802_r), this), write8_delegate(FUNC(bml3bus_mp1802_device::bml3_mp1802_w), this) ); + // overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work... + UINT8 *mainrom = device().machine().root_device().memregion("maincpu")->base(); + memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800); +} + +void bml3bus_mp1802_device::device_reset() +{ +} diff --git a/src/emu/bus/bml3/bml3mp1802.h b/src/emu/bus/bml3/bml3mp1802.h new file mode 100644 index 00000000000..81301c79661 --- /dev/null +++ b/src/emu/bus/bml3/bml3mp1802.h @@ -0,0 +1,50 @@ +/********************************************************************* + + bml3mp1802.h + + Hitachi MP-1802 floppy disk controller card for the MB-6890 + Hitachi MP-3550 floppy drive is attached + +*********************************************************************/ + +#ifndef __BML3BUS_MP1802__ +#define __BML3BUS_MP1802__ + +#include "emu.h" +#include "bml3bus.h" +#include "imagedev/flopdrv.h" +#include "machine/wd17xx.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bml3bus_mp1802_device: + public device_t, + public device_bml3bus_card_interface +{ +public: + // construction/destruction + bml3bus_mp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + DECLARE_READ8_MEMBER(bml3_mp1802_r); + DECLARE_WRITE8_MEMBER(bml3_mp1802_w); + DECLARE_WRITE_LINE_MEMBER(bml3_wd17xx_intrq_w); +protected: + virtual void device_start(); + virtual void device_reset(); + + required_device<mb8866_device> m_wd17xx; + +private: + UINT8 *m_rom; +}; + +// device type definition +extern const device_type BML3BUS_MP1802; + +#endif /* __BML3BUS_MP1802__ */ diff --git a/src/emu/bus/bml3/bml3mp1805.c b/src/emu/bus/bml3/bml3mp1805.c new file mode 100644 index 00000000000..2fb71c1605a --- /dev/null +++ b/src/emu/bus/bml3/bml3mp1805.c @@ -0,0 +1,178 @@ +/********************************************************************* + + bml3mp1805.c + + Hitachi MP-1805 floppy disk controller card for the MB-6890 + Floppy drive is attached + +*********************************************************************/ + +#include "emu.h" +#include "bml3mp1805.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type BML3BUS_MP1805 = &device_creator<bml3bus_mp1805_device>; + +static const floppy_interface bml3_mp1805_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_3_SSDD, + LEGACY_FLOPPY_OPTIONS_NAME(default), + NULL +}; + +WRITE_LINE_MEMBER( bml3bus_mp1805_device::bml3_mc6843_intrq_w ) +{ + if (state) { + m_bml3bus->set_nmi_line(PULSE_LINE); + } +} + +const mc6843_interface bml3_6843_if = +{ + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, bml3bus_mp1805_device, bml3_mc6843_intrq_w) +}; + + +#define MP1805_ROM_REGION "mp1805_rom" + +ROM_START( mp1805 ) + ROM_REGION(0x10000, MP1805_ROM_REGION, 0) + // MP-1805 disk controller ROM, which replaces part of the system ROM + ROM_LOAD( "mp1805.rom", 0xf800, 0x0800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22)) +ROM_END + +MACHINE_CONFIG_FRAGMENT( mp1805 ) + MCFG_MC6843_ADD( "mc6843", bml3_6843_if ) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(bml3_mp1805_floppy_interface) +MACHINE_CONFIG_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor bml3bus_mp1805_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( mp1805 ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *bml3bus_mp1805_device::device_rom_region() const +{ + return ROM_NAME( mp1805 ); +} + +READ8_MEMBER( bml3bus_mp1805_device::bml3_mp1805_r) +{ + // TODO: read supported or not? + // return mc6843_drq_r(m_mc6843) ? 0x00 : 0x80; + return -1; +} + +WRITE8_MEMBER( bml3bus_mp1805_device::bml3_mp1805_w) +{ + // b7 b6 b5 b4 b3 b2 b1 b0 + // MT ? ? ? D3 D2 D1 D0 + // MT: 0=motor off, 1=motor on + // Dn: 1=select drive <n> + int drive_select = data & 0x0f; + int drive; + // TODO: MESS UI for flipping disk? Note that D88 images are double-sided, but the physical drive is single-sided + int side = 0; + int motor = BIT(data, 7); + const char *floppy_name = NULL; + switch (drive_select) { + case 1: + drive = 0; + break; + case 2: + drive = 1; + break; + case 4: + drive = 2; + break; + case 8: + drive = 3; + break; + default: + // TODO: what's the correct behaviour if more than one drive select bit is set? Or no bit set? + drive = 0; + break; + } + switch (drive) { + case 0: + floppy_name = FLOPPY_0; + break; + case 1: + floppy_name = FLOPPY_1; + break; + case 2: + floppy_name = FLOPPY_2; + break; + case 3: + floppy_name = FLOPPY_3; + break; + } + device_t *floppy = subdevice(floppy_name); + m_mc6843->set_drive(drive); + floppy_mon_w(floppy, motor); + floppy_drive_set_ready_state(floppy, ASSERT_LINE, 0); + m_mc6843->set_side(side); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +bml3bus_mp1805_device::bml3bus_mp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, BML3BUS_MP1805, "Hitachi MP-1805 Floppy Controller Card", tag, owner, clock, "bml3mp1805", __FILE__), + device_bml3bus_card_interface(mconfig, *this), + m_mc6843(*this, "mc6843") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bml3bus_mp1805_device::device_start() +{ + // set_bml3bus_device makes m_slot valid + set_bml3bus_device(); + + m_rom = memregion(MP1805_ROM_REGION)->base(); + + // install into memory + address_space &space_prg = machine().firstcpu->space(AS_PROGRAM); + space_prg.install_readwrite_handler(0xff18, 0xff1f, read8_delegate( FUNC(mc6843_device::read), (mc6843_device*)m_mc6843), write8_delegate(FUNC(mc6843_device::write), (mc6843_device*)m_mc6843) ); + space_prg.install_readwrite_handler(0xff20, 0xff20, read8_delegate( FUNC(bml3bus_mp1805_device::bml3_mp1805_r), this), write8_delegate(FUNC(bml3bus_mp1805_device::bml3_mp1805_w), this) ); + // overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work... + UINT8 *mainrom = device().machine().root_device().memregion("maincpu")->base(); + memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800); +} + +void bml3bus_mp1805_device::device_reset() +{ +} diff --git a/src/emu/bus/bml3/bml3mp1805.h b/src/emu/bus/bml3/bml3mp1805.h new file mode 100644 index 00000000000..4f3ab58e9dd --- /dev/null +++ b/src/emu/bus/bml3/bml3mp1805.h @@ -0,0 +1,52 @@ +/********************************************************************* + + bml3mp1805.h + + Hitachi MP-1805 floppy disk controller card for the MB-6890 + Floppy drive is attached + +*********************************************************************/ + +#ifndef __BML3BUS_MP1805__ +#define __BML3BUS_MP1805__ + +#include "emu.h" +#include "bml3bus.h" +#include "imagedev/flopdrv.h" +#include "machine/mc6843.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bml3bus_mp1805_device: + public device_t, + public device_bml3bus_card_interface +{ +public: + // construction/destruction + bml3bus_mp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + DECLARE_READ8_MEMBER(bml3_mp1805_r); + DECLARE_WRITE8_MEMBER(bml3_mp1805_w); + + DECLARE_WRITE_LINE_MEMBER( bml3_mc6843_intrq_w ); + +protected: + virtual void device_start(); + virtual void device_reset(); + + required_device<mc6843_device> m_mc6843; + +private: + UINT8 *m_rom; +}; + +// device type definition +extern const device_type BML3BUS_MP1805; + +#endif /* __BML3BUS_MP1805__ */ diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index ad7574e0e1d..5677fcf627b 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -705,6 +705,7 @@ BUSOBJS += $(BUSOBJ)/rs232/keyboard.o BUSOBJS += $(BUSOBJ)/rs232/null_modem.o BUSOBJS += $(BUSOBJ)/rs232/rs232.o BUSOBJS += $(BUSOBJ)/rs232/ser_mouse.o +BUSOBJS += $(BUSOBJ)/rs232/teleprinter.o BUSOBJS += $(BUSOBJ)/rs232/terminal.o endif @@ -906,3 +907,94 @@ BUSOBJS += $(BUSOBJ)/gba/gba_slot.o BUSOBJS += $(BUSOBJ)/gba/rom.o endif +#------------------------------------------------- +# +#@src/emu/bus/bml3/bml3bus.h,BUSES += BML3 +#------------------------------------------------- +ifneq ($(filter BML3,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/bml3 +BUSOBJS += $(BUSOBJ)/bml3/bml3bus.o +BUSOBJS += $(BUSOBJ)/bml3/bml3mp1802.o +BUSOBJS += $(BUSOBJ)/bml3/bml3mp1805.o +BUSOBJS += $(BUSOBJ)/bml3/bml3kanji.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/coco/cococart.h,BUSES += COCO +#------------------------------------------------- +ifneq ($(filter COCO,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/coco +BUSOBJS += $(BUSOBJ)/coco/cococart.o +BUSOBJS += $(BUSOBJ)/coco/coco_232.o +BUSOBJS += $(BUSOBJ)/coco/coco_orch90.o +BUSOBJS += $(BUSOBJ)/coco/coco_pak.o +BUSOBJS += $(BUSOBJ)/coco/coco_fdc.o +BUSOBJS += $(BUSOBJ)/coco/coco_multi.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/cpc/cpcexp.h,BUSES += CPC +#------------------------------------------------- +ifneq ($(filter CPC,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/cpc +BUSOBJS += $(BUSOBJ)/cpc/cpcexp.o +BUSOBJS += $(BUSOBJ)/cpc/cpc_ssa1.o +BUSOBJS += $(BUSOBJ)/cpc/cpc_rom.o +BUSOBJS += $(BUSOBJ)/cpc/cpc_pds.o +BUSOBJS += $(BUSOBJ)/cpc/mface2.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/epson_sio/epson_sio.h,BUSES += EPSON_SIO +#------------------------------------------------- +ifneq ($(filter EPSON_SIO,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/epson_sio +BUSOBJS += $(BUSOBJ)/epson_sio/epson_sio.o +BUSOBJS += $(BUSOBJ)/epson_sio/pf10.o +BUSOBJS += $(BUSOBJ)/epson_sio/tf20.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/pce/pce_slot.h,BUSES += PCE +#------------------------------------------------- +ifneq ($(filter PCE,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/pce +BUSOBJS += $(BUSOBJ)/pce/pce_slot.o +BUSOBJS += $(BUSOBJ)/pce/pce_rom.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/x68k/x68kexp.h,BUSES += X68K +#------------------------------------------------- +ifneq ($(filter X68K,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/x68k +BUSOBJS += $(BUSOBJ)/x68k/x68kexp.o +BUSOBJS += $(BUSOBJ)/x68k/x68k_neptunex.o +BUSOBJS += $(BUSOBJ)/x68k/x68k_scsiext.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/abckb/abckb.h,BUSES += ABCKB +#------------------------------------------------- +ifneq ($(filter ABCKB,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/abckb +BUSOBJS += $(BUSOBJ)/abckb/abckb.o +BUSOBJS += $(BUSOBJ)/abckb/abc77.o +BUSOBJS += $(BUSOBJ)/abckb/abc99.o +BUSOBJS += $(BUSOBJ)/abckb/abc800kb.o +endif + +#------------------------------------------------- +# +#@src/emu/bus/compucolor/compclr_flp.h,BUSES += COMPUCOLOR +#------------------------------------------------- +ifneq ($(filter COMPUCOLOR,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/compucolor +BUSOBJS += $(BUSOBJ)/compucolor/floppy.o +endif diff --git a/src/emu/bus/coco/coco_232.c b/src/emu/bus/coco/coco_232.c new file mode 100644 index 00000000000..14cc989f9cd --- /dev/null +++ b/src/emu/bus/coco/coco_232.c @@ -0,0 +1,90 @@ +/*************************************************************************** + + coco_232.c + + Code for emulating the CoCo RS-232 PAK + +***************************************************************************/ + +#include "emu.h" +#include "coco_232.h" + + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +#define UART_TAG "uart" + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + +static MACHINE_CONFIG_FRAGMENT(coco_rs232) + MCFG_DEVICE_ADD(UART_TAG, MOS6551, 0) + MCFG_MOS6551_XTAL(XTAL_1_8432MHz) +MACHINE_CONFIG_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_232 = &device_creator<coco_232_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_232_device - constructor +//------------------------------------------------- + +coco_232_device::coco_232_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COCO_232, "CoCo RS-232 PAK", tag, owner, clock, "coco_232", __FILE__), + device_cococart_interface( mconfig, *this ), + m_uart(*this, UART_TAG) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_232_device::device_start() +{ +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor coco_232_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( coco_rs232 ); +} + +/*------------------------------------------------- + read +-------------------------------------------------*/ + +READ8_MEMBER(coco_232_device::read) +{ + UINT8 result = 0x00; + + if ((offset >= 0x28) && (offset <= 0x2F)) + result = m_uart->read(space, offset - 0x28); + + return result; +} + + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(coco_232_device::write) +{ + if ((offset >= 0x28) && (offset <= 0x2F)) + m_uart->write(space, offset - 0x28, data); +} diff --git a/src/emu/bus/coco/coco_232.h b/src/emu/bus/coco/coco_232.h new file mode 100644 index 00000000000..80d986a010c --- /dev/null +++ b/src/emu/bus/coco/coco_232.h @@ -0,0 +1,40 @@ +#pragma once + +#ifndef __COCO_232_H__ +#define __COCO_232_H__ + +#include "emu.h" +#include "cococart.h" +#include "machine/mos6551.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_232_device + +class coco_232_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_232_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; +protected: + // device-level overrides + virtual void device_start(); + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); +private: + // internal state + required_device<mos6551_device> m_uart; +}; + + +// device type definition +extern const device_type COCO_232; + +#endif /* __COCO_232_H__ */ diff --git a/src/emu/bus/coco/coco_fdc.c b/src/emu/bus/coco/coco_fdc.c new file mode 100644 index 00000000000..d8e559c371a --- /dev/null +++ b/src/emu/bus/coco/coco_fdc.c @@ -0,0 +1,672 @@ +/********************************************************************* + + coco_fdc.c + + CoCo/Dragon FDC + + The CoCo and Dragon both use the Western Digital floppy disk controllers. + The CoCo uses either the WD1793 or the WD1773, the Dragon uses the WD2797, + which mostly uses the same command set with some subtle differences, most + notably the 2797 handles disk side select internally. The Dragon Alpha also + uses the WD2797, however as this is a built in interface and not an external + cartrige, it is dealt with in the main coco.c file. + + The wd's variables are mapped to $FF48-$FF4B on the CoCo and on $FF40-$FF43 + on the Dragon. In addition, there is another register + called DSKREG that controls the interface with the wd1793. DSKREG is + detailed below: But they appear to be + + References: + CoCo: Disk Basic Unravelled + Dragon: Inferences from the PC-Dragon source code + DragonDos Controller, Disk and File Formats by Graham E Kinns + + --------------------------------------------------------------------------- + + DSKREG - the control register + CoCo ($FF40) Dragon ($FF48) + + Bit Bit + 7 halt enable flag 7 not used + 6 drive select #3 6 not used + 5 density (0=single, 1=double) 5 NMI enable flag + and NMI enable flag + 4 write precompensation 4 write precompensation + 3 drive motor activation 3 single density enable + 2 drive select #2 2 drive motor activation + 1 drive select #1 1 drive select high bit + 0 drive select #0 0 drive select low bit + + Reading from $FF48-$FF4F clears bit 7 of DSKREG ($FF40) + + --------------------------------------------------------------------------- + + 2007-02-22, P.Harvey-Smith + + Began implementing the Dragon Delta Dos controler, this was actually the first + Dragon disk controler to market, beating Dragon Data's by a couple of months, + it is based around the WD2791 FDC, which is compatible with the WD1793/WD2797 used + by the standard CoCo and Dragon disk controlers except that it used an inverted + data bus, which is the reason the read/write handlers invert the data. This + controler like, the DragonDos WD2797 is mapped at $FF40-$FF43, in the normal + register order. + + The Delta cart also has a register (74LS174 hex flipflop) at $FF44 encoded as + follows :- + + Bit + 7 not used + 6 not used + 5 not used + 4 Single (0) / Double (1) density select + 3 5.25"(0) / 8"(1) Clock select + 2 Side select + 1 Drive select ms bit + 0 Drive select ls bit + +*********************************************************************/ + +#include "emu.h" +#include "coco_fdc.h" +#include "imagedev/flopdrv.h" +#include "includes/coco.h" +#include "machine/wd17xx.h" +#include "imagedev/flopdrv.h" +#include "formats/coco_dsk.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +#define LOG_FDC 0 +#define WD_TAG "wd17xx" +#define DISTO_TAG "disto" +#define CLOUD9_TAG "cloud9" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +/*************************************************************************** + LOCAL VARIABLES +***************************************************************************/ + +static const floppy_interface coco_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_5_25_DSHD, + LEGACY_FLOPPY_OPTIONS_NAME(coco), + "floppy_5_25", + NULL +}; + + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ +/*------------------------------------------------- + real_time_clock +-------------------------------------------------*/ + +coco_rtc_type_t coco_fdc_device::real_time_clock() +{ + coco_rtc_type_t result = (coco_rtc_type_t) machine().root_device().ioport("real_time_clock")->read_safe(RTC_NONE); + + /* check to make sure we don't have any invalid values */ + if (((result == RTC_DISTO) && (m_disto_msm6242 == NULL)) + || ((result == RTC_CLOUD9) && (m_ds1315 == NULL))) + { + result = RTC_NONE; + } + + return result; +} +/*------------------------------------------------- + fdc_intrq_w - callback from the FDC +-------------------------------------------------*/ + +WRITE_LINE_MEMBER( coco_fdc_device::fdc_intrq_w ) +{ + set_intrq(state); + update_lines(); +} + + +/*------------------------------------------------- + fdc_drq_w - callback from the FDC +-------------------------------------------------*/ + +WRITE_LINE_MEMBER( coco_fdc_device::fdc_drq_w ) +{ + set_drq(state); + update_lines(); +} + + +//************************************************************************** +// COCO FDC +//************************************************************************** + +static const wd17xx_interface coco_wd17xx_interface = +{ + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, coco_fdc_device, fdc_intrq_w), + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, coco_fdc_device, fdc_drq_w), + {FLOPPY_0,FLOPPY_1,FLOPPY_2,FLOPPY_3} +}; + +static MACHINE_CONFIG_FRAGMENT(coco_fdc) + MCFG_WD1773_ADD(WD_TAG, coco_wd17xx_interface) + MCFG_DEVICE_ADD(DISTO_TAG, MSM6242, XTAL_32_768kHz) + MCFG_DS1315_ADD(CLOUD9_TAG) + + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(coco_floppy_interface) +MACHINE_CONFIG_END + +ROM_START( coco_fdc ) + ROM_REGION(0x4000,"eprom",ROMREGION_ERASE00) + ROM_LOAD_OPTIONAL( "disk10.rom", 0x0000, 0x2000, CRC(b4f9968e) SHA1(04115be3f97952b9d9310b52f806d04f80b40d03)) +ROM_END + +const device_type COCO_FDC = &device_creator<coco_fdc_device>; + +//------------------------------------------------- +// coco_fdc_device - constructor +//------------------------------------------------- +coco_fdc_device::coco_fdc_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_cococart_interface( mconfig, *this ) +{ +} + +coco_fdc_device::coco_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COCO_FDC, "CoCo FDC", tag, owner, clock, "coco_fdc", __FILE__), + device_cococart_interface( mconfig, *this ) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_fdc_device::device_start() +{ + m_owner = dynamic_cast<cococart_slot_device *>(owner()); + m_drq = 1; + m_disto_msm6242 = subdevice<msm6242_device>(DISTO_TAG); + m_ds1315 = subdevice<ds1315_device>(CLOUD9_TAG); + m_wd17xx = subdevice(WD_TAG); + m_dskreg = 0x00; + m_intrq = 0; + m_msm6242_rtc_address = 0; +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor coco_fdc_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( coco_fdc ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *coco_fdc_device::device_rom_region() const +{ + return ROM_NAME( coco_fdc ); +} + +/*------------------------------------------------- + get_cart_base +-------------------------------------------------*/ + +UINT8* coco_fdc_device::get_cart_base() +{ + return memregion("eprom")->base(); +} + +/*------------------------------------------------- + update_lines - CoCo specific disk + controller lines +-------------------------------------------------*/ + +void coco_fdc_device::update_lines() +{ + /* clear HALT enable under certain circumstances */ + if ((m_intrq != 0) && (m_dskreg & 0x20)) + m_dskreg &= ~0x80; /* clear halt enable */ + + /* set the NMI line */ + m_owner->cart_set_line(COCOCART_LINE_NMI, + ((m_intrq != 0) && (m_dskreg & 0x20)) ? COCOCART_LINE_VALUE_ASSERT : COCOCART_LINE_VALUE_CLEAR); + + /* set the HALT line */ + m_owner->cart_set_line(COCOCART_LINE_HALT, + ((m_drq == 0) && (m_dskreg & 0x80)) ? COCOCART_LINE_VALUE_ASSERT : COCOCART_LINE_VALUE_CLEAR); +} + +/*------------------------------------------------- + dskreg_w - function to write to CoCo + dskreg +-------------------------------------------------*/ + +void coco_fdc_device::dskreg_w(UINT8 data) +{ + UINT8 drive = 0; + UINT8 head = 0; + + if (LOG_FDC) + { + logerror("fdc_coco_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n", + data & 0x80 ? 'H' : 'h', + data & 0x40 ? '3' : '.', + data & 0x20 ? 'D' : 'S', + data & 0x10 ? 'P' : 'p', + data & 0x08 ? 'M' : 'm', + data & 0x04 ? '2' : '.', + data & 0x02 ? '1' : '.', + data & 0x01 ? '0' : '.', + data); + } + + /* An email from John Kowalski informed me that if the DS3 is + * high, and one of the other drive bits is selected (DS0-DS2), then the + * second side of DS0, DS1, or DS2 is selected. If multiple bits are + * selected in other situations, then both drives are selected, and any + * read signals get yucky. + */ + + if (data & 0x04) + drive = 2; + else if (data & 0x02) + drive = 1; + else if (data & 0x01) + drive = 0; + else if (data & 0x40) + drive = 3; + + device_t *floppy[4]; + + floppy[0] = subdevice(FLOPPY_0); + floppy[1] = subdevice(FLOPPY_1); + floppy[2] = subdevice(FLOPPY_2); + floppy[3] = subdevice(FLOPPY_3); + + for (int i = 0; i < 4; i++) + { + floppy_mon_w(floppy[i], i == drive ? CLEAR_LINE : ASSERT_LINE); + } + + head = ((data & 0x40) && (drive != 3)) ? 1 : 0; + + m_dskreg = data; + + update_lines(); + + wd17xx_set_drive(m_wd17xx, drive); + wd17xx_set_side(m_wd17xx, head); + wd17xx_dden_w(m_wd17xx, !BIT(m_dskreg, 5)); +} + +/*------------------------------------------------- + read +-------------------------------------------------*/ + +READ8_MEMBER(coco_fdc_device::read) +{ + UINT8 result = 0; + + switch(offset & 0xEF) + { + case 8: + result = wd17xx_status_r(m_wd17xx, space, 0); + break; + case 9: + result = wd17xx_track_r(m_wd17xx, space, 0); + break; + case 10: + result = wd17xx_sector_r(m_wd17xx, space, 0); + break; + case 11: + result = wd17xx_data_r(m_wd17xx, space, 0); + break; + } + + /* other stuff for RTCs */ + switch(offset) + { + case 0x10: /* FF50 */ + if (real_time_clock() == RTC_DISTO) + result = m_disto_msm6242->read(space,m_msm6242_rtc_address); + break; + + case 0x38: /* FF78 */ + if (real_time_clock() == RTC_CLOUD9) + m_ds1315->read_0(space, offset); + break; + + case 0x39: /* FF79 */ + if (real_time_clock() == RTC_CLOUD9) + m_ds1315->read_1(space, offset); + break; + + case 0x3C: /* FF7C */ + if (real_time_clock() == RTC_CLOUD9) + result = m_ds1315->read_data(space, offset); + break; + } + return result; +} + + + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(coco_fdc_device::write) +{ + switch(offset & 0x1F) + { + case 0: case 1: case 2: case 3: + case 4: case 5: case 6: case 7: + dskreg_w(data); + break; + case 8: + wd17xx_command_w(m_wd17xx, space, 0, data); + break; + case 9: + wd17xx_track_w(m_wd17xx, space, 0, data); + break; + case 10: + wd17xx_sector_w(m_wd17xx, space, 0, data); + break; + case 11: + wd17xx_data_w(m_wd17xx, space, 0, data); + break; + }; + + /* other stuff for RTCs */ + switch(offset) + { + case 0x10: /* FF50 */ + if (real_time_clock() == RTC_DISTO) + m_disto_msm6242->write(space,m_msm6242_rtc_address, data); + break; + + case 0x11: /* FF51 */ + if (real_time_clock() == RTC_DISTO) + m_msm6242_rtc_address = data & 0x0f; + break; + } +} + + +//************************************************************************** +// DRAGON FDC +//************************************************************************** + +static MACHINE_CONFIG_FRAGMENT(dragon_fdc) + MCFG_WD2797_ADD(WD_TAG, coco_wd17xx_interface) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(coco_floppy_interface) +MACHINE_CONFIG_END + + +ROM_START( dragon_fdc ) + ROM_REGION(0x4000,"eprom",ROMREGION_ERASE00) + ROM_LOAD_OPTIONAL( "ddos10.rom", 0x0000, 0x2000, CRC(b44536f6) SHA1(a8918c71d319237c1e3155bb38620acb114a80bc)) +ROM_END + +const device_type DRAGON_FDC = &device_creator<dragon_fdc_device>; + +//------------------------------------------------- +// dragon_fdc_device - constructor +//------------------------------------------------- +dragon_fdc_device::dragon_fdc_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) + : coco_fdc_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} +dragon_fdc_device::dragon_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : coco_fdc_device(mconfig, DRAGON_FDC, "Dragon FDC", tag, owner, clock, "dragon_fdc", __FILE__) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void dragon_fdc_device::device_start() +{ + m_owner = dynamic_cast<cococart_slot_device *>(owner()); + m_drq = 0; + m_wd17xx = subdevice(WD_TAG); + m_dskreg = 0x00; + m_intrq = 0; + m_msm6242_rtc_address = 0; +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor dragon_fdc_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( dragon_fdc ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *dragon_fdc_device::device_rom_region() const +{ + return ROM_NAME( dragon_fdc ); +} + + + +/*------------------------------------------------- + update_lines - Dragon specific disk + controller lines +-------------------------------------------------*/ + +void dragon_fdc_device::update_lines() +{ + /* set the NMI line */ + m_owner->cart_set_line(COCOCART_LINE_NMI, + ((m_intrq != 0) && (m_dskreg & 0x20)) ? COCOCART_LINE_VALUE_ASSERT : COCOCART_LINE_VALUE_CLEAR); + + /* set the CART line */ + m_owner->cart_set_line(COCOCART_LINE_CART, + (m_drq != 0) ? COCOCART_LINE_VALUE_ASSERT : COCOCART_LINE_VALUE_CLEAR); +} + + +/*------------------------------------------------- + dskreg_w - function to write to + Dragon dskreg +-------------------------------------------------*/ + +void dragon_fdc_device::dskreg_w(UINT8 data) +{ + if (LOG_FDC) + { + logerror("fdc_dragon_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n", + data & 0x80 ? 'X' : 'x', + data & 0x40 ? 'X' : 'x', + data & 0x20 ? 'N' : 'n', + data & 0x10 ? 'P' : 'p', + data & 0x08 ? 'S' : 'D', + data & 0x04 ? 'M' : 'm', + data & 0x02 ? '1' : '0', + data & 0x01 ? '1' : '0', + data); + } + + if (data & 0x04) + wd17xx_set_drive(m_wd17xx, data & 0x03); + + wd17xx_dden_w(m_wd17xx, BIT(data, 3)); + m_dskreg = data; +} + + + +/*------------------------------------------------- + read +-------------------------------------------------*/ + +READ8_MEMBER(dragon_fdc_device::read) +{ + UINT8 result = 0; + switch(offset & 0xEF) + { + case 0: + result = wd17xx_status_r(m_wd17xx, space, 0); + break; + case 1: + result = wd17xx_track_r(m_wd17xx, space, 0); + break; + case 2: + result = wd17xx_sector_r(m_wd17xx, space, 0); + break; + case 3: + result = wd17xx_data_r(m_wd17xx, space, 0); + break; + } + return result; +} + + + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(dragon_fdc_device::write) +{ + switch(offset & 0xEF) + { + case 0: + wd17xx_command_w(m_wd17xx, space, 0, data); + + /* disk head is encoded in the command byte */ + /* Only for type 3 & 4 commands */ + if (data & 0x80) + wd17xx_set_side(m_wd17xx, (data & 0x02) ? 1 : 0); + break; + case 1: + wd17xx_track_w(m_wd17xx, space, 0, data); + break; + case 2: + wd17xx_sector_w(m_wd17xx, space, 0, data); + break; + case 3: + wd17xx_data_w(m_wd17xx, space, 0, data); + break; + case 8: case 9: case 10: case 11: + case 12: case 13: case 14: case 15: + dskreg_w(data); + break; + }; +} + +//************************************************************************** +// SDTANDY FDC +//************************************************************************** + +ROM_START( sdtandy_fdc ) + ROM_REGION(0x4000,"eprom",ROMREGION_ERASE00) + ROM_LOAD_OPTIONAL( "sdtandy.rom", 0x0000, 0x2000, CRC(5d7779b7) SHA1(ca03942118f2deab2f6c8a89b8a4f41f2d0b94f1)) +ROM_END + +const device_type SDTANDY_FDC = &device_creator<sdtandy_fdc_device>; + +//------------------------------------------------- +// sdtandy_fdc_device - constructor +//------------------------------------------------- + +sdtandy_fdc_device::sdtandy_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : dragon_fdc_device(mconfig, SDTANDY_FDC, "SDTANDY FDC", tag, owner, clock, "sdtandy_fdc", __FILE__) +{ +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *sdtandy_fdc_device::device_rom_region() const +{ + return ROM_NAME( sdtandy_fdc ); +} + +//************************************************************************** +// COCO FDC v1.1 +//************************************************************************** + +ROM_START( coco_fdc_v11 ) + ROM_REGION(0x8000,"eprom",ROMREGION_ERASE00) + ROM_LOAD_OPTIONAL( "disk11.rom", 0x0000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1)) + ROM_RELOAD(0x2000, 0x2000) + ROM_RELOAD(0x4000, 0x2000) + ROM_RELOAD(0x6000, 0x2000) +ROM_END + +const device_type COCO_FDC_V11 = &device_creator<coco_fdc_v11_device>; + +//------------------------------------------------- +// coco_fdc_v11_device - constructor +//------------------------------------------------- + +coco_fdc_v11_device::coco_fdc_v11_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : coco_fdc_device(mconfig, COCO_FDC_V11, "CoCo FDC v1.1", tag, owner, clock, "coco_fdc_v11", __FILE__) +{ +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *coco_fdc_v11_device::device_rom_region() const +{ + return ROM_NAME( coco_fdc_v11 ); +} + +//************************************************************************** +// CP400 FDC +//************************************************************************** + +ROM_START( cp400_fdc ) + ROM_REGION(0x4000,"eprom",ROMREGION_ERASE00) + ROM_LOAD("cp400dsk.rom", 0x0000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b)) +ROM_END + +const device_type CP400_FDC = &device_creator<cp400_fdc_device>; + +//------------------------------------------------- +// cp400_fdc_device - constructor +//------------------------------------------------- + +cp400_fdc_device::cp400_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : coco_fdc_device(mconfig, CP400_FDC, "CP400 FDC", tag, owner, clock, "cp400_fdc", __FILE__) +{ +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *cp400_fdc_device::device_rom_region() const +{ + return ROM_NAME( cp400_fdc ); +} diff --git a/src/emu/bus/coco/coco_fdc.h b/src/emu/bus/coco/coco_fdc.h new file mode 100644 index 00000000000..6e82ca4646d --- /dev/null +++ b/src/emu/bus/coco/coco_fdc.h @@ -0,0 +1,155 @@ +#pragma once + +#ifndef __COCO_FDC_H__ +#define __COCO_FDC_H__ + +#include "emu.h" +#include "cococart.h" +#include "machine/msm6242.h" +#include "machine/ds1315.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_rtc_type_t + +enum coco_rtc_type_t +{ + RTC_DISTO = 0x00, + RTC_CLOUD9 = 0x01, + + RTC_NONE = 0xFF +}; + +// ======================> coco_fdc_device + +class coco_fdc_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + coco_fdc_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); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + virtual UINT8* get_cart_base(); + + virtual void update_lines(); + virtual void dskreg_w(UINT8 data); + + void set_intrq(UINT8 val) { m_intrq = val; } + void set_drq(UINT8 val) { m_drq = val; } + + DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); +protected: + // device-level overrides + virtual void device_start(); + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + + coco_rtc_type_t real_time_clock(); + + // internal state + cococart_slot_device *m_owner; + + UINT8 m_dskreg; + UINT8 m_drq : 1; + UINT8 m_intrq : 1; + + device_t *m_wd17xx; /* WD17xx */ + ds1315_device *m_ds1315; /* DS1315 */ + + /* Disto RTC */ + msm6242_device *m_disto_msm6242; /* 6242 RTC on Disto interface */ + offs_t m_msm6242_rtc_address; +}; + + +// device type definition +extern const device_type COCO_FDC; + +// ======================> coco_fdc_v11_device + +class coco_fdc_v11_device : + public coco_fdc_device +{ +public: + // construction/destruction + coco_fdc_v11_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; +}; + + +// device type definition +extern const device_type COCO_FDC_V11; + +// ======================> cp400_fdc_device + +class cp400_fdc_device : + public coco_fdc_device +{ +public: + // construction/destruction + cp400_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; +}; + + +// device type definition +extern const device_type CP400_FDC; + +// ======================> dragon_fdc_device + +class dragon_fdc_device : + public coco_fdc_device +{ +public: + // construction/destruction + dragon_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + dragon_fdc_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); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + virtual void update_lines(); + virtual void dskreg_w(UINT8 data); +protected: + // device-level overrides + virtual void device_start(); + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); +private: +}; + + +// device type definition +extern const device_type DRAGON_FDC; + +// ======================> sdtandy_fdc_device + +class sdtandy_fdc_device : + public dragon_fdc_device +{ +public: + // construction/destruction + sdtandy_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; +}; + + +// device type definition +extern const device_type SDTANDY_FDC; + +#endif /* __COCO_FDC_H__ */ diff --git a/src/emu/bus/coco/coco_multi.c b/src/emu/bus/coco/coco_multi.c new file mode 100644 index 00000000000..0f71766b516 --- /dev/null +++ b/src/emu/bus/coco/coco_multi.c @@ -0,0 +1,266 @@ +/*************************************************************************** + + coco_multi.c + + Code for emulating CoCo's Multi-Pak Interface + + The Multi-Pak interface multiplexes all I/O lines from the Color + Computer's expansion port to four identical ports. All I/O lines + are continuously multiplexed except: + + Pin 36 - *SCS + Pin 32 - *CTS + Pin 8 - *CART + + These I/O lines are switched in one of two ways. First, is the front + panel, four position switch. When adjusted the switch will direct the + MPI to target these three I/O lines to the selected slot. + + Second, the MPI will listen to writes to 0xff7f and respond accordingly: + + bit 0 --\___ Target *SCS to this slot number + bit 1 --/ + bit 2 ------ Ignore + bit 3 ------ Ignore + bit 4 --\___ Target *CTS and *CART to this slot number + bit 5 --/ + bit 6 ------ Ignore + bit 7 ------ Ignore + + After writing to 0xff7f, the position of the physical switch has no + effect until reset. + + Reading is supported on 0xff7f. It will reflect the position of the + physical switch. Until data is written to 0xff7f, then it will only + reflect what has been written until a reset. + + A common modification users of the OS-9 operating system made was to + tie all of the *CART pins together on the MPI motherboard. The *CART + line is connected to the 6809's IRQ line. This allowed any hardware + device in any slot to signal an IRQ to the CPU, no matter what the + switch position was. OS-9 was designed from the very start to poll + each device attached on every IRQ signal. + + Because of sloppy address decoding the original MPI also responds to + $FF9F. No software is known to take advantage of this. After the + introduction of the CoCo 3, which uses $FF9F internally, Tandy provided + free upgrades to any MPI to fix this problem. + + +***************************************************************************/ + +#include "emu.h" +#include "includes/coco.h" +#include "coco_multi.h" +#include "coco_232.h" +#include "coco_orch90.h" +#include "coco_pak.h" +#include "coco_fdc.h" + +#define SLOT1_TAG "slot1" +#define SLOT2_TAG "slot2" +#define SLOT3_TAG "slot3" +#define SLOT4_TAG "slot4" + + + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + +static SLOT_INTERFACE_START(coco_cart_slot1_3) + SLOT_INTERFACE("rs232", COCO_232) + SLOT_INTERFACE("orch90", COCO_ORCH90) + SLOT_INTERFACE("banked_16k", COCO_PAK_BANKED) + SLOT_INTERFACE("pak", COCO_PAK) +SLOT_INTERFACE_END +static SLOT_INTERFACE_START(coco_cart_slot4) + SLOT_INTERFACE("fdcv11", COCO_FDC_V11) + SLOT_INTERFACE("rs232", COCO_232) + SLOT_INTERFACE("orch90", COCO_ORCH90) + SLOT_INTERFACE("banked_16k", COCO_PAK_BANKED) + SLOT_INTERFACE("pak", COCO_PAK) +SLOT_INTERFACE_END + +WRITE_LINE_MEMBER(coco_multipak_device::multi_cart_w) +{ + cococart_slot_device *cart = dynamic_cast<cococart_slot_device *>(owner()); + cart->m_cart_callback.writeline(this,state); +} + +WRITE_LINE_MEMBER(coco_multipak_device::multi_nmi_w) +{ + cococart_slot_device *cart = dynamic_cast<cococart_slot_device *>(owner()); + cart->m_nmi_callback.writeline(this,state); +} + +WRITE_LINE_MEMBER(coco_multipak_device::multi_halt_w) +{ + cococart_slot_device *cart = dynamic_cast<cococart_slot_device *>(owner()); + cart->m_halt_callback.writeline(this,state); +} + +static const cococart_interface multi_cococart_interface = +{ + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, coco_multipak_device, multi_cart_w), + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, coco_multipak_device, multi_nmi_w), + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, coco_multipak_device, multi_halt_w) +}; + +static MACHINE_CONFIG_FRAGMENT(coco_multi) + MCFG_COCO_CARTRIDGE_ADD(SLOT1_TAG, multi_cococart_interface, coco_cart_slot1_3, NULL) + MCFG_COCO_CARTRIDGE_ADD(SLOT2_TAG, multi_cococart_interface, coco_cart_slot1_3, NULL) + MCFG_COCO_CARTRIDGE_ADD(SLOT3_TAG, multi_cococart_interface, coco_cart_slot1_3, NULL) + MCFG_COCO_CARTRIDGE_ADD(SLOT4_TAG, multi_cococart_interface, coco_cart_slot4, "fdcv11") +MACHINE_CONFIG_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_MULTIPAK = &device_creator<coco_multipak_device>; + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_multipak_device - constructor +//------------------------------------------------- + +coco_multipak_device::coco_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COCO_MULTIPAK, "CoCo Multi-Pak Interface", tag, owner, clock, "coco_multipak", __FILE__), + device_cococart_interface( mconfig, *this ) +{ +} + + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_multipak_device::device_start() +{ + // identify slots + m_slots[0] = dynamic_cast<cococart_slot_device *>(subdevice(SLOT1_TAG)); + m_slots[1] = dynamic_cast<cococart_slot_device *>(subdevice(SLOT2_TAG)); + m_slots[2] = dynamic_cast<cococart_slot_device *>(subdevice(SLOT3_TAG)); + m_slots[3] = dynamic_cast<cococart_slot_device *>(subdevice(SLOT4_TAG)); + m_owner = dynamic_cast<cococart_slot_device *>(owner()); + + // install $FF7F handler + write8_delegate wh = write8_delegate(FUNC(coco_multipak_device::ff7f_write), this); + machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM).install_write_handler(0xFF7F, 0xFF7F, wh); + + // initial state + m_select = 0xFF; + + // save state + save_item(NAME(m_select)); +} + + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void coco_multipak_device::device_reset() +{ + m_select = 0xFF; +} + + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor coco_multipak_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( coco_multi ); +} + + + +//------------------------------------------------- +// get_cart_base +//------------------------------------------------- + +UINT8* coco_multipak_device::get_cart_base() +{ + return active_cts_slot()->get_cart_base(); +} + + + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(coco_multipak_device::read) +{ + return active_scs_slot()->read(space,offset); +} + + + +//------------------------------------------------- +// write +//------------------------------------------------- + +WRITE8_MEMBER(coco_multipak_device::write) +{ + active_scs_slot()->write(space,offset,data); +} + + + +//------------------------------------------------- +// ff7f_write +//------------------------------------------------- + +WRITE8_MEMBER(coco_multipak_device::ff7f_write) +{ + set_select(data); +} + + + +//------------------------------------------------- +// set_select +//------------------------------------------------- + +void coco_multipak_device::set_select(UINT8 new_select) +{ + UINT8 xorval = m_select ^ new_select; + m_select = new_select; + if (xorval & 0x30) + cart_base_changed(); +} + + + +//------------------------------------------------- +// active_scs_slot +//------------------------------------------------- + +cococart_slot_device *coco_multipak_device::active_scs_slot(void) +{ + return m_slots[(m_select >> 0) & 0x03]; +} + + + +//------------------------------------------------- +// active_cts_slot +//------------------------------------------------- + +cococart_slot_device *coco_multipak_device::active_cts_slot(void) +{ + return m_slots[(m_select >> 4) & 0x03]; +} diff --git a/src/emu/bus/coco/coco_multi.h b/src/emu/bus/coco/coco_multi.h new file mode 100644 index 00000000000..f16ebe7cc5d --- /dev/null +++ b/src/emu/bus/coco/coco_multi.h @@ -0,0 +1,67 @@ +/*************************************************************************** + + coco_multi.h + + Multi-Pak interface emulation + +***************************************************************************/ + +#pragma once + +#ifndef __COCO_MULTI_H__ +#define __COCO_MULTI_H__ + +#include "emu.h" +#include "cococart.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_multipak_device + +class coco_multipak_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + + virtual UINT8* get_cart_base(); + + DECLARE_WRITE_LINE_MEMBER(multi_cart_w); + DECLARE_WRITE_LINE_MEMBER(multi_nmi_w); + DECLARE_WRITE_LINE_MEMBER(multi_halt_w); +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + +private: + // device references + cococart_slot_device *m_owner; + cococart_slot_device *m_slots[4]; + + // internal state + UINT8 m_select; + + // methods + DECLARE_WRITE8_MEMBER(ff7f_write); + cococart_slot_device *active_scs_slot(void); + cococart_slot_device *active_cts_slot(void); + void set_select(UINT8 new_select); +}; + + +// device type definition +extern const device_type COCO_MULTIPAK; + +#endif /* __COCO_MULTI_H__ */ diff --git a/src/emu/bus/coco/coco_orch90.c b/src/emu/bus/coco/coco_orch90.c new file mode 100644 index 00000000000..ba1aa29cf69 --- /dev/null +++ b/src/emu/bus/coco/coco_orch90.c @@ -0,0 +1,83 @@ +/*************************************************************************** + + orch90.c + + Code for emulating the CoCo Orch-90 (Orchestra 90) sound cartridge + + The Orch-90 was a simple sound cartridge; it had two 8-bit DACs + supporting stereo sound. The left channel was at $FF7A, and the right + channel was at $FF7B + +***************************************************************************/ + +#include "emu.h" +#include "coco_orch90.h" +#include "sound/dac.h" + +static MACHINE_CONFIG_FRAGMENT(coco_orch90) + MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") + MCFG_SOUND_ADD("dac_left", DAC, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0) + MCFG_SOUND_ADD("dac_right", DAC, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) +MACHINE_CONFIG_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_ORCH90 = &device_creator<coco_orch90_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_orch90_device - constructor +//------------------------------------------------- + +coco_orch90_device::coco_orch90_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COCO_ORCH90, "CoCo Orch-90 PAK", tag, owner, clock, "coco_orch90", __FILE__), + device_cococart_interface( mconfig, *this ) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_orch90_device::device_start() +{ + m_left_dac = subdevice<dac_device>("dac_left"); + m_right_dac = subdevice<dac_device>("dac_right"); +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor coco_orch90_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( coco_orch90 ); +} + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(coco_orch90_device::write) +{ + switch(offset) + { + case 0x3A: + /* left channel write */ + m_left_dac->write_unsigned8(data); + break; + + case 0x3B: + /* right channel write */ + m_right_dac->write_unsigned8(data); + break; + } +} diff --git a/src/emu/bus/coco/coco_orch90.h b/src/emu/bus/coco/coco_orch90.h new file mode 100644 index 00000000000..b7e27f43f32 --- /dev/null +++ b/src/emu/bus/coco/coco_orch90.h @@ -0,0 +1,40 @@ +#pragma once + +#ifndef __COCO_ORCH90_H__ +#define __COCO_ORCH90_H__ + +#include "emu.h" +#include "sound/dac.h" +#include "cococart.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_orch90_device + +class coco_orch90_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_orch90_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; +protected: + // device-level overrides + virtual void device_start(); + virtual DECLARE_WRITE8_MEMBER(write); +private: + // internal state + dac_device *m_left_dac; + dac_device *m_right_dac; +}; + + +// device type definition +extern const device_type COCO_ORCH90; + +#endif /* __COCO_ORCH90_H__ */ diff --git a/src/emu/bus/coco/coco_pak.c b/src/emu/bus/coco/coco_pak.c new file mode 100644 index 00000000000..f106d7617cc --- /dev/null +++ b/src/emu/bus/coco/coco_pak.c @@ -0,0 +1,178 @@ +/*************************************************************************** + + coco_pak.c + + Code for emulating standard CoCo cartridges + +***************************************************************************/ + +#include "emu.h" +#include "coco_pak.h" +#include "includes/coco.h" +#include "imagedev/cartslot.h" + +#define CARTSLOT_TAG "cart" + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + +static MACHINE_CONFIG_FRAGMENT(coco_pak) +MACHINE_CONFIG_END + +ROM_START( coco_pak ) + ROM_REGION(0x8000,CARTSLOT_TAG,ROMREGION_ERASE00) + ROM_CART_LOAD(CARTSLOT_TAG, 0x0000, 0x8000, ROM_OPTIONAL | ROM_MIRROR) +ROM_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_PAK = &device_creator<coco_pak_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_pak_device - constructor +//------------------------------------------------- +coco_pak_device::coco_pak_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_cococart_interface( mconfig, *this ) +{ +} + +coco_pak_device::coco_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COCO_PAK, "CoCo Program PAK", tag, owner, clock, "cocopak", __FILE__), + device_cococart_interface( mconfig, *this ) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_pak_device::device_start() +{ + m_cart = dynamic_cast<device_image_interface *>(owner()); + m_owner = dynamic_cast<cococart_slot_device *>(owner()); +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor coco_pak_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( coco_pak ); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *coco_pak_device::device_rom_region() const +{ + return ROM_NAME( coco_pak ); +} + +/*------------------------------------------------- + device_reset - device-specific startup +-------------------------------------------------*/ + +void coco_pak_device::device_reset() +{ + if (m_cart->exists()) { + cococart_line_value cart_line; + + cart_line = machine().root_device().ioport(CART_AUTOSTART_TAG)->read_safe(0x01) + ? COCOCART_LINE_VALUE_Q + : COCOCART_LINE_VALUE_CLEAR; + + /* normal CoCo PAKs tie their CART line to Q - the system clock */ + m_owner->cart_set_line(COCOCART_LINE_CART,cart_line); + } +} + +/*------------------------------------------------- + get_cart_base +-------------------------------------------------*/ + +UINT8* coco_pak_device::get_cart_base() +{ + return memregion(CARTSLOT_TAG)->base(); +} + +/*************************************************************************** + BANKED CARTRIDGES +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_PAK_BANKED = &device_creator<coco_pak_banked_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_pak_device - constructor +//------------------------------------------------- + +coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : coco_pak_device(mconfig, COCO_PAK_BANKED, "CoCo Program PAK (Banked)", tag, owner, clock, "cocopak_banked", __FILE__) +{ +} + +/*------------------------------------------------- + device_reset - device-specific startup +-------------------------------------------------*/ + +void coco_pak_banked_device::device_reset() +{ + coco_pak_device::device_reset(); + + banked_pak_set_bank(0); +} + +/*------------------------------------------------- + banked_pak_set_bank - function to set the bank +-------------------------------------------------*/ + +void coco_pak_banked_device::banked_pak_set_bank(UINT32 bank) +{ + UINT64 pos; + UINT32 i; + UINT8 *rom = memregion(CARTSLOT_TAG)->base(); + UINT32 rom_length = memregion(CARTSLOT_TAG)->bytes(); + + if (m_cart->exists()) { + pos = (bank * 0x4000) % m_cart->length(); + + for (i = 0; i < rom_length / 0x4000; i++) + { + m_cart->fseek(pos, SEEK_SET); + m_cart->fread(&rom[i * 0x4000], 0x4000); + } + } +} + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(coco_pak_banked_device::write) +{ + switch(offset) + { + case 0: + /* set the bank */ + banked_pak_set_bank(data); + break; + } +} diff --git a/src/emu/bus/coco/coco_pak.h b/src/emu/bus/coco/coco_pak.h new file mode 100644 index 00000000000..67f580f6daf --- /dev/null +++ b/src/emu/bus/coco/coco_pak.h @@ -0,0 +1,63 @@ +#pragma once + +#ifndef __COCO_PAK_H__ +#define __COCO_PAK_H__ + +#include "emu.h" +#include "cococart.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_pak_device + +class coco_pak_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + coco_pak_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); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + virtual UINT8* get_cart_base(); +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // internal state + device_image_interface *m_cart; + cococart_slot_device *m_owner; +}; + + +// device type definition +extern const device_type COCO_PAK; + +// ======================> coco_pak_banked_device + +class coco_pak_banked_device : + public coco_pak_device +{ +public: + // construction/destruction + coco_pak_banked_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // device-level overrides + virtual void device_reset(); + virtual DECLARE_WRITE8_MEMBER(write); +private: + void banked_pak_set_bank(UINT32 bank); +}; + + +// device type definition +extern const device_type COCO_PAK_BANKED; +#endif /* __COCO_PAK_H__ */ diff --git a/src/emu/bus/coco/cococart.c b/src/emu/bus/coco/cococart.c new file mode 100644 index 00000000000..85c8844e0e0 --- /dev/null +++ b/src/emu/bus/coco/cococart.c @@ -0,0 +1,459 @@ +/********************************************************************* + + cococart.c + + CoCo/Dragon cartridge management + +*********************************************************************/ + +#include "emu.h" +#include "cococart.h" +#include "emuopts.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +#define LOG_LINE 0 + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCOCART_SLOT = &device_creator<cococart_slot_device>; + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// cococart_slot_device - constructor +//------------------------------------------------- +cococart_slot_device::cococart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, COCOCART_SLOT, "CoCo Cartridge Slot", tag, owner, clock, "cococart_slot", __FILE__), + device_slot_interface(mconfig, *this), + device_image_interface(mconfig, *this) +{ +} + + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cococart_slot_device::device_start() +{ + for(int i=0; i<TIMER_POOL; i++ ) + { + m_cart_line.timer[i] = timer_alloc(TIMER_CART); + m_nmi_line.timer[i] = timer_alloc(TIMER_NMI); + m_halt_line.timer[i] = timer_alloc(TIMER_HALT); + } + + m_cart_line.timer_index = 0; + m_cart_line.delay = 0; + m_cart_line.value = COCOCART_LINE_VALUE_CLEAR; + m_cart_line.line = 0; + m_cart_line.q_count = 0; + m_cart_line.callback.resolve(m_cart_callback, *this); + + m_nmi_line.timer_index = 0; + /* 12 allowed one more instruction to finished after the line is pulled */ + m_nmi_line.delay = 12; + m_nmi_line.value = COCOCART_LINE_VALUE_CLEAR; + m_nmi_line.line = 0; + m_nmi_line.q_count = 0; + m_nmi_line.callback.resolve(m_nmi_callback, *this); + + m_halt_line.timer_index = 0; + /* 6 allowed one more instruction to finished after the line is pulled */ + m_halt_line.delay = 6; + m_halt_line.value = COCOCART_LINE_VALUE_CLEAR; + m_halt_line.line = 0; + m_halt_line.q_count = 0; + m_halt_line.callback.resolve(m_halt_callback, *this); + + m_cart = dynamic_cast<device_cococart_interface *>(get_card_device()); +} + + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void cococart_slot_device::device_config_complete() +{ + // inherit a copy of the static data + const cococart_interface *intf = reinterpret_cast<const cococart_interface *>(static_config()); + if (intf != NULL) + { + *static_cast<cococart_interface *>(this) = *intf; + } + + // or initialize to defaults if none provided + else + { + memset(&m_cart_callback, 0, sizeof(m_cart_callback)); + memset(&m_nmi_callback, 0, sizeof(m_nmi_callback)); + memset(&m_halt_callback, 0, sizeof(m_halt_callback)); + } + + // set brief and instance name + update_names(); +} + + + +//------------------------------------------------- +// device_timer - handle timer callbacks +//------------------------------------------------- + +void cococart_slot_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch(id) + { + case TIMER_CART: + set_line("CART", m_cart_line, (cococart_line_value) param); + break; + + case TIMER_NMI: + set_line("NMI", m_nmi_line, (cococart_line_value) param); + break; + + case TIMER_HALT: + set_line("HALT", m_halt_line, (cococart_line_value) param); + break; + } +} + + + +//------------------------------------------------- +// coco_cartridge_r +//------------------------------------------------- + +READ8_MEMBER(cococart_slot_device::read) +{ + UINT8 result = 0x00; + if (m_cart) + result = m_cart->read(space, offset); + return result; +} + + +//------------------------------------------------- +// coco_cartridge_w +//------------------------------------------------- + +WRITE8_MEMBER(cococart_slot_device::write) +{ + if (m_cart) + m_cart->write(space, offset, data); +} + + + +//------------------------------------------------- +// line_value_string +//------------------------------------------------- + +static const char *line_value_string(cococart_line_value value) +{ + const char *s = NULL; + switch(value) + { + case COCOCART_LINE_VALUE_CLEAR: + s = "CLEAR"; + break; + case COCOCART_LINE_VALUE_ASSERT: + s = "ASSERT"; + break; + case COCOCART_LINE_VALUE_Q: + s = "Q"; + break; + default: + fatalerror("Invalid value\n"); + break; + } + return s; +} + + + +//------------------------------------------------- +// set_line +//------------------------------------------------- + +void cococart_slot_device::set_line(const char *line_name, coco_cartridge_line &line, cococart_line_value value) +{ + if ((line.value != value) || (value == COCOCART_LINE_VALUE_Q)) + { + line.value = value; + + if (LOG_LINE) + logerror("[%s]: set_line(): %s <= %s\n", machine().describe_context(), line_name, line_value_string(value)); + /* engage in a bit of gymnastics for this odious 'Q' value */ + switch(line.value) + { + case COCOCART_LINE_VALUE_CLEAR: + line.line = 0x00; + line.q_count = 0; + break; + + case COCOCART_LINE_VALUE_ASSERT: + line.line = 0x01; + line.q_count = 0; + break; + + case COCOCART_LINE_VALUE_Q: + line.line = line.line ? 0x00 : 0x01; + if (line.q_count++ < 4) + set_line_timer(line, value); + break; + } + + /* invoke the callback, if present */ + if (!line.callback.isnull()) + line.callback(line.line); + } +} + + + +//------------------------------------------------- +// set_line_timer() +//------------------------------------------------- + +void cococart_slot_device::set_line_timer(coco_cartridge_line &line, cococart_line_value value) +{ + /* calculate delay; delay dependant on cycles per second */ + attotime delay = (line.delay != 0) + ? machine().firstcpu->cycles_to_attotime(line.delay) + : attotime::zero; + + line.timer[line.timer_index]->adjust(delay, (int) value); + line.timer_index = (line.timer_index + 1) % TIMER_POOL; +} + + + +//------------------------------------------------- +// twiddle_line_if_q +//------------------------------------------------- + +void cococart_slot_device::twiddle_line_if_q(coco_cartridge_line &line) +{ + if (line.value == COCOCART_LINE_VALUE_Q) + { + line.q_count = 0; + set_line_timer(line, COCOCART_LINE_VALUE_Q); + } +} + + + +//------------------------------------------------- +// coco_cartridge_twiddle_q_lines - hack to +// support twiddling the Q line +//------------------------------------------------- + +void cococart_slot_device::twiddle_q_lines() +{ + twiddle_line_if_q(m_cart_line); + twiddle_line_if_q(m_nmi_line); + twiddle_line_if_q(m_halt_line); +} + + +//------------------------------------------------- +// coco_cartridge_set_line +//------------------------------------------------- + +void cococart_slot_device::cart_set_line(cococart_line line, cococart_line_value value) +{ + switch (line) + { + case COCOCART_LINE_CART: + set_line_timer(m_cart_line, value); + break; + + case COCOCART_LINE_NMI: + set_line_timer(m_nmi_line, value); + break; + + case COCOCART_LINE_HALT: + set_line_timer(m_halt_line, value); + break; + + case COCOCART_LINE_SOUND_ENABLE: + // do nothing for now + break; + } +} + + + +//------------------------------------------------- +// get_cart_base +//------------------------------------------------- + +UINT8* cococart_slot_device::get_cart_base() +{ + if (m_cart != NULL) + return m_cart->get_cart_base(); + return NULL; +} + + + +//------------------------------------------------- +// set_cart_base_update +//------------------------------------------------- + +void cococart_slot_device::set_cart_base_update(cococart_base_update_delegate update) +{ + if (m_cart != NULL) + m_cart->set_cart_base_update(update); +} + + + +//------------------------------------------------- +// call_load +//------------------------------------------------- + +bool cococart_slot_device::call_load() +{ + if (m_cart) + { + offs_t read_length = 0; + if (software_entry() == NULL) + { + read_length = fread(m_cart->get_cart_base(), 0x8000); + } + else + { + read_length = get_software_region_length("rom"); + memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length); + } + while(read_length < 0x8000) + { + offs_t len = MIN(read_length, 0x8000 - read_length); + memcpy(m_cart->get_cart_base() + read_length, m_cart->get_cart_base(), len); + read_length += len; + } + } + return IMAGE_INIT_PASS; +} + + + +//------------------------------------------------- +// call_softlist_load +//------------------------------------------------- + +bool cococart_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 cococart_slot_device::get_default_card_software(astring &result) +{ + software_get_default_slot(result, "pak"); +} + + + + +//************************************************************************** +// DEVICE COCO CART INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_cococart_interface - constructor +//------------------------------------------------- + +device_cococart_interface::device_cococart_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ +} + + + +//------------------------------------------------- +// ~device_cococart_interface - destructor +//------------------------------------------------- + +device_cococart_interface::~device_cococart_interface() +{ +} + + + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(device_cococart_interface::read) +{ + return 0x00; +} + + + +//------------------------------------------------- +// write +//------------------------------------------------- + +WRITE8_MEMBER(device_cococart_interface::write) +{ +} + + + +//------------------------------------------------- +// get_cart_base +//------------------------------------------------- + +UINT8* device_cococart_interface::get_cart_base() +{ + return NULL; +} + + + +//------------------------------------------------- +// set_cart_base_update +//------------------------------------------------- + +void device_cococart_interface::set_cart_base_update(cococart_base_update_delegate update) +{ + m_update = update; +} + + + +//------------------------------------------------- +// cart_base_changed +//------------------------------------------------- + +void device_cococart_interface::cart_base_changed(void) +{ + if (!m_update.isnull()) + m_update(get_cart_base()); +} diff --git a/src/emu/bus/coco/cococart.h b/src/emu/bus/coco/cococart.h new file mode 100644 index 00000000000..e207ae26068 --- /dev/null +++ b/src/emu/bus/coco/cococart.h @@ -0,0 +1,175 @@ +/********************************************************************* + + cococart.h + + CoCo/Dragon cartridge management + +*********************************************************************/ + +#ifndef __COCOCART_H__ +#define __COCOCART_H__ + + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +/* TIMER_POOL: Must be power of two */ +#define TIMER_POOL 2 + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +/* output lines on the CoCo cartridge slot */ +enum cococart_line +{ + COCOCART_LINE_CART, /* connects to PIA1 CB1 */ + COCOCART_LINE_NMI, /* connects to NMI line on CPU */ + COCOCART_LINE_HALT, /* connects to HALT line on CPU */ + COCOCART_LINE_SOUND_ENABLE /* sound enable */ +}; + +/* since we have a special value "Q" - we have to use a special enum here */ +enum cococart_line_value +{ + COCOCART_LINE_VALUE_CLEAR, + COCOCART_LINE_VALUE_ASSERT, + COCOCART_LINE_VALUE_Q +}; + +struct coco_cartridge_line +{ + emu_timer *timer[TIMER_POOL]; + int timer_index; + int delay; + cococart_line_value value; + int line; + int q_count; + devcb_resolved_write_line callback; +}; + +// ======================> cococart_interface + +struct cococart_interface +{ + devcb_write_line m_cart_callback; + devcb_write_line m_nmi_callback; + devcb_write_line m_halt_callback; +}; + +// ======================> cococart_base_update_delegate + +// direct region update handler +typedef delegate<void (UINT8 *)> cococart_base_update_delegate; + + +// ======================> cococart_slot_device +class device_cococart_interface; + +class cococart_slot_device : public device_t, + public cococart_interface, + public device_slot_interface, + public device_image_interface +{ +public: + // construction/destruction + cococart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // image-level overrides + virtual bool call_load(); + virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry); + + 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 char *image_interface() const { return "coco_cart"; } + virtual const char *file_extensions() const { return "ccc,rom"; } + virtual const option_guide *create_option_guide() const { return NULL; } + + // slot interface overrides + virtual void get_default_card_software(astring &result); + + // reading and writing to $FF40-$FF7F + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + + // sets a cartridge line + void cart_set_line(cococart_line line, cococart_line_value value); + + // hack to support twiddling the Q line + void twiddle_q_lines(); + + // cart base + UINT8* get_cart_base(); + void set_cart_base_update(cococart_base_update_delegate update); + +private: + enum + { + TIMER_CART, + TIMER_NMI, + TIMER_HALT + }; + + // configuration + coco_cartridge_line m_cart_line; + coco_cartridge_line m_nmi_line; + coco_cartridge_line m_halt_line; + + // cartridge + device_cococart_interface *m_cart; + + // methods + void set_line(const char *line_name, coco_cartridge_line &line, cococart_line_value value); + void set_line_timer(coco_cartridge_line &line, cococart_line_value value); + void twiddle_line_if_q(coco_cartridge_line &line); +}; + +// device type definition +extern const device_type COCOCART_SLOT; + +// ======================> device_cococart_interface + +class device_cococart_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_cococart_interface(const machine_config &mconfig, device_t &device); + virtual ~device_cococart_interface(); + + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + + virtual UINT8* get_cart_base(); + void set_cart_base_update(cococart_base_update_delegate update); + +protected: + void cart_base_changed(void); + +private: + cococart_base_update_delegate m_update; +}; + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MCFG_COCO_CARTRIDGE_ADD(_tag,_config,_slot_intf,_def_slot) \ + MCFG_DEVICE_ADD(_tag, COCOCART_SLOT, 0) \ + MCFG_DEVICE_CONFIG(_config) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +#define MCFG_COCO_CARTRIDGE_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +#endif /* __COCOCART_H__ */ diff --git a/src/emu/bus/compucolor/floppy.c b/src/emu/bus/compucolor/floppy.c new file mode 100644 index 00000000000..62d8d2437b8 --- /dev/null +++ b/src/emu/bus/compucolor/floppy.c @@ -0,0 +1,255 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Compucolor Floppy Disk Drive emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +#include "floppy.h" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type COMPUCOLOR_FLOPPY_PORT = &device_creator<compucolor_floppy_port_device>; +const device_type COMPUCOLOR_FLOPPY = &device_creator<compucolor_floppy_device>; + + +//------------------------------------------------- +// SLOT_INTERFACE( compucolor_floppy_port_devices ) +//------------------------------------------------- + +SLOT_INTERFACE_START( compucolor_floppy_port_devices ) + SLOT_INTERFACE("floppy", COMPUCOLOR_FLOPPY) +SLOT_INTERFACE_END + + +//------------------------------------------------- +// FLOPPY_FORMATS( floppy_formats ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( compucolor_floppy_device::floppy_formats ) + FLOPPY_CCVF_FORMAT +FLOPPY_FORMATS_END + + +//------------------------------------------------- +// SLOT_INTERFACE( compucolor_floppies ) +//------------------------------------------------- + +static SLOT_INTERFACE_START( compucolor_floppies ) + SLOT_INTERFACE_INTERNAL( "525sssd", FLOPPY_525_SSSD ) +SLOT_INTERFACE_END + + +//------------------------------------------------- +// MACHINE_DRIVER( compucolor_floppy ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( compucolor_floppy ) + MCFG_FLOPPY_DRIVE_ADD("floppy", compucolor_floppies, "525sssd", compucolor_floppy_device::floppy_formats) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor compucolor_floppy_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( compucolor_floppy ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// device_compucolor_floppy_port_interface - constructor +//------------------------------------------------- + +device_compucolor_floppy_port_interface::device_compucolor_floppy_port_interface(const machine_config &mconfig, device_t &device) + : device_rs232_port_interface(mconfig, device) +{ +} + + +//------------------------------------------------- +// compucolor_floppy_port_device - constructor +//------------------------------------------------- + +compucolor_floppy_port_device::compucolor_floppy_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : rs232_port_device(mconfig, COMPUCOLOR_FLOPPY_PORT, "Compucolor Floppy Port", tag, owner, clock, "compclr_flp_port", __FILE__) +{ +} + + +//------------------------------------------------- +// compucolor_floppy_device - constructor +//------------------------------------------------- + +compucolor_floppy_device::compucolor_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, COMPUCOLOR_FLOPPY, "Compucolor floppy", tag, owner, clock, "compclr_flp", __FILE__), + device_compucolor_floppy_port_interface(mconfig, *this), + m_floppy(*this, "floppy:525sssd"), + m_rw(1), + m_stp(0), + m_sel(1), + m_period(attotime::from_hz(9600*8)) +{ + m_owner = dynamic_cast<compucolor_floppy_port_device *>(this->owner()); +} + + +//------------------------------------------------- +// device_config_complete - +//------------------------------------------------- + +void compucolor_floppy_port_device::device_config_complete() +{ + rs232_port_device::device_config_complete(); + + m_dev = dynamic_cast<device_compucolor_floppy_port_interface *>(get_card_device()); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void compucolor_floppy_port_device::device_start() +{ + rs232_port_device::device_start(); +} + + +void compucolor_floppy_device::device_start() +{ + // allocate timer + m_timer = timer_alloc(); + m_timer->adjust(attotime::from_hz(9600*8), 0, attotime::from_hz(9600*8)); + + // state saving + save_item(NAME(m_rw)); + save_item(NAME(m_stp)); + save_item(NAME(m_sel)); +} + + +//------------------------------------------------- +// device_timer - handle timer events +//------------------------------------------------- + +void compucolor_floppy_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (!m_sel && !m_rw) + { + output_rxd(read_bit()); + } +} + + +//------------------------------------------------- +// tx_w - +//------------------------------------------------- + +void compucolor_floppy_device::tx(UINT8 state) +{ + if (!m_sel && m_rw) + { + write_bit(state); + } +} + + +//------------------------------------------------- +// rw_w - +//------------------------------------------------- + +void compucolor_floppy_device::rw_w(int state) +{ + if (!m_rw && state) + { + output_rxd(1); + } + + m_rw = state; +} + + +//------------------------------------------------- +// stepper_w - +//------------------------------------------------- + +void compucolor_floppy_device::stepper_w(UINT8 data) +{ + if (!m_sel) + { + if ((m_stp == 1 && data == 4) || (m_stp == 2 && data == 1) || (m_stp == 4 && data == 2)) + { + // step in + m_floppy->dir_w(1); + m_floppy->stp_w(0); + m_floppy->stp_w(1); + } + else if ((m_stp == 1 && data == 2) || (m_stp == 2 && data == 4) || (m_stp == 4 && data == 1)) + { + // step out + m_floppy->dir_w(0); + m_floppy->stp_w(0); + m_floppy->stp_w(1); + } + } + + m_stp = data; +} + + +//------------------------------------------------- +// select_w - +//------------------------------------------------- + +void compucolor_floppy_device::select_w(int state) +{ + m_floppy->mon_w(state); + + if (!m_sel && state) + { + output_rxd(1); + } + + m_sel = state; +} + + +//------------------------------------------------- +// read_bit - +//------------------------------------------------- + +bool compucolor_floppy_device::read_bit() +{ + attotime when = machine().time(); + attotime edge = m_floppy->get_next_transition(when); + attotime next = when + m_period; + + return (edge.is_never() || edge >= next) ? 0 : 1; +} + + +//------------------------------------------------- +// write_bit - +//------------------------------------------------- + +void compucolor_floppy_device::write_bit(bool bit) +{ + // TODO +} diff --git a/src/emu/bus/compucolor/floppy.h b/src/emu/bus/compucolor/floppy.h new file mode 100644 index 00000000000..4d75e3ca923 --- /dev/null +++ b/src/emu/bus/compucolor/floppy.h @@ -0,0 +1,126 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Compucolor Floppy Disk Drive emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +*********************************************************************/ + +#pragma once + +#ifndef __COMPCLR_FLP__ +#define __COMPCLR_FLP__ + +#include "bus/rs232/rs232.h" +#include "formats/ccvf_dsk.h" +#include "imagedev/floppy.h" + + + +//************************************************************************** +// INTERFACE MACROS +//************************************************************************** + +#define MCFG_COMPUCOLOR_FLOPPY_PORT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, COMPUCOLOR_FLOPPY_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> device_compucolor_floppy_port_interface + +class device_compucolor_floppy_port_interface : public device_rs232_port_interface +{ +public: + device_compucolor_floppy_port_interface(const machine_config &mconfig, device_t &device); + virtual ~device_compucolor_floppy_port_interface() { } + + virtual void rw_w(int state) = 0; + virtual void stepper_w(UINT8 data) = 0; + virtual void select_w(int state) = 0; +}; + + +// ======================> compucolor_floppy_port_device + +class compucolor_floppy_port_device : public rs232_port_device +{ +public: + compucolor_floppy_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~compucolor_floppy_port_device() { } + + DECLARE_WRITE_LINE_MEMBER( rw_w ) { if (m_dev) m_dev->rw_w(state); } + void stepper_w(UINT8 data) { if (m_dev) m_dev->stepper_w(data); } + DECLARE_WRITE_LINE_MEMBER( select_w ) { if (m_dev) m_dev->select_w(state); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_config_complete(); + +private: + device_compucolor_floppy_port_interface *m_dev; +}; + + +// ======================> compucolor_floppy_device + +class compucolor_floppy_device : public device_t, + public device_compucolor_floppy_port_interface +{ +public: + // construction/destruction + compucolor_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + DECLARE_FLOPPY_FORMATS( floppy_formats ); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device_serial_port_interface overrides + virtual void tx(UINT8 state); + + // device_compucolor_floppy_port_interface overrides + virtual void rw_w(int state); + virtual void stepper_w(UINT8 data); + virtual void select_w(int state); + +private: + required_device<floppy_image_device> m_floppy; + + bool read_bit(); + void write_bit(bool bit); + + int m_rw; + int m_stp; + int m_sel; + + attotime m_period; + + compucolor_floppy_port_device *m_owner; + + emu_timer *m_timer; +}; + + +// device type definition +extern const device_type COMPUCOLOR_FLOPPY_PORT; +extern const device_type COMPUCOLOR_FLOPPY; + + +// slot devices +SLOT_INTERFACE_EXTERN( compucolor_floppy_port_devices ); + +#endif diff --git a/src/emu/bus/cpc/cpc_pds.c b/src/emu/bus/cpc/cpc_pds.c new file mode 100644 index 00000000000..19cb0bd1031 --- /dev/null +++ b/src/emu/bus/cpc/cpc_pds.c @@ -0,0 +1,87 @@ +/* + * cpc_pds.c -- CPC interface hardware for the Programmers Development System + * + * Created on: 10/02/2014 + */ + +#include "emu.h" +#include "cpc_pds.h" +#include "includes/amstrad.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type CPC_PDS = &device_creator<cpc_pds_device>; + + +static Z80PIO_INTERFACE( pio_intf ) +{ + DEVCB_NULL, //m_out_int_cb; + + DEVCB_NULL, //m_in_pa_cb; + DEVCB_NULL, //m_out_pa_cb; + DEVCB_NULL, //m_out_ardy_cb; + + DEVCB_NULL, //m_in_pb_cb; + DEVCB_NULL, //m_out_pb_cb; + DEVCB_NULL, //m_out_brdy_cb; +}; + +static MACHINE_CONFIG_FRAGMENT( cpc_pds ) + MCFG_Z80PIO_ADD("pio",XTAL_4MHz,pio_intf) // no clock on the PCB, so will presume that it uses the CPC's clock + + // no pass-through seen on remake PCBs, unknown if actual hardware had a pass-through port or not +MACHINE_CONFIG_END + + +machine_config_constructor cpc_pds_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cpc_pds ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +cpc_pds_device::cpc_pds_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_PDS, "Programmers Development System (CPC Target)", tag, owner, clock, "cpc_pds", __FILE__), + device_cpc_expansion_card_interface(mconfig, *this), + m_pio(*this,"pio") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cpc_pds_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + address_space& space = cpu->memory().space(AS_IO); + m_slot = dynamic_cast<cpc_expansion_slot_device *>(owner()); + + space.install_readwrite_handler(0xfbec,0xfbef,0,0,read8_delegate(FUNC(cpc_pds_device::pio_r),this),write8_delegate(FUNC(cpc_pds_device::pio_w),this)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cpc_pds_device::device_reset() +{ + // TODO +} + + +READ8_MEMBER(cpc_pds_device::pio_r) +{ + return m_pio->read(space,offset); +} + +WRITE8_MEMBER(cpc_pds_device::pio_w) +{ + m_pio->write(space,offset,data); +} diff --git a/src/emu/bus/cpc/cpc_pds.h b/src/emu/bus/cpc/cpc_pds.h new file mode 100644 index 00000000000..74f79add041 --- /dev/null +++ b/src/emu/bus/cpc/cpc_pds.h @@ -0,0 +1,56 @@ +/* + * cpc_pds.h -- CPC interface hardware for the Programmers Development System + * + * Created on: 10/02/2014 + * + * Contains a Z80 PIO used to communicate with PC-side hardware (8-bit ISA card containing an 8255 PPI), + * connected via a 16-pin cable. Although it would seem that the C64 has a different cable that directly + * interfaces with the user port. + * + * The Z80 PIO is mapped to the CPC at: + * FBEC Z80 PIO Port A Data (8bit data to/from PC) + * FBED Z80 PIO Port B Data (handshake to/from PC) + * FBEE Z80 PIO Port A Control + * FBEF Z80 PIO Port B Control + * + * More info: http://cpcwiki.eu/index.php/PDS_development_system + * + * TODO: Come up with some way to connect two instances of MESS, one running the PC software, the other + * running the target side + */ + +#ifndef CPC_PDS_H_ +#define CPC_PDS_H_ + +#include "emu.h" +#include "cpcexp.h" +#include "machine/z80pio.h" + +class cpc_pds_device : public device_t, + public device_cpc_expansion_card_interface +{ +public: + // construction/destruction + cpc_pds_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + + DECLARE_READ8_MEMBER(pio_r); + DECLARE_WRITE8_MEMBER(pio_w); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + cpc_expansion_slot_device *m_slot; + + required_device<z80pio_device> m_pio; +}; + +// device type definition +extern const device_type CPC_PDS; + +#endif /* CPC_PDS_H_ */ diff --git a/src/emu/bus/cpc/cpc_rom.c b/src/emu/bus/cpc/cpc_rom.c new file mode 100644 index 00000000000..ddf33f318e3 --- /dev/null +++ b/src/emu/bus/cpc/cpc_rom.c @@ -0,0 +1,136 @@ +/* + * cpc_rom.c + * Amstrad CPC mountable ROM image device + * + */ + +#include "emu.h" +#include "cpc_rom.h" +#include "includes/amstrad.h" + +const device_type CPC_ROM = &device_creator<cpc_rom_device>; + + +//************************************************************************** +// DEVICE CONFIG INTERFACE +//************************************************************************** + +CPC_EXPANSION_INTERFACE(sub_exp_intf) +{ + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, irq_w), + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, nmi_w), + DEVCB_NULL, // RESET + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romdis_w), // ROMDIS + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romen_w) // /ROMEN +}; + +// device machine config +static MACHINE_CONFIG_FRAGMENT( cpc_rom ) + MCFG_ROMSLOT_ADD("rom1") + MCFG_ROMSLOT_ADD("rom2") + MCFG_ROMSLOT_ADD("rom3") + MCFG_ROMSLOT_ADD("rom4") + MCFG_ROMSLOT_ADD("rom5") + MCFG_ROMSLOT_ADD("rom6") + + // pass-through + MCFG_CPC_EXPANSION_SLOT_ADD("exp",sub_exp_intf,cpc_exp_cards,NULL) + +MACHINE_CONFIG_END + + +machine_config_constructor cpc_rom_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cpc_rom ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +cpc_rom_device::cpc_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_ROM, "ROM Box", tag, owner, clock, "cpc_rom", __FILE__), + device_cpc_expansion_card_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cpc_rom_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cpc_rom_device::device_reset() +{ +} + + +/*** ROM image device ***/ + +// device type definition +const device_type ROMSLOT = &device_creator<rom_image_device>; + +//------------------------------------------------- +// rom_image_device - constructor +//------------------------------------------------- + +rom_image_device::rom_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ROMSLOT, "ROM image", tag, owner, clock, "rom_image", __FILE__), + device_image_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// rom_image_device - destructor +//------------------------------------------------- + +rom_image_device::~rom_image_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void rom_image_device::device_start() +{ + m_base = NULL; +} + +/*------------------------------------------------- + DEVICE_IMAGE_LOAD( rom ) +-------------------------------------------------*/ +bool rom_image_device::call_load() +{ + device_image_interface* image = this; + UINT64 size = image->length(); + + m_base = (UINT8*)malloc(16384); + if(size <= 16384) + { + image->fread(m_base,size); + } + else + { + image->fseek(size-16384,SEEK_SET); + image->fread(m_base,16384); + } + + return IMAGE_INIT_PASS; +} + + +/*------------------------------------------------- + DEVICE_IMAGE_UNLOAD( rom ) +-------------------------------------------------*/ +void rom_image_device::call_unload() +{ + free(m_base); + m_base = NULL; +} diff --git a/src/emu/bus/cpc/cpc_rom.h b/src/emu/bus/cpc/cpc_rom.h new file mode 100644 index 00000000000..c00f99f7f50 --- /dev/null +++ b/src/emu/bus/cpc/cpc_rom.h @@ -0,0 +1,88 @@ +/* + * cpc_rom.h + * Amstrad CPC mountable ROM image device + * + */ + +#ifndef CPC_ROM_H_ +#define CPC_ROM_H_ + +#include "emu.h" +#include "cpcexp.h" + +/*** ROM image device ***/ + +// ======================> rom_image_device + +class rom_image_device : public device_t, + public device_image_interface +{ +public: + // construction/destruction + rom_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~rom_image_device(); + + // image-level overrides + virtual bool call_load(); + virtual void call_unload(); + + virtual iodevice_t image_type() const { return IO_ROM; } + + 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 char *image_interface() const { return "cpc_rom"; } + virtual const char *file_extensions() const { return "rom,bin"; } + virtual const option_guide *create_option_guide() const { return NULL; } + + UINT8* base() { return m_base; } + +protected: + // device-level overrides + virtual void device_config_complete() { update_names(); } + virtual void device_start(); + +private: + UINT8* m_base; +}; + + +// device type definition +extern const device_type ROMSLOT; + + +#define MCFG_ROMSLOT_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, ROMSLOT, 0) + +/*** ROM box device ***/ + +class cpc_rom_device : public device_t, + public device_cpc_expansion_card_interface +{ +public: + // construction/destruction + cpc_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + + UINT8* base(UINT8 slot) { if(slot >=1 && slot <= 6) return m_rom[slot]->base(); else return NULL; } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + //cpc_expansion_slot_device *m_slot; + + rom_image_device* m_rom[6]; +}; + +// device type definition +extern const device_type CPC_ROM; + + +#endif diff --git a/src/emu/bus/cpc/cpc_ssa1.c b/src/emu/bus/cpc/cpc_ssa1.c new file mode 100644 index 00000000000..7e855493c66 --- /dev/null +++ b/src/emu/bus/cpc/cpc_ssa1.c @@ -0,0 +1,216 @@ +/* + * cpc_ssa1.c -- Amstrad SSA-1 Speech Synthesiser, dk'Tronics Speech Synthesiser + * + * Created on: 16/07/2011 + * + */ + + +#include "emu.h" +#include "cpc_ssa1.h" +#include "includes/amstrad.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type CPC_SSA1 = &device_creator<cpc_ssa1_device>; +const device_type CPC_DKSPEECH = &device_creator<cpc_dkspeech_device>; + +CPC_EXPANSION_INTERFACE(sub_exp_intf) +{ + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, irq_w), + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, nmi_w), + DEVCB_NULL, // RESET + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romdis_w), // ROMDIS + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romen_w) // /ROMEN +}; + +//------------------------------------------------- +// device I/O handlers +//------------------------------------------------- + +READ8_MEMBER(cpc_ssa1_device::ssa1_r) +{ + UINT8 ret = 0xff; + + if(get_sby() == 0) + ret &= ~0x80; + + if(get_lrq() != 0) + ret &= ~0x40; + + return ret; +} + +WRITE8_MEMBER(cpc_ssa1_device::ssa1_w) +{ + m_sp0256_device->ald_w(space, 0, data); +} + +READ8_MEMBER(cpc_dkspeech_device::dkspeech_r) +{ + UINT8 ret = 0xff; + + // SBY is not connected + + if(get_lrq() != 0) + ret &= ~0x80; + + return ret; +} + +WRITE8_MEMBER(cpc_dkspeech_device::dkspeech_w) +{ + m_sp0256_device->ald_w(space, 0, data & 0x3f); +} + +WRITE_LINE_MEMBER(cpc_ssa1_device::lrq_cb) +{ + set_lrq(state); +} + +WRITE_LINE_MEMBER(cpc_ssa1_device::sby_cb) +{ + set_sby(state); +} + +WRITE_LINE_MEMBER(cpc_dkspeech_device::lrq_cb) +{ + set_lrq(state); +} + +WRITE_LINE_MEMBER(cpc_dkspeech_device::sby_cb) +{ + set_sby(state); +} + +//------------------------------------------------- +// Device ROM definition +//------------------------------------------------- + +// Has no actual ROM, just that internal to the SP0256 +ROM_START( cpc_ssa1 ) + ROM_REGION( 0x10000, "sp0256", 0 ) + ROM_LOAD( "sp0256-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc) ) +ROM_END + +// Available in ROM and cassette versions. For now, we'll let the user choose to load the software via ROM (using a ROM box slot device) or cassette. +ROM_START( cpc_dkspeech ) + ROM_REGION( 0x10000, "sp0256", 0 ) + ROM_LOAD( "sp0256-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc) ) +ROM_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *cpc_ssa1_device::device_rom_region() const +{ + return ROM_NAME( cpc_ssa1 ); +} + +const rom_entry *cpc_dkspeech_device::device_rom_region() const +{ + return ROM_NAME( cpc_dkspeech ); +} + +// device machine config +static MACHINE_CONFIG_FRAGMENT( cpc_ssa1 ) + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("sp0256",SP0256,XTAL_3_12MHz) + MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(cpc_ssa1_device, lrq_cb)) + MCFG_SP0256_STANDBY_CB(WRITELINE(cpc_ssa1_device, sby_cb)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + // pass-through + MCFG_CPC_EXPANSION_SLOT_ADD("exp",sub_exp_intf,cpc_exp_cards,NULL) + +MACHINE_CONFIG_END + +static MACHINE_CONFIG_FRAGMENT( cpc_dkspeech ) + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("sp0256",SP0256,XTAL_4MHz) // uses the CPC's clock from pin 50 of the expansion port + MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(cpc_dkspeech_device, lrq_cb)) + MCFG_SP0256_STANDBY_CB(WRITELINE(cpc_dkspeech_device, sby_cb)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + // pass-through + MCFG_CPC_EXPANSION_SLOT_ADD("exp",sub_exp_intf,cpc_exp_cards,NULL) + +MACHINE_CONFIG_END + +machine_config_constructor cpc_ssa1_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cpc_ssa1 ); +} + +machine_config_constructor cpc_dkspeech_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cpc_dkspeech ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +cpc_ssa1_device::cpc_ssa1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_SSA1, "SSA-1", tag, owner, clock, "cpc_ssa1", __FILE__), + device_cpc_expansion_card_interface(mconfig, *this), + m_lrq(1), + m_sp0256_device(*this,"sp0256") +{ +} + +cpc_dkspeech_device::cpc_dkspeech_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_DKSPEECH, "DK'Tronics Speech Synthesiser", tag, owner, clock, "cpc_dkspeech", __FILE__), + device_cpc_expansion_card_interface(mconfig, *this), + m_lrq(1), + m_sp0256_device(*this,"sp0256") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cpc_ssa1_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + address_space& space = cpu->memory().space(AS_IO); + m_slot = dynamic_cast<cpc_expansion_slot_device *>(owner()); + + m_rom = memregion("sp0256")->base(); + +// m_sp0256_device = subdevice("sp0256"); + + space.install_readwrite_handler(0xfaee,0xfaee,0,0,read8_delegate(FUNC(cpc_ssa1_device::ssa1_r),this),write8_delegate(FUNC(cpc_ssa1_device::ssa1_w),this)); + space.install_readwrite_handler(0xfbee,0xfbee,0,0,read8_delegate(FUNC(cpc_ssa1_device::ssa1_r),this),write8_delegate(FUNC(cpc_ssa1_device::ssa1_w),this)); +} + +void cpc_dkspeech_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + address_space& space = cpu->memory().space(AS_IO); + m_slot = dynamic_cast<cpc_expansion_slot_device *>(owner()); + + m_rom = memregion("sp0256")->base(); + +// m_sp0256_device = subdevice("sp0256"); + + space.install_readwrite_handler(0xfbfe,0xfbfe,0,0,read8_delegate(FUNC(cpc_dkspeech_device::dkspeech_r),this),write8_delegate(FUNC(cpc_dkspeech_device::dkspeech_w),this)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cpc_ssa1_device::device_reset() +{ + m_sp0256_device->reset(); +} + +void cpc_dkspeech_device::device_reset() +{ + m_sp0256_device->reset(); +} diff --git a/src/emu/bus/cpc/cpc_ssa1.h b/src/emu/bus/cpc/cpc_ssa1.h new file mode 100644 index 00000000000..e3d1dd7a26a --- /dev/null +++ b/src/emu/bus/cpc/cpc_ssa1.h @@ -0,0 +1,126 @@ +/* + * cpc_ssa1.h -- Amstrad SSA-1 Speech Synthesiser, dk'Tronics Speech Synthesiser + * + * Created on: 16/07/2011 + * + * Amstrad SSA-1 - SP0256-AL2 based Speech Synthesiser and Sound Amplifier + * + * Uses on-board resonator, clocked at 3.12MHz + * + * Decodes only I/O lines A10, A4 and A0 + * Official I/O ports: + * &FBEE (read) + * - bit 7: SP0256 Status 1 (SBY) + * - bit 6: SP0256 Status 2 (/LRQ) + * + * &FBEE (write) + * - bits 7-0: SP0256 Allophone number (must be 0x00 to 0x3f, however, all data lines are hooked up) + * + * &FAEE (write) + * - same as above, used because of a bug in the driver software, but still works due to the way the I/O ports are + * decoded on the CPC. + * + * More info and PCB pics at http://www.cpcwiki.eu/index.php/Amstrad_SSA-1_Speech_Synthesizer + * + * + * dk'Tronics Speech Synthesiser - SP0256-AL2 based speech synthesiser + * + * Uses the CPC's clock of 4MHz from pin 50 of the expansion port, gives faster and higher pitched voices than the SSA-1 + * + * Official I/O ports: + * &FBFE (read) + * - bit 7: SP0256 Status 2 (/LRQ) + * + * &FBFE (write) + * - bits 5-0: SP0256 Allophone number + * + * More info and PCB pics at http://www.cpcwiki.eu/index.php/Dk%27tronics_Speech_Synthesizer + * + */ + +#ifndef CPC_SSA1_H_ +#define CPC_SSA1_H_ + + +#include "emu.h" +#include "cpcexp.h" +#include "sound/sp0256.h" + +class cpc_ssa1_device : public device_t, + public device_cpc_expansion_card_interface +{ +public: + // construction/destruction + cpc_ssa1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + + void set_lrq(UINT8 state) { m_lrq = state; } + UINT8 get_lrq() { return m_lrq; } + void set_sby(UINT8 state) { m_sby = state; } + UINT8 get_sby() { return m_sby; } + + DECLARE_READ8_MEMBER(ssa1_r); + DECLARE_WRITE8_MEMBER(ssa1_w); + DECLARE_WRITE_LINE_MEMBER(lrq_cb); + DECLARE_WRITE_LINE_MEMBER(sby_cb); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + cpc_expansion_slot_device *m_slot; + + UINT8 *m_rom; + UINT8 m_lrq; + UINT8 m_sby; + + required_device<sp0256_device> m_sp0256_device; +}; + +class cpc_dkspeech_device : public device_t, + public device_cpc_expansion_card_interface +{ +public: + // construction/destruction + cpc_dkspeech_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + + void set_lrq(UINT8 state) { m_lrq = state; } + UINT8 get_lrq() { return m_lrq; } + void set_sby(UINT8 state) { m_sby = state; } + UINT8 get_sby() { return m_sby; } + + DECLARE_READ8_MEMBER(dkspeech_r); + DECLARE_WRITE8_MEMBER(dkspeech_w); + DECLARE_WRITE_LINE_MEMBER(lrq_cb); + DECLARE_WRITE_LINE_MEMBER(sby_cb); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + cpc_expansion_slot_device *m_slot; + + UINT8 *m_rom; + UINT8 m_lrq; + UINT8 m_sby; + + required_device<sp0256_device> m_sp0256_device; +}; + +// device type definition +extern const device_type CPC_SSA1; +extern const device_type CPC_DKSPEECH; + + +#endif /* CPC_SSA1_H_ */ diff --git a/src/emu/bus/cpc/cpcexp.c b/src/emu/bus/cpc/cpcexp.c new file mode 100644 index 00000000000..fc00a6248e1 --- /dev/null +++ b/src/emu/bus/cpc/cpcexp.c @@ -0,0 +1,109 @@ +/* + * cpcexp.c -- Amstrad CPC Expansion port + * + * Created on: 16/07/2011 + * + */ + + +#include "emu.h" +#include "emuopts.h" +#include "cpcexp.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type CPC_EXPANSION_SLOT = &device_creator<cpc_expansion_slot_device>; + + +//************************************************************************** +// DEVICE CPC_EXPANSION CARD INTERFACE +//************************************************************************** + + +device_cpc_expansion_card_interface::device_cpc_expansion_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig,device) +{ +} + + +device_cpc_expansion_card_interface::~device_cpc_expansion_card_interface() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +cpc_expansion_slot_device::cpc_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_EXPANSION_SLOT, "Amstrad CPC expansion port", tag, owner, clock, "cpc_expansion_slot", __FILE__), + device_slot_interface(mconfig, *this) +{ +} + +cpc_expansion_slot_device::~cpc_expansion_slot_device() +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void cpc_expansion_slot_device::device_config_complete() +{ + // inherit a copy of the static data + const cpc_expansion_slot_interface *intf = reinterpret_cast<const cpc_expansion_slot_interface *>(static_config()); + if (intf != NULL) + { + *static_cast<cpc_expansion_slot_interface *>(this) = *intf; + } + + // or initialize to defaults if none provided + else + { + memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb)); + memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb)); + memset(&m_out_reset_cb, 0, sizeof(m_out_reset_cb)); + memset(&m_out_romdis_cb, 0, sizeof(m_out_romdis_cb)); + memset(&m_out_romen_cb, 0, sizeof(m_out_romen_cb)); + } +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cpc_expansion_slot_device::device_start() +{ + m_card = dynamic_cast<device_cpc_expansion_card_interface *>(get_card_device()); + + // resolve callbacks + m_out_irq_func.resolve(m_out_irq_cb, *this); + m_out_nmi_func.resolve(m_out_nmi_cb, *this); + m_out_reset_func.resolve(m_out_reset_cb, *this); + m_out_romdis_func.resolve(m_out_romdis_cb, *this); + m_out_romen_func.resolve(m_out_romen_cb, *this); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cpc_expansion_slot_device::device_reset() +{ +} + + +WRITE_LINE_MEMBER( cpc_expansion_slot_device::irq_w ) { m_out_irq_func(state); } +WRITE_LINE_MEMBER( cpc_expansion_slot_device::nmi_w ) { m_out_nmi_func(state); } +WRITE_LINE_MEMBER( cpc_expansion_slot_device::reset_w ) { m_out_reset_func(state); } +WRITE_LINE_MEMBER( cpc_expansion_slot_device::romdis_w ) { m_out_romdis_func(state); } +WRITE_LINE_MEMBER( cpc_expansion_slot_device::romen_w ) { m_out_romen_func(state); } diff --git a/src/emu/bus/cpc/cpcexp.h b/src/emu/bus/cpc/cpcexp.h new file mode 100644 index 00000000000..3e4df4f51a8 --- /dev/null +++ b/src/emu/bus/cpc/cpcexp.h @@ -0,0 +1,131 @@ +/* + * cpcexp.h -- Amstrad CPC Expansion port + * + * Created on: 16/07/2011 + * + * Pinout from CPC6128 User's Manual + * SOUND 1 2 GND + * A15 3 4 A14 + * A13 5 6 A12 + * A11 7 8 A10 + * A9 9 10 A8 + * A7 11 12 A6 + * A5 13 14 A4 + * A3 15 16 A2 + * A1 17 18 A0 + * D7 19 20 D6 + * D5 21 22 D4 + * D3 23 24 D2 + * D1 25 26 D0 + * +5v 27 28 _MREQ + * _M1 29 30 _RFSH + * _IORQ 31 32 _RD + * _WR 33 34 _HALT + * _INT 35 36 _NMI + * _BUSR2 37 38 _BUSAK + * READY 39 40 _BUS RESET + * _RESET 41 42 _ROMEN + * ROMDIS 43 44 _RAMRD + * RAMDIS 45 46 CURSOR + * L.PEN 47 48 _EXP + * GND 49 50 CLOCK + */ + +#pragma once + +#ifndef CPCEXP_H_ +#define CPCEXP_H_ + +#include "emu.h" + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +#define CPC_EXP_SLOT_TAG "cpcexp" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define CPC_EXPANSION_INTERFACE(_name) \ + const cpc_expansion_slot_interface (_name) = + + +#define MCFG_CPC_EXPANSION_SLOT_ADD(_tag, _config, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, CPC_EXPANSION_SLOT, 0) \ + MCFG_DEVICE_CONFIG(_config) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// expansion slot interface + +struct cpc_expansion_slot_interface +{ + devcb_write_line m_out_irq_cb; + devcb_write_line m_out_nmi_cb; + devcb_write_line m_out_reset_cb; + devcb_write_line m_out_romdis_cb; + devcb_write_line m_out_romen_cb; +}; + + +// ======================> device_cpc_expansion_card_interface + +// class representing interface-specific live cpc_expansion card +class device_cpc_expansion_card_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_cpc_expansion_card_interface(const machine_config &mconfig, device_t &device); + virtual ~device_cpc_expansion_card_interface(); + + // reset + virtual void cpc_reset_w() { }; +}; + + +// ======================> cpc_expansion_slot_device + +class cpc_expansion_slot_device : public device_t, + public cpc_expansion_slot_interface, + public device_slot_interface +{ +public: + // construction/destruction + cpc_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~cpc_expansion_slot_device(); + + DECLARE_WRITE_LINE_MEMBER( irq_w ); + DECLARE_WRITE_LINE_MEMBER( nmi_w ); + DECLARE_WRITE_LINE_MEMBER( reset_w ); + DECLARE_WRITE_LINE_MEMBER( romdis_w ); + DECLARE_WRITE_LINE_MEMBER( romen_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_config_complete(); + + devcb_resolved_write_line m_out_irq_func; + devcb_resolved_write_line m_out_nmi_func; + devcb_resolved_write_line m_out_reset_func; + devcb_resolved_write_line m_out_romdis_func; + devcb_resolved_write_line m_out_romen_func; + + device_cpc_expansion_card_interface *m_card; +}; + + +// device type definition +extern const device_type CPC_EXPANSION_SLOT; + +#endif /* CPCEXP_H_ */ diff --git a/src/emu/bus/cpc/mface2.c b/src/emu/bus/cpc/mface2.c new file mode 100644 index 00000000000..742a8365f33 --- /dev/null +++ b/src/emu/bus/cpc/mface2.c @@ -0,0 +1,348 @@ +/* + * mface2.c -- Romantic Robot Multiface II expansion device for the Amstrad CPC/CPC+ + * + * Created on: 31/07/2011 + */ + +#include "emu.h" +#include "mface2.h" +#include "includes/amstrad.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type CPC_MFACE2 = &device_creator<cpc_multiface2_device>; + +CPC_EXPANSION_INTERFACE(sub_exp_intf) +{ + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, irq_w), + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, nmi_w), + DEVCB_NULL, // RESET + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romdis_w), // ROMDIS + DEVCB_DEVICE_LINE_MEMBER("^^", cpc_expansion_slot_device, romen_w) // /ROMEN +}; + +// device machine config +static MACHINE_CONFIG_FRAGMENT( cpc_mface2 ) + // pass-through + MCFG_CPC_EXPANSION_SLOT_ADD("exp",sub_exp_intf,cpc_exp_cards,NULL) +MACHINE_CONFIG_END + +DIRECT_UPDATE_MEMBER( cpc_multiface2_device::amstrad_default ) +{ + return address; +} + +/* used to setup computer if a snapshot was specified */ +DIRECT_UPDATE_MEMBER( cpc_multiface2_device::amstrad_multiface_directoverride ) +{ + int pc; + + pc = machine().device("maincpu")->safe_pc(); + /* there are two places where CALL &0065 can be found + in the multiface rom. At this address there is a RET. + + To disable the multiface from being detected, the multiface + stop button must be pressed, then the program that was stopped + must be returned to. When this is done, the multiface cannot + be detected and the out operations to page the multiface + ram/rom into the address space will not work! */ + + /* I assume that the hardware in the multiface detects + the PC set to 0x065 and uses this to enable/disable the multiface + */ + + /* I also use this to allow the stop button to be pressed again */ + if (pc==0x0164) + { + /* first call? */ + m_multiface_flags |= MULTIFACE_VISIBLE; + } + else if (pc==0x0c98) + { + /* second call */ + + /* no longer visible */ + m_multiface_flags &= ~(MULTIFACE_VISIBLE|MULTIFACE_STOP_BUTTON_PRESSED); + + m_romdis=0; + m_slot->romen_w(0); + + /* clear op base override */ + machine().device("maincpu")->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(cpc_multiface2_device::amstrad_default),this)); + } + + return pc; +} + +int cpc_multiface2_device::multiface_hardware_enabled() +{ + if (m_multiface_ram!=NULL) + { + if ((ioport("multiface")->read() & 0x01)!=0) + { + return 1; + } + } + + return 0; +} + +/* multiface traps calls to 0x0065 when it is active. +This address has a RET and so executes no code. + +It is believed that it is used to make multiface invisible to programs */ + +/*#define MULTIFACE_0065_TOGGLE 0x0008*/ + + +void cpc_multiface2_device::multiface_rethink_memory() +{ + unsigned char *multiface_rom; + + /* multiface hardware enabled? */ + if (!multiface_hardware_enabled()) + return; + + multiface_rom = memregion("multiface")->base(); + + if ((m_multiface_flags & MULTIFACE_RAM_ROM_ENABLED)!=0 && m_romdis != 0) + { + /* set bank addressess */ + machine().root_device().membank("bank1")->set_base(multiface_rom); + machine().root_device().membank("bank2")->set_base(m_multiface_ram); + machine().root_device().membank("bank9")->set_base(multiface_rom); + machine().root_device().membank("bank10")->set_base(m_multiface_ram); + } +} + +machine_config_constructor cpc_multiface2_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cpc_mface2 ); +} + +void cpc_multiface2_device::check_button_state() +{ + if(!multiface_hardware_enabled()) + return; + // TODO: reset button + if (ioport("multiface")->read() & 0x02) + { + multiface_stop(); + } +} + +/* simulate the stop button has been pressed */ +void cpc_multiface2_device::multiface_stop() +{ + /* multiface hardware enabled? */ + if (!multiface_hardware_enabled()) + return; + + /* if stop button not already pressed, do press action */ + /* pressing stop button while multiface is running has no effect */ + if ((m_multiface_flags & MULTIFACE_STOP_BUTTON_PRESSED)==0) + { + /* initialise 0065 toggle */ + /*state->m_multiface_flags &= ~MULTIFACE_0065_TOGGLE;*/ + + m_multiface_flags |= MULTIFACE_RAM_ROM_ENABLED; + + /* stop button has been pressed, furthur pressess will not issue a NMI */ + m_multiface_flags |= MULTIFACE_STOP_BUTTON_PRESSED; + + m_romdis = 1; + m_slot->romen_w(1); + + /* page rom into memory */ + multiface_rethink_memory(); + + /* pulse the nmi line */ + m_slot->nmi_w(1); + m_slot->nmi_w(0); + + /* initialise 0065 override to monitor calls to 0065 */ + machine().device("maincpu")->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(cpc_multiface2_device::amstrad_multiface_directoverride),this)); + } +} + +/* any io writes are passed through here */ +int cpc_multiface2_device::multiface_io_write(UINT16 offset, UINT8 data) +{ + int ret = 0; + + /* multiface hardware enabled? */ + if (!multiface_hardware_enabled()) + return 0; + + /* visible? */ + if (m_multiface_flags & MULTIFACE_VISIBLE) + { + if (offset==0x0fee8) + { + m_multiface_flags |= MULTIFACE_RAM_ROM_ENABLED; + ret = 1; + } + + if (offset==0x0feea) + { + m_multiface_flags &= ~MULTIFACE_RAM_ROM_ENABLED; + ret = 1; + } + } + + /* update multiface ram with data */ + /* these are decoded fully! */ + switch ((offset>>8) & 0x0ff) + { + /* gate array */ + case 0x07f: + { + switch (data & 0x0c0) + { + /* pen index */ + case 0x00: + { + m_multiface_ram[0x01fcf] = data; + } + break; + /* pen colour */ + case 0x040: + { + int pen_index; + pen_index = m_multiface_ram[0x01fcf] & 0x0f; + if (m_multiface_ram[0x01fcf] & 0x010) + { + m_multiface_ram[0x01fdf + pen_index] = data; + } + else + { + m_multiface_ram[0x01f90 + pen_index] = data & 0x01f; + } + } + break; + /* rom/mode selection */ + case 0x080: + { + m_multiface_ram[0x01fef] = data; + } + break; + /* ram configuration */ + case 0x0c0: + { + m_multiface_ram[0x01fff] = data; + } + break; + default: + break; + } + } + break; + + /* crtc register index */ + case 0x0bc: + { + m_multiface_ram[0x01cff] = data; + } + break; + /* crtc register write */ + case 0x0bd: + { + int reg_index; + reg_index = m_multiface_ram[0x01cff] & 0x0f; + m_multiface_ram[0x01db0 + reg_index] = data; + } + break; + + + /* 8255 ppi control */ + case 0x0f7: + { + m_multiface_ram[0x017ff] = data; + } + break; + /* rom select */ + case 0x0df: + { + m_multiface_ram[0x01aac] = data; + } + break; + default: + break; + } + return ret; +} + +static INPUT_PORTS_START(cpc_mface2) + PORT_START("multiface") + PORT_CONFNAME(0x01, 0x00, "Multiface Two" ) + PORT_CONFSETTING(0x00, DEF_STR( Off) ) + PORT_CONFSETTING(0x01, DEF_STR( On) ) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Multiface Two's Stop Button") PORT_CODE(KEYCODE_F6) + // PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Multiface Two's Reset Button") PORT_CODE(KEYCODE_F3) Not implemented +INPUT_PORTS_END + + + +//------------------------------------------------- +// Device ROM definition +//------------------------------------------------- + +// Second known revision (1988) +ROM_START( cpc_mface2 ) + ROM_REGION( 0x2000, "multiface", 0 ) + ROM_LOAD("multface.rom", 0x0000, 0x2000, CRC(f36086de) SHA1(1431ec628d38f000715545dd2186b684c5fe5a6f)) +ROM_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *cpc_multiface2_device::device_rom_region() const +{ + return ROM_NAME( cpc_mface2 ); +} + +ioport_constructor cpc_multiface2_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( cpc_mface2 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +cpc_multiface2_device::cpc_multiface2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, CPC_MFACE2, "Multiface II", tag, owner, clock, "cpc_mf2", __FILE__), + device_cpc_expansion_card_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cpc_multiface2_device::device_start() +{ + m_slot = dynamic_cast<cpc_expansion_slot_device *>(owner()); + + /* after a reset the multiface is visible */ + m_multiface_flags = MULTIFACE_VISIBLE; + + /* allocate ram */ + m_multiface_ram = auto_alloc_array(machine(), UINT8, 8192); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cpc_multiface2_device::device_reset() +{ + /* stop button not pressed and ram/rom disabled */ + m_multiface_flags &= ~(MULTIFACE_STOP_BUTTON_PRESSED | + MULTIFACE_RAM_ROM_ENABLED); + /* as on the real hardware the multiface is visible after a reset! */ + m_multiface_flags |= MULTIFACE_VISIBLE; +} diff --git a/src/emu/bus/cpc/mface2.h b/src/emu/bus/cpc/mface2.h new file mode 100644 index 00000000000..917ddeeaeea --- /dev/null +++ b/src/emu/bus/cpc/mface2.h @@ -0,0 +1,69 @@ +/* + * mface2.h -- Romantic Robot Multiface II expansion device for the Amstrad CPC/CPC+ + * + * Created on: 31/07/2011 + * + * I/O Ports: + * - FEE8: Enables Multiface ROM and RAM + * - FEEA: Disables Multiface ROM and RAM + * + * When enabled, Multiface ROM is mapped to &0000, and RAM to &2000 + * + * When the Stop button is pressed, the Multiface II will generate an NMI + * (I guess the ROM/RAM is enabled when you do this also?) + * + * It also monitors all I/O port writes, so that it can restore them when resuming the current application. + */ + +#ifndef MFACE2_H_ +#define MFACE2_H_ + +#include "emu.h" +#include "cpcexp.h" + +/* stop button has been pressed */ +#define MULTIFACE_STOP_BUTTON_PRESSED 0x0001 +/* ram/rom is paged into memory space */ +#define MULTIFACE_RAM_ROM_ENABLED 0x0002 +/* when visible OUT commands are performed! */ +#define MULTIFACE_VISIBLE 0x0004 + + +class cpc_multiface2_device : public device_t, + public device_cpc_expansion_card_interface +{ +public: + // construction/destruction + cpc_multiface2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual ioport_constructor device_input_ports() const; + virtual machine_config_constructor device_mconfig_additions() const; + + int multiface_hardware_enabled(); + void multiface_rethink_memory(); + void multiface_stop(); + int multiface_io_write(UINT16 offset, UINT8 data); + void check_button_state(); +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + cpc_expansion_slot_device *m_slot; + + DIRECT_UPDATE_MEMBER( amstrad_default ); + DIRECT_UPDATE_MEMBER( amstrad_multiface_directoverride ); + + unsigned char *m_multiface_ram; + unsigned long m_multiface_flags; + + UINT8 m_romdis; +}; + +// device type definition +extern const device_type CPC_MFACE2; + +#endif /* MFACE2_H_ */ diff --git a/src/emu/bus/epson_sio/epson_sio.c b/src/emu/bus/epson_sio/epson_sio.c new file mode 100644 index 00000000000..442e6351208 --- /dev/null +++ b/src/emu/bus/epson_sio/epson_sio.c @@ -0,0 +1,116 @@ +/********************************************************************** + + EPSON SIO port emulation + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + +**********************************************************************/ + +#include "epson_sio.h" + +// supported devices +#include "pf10.h" +#include "tf20.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type EPSON_SIO = &device_creator<epson_sio_device>; + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_epson_sio_interface - constructor +//------------------------------------------------- + +device_epson_sio_interface::device_epson_sio_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device) +{ + m_slot = dynamic_cast<epson_sio_device *>(device.owner()); +} + + +//------------------------------------------------- +// ~device_epson_sio_interface - destructor +//------------------------------------------------- + +device_epson_sio_interface::~device_epson_sio_interface() +{ +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// epson_sio_device - constructor +//------------------------------------------------- + +epson_sio_device::epson_sio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, EPSON_SIO, "EPSON SIO port", tag, owner, clock, "epson_sio", __FILE__), + device_slot_interface(mconfig, *this), + m_write_rx(*this), + m_write_pin(*this) +{ +} + + +//------------------------------------------------- +// epson_sio_device - destructor +//------------------------------------------------- + +epson_sio_device::~epson_sio_device() +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void epson_sio_device::device_start() +{ + m_cart = dynamic_cast<device_epson_sio_interface *>(get_card_device()); + + m_write_rx.resolve_safe(); + m_write_pin.resolve_safe(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void epson_sio_device::device_reset() +{ +} + + +WRITE_LINE_MEMBER( epson_sio_device::tx_w ) +{ + if (m_cart != NULL) + m_cart->tx_w(state); +} + +WRITE_LINE_MEMBER( epson_sio_device::pout_w ) +{ + if (m_cart != NULL) + m_cart->pout_w(state); +} + + +//************************************************************************** +// SLOT INTERFACE +//************************************************************************** + +SLOT_INTERFACE_START( epson_sio_devices ) + SLOT_INTERFACE("pf10", EPSON_PF10) + SLOT_INTERFACE("tf20", EPSON_TF20) +SLOT_INTERFACE_END diff --git a/src/emu/bus/epson_sio/epson_sio.h b/src/emu/bus/epson_sio/epson_sio.h new file mode 100644 index 00000000000..f398d4d1ea1 --- /dev/null +++ b/src/emu/bus/epson_sio/epson_sio.h @@ -0,0 +1,97 @@ +/********************************************************************** + + EPSON SIO port emulation + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + +**********************************************************************/ + +#pragma once + +#ifndef __EPSON_SIO_H__ +#define __EPSON_SIO_H__ + +#include "emu.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_EPSON_SIO_ADD(_tag, _def_slot) \ + MCFG_DEVICE_ADD(_tag, EPSON_SIO, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(epson_sio_devices, _def_slot, false) + +#define MCFG_EPSON_SIO_RX(_rx) \ + downcast<epson_sio_device *>(device)->set_rx_callback(DEVCB2_##_rx); + +#define MCFG_EPSON_SIO_PIN(_pin) \ + downcast<epson_sio_device *>(device)->set_pin_callback(DEVCB2_##_pin); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class device_epson_sio_interface; + + +class epson_sio_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + epson_sio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~epson_sio_device(); + + // callbacks + template<class _rx> void set_rx_callback(_rx rx) { m_write_rx.set_callback(rx); } + template<class _pin> void set_pin_callback(_pin pin) { m_write_pin.set_callback(pin); } + + // called from owner + DECLARE_WRITE_LINE_MEMBER( tx_w ); + DECLARE_WRITE_LINE_MEMBER( pout_w ); + + // called from subdevice + DECLARE_WRITE_LINE_MEMBER( rx_w ) { m_write_rx(state); } + DECLARE_WRITE_LINE_MEMBER( pin_w ) { m_write_pin(state); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + device_epson_sio_interface *m_cart; + +private: + devcb2_write_line m_write_rx; + devcb2_write_line m_write_pin; +}; + + +// class representing interface-specific live sio device +class device_epson_sio_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_epson_sio_interface(const machine_config &mconfig, device_t &device); + virtual ~device_epson_sio_interface(); + + virtual void tx_w(int state) { }; + virtual void pout_w(int state) { }; + +protected: + epson_sio_device *m_slot; +}; + + +// device type definition +extern const device_type EPSON_SIO; + + +// supported devices +SLOT_INTERFACE_EXTERN( epson_sio_devices ); + + +#endif // __EPSON_SIO_H__ diff --git a/src/emu/bus/epson_sio/pf10.c b/src/emu/bus/epson_sio/pf10.c new file mode 100644 index 00000000000..1faf656637d --- /dev/null +++ b/src/emu/bus/epson_sio/pf10.c @@ -0,0 +1,242 @@ +/********************************************************************** + + EPSON PF-10 + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Battery operated portable 3.5" floppy drive + + Status: Needs lots of work. + +**********************************************************************/ + +#include "pf10.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type EPSON_PF10 = &device_creator<epson_pf10_device>; + + +//------------------------------------------------- +// address maps +//------------------------------------------------- + +static ADDRESS_MAP_START( cpu_mem, AS_PROGRAM, 8, epson_pf10_device ) + AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE("maincpu", hd6303y_cpu_device, m6801_io_r, m6801_io_w) + AM_RANGE(0x0040, 0x00ff) AM_RAM /* 192 bytes internal ram */ + AM_RANGE(0x0800, 0x0fff) AM_RAM /* external 2k ram */ + AM_RANGE(0x1000, 0x17ff) AM_READWRITE(fdc_r, fdc_w) + AM_RANGE(0x1800, 0x1fff) AM_WRITE(fdc_tc_w) + AM_RANGE(0xe000, 0xffff) AM_ROM AM_REGION("maincpu", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( cpu_io, AS_IO, 8, epson_pf10_device ) + AM_RANGE(M6801_PORT1, M6801_PORT1) AM_READWRITE(port1_r, port1_w) + AM_RANGE(M6801_PORT2, M6801_PORT2) AM_READWRITE(port2_r, port2_w) +ADDRESS_MAP_END + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( pf10 ) + ROM_REGION(0x2000, "maincpu", 0) + ROM_LOAD("k3pf1.bin", 0x0000, 0x2000, CRC(eef4593a) SHA1(bb176e4baf938fe58c2d32f7c46d7bb7b0627755)) +ROM_END + +const rom_entry *epson_pf10_device::device_rom_region() const +{ + return ROM_NAME( pf10 ); +} + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +static SLOT_INTERFACE_START( pf10_floppies ) + SLOT_INTERFACE( "smd165", EPSON_SMD_165 ) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( pf10 ) + MCFG_CPU_ADD("maincpu", HD6303Y, XTAL_4_9152MHz) // HD63A03XF + MCFG_CPU_PROGRAM_MAP(cpu_mem) + MCFG_CPU_IO_MAP(cpu_io) + MCFG_M6801_SER_TX(DEVWRITELINE(DEVICE_SELF, epson_pf10_device, hd6303_tx_w)) + + MCFG_UPD765A_ADD("upd765a", false, true) + MCFG_FLOPPY_DRIVE_ADD("upd765a:0", pf10_floppies, "smd165", floppy_image_device::default_floppy_formats) + + MCFG_EPSON_SIO_ADD("sio", NULL) + MCFG_EPSON_SIO_RX(DEVWRITELINE(DEVICE_SELF, epson_pf10_device, rxc_w)) + MCFG_EPSON_SIO_PIN(DEVWRITELINE(DEVICE_SELF, epson_pf10_device, pinc_w)) +MACHINE_CONFIG_END + +machine_config_constructor epson_pf10_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( pf10 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// epson_pf10_device - constructor +//------------------------------------------------- + +epson_pf10_device::epson_pf10_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, EPSON_PF10, "EPSON PF-10 Portable Floppy Unit", tag, owner, clock, "epson_pf10", __FILE__), + device_epson_sio_interface(mconfig, *this), + m_cpu(*this, "maincpu"), + m_fdc(*this, "upd765a"), + m_sio_output(*this, "sio"), + m_port1(0xff), + m_port2(0xff), + m_rxc(1) +{ + m_sio_input = dynamic_cast<epson_sio_device *>(owner); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void epson_pf10_device::device_start() +{ + m_timer = timer_alloc(0, NULL); + m_floppy = subdevice<floppy_connector>("upd765a:0")->get_device(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void epson_pf10_device::device_reset() +{ + m_timer->adjust(attotime::zero, 0, attotime::from_hz(38400 * 8)); +} + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void epson_pf10_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case 0: + m_cpu->m6801_clock_serial(); + break; + } +} + + +//************************************************************************** +// CPU +//************************************************************************** + +READ8_MEMBER( epson_pf10_device::port1_r ) +{ + logerror("%s: port1_r(%02x)\n", tag(), m_port1); + return m_port1; +} + +WRITE8_MEMBER( epson_pf10_device::port1_w ) +{ + logerror("%s: port1_w(%02x)\n", tag(), data); +} + +READ8_MEMBER( epson_pf10_device::port2_r ) +{ + logerror("%s: port2_r(%02x)\n", tag(), m_port2); + return m_port2; +} + +WRITE8_MEMBER( epson_pf10_device::port2_w ) +{ + m_floppy->mon_w(data & PORT2_MON); + logerror("%s: port2_w(%02x)\n", tag(), data); +} + +READ8_MEMBER( epson_pf10_device::fdc_r ) +{ + logerror("%s: fdc_r @ %04x\n", tag(), offset); + return 0xff; +} + +WRITE8_MEMBER( epson_pf10_device::fdc_w ) +{ + logerror("%s: fdc_w @ %04x (%02x)\n", tag(), offset, data); +} + +WRITE8_MEMBER( epson_pf10_device::fdc_tc_w ) +{ + logerror("%s: fdc_tc_w(%02x)\n", tag(), data); +} + + +//************************************************************************** +// SIO INTERFACE +//************************************************************************** + +//------------------------------------------------- +// rxc_w - rx input +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_pf10_device::rxc_w ) +{ + m_rxc = state; + m_sio_input->rx_w(m_hd6303_tx & m_rxc); +} + +//------------------------------------------------- +// pinc_w - pin input +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_pf10_device::pinc_w ) +{ + m_pinc = state; + m_sio_input->pin_w(m_pinc); +} + +//------------------------------------------------- +// hd6303_tx_w - rx output +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_pf10_device::hd6303_tx_w ) +{ + m_hd6303_tx = state; + m_sio_input->rx_w(m_hd6303_tx & m_rxc); +} + +//------------------------------------------------- +// tx_w - tx input +//------------------------------------------------- + +void epson_pf10_device::tx_w(int level) +{ + if (level) + m_port2 |= PORT2_RXD; + else + m_port2 &= ~PORT2_RXD; + + m_sio_output->tx_w(level); +} + +//------------------------------------------------- +// pout_w - pout input +//------------------------------------------------- + +void epson_pf10_device::pout_w(int level) +{ + m_sio_output->pout_w(level); +} diff --git a/src/emu/bus/epson_sio/pf10.h b/src/emu/bus/epson_sio/pf10.h new file mode 100644 index 00000000000..df0bdc56cfa --- /dev/null +++ b/src/emu/bus/epson_sio/pf10.h @@ -0,0 +1,102 @@ +/********************************************************************** + + EPSON PF-10 + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Battery operated portable 3.5" floppy drive + +**********************************************************************/ + +#pragma once + +#ifndef __PF10_H__ +#define __PF10_H__ + +#include "emu.h" +#include "cpu/m6800/m6800.h" +#include "machine/upd765.h" +#include "epson_sio.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class epson_pf10_device : public device_t, + public device_epson_sio_interface +{ +public: + // construction/destruction + epson_pf10_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + + // floppy disk controller + DECLARE_READ8_MEMBER( fdc_r ); + DECLARE_WRITE8_MEMBER( fdc_w ); + DECLARE_WRITE8_MEMBER( fdc_tc_w ); + + // hd6303 i/o + DECLARE_READ8_MEMBER( port1_r ); + DECLARE_WRITE8_MEMBER( port1_w ); + DECLARE_READ8_MEMBER( port2_r ); + DECLARE_WRITE8_MEMBER( port2_w ); + + // serial output from main cpu + DECLARE_WRITE_LINE_MEMBER( hd6303_tx_w ); + + // from sio output + DECLARE_WRITE_LINE_MEMBER( rxc_w ); + DECLARE_WRITE_LINE_MEMBER( pinc_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device_epson_sio_interface overrides + virtual void tx_w(int level); + virtual void pout_w(int level); + +private: + required_device<hd6303y_cpu_device> m_cpu; + required_device<upd765a_device> m_fdc; + required_device<epson_sio_device> m_sio_output; + + epson_sio_device *m_sio_input; + floppy_image_device *m_floppy; + + emu_timer *m_timer; + + UINT8 m_port1; + UINT8 m_port2; + + int m_rxc; + int m_hd6303_tx; + int m_pinc; + + // port definitions + enum + { + PORT2_SEEK = 0x01, + PORT2_SWCOM = 0x02, // ? + PORT2_RS232ON = 0x04, // to nmi? + PORT2_RXD = 0x08, + PORT2_TXD = 0x10, + PORT2_FDCRST = 0x20, + PORT2_MON = 0x40, + PORT2_BATCKEN = 0x80 // ? + }; +}; + + +// device type definition +extern const device_type EPSON_PF10; + + +#endif // __PF10_H__ diff --git a/src/emu/bus/epson_sio/tf20.c b/src/emu/bus/epson_sio/tf20.c new file mode 100644 index 00000000000..645b68365e6 --- /dev/null +++ b/src/emu/bus/epson_sio/tf20.c @@ -0,0 +1,343 @@ +/********************************************************************** + + EPSON TF-20 + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Dual 5.25" floppy drive with HX-20 factory option + + Status: Needs testing. + + http://fjkraan.home.xs4all.nl/comp/tf20/index.html + +**********************************************************************/ + +#include "tf20.h" + +#define XTAL_CR1 XTAL_8MHz +#define XTAL_CR2 XTAL_4_9152MHz + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type EPSON_TF20 = &device_creator<epson_tf20_device>; + +//------------------------------------------------- +// address maps +//------------------------------------------------- + +static ADDRESS_MAP_START( cpu_mem, AS_PROGRAM, 8, epson_tf20_device ) + AM_RANGE(0x0000, 0x7fff) AM_RAMBANK("bank1") + AM_RANGE(0x8000, 0xffff) AM_RAMBANK("bank2") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( cpu_io, AS_IO, 8, epson_tf20_device ) + ADDRESS_MAP_UNMAP_HIGH + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("3a", upd7201_device, ba_cd_r, ba_cd_w) + AM_RANGE(0xf6, 0xf6) AM_READ(rom_disable_r) + AM_RANGE(0xf7, 0xf7) AM_READ_PORT("tf20_dip") + AM_RANGE(0xf8, 0xf8) AM_READWRITE(upd765_tc_r, fdc_control_w) + AM_RANGE(0xfa, 0xfb) AM_DEVICE("5a", upd765a_device, map) +ADDRESS_MAP_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( tf20 ) + ROM_REGION(0x0800, "rom", 0) + ROM_LOAD("tfx.15e", 0x0000, 0x0800, CRC(af34f084) SHA1(c9bdf393f757ba5d8f838108ceb2b079be1d616e)) +ROM_END + +const rom_entry *epson_tf20_device::device_rom_region() const +{ + return ROM_NAME( tf20 ); +} + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +INPUT_PORTS_START( tf20 ) + PORT_START("tf20_dip") + PORT_DIPNAME(0x0f, 0x00, "Drive extension") + PORT_DIPLOCATION("TF-20:8,7,6,5") + PORT_DIPSETTING(0x00, "A & B Drive") + PORT_DIPSETTING(0x01, "C & D Drive") +INPUT_PORTS_END + +ioport_constructor epson_tf20_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( tf20 ); +} + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +static UPD7201_INTERFACE( tf20_upd7201_intf ) +{ + 0, 0, 0, 0, + + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, epson_tf20_device, txda_w), + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, epson_tf20_device, dtra_w), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL +}; + +static SLOT_INTERFACE_START( tf20_floppies ) + SLOT_INTERFACE( "sd320", EPSON_SD_320 ) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( tf20 ) + MCFG_CPU_ADD("19b", Z80, XTAL_CR1 / 2) /* uPD780C */ + MCFG_CPU_PROGRAM_MAP(cpu_mem) + MCFG_CPU_IO_MAP(cpu_io) + + // 64k internal ram + MCFG_RAM_ADD("ram") + MCFG_RAM_DEFAULT_SIZE("64k") + + // upd7201 serial interface + MCFG_UPD7201_ADD("3a", XTAL_CR1 / 2, tf20_upd7201_intf) + MCFG_UPD765_INTRQ_CALLBACK(INPUTLINE("19b", INPUT_LINE_IRQ0)) + + // floppy disk controller + MCFG_UPD765A_ADD("5a", true, true) + + // floppy drives + MCFG_FLOPPY_DRIVE_ADD("5a:0", tf20_floppies, "sd320", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("5a:1", tf20_floppies, "sd320", floppy_image_device::default_floppy_formats) + + // serial interface to another device + MCFG_EPSON_SIO_ADD("sio", NULL) + MCFG_EPSON_SIO_RX(DEVWRITELINE(DEVICE_SELF, epson_tf20_device, rxc_w)) + MCFG_EPSON_SIO_PIN(DEVWRITELINE(DEVICE_SELF, epson_tf20_device, pinc_w)) +MACHINE_CONFIG_END + +machine_config_constructor epson_tf20_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( tf20 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// epson_tf20_device - constructor +//------------------------------------------------- + +epson_tf20_device::epson_tf20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, EPSON_TF20, "EPSON TF-20 Dual Floppy Disk Drive", tag, owner, clock, "epson_tf20", __FILE__), + device_epson_sio_interface(mconfig, *this), + m_cpu(*this, "19b"), + m_ram(*this, "ram"), + m_fdc(*this, "5a"), + m_mpsc(*this, "3a"), + m_sio_output(*this, "sio"), + m_rxc(1) +{ + m_sio_input = dynamic_cast<epson_sio_device *>(owner); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void epson_tf20_device::device_start() +{ + // make sure the ram device is already running + if (!m_ram->started()) + throw device_missing_dependencies(); + + m_timer_serial = timer_alloc(0, NULL); + m_timer_tc = timer_alloc(1, NULL); + + m_cpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(epson_tf20_device::irq_callback),this)); + + m_fd0 = subdevice<floppy_connector>("5a:0")->get_device(); + m_fd1 = subdevice<floppy_connector>("5a:1")->get_device(); + + // enable second half of ram + m_cpu->space(AS_PROGRAM).install_ram(0x8000, 0xffff, m_ram->pointer() + 0x8000); + +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void epson_tf20_device::device_reset() +{ + // init timers + m_timer_serial->adjust(attotime::zero, 0, attotime::from_hz(XTAL_CR2 / 8)); + m_timer_tc->adjust(attotime::never); + + m_mpsc->rxa_w(1); + m_mpsc->rxb_w(1); + + // enable rom + m_cpu->space(AS_PROGRAM).install_rom(0x0000, 0x07ff, 0, 0x7800, memregion("rom")->base()); +} + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void epson_tf20_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case 0: + m_mpsc->rxca_w(1); + m_mpsc->rxca_w(0); + m_mpsc->txca_w(1); + m_mpsc->txca_w(0); + m_mpsc->rxcb_w(1); + m_mpsc->rxcb_w(0); + m_mpsc->txcb_w(1); + m_mpsc->txcb_w(0); + break; + + case 1: + logerror("%s: tc off\n", tag()); + m_fdc->tc_w(false); + break; + } +} + + +//************************************************************************** +// CPU & MEMORY +//************************************************************************** + +//------------------------------------------------- +// irq vector callback +//------------------------------------------------- + +IRQ_CALLBACK_MEMBER( epson_tf20_device::irq_callback ) +{ + return 0x00; +} + +// a read from this location disables the rom +READ8_MEMBER( epson_tf20_device::rom_disable_r ) +{ + // switch in ram + m_cpu->space(AS_PROGRAM).install_ram(0x0000, 0x7fff, m_ram->pointer()); + return 0xff; +} + + +//************************************************************************** +// FLOPPY DISK CONTROLLER +//************************************************************************** + +//------------------------------------------------- +// fdc interrupt +//------------------------------------------------- + +READ8_MEMBER( epson_tf20_device::upd765_tc_r ) +{ + logerror("%s: upd765_tc_r\n", space.machine().describe_context()); + + // toggle tc on read + m_fdc->tc_w(true); + m_timer_tc->adjust(attotime::zero); + + return 0xff; +} + +WRITE8_MEMBER( epson_tf20_device::fdc_control_w ) +{ + logerror("%s: tf20_fdc_control_w(%02x)\n", space.machine().describe_context(), data); + + // bit 0, motor on signal + m_fd0->mon_w(!BIT(data, 0)); + m_fd1->mon_w(!BIT(data, 0)); +} + + +//************************************************************************** +// SIO INTERFACE +//************************************************************************** + +//------------------------------------------------- +// rxc_w - rx input +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_tf20_device::rxc_w ) +{ + m_rxc = state; + m_sio_input->rx_w(m_txda & m_rxc); +} + +//------------------------------------------------- +// pinc_w - pin input +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_tf20_device::pinc_w ) +{ + m_pinc = state; + m_sio_input->pin_w(!m_dtra | m_pinc); +} + +//------------------------------------------------- +// txda_w - rx output +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_tf20_device::txda_w ) +{ + m_txda = state; + m_sio_input->rx_w(m_txda & m_rxc); +} + +//------------------------------------------------- +// dtra_w - pin output +//------------------------------------------------- + +WRITE_LINE_MEMBER( epson_tf20_device::dtra_w ) +{ + m_dtra = state; + m_sio_input->pin_w(!m_dtra | m_pinc); +} + +//------------------------------------------------- +// tx_w - tx input +//------------------------------------------------- + +void epson_tf20_device::tx_w(int level) +{ + m_mpsc->rxa_w(level); + m_sio_output->tx_w(level); +} + +//------------------------------------------------- +// pout_w - pout input +//------------------------------------------------- + +void epson_tf20_device::pout_w(int level) +{ + m_mpsc->ctsa_w(!level); + m_sio_output->pout_w(level); +} diff --git a/src/emu/bus/epson_sio/tf20.h b/src/emu/bus/epson_sio/tf20.h new file mode 100644 index 00000000000..9aa5f2c47cb --- /dev/null +++ b/src/emu/bus/epson_sio/tf20.h @@ -0,0 +1,92 @@ +/********************************************************************** + + EPSON TF-20 + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Dual 5.25" floppy drive with HX-20 factory option + +**********************************************************************/ + +#pragma once + +#ifndef __TF20_H__ +#define __TF20_H__ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "machine/ram.h" +#include "machine/upd765.h" +#include "machine/z80dart.h" +#include "epson_sio.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class epson_tf20_device : public device_t, + public device_epson_sio_interface +{ +public: + // construction/destruction + epson_tf20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + virtual ioport_constructor device_input_ports() const; + + // not really public + DECLARE_READ8_MEMBER( rom_disable_r ); + DECLARE_READ8_MEMBER( upd765_tc_r ); + DECLARE_WRITE8_MEMBER( fdc_control_w ); + IRQ_CALLBACK_MEMBER( irq_callback ); + DECLARE_WRITE_LINE_MEMBER( txda_w ); + DECLARE_WRITE_LINE_MEMBER( dtra_w ); + + // from sio output + DECLARE_WRITE_LINE_MEMBER( rxc_w ); + DECLARE_WRITE_LINE_MEMBER( pinc_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device_epson_sio_interface overrides + virtual void tx_w(int level); + virtual void pout_w(int level); + +private: + required_device<cpu_device> m_cpu; + required_device<ram_device> m_ram; + required_device<upd765a_device> m_fdc; + required_device<upd7201_device> m_mpsc; + required_device<epson_sio_device> m_sio_output; + + floppy_image_device *m_fd0; + floppy_image_device *m_fd1; + + emu_timer *m_timer_serial; + emu_timer *m_timer_tc; + + int m_rxc; + int m_txda; + int m_dtra; + int m_pinc; + + epson_sio_device *m_sio_input; + + static const int XTAL_CR1 = XTAL_8MHz; + static const int XTAL_CR2 = XTAL_4_9152MHz; +}; + + +// device type definition +extern const device_type EPSON_TF20; + + +#endif // __TF20_H__ diff --git a/src/emu/bus/pce/pce_rom.c b/src/emu/bus/pce/pce_rom.c new file mode 100644 index 00000000000..57b7a6a76bb --- /dev/null +++ b/src/emu/bus/pce/pce_rom.c @@ -0,0 +1,124 @@ +/*********************************************************************************************************** + + + PC-Engine & Turbografx-16 cart emulation + + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "pce_rom.h" + + +//------------------------------------------------- +// pce_rom_device - constructor +//------------------------------------------------- + +const device_type PCE_ROM_STD = &device_creator<pce_rom_device>; +const device_type PCE_ROM_CDSYS3 = &device_creator<pce_cdsys3_device>; +const device_type PCE_ROM_POPULOUS = &device_creator<pce_populous_device>; +const device_type PCE_ROM_SF2 = &device_creator<pce_sf2_device>; + + +pce_rom_device::pce_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_pce_cart_interface( mconfig, *this ) +{ +} + +pce_rom_device::pce_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, PCE_ROM_STD, "PCE & TG16 Carts", tag, owner, clock, "pce_rom", __FILE__), + device_pce_cart_interface( mconfig, *this ) +{ +} + +pce_cdsys3_device::pce_cdsys3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pce_rom_device(mconfig, PCE_ROM_CDSYS3, "PCE & TG16 CD-System Cart v3.00", tag, owner, clock, "pce_cdsys3", __FILE__) +{ +} + +pce_populous_device::pce_populous_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pce_rom_device(mconfig, PCE_ROM_POPULOUS, "PCE Populous Cart", tag, owner, clock, "pce_populous", __FILE__) +{ +} + +pce_sf2_device::pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pce_rom_device(mconfig, PCE_ROM_SF2, "PCE Street Fighters 2 Cart", tag, owner, clock, "pce_sf2", __FILE__) +{ +} + + +//------------------------------------------------- +// mapper specific start/reset +//------------------------------------------------- + + +void pce_sf2_device::device_start() +{ + save_item(NAME(m_bank_base)); +} + +void pce_sf2_device::device_reset() +{ + m_bank_base = 0; +} + + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +READ8_MEMBER(pce_rom_device::read_cart) +{ + int bank = offset / 0x20000; + return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)]; +} + + +READ8_MEMBER(pce_cdsys3_device::read_cart) +{ + int bank = offset / 0x20000; + if (m_ram && offset >= 0xd0000) + return m_ram[offset - 0xd0000]; + + return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)]; +} + +WRITE8_MEMBER(pce_cdsys3_device::write_cart) +{ + if (m_ram && offset >= 0xd0000) + m_ram[offset - 0xd0000] = data; +} + + +READ8_MEMBER(pce_populous_device::read_cart) +{ + int bank = offset / 0x20000; + if (m_ram && offset >= 0x80000 && offset < 0x88000) + return m_ram[offset & 0x7fff]; + + return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)]; +} + +WRITE8_MEMBER(pce_populous_device::write_cart) +{ + if (m_ram && offset >= 0x80000 && offset < 0x88000) + m_ram[offset & 0x7fff] = data; +} + + +READ8_MEMBER(pce_sf2_device::read_cart) +{ + if (offset < 0x80000) + return m_rom[offset]; + else + return m_rom[0x80000 + m_bank_base * 0x80000 + (offset & 0x7ffff)]; +} + +WRITE8_MEMBER(pce_sf2_device::write_cart) +{ + if (offset >= 0x1ff0 && offset < 0x1ff4) + m_bank_base = offset & 3; +} diff --git a/src/emu/bus/pce/pce_rom.h b/src/emu/bus/pce/pce_rom.h new file mode 100644 index 00000000000..1588757b96f --- /dev/null +++ b/src/emu/bus/pce/pce_rom.h @@ -0,0 +1,83 @@ +#ifndef __PCE_ROM_H +#define __PCE_ROM_H + +#include "pce_slot.h" + + +// ======================> pce_rom_device + +class pce_rom_device : public device_t, + public device_pce_cart_interface +{ +public: + // construction/destruction + pce_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); + pce_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start() {} + virtual void device_reset() {} + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart); +}; + +// ======================> pce_cdsys3_device + +class pce_cdsys3_device : public pce_rom_device +{ +public: + // construction/destruction + pce_cdsys3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart); + virtual DECLARE_WRITE8_MEMBER(write_cart); +}; + + +// ======================> pce_populous_device + +class pce_populous_device : public pce_rom_device +{ +public: + // construction/destruction + pce_populous_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart); + virtual DECLARE_WRITE8_MEMBER(write_cart); +}; + + +// ======================> pce_sf2_device + +class pce_sf2_device : public pce_rom_device +{ +public: + // construction/destruction + pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart); + virtual DECLARE_WRITE8_MEMBER(write_cart); + +private: + UINT8 m_bank_base; +}; + + + +// device type definition +extern const device_type PCE_ROM_STD; +extern const device_type PCE_ROM_CDSYS3; +extern const device_type PCE_ROM_POPULOUS; +extern const device_type PCE_ROM_SF2; + + + +#endif diff --git a/src/emu/bus/pce/pce_slot.c b/src/emu/bus/pce/pce_slot.c new file mode 100644 index 00000000000..68fb95e28d6 --- /dev/null +++ b/src/emu/bus/pce/pce_slot.c @@ -0,0 +1,384 @@ +/*********************************************************************************************************** + + + PC-Engine / Turbografx-16 cart emulation + (through slot devices) + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "pce_slot.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type PCE_CART_SLOT = &device_creator<pce_cart_slot_device>; + +//************************************************************************** +// PCE cartridges Interface +//************************************************************************** + +//------------------------------------------------- +// device_pce_cart_interface - constructor +//------------------------------------------------- + +device_pce_cart_interface::device_pce_cart_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_rom(NULL), + m_ram(NULL), + m_rom_size(0), + m_ram_size(0) +{ +} + + +//------------------------------------------------- +// ~device_pce_cart_interface - destructor +//------------------------------------------------- + +device_pce_cart_interface::~device_pce_cart_interface() +{ +} + +//------------------------------------------------- +// rom_alloc - alloc the space for the cart +//------------------------------------------------- + +void device_pce_cart_interface::rom_alloc(running_machine &machine, UINT32 size) +{ + if (m_rom == NULL) + { + m_rom = auto_alloc_array_clear(machine, UINT8, size); + m_rom_size = size; + } +} + + +//------------------------------------------------- +// ram_alloc - alloc the space for the ram +//------------------------------------------------- + +void device_pce_cart_interface::ram_alloc(running_machine &machine, UINT32 size) +{ + if (m_ram == NULL) + { + m_ram = auto_alloc_array_clear(machine, UINT8, size); + m_ram_size = size; + state_save_register_item_pointer(machine, "PCE_CART", this->device().tag(), 0, m_ram, m_ram_size); + } +} + +//------------------------------------------------- +// rom_map_setup - setup map of rom banks in 128K +// blocks, so to simplify ROM access to mirror +//------------------------------------------------- + +void device_pce_cart_interface::rom_map_setup(UINT32 size) +{ + int i; + + if (size == 0x60000) + { + // HuCard 384K are mapped with mirrored pieces + rom_bank_map[0] = 0; + rom_bank_map[1] = 1; + rom_bank_map[2] = 0; + rom_bank_map[3] = 1; + rom_bank_map[4] = 2; + rom_bank_map[5] = 2; + rom_bank_map[6] = 2; + rom_bank_map[7] = 2; + } + else + { + // setup the rom_bank_map array to faster ROM read + for (i = 0; i < size / 0x20000 && i < 8; i++) + rom_bank_map[i] = i; + + // fill up remaining blocks with mirrors + while (i % 8) + { + int j = 0, repeat_banks; + while ((i % (8 >> j)) && j < 3) + j++; + repeat_banks = i % (8 >> (j - 1)); + for (int k = 0; k < repeat_banks; k++) + rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks]; + i += repeat_banks; + } + } + // check bank map! +// for (i = 0; i < 8; i++) +// { +// printf("bank %3d = %3d\t", i, rom_bank_map[i]); +// } +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// pce_cart_slot_device - constructor +//------------------------------------------------- +pce_cart_slot_device::pce_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, PCE_CART_SLOT, "PCE & TG16 Cartridge Slot", tag, owner, clock, "pce_cart_slot", __FILE__), + device_image_interface(mconfig, *this), + device_slot_interface(mconfig, *this), + m_interface("pce_cart"), + m_type(PCE_STD) +{ +} + + +//------------------------------------------------- +// pce_cart_slot_device - destructor +//------------------------------------------------- + +pce_cart_slot_device::~pce_cart_slot_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void pce_cart_slot_device::device_start() +{ + m_cart = dynamic_cast<device_pce_cart_interface *>(get_card_device()); +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void pce_cart_slot_device::device_config_complete() +{ + // set brief and instance name + update_names(); +} + + +//------------------------------------------------- +// PCE PCB +//------------------------------------------------- + +struct pce_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 pce_slot slot_list[] = +{ + { PCE_STD, "rom" }, + { PCE_CDSYS3U, "cdsys3u" }, + { PCE_CDSYS3J, "cdsys3j" }, + { PCE_POPULOUS, "populous" }, + { PCE_SF2, "sf2" }, +}; + +static int pce_get_pcb_id(const char *slot) +{ + for (int i = 0; i < ARRAY_LENGTH(slot_list); i++) + { + if (!mame_stricmp(slot_list[i].slot_option, slot)) + return slot_list[i].pcb_id; + } + + return 0; +} + +static const char *pce_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 "rom"; +} + + +/*------------------------------------------------- + call load + -------------------------------------------------*/ + +bool pce_cart_slot_device::call_load() +{ + if (m_cart) + { + UINT32 offset = 0; + UINT32 len = (software_entry() == NULL) ? length() : get_software_region_length("rom"); + UINT8 *ROM; + + // From fullpath, check for presence of a header and skip it + if (software_entry() == NULL && (len % 0x4000) == 512) + { + logerror("Rom-header found, skipping\n"); + offset = 512; + len -= offset; + fseek(offset, SEEK_SET); + } + + m_cart->rom_alloc(machine(), len); + ROM = m_cart->get_rom_base(); + + if (software_entry() == NULL) + fread(ROM, len); + else + memcpy(ROM, get_software_region("rom"), len); + + // check for encryption (US carts) + if (ROM[0x1fff] < 0xe0) + { + UINT8 decrypted[256]; + + /* Initialize decryption table */ + for (int i = 0; i < 256; i++) + decrypted[i] = ((i & 0x01) << 7) | ((i & 0x02) << 5) | ((i & 0x04) << 3) | ((i & 0x08) << 1) | ((i & 0x10) >> 1) | ((i & 0x20 ) >> 3) | ((i & 0x40) >> 5) | ((i & 0x80) >> 7); + + /* Decrypt ROM image */ + for (int i = 0; i < len; i++) + ROM[i] = decrypted[ROM[i]]; + } + + m_cart->rom_map_setup(len); + + if (software_entry() == NULL) + m_type = get_cart_type(ROM, len); + else + { + const char *pcb_name = get_feature("slot"); + if (pcb_name) + m_type = pce_get_pcb_id(pcb_name); + } + //printf("Type: %s\n", pce_get_slot(m_type)); + + if (m_type == PCE_POPULOUS) + m_cart->ram_alloc(machine(), 0x8000); + if (m_type == PCE_CDSYS3J || m_type == PCE_CDSYS3U) + m_cart->ram_alloc(machine(), 0x30000); + + return IMAGE_INIT_PASS; + } + + return IMAGE_INIT_PASS; +} + + +/*------------------------------------------------- + call_unload + -------------------------------------------------*/ + +void pce_cart_slot_device::call_unload() +{ +} + + +/*------------------------------------------------- + call softlist load + -------------------------------------------------*/ + +bool pce_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_cart_type - code to detect NVRAM type from + fullpath + -------------------------------------------------*/ + +int pce_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) +{ + int type = PCE_STD; + + /* Check for Street fighter 2 */ + if (len == 0x280000) + type = PCE_SF2; + + /* Check for Populous */ + if (len >= 0x1f26 + 8 && !memcmp(ROM + 0x1f26, "POPULOUS", 8)) + type = PCE_POPULOUS; + + // Check for CD system card v3 which adds on-cart RAM to the system + if (!memcmp(ROM + 0x3FFB6, "PC Engine CD-ROM SYSTEM", 23)) + { + /* Check if 192KB additional system card ram should be used */ + if(!memcmp(ROM + 0x29D1, "VER. 3.", 7)) { type = PCE_CDSYS3J; } // JP version + else if(!memcmp(ROM + 0x29C4, "VER. 3.", 7 )) { type = PCE_CDSYS3U; } // US version + } + + return type; +} + + +/*------------------------------------------------- + get default card software + -------------------------------------------------*/ + +void pce_cart_slot_device::get_default_card_software(astring &result) +{ + if (open_image_file(mconfig().options())) + { + const char *slot_string = "rom"; + UINT32 len = core_fsize(m_file); + dynamic_buffer rom(len); + int type; + + core_fread(m_file, rom, len); + + type = get_cart_type(rom, len); + slot_string = pce_get_slot(type); + + //printf("type: %s\n", slot_string); + clear(); + + result.cpy(slot_string); + return; + } + + software_get_default_slot(result, "rom"); +} + +/*------------------------------------------------- + read + -------------------------------------------------*/ + +READ8_MEMBER(pce_cart_slot_device::read_cart) +{ + if (m_cart) + return m_cart->read_cart(space, offset); + else + return 0xff; +} + +/*------------------------------------------------- + write + -------------------------------------------------*/ + +WRITE8_MEMBER(pce_cart_slot_device::write_cart) +{ + if (m_cart) + m_cart->write_cart(space, offset, data); +} + + +/*------------------------------------------------- + Internal header logging + -------------------------------------------------*/ + +void pce_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len) +{ +} diff --git a/src/emu/bus/pce/pce_slot.h b/src/emu/bus/pce/pce_slot.h new file mode 100644 index 00000000000..655fffa57da --- /dev/null +++ b/src/emu/bus/pce/pce_slot.h @@ -0,0 +1,126 @@ +#ifndef __PCE_SLOT_H +#define __PCE_SLOT_H + +/*************************************************************************** + TYPE DEFINITIONS + ***************************************************************************/ + + +/* PCB */ +enum +{ + PCE_STD = 0, + PCE_CDSYS3J, + PCE_CDSYS3U, + PCE_POPULOUS, + PCE_SF2 +}; + + +// ======================> device_pce_cart_interface + +class device_pce_cart_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_pce_cart_interface(const machine_config &mconfig, device_t &device); + virtual ~device_pce_cart_interface(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart) { return 0xff; } + virtual DECLARE_WRITE8_MEMBER(write_cart) {}; + + void rom_alloc(running_machine &machine, UINT32 size); + void ram_alloc(running_machine &machine, 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_size; } + + // internal state + UINT8 *m_rom; + UINT8 *m_ram; + UINT32 m_rom_size; + UINT32 m_ram_size; + + void rom_map_setup(UINT32 size); + + UINT8 rom_bank_map[8]; // 128K chunks of rom +}; + + +// ======================> pce_cart_slot_device + +class pce_cart_slot_device : public device_t, + public device_image_interface, + public device_slot_interface +{ +public: + // construction/destruction + pce_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~pce_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 get_cart_type(UINT8 *ROM, UINT32 len); + + void setup_ram(UINT8 banks); + void internal_header_logging(UINT8 *ROM, UINT32 len); + + void set_intf(const char * interface) { m_interface = interface; } + + 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 1; } + 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 m_interface; } + virtual const char *file_extensions() const { return "pce,bin"; } + + // slot interface overrides + virtual void get_default_card_software(astring &result); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart); + virtual DECLARE_WRITE8_MEMBER(write_cart); + + +protected: + + const char *m_interface; + int m_type; + device_pce_cart_interface* m_cart; +}; + + + +// device type definition +extern const device_type PCE_CART_SLOT; + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS + ***************************************************************************/ + +#define MCFG_PCE_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ + MCFG_DEVICE_ADD(_tag, PCE_CART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \ + static_cast<pce_cart_slot_device *>(device)->set_intf("pce_cart"); + +#define MCFG_TG16_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ + MCFG_DEVICE_ADD(_tag, PCE_CART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \ + static_cast<pce_cart_slot_device *>(device)->set_intf("tg16_cart"); + + +#endif diff --git a/src/emu/bus/rs232/teleprinter.c b/src/emu/bus/rs232/teleprinter.c new file mode 100644 index 00000000000..59ed867d5c4 --- /dev/null +++ b/src/emu/bus/rs232/teleprinter.c @@ -0,0 +1,239 @@ +#include "teleprinter.h" + +#define KEYBOARD_TAG "keyboard" + +static const UINT8 teleprinter_font[128*8] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, + 0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00, + 0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, + 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, + 0x38,0x38,0x38,0x38,0x07,0x07,0x07,0x07, + 0x3f,0x3f,0x3f,0x3f,0x07,0x07,0x07,0x07, + 0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x38, + 0x07,0x07,0x07,0x07,0x38,0x38,0x38,0x38, + 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38, + 0x3f,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x38, + 0x00,0x00,0x00,0x00,0x3f,0x3f,0x3f,0x3f, + 0x07,0x07,0x07,0x07,0x3f,0x3f,0x3f,0x3f, + 0x38,0x38,0x38,0x38,0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x00,0x00,0x00,0x00,0x2a,0x15,0x2a,0x15, + 0x2a,0x15,0x2a,0x15,0x00,0x00,0x00,0x00, + 0x3f,0x3f,0x3f,0x3f,0x2a,0x15,0x2a,0x15, + 0x2a,0x15,0x2a,0x15,0x3f,0x3f,0x3f,0x3f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x08,0x08,0x08,0x08,0x00,0x08,0x00, + 0x14,0x14,0x14,0x00,0x00,0x00,0x00,0x00, + 0x14,0x14,0x3e,0x14,0x3e,0x14,0x14,0x00, + 0x08,0x3c,0x0a,0x1c,0x28,0x1e,0x08,0x00, + 0x06,0x26,0x10,0x08,0x04,0x32,0x30,0x00, + 0x08,0x14,0x14,0x0c,0x2a,0x12,0x2c,0x00, + 0x08,0x08,0x04,0x00,0x00,0x00,0x00,0x00, + 0x10,0x08,0x04,0x04,0x04,0x08,0x10,0x00, + 0x04,0x08,0x10,0x10,0x10,0x08,0x04,0x00, + 0x00,0x08,0x2a,0x1c,0x2a,0x08,0x00,0x00, + 0x00,0x08,0x08,0x3e,0x08,0x08,0x00,0x00, + 0x00,0x00,0x00,0x00,0x08,0x08,0x04,0x00, + 0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00, + 0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00, + 0x1c,0x22,0x32,0x2a,0x26,0x22,0x1c,0x00, + 0x08,0x0c,0x08,0x08,0x08,0x08,0x1c,0x00, + 0x1c,0x22,0x20,0x18,0x04,0x02,0x3e,0x00, + 0x3e,0x20,0x10,0x18,0x20,0x22,0x1c,0x00, + 0x10,0x18,0x14,0x12,0x3e,0x10,0x10,0x00, + 0x3e,0x02,0x1e,0x20,0x20,0x22,0x1c,0x00, + 0x10,0x08,0x04,0x1c,0x22,0x22,0x1c,0x00, + 0x3e,0x20,0x10,0x08,0x04,0x04,0x04,0x00, + 0x1c,0x22,0x22,0x1c,0x22,0x22,0x1c,0x00, + 0x1c,0x22,0x22,0x1c,0x10,0x08,0x04,0x00, + 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00, + 0x00,0x00,0x08,0x00,0x08,0x08,0x04,0x00, + 0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x00, + 0x00,0x00,0x3e,0x00,0x3e,0x00,0x00,0x00, + 0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00, + 0x1c,0x22,0x20,0x10,0x08,0x00,0x08,0x00, + 0x1c,0x22,0x32,0x2a,0x3a,0x02,0x3c,0x00, + 0x08,0x14,0x22,0x22,0x3e,0x22,0x22,0x00, + 0x1e,0x22,0x22,0x1e,0x22,0x22,0x1e,0x00, + 0x1c,0x22,0x02,0x02,0x02,0x22,0x1c,0x00, + 0x1e,0x24,0x24,0x24,0x24,0x24,0x1e,0x00, + 0x3e,0x02,0x02,0x1e,0x02,0x02,0x3e,0x00, + 0x3e,0x02,0x02,0x1e,0x02,0x02,0x02,0x00, + 0x1c,0x22,0x02,0x02,0x32,0x22,0x3c,0x00, + 0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x00, + 0x1c,0x08,0x08,0x08,0x08,0x08,0x1c,0x00, + 0x38,0x10,0x10,0x10,0x10,0x12,0x0c,0x00, + 0x22,0x12,0x0a,0x06,0x0a,0x12,0x22,0x00, + 0x02,0x02,0x02,0x02,0x02,0x02,0x3e,0x00, + 0x22,0x36,0x2a,0x2a,0x22,0x22,0x22,0x00, + 0x22,0x22,0x26,0x2a,0x32,0x22,0x22,0x00, + 0x1c,0x22,0x22,0x22,0x22,0x22,0x1c,0x00, + 0x1e,0x22,0x22,0x1e,0x02,0x02,0x02,0x00, + 0x1c,0x22,0x22,0x22,0x2a,0x12,0x2c,0x00, + 0x1e,0x22,0x22,0x1e,0x0a,0x12,0x22,0x00, + 0x1c,0x22,0x02,0x1c,0x20,0x22,0x1c,0x00, + 0x3e,0x08,0x08,0x08,0x08,0x08,0x08,0x00, + 0x22,0x22,0x22,0x22,0x22,0x22,0x1c,0x00, + 0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00, + 0x22,0x22,0x22,0x2a,0x2a,0x2a,0x14,0x00, + 0x22,0x22,0x14,0x08,0x14,0x22,0x22,0x00, + 0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x00, + 0x3e,0x20,0x10,0x08,0x04,0x02,0x3e,0x00, + 0x0e,0x02,0x02,0x02,0x02,0x02,0x0e,0x00, + 0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00, + 0x38,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + 0x08,0x1c,0x2a,0x08,0x08,0x08,0x08,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00, + 0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1c,0x20,0x3c,0x22,0x3c,0x00, + 0x02,0x02,0x1e,0x22,0x22,0x22,0x1e,0x00, + 0x00,0x00,0x3c,0x02,0x02,0x02,0x3c,0x00, + 0x20,0x20,0x3c,0x22,0x22,0x22,0x3c,0x00, + 0x00,0x00,0x1c,0x22,0x3e,0x02,0x1c,0x00, + 0x18,0x04,0x0e,0x04,0x04,0x04,0x04,0x00, + 0x00,0x00,0x3c,0x22,0x22,0x3c,0x20,0x18, + 0x02,0x02,0x1e,0x22,0x22,0x22,0x22,0x00, + 0x08,0x00,0x0c,0x08,0x08,0x08,0x1c,0x00, + 0x10,0x00,0x18,0x10,0x10,0x10,0x12,0x0c, + 0x02,0x02,0x22,0x12,0x0e,0x16,0x22,0x00, + 0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x00, + 0x00,0x00,0x16,0x2a,0x2a,0x2a,0x2a,0x00, + 0x00,0x00,0x1a,0x26,0x22,0x22,0x22,0x00, + 0x00,0x00,0x1c,0x22,0x22,0x22,0x1c,0x00, + 0x00,0x00,0x1e,0x22,0x22,0x1e,0x02,0x02, + 0x00,0x00,0x3c,0x22,0x22,0x3c,0x20,0x20, + 0x00,0x00,0x34,0x0c,0x04,0x04,0x04,0x00, + 0x00,0x00,0x3c,0x02,0x1c,0x20,0x1e,0x00, + 0x08,0x08,0x1c,0x08,0x08,0x08,0x10,0x00, + 0x00,0x00,0x22,0x22,0x22,0x32,0x2c,0x00, + 0x00,0x00,0x22,0x22,0x22,0x14,0x08,0x00, + 0x00,0x00,0x22,0x22,0x2a,0x2a,0x14,0x00, + 0x00,0x00,0x22,0x14,0x08,0x14,0x22,0x00, + 0x00,0x00,0x22,0x22,0x14,0x08,0x04,0x02, + 0x00,0x00,0x3e,0x10,0x08,0x04,0x3e,0x00, + 0x10,0x08,0x08,0x04,0x08,0x08,0x10,0x00, + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00, + 0x04,0x08,0x08,0x10,0x08,0x08,0x04,0x00, + 0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2a,0x15,0x2a,0x15,0x2a,0x15,0x2a,0x15 +}; + +teleprinter_device::teleprinter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : generic_terminal_device(mconfig, TELEPRINTER, "Teleprinter", tag, owner, clock, "teleprinter", __FILE__) +{ +} + +void teleprinter_device::scroll_line() +{ + memmove(m_buffer,m_buffer+TELEPRINTER_WIDTH,(TELEPRINTER_HEIGHT-1)*TELEPRINTER_WIDTH); + memset(m_buffer + TELEPRINTER_WIDTH*(TELEPRINTER_HEIGHT-1),0x20,TELEPRINTER_WIDTH); +} + +void teleprinter_device::write_char(UINT8 data) { + m_buffer[(TELEPRINTER_HEIGHT-1)*TELEPRINTER_WIDTH+m_x_pos] = data; + m_x_pos++; + if (m_x_pos >= TELEPRINTER_WIDTH) + { + m_x_pos = 0; + scroll_line(); + } +} + +void teleprinter_device::clear() { + memset(m_buffer,0,TELEPRINTER_WIDTH*TELEPRINTER_HEIGHT); + m_x_pos = 0; +} + +void teleprinter_device::term_write(UINT8 data) +{ + switch(data) { + case 10: m_x_pos = 0; + scroll_line(); + break; + case 13: m_x_pos = 0; break; + case 9: m_x_pos = (m_x_pos & 0xf8) + 8; + if (m_x_pos >= TELEPRINTER_WIDTH) + m_x_pos = TELEPRINTER_WIDTH-1; + + break; + case 16: break; + default: write_char(data); break; + } +} + +/*************************************************************************** + VIDEO HARDWARE +***************************************************************************/ +UINT32 teleprinter_device::tp_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + UINT8 code; + int y, c, x, b; + + for (y = 0; y < TELEPRINTER_HEIGHT; y++) + { + for (c = 0; c < 8; c++) + { + int horpos = 0; + for (x = 0; x < TELEPRINTER_WIDTH; x++) + { + code = teleprinter_font[(m_buffer[y*TELEPRINTER_WIDTH + x] & 0x7f) *8 + c]; + for (b = 0; b < 8; b++) + { + bitmap.pix32(y*8 + c, horpos++) = (code >> b) & 0x01 ? 0 : 0x00ffffff; + } + } + } + } + return 0; +} + +static ASCII_KEYBOARD_INTERFACE( keyboard_intf ) +{ + DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, generic_terminal_device, kbd_put) +}; + +/*************************************************************************** + VIDEO HARDWARE +***************************************************************************/ +MACHINE_CONFIG_FRAGMENT( generic_teleprinter ) + MCFG_SCREEN_ADD(TELEPRINTER_SCREEN_TAG, RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(TELEPRINTER_WIDTH*8, TELEPRINTER_HEIGHT*8) + MCFG_SCREEN_VISIBLE_AREA(0, TELEPRINTER_WIDTH*8-1, 0, TELEPRINTER_HEIGHT*8-1) + MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, teleprinter_device, tp_update) + MCFG_ASCII_KEYBOARD_ADD(KEYBOARD_TAG, keyboard_intf) +MACHINE_CONFIG_END + +machine_config_constructor teleprinter_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME(generic_teleprinter); +} + +/*------------------------------------------------- + device_reset - device-specific reset +-------------------------------------------------*/ + +void teleprinter_device::device_reset() +{ + clear(); + generic_terminal_device::device_reset(); +} + +const device_type TELEPRINTER = &device_creator<teleprinter_device>; diff --git a/src/emu/bus/rs232/teleprinter.h b/src/emu/bus/rs232/teleprinter.h new file mode 100644 index 00000000000..e73e687e49f --- /dev/null +++ b/src/emu/bus/rs232/teleprinter.h @@ -0,0 +1,45 @@ +#ifndef __TELEPRINTER_H__ +#define __TELEPRINTER_H__ + +#include "machine/terminal.h" + +#define TELEPRINTER_WIDTH 80 +#define TELEPRINTER_HEIGHT 50 + +#define GENERIC_TELEPRINTER_INTERFACE GENERIC_TERMINAL_INTERFACE + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ +#define TELEPRINTER_TAG "teleprinter" +#define TELEPRINTER_SCREEN_TAG "tty_screen" + +#define MCFG_GENERIC_TELEPRINTER_ADD(_tag, _intrf) \ + MCFG_DEVICE_ADD(_tag, TELEPRINTER, 0) \ + MCFG_DEVICE_CONFIG(_intrf) + +#define MCFG_GENERIC_TELEPRINTER_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +class teleprinter_device : public generic_terminal_device +{ +public: + teleprinter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + UINT32 tp_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect); +protected: + virtual void term_write(UINT8 data); + virtual void device_reset(); + virtual machine_config_constructor device_mconfig_additions() const; +private: + void scroll_line(); + void write_char(UINT8 data); + void clear(); +}; + +extern const device_type TELEPRINTER; + +#endif /* __TELEPRINTER_H__ */ diff --git a/src/emu/bus/x68k/x68k_neptunex.c b/src/emu/bus/x68k/x68k_neptunex.c new file mode 100644 index 00000000000..fb6fcf4bff7 --- /dev/null +++ b/src/emu/bus/x68k/x68k_neptunex.c @@ -0,0 +1,152 @@ +/* + * x68k_neptunex.c + */ + +#include "emu.h" +#include "machine/dp8390.h" +#include "x68k_neptunex.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type X68K_NEPTUNEX = &device_creator<x68k_neptune_device>; + +static const dp8390_interface neptune_dp8390_interface = { + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, x68k_neptune_device, x68k_neptune_irq_w), + DEVCB_NULL, + DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, x68k_neptune_device, x68k_neptune_mem_read), + DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, x68k_neptune_device, x68k_neptune_mem_write) +}; + + +// device machine config +static MACHINE_CONFIG_FRAGMENT( x68k_neptunex ) + MCFG_DP8390D_ADD("dp8390d", neptune_dp8390_interface) +MACHINE_CONFIG_END + +machine_config_constructor x68k_neptune_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( x68k_neptunex ); +} + +x68k_neptune_device::x68k_neptune_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, X68K_NEPTUNEX, "Neptune-X", tag, owner, clock, "x68k_neptunex", __FILE__), + device_x68k_expansion_card_interface(mconfig, *this), + m_dp8390(*this, "dp8390d") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void x68k_neptune_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + char mac[7]; + UINT32 num = rand(); + address_space& space = cpu->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner()); + memset(m_prom, 0x57, 16); + sprintf(mac+2, "\x1b%c%c%c", (num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff); + mac[0] = 0; mac[1] = 0; // avoid gcc warning + memcpy(m_prom, mac, 6); + m_dp8390->set_mac(mac); + space.install_readwrite_handler(0xece000,0xece3ff,read16_delegate(FUNC(x68k_neptune_device::x68k_neptune_port_r),this),write16_delegate(FUNC(x68k_neptune_device::x68k_neptune_port_w),this),0xffffffff); +} + +void x68k_neptune_device::device_reset() { + memcpy(m_prom, m_dp8390->get_mac(), 6); +} + +READ16_MEMBER(x68k_neptune_device::x68k_neptune_port_r) +{ + UINT16 data; + + if(offset >= 0x100+32 || offset < 0x100) + return 0xffff; + if(offset < 0x100+16) + { + m_dp8390->dp8390_cs(CLEAR_LINE); + return (m_dp8390->dp8390_r(space, offset, 0xff) << 8)| + m_dp8390->dp8390_r(space, offset+1, 0xff); + } + //if(mem_mask == 0x00ff) offset++; + switch(offset) + { + case 0x100+16: + m_dp8390->dp8390_cs(ASSERT_LINE); + data = m_dp8390->dp8390_r(space, offset, mem_mask); + data = ((data & 0x00ff) << 8) | ((data & 0xff00) >> 8); + return data; + case 0x100+31: + m_dp8390->dp8390_reset(CLEAR_LINE); + return 0; + default: + logerror("ne2000: invalid register read %02X\n", offset); + } + return 0; +} + +WRITE16_MEMBER(x68k_neptune_device::x68k_neptune_port_w) +{ + if(offset >= 0x100+32 || offset < 0x100) + return; + if(offset < 0x100+16) + { + m_dp8390->dp8390_cs(CLEAR_LINE); + if(mem_mask == 0x00ff) + { + data <<= 8; + offset++; + } + m_dp8390->dp8390_w(space, offset, data>>8, 0xff); + if(mem_mask == 0xffff) m_dp8390->dp8390_w(space, offset+1, data & 0xff, 0xff); + return; + } + //if(mem_mask == 0x00ff) offset++; + switch(offset) + { + case 0x100+16: + m_dp8390->dp8390_cs(ASSERT_LINE); + data = ((data & 0x00ff) << 8) | ((data & 0xff00) >> 8); + m_dp8390->dp8390_w(space, offset, data, mem_mask); + return; + case 0x100+31: + m_dp8390->dp8390_reset(ASSERT_LINE); + return; + default: + logerror("ne2000: invalid register write %02X\n", offset); + } + return; +} + +READ8_MEMBER(x68k_neptune_device::x68k_neptune_mem_read) +{ + if(offset < 32) return m_prom[offset>>1]; + if((offset < (16*1024)) || (offset >= (32*1024))) + { + logerror("ne2000: invalid memory read %04X\n", offset); + return 0xff; + } + return m_board_ram[offset - (16*1024)]; +} + +WRITE8_MEMBER(x68k_neptune_device::x68k_neptune_mem_write) +{ + if((offset < (16*1024)) || (offset >= (32*1024))) + { + logerror("ne2000: invalid memory write %04X\n", offset); + return; + } + m_board_ram[offset - (16*1024)] = data; +} + +WRITE_LINE_MEMBER(x68k_neptune_device::x68k_neptune_irq_w) +{ + machine().device("maincpu")->execute().set_input_line_vector(2, NEPTUNE_IRQ_VECTOR); + m_slot->irq2_w(state); + logerror("Neptune: IRQ2 set to %i\n",state); +} diff --git a/src/emu/bus/x68k/x68k_neptunex.h b/src/emu/bus/x68k/x68k_neptunex.h new file mode 100644 index 00000000000..277f902c74e --- /dev/null +++ b/src/emu/bus/x68k/x68k_neptunex.h @@ -0,0 +1,52 @@ +/* + * x68k_neptunex.h + * + * Neptune-X NE2000-based ethernet board for the X68000 + * + * Map: + * 0xECE000-0xECE3FF: "Y0" + * 0xECE400-0xECE7FF: "Y1" + */ + +#ifndef X68K_NEPTUNEX_H_ +#define X68K_NEPTUNEX_H_ + +#include "emu.h" +#include "machine/dp8390.h" +#include "x68kexp.h" + +#define NEPTUNE_IRQ_VECTOR 0xf9 + +class x68k_neptune_device : public device_t, + public device_x68k_expansion_card_interface +{ +public: + // construction/destruction + x68k_neptune_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + + void x68k_neptune_irq_w(int state); + DECLARE_READ8_MEMBER(x68k_neptune_mem_read); + DECLARE_WRITE8_MEMBER(x68k_neptune_mem_write); + DECLARE_READ16_MEMBER(x68k_neptune_port_r); + DECLARE_WRITE16_MEMBER(x68k_neptune_port_w); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + x68k_expansion_slot_device *m_slot; + + required_device<dp8390d_device> m_dp8390; + UINT8 m_board_ram[16*1024]; + UINT8 m_prom[16]; +}; + +// device type definition +extern const device_type X68K_NEPTUNEX; + +#endif /* X68K_NEPTUNEX_H_ */ diff --git a/src/emu/bus/x68k/x68k_scsiext.c b/src/emu/bus/x68k/x68k_scsiext.c new file mode 100644 index 00000000000..65c7dd01264 --- /dev/null +++ b/src/emu/bus/x68k/x68k_scsiext.c @@ -0,0 +1,102 @@ +/* + * x68k_scsiext.c + * + * Sharp CZ-6BS1 SCSI-1 controller + * + * Created on: 5/06/2012 + */ + +#include "emu.h" +#include "machine/scsibus.h" +#include "machine/scsihd.h" +#include "machine/mb89352.h" +#include "x68k_scsiext.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type X68K_SCSIEXT = &device_creator<x68k_scsiext_device>; + +static const mb89352_interface mb89352_intf = +{ + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER,x68k_scsiext_device,irq_w), + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER,x68k_scsiext_device,drq_w) +}; + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( x68k_cz6bs1 ) + ROM_REGION( 0x10000, "scsiexrom", 0 ) + ROM_LOAD16_WORD_SWAP( "scsiexrom.bin", 0x0000, 0x2000, CRC(7be488de) SHA1(49616c09a8986ffe6a12ad600febe512f7ba8ae4) ) +ROM_END + +const rom_entry *x68k_scsiext_device::device_rom_region() const +{ + return ROM_NAME( x68k_cz6bs1 ); +} + +// device machine config +static MACHINE_CONFIG_FRAGMENT( x68k_scsiext ) + MCFG_SCSIBUS_ADD("scsi") + MCFG_SCSIDEV_ADD("scsi:harddisk0", SCSIHD, SCSI_ID_0) + MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_1) + MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_2) + MCFG_SCSIDEV_ADD("scsi:harddisk3", SCSIHD, SCSI_ID_3) + MCFG_SCSIDEV_ADD("scsi:harddisk4", SCSIHD, SCSI_ID_4) + MCFG_SCSIDEV_ADD("scsi:harddisk5", SCSIHD, SCSI_ID_5) + MCFG_SCSIDEV_ADD("scsi:harddisk6", SCSIHD, SCSI_ID_6) + MCFG_MB89352A_ADD("scsi:mb89352",mb89352_intf) +MACHINE_CONFIG_END + +machine_config_constructor x68k_scsiext_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( x68k_scsiext ); +} + +x68k_scsiext_device::x68k_scsiext_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, X68K_SCSIEXT, "Sharp CZ-6BS1 SCSI-1", tag, owner, clock, "x68k_cz6bs1", __FILE__), + device_x68k_expansion_card_interface(mconfig, *this), + m_spc(*this, "scsi:mb89352") +{ +} + +void x68k_scsiext_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + UINT8* ROM; + astring temp; + address_space& space = cpu->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner()); + space.install_read_bank(0xea0020,0xea1fff,0,0,"scsi_ext"); + space.unmap_write(0xea0020,0xea1fff,0,0); + ROM = machine().root_device().memregion(subtag(temp,"scsiexrom"))->base(); + machine().root_device().membank("scsi_ext")->set_base(ROM); + space.install_readwrite_handler(0xea0000,0xea001f,0,0,read8_delegate(FUNC(x68k_scsiext_device::register_r),this),write8_delegate(FUNC(x68k_scsiext_device::register_w),this),0x00ff00ff); +} + +void x68k_scsiext_device::device_reset() +{ +} + +void x68k_scsiext_device::irq_w(int state) +{ + m_slot->irq2_w(state); // correct? Or perhaps selectable? +} + +void x68k_scsiext_device::drq_w(int state) +{ + // TODO +} + +READ8_MEMBER(x68k_scsiext_device::register_r) +{ + return m_spc->mb89352_r(space,offset); +} + +WRITE8_MEMBER(x68k_scsiext_device::register_w) +{ + m_spc->mb89352_w(space,offset,data); +} diff --git a/src/emu/bus/x68k/x68k_scsiext.h b/src/emu/bus/x68k/x68k_scsiext.h new file mode 100644 index 00000000000..74550ff8eb1 --- /dev/null +++ b/src/emu/bus/x68k/x68k_scsiext.h @@ -0,0 +1,44 @@ +/* + * x68k_scsiext.h + * + * Created on: 5/06/2012 + */ + +#ifndef X68K_SCSIEXT_H_ +#define X68K_SCSIEXT_H_ + +#include "emu.h" +#include "machine/mb89352.h" +#include "x68kexp.h" + +class x68k_scsiext_device : public device_t, + public device_x68k_expansion_card_interface +{ +public: + // construction/destruction + x68k_scsiext_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + void irq_w(int state); + void drq_w(int state); + DECLARE_READ8_MEMBER(register_r); + DECLARE_WRITE8_MEMBER(register_w); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); +private: + x68k_expansion_slot_device *m_slot; + + required_device<mb89352_device> m_spc; +}; + +// device type definition +extern const device_type X68K_SCSIEXT; + + +#endif /* X68K_SCSIEXT_H_ */ diff --git a/src/emu/bus/x68k/x68kexp.c b/src/emu/bus/x68k/x68kexp.c new file mode 100644 index 00000000000..f84319eda81 --- /dev/null +++ b/src/emu/bus/x68k/x68kexp.c @@ -0,0 +1,98 @@ +/* + * x68kexp.c + */ + +#include "emu.h" +#include "emuopts.h" +#include "x68kexp.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type X68K_EXPANSION_SLOT = &device_creator<x68k_expansion_slot_device>; + + +//************************************************************************** +// DEVICE CPC_EXPANSION CARD INTERFACE +//************************************************************************** + + +device_x68k_expansion_card_interface::device_x68k_expansion_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ +} + + +device_x68k_expansion_card_interface::~device_x68k_expansion_card_interface() +{ +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +x68k_expansion_slot_device::x68k_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, X68K_EXPANSION_SLOT, "Sharp X680x0 expansion slot", tag, owner, clock, "x68k_expansion_slot", __FILE__), + device_slot_interface(mconfig, *this) +{ +} + +x68k_expansion_slot_device::~x68k_expansion_slot_device() +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void x68k_expansion_slot_device::device_config_complete() +{ + // inherit a copy of the static data + const x68k_expansion_slot_interface *intf = reinterpret_cast<const x68k_expansion_slot_interface *>(static_config()); + if (intf != NULL) + { + *static_cast<x68k_expansion_slot_interface *>(this) = *intf; + } + + // or initialize to defaults if none provided + else + { + memset(&m_out_irq2_cb, 0, sizeof(m_out_irq2_cb)); + memset(&m_out_irq4_cb, 0, sizeof(m_out_irq4_cb)); + memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb)); + memset(&m_out_reset_cb, 0, sizeof(m_out_reset_cb)); + } +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void x68k_expansion_slot_device::device_start() +{ + m_card = dynamic_cast<device_x68k_expansion_card_interface *>(get_card_device()); + + // resolve callbacks + m_out_irq2_func.resolve(m_out_irq2_cb, *this); + m_out_irq4_func.resolve(m_out_irq4_cb, *this); + m_out_nmi_func.resolve(m_out_nmi_cb, *this); + m_out_reset_func.resolve(m_out_reset_cb, *this); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void x68k_expansion_slot_device::device_reset() +{ +} + + +WRITE_LINE_MEMBER( x68k_expansion_slot_device::irq2_w ) { m_out_irq2_func(state); } +WRITE_LINE_MEMBER( x68k_expansion_slot_device::irq4_w ) { m_out_irq4_func(state); } +WRITE_LINE_MEMBER( x68k_expansion_slot_device::nmi_w ) { m_out_nmi_func(state); } +WRITE_LINE_MEMBER( x68k_expansion_slot_device::reset_w ) { m_out_reset_func(state); } diff --git a/src/emu/bus/x68k/x68kexp.h b/src/emu/bus/x68k/x68kexp.h new file mode 100644 index 00000000000..05c384aae6c --- /dev/null +++ b/src/emu/bus/x68k/x68kexp.h @@ -0,0 +1,149 @@ +/* + * x68kexp.h + * + * Expansion slots for the X680x0 series + * + * Pinout: (from http://www.amy.hi-ho.ne.jp/shimada/neptune/x68k.html) + +-----+ + GND B1 |[] []| A1 GND + 10MHz B2 |[] []| A2 20MHz + #10MHz B3 |[] []| A3 GND + E B4 |[] []| A4 DB0 + AB1 B5 |[] []| A5 DB1 + AB2 B6 |[] []| A6 DB2 + AB3 B7 |[] []| A7 DB3 + AB4 B8 |[] []| A8 DB4 + AB5 B9 |[] []| A9 DB5 + AB6 B10 |[] []| A10 DB6 + GND B11 |[] []| A11 GND + AB7 B12 |[] []| A12 DB7 + AB8 B13 |[] []| A13 DB8 + AB9 B14 |[] []| A14 DB9 + AB10 B15 |[] []| A15 DB10 + AB11 B16 |[] []| A16 DB11 + AB12 B17 |[] []| A17 DB12 + AB13 B18 |[] []| A18 DB13 + AB14 B19 |[] []| A19 DB14 + AB15 B20 |[] []| A20 DB15 + GND B21 |[] []| A21 GND + AB16 B22 |[] []| A22 +12V + AB17 B23 |[] []| A23 +12V + AB18 B24 |[] []| A24 FC0 + AB19 B25 |[] []| A25 FC1 + AB20 B26 |[] []| A26 FC2 + AB21 B27 |[] []| A27 #AS + AB22 B28 |[] []| A28 #LDS + AB23 B29 |[] []| A29 #UDS + IDDIR B30 |[] []| A30 R/#W + N.C. B31 |[] []| A31 N.C. + HSYNC B32 |[] []| A32 -12V + VSYNC B33 |[] []| A33 -12V + #DONE B34 |[] []| A34 #VMA + #DTC B35 |[] []| A35 #EXVPA + #EXREQ B36 |[] []| A36 #DTACK + #EXACK B37 |[] []| A37 #EXRESET + #EXPCL B38 |[] []| A38 #HALT + #EXOWN B39 |[] []| A39 #EXBERR + #EXNMI B40 |[] []| A40 #EXPWON + GND B41 |[] []| A41 GND + #IRQ2 B42 |[] []| A42 Vcc2 + #IRQ4 B43 |[] []| A43 Vcc2 + #IACK2 B44 |[] []| A44 SELEN + #IACK4 B45 |[] []| A45 CASRDEN + #BR B46 |[] []| A46 CASWRL + #BG B47 |[] []| A47 CASWRU + #BGACK B48 |[] []| A48 INH2 + Vcc1 B49 |[] []| A49 Vcc1 + Vcc1 B50 |[] []| A50 Vcc1 + +-----+ + * + */ + +#ifndef X68KEXP_H_ +#define X68KEXP_H_ + +#include "emu.h" + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +#define X68K_EXP_SLOT_TAG "x68kexp" + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define X68K_EXPANSION_INTERFACE(_name) \ + const x68k_expansion_slot_interface (_name) = + + +#define MCFG_X68K_EXPANSION_SLOT_ADD(_tag, _config, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, X68K_EXPANSION_SLOT, 0) \ + MCFG_DEVICE_CONFIG(_config) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// expansion slot interface + +struct x68k_expansion_slot_interface +{ + devcb_write_line m_out_irq2_cb; + devcb_write_line m_out_irq4_cb; + devcb_write_line m_out_nmi_cb; + devcb_write_line m_out_reset_cb; +}; + +// ======================> device_x68k_expansion_card_interface + +// class representing interface-specific live x68k_expansion card +class device_x68k_expansion_card_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_x68k_expansion_card_interface(const machine_config &mconfig, device_t &device); + virtual ~device_x68k_expansion_card_interface(); + + // reset + virtual void x68k_reset_w() { }; +}; + + +// ======================> x68k_expansion_slot_device + +class x68k_expansion_slot_device : public device_t, + public x68k_expansion_slot_interface, + public device_slot_interface +{ +public: + // construction/destruction + x68k_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~x68k_expansion_slot_device(); + + DECLARE_WRITE_LINE_MEMBER( irq2_w ); + DECLARE_WRITE_LINE_MEMBER( irq4_w ); + DECLARE_WRITE_LINE_MEMBER( nmi_w ); + DECLARE_WRITE_LINE_MEMBER( reset_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_config_complete(); + + devcb_resolved_write_line m_out_irq2_func; + devcb_resolved_write_line m_out_irq4_func; + devcb_resolved_write_line m_out_nmi_func; + devcb_resolved_write_line m_out_reset_func; + + device_x68k_expansion_card_interface *m_card; +}; + + +// device type definition +extern const device_type X68K_EXPANSION_SLOT; + +#endif /* X68KEXP_H_ */ diff --git a/src/emu/machine/ds1315.c b/src/emu/machine/ds1315.c new file mode 100644 index 00000000000..c64ee315962 --- /dev/null +++ b/src/emu/machine/ds1315.c @@ -0,0 +1,218 @@ +/********************************************************************* + + ds1315.c + + Dallas Semiconductor's Phantom Time Chip DS1315. + + by tim lindner, November 2001. + +*********************************************************************/ + +#include "ds1315.h" +#include "coreutil.h" + + +const device_type DS1315 = &device_creator<ds1315_device>; + +ds1315_device::ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, DS1315, "Dallas Semiconductor DS1315", tag, owner, clock, "ds1315", __FILE__) +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void ds1315_device::device_config_complete() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ds1315_device::device_start() +{ + save_item(NAME(m_count)); + save_item(NAME(m_mode)); + save_item(NAME(m_raw_data)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void ds1315_device::device_reset() +{ + memset(m_raw_data, 0, sizeof(m_raw_data)); + m_count = 0; + m_mode = DS_SEEK_MATCHING; +} + + +/*************************************************************************** + LOCAL VARIABLES +***************************************************************************/ + +static const UINT8 ds1315_pattern[] = +{ + 1, 0, 1, 0, 0, 0, 1, 1, + 0, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 0, 1, + 0, 0, 1, 1, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 0, 1, 1, + 0, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 0, 1, + 0, 0, 1, 1, 1, 0, 1, 0 +}; + + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + +/*------------------------------------------------- + read_0 + -------------------------------------------------*/ + +READ8_MEMBER( ds1315_device::read_0 ) +{ + if (ds1315_pattern[m_count++] == 0) + { + if (m_count == 64) + { + /* entire pattern matched */ + m_count = 0; + m_mode = DS_CALENDAR_IO; + fill_raw_data(); + } + + return 0; + } + + m_count = 0; + m_mode = DS_SEEK_MATCHING; + return 0; +} + + +/*------------------------------------------------- + read_1 +-------------------------------------------------*/ + +READ8_MEMBER( ds1315_device::read_1 ) +{ + if (ds1315_pattern[m_count++] == 1) + { + m_count %= 64; + return 0; + } + + m_count = 0; + m_mode = DS_SEEK_MATCHING; + return 0; +} + + +/*------------------------------------------------- + read_data +-------------------------------------------------*/ + +READ8_MEMBER( ds1315_device::read_data ) +{ + UINT8 result; + + if (m_mode == DS_CALENDAR_IO) + { + result = m_raw_data[m_count++]; + + if (m_count == 64) + { + m_mode = DS_SEEK_MATCHING; + m_count = 0; + } + + return result; + } + + m_count = 0; + return 0; +} + + +/*------------------------------------------------- + write_data +-------------------------------------------------*/ + +WRITE8_MEMBER( ds1315_device::write_data ) +{ + if (m_mode == DS_CALENDAR_IO) + { + m_raw_data[m_count++] = data & 0x01; + + if (m_count == 64) + { + m_mode = DS_SEEK_MATCHING; + m_count = 0; + input_raw_data(); + } + return; + } + + m_count = 0; +} + + +/*------------------------------------------------- + fill_raw_data +-------------------------------------------------*/ + +void ds1315_device::fill_raw_data() +{ + /* This routine will (hopefully) call a standard 'C' library routine to get the current + date and time and then fill in the raw data struct. + */ + + system_time systime; + int raw[8], i, j; + + /* get the current date/time from the core */ + machine().current_datetime(systime); + + raw[0] = 0; /* tenths and hundreths of seconds are always zero */ + raw[1] = dec_2_bcd(systime.local_time.second); + raw[2] = dec_2_bcd(systime.local_time.minute); + raw[3] = dec_2_bcd(systime.local_time.hour); + + raw[4] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7); + raw[5] = dec_2_bcd(systime.local_time.mday); + raw[6] = dec_2_bcd(systime.local_time.month + 1); + raw[7] = dec_2_bcd(systime.local_time.year - 1900); /* Epoch is 1900 */ + + /* Ok now we have the raw bcd bytes. Now we need to push them into our bit array */ + + for (i = 0; i < 64; i++) + { + j = i / 8; + m_raw_data[i] = (raw[j] & 0x0001); + raw[j] = raw[j] >> 1; + } +} + + +/*------------------------------------------------- + ds1315_input_raw_data +-------------------------------------------------*/ + +void ds1315_device::input_raw_data() +{ + /* This routine is called when new date and time has been written to the + clock chip. Currently we ignore setting the date and time in the clock + chip. + + We always return the host's time when asked. + */ +} diff --git a/src/emu/machine/ds1315.h b/src/emu/machine/ds1315.h new file mode 100644 index 00000000000..d4ab0cfb967 --- /dev/null +++ b/src/emu/machine/ds1315.h @@ -0,0 +1,67 @@ +/********************************************************************* + + ds1315.h + + Dallas Semiconductor's Phantom Time Chip DS1315. + + by tim lindner, November 2001. + +*********************************************************************/ + +#ifndef __DS1315_H__ +#define __DS1315_H__ + +#include "emu.h" + + +/*************************************************************************** + MACROS +***************************************************************************/ + +enum ds1315_mode_t +{ + DS_SEEK_MATCHING, + DS_CALENDAR_IO +}; + +ALLOW_SAVE_TYPE(ds1315_mode_t); + +class ds1315_device : public device_t +{ +public: + ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + ~ds1315_device() {} + + DECLARE_READ8_MEMBER(read_0); + DECLARE_READ8_MEMBER(read_1); + DECLARE_READ8_MEMBER(read_data); + DECLARE_WRITE8_MEMBER(write_data); + +protected: + // device-level overrides + virtual void device_config_complete(); + virtual void device_start(); + virtual void device_reset(); + +private: + // internal state + + void fill_raw_data(); + void input_raw_data(); + + int m_count; + ds1315_mode_t m_mode; + UINT8 m_raw_data[8*8]; +}; + +extern const device_type DS1315; + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MCFG_DS1315_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, DS1315, 0) + + +#endif /* __DS1315_H__ */ diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak index 7d0f729b890..afb6096b58f 100644 --- a/src/emu/machine/machine.mak +++ b/src/emu/machine/machine.mak @@ -401,6 +401,15 @@ endif #------------------------------------------------- # +#@src/emu/machine/ds1315.h,MACHINES += DS1315 +#------------------------------------------------- + +ifneq ($(filter DS1315,$(MACHINES)),) +MACHINEOBJS += $(MACHINEOBJ)/ds1315.o +endif + +#------------------------------------------------- +# #@src/emu/machine/ds2401.h,MACHINES += DS2401 #------------------------------------------------- |