diff options
Diffstat (limited to 'src/mame/drivers/sdk85.cpp')
-rw-r--r-- | src/mame/drivers/sdk85.cpp | 179 |
1 files changed, 126 insertions, 53 deletions
diff --git a/src/mame/drivers/sdk85.cpp b/src/mame/drivers/sdk85.cpp index 2eeff6a9a4e..78bbad3e976 100644 --- a/src/mame/drivers/sdk85.cpp +++ b/src/mame/drivers/sdk85.cpp @@ -20,6 +20,12 @@ Download the User Manual to get the operating procedures. An example is Press SUBST key, enter an address, press NEXT key, enter data, then press NEXT to increment the address. +Warning: the default cold start routine fails to initialize SP properly, which will cause the GO +command to fail. SP can be set to point to the end of onboard RAM by the following sequence of +button presses: EXAM REG, 4, 2, 0, EXEC, EXAM REG, 5, F, F, EXEC. In TTY mode, use the "XS" +command to change SP. Another option is to push the RESET button again, which will leave SP +wherever it was in the monitor's scratchpad area. + ToDo: - Artwork @@ -38,10 +44,13 @@ Press 0 to restart. *************************************************************************************************************************************/ #include "emu.h" +#include "bus/rs232/rs232.h" +#include "bus/sdk85/memexp.h" #include "cpu/i8085/i8085.h" #include "machine/i8155.h" #include "machine/i8355.h" #include "machine/i8279.h" +#include "softlist.h" #include "sdk85.lh" @@ -51,23 +60,42 @@ public: sdk85_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_kdc(*this, "kdc") + , m_romio(*this, "romio") + , m_expromio(*this, "expromio") + , m_ramio(*this, "ramio") + , m_expramio(*this, "expramio") + , m_tty(*this, "tty") , m_keyboard(*this, "X%u", 0) , m_digits(*this, "digit%u", 0U) { } void sdk85(machine_config &config); + DECLARE_WRITE_LINE_MEMBER(reset_w); + DECLARE_WRITE_LINE_MEMBER(vect_intr_w); + private: - DECLARE_WRITE8_MEMBER(scanlines_w); - DECLARE_WRITE8_MEMBER(digit_w); - DECLARE_READ8_MEMBER(kbd_r); + DECLARE_READ_LINE_MEMBER(sid_r); + + void scanlines_w(u8 data); + void digit_w(u8 data); + u8 kbd_r(); + void sdk85_io(address_map &map); void sdk85_mem(address_map &map); u8 m_digit; virtual void machine_reset() override; virtual void machine_start() override { m_digits.resolve(); } - required_device<cpu_device> m_maincpu; + + required_device<i8085a_cpu_device> m_maincpu; + required_device<i8279_device> m_kdc; + required_device<i8355_device> m_romio; + required_device<sdk85_romexp_device> m_expromio; + required_device<i8155_device> m_ramio; + required_device<i8155_device> m_expramio; + required_device<rs232_port_device> m_tty; required_ioport_array<3> m_keyboard; output_finder<6> m_digits; }; @@ -78,103 +106,150 @@ void sdk85_state::machine_reset() m_maincpu->reset(); } +WRITE_LINE_MEMBER(sdk85_state::reset_w) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + if (!state) + { + m_kdc->reset(); + m_romio->reset(); + m_expromio->reset(); + m_ramio->reset(); + m_expramio->reset(); + } +} + +WRITE_LINE_MEMBER(sdk85_state::vect_intr_w) +{ + m_maincpu->set_input_line(I8085_RST75_LINE, state ? ASSERT_LINE : CLEAR_LINE); +} + +READ_LINE_MEMBER(sdk85_state::sid_r) +{ + // Actual HW has S25 switch to ground SID when using keyboard input instead of TTY RX + if (m_tty->get_card_device() == nullptr) + return 0; + else + return m_tty->rxd_r(); +} + void sdk85_state::sdk85_mem(address_map &map) { map.unmap_value_high(); - map(0x0000, 0x07ff).r("romio", FUNC(i8355_device::memory_r)); - map(0x0800, 0x0fff).r("expromio", FUNC(i8355_device::memory_r)); - map(0x1800, 0x1800).mirror(0x06ff).rw("kdc", FUNC(i8279_device::data_r), FUNC(i8279_device::data_w)); - map(0x1900, 0x1900).mirror(0x06ff).rw("kdc", FUNC(i8279_device::status_r), FUNC(i8279_device::cmd_w)); - map(0x2000, 0x20ff).mirror(0x0700).rw("ramio", FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); - map(0x2800, 0x28ff).mirror(0x0700).rw("expramio", FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); + map(0x0000, 0x07ff).r(m_romio, FUNC(i8355_device::memory_r)); + map(0x0800, 0x0fff).rw(m_expromio, FUNC(sdk85_romexp_device::memory_r), FUNC(sdk85_romexp_device::memory_w)); + map(0x1800, 0x1800).mirror(0x06ff).rw(m_kdc, FUNC(i8279_device::data_r), FUNC(i8279_device::data_w)); + map(0x1900, 0x1900).mirror(0x06ff).rw(m_kdc, FUNC(i8279_device::status_r), FUNC(i8279_device::cmd_w)); + map(0x2000, 0x20ff).mirror(0x0700).rw(m_ramio, FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); + map(0x2800, 0x28ff).mirror(0x0700).rw(m_expramio, FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); } void sdk85_state::sdk85_io(address_map &map) { map.unmap_value_high(); - map(0x00, 0x03).mirror(0x04).rw("romio", FUNC(i8355_device::io_r), FUNC(i8355_device::io_w)); - map(0x08, 0x0b).mirror(0x04).rw("expromio", FUNC(i8355_device::io_r), FUNC(i8355_device::io_w)); - map(0x20, 0x27).rw("ramio", FUNC(i8155_device::io_r), FUNC(i8155_device::io_w)); - map(0x28, 0x2f).rw("expramio", FUNC(i8155_device::io_r), FUNC(i8155_device::io_w)); + map(0x00, 0x03).mirror(0x04).rw(m_romio, FUNC(i8355_device::io_r), FUNC(i8355_device::io_w)); + map(0x08, 0x0b).mirror(0x04).rw(m_expromio, FUNC(sdk85_romexp_device::io_r), FUNC(sdk85_romexp_device::io_w)); + map(0x20, 0x27).rw(m_ramio, FUNC(i8155_device::io_r), FUNC(i8155_device::io_w)); + map(0x28, 0x2f).rw(m_expramio, FUNC(i8155_device::io_r), FUNC(i8155_device::io_w)); } /* Input ports */ static INPUT_PORTS_START( sdk85 ) PORT_START("X0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("3 I") PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("4 SPH") PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("5 SPL") PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("6 PCH") PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("7 PCL") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_START("X1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("8 H") PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("9 L") PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_START("X2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXEC") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NEXT") PORT_CODE(KEYCODE_UP) PORT_CHAR('^') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_R) PORT_CHAR('R') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SUBST") PORT_CODE(KEYCODE_T) PORT_CHAR('T') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXAM") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SINGLE") PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("EXEC .") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("NEXT ,") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("GO") PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("SUBST MEM") PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("EXAM REG") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("SINGLE STEP") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_BIT(0xC0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("INTR") // buttons hardwired to 8085 inputs + PORT_BIT(1, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("VECT INTR") PORT_WRITE_LINE_MEMBER(sdk85_state, vect_intr_w) PORT_CODE(KEYCODE_F2) + PORT_BIT(2, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("RESET") PORT_WRITE_LINE_MEMBER(sdk85_state, reset_w) PORT_CODE(KEYCODE_F1) INPUT_PORTS_END -WRITE8_MEMBER( sdk85_state::scanlines_w ) +void sdk85_state::scanlines_w(u8 data) { m_digit = data; } -WRITE8_MEMBER( sdk85_state::digit_w ) +void sdk85_state::digit_w(u8 data) { if (m_digit < 6) m_digits[m_digit] = bitswap<8>(~data, 3, 2, 1, 0, 7, 6, 5, 4); } -READ8_MEMBER( sdk85_state::kbd_r ) +u8 sdk85_state::kbd_r() { u8 data = (m_digit < 3) ? m_keyboard[m_digit]->read() : 0xff; return data; } +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_110 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_110 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_2 ) +DEVICE_INPUT_DEFAULTS_END + void sdk85_state::sdk85(machine_config &config) { /* basic machine hardware */ I8085A(config, m_maincpu, 6.144_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &sdk85_state::sdk85_mem); m_maincpu->set_addrmap(AS_IO, &sdk85_state::sdk85_io); + m_maincpu->in_sid_func().set(FUNC(sdk85_state::sid_r)); + m_maincpu->out_sod_func().set(m_tty, FUNC(rs232_port_device::write_txd)).invert(); - I8355(config, "romio", 6.144_MHz_XTAL / 2); // Monitor ROM (A14) + I8355(config, m_romio, 6.144_MHz_XTAL / 2); // Monitor ROM (A14) - I8355(config, "expromio", 6.144_MHz_XTAL / 2); // Expansion ROM (A15) + SDK85_ROMEXP(config, m_expromio, 6.144_MHz_XTAL / 2, sdk85_romexp_device::rom_options, nullptr); // Expansion ROM (A15) - i8155_device &i8155(I8155(config, "ramio", 6.144_MHz_XTAL / 2)); // Basic RAM (A16) - i8155.out_to_callback().set_inputline(m_maincpu, I8085_TRAP_LINE); + I8155(config, m_ramio, 6.144_MHz_XTAL / 2); // Basic RAM (A16) + m_ramio->out_to_callback().set_inputline(m_maincpu, I8085_TRAP_LINE); - I8155(config, "expramio", 6.144_MHz_XTAL / 2); // Expansion RAM (A17) + I8155(config, m_expramio, 6.144_MHz_XTAL / 2); // Expansion RAM (A17) /* video hardware */ config.set_default_layout(layout_sdk85); /* Devices */ - i8279_device &kdc(I8279(config, "kdc", 6.144_MHz_XTAL / 2)); // Keyboard/Display Controller (A13) - kdc.out_irq_callback().set_inputline("maincpu", I8085_RST55_LINE); // irq - kdc.out_sl_callback().set(FUNC(sdk85_state::scanlines_w)); // scan SL lines - kdc.out_disp_callback().set(FUNC(sdk85_state::digit_w)); // display A&B - kdc.in_rl_callback().set(FUNC(sdk85_state::kbd_r)); // kbd RL lines - kdc.in_shift_callback().set_constant(1); // Shift key - kdc.in_ctrl_callback().set_constant(1); + I8279(config, m_kdc, 6.144_MHz_XTAL / 2); // Keyboard/Display Controller (A13) + m_kdc->out_irq_callback().set_inputline(m_maincpu, I8085_RST55_LINE); // irq + m_kdc->out_sl_callback().set(FUNC(sdk85_state::scanlines_w)); // scan SL lines + m_kdc->out_disp_callback().set(FUNC(sdk85_state::digit_w)); // display A&B + m_kdc->in_rl_callback().set(FUNC(sdk85_state::kbd_r)); // kbd RL lines + m_kdc->in_shift_callback().set_constant(1); // Shift key + m_kdc->in_ctrl_callback().set_constant(1); + + RS232_PORT(config, m_tty, default_rs232_devices, nullptr); // actually a 20 mA current loop + m_tty->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); + + SOFTWARE_LIST(config, "rom_list").set_original("sdk85"); } /* ROM definition */ @@ -184,8 +259,6 @@ ROM_START( sdk85 ) ROMX_LOAD( "sdk85.a14", 0x0000, 0x0800, CRC(9d5a983f) SHA1(54e218560fbec009ac3de5cfb64b920241ef2eeb), ROM_BIOS(0) ) ROM_SYSTEM_BIOS(1, "mastermind", "Mastermind") ROMX_LOAD( "mastermind.a14", 0x0000, 0x0800, CRC(36b694ae) SHA1(4d8a5ae5d10e8f72a6e349c7eeaf1aa00c4e45e1), ROM_BIOS(1) ) - - ROM_REGION( 0x800, "expromio", ROMREGION_ERASEFF ) ROM_END /* Driver */ |