// license:MAME|LGPL-2.1+ // copyright-holders:Michael Zapf /**************************************************************************** TI-99/8 Address decoder and mapper See mapper8.c for documentation Michael Zapf February 2012: Rewritten as class *****************************************************************************/ #ifndef __MAPPER8__ #define __MAPPER8__ #include "emu.h" #include "ti99defs.h" extern const device_type MAINBOARD8; extern const device_type OSO; #define OSO_TAG "oso" #define NATIVE 0 #define TI99EM 1 #define PATGEN 2 #define PHYSIC 3 #define CONT 0 #define STOP 1 #define SRAMNAME "SRAM" #define ROM0NAME "ROM0" #define ROM1A0NAME "ROM1A" #define ROM1C0NAME "ROM1C" #define INTSNAME "INTS" #define DRAMNAME "DRAM" #define PCODENAME "PCODE" #define SRAM_SIZE 2048 #define DRAM_SIZE 65536 // We use these constants in the read/write functions. enum mapper8_device_kind { MAP8_UNDEF = 0, MAP8_SRAM, MAP8_ROM0, MAP8_ROM1A0, MAP8_ROM1C0, MAP8_DRAM, MAP8_PCODE, MAP8_INTS, MAP8_DEV // device by name }; struct mapper8_list_entry { const char* name; // Name of the device (used for looking up the device) int mode; // Mode of the system which applies to this entry int stop; // Mapper shall stop searching for a matching device when this entry applies UINT32 select_pattern; // State of the address line bits when addressing this device UINT32 address_mask; // Bits of the address bus used to address this device UINT32 write_select; // Additional bits set when doing write accesses to this device }; #define MAPPER8_CONFIG(name) \ const mapper8_config(name) = #define MCFG_MAINBOARD8_READY_CALLBACK(_write) \ devcb = &mainboard8_device::set_ready_wr_callback(*device, DEVCB2_##_write); struct mapper8_config { const mapper8_list_entry *devlist; }; /* Device list of the mapper. */ class logically_addressed_device { friend class simple_list; friend class mainboard8_device; public: logically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry) : m_kind(kind), m_device(busdevice), m_config(&entry) { }; private: logically_addressed_device *m_next; // needed for simple_list mapper8_device_kind m_kind; // named device or predefined device_t *m_device; // the actual device const mapper8_list_entry *m_config; }; /* Device list of the mapper. */ class physically_addressed_device { friend class simple_list; friend class mainboard8_device; public: physically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry) : m_kind(kind), m_device(busdevice), m_config(&entry) { }; private: physically_addressed_device *m_next; // needed for simple_list mapper8_device_kind m_kind; // named device or predefined device_t *m_device; // the actual device const mapper8_list_entry *m_config; }; /* Custom chip: OSO */ class ti998_oso_device : public device_t { public: ti998_oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); void device_start(); private: UINT8 m_data; UINT8 m_status; UINT8 m_control; UINT8 m_xmit; }; /* Main class */ class mainboard8_device : public bus8z_device { public: mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); template static devcb2_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast(device).m_ready.set_callback(object); } DECLARE_READ8_MEMBER( readm); // used from address map DECLARE_WRITE8_MEMBER( writem ); // used from address map DECLARE_READ8Z_MEMBER( readz ); DECLARE_WRITE8_MEMBER( write ); DECLARE_READ8Z_MEMBER(crureadz); DECLARE_WRITE8_MEMBER(cruwrite); void CRUS_set(bool state); void PTGE_set(bool state); void clock_in(int state); protected: void device_start(void); void device_reset(void); machine_config_constructor device_mconfig_additions() const; private: bool access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask ); bool access_logical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask ); void access_physical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask ); void access_physical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask ); void mapwrite(int offset, UINT8 data); // Ready line to the CPU devcb2_write_line m_ready; // All devices that are attached to the 16-bit address bus. simple_list m_logcomp; // All devices that are attached to the 24-bit mapped address bus. simple_list m_physcomp; // Select bit for the internal DSR. bool m_dsr_selected; // Select bit for the Hexbus DSR. bool m_hexbus_selected; // 99/4A compatibility mode. Name is taken from the spec. If 1, 99/4A compatibility is active. bool m_CRUS; // P-Code mode. Name is taken from the spec. If 0, P-Code libraries are available. // May be read as "Pascal and Text-to-speech GROM libraries Enable (Negative)" // Note: this is negative logic. GROMs are present only for PTGEN=0 // We use PTGE as the inverse signal. bool m_PTGE; // Counter for the wait states. int m_waitcount; // Address mapper registers. Each offset is selected by the first 4 bits // of the logical address. UINT32 m_pas_offset[16]; // SRAM area of the system. Directly connected to the address decoder. UINT8 *m_sram; // DRAM area of the system. Connected to the mapped address bus. UINT8 *m_dram; // ROM area of the system. Directly connected to the logical address decoder. UINT8 *m_rom0; // ROM area of the system. Directly connected to the physical address decoder. UINT8 *m_rom1; // P-Code ROM area of the system. Directly connected to the physical address decoder. UINT8 *m_pcode; // Custom chips required_device m_oso; }; #define MCFG_MAINBOARD8_ADD(_tag, _devices) \ MCFG_DEVICE_ADD(_tag, MAINBOARD8, 0) \ MCFG_DEVICE_CONFIG( _devices ) #endif