// license:BSD-3-Clause // copyright-holders:Patrick Mackinlay #ifndef MAME_MACHINE_ROSETTA_H #define MAME_MACHINE_ROSETTA_H #pragma once #include "cpu/romp/rsc.h" class rosetta_device : public device_t , public rsc_cpu_interface { public: // ram size in doublewords enum ram_size : unsigned { RAM_NONE = 0, RAM_1M = 0x0004'0000, RAM_2M = 0x0008'0000, RAM_4M = 0x0010'0000, RAM_8M = 0x0020'0000, RAM_16M = 0x0040'0000, }; rosetta_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, ram_size ram = RAM_NONE); template void set_mem(T &&tag, int spacenum) { m_mem_space.set_tag(std::forward(tag), spacenum); } template void set_rom(T &&tag) { m_rom.set_tag(std::forward(tag)); } auto out_pchk() { return m_out_pchk.bind(); } auto out_mchk() { return m_out_mchk.bind(); } using rsc_mode = rsc_bus_interface::rsc_mode; // rsc_cpu_interface overrides virtual bool fetch(u32 address, u16 &data, rsc_mode const mode) override; virtual bool ior(u32 address, u32 &data) override; virtual bool iow(u32 address, u32 data) override; // rsc_bus_interface overrides virtual bool load(u32 address, u8 &data, rsc_mode const mode, bool sp) override { return load(address, data, mode, sp); } virtual bool load(u32 address, u16 &data, rsc_mode const mode, bool sp) override { return load(address, data, mode, sp); } virtual bool load(u32 address, u32 &data, rsc_mode const mode, bool sp) override { return load(address, data, mode, sp); } virtual bool store(u32 address, u8 data, rsc_mode const mode, bool sp) override { return store(address, data, mode, sp); } virtual bool store(u32 address, u16 data, rsc_mode const mode, bool sp) override { return store(address, data, mode, sp); } virtual bool store(u32 address, u32 data, rsc_mode const mode, bool sp) override { return store(address, data, mode, sp); } virtual bool modify(u32 address, std::function f, rsc_mode const mode) override { return modify(address, f, mode); } virtual bool modify(u32 address, std::function f, rsc_mode const mode) override { return modify(address, f, mode); } virtual bool modify(u32 address, std::function f, rsc_mode const mode) override { return modify(address, f, mode); } protected: // device_t overrides virtual void device_validity_check(validity_checker &valid) const override; virtual void device_start() override; virtual void device_reset() override; virtual void device_post_load() override; // virtual address translation bool translate(u32 &address, bool system_processor, bool store); // rsc_bus_interface implementation template bool load(u32 address, T &data, rsc_mode const mode, bool sp); template bool store(u32 address, T data, rsc_mode const mode, bool sp); template bool modify(u32 address, std::function f, rsc_mode const mode); // register read handlers u32 segment_r(offs_t offset); u32 control_r(offs_t offset); u32 tlb_r(offs_t offset); // register write handlers void segment_w(offs_t offset, u32 data); void control_w(offs_t offset, u32 data); void tlb_w(offs_t offset, u32 data); // memory read handlers u32 rom_r(offs_t offset, u32 mem_mask); u32 ram_r(offs_t offset, u32 mem_mask); u32 rca_r(offs_t offset); // memory write handlers void rom_w(offs_t offset, u32 data, u32 mem_mask); void ram_w(offs_t offset, u32 data, u32 mem_mask); void rca_w(offs_t offset, u32 data); u8 compute_ecc(u32 const data) const; unsigned check_ecc(u32 &data, u8 const ecc) const; struct tlb_entry { u32 field0 = 0; // address tag u32 field1 = 0; // real page, valid, key u32 field2 = 0; // write, transaction identifier, lockbits }; tlb_entry tlb_search(u64 const virtual_address, bool const special); u32 tlb_reload(tlb_entry &tlb_entry, u64 const virtual_address, bool special = false); void tlb_inv_all(u32 data); void tlb_inv_segment(u32 data); void tlb_inv_address(u32 data); void compute_address(u32 data); void config_map(); void config_tlb(); enum mear_state : u32 { UNLOCKED, LOCKED, MEMORY, }; void set_mear(u32 const address, mear_state lock); void set_rmdr(u8 const ecc, bool lock); void set_pchk(bool state) { if (state != m_pchk_state) { m_pchk_state = state; // program check line is active low m_out_pchk(!m_pchk_state); } } void set_mchk(bool state) { // assume edge-triggered, active low if (state) { m_out_mchk(0); m_out_mchk(1); } else m_out_mchk(1); } private: required_address_space m_mem_space; required_region_ptr m_rom; output_finder<2> m_leds; devcb_write_line m_out_pchk; devcb_write_line m_out_mchk; memory_access<24, 2, 0, ENDIANNESS_BIG>::cache m_mem; // registers u32 m_segment[16]; u32 m_control[9]; // lock and line state mear_state m_mear_lock; bool m_rmdr_lock; bool m_led_lock; bool m_pchk_state; // tlb state tlb_entry m_tlb[16][2]; u16 m_tlb_lru; // storage std::unique_ptr m_ram; std::unique_ptr m_ecc; std::unique_ptr m_rca; // address translation constants u32 m_atag_mask; u32 m_page_mask; unsigned m_page_shift; u32 m_hat_base; u16 m_hat_mask; ram_size const m_ram_size; }; DECLARE_DEVICE_TYPE(ROSETTA, rosetta_device) #endif // MAME_MACHINE_ROSETTA_H