From 0e210f4347e1aa2c309dc918f927e05bbc228d15 Mon Sep 17 00:00:00 2001 From: arbee Date: Sun, 15 Jul 2018 18:41:14 -0400 Subject: [PATCH] decstation.cpp: added more devices, now runs enough to give an interactive PROM monitor. [R. Belmont] --- src/mame/drivers/decstation.cpp | 147 ++++++++++++++++++++++++++++++-- src/mame/machine/decioga.cpp | 42 ++++++++- src/mame/machine/decioga.h | 10 ++- 3 files changed, 189 insertions(+), 10 deletions(-) diff --git a/src/mame/drivers/decstation.cpp b/src/mame/drivers/decstation.cpp index 982337091c9..b7596a3f4d0 100644 --- a/src/mame/drivers/decstation.cpp +++ b/src/mame/drivers/decstation.cpp @@ -6,6 +6,10 @@ WANTED: all boot ROM dumps except 5000/133, all TURBOchannel card ROM dumps + NOTE: after all the spew of failing tests (it really wants a VT102 terminal), + press 'q' at the MORE prompt and wait a few seconds for the PROM monitor to appear. + Type 'ls' for a list of commands (this is a very UNIX-flavored PROM monitor). + Machine types: DECstation 3100 (PMAX/KN01): 16.67 MHz R2000 with FPU and MMU @@ -55,6 +59,13 @@ #include "emu.h" #include "cpu/mips/r3000.h" #include "machine/decioga.h" +#include "machine/mc146818.h" +#include "machine/z80scc.h" +#include "machine/ncr5390.h" +#include "machine/nscsi_bus.h" +#include "machine/nscsi_cd.h" +#include "machine/nscsi_hd.h" +#include "bus/rs232/rs232.h" class decstation_state : public driver_device { @@ -62,19 +73,35 @@ public: decstation_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu"), - m_ioga(*this, "ioga") + m_ioga(*this, "ioga"), + m_rtc(*this, "rtc"), + m_scc0(*this, "scc0"), + m_scc1(*this, "scc1"), + m_asc(*this, "scsibus:7:asc") { } void kn02da(machine_config &config); void init_decstation(); +protected: + DECLARE_READ_LINE_MEMBER(brcond0_r) { return ASSERT_LINE; } + + DECLARE_READ32_MEMBER(cfb_r); + DECLARE_WRITE32_MEMBER(cfb_w); + + void ncr5394(device_t *device); + private: virtual void machine_start() override; virtual void machine_reset() override; - virtual void video_start() override; + required_device m_maincpu; required_device m_ioga; + required_device m_rtc; + required_device m_scc0, m_scc1; + required_device m_asc; + void decstation_map(address_map &map); }; @@ -82,8 +109,59 @@ private: VIDEO HARDWARE ***************************************************************************/ -void decstation_state::video_start() +READ32_MEMBER(decstation_state::cfb_r) { + static const char fwver[8] = "V5.3a "; + static const char fwvendor[8] = "DEC "; + static const char fwmodule[8] = "PMAG-BA"; + static const char fwtype[8] = "TCF0 "; + static const char fwinfo[8] = "CX - D8"; + uint32_t addr = offset << 2; + + logerror("cfb_r: reading at %x\n", addr); + + // attempt to fake the ROM ID bytes of a PMAG-BA + // color framebuffer card. doesn't work for unknown reasons. + if ((addr >= 0x3c0400) && (addr < 0x3c0420)) + { + return fwver[(addr>>2)&0x7]; + } + if ((addr >= 0x3c0420) && (addr < 0x3c0440)) + { + return fwvendor[(addr>>2)&0x7]; + } + if ((addr >= 0x3c0440) && (addr < 0x3c0460)) + { + return fwmodule[(addr>>2)&0x7]; + } + if ((addr >= 0x3c0460) && (addr < 0x3c0480)) + { + return fwtype[(addr>>2)&0x7]; + } + if ((addr >= 0x3c0480) && (addr < 0x3c04a0)) + { + return fwinfo[(addr>>2)&0x7]; + } + + switch (addr) + { + case 0x3c03e0: return 1; // ROM width + case 0x3c03e4: return 4; // ROM stride + case 0x3c03e8: return 1; // ROM size in 8 KiB units + case 0x3c03ec: return 1; // card address space in 4 MiB units + case 0x3c03f0: return 0x55555555; // TURBOchannel ID bytes + case 0x3c03f4: return 0x00000000; + case 0x3c03f8: return 0xaaaaaaaa; + case 0x3c03fc: return 0xffffffff; + case 0x3c0470: return 0; // does card support parity? + } + + return 0xffffffff; +} + +WRITE32_MEMBER(decstation_state::cfb_w) +{ + logerror("cfb: %08x (mask %08x) @ %x\n", data, mem_mask, offset); } /*************************************************************************** @@ -105,7 +183,18 @@ void decstation_state::machine_reset() void decstation_state::decstation_map(address_map &map) { map(0x00000000, 0x07ffffff).ram(); // full 128 MB - map(0x1c000000, 0x1dffffff).m(m_ioga, FUNC(dec_ioga_device::map)); + map(0x10000000, 0x103cffff).rw(FUNC(decstation_state::cfb_r), FUNC(decstation_state::cfb_w)); + map(0x1c000000, 0x1c07ffff).m(m_ioga, FUNC(dec_ioga_device::map)); + map(0x1c100000, 0x1c100003).rw(m_scc0, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w)).umask32(0x0000ff00); + map(0x1c100004, 0x1c100007).rw(m_scc0, FUNC(z80scc_device::da_r), FUNC(z80scc_device::da_w)).umask32(0x0000ff00); + map(0x1c100008, 0x1c10000b).rw(m_scc0, FUNC(z80scc_device::cb_r), FUNC(z80scc_device::cb_w)).umask32(0x0000ff00); + map(0x1c10000c, 0x1c10000f).rw(m_scc0, FUNC(z80scc_device::db_r), FUNC(z80scc_device::db_w)).umask32(0x0000ff00); + map(0x1c180000, 0x1c180003).rw(m_scc1, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w)).umask32(0x0000ff00); + map(0x1c180004, 0x1c180007).rw(m_scc1, FUNC(z80scc_device::da_r), FUNC(z80scc_device::da_w)).umask32(0x0000ff00); + map(0x1c180008, 0x1c18000b).rw(m_scc1, FUNC(z80scc_device::cb_r), FUNC(z80scc_device::cb_w)).umask32(0x0000ff00); + map(0x1c18000c, 0x1c18000f).rw(m_scc1, FUNC(z80scc_device::db_r), FUNC(z80scc_device::db_w)).umask32(0x0000ff00); + map(0x1c200000, 0x1c2000ff).rw(m_rtc, FUNC(mc146818_device::read_direct), FUNC(mc146818_device::write_direct)).umask32(0x000000ff); + map(0x1c300000, 0x1c30003f).m(m_asc, FUNC(ncr53c94_device::map)).umask32(0x000000ff); map(0x1fc00000, 0x1fc3ffff).rom().region("user1", 0); } @@ -113,12 +202,60 @@ void decstation_state::decstation_map(address_map &map) MACHINE DRIVERS ***************************************************************************/ +void decstation_state::ncr5394(device_t *device) +{ + devcb_base *devcb; + (void)devcb; + MCFG_DEVICE_CLOCK(10000000) +} + +static void dec_scsi_devices(device_slot_interface &device) +{ + device.option_add("cdrom", NSCSI_CDROM); + device.option_add("harddisk", NSCSI_HARDDISK); + device.option_add_internal("asc", NCR53C94); +} + MACHINE_CONFIG_START(decstation_state::kn02da) - MCFG_DEVICE_ADD( "maincpu", R3041, 33000000 ) // FIXME: Should be R2000 + MCFG_DEVICE_ADD( "maincpu", R3041, 33000000 ) // FIXME: Should be R3000A MCFG_R3000_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_R3000_BRCOND0_INPUT(READLINE(*this, decstation_state, brcond0_r)) MCFG_DEVICE_PROGRAM_MAP( decstation_map ) MCFG_DEVICE_ADD("ioga", DECSTATION_IOGA, XTAL(12'500'000)) + + MCFG_DEVICE_ADD("rtc", MC146818, XTAL(32'768)) + MCFG_MC146818_IRQ_HANDLER(WRITELINE("ioga", dec_ioga_device, rtc_irq_w)) + MCFG_MC146818_BINARY(true) + + MCFG_DEVICE_ADD("scc0", SCC85C30, XTAL(14'745'600)/2) + //MCFG_Z80SCC_OUT_INT_CB(WRITELINE("ioga", dec_ioga_device, scc0_irq_w)) + + MCFG_DEVICE_ADD("scc1", SCC85C30, XTAL(14'745'600)/2) + //MCFG_Z80SCC_OUT_INT_CB(WRITELINE("ioga", dec_ioga_device, scc1_irq_w)) + MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("rs232a", rs232_port_device, write_txd)) + MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE("rs232b", rs232_port_device, write_txd)) + + MCFG_DEVICE_ADD("rs232a", RS232_PORT, default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(WRITELINE("scc1", z80scc_device, rxa_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("scc1", z80scc_device, dcda_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("scc1", z80scc_device, ctsa_w)) + + MCFG_DEVICE_ADD("rs232b", RS232_PORT, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(WRITELINE("scc1", z80scc_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("scc1", z80scc_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("scc1", z80scc_device, ctsb_w)) + + MCFG_NSCSI_BUS_ADD("scsibus") + MCFG_NSCSI_ADD("scsibus:0", dec_scsi_devices, "harddisk", false) + MCFG_NSCSI_ADD("scsibus:1", dec_scsi_devices, "cdrom", false) + MCFG_NSCSI_ADD("scsibus:2", dec_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:3", dec_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:4", dec_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:5", dec_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:6", dec_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:7", dec_scsi_devices, "asc", true) + MCFG_SLOT_OPTION_MACHINE_CONFIG("asc", [this] (device_t *device) { ncr5394(device); }) MACHINE_CONFIG_END static INPUT_PORTS_START( decstation ) diff --git a/src/mame/machine/decioga.cpp b/src/mame/machine/decioga.cpp index e40ed1ceffd..a65338f7fcd 100644 --- a/src/mame/machine/decioga.cpp +++ b/src/mame/machine/decioga.cpp @@ -3,8 +3,8 @@ /****************************************************************************** * * MIPS DECstation I/O Gate Array emulation -* -* +* This IC contains some address decoding, an interrupt controller, and +* a multi-channel DMA engine. */ #include "decioga.h" @@ -13,7 +13,9 @@ DEFINE_DEVICE_TYPE(DECSTATION_IOGA, dec_ioga_device, "decioga", "DECstation I/O void dec_ioga_device::map(address_map &map) { - map(0x040100, 0x040103).rw(FUNC(dec_ioga_device::csr_r), FUNC(dec_ioga_device::csr_w)); + map(0x040100, 0x040103).rw(FUNC(dec_ioga_device::csr_r), FUNC(dec_ioga_device::csr_w)); + map(0x040110, 0x040113).rw(FUNC(dec_ioga_device::intr_r), FUNC(dec_ioga_device::intr_w)); + map(0x040120, 0x040123).rw(FUNC(dec_ioga_device::imsk_r), FUNC(dec_ioga_device::imsk_w)); } dec_ioga_device::dec_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -24,10 +26,13 @@ dec_ioga_device::dec_ioga_device(const machine_config &mconfig, const char *tag, void dec_ioga_device::device_start() { save_item(NAME(m_csr)); + save_item(NAME(m_intr)); + save_item(NAME(m_imsk)); } void dec_ioga_device::device_reset() { + m_csr = m_intr = m_imsk = 0; } READ32_MEMBER(dec_ioga_device::csr_r) @@ -46,4 +51,35 @@ WRITE32_MEMBER(dec_ioga_device::csr_w) } printf("]\n"); #endif +} + +READ32_MEMBER(dec_ioga_device::intr_r) +{ + uint32_t rv = m_intr; + m_intr &= ~0x20; // 5000/133 boot ROM tests that reading clears this bit + //printf("m_intr = %08x\n", m_intr); + return rv; +} + +WRITE32_MEMBER(dec_ioga_device::intr_w) +{ + m_intr &= ~data; // clear bits on write +} + +READ32_MEMBER(dec_ioga_device::imsk_r) +{ + return m_imsk; +} + +WRITE32_MEMBER(dec_ioga_device::imsk_w) +{ + COMBINE_DATA(&m_imsk); +} + +WRITE_LINE_MEMBER(dec_ioga_device::rtc_irq_w) +{ + if (state == ASSERT_LINE) + { + m_intr |= 0x20; // tested by 5000/133 boot ROM circa BFC027C8 + } } \ No newline at end of file diff --git a/src/mame/machine/decioga.h b/src/mame/machine/decioga.h index b723d732f26..c014f5dd440 100644 --- a/src/mame/machine/decioga.h +++ b/src/mame/machine/decioga.h @@ -26,15 +26,21 @@ public: void map(address_map &map); + // irq inputs + DECLARE_WRITE_LINE_MEMBER(rtc_irq_w); + protected: virtual void device_start() override; virtual void device_reset() override; DECLARE_READ32_MEMBER(csr_r); DECLARE_WRITE32_MEMBER(csr_w); - + DECLARE_READ32_MEMBER(intr_r); + DECLARE_WRITE32_MEMBER(intr_w); + DECLARE_READ32_MEMBER(imsk_r); + DECLARE_WRITE32_MEMBER(imsk_w); private: - uint32_t m_csr; + uint32_t m_csr, m_intr, m_imsk; }; DECLARE_DEVICE_TYPE(DECSTATION_IOGA, dec_ioga_device)