diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index bd9c56f4718..e70daaaef9a 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4188,6 +4188,8 @@ if (BUSES["TI99"]~=null) then MAME_DIR .. "src/devices/bus/ti99/peb/tn_ide.h", MAME_DIR .. "src/devices/bus/ti99/peb/tn_usbsm.cpp", MAME_DIR .. "src/devices/bus/ti99/peb/tn_usbsm.h", + MAME_DIR .. "src/devices/bus/ti99/sidecar/arcturus.cpp", + MAME_DIR .. "src/devices/bus/ti99/sidecar/arcturus.h", } end diff --git a/src/devices/bus/ti99/internal/ioport.cpp b/src/devices/bus/ti99/internal/ioport.cpp index 3dccc08ed0e..5ca4f680e0a 100644 --- a/src/devices/bus/ti99/internal/ioport.cpp +++ b/src/devices/bus/ti99/internal/ioport.cpp @@ -80,6 +80,7 @@ #include "ioport.h" #include "splitter.h" #include "bus/ti99/peb/peribox.h" +#include "bus/ti99/sidecar/arcturus.h" DEFINE_DEVICE_TYPE(TI99_IOPORT, bus::ti99::internal::ioport_device, "ti99_ioport", "TI-99 I/O Port") @@ -176,12 +177,14 @@ void ti99_ioport_options_plain(device_slot_interface &device) { device.option_add("peb", TI99_PERIBOX); device.option_add("splitter", TI99_IOSPLIT); + device.option_add("arcturus", TI99_ARCTURUS); } void ti99_ioport_options_evpc(device_slot_interface &device) { device.option_add("peb", TI99_PERIBOX_EV); device.option_add("splitter", TI99_IOSPLIT); + device.option_add("arcturus", TI99_ARCTURUS); } // Used for the splitter (to avoid getting multiple EVPCs in the system) @@ -189,4 +192,5 @@ void ti99_ioport_options_evpc1(device_slot_interface &device) { device.option_add("peb", TI99_PERIBOX_EV1); device.option_add("splitter", TI99_IOSPLIT); + device.option_add("arcturus", TI99_ARCTURUS); } diff --git a/src/devices/bus/ti99/internal/splitter.cpp b/src/devices/bus/ti99/internal/splitter.cpp index b839d9793e3..404bd04d0c6 100644 --- a/src/devices/bus/ti99/internal/splitter.cpp +++ b/src/devices/bus/ti99/internal/splitter.cpp @@ -6,7 +6,7 @@ The I/O port splitter connects to the TI-99/4(A) console at its I/O port and provides two I/O ports. That way, two Peripheral Expansion boxes or one PEB and a sidecar chain may be connected. - + | Port 2 v +---+ @@ -16,9 +16,9 @@ | oooooooooo | |----------+ | oooooooooo | | +----------------- - + The splitter was designed 2015 by Jim Fetzner (as Tekumel Software) - + March 2025, Michael Zapf *****************************************************************************/ @@ -33,7 +33,7 @@ #define LOG_INT (1U << 3) #define LOG_READY (1U << 4) -#define VERBOSE (LOG_CONFIG | LOG_WARN) +// #define VERBOSE (LOG_CONFIG | LOG_WARN) #include "logmacro.h" @@ -139,7 +139,7 @@ void ioport_splitter_device::reset_in(int state) m_port2->reset_in(state); } -template +template void ioport_splitter_device::extint(int state) { LOGMASKED(LOG_INT, "propagating INTA from port %d to console: %d\n", port, state); @@ -147,11 +147,11 @@ void ioport_splitter_device::extint(int state) m_inta_flag |= port; // 1 or 2 else m_inta_flag &= ~port; // 1 or 2 - + set_extint((m_inta_flag != 0)? ASSERT_LINE : CLEAR_LINE); } -template +template void ioport_splitter_device::ready(int state) { LOGMASKED(LOG_READY, "Incoming READY=%d from port %d\n", state, port); @@ -180,7 +180,7 @@ void ioport_splitter_device::device_add_mconfig(machine_config &config) { TI99_IOPORT(config, m_port1, 1, ti99_ioport_options_evpc1, nullptr); TI99_IOPORT(config, m_port2, 2, ti99_ioport_options_evpc1, nullptr); - + m_port1->extint_cb().set(FUNC(ioport_splitter_device::extint<1>)); m_port2->extint_cb().set(FUNC(ioport_splitter_device::extint<2>)); m_port1->ready_cb().set(FUNC(ioport_splitter_device::ready<1>)); diff --git a/src/devices/bus/ti99/internal/splitter.h b/src/devices/bus/ti99/internal/splitter.h index 350b4f2666d..c12fac3648f 100644 --- a/src/devices/bus/ti99/internal/splitter.h +++ b/src/devices/bus/ti99/internal/splitter.h @@ -1,9 +1,9 @@ // license:LGPL-2.1+ // copyright-holders:Michael Zapf /**************************************************************************** - - I/O port splitter - + + I/O port splitter + This plugs into the I/O port of the console as an ioport_attached_device, and it offers two new I/O ports. @@ -14,7 +14,7 @@ #pragma once -#include "ioport.h" +#include "ioport.h" namespace bus::ti99::internal { @@ -49,10 +49,10 @@ protected: // Callbacks from the two ports template void extint(int state); template void ready(int state); - + int m_inta_flag; int m_ready_flag; - + private: required_device m_port1; required_device m_port2; @@ -62,4 +62,4 @@ private: DECLARE_DEVICE_TYPE_NS(TI99_IOSPLIT, bus::ti99::internal, ioport_splitter_device) -#endif /* __TI99SPLITTER__ */ +#endif /* MAME_BUS_TI99_INTERNAL_SPLITTER_H */ diff --git a/src/devices/bus/ti99/sidecar/arcturus.cpp b/src/devices/bus/ti99/sidecar/arcturus.cpp new file mode 100644 index 00000000000..1afe6f3591e --- /dev/null +++ b/src/devices/bus/ti99/sidecar/arcturus.cpp @@ -0,0 +1,93 @@ +// license:LGPL-2.1+ +// copyright-holders:Michael Zapf +/**************************************************************************** + + Arcturus sidecar cartridge + Michael Zapf + +*****************************************************************************/ + +#include "emu.h" +#include "arcturus.h" + +#define LOG_WARN (1U << 1) // Warnings + +// #define VERBOSE (LOG_GENERAL | LOG_WARN) + +#include "logmacro.h" + +#define TI99_CARTSC_4000 "mem4000" +#define TI99_CARTSC_A000 "mema000" +#define TI99_CARTSC_C000 "memc000" +#define TI99_CARTSC_RAM "ram" + +DEFINE_DEVICE_TYPE(TI99_ARCTURUS, bus::ti99::sidecar::arcturus_device, "arcturus", "Arcturus sidecar cartridge") + +namespace bus::ti99::sidecar { + +/* + Constructor called from subclasses. +*/ +arcturus_device::arcturus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bus::ti99::internal::ioport_attached_device(mconfig, TI99_ARCTURUS, tag, owner, clock), + m_ram(*this, TI99_CARTSC_RAM) +{ +} + +void arcturus_device::readz(offs_t offset, uint8_t *value) +{ + switch ((offset >> 13)&0x07) + { + case 0: + case 3: + case 4: + case 7: + break; + case 1: + *value = m_ram->pointer()[offset & 0x07ff]; + break; + case 2: + *value = m_rom4[offset & 0x1fff]; + break; + case 5: + *value = m_roma[offset & 0x1fff]; + break; + case 6: + *value = m_romc[offset & 0x1fff]; + break; + } +} + +void arcturus_device::write(offs_t offset, uint8_t data) +{ + if (((offset >> 13)&0x07)==1) + m_ram->pointer()[offset & 0x07ff] = data; +} + +void arcturus_device::device_start() +{ + m_rom4 = memregion(TI99_CARTSC_4000)->base(); + m_roma = memregion(TI99_CARTSC_A000)->base(); + m_romc = memregion(TI99_CARTSC_C000)->base(); +} + +ROM_START( ti99_arcturus ) + ROM_REGION(0x2000, TI99_CARTSC_4000, 0) + ROM_LOAD("arcturus.u1", 0x0000, 0x2000, CRC(28ba65ec) SHA1(63329930c71ef776e8598a8d4c580c41bd52a339)) + ROM_REGION(0x2000, TI99_CARTSC_A000, 0) + ROM_LOAD("arcturus.u2", 0x0000, 0x2000, CRC(91e6910a) SHA1(51c1f75d4e9d74af21c0b43188fc0ffc4a3ad4c0)) + ROM_REGION(0x2000, TI99_CARTSC_C000, 0) + ROM_LOAD("arcturus.u3", 0x0000, 0x2000, CRC(e9ce9f4e) SHA1(65850c57e9480a5d8bdd852692f18d0162ca1406)) +ROM_END + +void arcturus_device::device_add_mconfig(machine_config& config) +{ + RAM(config, TI99_CARTSC_RAM).set_default_size("2K").set_default_value(0); +} + +const tiny_rom_entry *arcturus_device::device_rom_region() const +{ + return ROM_NAME( ti99_arcturus ); +} + +} // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/sidecar/arcturus.h b/src/devices/bus/ti99/sidecar/arcturus.h new file mode 100644 index 00000000000..45737f3513c --- /dev/null +++ b/src/devices/bus/ti99/sidecar/arcturus.h @@ -0,0 +1,49 @@ +// license:LGPL-2.1+ +// copyright-holders:Michael Zapf +/**************************************************************************** + + Arcturus sidecar cartridge + Michael Zapf + +*****************************************************************************/ + +#ifndef MAME_BUS_TI99_SIDECAR_ARCTURUS_H +#define MAME_BUS_TI99_SIDECAR_ARCTURUS_H + +#pragma once + +#include "bus/ti99/internal/ioport.h" +#include "machine/ram.h" + +namespace bus::ti99::sidecar { + +/***************************************************************************** + Arcturus sidecar cartridge +******************************************************************************/ + +class arcturus_device : public bus::ti99::internal::ioport_attached_device +{ +public: + arcturus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual void readz(offs_t offset, uint8_t *value) override; + virtual void write(offs_t offset, uint8_t data) override; + +protected: + virtual void device_start() override ATTR_COLD; + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + +private: + // ROMs + uint8_t* m_rom4; + uint8_t* m_roma; + uint8_t* m_romc; + + required_device m_ram; +}; + +} // end namespace bus::ti99::internal + +DECLARE_DEVICE_TYPE_NS(TI99_ARCTURUS, bus::ti99::sidecar, arcturus_device) + +#endif // MAME_BUS_TI99_SIDECAR_ARCTURUS_H