From 6992b3816e0c0b059258de6594e928e151d42aa7 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Tue, 16 May 2023 22:03:09 +0100 Subject: bus/psion: Added SIBO and Honda expansion port devices: - 3Fax Modem, 3Link Parallel Printer Interface, 3Link RS232 Serial Interface, and Siena SSD Drive. psion/psion3a.cpp: Added wakeup with specific keys, and SIBO/Honda expansion ports. psion/siena.cpp: Added wakeup with specific keys, and Honda expansion port. psion/workabout.cpp: Added wakeup with specific keys. machine/psion_asic5.cpp: Partially implemented peripheral mode. machine/psion_asic9.cpp: Implemented memory protection, and additional external interrupt lines. --- scripts/src/bus.lua | 33 ++++ scripts/src/machine.lua | 15 ++ src/devices/bus/psion/honda/slot.cpp | 105 +++++++++++++ src/devices/bus/psion/honda/slot.h | 99 ++++++++++++ src/devices/bus/psion/honda/ssd.cpp | 56 +++++++ src/devices/bus/psion/honda/ssd.h | 51 +++++++ src/devices/bus/psion/sibo/3fax.cpp | 84 +++++++++++ src/devices/bus/psion/sibo/3fax.h | 54 +++++++ src/devices/bus/psion/sibo/3link.cpp | 133 +++++++++++++++++ src/devices/bus/psion/sibo/3link.h | 83 +++++++++++ src/devices/bus/psion/sibo/slot.cpp | 101 +++++++++++++ src/devices/bus/psion/sibo/slot.h | 90 +++++++++++ src/devices/machine/psion_asic4.cpp | 169 +++++++++++++++++++++ src/devices/machine/psion_asic4.h | 59 ++++++++ src/devices/machine/psion_asic5.cpp | 186 ++++++++++++++++------- src/devices/machine/psion_asic5.h | 79 +++------- src/devices/machine/psion_asic9.cpp | 138 ++++++++++------- src/devices/machine/psion_asic9.h | 26 +++- src/devices/machine/psion_ssd.cpp | 256 +++++++++++++++++++++++++++++++ src/devices/machine/psion_ssd.h | 82 ++++++++++ src/mame/psion/psion3a.cpp | 127 ++++++++++------ src/mame/psion/psion_ssd.cpp | 281 ----------------------------------- src/mame/psion/psion_ssd.h | 84 ----------- src/mame/psion/siena.cpp | 47 ++++-- src/mame/psion/workabout.cpp | 22 ++- 25 files changed, 1859 insertions(+), 601 deletions(-) create mode 100644 src/devices/bus/psion/honda/slot.cpp create mode 100644 src/devices/bus/psion/honda/slot.h create mode 100644 src/devices/bus/psion/honda/ssd.cpp create mode 100644 src/devices/bus/psion/honda/ssd.h create mode 100644 src/devices/bus/psion/sibo/3fax.cpp create mode 100644 src/devices/bus/psion/sibo/3fax.h create mode 100644 src/devices/bus/psion/sibo/3link.cpp create mode 100644 src/devices/bus/psion/sibo/3link.h create mode 100644 src/devices/bus/psion/sibo/slot.cpp create mode 100644 src/devices/bus/psion/sibo/slot.h create mode 100644 src/devices/machine/psion_asic4.cpp create mode 100644 src/devices/machine/psion_asic4.h create mode 100644 src/devices/machine/psion_ssd.cpp create mode 100644 src/devices/machine/psion_ssd.h delete mode 100644 src/mame/psion/psion_ssd.cpp delete mode 100644 src/mame/psion/psion_ssd.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 889b669b959..b7160a04435 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2212,6 +2212,39 @@ if (BUSES["POFO"]~=null) then } end + +--------------------------------------------------- +-- +--@src/devices/bus/psion/honda/slot.h,BUSES["PSION_HONDA"] = true +--------------------------------------------------- + +if (BUSES["PSION_HONDA"]~=null) then + files { + MAME_DIR .. "src/devices/bus/psion/honda/slot.cpp", + MAME_DIR .. "src/devices/bus/psion/honda/slot.h", + MAME_DIR .. "src/devices/bus/psion/honda/ssd.cpp", + MAME_DIR .. "src/devices/bus/psion/honda/ssd.h", + } +end + + +--------------------------------------------------- +-- +--@src/devices/bus/psion/sibo/slot.h,BUSES["PSION_SIBO"] = true +--------------------------------------------------- + +if (BUSES["PSION_SIBO"]~=null) then + files { + MAME_DIR .. "src/devices/bus/psion/sibo/slot.cpp", + MAME_DIR .. "src/devices/bus/psion/sibo/slot.h", + MAME_DIR .. "src/devices/bus/psion/sibo/3fax.cpp", + MAME_DIR .. "src/devices/bus/psion/sibo/3fax.h", + MAME_DIR .. "src/devices/bus/psion/sibo/3link.cpp", + MAME_DIR .. "src/devices/bus/psion/sibo/3link.h", + } +end + + --------------------------------------------------- -- --@src/devices/bus/rc2014/rc2014.h,BUSES["RC2014"] = true diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 1b373a32cc2..fb62db5756b 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2897,12 +2897,15 @@ end --------------------------------------------------- -- +--@src/devices/machine/psion_asic4.h,MACHINES["PSION_ASIC"] = true --@src/devices/machine/psion_asic5.h,MACHINES["PSION_ASIC"] = true --@src/devices/machine/psion_asic9.h,MACHINES["PSION_ASIC"] = true --------------------------------------------------- if (MACHINES["PSION_ASIC"]~=null) then files { + MAME_DIR .. "src/devices/machine/psion_asic4.cpp", + MAME_DIR .. "src/devices/machine/psion_asic4.h", MAME_DIR .. "src/devices/machine/psion_asic5.cpp", MAME_DIR .. "src/devices/machine/psion_asic5.h", MAME_DIR .. "src/devices/machine/psion_asic9.cpp", @@ -2910,6 +2913,18 @@ if (MACHINES["PSION_ASIC"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/psion_ssd.h,MACHINES["PSION_SSD"] = true +--------------------------------------------------- + +if (MACHINES["PSION_SSD"]~=null) then + files { + MAME_DIR .. "src/devices/machine/psion_ssd.cpp", + MAME_DIR .. "src/devices/machine/psion_ssd.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/pxa255.h,MACHINES["PXA255"] = true diff --git a/src/devices/bus/psion/honda/slot.cpp b/src/devices/bus/psion/honda/slot.cpp new file mode 100644 index 00000000000..049e9d7237a --- /dev/null +++ b/src/devices/bus/psion/honda/slot.cpp @@ -0,0 +1,105 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Honda Expansion slot emulation + + This port is on Series 3c/3mx/Siena machines only. + + TODO: + - add RS232 interface handlers + +**********************************************************************/ + +#include "emu.h" +#include "slot.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PSION_HONDA_SLOT, psion_honda_slot_device, "psion_honda_slot", "Psion Honda Expansion slot") + + +//************************************************************************** +// DEVICE PSION_EXP PORT INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_psion_honda_interface - constructor +//------------------------------------------------- + +device_psion_honda_interface::device_psion_honda_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "psionhonda") +{ + m_slot = dynamic_cast(device.owner()); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// psion_honda_slot_device - constructor +//------------------------------------------------- + +psion_honda_slot_device::psion_honda_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_HONDA_SLOT, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_card(nullptr) + , m_int_cb(*this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_honda_slot_device::device_start() +{ + m_card = get_card_device(); + + // resolve callbacks + m_int_cb.resolve_safe(); +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +uint8_t psion_honda_slot_device::data_r() +{ + return m_card ? m_card->data_r() : 0x00; +} + + +//------------------------------------------------- +// write +//------------------------------------------------- + +void psion_honda_slot_device::data_w(uint16_t data) +{ + if (m_card) + m_card->data_w(data); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( psion_honda_devices ) +//------------------------------------------------- + +// slot devices +//#include "parallel.h" +//#include "pclink.h" +#include "ssd.h" + +void psion_honda_devices(device_slot_interface &device) +{ + //device.option_add("parallel", PSION_PARALLEL); // Psion Parallel Printer Link cable + //device.option_add("pclink", PSION_PCLINK); // Psion PC Link cable + device.option_add("ssd", PSION_SIENA_SSD); // Psion Siena SSD Drive +} diff --git a/src/devices/bus/psion/honda/slot.h b/src/devices/bus/psion/honda/slot.h new file mode 100644 index 00000000000..f0283f17139 --- /dev/null +++ b/src/devices/bus/psion/honda/slot.h @@ -0,0 +1,99 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Honda Expansion slot emulation + +********************************************************************** + + Pin Name Comments + + 1 VEXT + 2 RTS + 3 DTR + 4 TXD + 5 DSR + 6 DCD + 7 CTS + 8 RXD + 9 SDOE + 10 XSTAT + 11 EXON + 12 INT + 13 SD + 14 SCK + 15 GND + +**********************************************************************/ + +#ifndef MAME_BUS_PSION_HONDA_SLOT_H +#define MAME_BUS_PSION_HONDA_SLOT_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_honda_slot_device + +class device_psion_honda_interface; + +class psion_honda_slot_device : public device_t, public device_single_card_slot_interface +{ +public: + // construction/destruction + template + psion_honda_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option) + : psion_honda_slot_device(mconfig, tag, owner) + { + option_reset(); + slot_options(*this); + set_default_option(default_option); + set_fixed(false); + } + + psion_honda_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // callbacks + auto int_cb() { return m_int_cb.bind(); } + + uint8_t data_r(); + void data_w(uint16_t data); + + DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_cb(state); } + +protected: + // device-level overrides + virtual void device_start() override; + + device_psion_honda_interface *m_card; + +private: + devcb_write_line m_int_cb; +}; + + +// ======================> device_psion_honda_interface + +class device_psion_honda_interface : public device_interface +{ +public: + virtual uint8_t data_r() { return 0x00; } + virtual void data_w(uint16_t data) { } + +protected: + device_psion_honda_interface(const machine_config &mconfig, device_t &device); + + psion_honda_slot_device *m_slot; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_HONDA_SLOT, psion_honda_slot_device) + +void psion_honda_devices(device_slot_interface &device); + + +#endif // MAME_BUS_PSION_HONDA_SLOT_H diff --git a/src/devices/bus/psion/honda/ssd.cpp b/src/devices/bus/psion/honda/ssd.cpp new file mode 100644 index 00000000000..8e7eef8d3f5 --- /dev/null +++ b/src/devices/bus/psion/honda/ssd.cpp @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Siena SSD Drive + +**********************************************************************/ + +#include "emu.h" +#include "ssd.h" +#include "bus/rs232/rs232.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PSION_SIENA_SSD, psion_siena_ssd_device, "psion_siena_ssd", "Psion Siena SSD Drive") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void psion_siena_ssd_device::device_add_mconfig(machine_config &config) +{ + PSION_SSD(config, m_ssd); + m_ssd->door_cb().set(DEVICE_SELF_OWNER, FUNC(psion_honda_slot_device::int_w)); + + RS232_PORT(config, "rs232", default_rs232_devices, nullptr); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// psion_siena_ssd_device - constructor +//------------------------------------------------- + +psion_siena_ssd_device::psion_siena_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_SIENA_SSD, tag, owner, clock) + , device_psion_honda_interface(mconfig, *this) + , m_ssd(*this, "ssd") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_siena_ssd_device::device_start() +{ +} diff --git a/src/devices/bus/psion/honda/ssd.h b/src/devices/bus/psion/honda/ssd.h new file mode 100644 index 00000000000..171b0549110 --- /dev/null +++ b/src/devices/bus/psion/honda/ssd.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Siena SSD Drive + +**********************************************************************/ + +#ifndef MAME_BUS_PSION_HONDA_SSD_H +#define MAME_BUS_PSION_HONDA_SSD_H + +#include "slot.h" +#include "machine/psion_ssd.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_siena_ssd_device + +class psion_siena_ssd_device : + public device_t, + public device_psion_honda_interface +{ +public: + // construction/destruction + psion_siena_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + static constexpr feature_type unemulated_features() { return feature::COMMS; } + +protected: + // device_t overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t data_r() override { return m_ssd->data_r(); } + virtual void data_w(uint16_t data) override { m_ssd->data_w(data); } + +private: + required_device m_ssd; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_SIENA_SSD, psion_siena_ssd_device) + + +#endif // MAME_BUS_PSION_HONDA_SSD_H diff --git a/src/devices/bus/psion/sibo/3fax.cpp b/src/devices/bus/psion/sibo/3fax.cpp new file mode 100644 index 00000000000..a85f81d5200 --- /dev/null +++ b/src/devices/bus/psion/sibo/3fax.cpp @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion 3Fax Modem + + TODO: add other devices + - 32K RAM (KM62256) + - R6653-21 + - Flash N28F010-150 + +**********************************************************************/ + +#include "emu.h" +#include "3fax.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PSION_3FAX_MODEM, psion_3fax_modem_device, "psion_3fax", "Psion 3Fax Modem") + + +//------------------------------------------------- +// ROM( 3fax ) +//------------------------------------------------- + +ROM_START(3fax) + ROM_REGION(0x100000, "rom", 0) + ROM_LOAD("3fax_v2.01.rom", 0x0000, 0x100000, CRC(55c7c95b) SHA1(85d6f7e3cd316be5f49e7dd25755673144fce3d7)) +ROM_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *psion_3fax_modem_device::device_rom_region() const +{ + return ROM_NAME(3fax); +} + + +void psion_3fax_modem_device::asic4_map(address_map &map) +{ + map(0x400000, 0x4fffff).rom().region("rom", 0); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void psion_3fax_modem_device::device_add_mconfig(machine_config &config) +{ + PSION_ASIC4(config, m_asic4); + m_asic4->set_ext_info_byte(0xac6); + m_asic4->set_addrmap(0, &psion_3fax_modem_device::asic4_map); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// psion_3fax_modem_device - constructor +//------------------------------------------------- + +psion_3fax_modem_device::psion_3fax_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_3FAX_MODEM, tag, owner, clock) + , device_psion_sibo_interface(mconfig, *this) + , m_asic4(*this, "asic4") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_3fax_modem_device::device_start() +{ +} diff --git a/src/devices/bus/psion/sibo/3fax.h b/src/devices/bus/psion/sibo/3fax.h new file mode 100644 index 00000000000..392720d71d0 --- /dev/null +++ b/src/devices/bus/psion/sibo/3fax.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion 3Fax Modem + +**********************************************************************/ + +#ifndef MAME_BUS_PSION_SIBO_3FAX_H +#define MAME_BUS_PSION_SIBO_3FAX_H + +#include "slot.h" +#include "machine/psion_asic4.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_3fax_modem_device + +class psion_3fax_modem_device : + public device_t, + public device_psion_sibo_interface +{ +public: + // construction/destruction + psion_3fax_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + static constexpr feature_type unemulated_features() { return feature::COMMS; } + +protected: + // device_t overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual uint8_t data_r() override { return m_asic4->data_r(); } + virtual void data_w(uint16_t data) override { m_asic4->data_w(data); } + +private: + required_device m_asic4; + + void asic4_map(address_map &map); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_3FAX_MODEM, psion_3fax_modem_device) + + +#endif // MAME_BUS_PSION_SIBO_3FAX_H diff --git a/src/devices/bus/psion/sibo/3link.cpp b/src/devices/bus/psion/sibo/3link.cpp new file mode 100644 index 00000000000..12b7d7d3343 --- /dev/null +++ b/src/devices/bus/psion/sibo/3link.cpp @@ -0,0 +1,133 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion 3Link RS232 Serial Interface / Parallel Printer Interface + +**********************************************************************/ + +#include "emu.h" +#include "3link.h" +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PSION_3LINK_SERIAL, psion_3link_serial_device, "psion_3link_ser", "Psion 3Link RS232 Serial Interface") +DEFINE_DEVICE_TYPE(PSION_3LINK_PARALLEL, psion_3link_parallel_device, "psion_3link_par", "Psion 3Link Parallel Printer Interface") + + +//------------------------------------------------- +// ROM( 3link_serial ) +//------------------------------------------------- + +ROM_START(3link_serial) + ROM_REGION(0x20000, "rom", 0) + ROM_LOAD("3link_v1.21f.rom", 0x0000, 0x20000, CRC(211f6218) SHA1(11cab06779ea19f109970dfa641b89f0121bfd95)) +ROM_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *psion_3link_serial_device::device_rom_region() const +{ + return ROM_NAME(3link_serial); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void psion_3link_serial_device::device_add_mconfig(machine_config &config) +{ + PSION_ASIC5(config, m_asic5, DERIVED_CLOCK(1, 1)).set_mode(psion_asic5_device::PERIPHERAL_MODE); + m_asic5->set_info_byte(0x05); // ROM + RS232 + m_asic5->readpa_handler().set([this]() { return m_rom[m_addr_latch & 0x1ffff]; }); + m_asic5->writepb_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0xffff00) | (data << 0); }); + m_asic5->writepd_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0xff00ff) | (data << 8); }); + m_asic5->writepe_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0x00ffff) | (BIT(~data, 1) << 16); }); // CS2 + + RS232_PORT(config, "rs232", default_rs232_devices, nullptr); +} + +void psion_3link_parallel_device::device_add_mconfig(machine_config &config) +{ + PSION_ASIC5(config, m_asic5, DERIVED_CLOCK(1, 1)).set_mode(psion_asic5_device::PERIPHERAL_MODE); + m_asic5->set_info_byte(0x02); // Parallel + m_asic5->readpa_handler().set("cent_status_in", FUNC(input_buffer_device::read)); + m_asic5->writepb_handler().set("cent_data_out", FUNC(output_latch_device::write)); + m_asic5->writepc_handler().set("cent_ctrl_out", FUNC(output_latch_device::write)); + + centronics_device ¢ronics(CENTRONICS(config, "centronics", centronics_devices, "printer")); + centronics.busy_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit4)); + centronics.ack_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit5)); + centronics.fault_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit6)); + centronics.perror_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit7)); + + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + centronics.set_output_latch(cent_data_out); + + output_latch_device ¢_ctrl_out(OUTPUT_LATCH(config, "cent_ctrl_out")); + cent_ctrl_out.bit_handler<4>().set("centronics", FUNC(centronics_device::write_strobe)); + cent_ctrl_out.bit_handler<5>().set("centronics", FUNC(centronics_device::write_init)); + cent_ctrl_out.bit_handler<6>().set("centronics", FUNC(centronics_device::write_autofd)); + cent_ctrl_out.bit_handler<7>().set("centronics", FUNC(centronics_device::write_select_in)); + + INPUT_BUFFER(config, "cent_status_in"); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// psion_3link_device - constructor +//------------------------------------------------- + +psion_3link_serial_device::psion_3link_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_3LINK_SERIAL, tag, owner, clock) + , device_psion_sibo_interface(mconfig, *this) + , m_rom(*this, "rom") + , m_asic5(*this, "asic5") +{ +} + +psion_3link_parallel_device::psion_3link_parallel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_3LINK_PARALLEL, tag, owner, clock) + , device_psion_sibo_interface(mconfig, *this) + , m_asic5(*this, "asic5") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_3link_serial_device::device_start() +{ +} + +void psion_3link_parallel_device::device_start() +{ +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void psion_3link_serial_device::device_reset() +{ + m_addr_latch = 0x00; +} + +void psion_3link_parallel_device::device_reset() +{ +} diff --git a/src/devices/bus/psion/sibo/3link.h b/src/devices/bus/psion/sibo/3link.h new file mode 100644 index 00000000000..162b2af18f5 --- /dev/null +++ b/src/devices/bus/psion/sibo/3link.h @@ -0,0 +1,83 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion 3Link RS232 Serial Interface / Parallel Printer Interface + +**********************************************************************/ + +#ifndef MAME_BUS_PSION_SIBO_3LINK_H +#define MAME_BUS_PSION_SIBO_3LINK_H + +#include "slot.h" +#include "machine/psion_asic5.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_3link_serial_device + +class psion_3link_serial_device : + public device_t, + public device_psion_sibo_interface +{ +public: + // construction/destruction + psion_3link_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + static constexpr feature_type unemulated_features() { return feature::COMMS; } + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual uint8_t data_r() override { return m_asic5->data_r(); } + virtual void data_w(uint16_t data) override { m_asic5->data_w(data); } + +private: + required_region_ptr m_rom; + required_device m_asic5; + + uint32_t m_addr_latch; +}; + + +// ======================> psion_3link_parallel_device + +class psion_3link_parallel_device : + public device_t, + public device_psion_sibo_interface +{ +public: + // construction/destruction + psion_3link_parallel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t data_r() override { return m_asic5->data_r(); } + virtual void data_w(uint16_t data) override { m_asic5->data_w(data); } + +private: + required_device m_asic5; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_3LINK_SERIAL, psion_3link_serial_device) +DECLARE_DEVICE_TYPE(PSION_3LINK_PARALLEL, psion_3link_parallel_device) + + +#endif // MAME_BUS_PSION_SIBO_3LINK_H diff --git a/src/devices/bus/psion/sibo/slot.cpp b/src/devices/bus/psion/sibo/slot.cpp new file mode 100644 index 00000000000..5aff9dba4af --- /dev/null +++ b/src/devices/bus/psion/sibo/slot.cpp @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Reduced External Expansion slot emulation + + This port is on Series 3/3a machines only. + +**********************************************************************/ + +#include "emu.h" +#include "slot.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PSION_SIBO_SLOT, psion_sibo_slot_device, "psion_sibo_slot", "Psion Reduced External Expansion slot") + + +//************************************************************************** +// DEVICE PSION_EXP PORT INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_psion_sibo_interface - constructor +//------------------------------------------------- + +device_psion_sibo_interface::device_psion_sibo_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "psionsibo") +{ + m_slot = dynamic_cast(device.owner()); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// psion_sibo_slot_device - constructor +//------------------------------------------------- + +psion_sibo_slot_device::psion_sibo_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_SIBO_SLOT, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_card(nullptr) + , m_int_cb(*this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_sibo_slot_device::device_start() +{ + m_card = get_card_device(); + + // resolve callbacks + m_int_cb.resolve_safe(); +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +uint8_t psion_sibo_slot_device::data_r() +{ + return m_card ? m_card->data_r() : 0x00; +} + + +//------------------------------------------------- +// write +//------------------------------------------------- + +void psion_sibo_slot_device::data_w(uint16_t data) +{ + if (m_card) + m_card->data_w(data); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( psion_sibo_devices ) +//------------------------------------------------- + +// slot devices +#include "3fax.h" +#include "3link.h" + +void psion_sibo_devices(device_slot_interface &device) +{ + device.option_add("fax", PSION_3FAX_MODEM); // Psion 3Fax Modem + device.option_add("parallel", PSION_3LINK_PARALLEL); // Psion 3Link Parallel Printer Interface + device.option_add("serial", PSION_3LINK_SERIAL); // Psion 3Link RS232 Serial Interface +} diff --git a/src/devices/bus/psion/sibo/slot.h b/src/devices/bus/psion/sibo/slot.h new file mode 100644 index 00000000000..5ea3af924a7 --- /dev/null +++ b/src/devices/bus/psion/sibo/slot.h @@ -0,0 +1,90 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Psion Reduced External Expansion slot emulation + +********************************************************************** + + Pin Name Comments + + 1 MSD Master SIBO serial protocol data line - pulled low + 2 MCLK Master SIBO serial protocol clock line - low in standby + 3 Vcc +5 volt supply, switched off in standby + 4 GND Signal ground, this signal should mate first when connector inserted + 5 SSD/INT Slave SIBO serial data line or active high interrupt input + 6 SCK/EXON Slave SIBO serial clock line or active high switch on input + +**********************************************************************/ + +#ifndef MAME_BUS_PSION_SIBO_SLOT_H +#define MAME_BUS_PSION_SIBO_SLOT_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_sibo_slot_device + +class device_psion_sibo_interface; + +class psion_sibo_slot_device : public device_t, public device_single_card_slot_interface +{ +public: + // construction/destruction + template + psion_sibo_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option) + : psion_sibo_slot_device(mconfig, tag, owner) + { + option_reset(); + slot_options(*this); + set_default_option(default_option); + set_fixed(false); + } + + psion_sibo_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // callbacks + auto int_cb() { return m_int_cb.bind(); } + + uint8_t data_r(); + void data_w(uint16_t data); + + DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_cb(state); } + +protected: + // device-level overrides + virtual void device_start() override; + + device_psion_sibo_interface *m_card; + +private: + devcb_write_line m_int_cb; +}; + + +// ======================> device_psion_sibo_interface + +class device_psion_sibo_interface : public device_interface +{ +public: + virtual uint8_t data_r() { return 0x00; } + virtual void data_w(uint16_t data) { } + +protected: + device_psion_sibo_interface(const machine_config &mconfig, device_t &device); + + psion_sibo_slot_device *m_slot; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_SIBO_SLOT, psion_sibo_slot_device) + +void psion_sibo_devices(device_slot_interface &device); + + +#endif // MAME_BUS_PSION_SIBO_SLOT_H diff --git a/src/devices/machine/psion_asic4.cpp b/src/devices/machine/psion_asic4.cpp new file mode 100644 index 00000000000..90c1987071e --- /dev/null +++ b/src/devices/machine/psion_asic4.cpp @@ -0,0 +1,169 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/****************************************************************************** + + Psion ASIC4 + + ASIC4 is a serial protocol slave IC for addressing memory and general + memory-mapped peripherals. It is used in SSDs to convert SIBO serial protocol + signals into addresses within the memory range of the memory pack. ASIC4 was + designed to be a cut-down version of ASIC5 which was the original SIBO serial + protocol slave chip. + + A27 A26 A25 A24 D7 D6 D5 D4 D3 D2 D1 D0 + M Peripheral Id Memory Type No. devices Memory Size + 1 0 0 0 No peripheral 0 0 0 RAM 0 0 1 device 0 0 0 No memory + 0 0 1 Turbo RS232 (16550) 0 0 1 Type 1 Flash 0 1 2 devices 0 0 1 32K + 0 1 0 3Fax 0 1 0 Type 2 Flash 1 0 3 devices 0 1 0 64K + 1 1 1 Extended info in ROM 1 1 0 ROM 1 1 4 devices 0 1 1 128K + 1 0 0 256K + 1 0 1 512K + 1 1 0 1M + +******************************************************************************/ + +#include "emu.h" +#include "psion_asic4.h" + +#define VERBOSE 0 +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + + +DEFINE_DEVICE_TYPE(PSION_ASIC4, psion_asic4_device, "psion_asic4", "Psion ASIC4") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +psion_asic4_device::psion_asic4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_ASIC4, tag, owner, clock) + , device_memory_interface(mconfig, *this) + , m_space_config("program", ENDIANNESS_LITTLE, 8, 28) +{ +} + + +device_memory_interface::space_config_vector psion_asic4_device::memory_space_config() const +{ + return space_config_vector{ std::make_pair(0, &m_space_config) }; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_asic4_device::device_start() +{ + m_space = &space(0); + + save_item(NAME(m_addr_latch)); + save_item(NAME(m_addr_writes)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void psion_asic4_device::device_reset() +{ + m_addr_latch = 0x00; + m_addr_writes = 0; +} + + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +void psion_asic4_device::data_w(uint16_t data) +{ + switch (data & 0x300) + { + case NULL_FRAME: + break; + + case CONTROL_FRAME: + m_sibo_control = data & 0xff; + + // reset address register to LSB + m_addr_writes = 0; + break; + + case DATA_FRAME: + data &= 0xff; + switch (m_sibo_control & 0x0f) + { + case 0x00: // Data register + LOG("%s data_w: Data register %02x\n", machine().describe_context(), data); + m_space->write_byte(m_addr_latch, data); + break; + + case 0x01: // Device Size register + LOG("%s data_w: Device Size register %02x\n", machine().describe_context(), data); + break; + + case 0x02: // Address Increment register + LOG("%s data_w: Address Increment register %02x\n", machine().describe_context(), data); + m_addr_latch = (m_addr_latch & 0xffffff0) | ((m_addr_latch + 1) & 0x0f); + break; + + case 0x03: // Address register + LOG("%s data_w: Address register %02x\n", machine().describe_context(), data); + if (m_addr_writes == 0) + m_addr_latch = 0x00; + m_addr_latch |= data << (m_addr_writes << 3); + m_addr_writes = (m_addr_writes + 1) & 3; + break; + + case 0x07: // Control register + LOG("%s data_w: Control register %02x\n", machine().describe_context(), data); + break; + + default: + LOG("%s data_w: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data); + break; + } + break; + } +} + +uint8_t psion_asic4_device::data_r() +{ + uint8_t data = 0x00; + + switch (m_sibo_control & 0xc0) + { + case 0x40: // SerialSelect + switch (m_sibo_control & 0x0f) + { + case 0x06: // Asic4Id + data = m_info_byte & 0xff; // A4InfoByte + break; + } + break; + + case 0xc0: // SerialRead + switch (m_sibo_control & 0x0f) + { + case 0x00: // Data register + data = m_space->read_byte(m_addr_latch); + LOG("%s data_r: Data register %02x\n", machine().describe_context(), data); + m_addr_latch++; + break; + + case 0x01: // Input register + data = (m_info_byte >> 4) & 0xf0; + LOG("%s data_r: Input register %02x\n", machine().describe_context(), data); + break; + + default: + LOG("%s data_r: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data); + break; + } + break; + } + + return data; +} diff --git a/src/devices/machine/psion_asic4.h b/src/devices/machine/psion_asic4.h new file mode 100644 index 00000000000..42860d1c11d --- /dev/null +++ b/src/devices/machine/psion_asic4.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/****************************************************************************** + + Psion ASIC4 + +******************************************************************************/ + +#ifndef MAME_MACHINE_PSION_ASIC4_H +#define MAME_MACHINE_PSION_ASIC4_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> psion_asic4_device + +class psion_asic4_device : public device_t, public device_memory_interface +{ +public: + psion_asic4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + void set_ext_info_byte(uint16_t info) { m_info_byte = info; } + + void data_w(uint16_t data); + uint8_t data_r(); + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + +private: + address_space_config m_space_config; + + address_space *m_space; + + static constexpr uint16_t NULL_FRAME = 0x000; + static constexpr uint16_t CONTROL_FRAME = 0x100; + static constexpr uint16_t DATA_FRAME = 0x200; + + uint32_t m_addr_latch; + uint8_t m_addr_writes; + + uint16_t m_info_byte; + uint8_t m_sibo_control; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_ASIC4, psion_asic4_device) + +#endif // MAME_MACHINE_PSION_ASIC4_H diff --git a/src/devices/machine/psion_asic5.cpp b/src/devices/machine/psion_asic5.cpp index 9e002b6f4af..219421e1660 100644 --- a/src/devices/machine/psion_asic5.cpp +++ b/src/devices/machine/psion_asic5.cpp @@ -10,8 +10,27 @@ parallel port interface, an 8-bit parallel I/O port, a serial bar code controller or a serial RS232 converter. + PC6 PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 + Pack Mode Memory Type No. devices Memory Size + 1 0 0 0 RAM 0 0 1 device 0 0 0 No memory + 0 0 1 Type 1 Flash 0 1 2 devices 0 0 1 32K + 0 1 0 Type 2 Flash 1 0 3 devices 0 1 0 64K + 1 1 0 ROM 1 1 4 devices 0 1 1 128K + 1 1 1 Write protect 1 0 0 256K + 1 0 1 512K + 1 1 0 1M + Peripheral Mode Type + 0 x x 0 x x x x 1 RS232 port + x x 0 x x x 1 x Centronics (Parallel) port + x x 0 x x 1 x X ROM + x x 0 x 1 x x X Magnetic Card Reader + x x 0 0 x x x x Barcode reader + x x 0 1 x x x x USA modem + x 1 0 x x x x x Modem + 1 x 0 x x x x x RS232 TTL + TODO: - - implement peripheral mode + - implement UART ******************************************************************************/ @@ -23,48 +42,36 @@ #include "logmacro.h" -DEFINE_DEVICE_TYPE(PSION_ASIC5_PACK, psion_asic5_pack_device, "psion_asic5_pack", "Psion ASIC5 (Pack mode)") -DEFINE_DEVICE_TYPE(PSION_ASIC5_PERIPHERAL, psion_asic5_peripheral_device, "psion_asic5_peripheral", "Psion ASIC5 (Peripheral mode)") +DEFINE_DEVICE_TYPE(PSION_ASIC5, psion_asic5_device, "psion_asic5", "Psion ASIC5") //************************************************************************** // LIVE DEVICE //************************************************************************** -psion_asic5_device::psion_asic5_device(const machine_config &mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock) +psion_asic5_device::psion_asic5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_ASIC5, tag, owner, clock) + , device_serial_interface(mconfig, *this) + , m_mode(~uint8_t(0)) , m_in_a_handler(*this) , m_in_b_handler(*this) , m_out_a_handler(*this) , m_out_b_handler(*this) , m_out_c_handler(*this) , m_out_d_handler(*this) + , m_out_e_handler(*this) { } -psion_asic5_pack_device::psion_asic5_pack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : psion_asic5_device(mconfig, PSION_ASIC5_PACK, tag, owner, clock) -{ -} - -psion_asic5_peripheral_device::psion_asic5_peripheral_device(const machine_config &mconfig, const char * tag, device_t *owner, uint32_t clock) - : psion_asic5_device(mconfig, PSION_ASIC5_PERIPHERAL, tag, owner, clock) - , m_serial(*this, "serial") - //, m_irq4_callback(*this) - //, m_txd1_callback(*this) - //, m_dtr1_callback(*this) - //, m_rts1_callback(*this) -{ -} +//------------------------------------------------- +// device_validity_check - device-specific checks +//------------------------------------------------- -void psion_asic5_peripheral_device::device_add_mconfig(machine_config &config) +void psion_asic5_device::device_validity_check(validity_checker &valid) const { - NS16550(config, m_serial, clock() / 13); - //m_serial->out_int_callback().set([this](int state) { m_irq4_callback(state); }); - //m_serial->out_tx_callback().set([this](int state) { m_txd1_callback(state); }); - //m_serial->out_dtr_callback().set([this](int state) { m_dtr1_callback(state); }); - //m_serial->out_rts_callback().set([this](int state) { m_rts1_callback(state); }); + if ((PACK_MODE != m_mode) && (PERIPHERAL_MODE != m_mode)) + osd_printf_error("Power on reset pin PC6 not configured\n"); } @@ -80,6 +87,13 @@ void psion_asic5_device::device_start() m_out_b_handler.resolve_safe(); m_out_c_handler.resolve_safe(); m_out_d_handler.resolve_safe(); + m_out_e_handler.resolve_safe(); + + save_item(NAME(m_port_b_counter)); + save_item(NAME(m_port_b_latch)); + save_item(NAME(m_port_b_mode)); + save_item(NAME(m_port_dc_writes)); + save_item(NAME(m_int_mask)); } //------------------------------------------------- @@ -88,8 +102,9 @@ void psion_asic5_device::device_start() void psion_asic5_device::device_reset() { - m_portb_ctrl = 0x00; - m_portb_counter = 0x00; + m_port_b_counter = 0x00; + m_port_b_latch = 0x00; + m_port_b_mode = 0x00; } @@ -110,7 +125,6 @@ void psion_asic5_device::data_w(uint16_t data) switch (m_sibo_control & 0xc0) { case 0x80: // SerialWrite - //if (m_sibo_control == 0x82) // write A3Setup if (m_sibo_control == 0x93) // Multi Port D and C writes m_port_dc_writes = 0; break; @@ -124,16 +138,23 @@ void psion_asic5_device::data_w(uint16_t data) case 0x00: // Port A write data LOG("%s data_w: Port A write data %02x\n", machine().describe_context(), data); m_out_a_handler(data); + if (BIT(m_port_b_mode, 1, 2) == 0) // Counter mode + { + m_out_b_handler(++m_port_b_counter); + } break; case 0x01: // Port B write data LOG("%s data_w: Port B write data %02x\n", machine().describe_context(), data); - m_out_b_handler(data); + if (BIT(m_port_b_mode, 1, 2) == 1) // Latch mode + { + m_out_b_handler(m_port_b_latch = data); + } break; case 0x02: // Port B control - LOG("%s data_w: Port B control %02x\n", machine().describe_context(), data); - m_portb_ctrl = data; + LOG("%s data_w: Port B mode %02x\n", machine().describe_context(), data); + m_port_b_mode = data; break; case 0x03: // Port D and C write data @@ -146,20 +167,45 @@ void psion_asic5_device::data_w(uint16_t data) { LOG("%s data_w: Port D write data %02x\n", machine().describe_context(), data); m_out_d_handler(data); - m_portb_counter = 0x00; - m_out_b_handler(m_portb_counter); + if (BIT(m_port_b_mode, 1, 2) == 0) // Counter mode + { + m_out_b_handler(m_port_b_counter = 0); + } } m_port_dc_writes++; break; case 0x06: // Interrupt mask write - LOG("%s data_w: out int mask %02x\n", machine().describe_context(), data); - m_interrupt_mask = data; + LOG("%s data_w: Interrupt mask write %02x\n", machine().describe_context(), data); + m_int_mask = data; + break; + + case 0x07: // Control register + LOG("%s data_w: Control register %02x\n", machine().describe_context(), data); + m_out_e_handler(data & 7); + break; + + case 0x08: // UART Control register + LOG("%s data_w: UART Control register %02x\n", machine().describe_context(), data); + set_data_frame(1, 5 + BIT(data, 1, 2), BIT(data, 3) ? (BIT(data, 4) ? PARITY_ODD : PARITY_EVEN) : PARITY_NONE, BIT(data, 5) ? STOP_BITS_2 : STOP_BITS_1); + break; + + case 0x09: // UART Transmit holding register + LOG("%s data_w: UART Transmit holding register %02x\n", machine().describe_context(), data); + transmit_register_setup(data); + break; + + case 0x0a: // UART Baud rate LSB + LOG("%s data_w: UART Baud rate LSB %02x\n", machine().describe_context(), data); break; - //case 0x07: // Control register - // m = data; - // break; + case 0x0b: // UART Baud rate MSB + LOG("%s data_w: UART Baud rate MSB %02x\n", machine().describe_context(), data); + break; + + case 0x0c: // Port 1 and 2 reset + LOG("%s data_w: Port 1 and 2 reset %02x\n", machine().describe_context(), data); + break; default: LOG("%s data_w: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data); @@ -177,8 +223,14 @@ uint8_t psion_asic5_device::data_r() switch (m_sibo_control & 0xc0) { case 0x40: // SerialSelect - if (m_sibo_control == 0x42) // Asic5PackId - data = m_info_byte; // A3InfoByte + switch (m_sibo_control & 0x0f) + { + case 0x02: // Asic5PackId + case 0x03: // Asic5NormalId + if (BIT(m_sibo_control, 0) == m_mode) + data = m_info_byte; // A5InfoByte + break; + } break; case 0xc0: // SerialRead @@ -187,32 +239,60 @@ uint8_t psion_asic5_device::data_r() case 0x00: // Port A read data data = m_in_a_handler(); LOG("%s data_r: Port A read data %02x\n", machine().describe_context(), data); - if (m_sibo_control & 0x90) // Multi, increment Port B + if (BIT(m_port_b_mode, 1, 2) == 0) // Counter mode { - m_portb_counter++; - m_out_b_handler(m_portb_counter); + m_out_b_handler(++m_port_b_counter); } break; case 0x01: // Port B read data - data = m_in_b_handler(); + if (BIT(m_port_b_mode, 1, 2) == 1) // Latch mode + { + data = m_port_b_latch; + } LOG("%s data_r: Port B read data %02x\n", machine().describe_context(), data); break; case 0x02: // Port B counter - m_portb_counter++; - m_out_b_handler(m_portb_counter); - LOG("%s data_r: Port B counter %02x\n", machine().describe_context(), m_portb_counter); + if (BIT(m_port_b_mode, 1, 2) == 0) // Counter mode + { + m_out_b_handler(++m_port_b_counter); + } + LOG("%s data_r: Port B counter %02x\n", machine().describe_context(), m_port_b_counter); break; - case 0x06: // Interrupt mask write - data = m_interrupt_mask; - LOG("%s data_r: in int mask %02x\n", machine().describe_context(), data); + case 0x06: // Interrupt mask read + data = m_int_mask; + LOG("%s data_r: Interrupt mask read %02x\n", machine().describe_context(), data); + break; + + case 0x08: // UART Status register + data |= is_transmit_register_empty() ? 1 << 3 : 0; + data |= is_receive_framing_error() ? 1 << 6 : 0; + data |= is_receive_parity_error() ? 1 << 7 : 0; + LOG("%s data_r: UART Status register %02x\n", machine().describe_context(), data); + break; + + case 0x09: // UART Receive register + data = get_received_char(); + LOG("%s data_r: UART Receive register %02x\n", machine().describe_context(), data); break; - //case 0x07: // Control register - // m = data; - // break; + case 0x0c: // Synchronous Port 1 read + LOG("%s data_r: Synchronous Port 1 read %02x\n", machine().describe_context(), data); + break; + + case 0x0d: // Barcode read data + // 0 PC4 4 PB4 + // 1 PC7 5 PB5 + // 2 PB2 6 PB6 + // 3 PB3 7 PB7 + LOG("%s data_r: Barcode read data %02x\n", machine().describe_context(), data); + break; + + case 0x0e: // Synchronous Port 2 read + LOG("%s data_r: Synchronous Port 2 read %02x\n", machine().describe_context(), data); + break; default: LOG("%s data_r: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data); diff --git a/src/devices/machine/psion_asic5.h b/src/devices/machine/psion_asic5.h index fbd07e89d46..aa221c9b8bd 100644 --- a/src/devices/machine/psion_asic5.h +++ b/src/devices/machine/psion_asic5.h @@ -11,7 +11,7 @@ #pragma once -#include "machine/ins8250.h" +#include "diserial.h" //************************************************************************** @@ -20,9 +20,19 @@ // ======================> psion_asic5_device -class psion_asic5_device : public device_t +class psion_asic5_device : public device_t, public device_serial_interface { public: + enum pc6_state + { + PACK_MODE = 0, + PERIPHERAL_MODE = 1 + }; + + psion_asic5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + void set_mode(pc6_state mode) { m_mode = mode; } + auto readpa_handler() { return m_in_a_handler.bind(); } auto readpb_handler() { return m_in_b_handler.bind(); } @@ -30,6 +40,7 @@ public: auto writepb_handler() { return m_out_b_handler.bind(); } auto writepc_handler() { return m_out_c_handler.bind(); } auto writepd_handler() { return m_out_d_handler.bind(); } + auto writepe_handler() { return m_out_e_handler.bind(); } void set_info_byte(uint8_t info) { m_info_byte = info; } @@ -37,10 +48,8 @@ public: uint8_t data_r(); protected: - // construction/destruction - psion_asic5_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides + // device_t overrides + virtual void device_validity_check(validity_checker &valid) const override; virtual void device_start() override; virtual void device_reset() override; @@ -49,68 +58,28 @@ private: static constexpr uint16_t CONTROL_FRAME = 0x100; static constexpr uint16_t DATA_FRAME = 0x200; + uint8_t m_mode; + devcb_read8 m_in_a_handler; devcb_read8 m_in_b_handler; devcb_write8 m_out_a_handler; devcb_write8 m_out_b_handler; devcb_write8 m_out_c_handler; devcb_write8 m_out_d_handler; + devcb_write8 m_out_e_handler; - // Slave control mode - static constexpr uint8_t READ_WRITE_SELECT = 0xc0; - static constexpr uint8_t BYTE_WORD_TRANSFER = 0xa0; - static constexpr uint8_t SINGLE_MULTI_TRANSFER = 0x90; - - // registers - uint8_t m_portb_counter; - uint8_t m_portb_ctrl; - int m_port_dc_writes; - uint8_t m_interrupt_mask; + uint8_t m_port_b_counter; + uint8_t m_port_b_latch; + uint8_t m_port_b_mode; + uint8_t m_port_dc_writes; + uint8_t m_int_mask; - // internal uint8_t m_info_byte; uint8_t m_sibo_control; }; -// ======================> psion_asic5_pack_device - -class psion_asic5_pack_device : public psion_asic5_device -{ -public: - // construction/destruction - psion_asic5_pack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); -}; - - -// ======================> psion_asic5_peripheral_device - -class psion_asic5_peripheral_device : public psion_asic5_device -{ -public: - // construction/destruction - psion_asic5_peripheral_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - - //auto irq4() { return m_irq4_callback.bind(); } - //auto txd1() { return m_txd1_callback.bind(); } - //auto dtr1() { return m_dtr1_callback.bind(); } - //auto rts1() { return m_rts1_callback.bind(); } - -protected: - virtual void device_add_mconfig(machine_config &config) override; - -private: - required_device m_serial; - - //devcb_write_line m_irq4_callback; - //devcb_write_line m_txd1_callback; - //devcb_write_line m_dtr1_callback; - //devcb_write_line m_rts1_callback; -}; - - // device type definition -DECLARE_DEVICE_TYPE(PSION_ASIC5_PACK, psion_asic5_pack_device) -DECLARE_DEVICE_TYPE(PSION_ASIC5_PERIPHERAL, psion_asic5_peripheral_device) +DECLARE_DEVICE_TYPE(PSION_ASIC5, psion_asic5_device) #endif // MAME_MACHINE_PSION_ASIC5_H diff --git a/src/devices/machine/psion_asic9.cpp b/src/devices/machine/psion_asic9.cpp index 13584e0049d..d1ddc141880 100644 --- a/src/devices/machine/psion_asic9.cpp +++ b/src/devices/machine/psion_asic9.cpp @@ -11,9 +11,9 @@ free-running clock (FRC) and a codec interface for sound. TODO: - - memory protection - improve RAM configuration for mx machines - set RTC timer + - ASIC9MX implements V30MX, and likely the unknown Temic device found in 3c/Siena ******************************************************************************/ @@ -28,18 +28,19 @@ #include "logmacro.h" -DEFINE_DEVICE_TYPE(PSION_ASIC9, psion_asic9_device, "psion_asic9", "Psion ASIC9") +DEFINE_DEVICE_TYPE(PSION_ASIC9, psion_asic9_device, "psion_asic9", "Psion ASIC9 V30H") +DEFINE_DEVICE_TYPE(PSION_ASIC9MX, psion_asic9mx_device, "psion_asic9mx", "Psion ASIC9 V30MX") //************************************************************************** // LIVE DEVICE //************************************************************************** -psion_asic9_device::psion_asic9_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, PSION_ASIC9, tag, owner, clock) +psion_asic9_device::psion_asic9_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) - , m_maincpu(*this, "maincpu") + , m_v30(*this, "v30") , m_ram(*this, finder_base::DUMMY_TAG) , m_rom(*this, finder_base::DUMMY_TAG) , m_ram_config("asic9_ram", ENDIANNESS_LITTLE, 16, 24, 0) @@ -49,7 +50,6 @@ psion_asic9_device::psion_asic9_device(const machine_config &mconfig, const char , m_frc2_timer(nullptr) , m_watchdog_timer(nullptr) , m_rtc_timer(nullptr) - , m_configure_ram_cb(*this) , m_buz_cb(*this) , m_col_cb(*this) , m_port_ab_r(*this) @@ -59,6 +59,16 @@ psion_asic9_device::psion_asic9_device(const machine_config &mconfig, const char { } +psion_asic9_device::psion_asic9_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : psion_asic9_device(mconfig, PSION_ASIC9, tag, owner, clock) +{ +} + +psion_asic9mx_device::psion_asic9mx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : psion_asic9_device(mconfig, PSION_ASIC9MX, tag, owner, clock) +{ +} + void psion_asic9_device::mem_map(address_map &map) { @@ -77,10 +87,10 @@ void psion_asic9_device::io_map(address_map &map) void psion_asic9_device::device_add_mconfig(machine_config &config) { - V30(config, m_maincpu, DERIVED_CLOCK(1, 1)); - m_maincpu->set_addrmap(AS_PROGRAM, &psion_asic9_device::mem_map); - m_maincpu->set_addrmap(AS_IO, &psion_asic9_device::io_map); - m_maincpu->set_irq_acknowledge_callback(FUNC(psion_asic9_device::inta_cb)); + V30(config, m_v30, DERIVED_CLOCK(1, 1)); + m_v30->set_addrmap(AS_PROGRAM, &psion_asic9_device::mem_map); + m_v30->set_addrmap(AS_IO, &psion_asic9_device::io_map); + m_v30->set_irq_acknowledge_callback(FUNC(psion_asic9_device::inta_cb)); } @@ -121,6 +131,9 @@ void psion_asic9_device::device_resolve_objects() void psion_asic9_device::device_start() { + if (!m_ram->started()) + throw device_missing_dependencies(); + m_ram_space = &space(AS_A9_RAM); m_rom_space = &space(AS_A9_ROM); @@ -214,7 +227,6 @@ void psion_asic9_device::device_reset() m_a9_control_extra = 0x00; m_rtc = time(nullptr) - 946684800; - //m_a9_status |= 0x2000; // A9MReset m_a9_status |= 0xe000; // A9MCold m_a9_serial_control = 0x00; m_a9_channel_select = 0x00; @@ -276,22 +288,32 @@ TIMER_CALLBACK_MEMBER(psion_asic9_device::rtc) m_rtc++; } -WRITE_LINE_MEMBER(psion_asic9_device::eint_w) +WRITE_LINE_MEMBER(psion_asic9_device::eint0_w) +{ + if (state) + m_a9_interrupt_status |= 0x08; // A9MExpIntC + else + m_a9_interrupt_status &= ~0x08; + + update_interrupts(); +} + +WRITE_LINE_MEMBER(psion_asic9_device::eint1_w) { if (state) - m_a9_interrupt_status |= 0x10; // Asic2Int + m_a9_interrupt_status |= 0x10; // A9MExpIntA else m_a9_interrupt_status &= ~0x10; update_interrupts(); } -WRITE_LINE_MEMBER(psion_asic9_device::enmi_w) +WRITE_LINE_MEMBER(psion_asic9_device::eint2_w) { if (state) - m_a9_control |= 0x0200; // ExternalNmi + m_a9_interrupt_status |= 0x20; // A9MExpIntB else - m_a9_control &= ~0x0200; + m_a9_interrupt_status &= ~0x20; update_interrupts(); } @@ -312,8 +334,8 @@ void psion_asic9_device::update_interrupts() bool irq = m_a9_interrupt_status & m_a9_interrupt_mask; bool nmi = m_a9_status & 0x000f; - m_maincpu->set_input_line(INPUT_LINE_IRQ0, irq ? ASSERT_LINE : CLEAR_LINE); - m_maincpu->set_input_line(INPUT_LINE_NMI, nmi ? ASSERT_LINE : CLEAR_LINE); + m_v30->set_input_line(INPUT_LINE_IRQ0, irq ? ASSERT_LINE : CLEAR_LINE); + m_v30->set_input_line(INPUT_LINE_NMI, nmi ? ASSERT_LINE : CLEAR_LINE); } @@ -343,7 +365,7 @@ IRQ_CALLBACK_MEMBER(psion_asic9_device::inta_cb) TIMER_CALLBACK_MEMBER(psion_asic9_device::busy) { - m_maincpu->set_input_line(NEC_INPUT_LINE_POLL, ASSERT_LINE); + m_v30->set_input_line(NEC_INPUT_LINE_POLL, ASSERT_LINE); } @@ -404,46 +426,62 @@ uint8_t psion_asic9_device::col_r() bool psion_asic9_device::is_protected(offs_t offset) { - //if (m_a9_protection_mode && (offset <= m_a9_protection_lower || offset > m_a9_protection_upper)) - //{ - // LOG("%s is_protected: %05x < %05x <= %05x\n", machine().describe_context(), m_a9_protection_lower, offset, m_a9_protection_upper); - // m_a9_status |= 0x0002; // A9MProtectedModeNMI - // update_interrupts(); - // return true; - //} + if (m_a9_protection_mode && (offset <= m_a9_protection_lower || offset > m_a9_protection_upper)) + { + LOG("%s is_protected: %05x < %05x <= %05x\n", machine().describe_context(), m_a9_protection_lower, offset, m_a9_protection_upper); + m_a9_status |= 0x0002; // A9MProtectedModeNMI + update_interrupts(); + return true; + } return false; } -uint16_t psion_asic9_device::mem_r(offs_t offset, uint16_t mem_mask) +offs_t psion_asic9_device::translate_address(offs_t offset) { - uint16_t data = 0xffff; - - offset <<= 1; - switch (offset & 0xf0000) { case 0x00000: case 0x10000: case 0x20000: case 0x30000: case 0x40000: case 0x50000: - data = m_ram_space->read_word(offset, mem_mask); break; case 0x60000: - data = m_ram_space->read_word((m_a9_psel_6000 << 16) | (offset & 0xffff), mem_mask); + offset = (m_a9_psel_6000 << 16) | (offset & 0xffff); break; case 0x70000: - data = m_ram_space->read_word((m_a9_psel_7000 << 16) | (offset & 0xffff), mem_mask); + offset = (m_a9_psel_7000 << 16) | (offset & 0xffff); break; case 0x80000: - data = m_rom_space->read_word((m_a9_psel_8000 << 16) | (offset & 0xffff), mem_mask); + offset = (m_a9_psel_8000 << 16) | (offset & 0xffff); break; case 0x90000: - data = m_rom_space->read_word((m_a9_psel_9000 << 16) | (offset & 0xffff), mem_mask); + offset = (m_a9_psel_9000 << 16) | (offset & 0xffff); break; case 0xa0000: case 0xb0000: case 0xc0000: case 0xd0000: case 0xe0000: case 0xf0000: - data = m_rom_space->read_word(0xf00000 | offset, mem_mask); + offset = 0xf00000 | offset; + break; + } + return offset; +} + +uint16_t psion_asic9_device::mem_r(offs_t offset, uint16_t mem_mask) +{ + uint16_t data = 0xffff; + + offset <<= 1; + + offs_t addr = translate_address(offset); + + switch (offset & 0x80000) + { + case 0x00000: + data = m_ram_space->read_word(addr, mem_mask); + break; + + case 0x80000: + data = m_rom_space->read_word(addr, mem_mask); break; } @@ -454,20 +492,14 @@ void psion_asic9_device::mem_w(offs_t offset, uint16_t data, uint16_t mem_mask) { offset <<= 1; - if (!is_protected(offset)) + offs_t addr = translate_address(offset); + + if (!is_protected(addr)) { - switch (offset & 0xf0000) + switch (offset & 0x80000) { - case 0x00000: case 0x10000: case 0x20000: case 0x30000: case 0x40000: case 0x50000: - m_ram_space->write_word(offset, data, mem_mask); - break; - - case 0x60000: - m_ram_space->write_word((m_a9_psel_6000 << 16) | (offset & 0xffff), data, mem_mask); - break; - - case 0x70000: - m_ram_space->write_word((m_a9_psel_7000 << 16) | (offset & 0xffff), data, mem_mask); + case 0x00000: + m_ram_space->write_word(addr, data, mem_mask); break; } } @@ -1017,9 +1049,9 @@ void psion_asic9_device::io_w(offs_t offset, uint16_t data, uint16_t mem_mask) // WriteSingle 10000000b; ReadSingle 11000000b // WriteMulti 10010000b; ReadMulti 11010000b // Reset 00000000b; Select 01000000b - // Asic4Id 001h; Asic5PackId 002h + // Asic2SlaveId 001h; Asic5PackId 002h // Asic5NormalId 003h; Asic6Id 004h - // Asic8Id 005h; Asic2SlaveId 01fh + // Asic8Id 005h; Asic4Id 006h LOG("%s io_w: A2SerialControl <= %02x\n", machine().describe_context(), data & 0xff); m_a9_serial_control = data & 0xff; transmit_frame(CONTROL_FRAME | m_a9_serial_control); @@ -1069,7 +1101,7 @@ bool psion_asic9_device::channel_active(int channel) void psion_asic9_device::transmit_frame(uint16_t data) { m_busy_timer->adjust(attotime::from_ticks(12, clock() / 2)); - m_maincpu->set_input_line(NEC_INPUT_LINE_POLL, CLEAR_LINE); + m_v30->set_input_line(NEC_INPUT_LINE_POLL, CLEAR_LINE); for (int ch = 0; ch < 8; ch++) { @@ -1086,7 +1118,7 @@ uint8_t psion_asic9_device::receive_frame() uint8_t data = 0x00; m_busy_timer->adjust(attotime::from_ticks(12, clock() / 2)); - m_maincpu->set_input_line(NEC_INPUT_LINE_POLL, CLEAR_LINE); + m_v30->set_input_line(NEC_INPUT_LINE_POLL, CLEAR_LINE); for (int ch = 0; ch < 8; ch++) { diff --git a/src/devices/machine/psion_asic9.h b/src/devices/machine/psion_asic9.h index 142ab33c7c9..8e1adb943be 100644 --- a/src/devices/machine/psion_asic9.h +++ b/src/devices/machine/psion_asic9.h @@ -47,13 +47,16 @@ public: IRQ_CALLBACK_MEMBER(inta_cb); - DECLARE_WRITE_LINE_MEMBER(eint_w); - DECLARE_WRITE_LINE_MEMBER(enmi_w); + DECLARE_WRITE_LINE_MEMBER(eint0_w); + DECLARE_WRITE_LINE_MEMBER(eint1_w); + DECLARE_WRITE_LINE_MEMBER(eint2_w); DECLARE_WRITE_LINE_MEMBER(medchng_w); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); protected: + psion_asic9_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_add_mconfig(machine_config &config) override; virtual void device_resolve_objects() override; virtual void device_start() override; @@ -62,7 +65,7 @@ protected: virtual space_config_vector memory_space_config() const override; private: - required_device m_maincpu; + required_device m_v30; required_device m_ram; required_memory_region m_rom; @@ -92,6 +95,7 @@ private: void update_interrupts(); bool is_protected(offs_t offset); + offs_t translate_address(offs_t offset); uint8_t m_ram_type; uint32_t ram_device_size(uint8_t device_type); @@ -110,8 +114,8 @@ private: uint16_t m_frc2_reload; uint8_t m_watchdog_count; bool m_a9_protection_mode; - uint16_t m_a9_protection_upper; - uint16_t m_a9_protection_lower; + uint32_t m_a9_protection_upper; + uint32_t m_a9_protection_lower; uint8_t m_a9_port_ab_ddr; uint8_t m_a9_port_c_ddr; uint8_t m_a9_port_d_ddr; @@ -126,7 +130,6 @@ private: uint8_t m_a9_serial_control; uint8_t m_a9_channel_select; - devcb_write8 m_configure_ram_cb; devcb_write_line m_buz_cb; devcb_write8 m_col_cb; devcb_read16 m_port_ab_r; @@ -149,7 +152,18 @@ private: }; +// ======================> psion_asic9mx_device + +class psion_asic9mx_device : public psion_asic9_device +{ +public: + // construction/destruction + psion_asic9mx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + // device type definition DECLARE_DEVICE_TYPE(PSION_ASIC9, psion_asic9_device) +DECLARE_DEVICE_TYPE(PSION_ASIC9MX, psion_asic9mx_device) #endif // MAME_MACHINE_PSION_ASIC9_H diff --git a/src/devices/machine/psion_ssd.cpp b/src/devices/machine/psion_ssd.cpp new file mode 100644 index 00000000000..ef1d0268b5b --- /dev/null +++ b/src/devices/machine/psion_ssd.cpp @@ -0,0 +1,256 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/**************************************************************************** + + Psion Solid State Disk emulation + + + Memory Type No. devices Memory Size + D7 D6 D5 D4 D3 D2 D1 D0 + 0 0 0 RAM 0 0 1 device 0 0 0 No memory + 0 0 1 Type 1 Flash 0 1 2 devices 0 0 1 32K + 0 1 0 Type 2 Flash 1 0 3 devices 0 1 0 64K + 0 1 1 Type 3 Flash 1 1 4 devices 0 1 1 128K + 1 0 0 Type 4 Flash 1 0 0 256K + 1 0 1 Type 5 Flash 1 0 1 512K + 1 1 0 Read only SSD (ROM) 1 1 0 1M + 1 1 1 Hardware Write protected SSD 1 1 1 2M + + Info Byte (* = confirmed) + Psion Solid State Disk 64K Flash 001 01 001 0x29 + Psion Solid State Disk 128K Flash * 001 00 011 0x23 + - MC200 System Disk * 111 00 011 0xE3 + - MC400 System Disk * 111 00 011 0xE3 + Psion Solid State Disk 256K Flash * 001 01 011 0x2B + - MC Word System Disk * 111 01 011 0xEB + Psion Solid State Disk 512K Flash 001 01 100 0x2C + Psion Solid State Disk 1MB Flash * 001 11 100 0x3C + Psion Solid State Disk 2MB Flash * 001 11 101 0x3D + Psion Solid State Disk 4MB Flash 001 11 110 0x3E + Psion Solid State Disk 8MB Flash * 001 11 111 0x3F + + Psion Solid State Disk 64K RAM 000 01 001 0x09 + Psion Solid State Disk 128K RAM 000 11 001 0x19 + Psion Solid State Disk 512K RAM 000 11 011 0x1B + Psion Solid State Disk 1MB RAM 000 11 100 0x1C + Psion Solid State Disk 2MB RAM 000 11 101 0x1D + +****************************************************************************/ + +#include "emu.h" +#include "psion_ssd.h" + +#include "softlist_dev.h" + + +DEFINE_DEVICE_TYPE(PSION_SSD, psion_ssd_device, "psion_ssd", "Psion Solid State Disk") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void psion_ssd_device::device_add_mconfig(machine_config &config) +{ + PSION_ASIC5(config, m_asic5, DERIVED_CLOCK(1, 1)).set_mode(psion_asic5_device::PACK_MODE); + m_asic5->readpa_handler().set([this]() { return m_ssd_data[latched_addr()]; }); + m_asic5->writepa_handler().set([this](uint8_t data) { m_ssd_data[latched_addr()] = data; }); + m_asic5->writepb_handler().set([this](uint8_t data) { m_port_latch = (m_port_latch & 0xffff00) | (data << 0); }); + m_asic5->writepd_handler().set([this](uint8_t data) { m_port_latch = (m_port_latch & 0xff00ff) | (data << 8); }); + m_asic5->writepc_handler().set([this](uint8_t data) { m_port_latch = (m_port_latch & 0x00ffff) | (data << 16); }); +} + + +//------------------------------------------------- +// psion_ssd_device - constructor +//------------------------------------------------- + +psion_ssd_device::psion_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PSION_SSD, tag, owner, clock) + , device_memcard_image_interface(mconfig, *this) + , m_region(*this, DEVICE_SELF) + , m_asic5(*this, "asic5") + , m_door_cb(*this) + , m_door_timer(nullptr) + , m_info_byte(0) + , m_port_latch(0) + , m_mem_width(0) +{ +} + + +//------------------------------------------------- +// psion_ssd_device - destructor +//------------------------------------------------- + +psion_ssd_device::~psion_ssd_device() +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void psion_ssd_device::device_resolve_objects() +{ + m_door_cb.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void psion_ssd_device::device_start() +{ + m_ssd_data = make_unique_clear(0x800000); + + // insert default System disk + if (m_region.found()) + { + uint32_t size = m_region->bytes(); + memcpy(&m_ssd_data[0], m_region->base(), size); + set_info_byte(size, SSD_FLASH1); + } + + m_door_timer = timer_alloc(FUNC(psion_ssd_device::close_door), this); + m_door_timer->reset(); + + save_pointer(NAME(m_ssd_data), 0x800000); + save_item(NAME(m_info_byte)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void psion_ssd_device::device_reset() +{ + m_port_latch = 0x00; + + // open the door + m_door_cb(ASSERT_LINE); + + // setup the timer to close the door + m_door_timer->adjust(attotime::from_msec(200)); +} + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void psion_ssd_device::device_config_complete() +{ + add_format("ssd", "Psion Solid State Disk image", "bin,rom", ""); +} + + +//------------------------------------------------- +// get_software_list_loader - +//------------------------------------------------- + +const software_list_loader &psion_ssd_device::get_software_list_loader() const +{ + return image_software_list_loader::instance(); +} + + +TIMER_CALLBACK_MEMBER(psion_ssd_device::close_door) +{ + // close the door + m_door_cb(CLEAR_LINE); +} + + +std::pair psion_ssd_device::call_load() +{ + device_image_interface *image = nullptr; + interface(image); + + uint32_t size = image->length(); + + if (size < 0x10000 || size > 0x800000 || (size & (size - 1)) != 0) + return std::make_pair(image_error::INVALIDLENGTH, "Invalid size, must be 64K, 128K, 256K, 512K, 1M, 2M, 4M, 8M"); + + image->fread(m_ssd_data.get(), size); + + // check for Flash header + if ((m_ssd_data[0] | (m_ssd_data[1] << 8)) == 0xf1a5) // Flash + set_info_byte(size, SSD_FLASH1); + else + set_info_byte(size, SSD_RAM); + + // open the door + m_door_cb(ASSERT_LINE); + + // setup the timer to close the door + m_door_timer->adjust(attotime::from_msec(200)); + + return std::make_pair(std::error_condition(), std::string()); +} + + +void psion_ssd_device::call_unload() +{ + memset(m_ssd_data.get(), 0, sizeof(m_ssd_data)); + set_info_byte(0); +} + + +uint32_t psion_ssd_device::latched_addr() +{ + return (m_port_latch & make_bitmask(m_mem_width)) | (BIT(m_port_latch, 22, 2) << m_mem_width); +} + + +void psion_ssd_device::set_info_byte(uint32_t size, uint8_t type) +{ + m_info_byte = 0x00; + + // Type 1 Flash or RAM + if (type != SSD_RAM) + m_info_byte |= 0x20; + + // No. devices and size + switch (size) + { + case 0x010000: m_info_byte |= 0x09; m_mem_width = 15; break; // 64K (2 x 32K) + case 0x020000: m_info_byte |= 0x03; m_mem_width = 17; break; // 128K (1 x 128K) + case 0x040000: m_info_byte |= 0x0b; m_mem_width = 17; break; // 256K (2 x 128K) + case 0x080000: m_info_byte |= 0x0c; m_mem_width = 18; break; // 512K (2 x 256K) + case 0x100000: m_info_byte |= 0x1c; m_mem_width = 18; break; // 1M (4 x 256K) + case 0x200000: m_info_byte |= 0x1d; m_mem_width = 19; break; // 2M (4 x 512K) + case 0x400000: m_info_byte |= 0x1e; m_mem_width = 20; break; // 4M (4 x 1M) + case 0x800000: m_info_byte |= 0x1f; m_mem_width = 21; break; // 8M (4 x 2M) + } + + // write protected + m_info_byte |= 0xe0; + + // set pull-ups on ASIC5 + m_asic5->set_info_byte(m_info_byte); +} + + +uint8_t psion_ssd_device::data_r() +{ + if (m_info_byte & 7) + { + return m_asic5->data_r(); + } + return 0x00; +} + +void psion_ssd_device::data_w(uint16_t data) +{ + if (m_info_byte & 7) + { + m_asic5->data_w(data); + } +} diff --git a/src/devices/machine/psion_ssd.h b/src/devices/machine/psion_ssd.h new file mode 100644 index 00000000000..b80bbb7f392 --- /dev/null +++ b/src/devices/machine/psion_ssd.h @@ -0,0 +1,82 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/**************************************************************************** + + Psion Solid State Disk emulation + +****************************************************************************/ + +#ifndef MAME_MACHINE_PSION_SSD_H +#define MAME_MACHINE_PSION_SSD_H + +#include "machine/psion_asic5.h" +#include "imagedev/memcard.h" + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +// ======================> psion_ssd_device + +class psion_ssd_device : public device_t, public device_memcard_image_interface +{ +public: + // construction/destruction + psion_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~psion_ssd_device(); + + // callbacks + auto door_cb() { return m_door_cb.bind(); } + + uint8_t data_r(); + void data_w(uint16_t data); + +protected: + // device_t implementation + virtual void device_resolve_objects() override; + virtual void device_config_complete() override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + // device_image_interface implementation + virtual std::pair call_load() override; + virtual void call_unload() override; + + virtual bool is_reset_on_load() const noexcept override { return false; } + virtual const char *image_interface() const noexcept override { return "psion_ssd"; } + virtual const char *file_extensions() const noexcept override { return "rom,bin"; } + virtual const char *image_type_name() const noexcept override { return "ssd"; } + virtual const char *image_brief_type_name() const noexcept override { return "ssd"; } + + // device_image_interface implementation + virtual const software_list_loader &get_software_list_loader() const override; + +private: + optional_memory_region m_region; + required_device m_asic5; + + TIMER_CALLBACK_MEMBER(close_door); + + devcb_write_line m_door_cb; + emu_timer *m_door_timer; + + std::unique_ptr m_ssd_data; + + void set_info_byte(uint32_t size, uint8_t type = 0); + uint32_t latched_addr(); + + uint8_t m_info_byte; + uint32_t m_port_latch; + int m_mem_width; + + static constexpr uint8_t SSD_RAM = 0; + static constexpr uint8_t SSD_FLASH1 = 1; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(PSION_SSD, psion_ssd_device) + +#endif // MAME_MACHINE_PSION_SSD_H diff --git a/src/mame/psion/psion3a.cpp b/src/mame/psion/psion3a.cpp index f0d92278dd1..70ec2edc9e8 100644 --- a/src/mame/psion/psion3a.cpp +++ b/src/mame/psion/psion3a.cpp @@ -14,10 +14,11 @@ #include "emu.h" #include "machine/psion_asic9.h" +#include "machine/psion_ssd.h" #include "machine/ram.h" #include "sound/spkrdev.h" -//#include "bus/psion/exp/slot.h" -#include "psion_ssd.h" +#include "bus/psion/honda/slot.h" +#include "bus/psion/sibo/slot.h" #include "emupal.h" #include "screen.h" @@ -39,14 +40,18 @@ public: , m_keyboard(*this, "COL%u", 0U) , m_speaker(*this, "speaker") , m_ssd(*this, "ssd%u", 1U) - //, m_exp(*this, "exp") + , m_sibo(*this, "sibo") + , m_honda(*this, "honda") { } + void psion_asic9(machine_config &config); void psion3a(machine_config &config); void psion3a2(machine_config &config); void psion3c(machine_config &config); void psion3mx(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(wakeup); + protected: virtual void machine_start() override; virtual void machine_reset() override; @@ -58,7 +63,8 @@ private: required_ioport_array<8> m_keyboard; required_device m_speaker; required_device_array m_ssd; - //required_device m_exp; + optional_device m_sibo; + optional_device m_honda; void palette_init(palette_device &palette); @@ -87,9 +93,9 @@ static INPUT_PORTS_START( psion3a ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME(UTF8_DOWN" Pg Dn") PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("Psion") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Sheet") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Data") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Sheet") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Data") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_START("COL1") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -100,9 +106,9 @@ static INPUT_PORTS_START( psion3a ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR('*') PORT_CHAR(':') PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Shift (L)") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("Agenda") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("System") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("Agenda") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("System") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_START("COL2") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) PORT_NAME("Delete") @@ -114,8 +120,8 @@ static INPUT_PORTS_START( psion3a ) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Control") PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Word") + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Word") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_START("COL3") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -135,7 +141,7 @@ static INPUT_PORTS_START( psion3a ) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_NAME("Caps") + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_NAME("\xe2\x97\x86 Caps") PORT_START("COL5") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -164,7 +170,7 @@ static INPUT_PORTS_START( psion3a ) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME(UTF8_UP" Pg Up") PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc On") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc On") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) INPUT_PORTS_END @@ -176,23 +182,23 @@ static INPUT_PORTS_START( psion3a_de ) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('z') PORT_CHAR('Z') PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME(UTF8_LEFT" Pos1") PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME(UTF8_DOWN" Bild Dn") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Tabelle") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Uhr") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Daten") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Tabelle") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Uhr") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Daten") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_MODIFY("COL1") PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR(0xdf) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('+') PORT_CHAR('<') PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=') PORT_CHAR('}') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR('*') PORT_CHAR('>') - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Rechner") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Rechner") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_MODIFY("COL2") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) PORT_NAME("Entf") PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') PORT_CHAR('[') PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') PORT_CHAR(']') PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Strg") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("Welt") + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("Welt") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_MODIFY("COL3") PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') @@ -214,7 +220,7 @@ static INPUT_PORTS_START( psion3a_de ) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') PORT_CHAR(0xba) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME(UTF8_UP" Bild Up") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc Ein") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc Ein") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) INPUT_PORTS_END @@ -222,7 +228,7 @@ static INPUT_PORTS_START( psion3c ) PORT_INCLUDE(psion3a) PORT_MODIFY("COL2") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_NAME("Jotter") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_NAME("Jotter") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) INPUT_PORTS_END @@ -230,7 +236,7 @@ INPUT_PORTS_END // PORT_INCLUDE(psion3a_de) // // PORT_MODIFY("COL2") -// PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_NAME("Notiz") +// PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_NAME("Notiz") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) //INPUT_PORTS_END @@ -239,21 +245,27 @@ static INPUT_PORTS_START( pocketbk2 ) PORT_MODIFY("COL0") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("Acorn") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Abacus") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Cards") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Abacus") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Cards") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_MODIFY("COL1") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("Schedule") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("Desktop") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("Schedule") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("Desktop") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) PORT_MODIFY("COL2") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") - PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Write") + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) + PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Write") PORT_CHANGED_MEMBER(DEVICE_SELF, psion3a_state, wakeup, 0) INPUT_PORTS_END +INPUT_CHANGED_MEMBER(psion3a_state::wakeup) +{ + m_asic9->eint0_w(newval); +} + + uint16_t psion3a_state::kbd_r() { uint16_t data = 0x00; @@ -276,7 +288,7 @@ void psion3a_state::palette_init(palette_device &palette) } -void psion3a_state::psion3a(machine_config &config) +void psion3a_state::psion_asic9(machine_config &config) { PSION_ASIC9(config, m_asic9, 7.68_MHz_XTAL); // V30H m_asic9->set_ram_rom("ram", "rom"); @@ -284,12 +296,10 @@ void psion3a_state::psion3a(machine_config &config) m_asic9->buz_cb().set(m_speaker, FUNC(speaker_sound_device::level_w)); //m_asic9->buzvol_cb().set([this](int state) { m_speaker->set_output_gain(ALL_OUTPUTS, state ? 1.0 : 0.25); }); m_asic9->col_cb().set([this](uint8_t data) { m_key_col = data; }); - m_asic9->data_r<0>().set(m_ssd[0], FUNC(psion_ssd_device::data_r)); // SSD Pack 1 - m_asic9->data_w<0>().set(m_ssd[0], FUNC(psion_ssd_device::data_w)); - m_asic9->data_r<1>().set(m_ssd[1], FUNC(psion_ssd_device::data_r)); // SSD Pack 2 - m_asic9->data_w<1>().set(m_ssd[1], FUNC(psion_ssd_device::data_w)); - //m_asic9->data_r<4>().set(m_exp, FUNC(psion_exp_slot_device::data_r)); // Expansion port - //m_asic9->data_w<4>().set(m_exp, FUNC(psion_exp_slot_device::data_w)); + m_asic9->data_r<0>().set(m_ssd[1], FUNC(psion_ssd_device::data_r)); // SSD Pack 2 + m_asic9->data_w<0>().set(m_ssd[1], FUNC(psion_ssd_device::data_w)); + m_asic9->data_r<1>().set(m_ssd[0], FUNC(psion_ssd_device::data_r)); // SSD Pack 1 + m_asic9->data_w<1>().set(m_ssd[0], FUNC(psion_ssd_device::data_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); screen.set_size(480, 160); @@ -299,23 +309,34 @@ void psion3a_state::psion3a(machine_config &config) screen.set_palette(m_palette); PALETTE(config, "palette", FUNC(psion3a_state::palette_init), 3); - // TODO: M7542 - SPEAKER(config, "mono").front_center(); SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 1.00); // Piezo buzzer - RAM(config, m_ram).set_default_size("512K").set_extra_options("256K"); + RAM(config, m_ram); PSION_SSD(config, m_ssd[0]); m_ssd[0]->door_cb().set(m_asic9, FUNC(psion_asic9_device::medchng_w)); PSION_SSD(config, m_ssd[1]); m_ssd[1]->door_cb().set(m_asic9, FUNC(psion_asic9_device::medchng_w)); - //PSION_EXP_SLOT(config, m_exp, psion_exp_devices, nullptr); - SOFTWARE_LIST(config, "ssd_list").set_original("psion_ssd").set_filter("S3,S3A"); } +void psion3a_state::psion3a(machine_config &config) +{ + psion_asic9(config); + + m_ram->set_default_size("512K").set_extra_options("256K"); + + // SIBO expansion port + PSION_SIBO_SLOT(config, m_sibo, psion_sibo_devices, nullptr); + //m_sibo->int_cb().set(m_asic9, FUNC(psion_asic9_device::eint_w)); // TODO: unknown interrupt line + m_asic9->data_r<4>().set(m_sibo, FUNC(psion_sibo_slot_device::data_r)); + m_asic9->data_w<4>().set(m_sibo, FUNC(psion_sibo_slot_device::data_w)); + + // TODO: M7542 +} + void psion3a_state::psion3a2(machine_config &config) { psion3a(config); @@ -325,18 +346,24 @@ void psion3a_state::psion3a2(machine_config &config) void psion3a_state::psion3c(machine_config &config) { - psion3a(config); + psion_asic9(config); m_ram->set_default_size("2M").set_extra_options("1M"); // TODO: M7702 - // TODO: add Honda port + // TODO: unknown Temic device, likely provides RS232/Parallel to Honda port + + // Honda expansion port + PSION_HONDA_SLOT(config, m_honda, psion_honda_devices, nullptr); + //m_honda->int_cb().set(m_asic9, FUNC(psion_asic9_device::eint_w)); // TODO: unknown interrupt line + m_asic9->data_r<4>().set(m_honda, FUNC(psion_honda_slot_device::data_r)); + m_asic9->data_w<4>().set(m_honda, FUNC(psion_honda_slot_device::data_w)); } void psion3a_state::psion3mx(machine_config &config) { - psion3a(config); + psion_asic9(config); m_asic9->set_clock(3.6864_MHz_XTAL * 15 / 2); // V30MX @@ -344,7 +371,11 @@ void psion3a_state::psion3mx(machine_config &config) // TODO: M7702 - // TODO: add Honda port + // Honda expansion port + PSION_HONDA_SLOT(config, m_honda, psion_honda_devices, nullptr); + //m_honda->int_cb().set(m_asic9, FUNC(psion_asic9_device::eint_w)); // TODO: unknown interrupt line + m_asic9->data_r<4>().set(m_honda, FUNC(psion_honda_slot_device::data_r)); + m_asic9->data_w<4>().set(m_honda, FUNC(psion_honda_slot_device::data_w)); } @@ -363,10 +394,11 @@ ROM_END ROM_START(psion3a2_de) ROM_REGION16_LE(0x200000, "rom", 0) ROM_SYSTEM_BIOS(0, "341f", "V3.41F/DEU") - ROMX_LOAD("s3a_v3.41f_eng.bin", 0x000000, 0x200000, CRC(1f21cb0a) SHA1(fbb9c3356cf8b1d89b8cf50fc12175568c74ce3e), ROM_BIOS(0)) + ROMX_LOAD("s3a_v3.41f_deu.bin", 0x000000, 0x200000, CRC(1f21cb0a) SHA1(fbb9c3356cf8b1d89b8cf50fc12175568c74ce3e), ROM_BIOS(0)) ROM_END ROM_START(psion3c) + // Versions advertised: English, German, French, Flemish and Dutch ROM_REGION16_LE(0x200000, "rom", 0) ROM_SYSTEM_BIOS(0, "520f", "V5.20F/ENG") ROMX_LOAD("oak_v5.20f_eng.bin", 0x000000, 0x200000, CRC(d8e672ca) SHA1(23e7570ddbecbfd50953ce6a6b7ead7128814402), ROM_BIOS(0)) @@ -392,5 +424,6 @@ COMP( 1993, psion3a, 0, 0, psion3a, psion3a, psion3a_stat COMP( 1994, pocketbk2, psion3a, 0, psion3a, pocketbk2, psion3a_state, empty_init, "Acorn Computers", "Pocket Book II", MACHINE_NOT_WORKING ) COMP( 1995, psion3a2, psion3a, 0, psion3a2, psion3a, psion3a_state, empty_init, "Psion", "Series 3a (2M)", MACHINE_NOT_WORKING ) COMP( 1995, psion3a2_de, psion3a, 0, psion3a2, psion3a_de, psion3a_state, empty_init, "Psion", "Series 3a (2M) (German)", MACHINE_NOT_WORKING ) +//COMP( 1996, psion3a2_ru, psion3a, 0, psion3a2, psion3a, psion3a_state, empty_init, "Psion", "Series 3a (2M) (Russian)", MACHINE_NOT_WORKING ) COMP( 1996, psion3c, 0, 0, psion3c, psion3c, psion3a_state, empty_init, "Psion", "Series 3c", MACHINE_NOT_WORKING ) COMP( 1998, psion3mx, 0, 0, psion3mx, psion3c, psion3a_state, empty_init, "Psion", "Series 3mx", MACHINE_NOT_WORKING ) diff --git a/src/mame/psion/psion_ssd.cpp b/src/mame/psion/psion_ssd.cpp deleted file mode 100644 index ce7a265488b..00000000000 --- a/src/mame/psion/psion_ssd.cpp +++ /dev/null @@ -1,281 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nigel Barnes -/**************************************************************************** - - Psion Solid State Disk emulation - - - Memory Type No. devices Memory Size - D7 D6 D5 D4 D3 D2 D1 D0 - 0 0 0 RAM 0 0 1 device 0 0 0 No memory - 0 0 1 Type 1 Flash 0 1 2 devices 0 0 1 32K - 0 1 0 Type 2 Flash 1 0 3 devices 0 1 0 64K - 0 1 1 Type 3 Flash 1 1 4 devices 0 1 1 128K - 1 0 0 Type 4 Flash 1 0 0 256K - 1 0 1 Type 5 Flash 1 0 1 512K - 1 1 0 Read only SSD (ROM) 1 1 0 1M - 1 1 1 Hardware Write protected SSD 1 1 1 2M - - Info Byte (* = confirmed) - Psion Solid State Disk 64K Flash 001 01 001 0x29 - Psion Solid State Disk 128K Flash * 001 00 011 0x23 - - MC200 System Disk * 111 00 011 0xE3 - - MC400 System Disk * 111 00 011 0xE3 - Psion Solid State Disk 256K Flash * 001 01 011 0x2B - - MC Word System Disk * 111 01 011 0xEB - Psion Solid State Disk 512K Flash 001 01 100 0x2C - Psion Solid State Disk 1MB Flash * 001 11 100 0x3C - Psion Solid State Disk 2MB Flash * 001 11 101 0x3D - Psion Solid State Disk 4MB Flash 001 11 110 0x3E - Psion Solid State Disk 8MB Flash * 001 11 111 0x3F - - Psion Solid State Disk 64K RAM 000 01 001 0x09 - Psion Solid State Disk 128K RAM 000 11 001 0x19 - Psion Solid State Disk 512K RAM 000 11 011 0x1B - Psion Solid State Disk 1MB RAM 000 11 100 0x1C - Psion Solid State Disk 2MB RAM 000 11 101 0x1D - -****************************************************************************/ - -#include "emu.h" -#include "psion_ssd.h" - -#include "softlist_dev.h" - - -DEFINE_DEVICE_TYPE(PSION_SSD, psion_ssd_device, "psion_ssd", "Psion Solid State Disk") - - -//------------------------------------------------- -// device_add_mconfig - add device configuration -//------------------------------------------------- - -void psion_ssd_device::device_add_mconfig(machine_config &config) -{ - PSION_ASIC5_PACK(config, m_asic5); - m_asic5->readpa_handler().set([this]() { return m_ssd_data[latched_addr()]; }); - m_asic5->writepa_handler().set([this](uint8_t data) { m_ssd_data[latched_addr()] = data; }); - m_asic5->writepb_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0xffff00) | (data << 0); }); - m_asic5->writepd_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0xff00ff) | (data << 8); }); - m_asic5->writepc_handler().set([this](uint8_t data) { m_addr_latch = (m_addr_latch & 0x00ffff) | (data << 16); }); -} - - -//------------------------------------------------- -// psion_ssd_device - constructor -//------------------------------------------------- - -psion_ssd_device::psion_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, PSION_SSD, tag, owner, clock) - , device_memcard_image_interface(mconfig, *this) - , m_region(*this, DEVICE_SELF) - , m_asic5(*this, "asic5") - , m_door_cb(*this) - , m_door_timer(nullptr) - , m_info_byte(0) - , m_addr_latch(0) - , m_mem_width(0) -{ -} - - -//------------------------------------------------- -// psion_ssd_device - destructor -//------------------------------------------------- - -psion_ssd_device::~psion_ssd_device() -{ -} - - -//------------------------------------------------- -// device_resolve_objects - resolve objects that -// may be needed for other devices to set -// initial conditions at start time -//------------------------------------------------- - -void psion_ssd_device::device_resolve_objects() -{ - m_door_cb.resolve_safe(); -} - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void psion_ssd_device::device_start() -{ - m_ssd_data = make_unique_clear(0x800000); - - // insert default System disk - if (m_region.found()) - { - uint32_t size = m_region->bytes(); - memcpy(&m_ssd_data[0], m_region->base(), size); - set_info_byte(size, SSD_FLASH1); - } - - m_door_timer = timer_alloc(FUNC(psion_ssd_device::close_door), this); - m_door_timer->reset(); - - save_pointer(NAME(m_ssd_data), 0x800000); - save_item(NAME(m_info_byte)); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void psion_ssd_device::device_reset() -{ - m_addr_latch = 0x00; - - // open the door - m_door_cb(ASSERT_LINE); - - // setup the timer to close the door - m_door_timer->adjust(attotime::from_msec(200)); -} - - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void psion_ssd_device::device_config_complete() -{ - add_format("ssd", "Psion Solid State Disk image", "bin,rom", ""); -} - - -//------------------------------------------------- -// get_software_list_loader - -//------------------------------------------------- - -const software_list_loader &psion_ssd_device::get_software_list_loader() const -{ - return image_software_list_loader::instance(); -} - - - -TIMER_CALLBACK_MEMBER(psion_ssd_device::close_door) -{ - // close the door - m_door_cb(CLEAR_LINE); -} - - -std::pair psion_ssd_device::call_load() -{ - device_image_interface *image = nullptr; - interface(image); - - uint32_t size = image->length(); - - if (size < 0x10000 || size > 0x800000 || (size & (size - 1)) != 0) - return std::make_pair(image_error::INVALIDLENGTH, "Invalid size, must be 64K, 128K, 256K, 512K, 1M, 2M, 4M, 8M"); - - image->fread(m_ssd_data.get(), size); - - // check for Flash header - if ((m_ssd_data[0] | (m_ssd_data[1] << 8)) == 0xf1a5) // Flash - set_info_byte(size, SSD_FLASH1); - else - set_info_byte(size, SSD_RAM); - - // open the door - m_door_cb(ASSERT_LINE); - - // setup the timer to close the door - m_door_timer->adjust(attotime::from_msec(200)); - - return std::make_pair(std::error_condition(), std::string()); -} - - -void psion_ssd_device::call_unload() -{ - memset(m_ssd_data.get(), 0, sizeof(m_ssd_data)); - set_info_byte(0); -} - - -uint32_t psion_ssd_device::latched_addr() -{ - return (m_addr_latch & make_bitmask(m_mem_width)) | (BIT(m_addr_latch, 22, 2) << m_mem_width); -} - - -void psion_ssd_device::set_info_byte(uint32_t size, uint8_t type) -{ - m_info_byte = 0x00; - - // Type 1 Flash or RAM - if (type != SSD_RAM) - m_info_byte |= 0x20; - - // No. devices and size - switch (size) - { - case 0x010000: // 64K (2 x 32K) - m_info_byte = 0x09; - m_mem_width = 15; - break; - case 0x020000: // 128K (1 x 128K) - m_info_byte = 0x03; - m_mem_width = 17; - break; - case 0x040000: // 256K (2 x 128K) - m_info_byte = 0x0b; - m_mem_width = 17; - break; - case 0x080000: // 512K (2 x 256K) - m_info_byte = 0x0c; - m_mem_width = 18; - break; - case 0x100000: // 1M (4 x 256K) - m_info_byte = 0x1c; - m_mem_width = 18; - break; - case 0x200000: // 2M (4 x 512K) - m_info_byte = 0x1d; - m_mem_width = 19; - break; - case 0x400000:// 4M (4 x 1M) - m_info_byte = 0x1e; - m_mem_width = 20; - break; - case 0x800000:// 8M (4 x 2M) - m_info_byte = 0x1f; - m_mem_width = 21; - break; - } - - // write protected - m_info_byte |= 0xe0; - - // set pull-ups on ASIC5 - m_asic5->set_info_byte(m_info_byte); -} - - -uint8_t psion_ssd_device::data_r() -{ - if (m_info_byte) - { - return m_asic5->data_r(); - } - return 0x00; -} - -void psion_ssd_device::data_w(uint16_t data) -{ - if (m_info_byte) - { - m_asic5->data_w(data); - } -} diff --git a/src/mame/psion/psion_ssd.h b/src/mame/psion/psion_ssd.h deleted file mode 100644 index 0bd724e70e6..00000000000 --- a/src/mame/psion/psion_ssd.h +++ /dev/null @@ -1,84 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nigel Barnes -/**************************************************************************** - - Psion Solid State Disk emulation - -****************************************************************************/ - -#ifndef MAME_PSION_PSION_SSD_H -#define MAME_PSION_PSION_SSD_H - -#include "machine/psion_asic5.h" -#include "imagedev/memcard.h" - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -// ======================> psion_ssd_device - -class psion_ssd_device : public device_t, public device_memcard_image_interface -{ -public: - // construction/destruction - psion_ssd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - virtual ~psion_ssd_device(); - - // callbacks - auto door_cb() { return m_door_cb.bind(); } - - uint8_t data_r(); - void data_w(uint16_t data); - -protected: - // device_t implementation - virtual void device_resolve_objects() override; - virtual void device_config_complete() override; - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_add_mconfig(machine_config &config) override; - - // device_image_interface implementation - virtual std::pair call_load() override; - virtual void call_unload() override; - - virtual bool is_reset_on_load() const noexcept override { return false; } - virtual const char *image_interface() const noexcept override { return "psion_ssd"; } - virtual const char *file_extensions() const noexcept override { return "rom,bin"; } - virtual const char *image_type_name() const noexcept override { return "ssd"; } - virtual const char *image_brief_type_name() const noexcept override { return "ssd"; } - - // device_image_interface implementation - virtual const software_list_loader &get_software_list_loader() const override; - -private: - optional_memory_region m_region; - required_device m_asic5; - - inline uint32_t mem_addr() const noexcept { return (m_addr_latch & make_bitmask(m_mem_width)) | (BIT(m_addr_latch, 22, 2) << m_mem_width); } - - TIMER_CALLBACK_MEMBER(close_door); - - devcb_write_line m_door_cb; - emu_timer *m_door_timer; - - std::unique_ptr m_ssd_data; - - void set_info_byte(uint32_t size, uint8_t type = 0); - uint32_t latched_addr(); - - uint8_t m_info_byte; - uint32_t m_addr_latch; - int m_mem_width; - - static constexpr uint8_t SSD_RAM = 0; - static constexpr uint8_t SSD_FLASH1 = 1; -}; - - -// device type definition -DECLARE_DEVICE_TYPE(PSION_SSD, psion_ssd_device) - -#endif // MAME_PSION_PSION_SSD_H diff --git a/src/mame/psion/siena.cpp b/src/mame/psion/siena.cpp index c8631fd43cb..b4b471cac7b 100644 --- a/src/mame/psion/siena.cpp +++ b/src/mame/psion/siena.cpp @@ -13,6 +13,7 @@ #include "machine/psion_asic9.h" #include "machine/ram.h" #include "sound/spkrdev.h" +#include "bus/psion/honda/slot.h" #include "emupal.h" #include "screen.h" @@ -33,10 +34,13 @@ public: , m_palette(*this, "palette") , m_keyboard(*this, "COL%u", 0U) , m_speaker(*this, "speaker") + , m_honda(*this, "honda") { } void siena(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(wakeup); + protected: virtual void machine_start() override; virtual void machine_reset() override; @@ -47,6 +51,7 @@ private: required_device m_palette; required_ioport_array<8> m_keyboard; required_device m_speaker; + required_device m_honda; void palette_init(palette_device &palette); @@ -75,7 +80,7 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2') PORT_NAME("2 MR") PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_NAME("1 Min") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("On/CE") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_NAME("On/CE") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNKNOWN) PORT_START("COL1") @@ -87,8 +92,8 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR('(') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("Fn") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("IR Send") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Word") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("IR Send") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("Word") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_START("COL2") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0xa3) @@ -111,8 +116,8 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_NAME("= %") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Shift (L)") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Off") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_NAME("Time") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_START("COL4") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR('%') @@ -124,7 +129,7 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') PORT_NAME("+ M+") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Shift (R)") PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_NAME("World") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_START("COL5") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR('^') @@ -134,21 +139,21 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) PORT_NAME("Del") PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_NAME(u8"×") - PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNKNOWN) - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Sheet") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_NAME("Off") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_NAME("Sheet") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_NAME("Calc") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_START("COL6") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR('!') PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR('\\') PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') - PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_NAME("Caps") + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_NAME("\xe2\x97\x86 Caps") PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(']') PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR('*') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR('/') PORT_NAME(u8"÷") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-') PORT_NAME("- M-") - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc") - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Data") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("Esc") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("Data") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) PORT_START("COL7") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) PORT_NAME("Tab") @@ -160,10 +165,16 @@ static INPUT_PORTS_START( siena ) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR('.') PORT_NAME(". +/-") PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Control") PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("System") + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("System") PORT_CHANGED_MEMBER(DEVICE_SELF, siena_state, wakeup, 0) INPUT_PORTS_END +INPUT_CHANGED_MEMBER(siena_state::wakeup) +{ + m_asic9->eint0_w(newval); +} + + uint16_t siena_state::kbd_r() { uint16_t data = 0x00; @@ -207,9 +218,15 @@ void siena_state::siena(machine_config &config) RAM(config, m_ram).set_default_size("512K").set_extra_options("1M"); - // TODO: add Honda port + // TODO: unknown Temic device, likely provides RS232/Parallel to Honda port + + // Honda expansion port + PSION_HONDA_SLOT(config, m_honda, psion_honda_devices, "ssd"); + m_honda->int_cb().set(m_asic9, FUNC(psion_asic9_device::medchng_w)); // TODO: verify interrupt line + m_asic9->data_r<4>().set(m_honda, FUNC(psion_honda_slot_device::data_r)); + m_asic9->data_w<4>().set(m_honda, FUNC(psion_honda_slot_device::data_w)); - SOFTWARE_LIST(config, "ssd_list").set_original("psion_ssd").set_filter("WA"); + SOFTWARE_LIST(config, "ssd_list").set_original("psion_ssd").set_filter("SIENA"); } diff --git a/src/mame/psion/workabout.cpp b/src/mame/psion/workabout.cpp index 685697e7d36..be4ad26c49b 100644 --- a/src/mame/psion/workabout.cpp +++ b/src/mame/psion/workabout.cpp @@ -11,10 +11,10 @@ #include "emu.h" #include "machine/psion_asic9.h" +#include "machine/psion_ssd.h" #include "machine/ram.h" #include "sound/spkrdev.h" //#include "bus/psion/exp/slot.h" -#include "psion_ssd.h" #include "emupal.h" #include "screen.h" @@ -43,6 +43,8 @@ public: void psionwa(machine_config &config); void psionwamx(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(wakeup); + protected: virtual void machine_start() override; virtual void machine_reset() override; @@ -83,7 +85,7 @@ static INPUT_PORTS_START( workabout ) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PORT_CHAR('}') PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME(UTF8_DOWN) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("On/Esc") + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_NAME("On/Esc") PORT_CHANGED_MEMBER(DEVICE_SELF, workabout_state, wakeup, 0) PORT_START("COL1") PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') @@ -141,7 +143,7 @@ static INPUT_PORTS_START( workabout ) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(';') PORT_CHAR('<') PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CHAR('~') - PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_NAME("Off") PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Contrast") PORT_BIT(0x180, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -157,6 +159,12 @@ static INPUT_PORTS_START( workabout ) INPUT_PORTS_END +INPUT_CHANGED_MEMBER(workabout_state::wakeup) +{ + m_asic9->eint0_w(newval); +} + + uint16_t workabout_state::kbd_r() { uint16_t data = 0x00; @@ -186,10 +194,10 @@ void workabout_state::workabout(machine_config &config) m_asic9->port_ab_r().set(FUNC(workabout_state::kbd_r)); m_asic9->buz_cb().set(m_speaker, FUNC(speaker_sound_device::level_w)); m_asic9->col_cb().set([this](uint8_t data) { m_key_col = data; }); - m_asic9->data_r<0>().set(m_ssd[0], FUNC(psion_ssd_device::data_r)); // SSD Pack 1 - m_asic9->data_w<0>().set(m_ssd[0], FUNC(psion_ssd_device::data_w)); - m_asic9->data_r<1>().set(m_ssd[1], FUNC(psion_ssd_device::data_r)); // SSD Pack 2 - m_asic9->data_w<1>().set(m_ssd[1], FUNC(psion_ssd_device::data_w)); + m_asic9->data_r<0>().set(m_ssd[1], FUNC(psion_ssd_device::data_r)); // SSD Pack 1 + m_asic9->data_w<0>().set(m_ssd[1], FUNC(psion_ssd_device::data_w)); + m_asic9->data_r<1>().set(m_ssd[0], FUNC(psion_ssd_device::data_r)); // SSD Pack 2 + m_asic9->data_w<1>().set(m_ssd[0], FUNC(psion_ssd_device::data_w)); //m_asic9->data_r<2>().set(m_exp[0], FUNC(psion_exp_slot_device::data_r)); // Expansion port A //m_asic9->data_w<2>().set(m_exp[0], FUNC(psion_exp_slot_device::data_w)); //m_asic9->data_r<3>().set(m_exp[1], FUNC(psion_exp_slot_device::data_r)); // Expansion port B -- cgit v1.2.3