From dc910919596886814033f28ae7a898408b999245 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Sun, 21 Jun 2020 15:17:25 +0200 Subject: ti99_2: Emulate the expansion port and a 32K expansion module. --- src/devices/bus/ti99/internal/992board.cpp | 86 +++++++++++++++++++++++++++++- src/devices/bus/ti99/internal/992board.h | 77 ++++++++++++++++++++++++++ src/mame/drivers/ti99_2.cpp | 20 ++++--- 3 files changed, 176 insertions(+), 7 deletions(-) diff --git a/src/devices/bus/ti99/internal/992board.cpp b/src/devices/bus/ti99/internal/992board.cpp index 20b96f84186..031f82d7fe5 100644 --- a/src/devices/bus/ti99/internal/992board.cpp +++ b/src/devices/bus/ti99/internal/992board.cpp @@ -7,7 +7,12 @@ This component implements the custom video controller and interface chip from the TI-99/2 console. + Also, we emulate the expansion port at the backside of the console; there + are no known expansions except for a RAM expansion that is mentioned + in the specifications. + May 2018 + June 2020 ***************************************************************************/ @@ -20,8 +25,9 @@ #define LOG_HEXBUS (1U<<4) // Hexbus logging #define LOG_BANK (1U<<5) // Change ROM banks #define LOG_KEYBOARD (1U<<6) // Keyboard operation +#define LOG_EXPRAM (1U<<7) // Expansion RAM -#define VERBOSE ( LOG_WARN ) +#define VERBOSE ( LOG_GENERAL | LOG_WARN ) #include "logmacro.h" @@ -128,6 +134,8 @@ DEFINE_DEVICE_TYPE_NS(VIDEO99232, bus::ti99::internal, video992_32_device, "vide DEFINE_DEVICE_TYPE_NS(IO99224, bus::ti99::internal, io992_24_device, "io992_24", "TI-99/2 I/O controller 24K version") DEFINE_DEVICE_TYPE_NS(IO99232, bus::ti99::internal, io992_32_device, "io992_32", "TI-99/2 I/O controller 32K version") +DEFINE_DEVICE_TYPE_NS(TI992_EXPPORT, bus::ti99::internal, ti992_expport_device, "ti992_expport", "TI-99/2 Expansion Port") +DEFINE_DEVICE_TYPE_NS(TI992_RAM32K, bus::ti99::internal, ti992_expram_device, "ti992_ram32k", "TI-99/2 RAM Expansion 32K") namespace bus { namespace ti99 { namespace internal { @@ -596,6 +604,82 @@ ioport_constructor io992_device::device_input_ports() const return INPUT_PORTS_NAME( keys992 ); } +/******************************************************************** + Expansion port +********************************************************************/ + +ti992_expport_device::ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TI992_EXPPORT, tag, owner, clock), + device_slot_interface(mconfig, *this), + m_connected(nullptr) +{ +} + +void ti992_expport_device::readz(offs_t offset, uint8_t *value) +{ + if (m_connected != nullptr) + m_connected->readz(offset, value); +} + +void ti992_expport_device::write(offs_t offset, uint8_t data) +{ + if (m_connected != nullptr) + m_connected->write(offset, data); +} + +void ti992_expport_device::device_config_complete() +{ + m_connected = static_cast(subdevices().first()); +} + +/* + 32K Expansion cartridge + Maps at 6000 - DFFF + This is the only known expansion device +*/ +ti992_expram_device::ti992_expram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + ti992_expport_attached_device(mconfig, TI992_RAM32K, tag, owner, clock), + m_ram(*this, "ram32k") +{ +} + +void ti992_expram_device::readz(offs_t offset, uint8_t *value) +{ + // 000 -> 100 100 -> 000 + // 001 -> 101 101 -> 001 + // 010 -> 110 110 -> 010 + // 011 -> 011 111 -> 111 + offs_t address = offset; + if ((offset & 0x6000) != 0x6000) address ^= 0x8000; + if ((address & 0x8000)==0) + { + *value = m_ram->read(address); + LOGMASKED(LOG_EXPRAM, "expram %04x -> %02x\n", offset, *value); + } +} + +void ti992_expram_device::write(offs_t offset, uint8_t value) +{ + offs_t address = offset; + if ((offset & 0x6000) != 0x6000) address ^= 0x8000; + if ((address & 0x8000)==0) + { + m_ram->write(address, value); + LOGMASKED(LOG_EXPRAM, "expram %04x <- %02x\n", offset, value); + } +} + +void ti992_expram_device::device_add_mconfig(machine_config &config) +{ + RAM(config, m_ram, 0); + m_ram->set_default_size("32k"); + m_ram->set_default_value(0); +} + } } } +void ti992_expport_options(device_slot_interface &device) +{ + device.option_add("ram32k", TI992_RAM32K); +} diff --git a/src/devices/bus/ti99/internal/992board.h b/src/devices/bus/ti99/internal/992board.h index 75849ce2aea..83f42035839 100644 --- a/src/devices/bus/ti99/internal/992board.h +++ b/src/devices/bus/ti99/internal/992board.h @@ -21,6 +21,7 @@ #include "screen.h" #include "bus/hexbus/hexbus.h" #include "imagedev/cassette.h" +#include "machine/ram.h" #define TI992_CASSETTE "cassette" #define TI992_VDC_TAG "vdc" @@ -149,11 +150,87 @@ public: io992_32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +/******************************************************************** + + Expansion port + This is modeled after the ioport connector of the TI-99/4A + + However, since there are basically no expansion cards available, + and only the memory expansion was described in the specs, we + only include the necessary connections. + +********************************************************************/ +#define TI992_EXPPORT_TAG "expport" + +class ti992_expport_attached_device : public device_t +{ +public: + ti992_expport_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock) + { } + + // Methods called from the console + virtual void readz(offs_t offset, uint8_t *value) { } + virtual void write(offs_t offset, uint8_t data) { } +}; + +class ti992_expport_device : public device_t, public device_slot_interface +{ + friend class expport_attached_device; + +public: + template + ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, U &&opts, const char *dflt) + : ti992_expport_device(mconfig, tag, owner, clock) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + } + + ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // Methods called from the console + // More methods should be added, once we can find further 99/2 cartridges + void readz(offs_t offset, uint8_t *value); + void write(offs_t offset, uint8_t data); + +protected: + void device_start() override { }; + void device_config_complete() override; + +private: + ti992_expport_attached_device* m_connected; +}; + +// RAM expansion + +class ti992_expram_device : public ti992_expport_attached_device +{ +public: + ti992_expram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void readz(offs_t offset, uint8_t *value) override; + void write(offs_t offset, uint8_t data) override; + +private: + void device_start() override {}; + void device_add_mconfig(machine_config &config) override; + required_device m_ram; +}; + + } } } // end namespace bus::ti99::internal +DECLARE_DEVICE_TYPE_NS(TI992_EXPPORT, bus::ti99::internal, ti992_expport_device) + +void ti992_expport_options(device_slot_interface &device); + DECLARE_DEVICE_TYPE_NS(VIDEO99224, bus::ti99::internal, video992_24_device) DECLARE_DEVICE_TYPE_NS(VIDEO99232, bus::ti99::internal, video992_32_device) DECLARE_DEVICE_TYPE_NS(IO99224, bus::ti99::internal, io992_24_device) DECLARE_DEVICE_TYPE_NS(IO99232, bus::ti99::internal, io992_32_device) +DECLARE_DEVICE_TYPE_NS(TI992_RAM32K, bus::ti99::internal, ti992_expram_device) + #endif // MAME_BUS_TI99_INTERNAL_992BOARD_H diff --git a/src/mame/drivers/ti99_2.cpp b/src/mame/drivers/ti99_2.cpp index faf077a3dba..4bd2a136bf4 100644 --- a/src/mame/drivers/ti99_2.cpp +++ b/src/mame/drivers/ti99_2.cpp @@ -193,6 +193,7 @@ public: m_io992(*this, TI992_IO_TAG), m_cassette(*this, TI992_CASSETTE), m_ram(*this, TI992_RAM_TAG), + m_expport(*this, TI992_EXPPORT_TAG), m_otherbank(false), m_rom(nullptr), m_ram_start(0xf000), @@ -230,6 +231,8 @@ private: required_device m_cassette; required_device m_ram; + required_device m_expport; + bool m_otherbank; uint8_t* m_rom; @@ -322,6 +325,7 @@ void ti99_2_state::intflag_write(offs_t offset, uint8_t data) */ uint8_t ti99_2_state::mem_read(offs_t offset) { + uint8_t value = 0; if (m_maincpu->is_onchip(offset)) return m_maincpu->debug_read_onchip_memory(offset&0xff); int page = offset >> 12; @@ -329,22 +333,23 @@ uint8_t ti99_2_state::mem_read(offs_t offset) if (page>=0 && page<4) { // ROM, unbanked - return m_rom[offset]; + value = m_rom[offset]; } if (page>=4 && page<6) { // ROM, banked on 32K version if (m_otherbank) offset = (offset & 0x1fff) | 0x10000; - return m_rom[offset]; + value = m_rom[offset]; } if ((page >= m_first_ram_page) && (page < 15)) { - return m_ram->pointer()[offset - m_ram_start]; + value = m_ram->pointer()[offset - m_ram_start]; } - LOGMASKED(LOG_WARN, "Unmapped read access at %04x\n", offset); - return 0; + m_expport->readz(offset, &value); + + return value; } void ti99_2_state::mem_write(offs_t offset, uint8_t data) @@ -370,7 +375,7 @@ void ti99_2_state::mem_write(offs_t offset, uint8_t data) return; } - LOGMASKED(LOG_WARN, "Unmapped write access at %04x\n", offset); + m_expport->write(offset, data); } /* @@ -470,6 +475,9 @@ void ti99_2_state::ti99_2(machine_config& config) // Hexbus HEXBUS(config, TI992_HEXBUS_TAG, 0, hexbus_options, nullptr); + + // Expansion port (backside) + TI992_EXPPORT(config, m_expport, 0, ti992_expport_options, nullptr); } /* -- cgit v1.2.3