diff options
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 |
commit | 99efb472772833e1b15c07d9e5d9d9069a53560d (patch) | |
tree | e56cb4bb2abdebb8b1701b7f6b7b2d118765e470 | |
parent | 4bddb07439281403c7d9566bd1223b43bb584eee (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.cpp | 17 | ||||
-rw-r--r-- | src/devices/bus/interpro/keyboard/keyboard.h | 42 | ||||
-rw-r--r-- | src/devices/bus/interpro/mouse/mouse.h | 21 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/edge.cpp | 249 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/edge.h | 97 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/gt.cpp | 67 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/gt.h | 36 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/sr.cpp | 192 | ||||
-rw-r--r-- | src/devices/bus/interpro/sr/sr.h | 317 | ||||
-rw-r--r-- | src/devices/cpu/clipper/clipper.cpp | 269 | ||||
-rw-r--r-- | src/devices/machine/28fxxx.h | 4 | ||||
-rw-r--r-- | src/devices/machine/i82586.h | 6 | ||||
-rw-r--r-- | src/mame/drivers/interpro.cpp | 374 | ||||
-rw-r--r-- | src/mame/includes/interpro.h | 3 | ||||
-rw-r--r-- | src/mame/machine/cammu.cpp | 466 | ||||
-rw-r--r-- | src/mame/machine/cammu.h | 326 | ||||
-rw-r--r-- | src/mame/machine/interpro_ioga.cpp | 32 | ||||
-rw-r--r-- | src/mame/machine/interpro_ioga.h | 2 | ||||
-rw-r--r-- | src/mame/machine/interpro_sga.cpp | 10 | ||||
-rw-r--r-- | src/mame/machine/interpro_sga.h | 7 |
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 |