summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-08-07 22:59:06 +0700
committer R. Belmont <rb6502@users.noreply.github.com>2018-08-07 11:59:06 -0400
commit99efb472772833e1b15c07d9e5d9d9069a53560d (patch)
treee56cb4bb2abdebb8b1701b7f6b7b2d118765e470
parent4bddb07439281403c7d9566bd1223b43bb584eee (diff)
interpro: devcb3 goodness (nw) (#3737)
* interpro: devcb3 goodness (nw) * interpro: more mcfg and some devcb3 (nw) Please excuse the mess in the edge driver for now - this is a major WIP and not understood at all well at this point. * interpro: various fixes/improvements (nw) clipper: fix bugs in carry flag handling, prefer sign bit for tests cammu: implement tlb, use memory_access_cache, remove device address map interpro: use locals for mouse and bus ioga: use memory_access_cache * interpro: doh (nw)
-rw-r--r--src/devices/bus/interpro/keyboard/keyboard.cpp17
-rw-r--r--src/devices/bus/interpro/keyboard/keyboard.h42
-rw-r--r--src/devices/bus/interpro/mouse/mouse.h21
-rw-r--r--src/devices/bus/interpro/sr/edge.cpp249
-rw-r--r--src/devices/bus/interpro/sr/edge.h97
-rw-r--r--src/devices/bus/interpro/sr/gt.cpp67
-rw-r--r--src/devices/bus/interpro/sr/gt.h36
-rw-r--r--src/devices/bus/interpro/sr/sr.cpp192
-rw-r--r--src/devices/bus/interpro/sr/sr.h317
-rw-r--r--src/devices/cpu/clipper/clipper.cpp269
-rw-r--r--src/devices/machine/28fxxx.h4
-rw-r--r--src/devices/machine/i82586.h6
-rw-r--r--src/mame/drivers/interpro.cpp374
-rw-r--r--src/mame/includes/interpro.h3
-rw-r--r--src/mame/machine/cammu.cpp466
-rw-r--r--src/mame/machine/cammu.h326
-rw-r--r--src/mame/machine/interpro_ioga.cpp32
-rw-r--r--src/mame/machine/interpro_ioga.h2
-rw-r--r--src/mame/machine/interpro_sga.cpp10
-rw-r--r--src/mame/machine/interpro_sga.h7
20 files changed, 1475 insertions, 1062 deletions
diff --git a/src/devices/bus/interpro/keyboard/keyboard.cpp b/src/devices/bus/interpro/keyboard/keyboard.cpp
index 518ae7176f3..10b0a038d9e 100644
--- a/src/devices/bus/interpro/keyboard/keyboard.cpp
+++ b/src/devices/bus/interpro/keyboard/keyboard.cpp
@@ -10,22 +10,13 @@
DEFINE_DEVICE_TYPE(INTERPRO_KEYBOARD_PORT, interpro_keyboard_port_device, "interpro_keyboard_port", "InterPro Keyboard Port")
interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
- : interpro_keyboard_port_device(mconfig, INTERPRO_KEYBOARD_PORT, tag, owner, clock)
-{
-}
-
-interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, type, tag, owner, clock)
+ : device_t(mconfig, INTERPRO_KEYBOARD_PORT, tag, owner, clock)
, device_slot_interface(mconfig, *this)
, m_rxd_handler(*this)
, m_dev(nullptr)
{
}
-interpro_keyboard_port_device::~interpro_keyboard_port_device()
-{
-}
-
void interpro_keyboard_port_device::device_config_complete()
{
m_dev = dynamic_cast<device_interpro_keyboard_port_interface *>(get_card_device());
@@ -34,8 +25,6 @@ void interpro_keyboard_port_device::device_config_complete()
void interpro_keyboard_port_device::device_start()
{
m_rxd_handler.resolve_safe();
-
- save_item(NAME(m_rxd));
}
WRITE_LINE_MEMBER(interpro_keyboard_port_device::write_txd)
@@ -50,10 +39,6 @@ device_interpro_keyboard_port_interface::device_interpro_keyboard_port_interface
{
}
-device_interpro_keyboard_port_interface::~device_interpro_keyboard_port_interface()
-{
-}
-
#include "hle.h"
#include "lle.h"
diff --git a/src/devices/bus/interpro/keyboard/keyboard.h b/src/devices/bus/interpro/keyboard/keyboard.h
index 9d40e5a9e96..83347f17114 100644
--- a/src/devices/bus/interpro/keyboard/keyboard.h
+++ b/src/devices/bus/interpro/keyboard/keyboard.h
@@ -5,13 +5,6 @@
#pragma once
-#define MCFG_INTERPRO_KEYBOARD_PORT_ADD(tag, slot_intf, def_slot) \
- MCFG_DEVICE_ADD(tag, INTERPRO_KEYBOARD_PORT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(slot_intf, def_slot, false)
-
-#define MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(cb) \
- downcast<interpro_keyboard_port_device &>(*device).set_rxd_handler(DEVCB_##cb);
-
class device_interpro_keyboard_port_interface;
class interpro_keyboard_port_device : public device_t, public device_slot_interface
@@ -19,25 +12,31 @@ class interpro_keyboard_port_device : public device_t, public device_slot_interf
friend class device_interpro_keyboard_port_interface;
public:
- interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
- virtual ~interpro_keyboard_port_device();
-
- // static configuration helpers
- template <class Object> devcb_base &set_rxd_handler(Object &&cb) { return m_rxd_handler.set_callback(std::forward<Object>(cb)); }
-
+ template <typename T>
+ interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option)
+ : interpro_keyboard_port_device(mconfig, tag, owner)
+ {
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+ interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0);
+
+ // callback configuration
+ auto rxd_handler_cb() { return m_rxd_handler.bind(); }
+
+ // input lines
DECLARE_WRITE_LINE_MEMBER(write_txd);
protected:
- interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock);
-
virtual void device_start() override;
virtual void device_config_complete() override;
- int m_rxd;
-
+private:
devcb_write_line m_rxd_handler;
-private:
device_interpro_keyboard_port_interface *m_dev;
};
@@ -46,15 +45,14 @@ class device_interpro_keyboard_port_interface : public device_slot_card_interfac
friend class interpro_keyboard_port_device;
public:
- virtual ~device_interpro_keyboard_port_interface() override;
-
+ // input lines
virtual DECLARE_WRITE_LINE_MEMBER(input_txd) { }
-
- DECLARE_WRITE_LINE_MEMBER(output_rxd) { m_port->m_rxd = state; m_port->m_rxd_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER(output_rxd) { m_port->m_rxd_handler(state); }
protected:
device_interpro_keyboard_port_interface(machine_config const &mconfig, device_t &device);
+private:
interpro_keyboard_port_device *m_port;
};
diff --git a/src/devices/bus/interpro/mouse/mouse.h b/src/devices/bus/interpro/mouse/mouse.h
index d13ee669e48..c5969ba4667 100644
--- a/src/devices/bus/interpro/mouse/mouse.h
+++ b/src/devices/bus/interpro/mouse/mouse.h
@@ -5,9 +5,6 @@
#pragma once
-#define MCFG_MOUSE_STATE_CB(_state_cb) \
- downcast<interpro_mouse_port_device &>(*device).set_state_callback(DEVCB_##_state_cb);
-
class device_interpro_mouse_port_interface;
class interpro_mouse_port_device : public device_t, public device_slot_interface
@@ -15,9 +12,20 @@ class interpro_mouse_port_device : public device_t, public device_slot_interface
friend class device_interpro_mouse_port_interface;
public:
- interpro_mouse_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+ template <typename T>
+ interpro_mouse_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option)
+ : interpro_mouse_port_device(mconfig, tag, owner)
+ {
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+ interpro_mouse_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0);
- template <class Object> devcb_base &set_state_callback(Object &&cb) { return m_state_func.set_callback(std::forward<Object>(cb)); }
+ // callback configuration
+ auto state_func() { return m_state_func.bind(); }
protected:
// device-level overrides
@@ -25,9 +33,9 @@ protected:
virtual void device_start() override;
virtual void device_config_complete() override;
+private:
devcb_write32 m_state_func;
-private:
device_interpro_mouse_port_interface *m_device;
};
@@ -41,6 +49,7 @@ public:
protected:
device_interpro_mouse_port_interface(machine_config const &mconfig, device_t &device);
+private:
interpro_mouse_port_device *m_port;
};
diff --git a/src/devices/bus/interpro/sr/edge.cpp b/src/devices/bus/interpro/sr/edge.cpp
index ec9598bb663..bcd1f58754d 100644
--- a/src/devices/bus/interpro/sr/edge.cpp
+++ b/src/devices/bus/interpro/sr/edge.cpp
@@ -80,6 +80,12 @@
* Y3 33.3333MHz crystal
* Y4? 40.0MHz crystal
*
+ * TMS44C256-80SD 256Kx4 Fast Page DRAM (total 6MiB)
+ * U242-U253 12 parts
+ * U256-U267 12 parts
+ * U275-U286 12 parts
+ * U289-U300 12 parts
+ *
* EDGE-2 Plus Frame Buffer (PCB896)
*
* Ref Part Function
@@ -91,8 +97,15 @@
* U360 164.609300MHz crystal Pixel clock
*
* MCM6294P20 16Kx4 Bit Synchronous Static RAM (total 256KiB)
- * U233-240 group 1, 8 parts = 16Kx32
- * U300-323 group 2, 24 parts = 16Kx32x3
+ * U233-240 8 parts
+ * U300-323 24 parts
+ *
+ * M5M442256AL-8 256Kx4 Video DRAM (total 9MiB)
+ * U73-U80 8 parts
+ * U82-U97 16 parts
+ * U99-U114 16 parts
+ * U116-U131 16 parts
+ * U133-U148 16 parts
*
* Processor board idprom feature byte 0 contains various flags:
*
@@ -194,7 +207,8 @@
#include "emu.h"
#include "edge.h"
-#define LOG_GENERAL (1U << 0)
+#define LOG_GENERAL (1U << 0)
+#define LOG_INTERRUPT (1U << 1)
#define VERBOSE (LOG_GENERAL)
@@ -207,10 +221,53 @@ DEFINE_DEVICE_TYPE(MPCBA63, mpcba63_device, "mpcba63", "EDGE-2 Frame Buffer f/1M
DEFINE_DEVICE_TYPE(MSMT094, msmt094_device, "msmt094", "EDGE-2 Plus Processor f/1 2Mp-FB")
DEFINE_DEVICE_TYPE(MPCB896, mpcb896_device, "mpcb896", "EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60)")
-void edge1_device_base::map(address_map &map)
+// TODO: move masks to the header when finalised
+enum control_mask
{
- srx_card_device_base::map(map);
+ NO_HOLD = 0x01, // release DSP hold
+ DSP_1_HOLD_L = 0x02, // hold DSP 1
+ // 0x04 maybe reset?
+ FIFO_LW_ENB = 0x08, // fifo low water interrupt enable
+ HOLD_ENB = 0x10, // DSP hold interrupt enable
+ HOLDA_INT_H = 0x20, // DSP hold interrupt asserted (aka HOLD_INTR)
+ FIFO_LW_INTR = 0x40, // fifo low water interrupt asserted (ififo)
+ FIFO_HW_INTR = 0x80, // fifo high water interrupt asserted (ififo)
+};
+
+enum status_mask
+{
+ DSP_1_HOLDA_H = 0x01, // aka DSP_HOLDA
+ FIFO_EMPTY = 0x02, // aka IFIFO_EMPTY?
+ FIFO_HFULL = 0x04,
+ KREG_OUT_FULL = 0x08,
+ KREG_IN_FULL = 0x10,
+
+ // SRX_INT0_H
+ // SRX_PORT_RDY
+};
+
+enum attention_mask
+{
+ ATN_TRACK = 0x00010000, // cursor change
+ ATN_DISP = 0x00020000, // changing contrast or blanking
+ ATN_MMOUT = 0x00040000, // request for memory-mapped output
+ ATN_KREQ = 0x00080000, // verify following request is from kernel
+};
+
+enum reg0_mask
+{
+/*
+ 0x08,
+ 0x10, // mouse button interrupt?
+ 0x20,
+ 0x40,
+*/
+ SCC_INT = 0x80, // serial controller
+ VBLANK = 0x1000, // vertical blank?
+};
+void edge1_device_base::map(address_map &map)
+{
/*
* ODT reports
* 000 user 1 mouse/interrupt
@@ -248,12 +305,14 @@ void edge1_device_base::map_dynamic(address_map &map)
[this](address_space &space, offs_t offset, u8 mem_mask) { return m_sram->read(offset); },
[this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_sram->write(offset, data); });
+
map(0x01000000, 0x013fffff).lrw8("vram",
[this](address_space &space, offs_t offset, u8 mem_mask) { return m_vram->read((offset >> 2) | (offset & 0x3)); },
[this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_vram->write((offset >> 2) | (offset & 0x3), data); });
//map(0x02028200, 0x0202827f).lr32("idprom",
// [this](address_space &space, offs_t offset, u8 mem_mask) { return memregion("idprom")->as_u32(offset); });
+ map(0x02028508, 0x0202850b).rw(FUNC(edge1_device_base::srx_master_control_r), FUNC(edge1_device_base::srx_master_control_w));
map(0x02410000, 0x0241000f).m("ramdac", FUNC(bt458_device::map)).umask32(0x000000ff);
@@ -265,13 +324,13 @@ void edge1_device_base::map_dynamic(address_map &map)
// 0x02410014
// 0x02410018 - ramdac/screen/buffer select?
+ map(0x02410018, 0x0241001b).noprw();
// 0x02410040 - reg0?
+ map(0x02410040, 0x02410043).noprw();
}
void edge2_processor_device_base::map(address_map &map)
{
- srx_card_device_base::map(map);
-
map(0x100, 0x103).nopr(); // control
map(0x104, 0x107).nopr(); // status/attention
map(0x108, 0x10b).nopr(); // fifo
@@ -289,10 +348,11 @@ void edge2_processor_device_base::map(address_map &map)
void edge2plus_processor_device_base::map(address_map &map)
{
- srx_card_device_base::map(map);
-
map(0x000, 0x003).rw(FUNC(edge2plus_processor_device_base::reg0_r), FUNC(edge2plus_processor_device_base::reg0_w));
+ map(0x008, 0x008).lr8("mouse_x", [this](address_space &space, offs_t offset, u8 mem_mask) { return 0; });
+ map(0x00c, 0x00c).lr8("mouse_y", [this](address_space &space, offs_t offset, u8 mem_mask) { return 0; });
+
map(0x010, 0x01f).rw("scc", FUNC(z80scc_device::cd_ab_r), FUNC(z80scc_device::cd_ab_w)).umask32(0x000000ff);
map(0x100, 0x103).rw(FUNC(edge2plus_processor_device_base::control_r), FUNC(edge2plus_processor_device_base::control_w));
@@ -337,12 +397,10 @@ void edge2plus_framebuffer_device_base::map_dynamic(address_map &map)
void edge2_framebuffer_device_base::map(address_map &map)
{
- srx_card_device_base::map(map);
}
void edge2plus_framebuffer_device_base::map(address_map &map)
{
- srx_card_device_base::map(map);
}
ROM_START(mpcb828)
@@ -368,6 +426,24 @@ ROM_END
ROM_START(msmt094)
ROM_REGION(0x80, "idprom", 0)
ROM_LOAD32_BYTE("msmt0940.bin", 0x0, 0x20, CRC(55493b9e) SHA1(6e0668f7e85e1bb5b2ecc6e5a5ab53e5281f22e9))
+
+ // 40 and 70 are sequential and have same date stamp
+ ROM_REGION(0x40000, "prg1", 0)
+ ROMX_LOAD("mprgp040b_apr_02_92.u313", 0, 0x10000, CRC(3b3fce3d) SHA1(077ddf9124d1cbca4be1f1deffa39b10f6a80fb2), ROM_SKIP(3))
+ ROMX_LOAD("mprgp070b_apr_02_92.u310", 2, 0x10000, CRC(29020df3) SHA1(e3c20d361acf5a9d496c3057a9baa108bd840acc), ROM_SKIP(3))
+ ROMX_LOAD("mprgp080b_apr_02_92.u306", 3, 0x10000, CRC(61efb8f7) SHA1(4f70230d01b9e1ee76b187a2d6653601b120578e), ROM_SKIP(3))
+ ROMX_LOAD("mprgp050b_apr_02_92.u239", 1, 0x10000, CRC(866975b2) SHA1(b8caa30bd2824ee28bb82afe9275268822ac8f40), ROM_SKIP(3))
+
+ // 64k treated as 256k?
+ ROM_REGION(0x40000, "mprgp060b", 0)
+ ROM_LOAD32_BYTE("mprgp060b_16_mar_92.u222", 0, 0x10000, CRC(9bac2c00) SHA1(b31b8930d501277dd2a8d3438ac8422de412c8f6))
+
+ ROM_REGION(0x4000, "mprgp010a", 0)
+ ROM_LOAD("mprgp010a_04_01_92.u207", 0, 0x4000, CRC(e461ab92) SHA1(ddf0a9ed635e54f2b32e54b39850204a3532f9f9))
+
+ ROM_REGION(0x4000, "mprgp020a", 0)
+ ROM_LOAD("mprgp020a_31_mar_92.u206", 0, 0x4000, CRC(38c129b4) SHA1(a33cd5c0f3e45fdd7e22df2ff1648f4d73b09b19))
+
ROM_END
ROM_START(mpcb896)
@@ -376,21 +452,21 @@ ROM_START(mpcb896)
ROM_END
/*
-* MPCB828: EDGE-1 graphics, 1 megapixel, single screen, 60Hz refresh.
-*
-* Screen timings to match PCB963.
-*
-* "9 planes (1 for highlights) of double-buffered graphics, 256 colours from 16.7 million"
-* 1024x1024x10x2 == 2621440 bytes == 2560KiB == 2.5MiB
-* FIXME: diag reports 128KiB static ram, 1MiB video ram, 4 screens, 1 user, z-buffer absent
-*
-*/
+ * MPCB828: EDGE-1 graphics, 1 megapixel, single screen, 60Hz refresh.
+ *
+ * Screen timings to match PCB963.
+ *
+ * "9 planes (1 for highlights) of double-buffered graphics, 256 colours from 16.7 million"
+ * 1024x1024x10x2 == 2621440 bytes == 2560KiB == 2.5MiB
+ * FIXME: diag reports 128KiB static ram, 1MiB video ram, 4 screens, 1 user, z-buffer absent
+ *
+ */
MACHINE_CONFIG_START(mpcb828_device::device_add_mconfig)
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + 20, 1184 + 296 + 20, 920, 34, 884 + 34)
//MCFG_SCREEN_RAW_PARAMS(83'020'800, 1184, 0, 1184, 884, 0, 884)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb828_device, screen_update)
- MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank))
+ MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, mpcb828_device, vblank))
MCFG_DEVICE_ADD("sram", RAM, 0)
MCFG_RAM_DEFAULT_SIZE("128KiB")
@@ -402,6 +478,7 @@ MACHINE_CONFIG_START(mpcb828_device::device_add_mconfig)
MCFG_DEVICE_ADD("dsp", TMS32030, 1) // 30_MHz_XTAL
MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, mpcb828_device, holda))
+ //MCFG_DEVICE_ADDRESS_MAP(0, map_dynamic<2>)
MCFG_DEVICE_ADD("ramdac", BT458, 83'020'800)
@@ -409,8 +486,7 @@ MACHINE_CONFIG_START(mpcb828_device::device_add_mconfig)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, mpcb828_device, scc_irq))
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd))
- MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us")
- MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w))
+ INTERPRO_KEYBOARD_PORT(config, "kbd", interpro_keyboard_devices, "hle_en_us").rxd_handler_cb().set("scc", FUNC(z80scc_device::rxa_w));
MACHINE_CONFIG_END
/*
@@ -444,8 +520,7 @@ MACHINE_CONFIG_START(mpcb849_device::device_add_mconfig)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, mpcb849_device, scc_irq))
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd))
- MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us")
- MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w))
+ INTERPRO_KEYBOARD_PORT(config, "kbd", interpro_keyboard_devices, "hle_en_us").rxd_handler_cb().set("scc", FUNC(z80scc_device::rxa_w));
MACHINE_CONFIG_END
/*
@@ -482,6 +557,12 @@ MACHINE_CONFIG_START(msmt094_device::device_add_mconfig)
// FIXME: actually 33.333_MHz_XTAL
MCFG_DEVICE_ADD("dsp1", TMS32030, 1)
MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, msmt094_device, holda))
+ MCFG_DEVICE_ADDRESS_MAP(0, dsp1_map)
+
+ MCFG_DEVICE_ADD("ram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("6MiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
//MCFG_DEVICE_ADD("dsp2", TMS32030, 40_MHz_XTAL)
//MCFG_DEVICE_ADD("dsp3", TMS32030, 40_MHz_XTAL)
@@ -490,8 +571,7 @@ MACHINE_CONFIG_START(msmt094_device::device_add_mconfig)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, msmt094_device, scc_irq))
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd))
- MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us")
- MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w))
+ INTERPRO_KEYBOARD_PORT(config, "kbd", interpro_keyboard_devices, "hle_en_us").rxd_handler_cb().set("scc", FUNC(z80scc_device::rxa_w));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(mpcb896_device::device_add_mconfig)
@@ -515,7 +595,7 @@ MACHINE_CONFIG_END
edge1_device_base::edge1_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
, m_screen(*this, "screen")
, m_sram(*this, "sram")
, m_vram(*this, "vram")
@@ -527,13 +607,13 @@ edge1_device_base::edge1_device_base(const machine_config &mconfig, device_type
edge2_processor_device_base::edge2_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
{
}
edge2plus_processor_device_base::edge2plus_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
, m_dsp1(*this, "dsp1")
, m_screen(nullptr)
{
@@ -541,13 +621,13 @@ edge2plus_processor_device_base::edge2plus_processor_device_base(const machine_c
edge2_framebuffer_device_base::edge2_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
{
}
edge2plus_framebuffer_device_base::edge2plus_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
, m_screen(*this, "screen")
, m_sram(*this, "sram")
, m_vram(*this, "vram")
@@ -617,42 +697,26 @@ const tiny_rom_entry *mpcb896_device::device_rom_region() const
void edge1_device_base::device_start()
{
- set_bus_device();
-
// FIXME: dynamically allocate SR region 4
m_bus->install_map(*this, 0x90000000, 0x93ffffff, &edge1_device_base::map_dynamic);
}
-void edge2_processor_device_base::device_start()
-{
- set_bus_device();
-}
-
-void edge2plus_processor_device_base::device_start()
-{
- set_bus_device();
-}
-
-void edge2_framebuffer_device_base::device_start()
-{
- set_bus_device();
-}
void edge2plus_framebuffer_device_base::device_start()
{
- set_bus_device();
-
// find the processor board and notify it of our screen
edge2plus_processor_device_base *processor = m_bus->get_card<edge2plus_processor_device_base>();
if (processor != nullptr)
{
LOG("found processor device %s\n", processor->tag());
- processor->register_screen(m_screen);
+ processor->register_screen(m_screen, m_sram);
}
// FIXME: dynamically allocate SR region 4
m_bus->install_map(*this, 0x90000000, 0x93ffffff, &edge2plus_framebuffer_device_base::map_dynamic);
+
+ processor->m_dsp1->set_addrmap(0, address_map_constructor(&edge2plus_framebuffer_device_base::map_dynamic, processor->m_dsp1->tag(), this));
}
u32 mpcb849_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -665,6 +729,18 @@ u32 mpcba63_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, c
return 0;
}
+WRITE_LINE_MEMBER(edge1_device_base::vblank)
+{
+ if (state)
+ {
+ // TODO: set vblank status
+ m_bus->vblank_w(ASSERT_LINE);
+ m_bus->vblank_w(CLEAR_LINE);
+ }
+ else
+ ; // TODO: clear vblank status
+}
+
u32 edge1_device_base::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
u8 *pixel_data = m_vram->pointer();
@@ -698,6 +774,10 @@ u32 edge2plus_framebuffer_device_base::screen_update(screen_device &screen, bitm
WRITE32_MEMBER(edge1_device_base::control_w)
{
+ // clear interrupt
+ if (m_control & HOLDA_INT_H && !(data & HOLDA_INT_H))
+ irq0(CLEAR_LINE);
+
COMBINE_DATA(&m_control);
// release dsp 1 hold
@@ -711,7 +791,7 @@ WRITE32_MEMBER(edge1_device_base::control_w)
WRITE_LINE_MEMBER(edge1_device_base::holda)
{
- LOG("hold acknowledge %d\n", state);
+ LOGMASKED(LOG_INTERRUPT, "hold acknowledge %d\n", state);
if (state)
{
@@ -743,7 +823,7 @@ WRITE32_MEMBER(edge2plus_processor_device_base::control_w)
WRITE_LINE_MEMBER(edge2plus_processor_device_base::holda)
{
- LOG("hold acknowledge %d\n", state);
+ LOGMASKED(LOG_INTERRUPT, "hold acknowledge %d\n", state);
if (state)
{
@@ -759,16 +839,73 @@ WRITE_LINE_MEMBER(edge2plus_processor_device_base::holda)
m_status &= ~DSP_1_HOLDA_H;
}
+void edge2plus_processor_device_base::dsp1_map(address_map &map)
+{
+ map(0x00000, 0x3ffff).lrw8("sram",
+ [this](address_space &space, offs_t offset, u8 mem_mask) { return m_sram->read(offset); },
+ [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_sram->write(offset, data); });
+
+ map(0x40000, 0x7ffff).lr32("prg1",
+ [this](address_space &space, offs_t offset, u32 mem_mask) { return memregion("prg1")->as_u32(offset); });
+}
+
+
WRITE32_MEMBER(edge2plus_framebuffer_device_base::lut_select_w)
{
LOG("select ramdac %d\n", data);
- void (bt457_device::*map)(address_map &) = &bt457_device::map;
+ //void (bt457_device::*map)(address_map &) = &bt457_device::map;
// TODO: not sure what should happen for values > 2
// FIXME: this should probably be some kind of bank device, including the idprom
- m_bus->main_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8);
- m_bus->io_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8);
+ //m_bus->main_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8);
+ //m_bus->io_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8);
// lookup table 3 enables address range 92030000-92030fff, written with zeroes
}
+
+WRITE_LINE_MEMBER(edge1_device_base::scc_irq)
+{
+ if (state)
+ m_reg0 |= SCC_INT;
+ else
+ m_reg0 &= ~SCC_INT;
+
+ irq0(state);
+}
+
+READ32_MEMBER(edge1_device_base::reg0_r)
+{
+ return ((m_reg0 & ~VBLANK) | (m_screen->vblank() ? VBLANK : 0));
+}
+
+WRITE32_MEMBER(edge1_device_base::kernel_w)
+{
+ COMBINE_DATA(&m_kernel);
+
+ m_status |= KREG_IN_FULL; // FIXME: what clears this?
+}
+
+WRITE_LINE_MEMBER(edge2plus_processor_device_base::scc_irq)
+{
+ if (state)
+ m_reg0 |= SCC_INT;
+ else
+ m_reg0 &= ~SCC_INT;
+
+ irq0(state);
+}
+
+WRITE32_MEMBER(edge2plus_processor_device_base::kernel_w)
+{
+ COMBINE_DATA(&m_kernel);
+
+ m_status |= KREG_IN_FULL; // FIXME: what clears this?
+}
+
+READ32_MEMBER(edge2plus_processor_device_base::reg0_r)
+{
+ LOG("reg0_r vblank %d\n", m_screen->vblank());
+
+ return (m_screen == nullptr) ? (m_reg0 & ~VBLANK) : ((m_reg0 & ~VBLANK) | (m_screen->vblank() ? VBLANK : 0));
+}
diff --git a/src/devices/bus/interpro/sr/edge.h b/src/devices/bus/interpro/sr/edge.h
index 5f3247b5158..e8a66459271 100644
--- a/src/devices/bus/interpro/sr/edge.h
+++ b/src/devices/bus/interpro/sr/edge.h
@@ -14,52 +14,11 @@
#include "machine/z80scc.h"
#include "bus/interpro/keyboard/keyboard.h"
-enum control_mask
-{
- NO_HOLD = 0x01, // release DSP hold
- DSP_1_HOLD_L = 0x02, // hold DSP 1
- // 0x04 maybe reset?
- FIFO_LW_ENB = 0x08, // fifo low water interrupt enable
- HOLD_ENB = 0x10, // DSP hold interrupt enable
- HOLDA_INT_H = 0x20, // DSP hold interrupt asserted (aka HOLD_INTR)
- FIFO_LW_INTR = 0x40, // fifo low water interrupt asserted (ififo)
- FIFO_HW_INTR = 0x80, // fifo high water interrupt asserted (ififo)
-};
-
-enum status_mask
-{
- DSP_1_HOLDA_H = 0x01, // aka DSP_HOLDA
- FIFO_EMPTY = 0x02, // aka IFIFO_EMPTY?
- FIFO_HFULL = 0x04,
- KREG_OUT_FULL = 0x08,
- KREG_IN_FULL = 0x10,
-
- // SRX_INT0_H
- // SRX_PORT_RDY
-};
-
-enum attention_mask
-{
-};
-
-enum reg0_mask
-{
-/*
- 0x08,
- 0x10, // mouse button interrupt?
- 0x20,
- 0x40,
-*/
- SCC_INT = 0x80, // serial controller
- VBLANK = 0x1000, // vertical blank?
-};
-
-class edge1_device_base : public device_t, public srx_card_device_base
+class edge1_device_base : public device_t, public device_srx_card_interface
{
public:
- const char *tag() const { return device_t::tag(); }
-
DECLARE_WRITE_LINE_MEMBER(holda);
+ DECLARE_WRITE_LINE_MEMBER(vblank);
protected:
edge1_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -70,9 +29,9 @@ protected:
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(scc_irq) { if (state) m_reg0 |= SCC_INT; else m_reg0 &= ~SCC_INT; irq0(state); }
+ DECLARE_WRITE_LINE_MEMBER(scc_irq);
- DECLARE_READ32_MEMBER(reg0_r) { return ((m_reg0 & ~VBLANK) | (m_screen->vblank() ? VBLANK : 0)); }
+ DECLARE_READ32_MEMBER(reg0_r);
DECLARE_WRITE32_MEMBER(reg0_w) { COMBINE_DATA(&m_reg0); }
DECLARE_READ32_MEMBER(control_r) { return m_control; };
@@ -82,7 +41,7 @@ protected:
DECLARE_READ32_MEMBER(fifo_r) { return m_fifo; };
DECLARE_WRITE32_MEMBER(fifo_w) { COMBINE_DATA(&m_fifo); }
DECLARE_READ32_MEMBER(kernel_r) { return m_kernel; };
- DECLARE_WRITE32_MEMBER(kernel_w) { COMBINE_DATA(&m_kernel); m_status |= KREG_IN_FULL; } // FIXME: what clears this?
+ DECLARE_WRITE32_MEMBER(kernel_w);
DECLARE_READ32_MEMBER(attention_r) { return m_attention; };
DECLARE_WRITE32_MEMBER(attention_w) { COMBINE_DATA(&m_attention); }
@@ -90,6 +49,9 @@ protected:
DECLARE_WRITE32_MEMBER(ififo_lwm_w) { COMBINE_DATA(&m_ififo_lwm); }
DECLARE_WRITE32_MEMBER(ififo_hwm_w) { COMBINE_DATA(&m_ififo_hwm); }
+ DECLARE_READ32_MEMBER(srx_master_control_r) { return m_srx_master_control; }
+ DECLARE_WRITE32_MEMBER(srx_master_control_w) { COMBINE_DATA(&m_srx_master_control); }
+
required_device<screen_device> m_screen;
required_device<ram_device> m_sram;
required_device<ram_device> m_vram;
@@ -108,57 +70,54 @@ private:
u32 m_ififo_lwm;
u32 m_ififo_hwm;
+
+ u32 m_srx_master_control;
};
-class edge2_processor_device_base : public device_t, public srx_card_device_base
+class edge2_processor_device_base : public device_t, public device_srx_card_interface
{
-public:
- const char *tag() const { return device_t::tag(); }
-
protected:
edge2_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
- virtual void device_start() override;
+ virtual void device_start() override {};
};
-class edge2_framebuffer_device_base : public device_t, public srx_card_device_base
+class edge2_framebuffer_device_base : public device_t, public device_srx_card_interface
{
-public:
- const char *tag() const { return device_t::tag(); }
-
protected:
edge2_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
- virtual void device_start() override;
+ virtual void device_start() override {};
};
-class edge2plus_processor_device_base : public device_t, public srx_card_device_base
+class edge2plus_processor_device_base : public device_t, public device_srx_card_interface
{
public:
- const char *tag() const { return device_t::tag(); }
-
- void register_screen(screen_device *screen) { m_screen = screen; }
+ void register_screen(screen_device *screen, ram_device *ram) { m_screen = screen; m_sram = ram; }
+ required_device<tms3203x_device> m_dsp1;
protected:
edge2plus_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
- virtual void device_start() override;
+ void dsp1_map(address_map &map);
+
+ virtual void device_start() override {};
DECLARE_WRITE_LINE_MEMBER(holda);
- DECLARE_WRITE_LINE_MEMBER(scc_irq) { if (state) m_reg0 |= SCC_INT; else m_reg0 &= ~SCC_INT; irq0(state); }
+ DECLARE_WRITE_LINE_MEMBER(scc_irq);
DECLARE_READ32_MEMBER(control_r) { return m_control; };
DECLARE_WRITE32_MEMBER(control_w);
DECLARE_READ32_MEMBER(status_r) { return m_status; };
DECLARE_WRITE32_MEMBER(status_w) { COMBINE_DATA(&m_status); }
DECLARE_READ32_MEMBER(kernel_r) { return m_kernel; };
- DECLARE_WRITE32_MEMBER(kernel_w) { COMBINE_DATA(&m_kernel); m_status |= KREG_IN_FULL; } // FIXME: what clears this?
+ DECLARE_WRITE32_MEMBER(kernel_w);
DECLARE_WRITE32_MEMBER(mapping_w) { COMBINE_DATA(&m_mapping); }
DECLARE_READ32_MEMBER(attention_r) { return m_attention; };
DECLARE_WRITE32_MEMBER(attention_w) { COMBINE_DATA(&m_attention); }
@@ -166,11 +125,9 @@ protected:
DECLARE_WRITE32_MEMBER(ififo_lwm_w) { COMBINE_DATA(&m_ififo_lwm); }
DECLARE_WRITE32_MEMBER(ififo_hwm_w) { COMBINE_DATA(&m_ififo_hwm); }
- DECLARE_READ32_MEMBER(reg0_r) { m_reg0 ^= VBLANK; return m_reg0; }
- //DECLARE_READ32_MEMBER(reg0_r) { logerror("reg0_r vblank %d\n", m_screen->vblank()); return (m_screen == nullptr) ? (m_reg0 & ~VBLANK) : ((m_reg0 & ~VBLANK) | (m_screen->vblank() ? VBLANK : 0)); }
+ DECLARE_READ32_MEMBER(reg0_r);
DECLARE_WRITE32_MEMBER(reg0_w) { COMBINE_DATA(&m_reg0); }
- required_device<tms3203x_device> m_dsp1;
private:
u32 m_control;
@@ -185,14 +142,14 @@ private:
u32 m_reg0;
screen_device *m_screen;
+ ram_device *m_sram;
};
-class edge2plus_framebuffer_device_base : public device_t, public srx_card_device_base
+class edge2plus_framebuffer_device_base : public device_t, public device_srx_card_interface
{
-public:
- const char *tag() const { return device_t::tag(); }
-
protected:
+ friend class edge2plus_processor_device_base;
+
edge2plus_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp
index 409ddcd18f8..bcb4b03538c 100644
--- a/src/devices/bus/interpro/sr/gt.cpp
+++ b/src/devices/bus/interpro/sr/gt.cpp
@@ -153,7 +153,8 @@ void gt_device_base::map(address_map &map)
void single_gt_device_base::map(address_map &map)
{
gt_device_base::map(map);
- map(0x00000080, 0x0000008f).m("ramdac0", FUNC(bt459_device::map)).umask32(0x000000ff);
+
+ map(0x00000080, 0x0000008f).m(get_gt(0).ramdac, FUNC(bt459_device::map)).umask32(0x000000ff);
map(0x00000090, 0x0000009f).nopw(); // second (missing) ramdac
map(0x00400000, 0x005fffff).rw(FUNC(single_gt_device_base::buffer_r), FUNC(single_gt_device_base::buffer_w));
@@ -163,8 +164,8 @@ void dual_gt_device_base::map(address_map &map)
{
gt_device_base::map(map);
- map(0x00000080, 0x0000008f).m("ramdac0", FUNC(bt459_device::map)).umask32(0x000000ff);
- map(0x00000090, 0x0000009f).m("ramdac1", FUNC(bt459_device::map)).umask32(0x000000ff);
+ map(0x00000080, 0x0000008f).m(get_gt(0).ramdac, FUNC(bt459_device::map)).umask32(0x000000ff);
+ map(0x00000090, 0x0000009f).m(get_gt(1).ramdac, FUNC(bt459_device::map)).umask32(0x000000ff);
map(0x00400000, 0x007fffff).rw(FUNC(dual_gt_device_base::buffer_r), FUNC(dual_gt_device_base::buffer_w));
}
@@ -217,28 +218,28 @@ ROM_END
* These inputs give htotal=1504 and vtotal=920 with high confidence.
*/
MACHINE_CONFIG_START(mpcb963_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + GT_X_DELTA, 1184 + 296 + GT_X_DELTA, 920, 34, 884 + 34)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb963_device, screen_update0)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_cbus_card_interface, vblank))
- MCFG_DEVICE_ADD("ramdac0", BT459, 83'020'800)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 83'020'800)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
MACHINE_CONFIG_END
// Same as MPCB963, but dual screen.
MACHINE_CONFIG_START(mpcba79_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + GT_X_DELTA, 1184 + 296 + GT_X_DELTA, 920, 34, 884 + 34)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcba79_device, screen_update0)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_cbus_card_interface, vblank))
- MCFG_DEVICE_ADD("ramdac0", BT459, 83'020'800)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 83'020'800)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
- MCFG_SCREEN_ADD("screen1", RASTER)
+ MCFG_SCREEN_ADD(get_gt(1).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + GT_X_DELTA, 1184 + 296 + GT_X_DELTA, 920, 34, 884 + 34)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcba79_device, screen_update1)
- MCFG_DEVICE_ADD("ramdac1", BT459, 83'020'800)
- MCFG_DEVICE_ADD("bpu1", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(1).ramdac, BT459, 83'020'800)
+ MCFG_DEVICE_ADD(get_gt(1).bpu, DP8510, 0)
MACHINE_CONFIG_END
/*
@@ -252,28 +253,28 @@ MACHINE_CONFIG_END
* giving hsync=71.744kHz and vsync~=75.97Hz.
*/
MACHINE_CONFIG_START(msmt070_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(105'561'000, 1472, 264 + GT_X_DELTA, 1184 + 264 + GT_X_DELTA, 944, 57, 884 + 57)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, msmt070_device, screen_update0)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_cbus_card_interface, vblank))
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 0)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
MACHINE_CONFIG_END
// Same as MSMT070, but dual screen.
MACHINE_CONFIG_START(msmt071_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(105'561'000, 1472, 264 + GT_X_DELTA, 1184 + 264 + GT_X_DELTA, 944, 57, 884 + 57)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, msmt071_device, screen_update0)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_cbus_card_interface, vblank))
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 0)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
- MCFG_SCREEN_ADD("screen1", RASTER)
+ MCFG_SCREEN_ADD(get_gt(1).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(105'561'000, 1472, 264 + GT_X_DELTA, 1184 + 264 + GT_X_DELTA, 944, 57, 884 + 57)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, msmt071_device, screen_update1)
- MCFG_DEVICE_ADD("ramdac1", BT459, 0)
- MCFG_DEVICE_ADD("bpu1", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(1).ramdac, BT459, 0)
+ MCFG_DEVICE_ADD(get_gt(1).bpu, DP8510, 0)
MACHINE_CONFIG_END
/*
@@ -288,12 +289,12 @@ MACHINE_CONFIG_END
* giving pixel clock 209.2608MHz and vsync 76.13Hz.
*/
MACHINE_CONFIG_START(msmt081_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(209'260'800, 2076, 391 + GT_X_DELTA, 1664 + 391 + GT_X_DELTA, 1324, 74, 1248 + 74)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, msmt081_device, screen_update0)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_cbus_card_interface, vblank))
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 0)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
MACHINE_CONFIG_END
/*
@@ -306,12 +307,12 @@ MACHINE_CONFIG_END
* giving pixel clock 209.2608MHz and vsync 76.13Hz.
*/
MACHINE_CONFIG_START(mpcbb92_device::device_add_mconfig)
- MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_ADD(get_gt(0).screen, RASTER)
MCFG_SCREEN_RAW_PARAMS(209'260'800, 2076, 391 + GT_X_DELTA, 1664 + 391 + GT_X_DELTA, 1324, 74, 1248 + 74)
MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcbb92_device, screen_update0)
//MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, srx_card_device_base, irq0))
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
- MCFG_DEVICE_ADD("bpu0", DP8510, 0)
+ MCFG_DEVICE_ADD(get_gt(0).ramdac, BT459, 0)
+ MCFG_DEVICE_ADD(get_gt(0).bpu, DP8510, 0)
MACHINE_CONFIG_END
gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
@@ -333,37 +334,37 @@ dual_gt_device_base::dual_gt_device_base(const machine_config &mconfig, device_t
mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: single_gt_device_base(mconfig, MPCB963, tag, owner, clock)
- , cbus_card_device_base(mconfig, *this)
+ , device_cbus_card_interface(mconfig, *this)
{
}
mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: dual_gt_device_base(mconfig, MPCBA79, tag, owner, clock)
- , cbus_card_device_base(mconfig, *this)
+ , device_cbus_card_interface(mconfig, *this)
{
}
msmt070_device::msmt070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: single_gt_device_base(mconfig, MSMT070, tag, owner, clock)
- , cbus_card_device_base(mconfig, *this)
+ , device_cbus_card_interface(mconfig, *this)
{
}
msmt071_device::msmt071_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: dual_gt_device_base(mconfig, MSMT071, tag, owner, clock)
- , cbus_card_device_base(mconfig, *this)
+ , device_cbus_card_interface(mconfig, *this)
{
}
msmt081_device::msmt081_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: single_gt_device_base(mconfig, MSMT081, tag, owner, clock)
- , cbus_card_device_base(mconfig, *this)
+ , device_cbus_card_interface(mconfig, *this)
{
}
mpcbb92_device::mpcbb92_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: single_gt_device_base(mconfig, MPCBB92, tag, owner, clock)
- , srx_card_device_base(mconfig, *this)
+ , device_srx_card_interface(mconfig, *this)
{
}
diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h
index ecb5da0a3a2..f2e277dafad 100644
--- a/src/devices/bus/interpro/sr/gt.h
+++ b/src/devices/bus/interpro/sr/gt.h
@@ -296,81 +296,69 @@ private:
gt_t m_gt[GT_SCREEN_COUNT];
};
-class mpcb963_device : public single_gt_device_base, public cbus_card_device_base
+class mpcb963_device : public single_gt_device_base, public device_cbus_card_interface
{
public:
mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { cbus_card_device_base::map(map); single_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { single_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class mpcba79_device : public dual_gt_device_base, public cbus_card_device_base
+class mpcba79_device : public dual_gt_device_base, public device_cbus_card_interface
{
public:
mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { cbus_card_device_base::map(map); dual_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { dual_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class msmt070_device : public single_gt_device_base, public cbus_card_device_base
+class msmt070_device : public single_gt_device_base, public device_cbus_card_interface
{
public:
msmt070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { cbus_card_device_base::map(map); single_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { single_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class msmt071_device : public dual_gt_device_base, public cbus_card_device_base
+class msmt071_device : public dual_gt_device_base, public device_cbus_card_interface
{
public:
msmt071_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { cbus_card_device_base::map(map); dual_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { dual_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class msmt081_device : public single_gt_device_base, public cbus_card_device_base
+class msmt081_device : public single_gt_device_base, public device_cbus_card_interface
{
public:
msmt081_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { cbus_card_device_base::map(map); single_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { single_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class mpcbb92_device : public single_gt_device_base, public srx_card_device_base
+class mpcbb92_device : public single_gt_device_base, public device_srx_card_interface
{
public:
mpcbb92_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_start() override { gt_device_base::device_start(); set_bus_device(); }
-
- virtual void map(address_map &map) override { srx_card_device_base::map(map); single_gt_device_base::map(map); }
+ virtual void map(address_map &map) override { single_gt_device_base::map(map); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp
index e8efa39cbef..5a516abd1d4 100644
--- a/src/devices/bus/interpro/sr/sr.cpp
+++ b/src/devices/bus/interpro/sr/sr.cpp
@@ -259,204 +259,98 @@
#define VERBOSE 0
#include "logmacro.h"
-DEFINE_DEVICE_TYPE(CBUS, cbus_device, "cbus", "InterPro CBUS")
+DEFINE_DEVICE_TYPE(CBUS_BUS, cbus_bus_device, "cbus_bus", "InterPro CBUS bus")
DEFINE_DEVICE_TYPE(CBUS_SLOT, cbus_slot_device, "cbus_slot", "InterPro CBUS slot")
-DEFINE_DEVICE_TYPE(SRX, srx_device, "srx", "InterPro SRX")
+DEFINE_DEVICE_TYPE(SRX_BUS, srx_bus_device, "srx_bus", "InterPro SRX bus")
DEFINE_DEVICE_TYPE(SRX_SLOT, srx_slot_device, "srx_slot", "InterPro SRX slot")
-cbus_slot_device::cbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, CBUS_SLOT, tag, owner, clock)
- , device_slot_interface(mconfig, *this)
- , m_bus_tag(nullptr)
- , m_slot_tag(nullptr)
-{
-}
-
-void cbus_slot_device::set_tags(const char *bus_tag, const char *slot_tag)
-{
- m_bus_tag = bus_tag;
- m_slot_tag = slot_tag;
-}
-
-void cbus_slot_device::device_start()
-{
- device_cbus_card_interface *dev = dynamic_cast<device_cbus_card_interface *>(get_card_device());
-
- if (dev)
- dev->set_tags(m_bus_tag, m_slot_tag);
-}
-
-cbus_device::cbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, CBUS, tag, owner, clock)
- , m_out_irq0_cb(*this)
- , m_out_irq1_cb(*this)
- , m_out_irq2_cb(*this)
- , m_out_vblank_cb(*this)
- , m_memory_tag(nullptr)
-{
-}
-
-void cbus_device::set_memory(const char *const tag, const int main_spacenum, const int io_spacenum)
-{
- m_memory_tag = tag;
- m_main_spacenum = main_spacenum;
- m_io_spacenum = io_spacenum;
-}
-
-void cbus_device::device_start()
+void interpro_bus_device::device_resolve_objects()
{
- assert_always(m_memory_tag != nullptr, "memory tag and address spaces must be configured");
-
- // get the memory spaces
- device_memory_interface *memory;
- siblingdevice(m_memory_tag)->interface(memory);
- m_main_space = &memory->space(m_main_spacenum);
- m_io_space = &memory->space(m_io_spacenum);
+ m_main_space = &m_maincpu->space(0);
+ m_io_space = &m_maincpu->space(1);
// resolve callbacks
m_out_irq0_cb.resolve_safe();
m_out_irq1_cb.resolve_safe();
m_out_irq2_cb.resolve_safe();
m_out_vblank_cb.resolve_safe();
-
- // FIXME: silence the slot address map
- m_main_space->nop_read(CBUS_BASE, CBUS_BASE + (CBUS_STRIDE * (CBUS_COUNT - 1)) + (CBUS_SIZE - 1));
- m_io_space->nop_read(CBUS_BASE, CBUS_BASE + (CBUS_STRIDE * (CBUS_COUNT - 1)) + (CBUS_SIZE - 1));
-
- // empty the slots
- m_slot_count = 0;
- for (device_cbus_card_interface *&slot : m_slot)
- slot = nullptr;
}
-void cbus_device::device_reset()
+cbus_bus_device::cbus_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : interpro_bus_device(mconfig, CBUS_BUS, tag, owner, clock)
+ , m_slot_count(0)
{
+ std::fill(std::begin(m_slot), std::end(m_slot), nullptr);
}
-device_cbus_card_interface::device_cbus_card_interface(const machine_config &mconfig, device_t &device)
- : device_slot_card_interface(mconfig, device)
- , m_bus(nullptr)
- , m_bus_tag(nullptr)
- , m_slot_tag(nullptr)
+void cbus_bus_device::device_start()
{
}
-void device_cbus_card_interface::set_bus_device()
-{
- // get a reference to the bus
- m_bus = dynamic_cast<cbus_device *>(device().machine().device(m_bus_tag));
-
- // install the card in the next available slot
- m_bus->install_card(*this, &device_cbus_card_interface::map);
-}
-
-cbus_card_device_base::cbus_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region)
- : device_cbus_card_interface(mconfig, device)
- , m_idprom_region(idprom_region)
+cbus_slot_device::cbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, CBUS_SLOT, tag, owner, clock)
+ , device_slot_interface(mconfig, *this)
+ , m_bus(*this, finder_base::DUMMY_TAG)
{
}
-void cbus_card_device_base::map(address_map &map)
+void cbus_slot_device::device_resolve_objects()
{
- // TODO: use lambda until device submaps support unit masks
- map(0x00, 0x7f).lr32(m_idprom_region,
- [this](address_space &space, offs_t offset, u32 mem_mask) { return device().memregion(m_idprom_region)->as_u32(offset); });
-}
+ device_cbus_card_interface *const card(dynamic_cast<device_cbus_card_interface *>(get_card_device()));
-srx_slot_device::srx_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, SRX_SLOT, tag, owner, clock)
- , device_slot_interface(mconfig, *this)
- , m_bus_tag(nullptr)
- , m_slot_tag(nullptr)
-{
+ if (card)
+ card->set_bus_device(*m_bus);
}
-void srx_slot_device::set_tags(const char *bus_tag, const char *slot_tag)
+void cbus_slot_device::device_start()
{
- m_bus_tag = bus_tag;
- m_slot_tag = slot_tag;
}
-void srx_slot_device::device_start()
+void device_cbus_card_interface::set_bus_device(cbus_bus_device &bus_device)
{
- device_srx_card_interface *dev = dynamic_cast<device_srx_card_interface *>(get_card_device());
+ // keep a reference to the bus
+ m_bus = &bus_device;
- if (dev)
- dev->set_tags(m_bus_tag, m_slot_tag);
+ // install the card in the next available slot
+ m_bus->install_card(*this, device().memregion(m_idprom_region), &device_cbus_card_interface::map);
}
-srx_device::srx_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, SRX, tag, owner, clock)
- , m_out_irq0_cb(*this)
- , m_out_irq1_cb(*this)
- , m_out_irq2_cb(*this)
- , m_out_vblank_cb(*this)
- , m_memory_tag(nullptr)
+srx_bus_device::srx_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : interpro_bus_device(mconfig, SRX_BUS, tag, owner, clock)
+ , m_slot_count(1) // first slot is used by the system board
{
+ std::fill(std::begin(m_slot), std::end(m_slot), nullptr);
}
-void srx_device::set_memory(const char *const tag, const int main_spacenum, const int io_spacenum)
+void srx_bus_device::device_start()
{
- m_memory_tag = tag;
- m_main_spacenum = main_spacenum;
- m_io_spacenum = io_spacenum;
}
-void srx_device::device_start()
+srx_slot_device::srx_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, SRX_SLOT, tag, owner, clock)
+ , device_slot_interface(mconfig, *this)
+ , m_bus(*this, finder_base::DUMMY_TAG)
{
- assert_always(m_memory_tag != nullptr, "memory tag and address spaces must be configured");
-
- // get the memory spaces
- device_memory_interface *memory;
- siblingdevice(m_memory_tag)->interface(memory);
- m_main_space = &memory->space(m_main_spacenum);
- m_io_space = &memory->space(m_io_spacenum);
-
- // resolve callbacks
- m_out_irq0_cb.resolve_safe();
- m_out_irq1_cb.resolve_safe();
- m_out_irq2_cb.resolve_safe();
- m_out_vblank_cb.resolve_safe();
-
- // empty the slots
- for (device_srx_card_interface *&slot : m_slot)
- slot = nullptr;
-
- // first slot is used by the system board
- m_slot_count = 1;
}
-void srx_device::device_reset()
+void srx_slot_device::device_resolve_objects()
{
-}
+ device_srx_card_interface *const card(dynamic_cast<device_srx_card_interface *>(get_card_device()));
-device_srx_card_interface::device_srx_card_interface(const machine_config &mconfig, device_t &device)
- : device_slot_card_interface(mconfig, device)
- , m_bus(nullptr)
- , m_bus_tag(nullptr)
- , m_slot_tag(nullptr)
-{
+ if (card)
+ card->set_bus_device(*m_bus);
}
-void device_srx_card_interface::set_bus_device()
+void srx_slot_device::device_start()
{
- // get a reference to the bus
- m_bus = dynamic_cast<srx_device *>(device().machine().device(m_bus_tag));
-
- // install the card in the next available slot
- m_bus->install_card(*this, &device_srx_card_interface::map);
}
-srx_card_device_base::srx_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region)
- : device_srx_card_interface(mconfig, device)
- , m_idprom_region(idprom_region)
+void device_srx_card_interface::set_bus_device(srx_bus_device &bus_device)
{
-}
+ // keep a reference to the bus
+ m_bus = &bus_device;
-void srx_card_device_base::map(address_map &map)
-{
- // TODO: use lambda until device submaps support unit masks
- map(0x7f80, 0x7fff).lr32(m_idprom_region,
- [this](address_space &space, offs_t offset, u32 mem_mask) { return device().memregion(m_idprom_region)->as_u32(offset); });
+ // install the card in the next available slot
+ m_bus->install_card(*this, device().memregion(m_idprom_region), &device_srx_card_interface::map);
}
diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h
index 9d23fad04e5..d36f79f0f76 100644
--- a/src/devices/bus/interpro/sr/sr.h
+++ b/src/devices/bus/interpro/sr/sr.h
@@ -6,96 +6,70 @@
#pragma once
-#define MCFG_CBUS_OUT_IRQ0_CB(_devcb) \
- downcast<cbus_device &>(*device).set_out_irq0_callback(DEVCB_##_devcb);
-
-#define MCFG_CBUS_OUT_IRQ1_CB(_devcb) \
- downcast<cbus_device &>(*device).set_out_irq1_callback(DEVCB_##_devcb);
-
-#define MCFG_CBUS_OUT_IRQ2_CB(_devcb) \
- downcast<cbus_device &>(*device).set_out_irq2_callback(DEVCB_##_devcb);
-
-#define MCFG_CBUS_OUT_VBLANK_CB(_devcb) \
- downcast<cbus_device &>(*device).set_out_vblank_callback(DEVCB_##_devcb);
-
-#define MCFG_CBUS_SLOT_ADD(_bus_tag, _slot_tag, _slot_intf, _def_slot, _fixed) \
- MCFG_DEVICE_ADD(_slot_tag, CBUS_SLOT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \
- downcast<cbus_slot_device &>(*device).set_tags(_bus_tag, _slot_tag);
-
-#define MCFG_CBUS_MEMORY(_tag, _main_spacenum, _io_spacenum) \
- downcast<cbus_device &>(*device).set_memory(_tag, _main_spacenum, _io_spacenum);
-
-
-#define MCFG_SRX_OUT_IRQ0_CB(_devcb) \
- downcast<srx_device &>(*device).set_out_irq0_callback(DEVCB_##_devcb);
-
-#define MCFG_SRX_OUT_IRQ1_CB(_devcb) \
- downcast<srx_device &>(*device).set_out_irq1_callback(DEVCB_##_devcb);
-
-#define MCFG_SRX_OUT_IRQ2_CB(_devcb) \
- downcast<srx_device &>(*device).set_out_irq2_callback(DEVCB_##_devcb);
-
-#define MCFG_SRX_OUT_VBLANK_CB(_devcb) \
- downcast<srx_device &>(*device).set_out_vblank_callback(DEVCB_##_devcb);
-
-#define MCFG_SRX_SLOT_ADD(_bus_tag, _slot_tag, _slot_intf, _def_slot, _fixed) \
- MCFG_DEVICE_ADD(_slot_tag, SRX_SLOT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \
- downcast<srx_slot_device &>(*device).set_tags(_bus_tag, _slot_tag);
-
-#define MCFG_SRX_MEMORY(_tag, _main_spacenum, _io_spacenum) \
- downcast<srx_device &>(*device).set_memory(_tag, _main_spacenum, _io_spacenum);
-
-
-class cbus_slot_device : public device_t, public device_slot_interface
+class interpro_bus_device : public device_t
{
public:
- // construction/destruction
- cbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ // callback configuration
+ auto out_irq0_cb() { return m_out_irq0_cb.bind(); }
+ auto out_irq1_cb() { return m_out_irq1_cb.bind(); }
+ auto out_irq2_cb() { return m_out_irq2_cb.bind(); }
+ auto out_vblank_cb() { return m_out_vblank_cb.bind(); }
- // inline configuration
- void set_tags(const char *bus_tag, const char *slot_tag);
+ DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); }
+ DECLARE_WRITE_LINE_MEMBER(vblank_w) { m_out_vblank_cb(state); }
protected:
- cbus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ // construction/destruction
+ interpro_bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_main_space(nullptr)
+ , m_io_space(nullptr)
+ , m_out_irq0_cb(*this)
+ , m_out_irq1_cb(*this)
+ , m_out_irq2_cb(*this)
+ , m_out_vblank_cb(*this)
+ {
+ }
// device-level overrides
- virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+
+ // internal state
+ required_device<cpu_device> m_maincpu;
+ address_space *m_main_space;
+ address_space *m_io_space;
- // configuration
- const char *m_bus_tag;
- const char *m_slot_tag;
+private:
+ devcb_write_line m_out_irq0_cb;
+ devcb_write_line m_out_irq1_cb;
+ devcb_write_line m_out_irq2_cb;
+ devcb_write_line m_out_vblank_cb;
};
class device_cbus_card_interface;
-class cbus_device : public device_t
+class cbus_bus_device : public interpro_bus_device
{
public:
// construction/destruction
- cbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-
- // inline configuration
- template <class Object> devcb_base &set_out_irq0_callback(Object &&cb) { return m_out_irq0_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_irq1_callback(Object &&cb) { return m_out_irq1_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_irq2_callback(Object &&cb) { return m_out_irq2_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_vblank_callback(Object &&cb) { return m_out_vblank_cb.set_callback(std::forward<Object>(cb)); }
-
- void set_memory(const char *const tag, const int main_spacenum, const int io_spacenum);
+ template <typename T>
+ cbus_bus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&cpu_device)
+ : cbus_bus_device(mconfig, tag, owner, clock)
+ {
+ m_maincpu.set_tag(std::forward<T>(cpu_device));
+ }
+ cbus_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
static const u32 CBUS_BASE = 0x87000000;
static const u32 CBUS_SIZE = 0x01000000;
static const u32 CBUS_STRIDE = 0x08000000;
static const int CBUS_COUNT = 16;
- DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(vblank_w) { m_out_vblank_cb(state); }
-
// installation function for card devices
- template <typename T> void install_card(T &device, void (T::*map)(address_map &map))
+ template <typename T> void install_card(T &device, memory_region *idprom, void (T::*map)(address_map &map))
{
// record the device in the next free slot
m_slot[m_slot_count] = &device;
@@ -104,6 +78,11 @@ public:
offs_t start = CBUS_BASE + m_slot_count * CBUS_STRIDE;
offs_t end = start + (CBUS_SIZE - 1);
+ // install the idprom region
+ read32_delegate idprom_r([idprom](address_space &space, offs_t offset, u32 mem_mask) { return idprom->as_u32(offset); }, idprom->name());
+ m_main_space->install_read_handler(start, start | 0x7f, idprom_r);
+ m_io_space->install_read_handler(start, start | 0x7f, idprom_r);
+
// install the device address map
m_main_space->install_device(start, end, device, map);
m_io_space->install_device(start, end, device, map);
@@ -112,115 +91,87 @@ public:
}
protected:
- cbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
-
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
-
- // internal state
- address_space *m_main_space;
- address_space *m_io_space;
-
- devcb_write_line m_out_irq0_cb;
- devcb_write_line m_out_irq1_cb;
- devcb_write_line m_out_irq2_cb;
- devcb_write_line m_out_vblank_cb;
private:
device_cbus_card_interface *m_slot[CBUS_COUNT];
int m_slot_count;
-
- const char *m_memory_tag;
- int m_main_spacenum;
- int m_io_spacenum;
};
-class device_cbus_card_interface : public device_slot_card_interface
+class cbus_slot_device : public device_t, public device_slot_interface
{
public:
- void set_bus_device();
-
- // inline configuration
- void set_tags(const char *bus_tag, const char *slot_tag) { m_bus_tag = bus_tag; m_slot_tag = slot_tag; }
-
- DECLARE_WRITE_LINE_MEMBER(irq0) { m_bus->irq0_w(state); }
- DECLARE_WRITE_LINE_MEMBER(irq1) { m_bus->irq1_w(state); }
- DECLARE_WRITE_LINE_MEMBER(irq2) { m_bus->irq2_w(state); }
- DECLARE_WRITE_LINE_MEMBER(vblank) { m_bus->vblank_w(state); }
+ // construction/destruction
+ template <typename T, typename U>
+ cbus_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&bus_tag, U &&slot_options, const char *default_option, const bool fixed)
+ : cbus_slot_device(mconfig, tag, owner, clock)
+ {
+ m_bus.set_tag(std::forward<T>(bus_tag));
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(fixed);
+ }
+ cbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
- device_cbus_card_interface(const machine_config &mconfig, device_t &device);
-
- virtual void map(address_map &map) = 0;
+ // device-level overrides
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
- cbus_device *m_bus;
- const char *m_bus_tag;
- const char *m_slot_tag;
+private:
+ required_device<cbus_bus_device> m_bus;
};
-class cbus_card_device_base : public device_cbus_card_interface
+class device_cbus_card_interface : public device_slot_card_interface
{
protected:
- cbus_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom");
+ friend class cbus_slot_device;
public:
- const char *tag() { return device().tag(); }
+ DECLARE_WRITE_LINE_MEMBER(irq0) { m_bus->irq0_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq1) { m_bus->irq1_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq2) { m_bus->irq2_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(vblank) { m_bus->vblank_w(state); }
protected:
- virtual void map(address_map &map) override;
-
-private:
- const char *const m_idprom_region;
-};
-
-class srx_slot_device : public device_t, public device_slot_interface
-{
-public:
- // construction/destruction
- srx_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-
- // inline configuration
- void set_tags(const char *bus_tag, const char *slot_tag);
+ device_cbus_card_interface(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom")
+ : device_slot_card_interface(mconfig, device)
+ , m_bus(nullptr)
+ , m_idprom_region(idprom_region)
+ {
+ }
-protected:
- srx_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ virtual void map(address_map &map) = 0;
- // device-level overrides
- virtual void device_start() override;
+private:
+ void set_bus_device(cbus_bus_device &bus_device);
- // configuration
- const char *m_bus_tag;
- const char *m_slot_tag;
+ cbus_bus_device *m_bus;
+ const char *const m_idprom_region;
};
class device_srx_card_interface;
-class srx_device : public device_t
+class srx_bus_device : public interpro_bus_device
{
public:
// construction/destruction
- srx_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-
- // inline configuration
- template <class Object> devcb_base &set_out_irq0_callback(Object &&cb) { return m_out_irq0_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_irq1_callback(Object &&cb) { return m_out_irq1_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_irq2_callback(Object &&cb) { return m_out_irq2_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_vblank_callback(Object &&cb) { return m_out_vblank_cb.set_callback(std::forward<Object>(cb)); }
-
- void set_memory(const char *const tag, const int main_spacenum, const int io_spacenum);
+ template <typename T>
+ srx_bus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&cpu_device)
+ : srx_bus_device(mconfig, tag, owner, clock)
+ {
+ m_maincpu.set_tag(std::forward<T>(cpu_device));
+ }
+ srx_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
static const u32 SRX_BASE = 0x8f000000;
static const u32 SRX_SIZE = 0x8000;
static const int SRX_COUNT = 32;
- DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); }
- DECLARE_WRITE_LINE_MEMBER(vblank_w) { m_out_vblank_cb(state); }
-
// installation function for card devices
- template <typename T> void install_card(T &device, void (T::*map)(address_map &map))
+ template <typename T> void install_card(T &device, memory_region *idprom, void (T::*map)(address_map &map))
{
// record the device in the next free slot
m_slot[m_slot_count] = &device;
@@ -229,6 +180,11 @@ public:
offs_t start = SRX_BASE + m_slot_count * SRX_SIZE;
offs_t end = start + (SRX_SIZE - 1);
+ // install the idprom region
+ read32_delegate idprom_r([idprom](address_space &space, offs_t offset, u32 mem_mask) { return idprom->as_u32(offset); }, idprom->name());
+ m_main_space->install_read_handler(start | 0x7f80, start | 0x7fff, idprom_r);
+ m_io_space->install_read_handler(start | 0x7f80, start | 0x7fff, idprom_r);
+
// install the device address map
m_main_space->install_device(start, end, device, map);
m_io_space->install_device(start, end, device, map);
@@ -252,75 +208,72 @@ public:
m_io_space->install_device(start, end, device, map);
}
- address_space *main_space() { return m_main_space; }
- address_space *io_space() { return m_io_space; }
-
protected:
- srx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
-
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
-
- // internal state
- address_space *m_main_space;
- address_space *m_io_space;
-
- devcb_write_line m_out_irq0_cb;
- devcb_write_line m_out_irq1_cb;
- devcb_write_line m_out_irq2_cb;
- devcb_write_line m_out_vblank_cb;
private:
device_srx_card_interface *m_slot[SRX_COUNT];
int m_slot_count;
-
- const char *m_memory_tag;
- int m_main_spacenum;
- int m_io_spacenum;
};
-class device_srx_card_interface : public device_slot_card_interface
+class srx_slot_device : public device_t, public device_slot_interface
{
public:
- void set_bus_device();
-
- // inline configuration
- void set_tags(const char *bus_tag, const char *slot_tag) { m_bus_tag = bus_tag; m_slot_tag = slot_tag; }
-
- DECLARE_WRITE_LINE_MEMBER(irq0) { m_bus->irq0_w(state); }
- DECLARE_WRITE_LINE_MEMBER(irq1) { m_bus->irq1_w(state); }
- DECLARE_WRITE_LINE_MEMBER(irq2) { m_bus->irq2_w(state); }
- DECLARE_WRITE_LINE_MEMBER(vblank) { m_bus->vblank_w(state); }
+ // construction/destruction
+ template <typename T, typename U>
+ srx_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&bus_tag, U &&slot_options, const char *default_option, const bool fixed)
+ : srx_slot_device(mconfig, tag, owner, clock)
+ {
+ m_bus.set_tag(std::forward<T>(bus_tag));
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(fixed);
+ }
+ srx_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
- device_srx_card_interface(const machine_config &mconfig, device_t &device);
-
- virtual void map(address_map &map) = 0;
+ // device-level overrides
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
- srx_device *m_bus;
- const char *m_bus_tag;
- const char *m_slot_tag;
+private:
+ required_device<srx_bus_device> m_bus;
};
-class srx_card_device_base : public device_srx_card_interface
+class device_srx_card_interface : public device_slot_card_interface
{
protected:
- srx_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom");
+ friend class srx_slot_device;
public:
- const char *tag() { return device().tag(); }
+ DECLARE_WRITE_LINE_MEMBER(irq0) { m_bus->irq0_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq1) { m_bus->irq1_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(irq2) { m_bus->irq2_w(state); }
+ DECLARE_WRITE_LINE_MEMBER(vblank) { m_bus->vblank_w(state); }
protected:
- virtual void map(address_map &map) override;
+ device_srx_card_interface(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom")
+ : device_slot_card_interface(mconfig, device)
+ , m_bus(nullptr)
+ , m_idprom_region(idprom_region)
+ {
+ }
-private:
+ virtual void map(address_map &map) = 0;
+
+// FIXME: when we sort out the EDGE cards this stuff will be private
+//private:
+ void set_bus_device(srx_bus_device &bus_device);
+
+ srx_bus_device *m_bus;
const char *const m_idprom_region;
};
-DECLARE_DEVICE_TYPE(CBUS, cbus_device)
+DECLARE_DEVICE_TYPE(CBUS_BUS, cbus_bus_device)
DECLARE_DEVICE_TYPE(CBUS_SLOT, cbus_slot_device)
-DECLARE_DEVICE_TYPE(SRX, srx_device)
+DECLARE_DEVICE_TYPE(SRX_BUS, srx_bus_device)
DECLARE_DEVICE_TYPE(SRX_SLOT, srx_slot_device)
#endif // MAME_BUS_INTERPRO_SR_SR_H
diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp
index f758db66eaf..67eebf611cf 100644
--- a/src/devices/cpu/clipper/clipper.cpp
+++ b/src/devices/cpu/clipper/clipper.cpp
@@ -31,25 +31,22 @@
#define R1 (m_info.r1)
#define R2 (m_info.r2)
-// macros for setting psw condition codes
+#define BIT31(x) BIT(x, 31)
+#define BIT63(x) BIT(x, 63)
+
+// macros for computing and setting condition codes
#define FLAGS(C,V,Z,N) \
- m_psw = (m_psw & ~(PSW_C | PSW_V | PSW_Z | PSW_N)) | (((C) << 3) | ((V) << 2) | ((Z) << 1) | ((N) << 0));
-#define FLAGS_CV(C,V) \
- m_psw = (m_psw & ~(PSW_C | PSW_V)) | (((C) << 3) | ((V) << 2));
-#define FLAGS_ZN(Z,N) \
- m_psw = (m_psw & ~(PSW_Z | PSW_N)) | (((Z) << 1) | ((N) << 0));
-
-// over/underflow for addition/subtraction from here: http://stackoverflow.com/questions/199333/how-to-detect-integer-overflow-in-c-c
-#define OF_ADD(a, b) ((b > 0) && (a > INT32_MAX - b))
-#define UF_ADD(a, b) ((b < 0) && (a < INT32_MIN - b))
-#define OF_SUB(a, b) ((b < 0) && (a > INT32_MAX + b))
-#define UF_SUB(a, b) ((b > 0) && (a < INT32_MIN + b))
-
-// CLIPPER logic for carry and overflow flags
-#define C_ADD(a, b) (u32(a) + u32(b) < u32(a))
-#define V_ADD(a, b) (OF_ADD(s32(a), s32(b)) || UF_ADD(s32(a), s32(b)))
-#define C_SUB(a, b) (u32(a) < u32(b))
-#define V_SUB(a, b) (OF_SUB(s32(a), s32(b)) || UF_SUB(s32(a), s32(b)))
+ m_psw = (m_psw & ~(PSW_C | PSW_V | PSW_Z | PSW_N)) | (((C) << 3) | ((V) << 2) | ((Z) << 1) | ((N) << 0))
+
+#define FLAGS_ADD(op2, op1, result) FLAGS( \
+ (BIT31(op2) && BIT31(op1)) || (!BIT31(result) && (BIT31(op2) || BIT31(op1))), \
+ (BIT31(op2) == BIT31(op1)) && (BIT31(result) != BIT31(op2)), \
+ result == 0, BIT31(result))
+
+#define FLAGS_SUB(op2, op1, result) FLAGS( \
+ (!BIT31(op2) && BIT31(op1)) || (BIT31(result) && (!BIT31(op2) || BIT31(op1))), \
+ (BIT31(op2) != BIT31(op1)) && (BIT31(result) != BIT31(op2)), \
+ result == 0, BIT31(result))
DEFINE_DEVICE_TYPE(CLIPPER_C100, clipper_c100_device, "clipper_c100", "C100 CLIPPER")
DEFINE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device, "clipper_c300", "C300 CLIPPER")
@@ -114,12 +111,9 @@ inline u64 rotr64(u64 x, u8 shift)
void clipper_device::device_start()
{
- // map spaces to system tags
- std::vector<address_space *> spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), &space(0), &machine().dummy_space() };
-
// configure the cammu address spaces
- get_icammu().set_spaces(spaces);
- get_dcammu().set_spaces(spaces);
+ get_dcammu().set_spaces(space(0), space(1), space(2));
+ get_icammu().set_spaces(space(0), space(1), space(2));
// set our instruction counter
set_icountptr(m_icount);
@@ -580,7 +574,7 @@ void clipper_device::execute_instruction()
break;
case 0x25:
// cmps: compare single floating
- FLAGS(0, 0, float32_eq(get_fp32(R2), get_fp32(R1)), float32_lt(get_fp32(R2), get_fp32(R1)))
+ FLAGS(0, 0, float32_eq(get_fp32(R2), get_fp32(R1)), float32_lt(get_fp32(R2), get_fp32(R1)));
// flag unordered
if (float_exception_flags & float_flag_invalid)
m_psw |= PSW_Z | PSW_N;
@@ -592,7 +586,7 @@ void clipper_device::execute_instruction()
break;
case 0x27:
// cmpd: compare double floating
- FLAGS(0, 0, float64_eq(get_fp64(R2), get_fp64(R1)), float64_lt(get_fp64(R2), get_fp64(R1)))
+ FLAGS(0, 0, float64_eq(get_fp64(R2), get_fp64(R1)), float64_lt(get_fp64(R2), get_fp64(R1)));
// flag unordered
if (float_exception_flags & float_flag_invalid)
m_psw |= PSW_Z | PSW_N;
@@ -636,7 +630,7 @@ void clipper_device::execute_instruction()
break;
case 0x30:
// shaw: shift arithmetic word
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
{
// save the bits that will be shifted out plus new sign bit
const s32 v = s32(m_r[R2]) >> (31 - m_r[R1]);
@@ -644,18 +638,18 @@ void clipper_device::execute_instruction()
m_r[R2] <<= m_r[R1];
// overflow is set if sign changes during shift
- FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, BIT31(m_r[R2]));
}
else
{
m_r[R2] = s32(m_r[R2]) >> -m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
}
// FLAGS: 0VZN
break;
case 0x31:
// shal: shift arithmetic longword
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
{
// save the bits that will be shifted out plus new sign bit
const s64 v = s64(get_64(R2)) >> (63 - m_r[R1]);
@@ -663,55 +657,55 @@ void clipper_device::execute_instruction()
set_64(R2, get_64(R2) << m_r[R1]);
// overflow is set if sign changes during shift
- FLAGS(0, v != 0 && v != -1, get_64(R2) == 0, s64(get_64(R2)) < 0)
+ FLAGS(0, v != 0 && v != -1, get_64(R2) == 0, BIT63(get_64(R2)));
}
else
{
set_64(R2, s64(get_64(R2)) >> -m_r[R1]);
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0)
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
}
// FLAGS: 0VZN
break;
case 0x32:
// shlw: shift logical word
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
m_r[R2] <<= m_r[R1];
else
m_r[R2] >>= -m_r[R1];
// FLAGS: 00ZN
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0);
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
break;
case 0x33:
// shll: shift logical longword
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
set_64(R2, get_64(R2) << m_r[R1]);
else
set_64(R2, get_64(R2) >> -m_r[R1]);
// FLAGS: 00ZN
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0);
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
break;
case 0x34:
// rotw: rotate word
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
m_r[R2] = rotl32(m_r[R2], m_r[R1]);
else
m_r[R2] = rotr32(m_r[R2], -m_r[R1]);
// FLAGS: 00ZN
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0);
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
break;
case 0x35:
// rotl: rotate longword
- if (s32(m_r[R1]) > 0)
+ if (!BIT31(m_r[R1]))
set_64(R2, rotl64(get_64(R2), m_r[R1]));
else
set_64(R2, rotr64(get_64(R2), -m_r[R1]));
// FLAGS: 00ZN
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0);
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
break;
case 0x38:
// shai: shift arithmetic immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
{
// save the bits that will be shifted out plus new sign bit
const s32 v = s32(m_r[R2]) >> (31 - m_info.imm);
@@ -719,19 +713,19 @@ void clipper_device::execute_instruction()
m_r[R2] <<= m_info.imm;
// overflow is set if sign changes during shift
- FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, BIT31(m_r[R2]));
}
else
{
m_r[R2] = s32(m_r[R2]) >> -m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
}
// FLAGS: 0VZN
// TRAPS: I
break;
case 0x39:
// shali: shift arithmetic longword immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
{
// save the bits that will be shifted out plus new sign bit
const s64 v = s64(get_64(R2)) >> (63 - m_info.imm);
@@ -739,53 +733,53 @@ void clipper_device::execute_instruction()
set_64(R2, get_64(R2) << m_info.imm);
// overflow is set if sign changes during shift
- FLAGS(0, v != 0 && v != -1, get_64(R2) == 0, s64(get_64(R2)) < 0)
+ FLAGS(0, v != 0 && v != -1, get_64(R2) == 0, BIT63(get_64(R2)));
}
else
{
set_64(R2, s64(get_64(R2)) >> -m_info.imm);
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0)
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
}
// FLAGS: 0VZN
// TRAPS: I
break;
case 0x3a:
// shli: shift logical immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
m_r[R2] <<= m_info.imm;
else
m_r[R2] >>= -m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0);
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x3b:
// shlli: shift logical longword immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
set_64(R2, get_64(R2) << m_info.imm);
else
set_64(R2, get_64(R2) >> -m_info.imm);
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0);
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x3c:
// roti: rotate immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
m_r[R2] = rotl32(m_r[R2], m_info.imm);
else
m_r[R2] = rotr32(m_r[R2], -m_info.imm);
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0);
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x3d:
// rotli: rotate longword immediate
- if (s32(m_info.imm) > 0)
+ if (!BIT31(m_info.imm))
set_64(R2, rotl64(get_64(R2), m_info.imm));
else
set_64(R2, rotr64(get_64(R2), -m_info.imm));
- FLAGS(0, 0, get_64(R2) == 0, s64(get_64(R2)) < 0);
+ FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
// FLAGS: 00ZN
// TRAPS: I
break;
@@ -924,95 +918,123 @@ void clipper_device::execute_instruction()
case 0x80:
// addw: add word
- FLAGS_CV(C_ADD(m_r[R2], m_r[R1]), V_ADD(m_r[R2], m_r[R1]))
- m_r[R2] += m_r[R1];
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] + m_r[R1];
+
+ FLAGS_ADD(m_r[R2], m_r[R1], result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0x82:
// addq: add quick
- FLAGS_CV(C_ADD(m_r[R2], R1), V_ADD(m_r[R2], R1))
- m_r[R2] += R1;
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] + m_info.r1;
+
+ FLAGS_ADD(m_r[R2], m_info.r1, result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0x83:
// addi: add immediate
- FLAGS_CV(C_ADD(m_r[R2], m_info.imm), V_ADD(m_r[R2], m_info.imm))
- m_r[R2] += m_info.imm;
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] + m_info.imm;
+
+ FLAGS_ADD(m_r[R2], m_info.imm, result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
// TRAPS: I
break;
case 0x84:
// movw: move word
m_r[R2] = m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
break;
case 0x86:
// loadq: load quick
- m_r[R2] = R1;
- FLAGS(0, 0, m_r[R2] == 0, 0)
+ m_r[R2] = m_info.r1;
+ FLAGS(0, 0, m_r[R2] == 0, 0);
// FLAGS: 00Z0
break;
case 0x87:
// loadi: load immediate
m_r[R2] = m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x88:
// andw: and word
m_r[R2] &= m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
break;
case 0x8b:
// andi: and immediate
m_r[R2] &= m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x8c:
// orw: or word
m_r[R2] |= m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
break;
case 0x8f:
// ori: or immediate
m_r[R2] |= m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0x90:
// addwc: add word with carry
- FLAGS_CV(C_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))))
- m_r[R2] += m_r[R1] + (PSW(C) ? 1 : 0);
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] + m_r[R1] + (PSW(C) ? 1 : 0);
+
+ FLAGS_ADD(m_r[R2], m_r[R1], result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0x91:
// subwc: subtract word with carry
- FLAGS_CV(C_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))))
- m_r[R2] -= m_r[R1] + (PSW(C) ? 1 : 0);
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] - m_r[R1] - (PSW(C) ? 1 : 0);
+
+ FLAGS_SUB(m_r[R2], m_r[R1], result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0x93:
// negw: negate word
- FLAGS_CV(m_r[R1] != 0, s32(m_r[R1]) == INT32_MIN)
- m_r[R2] = -m_r[R1];
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = -m_r[R1];
+
+ FLAGS(
+ m_r[R1] != 0,
+ s32(m_r[R1]) == INT32_MIN,
+ result == 0,
+ BIT31(result));
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
@@ -1021,7 +1043,7 @@ void clipper_device::execute_instruction()
{
const s64 product = mul_32x32(m_r[R1], m_r[R2]);
m_r[R2] = s32(product);
- FLAGS(0, (u64(product) >> 32) != (BIT(product, 31) ? ~u32(0) : 0), 0, 0)
+ FLAGS(0, (u64(product) >> 32) != (BIT31(product) ? ~u32(0) : 0), 0, 0);
// FLAGS: 0V00
}
break;
@@ -1030,7 +1052,7 @@ void clipper_device::execute_instruction()
{
const s64 product = mul_32x32(m_r[R1], m_r[R2]);
set_64(R2, product);
- FLAGS(0, (u64(product) >> 32) != (BIT(product, 31) ? ~u32(0) : 0), 0, 0)
+ FLAGS(0, (u64(product) >> 32) != (BIT31(product) ? ~u32(0) : 0), 0, 0);
// FLAGS: 0V00
}
break;
@@ -1039,7 +1061,7 @@ void clipper_device::execute_instruction()
{
const u64 product = mulu_32x32(m_r[R1], m_r[R2]);
m_r[R2] = u32(product);
- FLAGS(0, (product >> 32) != 0, 0, 0)
+ FLAGS(0, (product >> 32) != 0, 0, 0);
// FLAGS: 0V00
}
break;
@@ -1048,7 +1070,7 @@ void clipper_device::execute_instruction()
{
const u64 product = mulu_32x32(m_r[R1], m_r[R2]);
set_64(R2, product);
- FLAGS(0, (product >> 32) != 0, 0, 0)
+ FLAGS(0, (product >> 32) != 0, 0, 0);
// FLAGS: 0V00
}
break;
@@ -1057,7 +1079,7 @@ void clipper_device::execute_instruction()
if (m_r[R1] != 0)
{
// FLAGS: 0V00
- FLAGS(0, s32(m_r[R2]) == INT32_MIN && s32(m_r[R1]) == -1, 0, 0)
+ FLAGS(0, s32(m_r[R2]) == INT32_MIN && s32(m_r[R1]) == -1, 0, 0);
m_r[R2] = s32(m_r[R2]) / s32(m_r[R1]);
}
else
@@ -1069,7 +1091,7 @@ void clipper_device::execute_instruction()
if (m_r[R1] != 0)
{
// FLAGS: 0V00
- FLAGS(0, s32(m_r[R2]) == INT32_MIN && s32(m_r[R1]) == -1, 0, 0)
+ FLAGS(0, s32(m_r[R2]) == INT32_MIN && s32(m_r[R1]) == -1, 0, 0);
m_r[R2] = s32(m_r[R2]) % s32(m_r[R1]);
}
else
@@ -1082,7 +1104,7 @@ void clipper_device::execute_instruction()
{
m_r[R2] = m_r[R2] / m_r[R1];
// FLAGS: 0000
- FLAGS(0, 0, 0, 0)
+ FLAGS(0, 0, 0, 0);
}
else
// TRAPS: D
@@ -1094,7 +1116,7 @@ void clipper_device::execute_instruction()
{
m_r[R2] = m_r[R2] % m_r[R1];
// FLAGS: 0000
- FLAGS(0, 0, 0, 0)
+ FLAGS(0, 0, 0, 0);
}
else
// TRAPS: D
@@ -1102,69 +1124,93 @@ void clipper_device::execute_instruction()
break;
case 0xa0:
// subw: subtract word
- FLAGS_CV(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]))
- m_r[R2] -= m_r[R1];
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] - m_r[R1];
+
+ FLAGS_SUB(m_r[R2], m_r[R1], result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0xa2:
// subq: subtract quick
- FLAGS_CV(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1))
- m_r[R2] -= R1;
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] - m_info.r1;
+
+ FLAGS_SUB(m_r[R2], m_info.r1, result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
break;
case 0xa3:
// subi: subtract immediate
- FLAGS_CV(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm))
- m_r[R2] -= m_info.imm;
- FLAGS_ZN(m_r[R2] == 0, s32(m_r[R2]) < 0)
+ {
+ const u32 result = m_r[R2] - m_info.imm;
+
+ FLAGS_SUB(m_r[R2], m_info.imm, result);
+
+ m_r[R2] = result;
+ }
// FLAGS: CVZN
// TRAPS: I
break;
case 0xa4:
// cmpw: compare word
- FLAGS(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]), m_r[R2] == m_r[R1], s32(m_r[R2]) < s32(m_r[R1]))
+ {
+ const u32 result = m_r[R2] - m_r[R1];
+
+ FLAGS_SUB(m_r[R2], m_r[R1], result);
+ }
// FLAGS: CVZN
break;
case 0xa6:
// cmpq: compare quick
- FLAGS(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1), m_r[R2] == R1, s32(m_r[R2]) < s32(R1))
+ {
+ const u32 result = m_r[R2] - m_info.r1;
+
+ FLAGS_SUB(m_r[R2], m_info.r1, result);
+ }
// FLAGS: CVZN
break;
case 0xa7:
// cmpi: compare immediate
- FLAGS(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm), m_r[R2] == m_info.imm, s32(m_r[R2]) < s32(m_info.imm))
+ {
+ const u32 result = m_r[R2] - m_info.imm;
+
+ FLAGS_SUB(m_r[R2], m_info.imm, result);
+ }
// FLAGS: CVZN
// TRAPS: I
break;
case 0xa8:
// xorw: exclusive or word
m_r[R2] ^= m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
break;
case 0xab:
// xori: exclusive or immediate
m_r[R2] ^= m_info.imm;
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
break;
case 0xac:
// notw: not word
m_r[R2] = ~m_r[R1];
- FLAGS(0, 0, m_r[R2] == 0, s32(m_r[R2]) < 0)
+ FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
break;
case 0xae:
// notq: not quick
m_r[R2] = ~R1;
- FLAGS(0, 0, 0, 1)
+ FLAGS(0, 0, 0, 1);
// FLAGS: 0001
break;
@@ -1229,10 +1275,15 @@ void clipper_device::execute_instruction()
while (m_r[0])
{
// read and compare bytes (as signed 32 bit integers)
- get_dcammu().load<s8>(m_ssw, m_r[1], [this](s32 byte1) {
- get_dcammu().load<s8>(m_ssw, m_r[2], [this, byte1](s32 byte2) {
- if (byte1 != byte2)
- FLAGS(C_SUB(byte2, byte1), V_SUB(byte2, byte1), byte2 == byte1, byte2 < byte1); }); });
+ get_dcammu().load<s8>(m_ssw, m_r[1], [this](s32 byte1)
+ {
+ get_dcammu().load<s8>(m_ssw, m_r[2], [this, byte1](s32 byte2)
+ {
+ const s32 result = byte2 - byte1;
+
+ FLAGS_SUB(byte2, byte1, result);
+ });
+ });
// abort on exception or mismatch
if (m_exception || !PSW(Z))
@@ -1424,14 +1475,14 @@ void clipper_device::execute_instruction()
case 0x00:
// movus: move user to supervisor
m_rs[m_info.macro & 0xf] = m_ru[(m_info.macro >> 4) & 0xf];
- FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, s32(m_rs[m_info.macro & 0xf]) < 0)
+ FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, BIT31(m_rs[m_info.macro & 0xf]));
// FLAGS: 00ZN
// TRAPS: S
break;
case 0x01:
// movsu: move supervisor to user
m_ru[m_info.macro & 0xf] = m_rs[(m_info.macro >> 4) & 0xf];
- FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, s32(m_ru[m_info.macro & 0xf]) < 0)
+ FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, BIT31(m_ru[m_info.macro & 0xf]));
// FLAGS: 00ZN
// TRAPS: S
break;
diff --git a/src/devices/machine/28fxxx.h b/src/devices/machine/28fxxx.h
index 313cda82873..e045a91f27c 100644
--- a/src/devices/machine/28fxxx.h
+++ b/src/devices/machine/28fxxx.h
@@ -69,13 +69,13 @@ private:
class intel_28f010_device : public base_28fxxx_device
{
public:
- intel_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ intel_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class amd_28f010_device : public base_28fxxx_device
{
public:
- amd_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ amd_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
DECLARE_DEVICE_TYPE(INTEL_28F010, intel_28f010_device)
diff --git a/src/devices/machine/i82586.h b/src/devices/machine/i82586.h
index 93f45d82574..e45e46fe4f4 100644
--- a/src/devices/machine/i82586.h
+++ b/src/devices/machine/i82586.h
@@ -6,9 +6,6 @@
#pragma once
-#define MCFG_I82586_IRQ_CB(_out_irq) \
- downcast<i82586_base_device &>(*device).set_out_irq_callback(DEVCB_##_out_irq);
-
class i82586_base_device :
public device_t,
public device_memory_interface,
@@ -157,7 +154,8 @@ public:
static const u32 FCS_RESIDUE = 0xdebb20e3; // the residue after computing the fcs over a complete frame (including fcs)
- template <class Object> devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq.set_callback(std::forward<Object>(cb)); }
+ // callback configuration
+ auto out_irq_cb() { return m_out_irq.bind(); }
DECLARE_WRITE_LINE_MEMBER(ca);
virtual void recv_cb(u8 *buf, int length) override;
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index e4a252547f7..e2f17436e82 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -40,9 +40,9 @@
* 6600 1991 C400 40 MIPS emerald IOI, SRX bus?
* 2400 1992 C4T 36 MIPS/33 SPECmarks 40MHz? sapphire CBUS
* 6400 1992 C4T 36 MIPS/33 SPECmarks 40MHz sapphire SRX
- * 2700 1993 C400I 40.1 SPECmark89 sapphire 2 CBUS
- * 6700 1993 C400I 40.1 SPECmark89 sapphire 2 SRX
- * 6800 1993 C400I 67.2 SPECmark89 sapphire 3 SRX
+ * 2700 1993 C400I 61 MIPS?/40.1 SPECmark89 sapphire 2 CBUS
+ * 6700 1993 C400I 61 MIPS?/40.1 SPECmark89 sapphire 2 SRX
+ * 6800 1993 C400I 85 MIPS/67.2 SPECmark89 sapphire 3 SRX
* 2500 1993 C400I 19.9 SPECint92 sapphire
* 2800 1994 C400I sapphire 3 CBUS?
*
@@ -53,12 +53,9 @@
*
* A: case type (2=desktop, 6=minicase)
* B: CPU type (0=C300, 4=C4T, 6=C400?, 7/8/5 = C400I)
- * C: graphics type (0=none, 3/5=GT, 4=EDGE-1, 8 = EDGE-2)
+ * C: graphics type (0=none, 2=GT, 3=GT+, 5=GTII, 4=EDGE-1, 8=EDGE-2/2+)
* D: usually 0, 6xxx systems have 5, 7 and 9 options (backplane type?)
*
- * Graphics type 3 is for GT graphics fitted to a 2xxx system, and type 5 when
- * fitted to a 6xxx system. The latter is possibly also known as GTDB.
- *
* Both the desktop and minicase units supported expansion slots with a variety
* of cards, although with different profiles and connectors between 2xxx and
* 6xxx systems. The 2xxx bus is referred to as CBUS, with the 6xxx bus known
@@ -663,19 +660,11 @@ void sapphire_state::sapphire_main_map(address_map &map)
void emerald_state::emerald_io_map(address_map &map)
{
emerald_base_map(map);
-
- map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
- map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
- map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void turquoise_state::turquoise_io_map(address_map &map)
{
turquoise_base_map(map);
-
- map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
- map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
- map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void sapphire_state::sapphire_io_map(address_map &map)
@@ -740,13 +729,13 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(interpro_state::interpro_scc2)
MCFG_DEVICE_MODIFY(INTERPRO_SCC2_TAG)
- MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_port_device, write_txd))
+ MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(m_keyboard, interpro_keyboard_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(INTERPRO_SERIAL_PORT0_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(m_ioga, interpro_ioga_device, ir11_w))
MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial0))
- MCFG_INTERPRO_KEYBOARD_PORT_ADD(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_devices, "lle_en_us")
- MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxa_w))
+ INTERPRO_KEYBOARD_PORT(config, m_keyboard, interpro_keyboard_devices, "lle_en_us");
+ m_keyboard->rxd_handler_cb().set(m_scc2, FUNC(z80scc_device::rxa_w));
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT0_TAG, RS232_PORT, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxb_w))
@@ -817,15 +806,15 @@ static INPUT_PORTS_START(interpro)
INPUT_PORTS_END
MACHINE_CONFIG_START(interpro_state::interpro)
- MCFG_RAM_ADD(RAM_TAG)
- MCFG_RAM_DEFAULT_SIZE("16M")
- MCFG_RAM_EXTRA_OPTIONS("32M,64M,128M,256M")
+ RAM(config, m_ram, 0);
+ m_ram->set_default_size("16M");
+ m_ram->set_extra_options("32M,64M,128M,256M");
// memory control gate array
// srx gate array
- MCFG_DEVICE_ADD(m_sga, INTERPRO_SGA, 0)
- MCFG_INTERPRO_SGA_BERR_CB(WRITE32(m_ioga, interpro_ioga_device, bus_error))
+ INTERPRO_SGA(config, m_sga, 0);
+ m_sga->berr_callback().set(m_ioga, FUNC(interpro_ioga_device::bus_error));
// floppy
@@ -852,9 +841,8 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// i/o gate array
// mouse
- MCFG_DEVICE_ADD(INTERPRO_MOUSE_PORT_TAG, INTERPRO_MOUSE_PORT, 0)
- MCFG_DEVICE_SLOT_INTERFACE(interpro_mouse_devices, "interpro_mouse", false)
- MCFG_MOUSE_STATE_CB(WRITE32(m_ioga, interpro_ioga_device, mouse_status_w))
+ interpro_mouse_port_device &mouse(INTERPRO_MOUSE_PORT(config, INTERPRO_MOUSE_PORT_TAG, interpro_mouse_devices, "interpro_mouse"));
+ mouse.state_func().set(m_ioga, FUNC(interpro_ioga_device::mouse_status_w));
// system layout
config.set_default_layout(layout_interpro);
@@ -872,19 +860,18 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
- MCFG_DEVICE_ADD(m_i_cammu, CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
+ CAMMU_C3(config, m_i_cammu, 0);
+ m_i_cammu->exception_callback().set(m_maincpu, FUNC(clipper_device::set_exception));
- MCFG_DEVICE_ADD(m_d_cammu, CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
- MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
+ CAMMU_C3(config, m_d_cammu, 0);
+ m_d_cammu->exception_callback().set(m_maincpu, FUNC(clipper_device::set_exception));
+ m_d_cammu->add_linked(m_i_cammu);
// boot fails memory test without this
- MCFG_DEVICE_MODIFY(RAM_TAG)
- MCFG_RAM_DEFAULT_VALUE(0x00)
+ m_ram->set_default_value(0);
// memory control gate array
- MCFG_DEVICE_ADD(m_mcga, INTERPRO_MCGA, 0)
+ INTERPRO_MCGA(config, m_mcga, 0);
// floppy controller
MCFG_I82072_ADD(m_fdc, false)
@@ -897,9 +884,9 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_FLOPPY_DRIVE_SOUND(false)
// serial controllers and ports
- MCFG_DEVICE_ADD(m_scc1, SCC85C30, 4.9152_MHz_XTAL)
+ SCC85C30(config, m_scc1, 4.9152_MHz_XTAL);
interpro_scc1(config);
- MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
+ SCC85C30(config, m_scc2, 4.9152_MHz_XTAL);
interpro_scc2(config);
// scsi controller
@@ -907,9 +894,9 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(m_eth, I82586, 10_MHz_XTAL)
- MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
- MCFG_DEVICE_ADDRESS_MAP(0, interpro_82586_map)
+ I82586(config, m_eth, 10_MHz_XTAL);
+ m_eth->out_irq_cb().set(m_ioga, FUNC(interpro_ioga_device::ir12_w));
+ m_eth->set_addrmap(0, &emerald_state::interpro_82586_map);
// i/o gate array
EMERALD_IOGA(config, m_ioga, 0);
@@ -919,25 +906,25 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::turquoise)
interpro(config);
+
MCFG_DEVICE_ADD(m_maincpu, CLIPPER_C300, 12.5_MHz_XTAL)
MCFG_DEVICE_ADDRESS_MAP(0, turquoise_main_map)
MCFG_DEVICE_ADDRESS_MAP(1, turquoise_io_map)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
- MCFG_DEVICE_ADD(m_i_cammu, CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
+ CAMMU_C3(config, m_i_cammu, 0);
+ m_i_cammu->exception_callback().set(m_maincpu, FUNC(clipper_device::set_exception));
- MCFG_DEVICE_ADD(m_d_cammu, CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
- MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
+ CAMMU_C3(config, m_d_cammu, 0);
+ m_d_cammu->exception_callback().set(m_maincpu, FUNC(clipper_device::set_exception));
+ m_d_cammu->add_linked(m_i_cammu);
// boot fails memory test without this
- MCFG_DEVICE_MODIFY(RAM_TAG)
- MCFG_RAM_DEFAULT_VALUE(0x00)
+ m_ram->set_default_value(0);
// memory control gate array
- MCFG_DEVICE_ADD(m_mcga, INTERPRO_MCGA, 0)
+ INTERPRO_MCGA(config, m_mcga, 0);
// floppy controller
MCFG_I82072_ADD(m_fdc, false)
@@ -949,9 +936,9 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_FLOPPY_DRIVE_SOUND(false)
// serial controllers and ports
- MCFG_DEVICE_ADD(m_scc1, SCC85C30, 4.9152_MHz_XTAL)
+ SCC85C30(config, m_scc1, 4.9152_MHz_XTAL);
interpro_scc1(config);
- MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
+ SCC85C30(config, m_scc2, 4.9152_MHz_XTAL);
interpro_scc2(config);
// scsi controller
@@ -959,24 +946,14 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(m_eth, I82586, 0)
- MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
- MCFG_DEVICE_ADDRESS_MAP(0, interpro_82586_map)
+ I82586(config, m_eth, 10_MHz_XTAL);
+ m_eth->out_irq_cb().set(m_ioga, FUNC(interpro_ioga_device::ir12_w));
+ m_eth->set_addrmap(0, &turquoise_state::interpro_82586_map);
// i/o gate array
TURQUOISE_IOGA(config, m_ioga, 0);
m_ioga->set_memory(m_maincpu, 0);
ioga(config);
-
- // cbus and slots
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
- MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
- MCFG_CBUS_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
- MCFG_CBUS_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
- MCFG_CBUS_OUT_VBLANK_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, nullptr, false)
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::sapphire)
@@ -988,11 +965,11 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
// FIXME: 2400/6400 should be C4T cammu?
- MCFG_DEVICE_ADD(m_mmu, CAMMU_C4I, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
+ CAMMU_C4I(config, m_mmu, 0);
+ m_mmu->exception_callback().set(m_maincpu, FUNC(clipper_device::set_exception));
// memory control gate array
- MCFG_DEVICE_ADD(m_mcga, INTERPRO_FMCC, 0)
+ INTERPRO_FMCC(config, m_mcga, 0);
// floppy controller
MCFG_N82077AA_ADD(m_fdc, n82077aa_device::MODE_PS2)
@@ -1004,12 +981,12 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
MCFG_FLOPPY_DRIVE_SOUND(false)
// srx arbiter gate array
- MCFG_DEVICE_ADD(m_arbga, INTERPRO_ARBGA, 0)
+ INTERPRO_ARBGA(config, m_arbga, 0);
// serial controllers and ports
- MCFG_DEVICE_ADD(m_scc1, SCC85230, 4.9152_MHz_XTAL)
+ SCC85230(config, m_scc1, 4.9152_MHz_XTAL);
interpro_scc1(config);
- MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
+ SCC85C30(config, m_scc2, 4.9152_MHz_XTAL);
interpro_scc2(config);
// scsi controller
@@ -1017,9 +994,9 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(m_eth, I82596_LE16, 20_MHz_XTAL)
- MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
- MCFG_DEVICE_ADDRESS_MAP(0, interpro_82596_map)
+ I82596_LE16(config, m_eth, 20_MHz_XTAL);
+ m_eth->out_irq_cb().set(m_ioga, FUNC(interpro_ioga_device::ir12_w));
+ m_eth->set_addrmap(0, &sapphire_state::interpro_82596_map);
// i/o gate array
SAPPHIRE_IOGA(config, m_ioga, 0);
@@ -1027,202 +1004,213 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
ioga(config);
// flash memory
- MCFG_DEVICE_ADD(m_flash_lsb, INTEL_28F010, 0)
- MCFG_DEVICE_ADD(m_flash_msb, INTEL_28F010, 0)
+ INTEL_28F010(config, m_flash_lsb);
+ INTEL_28F010(config, m_flash_msb);
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::ip2000)
turquoise(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(40_MHz_XTAL)
+ //m_maincpu->set_clock(40_MHz_XTAL);
- // GT graphics (2020)
- MCFG_DEVICE_MODIFY(INTERPRO_SLOT_TAG ":0")
- MCFG_SLOT_DEFAULT_OPTION("mpcb963")
+ // bus and slots (default to 2020 with GT graphics)
+ cbus_bus_device &bus(CBUS_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
+
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":0", 0, bus, cbus_cards, "mpcb963", false);
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, cbus_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "2000")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2400)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(50_MHz_XTAL)
+ //m_maincpu->set_clock(50_MHz_XTAL);
+
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR0);
+
+ // bus and slots (default to 2430 with GT+ graphics)
+ cbus_bus_device &bus(CBUS_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
- // cbus and slots (default to 2430 with GT+ graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
- MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":0", 0, bus, cbus_cards, "msmt070", false);
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, cbus_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "2400")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2500)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(XTAL(?)
+ //m_maincpu->set_clock(?);
- // cbus and slots (default to 2530 with GT+ graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
- MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
+ // FIXME: don't know which cammu revision
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR0);
- // GT II graphics?
- //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+ // bus and slots (default to 2530 with GT+ graphics)
+ cbus_bus_device &bus(CBUS_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
- // FIXME: don't know which cammu revision
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ // GT II graphics (msmt135)?
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":0", 0, bus, cbus_cards, "msmt070", false);
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, cbus_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "2500")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2700)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(?)
+ //m_maincpu->set_clock(?);
+
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR2);
- // cbus and slots (default to 2730 with GT+ graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
- MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
+ // bus and slots (default to 2730 with GT+ graphics)
+ cbus_bus_device &bus(CBUS_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
- // GT II graphics?
- //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
+ // GT II graphics (msmt135)?
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":0", 0, bus, cbus_cards, "msmt070", false);
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, cbus_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "2700")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2800)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(?)
+ //m_maincpu->set_clock(?);
- // cbus and slots (default to 2830 with GT+ graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
- MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
- MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
+ // FIXME: don't know which cammu revision
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR2);
- // GT II graphics?
- //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+ // bus and slots (default to 2830 with GT+ graphics)
+ cbus_bus_device &bus(CBUS_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
- // FIXME: don't know which cammu revision
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ // GT II graphics (msmt135)?
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":0", 0, bus, cbus_cards, "msmt070", false);
+ CBUS_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, cbus_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "2800")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(emerald_state::ip6000)
emerald(config);
-
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(80_MHz_XTAL / 2)
+ //m_maincpu->set_clock(80_MHz_XTAL / 2);
// EDGE systems use graphics keyboard
- MCFG_DEVICE_MODIFY(INTERPRO_KEYBOARD_PORT_TAG)
- MCFG_SLOT_DEFAULT_OPTION(nullptr)
-
- // srx and slots (default to 6040 with EDGE-1 graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
- MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
- MCFG_SRX_OUT_VBLANK_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "mpcb828", false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":4", srx_cards, nullptr, false)
+ m_keyboard->set_default_option(nullptr);
+
+ // bus and slots (default to 6040 with EDGE-1 graphics)
+ srx_bus_device &bus(SRX_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
+
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, srx_cards, "mpcb828", false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":2", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":3", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":4", 0, bus, srx_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "6000")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip6400)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(36_MHz_XTAL)
-
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
-
- // srx and slots (default to 6450 with GT II graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
- MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "mpcbb92", false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":4", srx_cards, nullptr, false)
+ //m_maincpu->set_clock(36_MHz_XTAL);
+
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR0);
+
+ // bus and slots (default to 6450 with GT II graphics)
+ srx_bus_device &bus(SRX_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
+
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, srx_cards, "mpcbb92", false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":2", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":3", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":4", 0, bus, srx_cards, nullptr, false);
+
+ // EDGE systems use graphics keyboard
+ //m_keyboard->set_default_option(nullptr);
// EDGE-2 graphics (6480)
- //MCFG_SRX_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":1", srx_cards, "mpcb030", false)
- //MCFG_SRX_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":2", srx_cards, "mpcba63", false)
+ //SRX_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, srx_cards, "mpcb030", false);
+ //SRX_SLOT(config, INTERPRO_SLOT_TAG ":2", 0, bus, srx_cards, "mpcba63", false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "6400")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip6700)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(?)
+ //m_maincpu->set_clock(?);
// FIXME: don't know which cammu revision
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
-
- // srx and slots (default to 6780 with EDGE-2 Plus graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
- MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "msmt094", false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, "mpcb896", false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":4", srx_cards, nullptr, false)
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR2);
+
+ // EDGE systems use graphics keyboard
+ m_keyboard->set_default_option(nullptr);
+
+ // bus and slots (default to 6780 with EDGE-2 Plus graphics)
+ srx_bus_device &bus(SRX_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
+
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, srx_cards, "msmt094", false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":2", 0, bus, srx_cards, "mpcb896", false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":3", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":4", 0, bus, srx_cards, nullptr, false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "6700")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip6800)
sapphire(config);
- //MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(?)
+ //m_maincpu->set_clock(?);
// FIXME: don't know which cammu revision
- MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
- MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
+ m_mmu->set_cammu_id(cammu_c4i_device::CID_C4IR2);
// EDGE systems use graphics keyboard
- MCFG_DEVICE_MODIFY(INTERPRO_KEYBOARD_PORT_TAG)
- MCFG_SLOT_DEFAULT_OPTION(nullptr)
-
- // srx and slots (default to 6880 with EDGE-2 Plus graphics)
- MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
- MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, "msmt094", false)
- MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":4", srx_cards, "mpcb896", false)
+ m_keyboard->set_default_option(nullptr);
+
+ // bus and slots (default to 6880 with EDGE-2 Plus graphics)
+ srx_bus_device &bus(SRX_BUS(config, INTERPRO_SLOT_TAG, 0, m_maincpu));
+
+ bus.out_irq0_cb().set(m_ioga, FUNC(interpro_ioga_device::ir3_w));
+ bus.out_irq1_cb().set(m_ioga, FUNC(interpro_ioga_device::ir4_w));
+ bus.out_irq2_cb().set(m_ioga, FUNC(interpro_ioga_device::ir5_w));
+ bus.out_vblank_cb().set(m_ioga, FUNC(interpro_ioga_device::ir6_w));
+
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":1", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":2", 0, bus, srx_cards, nullptr, false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":3", 0, bus, srx_cards, "msmt094", false);
+ SRX_SLOT(config, INTERPRO_SLOT_TAG ":4", 0, bus, srx_cards, "mpcb896", false);
MCFG_SOFTWARE_LIST_FILTER("softlist", "6800")
MACHINE_CONFIG_END
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index 0dac4f4403b..0df07883eac 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -79,6 +79,7 @@ public:
, m_scsibus(*this, INTERPRO_SCSI_TAG)
, m_eth(*this, INTERPRO_ETH_TAG)
, m_ioga(*this, INTERPRO_IOGA_TAG)
+ , m_keyboard(*this, INTERPRO_KEYBOARD_PORT_TAG)
, m_diag_led(*this, "digit0")
{
}
@@ -96,6 +97,8 @@ public:
required_device<i82586_base_device> m_eth;
required_device<interpro_ioga_device> m_ioga;
+ required_device<interpro_keyboard_port_device> m_keyboard;
+
void init_common();
virtual DECLARE_READ32_MEMBER(unmapped_r);
diff --git a/src/mame/machine/cammu.cpp b/src/mame/machine/cammu.cpp
index 721f8ed5cc9..3db37813700 100644
--- a/src/mame/machine/cammu.cpp
+++ b/src/mame/machine/cammu.cpp
@@ -22,9 +22,8 @@
* Another reference: http://www.eecs.berkeley.edu/Pubs/TechRpts/1986/CSD-86-289.pdf
*
* TODO
- * - rework cammu addressing (to allow unaligned tlb access)
+ * - c4 variants
* - fault register values
- * - hard-wired and dynamic tlb
* - cache
* - bus errors
*/
@@ -37,6 +36,7 @@
#define LOG_GENERAL (1U << 0)
#define LOG_ACCESS (1U << 1)
#define LOG_DTU (1U << 2)
+#define LOG_TLB (1U << 3)
//#define VERBOSE (LOG_GENERAL | LOG_ACCESS | LOG_DTU)
#include "logmacro.h"
@@ -92,26 +92,6 @@ void cammu_c4i_device::map(address_map &map)
map(0x0c0, 0x0c3).rw(FUNC(cammu_c4i_device::test_address_r), FUNC(cammu_c4i_device::test_address_w));
}
-void cammu_c3_device::map(address_map &map)
-{
- map(0x000, 0x0ff).noprw(); // tlb
- map(0x104, 0x107).rw(FUNC(cammu_c3_device::s_pdo_r), FUNC(cammu_c3_device::s_pdo_w));
- map(0x108, 0x10b).rw(FUNC(cammu_c3_device::u_pdo_r), FUNC(cammu_c3_device::u_pdo_w));
- map(0x110, 0x113).rw(FUNC(cammu_c3_device::fault_r), FUNC(cammu_c3_device::fault_w));
- map(0x140, 0x143).rw(FUNC(cammu_c3_device::control_r), FUNC(cammu_c3_device::control_w));
- map(0x180, 0x183).rw(FUNC(cammu_c3_device::reset_r), FUNC(cammu_c3_device::reset_w));
-}
-
-void cammu_c3_device::map_global(address_map &map)
-{
- map(0x000, 0x0ff).noprw(); // global tlb
- map(0x104, 0x107).w(FUNC(cammu_c3_device::g_s_pdo_w));
- map(0x108, 0x10b).w(FUNC(cammu_c3_device::g_u_pdo_w));
- map(0x110, 0x113).w(FUNC(cammu_c3_device::g_fault_w));
- map(0x140, 0x143).w(FUNC(cammu_c3_device::g_control_w));
- map(0x180, 0x183).w(FUNC(cammu_c3_device::g_reset_w));
-}
-
DEFINE_DEVICE_TYPE(CAMMU_C4T, cammu_c4t_device, "c4t", "C4E/C4T CAMMU")
DEFINE_DEVICE_TYPE(CAMMU_C4I, cammu_c4i_device, "c4i", "C4I CAMMU")
DEFINE_DEVICE_TYPE(CAMMU_C3, cammu_c3_device, "c3", "C1/C3 CAMMU")
@@ -133,8 +113,8 @@ cammu_c4_device::cammu_c4_device(const machine_config &mconfig, device_type type
cammu_c3_device::cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cammu_device(mconfig, CAMMU_C3, tag, owner, clock)
- , m_control(CID_C3)
, m_linked{ this }
+ , m_control(CID_C3)
{
}
@@ -210,7 +190,17 @@ void cammu_c3_device::device_start()
save_item(NAME(m_u_pdo));
save_item(NAME(m_fault));
save_item(NAME(m_control));
- save_item(NAME(m_reset));
+
+ for (tlb_set_t &tlb_set : m_tlb)
+ {
+ tlb_set.u = false;
+
+ tlb_set.w.ra = tlb_set.w.va = 0;
+ tlb_set.w.cache = m_memory[ST0].space->cache<2, 0, ENDIANNESS_LITTLE>();
+
+ tlb_set.x.ra = tlb_set.x.va = 0;
+ tlb_set.x.cache = m_memory[ST0].space->cache<2, 0, ENDIANNESS_LITTLE>();
+ }
}
void cammu_c3_device::device_reset()
@@ -218,14 +208,25 @@ void cammu_c3_device::device_reset()
cammu_device::device_reset();
m_control = (m_control & CNTL_CID) | (CNTL_ATE | UST_3 | CNTL_EWIR | CNTL_EWIW | CNTL_EWCW | CNTL_EP);
- m_reset = 0;
}
-void cammu_device::set_spaces(std::vector<address_space *> spaces)
+void cammu_device::set_spaces(address_space &main_space, address_space &io_space, address_space &boot_space)
{
- assert_always(spaces.size() == 8, "exactly 8 address space pointers are required");
+ m_memory[ST0].space = &main_space;
+ m_memory[ST1].space = &main_space;
+ m_memory[ST2].space = &main_space;
+ m_memory[ST3].space = &main_space;
+
+ m_memory[ST4].space = &io_space;
+ m_memory[ST5].space = &boot_space;
+ m_memory[ST6].space = &main_space;
- std::copy(spaces.begin(), spaces.end(), std::begin(m_space));
+ // FIXME: this tag is probably not used, but if it is, need to figure
+ // out how to implement it properly.
+ m_memory[ST7].space = &main_space;
+
+ for (memory_t &memory : m_memory)
+ memory.cache = memory.space->cache<2, 0, ENDIANNESS_LITTLE>();
}
bool cammu_device::memory_translate(const u32 ssw, const int spacenum, const int intention, offs_t &address)
@@ -237,7 +238,7 @@ bool cammu_device::memory_translate(const u32 ssw, const int spacenum, const int
EXECUTE);
// check that the requested space number matches the mapped space
- if (translated.space != nullptr && translated.space->spacenum() == spacenum)
+ if (translated.cache && translated.cache->space().spacenum() == spacenum)
{
address = translated.address;
@@ -257,14 +258,9 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
{
if ((mode == EXECUTE && (virtual_address & 0x1)) || (mode != EXECUTE && virtual_address & (size - 1)))
{
- // FIXME: tlb access is not aligned; this hack lets us ignore for now
- if (mode == EXECUTE || user || (virtual_address & 0xfffff900) != 0x00004800)
- {
- set_fault_address(virtual_address);
- m_exception_func(mode == EXECUTE ? EXCEPTION_I_ALIGNMENT_FAULT : EXCEPTION_D_ALIGNMENT_FAULT);
+ set_fault(virtual_address, mode == EXECUTE ? EXCEPTION_I_ALIGNMENT_FAULT : EXCEPTION_D_ALIGNMENT_FAULT);
- return { nullptr, 0 };
- }
+ return { nullptr, 0 };
}
}
@@ -274,24 +270,24 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
switch (virtual_address & 0x7000)
{
// pages 0-3: main space pages 0-3
- case 0x0000: return { m_space[ST1], virtual_address & 0x3fff };
- case 0x1000: return { m_space[ST2], virtual_address & 0x3fff };
- case 0x2000: return { m_space[ST3], virtual_address & 0x3fff };
- case 0x3000: return { m_space[ST3], virtual_address & 0x3fff };
+ case 0x0000: return { m_memory[ST1].cache, virtual_address & 0x3fff };
+ case 0x1000: return { m_memory[ST2].cache, virtual_address & 0x3fff };
+ case 0x2000: return { m_memory[ST3].cache, virtual_address & 0x3fff };
+ case 0x3000: return { m_memory[ST3].cache, virtual_address & 0x3fff };
// pages 4-5: i/o space pages 0-1
- case 0x4000: return { m_space[ST4], virtual_address & 0x1fff };
- case 0x5000: return { m_space[ST4], virtual_address & 0x1fff };
+ case 0x4000: return { m_memory[ST4].cache, virtual_address & 0x1fff };
+ case 0x5000: return { m_memory[ST4].cache, virtual_address & 0x1fff };
// pages 6-7: boot space pages 0-1
- case 0x6000: return { m_space[ST5], virtual_address & 0x1fff };
- case 0x7000: return { m_space[ST5], virtual_address & 0x1fff };
+ case 0x6000: return { m_memory[ST5].cache, virtual_address & 0x1fff };
+ case 0x7000: return { m_memory[ST5].cache, virtual_address & 0x1fff };
}
}
// if not in mapped mode, use unmapped system tag
if ((ssw & SSW_M) == 0)
- return { m_space[get_ust_space()], virtual_address };
+ return { m_memory[get_ust_space()].cache, virtual_address };
// get the page table entry
pte_t pte = get_pte(virtual_address, user);
@@ -305,8 +301,7 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
mode == EXECUTE ? "instruction" : "data",
virtual_address, ssw, pte.entry, machine().describe_context());
- set_fault_address(virtual_address);
- m_exception_func(mode == EXECUTE ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT);
+ set_fault(virtual_address, mode == EXECUTE ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT);
}
return { nullptr, 0 };
@@ -320,8 +315,7 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
LOGMASKED(LOG_ACCESS, "execute protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
virtual_address, ssw, pte.entry, machine().describe_context());
- set_fault_address(virtual_address);
- m_exception_func(EXCEPTION_I_EXECUTE_PROTECT_FAULT);
+ set_fault(virtual_address, EXCEPTION_I_EXECUTE_PROTECT_FAULT);
return { nullptr, 0 };
}
@@ -331,8 +325,7 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
LOGMASKED(LOG_ACCESS, "read protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
virtual_address, ssw, pte.entry, machine().describe_context());
- set_fault_address(virtual_address);
- m_exception_func(EXCEPTION_D_READ_PROTECT_FAULT);
+ set_fault(virtual_address, EXCEPTION_D_READ_PROTECT_FAULT);
return { nullptr, 0 };
}
@@ -342,8 +335,7 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
LOGMASKED(LOG_ACCESS, "write protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
virtual_address, ssw, pte.entry, machine().describe_context());
- set_fault_address(virtual_address);
- m_exception_func(EXCEPTION_D_WRITE_PROTECT_FAULT);
+ set_fault(virtual_address, EXCEPTION_D_WRITE_PROTECT_FAULT);
return { nullptr, 0 };
}
@@ -351,16 +343,213 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
// set pte referenced and dirty flags
if ((mode & WRITE) && !(pte.entry & PTE_D))
- m_space[ST0]->write_dword(pte.address, pte.entry | PTE_D | PTE_R);
+ m_memory[ST0].cache->write_dword(pte.address, pte.entry | PTE_D | PTE_R);
else if (!(pte.entry & PTE_R))
- m_space[ST0]->write_dword(pte.address, pte.entry | PTE_R);
+ m_memory[ST0].cache->write_dword(pte.address, pte.entry | PTE_R);
// translate the address
LOGMASKED(LOG_DTU, "%s address translated 0x%08x\n", mode == EXECUTE ? "instruction" : "data",
(pte.entry & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK));
// return the system tag and translated address
- return { m_space[system_tag_t((pte.entry & PTE_ST) >> PTE_ST_SHIFT)], (pte.entry & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK) };
+ return { m_memory[(pte.entry & PTE_ST) >> ST_SHIFT].cache, (pte.entry & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK) };
+}
+
+cammu_c3_device::tlb_line_t &cammu_c3_device::tlb_lookup(const bool user, const u32 virtual_address, const access_type mode)
+{
+ const u8 set = (virtual_address >> 12) & 0x3f;
+ tlb_set_t &tlb_set = m_tlb[set];
+
+ // check w compartment
+ if ((tlb_set.w.va & TLB_VA_VA) == (virtual_address & TLB_VA_VA) && (((user && (tlb_set.w.va & TLB_VA_UV)) || (!user && (tlb_set.w.va & TLB_VA_SV)))))
+ {
+ LOGMASKED(LOG_TLB, "tlb_lookup 0x%08x set %2d line W hit 0x%08x\n", virtual_address, set, tlb_set.w.ra);
+
+ // mark x line least recently used
+ tlb_set.u = true;
+
+ return tlb_set.w;
+ }
+
+ // check x compartment
+ if ((tlb_set.x.va & TLB_VA_VA) == (virtual_address & TLB_VA_VA) && (((user && (tlb_set.x.va & TLB_VA_UV))) || (!user && (tlb_set.x.va & TLB_VA_SV))))
+ {
+ LOGMASKED(LOG_TLB, "tlb_lookup 0x%08x set %2d line X hit 0x%08x\n", virtual_address, set, tlb_set.x.ra);
+
+ // mark w line least recently used
+ tlb_set.u = false;
+
+ return tlb_set.x;
+ }
+
+ // return the least recently used line
+ if (tlb_set.u)
+ {
+ LOGMASKED(LOG_TLB, "tlb_lookup 0x%08x set %2d line X miss\n", virtual_address, set);
+
+ tlb_set.u = false;
+ tlb_set.x.ra &= ~TLB_RA_R;
+
+ return tlb_set.x;
+ }
+ else
+ {
+ LOGMASKED(LOG_TLB, "tlb_lookup 0x%08x set %2d line W miss\n", virtual_address, set);
+
+ tlb_set.u = true;
+ tlb_set.w.ra &= ~TLB_RA_R;
+
+ return tlb_set.w;
+ }
+}
+
+cammu_device::translated_t cammu_c3_device::translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode)
+{
+ // get effective user/supervisor mode
+ const bool user = (mode == EXECUTE) ? (ssw & SSW_U) : (ssw & (SSW_U | SSW_UU));
+
+ // check for alignment faults
+ if (!machine().side_effects_disabled() && get_alignment())
+ {
+ if ((mode == EXECUTE && (virtual_address & 0x1)) || (mode != EXECUTE && virtual_address & (size - 1)))
+ {
+ set_fault(virtual_address, mode == EXECUTE ? EXCEPTION_I_ALIGNMENT_FAULT : EXCEPTION_D_ALIGNMENT_FAULT);
+
+ return { nullptr, 0 };
+ }
+ }
+
+ // in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb
+ if (!user && (virtual_address & ~0x7fff) == 0)
+ {
+ switch (virtual_address & 0x7000)
+ {
+ // pages 0-3: main space pages 0-3
+ case 0x0000: return { m_memory[ST1].cache, virtual_address & 0x3fff };
+ case 0x1000: return { m_memory[ST2].cache, virtual_address & 0x3fff };
+ case 0x2000: return { m_memory[ST3].cache, virtual_address & 0x3fff };
+ case 0x3000: return { m_memory[ST3].cache, virtual_address & 0x3fff };
+
+ // pages 4-5: i/o space pages 0-1
+ case 0x4000: return { m_memory[ST4].cache, virtual_address & 0x1fff };
+ case 0x5000: return { m_memory[ST4].cache, virtual_address & 0x1fff };
+
+ // pages 6-7: boot space pages 0-1
+ case 0x6000: return { m_memory[ST5].cache, virtual_address & 0x1fff };
+ case 0x7000: return { m_memory[ST5].cache, virtual_address & 0x1fff };
+ }
+ }
+
+ // if not in mapped mode, use unmapped system tag
+ if ((ssw & SSW_M) == 0)
+ return { m_memory[get_ust_space()].cache, virtual_address };
+
+ // check translation lookaside buffer
+ tlb_line_t &tlbl = tlb_lookup(user, virtual_address, mode);
+
+ pte_t pte = { PTE_F, 0 };
+
+ // handle translation lookaside buffer miss
+ if (!(tlbl.ra & TLB_RA_R))
+ {
+ // get the page table entry
+ pte = get_pte(virtual_address, user);
+
+ // check for page faults
+ if (pte.entry & PTE_F)
+ {
+ if (!machine().side_effects_disabled())
+ {
+ LOG("%s page fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
+ mode == EXECUTE ? "instruction" : "data",
+ virtual_address, ssw, pte.entry, machine().describe_context());
+
+ set_fault(virtual_address, mode == EXECUTE ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT);
+ }
+
+ return { nullptr, 0 };
+ }
+
+ // update tlb line from page table entry
+ // FIXME: not sure if user/supervisor valid follow actual or effective mode?
+ tlbl.va = (virtual_address & TLB_VA_VA) | (user ? TLB_VA_UV : TLB_VA_SV);
+ tlbl.ra = pte.entry;
+ }
+
+ // check protection level
+ if (!machine().side_effects_disabled())
+ {
+ if ((mode == EXECUTE) && !get_access(EXECUTE, tlbl.ra, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "execute protection fault address 0x%08x ssw 0x%08x (%s)\n",
+ virtual_address, ssw, machine().describe_context());
+
+ set_fault(virtual_address, EXCEPTION_I_EXECUTE_PROTECT_FAULT);
+
+ return { nullptr, 0 };
+ }
+ if ((mode & READ) && !get_access(READ, tlbl.ra, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "read protection fault address 0x%08x ssw 0x%08x (%s)\n",
+ virtual_address, ssw, machine().describe_context());
+
+ set_fault(virtual_address, EXCEPTION_D_READ_PROTECT_FAULT);
+
+ return { nullptr, 0 };
+ }
+ if ((mode & WRITE) && !get_access(WRITE, tlbl.ra, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "write protection fault address 0x%08x ssw 0x%08x (%s)\n",
+ virtual_address, ssw, machine().describe_context());
+
+ set_fault(virtual_address, EXCEPTION_D_WRITE_PROTECT_FAULT);
+
+ return { nullptr, 0 };
+ }
+ }
+
+ // update dirty flag
+ if ((mode & WRITE) && !(tlbl.ra & TLB_RA_D))
+ {
+ // fetch the page table entry if needed
+ if (pte.entry & PTE_F)
+ pte = get_pte(virtual_address, user);
+
+ // set page table entry dirty flag
+ if (!(pte.entry & PTE_D))
+ {
+ pte.entry |= PTE_D | PTE_R;
+ m_memory[ST0].cache->write_dword(pte.address, pte.entry);
+ }
+
+ tlbl.ra |= TLB_RA_D | TLB_RA_R;
+ }
+
+ // update referenced flag
+ if (!(tlbl.ra & TLB_RA_R))
+ {
+ // fetch the page table entry if needed
+ if (pte.entry & PTE_F)
+ pte = get_pte(virtual_address, user);
+
+ // set page table entry referenced flag
+ if (!(pte.entry & PTE_R))
+ {
+ pte.entry |= PTE_R;
+ m_memory[ST0].cache->write_dword(pte.address, pte.entry);
+ }
+
+ tlbl.ra |= TLB_RA_R;
+ }
+
+ // return the system tag and translated address
+ LOGMASKED(LOG_DTU, "%s address translated 0x%08x\n", mode == EXECUTE ? "instruction" : "data",
+ (tlbl.ra & TLB_RA_RA) | (virtual_address & CAMMU_PAGE_MASK));
+
+ if (tlbl.ra & 0x800)
+ return { m_memory[(tlbl.ra & TLB_RA_ST) >> ST_SHIFT].cache, (tlbl.ra & TLB_RA_RA) | (virtual_address & CAMMU_PAGE_MASK) };
+ else
+ return { tlbl.cache, (tlbl.ra & TLB_RA_RA) | (virtual_address & CAMMU_PAGE_MASK) };
}
// return the page table entry for a given virtual address
@@ -373,7 +562,7 @@ cammu_device::pte_t cammu_device::get_pte(const u32 va, const bool user)
const u32 ptdi = (va & VA_PTDI) >> 20;
// fetch page table directory entry
- const u32 ptde = m_space[ST0]->read_dword(pdo | ptdi);
+ const u32 ptde = m_memory[ST0].cache->read_dword(pdo | ptdi);
LOGMASKED(LOG_DTU, "get_pte pdo 0x%08x ptdi 0x%08x ptde 0x%08x\n", pdo, ptdi, ptde);
@@ -388,7 +577,7 @@ cammu_device::pte_t cammu_device::get_pte(const u32 va, const bool user)
const u32 pti = (va & VA_PTI) >> 10;
// fetch page table entry
- pte_t pte = { m_space[ST0]->read_dword(pto | pti), pto | pti };
+ pte_t pte = { m_memory[ST0].cache->read_dword(pto | pti), pto | pti };
LOGMASKED(LOG_DTU, "get_pte pto 0x%08x pti 0x%08x pte 0x%08x\n", pto, pti, pte.entry);
@@ -430,3 +619,164 @@ const u8 cammu_c3_device::protection_matrix[4][16] =
{ N, N, RW, RW, RW, R, R, RWE, N, N, RE, RE, N, RE, N, N },
{ N, N, N, RW, R, R, R, RWE, N, N, N, RE, RE, N, RE, N }
};
+
+void cammu_c3_device::reset_w(const u32 data)
+{
+ // translation lookaside buffer reset operations
+ if (data & (RESET_RSV | RESET_RUV | RESET_RD | RESET_RR))
+ {
+ LOGMASKED(LOG_TLB, "reset_w%s%s%s%s (%s)\n",
+ (data & RESET_RSV) ? " RSV" : "",
+ (data & RESET_RUV) ? " RUV" : "",
+ (data & RESET_RD) ? " RD" : "",
+ (data & RESET_RR) ? " RR" : "",
+ machine().describe_context());
+
+ const u32 va_mask = ((data & RESET_RSV) ? TLB_VA_SV : 0) | ((data & RESET_RUV) ? TLB_VA_UV : 0);
+ const u32 ra_mask = ((data & RESET_RD) ? TLB_RA_D : 0) | ((data & RESET_RR) ? TLB_RA_R : 0);
+
+ for (tlb_set_t &tlb_set : m_tlb)
+ {
+ tlb_set.w.va &= ~va_mask;
+ tlb_set.w.ra &= ~ra_mask;
+ tlb_set.x.va &= ~va_mask;
+ tlb_set.x.ra &= ~ra_mask;
+ }
+ }
+}
+
+u32 cammu_c3_device::tlb_r(const u8 address) const
+{
+ const u8 set = address >> 2;
+ u32 result = 0;
+
+ switch (address & 0x3)
+ {
+ case 0x0: result = m_tlb[set].w.ra | (m_tlb[set].u ? TLB_RA_U : 0); break;
+ case 0x1: result = m_tlb[set].w.va; break;
+ case 0x2: result = m_tlb[set].x.ra | (m_tlb[set].u ? TLB_RA_U : 0); break;
+ case 0x3: result = m_tlb[set].x.va; break;
+ }
+
+ LOGMASKED(LOG_TLB, "tlb_r set %2d line %c %s 0x%08x (%s)\n",
+ set, (address & 0x2) ? 'X' : 'W', (address & 0x1) ? "va" : "ra",
+ result, machine().describe_context());
+
+ return result;
+}
+
+void cammu_c3_device::tlb_w(const u8 address, const u32 data)
+{
+ const u32 mem_mask = ~TLB_RA_U;
+ const u8 set = address >> 2;
+
+ LOGMASKED(LOG_TLB, "tlb_w set %2d line %c %s 0x%08x (%s)\n",
+ set, (address & 0x2) ? 'X' : 'W', (address & 0x1) ? "va" : "ra",
+ data, machine().describe_context());
+
+ switch (address & 0x3)
+ {
+ case 0x0: COMBINE_DATA(&m_tlb[set].w.ra); break;
+ case 0x1: COMBINE_DATA(&m_tlb[set].w.va); break;
+ case 0x2: COMBINE_DATA(&m_tlb[set].x.ra); break;
+ case 0x3: COMBINE_DATA(&m_tlb[set].x.va); break;
+ }
+}
+
+u32 cammu_c3_device::cammu_r(const u32 address)
+{
+ switch (address & CAMMU_SELECT)
+ {
+ case CAMMU_D_TLB:
+ return tlb_r(address);
+
+ case CAMMU_D_REG:
+ switch (address & 0xff)
+ {
+ case CAMMU_REG_SPDO: return s_pdo_r();
+ case CAMMU_REG_UPDO: return u_pdo_r();
+ case CAMMU_REG_FAULT: return fault_r();
+ case CAMMU_REG_CONTROL: return control_r();
+ }
+ break;
+
+ case CAMMU_I_TLB:
+ return m_linked[1]->tlb_r(address);
+
+ case CAMMU_I_REG:
+ switch (address & 0xff)
+ {
+ case CAMMU_REG_SPDO: return m_linked[1]->s_pdo_r();
+ case CAMMU_REG_UPDO: return m_linked[1]->u_pdo_r();
+ case CAMMU_REG_FAULT: return m_linked[1]->fault_r();
+ case CAMMU_REG_CONTROL: return m_linked[1]->control_r();
+ }
+ break;
+ }
+
+ LOG("cammu_r unknown address 0x%08x\n", address);
+ return 0;
+}
+
+void cammu_c3_device::cammu_w(const u32 address, const u32 data)
+{
+ switch (address & CAMMU_SELECT)
+ {
+ case CAMMU_D_TLB:
+ tlb_w(address, data);
+ break;
+
+ case CAMMU_D_REG:
+ switch (address & 0xff)
+ {
+ case CAMMU_REG_SPDO: s_pdo_w(data); break;
+ case CAMMU_REG_UPDO: u_pdo_w(data); break;
+ case CAMMU_REG_FAULT: fault_w(data); break;
+ case CAMMU_REG_CONTROL: control_w(data); break;
+ case CAMMU_REG_RESET: reset_w(data); break;
+ default:
+ break;
+ }
+ break;
+
+ case CAMMU_I_TLB:
+ m_linked[1]->tlb_w(address, data);
+ break;
+
+ case CAMMU_I_REG:
+ switch (address & 0xff)
+ {
+ case CAMMU_REG_SPDO: m_linked[1]->s_pdo_w(data); break;
+ case CAMMU_REG_UPDO: m_linked[1]->u_pdo_w(data); break;
+ case CAMMU_REG_FAULT: m_linked[1]->fault_w(data); break;
+ case CAMMU_REG_CONTROL: m_linked[1]->control_w(data); break;
+ case CAMMU_REG_RESET: m_linked[1]->reset_w(data); break;
+ default:
+ break;
+ }
+ break;
+
+ case CAMMU_G_TLB:
+ for (cammu_c3_device *cammu : m_linked)
+ cammu->tlb_w(address, data);
+ break;
+
+ case CAMMU_G_REG:
+ for (cammu_c3_device *cammu : m_linked)
+ switch (address & 0xff)
+ {
+ case CAMMU_REG_SPDO: cammu->s_pdo_w(data); break;
+ case CAMMU_REG_UPDO: cammu->u_pdo_w(data); break;
+ case CAMMU_REG_FAULT: cammu->fault_w(data); break;
+ case CAMMU_REG_CONTROL: cammu->control_w(data); break;
+ case CAMMU_REG_RESET: cammu->reset_w(data); break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ LOG("cammu_w unknown address 0x%08x data 0x%08x\n", address, data);
+ break;
+ }
+}
diff --git a/src/mame/machine/cammu.h b/src/mame/machine/cammu.h
index e852beb4c37..1a600efa6cb 100644
--- a/src/mame/machine/cammu.h
+++ b/src/mame/machine/cammu.h
@@ -8,19 +8,10 @@
#include "cpu/clipper/common.h"
-#define MCFG_CAMMU_ID(_id) \
- downcast<cammu_c4_device &>(*device).set_cammu_id(_id);
-
-#define MCFG_CAMMU_EXCEPTION_CB(_exceptioncb) \
- downcast<cammu_device &>(*device).set_exception_callback(DEVCB_##_exceptioncb);
-
-#define MCFG_CAMMU_LINK(_tag) \
- downcast<cammu_c3_device &>(*device).add_linked(_tag);
-
class cammu_device : public device_t
{
public:
- template <class Object> devcb_base &set_exception_callback(Object &&cb) { return m_exception_func.set_callback(std::forward<Object>(cb)); }
+ auto exception_callback() { return m_exception_func.bind(); }
static const u32 CAMMU_PAGE_SIZE = 0x1000;
static const u32 CAMMU_PAGE_MASK = (CAMMU_PAGE_SIZE - 1);
@@ -51,7 +42,8 @@ public:
PTE_LOCK = 0x00000100 // page lock (software)
};
- static const int PTE_ST_SHIFT = 9;
+ static constexpr int PL_SHIFT = 3;
+ static constexpr int ST_SHIFT = 9;
enum va_mask : u32
{
@@ -72,112 +64,132 @@ public:
ST7 = 7 // slave i/o
};
- virtual void map(address_map &map) = 0;
+ void set_spaces(address_space &main_space, address_space &io_space, address_space &boot_space);
- void set_spaces(std::vector<address_space *> spaces);
+ // translation lookaside buffer and register access
+ virtual u32 cammu_r(const u32 address) = 0;
+ virtual void cammu_w(const u32 address, const u32 data) = 0;
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(T)>>::value, bool> load(const u32 ssw, const u32 address, U &&apply)
{
- translated_t t = translate_address(ssw, address, access_size(sizeof(T)), READ);
-
- if (t.space != nullptr)
+ // check for cammu access
+ if ((ssw & (SSW_UU | SSW_U)) || ((address & ~0x7ff) != 0x00004800))
{
+ translated_t t = translate_address(ssw, address, access_size(sizeof(T)), READ);
+
+ if (!t.cache)
+ return false;
+
switch (sizeof(T))
{
- case 1: apply(T(t.space->read_byte(t.address))); break;
- case 2: apply(T(t.space->read_word(t.address))); break;
- case 4: apply(T(t.space->read_dword(t.address))); break;
- case 8: apply(T(t.space->read_qword(t.address))); break;
- default: fatalerror("unhandled load size %d\n", access_size(sizeof(T)));
+ case 1: apply(T(t.cache->read_byte(t.address))); break;
+ case 2: apply(T(t.cache->read_word(t.address))); break;
+ case 4: apply(T(t.cache->read_dword(t.address))); break;
+ case 8: apply(T(t.cache->read_qword(t.address))); break;
+ default:
+ fatalerror("unhandled load 0x%08x size %d (%s)",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
}
-
- return true;
}
+ else if (sizeof(T) == 4)
+ apply(cammu_r(address));
else
- return false;
+ fatalerror("unhandled cammu load 0x%08x size %d (%s)",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
+
+ return true;
}
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, T>::value, bool> store(const u32 ssw, const u32 address, U data)
{
- translated_t t = translate_address(ssw, address, access_size(sizeof(T)), WRITE);
-
- if (t.space != nullptr)
+ // check for cammu access
+ if ((ssw & (SSW_UU | SSW_U)) || ((address & ~0x7ff) != 0x00004800))
{
+ translated_t t = translate_address(ssw, address, access_size(sizeof(T)), WRITE);
+
+ if (!t.cache)
+ return false;
+
switch (sizeof(T))
{
- case 1: t.space->write_byte(t.address, T(data)); break;
- case 2: t.space->write_word(t.address, T(data)); break;
- case 4: t.space->write_dword(t.address, T(data)); break;
- case 8: t.space->write_qword(t.address, T(data)); break;
- default: fatalerror("unhandled store size %d\n", access_size(sizeof(T)));
+ case 1: t.cache->write_byte(t.address, T(data)); break;
+ case 2: t.cache->write_word(t.address, T(data)); break;
+ case 4: t.cache->write_dword(t.address, T(data)); break;
+ case 8: t.cache->write_qword(t.address, T(data)); break;
+ default:
+ fatalerror("unhandled store 0x%08x size %d (%s)",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
}
-
- return true;
}
+ else if (sizeof(T) == 4)
+ cammu_w(address, data);
else
- return false;
+ fatalerror("unhandled cammu store 0x%08x size %d (%s)",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
+
+ return true;
}
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<T(T)>>::value, bool> modify(const u32 ssw, const u32 address, U &&apply)
{
translated_t t = translate_address(ssw, address, access_size(sizeof(T)), access_type(READ | WRITE));
- if (t.space != nullptr)
- {
- switch (sizeof(T))
- {
- case 4: t.space->write_dword(t.address, apply(T(t.space->read_dword(t.address)))); break;
- default: fatalerror("unhandled modify size %d\n", access_size(sizeof(T)));
- }
+ if (!t.cache)
+ return false;
- return true;
+ switch (sizeof(T))
+ {
+ case 4: t.cache->write_dword(t.address, apply(T(t.cache->read_dword(t.address)))); break;
+ default:
+ fatalerror("unhandled modify 0x%08x size %d (%s)",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
}
- else
- return false;
+
+ return true;
}
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(T)>>::value, bool> fetch(const u32 ssw, const u32 address, U &&apply)
{
translated_t t = translate_address(ssw, address, access_size(sizeof(T)), EXECUTE);
- if (t.space != nullptr)
+ if (!t.cache)
+ return false;
+
+ switch (sizeof(T))
{
- switch (sizeof(T))
+ case 2: apply(T(t.cache->read_word(t.address))); break;
+ case 4:
{
- case 2: apply(T(t.space->read_word(t.address))); break;
- case 4:
+ // check for unaligned access
+ if (address & 0x2)
{
- // check for unaligned access
- if (address & 0x2)
+ // check for page span
+ if ((address & CAMMU_PAGE_MASK) == (CAMMU_PAGE_SIZE - 2))
{
- // check for page span
- if ((address & CAMMU_PAGE_MASK) == (CAMMU_PAGE_SIZE - 2))
+ translated_t u = translate_address(ssw, address + 2, access_size(sizeof(u16)), EXECUTE);
+ if (u.cache)
{
- translated_t u = translate_address(ssw, address + 2, access_size(sizeof(u16)), EXECUTE);
- if (u.space != nullptr)
- {
- const u16 lsw = t.space->read_word(t.address);
- const u16 msw = u.space->read_word(u.address);
-
- apply((T(msw) << 16) | lsw);
- }
- else
- return false;
+ const u16 lsw = t.cache->read_word(t.address);
+ const u16 msw = t.cache->read_word(u.address);
+
+ apply((T(msw) << 16) | lsw);
}
else
- apply(T(t.space->read_dword_unaligned(t.address)));
+ return false;
}
else
- apply(T(t.space->read_dword(t.address)));
+ apply(T(t.cache->read_dword_unaligned(t.address)));
}
- break;
- default: fatalerror("unhandled fetch size %d\n", access_size(sizeof(T)));
+ else
+ apply(T(t.cache->read_dword(t.address)));
}
-
- return true;
+ break;
+ default:
+ fatalerror("unhandled fetch 0x%08x size %d (%s)\n",
+ address, access_size(sizeof(T)), machine().describe_context().c_str());
}
- else
- return false;
+
+ return true;
}
// address translation for debugger
@@ -213,20 +225,26 @@ protected:
RWE = READ | WRITE | EXECUTE,
};
-private:
- // address translation
struct translated_t
{
- address_space *const space;
+ memory_access_cache<2, 0, ENDIANNESS_LITTLE> *const cache;
const u32 address;
};
- translated_t translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode);
struct pte_t
{
- const u32 entry;
- const u32 address;
+ u32 entry;
+ u32 address;
};
+
+ struct memory_t
+ {
+ address_space *space;
+ memory_access_cache<2, 0, ENDIANNESS_LITTLE> *cache;
+ };
+
+ // address translation
+ virtual translated_t translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode);
pte_t get_pte(const u32 va, const bool user);
// helpers
@@ -234,16 +252,21 @@ private:
virtual bool get_alignment() const = 0;
virtual u32 get_pdo(const bool user) const = 0;
virtual system_tag_t get_ust_space() const = 0;
+ virtual void set_fault(const u32 address, const exception_vector type) = 0;
- virtual void set_fault_address(const u32 va) = 0;
-
+ // device state
devcb_write16 m_exception_func;
- address_space *m_space[8];
+ memory_t m_memory[8];
};
class cammu_c4_device : public cammu_device
{
public:
+ // TODO: translation lookaside buffer and register access
+ virtual void map(address_map &map) = 0;
+ virtual u32 cammu_r(const u32 address) override { return 0; }
+ virtual void cammu_w(const u32 address, const u32 data) override {}
+
void set_cammu_id(const u32 cammu_id) { m_control = cammu_id; }
DECLARE_READ32_MEMBER(s_pdo_r) { return m_s_pdo; }
@@ -277,7 +300,7 @@ protected:
virtual bool get_access(const access_type mode, const u32 pte, const u32 ssw) const override;
virtual u32 get_pdo(const bool user) const override { return user ? m_u_pdo : m_s_pdo; }
- virtual void set_fault_address(const u32 va) override { m_fault_address_1 = va; }
+ virtual void set_fault(const u32 address, const exception_vector type) override { m_fault_address_1 = address; m_exception_func(type); }
u32 m_s_pdo;
u32 m_u_pdo;
@@ -484,10 +507,87 @@ class cammu_c3_device : public cammu_device
public:
cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- virtual void map(address_map &map) override;
- virtual void map_global(address_map &map);
+ void add_linked(cammu_c3_device *child) { m_linked.push_back(child); }
- void add_linked(const char *const tag) { m_linked.push_back(downcast<cammu_c3_device *>(siblingdevice(tag))); }
+protected:
+ // device-level overrides
+ virtual void device_reset() override;
+ virtual void device_start() override;
+
+ // translation lookaside buffer and register access
+ virtual u32 cammu_r(const u32 address) override;
+ virtual void cammu_w(const u32 address, const u32 data) override;
+
+ // address translation
+ virtual translated_t translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode) override;
+
+private:
+ enum cammu_address_mask : u32
+ {
+ CAMMU_TLB_VA = 0x00000001, // tlb va/ra select
+ CAMMU_TLB_X = 0x00000002, // tlb x/w line select
+ CAMMU_TLB_SET = 0x000000fc, // tlb set select
+ CAMMU_REG = 0x000000ff, // register select
+ CAMMU_SELECT = 0x00000700, // cammu select
+ };
+ enum tlb_ra_mask : u32
+ {
+ TLB_RA_U = 0x00000001, // used flag
+ TLB_RA_R = 0x00000002, // referenced flag
+ TLB_RA_D = 0x00000004, // dirty flag
+ TLB_RA_PL = 0x00000078, // protection level
+ TLB_RA_ST = 0x00000e00, // system tag
+ TLB_RA_RA = 0xfffff000, // real address
+ };
+ enum tlb_va_mask : u32
+ {
+ TLB_VA_UV = 0x00000002, // user valid flag
+ TLB_VA_SV = 0x00000004, // supervisor valid flag
+ TLB_VA_VA = 0xfffc0000, // virtual address tag
+ };
+
+ /*
+ * The C1/C3 CAMMU has 64-entry, two-way set associative TLB, with lines
+ * grouped into W and X compartments. The associated U flag is set to
+ * indicate that the W line of the set was most recently accessed, and
+ * cleared when the X line was most recently accessed. On TLB miss, the
+ * least recently used line as indicated by this flag is replaced.
+ *
+ * Each line consists of a real address field and a virtual address field.
+ * The real address field format is practically identical to the page table
+ * entry format.
+ */
+ struct tlb_line_t
+ {
+ u32 ra; // real address field
+ u32 va; // virtual address field
+
+ memory_access_cache<2, 0, ENDIANNESS_LITTLE> *cache;
+ };
+ struct tlb_set_t
+ {
+ tlb_line_t w;
+ tlb_line_t x;
+ bool u;
+ };
+
+ enum cammu_select_mask : u32
+ {
+ CAMMU_D_TLB = 0x000, // d-cammu tlb
+ CAMMU_D_REG = 0x100, // d-cammu register
+ CAMMU_I_TLB = 0x200, // i-cammu tlb
+ CAMMU_I_REG = 0x300, // i-cammu register
+ CAMMU_G_TLB = 0x400, // global tlb
+ CAMMU_G_REG = 0x500, // global register
+ };
+ enum cammu_register_mask : u8
+ {
+ CAMMU_REG_SPDO = 0x04, // supervisor pdo register
+ CAMMU_REG_UPDO = 0x08, // user pdo register
+ CAMMU_REG_FAULT = 0x10, // fault register
+ CAMMU_REG_CONTROL = 0x40, // control register
+ CAMMU_REG_RESET = 0x80, // reset register
+ };
enum control_mask : u32
{
@@ -500,59 +600,61 @@ public:
CNTL_ATE = 0x00000200, // alignment trap enable
CNTL_CID = 0xff000000 // cammu id
};
-
- enum ust_mask : u32
+ enum control_ust_mask : u32
{
UST_0 = 0x00000000, // private, write-through, main memory space
UST_1 = 0x00000010, // shared, write-through, main memory space
UST_2 = 0x00000020, // private, copy-back, main memory space
UST_3 = 0x00000030 // noncacheable, main memory space
};
-
enum control_cid_mask : u32
{
CID_C3 = 0x00000000 // unknown
};
- DECLARE_READ32_MEMBER(s_pdo_r) { return m_s_pdo; }
- DECLARE_WRITE32_MEMBER(s_pdo_w) { m_s_pdo = ((m_s_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; }
- DECLARE_READ32_MEMBER(u_pdo_r) { return m_u_pdo; }
- DECLARE_WRITE32_MEMBER(u_pdo_w) { m_u_pdo = ((m_u_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; }
- DECLARE_READ32_MEMBER(fault_r) { return m_fault; }
- DECLARE_WRITE32_MEMBER(fault_w) { m_fault = data; }
- DECLARE_READ32_MEMBER(control_r) { return m_control; }
- DECLARE_WRITE32_MEMBER(control_w) { m_control = ((m_control & (~mem_mask | CNTL_CID)) | (data & (mem_mask & ~CNTL_CID))); }
- DECLARE_READ32_MEMBER(reset_r) { return m_reset; }
- DECLARE_WRITE32_MEMBER(reset_w) { m_reset = data; }
+ enum reset_mask : u32
+ {
+ RESET_RLVW = 0x00000001, // reset all W line LV flags in cache
+ RESET_RLVX = 0x00000002, // reset all X line LV flags in cache
+ RESET_RSV = 0x00000004, // reset all SV flags in tlb
+ RESET_RUV = 0x00000008, // reset all UV flags in tlb
+ RESET_RD = 0x00000010, // reset all D flags in tlb
+ RESET_RR = 0x00000020, // reset all R flags in tlb
+ RESET_RU = 0x00000040, // reset all U flags in cache
+ };
- // global methods - relay to each linked device
- DECLARE_WRITE32_MEMBER(g_s_pdo_w) { for (cammu_c3_device *dev : m_linked) dev->s_pdo_w(space, offset, data, mem_mask); }
- DECLARE_WRITE32_MEMBER(g_u_pdo_w) { for (cammu_c3_device *dev : m_linked) dev->u_pdo_w(space, offset, data, mem_mask); }
- DECLARE_WRITE32_MEMBER(g_fault_w) { for (cammu_c3_device *dev : m_linked) dev->fault_w(space, offset, data, mem_mask); }
- DECLARE_WRITE32_MEMBER(g_control_w) { for (cammu_c3_device *dev : m_linked) dev->control_w(space, offset, data, mem_mask); }
- DECLARE_WRITE32_MEMBER(g_reset_w) { for (cammu_c3_device *dev : m_linked) dev->reset_w(space, offset, data, mem_mask); }
+ u32 tlb_r(const u8 address) const;
+ void tlb_w(const u8 address, const u32 data);
+ tlb_line_t &tlb_lookup(const bool user, const u32 virtual_address, const access_type mode);
-protected:
- virtual void device_reset() override;
- virtual void device_start() override;
+ u32 s_pdo_r() const { return m_s_pdo; }
+ void s_pdo_w(const u32 data) { m_s_pdo = data & PDO_MASK; }
+ u32 u_pdo_r() const { return m_u_pdo; }
+ void u_pdo_w(const u32 data) { m_u_pdo = data & PDO_MASK; }
+ u32 fault_r() const { return m_fault; }
+ void fault_w(const u32 data) { m_fault = data; }
+ u32 control_r() const { return m_control; }
+ void control_w(const u32 data) { m_control = (m_control & CNTL_CID) | (data & ~CNTL_CID); }
+ void reset_w(const u32 data);
- virtual bool get_access(const access_type mode, const u32 pte, const u32 ssw) const override;
virtual bool get_alignment() const override { return m_control & CNTL_ATE; }
- virtual u32 get_pdo(const bool user) const override { return user ? m_u_pdo : m_s_pdo; }
virtual system_tag_t get_ust_space() const override { return system_tag_t((m_control & CNTL_UST) >> 4); }
+ virtual bool get_access(const access_type mode, const u32 pte, const u32 ssw) const override;
+ virtual u32 get_pdo(const bool user) const override { return user ? m_u_pdo : m_s_pdo; }
- virtual void set_fault_address(const u32 va) override { m_fault = va; }
+ virtual void set_fault(const u32 address, const exception_vector type) override { m_fault = address; m_exception_func(type); }
-private:
static const u8 protection_matrix[4][16];
+ // device state
+ std::vector<cammu_c3_device *> m_linked;
+
u32 m_s_pdo;
u32 m_u_pdo;
u32 m_fault;
u32 m_control;
- u32 m_reset;
- std::vector<cammu_c3_device *> m_linked;
+ tlb_set_t m_tlb[64];
};
// device type definitions
diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp
index 95fff249df7..7f59e4dedd1 100644
--- a/src/mame/machine/interpro_ioga.cpp
+++ b/src/mame/machine/interpro_ioga.cpp
@@ -134,7 +134,7 @@ DEFINE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device, "ioga_s", "I/O Gate Arra
interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, m_memory_device(*this, finder_base::DUMMY_TAG)
- , m_memory_space(nullptr)
+ , m_memory(nullptr)
, m_out_nmi_func(*this)
, m_out_irq_func(*this)
, m_out_irq_vector_func(*this)
@@ -170,8 +170,10 @@ void interpro_ioga_device::device_start()
{
// get the memory space
if (!m_memory_device->has_space(m_memory_spacenum))
- throw emu_fatalerror("%s: Device %s (%s) doen't have memory space %d\n", tag(), m_memory_device->device().tag(), m_memory_device->device().name(), m_memory_spacenum);
- m_memory_space = &m_memory_device->space(m_memory_spacenum);
+ fatalerror("%s: device %s (%s) doesn't have memory space %d\n",
+ tag(), m_memory_device->device().tag(), m_memory_device->device().name(), m_memory_spacenum);
+
+ m_memory = m_memory_device->space(m_memory_spacenum).cache<2, 0, ENDIANNESS_LITTLE>();
// resolve callbacks
m_out_nmi_func.resolve();
@@ -695,9 +697,9 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
{
// transfer from the memory to device or device to memory
if (dma_channel.control & DMA_CTRL_WRITE)
- dma_channel.device_w(m_memory_space->read_byte(dma_channel.real_address));
+ dma_channel.device_w(m_memory->read_byte(dma_channel.real_address));
else
- m_memory_space->write_byte(dma_channel.real_address, dma_channel.device_r());
+ m_memory->write_byte(dma_channel.real_address, dma_channel.device_r());
// increment address and decrement count
dma_channel.real_address++;
@@ -711,7 +713,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
// translate virtual address
if (dma_channel.control & DMA_CTRL_VIRTUAL)
{
- const u32 ptde = m_memory_space->read_dword(dma_channel.virtual_address);
+ const u32 ptde = m_memory->read_dword(dma_channel.virtual_address);
dma_channel.virtual_address += 4;
// FIXME: ignore the page fault flag?
@@ -888,7 +890,7 @@ void interpro_ioga_device::dma_w(address_space &space, offs_t offset, u32 data,
// translate virtual address
if (data & DMA_CTRL_VIRTUAL)
{
- const u32 ptde = m_memory_space->read_dword(dma_channel.virtual_address);
+ const u32 ptde = m_memory->read_dword(dma_channel.virtual_address);
dma_channel.virtual_address += 4;
// FIXME: ignore the page fault flag?
@@ -930,7 +932,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::serial_dma)
// TODO: work out which control register bits indicate read from device
if (dma_channel.control & SDMA_SEND)
{
- u8 data = m_memory_space->read_byte(dma_channel.address);
+ u8 data = m_memory->read_byte(dma_channel.address);
LOGMASKED(LOG_SERIALDMA, "dma: transmitting byte 0x%02x to serial channel %d\n",
data, dma_channel.channel);
@@ -944,7 +946,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::serial_dma)
LOGMASKED(LOG_SERIALDMA, "dma: receiving byte 0x%02x from serial channel %d\n",
data, dma_channel.channel);
- m_memory_space->write_byte(dma_channel.address, data);
+ m_memory->write_byte(dma_channel.address, data);
}
// increment address and decrement count
@@ -1301,14 +1303,14 @@ WRITE16_MEMBER(emerald_ioga_device::eth_w)
LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x mask 0x%04x data 0x%04x\n",
address, mem_mask, data);
- m_memory_space->write_word(address, data, mem_mask);
+ m_memory->write_word(address, data, mem_mask);
}
READ16_MEMBER(emerald_ioga_device::eth_r)
{
const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
- const u16 data = m_memory_space->read_word(address, mem_mask);
+ const u16 data = m_memory->read_word(address, mem_mask);
LOGMASKED(LOG_NETWORK, "eth_r 0x%08x mask 0x%04x data 0x%04x\n",
address, mem_mask, data);
@@ -1362,14 +1364,14 @@ WRITE16_MEMBER(turquoise_ioga_device::eth_w)
LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x mask 0x%04x data 0x%04x\n",
address, mem_mask, data);
- m_memory_space->write_word(address, data, mem_mask);
+ m_memory->write_word(address, data, mem_mask);
}
READ16_MEMBER(turquoise_ioga_device::eth_r)
{
const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
- const u16 data = m_memory_space->read_word(address, mem_mask);
+ const u16 data = m_memory->read_word(address, mem_mask);
LOGMASKED(LOG_NETWORK, "eth_r 0x%08x mask 0x%04x data 0x%04x\n",
address, mem_mask, data);
@@ -1450,7 +1452,7 @@ WRITE16_MEMBER(sapphire_ioga_device::eth_w)
LOGMASKED(LOG_NETWORK, "eth_w channel %c address 0x%08x mask 0x%08x data 0x%04x\n",
channel + 'A', address, mem_mask, data);
- m_memory_space->write_word(address, data, mem_mask);
+ m_memory->write_word(address, data, mem_mask);
}
READ16_MEMBER(sapphire_ioga_device::eth_r)
@@ -1469,7 +1471,7 @@ READ16_MEMBER(sapphire_ioga_device::eth_r)
offset << 1, address);
}
- u16 data = m_memory_space->read_word(address, mem_mask);
+ u16 data = m_memory->read_word(address, mem_mask);
LOGMASKED(LOG_NETWORK, "eth_r channel %c address 0x%08x mask 0x%08x data 0x%04x\n",
channel + 'A', address, mem_mask, data);
return data;
diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h
index 8527e3aca18..3be090eb16b 100644
--- a/src/mame/machine/interpro_ioga.h
+++ b/src/mame/machine/interpro_ioga.h
@@ -248,7 +248,7 @@ protected:
required_device<device_memory_interface> m_memory_device;
int m_memory_spacenum;
- address_space *m_memory_space;
+ memory_access_cache<2, 0, ENDIANNESS_LITTLE> *m_memory;
// callbacks
devcb_write_line m_out_nmi_func;
diff --git a/src/mame/machine/interpro_sga.cpp b/src/mame/machine/interpro_sga.cpp
index 7f48abb6631..511e5a5f098 100644
--- a/src/mame/machine/interpro_sga.cpp
+++ b/src/mame/machine/interpro_sga.cpp
@@ -70,14 +70,14 @@ void interpro_sga_device::map(address_map &map)
DEFINE_DEVICE_TYPE(INTERPRO_SGA, interpro_sga_device, "sga", "SRX Gate Array")
interpro_sga_device::interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, INTERPRO_SGA, tag, owner, clock),
- out_berr_func(*this)
+ : device_t(mconfig, INTERPRO_SGA, tag, owner, clock)
+ , m_berr_func(*this)
{
}
void interpro_sga_device::device_start()
{
- out_berr_func.resolve();
+ m_berr_func.resolve();
save_item(NAME(m_gcsr));
save_item(NAME(m_ipoll));
@@ -152,9 +152,9 @@ WRITE32_MEMBER(interpro_sga_device::ddtc1_w)
// error cycle - bit 0x10 indicates source address error (dspad1)
// now expecting 0x5463?
if ((m_dspad1 & 0xfffff000) == 0x40000000)
- out_berr_func(space, 0x5433, m_dspad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x30 | CT(3)
+ m_berr_func(space, 0x5433, m_dspad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x30 | CT(3)
else
- out_berr_func(space, 0x5423, m_ddpad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x20 | CT(3)
+ m_berr_func(space, 0x5423, m_ddpad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x20 | CT(3)
// 0x5423 = BERR|SNAPOK | BG(ICAMMU)? | CT(23)
// 0x5433 = BERR|SNAPOK | BG(ICAMMU)? | CT(33)
diff --git a/src/mame/machine/interpro_sga.h b/src/mame/machine/interpro_sga.h
index c845722eb0e..7023a6b43de 100644
--- a/src/mame/machine/interpro_sga.h
+++ b/src/mame/machine/interpro_sga.h
@@ -6,15 +6,12 @@
#pragma once
-#define MCFG_INTERPRO_SGA_BERR_CB(_out_berr) \
- downcast<interpro_sga_device &>(*device).set_out_berr_callback(DEVCB_##_out_berr);
-
class interpro_sga_device : public device_t
{
public:
interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- template <class Object> devcb_base &set_out_berr_callback(Object &&cb) { return out_berr_func.set_callback(std::forward<Object>(cb)); }
+ auto berr_callback() { return m_berr_func.bind(); }
virtual void map(address_map &map);
@@ -185,7 +182,7 @@ private:
u32 m_dcksum0; // dma 1 device checksum register 0
u32 m_dcksum1; // dma 1 device checksum register 1
- devcb_write32 out_berr_func;
+ devcb_write32 m_berr_func;
};
// device type definition