sdk85: Updates and expansion

- Make second 8355 into ROM expansion slot that can load custom 8755 programs
- Add software list for expansion ROMs, including Peter Naszvadi's version of Mastermind
- Add optional TTY interface
- Improve accuracy of button labels and change key bindings
- Add vectored interrupt and soft reset buttons
This commit is contained in:
AJR 2020-01-29 19:56:07 -05:00
parent bfe833c3b9
commit 4e0540d25b
8 changed files with 454 additions and 53 deletions

31
hash/sdk85.xml Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
<softwarelist name="sdk85" description="SDK-85 expansion ROMs">
<software name="ap29" supported="no">
<!-- Program listed in "Using the Intel 8085 Serial I/O Lines" application note -->
<!-- CRT and cassette tape interfaces require custom SID/SOD hookups -->
<description>AP-29 Serial I/O Routines</description>
<year>1977</year>
<publisher>Intel</publisher>
<info name="author" value="John Wharton"/>
<part name="prom" interface="sdk85_rom">
<dataarea name="rom" size="2048">
<rom name="ap29.bin" size="2048" crc="c17c3020" sha1="d96dd85fd47ad4af41366a4df758a421b1c39d49"/>
</dataarea>
</part>
</software>
<software name="mmind">
<description>Mastermind</description>
<year>2019</year>
<publisher>hack (Peter Naszvadi)</publisher>
<info name="author" value="Paolo Forlani and Stefano Bodrato"/>
<part name="prom" interface="sdk85_rom">
<dataarea name="rom" size="2048">
<rom name="mastermind.a15" size="2048" crc="0538e162" sha1="c351975e2cf515cee29fcaeb04ef47189afe5250"/>
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -2668,6 +2668,20 @@ if (BUSES["NES_CTRL"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/bus/sdk85/memexp.h,BUSES["SDK85"] = true
---------------------------------------------------
if (BUSES["SDK85"]~=null) then
files {
MAME_DIR .. "src/devices/bus/sdk85/memexp.cpp",
MAME_DIR .. "src/devices/bus/sdk85/memexp.h",
MAME_DIR .. "src/devices/bus/sdk85/i8755.cpp",
MAME_DIR .. "src/devices/bus/sdk85/i8755.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/snes/snes_slot.h,BUSES["SNES"] = true

View File

@ -862,6 +862,7 @@ BUSES["SATURN"] = true
BUSES["SBUS"] = true
BUSES["SCSI"] = true
BUSES["SCV"] = true
BUSES["SDK85"] = true
BUSES["SEGA8"] = true
BUSES["SG1000_EXP"] = true
BUSES["SGIKBD"] = true

View File

@ -0,0 +1,65 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#include "emu.h"
#include "i8755.h"
// device type definition
DEFINE_DEVICE_TYPE(SDK85_I8755, sdk85exp_i8755_device, "sdk85exp_i8755", "SDK-85 PROM I/O Expansion (Intel 8755)")
sdk85exp_i8755_device::sdk85exp_i8755_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SDK85_I8755, tag, owner, clock)
, device_sdk85_romexp_card_interface(mconfig, *this)
, m_i8755(*this, "i8755")
{
}
void sdk85exp_i8755_device::device_start()
{
}
u8 sdk85exp_i8755_device::read_memory(offs_t offset)
{
return m_i8755->memory_r(offset);
}
void sdk85exp_i8755_device::write_memory(offs_t offset, u8 data)
{
logerror("Writing %02Xh to base + %03Xh\n", data, offset);
m_i8755->io_w(offset & 3, data);
}
u8 sdk85exp_i8755_device::read_io(offs_t offset)
{
return m_i8755->io_r(offset & 3);
}
void sdk85exp_i8755_device::write_io(offs_t offset, u8 data)
{
m_i8755->io_w(offset & 3, data);
}
void sdk85exp_i8755_device::device_add_mconfig(machine_config &config)
{
I8355(config, m_i8755, DERIVED_CLOCK(1, 1));
}
u8 *sdk85exp_i8755_device::get_rom_base(u32 size)
{
if (size != 0x800)
{
osd_printf_error("sdk85exp_i8755: Data length must be 2,048 bytes\n");
return nullptr;
}
return memregion("i8755")->base();
}
ROM_START(sdk85exp_i8755)
ROM_REGION(0x800, "i8755", ROMREGION_ERASE00)
ROM_END
const tiny_rom_entry *sdk85exp_i8755_device::device_rom_region() const
{
return ROM_NAME(sdk85exp_i8755);
}

View File

@ -0,0 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#ifndef MAME_BUS_SDK85_I8755_H
#define MAME_BUS_SDK85_I8755_H
#pragma once
#include "memexp.h"
#include "machine/i8355.h"
// ======================> sdk85exp_i8755_device
class sdk85exp_i8755_device : public device_t, public device_sdk85_romexp_card_interface
{
public:
// construction/destruction
sdk85exp_i8755_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
// device_sdk85_romexp_card_interface overrides
virtual u8 read_memory(offs_t offset) override;
virtual void write_memory(offs_t offset, u8 data) override;
virtual u8 read_io(offs_t offset) override;
virtual void write_io(offs_t offset, u8 data) override;
virtual u8 *get_rom_base(u32 size) override;
private:
required_device<i8355_device> m_i8755;
};
// device type declaration
DECLARE_DEVICE_TYPE(SDK85_I8755, sdk85exp_i8755_device)
#endif // MAME_BUS_SDK85_I8755_H

View File

@ -0,0 +1,94 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/***************************************************************************
SDK-85 memory expansion (ALE-multiplexed)
***************************************************************************/
#include "emu.h"
#include "memexp.h"
#include "i8755.h"
// device type definition
DEFINE_DEVICE_TYPE(SDK85_ROMEXP, sdk85_romexp_device, "sdk85_romexp", "SDK-85 expansion ROM socket")
sdk85_romexp_device::sdk85_romexp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SDK85_ROMEXP, tag, owner, clock)
, device_image_interface(mconfig, *this)
, device_single_card_slot_interface<device_sdk85_romexp_card_interface>(mconfig, *this)
, m_dev(nullptr)
{
}
image_init_result sdk85_romexp_device::call_load()
{
if (get_card_device() != nullptr)
{
u32 size = loaded_through_softlist() ? get_software_region_length("rom") : length();
u8 *base = get_card_device()->get_rom_base(size);
if (base == nullptr)
return image_init_result::FAIL;
if (loaded_through_softlist())
memcpy(base, get_software_region("rom"), size);
else
fread(base, size);
}
return image_init_result::PASS;
}
std::string sdk85_romexp_device::get_default_card_software(get_default_card_software_hook &hook) const
{
return software_get_default_slot("i8755");
}
void sdk85_romexp_device::device_start()
{
m_dev = get_card_device();
}
u8 sdk85_romexp_device::memory_r(offs_t offset)
{
if (m_dev != nullptr)
return m_dev->read_memory(offset);
else
return 0xff;
}
void sdk85_romexp_device::memory_w(offs_t offset, u8 data)
{
if (m_dev != nullptr)
m_dev->write_memory(offset, data);
}
u8 sdk85_romexp_device::io_r(offs_t offset)
{
if (m_dev != nullptr)
return m_dev->read_io(offset);
else
return 0xff;
}
void sdk85_romexp_device::io_w(offs_t offset, u8 data)
{
if (m_dev != nullptr)
m_dev->write_io(offset, data);
}
void sdk85_romexp_device::rom_options(device_slot_interface &slot)
{
slot.option_add_internal("i8755", SDK85_I8755);
}
device_sdk85_romexp_card_interface::device_sdk85_romexp_card_interface(const machine_config &mconfig, device_t &device)
: device_interface(device, "sdk85_romexp")
{
}
u8 *device_sdk85_romexp_card_interface::get_rom_base(u32 size)
{
return nullptr;
}

View File

@ -0,0 +1,83 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#ifndef MAME_BUS_SDK85_MEMEXP_H
#define MAME_BUS_SDK85_MEMEXP_H
#pragma once
#include "softlist_dev.h"
// ======================> device_sdk85_romexp_card_interface
class device_sdk85_romexp_card_interface : public device_interface
{
friend class sdk85_romexp_device;
protected:
device_sdk85_romexp_card_interface(const machine_config &mconfig, device_t &device);
virtual u8 read_memory(offs_t offset) = 0;
virtual void write_memory(offs_t offset, u8 data) = 0;
virtual u8 read_io(offs_t offset) = 0;
virtual void write_io(offs_t offset, u8 data) = 0;
virtual u8 *get_rom_base(u32 size);
};
// ======================> sdk85_romexp_device
class sdk85_romexp_device : public device_t,
public device_image_interface,
public device_single_card_slot_interface<device_sdk85_romexp_card_interface>
{
public:
// construction/destruction
sdk85_romexp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
template <typename T>
sdk85_romexp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt)
: sdk85_romexp_device(mconfig, tag, owner, clock)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
static void rom_options(device_slot_interface &device);
u8 memory_r(offs_t offset);
void memory_w(offs_t offset, u8 data);
u8 io_r(offs_t offset);
void io_w(offs_t offset, u8 data);
protected:
// device-level overrides
virtual void device_start() override;
// image-level overrides
virtual image_init_result call_load() override;
virtual void call_unload() override { }
virtual iodevice_t image_type() const noexcept override { return IO_ROM; }
virtual bool is_readable() const noexcept override { return true; }
virtual bool is_writeable() const noexcept override { return false; }
virtual bool is_creatable() const noexcept override { return false; }
virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return true; }
virtual const char *image_interface() const noexcept override { return "sdk85_rom"; }
virtual const char *file_extensions() const noexcept override { return "bin"; }
virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
private:
device_sdk85_romexp_card_interface *m_dev;
};
// device type declaration
DECLARE_DEVICE_TYPE(SDK85_ROMEXP, sdk85_romexp_device)
#endif // MAME_BUS_SDK85_MEMEXP_H

View File

@ -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 */