From 48c0c4a2691063206451dd75570d93409ff57834 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sun, 18 Nov 2018 00:44:15 +0100 Subject: sgi: Various minor fixes and improvements, nw --- scripts/target/mame/mess.lua | 2 + src/mame/drivers/indigo.cpp | 836 ++++---------------------------------- src/mame/drivers/indy_indigo2.cpp | 37 +- src/mame/drivers/o2.cpp | 1 + src/mame/machine/hpc1.cpp | 725 +++++++++++++++++++++++++++++++++ src/mame/machine/hpc1.h | 136 +++++++ src/mame/machine/hpc3.h | 4 +- src/mame/machine/sgi.cpp | 494 ++++++++++++---------- src/mame/machine/sgi.h | 25 +- 9 files changed, 1264 insertions(+), 996 deletions(-) create mode 100644 src/mame/machine/hpc1.cpp create mode 100644 src/mame/machine/hpc1.h diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 202c06ba876..5c800e9fefd 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3020,6 +3020,8 @@ files { MAME_DIR .. "src/mame/machine/sgi.h", MAME_DIR .. "src/mame/machine/hal2.cpp", MAME_DIR .. "src/mame/machine/hal2.h", + MAME_DIR .. "src/mame/machine/hpc1.cpp", + MAME_DIR .. "src/mame/machine/hpc1.h", MAME_DIR .. "src/mame/machine/hpc3.cpp", MAME_DIR .. "src/mame/machine/hpc3.h", MAME_DIR .. "src/mame/machine/ioc2.cpp", diff --git a/src/mame/drivers/indigo.cpp b/src/mame/drivers/indigo.cpp index 6e177d7a56c..66f9271de16 100644 --- a/src/mame/drivers/indigo.cpp +++ b/src/mame/drivers/indigo.cpp @@ -1,61 +1,40 @@ // license:BSD-3-Clause // copyright-holders:Ryan Holtz -/*********************************************************************\ -* -* SGI Indigo workstation -* -* Skeleton Driver -* -* Todo: Everything -* -* Memory map: -* -* 1fa00000 - 1fa02047 Memory Controller -* 1fb80000 - 1fb9a7ff HPC1 CHIP0 -* 1fc00000 - 1fc7ffff BIOS -* -\*********************************************************************/ +/********************************************************************* + + SGI Indigo workstation + + To-Do: + - IP12 (R3000): + * Everything + - IP20 (R4000): + * Figure out why the keyboard/mouse diagnostic fails + * Work out a proper RAM mapping, or why the installer bails due + to trying to access virtual address ffffa02c: + 88002584: lw $sp,-$5fd4($0) + +**********************************************************************/ #include "emu.h" -#include "bus/rs232/rs232.h" -#include "bus/rs232/hlemouse.h" -#include "bus/scsi/scsi.h" -#include "bus/scsi/scsicd512.h" -#include "bus/scsi/scsihd.h" -#include "bus/sgikbd/sgikbd.h" //#include "cpu/dsp56k/dsp56k.h" #include "cpu/mips/mips1.h" #include "cpu/mips/mips3.h" -#include "machine/dp8573.h" #include "machine/eepromser.h" -#include "machine/pit8253.h" +#include "machine/hpc1.h" #include "machine/sgi.h" -#include "machine/wd33c93.h" -#include "machine/z80scc.h" #include "emupal.h" #include "screen.h" -#include "speaker.h" #define ENABLE_ENTRY_GFX (1) #define LOG_UNKNOWN (1 << 0) #define LOG_INT (1 << 1) -#define LOG_HPC (1 << 2) -#define LOG_EEPROM (1 << 4) -#define LOG_DMA (1 << 5) -#define LOG_SCSI (1 << 6) -#define LOG_SCSI_DMA (1 << 7) -#define LOG_DUART0 (1 << 8) -#define LOG_DUART1 (1 << 9) -#define LOG_DUART2 (1 << 10) -#define LOG_PIT (1 << 11) -#define LOG_DSP (1 << 12) -#define LOG_GFX (1 << 13) -#define LOG_GFX_CMD (1 << 14) -#define LOG_DUART (LOG_DUART0 | LOG_DUART1 | LOG_DUART2) -#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_HPC | LOG_EEPROM | LOG_DMA | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT | LOG_DSP | LOG_GFX | LOG_GFX_CMD) - -#define VERBOSE (LOG_ALL & ~(LOG_DUART0 | LOG_DUART1 | LOG_SCSI | LOG_SCSI_DMA | LOG_EEPROM | LOG_PIT | LOG_DSP)) +#define LOG_DSP (1 << 2) +#define LOG_GFX (1 << 3) +#define LOG_GFX_CMD (1 << 4) +#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_DSP | LOG_GFX | LOG_GFX_CMD) + +#define VERBOSE (LOG_UNKNOWN) #include "logmacro.h" class indigo_state : public driver_device @@ -63,12 +42,9 @@ class indigo_state : public driver_device public: indigo_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_wd33c93(*this, "wd33c93") - , m_scc(*this, "scc%u", 0U) + , m_hpc(*this, "hpc") , m_eeprom(*this, "eeprom") - , m_pit(*this, "pit") - , m_rtc(*this, "rtc") + , m_share1(*this, "share1") , m_dsp_ram(*this, "dspram") , m_palette(*this, "palette") { @@ -80,59 +56,19 @@ protected: virtual void machine_start() override; virtual void machine_reset() override; - DECLARE_READ32_MEMBER(hpc_r); - DECLARE_WRITE32_MEMBER(hpc_w); DECLARE_READ32_MEMBER(int_r); DECLARE_WRITE32_MEMBER(int_w); DECLARE_READ32_MEMBER(dsp_ram_r); DECLARE_WRITE32_MEMBER(dsp_ram_w); DECLARE_READ32_MEMBER(entry_r); DECLARE_WRITE32_MEMBER(entry_w); - DECLARE_WRITE_LINE_MEMBER(scsi_irq); - - void set_timer_int_clear(uint32_t data); - DECLARE_WRITE_LINE_MEMBER(timer0_int); - DECLARE_WRITE_LINE_MEMBER(timer1_int); - DECLARE_WRITE_LINE_MEMBER(timer2_int); - DECLARE_WRITE_LINE_MEMBER(duart0_int_w); - DECLARE_WRITE_LINE_MEMBER(duart1_int_w); - DECLARE_WRITE_LINE_MEMBER(duart2_int_w); - - void duart_int_w(int channel, int status); - void raise_local_irq(int channel, uint8_t source_mask); - void lower_local_irq(int channel, uint8_t source_mask); - void update_irq(int channel); - - void fetch_chain(address_space &space); - void advance_chain(address_space &space); - void scsi_dma(); void do_rex_command(); - static void cdrom_config(device_t *device); void indigo_map(address_map &map); uint32_t screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect); - enum - { - LOCAL0_FIFO_GIO0 = 0x01, - LOCAL0_PARALLEL = 0x02, - LOCAL0_SCSI = 0x04, - LOCAL0_ETHERNET = 0x08, - LOCAL0_GFX_DMA = 0x10, - LOCAL0_DUART = 0x20, - LOCAL0_GIO1 = 0x40, - LOCAL0_VME0 = 0x80, - - LOCAL1_GR1_CASE = 0x02, - LOCAL1_VME1 = 0x08, - LOCAL1_DSP = 0x10, - LOCAL1_ACFAIL = 0x20, - LOCAL1_VIDEO = 0x40, - LOCAL1_RETRACE_GIO2 = 0x80 - }; - enum { REX15_PAGE0_SET = 0x00000000, @@ -179,27 +115,6 @@ protected: REX15_CONTROL = 0x06 }; - struct hpc_t - { - uint8_t m_misc_status; - uint32_t m_cpu_aux_ctrl; - uint32_t m_parbuf_ptr; - uint32_t m_local_int_status[2]; - uint32_t m_local_int_mask[2]; - bool m_int_status[2]; - uint32_t m_vme_intmask0; - uint32_t m_vme_intmask1; - uint32_t m_scsi0_dma_desc; - uint32_t m_scsi0_dma_ctrl; - uint32_t m_scsi0_dma_addr; - uint32_t m_scsi0_dma_flag; - uint32_t m_scsi0_dma_next; - uint16_t m_scsi0_dma_length; - bool m_scsi0_dma_to_mem; - bool m_scsi0_dma_active; - bool m_scsi0_dma_end; - }; - struct lg1_t { uint32_t m_config_sel; @@ -223,56 +138,27 @@ protected: uint8_t m_palette_idx; uint8_t m_palette_channel; uint8_t m_palette_entry[3]; - bool m_waiting_for_palette_addr; uint8_t m_pix_read_mask[256]; }; - enum - { - HPC_DMACTRL_RESET = 0x01, - HPC_DMACTRL_FLUSH = 0x02, - HPC_DMACTRL_TO_MEM = 0x10, - HPC_DMACTRL_ENABLE = 0x80 - }; - - required_device m_maincpu; - required_device m_wd33c93; - required_device_array m_scc; + required_device m_hpc; required_device m_eeprom; - required_device m_pit; - required_device m_rtc; + required_shared_ptr m_share1; required_shared_ptr m_dsp_ram; required_device m_palette; - hpc_t m_hpc; + address_space *m_space; + lg1_t m_lg1; std::unique_ptr m_framebuffer; - uint8_t m_duart_int_status; - - static char const *const RS232A_TAG; - static char const *const RS232B_TAG; - - static const XTAL SCC_PCLK; - static const XTAL SCC_RXA_CLK; - static const XTAL SCC_TXA_CLK; - static const XTAL SCC_RXB_CLK; - static const XTAL SCC_TXB_CLK; }; -/*static*/ char const *const indigo_state::RS232A_TAG = "rs232a"; -/*static*/ char const *const indigo_state::RS232B_TAG = "rs232b"; - -/*static*/ const XTAL indigo_state::SCC_PCLK = 10_MHz_XTAL; -/*static*/ const XTAL indigo_state::SCC_RXA_CLK = 3.6864_MHz_XTAL; // Needs verification -/*static*/ const XTAL indigo_state::SCC_TXA_CLK = XTAL(0); -/*static*/ const XTAL indigo_state::SCC_RXB_CLK = 3.6864_MHz_XTAL; // Needs verification -/*static*/ const XTAL indigo_state::SCC_TXB_CLK = XTAL(0); - class indigo3k_state : public indigo_state { public: indigo3k_state(const machine_config &mconfig, device_type type, const char *tag) : indigo_state(mconfig, type, tag) + , m_maincpu(*this, "maincpu") { } @@ -280,6 +166,8 @@ public: protected: void mem_map(address_map &map); + + required_device m_maincpu; }; class indigo4k_state : public indigo_state @@ -287,38 +175,28 @@ class indigo4k_state : public indigo_state public: indigo4k_state(const machine_config &mconfig, device_type type, const char *tag) : indigo_state(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_mem_ctrl(*this, "memctrl") { } void indigo4k(machine_config &config); protected: + virtual void machine_reset() override; + void mem_map(address_map &map); + + DECLARE_WRITE32_MEMBER(write_ram); + + required_device m_maincpu; + required_device m_mem_ctrl; }; void indigo_state::machine_start() { m_framebuffer = std::make_unique(1024*768); - save_item(NAME(m_hpc.m_misc_status)); - save_item(NAME(m_hpc.m_cpu_aux_ctrl)); - save_item(NAME(m_hpc.m_parbuf_ptr)); - save_item(NAME(m_hpc.m_local_int_status)); - save_item(NAME(m_hpc.m_local_int_mask)); - save_item(NAME(m_hpc.m_int_status)); - save_item(NAME(m_hpc.m_vme_intmask0)); - save_item(NAME(m_hpc.m_vme_intmask1)); - - save_item(NAME(m_hpc.m_scsi0_dma_desc)); - save_item(NAME(m_hpc.m_scsi0_dma_ctrl)); - save_item(NAME(m_hpc.m_scsi0_dma_addr)); - save_item(NAME(m_hpc.m_scsi0_dma_flag)); - save_item(NAME(m_hpc.m_scsi0_dma_next)); - save_item(NAME(m_hpc.m_scsi0_dma_length)); - save_item(NAME(m_hpc.m_scsi0_dma_to_mem)); - save_item(NAME(m_hpc.m_scsi0_dma_active)); - save_item(NAME(m_hpc.m_scsi0_dma_end)); - save_item(NAME(m_lg1.m_config_sel)); save_item(NAME(m_lg1.m_write_addr)); save_item(NAME(m_lg1.m_control)); @@ -338,538 +216,23 @@ void indigo_state::machine_start() save_item(NAME(m_lg1.m_palette_idx)); save_item(NAME(m_lg1.m_palette_channel)); save_item(NAME(m_lg1.m_palette_entry)); - save_item(NAME(m_lg1.m_waiting_for_palette_addr)); save_item(NAME(m_lg1.m_pix_read_mask)); - save_item(NAME(m_duart_int_status)); - save_pointer(NAME(&m_framebuffer[0]), 1024*768); } void indigo_state::machine_reset() { - memset(&m_hpc, 0, sizeof(hpc_t)); memset(&m_lg1, 0, sizeof(lg1_t)); memset(&m_framebuffer[0], 0, 1024*768); - m_duart_int_status = 0; -} - -READ32_MEMBER(indigo_state::hpc_r) -{ - if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) - return m_rtc->read(space, offset - 0xe00/4); - - switch (offset) - { - case 0x005c/4: - LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: HPC Unknown Read: %08x & %08x\n", - machine().describe_context(), 0x1fb80000 + offset*4, mem_mask); - return 0; - case 0x0094/4: - LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_scsi0_dma_ctrl, mem_mask); - return m_hpc.m_scsi0_dma_ctrl; - case 0x00ac/4: - LOGMASKED(LOG_HPC, "%s: HPC Parallel Buffer Pointer Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_parbuf_ptr, mem_mask); - return m_hpc.m_parbuf_ptr; - case 0x00c0/4: - LOGMASKED(LOG_HPC, "%s: HPC Endianness Read: %08x & %08x\n", machine().describe_context(), 0x00000040, mem_mask); - return 0x00000040; - case 0x0120/4: - { - uint32_t ret = m_wd33c93->read(space, 0) << 8; - LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); - return ret; - } - case 0x0124/4: - { - uint32_t ret = m_wd33c93->read(space, 1) << 8; - LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); - return ret; - } - case 0x01b0/4: - LOGMASKED(LOG_HPC, "%s: HPC Misc. Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_misc_status, mem_mask); - return m_hpc.m_misc_status; - case 0x01bc/4: - { - uint32_t ret = (m_hpc.m_cpu_aux_ctrl & ~0x10) | m_eeprom->do_read() << 4; - LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); - return ret; - } - case 0x01c0/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_status[0], mem_mask); - return m_hpc.m_local_int_status[0]; - case 0x01c4/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Mask Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_mask[0], mem_mask); - return m_hpc.m_local_int_mask[0]; - case 0x01c8/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_status[1], mem_mask); - return m_hpc.m_local_int_status[1]; - case 0x01cc/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Mask Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_mask[1], mem_mask); - return m_hpc.m_local_int_mask[1]; - case 0x01d4/4: - LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 0 Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_vme_intmask0, mem_mask); - return m_hpc.m_vme_intmask0; - case 0x01d8/4: - LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 1 Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_vme_intmask1, mem_mask); - return m_hpc.m_vme_intmask1; - case 0x01f0/4: - { - const uint8_t data = m_pit->read(0); - LOGMASKED(LOG_PIT, "%s: Read Timer Count0 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); - return data; - } - case 0x01f4/4: - { - const uint8_t data = m_pit->read(1); - LOGMASKED(LOG_PIT, "%s: Read Timer Count1 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); - return data; - } - case 0x01f8/4: - { - const uint8_t data = m_pit->read(2); - LOGMASKED(LOG_PIT, "%s: Read Timer Count2 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); - return data; - } - case 0x01fc/4: - { - const uint8_t data = m_pit->read(3); - LOGMASKED(LOG_PIT, "%s: Read Timer Control Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); - return data; - } - case 0x0d00/4: - case 0x0d10/4: - case 0x0d20/4: - { - const uint32_t index = (offset >> 2) & 3; - uint32_t ret = m_scc[index]->ba_cd_r(space, 3); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); - return ret; - } - case 0x0d04/4: - case 0x0d14/4: - case 0x0d24/4: - { - const uint32_t index = (offset >> 2) & 3; - const uint32_t ret = m_scc[index]->ba_cd_r(space, 2); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); - return ret; - } - case 0x0d08/4: - case 0x0d18/4: - case 0x0d28/4: - { - const uint32_t index = (offset >> 2) & 3; - const uint32_t ret = m_scc[index]->ba_cd_r(space, 1); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); - return ret; - } - case 0x0d0c/4: - case 0x0d1c/4: - case 0x0d2c/4: - { - const uint32_t index = (offset >> 2) & 3; - const uint32_t ret = m_scc[index]->ba_cd_r(space, 0); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); - return ret; - } - default: - LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: Unknown HPC Read: %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, mem_mask); - return 0; - } - return 0; -} - -void indigo_state::fetch_chain(address_space &space) -{ - m_hpc.m_scsi0_dma_flag = space.read_dword(m_hpc.m_scsi0_dma_desc); - m_hpc.m_scsi0_dma_addr = space.read_dword(m_hpc.m_scsi0_dma_desc+4); - m_hpc.m_scsi0_dma_next = space.read_dword(m_hpc.m_scsi0_dma_desc+8); - m_hpc.m_scsi0_dma_length = m_hpc.m_scsi0_dma_flag & 0x1fff; - LOGMASKED(LOG_SCSI_DMA, "Fetched SCSI DMA Descriptor block:\n"); - LOGMASKED(LOG_SCSI_DMA, " Ctrl: %08x\n", m_hpc.m_scsi0_dma_flag); - LOGMASKED(LOG_SCSI_DMA, " Addr: %08x\n", m_hpc.m_scsi0_dma_addr); - LOGMASKED(LOG_SCSI_DMA, " Next: %08x\n", m_hpc.m_scsi0_dma_next); - LOGMASKED(LOG_SCSI_DMA, " Length: %04x\n", m_hpc.m_scsi0_dma_length); - m_hpc.m_scsi0_dma_end = BIT(m_hpc.m_scsi0_dma_addr, 31); - m_hpc.m_scsi0_dma_addr &= 0x0fffffff; - m_hpc.m_scsi0_dma_next &= 0x0fffffff; -} - -void indigo_state::advance_chain(address_space &space) -{ - m_hpc.m_scsi0_dma_addr++; - m_hpc.m_scsi0_dma_length--; - if (m_hpc.m_scsi0_dma_length == 0) - { - if (m_hpc.m_scsi0_dma_end) - { - LOGMASKED(LOG_SCSI_DMA, "HPC: Disabling SCSI DMA due to end of chain\n"); - m_hpc.m_scsi0_dma_active = false; - m_hpc.m_scsi0_dma_ctrl &= ~HPC_DMACTRL_ENABLE; - } - else - { - m_hpc.m_scsi0_dma_desc = m_hpc.m_scsi0_dma_next; - fetch_chain(space); - } - } -} - -WRITE32_MEMBER(indigo_state::hpc_w) -{ - if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) - { - m_rtc->write(space, offset - 0xe00/4, (uint8_t)data); - return; - } - - switch (offset) - { - case 0x0090/4: - LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Descriptor Pointer Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_scsi0_dma_desc = data; - fetch_chain(space); - break; - - case 0x0094/4: - LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_scsi0_dma_ctrl = data &~ (HPC_DMACTRL_FLUSH | HPC_DMACTRL_RESET); - m_hpc.m_scsi0_dma_to_mem = (m_hpc.m_scsi0_dma_ctrl & HPC_DMACTRL_TO_MEM); - m_hpc.m_scsi0_dma_active = (m_hpc.m_scsi0_dma_ctrl & HPC_DMACTRL_ENABLE); - break; - - case 0x00ac/4: - LOGMASKED(LOG_HPC, "%s: HPC Parallel Buffer Pointer Write: %08x (%08x)\n", machine().describe_context(), data, mem_mask); - m_hpc.m_parbuf_ptr = data; - break; - case 0x0120/4: - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_wd33c93->write(space, 0, (uint8_t)(data >> 8)); - } - break; - case 0x0124/4: - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Data Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_wd33c93->write(space, 1, (uint8_t)(data >> 8)); - } - break; - case 0x01b0/4: - LOGMASKED(LOG_HPC, "%s: HPC Misc. Status Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - if (BIT(data, 0)) - LOGMASKED(LOG_HPC, " Force DSP hard reset\n" ); - - if (BIT(data, 1)) - LOGMASKED(LOG_HPC, " Force IRQA\n" ); - - if (BIT(data, 2)) - LOGMASKED(LOG_HPC, " Set IRQA polarity high\n" ); - else - LOGMASKED(LOG_HPC, " Set IRQA polarity low\n" ); - - if (BIT(data, 3)) - LOGMASKED(LOG_HPC, " SRAM size: 32K\n" ); - else - LOGMASKED(LOG_HPC, " SRAM size: 8K\n" ); - - m_hpc.m_misc_status = data; - break; - case 0x01bc/4: - m_hpc.m_cpu_aux_ctrl = data; - LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask ); - if (BIT(data, 0)) - { - LOGMASKED(LOG_EEPROM, " CPU board LED on\n"); - } - m_eeprom->di_write(BIT(data, 3)); - m_eeprom->cs_write(BIT(data, 1)); - m_eeprom->clk_write(BIT(data, 2)); - break; - case 0x01c0/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask); - break; - case 0x01c4/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_local_int_mask[0] = data; - break; - case 0x01c8/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask); - break; - case 0x01cc/4: - LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_local_int_mask[1] = data; - break; - case 0x01d4/4: - LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_vme_intmask0 = data; - break; - case 0x01d8/4: - LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_hpc.m_vme_intmask1 = data; - break; - case 0x01e0/4: - LOGMASKED(LOG_PIT, "%s: HPC Write Timer Interrupt Clear Register: %08x\n", machine().describe_context(), data); - set_timer_int_clear(data); - break; - case 0x01f0/4: - LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count0 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - if (ACCESSING_BITS_24_31) - m_pit->write(0, (uint8_t)(data >> 24)); - else if (ACCESSING_BITS_0_7) - m_pit->write(0, (uint8_t)data); - return; - case 0x01f4/4: - LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count1 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_pit->write(1, (uint8_t)data); - return; - case 0x01f8/4: - LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count2 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_pit->write(2, (uint8_t)data); - return; - case 0x01fc/4: - LOGMASKED(LOG_PIT, "%s: HPC Write Timer Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_pit->write(3, (uint8_t)data); - return; - case 0x0d00/4: - case 0x0d10/4: - case 0x0d20/4: - { - const uint32_t index = (offset >> 2) & 3; - m_scc[index]->ba_cd_w(space, 3, (uint8_t)data); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); - break; - } - case 0x0d04/4: - case 0x0d14/4: - case 0x0d24/4: - { - const uint32_t index = (offset >> 2) & 3; - m_scc[index]->ba_cd_w(space, 2, (uint8_t)data); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); - break; - } - case 0x0d08/4: - case 0x0d18/4: - case 0x0d28/4: - { - const uint32_t index = (offset >> 2) & 3; - m_scc[index]->ba_cd_w(space, 1, (uint8_t)data); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); - break; - } - case 0x0d0c/4: - case 0x0d1c/4: - case 0x0d2c/4: - { - const uint32_t index = (offset >> 2) & 3; - m_scc[index]->ba_cd_w(space, 0, (uint8_t)data); - LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); - break; - } - default: - LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: Unknown HPC write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, data, mem_mask); - break; - } -} - -void indigo_state::scsi_dma() -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - int byte_count = m_wd33c93->get_dma_count(); - - LOGMASKED(LOG_SCSI_DMA, "HPC: Transferring %d bytes %s %08x %s SCSI0\n", - byte_count, m_hpc.m_scsi0_dma_to_mem ? "to" : "from", m_hpc.m_scsi0_dma_addr, m_hpc.m_scsi0_dma_to_mem ? "from" : "to"); - - uint8_t dma_buffer[512]; - if (m_hpc.m_scsi0_dma_to_mem) - { - // HPC SCSI DMA: device to host - if (byte_count <= 512) - { - m_wd33c93->dma_read_data(byte_count, dma_buffer); - - for (int i = 0; i < byte_count; i++) - { - LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr); - space.write_byte(m_hpc.m_scsi0_dma_addr, dma_buffer[i]); - advance_chain(space); - if (!m_hpc.m_scsi0_dma_active) - break; - } - } - else - { - while (byte_count) - { - int sub_count = m_wd33c93->dma_read_data(512, dma_buffer); - - for (int i = 0; i < sub_count; i++) - { - LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr); - space.write_byte(m_hpc.m_scsi0_dma_addr, dma_buffer[i]); - advance_chain(space); - if (!m_hpc.m_scsi0_dma_active) - break; - } - - byte_count -= sub_count; - if (!m_hpc.m_scsi0_dma_active) - break; - } - } - } - else - { - // HPC SCSI DMA: host to device - if (byte_count <= 512) - { - for (int i = 0; i < byte_count; i++) - { - dma_buffer[i] = space.read_byte(m_hpc.m_scsi0_dma_addr); - LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr); - advance_chain(space); - if (!m_hpc.m_scsi0_dma_active) - break; - } - - m_wd33c93->dma_write_data(byte_count, dma_buffer); - } - else - { - while (byte_count) - { - int sub_count = std::min(512, byte_count); - - for (int i = 0; i < sub_count; i++) - { - dma_buffer[i] = space.read_byte(m_hpc.m_scsi0_dma_addr); - LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr); - advance_chain(space); - if (!m_hpc.m_scsi0_dma_active) - break; - } - - m_wd33c93->dma_write_data(sub_count, dma_buffer); - - if (!m_hpc.m_scsi0_dma_active) - { - break; - } - else - { - byte_count -= sub_count; - } - } - } - } - - // clear DMA on the controller - m_wd33c93->clear_dma(); -} - -WRITE_LINE_MEMBER(indigo_state::scsi_irq) -{ - if (state) - { - LOGMASKED(LOG_SCSI, "SCSI: Set IRQ\n"); - int count = m_wd33c93->get_dma_count(); - LOGMASKED(LOG_SCSI_DMA, "SCSI: count %d, active %d\n", count, m_hpc.m_scsi0_dma_active); - if (count && m_hpc.m_scsi0_dma_active) - scsi_dma(); - - raise_local_irq(0, LOCAL0_SCSI); - } - else - { - LOGMASKED(LOG_SCSI, "SCSI: Clear IRQ\n"); - lower_local_irq(0, LOCAL0_SCSI); - } -} - -void indigo_state::set_timer_int_clear(uint32_t data) -{ - if (BIT(data, 0)) - { - LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 0 Interrupt: %d\n", data); - m_maincpu->set_input_line(MIPS3_IRQ2, CLEAR_LINE); - } - if (BIT(data, 1)) - { - LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 1 Interrupt: %d\n", data); - m_maincpu->set_input_line(MIPS3_IRQ3, CLEAR_LINE); - } } -WRITE_LINE_MEMBER(indigo_state::timer0_int) +void indigo4k_state::machine_reset() { - LOGMASKED(LOG_PIT, "Timer0 Interrupt: %d\n", state); - if (state) - m_maincpu->set_input_line(MIPS3_IRQ2, ASSERT_LINE); -} - -WRITE_LINE_MEMBER(indigo_state::timer1_int) -{ - LOGMASKED(LOG_PIT, "Timer2 Interrupt: %d\n", state); - if (state) - m_maincpu->set_input_line(MIPS3_IRQ3, ASSERT_LINE); -} + indigo_state::machine_reset(); -WRITE_LINE_MEMBER(indigo_state::timer2_int) -{ - LOGMASKED(LOG_PIT, "Timer2 Interrupt (Disabled): %d\n", state); -} - -WRITE_LINE_MEMBER(indigo_state::duart0_int_w) { duart_int_w(0, state); } -WRITE_LINE_MEMBER(indigo_state::duart1_int_w) { duart_int_w(1, state); } -WRITE_LINE_MEMBER(indigo_state::duart2_int_w) { duart_int_w(2, state); } - -void indigo_state::duart_int_w(int channel, int state) -{ - m_duart_int_status &= ~(1 << channel); - m_duart_int_status |= state << channel; - - if (m_duart_int_status) - { - LOGMASKED(LOG_DUART0 << channel, "Raising DUART Interrupt: %02x\n", m_duart_int_status); - raise_local_irq(0, LOCAL0_DUART); - } - else - { - LOGMASKED(LOG_DUART0 << channel, "Lowering DUART Interrupt\n"); - lower_local_irq(0, LOCAL0_DUART); - } -} - -void indigo_state::raise_local_irq(int channel, uint8_t source_mask) -{ - m_hpc.m_local_int_status[channel] |= source_mask; - - bool old_status = m_hpc.m_int_status[channel]; - m_hpc.m_int_status[channel] = (m_hpc.m_local_int_status[channel] & m_hpc.m_local_int_mask[channel]); - - if (old_status != m_hpc.m_int_status[channel]) - update_irq(channel); -} - -void indigo_state::lower_local_irq(int channel, uint8_t source_mask) -{ - m_hpc.m_local_int_status[channel] &= ~source_mask; - - bool old_status = m_hpc.m_int_status[channel]; - m_hpc.m_int_status[channel] = (m_hpc.m_local_int_status[channel] & m_hpc.m_local_int_mask[channel]); - - if (old_status != m_hpc.m_int_status[channel]) - update_irq(channel); -} - -void indigo_state::update_irq(int channel) -{ - LOGMASKED(LOG_INT, "%s IRQ%d: %02x & %02x\n", channel, m_hpc.m_int_status[channel] ? "Asserting" : "Clearing", - m_hpc.m_local_int_status[channel], m_hpc.m_local_int_mask[channel]); - m_maincpu->set_input_line(MIPS3_IRQ0, m_hpc.m_int_status[channel] ? ASSERT_LINE : CLEAR_LINE); + // set up low RAM mirror + membank("bank1")->set_base(m_share1); } READ32_MEMBER(indigo_state::int_r) @@ -1150,12 +513,8 @@ uint32_t indigo_state::screen_update(screen_device &device, bitmap_rgb32 &bitmap void indigo_state::indigo_map(address_map &map) { - map(0x00000000, 0x0007ffff).ram().share("share1"); - map(0x08000000, 0x0fffffff).ram().share("share2"); - map(0x10000000, 0x13ffffff).ram().share("share3"); - map(0x18000000, 0x1bffffff).ram().share("share4"); map(0x1f3f0000, 0x1f3fffff).rw(FUNC(indigo_state::entry_r), FUNC(indigo_state::entry_w)); - map(0x1fb80000, 0x1fb8ffff).rw(FUNC(indigo_state::hpc_r), FUNC(indigo_state::hpc_w)); + map(0x1fb80000, 0x1fb8ffff).rw(m_hpc, FUNC(hpc1_device::read), FUNC(hpc1_device::write)); map(0x1fbd9000, 0x1fbd903f).rw(FUNC(indigo_state::int_r), FUNC(indigo_state::int_w)); map(0x1fbe0000, 0x1fbfffff).rw(FUNC(indigo_state::dsp_ram_r), FUNC(indigo_state::dsp_ram_w)).share("dspram"); } @@ -1163,32 +522,41 @@ void indigo_state::indigo_map(address_map &map) void indigo3k_state::mem_map(address_map &map) { indigo_map(map); - map(0x1fc00000, 0x1fc3ffff).rom().share("share5").region("user1", 0); + map(0x1fc00000, 0x1fc3ffff).rom().share("share10").region("user1", 0); } -void indigo4k_state::mem_map(address_map &map) +WRITE32_MEMBER(indigo4k_state::write_ram) { - indigo_map(map); - map(0x1fa00000, 0x1fa1ffff).rw("sgi_mc", FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write)); - map(0x1fc00000, 0x1fc7ffff).rom().share("share5").region("user1", 0); -} + // if banks 2 or 3 are enabled, kill it, we only want 128MB + if (m_mem_ctrl->read(space, 0xc8/4, 0xffffffff) & 0x10001000) + { + // a random perturbation so the memory test fails + data ^= 0xffffffff; + } -static INPUT_PORTS_START( indigo ) - PORT_START("unused") - PORT_BIT ( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) -INPUT_PORTS_END + // if banks 0 or 1 have 2 membanks, also kill it, we only want 128MB + if (m_mem_ctrl->read(space, 0xc0/4, 0xffffffff) & 0x40004000) + { + // a random perturbation so the memory test fails + data ^= 0xffffffff; + } -void indigo_state::cdrom_config(device_t *device) -{ - cdda_device *cdda = device->subdevice("cdda"); - cdda->add_route(ALL_OUTPUTS, ":mono", 1.0); + COMBINE_DATA(&m_share1[offset & 0x03ffffff]); } -static void indigo_mice(device_slot_interface &device) +void indigo4k_state::mem_map(address_map &map) { - device.option_add("sgimouse", SGI_HLE_SERIAL_MOUSE); + indigo_map(map); + map(0x00000000, 0x0007ffff).bankrw("bank1"); + map(0x08000000, 0x17ffffff).ram().share("share1").w(FUNC(indigo4k_state::write_ram)); /* 128 MB of main RAM */ + map(0x1fa00000, 0x1fa1ffff).rw(m_mem_ctrl, FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write)); + map(0x1fc00000, 0x1fc7ffff).rom().share("share5").region("user1", 0); + map(0x20000000, 0x27ffffff).ram().share("share1").w(FUNC(indigo4k_state::write_ram)); /* 128 MB of main RAM */ } +static INPUT_PORTS_START(indigo) +INPUT_PORTS_END + void indigo_state::indigo_base(machine_config &config) { /* video hardware */ @@ -1201,65 +569,7 @@ void indigo_state::indigo_base(machine_config &config) PALETTE(config, m_palette, 256); - SPEAKER(config, "mono").front_center(); - - SCC8530N(config, m_scc[0], SCC_PCLK); - m_scc[0]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); - m_scc[0]->out_int_callback().set(FUNC(indigo_state::duart0_int_w)); - m_scc[0]->out_txda_callback().set("keyboard", FUNC(sgi_keyboard_port_device::write_txd)); - - SCC8530N(config, m_scc[1], SCC_PCLK); - m_scc[1]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); - m_scc[1]->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd)); - m_scc[1]->out_dtra_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_dtr)); - m_scc[1]->out_rtsa_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_rts)); - m_scc[1]->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd)); - m_scc[1]->out_dtrb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_dtr)); - m_scc[1]->out_rtsb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_rts)); - m_scc[1]->out_int_callback().set(FUNC(indigo_state::duart1_int_w)); - - SCC8530N(config, m_scc[2], SCC_PCLK); - m_scc[2]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); - m_scc[2]->out_int_callback().set(FUNC(indigo_state::duart2_int_w)); - - SGIKBD_PORT(config, "keyboard", default_sgi_keyboard_devices, "hlekbd").rxd_handler().set(m_scc[0], FUNC(z80scc_device::rxa_w)); - - rs232_port_device &mouseport(RS232_PORT(config, "mouseport", indigo_mice, "sgimouse")); - mouseport.set_fixed(true); - mouseport.rxd_handler().set(m_scc[0], FUNC(scc8530_device::rxa_w)); - mouseport.cts_handler().set(m_scc[0], FUNC(scc8530_device::ctsa_w)); - mouseport.dcd_handler().set(m_scc[0], FUNC(scc8530_device::dcda_w)); - - rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr)); - rs232a.cts_handler().set(m_scc[1], FUNC(scc8530_device::ctsa_w)); - rs232a.dcd_handler().set(m_scc[1], FUNC(scc8530_device::dcda_w)); - rs232a.rxd_handler().set(m_scc[1], FUNC(scc8530_device::rxa_w)); - - rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr)); - rs232b.cts_handler().set(m_scc[1], FUNC(scc8530_device::ctsb_w)); - rs232b.dcd_handler().set(m_scc[1], FUNC(scc8530_device::dcdb_w)); - rs232b.rxd_handler().set(m_scc[1], FUNC(scc8530_device::rxb_w)); - - scsi_port_device &scsi(SCSI_PORT(config, "scsi")); - scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1)); - scsi.set_slot_device(2, "cdrom", RRD45, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4)); - scsi.slot(2).set_option_machine_config("cdrom", cdrom_config); - - DP8573(config, m_rtc); - - WD33C93(config, m_wd33c93); - m_wd33c93->set_scsi_port("scsi"); - m_wd33c93->irq_cb().set(FUNC(indigo_state::scsi_irq)); - EEPROM_93C56_16BIT(config, m_eeprom); - - PIT8254(config, m_pit, 0); - m_pit->set_clk<0>(1000000); - m_pit->set_clk<1>(1000000); - m_pit->set_clk<2>(1500000); - m_pit->out_handler<0>().set(FUNC(indigo_state::timer0_int)); - m_pit->out_handler<1>().set(FUNC(indigo_state::timer1_int)); - m_pit->out_handler<2>().set(FUNC(indigo_state::timer2_int)); } void indigo3k_state::indigo3k(machine_config &config) @@ -1269,17 +579,21 @@ void indigo3k_state::indigo3k(machine_config &config) R3000A(config, m_maincpu, 33.333_MHz_XTAL, 32768, 32768); downcast(*m_maincpu).set_endianness(ENDIANNESS_BIG); m_maincpu->set_addrmap(AS_PROGRAM, &indigo3k_state::mem_map); + + SGI_HPC1(config, m_hpc, m_maincpu, m_eeprom); } void indigo4k_state::indigo4k(machine_config &config) { indigo_base(config); - mips3_device &cpu(R4400BE(config, m_maincpu, 50000000*3)); + + mips3_device &cpu(R4000BE(config, m_maincpu, 50000000*2)); cpu.set_icache_size(32768); cpu.set_dcache_size(32768); cpu.set_addrmap(AS_PROGRAM, &indigo4k_state::mem_map); - SGI_MC(config, "sgi_mc"); + SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom); + SGI_HPC1(config, m_hpc, m_maincpu, m_eeprom); } ROM_START( indigo3k ) diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 90d035ae60d..bb88f667315 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -67,6 +67,7 @@ #include "cpu/mips/mips3.h" #include "machine/ds1386.h" +#include "machine/eepromser.h" #include "machine/hal2.h" #include "machine/hpc3.h" #include "machine/ioc2.h" @@ -91,6 +92,7 @@ public: , m_mainram(*this, "mainram") , m_mem_ctrl(*this, "memctrl") , m_scsi_ctrl(*this, "wd33c93") + , m_eeprom(*this, "eeprom") , m_ldac(*this, "ldac") , m_rdac(*this, "rdac") , m_newport(*this, "newport") @@ -108,6 +110,8 @@ public: protected: virtual void machine_reset() override; + DECLARE_READ32_MEMBER(eeprom_r); + DECLARE_WRITE32_MEMBER(eeprom_w); DECLARE_READ32_MEMBER(enet_r); DECLARE_WRITE32_MEMBER(enet_w); DECLARE_READ32_MEMBER(eisa_io_r); @@ -127,6 +131,7 @@ protected: required_shared_ptr m_mainram; required_device m_mem_ctrl; required_device m_scsi_ctrl; + required_device m_eeprom; required_device m_ldac; required_device m_rdac; required_device m_newport; @@ -135,7 +140,7 @@ protected: required_device m_ioc2; required_device m_rtc; - inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... ); + uint32_t m_cpu_aux_ctrl; }; /*static*/ char const *const ip22_state::HAL2_TAG = "hal2"; @@ -160,19 +165,21 @@ private: required_device m_scsi_ctrl2; }; -#define VERBOSE_LEVEL ( 0 ) +READ32_MEMBER(ip22_state::eeprom_r) +{ + // Disabled - we don't have a dump from real hardware, and IRIX 5.x freaks out with default contents. + uint32_t ret = (m_cpu_aux_ctrl & ~0x10);// | m_eeprom->do_read() << 4; + logerror("%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; +} -inline void ATTR_PRINTF(3,4) ip22_state::verboselog(int n_level, const char *s_fmt, ... ) +WRITE32_MEMBER(ip22_state::eeprom_w) { - if( VERBOSE_LEVEL >= n_level ) - { - va_list v; - char buf[ 32768 ]; - va_start( v, s_fmt ); - vsprintf( buf, s_fmt, v ); - va_end( v ); - logerror("%08x: %s", m_maincpu->pc(), buf); - } + m_cpu_aux_ctrl = data; + logerror("%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_eeprom->di_write(BIT(data, 3)); + m_eeprom->cs_write(BIT(data, 1)); + m_eeprom->clk_write(BIT(data, 2)); } READ32_MEMBER(ip22_state::enet_r) @@ -232,7 +239,7 @@ void ip22_state::ip22_map(address_map &map) map(0x1fb80000, 0x1fb8ffff).rw(m_hpc3, FUNC(hpc3_device::pbusdma_r), FUNC(hpc3_device::pbusdma_w)); map(0x1fb90000, 0x1fb9ffff).rw(m_hpc3, FUNC(hpc3_device::hd_enet_r), FUNC(hpc3_device::hd_enet_w)); - map(0x1fbb0000, 0x1fbb0003).ram(); /* unknown, but read a lot and discarded */ + map(0x1fbb0008, 0x1fbb000b).rw(FUNC(ip22_state::eeprom_r), FUNC(ip22_state::eeprom_w)); map(0x1fbc0000, 0x1fbc7fff).rw(m_hpc3, FUNC(hpc3_device::hd_r<0>), FUNC(hpc3_device::hd_w<0>)); map(0x1fbd4000, 0x1fbd44ff).rw(FUNC(ip22_state::enet_r), FUNC(ip22_state::enet_w)); map(0x1fbd8000, 0x1fbd83ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write)); @@ -291,7 +298,7 @@ void ip22_state::ip22_base(machine_config &config) NEWPORT_VIDEO(config, m_newport, m_maincpu, m_ioc2); - SGI_MC(config, m_mem_ctrl); + SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom); SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -323,6 +330,8 @@ void ip22_state::ip22_base(machine_config &config) SGI_IOC2_GUINNESS(config, m_ioc2, m_maincpu); DS1386_8K(config, m_rtc, 32768); + + EEPROM_93C56_16BIT(config, m_eeprom); } void ip22_state::ip225015(machine_config &config) diff --git a/src/mame/drivers/o2.cpp b/src/mame/drivers/o2.cpp index 7fd7145fd95..5c2c28b6bb8 100644 --- a/src/mame/drivers/o2.cpp +++ b/src/mame/drivers/o2.cpp @@ -41,6 +41,7 @@ protected: void o2_state::mem_map(address_map &map) { + map(0x00000000, 0x00000fff).ram(); map(0x1fc00000, 0x1fc7ffff).rom().region("user1", 0); } diff --git a/src/mame/machine/hpc1.cpp b/src/mame/machine/hpc1.cpp new file mode 100644 index 00000000000..9dce211eac4 --- /dev/null +++ b/src/mame/machine/hpc1.cpp @@ -0,0 +1,725 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************** + + SGI HPC1 "High-performance Peripheral Controller" emulation + +**********************************************************************/ + +#include "emu.h" +#include "cpu/mips/mips3.h" +#include "bus/rs232/rs232.h" +#include "bus/rs232/hlemouse.h" +#include "bus/scsi/scsi.h" +#include "bus/scsi/scsicd512.h" +#include "bus/scsi/scsihd.h" +#include "bus/sgikbd/sgikbd.h" +#include "machine/hpc1.h" +#include "speaker.h" + +#define LOG_UNKNOWN (1 << 0) +#define LOG_READS (1 << 1) +#define LOG_WRITES (1 << 2) +#define LOG_INT (1 << 3) +#define LOG_EEPROM (1 << 4) +#define LOG_SCSI (1 << 5) +#define LOG_SCSI_DMA (1 << 6) +#define LOG_DUART0 (1 << 7) +#define LOG_DUART1 (1 << 8) +#define LOG_DUART2 (1 << 9) +#define LOG_PIT (1 << 10) +#define LOG_REGS (LOG_UNKNOWN | LOG_READS | LOG_WRITES) +#define LOG_DUART (LOG_DUART0 | LOG_DUART1 | LOG_DUART2) +#define LOG_ALL (LOG_REGS | LOG_INT | LOG_EEPROM | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT) + +#define VERBOSE (LOG_UNKNOWN) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(SGI_HPC1, hpc1_device, "hpc1", "SGI HPC1") + +/*static*/ char const *const hpc1_device::RS232A_TAG = "rs232a"; +/*static*/ char const *const hpc1_device::RS232B_TAG = "rs232b"; + +/*static*/ const XTAL hpc1_device::SCC_PCLK = 10_MHz_XTAL; +/*static*/ const XTAL hpc1_device::SCC_RXA_CLK = 3.6864_MHz_XTAL; // Needs verification +/*static*/ const XTAL hpc1_device::SCC_TXA_CLK = XTAL(0); +/*static*/ const XTAL hpc1_device::SCC_RXB_CLK = 3.6864_MHz_XTAL; // Needs verification +/*static*/ const XTAL hpc1_device::SCC_TXB_CLK = XTAL(0); + +hpc1_device::hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SGI_HPC1, tag, owner, clock) + , m_maincpu(*this, finder_base::DUMMY_TAG) + , m_eeprom(*this, finder_base::DUMMY_TAG) + , m_wd33c93(*this, "wd33c93") + , m_scc(*this, "scc%u", 0U) + , m_pit(*this, "pit") + , m_rtc(*this, "rtc") +{ +} + +void hpc1_device::device_start() +{ + save_item(NAME(m_misc_status)); + save_item(NAME(m_cpu_aux_ctrl)); + save_item(NAME(m_parbuf_ptr)); + save_item(NAME(m_local_int_status)); + save_item(NAME(m_local_int_mask)); + save_item(NAME(m_int_status)); + save_item(NAME(m_vme_int_mask)); + + save_item(NAME(m_scsi_dma.m_desc)); + save_item(NAME(m_scsi_dma.m_ctrl)); + save_item(NAME(m_scsi_dma.m_addr)); + save_item(NAME(m_scsi_dma.m_flag)); + save_item(NAME(m_scsi_dma.m_next)); + save_item(NAME(m_scsi_dma.m_length)); + save_item(NAME(m_scsi_dma.m_to_mem)); + save_item(NAME(m_scsi_dma.m_active)); + save_item(NAME(m_scsi_dma.m_end)); + + save_item(NAME(m_duart_int_status)); +} + +void hpc1_device::device_reset() +{ + m_misc_status = 0; + m_cpu_aux_ctrl = 0; + m_parbuf_ptr = 0; + memset(m_local_int_status, 0, sizeof(uint32_t) * 2); + memset(m_local_int_mask, 0, sizeof(uint32_t) * 2); + memset(m_int_status, 0, sizeof(bool) * 2); + memset(m_vme_int_mask, 0, sizeof(uint32_t) * 2); + + m_scsi_dma.m_desc = 0; + m_scsi_dma.m_ctrl = 0; + m_scsi_dma.m_addr = 0; + m_scsi_dma.m_flag = 0; + m_scsi_dma.m_next = 0; + m_scsi_dma.m_length = 0; + m_scsi_dma.m_to_mem = false; + m_scsi_dma.m_active = false; + m_scsi_dma.m_end = false; + + m_duart_int_status = 0; + + m_cpu_space = &m_maincpu->space(AS_PROGRAM); +} + +//************************************************************************** +// DEVICE HARDWARE +//************************************************************************** + +void hpc1_device::cdrom_config(device_t *device) +{ + cdda_device *cdda = device->subdevice("cdda"); + cdda->add_route(ALL_OUTPUTS, "^^mono", 1.0); +} + +void hpc1_device::indigo_mice(device_slot_interface &device) +{ + device.option_add("sgimouse", SGI_HLE_SERIAL_MOUSE); +} + +void hpc1_device::device_add_mconfig(machine_config &config) +{ + SCC85C30(config, m_scc[0], SCC_PCLK); + m_scc[0]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); + m_scc[0]->out_int_callback().set(FUNC(hpc1_device::duart0_int_w)); + m_scc[0]->out_txda_callback().set("keyboard", FUNC(sgi_keyboard_port_device::write_txd)); + + SCC85C30(config, m_scc[1], SCC_PCLK); + m_scc[1]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); + m_scc[1]->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd)); + m_scc[1]->out_dtra_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_dtr)); + m_scc[1]->out_rtsa_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_rts)); + m_scc[1]->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd)); + m_scc[1]->out_dtrb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_dtr)); + m_scc[1]->out_rtsb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_rts)); + m_scc[1]->out_int_callback().set(FUNC(hpc1_device::duart1_int_w)); + + SCC85C30(config, m_scc[2], SCC_PCLK); + m_scc[2]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value()); + m_scc[2]->out_int_callback().set(FUNC(hpc1_device::duart2_int_w)); + + SGIKBD_PORT(config, "keyboard", default_sgi_keyboard_devices, "hlekbd").rxd_handler().set(m_scc[0], FUNC(z80scc_device::rxa_w)); + + rs232_port_device &mouseport(RS232_PORT(config, "mouseport", indigo_mice, "sgimouse")); + mouseport.set_fixed(true); + mouseport.rxd_handler().set(m_scc[0], FUNC(scc85c30_device::rxb_w)); + mouseport.cts_handler().set(m_scc[0], FUNC(scc85c30_device::ctsb_w)); + mouseport.dcd_handler().set(m_scc[0], FUNC(scc85c30_device::dcdb_w)); + + rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr)); + rs232a.cts_handler().set(m_scc[1], FUNC(scc85c30_device::ctsa_w)); + rs232a.dcd_handler().set(m_scc[1], FUNC(scc85c30_device::dcda_w)); + rs232a.rxd_handler().set(m_scc[1], FUNC(scc85c30_device::rxa_w)); + + rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr)); + rs232b.cts_handler().set(m_scc[1], FUNC(scc85c30_device::ctsb_w)); + rs232b.dcd_handler().set(m_scc[1], FUNC(scc85c30_device::dcdb_w)); + rs232b.rxd_handler().set(m_scc[1], FUNC(scc85c30_device::rxb_w)); + + scsi_port_device &scsi(SCSI_PORT(config, "scsi")); + scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1)); + scsi.set_slot_device(2, "cdrom", RRD45, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4)); + scsi.slot(2).set_option_machine_config("cdrom", cdrom_config); + + DP8573(config, m_rtc); + + WD33C93(config, m_wd33c93); + m_wd33c93->set_scsi_port("scsi"); + m_wd33c93->irq_cb().set(FUNC(hpc1_device::scsi_irq)); + + PIT8254(config, m_pit, 0); + m_pit->set_clk<0>(1000000); + m_pit->set_clk<1>(1000000); + m_pit->set_clk<2>(1000000); + m_pit->out_handler<0>().set(FUNC(hpc1_device::timer0_int)); + m_pit->out_handler<1>().set(FUNC(hpc1_device::timer1_int)); + m_pit->out_handler<2>().set(FUNC(hpc1_device::timer2_int)); + + SPEAKER(config, "mono").front_center(); +} + +//************************************************************************** +// REGISTER ACCESS +//************************************************************************** + +READ32_MEMBER(hpc1_device::read) +{ + if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) + return m_rtc->read(space, offset - 0xe00/4); + + switch (offset) + { + case 0x005c/4: + LOGMASKED(LOG_UNKNOWN, "%s: HPC Unknown Read: %08x & %08x\n", + machine().describe_context(), 0x1fb80000 + offset*4, mem_mask); + return 0; + case 0x0094/4: + LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Read: %08x & %08x\n", machine().describe_context(), m_scsi_dma.m_ctrl, mem_mask); + return m_scsi_dma.m_ctrl; + case 0x00ac/4: + LOGMASKED(LOG_READS, "%s: HPC Parallel Buffer Pointer Read: %08x & %08x\n", machine().describe_context(), m_parbuf_ptr, mem_mask); + return m_parbuf_ptr; + case 0x00c0/4: + LOGMASKED(LOG_READS, "%s: HPC Endianness Read: %08x & %08x\n", machine().describe_context(), 0x00000000, mem_mask); + return 0x00000000; + case 0x0120/4: + { + uint32_t ret = m_wd33c93->read(space, 0) << 8; + LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; + } + case 0x0124/4: + { + uint32_t ret = m_wd33c93->read(space, 1) << 8; + LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; + } + case 0x01b0/4: + LOGMASKED(LOG_READS, "%s: HPC Misc. Status Read: %08x & %08x\n", machine().describe_context(), m_misc_status, mem_mask); + return m_misc_status; + case 0x01bc/4: + { + uint32_t ret = (m_cpu_aux_ctrl & ~0x10) | m_eeprom->do_read() << 4; + LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; + } + case 0x01c0/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Status Read: %08x & %08x\n", machine().describe_context(), m_local_int_status[0], mem_mask); + return m_local_int_status[0]; + case 0x01c4/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Mask Read: %08x & %08x\n", machine().describe_context(), m_local_int_mask[0], mem_mask); + return m_local_int_mask[0]; + case 0x01c8/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Status Read: %08x & %08x\n", machine().describe_context(), m_local_int_status[1], mem_mask); + return m_local_int_status[1]; + case 0x01cc/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Mask Read: %08x & %08x\n", machine().describe_context(), m_local_int_mask[1], mem_mask); + return m_local_int_mask[1]; + case 0x01d4/4: + LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 0 Read: %08x & %08x\n", machine().describe_context(), m_vme_int_mask[0], mem_mask); + return m_vme_int_mask[0]; + case 0x01d8/4: + LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 1 Read: %08x & %08x\n", machine().describe_context(), m_vme_int_mask[1], mem_mask); + return m_vme_int_mask[1]; + case 0x01f0/4: + { + const uint8_t data = m_pit->read(0); + LOGMASKED(LOG_PIT, "%s: Read Timer Count0 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); + return data; + } + case 0x01f4/4: + { + const uint8_t data = m_pit->read(1); + LOGMASKED(LOG_PIT, "%s: Read Timer Count1 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); + return data; + } + case 0x01f8/4: + { + const uint8_t data = m_pit->read(2); + LOGMASKED(LOG_PIT, "%s: Read Timer Count2 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); + return data; + } + case 0x01fc/4: + { + const uint8_t data = m_pit->read(3); + LOGMASKED(LOG_PIT, "%s: Read Timer Control Register: %02x & %08x\n", machine().describe_context(), data, mem_mask); + return data; + } + case 0x0d00/4: + case 0x0d10/4: + case 0x0d20/4: + { + const uint32_t index = (offset >> 2) & 3; + uint32_t ret = m_scc[index]->ba_cd_r(space, 3); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); + return ret; + } + case 0x0d04/4: + case 0x0d14/4: + case 0x0d24/4: + { + const uint32_t index = (offset >> 2) & 3; + const uint32_t ret = m_scc[index]->ba_cd_r(space, 2); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); + return ret; + } + case 0x0d08/4: + case 0x0d18/4: + case 0x0d28/4: + { + const uint32_t index = (offset >> 2) & 3; + const uint32_t ret = m_scc[index]->ba_cd_r(space, 1); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); + return ret; + } + case 0x0d0c/4: + case 0x0d1c/4: + case 0x0d2c/4: + { + const uint32_t index = (offset >> 2) & 3; + const uint32_t ret = m_scc[index]->ba_cd_r(space, 0); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask); + return ret; + } + default: + LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC Read: %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, mem_mask); + return 0; + } + return 0; +} + +WRITE32_MEMBER(hpc1_device::write) +{ + if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) + { + m_rtc->write(space, offset - 0xe00/4, (uint8_t)data); + return; + } + + switch (offset) + { + case 0x0090/4: + LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Descriptor Pointer Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_scsi_dma.m_desc = data; + fetch_chain(); + break; + + case 0x0094/4: + LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_scsi_dma.m_ctrl = data &~ (HPC_DMACTRL_FLUSH | HPC_DMACTRL_RESET); + m_scsi_dma.m_to_mem = (m_scsi_dma.m_ctrl & HPC_DMACTRL_TO_MEM); + m_scsi_dma.m_active = (m_scsi_dma.m_ctrl & HPC_DMACTRL_ENABLE); + break; + + case 0x00ac/4: + LOGMASKED(LOG_WRITES, "%s: HPC Parallel Buffer Pointer Write: %08x (%08x)\n", machine().describe_context(), data, mem_mask); + m_parbuf_ptr = data; + break; + case 0x0120/4: + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_wd33c93->write(space, 0, (uint8_t)(data >> 8)); + } + break; + case 0x0124/4: + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Data Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_wd33c93->write(space, 1, (uint8_t)(data >> 8)); + } + break; + case 0x01b0/4: + LOGMASKED(LOG_WRITES, "%s: HPC Misc. Status Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (BIT(data, 0)) + LOGMASKED(LOG_WRITES, " Force DSP hard reset\n" ); + + if (BIT(data, 1)) + LOGMASKED(LOG_WRITES, " Force IRQA\n" ); + + if (BIT(data, 2)) + LOGMASKED(LOG_WRITES, " Set IRQA polarity high\n" ); + else + LOGMASKED(LOG_WRITES, " Set IRQA polarity low\n" ); + + if (BIT(data, 3)) + LOGMASKED(LOG_WRITES, " SRAM size: 32K\n" ); + else + LOGMASKED(LOG_WRITES, " SRAM size: 8K\n" ); + + m_misc_status = data; + break; + case 0x01bc/4: + m_cpu_aux_ctrl = data; + LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask ); + if (BIT(data, 0)) + { + LOGMASKED(LOG_EEPROM, " CPU board LED on\n"); + } + m_eeprom->di_write(BIT(data, 3)); + m_eeprom->cs_write(BIT(data, 1)); + m_eeprom->clk_write(BIT(data, 2)); + break; + case 0x01c0/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x01c4/4: + { + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + const uint32_t old_mask = m_local_int_mask[0]; + m_local_int_mask[0] = data; + if (old_mask != m_local_int_mask[0]) + update_irq(0); + break; + } + case 0x01c8/4: + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x01cc/4: + { + LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + const uint32_t old_mask = m_local_int_mask[1]; + m_local_int_mask[1] = data; + if (old_mask != m_local_int_mask[1]) + update_irq(1); + break; + } + case 0x01d4/4: + LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_vme_int_mask[0] = data; + break; + case 0x01d8/4: + LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_vme_int_mask[1] = data; + break; + case 0x01e0/4: + LOGMASKED(LOG_PIT, "%s: HPC Write Timer Interrupt Clear Register: %08x\n", machine().describe_context(), data); + set_timer_int_clear(data); + break; + case 0x01f0/4: + LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count0 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (ACCESSING_BITS_24_31) + m_pit->write(0, (uint8_t)(data >> 24)); + else if (ACCESSING_BITS_0_7) + m_pit->write(0, (uint8_t)data); + return; + case 0x01f4/4: + LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count1 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_pit->write(1, (uint8_t)data); + return; + case 0x01f8/4: + LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count2 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_pit->write(2, (uint8_t)data); + return; + case 0x01fc/4: + LOGMASKED(LOG_PIT, "%s: HPC Write Timer Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_pit->write(3, (uint8_t)data); + return; + case 0x0d00/4: + case 0x0d10/4: + case 0x0d20/4: + { + const uint32_t index = (offset >> 2) & 3; + m_scc[index]->ba_cd_w(space, 3, (uint8_t)data); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + break; + } + case 0x0d04/4: + case 0x0d14/4: + case 0x0d24/4: + { + const uint32_t index = (offset >> 2) & 3; + m_scc[index]->ba_cd_w(space, 2, (uint8_t)data); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + break; + } + case 0x0d08/4: + case 0x0d18/4: + case 0x0d28/4: + { + const uint32_t index = (offset >> 2) & 3; + m_scc[index]->ba_cd_w(space, 1, (uint8_t)data); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + break; + } + case 0x0d0c/4: + case 0x0d1c/4: + case 0x0d2c/4: + { + const uint32_t index = (offset >> 2) & 3; + m_scc[index]->ba_cd_w(space, 0, (uint8_t)data); + LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + break; + } + default: + LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, data, mem_mask); + break; + } +} + +//************************************************************************** +// SCSI DMA +//************************************************************************** + +void hpc1_device::fetch_chain() +{ + m_scsi_dma.m_flag = m_cpu_space->read_dword(m_scsi_dma.m_desc); + m_scsi_dma.m_addr = m_cpu_space->read_dword(m_scsi_dma.m_desc+4); + m_scsi_dma.m_next = m_cpu_space->read_dword(m_scsi_dma.m_desc+8); + m_scsi_dma.m_length = m_scsi_dma.m_flag & 0x1fff; + LOGMASKED(LOG_SCSI_DMA, "Fetched SCSI DMA Descriptor block:\n"); + LOGMASKED(LOG_SCSI_DMA, " Ctrl: %08x\n", m_scsi_dma.m_flag); + LOGMASKED(LOG_SCSI_DMA, " Addr: %08x\n", m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, " Next: %08x\n", m_scsi_dma.m_next); + LOGMASKED(LOG_SCSI_DMA, " Length: %04x\n", m_scsi_dma.m_length); + m_scsi_dma.m_end = BIT(m_scsi_dma.m_addr, 31); + m_scsi_dma.m_addr &= 0x0fffffff; + m_scsi_dma.m_next &= 0x0fffffff; +} + +void hpc1_device::advance_chain() +{ + m_scsi_dma.m_addr++; + m_scsi_dma.m_length--; + if (m_scsi_dma.m_length == 0) + { + if (m_scsi_dma.m_end) + { + LOGMASKED(LOG_SCSI_DMA, "HPC: Disabling SCSI DMA due to end of chain\n"); + m_scsi_dma.m_active = false; + m_scsi_dma.m_ctrl &= ~HPC_DMACTRL_ENABLE; + } + else + { + m_scsi_dma.m_desc = m_scsi_dma.m_next; + fetch_chain(); + } + } +} + +void hpc1_device::scsi_dma() +{ + int byte_count = m_wd33c93->get_dma_count(); + + LOGMASKED(LOG_SCSI_DMA, "HPC: Transferring %d bytes %s %08x %s SCSI0\n", + byte_count, m_scsi_dma.m_to_mem ? "to" : "from", m_scsi_dma.m_addr, m_scsi_dma.m_to_mem ? "from" : "to"); + + uint8_t dma_buffer[512]; + if (m_scsi_dma.m_to_mem) + { + // HPC SCSI DMA: device to host + if (byte_count <= 512) + { + m_wd33c93->dma_read_data(byte_count, dma_buffer); + + for (int i = 0; i < byte_count; i++) + { + LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + } + else + { + while (byte_count) + { + int sub_count = m_wd33c93->dma_read_data(512, dma_buffer); + + for (int i = 0; i < sub_count; i++) + { + LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + byte_count -= sub_count; + if (!m_scsi_dma.m_active) + break; + } + } + } + else + { + // HPC SCSI DMA: host to device + if (byte_count <= 512) + { + for (int i = 0; i < byte_count; i++) + { + dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + m_wd33c93->dma_write_data(byte_count, dma_buffer); + } + else + { + while (byte_count) + { + int sub_count = std::min(512, byte_count); + + for (int i = 0; i < sub_count; i++) + { + dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + m_wd33c93->dma_write_data(sub_count, dma_buffer); + + if (!m_scsi_dma.m_active) + { + break; + } + else + { + byte_count -= sub_count; + } + } + } + } + + // clear DMA on the controller + m_wd33c93->clear_dma(); +} + +//************************************************************************** +// PIT TIMERS +//************************************************************************** + +void hpc1_device::set_timer_int_clear(uint32_t data) +{ + if (BIT(data, 0)) + { + LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 0 Interrupt: %d\n", data); + m_maincpu->set_input_line(MIPS3_IRQ2, CLEAR_LINE); + } + if (BIT(data, 1)) + { + LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 1 Interrupt: %d\n", data); + m_maincpu->set_input_line(MIPS3_IRQ3, CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER(hpc1_device::timer0_int) +{ + LOGMASKED(LOG_PIT, "Timer0 Interrupt: %d\n", state); + if (state) + m_maincpu->set_input_line(MIPS3_IRQ2, ASSERT_LINE); +} + +WRITE_LINE_MEMBER(hpc1_device::timer1_int) +{ + LOGMASKED(LOG_PIT, "Timer2 Interrupt: %d\n", state); + if (state) + m_maincpu->set_input_line(MIPS3_IRQ3, ASSERT_LINE); +} + +WRITE_LINE_MEMBER(hpc1_device::timer2_int) +{ + LOGMASKED(LOG_PIT, "Timer2 Interrupt (Disabled): %d\n", state); +} + +//************************************************************************** +// SERIAL DUARTS +//************************************************************************** + +WRITE_LINE_MEMBER(hpc1_device::duart0_int_w) { duart_int_w(0, state); } +WRITE_LINE_MEMBER(hpc1_device::duart1_int_w) { duart_int_w(1, state); } +WRITE_LINE_MEMBER(hpc1_device::duart2_int_w) { duart_int_w(2, state); } + +void hpc1_device::duart_int_w(int channel, int state) +{ + m_duart_int_status &= ~(1 << channel); + m_duart_int_status |= state << channel; + + if (m_duart_int_status) + { + LOGMASKED(LOG_DUART0 << channel, "Raising DUART Interrupt: %02x\n", m_duart_int_status); + raise_local_irq(0, LOCAL0_DUART); + } + else + { + LOGMASKED(LOG_DUART0 << channel, "Lowering DUART Interrupt\n"); + lower_local_irq(0, LOCAL0_DUART); + } +} + +//************************************************************************** +// INTERRUPTS +//************************************************************************** + +void hpc1_device::raise_local_irq(int channel, uint8_t source_mask) +{ + m_local_int_status[channel] |= source_mask; + update_irq(channel); +} + +void hpc1_device::lower_local_irq(int channel, uint8_t source_mask) +{ + m_local_int_status[channel] &= ~source_mask; + update_irq(channel); +} + +void hpc1_device::update_irq(int channel) +{ + bool old_status = m_int_status[channel]; + m_int_status[channel] = (m_local_int_status[channel] & m_local_int_mask[channel]); + + if (old_status != m_int_status[channel]) + { + LOGMASKED(LOG_INT, "%s IRQ%d: %02x & %02x\n", m_int_status[channel] ? "Asserting" : "Clearing", channel, + m_local_int_status[channel], m_local_int_mask[channel]); + m_maincpu->set_input_line(MIPS3_IRQ0 + channel, m_int_status[channel] ? ASSERT_LINE : CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER(hpc1_device::scsi_irq) +{ + if (state) + { + LOGMASKED(LOG_SCSI, "SCSI: Set IRQ\n"); + int count = m_wd33c93->get_dma_count(); + LOGMASKED(LOG_SCSI_DMA, "SCSI: count %d, active %d\n", count, m_scsi_dma.m_active); + if (count && m_scsi_dma.m_active) + scsi_dma(); + + raise_local_irq(0, LOCAL0_SCSI); + } + else + { + LOGMASKED(LOG_SCSI, "SCSI: Clear IRQ\n"); + lower_local_irq(0, LOCAL0_SCSI); + } +} diff --git a/src/mame/machine/hpc1.h b/src/mame/machine/hpc1.h new file mode 100644 index 00000000000..beee8affc06 --- /dev/null +++ b/src/mame/machine/hpc1.h @@ -0,0 +1,136 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************** + + SGI HPC1 "High-performance Peripheral Controller" emulation + +**********************************************************************/ + +#ifndef MAME_MACHINE_HPC1_H +#define MAME_MACHINE_HPC1_H + +#pragma once + +#include "machine/dp8573.h" +#include "machine/eepromser.h" +#include "machine/pit8253.h" +#include "machine/wd33c93.h" +#include "machine/z80scc.h" + +class hpc1_device : public device_t +{ +public: + template + hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag) + : hpc1_device(mconfig, tag, owner, (uint32_t)0) + { + m_maincpu.set_tag(std::forward(cpu_tag)); + m_eeprom.set_tag(std::forward(eeprom_tag)); + } + + hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + DECLARE_WRITE_LINE_MEMBER(scsi_irq); + + void set_timer_int_clear(uint32_t data); + DECLARE_WRITE_LINE_MEMBER(timer0_int); + DECLARE_WRITE_LINE_MEMBER(timer1_int); + DECLARE_WRITE_LINE_MEMBER(timer2_int); + DECLARE_WRITE_LINE_MEMBER(duart0_int_w); + DECLARE_WRITE_LINE_MEMBER(duart1_int_w); + DECLARE_WRITE_LINE_MEMBER(duart2_int_w); + + void duart_int_w(int channel, int status); + void raise_local_irq(int channel, uint8_t source_mask); + void lower_local_irq(int channel, uint8_t source_mask); + void update_irq(int channel); + + void fetch_chain(); + void advance_chain(); + void scsi_dma(); + + required_device m_maincpu; + required_device m_eeprom; + required_device m_wd33c93; + required_device_array m_scc; + required_device m_pit; + required_device m_rtc; + + enum + { + LOCAL0_FIFO_GIO0 = 0x01, + LOCAL0_PARALLEL = 0x02, + LOCAL0_SCSI = 0x04, + LOCAL0_ETHERNET = 0x08, + LOCAL0_GFX_DMA = 0x10, + LOCAL0_DUART = 0x20, + LOCAL0_GIO1 = 0x40, + LOCAL0_VME0 = 0x80, + + LOCAL1_GR1_CASE = 0x02, + LOCAL1_VME1 = 0x08, + LOCAL1_DSP = 0x10, + LOCAL1_ACFAIL = 0x20, + LOCAL1_VIDEO = 0x40, + LOCAL1_RETRACE_GIO2 = 0x80 + }; + + enum + { + HPC_DMACTRL_RESET = 0x01, + HPC_DMACTRL_FLUSH = 0x02, + HPC_DMACTRL_TO_MEM = 0x10, + HPC_DMACTRL_ENABLE = 0x80 + }; + + struct scsi_dma_t + { + uint32_t m_desc; + uint32_t m_ctrl; + uint32_t m_addr; + uint32_t m_flag; + uint32_t m_next; + uint16_t m_length; + bool m_to_mem; + bool m_active; + bool m_end; + }; + + static void cdrom_config(device_t *device); + static void indigo_mice(device_slot_interface &device); + + uint8_t m_misc_status; + uint32_t m_cpu_aux_ctrl; + uint32_t m_parbuf_ptr; + uint32_t m_local_int_status[2]; + uint32_t m_local_int_mask[2]; + bool m_int_status[2]; + uint32_t m_vme_int_mask[2]; + + scsi_dma_t m_scsi_dma; + + uint8_t m_duart_int_status; + + address_space *m_cpu_space; + + static char const *const RS232A_TAG; + static char const *const RS232B_TAG; + + static const XTAL SCC_PCLK; + static const XTAL SCC_RXA_CLK; + static const XTAL SCC_TXA_CLK; + static const XTAL SCC_RXB_CLK; + static const XTAL SCC_TXB_CLK; +}; + +DECLARE_DEVICE_TYPE(SGI_HPC1, hpc1_device) + +#endif // MAME_MACHINE_HPC1_H diff --git a/src/mame/machine/hpc3.h b/src/mame/machine/hpc3.h index a26ecd9d1e1..d4d2a5af94b 100644 --- a/src/mame/machine/hpc3.h +++ b/src/mame/machine/hpc3.h @@ -151,10 +151,8 @@ protected: uint32_t m_pio_config[10]; address_space *m_cpu_space; - - inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... ); }; DECLARE_DEVICE_TYPE(SGI_HPC3, hpc3_device) -#endif // MAME_MACHINE_HAL2_H +#endif // MAME_MACHINE_HPC3_H diff --git a/src/mame/machine/sgi.cpp b/src/mame/machine/sgi.cpp index 2fde6ff07cc..2375c7979cb 100644 --- a/src/mame/machine/sgi.cpp +++ b/src/mame/machine/sgi.cpp @@ -10,67 +10,69 @@ #include "emu.h" #include "sgi.h" +#include "cpu/mips/mips3.h" -#define LOG_READS (1 << 0) -#define LOG_WRITES (1 << 1) -#define LOG_RPSS (1 << 2) -#define LOG_WATCHDOG (1 << 3) -#define LOG_MEMCFG (1 << 4) -#define LOG_UNKNOWN (1 << 5) +#define LOG_UNKNOWN (1 << 0) +#define LOG_READS (1 << 1) +#define LOG_WRITES (1 << 2) +#define LOG_RPSS (1 << 3) +#define LOG_WATCHDOG (1 << 4) +#define LOG_MEMCFG (1 << 5) +#define LOG_MEMCFG_EXT (1 << 6) +#define LOG_EEPROM (1 << 7) #define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_RPSS | LOG_WATCHDOG | LOG_UNKNOWN) -#define VERBOSE (0) +#define VERBOSE (LOG_UNKNOWN) #include "logmacro.h" DEFINE_DEVICE_TYPE(SGI_MC, sgi_mc_device, "sgi_mc", "SGI Memory Controller") sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, SGI_MC, tag, owner, clock), - m_rpss_timer(nullptr), - m_cpu_control0(0), - m_cpu_control1(0), - m_watchdog(0), - m_sys_id(0), - m_rpss_divider(0), - m_refcnt_preload(0), - m_refcnt(0), - m_gio64_arb_param(0), - m_arb_cpu_time(0), - m_arb_burst_time(0), - m_mem_config0(0), - m_mem_config1(0), - m_cpu_mem_access_config(0), - m_gio_mem_access_config(0), - m_cpu_error_addr(0), - m_cpu_error_status(0), - m_gio_error_addr(0), - m_gio_error_status(0), - m_sys_semaphore(0), - m_gio_lock(0), - m_eisa_lock(0), - m_gio64_translate_mask(0), - m_gio64_substitute_bits(0), - m_dma_int_cause(0), - m_dma_control(0), - m_dma_tlb_entry0_hi(0), - m_dma_tlb_entry0_lo(0), - m_dma_tlb_entry1_hi(0), - m_dma_tlb_entry1_lo(0), - m_dma_tlb_entry2_hi(0), - m_dma_tlb_entry2_lo(0), - m_dma_tlb_entry3_hi(0), - m_dma_tlb_entry3_lo(0), - m_rpss_counter(0), - m_dma_mem_addr(0), - m_dma_size(0), - m_dma_stride(0), - m_dma_gio64_addr(0), - m_dma_mode(0), - m_dma_count(0), - m_dma_running(0), - m_rpss_divide_counter(0), - m_rpss_divide_count(0), - m_rpss_increment(0) + : device_t(mconfig, SGI_MC, tag, owner, clock) + , m_maincpu(*this, finder_base::DUMMY_TAG) + , m_eeprom(*this, finder_base::DUMMY_TAG) + , m_rpss_timer(nullptr) + , m_watchdog(0) + , m_sys_id(0) + , m_rpss_divider(0) + , m_refcnt_preload(0) + , m_refcnt(0) + , m_gio64_arb_param(0) + , m_arb_cpu_time(0) + , m_arb_burst_time(0) + , m_cpu_mem_access_config(0) + , m_gio_mem_access_config(0) + , m_cpu_error_addr(0) + , m_cpu_error_status(0) + , m_gio_error_addr(0) + , m_gio_error_status(0) + , m_sys_semaphore(0) + , m_gio_lock(0) + , m_eisa_lock(0) + , m_gio64_translate_mask(0) + , m_gio64_substitute_bits(0) + , m_dma_int_cause(0) + , m_dma_control(0) + , m_dma_tlb_entry0_hi(0) + , m_dma_tlb_entry0_lo(0) + , m_dma_tlb_entry1_hi(0) + , m_dma_tlb_entry1_lo(0) + , m_dma_tlb_entry2_hi(0) + , m_dma_tlb_entry2_lo(0) + , m_dma_tlb_entry3_hi(0) + , m_dma_tlb_entry3_lo(0) + , m_rpss_counter(0) + , m_dma_mem_addr(0) + , m_dma_size(0) + , m_dma_stride(0) + , m_dma_gio64_addr(0) + , m_dma_mode(0) + , m_dma_count(0) + , m_dma_running(0) + , m_eeprom_ctrl(0) + , m_rpss_divide_counter(0) + , m_rpss_divide_count(0) + , m_rpss_increment(0) { } @@ -83,18 +85,17 @@ void sgi_mc_device::device_start() // if Indigo2, ID appropriately if (!strcmp(machine().system().name, "ip244415")) { - m_sys_id = 0x11; // rev. B MC, EISA bus present + m_sys_id = 0x12; // rev. C MC, EISA bus present } else { - m_sys_id = 0x01; // rev. B MC, no EISA bus + m_sys_id = 0x02; // rev. C MC, no EISA bus } m_rpss_timer = timer_alloc(TIMER_RPSS); m_rpss_timer->adjust(attotime::never); - save_item(NAME(m_cpu_control0)); - save_item(NAME(m_cpu_control1)); + save_item(NAME(m_cpu_control)); save_item(NAME(m_watchdog)); save_item(NAME(m_sys_id)); save_item(NAME(m_rpss_divider)); @@ -103,8 +104,7 @@ void sgi_mc_device::device_start() save_item(NAME(m_gio64_arb_param)); save_item(NAME(m_arb_cpu_time)); save_item(NAME(m_arb_burst_time)); - save_item(NAME(m_mem_config0)); - save_item(NAME(m_mem_config1)); + save_item(NAME(m_mem_config)); save_item(NAME(m_cpu_mem_access_config)); save_item(NAME(m_gio_mem_access_config)); save_item(NAME(m_cpu_error_addr)); @@ -134,6 +134,7 @@ void sgi_mc_device::device_start() save_item(NAME(m_dma_mode)); save_item(NAME(m_dma_count)); save_item(NAME(m_dma_running)); + save_item(NAME(m_eeprom_ctrl)); save_item(NAME(m_semaphore)); save_item(NAME(m_rpss_divide_counter)); save_item(NAME(m_rpss_divide_count)); @@ -142,148 +143,203 @@ void sgi_mc_device::device_start() void sgi_mc_device::device_reset() { + m_cpu_control[0] = 0; + m_cpu_control[1] = 0; + m_watchdog = 0; + m_rpss_divider = 0x0104; + m_refcnt_preload = 0; + m_refcnt = 0; + m_gio64_arb_param = 0; + m_arb_cpu_time = 0; + m_arb_burst_time = 0; + m_mem_config[0] = 0; + m_mem_config[1] = 0; + m_cpu_mem_access_config = 0; + m_gio_mem_access_config = 0; + m_cpu_error_addr = 0; + m_cpu_error_status = 0; + m_gio_error_addr = 0; + m_gio_error_status = 0; + m_sys_semaphore = 0; + m_gio_lock = 0; + m_eisa_lock = 0; + m_gio64_translate_mask = 0; + m_gio64_substitute_bits = 0; + m_dma_int_cause = 0; + m_dma_control = 0; + m_dma_tlb_entry0_hi = 0; + m_dma_tlb_entry0_lo = 0; + m_dma_tlb_entry1_hi = 0; + m_dma_tlb_entry1_lo = 0; + m_dma_tlb_entry2_hi = 0; + m_dma_tlb_entry2_lo = 0; + m_dma_tlb_entry3_hi = 0; + m_dma_tlb_entry3_lo = 0; + m_rpss_counter = 0; + m_dma_mem_addr = 0; + m_dma_size = 0; + m_dma_stride = 0; + m_dma_gio64_addr = 0; + m_dma_mode = 0; + m_dma_count = 0; + m_dma_running = 0; + m_eeprom_ctrl = 0; memset(m_semaphore, 0, sizeof(uint32_t) * 16); m_rpss_timer->adjust(attotime::from_hz(10000000), 0, attotime::from_hz(10000000)); - m_rpss_divider = 0x0104; m_rpss_divide_counter = 4; m_rpss_divide_count = 4; m_rpss_increment = 1; } +void sgi_mc_device::set_cpu_buserr(uint32_t address) +{ + m_cpu_error_addr = address; + m_cpu_error_status = 0x00000400; + if (address & 1) + m_cpu_error_status |= 0x000000f0; + else + m_cpu_error_status |= 0x0000000f; +} + READ32_MEMBER(sgi_mc_device::read) { - offset <<= 2; - switch (offset & ~4) + switch (offset & ~1) { - case 0x0000: - LOGMASKED(LOG_READS, "%s: CPU Control 0 Read: %08x & %08x\n", machine().describe_context(), m_cpu_control0, mem_mask); - return m_cpu_control0; - case 0x0008: - LOGMASKED(LOG_READS, "%s: CPU Control 1 Read: %08x & %08x\n", machine().describe_context(), m_cpu_control1, mem_mask); - return m_cpu_control1; - case 0x0010: + case 0x0000/4: + case 0x0008/4: + { + const uint32_t index = (offset >> 3) & 1; + LOGMASKED(LOG_READS, "%s: CPU Control %d Read: %08x & %08x\n", machine().describe_context(), index, m_cpu_control[index], mem_mask); + return m_cpu_control[index]; + } + case 0x0010/4: LOGMASKED(LOG_WATCHDOG, "%s: Watchdog Timer Read: %08x & %08x\n", machine().describe_context(), m_watchdog, mem_mask); return m_watchdog; - case 0x0018: + case 0x0018/4: LOGMASKED(LOG_READS, "%s: System ID Read: %08x & %08x\n", machine().describe_context(), m_sys_id, mem_mask); return m_sys_id; - case 0x0028: + case 0x0028/4: LOGMASKED(LOG_RPSS, "%s: RPSS Divider Read: %08x & %08x\n", machine().describe_context(), m_rpss_divider, mem_mask); return m_rpss_divider; - case 0x0030: - LOGMASKED(LOG_READS, "%s: R4000 EEPROM Read\n", machine().describe_context()); - return 0; - case 0x0040: + case 0x0030/4: + { + // Disabled - we don't have a dump from real hardware, and IRIX 5.x freaks out with default contents. + uint32_t ret = (m_eeprom_ctrl & ~0x10);// | m_eeprom->do_read() << 4; + LOGMASKED(LOG_READS, "%s: R4000 EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; + } + case 0x0040/4: LOGMASKED(LOG_READS, "%s: Refresh Count Preload Read: %08x & %08x\n", machine().describe_context(), m_refcnt_preload, mem_mask); return m_refcnt_preload; - case 0x0048: + case 0x0048/4: LOGMASKED(LOG_READS, "%s: Refresh Count Read: %08x & %08x\n", machine().describe_context(), m_refcnt, mem_mask); return m_refcnt; - case 0x0080: + case 0x0080/4: LOGMASKED(LOG_READS, "%s: GIO64 Arbitration Param Read: %08x & %08x\n", machine().describe_context(), m_gio64_arb_param, mem_mask); return m_gio64_arb_param; - case 0x0088: + case 0x0088/4: LOGMASKED(LOG_READS, "%s: Arbiter CPU Time Read: %08x & %08x\n", machine().describe_context(), m_arb_cpu_time, mem_mask); return m_arb_cpu_time; - case 0x0098: + case 0x0098/4: LOGMASKED(LOG_READS, "%s: Arbiter Long Burst Time Read: %08x & %08x\n", machine().describe_context(), m_arb_burst_time, mem_mask); return m_arb_burst_time; - case 0x00c0: - LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 0 Read: %08x & %08x\n", machine().describe_context(), m_mem_config0, mem_mask); - return m_mem_config0; - case 0x00c8: - LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 1 Read: %08x & %08x\n", machine().describe_context(), m_mem_config1, mem_mask); - return m_mem_config1; - case 0x00d0: + case 0x00c0/4: + case 0x00c8/4: + { + const uint32_t index = (offset >> 1) & 1; + LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register %d Read: %08x & %08x\n", machine().describe_context(), index, m_mem_config[index], mem_mask); + return m_mem_config[index]; + } + case 0x00d0/4: LOGMASKED(LOG_READS, "%s: CPU Memory Access Config Params Read: %08x & %08x\n", machine().describe_context(), m_cpu_mem_access_config, mem_mask); return m_cpu_mem_access_config; - case 0x00d8: + case 0x00d8/4: LOGMASKED(LOG_READS, "%s: GIO Memory Access Config Params Read: %08x & %08x\n", machine().describe_context(), m_gio_mem_access_config, mem_mask); return m_gio_mem_access_config; - case 0x00e0: + case 0x00e0/4: LOGMASKED(LOG_READS, "%s: CPU Error Address Read: %08x & %08x\n", machine().describe_context(), m_cpu_error_addr, mem_mask); return m_cpu_error_addr; - case 0x00e8: + case 0x00e8/4: LOGMASKED(LOG_READS, "%s: CPU Error Status Read: %08x & %08x\n", machine().describe_context(), m_cpu_error_status, mem_mask); return m_cpu_error_status; - case 0x00f0: + case 0x00f0/4: LOGMASKED(LOG_READS, "%s: GIO Error Address Read: %08x & %08x\n", machine().describe_context(), m_gio_error_addr, mem_mask); return m_gio_error_addr; - case 0x00f8: + case 0x00f8/4: LOGMASKED(LOG_READS, "%s: GIO Error Status Read: %08x & %08x\n", machine().describe_context(), m_gio_error_status, mem_mask); return m_gio_error_status; - case 0x0100: + case 0x0100/4: LOGMASKED(LOG_READS, "%s: System Semaphore Read: %08x & %08x\n", machine().describe_context(), m_sys_semaphore, mem_mask); return m_sys_semaphore; - case 0x0108: + case 0x0108/4: LOGMASKED(LOG_READS, "%s: GIO Lock Read: %08x & %08x\n", machine().describe_context(), m_gio_lock, mem_mask); return m_gio_lock; - case 0x0110: + case 0x0110/4: LOGMASKED(LOG_READS, "%s: EISA Lock Read: %08x & %08x\n", machine().describe_context(), m_eisa_lock, mem_mask); return m_eisa_lock; - case 0x0150: + case 0x0150/4: LOGMASKED(LOG_READS, "%s: GIO64 Translation Address Mask Read: %08x & %08x\n", machine().describe_context(), m_gio64_translate_mask, mem_mask); return m_gio64_translate_mask; - case 0x0158: + case 0x0158/4: LOGMASKED(LOG_READS, "%s: GIO64 Translation Address Substitution Bits Read: %08x & %08x\n", machine().describe_context(), m_gio64_substitute_bits, mem_mask); return m_gio64_substitute_bits; - case 0x0160: + case 0x0160/4: LOGMASKED(LOG_READS, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask); return m_dma_int_cause; - case 0x0168: + case 0x0168/4: LOGMASKED(LOG_READS, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask); return m_dma_control; - case 0x0180: + case 0x0180/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_hi, mem_mask); return m_dma_tlb_entry0_hi; - case 0x0188: + case 0x0188/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_lo, mem_mask); return m_dma_tlb_entry0_lo; - case 0x0190: + case 0x0190/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_hi, mem_mask); return m_dma_tlb_entry1_hi; - case 0x0198: + case 0x0198/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_lo, mem_mask); return m_dma_tlb_entry1_lo; - case 0x01a0: + case 0x01a0/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_hi, mem_mask); return m_dma_tlb_entry2_hi; - case 0x01a8: + case 0x01a8/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_lo, mem_mask); return m_dma_tlb_entry2_lo; - case 0x01b0: + case 0x01b0/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_hi, mem_mask); return m_dma_tlb_entry3_hi; - case 0x01b8: + case 0x01b8/4: LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_lo, mem_mask); return m_dma_tlb_entry3_lo; - case 0x1000: + case 0x1000/4: LOGMASKED(LOG_RPSS, "%s: RPSS 100ns Counter Read: %08x & %08x\n", machine().describe_context(), m_rpss_counter, mem_mask); return m_rpss_counter; - case 0x2000: - case 0x2008: + case 0x2000/4: + case 0x2008/4: LOGMASKED(LOG_READS, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask); return m_dma_mem_addr; - case 0x2010: + case 0x2010/4: LOGMASKED(LOG_READS, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask); return m_dma_size; - case 0x2018: + case 0x2018/4: LOGMASKED(LOG_READS, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask); return m_dma_stride; - case 0x2020: - case 0x2028: + case 0x2020/4: + case 0x2028/4: LOGMASKED(LOG_READS, "%s: DMA GIO64 Address Read: %08x & %08x\n", machine().describe_context(), m_dma_gio64_addr, mem_mask); return m_dma_gio64_addr; - case 0x2030: + case 0x2030/4: LOGMASKED(LOG_READS, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask); return m_dma_mode; - case 0x2038: + case 0x2038/4: LOGMASKED(LOG_READS, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask); return m_dma_count; - case 0x2040: + case 0x2040/4: LOGMASKED(LOG_READS, "%s: DMA Start Read\n", machine().describe_context()); return 0; - case 0x2048: + case 0x2048/4: LOGMASKED(LOG_READS, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask); if (m_dma_running == 1) { @@ -294,30 +350,31 @@ READ32_MEMBER(sgi_mc_device::read) { return 0; } - case 0x10000: - case 0x11000: - case 0x12000: - case 0x13000: - case 0x14000: - case 0x15000: - case 0x16000: - case 0x17000: - case 0x18000: - case 0x19000: - case 0x1a000: - case 0x1b000: - case 0x1c000: - case 0x1d000: - case 0x1e000: - case 0x1f000: + case 0x10000/4: + case 0x11000/4: + case 0x12000/4: + case 0x13000/4: + case 0x14000/4: + case 0x15000/4: + case 0x16000/4: + case 0x17000/4: + case 0x18000/4: + case 0x19000/4: + case 0x1a000/4: + case 0x1b000/4: + case 0x1c000/4: + case 0x1d000/4: + case 0x1e000/4: + case 0x1f000/4: { - const uint32_t data = m_semaphore[(offset - 0x10000) >> 12]; - LOGMASKED(LOG_READS, "%s: Semaphore %d Read: %08x & %08x\n", machine().describe_context(), (offset - 0x10000) >> 12, data, mem_mask); - m_semaphore[(offset - 0x10000) >> 12] = 1; + const uint32_t index = (offset - 0x4000) >> 10; + const uint32_t data = m_semaphore[index]; + LOGMASKED(LOG_READS, "%s: Semaphore %d Read: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + m_semaphore[index] = 1; return data; } default: - LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: Unmapped MC read: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset, mem_mask); + LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: Unmapped MC read: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset*4, mem_mask); return 0; } return 0; @@ -325,198 +382,219 @@ READ32_MEMBER(sgi_mc_device::read) WRITE32_MEMBER( sgi_mc_device::write ) { - offset <<= 2; - switch (offset & ~4) + switch (offset & ~1) { - case 0x0000: - LOGMASKED(LOG_WRITES, "%s: CPU Control 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_cpu_control0 = data; - break; - case 0x0008: - LOGMASKED(LOG_WRITES, "%s: CPU Control 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_cpu_control1 = data; + case 0x0000/4: + case 0x0008/4: + { + const uint32_t index = (offset >> 1) & 1; + LOGMASKED(LOG_WRITES, "%s: CPU Control %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + m_cpu_control[index] = data; break; - case 0x0010: + } + case 0x0010/4: LOGMASKED(LOG_WATCHDOG, "%s: Watchdog Timer Clear\n", machine().describe_context()); m_watchdog = 0; break; - case 0x0028: + case 0x0028/4: LOGMASKED(LOG_RPSS, "%s: RPSS Divider Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_rpss_divider = data; m_rpss_divide_count = (int)(m_rpss_divider & 0xff); m_rpss_divide_counter = m_rpss_divide_count; m_rpss_increment = (m_rpss_divider >> 8) & 0xff; break; - case 0x0030: + case 0x0030/4: LOGMASKED(LOG_WRITES, "%s: R4000 EEPROM Write: CS:%d, SCK:%d, SO:%d\n", machine().describe_context(), BIT(data, 1), BIT(data, 2), BIT(data, 3)); + m_eeprom_ctrl = data; + m_eeprom->di_write(BIT(data, 3)); + m_eeprom->cs_write(BIT(data, 1)); + m_eeprom->clk_write(BIT(data, 2)); break; - case 0x0040: + case 0x0040/4: LOGMASKED(LOG_WRITES, "%s: Refresh Count Preload Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_refcnt_preload = data; break; - case 0x0080: + case 0x0080/4: LOGMASKED(LOG_WRITES, "%s: GIO64 Arbitration Param Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_gio64_arb_param = data; break; - case 0x0088: + case 0x0088/4: LOGMASKED(LOG_WRITES, "%s: Arbiter CPU Time Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_arb_cpu_time = data; break; - case 0x0098: + case 0x0098/4: LOGMASKED(LOG_WRITES, "%s: Arbiter Long Burst Time Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_arb_burst_time = data; break; - case 0x00c0: - LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_mem_config0 = data; - break; - case 0x00c8: - LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_mem_config1 = data; + case 0x00c0/4: + case 0x00c8/4: + { + static const char* const s_mem_size[32] = { + "256Kx36", "512Kx36, 2 subbanks", "Invalid", "1Mx36", "Invalid", "Invalid", "Invalid", "2Mx36, 2 subbanks", + "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "4Mx36", + "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", + "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "8Mx36, 2 subbanks" }; + const uint32_t index = (offset >> 1) & 1; + LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Base Address: %02x\n", machine().describe_context(), index, (data >> 16) & 0xff); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, SIMM Size: %02x (%s)\n", machine().describe_context(), index, (data >> 24) & 0x1f, s_mem_size[(data >> 24) & 0x1f]); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Valid: %d\n", machine().describe_context(), index, BIT(data, 29)); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, # Subbanks: %d\n", machine().describe_context(), index, BIT(data, 30) + 1); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Base Address: %02x\n", machine().describe_context(), index+1, data & 0xff); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, SIMM Size: %02x (%s)\n", machine().describe_context(), index+1, (data >> 8) & 0x1f, s_mem_size[(data >> 8) & 0x1f]); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Valid: %d\n", machine().describe_context(), index+1, BIT(data, 13)); + LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, # Subbanks: %d\n", machine().describe_context(), index+1, BIT(data, 14) + 1); + m_mem_config[index] = data; break; - case 0x00d0: + } + case 0x00d0/4: LOGMASKED(LOG_WRITES, "%s: CPU Memory Access Config Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_cpu_mem_access_config = data; break; - case 0x00d8: + case 0x00d8/4: LOGMASKED(LOG_WRITES, "%s: GIO Memory Access Config Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_gio_mem_access_config = data; break; - case 0x00e8: + case 0x00e8/4: LOGMASKED(LOG_WRITES, "%s: CPU Error Status Clear\n", machine().describe_context()); + m_maincpu->set_input_line(MIPS3_IRQ4, CLEAR_LINE); m_cpu_error_status = 0; break; - case 0x00f8: + case 0x00f8/4: LOGMASKED(LOG_WRITES, "%s: GIO Error Status Clear\n", machine().describe_context()); + m_maincpu->set_input_line(MIPS3_IRQ4, CLEAR_LINE); m_gio_error_status = 0; break; - case 0x0100: + case 0x0100/4: LOGMASKED(LOG_WRITES, "%s: System Semaphore Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_sys_semaphore = data; break; - case 0x0108: + case 0x0108/4: LOGMASKED(LOG_WRITES, "%s: GIO Lock Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_gio_lock = data; break; - case 0x0110: + case 0x0110/4: LOGMASKED(LOG_WRITES, "%s: EISA Lock Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_eisa_lock = data; break; - case 0x0150: + case 0x0150/4: LOGMASKED(LOG_WRITES, "%s: GIO64 Translation Address Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_gio64_translate_mask = data; break; - case 0x0158: + case 0x0158/4: LOGMASKED(LOG_WRITES, "%s: GIO64 Translation Address Substitution Bits Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_gio64_substitute_bits = data; break; - case 0x0160: + case 0x0160/4: LOGMASKED(LOG_WRITES, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_int_cause = data; break; - case 0x0168: + case 0x0168/4: LOGMASKED(LOG_WRITES, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_control = data; break; - case 0x0180: + case 0x0180/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry0_hi = data; break; - case 0x0188: + case 0x0188/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry0_lo = data; break; - case 0x0190: + case 0x0190/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry1_hi = data; break; - case 0x0198: + case 0x0198/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry1_lo = data; break; - case 0x01a0: + case 0x01a0/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 2 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry2_hi = data; break; - case 0x01a8: + case 0x01a8/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 2 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry2_lo = data; break; - case 0x01b0: + case 0x01b0/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 3 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry3_hi = data; break; - case 0x01b8: + case 0x01b8/4: LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 3 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_tlb_entry3_lo = data; break; - case 0x2000: + case 0x2000/4: LOGMASKED(LOG_WRITES, "%s: DMA Memory Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_mem_addr = data; break; - case 0x2008: + case 0x2008/4: LOGMASKED(LOG_WRITES, "%s: DMA Memory Address + Default Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_mem_addr = data; break; - case 0x2010: + case 0x2010/4: LOGMASKED(LOG_WRITES, "%s: DMA Line Count and Width Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_size = data; break; - case 0x2018: + case 0x2018/4: LOGMASKED(LOG_WRITES, "%s: DMA Line Zoom and Stride Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_stride = data; break; - case 0x2020: + case 0x2020/4: LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_gio64_addr = data; break; - case 0x2028: + case 0x2028/4: LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write + Start DMA: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_gio64_addr = data; // Start DMA m_dma_running = 1; break; - case 0x2030: + case 0x2030/4: LOGMASKED(LOG_WRITES, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_mode = data; break; - case 0x2038: + case 0x2038/4: LOGMASKED(LOG_WRITES, "%s: DMA Zoom Count + Byte Count Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_count = data; break; - case 0x2040: + case 0x2040/4: LOGMASKED(LOG_WRITES, "%s: DMA Start Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); // Start DMA m_dma_running = 1; break; - case 0x2070: + case 0x2070/4: LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write + Default Params Write + Start DMA: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_gio64_addr = data; // Start DMA m_dma_running = 1; break; - case 0x10000: - case 0x11000: - case 0x12000: - case 0x13000: - case 0x14000: - case 0x15000: - case 0x16000: - case 0x17000: - case 0x18000: - case 0x19000: - case 0x1a000: - case 0x1b000: - case 0x1c000: - case 0x1d000: - case 0x1e000: - case 0x1f000: - LOGMASKED(LOG_WRITES, "%s: Semaphore %d Write: %08x & %08x\n", machine().describe_context(), (offset - 0x10000) >> 12, data, mem_mask); - m_semaphore[(offset - 0x10000) >> 12] = data & 1; + case 0x10000/4: + case 0x11000/4: + case 0x12000/4: + case 0x13000/4: + case 0x14000/4: + case 0x15000/4: + case 0x16000/4: + case 0x17000/4: + case 0x18000/4: + case 0x19000/4: + case 0x1a000/4: + case 0x1b000/4: + case 0x1c000/4: + case 0x1d000/4: + case 0x1e000/4: + case 0x1f000/4: + { + const uint32_t index = (offset - 0x10000/4) >> 10; + LOGMASKED(LOG_WRITES, "%s: Semaphore %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask); + m_semaphore[index] = data & 1; break; + } default: - LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: Unmapped MC write: %08x: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset, data, mem_mask); + LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: Unmapped MC write: %08x: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset*4, data, mem_mask); break; } } diff --git a/src/mame/machine/sgi.h b/src/mame/machine/sgi.h index c66c81f5c32..634c286ba2d 100644 --- a/src/mame/machine/sgi.h +++ b/src/mame/machine/sgi.h @@ -13,12 +13,17 @@ #pragma once +#include "machine/eepromser.h" + class sgi_mc_device : public device_t { public: - sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner) + template + sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag) : sgi_mc_device(mconfig, tag, owner, (uint32_t)0) { + m_maincpu.set_tag(std::forward(cpu_tag)); + m_eeprom.set_tag(std::forward(eeprom_tag)); } sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -26,6 +31,8 @@ public: DECLARE_READ32_MEMBER(read); DECLARE_WRITE32_MEMBER(write); + void set_cpu_buserr(uint32_t address); + protected: // device-level overrides virtual void device_start() override; @@ -35,10 +42,12 @@ protected: static const device_timer_id TIMER_RPSS = 0; private: - // internal state + required_device m_maincpu; + required_device m_eeprom; + emu_timer *m_rpss_timer; - uint32_t m_cpu_control0; - uint32_t m_cpu_control1; + + uint32_t m_cpu_control[2]; uint32_t m_watchdog; uint32_t m_sys_id; uint32_t m_rpss_divider; @@ -47,8 +56,7 @@ private: uint32_t m_gio64_arb_param; uint32_t m_arb_cpu_time; uint32_t m_arb_burst_time; - uint32_t m_mem_config0; - uint32_t m_mem_config1; + uint32_t m_mem_config[2]; uint32_t m_cpu_mem_access_config; uint32_t m_gio_mem_access_config; uint32_t m_cpu_error_addr; @@ -78,14 +86,11 @@ private: uint32_t m_dma_mode; uint32_t m_dma_count; uint32_t m_dma_running; + uint32_t m_eeprom_ctrl; uint32_t m_semaphore[16]; int m_rpss_divide_counter; int m_rpss_divide_count; uint8_t m_rpss_increment; - - void update(); - TIMER_CALLBACK_MEMBER(update_callback); - void timer_init(); }; DECLARE_DEVICE_TYPE(SGI_MC, sgi_mc_device) -- cgit v1.2.3