diff options
Diffstat (limited to 'src/mame/drivers/sun4.cpp')
-rw-r--r-- | src/mame/drivers/sun4.cpp | 1004 |
1 files changed, 187 insertions, 817 deletions
diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index 0c5fabe29c5..83c85edc821 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -519,17 +519,10 @@ const sparc_disassembler::asi_desc_map::value_type sun4c_asi_desc[] = { }; } -enum -{ - ARCH_SUN4 = 0, - ARCH_SUN4C, - ARCH_SUN4E -}; - -class sun4_state : public driver_device +class sun4_base_state : public driver_device { public: - sun4_state(const machine_config &mconfig, device_type type, const char *tag) + sun4_base_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_mmu(*this, "mmu") @@ -541,87 +534,26 @@ public: , m_lance(*this, LANCE_TAG) , m_scsibus(*this, "scsibus") , m_scsi(*this, "scsibus:7:ncr53c90a") - , m_sbus(*this, "sbus") - , m_sbus_slot(*this, "slot%u", 1U) - , m_type0space(*this, "type0") , m_type1space(*this, "type1") , m_ram(*this, RAM_TAG) , m_rom(*this, "user1") - , m_rom_ptr(nullptr) { } - void sun4c(machine_config &config); - void sun4_20(machine_config &config); - void sun4_40(machine_config &config); - void sun4_50(machine_config &config); - void sun4_60(machine_config &config); - void sun4_65(machine_config &config); - void sun4_75(machine_config &config); - void sun4(machine_config &config); - - void init_sun4(); - void init_sun4c(); + void sun4_base(machine_config &config); -private: +protected: virtual void machine_reset() override; virtual void machine_start() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; static const device_timer_id TIMER_0 = 0; static const device_timer_id TIMER_1 = 1; - static const device_timer_id TIMER_RESET = 2; - enum insn_data_mode - { - USER_INSN, - SUPER_INSN, - USER_DATA, - SUPER_DATA - }; + DECLARE_READ32_MEMBER( debugger_r ); + DECLARE_WRITE32_MEMBER( debugger_w ); - enum - { - // system enable constants - ENA_NOTBOOT = 0x80, - ENA_SDVMA = 0x20, - ENA_CACHE = 0x10, - ENA_RESET = 0x04, - ENA_DIAG = 0x01, - - // page table entry constants - PM_VALID = 0x80000000, // page is valid - PM_WRITEMASK = 0x40000000, // writable? - PM_SYSMASK = 0x20000000, // system use only? - PM_CACHE = 0x10000000, // cachable? - PM_TYPEMASK = 0x0c000000, // type mask - PM_ACCESSED = 0x02000000, // accessed flag - PM_MODIFIED = 0x01000000 // modified flag - }; - - DECLARE_READ32_MEMBER( sun4_cache_flush_r ); - DECLARE_WRITE32_MEMBER( sun4_cache_flush_w ); - DECLARE_READ32_MEMBER( sun4_system_r ); - DECLARE_WRITE32_MEMBER( sun4_system_w ); - DECLARE_READ32_MEMBER( sun4_segment_map_r ); - DECLARE_WRITE32_MEMBER( sun4_segment_map_w ); - DECLARE_READ32_MEMBER( sun4_page_map_r ); - DECLARE_WRITE32_MEMBER( sun4_page_map_w ); - template <insn_data_mode MODE> DECLARE_READ32_MEMBER( sun4_insn_data_r ); - DECLARE_WRITE32_MEMBER( sun4_insn_data_w ); - - DECLARE_READ32_MEMBER( sun4c_debugger_r ); - DECLARE_WRITE32_MEMBER( sun4c_debugger_w ); - - DECLARE_READ32_MEMBER( sun4_mmu_r ); - DECLARE_WRITE32_MEMBER( sun4_mmu_w ); - DECLARE_READ32_MEMBER( sun4c_mmu_r ); - DECLARE_WRITE32_MEMBER( sun4c_mmu_w ); - DECLARE_READ32_MEMBER( ram_r ); - DECLARE_WRITE32_MEMBER( ram_w ); - DECLARE_READ32_MEMBER( timeout_r ); - DECLARE_WRITE32_MEMBER( timeout_w ); - DECLARE_READ32_MEMBER( ss1_sl0_id ); + DECLARE_READ32_MEMBER( sl0_id ); DECLARE_READ32_MEMBER( timer_r ); DECLARE_WRITE32_MEMBER( timer_w ); DECLARE_READ8_MEMBER( irq_r ); @@ -632,7 +564,6 @@ private: DECLARE_WRITE8_MEMBER( auxio_w ); DECLARE_READ32_MEMBER( dma_r ); DECLARE_WRITE32_MEMBER( dma_w ); - DECLARE_WRITE32_MEMBER( buserr_w ); DECLARE_WRITE_LINE_MEMBER( scsi_irq ); DECLARE_WRITE_LINE_MEMBER( scsi_drq ); @@ -646,29 +577,12 @@ private: void ncr53c90a(device_t *device); - void sun4_system_map(address_map &map); - void sun4_segment_map(address_map &map); - void sun4_page_map(address_map &map); - void sun4_insn_map(address_map &map); - void sun4_supervisor_insn_map(address_map &map); - void sun4_data_map(address_map &map); - void sun4_supervisor_data_map(address_map &map); - - void sun4c_debugger_map(address_map &map); + void debugger_map(address_map &map); - void type0space_map(address_map &map); - void type1space_map(address_map &map); - void type1space_sbus_map(address_map &map); - void type1space_s4_map(address_map &map); - - enum sun4_arch - { - SUN4 = 0, - SUN4C = 1 - }; + void type1space_base_map(address_map &map); - required_device<mb86901_device> m_maincpu; - required_device<sun4c_mmu_device> m_mmu; + required_device<sparc_base_device> m_maincpu; + required_device<sun4_mmu_base_device> m_mmu; required_device<m48t02_device> m_timekpr; @@ -681,65 +595,11 @@ private: required_device<nscsi_bus_device> m_scsibus; required_device<ncr53c90a_device> m_scsi; - optional_device<sbus_device> m_sbus; - optional_device_array<sbus_slot_device, 3> m_sbus_slot; - optional_device<address_map_bank_device> m_type0space; - optional_device<address_map_bank_device> m_type1space; + required_device<address_map_bank_device> m_type1space; memory_access_cache<2, 0, ENDIANNESS_BIG> *m_type1_cache; required_device<ram_device> m_ram; required_memory_region m_rom; - struct page_entry_t - { - uint32_t valid; - uint32_t writable; - uint32_t supervisor; - uint32_t uncached; - uint32_t accessed; - uint32_t modified; - uint32_t page; - uint8_t type; - uint8_t pad[3]; - - uint32_t to_uint() - { - return valid | writable | supervisor | uncached | (type << 26) | accessed | modified | (page >> 11); - } - - void merge_uint(uint32_t data, uint32_t mem_mask) - { - const uint32_t new_value = (to_uint() & ~mem_mask) | (data & mem_mask); - valid = new_value & PM_VALID; - writable = new_value & PM_WRITEMASK; - supervisor = new_value & PM_SYSMASK; - uncached = new_value & PM_CACHE; - type = (new_value & PM_TYPEMASK) >> 26; - accessed = new_value & PM_ACCESSED; - modified = new_value & PM_MODIFIED; - page = (new_value & 0x7ffff) << 11; - } - }; - - uint8_t m_segmap[16][4096]; - page_entry_t m_pagemap[16384]; - uint32_t m_cachetags[16384]; - uint32_t m_cachedata[16384]; - - uint32_t *m_rom_ptr; - uint32_t *m_ram_ptr; - uint32_t m_ram_size; - uint32_t m_ram_size_words; - uint32_t m_context; - uint32_t m_context_masked; - uint8_t m_system_enable; - bool m_fetch_bootrom; - uint32_t m_buserr[4]; - - uint32_t m_segmap_masked[16][4096]; - uint8_t *m_curr_segmap; - uint32_t *m_curr_segmap_masked; - bool m_page_valid[16384]; - uint8_t m_auxio; uint32_t m_counter[4]; uint32_t m_dma[4]; @@ -751,331 +611,75 @@ private: uint8_t m_irq_reg; // IRQ control uint8_t m_scc1_int, m_scc2_int; - uint8_t m_diag; - int m_arch; attotime m_c0_last_read_time; attotime m_c1_last_read_time; emu_timer *m_c0_timer; emu_timer *m_c1_timer; - emu_timer *m_reset_timer; void dma_check_interrupts(); void dma_transfer(); void dma_transfer_write(); void dma_transfer_read(); - void l2p_command(int ref, const std::vector<std::string> ¶ms); void fcodes_command(int ref, const std::vector<std::string> ¶ms); }; -READ32_MEMBER( sun4_state::sun4_system_r ) -{ - switch (offset >> 26) - { - case 3: // context reg - if (mem_mask == 0x00ff0000) return m_context<<16; - return m_context<<24; - - case 4: // system enable reg - return m_system_enable<<24; - - case 6: // bus error register - //printf("sun4: read buserror, PC=%x (mask %08x)\n", m_maincpu->pc(), mem_mask); - return 0; - - case 8: // (d-)cache tags - //logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc()); - return m_cachetags[offset&0xfff]; - - case 9: // (d-)cache data - //logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc()); - return 0xffffffff; - - case 0xf: // UART bypass - //printf("read UART bypass @ %x mask %08x (PC=%x)\n", offset<<2, mem_mask, m_maincpu->pc()); - switch (offset & 3) - { - case 0: if (mem_mask == 0xff000000) return m_scc2->cb_r(offset)<<24; else return m_scc2->db_r(offset)<<8; break; - case 1: if (mem_mask == 0xff000000) return m_scc2->ca_r(offset)<<24; else return m_scc2->da_r(offset)<<8; break; - } - return 0xffffffff; - - case 0: - default: - //logerror("sun4: ASI 2 space unhandled read @ %x (PC=%x)\n", offset<<2, m_maincpu->pc()); - return 0; - } -} - -WRITE32_MEMBER( sun4_state::sun4_system_w ) +class sun4_state : public sun4_base_state { - switch (offset >> 26) +public: + sun4_state(const machine_config &mconfig, device_type type, const char *tag) + : sun4_base_state(mconfig, type, tag) { - case 3: // context reg - //printf("%08x to context, mask %08x, offset %x\n", data, mem_mask, offset); - m_context = data>>24; - return; - - case 4: // system enable reg - m_system_enable = data>>24; - - if (m_system_enable & ENA_RESET) - { - m_reset_timer->adjust(attotime::from_usec(1), 0); - m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE); - //logerror("%s: Asserting reset line\n", machine().describe_context()); - } - //printf("%08x to system enable, mask %08x\n", data, mem_mask); - if (m_system_enable & ENA_RESET) - { - m_system_enable = 0; - m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - } - return; - - case 7: // diag reg - m_diag = data >> 24; - #if 1 - printf("sun4: CPU LEDs to %02x (PC=%x) => ", ((data>>24) & 0xff) ^ 0xff, m_maincpu->pc()); - for (int i = 0; i < 8; i++) - { - if (m_diag & (1<<i)) - { - printf("."); - } - else - { - printf("*"); - } - } - printf("\n"); - #endif - return; - - case 8: // cache tags - //logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc()); - m_cachetags[offset&0xfff] = data; - return; - - case 9: // cache data - //logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc()); - return; - - case 0xf: // UART bypass - //printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask); - switch (offset & 3) - { - case 0: if (mem_mask == 0xff000000) m_scc2->cb_w(offset, data>>24); else m_scc2->db_w(offset, data>>8); break; - case 1: if (mem_mask == 0xff000000) m_scc2->ca_w(offset, data>>24); else { m_scc2->da_w(offset, data>>8); printf("%c", data>>8); } break; - } - return; - - case 0: // IDPROM - default: - //logerror("sun4: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x)\n", data, offset<<2, mem_mask, m_maincpu->pc()); - return; } -} -READ32_MEMBER( sun4_state::sun4_segment_map_r ) -{ - //printf("sun4: read segment map @ %x (ctx %d entry %d, mem_mask %08x, PC=%x)\n", offset << 2, m_context, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc()); - if (mem_mask == 0xffff0000) - return m_curr_segmap[(offset>>16) & 0xfff]<<16; - else if (mem_mask == 0xff000000) - return m_curr_segmap[(offset>>16) & 0xfff]<<24; - else if (mem_mask == 0xffffffff) - return m_curr_segmap[(offset>>16) & 0xfff]; - else - logerror("sun4: read segment map w/ unknown mask %08x\n", mem_mask); - return 0x0; -} - -WRITE32_MEMBER( sun4_state::sun4_segment_map_w ) -{ - uint8_t segdata = 0; - //printf("segment write, mask %08x, PC=%x\n", mem_mask, m_maincpu->pc()); - if (mem_mask == 0xffff0000) segdata = (data >> 16) & 0xff; - else if (mem_mask == 0xff000000) segdata = (data >> 24) & 0xff; - else logerror("sun4: writing segment map with unknown mask %08x, PC=%x\n", mem_mask, m_maincpu->pc()); - - //printf("sun4: %08x to segment map @ %x (ctx %d entry %d, mem_mask %08x, PC=%x)\n", segdata, offset << 2, m_context, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc()); - m_curr_segmap[(offset>>16) & 0xfff] = segdata; - m_curr_segmap_masked[(offset>>16) & 0xfff] = segdata << 5; -} - -READ32_MEMBER( sun4_state::sun4_page_map_r ) -{ - uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 11) & 0x1f); - //printf("sun4: read page map @ %x (entry %d, seg %d, PMEG %d, mem_mask %08x, PC=%x)\n", offset << 2, page, (offset >> 16) & 0xfff, m_segmap[m_context][(offset >> 16) & 0xfff] & m_pmeg_mask, mem_mask, m_maincpu->pc()); - return m_pagemap[page].to_uint(); -} - -WRITE32_MEMBER( sun4_state::sun4_page_map_w ) -{ - const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 11) & 0x1f); - //printf("sun4: %08x to page map @ %x (entry %d, mem_mask %08x, PC=%x)\n", data, offset << 2, page, mem_mask, m_maincpu->pc()); - m_pagemap[page].merge_uint(data, mem_mask); - m_page_valid[page] = m_pagemap[page].valid; -} - -READ32_MEMBER( sun4_state::sun4c_debugger_r ) -{ - return m_mmu->insn_data_r<sun4c_mmu_device::SUPER_INSN>(offset, mem_mask); -} + void sun4(machine_config &config); -WRITE32_MEMBER( sun4_state::sun4c_debugger_w ) -{ - m_mmu->insn_data_w<sun4c_mmu_device::SUPER_INSN>(offset, data, mem_mask); -} +private: + void type1space_map(address_map &map); +}; -template <sun4_state::insn_data_mode MODE> -READ32_MEMBER( sun4_state::sun4_insn_data_r ) +class sun4c_state : public sun4_base_state { - // supervisor program fetches in boot state are special - if (m_fetch_bootrom && MODE == SUPER_INSN) +public: + sun4c_state(const machine_config &mconfig, device_type type, const char *tag) + : sun4_base_state(mconfig, type, tag) + , m_sbus(*this, "sbus") + , m_sbus_slot(*this, "slot%u", 1U) { - return m_rom_ptr[offset & 0x1ffff]; } - // it's translation time - const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff]; - const uint32_t entry_index = pmeg | ((offset >> 11) & 0x1f); - - if (m_page_valid[entry_index]) - { - page_entry_t &entry = m_pagemap[entry_index]; - entry.accessed = PM_ACCESSED; - - const uint32_t tmp = entry.page | (offset & 0x7ff); + void sun4c(machine_config &config); + void sun4_20(machine_config &config); + void sun4_40(machine_config &config); + void sun4_50(machine_config &config); + void sun4_60(machine_config &config); + void sun4_65(machine_config &config); + void sun4_75(machine_config &config); - //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), m_maincpu->pc()); +private: + virtual void machine_start() override; + virtual void machine_reset() override; - switch (entry.type) - { - case 0: // type 0 space - return m_type0space->read32(tmp, mem_mask); + template <int Line> DECLARE_WRITE_LINE_MEMBER(sbus_irq_w); - case 1: // type 1 space - // magic EPROM bypass - if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2))) - { - return m_rom_ptr[offset & 0x1ffff]; - } - //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2); - return m_type1space->read32(tmp, mem_mask); + void type1space_map(address_map &map); - default: - //logerror("sun4: access to unhandled memory type\n"); - return 0; - } - } - else - { - if (!machine().side_effects_disabled()) - { - //logerror("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_maincpu->pc()); - m_maincpu->set_mae(); - m_buserr[0] |= 0x80; // invalid PTE - m_buserr[0] &= ~0x8000; // read - m_buserr[1] = offset<<2; - if (mem_mask != ~0 && mem_mask != 0xffff0000 && mem_mask != 0xff000000) - { - if (mem_mask == 0x0000ffff || mem_mask == 0x0000ff00) - { - m_buserr[1] |= 2; - } - else if (mem_mask == 0x00ff0000) - { - m_buserr[1] |= 1; - } - else if (mem_mask == 0x000000ff) - { - m_buserr[1] |= 3; - } - } - } - return 0; - } -} + required_device<sbus_device> m_sbus; + required_device_array<sbus_slot_device, 3> m_sbus_slot; +}; -WRITE32_MEMBER( sun4_state::sun4_insn_data_w ) +READ32_MEMBER( sun4_base_state::debugger_r ) { - // it's translation time - const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff]; - const uint32_t entry_index = pmeg | ((offset >> 11) & 0x1f); - - if (m_page_valid[entry_index]) - { - page_entry_t &entry = m_pagemap[entry_index]; - entry.accessed = PM_ACCESSED; - - uint32_t tmp = entry.page | (offset & 0x7ff); - - //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), m_maincpu->pc()); - - switch (entry.type) - { - case 0: // type 0 - m_type0space->write32(tmp, data, mem_mask); - return; - - case 1: // type 1 - //printf("write device space @ %x\n", tmp<<1); - m_type1space->write32(tmp, data, mem_mask); - return; - - default: - //logerror("sun4: access to memory type not defined in sun4\n"); - return; - } - } - else - { - //logerror("sun4: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_maincpu->pc()); - //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); - //m_buserr[0] = 0x8; // invalid PTE - //m_buserr[1] = offset<<2; - } + return m_mmu->insn_data_r<sun4_mmu_base_device::SUPER_INSN>(offset, mem_mask); } -// make debugger fetches emulate supervisor program for best compatibility with boot PROM execution -//if (machine().side_effects_disabled()) asi = 9; - -void sun4_state::l2p_command(int ref, const std::vector<std::string> ¶ms) +WRITE32_MEMBER( sun4_base_state::debugger_w ) { - uint64_t addr, offset; - - if (!machine().debugger().commands().validate_number_parameter(params[0], addr)) return; - - addr &= 0xffffffff; - offset = addr >> 2; - - uint8_t pmeg = 0; - uint32_t entry_index = 0, tmp = 0; - uint32_t entry_value = 0; - - if (m_arch == ARCH_SUN4) - { - pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff]; - entry_index = pmeg | ((offset >> 11) & 0x1f); - tmp = m_pagemap[entry_index].page | (offset & 0x7ff); - entry_value = m_pagemap[entry_index].to_uint(); - } - - if (m_page_valid[entry_index]) - { - machine().debugger().console().printf("logical %08x => phys %08x, type %d (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, m_pagemap[entry_index].type, pmeg, entry_index, entry_value); - } - else - { - machine().debugger().console().printf("logical %08x points to an invalid PTE! (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, pmeg, entry_index, entry_value); - } + m_mmu->insn_data_w<sun4_mmu_base_device::SUPER_INSN>(offset, data, mem_mask); } -void sun4_state::fcodes_command(int ref, const std::vector<std::string> ¶ms) +void sun4_base_state::fcodes_command(int ref, const std::vector<std::string> ¶ms) { #if SUN4_LOG_FCODES if (params < 1) @@ -1096,118 +700,51 @@ void sun4_state::fcodes_command(int ref, const std::vector<std::string> ¶ms) #endif } -void sun4_state::sun4_system_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_system_r), FUNC(sun4_state::sun4_system_w)); -} - -void sun4_state::sun4_segment_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_segment_map_r), FUNC(sun4_state::sun4_segment_map_w)); -} - -void sun4_state::sun4_page_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_page_map_r), FUNC(sun4_state::sun4_page_map_w)); -} - -void sun4_state::sun4_supervisor_insn_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_insn_data_r<SUPER_INSN>), FUNC(sun4_state::sun4_insn_data_w)); -} - -void sun4_state::sun4_supervisor_data_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_insn_data_r<SUPER_DATA>), FUNC(sun4_state::sun4_insn_data_w)); -} - -void sun4_state::sun4_insn_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_insn_data_r<USER_INSN>), FUNC(sun4_state::sun4_insn_data_w)); -} - -void sun4_state::sun4_data_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_insn_data_r<USER_DATA>), FUNC(sun4_state::sun4_insn_data_w)); -} - -void sun4_state::sun4c_debugger_map(address_map &map) -{ - map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_debugger_r), FUNC(sun4_state::sun4c_debugger_w)); -} +// make debugger fetches emulate supervisor program for best compatibility with boot PROM execution -void sun4_state::type0space_map(address_map &map) +void sun4_base_state::debugger_map(address_map &map) { - map.unmap_value_high(); - map(0x00000000, 0x00ffffff).rw(FUNC(sun4_state::ram_r), FUNC(sun4_state::ram_w)); - map(0x04000000, 0x0fffffff).rw(FUNC(sun4_state::timeout_r), FUNC(sun4_state::timeout_w)); + map(0x00000000, 0xffffffff).rw(FUNC(sun4_base_state::debugger_r), FUNC(sun4_base_state::debugger_w)); } -void sun4_state::type1space_map(address_map &map) +void sun4_base_state::type1space_base_map(address_map &map) { map(0x00000000, 0x0000000f).rw(m_scc1, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask32(0xff00ff00); map(0x01000000, 0x0100000f).rw(m_scc2, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask32(0xff00ff00); map(0x02000000, 0x020007ff).rw(m_timekpr, FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)); - map(0x03000000, 0x0300000f).rw(FUNC(sun4_state::timer_r), FUNC(sun4_state::timer_w)).mirror(0xfffff0); - map(0x05000000, 0x05000003).rw(FUNC(sun4_state::irq_r), FUNC(sun4_state::irq_w)); + map(0x03000000, 0x0300000f).rw(FUNC(sun4_base_state::timer_r), FUNC(sun4_base_state::timer_w)).mirror(0xfffff0); + map(0x05000000, 0x05000003).rw(FUNC(sun4_base_state::irq_r), FUNC(sun4_base_state::irq_w)); map(0x06000000, 0x0607ffff).rom().region("user1", 0); - map(0x07200000, 0x07200007).rw(FUNC(sun4_state::fdc_r), FUNC(sun4_state::fdc_w)); - map(0x07400003, 0x07400003).rw(FUNC(sun4_state::auxio_r), FUNC(sun4_state::auxio_w)); - map(0x08000000, 0x08000003).r(FUNC(sun4_state::ss1_sl0_id)); // slot 0 contains SCSI/DMA/Ethernet - map(0x08400000, 0x0840000f).rw(FUNC(sun4_state::dma_r), FUNC(sun4_state::dma_w)); + map(0x07200000, 0x07200007).rw(FUNC(sun4_base_state::fdc_r), FUNC(sun4_base_state::fdc_w)); + map(0x07400003, 0x07400003).rw(FUNC(sun4_base_state::auxio_r), FUNC(sun4_base_state::auxio_w)); + map(0x08000000, 0x08000003).r(FUNC(sun4_base_state::sl0_id)); // internal slot 0 contains SCSI/DMA/Ethernet + map(0x08400000, 0x0840000f).rw(FUNC(sun4_base_state::dma_r), FUNC(sun4_base_state::dma_w)); map(0x08800000, 0x0880002f).m(m_scsi, FUNC(ncr53c90a_device::map)).umask32(0xff000000); map(0x08c00000, 0x08c00003).rw(m_lance, FUNC(am79c90_device::regs_r), FUNC(am79c90_device::regs_w)); } -void sun4_state::type1space_sbus_map(address_map &map) +void sun4c_state::type1space_map(address_map &map) { - type1space_map(map); + type1space_base_map(map); map(0x0a000000, 0x0fffffff).rw(m_sbus, FUNC(sbus_device::read), FUNC(sbus_device::write)); } -void sun4_state::type1space_s4_map(address_map &map) +void sun4_state::type1space_map(address_map &map) { - map(0x00000000, 0x0000000f).rw(m_scc1, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask32(0xff00ff00); - map(0x01000000, 0x0100000f).rw(m_scc2, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask32(0xff00ff00); + type1space_base_map(map); } /* Input ports */ static INPUT_PORTS_START( sun4 ) INPUT_PORTS_END -void sun4_state::machine_reset() +void sun4_base_state::machine_start() { - m_auxio = 0xc0; - m_irq_reg = 0; - m_scc1_int = m_scc2_int = 0; - m_scsi_irq = 0; - m_fdc_irq = 0; - m_dma_irq = false; - m_dma_tc_read = false; - m_dma_pack_register = 0; - - m_c0_last_read_time = attotime::zero; - m_c1_last_read_time = attotime::zero; - m_counter[0] = 1 << 10; - m_counter[2] = 1 << 10; - - memset(m_counter, 0, sizeof(m_counter)); - memset(m_dma, 0, sizeof(m_dma)); -} - -void sun4_state::machine_start() -{ - m_rom_ptr = (uint32_t *)m_rom->base(); - m_ram_ptr = (uint32_t *)m_ram->pointer(); - m_ram_size = m_ram->size(); - m_ram_size_words = m_ram_size >> 2; - if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("l2p", CMDFLAG_NONE, 0, 1, 1, std::bind(&sun4_state::l2p_command, this, _1, _2)); #if SUN4_LOG_FCODES - machine().debugger().console().register_command("fcodes", CMDFLAG_NONE, 0, 1, 1, std::bind(&sun4_state::fcodes_command, this, _1, _2)); + machine().debugger().console().register_command("fcodes", CMDFLAG_NONE, 0, 1, 1, std::bind(&sun4_base_state::fcodes_command, this, _1, _2)); #endif } @@ -1217,39 +754,6 @@ void sun4_state::machine_start() m_c0_timer->adjust(attotime::from_usec(1), 0, attotime::from_usec(1)); m_c1_timer->adjust(attotime::from_usec(1), 0, attotime::from_usec(1)); - // allocate timer for system reset - m_reset_timer = timer_alloc(TIMER_RESET); - m_reset_timer->adjust(attotime::never); - - for (int i = 0; i < 16; i++) - { - save_item(NAME(m_segmap[i]), i); - save_item(NAME(m_segmap_masked[i]), i); - } - - for (int i = 0; i < 16384; i++) - { - save_item(NAME(m_pagemap[i].valid), i); - save_item(NAME(m_pagemap[i].writable), i); - save_item(NAME(m_pagemap[i].supervisor), i); - save_item(NAME(m_pagemap[i].uncached), i); - save_item(NAME(m_pagemap[i].accessed), i); - save_item(NAME(m_pagemap[i].modified), i); - save_item(NAME(m_pagemap[i].page), i); - save_item(NAME(m_pagemap[i].type), i); - } - - save_item(NAME(m_cachetags)); - save_item(NAME(m_cachedata)); - save_item(NAME(m_ram_size)); - save_item(NAME(m_ram_size_words)); - save_item(NAME(m_context)); - save_item(NAME(m_context_masked)); - save_item(NAME(m_system_enable)); - save_item(NAME(m_fetch_bootrom)); - save_item(NAME(m_buserr)); - save_item(NAME(m_page_valid)); - save_item(NAME(m_auxio)); save_item(NAME(m_counter)); save_item(NAME(m_dma)); @@ -1262,93 +766,39 @@ void sun4_state::machine_start() save_item(NAME(m_irq_reg)); save_item(NAME(m_scc1_int)); save_item(NAME(m_scc2_int)); - save_item(NAME(m_diag)); - save_item(NAME(m_arch)); } -READ32_MEMBER( sun4_state::ram_r ) +void sun4c_state::machine_start() { - return m_ram_ptr[offset]; + sun4_base_state::machine_start(); } -WRITE32_MEMBER( sun4_state::ram_w ) +void sun4_base_state::machine_reset() { -#if 0 - // if writing bad parity is enabled - if (((m_parregs[0] & 0x20000000) == 0x20000000) && - (m_irqctrl & 0x01000000) && - !(m_bInBusErr)) - { - m_parregs[1] = offset<<2; - //printf("Generating parity error, mem_mask %08x\n", mem_mask); - switch (mem_mask) - { - case 0xff000000: - m_parregs[0] |= 0x08<<24; - break; - - case 0x00ff0000: - m_parregs[1] += 1; - m_parregs[0] |= 0x04<<24; - break; - - case 0x0000ff00: - m_parregs[1] += 2; - m_parregs[0] |= 0x02<<24; - break; - - case 0x000000ff: - m_parregs[1] += 3; - m_parregs[0] |= 0x01<<24; - break; - - case 0x0000ffff: - m_parregs[1] += 2; - m_parregs[0] |= 0x03<<24; - break; - - case 0xffff0000: - m_parregs[0] |= 0x0c<<24; - break; - - case 0xffffffff: // no address adjust, show all 4 lanes as problematic - m_parregs[0] |= 0x0f<<24; - break; - } - - // indicate parity interrupt - m_parregs[0] |= 0x80000000; - - // and can we take that now? - if (m_parregs[0] & 0x40000000) - { - } - } -#endif - - //printf("ram_w: %08x to %08x (mask %08x)\n", data, offset<<2, mem_mask); - - //if ((offset<<2) == 0xfb2000) printf("write %08x to %08x, mask %08x, PC=%x\n", data, offset<<2, mem_mask, m_maincpu->pc()); + m_auxio = 0xc0; + m_irq_reg = 0; + m_scc1_int = m_scc2_int = 0; + m_scsi_irq = 0; + m_fdc_irq = 0; + m_dma_irq = false; + m_dma_tc_read = false; + m_dma_pack_register = 0; - COMBINE_DATA(&m_ram_ptr[offset]); -} + m_c0_last_read_time = attotime::zero; + m_c1_last_read_time = attotime::zero; + m_counter[0] = 1 << 10; + m_counter[2] = 1 << 10; -READ32_MEMBER( sun4_state::timeout_r ) -{ - m_buserr[0] = 0x20; // read timeout - m_buserr[1] = 0x04000000 + (offset << 2); - m_maincpu->set_mae(); - return 0; + memset(m_counter, 0, sizeof(m_counter)); + memset(m_dma, 0, sizeof(m_dma)); } -WRITE32_MEMBER( sun4_state::timeout_w ) +void sun4c_state::machine_reset() { - m_buserr[0] = 0x8020; // write timeout - m_buserr[1] = 0x04000000 + (offset << 2); - m_maincpu->set_mae(); + sun4_base_state::machine_reset(); } -READ8_MEMBER( sun4_state::fdc_r ) +READ8_MEMBER( sun4_base_state::fdc_r ) { if (machine().side_effects_disabled()) return 0; @@ -1378,7 +828,7 @@ READ8_MEMBER( sun4_state::fdc_r ) return 0; } -WRITE8_MEMBER( sun4_state::fdc_w ) +WRITE8_MEMBER( sun4_base_state::fdc_w ) { switch(offset) { @@ -1401,13 +851,13 @@ WRITE8_MEMBER( sun4_state::fdc_w ) } } -READ8_MEMBER( sun4_state::auxio_r ) +READ8_MEMBER( sun4_base_state::auxio_r ) { //logerror("%s: auxio_r: %02x\n", machine().describe_context(), m_auxio); return m_auxio; } -WRITE8_MEMBER( sun4_state::auxio_w ) +WRITE8_MEMBER( sun4_base_state::auxio_w ) { //logerror("%s: auxio_w: %02x, drive_sel:%d tc:%d eject:%d LED:%d\n", machine().describe_context(), data, BIT(data, 3), BIT(data, 2), BIT(data, 1), BIT(data, 0)); m_auxio = (m_auxio & 0xf0) | (data & 0x0f); @@ -1422,13 +872,13 @@ WRITE8_MEMBER( sun4_state::auxio_w ) } } -READ8_MEMBER( sun4_state::irq_r ) +READ8_MEMBER( sun4_base_state::irq_r ) { //logerror("%02x from IRQ\n", m_irq_reg); return m_irq_reg; } -WRITE8_MEMBER( sun4_state::irq_w ) +WRITE8_MEMBER( sun4_base_state::irq_w ) { const uint8_t old_irq = m_irq_reg; m_irq_reg = data; @@ -1441,16 +891,17 @@ WRITE8_MEMBER( sun4_state::irq_w ) if (BIT(changed, 0)) { + int enabled_state = BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE; if (BIT(m_irq_reg, 7) && BIT(m_counter[2] | m_counter[3], 31)) - m_maincpu->set_input_line(SPARC_IRQ14, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(SPARC_IRQ14, enabled_state); if (BIT(m_irq_reg, 5) && BIT(m_counter[0] | m_counter[1], 31)) - m_maincpu->set_input_line(SPARC_IRQ10, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(SPARC_IRQ10, enabled_state); if (BIT(m_irq_reg, 3)) - m_maincpu->set_input_line(SPARC_IRQ6, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(SPARC_IRQ6, enabled_state); if (BIT(m_irq_reg, 2)) - m_maincpu->set_input_line(SPARC_IRQ4, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(SPARC_IRQ4, enabled_state); if (BIT(m_irq_reg, 1)) - m_maincpu->set_input_line(SPARC_IRQ1, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(SPARC_IRQ1, enabled_state); } else if (BIT(m_irq_reg, 0)) { @@ -1467,21 +918,21 @@ WRITE8_MEMBER( sun4_state::irq_w ) } } -WRITE_LINE_MEMBER( sun4_state::scc1_int ) +WRITE_LINE_MEMBER( sun4_base_state::scc1_int ) { m_scc1_int = state; m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE); } -WRITE_LINE_MEMBER( sun4_state::scc2_int ) +WRITE_LINE_MEMBER( sun4_base_state::scc2_int ) { m_scc2_int = state; m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE); } -void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +void sun4_base_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { @@ -1522,16 +973,10 @@ void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, v } } break; - - case TIMER_RESET: - m_reset_timer->adjust(attotime::never); - m_maincpu->set_input_line(SPARC_RESET, CLEAR_LINE); - //printf("Clearing reset line\n"); - break; } } -READ32_MEMBER( sun4_state::timer_r ) +READ32_MEMBER( sun4_base_state::timer_r ) { const uint32_t ret = m_counter[offset]; @@ -1562,7 +1007,7 @@ READ32_MEMBER( sun4_state::timer_r ) return ret; } -WRITE32_MEMBER( sun4_state::timer_w ) +WRITE32_MEMBER( sun4_base_state::timer_w ) { COMBINE_DATA(&m_counter[offset]); @@ -1591,7 +1036,7 @@ WRITE32_MEMBER( sun4_state::timer_w ) } } -void sun4_state::dma_check_interrupts() +void sun4_base_state::dma_check_interrupts() { bool tc_interrupt = (m_dma[DMA_CTRL] & DMA_TC) != 0 && !m_dma_tc_read; bool scsi_interrupt = m_scsi_irq != 0; @@ -1611,7 +1056,7 @@ void sun4_state::dma_check_interrupts() } } -void sun4_state::dma_transfer_write() +void sun4_base_state::dma_transfer_write() { //logerror("DMAing from device to RAM\n"); @@ -1629,12 +1074,7 @@ void sun4_state::dma_transfer_write() pack_cnt++; if (pack_cnt == 4) { - //logerror("Writing pack register %08x to %08x\n", m_dma_pack_register, m_dma[DMA_ADDR]); - if (m_arch == ARCH_SUN4C) - m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0); - //else - TODO - //sun4_insn_data_w(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0); - + m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0); pack_cnt = 0; m_dma_pack_register = 0; m_dma[DMA_ADDR] += 4; @@ -1645,7 +1085,7 @@ void sun4_state::dma_transfer_write() m_dma[DMA_CTRL] |= pack_cnt << DMA_PACK_CNT_SHIFT; } -void sun4_state::dma_transfer_read() +void sun4_base_state::dma_transfer_read() { //logerror("DMAing from RAM to device\n"); @@ -1655,10 +1095,7 @@ void sun4_state::dma_transfer_read() { if (!word_cached) { - if (m_arch == ARCH_SUN4C) - current_word = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, ~0); - //else - TODO - //current_word = sun4_insn_data_r<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, ~0); + current_word = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, ~0); word_cached = true; //logerror("Current word: %08x\n", current_word); } @@ -1677,7 +1114,7 @@ void sun4_state::dma_transfer_read() } } -void sun4_state::dma_transfer() +void sun4_base_state::dma_transfer() { if (m_dma[DMA_CTRL] & DMA_WRITE) dma_transfer_write(); @@ -1692,7 +1129,7 @@ void sun4_state::dma_transfer() } } -READ32_MEMBER( sun4_state::dma_r ) +READ32_MEMBER( sun4_base_state::dma_r ) { if (offset == DMA_CTRL && (m_dma[DMA_CTRL] & DMA_TC) != 0) { @@ -1702,7 +1139,7 @@ READ32_MEMBER( sun4_state::dma_r ) return m_dma[offset]; } -WRITE32_MEMBER( sun4_state::dma_w ) +WRITE32_MEMBER( sun4_base_state::dma_w ) { switch (offset) { @@ -1735,10 +1172,7 @@ WRITE32_MEMBER( sun4_state::dma_w ) const uint32_t bit_index = (3 - i) * 8; //const uint32_t value = m_dma_pack_register & (0xff << bit_index); //logerror("dma_w: draining %02x to RAM address %08x & %08x\n", value >> bit_index, m_dma[DMA_ADDR], 0xff << (24 - bit_index)); - if (m_arch == ARCH_SUN4C) - m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index); - else - sun4_insn_data_w(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index); + m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index); m_dma[DMA_ADDR]++; } m_dma_pack_register = 0; @@ -1766,7 +1200,7 @@ WRITE32_MEMBER( sun4_state::dma_w ) } } -WRITE_LINE_MEMBER( sun4_state::scsi_irq ) +WRITE_LINE_MEMBER( sun4_base_state::scsi_irq ) { int old_irq = m_scsi_irq; m_scsi_irq = state; @@ -1777,7 +1211,7 @@ WRITE_LINE_MEMBER( sun4_state::scsi_irq ) } } -WRITE_LINE_MEMBER( sun4_state::scsi_drq ) +WRITE_LINE_MEMBER( sun4_base_state::scsi_drq ) { //logerror("scsi_drq %d\n", state); m_dma[DMA_CTRL] &= ~DMA_REQ_PEND; @@ -1793,7 +1227,7 @@ WRITE_LINE_MEMBER( sun4_state::scsi_drq ) } } -WRITE_LINE_MEMBER( sun4_state::fdc_irq ) +WRITE_LINE_MEMBER( sun4_base_state::fdc_irq ) { int old_irq = m_fdc_irq; m_fdc_irq = state; @@ -1804,18 +1238,19 @@ WRITE_LINE_MEMBER( sun4_state::fdc_irq ) } } -WRITE32_MEMBER( sun4_state::buserr_w ) +// indicate on-board SCSI/DMA/Ethernet card exists +READ32_MEMBER( sun4_base_state::sl0_id ) { - COMBINE_DATA(&m_buserr[offset]); + return 0xfe810101; } -// indicate 4/60 SCSI/DMA/Ethernet card exists -READ32_MEMBER( sun4_state::ss1_sl0_id ) +template <int Line> +WRITE_LINE_MEMBER(sun4c_state::sbus_irq_w) { - return 0xfe810101; + m_maincpu->set_input_line(Line, state); } -FLOPPY_FORMATS_MEMBER( sun4_state::floppy_formats ) +FLOPPY_FORMATS_MEMBER( sun4_base_state::floppy_formats ) FLOPPY_PC_FORMAT FLOPPY_FORMATS_END @@ -1837,77 +1272,55 @@ static void sun_scsi_devices(device_slot_interface &device) device.set_option_machine_config("cdrom", sun4_cdrom); } -void sun4_state::ncr53c90a(device_t *device) +void sun4_base_state::ncr53c90a(device_t *device) { ncr53c90a_device &adapter = downcast<ncr53c90a_device &>(*device); adapter.set_clock(10000000); - adapter.irq_handler_cb().set(*this, FUNC(sun4_state::scsi_irq)); - adapter.drq_handler_cb().set(*this, FUNC(sun4_state::scsi_drq)); + adapter.irq_handler_cb().set(*this, FUNC(sun4_base_state::scsi_irq)); + adapter.drq_handler_cb().set(*this, FUNC(sun4_base_state::scsi_drq)); } -void sun4_state::sun4(machine_config &config) +void sun4_base_state::sun4_base(machine_config &config) { - /* basic machine hardware */ - MB86901(config, m_maincpu, 16'670'000); - m_maincpu->add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(sun4_asi_desc); }); - m_maincpu->set_addrmap(0, &sun4_state::sun4c_debugger_map); - - // TODO: MMU for sun4 hardware - SUN4C_MMU(config, m_mmu, 25'000'000, 7, 0x7f); - m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32)); - m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32)); - m_mmu->set_cpu(m_maincpu); - m_mmu->set_ram(m_ram); - m_mmu->set_rom("user1"); - m_mmu->set_scc(m_scc2); - m_maincpu->set_mmu(m_mmu); - - RAM(config, m_ram); - m_ram->set_default_size("16M"); - m_ram->set_default_value(0x00); + RAM(config, m_ram).set_default_size("16M").set_default_value(0x00); + m_ram->set_extra_options("4M,8M,12M,16M,20M,24M,28M,32M,36M,40M,48M,52M,64M"); M48T02(config, TIMEKEEPER_TAG, 0); - I82072(config, m_fdc, 24_MHz_XTAL); + N82077AA(config, m_fdc, 24_MHz_XTAL); m_fdc->set_ready_line_connected(false); - m_fdc->intrq_wr_callback().set(FUNC(sun4_state::fdc_irq)); - FLOPPY_CONNECTOR(config, m_floppy, sun_floppies, "35hd", sun4_state::floppy_formats); - - // MMU Type 0 device space - ADDRESS_MAP_BANK(config, m_type0space).set_map(&sun4_state::type0space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); - - // MMU Type 1 device space - ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4_state::type1space_s4_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); + m_fdc->intrq_wr_callback().set(FUNC(sun4_base_state::fdc_irq)); + FLOPPY_CONNECTOR(config, m_floppy, sun_floppies, "35hd", sun4_base_state::floppy_formats); // Ethernet AM79C90(config, m_lance); - m_lance->dma_in().set([this](address_space &space, offs_t offset) + m_lance->dma_in().set([this](offs_t offset) { - u32 const data = sun4_insn_data_r<SUPER_DATA>(space, (0xff000000U | offset) >> 2); + u32 const data = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, 0xffffffffU); return (offset & 2) ? u16(data) : u16(data >> 16); }); - m_lance->dma_out().set([this](address_space &space, offs_t offset, u16 data, u16 mem_mask) + m_lance->dma_out().set([this](offs_t offset, u16 data, u16 mem_mask) { if (offset & 2) - sun4_insn_data_w(space, (0xff000000U | offset) >> 2, data, mem_mask); + m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, data, mem_mask); else - sun4_insn_data_w(space, (0xff000000U | offset) >> 2, u32(data) << 16, u32(mem_mask) << 16); + m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, u32(data) << 16, u32(mem_mask) << 16); }); // Keyboard/mouse SCC85C30(config, m_scc1, 4.9152_MHz_XTAL); - m_scc1->out_int_callback().set(FUNC(sun4_state::scc1_int)); + m_scc1->out_int_callback().set(FUNC(sun4_base_state::scc1_int)); m_scc1->out_txda_callback().set(KEYBOARD_TAG, FUNC(sun_keyboard_port_device::write_txd)); - m_scc1->out_txdb_callback().set(MOUSE_TAG, FUNC(sun_mouse_port_device::write_txd)); + // no mouse TxD connection - replaced with soft power request input - SUNKBD_PORT(config, KEYBOARD_TAG, default_sun_keyboard_devices, "type4hle").rxd_handler().set(m_scc1, FUNC(z80scc_device::rxa_w)); + SUNKBD_PORT(config, KEYBOARD_TAG, default_sun_keyboard_devices, "type5hle").rxd_handler().set(m_scc1, FUNC(z80scc_device::rxa_w)); SUNMOUSE_PORT(config, MOUSE_TAG, default_sun_mouse_devices, "hle1200").rxd_handler().set(m_scc1, FUNC(z80scc_device::rxb_w)); // RS232 serial ports SCC85C30(config, m_scc2, 4.9152_MHz_XTAL); - m_scc2->out_int_callback().set(FUNC(sun4_state::scc2_int)); + m_scc2->out_int_callback().set(FUNC(sun4_base_state::scc2_int)); m_scc2->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd)); m_scc2->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd)); @@ -1932,14 +1345,19 @@ void sun4_state::sun4(machine_config &config) NSCSI_CONNECTOR(config, "scsibus:7", sun_scsi_devices, "ncr53c90a", true).set_option_machine_config("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); }); } -void sun4_state::sun4c(machine_config &config) +void sun4_state::sun4(machine_config &config) { /* basic machine hardware */ - MB86901(config, m_maincpu, 20'000'000); - m_maincpu->add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(sun4c_asi_desc); }); - m_maincpu->set_addrmap(0, &sun4_state::sun4c_debugger_map); + SPARCV7(config, m_maincpu, 16'670'000); + m_maincpu->add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(sun4_asi_desc); }); + m_maincpu->set_addrmap(0, &sun4_state::debugger_map); - SUN4C_MMU(config, m_mmu, 20'000'000, 7, 0x7f); + sun4_base(config); + + // MMU Type 1 device space + ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4_state::type1space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); + + SUN4_MMU(config, m_mmu, 25'000'000); m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32)); m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32)); m_mmu->set_cpu(m_maincpu); @@ -1947,82 +1365,44 @@ void sun4_state::sun4c(machine_config &config) m_mmu->set_rom("user1"); m_mmu->set_scc(m_scc2); m_maincpu->set_mmu(m_mmu); +} - RAM(config, m_ram).set_default_size("16M").set_default_value(0x00); - m_ram->set_extra_options("4M,8M,12M,16M,20M,24M,28M,32M,36M,40M,48M,52M,64M"); - - M48T02(config, TIMEKEEPER_TAG, 0); - - N82077AA(config, m_fdc, 24_MHz_XTAL); - m_fdc->set_ready_line_connected(false); - m_fdc->intrq_wr_callback().set(FUNC(sun4_state::fdc_irq)); - FLOPPY_CONNECTOR(config, m_floppy, sun_floppies, "35hd", sun4_state::floppy_formats); +void sun4c_state::sun4c(machine_config &config) +{ + /* basic machine hardware */ + SPARCV7(config, m_maincpu, 20'000'000); + m_maincpu->add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(sun4c_asi_desc); }); + m_maincpu->set_addrmap(0, &sun4c_state::debugger_map); - // MMU Type 0 device space - ADDRESS_MAP_BANK(config, m_type0space).set_map(&sun4_state::type0space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); + sun4_base(config); // MMU Type 1 device space - ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); - - // Ethernet - AM79C90(config, m_lance); - m_lance->dma_in().set([this](offs_t offset) - { - u32 const data = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, 0xffffffffU); - - return (offset & 2) ? u16(data) : u16(data >> 16); - }); - m_lance->dma_out().set([this](offs_t offset, u16 data, u16 mem_mask) - { - if (offset & 2) - m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, data, mem_mask); - else - m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, u32(data) << 16, u32(mem_mask) << 16); - }); - - // Keyboard/mouse - SCC85C30(config, m_scc1, 4.9152_MHz_XTAL); - m_scc1->out_int_callback().set(FUNC(sun4_state::scc1_int)); - m_scc1->out_txda_callback().set(KEYBOARD_TAG, FUNC(sun_keyboard_port_device::write_txd)); - // no mouse TxD connection - replaced with soft power request input - - SUNKBD_PORT(config, KEYBOARD_TAG, default_sun_keyboard_devices, "type5hle").rxd_handler().set(m_scc1, FUNC(z80scc_device::rxa_w)); - SUNMOUSE_PORT(config, MOUSE_TAG, default_sun_mouse_devices, "hle1200").rxd_handler().set(m_scc1, FUNC(z80scc_device::rxb_w)); - - // RS232 serial ports - SCC85C30(config, m_scc2, 4.9152_MHz_XTAL); - m_scc2->out_int_callback().set(FUNC(sun4_state::scc2_int)); - m_scc2->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd)); - m_scc2->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd)); + ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4c_state::type1space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000); - rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr)); - rs232a.rxd_handler().set(m_scc2, FUNC(z80scc_device::rxa_w)); - rs232a.dcd_handler().set(m_scc2, FUNC(z80scc_device::dcda_w)); - rs232a.cts_handler().set(m_scc2, FUNC(z80scc_device::ctsa_w)); - - rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr)); - rs232b.rxd_handler().set(m_scc2, FUNC(z80scc_device::rxb_w)); - rs232b.dcd_handler().set(m_scc2, FUNC(z80scc_device::dcdb_w)); - rs232b.cts_handler().set(m_scc2, FUNC(z80scc_device::ctsb_w)); - - NSCSI_BUS(config, "scsibus"); - NSCSI_CONNECTOR(config, "scsibus:0", sun_scsi_devices, "harddisk"); - NSCSI_CONNECTOR(config, "scsibus:1", sun_scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsibus:2", sun_scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsibus:3", sun_scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsibus:4", sun_scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsibus:5", sun_scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsibus:6", sun_scsi_devices, "cdrom"); - NSCSI_CONNECTOR(config, "scsibus:7", sun_scsi_devices, "ncr53c90a", true).set_option_machine_config("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); }); + SUN4C_MMU(config, m_mmu, 20'000'000); + m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32)); + m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32)); + m_mmu->set_cpu(m_maincpu); + m_mmu->set_ram(m_ram); + m_mmu->set_rom("user1"); + m_mmu->set_scc(m_scc2); + m_maincpu->set_mmu(m_mmu); // SBus SBUS(config, m_sbus, 20'000'000, "maincpu", "type1"); + m_sbus->irq<0>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ1>)); + m_sbus->irq<1>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ2>)); + m_sbus->irq<2>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ3>)); + m_sbus->irq<3>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ5>)); + m_sbus->irq<4>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ7>)); + m_sbus->irq<5>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ8>)); + m_sbus->irq<6>().set(FUNC(sun4c_state::sbus_irq_w<SPARC_IRQ9>)); SBUS_SLOT(config, m_sbus_slot[0], 20'000'000, m_sbus, 0, sbus_cards, nullptr); SBUS_SLOT(config, m_sbus_slot[1], 20'000'000, m_sbus, 1, sbus_cards, nullptr); SBUS_SLOT(config, m_sbus_slot[2], 20'000'000, m_sbus, 2, sbus_cards, nullptr); } -void sun4_state::sun4_20(machine_config &config) +void sun4c_state::sun4_20(machine_config &config) { sun4c(config); @@ -2034,7 +1414,7 @@ void sun4_state::sun4_20(machine_config &config) m_sbus_slot[2]->set_fixed(true); } -void sun4_state::sun4_40(machine_config &config) +void sun4c_state::sun4_40(machine_config &config) { sun4c(config); @@ -2051,7 +1431,7 @@ void sun4_state::sun4_40(machine_config &config) m_sbus_slot[2]->set_fixed(true); } -void sun4_state::sun4_50(machine_config &config) +void sun4c_state::sun4_50(machine_config &config) { sun4c(config); @@ -2069,12 +1449,12 @@ void sun4_state::sun4_50(machine_config &config) m_sbus_slot[2]->set_fixed(true); } -void sun4_state::sun4_60(machine_config &config) +void sun4c_state::sun4_60(machine_config &config) { sun4c(config); } -void sun4_state::sun4_65(machine_config &config) +void sun4c_state::sun4_65(machine_config &config) { sun4c(config); @@ -2088,7 +1468,7 @@ void sun4_state::sun4_65(machine_config &config) m_sbus_slot[2]->set_default_option("bwtwo"); } -void sun4_state::sun4_75(machine_config &config) +void sun4c_state::sun4_75(machine_config &config) { sun4c(config); @@ -2338,33 +1718,23 @@ ROM_START( sun_s20 ) ROMX_LOAD( "ss10-20_v2.25r.rom", 0x0000, 0x80000, CRC(105ba132) SHA1(58530e88369d1d26ab11475c7884205f2299d255), ROM_BIOS(1)) ROM_END -void sun4_state::init_sun4() -{ - m_arch = ARCH_SUN4; -} - -void sun4_state::init_sun4c() -{ - m_arch = ARCH_SUN4C; -} - /* Drivers */ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS // sun4 -COMP( 198?, sun4_110, 0, 0, sun4, sun4, sun4_state, init_sun4, "Sun Microsystems", "Sun 4/110", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 1987, sun4_300, 0, 0, sun4, sun4, sun4_state, init_sun4, "Sun Microsystems", "Sun 4/3x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 198?, sun4_400, 0, 0, sun4, sun4, sun4_state, init_sun4, "Sun Microsystems", "Sun 4/4x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 198?, sun4_110, 0, 0, sun4, sun4, sun4_state, empty_init, "Sun Microsystems", "Sun 4/110", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1987, sun4_300, 0, 0, sun4, sun4, sun4_state, empty_init, "Sun Microsystems", "Sun 4/3x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 198?, sun4_400, 0, 0, sun4, sun4, sun4_state, empty_init, "Sun Microsystems", "Sun 4/4x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // sun4c -COMP( 1990, sun4_40, sun4_300, 0, sun4_40, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -COMP( 1991, sun4_50, sun4_300, 0, sun4_50, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 199?, sun4_20, sun4_300, 0, sun4_20, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 1989, sun4_60, sun4_300, 0, sun4_60, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -COMP( 1990, sun4_65, sun4_300, 0, sun4_65, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1+ (Sun 4/65)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 1990, sun4_75, sun4_300, 0, sun4_75, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1990, sun4_40, sun4_300, 0, sun4_40, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +COMP( 1991, sun4_50, sun4_300, 0, sun4_50, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 199?, sun4_20, sun4_300, 0, sun4_20, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1989, sun4_60, sun4_300, 0, sun4_60, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +COMP( 1990, sun4_65, sun4_300, 0, sun4_65, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation 1+ (Sun 4/65)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1990, sun4_75, sun4_300, 0, sun4_75, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // sun4m (using the SPARC "reference MMU", probably will go to a separate driver) -COMP( 1992, sun_s10, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 1994, sun_s20, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1992, sun_s10, sun4_300, 0, sun4c, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1994, sun_s20, sun4_300, 0, sun4c, sun4, sun4c_state, empty_init, "Sun Microsystems", "SPARCstation 20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |