diff options
author | 2019-07-20 12:31:21 +1000 | |
---|---|---|
committer | 2019-07-20 12:31:21 +1000 | |
commit | d2926fa02cef5bf728eac74c9e5586aced02a80b (patch) | |
tree | 820d62305954ff68c7c8bb87c8a08d1b7ce4b2c3 /src/mame/drivers/sb8085.cpp | |
parent | 24c462dbdb4ed2992af2f8767bf9c56979e7f1be (diff) | |
parent | 68139508715a0375e657add4197582271ef446ec (diff) |
Merge remote-tracking branch 'upstream/master'
# Conflicts:
# src/emu/digfx.h
Diffstat (limited to 'src/mame/drivers/sb8085.cpp')
-rw-r--r-- | src/mame/drivers/sb8085.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/mame/drivers/sb8085.cpp b/src/mame/drivers/sb8085.cpp new file mode 100644 index 00000000000..240f1ba3404 --- /dev/null +++ b/src/mame/drivers/sb8085.cpp @@ -0,0 +1,312 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Preliminary driver for Space Byte 8085 CPU. + + This is an early Intel 8085-based single-board computer whose onboard + I/O consists of RS232 ports for a CRT and serial printer and a parallel + interface intended for use with ICOM's FD 3700 or Frugal Floppy disk + controller. The resident monitor program also supports the Tarbell + cassette tape interface and the PolyMorphic Systems Video Terminal + Interface. + + The bus connector is only somewhat S-100 compatible. Anticipating the + draft IEEE standard, no clock signal is placed on pin 25 or 49 (though + documentation recommends jumpering pin 49 to the 3.072 MHz clock on pin + 24 for the VTI). The conventional INT and VI0-7 pins are disregarded in + favor of collecting the four 8085-specific interrupts on pins 12-15 in + ascending order of priority. SDSB/CDSB/ASDB/DODSB are also disregarded, + and there is an alternate PHOLD input on pin 16. + + Space Byte also advertised a 16K static RAM board and a 2708/2716 + EPROM programmer for use in this system. + +***************************************************************************/ + +#include "emu.h" + +#include "cpu/i8085/i8085.h" +#include "bus/rs232/rs232.h" +#include "bus/s100/s100.h" +#include "bus/s100/polyvti.h" +#include "bus/s100/seals8k.h" +#include "machine/i8155.h" +#include "machine/i8251.h" + +class sb8085_state : public driver_device +{ +public: + sb8085_state(const machine_config &config, device_type type, const char *tag) + : driver_device(config, type, tag) + , m_maincpu(*this, "maincpu") + , m_i8155(*this, "i8155") + , m_usart(*this, "usart") + , m_crt(*this, "crt") + , m_printer(*this, "printer") + , m_s100(*this, "s100") + , m_program(*this, "program") + , m_config_select(*this, "SELECT") + , m_portd(*this, "PORTD") + { + } + + static constexpr feature_type unemulated_features() { return feature::DISK | feature::TAPE; } + + void sb8085(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + bool board_selected(offs_t offset); + u8 mem_r(offs_t offset); + void mem_w(offs_t offset, u8 data); + u8 in_r(offs_t offset); + void out_w(offs_t offset, u8 data); + DECLARE_WRITE_LINE_MEMBER(phantom_disable_w); + + DECLARE_WRITE_LINE_MEMBER(printer_select_w); + DECLARE_WRITE_LINE_MEMBER(usart_txd_w); + DECLARE_WRITE_LINE_MEMBER(crt_rts_w); + DECLARE_WRITE_LINE_MEMBER(printer_rts_w); + + void mem_map(address_map &map); + void io_map(address_map &map); + + required_device<i8085a_cpu_device> m_maincpu; + required_device<i8155_device> m_i8155; + required_device<i8251_device> m_usart; + required_device<rs232_port_device> m_crt; + required_device<rs232_port_device> m_printer; + required_device<s100_bus_device> m_s100; + required_region_ptr<u8> m_program; + required_ioport m_config_select; + required_ioport m_portd; + + bool m_phantom; + bool m_printer_select; + bool m_usart_txd; + bool m_crt_rts; + bool m_printer_rts; +}; + +void sb8085_state::machine_start() +{ + m_printer_select = false; + m_usart_txd = true; + m_crt_rts = true; + m_printer_rts = true; + + // Pins 6, 8, 5 (printer) are tied to +12 + m_crt->write_dtr(0); + m_printer->write_rts(0); + m_printer->write_dtr(0); + + save_item(NAME(m_phantom)); + save_item(NAME(m_printer_select)); + save_item(NAME(m_usart_txd)); + save_item(NAME(m_crt_rts)); + save_item(NAME(m_printer_rts)); +} + +void sb8085_state::machine_reset() +{ + m_phantom = false; +} + +bool sb8085_state::board_selected(offs_t offset) +{ + if (!m_phantom) + return true; + + ioport_value config = m_config_select->read(); + return !BIT(config, 1) || (offset & 0xe000) == (BIT(config, 0) ? 0xe000 : 0xc000); +} + +u8 sb8085_state::mem_r(offs_t offset) +{ + if (board_selected(offset)) + { + if ((offset & 0x1c00) < 0x0c00) + return m_program[offset & 0xfff]; + else if ((offset & 0x1c00) >= 0x1800) + return m_i8155->memory_r(offset & 0xff); + else + return 0xff; + } + else + return m_s100->smemr_r(offset); +} + +void sb8085_state::mem_w(offs_t offset, u8 data) +{ + if (board_selected(offset)) + { + if ((offset & 0x1c00) >= 0x1800) + m_i8155->memory_w(offset & 0xff, data); + } + else + m_s100->mwrt_w(offset, data); +} + +u8 sb8085_state::in_r(offs_t offset) +{ + offset |= offset << 8; + if (board_selected(offset)) + { + if ((offset & 0x1c00) == 0x0000) + return m_usart->read(BIT(offset, 8)); + else if ((offset & 0x1c00) == 0x0c00) + return m_portd->read() ^ 0xff; + else if ((offset & 0x1c00) >= 0x1800) + return m_i8155->io_r(offset & 7); + else + return 0xff; + } + else + return m_s100->sinp_r(offset); +} + +void sb8085_state::out_w(offs_t offset, u8 data) +{ + offset |= offset << 8; + if (board_selected(offset)) + { + if ((offset & 0x1c00) == 0x0000) + m_usart->write(BIT(offset, 8), data); + else if ((offset & 0x1c00) >= 0x1800) + m_i8155->io_w(offset & 7, data); + } + else + m_s100->sout_w(offset, data); +} + +WRITE_LINE_MEMBER(sb8085_state::phantom_disable_w) +{ + if (!state) + m_phantom = true; +} + +WRITE_LINE_MEMBER(sb8085_state::printer_select_w) +{ + if (state && m_printer_select) + { + m_printer_select = false; + m_crt->write_txd(m_usart_txd); + m_printer->write_txd(1); + m_usart->write_cts(m_crt_rts); + } + else if (!state && !m_printer_select) + { + m_printer_select = true; + m_crt->write_txd(1); + m_printer->write_txd(m_usart_txd); + m_usart->write_cts(m_printer_rts); + } +} + +WRITE_LINE_MEMBER(sb8085_state::usart_txd_w) +{ + m_usart_txd = state; + if (m_printer_select) + m_printer->write_txd(state); + else + m_crt->write_txd(state); +} + +WRITE_LINE_MEMBER(sb8085_state::crt_rts_w) +{ + m_crt_rts = state; + if (!m_printer_select) + m_usart->write_cts(state); +} + +WRITE_LINE_MEMBER(sb8085_state::printer_rts_w) +{ + m_printer_rts = state; + if (m_printer_select) + m_usart->write_cts(state); +} + +void sb8085_state::mem_map(address_map &map) +{ + map(0x0000, 0xffff).rw(FUNC(sb8085_state::mem_r), FUNC(sb8085_state::mem_w)); +} + +void sb8085_state::io_map(address_map &map) +{ + map(0x00, 0xff).rw(FUNC(sb8085_state::in_r), FUNC(sb8085_state::out_w)); +} + +INPUT_PORTS_START(sb8085) + PORT_START("SELECT") + PORT_CONFNAME(3, 2, "Board select") + PORT_CONFSETTING(0, "Single board") + PORT_CONFSETTING(2, "C000-DFFFH") + PORT_CONFSETTING(3, "E000-FFFFH") + + PORT_START("PORTD") + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) // from disk connector +INPUT_PORTS_END + + +static void sb8085_s100_devices(device_slot_interface &device) +{ + device.option_add("vti", S100_POLY_VTI); + device.option_add("8ksc", S100_8K_SC); + device.option_add("8kscbb", S100_8K_SC_BB); +} + +static DEVICE_INPUT_DEFAULTS_START(terminal) + DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_9600) + DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_9600) + 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 sb8085_state::sb8085(machine_config &config) +{ + I8085A(config, m_maincpu, 6.144_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &sb8085_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &sb8085_state::io_map); + m_maincpu->in_sid_func().set(m_crt, FUNC(rs232_port_device::rxd_r)); + + I8155(config, m_i8155, 6.144_MHz_XTAL / 2); + m_i8155->out_pc_callback().set(FUNC(sb8085_state::phantom_disable_w)).bit(5); + m_i8155->out_to_callback().set(m_usart, FUNC(i8251_device::write_txc)); + m_i8155->out_to_callback().append(m_usart, FUNC(i8251_device::write_rxc)); + + I8251(config, m_usart, 6.144_MHz_XTAL / 2); + m_usart->rts_handler().set(m_crt, FUNC(rs232_port_device::write_rts)); + m_usart->txd_handler().set(FUNC(sb8085_state::usart_txd_w)); + m_usart->dtr_handler().set(FUNC(sb8085_state::printer_select_w)); + + RS232_PORT(config, m_crt, default_rs232_devices, nullptr); + m_crt->rxd_handler().set(m_usart, FUNC(i8251_device::write_rxd)); + m_crt->cts_handler().set(FUNC(sb8085_state::crt_rts_w)); + m_crt->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); + + RS232_PORT(config, m_printer, default_rs232_devices, nullptr); + m_printer->cts_handler().set(FUNC(sb8085_state::printer_rts_w)); + + S100_BUS(config, m_s100, 6.144_MHz_XTAL / 2); + S100_SLOT(config, "s100:1", sb8085_s100_devices, "vti"); + S100_SLOT(config, "s100:2", sb8085_s100_devices, nullptr); + S100_SLOT(config, "s100:3", sb8085_s100_devices, nullptr); + S100_SLOT(config, "s100:4", sb8085_s100_devices, nullptr); +} + + +ROM_START(sb8085) + ROM_REGION(0xc00, "program", 0) + // From manual listing titled "SPACE BYTE 8085 PROM MONITOR 11-14-77" to be programmed on 3 TMS2708JL + ROM_LOAD("1.u19", 0x000, 0x400, CRC(9e1f11dd) SHA1(4c4482baa133dd6d437aaf749e31b72c9718eb97)) + ROM_LOAD("2.u20", 0x400, 0x400, CRC(2426af98) SHA1(b6e37041f997aeea13be79df10dc410f4b0c51a6)) + ROM_LOAD("3.u21", 0x800, 0x400, CRC(088ad01b) SHA1(6832e63dc1769db09107bc09f4c2cfb158dd8d33)) +ROM_END + +COMP(1977, sb8085, 0, 0, sb8085, sb8085, sb8085_state, empty_init, "Space Byte", "Space Byte 8085", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) |