summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/ti99/internal/gromport.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/ti99/internal/gromport.h')
-rw-r--r--src/devices/bus/ti99/internal/gromport.h468
1 files changed, 468 insertions, 0 deletions
diff --git a/src/devices/bus/ti99/internal/gromport.h b/src/devices/bus/ti99/internal/gromport.h
new file mode 100644
index 00000000000..87985ce08fa
--- /dev/null
+++ b/src/devices/bus/ti99/internal/gromport.h
@@ -0,0 +1,468 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/***************************************************************************
+ Gromport (Cartridge port) of the TI-99 consoles
+ For details see gromport.cpp
+
+ Michael Zapf
+***************************************************************************/
+
+#ifndef MAME_BUS_TI99_INTERNAL_GROMPORT_H
+#define MAME_BUS_TI99_INTERNAL_GROMPORT_H
+
+#pragma once
+
+#include "bus/ti99/ti99defs.h"
+#include "machine/tmc0430.h"
+#include "softlist_dev.h"
+
+namespace bus { namespace ti99 { namespace internal {
+
+class cartridge_connector_device;
+
+class gromport_device : public bus8z_device, public device_slot_interface
+{
+public:
+ gromport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz);
+ DECLARE_WRITE8_MEMBER(cruwrite);
+ DECLARE_WRITE_LINE_MEMBER(ready_line);
+
+ DECLARE_WRITE_LINE_MEMBER(romgq_line);
+
+ // Combined GROM select lines
+ DECLARE_WRITE8_MEMBER(set_gromlines);
+
+ DECLARE_WRITE_LINE_MEMBER(gclock_in);
+
+ static void set_mask(device_t &device, int mask) { downcast<gromport_device &>(device).m_mask = mask; }
+
+ template <class Object> static devcb_base &static_set_ready_callback(device_t &device, Object &&cb) { return downcast<gromport_device &>(device).m_console_ready.set_callback(std::forward<Object>(cb)); }
+ template <class Object> static devcb_base &static_set_reset_callback(device_t &device, Object &&cb) { return downcast<gromport_device &>(device).m_console_reset.set_callback(std::forward<Object>(cb)); }
+
+ void cartridge_inserted();
+ bool is_grom_idle();
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_config_complete() override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ cartridge_connector_device* m_connector;
+ bool m_reset_on_insert;
+ devcb_write_line m_console_ready;
+ devcb_write_line m_console_reset;
+ int m_mask;
+ int m_romgq;
+};
+
+/****************************************************************************/
+
+class ti99_cartridge_pcb;
+
+class ti99_cartridge_device : public bus8z_device, public device_image_interface
+{
+public:
+ ti99_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz);
+ DECLARE_WRITE8_MEMBER(cruwrite);
+
+ DECLARE_WRITE_LINE_MEMBER(ready_line);
+ DECLARE_WRITE_LINE_MEMBER(romgq_line);
+ DECLARE_WRITE8_MEMBER(set_gromlines);
+
+ DECLARE_WRITE_LINE_MEMBER(gclock_in);
+
+ bool is_available() { return m_pcb != nullptr; }
+ void set_slot(int i);
+ bool is_grom_idle();
+
+protected:
+ virtual void device_start() override { }
+ virtual void device_config_complete() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const tiny_rom_entry* device_rom_region() const override;
+
+ // Image handling: implementation of methods which are abstract in the parent
+ image_init_result call_load() override;
+ void call_unload() override;
+ virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
+
+ void prepare_cartridge();
+
+ // device_image_interface
+ iodevice_t image_type() const override { return IO_CARTSLOT; }
+ bool is_readable() const override { return true; }
+ bool is_writeable() const override { return false; }
+ bool is_creatable() const override { return false; }
+ bool must_be_loaded() const override { return false; }
+ bool is_reset_on_load() const override { return false; }
+ const char *image_interface() const override { return "ti99_cart"; }
+ const char *file_extensions() const override { return "rpk"; }
+
+private:
+ class rpk_socket;
+ class rpk_reader;
+ class rpk;
+
+ bool m_readrom;
+ int m_pcbtype;
+ int m_slot;
+ int get_index_from_tagname();
+
+ std::unique_ptr<ti99_cartridge_pcb> m_pcb; // inbound
+ cartridge_connector_device* m_connector; // outbound
+
+ // RPK which is associated to this cartridge
+ // When we close it, the contents are saved to NVRAM if available
+ rpk *m_rpk;
+};
+
+/****************************************************************************/
+
+class cartridge_connector_device : public bus8z_device
+{
+public:
+ virtual DECLARE_READ8Z_MEMBER(crureadz) = 0;
+ virtual DECLARE_WRITE8_MEMBER(cruwrite) = 0;
+
+ virtual DECLARE_WRITE_LINE_MEMBER(romgq_line) = 0;
+ virtual DECLARE_WRITE8_MEMBER(set_gromlines) = 0;
+
+ virtual DECLARE_WRITE_LINE_MEMBER(gclock_in) = 0;
+
+ DECLARE_WRITE_LINE_MEMBER(ready_line);
+
+ virtual void insert(int index, ti99_cartridge_device* cart) { m_gromport->cartridge_inserted(); }
+ virtual void remove(int index) { }
+ virtual bool is_grom_idle() = 0;
+
+protected:
+ cartridge_connector_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ virtual void device_config_complete() override;
+
+ gromport_device* m_gromport;
+ bool m_grom_selected;
+};
+
+/*
+ Single cartridge connector.
+*/
+class ti99_single_cart_conn_device : public cartridge_connector_device
+{
+public:
+ ti99_single_cart_conn_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz) override;
+ DECLARE_WRITE8_MEMBER(cruwrite) override;
+ DECLARE_WRITE_LINE_MEMBER(romgq_line) override;
+ DECLARE_WRITE8_MEMBER(set_gromlines) override;
+ DECLARE_WRITE_LINE_MEMBER(gclock_in) override;
+
+ bool is_grom_idle() override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+private:
+ ti99_cartridge_device *m_cartridge;
+};
+
+/*
+ Multi cartridge connector.
+*/
+
+/* We set the number of slots to 4, although we may have up to 16. From a
+ logical point of view we could have 256, but the operating system only checks
+ the first 16 banks. */
+
+class ti99_multi_cart_conn_device : public cartridge_connector_device
+{
+public:
+ ti99_multi_cart_conn_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz) override;
+ DECLARE_WRITE8_MEMBER(cruwrite) override;
+ DECLARE_WRITE_LINE_MEMBER(romgq_line) override;
+ DECLARE_WRITE8_MEMBER(set_gromlines) override;
+ DECLARE_WRITE_LINE_MEMBER(gclock_in) override;
+
+ void insert(int index, ti99_cartridge_device* cart) override;
+ void remove(int index) override;
+ DECLARE_INPUT_CHANGED_MEMBER( switch_changed );
+
+ bool is_grom_idle() override;
+
+protected:
+ static constexpr unsigned NUMBER_OF_CARTRIDGE_SLOTS = 4;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ bool m_readrom;
+ int m_active_slot;
+ int m_fixed_slot;
+ int m_next_free_slot;
+ ti99_cartridge_device* m_cartridge[NUMBER_OF_CARTRIDGE_SLOTS];
+
+ void set_slot(int slotnumber);
+ int get_active_slot(bool changebase, offs_t offset);
+};
+
+/*
+ GRAM Kracker.
+*/
+class ti99_gkracker_device : public cartridge_connector_device, public device_nvram_interface
+{
+public:
+ ti99_gkracker_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz) override;
+ DECLARE_WRITE8_MEMBER(cruwrite) override;
+ DECLARE_WRITE_LINE_MEMBER(romgq_line) override;
+ DECLARE_WRITE8_MEMBER(set_gromlines) override;
+ DECLARE_WRITE_LINE_MEMBER(gclock_in) override;
+
+ void insert(int index, ti99_cartridge_device* cart) override;
+ void remove(int index) override;
+ DECLARE_INPUT_CHANGED_MEMBER( gk_changed );
+
+ // We may have a cartridge plugged into the GK
+ bool is_grom_idle() override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const tiny_rom_entry* device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ // device_nvram_interface
+ void nvram_default() override;
+ void nvram_read(emu_file &file) override;
+ void nvram_write(emu_file &file) override;
+
+private:
+ int m_gk_switch[6]; // Used to cache the switch settings.
+
+ bool m_romspace_selected;
+ int m_ram_page;
+ int m_grom_address;
+ uint8_t* m_ram_ptr;
+ uint8_t* m_grom_ptr;
+
+ bool m_waddr_LSB;
+
+ ti99_cartridge_device *m_cartridge; // guest cartridge
+
+ // Just for proper initialization
+ void gk_install_menu(const char* menutext, int len, int ptr, int next, int start);
+};
+
+/****************************************************************************/
+
+class ti99_cartridge_pcb
+{
+ friend class ti99_cartridge_device;
+public:
+ ti99_cartridge_pcb();
+ virtual ~ti99_cartridge_pcb() { }
+
+protected:
+ virtual DECLARE_READ8Z_MEMBER(readz);
+ virtual DECLARE_WRITE8_MEMBER(write);
+ virtual DECLARE_READ8Z_MEMBER(crureadz);
+ virtual DECLARE_WRITE8_MEMBER(cruwrite);
+
+ DECLARE_WRITE_LINE_MEMBER(romgq_line);
+ virtual DECLARE_WRITE8_MEMBER(set_gromlines);
+ DECLARE_WRITE_LINE_MEMBER(gclock_in);
+
+ DECLARE_READ8Z_MEMBER(gromreadz);
+ DECLARE_WRITE8_MEMBER(gromwrite);
+ inline void set_grom_pointer(int number, device_t *dev);
+ void set_cartridge(ti99_cartridge_device *cart);
+ const char* tag() { return m_tag; }
+ void set_tag(const char* tag) { m_tag = tag; }
+ bool is_grom_idle() { return m_grom_idle; }
+
+ ti99_cartridge_device* m_cart;
+ tmc0430_device* m_grom[5];
+ bool m_grom_idle;
+ int m_grom_size;
+ int m_rom_size;
+ int m_ram_size;
+
+ uint8_t* m_rom_ptr;
+ uint8_t* m_ram_ptr;
+ bool m_romspace_selected;
+ int m_rom_page; // for some cartridge types
+ uint8_t* m_grom_ptr; // for gromemu
+ int m_grom_address; // for gromemu
+ int m_ram_page; // for super
+ const char* m_tag;
+ std::vector<uint8_t> m_nvram; // for MiniMemory
+ std::vector<uint8_t> m_ram; // for MBX
+};
+
+/******************** Standard cartridge ******************************/
+
+class ti99_standard_cartridge : public ti99_cartridge_pcb
+{
+public:
+};
+
+/*********** Paged cartridge (like Extended Basic) ********************/
+
+class ti99_paged12k_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/*********** Paged cartridge (others) ********************/
+
+class ti99_paged16k_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/********************** Mini Memory ***********************************/
+
+class ti99_minimem_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/********************* Super Space II *********************************/
+
+class ti99_super_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz) override;
+ DECLARE_WRITE8_MEMBER(cruwrite) override;
+};
+
+/************************* MBX ***************************************/
+
+class ti99_mbx_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/********************** Paged 379i ************************************/
+
+class ti99_paged379i_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+private:
+ int get_paged379i_bank(int rompage);
+};
+
+/********************** Paged 378 ************************************/
+
+class ti99_paged378_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/********************** Paged 377 ************************************/
+
+class ti99_paged377_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+};
+
+/********************** Paged CRU ************************************/
+
+class ti99_pagedcru_cartridge : public ti99_cartridge_pcb
+{
+public:
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(crureadz) override;
+ DECLARE_WRITE8_MEMBER(cruwrite) override;
+};
+
+/********************** GROM emulation cartridge ************************************/
+
+class ti99_gromemu_cartridge : public ti99_cartridge_pcb
+{
+public:
+ ti99_gromemu_cartridge(): m_waddr_LSB(false), m_grom_selected(false), m_grom_read_mode(false), m_grom_address_mode(false)
+ { m_grom_address = 0; }
+ DECLARE_READ8Z_MEMBER(readz) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+ DECLARE_READ8Z_MEMBER(gromemureadz);
+ DECLARE_WRITE8_MEMBER(gromemuwrite);
+ DECLARE_WRITE8_MEMBER(set_gromlines) override;
+
+private:
+ bool m_waddr_LSB;
+ bool m_grom_selected;
+ bool m_grom_read_mode;
+ bool m_grom_address_mode;
+};
+
+} } } // end namespace bus::ti99::internal
+
+SLOT_INTERFACE_EXTERN(gromport4);
+SLOT_INTERFACE_EXTERN(gromport8);
+
+#define MCFG_GROMPORT4_ADD( _tag ) \
+ MCFG_DEVICE_ADD(_tag, TI99_GROMPORT, 0) \
+ bus::ti99::internal::gromport_device::set_mask(*device, 0x1fff); \
+ MCFG_DEVICE_SLOT_INTERFACE(gromport4, "single", false)
+
+#define MCFG_GROMPORT8_ADD( _tag ) \
+ MCFG_DEVICE_ADD(_tag, TI99_GROMPORT, 0) \
+ bus::ti99::internal::gromport_device::set_mask(*device, 0x3fff); \
+ MCFG_DEVICE_SLOT_INTERFACE(gromport8, "single", false)
+
+#define MCFG_GROMPORT_READY_HANDLER( _ready ) \
+ devcb = &bus::ti99::internal::gromport_device::static_set_ready_callback( *device, DEVCB_##_ready );
+
+#define MCFG_GROMPORT_RESET_HANDLER( _reset ) \
+ devcb = &bus::ti99::internal::gromport_device::static_set_reset_callback( *device, DEVCB_##_reset );
+
+DECLARE_DEVICE_TYPE_NS(TI99_GROMPORT, bus::ti99::internal, gromport_device)
+DECLARE_DEVICE_TYPE_NS(TI99_CART, bus::ti99::internal, ti99_cartridge_device)
+DECLARE_DEVICE_TYPE_NS(TI99_GROMPORT_SINGLE, bus::ti99::internal, ti99_single_cart_conn_device)
+DECLARE_DEVICE_TYPE_NS(TI99_GROMPORT_MULTI, bus::ti99::internal, ti99_multi_cart_conn_device)
+DECLARE_DEVICE_TYPE_NS(TI99_GROMPORT_GK, bus::ti99::internal, ti99_gkracker_device)
+
+#endif // MAME_BUS_TI99_INTERNAL_GROMPORT_H