summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-09-20 18:08:59 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2018-09-20 18:08:59 +0700
commit895ffe0763a713fe644c53afe573e9839ee822a1 (patch)
treeea2fce92c128113a39eeee2c9ddb70650917e4cb
parent234a7768328a8fc2bbc857f63f157df8bc24a208 (diff)
jazz: new skeleton driver (nw)
A skeleton for the Microsoft Jazz architecture, which was implemented in the MIPS Magnum 4000, Olivetti M700-10 and was the base/origin of several other MIPS ARC systems. * added skeleton Inmos G300/G332/G364 device * added skeleton NatSemi DP83932C SONIC device * added skeleton MCT-ADR device
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/src/video.lua12
-rw-r--r--scripts/target/mame/mess.lua11
-rw-r--r--src/devices/machine/dp83932c.cpp140
-rw-r--r--src/devices/machine/dp83932c.h59
-rw-r--r--src/devices/video/ims_cvc.cpp139
-rw-r--r--src/devices/video/ims_cvc.h142
-rw-r--r--src/mame/drivers/jazz.cpp206
-rw-r--r--src/mame/includes/jazz.h97
-rw-r--r--src/mame/machine/jazz_mct_adr.cpp51
-rw-r--r--src/mame/machine/jazz_mct_adr.h25
-rw-r--r--src/mame/mame.lst4
12 files changed, 898 insertions, 0 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index 7c1cc8e66ca..cd141b26cb3 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -3180,6 +3180,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/dp83932c.h,MACHINES["DP83932C"] = true
+---------------------------------------------------
+
+if (MACHINES["DP83932C"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/dp83932c.cpp",
+ MAME_DIR .. "src/devices/machine/dp83932c.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/pc_lpt.h,MACHINES["PC_LPT"] = true
---------------------------------------------------
diff --git a/scripts/src/video.lua b/scripts/src/video.lua
index c014a026fad..a5b47457dd3 100644
--- a/scripts/src/video.lua
+++ b/scripts/src/video.lua
@@ -497,6 +497,18 @@ end
--------------------------------------------------
--
+--@src/devices/video/ims_cvc.h,VIDEOS["IMS_CVC"] = true
+--------------------------------------------------
+
+if (VIDEOS["IMS_CVC"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/video/ims_cvc.cpp",
+ MAME_DIR .. "src/devices/video/ims_cvc.h",
+ }
+end
+
+--------------------------------------------------
+--
--@src/devices/video/m50458.h,VIDEOS["M50458"] = true
--------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index b8a01662661..3ad7dd9413a 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -324,6 +324,7 @@ VIDEOS["HUC6272"] = true
VIDEOS["I8244"] = true
VIDEOS["I82730"] = true
VIDEOS["I8275"] = true
+VIDEOS["IMS_CVC"] = true
--VIDEOS["M50458"] = true
--VIDEOS["MB90082"] = true
--VIDEOS["MB_VCU"] = true
@@ -420,6 +421,7 @@ MACHINES["CS4031"] = true
MACHINES["CS8221"] = true
MACHINES["CXD1095"] = true
MACHINES["DP8390"] = true
+MACHINES["DP83932C"] = true
--MACHINES["DS1204"] = true
MACHINES["DS1302"] = true
MACHINES["DS1315"] = true
@@ -1064,6 +1066,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"interton",
"intv",
"isc",
+ "jazz",
"kaypro",
"koei",
"kontron",
@@ -2340,6 +2343,14 @@ files {
MAME_DIR .. "src/mame/drivers/compucolor.cpp",
}
+createMESSProjects(_target, _subtarget, "jazz")
+files {
+ MAME_DIR .. "src/mame/drivers/jazz.cpp",
+ MAME_DIR .. "src/mame/includes/jazz.h",
+ MAME_DIR .. "src/mame/machine/jazz_mct_adr.cpp",
+ MAME_DIR .. "src/mame/machine/jazz_mct_adr.h",
+}
+
createMESSProjects(_target, _subtarget, "kaypro")
files {
MAME_DIR .. "src/mame/drivers/kaypro.cpp",
diff --git a/src/devices/machine/dp83932c.cpp b/src/devices/machine/dp83932c.cpp
new file mode 100644
index 00000000000..c8c7fcfcd9e
--- /dev/null
+++ b/src/devices/machine/dp83932c.cpp
@@ -0,0 +1,140 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An implementation of the National Semiconductor DP83932C SONIC™ (Systems-
+ * Oriented Network Interface Controller) device.
+ *
+ * References:
+ *
+ * http://bitsavers.org/components/national/_dataBooks/1995_National_Ethernet_Databook.pdf
+ *
+ * TODO
+ * - everything (skeleton only)
+ */
+
+#include "emu.h"
+#include "dp83932c.h"
+#include "hashing.h"
+
+#define VERBOSE 0
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(DP83932C_BE, dp83932c_be_device, "dp83932c_be", "National Semiconductor DP83932C SONIC (big)")
+DEFINE_DEVICE_TYPE(DP83932C_LE, dp83932c_le_device, "dp83932c_le", "National Semiconductor DP83932C SONIC (little)")
+
+dp83932c_device::dp83932c_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endian)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , device_network_interface(mconfig, *this, 10.0f)
+ , m_space_config("shared", endian, 32, 32)
+ , m_out_int(*this)
+{
+}
+
+dp83932c_be_device::dp83932c_be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : dp83932c_device(mconfig, DP83932C_BE, tag, owner, clock, ENDIANNESS_BIG)
+{
+}
+
+dp83932c_le_device::dp83932c_le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : dp83932c_device(mconfig, DP83932C_LE, tag, owner, clock, ENDIANNESS_LITTLE)
+{
+}
+
+void dp83932c_device::map(address_map &map)
+{
+/*
+ // command and status registers
+ map(0x00, 0x03).rw(FUNC(dp83932c_device::cr_r), FUNC(dp83932c_device::cr_w));
+ map(0x04, 0x07).rw(FUNC(dp83932c_device::dcr_r), FUNC(dp83932c_device::dcr_w));
+ map(0x08, 0x0b).rw(FUNC(dp83932c_device::rcr_r), FUNC(dp83932c_device::rcr_w));
+ map(0x0c, 0x0f).rw(FUNC(dp83932c_device::tcr_r), FUNC(dp83932c_device::tcr_w));
+ map(0x10, 0x13).rw(FUNC(dp83932c_device::imr_r), FUNC(dp83932c_device::imr_w));
+ map(0x14, 0x17).rw(FUNC(dp83932c_device::isr_r), FUNC(dp83932c_device::isr_w));
+
+ // transmit registers
+ map(0x18, 0x1b).rw(FUNC(dp83932c_device::utda_r), FUNC(dp83932c_device::utda_w));
+ map(0x1c, 0x1f).rw(FUNC(dp83932c_device::ctda_r), FUNC(dp83932c_device::ctda_w));
+
+ // tps
+ // tfc
+ // tsa0
+ // tsa1
+ // tfs
+
+ // receive registers
+ map(0x34, 0x37).rw(FUNC(dp83932c_device::urda_r), FUNC(dp83932c_device::urda_w));
+ map(0x38, 0x3b).rw(FUNC(dp83932c_device::crda_r), FUNC(dp83932c_device::crda_w));
+
+ // crba0
+ // crba1
+ // rbwc0
+ // rbwc1
+ // eobc
+ // urra
+ // rsa
+ // rea
+ // rrp
+ // rwp
+ // trba0
+ // trba1
+ // tbwc0
+ // tbwc1
+ // addr0
+ // addr1
+ // llfa
+ // ttda
+ // cep
+ // cap2
+ // cap1
+ // cap0
+ // ce
+ // cdp
+ // cdc
+ // sr
+ // wt0
+ // wt1
+ // rsc
+ // crct
+ // faet
+ // mpt
+ // mdt
+
+ // 30-3e internal use registers
+*/
+}
+
+void dp83932c_device::device_start()
+{
+ m_space = &space(0);
+ m_out_int.resolve();
+}
+
+void dp83932c_device::device_reset()
+{
+}
+
+void dp83932c_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+}
+
+device_memory_interface::space_config_vector dp83932c_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+void dp83932c_device::send_complete_cb(int result)
+{
+}
+
+int dp83932c_device::recv_start_cb(u8 *buf, int length)
+{
+ return 0;
+}
+
+void dp83932c_device::recv_complete_cb(int result)
+{
+}
diff --git a/src/devices/machine/dp83932c.h b/src/devices/machine/dp83932c.h
new file mode 100644
index 00000000000..27f5ae60d85
--- /dev/null
+++ b/src/devices/machine/dp83932c.h
@@ -0,0 +1,59 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_MACHINE_DP83932C_H
+#define MAME_MACHINE_DP83932C_H
+
+#pragma once
+
+class dp83932c_device :
+ public device_t,
+ public device_memory_interface,
+ public device_network_interface
+{
+public:
+ // callback configuration
+ auto out_int_cb() { return m_out_int.bind(); }
+
+ void map(address_map &map);
+
+protected:
+ dp83932c_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endian);
+
+ // device_t overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
+ // device_network_interface overrides
+ virtual void send_complete_cb(int result) override;
+ virtual int recv_start_cb(u8 *buf, int length) override;
+ virtual void recv_complete_cb(int result) override;
+
+private:
+ // device_memory_interface members
+ const address_space_config m_space_config;
+ address_space *m_space;
+
+ devcb_write_line m_out_int;
+};
+
+class dp83932c_be_device : public dp83932c_device
+{
+public:
+ dp83932c_be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class dp83932c_le_device : public dp83932c_device
+{
+public:
+ dp83932c_le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+DECLARE_DEVICE_TYPE(DP83932C_BE, dp83932c_be_device)
+DECLARE_DEVICE_TYPE(DP83932C_LE, dp83932c_le_device)
+
+#endif // MAME_MACHINE_DP83932C_H
diff --git a/src/devices/video/ims_cvc.cpp b/src/devices/video/ims_cvc.cpp
new file mode 100644
index 00000000000..ca6efc1b7d1
--- /dev/null
+++ b/src/devices/video/ims_cvc.cpp
@@ -0,0 +1,139 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An implementation of the INMOS G300, G332 and G364 CVC (Colour Video
+ * Controller) devices.
+ *
+ * References:
+ *
+ * http://bitsavers.org/components/inmos/graphics/72-TRN-204-01_Graphics_Databook_Second_Edition_1990.pdf
+ *
+ * TODO
+ * - everything (skeleton only)
+ */
+
+#include "emu.h"
+#include "ims_cvc.h"
+
+#include "screen.h"
+
+#define VERBOSE 0
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(G300, g300_device, "g300", "INMOS G300 Colour Video Controller")
+DEFINE_DEVICE_TYPE(G332, g332_device, "g332", "INMOS G332 Colour Video Controller")
+DEFINE_DEVICE_TYPE(G364, g364_device, "g364", "INMOS G364 Colour Video Controller")
+
+ims_cvc_device::ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , device_palette_interface(mconfig, *this)
+ , m_space_config("shared", ENDIANNESS_LITTLE, 32, 24)
+{
+}
+
+g300_device::g300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ims_cvc_device(mconfig, G300, tag, owner, clock)
+{
+}
+
+g332_device::g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : ims_cvc_device(mconfig, type, tag, owner, clock)
+{
+}
+
+g332_device::g332_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ims_cvc_device(mconfig, G332, tag, owner, clock)
+{
+}
+
+g364_device::g364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : g332_device(mconfig, G364, tag, owner, clock)
+{
+}
+
+device_memory_interface::space_config_vector ims_cvc_device::memory_space_config() const
+{
+ return space_config_vector{
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+void g300_device::map(address_map &map)
+{
+ // datasheet gives unshifted addresses
+ const int shift = 2;
+
+ // colour palette
+ map(0x000 << shift, (0x0ff << shift) | 0x3).rw(FUNC(g300_device::colour_palette_r), FUNC(g300_device::colour_palette_w));
+
+ // data path registers
+ map(0x121, (0x121 << shift) | 0x3).rw(FUNC(g300_device::halfsync_r), FUNC(g300_device::halfsync_w));
+ map(0x122, (0x122 << shift) | 0x3).rw(FUNC(g300_device::backporch_r), FUNC(g300_device::backporch_w));
+ map(0x123, (0x123 << shift) | 0x3).rw(FUNC(g300_device::display_r), FUNC(g300_device::display_w));
+ map(0x124, (0x124 << shift) | 0x3).rw(FUNC(g300_device::shortdisplay_r), FUNC(g300_device::shortdisplay_w));
+ map(0x125, (0x125 << shift) | 0x3).rw(FUNC(g300_device::broadpulse_r), FUNC(g300_device::broadpulse_w));
+ map(0x126, (0x126 << shift) | 0x3).rw(FUNC(g300_device::vsync_r), FUNC(g300_device::vsync_w));
+ map(0x127, (0x127 << shift) | 0x3).rw(FUNC(g300_device::vblank_r), FUNC(g300_device::vblank_w));
+ map(0x128, (0x128 << shift) | 0x3).rw(FUNC(g300_device::vdisplay_r), FUNC(g300_device::vdisplay_w));
+ map(0x129, (0x129 << shift) | 0x3).rw(FUNC(g300_device::linetime_r), FUNC(g300_device::linetime_w));
+ map(0x12a, (0x12a << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w));
+ map(0x12b, (0x12b << shift) | 0x3).rw(FUNC(g300_device::meminit_r), FUNC(g300_device::meminit_w));
+ map(0x12c, (0x12c << shift) | 0x3).rw(FUNC(g300_device::transferdelay_r), FUNC(g300_device::transferdelay_w));
+
+ map(0x140 << shift, (0x140 << shift) | 0x3).rw(FUNC(g300_device::mask_r), FUNC(g300_device::mask_w));
+ map(0x160 << shift, (0x160 << shift) | 0x3).rw(FUNC(g300_device::control_r), FUNC(g300_device::control_w));
+ map(0x180 << shift, (0x180 << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w));
+ map(0x1a0 << shift, (0x1a0 << shift) | 0x3).w(FUNC(g300_device::boot_w));
+}
+
+void g332_device::map(address_map &map)
+{
+ // datasheet gives unshifted addresses
+ const int shift = 2; // TODO: 64 bit mode
+
+ map(0x000 << shift, (0x000 << shift) | 0x3).w(FUNC(g332_device::boot_w));
+
+ // data path registers
+ map(0x021, (0x021 << shift) | 0x3).rw(FUNC(g332_device::halfsync_r), FUNC(g332_device::halfsync_w));
+ map(0x022, (0x022 << shift) | 0x3).rw(FUNC(g332_device::backporch_r), FUNC(g332_device::backporch_w));
+ map(0x023, (0x023 << shift) | 0x3).rw(FUNC(g332_device::display_r), FUNC(g332_device::display_w));
+ map(0x024, (0x024 << shift) | 0x3).rw(FUNC(g332_device::shortdisplay_r), FUNC(g332_device::shortdisplay_w));
+ map(0x025, (0x025 << shift) | 0x3).rw(FUNC(g332_device::broadpulse_r), FUNC(g332_device::broadpulse_w));
+ map(0x026, (0x026 << shift) | 0x3).rw(FUNC(g332_device::vsync_r), FUNC(g332_device::vsync_w));
+ map(0x027, (0x027 << shift) | 0x3).rw(FUNC(g332_device::vpreequalise_r), FUNC(g332_device::vpreequalise_w));
+ map(0x028, (0x028 << shift) | 0x3).rw(FUNC(g332_device::vpostequalise_r), FUNC(g332_device::vpostequalise_w));
+ map(0x029, (0x029 << shift) | 0x3).rw(FUNC(g332_device::vblank_r), FUNC(g332_device::vblank_w));
+ map(0x02a, (0x02a << shift) | 0x3).rw(FUNC(g332_device::vdisplay_r), FUNC(g332_device::vdisplay_w));
+ map(0x02b, (0x02b << shift) | 0x3).rw(FUNC(g332_device::linetime_r), FUNC(g332_device::linetime_w));
+ map(0x02c, (0x02c << shift) | 0x3).rw(FUNC(g332_device::linestart_r), FUNC(g332_device::linestart_w));
+ map(0x02d, (0x02d << shift) | 0x3).rw(FUNC(g332_device::meminit_r), FUNC(g332_device::meminit_w));
+ map(0x02e, (0x02e << shift) | 0x3).rw(FUNC(g332_device::transferdelay_r), FUNC(g332_device::transferdelay_w));
+
+ map(0x040 << shift, (0x040 << shift) | 0x3).rw(FUNC(g332_device::mask_r), FUNC(g332_device::mask_w));
+ map(0x060 << shift, (0x060 << shift) | 0x3).rw(FUNC(g332_device::control_a_r), FUNC(g332_device::control_a_w));
+ map(0x070 << shift, (0x070 << shift) | 0x3).rw(FUNC(g332_device::control_b_r), FUNC(g332_device::control_b_w));
+ map(0x080 << shift, (0x080 << shift) | 0x3).rw(FUNC(g332_device::tos_r), FUNC(g332_device::tos_w));
+
+ // cursor palette (0a1-0a3)
+ // checksum registers (0c0-0c2)
+
+ // colour palette
+ map(0x100 << shift, (0x1ff << shift) | 0x3).rw(FUNC(g332_device::colour_palette_r), FUNC(g332_device::colour_palette_w));
+
+ // cursor store (200-3ff)
+ // cursor position (0c7)
+}
+
+void ims_cvc_device::device_start()
+{
+}
+
+void ims_cvc_device::device_reset()
+{
+}
+
+void ims_cvc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+}
diff --git a/src/devices/video/ims_cvc.h b/src/devices/video/ims_cvc.h
new file mode 100644
index 00000000000..25c0163642d
--- /dev/null
+++ b/src/devices/video/ims_cvc.h
@@ -0,0 +1,142 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+#ifndef MAME_VIDEO_IMS_CVC_H
+#define MAME_VIDEO_IMS_CVC_H
+
+#pragma once
+
+class ims_cvc_device :
+ public device_t,
+ public device_memory_interface,
+ public device_palette_interface
+{
+public:
+ virtual void map(address_map &map) = 0;
+
+ void screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+protected:
+ ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device_t overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
+ // device_palette_interface overrides
+ virtual u32 palette_entries() const override { return 256; } // FIXME
+
+ u32 colour_palette_r(const offs_t offset) { return 0; }
+ void colour_palette_w(const offs_t offset, const u32 data) {}
+ u32 halfsync_r() { return m_halfsync; }
+ void halfsync_w(const u32 data) { m_halfsync = data; }
+ u32 backporch_r() { return m_backporch; }
+ void backporch_w(const u32 data) { m_backporch = data; }
+ u32 display_r() { return m_display; }
+ void display_w(const u32 data) { m_display = data; }
+ u32 shortdisplay_r() { return m_shortdisplay; }
+ void shortdisplay_w(const u32 data) { m_shortdisplay = data; }
+ u32 broadpulse_r() { return m_broadpulse; }
+ void broadpulse_w(const u32 data) { m_broadpulse = data; }
+ u32 vsync_r() { return m_vsync; }
+ void vsync_w(const u32 data) { m_vsync = data; }
+ u32 vblank_r() { return m_vblank; }
+ void vblank_w(const u32 data) { m_vblank = data; }
+ u32 vdisplay_r() { return m_vdisplay; }
+ void vdisplay_w(const u32 data) { m_vdisplay = data; }
+ u32 linetime_r() { return m_linetime; }
+ void linetime_w(const u32 data) { m_linetime = data; }
+ //u32 tos_r() { return m_tos; }
+ //void tos_w(const u32 data) { m_tos = data; }
+ u32 meminit_r() { return m_meminit; }
+ void meminit_w(const u32 data) { m_meminit = data; }
+ u32 transferdelay_r() { return m_transferdelay; }
+ void transferdelay_w(const u32 data) { m_transferdelay = data; }
+
+ u32 mask_r() { return m_mask; }
+ void mask_w(const u32 data) { m_mask = data; }
+ u32 tos_r() { return m_tos; }
+ void tos_w(const u32 data) { m_tos = data; }
+
+ void boot_w(const u32 data) { m_boot = data; }
+
+private:
+ // device_memory_interface members
+ const address_space_config m_space_config;
+ address_space *m_space;
+
+ // device state
+ u32 m_halfsync;
+ u32 m_backporch;
+ u32 m_display;
+ u32 m_shortdisplay;
+ u32 m_broadpulse;
+ u32 m_vsync;
+ u32 m_vblank;
+ u32 m_vdisplay;
+ u32 m_linetime;
+ u32 m_meminit;
+ u32 m_transferdelay;
+
+ u32 m_mask;
+ u32 m_tos;
+ u32 m_boot;
+};
+
+class g300_device : public ims_cvc_device
+{
+public:
+ g300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void map(address_map &map) override;
+
+protected:
+ u32 control_r() { return m_control; }
+ void control_w(const u32 data) { m_control = data; }
+
+private:
+ u32 m_control;
+};
+
+class g332_device : public ims_cvc_device
+{
+public:
+ g332_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void map(address_map &map) override;
+
+protected:
+ g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ u32 vpreequalise_r() { return m_vpreequalise; }
+ void vpreequalise_w(const u32 data) { m_vpreequalise = data; }
+ u32 vpostequalise_r() { return m_vpostequalise; }
+ void vpostequalise_w(const u32 data) { m_vpostequalise = data; }
+ u32 linestart_r() { return m_linestart; }
+ void linestart_w(const u32 data) { m_linestart = data; }
+ u32 control_a_r() { return m_control_a; }
+ void control_a_w(const u32 data) { m_control_a = data; }
+ u32 control_b_r() { return m_control_b; }
+ void control_b_w(const u32 data) { m_control_b = data; }
+
+private:
+ u32 m_vpreequalise;
+ u32 m_vpostequalise;
+ u32 m_linestart;
+ u32 m_control_a;
+ u32 m_control_b;
+};
+
+class g364_device : public g332_device
+{
+public:
+ g364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+DECLARE_DEVICE_TYPE(G300, g300_device)
+DECLARE_DEVICE_TYPE(G332, g332_device)
+DECLARE_DEVICE_TYPE(G364, g364_device)
+
+#endif // MAME_VIDEO_IMS_CVC_H
diff --git a/src/mame/drivers/jazz.cpp b/src/mame/drivers/jazz.cpp
new file mode 100644
index 00000000000..14b9d0876dc
--- /dev/null
+++ b/src/mame/drivers/jazz.cpp
@@ -0,0 +1,206 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An emulation of systems based on the Jazz computer architecture, originally
+ * developed by Microsoft. Specific systems which implemented this architecture
+ * include the MIPS Magnum/Millenium 4000 and Olivetti M700-10.
+ *
+ * References:
+ *
+ * https://www.linux-mips.org/wiki/Jazz
+ * http://gunkies.org/wiki/MIPS_Magnum
+ * http://www.sensi.org/~alec/mips/mips-history.html
+ *
+ * TODO
+ * - everything (skeleton only)
+ *
+ * Unconfirmed parts lists from ARCSystem reference design (which appears to
+ * be very similar or identical to the Jazz system) taken from:
+ * https://www.linux-mips.org/archives/riscy/1993-12/msg00013.html
+ *
+ * Ref Part Function
+ *
+ * System board:
+ *
+ * Dallas DS1287 RTC and NVRAM
+ * Dallas DS1225Y 8k non-volatile SRAM
+ * WD16C552 Dual serial and parallel port controller
+ * Intel N82077A Floppy drive controller
+ * National DP83932BFV Ethernet controller
+ * Intel 82358 EISA Bus Controller
+ * Intel 82357 EISA Integrated System Peripheral (ISP)
+ * Intel 82352 x 2 EISA Bus Buffer (EBB)
+ * Emulex FAS216 SCSI controller
+ * 27C01 128k EPROM
+ * 28F020 256k flash memory
+ * NEC μPD31432 ARC address path ASIC
+ * NEC μPD31431 x 2 ARC data path ASIC
+ * NEC μPD30400 R4000PC/50 CPU
+ *
+ * Audio board:
+ *
+ * Crystal CS4215 Audio codec
+ * Altera FPGA x 4 Audio DMA
+ *
+ * Video board:
+ *
+ * 27C010 128k EPROM
+ * IMS G364-11S Video controller
+ * NEC μPD42274V-80 x 16 256kx4 VRAM (2MiB)
+ */
+
+#include "emu.h"
+
+#include "includes/jazz.h"
+
+#include "debugger.h"
+
+#define VERBOSE 0
+#include "logmacro.h"
+
+void jazz_state::machine_start()
+{
+}
+
+void jazz_state::machine_reset()
+{
+}
+
+void jazz_state::init_common()
+{
+ // map the configured ram
+ m_maincpu->space(AS_PROGRAM).install_ram(0, m_ram->mask(), m_ram->pointer());
+}
+
+void jazz_state::jazz_common_map(address_map &map)
+{
+ map(0x1fc00000, 0x1fc3ffff).r(m_flash, FUNC(amd_28f020_device::read));
+
+ // FIXME: lots of guesswork and assumptions here for now
+ map(0x80000000, 0x80000fff).m(m_mct_adr, FUNC(jazz_mct_adr_device::map));
+ map(0x80001000, 0x80001fff).m(m_network, FUNC(dp83932c_device::map));
+ //map(0x80002000, 0x80002fff).m(m_scsi, FUNC(ncr5390_device::map)).umask32(0x000000ff);
+ map(0x80003000, 0x80003fff).m(m_fdc, FUNC(n82077aa_device::map));
+ //map(0x80004000, 0x80004fff).rw(m_rtc, FUNC(mc146818_device::read), FUNC(mc146818_device::write));
+ //map(0x80005000, 0x80005fff).m() // keyboard/mouse
+ //map(0x80006000, 0x80006fff).m() // serial1
+ //map(0x80007000, 0x80007fff).m() // serial2
+ //map(0x80008000, 0x80008fff).m() // parallel
+ map(0x80009000, 0x80009fff).ram().share("nvram"); // unprotected?
+ map(0x8000a000, 0x8000afff).ram().share("nvram"); // protected?
+ map(0x8000b000, 0x8000bfff).ram().share("nvram"); // read-only? also sonic IO access?
+ //map(0x8000c000, 0x8000cfff) // sound
+ map(0x8000d000, 0x8000dfff).noprw(); // dummy dma device?
+
+ map(0x8000f000, 0x8000f001).rw(FUNC(jazz_state::led_r), FUNC(jazz_state::led_w));
+
+ //map(0x800e0000, 0x800e0000).rw(FUNC(jazz_state::dram_config_r), FUNC(jazz_state::dram_config_w));
+
+ map(0xe0800000, 0xe0bfffff).ram().share("vram"); // framebuffer?
+
+ map(0xfff00000, 0xfff3ffff).r(m_flash, FUNC(amd_28f020_device::read)); // mirror?
+}
+
+static void jazz_scsi_devices(device_slot_interface &device)
+{
+ device.option_add("harddisk", NSCSI_HARDDISK);
+ device.option_add("cdrom", NSCSI_CDROM);
+}
+
+void jazz_state::jazz(machine_config &config)
+{
+ m_maincpu->set_addrmap(AS_PROGRAM, &jazz_state::jazz_common_map);
+
+ RAM(config, m_ram, 0);
+ m_ram->set_default_size("8M");
+ m_ram->set_extra_options("16M,32M,64M,128M,256M");
+ m_ram->set_default_value(0);
+
+ // FIXME: may require big and little endian variants
+ JAZZ_MCT_ADR(config, m_mct_adr, 0);
+
+ // scsi bus and devices
+ NSCSI_BUS(config, m_scsibus, 0);
+
+ nscsi_connector &harddisk(NSCSI_CONNECTOR(config, "scsi:0", 0));
+ jazz_scsi_devices(harddisk);
+ harddisk.set_default_option("harddisk");
+
+ nscsi_connector &cdrom(NSCSI_CONNECTOR(config, "scsi:6", 0));
+ jazz_scsi_devices(cdrom);
+ cdrom.set_default_option("cdrom");
+
+ jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:1", 0));
+ jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:2", 0));
+ jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:3", 0));
+ jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:4", 0));
+ jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:5", 0));
+
+ // scsi host adapter
+ nscsi_connector &adapter(NSCSI_CONNECTOR(config, "scsi:7", 0));
+ adapter.option_add_internal("host", NCR53C90A);
+ adapter.set_default_option("host");
+ adapter.set_fixed(true);
+
+ N82077AA(config, m_fdc, 24_MHz_XTAL);
+
+ MC146818(config, m_rtc, 32.768_kHz_XTAL);
+
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
+
+ AMD_28F020(config, m_flash);
+
+ // pc keyboard controller?
+ pc_kbdc_device &kbdc(PC_KBDC(config, "pc_kbdc", 0));
+ kbdc.out_clock_cb().set(m_kbdc, FUNC(at_keyboard_controller_device::keyboard_clock_w));
+ kbdc.out_data_cb().set(m_kbdc, FUNC(at_keyboard_controller_device::keyboard_data_w));
+
+ // keyboard port
+ pc_kbdc_slot_device &kbd(PC_KBDC_SLOT(config, "kbd", 0));
+ pc_at_keyboards(kbd);
+ kbd.set_default_option(STR_KBD_IBM_PC_AT_84);
+ kbd.set_pc_kbdc_slot(&kbdc);
+
+ // at keyboard controller
+ AT_KEYBOARD_CONTROLLER(config, m_kbdc, 12_MHz_XTAL);
+ m_kbdc->system_reset_cb().set_inputline(m_maincpu, INPUT_LINE_RESET);
+ m_kbdc->keyboard_clock_cb().set(kbdc, FUNC(pc_kbdc_device::clock_write_from_mb));
+ m_kbdc->keyboard_data_cb().set(kbdc, FUNC(pc_kbdc_device::data_write_from_mb));
+
+ G364(config, m_ramdac, 0);
+}
+
+void jazz_state::mmr4000be(machine_config &config)
+{
+ R4000BE(config, m_maincpu, 50_MHz_XTAL);
+
+ jazz(config);
+
+ DP83932C_BE(config, m_network, 20_MHz_XTAL);
+}
+
+void jazz_state::mmr4000le(machine_config &config)
+{
+ R4000LE(config, m_maincpu, 50_MHz_XTAL);
+
+ jazz(config);
+
+ DP83932C_LE(config, m_network, 20_MHz_XTAL);
+}
+
+ROM_START(mmr4000be)
+ ROM_REGION32_BE(0x40000, "flash", 0)
+ ROM_SYSTEM_BIOS(0, "riscos", "R4000 RISC/os PROM")
+ ROMX_LOAD("riscos.bin", 0x00000, 0x40000, CRC(cea6bc8f) SHA1(3e47b4ad5d1a0c7aac649e6aef3df1bf86fc938b), ROM_BIOS(0))
+ROM_END
+
+ROM_START(mmr4000le)
+ ROM_REGION32_LE(0x40000, "flash", 0)
+ ROM_SYSTEM_BIOS(0, "ntprom", "R4000 Windows NT PROM")
+ ROMX_LOAD("ntprom.bin", 0x00000, 0x40000, CRC(d91018d7) SHA1(316de17820192c89b8ee6d9936ab8364a739ca53), ROM_BIOS(0))
+ROM_END
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
+COMP( 1992, mmr4000be, 0, 0, mmr4000be, 0, jazz_state, init_common, "MIPS", "Magnum R4000 (big)", MACHINE_IS_SKELETON)
+COMP( 1992, mmr4000le, 0, 0, mmr4000le, 0, jazz_state, init_common, "MIPS", "Magnum R4000 (little)", MACHINE_IS_SKELETON)
diff --git a/src/mame/includes/jazz.h b/src/mame/includes/jazz.h
new file mode 100644
index 00000000000..d666b81a45a
--- /dev/null
+++ b/src/mame/includes/jazz.h
@@ -0,0 +1,97 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_INCLUDES_JAZZ_H
+#define MAME_INCLUDES_JAZZ_H
+
+#pragma once
+
+#include "cpu/mips/mips3.h"
+
+// memory
+#include "machine/ram.h"
+#include "machine/nvram.h"
+#include "machine/28fxxx.h"
+
+// various hardware
+#include "machine/jazz_mct_adr.h"
+#include "machine/dp83932c.h"
+#include "machine/mc146818.h"
+#include "machine/ncr5390.h"
+#include "machine/upd765.h"
+#include "machine/at_keybc.h"
+
+// video
+#include "screen.h"
+#include "video/ims_cvc.h"
+
+// busses and connectors
+#include "machine/nscsi_bus.h"
+#include "machine/nscsi_cd.h"
+#include "machine/nscsi_hd.h"
+#include "bus/rs232/rs232.h"
+#include "bus/pc_kbd/pc_kbdc.h"
+#include "bus/pc_kbd/keyboards.h"
+
+class jazz_state : public driver_device
+{
+public:
+ jazz_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "cpu")
+ , m_ram(*this, "ram")
+ , m_mct_adr(*this, "mct_adr")
+ , m_scsibus(*this, "scsi")
+ , m_scsi(*this, "scsi:7:host")
+ , m_fdc(*this, "fdc")
+ , m_rtc(*this, "rtc")
+ , m_nvram(*this, "nvram")
+ , m_flash(*this, "flash")
+ , m_kbdc(*this, "kbdc")
+ , m_network(*this, "net")
+ , m_ramdac(*this, "g364")
+ {
+ }
+
+protected:
+ // driver_device overrides
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ // address maps
+ void jazz_common_map(address_map &map);
+
+ // machine config
+ void jazz(machine_config &config);
+public:
+ void mmr4000be(machine_config &config);
+ void mmr4000le(machine_config &config);
+
+ void init_common();
+
+protected:
+ // devices
+ required_device<mips3_device> m_maincpu;
+ required_device<ram_device> m_ram;
+ required_device<jazz_mct_adr_device> m_mct_adr;
+ required_device<nscsi_bus_device> m_scsibus;
+ required_device<ncr5390_device> m_scsi;
+ required_device<n82077aa_device> m_fdc;
+ required_device<mc146818_device> m_rtc;
+ required_device<nvram_device> m_nvram;
+ required_device<amd_28f020_device> m_flash;
+ required_device<at_keyboard_controller_device> m_kbdc;
+ required_device<dp83932c_device> m_network;
+ //required_device<screen_device> m_screen;
+ required_device<g364_device> m_ramdac;
+
+ // helpers
+ u8 led_r() { return m_led; }
+ void led_w(const u8 data) { logerror("led 0x%02x\n", data); m_led = data; }
+
+private:
+ // machine state
+ u8 m_led;
+};
+
+#endif // MAME_INCLUDES_JAZZ_H
diff --git a/src/mame/machine/jazz_mct_adr.cpp b/src/mame/machine/jazz_mct_adr.cpp
new file mode 100644
index 00000000000..e14075f3f3f
--- /dev/null
+++ b/src/mame/machine/jazz_mct_adr.cpp
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An implementation of the MCT-ADR device found in Microsoft Jazz/MIPS
+ * ARCSystem 100 architecture systems. This device was originally designed
+ * by Microsoft, and then implemented and used in various forms by MIPS,
+ * Olivetti, LSI Logic, NEC, Acer and others.
+ *
+ * Specific implementations/derivatives include:
+ *
+ * LSI Logic R4030/R4230
+ * NEC μPD31432
+ * ALI M6101-A1
+ *
+ * References:
+ *
+ * https://datasheet.datasheetarchive.com/originals/scans/Scans-054/DSAIH000102184.pdf
+ * https://github.com/torvalds/linux/tree/master/arch/mips/jazz/
+ * http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/arc/jazz/
+ *
+ * TODO
+ * - everything (skeleton only)
+ */
+
+#include "emu.h"
+#include "jazz_mct_adr.h"
+
+#define VERBOSE 0
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(JAZZ_MCT_ADR, jazz_mct_adr_device, "jazz_mct_adr", "Jazz MCT-ADR")
+
+jazz_mct_adr_device::jazz_mct_adr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, JAZZ_MCT_ADR, tag, owner, clock)
+{
+}
+
+void jazz_mct_adr_device::map(address_map &map)
+{
+ map(0x000, 0x003).lr32("config", [](){ return 0x00000000; });
+ map(0x008, 0x00b).lr32("revision", [](){ return 0xf0000000; });
+}
+
+void jazz_mct_adr_device::device_start()
+{
+}
+
+void jazz_mct_adr_device::device_reset()
+{
+}
diff --git a/src/mame/machine/jazz_mct_adr.h b/src/mame/machine/jazz_mct_adr.h
new file mode 100644
index 00000000000..dd2b651d25c
--- /dev/null
+++ b/src/mame/machine/jazz_mct_adr.h
@@ -0,0 +1,25 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_MACHINE_JAZZ_MCT_ADR_H
+#define MAME_MACHINE_JAZZ_MCT_ADR_H
+
+#pragma once
+
+class jazz_mct_adr_device : public device_t
+{
+public:
+ jazz_mct_adr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void map(address_map &map);
+
+protected:
+ // device_t overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(JAZZ_MCT_ADR, jazz_mct_adr_device)
+
+#endif // MAME_MACHINE_JAZZ_MCT_ADR_H
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 13291fa64db..384bd1bef8e 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -15922,6 +15922,10 @@ jankenmn // (c) 1985 Sunwise
@source:jantotsu.cpp
jantotsu // (c) 1983 Sanritsu
+@source:jazz.cpp
+mmr4000be // MIPS Magnum R4000 (big)
+mmr4000le // MIPS Magnum R4000 (little)
+
@source:jchan.cpp
jchan // (c) 1995 Kaneko
jchan2 // (c) 1995 Kaneko