summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-05-15 21:01:13 +0700
committer Olivier Galibert <galibert@pobox.com>2018-05-15 16:01:13 +0200
commit90dc8100237508469cbd741dd8e3d9787c207878 (patch)
tree41327b9f411be77c15aa7216a2a7de192f91fdae
parent4a0bbac3b5972755e66bfe322fc750e1087075ce (diff)
interpro: wip checkpoint (nw) (#3573)
* softfloat3: do we like this better? (nw) * softfloat3: it gets the hose again (nw) * softfloat3: sonofa (nw) * interpro: wip checkpoint (nw) * added 6x00 models * added EDGE graphics skeleton * split bus/cards into two types * various fixes/changes
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/interpro/sr/edge.cpp774
-rw-r--r--src/devices/bus/interpro/sr/edge.h294
-rw-r--r--src/devices/bus/interpro/sr/gt.cpp357
-rw-r--r--src/devices/bus/interpro/sr/gt.h96
-rw-r--r--src/devices/bus/interpro/sr/sr.cpp166
-rw-r--r--src/devices/bus/interpro/sr/sr.h260
-rw-r--r--src/devices/bus/interpro/sr/sr_cards.cpp20
-rw-r--r--src/devices/bus/interpro/sr/sr_cards.h3
-rw-r--r--src/mame/drivers/interpro.cpp425
-rw-r--r--src/mame/includes/interpro.h36
-rw-r--r--src/mame/machine/interpro_ioga.cpp132
-rw-r--r--src/mame/machine/interpro_ioga.h21
-rw-r--r--src/mame/mame.lst4
14 files changed, 2201 insertions, 389 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index fecb4721bbe..fa21eeb2482 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -3404,6 +3404,8 @@ if (BUSES["INTERPRO_SR"]~=null) then
MAME_DIR .. "src/devices/bus/interpro/sr/sr_cards.h",
MAME_DIR .. "src/devices/bus/interpro/sr/gt.cpp",
MAME_DIR .. "src/devices/bus/interpro/sr/gt.h",
+ MAME_DIR .. "src/devices/bus/interpro/sr/edge.cpp",
+ MAME_DIR .. "src/devices/bus/interpro/sr/edge.h",
}
end
diff --git a/src/devices/bus/interpro/sr/edge.cpp b/src/devices/bus/interpro/sr/edge.cpp
new file mode 100644
index 00000000000..80c8fc6e0f9
--- /dev/null
+++ b/src/devices/bus/interpro/sr/edge.cpp
@@ -0,0 +1,774 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An emulation of Extensible Display Geometry Engine (EDGE) graphics, for
+ * Intergraph InterPro systems.
+ *
+ * TODO
+ * - this is a WIP checkpoint, very little is working
+ * - dumb framebuffer is working in 8bpp mode
+ * - missing dumps for EDGE-2 EPROMs
+ *
+ * List of EDGE graphics cards:
+ *
+ * 004 EDGE-2 Processor f/2 2Mp-FB's
+ * 009 EDGE II Frame Buffer for ImageStation
+ * 030 EDGE-2 Processor f/1 or 2 1Mp-FB's
+ * 031 EDGE-2 Processor f/1 2Mp-FB
+ * 093 EDGE-2 Plus Processor f/1 or 2 1Mp-FB's
+ * 094 EDGE-2 Plus Processor f/1 2Mp-FB
+ * 095 EDGE-2 Plus Processor f/2 2Mp-FB's
+ * 096 EDGE-2 Plus Frame Buffer f/1Mp Monitor
+ * 828 EDGE-1 Graphics f/1 1Mp Monitor (55K/60)
+ * 849 EDGE-1 Graphics f/1 2Mp Monitor (55K/60)
+ * 896 EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60)
+ * 897 EDGE-2 Processor f/1 2Mp-FB
+ * 904 EDGE-1 Graphics f/2 1Mp Monitors (55K/60)
+ * 965 EDGE-1 Graphics f/1 1Mp Monitor (66K/72)
+ * 966 EDGE-1 Graphics f/2 1Mp Monitors (66K/72)
+ * A63 EDGE-2 Frame Buffer f/1Mp Monitor (55K/60)
+ * B15 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) -T
+ * B16 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) -T
+ *
+ * EDGE-1 (PCB828)
+ *
+ * Ref Part Function
+ * U126 TMS320C30GBL DSP
+ * U173 ST D9026 SRX bus interface?
+ * MKJF03WG-00 C
+ * CICD7140A
+ * U214 Z8530H-6JC Keyboard/tablet serial controller
+ * U212 DP8510V Bitblt unit
+ * U229 DP8510V Bitblt unit
+ * U221 Bt 458KG110 RAMDAC
+ * U247 80.0208 MHz crystal Pixel clock source
+ * Y1 30.0 MHz crystal DSP clock source
+ * Y2 4.9152 MHz crystal SCC clock source
+ * TC55417P-25H 16Kx4 static RAM (16 parts, total 128KiB)
+ * Am7202-25RC 1024x9 FIFO (4 parts)
+ * TC524258AZ-10 256Kx4 VRAM (20 parts, total 2560KiB)
+ *
+ * EDGE-2 Plus Processor (SMT094)
+ *
+ * Ref Part Function
+ * U45 Zilog Z0853006VSC SCC Serial controller
+ * U49 Intergraph CICD87307
+ * 202100
+ * U94 NS SCX6B64ABM/NU6
+ * U107 VLSI CICD93708
+ * VGT8203C4588
+ * U132 VLSI CICD93809
+ * 8207C4587
+ * U133 TMS320C30GBL DSP
+ * U134 ST ZDD0J131 SRX bus interface?
+ * MKJF03WG-00 C
+ * CICD7140A
+ * Z104463BA
+ * U191 NS SCX6B86ABN/NU6
+ * U201 TMX320C30GEL40 DSP
+ * U206? MPRGP020A 31 MAR 92 EPROM
+ * U207? MPRGP010A 04 01 92 EPROM
+ * U222 MPRGP060B 16 MAR 92 EPROM
+ * U239 MPRGP050B APR 02 92 EPROM
+ * U306 MPRGP080B APR 02 92 EPROM
+ * U310 MPRGP070B APR 02 92 EPROM
+ * U313 MPRGP040B APR 02 92 EPROM
+ * U303 TMX320C30GEL40 DSP
+ * Y1 4.915200MHz crystal
+ * Y2 66.666700MHz crystal
+ * Y3 33.3333MHz crystal
+ * Y4? 40.0MHz crystal
+ *
+ * EDGE-2 Plus Frame Buffer (PCB896)
+ *
+ * Ref Part Function
+ * U11 CICD87408 TC110G14AY
+ * U336 Brooktree PS045701-165 Single-channel RAMDAC (blue)
+ * U337 Brooktree PS045701-165 Single-channel RAMDAC (green)
+ * U338 Brooktree PS045701-165 Single-channel RAMDAC (red)
+ * U340 Brooktree Bt439KC Clock generator and synchronizer
+ * 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
+ *
+ * Processor board idprom feature byte 0 contains various flags:
+ *
+ * if ((id->i_feature[0] & 0x04) == 0)
+ * EDGctrl.c_flag |= EDGEII_PLUS;
+ *
+ * On the frame buffer:
+ * if (id->i_feature[0] & 3 == 0) EDGE_M2_1MPIX else EDGE_M2_2MPIX
+ */
+
+/*
+ * Work in progress notes (EDGE-2 Plus)
+ *
+ * processor board: 0x8f008000
+ * 000 mouse/interrupt
+ *
+ * 008 mouse X
+ * 00c mouse Y
+ * 010 scc chan B control (tablet)
+ * 014 scc chan A control (keyboard)
+ * 018 scc chan B data (tablet)
+ * 01c scc chan A data (keyboard)
+ *
+ * SRX bus registers
+ * 100 system control
+ * 104 system status
+ * 108 SRX input fifo (W/O)
+ * 10c SRX kernel
+ * 110 SRX mapping (W/O)
+ * 114 SRX attention
+ *
+ * 130 ififo low water mark (W/O)
+ * 134 ififo high water mark (W/O)
+ *
+ * ff80 idprom
+ *
+ * SRX region 4
+ * SRreg4 = 0x90000000 // Emerald uses 0xbf000000-0xffffffff
+ * SRreg4 + 0x02028298 - virtual contrast register
+ * SRreg4 + 0x02028088 - base address/fb enable?
+ * SRreg4 += 0x04000000 // 64M - 32M memory, 32M regs?
+
+ * 0x90000000 256kB static ram (end address 0x9003ffff)
+ * video ram?
+ *
+ * 0x91000000-0x91ffffff == 16 megabytes, probably video ram, where is the remaining 2M?
+ *
+ * 0x92028000
+ * 084 <- 0
+ * 088 base address/fb enable <- 0, 8, 9, a, b (typically reads from 92028300 after writing)?
+ * bottom 2 bits are board select?
+ * 098 <- 0x00ffffff
+ * 0x92028100
+ * 0x92028200 - framebuffer board
+ * 200 idprom
+ * 280 RAMDAC addr reg
+ * 284 RAMDAC CPAL reg - colour palette
+ * 288 RAMDAC ctrl reg
+ * 28c RAMDAC OPAL reg - overlay palette
+ * 290 lookup table select reg
+ * 294 pixel tag LUT context reg
+ * 298 contrast reg
+ *
+ * 0x92028300 - ?
+ * 300 = 1, r/w
+ * 304 read in a loop waiting for value & 0x1000 == 0
+ * 354 = ff
+ *
+ * 0x92028400 - processor board (P-bus?)
+ * 400 P-bus status (maybe shifted attention bits?), 0x1000 == KREG IN FULL
+ * 404 pipeline ctrl/sts
+ * 408 kernel
+ * 40c IFIFO (integer)
+ * 500 SRX master data
+ * 504 SRX master addr
+ * 508 SRX master attn/ctrl
+ * 50c IFIFO (floating point)
+ *
+ * 0x92030000 - unknown at least 256 dwords
+ *
+ * RE - render engine
+ * ILUT - inverse LUT?
+ * ISQLUT - inverse square root LUT
+ *
+ * FIFO 2, FIFO 3, render FIFO
+ * P-bus, S-bus, R-bus
+ * static RAM
+ *
+ * P-bus == TMS320C30 peripheral/primary bus?
+ * C30 has primary (24 bit address) and expansion (13 bit address) bus, both 32 bit data
+ *
+ * peripheral bus is internal (serial and timers)
+ *
+ * sram test at 5a76ec, sub_5a765c, sub_5a76b0(ram size in dwords)
+ * video ram test at sub_5a7ad0
+ * address 5a33de, 5a2dbc
+ */
+
+#include "emu.h"
+#include "edge.h"
+
+#define LOG_GENERAL (1U << 0)
+
+#define VERBOSE (LOG_GENERAL)
+
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(MPCB828, mpcb828_device, "mpcb828", "EDGE-1 Graphics f/1 1Mp Monitor (55K/60)")
+DEFINE_DEVICE_TYPE(MPCB849, mpcb849_device, "mpcb849", "EDGE-1 Graphics f/1 2Mp Monitor (55K/60)")
+DEFINE_DEVICE_TYPE(MPCB030, mpcb030_device, "mpcb030", "EDGE-2 Processor f/1 or 2 1Mp-FB's")
+DEFINE_DEVICE_TYPE(MPCBA63, mpcba63_device, "mpcba63", "EDGE-2 Frame Buffer f/1Mp Monitor (55K/60)")
+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)
+{
+ srx_card_device_base::map(map);
+
+ /*
+ * ODT reports
+ * 000 user 1 mouse/interrupt
+ * 008 user 1 mouse X counter
+ * 00c user 1 mouse Y counter
+ * 020 user 2 mouse/interrupt
+ * 028 user 2 mouse X counter
+ * 02c user 2 mouse Y counter
+ * 100 system control
+ * 104 system status
+ * 108 input FIFO (W/O)
+ * 10c kernel
+ * 110 mapping (W/O)
+ * 114 attention
+ */
+ map(0x000, 0x003).rw(this, FUNC(edge1_device_base::reg0_r), FUNC(edge1_device_base::reg0_w));
+
+ map(0x010, 0x01f).rw("scc", FUNC(z80scc_device::cd_ab_r), FUNC(z80scc_device::cd_ab_w)).umask32(0x000000ff);
+
+ map(0x100, 0x103).rw(this, FUNC(edge1_device_base::control_r), FUNC(edge1_device_base::control_w));
+ map(0x104, 0x107).rw(this, FUNC(edge1_device_base::status_r), FUNC(edge1_device_base::status_w));
+ map(0x108, 0x10b).rw(this, FUNC(edge1_device_base::fifo_r), FUNC(edge1_device_base::fifo_w));
+ map(0x10c, 0x10f).rw(this, FUNC(edge1_device_base::kernel_r), FUNC(edge1_device_base::kernel_w));
+
+ map(0x114, 0x117).rw(this, FUNC(edge1_device_base::attention_r), FUNC(edge1_device_base::attention_w));
+
+ map(0x130, 0x133).w(this, FUNC(edge1_device_base::ififo_lwm_w));
+ map(0x134, 0x137).w(this, FUNC(edge1_device_base::ififo_hwm_w));
+}
+
+void edge1_device_base::map_dynamic(address_map &map)
+{
+ // TODO: map using lambdas until mixed-size submaps work
+ map(0x00000000, 0x0001ffff).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(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(0x02410000, 0x0241000f).m("ramdac", FUNC(bt458_device::map)).umask32(0x000000ff);
+
+ // 0x02400004
+ // 0x02400088
+ // 0x0240008c
+ // 0x02400008
+ // 0x02400098 - contrast
+
+ // 0x02410014
+ // 0x02410018 - ramdac/screen/buffer select?
+ // 0x02410040 - reg0?
+}
+
+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
+ map(0x10c, 0x10f).nopr(); // kreg
+
+ map(0x114, 0x117).nopr(); // status/interrupt
+
+ map(0x130, 0x133).nopr(); // fifo low water mark
+ map(0x134, 0x137).nopr(); // fifo high water mark
+
+ // SRreg4 = 0x90000000
+ // SRreg4 + 0x02028298 - virtual contrast register
+ // SRreg4 + 0x02028088 - base address/fb enable?
+}
+
+void edge2plus_processor_device_base::map(address_map &map)
+{
+ srx_card_device_base::map(map);
+
+ map(0x000, 0x003).rw(this, FUNC(edge2plus_processor_device_base::reg0_r), FUNC(edge2plus_processor_device_base::reg0_w));
+
+ map(0x010, 0x01f).rw("scc", FUNC(z80scc_device::cd_ab_r), FUNC(z80scc_device::cd_ab_w)).umask32(0x000000ff);
+
+ map(0x100, 0x103).rw(this, FUNC(edge2plus_processor_device_base::control_r), FUNC(edge2plus_processor_device_base::control_w));
+ map(0x104, 0x107).rw(this, FUNC(edge2plus_processor_device_base::status_r), FUNC(edge2plus_processor_device_base::status_w));
+
+ map(0x10c, 0x10f).rw(this, FUNC(edge2plus_processor_device_base::kernel_r), FUNC(edge2plus_processor_device_base::kernel_w));
+ map(0x110, 0x113).w(this, FUNC(edge2plus_processor_device_base::mapping_w));
+ map(0x114, 0x117).rw(this, FUNC(edge2plus_processor_device_base::attention_r), FUNC(edge2plus_processor_device_base::attention_w));
+
+ map(0x130, 0x133).w(this, FUNC(edge2plus_processor_device_base::ififo_lwm_w));
+ map(0x134, 0x137).w(this, FUNC(edge2plus_processor_device_base::ififo_hwm_w));
+
+ // 0x300 fifo
+
+
+ // scnxdiag only on II+
+}
+
+// NOTE: at boot, boards 0-3 are selected, and the idprom mirror probed - each valid idprom
+// is identified as being an additional board.
+void edge2plus_framebuffer_device_base::map_dynamic(address_map &map)
+{
+ // TODO: map using lambdas until mixed-size submaps work
+
+ map(0x00000000, 0x0003ffff).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(0x01000000, 0x01ffffff).lrw8("vram",
+ [this](address_space &space, offs_t offset, u8 mem_mask) { return m_vram->read(offset); },
+ [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_vram->write(offset, data); });
+
+ map(0x02028088, 0x0202808b).w(this, FUNC(edge2plus_framebuffer_device_base::select_w));
+
+ map(0x02028200, 0x0202827f).lr32("idprom",
+ [this](address_space &space, offs_t offset, u8 mem_mask) { return m_select == 0 ? memregion("idprom")->as_u32(offset) : space.unmap(); });
+
+ map(0x02028290, 0x02028293).w(this, FUNC(edge2plus_framebuffer_device_base::lut_select_w));
+ map(0x02028300, 0x02028303).w(this, FUNC(edge2plus_framebuffer_device_base::unk_300_w));
+ map(0x02028304, 0x02028307).r(this, FUNC(edge2plus_framebuffer_device_base::unk_304_r));
+}
+
+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)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcb828d.bin", 0x0, 0x20, CRC(997c09f1) SHA1(5378e33ef62309bc0c8cbe9ccbd87fd871bdc195))
+ROM_END
+
+ROM_START(mpcb849)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcb849a.bin", 0x0, 0x20, NO_DUMP)
+ROM_END
+
+ROM_START(mpcb030)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcb030a.bin", 0x0, 0x20, NO_DUMP)
+ROM_END
+
+ROM_START(mpcba63)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcba63b.bin", 0x0, 0x20, NO_DUMP)
+ROM_END
+
+ROM_START(msmt094)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("msmt0940.bin", 0x0, 0x20, CRC(55493b9e) SHA1(6e0668f7e85e1bb5b2ecc6e5a5ab53e5281f22e9))
+ROM_END
+
+ROM_START(mpcb896)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcb896b.bin", 0x0, 0x20, CRC(c8d60037) SHA1(550aab8b0c8d85c9a69fe94ae042b6bb9f9d7db1))
+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
+*
+*/
+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_DEVICE_ADD("sram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("128KiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("vram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("2560KiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("dsp", TMS32030, 1) // 30_MHz_XTAL
+ MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, mpcb828_device, holda))
+
+ MCFG_DEVICE_ADD("ramdac", BT458, 83'020'800)
+
+ MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0)
+ 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))
+MACHINE_CONFIG_END
+
+/*
+ * MPCB849: EDGE-1 graphics, 2 megapixels, single screen, 60Hz refresh.
+ *
+ * System software gives visible pixels 1664x1248. Vertical refresh is assumed to
+ * be 60Hz, horizontal sync ~55kHz.
+ *
+ * Inputs htotal=? (1664+?) and vtotal=? (1248+?) give hsync=?kHz.
+ */
+MACHINE_CONFIG_START(mpcb849_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(164'609'300, 2112, 0, 1664, 1299, 0, 1248)
+ MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb849_device, screen_update)
+ MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank))
+
+ MCFG_DEVICE_ADD("sram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("128KiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("vram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("5120KiB") // guess
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("dsp", TMS32030, 1) // 30_MHz_XTAL
+ MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, mpcb828_device, holda))
+
+ MCFG_DEVICE_ADD("ramdac", BT458, 0) // unconfirmed clock
+
+ MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0)
+ 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))
+MACHINE_CONFIG_END
+
+/*
+ * MPCB030/MPCBA63: EDGE-2 graphics, 1 megapixel, single/dual screen, 60Hz refresh.
+ *
+ * System software gives visible pixels 1184x884. Vertical refresh is assumed to
+ * be 60Hz, horizontal sync ~55kHz.
+ *
+ * Inputs htotal=? (1184+?) and vtotal=? (884+?) give hsync=?kHz.
+ */
+MACHINE_CONFIG_START(mpcb030_device::device_add_mconfig)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(mpcba63_device::device_add_mconfig)
+ //MCFG_SCREEN_ADD("screen", RASTER)
+ // screen params copied from GT
+ //MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + 20, 1184 + 296 + 20, 920, 34, 884 + 34)
+ //MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcba63_device, screen_update)
+ //MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(?, vblank))
+ //MCFG_DEVICE_ADD("ramdac0", BT457, 0) // PS045701-165
+ //MCFG_DEVICE_ADD("ramdac0", BT457, 0)
+ //MCFG_DEVICE_ADD("ramdac0", BT457, 0)
+MACHINE_CONFIG_END
+
+/*
+ * MSMT094/MPCB896: EDGE-2 Plus graphics, 2 megapixels, single screen, 60Hz refresh.
+ *
+ * System software gives visible pixels 1664x1248. Board documentation gives
+ * pixel clock 164.6093MHz. Vertical refresh is assumed to be 60Hz.
+ *
+ * Inputs htotal=2112 (1664+448) and vtotal=1299 (1248+51) give hsync=77.940kHz.
+ */
+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_ADD("dsp2", TMS32030, 40_MHz_XTAL)
+ //MCFG_DEVICE_ADD("dsp3", TMS32030, 40_MHz_XTAL)
+
+ // FIXME: actually Z0853006VSC
+ MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0)
+ 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))
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(mpcb896_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(164'609'300, 2112, 0, 1664, 1299, 0, 1248)
+ MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb896_device, screen_update)
+ MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank))
+
+ MCFG_DEVICE_ADD("sram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("256KiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("vram", RAM, 0)
+ MCFG_RAM_DEFAULT_SIZE("18MiB")
+ MCFG_RAM_DEFAULT_VALUE(0)
+
+ MCFG_DEVICE_ADD("ramdac0", BT457, 164'609'300)
+ MCFG_DEVICE_ADD("ramdac1", BT457, 164'609'300)
+ MCFG_DEVICE_ADD("ramdac2", BT457, 164'609'300)
+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)
+ , m_screen(*this, "screen")
+ , m_sram(*this, "sram")
+ , m_vram(*this, "vram")
+ , m_dsp(*this, "dsp")
+ , m_ramdac(*this, "ramdac")
+ , m_scc(*this, "scc")
+{
+}
+
+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)
+{
+}
+
+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)
+ , m_dsp1(*this, "dsp1")
+ , m_screen(nullptr)
+{
+}
+
+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)
+{
+}
+
+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)
+ , m_screen(*this, "screen")
+ , m_sram(*this, "sram")
+ , m_vram(*this, "vram")
+ , m_ramdac(*this, "ramdac%u", 0U)
+{
+}
+
+mpcb828_device::mpcb828_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge1_device_base(mconfig, MPCB828, tag, owner, clock)
+{
+}
+
+mpcb849_device::mpcb849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge1_device_base(mconfig, MPCB849, tag, owner, clock)
+{
+}
+
+mpcb030_device::mpcb030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge2_processor_device_base(mconfig, MPCB030, tag, owner, clock)
+{
+}
+
+mpcba63_device::mpcba63_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge2_framebuffer_device_base(mconfig, MPCBA63, tag, owner, clock)
+{
+}
+
+msmt094_device::msmt094_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge2plus_processor_device_base(mconfig, MSMT094, tag, owner, clock)
+{
+}
+
+mpcb896_device::mpcb896_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : edge2plus_framebuffer_device_base(mconfig, MPCB896, tag, owner, clock)
+{
+}
+
+const tiny_rom_entry *mpcb828_device::device_rom_region() const
+{
+ return ROM_NAME(mpcb828);
+}
+
+const tiny_rom_entry *mpcb849_device::device_rom_region() const
+{
+ return ROM_NAME(mpcb849);
+}
+
+const tiny_rom_entry *mpcb030_device::device_rom_region() const
+{
+ return ROM_NAME(mpcb030);
+}
+
+const tiny_rom_entry *mpcba63_device::device_rom_region() const
+{
+ return ROM_NAME(mpcba63);
+}
+
+const tiny_rom_entry *msmt094_device::device_rom_region() const
+{
+ return ROM_NAME(msmt094);
+}
+
+const tiny_rom_entry *mpcb896_device::device_rom_region() const
+{
+ return ROM_NAME(mpcb896);
+}
+
+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);
+ }
+
+ // FIXME: dynamically allocate SR region 4
+ m_bus->install_map(*this, 0x90000000, 0x93ffffff, &edge2plus_framebuffer_device_base::map_dynamic);
+}
+
+u32 mpcb849_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ return 0;
+}
+
+u32 mpcba63_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ return 0;
+}
+
+u32 edge1_device_base::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ u8 *pixel_data = m_vram->pointer();
+
+ // 8bpp mode
+ for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
+ for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++)
+ bitmap.pix(y, x) = m_ramdac->pen_color(*pixel_data++);
+
+ return 0;
+}
+
+u32 edge2plus_framebuffer_device_base::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ u8 *pixel_data = m_vram->pointer();
+
+ // 8bpp mode
+ for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
+ for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++)
+ {
+ const u8 index = *pixel_data++;
+
+ bitmap.pix(y, x) = rgb_t(
+ m_ramdac[0]->palette_lookup(index),
+ m_ramdac[1]->palette_lookup(index),
+ m_ramdac[2]->palette_lookup(index));
+ }
+
+ return 0;
+}
+
+WRITE32_MEMBER(edge1_device_base::control_w)
+{
+ COMBINE_DATA(&m_control);
+
+ // release dsp 1 hold
+ if (data & NO_HOLD)
+ m_dsp->set_input_line(TMS3203X_HOLD, CLEAR_LINE);
+
+ // hold dsp 1
+ if (!(data & DSP_1_HOLD_L))
+ m_dsp->set_input_line(TMS3203X_HOLD, ASSERT_LINE);
+}
+
+WRITE_LINE_MEMBER(edge1_device_base::holda)
+{
+ LOG("hold acknowledge %d\n", state);
+
+ if (state)
+ {
+ m_status |= DSP_1_HOLDA_H;
+
+ if (m_control & HOLD_ENB)
+ {
+ m_control |= HOLDA_INT_H;
+
+ irq0(ASSERT_LINE);
+ }
+ }
+ else
+ m_status &= ~DSP_1_HOLDA_H;
+}
+
+WRITE32_MEMBER(edge2plus_processor_device_base::control_w)
+{
+ COMBINE_DATA(&m_control);
+
+ // release dsp 1 hold
+ if (data & NO_HOLD)
+ m_dsp1->set_input_line(TMS3203X_HOLD, CLEAR_LINE);
+
+ // hold dsp 1
+ if (!(data & DSP_1_HOLD_L))
+ m_dsp1->set_input_line(TMS3203X_HOLD, ASSERT_LINE);
+}
+
+WRITE_LINE_MEMBER(edge2plus_processor_device_base::holda)
+{
+ LOG("hold acknowledge %d\n", state);
+
+ if (state)
+ {
+ m_status |= DSP_1_HOLDA_H;
+
+ if (m_control & HOLD_ENB)
+ {
+ m_control |= HOLDA_INT_H;
+ irq0(ASSERT_LINE);
+ }
+ }
+ else
+ m_status &= ~DSP_1_HOLDA_H;
+}
+
+WRITE32_MEMBER(edge2plus_framebuffer_device_base::lut_select_w)
+{
+ LOG("select ramdac %d\n", data);
+
+ 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);
+
+ // lookup table 3 enables address range 92030000-92030fff, written with zeroes
+}
diff --git a/src/devices/bus/interpro/sr/edge.h b/src/devices/bus/interpro/sr/edge.h
new file mode 100644
index 00000000000..f8c73cfced7
--- /dev/null
+++ b/src/devices/bus/interpro/sr/edge.h
@@ -0,0 +1,294 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+#ifndef MAME_BUS_INTERPRO_SR_EDGE_H
+#define MAME_BUS_INTERPRO_SR_EDGE_H
+
+#pragma once
+
+#include "sr.h"
+
+#include "screen.h"
+#include "machine/ram.h"
+#include "cpu/tms32031/tms32031.h"
+#include "video/bt45x.h"
+#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
+{
+public:
+ const char *tag() const { return device_t::tag(); }
+
+ DECLARE_WRITE_LINE_MEMBER(holda);
+
+protected:
+ edge1_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 map_dynamic(address_map &map);
+ virtual void device_start() override;
+
+ 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_READ32_MEMBER(reg0_r) { return ((m_reg0 & ~VBLANK) | (m_screen->vblank() ? VBLANK : 0)); }
+ DECLARE_WRITE32_MEMBER(reg0_w) { COMBINE_DATA(&m_reg0); }
+
+ 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(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_READ32_MEMBER(attention_r) { return m_attention; };
+ DECLARE_WRITE32_MEMBER(attention_w) { COMBINE_DATA(&m_attention); }
+
+ DECLARE_WRITE32_MEMBER(ififo_lwm_w) { COMBINE_DATA(&m_ififo_lwm); }
+ DECLARE_WRITE32_MEMBER(ififo_hwm_w) { COMBINE_DATA(&m_ififo_hwm); }
+
+ required_device<screen_device> m_screen;
+ required_device<ram_device> m_sram;
+ required_device<ram_device> m_vram;
+ required_device<tms3203x_device> m_dsp;
+ required_device<bt458_device> m_ramdac;
+ required_device<z80scc_device> m_scc;
+
+private:
+ u32 m_reg0;
+
+ u32 m_control;
+ u32 m_status;
+ u32 m_fifo;
+ u32 m_kernel;
+ u32 m_attention;
+
+ u32 m_ififo_lwm;
+ u32 m_ififo_hwm;
+};
+
+class edge2_processor_device_base : public device_t, public srx_card_device_base
+{
+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;
+};
+
+class edge2_framebuffer_device_base : public device_t, public srx_card_device_base
+{
+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;
+};
+
+class edge2plus_processor_device_base : public device_t, public srx_card_device_base
+{
+public:
+ const char *tag() const { return device_t::tag(); }
+
+ void register_screen(screen_device *screen) { m_screen = screen; }
+
+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;
+
+ 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_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(mapping_w) { COMBINE_DATA(&m_mapping); }
+ DECLARE_READ32_MEMBER(attention_r) { return m_attention; };
+ DECLARE_WRITE32_MEMBER(attention_w) { COMBINE_DATA(&m_attention); }
+
+ 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_WRITE32_MEMBER(reg0_w) { COMBINE_DATA(&m_reg0); }
+
+ required_device<tms3203x_device> m_dsp1;
+
+private:
+ u32 m_control;
+ u32 m_status;
+ u32 m_attention;
+ u32 m_mapping;
+ u32 m_kernel;
+
+ u32 m_ififo_lwm;
+ u32 m_ififo_hwm;
+
+ u32 m_reg0;
+
+ screen_device *m_screen;
+};
+
+class edge2plus_framebuffer_device_base : public device_t, public srx_card_device_base
+{
+public:
+ const char *tag() const { return device_t::tag(); }
+
+protected:
+ 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;
+ virtual void device_start() override;
+
+ virtual void map_dynamic(address_map &map);
+
+ u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+ DECLARE_WRITE32_MEMBER(lut_select_w);
+
+ DECLARE_WRITE32_MEMBER(unk_300_w) { m_unk_304 = 0x1000; }
+ DECLARE_READ32_MEMBER(unk_304_r) { m_unk_304 ^= 0x1000; return m_unk_304; }
+
+ DECLARE_WRITE32_MEMBER(select_w) { COMBINE_DATA(&m_select); }
+
+ required_device<screen_device> m_screen;
+ required_device<ram_device> m_sram;
+ required_device<ram_device> m_vram;
+ required_device_array<bt457_device, 3> m_ramdac;
+
+private:
+ u32 m_unk_304;
+ u32 m_select;
+};
+
+class mpcb828_device : public edge1_device_base
+{
+public:
+ mpcb828_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class mpcb849_device : public edge1_device_base
+{
+public:
+ mpcb849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+};
+
+class mpcb030_device : public edge2_processor_device_base
+{
+public:
+ mpcb030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msmt094_device : public edge2plus_processor_device_base
+{
+public:
+ msmt094_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class mpcba63_device : public edge2_framebuffer_device_base
+{
+public:
+ mpcba63_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+};
+
+class mpcb896_device : public edge2plus_framebuffer_device_base
+{
+public:
+ mpcb896_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(MPCB828, mpcb828_device)
+DECLARE_DEVICE_TYPE(MPCB849, mpcb849_device)
+DECLARE_DEVICE_TYPE(MPCB030, mpcb030_device)
+DECLARE_DEVICE_TYPE(MPCBA63, mpcba63_device)
+DECLARE_DEVICE_TYPE(MSMT094, msmt094_device)
+DECLARE_DEVICE_TYPE(MPCB896, mpcb896_device)
+
+#endif // MAME_BUS_INTERPRO_SR_EDGE_H
diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp
index d992ef54f02..95fb1c0750c 100644
--- a/src/devices/bus/interpro/sr/gt.cpp
+++ b/src/devices/bus/interpro/sr/gt.cpp
@@ -50,7 +50,6 @@
*/
#include "emu.h"
-#include "screen.h"
#include "gt.h"
@@ -65,9 +64,10 @@
DEFINE_DEVICE_TYPE(MPCB963, mpcb963_device, "mpcb963", "2000 Graphics f/1 1Mp Monitor")
DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Monitors")
-DEFINE_DEVICE_TYPE(MPCB070, mpcb070_device, "mpcb070", "2400 Graphics f/1 1Mp Monitor (V-76)")
-DEFINE_DEVICE_TYPE(MPCB071, mpcb071_device, "mpcb071", "2400 Graphics f/2 1Mp Monitors (V-76)")
-DEFINE_DEVICE_TYPE(MPCB081, mpcb081_device, "mpcb081", "2400 Graphics f/1 2Mp Monitor (V-60/76)")
+DEFINE_DEVICE_TYPE(MSMT070, msmt070_device, "msmt070", "2400 Graphics f/1 1Mp Monitor (V-76)")
+DEFINE_DEVICE_TYPE(MSMT071, msmt071_device, "msmt071", "2400 Graphics f/2 1Mp Monitors (V-76)")
+DEFINE_DEVICE_TYPE(MSMT081, msmt081_device, "msmt081", "2400 Graphics f/1 2Mp Monitor (V-60/76)")
+DEFINE_DEVICE_TYPE(MPCBB92, mpcbb92_device, "mpcbb92", "GT II Graphics f/1 2Mp Monitor (V-60/76)")
void gt_device_base::map(address_map &map)
{
@@ -154,8 +154,6 @@ void gt_device_base::map(address_map &map)
void single_gt_device_base::map(address_map &map)
{
gt_device_base::map(map);
-
- map(0x00000000, 0x0000007f).r(this, FUNC(single_gt_device_base::idprom_r));
map(0x00000080, 0x0000008f).m("ramdac0", FUNC(bt459_device::map)).umask32(0x000000ff);
map(0x00400000, 0x005fffff).rw(this, FUNC(single_gt_device_base::buffer_r), FUNC(single_gt_device_base::buffer_w));
@@ -165,7 +163,6 @@ void dual_gt_device_base::map(address_map &map)
{
gt_device_base::map(map);
- map(0x00000000, 0x0000007f).r(this, FUNC(dual_gt_device_base::idprom_r));
map(0x00000080, 0x0000008f).m("ramdac0", FUNC(bt459_device::map)).umask32(0x000000ff);
map(0x00000090, 0x0000009f).m("ramdac1", FUNC(bt459_device::map)).umask32(0x000000ff);
@@ -182,19 +179,24 @@ ROM_START(mpcba79)
ROM_LOAD32_BYTE("mpcba79a.bin", 0x0, 0x20, CRC(a223fb92) SHA1(6dbd2aa75f1052b2467638e7d6e72c151fe23cfd))
ROM_END
-ROM_START(mpcb070)
+ROM_START(msmt070)
ROM_REGION(0x80, "idprom", 0)
- ROM_LOAD32_BYTE("mpcb070b.bin", 0x0, 0x20, CRC(e0c302d1) SHA1(df2086fbd667605dd2c4a61d48dbcd0a38376e20))
+ ROM_LOAD32_BYTE("msmt070b.bin", 0x0, 0x20, CRC(ad11a4e6) SHA1(e620cd37a1e36d2c548b7783ece336428ec75b0e))
ROM_END
-ROM_START(mpcb071)
+ROM_START(msmt071)
ROM_REGION(0x80, "idprom", 0)
- ROM_LOAD32_BYTE("mpcb071b.bin", 0x0, 0x20, CRC(a9b635d7) SHA1(1b39d98a2f74cfa0a7b430b838412fbc1ade0e5d))
+ ROM_LOAD32_BYTE("msmt071b.bin", 0x0, 0x20, CRC(e46493e0) SHA1(49bd1890cc71dd8a7cbf5e17bf04843d6e075299))
ROM_END
-ROM_START(mpcb081)
+ROM_START(msmt081)
ROM_REGION(0x80, "idprom", 0)
- ROM_LOAD32_BYTE("mpcb081b.bin", 0x0, 0x20, CRC(79cec897) SHA1(ccda82a61c435800b7894a256deea22ea5dc4c87))
+ ROM_LOAD32_BYTE("msmt081b.bin", 0x0, 0x20, CRC(341c6ea0) SHA1(a5da37c3d9e040fc6d9ca99b82a25ed3ce4c57ff))
+ROM_END
+
+ROM_START(mpcbb92)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcbb92a.bin", 0x0, 0x20, CRC(cd7dc552) SHA1(3e34500cb20471db27c0abf657ea26dd0be4361d))
ROM_END
// FIXME: can't account for this delta yet
@@ -205,102 +207,163 @@ ROM_END
// in the cursor diagnostic tests. Visual mouse cursor positioning does seem to
// be correct however, so don't quite understand where the problem is.
-// GT, 60Hz, single 1MPix
+/*
+ * MPCB963: GT graphics, 1 megapixel, single screen, 60Hz refresh.
+ *
+ * System software gives visible pixels 1184x884 and offsets h=296 v=34. Board
+ * documentation gives pixel clock 83.0208MHz. Vertical refresh is assumed to
+ * be 60Hz. Web source gives horizontal sync as 55.2kHz.
+ *
+ * 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_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 296 + GT_X_DELTA, 296 + GT_X_DELTA, GT_XPIXELS + 296 + GT_X_DELTA, GT_YPIXELS + 34, 34, GT_YPIXELS + 34)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0)
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
+ 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)
MACHINE_CONFIG_END
-// GT, 60Hz, dual 1MPix
+// Same as MPCB963, but dual screen.
MACHINE_CONFIG_START(mpcba79_device::device_add_mconfig)
MCFG_SCREEN_ADD("screen0", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 296 + GT_X_DELTA, 296 + GT_X_DELTA, GT_XPIXELS + 296 + GT_X_DELTA, GT_YPIXELS + 34, 34, GT_YPIXELS + 34)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0)
- MCFG_DEVICE_ADD("ramdac0", BT459, 0)
+ 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_SCREEN_ADD("screen1", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 296 + GT_X_DELTA, 296 + GT_X_DELTA, GT_XPIXELS + 296 + GT_X_DELTA, GT_YPIXELS + 34, 34, GT_YPIXELS + 34)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1)
- MCFG_DEVICE_ADD("ramdac1", BT459, 0)
+ 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)
MACHINE_CONFIG_END
-// GT+, 76Hz, single 1MPix
-MACHINE_CONFIG_START(mpcb070_device::device_add_mconfig)
+/*
+ * MSMT070: GT+ graphics, 1 megapixel, single screen, 76Hz refresh.
+ *
+ * System software gives visible pixels 1184x884 and offsets h=264 v=57. Board
+ * documentation gives pixel clock 105.561MHz. Vertical refresh is assumed to
+ * be 76Hz.
+ *
+ * These inputs give htotal=1472 and vtotal=944 with medium confidence, also
+ * giving hsync=71.744kHz and vsync~=75.97Hz.
+ */
+MACHINE_CONFIG_START(msmt070_device::device_add_mconfig)
MCFG_SCREEN_ADD("screen0", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 264 + GT_X_DELTA, 264 + GT_X_DELTA, GT_XPIXELS + 264 + GT_X_DELTA, GT_YPIXELS + 57, 57, GT_YPIXELS + 57)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcb070_device, screen_update0)
+ 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)
MACHINE_CONFIG_END
-// GT+, 76Hz, dual 1MPix
-MACHINE_CONFIG_START(mpcb071_device::device_add_mconfig)
+// Same as MSMT070, but dual screen.
+MACHINE_CONFIG_START(msmt071_device::device_add_mconfig)
MCFG_SCREEN_ADD("screen0", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 264 + GT_X_DELTA, 264 + GT_X_DELTA, GT_XPIXELS + 264 + GT_X_DELTA, GT_YPIXELS + 57, 57, GT_YPIXELS + 57)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcb071_device, screen_update0)
+ 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_SCREEN_ADD("screen1", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS + 264 + GT_X_DELTA, 264 + GT_X_DELTA, GT_XPIXELS + 264 + GT_X_DELTA, GT_YPIXELS + 57, 57, GT_YPIXELS + 57)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcb071_device, screen_update1)
+ 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)
MACHINE_CONFIG_END
-// GT+, 76Hz, single 2MPix
-MACHINE_CONFIG_START(mpcb081_device::device_add_mconfig)
+/*
+* MSMT081: GT+ graphics, 2 megapixel, single screen, 60Hz/76Hz refresh.
+*
+* System software gives visible pixels 1664x1248 and offsets h=391 v=74 (76Hz)
+* and h=407 v=48 (60Hz).
+* Vertical sync is assumed to be 76Hz. Web source gives horizontal sync as
+* 100.8kHz.
+*
+* These inputs give htotal 2076 and vtotal 1324 with low confidence, also
+* giving pixel clock 209.2608MHz and vsync 76.13Hz.
+*/
+MACHINE_CONFIG_START(msmt081_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen0", 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)
+MACHINE_CONFIG_END
+
+/*
+* MPCBB92: GT II graphics (GTDB), 2 megapixel, single screen, 60Hz/76Hz refresh.
+*
+* System software gives visible pixels 1664x1248 and offsets h=391 v=74 (76Hz)
+* and h=407 v=48 (60Hz). Vertical sync is assumed to be 60Hz.
+*
+* These inputs give htotal 2076 and vtotal 1324 with low confidence, also
+* giving pixel clock 209.2608MHz and vsync 76.13Hz.
+*/
+MACHINE_CONFIG_START(mpcbb92_device::device_add_mconfig)
MCFG_SCREEN_ADD("screen0", RASTER)
- MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, 1664 + 391 + GT_X_DELTA, 391 + GT_X_DELTA, 1664 + 391 + GT_X_DELTA, 1248 + 74, 74, 1248 + 74)
- MCFG_SCREEN_UPDATE_DEVICE("", mpcb081_device, screen_update0)
+ 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)
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)
- : sr_card_device_base(mconfig, type, tag, owner, clock)
+ : device_t(mconfig, type, tag, owner, clock)
{
}
single_gt_device_base::single_gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: gt_device_base(mconfig, type, tag, owner, clock)
- , m_screen{ { { *this, "ramdac0" },{ *this, "bpu0" } } }
+ , m_gt{ { { *this, "screen0" },{ *this, "ramdac0" },{ *this, "bpu0" } } }
{
}
dual_gt_device_base::dual_gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: gt_device_base(mconfig, type, tag, owner, clock)
- , m_screen{ { { *this, "ramdac0" },{ *this, "bpu0" } },{ { *this, "ramdac1" },{ *this, "bpu1" } } }
+ , m_gt{ { { *this, "screen0" },{ *this, "ramdac0" },{ *this, "bpu0" } },{ { *this, "screen1" },{ *this, "ramdac1" },{ *this, "bpu1" } } }
{
}
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)
{
}
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)
+{
+}
+
+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)
{
}
-mpcb070_device::mpcb070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : single_gt_device_base(mconfig, MPCB070, tag, owner, clock)
+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)
{
}
-mpcb071_device::mpcb071_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : dual_gt_device_base(mconfig, MPCB071, tag, owner, clock)
+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)
{
}
-mpcb081_device::mpcb081_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : single_gt_device_base(mconfig, MPCB081, tag, owner, clock)
+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)
{
}
@@ -314,66 +377,46 @@ const tiny_rom_entry *mpcba79_device::device_rom_region() const
return ROM_NAME(mpcba79);
}
-const tiny_rom_entry *mpcb070_device::device_rom_region() const
+const tiny_rom_entry *msmt070_device::device_rom_region() const
{
- return ROM_NAME(mpcb070);
+ return ROM_NAME(msmt070);
}
-const tiny_rom_entry *mpcb071_device::device_rom_region() const
+const tiny_rom_entry *msmt071_device::device_rom_region() const
{
- return ROM_NAME(mpcb071);
+ return ROM_NAME(msmt071);
}
-const tiny_rom_entry *mpcb081_device::device_rom_region() const
+const tiny_rom_entry *msmt081_device::device_rom_region() const
{
- return ROM_NAME(mpcb081);
+ return ROM_NAME(msmt081);
}
-void gt_device_base::device_start()
+const tiny_rom_entry *mpcbb92_device::device_rom_region() const
{
- sr_card_device_base::device_start();
+ return ROM_NAME(mpcbb92);
+}
+void gt_device_base::device_start()
+{
save_item(NAME(m_control));
for (int i = 0; i < get_screen_count(); i++)
{
- gt_screen_t &screen = get_screen(i);
+ gt_t &gt = get_gt(i);
// FIXME: handle different buffer sizes
- screen.buffer.reset(new u8[GT_BUFFER_SIZE * 2]);
- screen.mask.reset(new u8[GT_BUFFER_SIZE * 2]);
+ gt.buffer.reset(new u8[GT_BUFFER_SIZE * 2]);
+ gt.mask.reset(new u8[GT_BUFFER_SIZE * 2]);
- save_pointer(screen.buffer.get(), util::string_format("buffer%i", i).c_str(), GT_BUFFER_SIZE * 2);
- save_pointer(screen.mask.get(), util::string_format("mask%i", i).c_str(), GT_BUFFER_SIZE * 2);
+ save_pointer(gt.buffer.get(), util::string_format("buffer%i", i).c_str(), GT_BUFFER_SIZE * 2);
+ save_pointer(gt.mask.get(), util::string_format("mask%i", i).c_str(), GT_BUFFER_SIZE * 2);
}
// allocate timers
m_blit_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt_device_base::blit), this));
m_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt_device_base::line), this));
m_done_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt_device_base::done), this));
-
- // FIXME: 76Hz boards
- m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt_device_base::vblank), this));
-
- // TODO: turn this off for now because it's not right
- //m_vblank_timer->adjust(attotime::from_hz(60), ASSERT_LINE);
-}
-
-TIMER_CALLBACK_MEMBER(gt_device_base::vblank)
-{
- // restart timer
- if (param == ASSERT_LINE)
- {
- m_control |= GFX_VERT_BLNK;
- m_vblank_timer->adjust(attotime::from_msec(5), CLEAR_LINE);
-
- irq(param);
- }
- else
- {
- m_control &= ~GFX_VERT_BLNK;
- m_vblank_timer->adjust(attotime::attotime::from_hz(60), ASSERT_LINE);
- }
}
WRITE32_MEMBER(gt_device_base::control_w)
@@ -386,21 +429,21 @@ WRITE32_MEMBER(gt_device_base::control_w)
// reset the bitblt fifo pointers
for (int i = 0; i < get_screen_count(); i++)
- get_screen(i).bpu->reset();
+ get_gt(i).bpu->reset();
m_done_timer->adjust(attotime::from_msec(10), GFX_GRPHCS_BUSY);
}
// pass direction to bpu
for (int i = 0; i < get_screen_count(); i++)
- get_screen(i).bpu->barrel_input_select((data & GFX_BLIT_DIR) ? ASSERT_LINE : CLEAR_LINE);
+ get_gt(i).bpu->barrel_input_select((data & GFX_BLIT_DIR) ? ASSERT_LINE : CLEAR_LINE);
m_control = data;
}
WRITE32_MEMBER(single_gt_device_base::blit_control_w)
{
- m_screen[0].bpu->control_w(
+ m_gt[0].bpu->control_w(
((data & BLIT0_CONTROL_FS) >> 4) << 12 |
((data & BLIT0_CONTROL_SN) >> 12) << 8 |
((data & BLIT0_CONTROL_LM) >> 20) << 4 |
@@ -410,13 +453,13 @@ WRITE32_MEMBER(single_gt_device_base::blit_control_w)
WRITE32_MEMBER(dual_gt_device_base::blit_control_w)
{
// TODO: find a test case with blits to second screen and verify
- m_screen[0].bpu->control_w(
+ m_gt[0].bpu->control_w(
((data & BLIT0_CONTROL_FS) >> 4) << 12 |
((data & BLIT0_CONTROL_SN) >> 12) << 8 |
((data & BLIT0_CONTROL_LM) >> 20) << 4 |
((data & BLIT0_CONTROL_RM) >> 28) << 0);
- m_screen[1].bpu->control_w(
+ m_gt[1].bpu->control_w(
((data & BLIT1_CONTROL_FS) >> 0) << 12 |
((data & BLIT1_CONTROL_SN) >> 8) << 8 |
((data & BLIT1_CONTROL_LM) >> 16) << 4 |
@@ -464,7 +507,7 @@ WRITE32_MEMBER(gt_device_base::ri_xfer_w)
LOG("ri_xfer_w 0x%08x mem_mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
// initiate ri line draw
- const gt_screen_t &gt_screen = active_screen();
+ const gt_t &gt = active_gt();
int address = m_ri_initial_address;
int error = m_ri_initial_error;
@@ -473,7 +516,7 @@ WRITE32_MEMBER(gt_device_base::ri_xfer_w)
{
// FIXME: how do we know which buffer to write?
if (i || m_control & GFX_DRAW_FIRST)
- write_vram(gt_screen, address, m_plane_data);
+ write_vram(gt, address, m_plane_data);
if (error >= 0)
{
@@ -626,7 +669,7 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
m_control, m_blit_src_address, m_blit_dst_address, m_blit_width,
m_blit_width >> 2, (m_control & GFX_BLIT_DIR) ? "decrementing" : "incrementing");
- const gt_screen_t &screen = active_screen();
+ const gt_t &gt = active_gt();
const int delta = (m_control & GFX_BLIT_DIR) ? -4 : 4;
const int count = m_blit_width >> 2;
@@ -640,36 +683,36 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
{
if (!(m_control & GFX_DATA_SEL))
{
- const u8 *src_data = &screen.buffer[src_address];
- const u8 *src_mask = &screen.mask[src_address];
+ const u8 *src_data = &gt.buffer[src_address];
+ const u8 *src_mask = &gt.mask[src_address];
if (m_control & GFX_MASK_ENA)
- screen.bpu->source_w(HI(
+ gt.bpu->source_w(HI(
src_mask[0] ? m_plane_data : src_data[0],
src_mask[1] ? m_plane_data : src_data[1],
src_mask[2] ? m_plane_data : src_data[2],
src_mask[3] ? m_plane_data : src_data[3]), false);
else
- screen.bpu->source_w(HI(src_data[0], src_data[1], src_data[2], src_data[3]), false);
+ gt.bpu->source_w(HI(src_data[0], src_data[1], src_data[2], src_data[3]), false);
src_address += delta;
}
else
- screen.bpu->source_w(HI(m_plane_data, m_plane_data, m_plane_data, m_plane_data), false);
+ gt.bpu->source_w(HI(m_plane_data, m_plane_data, m_plane_data, m_plane_data), false);
}
// bitblt address loop
for (int word = 0; word < count; word++)
{
// drive left and right mask enables
- screen.bpu->left_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? count - 1 : 0));
- screen.bpu->right_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? 0 : count - 1));
+ gt.bpu->left_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? count - 1 : 0));
+ gt.bpu->right_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? 0 : count - 1));
// load bpu source
if (!(m_control & GFX_DATA_SEL))
{
- const u8 *src_data = &screen.buffer[src_address];
- const u8 *src_mask = &screen.mask[src_address];
+ const u8 *src_data = &gt.buffer[src_address];
+ const u8 *src_mask = &gt.mask[src_address];
LOGMASKED(LOG_BLIT, "blit src data %3d address 0x%08x %02x %02x %02x %02x\n",
word, src_address, src_data[0], src_data[1], src_data[2], src_data[3]);
@@ -679,38 +722,38 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
LOGMASKED(LOG_BLIT, "blit src mask %3d address 0x%08x %02x %02x %02x %02x\n",
word, src_address, src_mask[0], src_mask[1], src_mask[2], src_mask[3]);
- screen.bpu->source_w(HI(
+ gt.bpu->source_w(HI(
src_mask[0] ? m_plane_data : src_data[0],
src_mask[1] ? m_plane_data : src_data[1],
src_mask[2] ? m_plane_data : src_data[2],
src_mask[3] ? m_plane_data : src_data[3]));
}
else
- screen.bpu->source_w(HI(src_data[0], src_data[1], src_data[2], src_data[3]));
+ gt.bpu->source_w(HI(src_data[0], src_data[1], src_data[2], src_data[3]));
src_address += delta;
}
else
- screen.bpu->source_w(HI(m_plane_data, m_plane_data, m_plane_data, m_plane_data));
+ gt.bpu->source_w(HI(m_plane_data, m_plane_data, m_plane_data, m_plane_data));
// load bpu destination
{
- const u8 *dst_data = (m_control & GFX_MASK_SEL) ? &screen.mask[dst_address] : &screen.buffer[dst_address];
+ const u8 *dst_data = (m_control & GFX_MASK_SEL) ? &gt.mask[dst_address] : &gt.buffer[dst_address];
LOGMASKED(LOG_BLIT, "blit dst data %3d address 0x%08x %02x %02x %02x %02x\n",
word, dst_address, dst_data[0], dst_data[1], dst_data[2], dst_data[3]);
- screen.bpu->destination_w(HI(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
+ gt.bpu->destination_w(HI(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
}
// fetch bpu output
- const u16 output = screen.bpu->output_r();
+ const u16 output = gt.bpu->output_r();
if (!(m_control & GFX_MASK_SEL))
{
// write output to pixel ram
- u8 *out_data = &screen.buffer[dst_address];
- const u8 *out_mask = &screen.mask[dst_address];
+ u8 *out_data = &gt.buffer[dst_address];
+ const u8 *out_mask = &gt.mask[dst_address];
if (!(m_control & GFX_MASK_ENA) || out_mask[0] == 0)
out_data[0] = (out_data[0] & ~(0xf0 | m_plane_enable)) | (((output & 0xf000) >> 8) & m_plane_enable);
@@ -724,7 +767,7 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
else
{
// write output to mask ram
- u8 *out_data = &screen.mask[dst_address];
+ u8 *out_data = &gt.mask[dst_address];
out_data[0] = output & 0x8000 ? 0x80 : 0x00;
out_data[1] = output & 0x0800 ? 0x80 : 0x00;
@@ -747,20 +790,20 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
{
if (!(m_control & GFX_DATA_SEL))
{
- const u8 *src_data = &screen.buffer[src_address];
- const u8 *src_mask = &screen.mask[src_address];
+ const u8 *src_data = &gt.buffer[src_address];
+ const u8 *src_mask = &gt.mask[src_address];
if (m_control & GFX_MASK_ENA)
- screen.bpu->source_w(LO(
+ gt.bpu->source_w(LO(
src_mask[0] ? m_plane_data : src_data[0],
src_mask[1] ? m_plane_data : src_data[1],
src_mask[2] ? m_plane_data : src_data[2],
src_mask[3] ? m_plane_data : src_data[3]), false);
else
- screen.bpu->source_w(LO(src_data[0], src_data[1], src_data[2], src_data[3]), false);
+ gt.bpu->source_w(LO(src_data[0], src_data[1], src_data[2], src_data[3]), false);
}
else
- screen.bpu->source_w(LO(m_plane_data, m_plane_data, m_plane_data, m_plane_data), false);
+ gt.bpu->source_w(LO(m_plane_data, m_plane_data, m_plane_data, m_plane_data), false);
src_address += delta;
}
@@ -769,46 +812,46 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
for (int word = 0; word < count; word++)
{
// drive left and right mask enables
- screen.bpu->left_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? count - 1 : 0));
- screen.bpu->right_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? 0 : count - 1));
+ gt.bpu->left_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? count - 1 : 0));
+ gt.bpu->right_mask_enable(word == ((m_control & GFX_BLIT_DIR) ? 0 : count - 1));
// load bpu source
if (!(m_control & GFX_DATA_SEL))
{
- const u8 *src_data = &screen.buffer[src_address];
- const u8 *src_mask = &screen.mask[src_address];
+ const u8 *src_data = &gt.buffer[src_address];
+ const u8 *src_mask = &gt.mask[src_address];
if (m_control & GFX_MASK_ENA)
{
- screen.bpu->source_w(LO(
+ gt.bpu->source_w(LO(
src_mask[0] ? m_plane_data : src_data[0],
src_mask[1] ? m_plane_data : src_data[1],
src_mask[2] ? m_plane_data : src_data[2],
src_mask[3] ? m_plane_data : src_data[3]));
}
else
- screen.bpu->source_w(LO(src_data[0], src_data[1], src_data[2], src_data[3]));
+ gt.bpu->source_w(LO(src_data[0], src_data[1], src_data[2], src_data[3]));
src_address += delta;
}
else
- screen.bpu->source_w(LO(m_plane_data, m_plane_data, m_plane_data, m_plane_data));
+ gt.bpu->source_w(LO(m_plane_data, m_plane_data, m_plane_data, m_plane_data));
// load bpu destination
{
- const u8 *dst_data = (m_control & GFX_MASK_SEL) ? &screen.mask[dst_address] : &screen.buffer[dst_address];
+ const u8 *dst_data = (m_control & GFX_MASK_SEL) ? &gt.mask[dst_address] : &gt.buffer[dst_address];
- screen.bpu->destination_w(LO(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
+ gt.bpu->destination_w(LO(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
}
// fetch bpu output
- const u16 output = screen.bpu->output_r();
+ const u16 output = gt.bpu->output_r();
if (!(m_control & GFX_MASK_SEL))
{
// write output to pixel ram
- u8 *out_data = &screen.buffer[dst_address];
- const u8 *out_mask = &screen.mask[dst_address];
+ u8 *out_data = &gt.buffer[dst_address];
+ const u8 *out_mask = &gt.mask[dst_address];
if (!(m_control & GFX_MASK_ENA) || out_mask[0] == 0)
out_data[0] = (out_data[0] & ~(0x0f | m_plane_enable)) | (((output & 0xf000) >> 12) & m_plane_enable);
@@ -829,8 +872,8 @@ TIMER_CALLBACK_MEMBER(gt_device_base::blit)
}
// clear mask enable lines
- screen.bpu->left_mask_enable(CLEAR_LINE);
- screen.bpu->right_mask_enable(CLEAR_LINE);
+ gt.bpu->left_mask_enable(CLEAR_LINE);
+ gt.bpu->right_mask_enable(CLEAR_LINE);
// complete with delay
if (GT_DIAG)
@@ -882,12 +925,12 @@ WRITE8_MEMBER(gt_device_base::plane_data_w)
}
#define U32(b0,b1,b2,b3) (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | ((b3) << 0))
-u32 gt_device_base::buffer_read(const gt_screen_t &screen, const offs_t offset) const
+u32 gt_device_base::buffer_read(const gt_t &gt, const offs_t offset) const
{
const u32 src_address = offset << 2;
- const u8 *src = &screen.buffer[src_address];
- const u8 *mask = &screen.mask[src_address];
+ const u8 *src = &gt.buffer[src_address];
+ const u8 *mask = &gt.mask[src_address];
if (m_control & GFX_MASK_SEL)
return U32(mask[3], mask[2], mask[1], mask[0]);
@@ -903,7 +946,7 @@ u32 gt_device_base::buffer_read(const gt_screen_t &screen, const offs_t offset)
return U32(src[3], src[2], src[1], src[0]);
}
-void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset, const u32 data, const u32 mask)
+void gt_device_base::buffer_write(const gt_t &gt, const offs_t offset, const u32 data, const u32 mask)
{
const u32 dst_address = offset << 2;
@@ -918,17 +961,17 @@ void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset
if (m_control & GFX_RMW_MD)
{
// read/modify/write mode, use bpu to compute result
- const u8 *dst_data = &screen.buffer[dst_address];
+ const u8 *dst_data = &gt.buffer[dst_address];
- screen.bpu->source_w(HI(out_data[0], out_data[1], out_data[2], out_data[3]));
- screen.bpu->destination_w(HI(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
+ gt.bpu->source_w(HI(out_data[0], out_data[1], out_data[2], out_data[3]));
+ gt.bpu->destination_w(HI(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
- const u16 out_hi = screen.bpu->output_r();
+ const u16 out_hi = gt.bpu->output_r();
- screen.bpu->source_w(LO(out_data[0], out_data[1], out_data[2], out_data[3]));
- screen.bpu->destination_w(LO(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
+ gt.bpu->source_w(LO(out_data[0], out_data[1], out_data[2], out_data[3]));
+ gt.bpu->destination_w(LO(dst_data[0], dst_data[1], dst_data[2], dst_data[3]));
- const u16 out_lo = screen.bpu->output_r();
+ const u16 out_lo = gt.bpu->output_r();
out_data[0] = ((out_hi & 0x000f) << 28 | (out_lo & 0x000f) << 24);
out_data[1] = ((out_hi & 0x00f0) << 16 | (out_lo & 0x00f0) << 12);
@@ -947,7 +990,7 @@ void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset
if (m_control & GFX_MASK_SEL)
{
// write to mask
- u8 *dst_data = &screen.mask[dst_address];
+ u8 *dst_data = &gt.mask[dst_address];
if (out_mask & 0x000000ff) dst_data[0] = out_data[0] & 0x80;
if (out_mask & 0x0000ff00) dst_data[1] = out_data[1] & 0x80;
@@ -957,8 +1000,8 @@ void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset
else if (m_control & GFX_MASK_ENA)
{
// masked write to buffer
- u8 *dst_mask = &screen.mask[dst_address];
- u8 *dst_data = &screen.buffer[dst_address];
+ u8 *dst_mask = &gt.mask[dst_address];
+ u8 *dst_data = &gt.buffer[dst_address];
if ((out_mask & 0x000000ff) && (dst_mask[0] == 0)) dst_data[0] = out_data[0];
if ((out_mask & 0x0000ff00) && (dst_mask[1] == 0)) dst_data[1] = out_data[1];
@@ -968,7 +1011,7 @@ void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset
else
{
// unmasked write to buffer
- u8 *dst_data = &screen.buffer[dst_address];
+ u8 *dst_data = &gt.buffer[dst_address];
if (out_mask & 0x000000ff) dst_data[0] = out_data[0];
if (out_mask & 0x0000ff00) dst_data[1] = out_data[1];
@@ -979,27 +1022,30 @@ void gt_device_base::buffer_write(const gt_screen_t &screen, const offs_t offset
u32 single_gt_device_base::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- const gt_screen_t &gt_screen = m_screen[0];
+ const gt_t &gt = m_gt[0];
- gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN0_DISP_BUF1 ? &gt_screen.buffer[GT_BUFFER_SIZE] : &gt_screen.buffer[0]);
+ gt.ramdac->screen_update(screen, bitmap, cliprect,
+ (m_control & GFX_SCREEN0_DISP_BUF1) ? &gt.buffer[GT_BUFFER_SIZE] : &gt.buffer[0]);
return 0;
}
u32 dual_gt_device_base::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- const gt_screen_t &gt_screen = m_screen[0];
+ const gt_t &gt = m_gt[0];
- gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN0_DISP_BUF1 ? &gt_screen.buffer[GT_BUFFER_SIZE] : &gt_screen.buffer[0]);
+ gt.ramdac->screen_update(screen, bitmap, cliprect,
+ (m_control & GFX_SCREEN0_DISP_BUF1) ? &gt.buffer[GT_BUFFER_SIZE] : &gt.buffer[0]);
return 0;
}
u32 dual_gt_device_base::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- const gt_screen_t &gt_screen = m_screen[1];
+ const gt_t &gt = m_gt[1];
- gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN1_DISP_BUF1 ? &gt_screen.buffer[GT_BUFFER_SIZE] : &gt_screen.buffer[0]);
+ gt.ramdac->screen_update(screen, bitmap, cliprect,
+ (m_control & GFX_SCREEN1_DISP_BUF1) ? &gt.buffer[GT_BUFFER_SIZE] : &gt.buffer[0]);
return 0;
}
@@ -1325,7 +1371,7 @@ bool gt_device_base::kuzmin_clip(s16 x1, s16 y1, s16 x2, s16 y2, s16 clip_xmin,
void gt_device_base::bresenham_line(s16 major, s16 minor, s16 major_step, s16 minor_step, int steps, s16 error, s16 error_major, s16 error_minor, bool shallow)
{
- const gt_screen_t &gt_screen = active_screen();
+ const gt_t &gt = active_gt();
LOG("bresenham_line begin %d,%d steps %d\n", shallow ? major : minor, shallow ? minor : major, steps);
@@ -1333,7 +1379,10 @@ void gt_device_base::bresenham_line(s16 major, s16 minor, s16 major_step, s16 mi
{
// FIXME: which buffer?
if (i || m_control & GFX_DRAW_FIRST)
- write_vram(gt_screen, shallow ? minor * GT_XPIXELS + major : major * GT_XPIXELS + minor, m_plane_data);
+ write_vram(gt, shallow
+ ? minor * gt.screen->visible_area().width() + major
+ : major * gt.screen->visible_area().width() + minor,
+ m_plane_data);
if (error >= 0)
{
@@ -1350,14 +1399,14 @@ void gt_device_base::bresenham_line(s16 major, s16 minor, s16 major_step, s16 mi
}
// TODO: eliminate this function completely when we fully understand the buffer write pipeline.
-void gt_device_base::write_vram(const gt_screen_t &screen, const offs_t offset, const u8 data)
+void gt_device_base::write_vram(const gt_t &gt, const offs_t offset, const u8 data)
{
if (false)
{
const int shift_amount = ((offset & 0x3) << 3);
- buffer_write(screen, offset >> 2, data << shift_amount, 0xff << shift_amount);
+ buffer_write(gt, offset >> 2, data << shift_amount, 0xff << shift_amount);
}
else
- screen.buffer[offset] = data;
+ gt.buffer[offset] = data;
}
diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h
index 6d9098c7043..8215f37c298 100644
--- a/src/devices/bus/interpro/sr/gt.h
+++ b/src/devices/bus/interpro/sr/gt.h
@@ -6,20 +6,18 @@
#pragma once
#include "sr.h"
+#include "screen.h"
#include "video/bt459.h"
#include "video/dp8510.h"
-class gt_device_base : public sr_card_device_base
+class gt_device_base : public device_t
{
protected:
gt_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 map(address_map &map);
public:
- static const u32 GT_PIXCLOCK = 80'000'000; // just a guess
- static const int GT_XPIXELS = 1184;
- static const int GT_YPIXELS = 884;
static const int GT_BUFFER_SIZE = 0x100000; // 1 megabyte
static const u32 GT_BUFFER_MASK = (GT_BUFFER_SIZE - 1);
@@ -56,7 +54,7 @@ public:
GFX_MONSENSE_60HZ = 0x0e000000
};
- DECLARE_READ32_MEMBER(control_r) { return m_control; };
+ DECLARE_READ32_MEMBER(control_r) { return m_control | (get_gt(0).screen->vblank() ? GFX_VERT_BLNK : 0); }
DECLARE_WRITE32_MEMBER(control_w);
DECLARE_READ8_MEMBER(contrast_dac_r) { return m_contrast_dac; }
@@ -176,22 +174,22 @@ protected:
typedef struct
{
+ required_device<screen_device> screen;
required_device<bt459_device> ramdac;
required_device<dp8510_device> bpu;
std::unique_ptr<u8[]> buffer;
std::unique_ptr<u8[]> mask;
}
- gt_screen_t;
+ gt_t;
virtual const int get_screen_count() const = 0;
- virtual gt_screen_t &get_screen(const int number) = 0;
- virtual const gt_screen_t &active_screen() const = 0;
+ virtual gt_t &get_gt(const int number) = 0;
+ virtual const gt_t &active_gt() const = 0;
- u32 buffer_read(const gt_screen_t &screen, const offs_t offset) const;
- void buffer_write(const gt_screen_t &screen, const offs_t offset, const u32 data, const u32 mask);
+ u32 buffer_read(const gt_t &gt, const offs_t offset) const;
+ void buffer_write(const gt_t &gt, const offs_t offset, const u32 data, const u32 mask);
- TIMER_CALLBACK_MEMBER(vblank);
TIMER_CALLBACK_MEMBER(blit);
TIMER_CALLBACK_MEMBER(line);
TIMER_CALLBACK_MEMBER(done);
@@ -200,7 +198,7 @@ protected:
bool kuzmin_clip(s16 sx1, s16 sy1, s16 sx2, s16 sy2, s16 wx1, s16 wy1, s16 wx2, s16 wy2);
void bresenham_line(s16 major, s16 minor, s16 major_step, s16 minor_step, int steps, s16 error, s16 error_major, s16 error_minor, bool shallow);
- void write_vram(const gt_screen_t &screen, const offs_t offset, const u8 data);
+ void write_vram(const gt_t &gt, const offs_t offset, const u8 data);
u8 m_contrast_dac;
@@ -244,7 +242,6 @@ protected:
u32 m_ri_control;
u32 m_ri_xfer;
- emu_timer *m_vblank_timer;
emu_timer *m_blit_timer;
emu_timer *m_line_timer;
emu_timer *m_done_timer;
@@ -259,19 +256,19 @@ protected:
virtual DECLARE_WRITE32_MEMBER(blit_control_w) override;
- DECLARE_READ32_MEMBER(buffer_r) { return buffer_read(m_screen[0], offset); }
- DECLARE_WRITE32_MEMBER(buffer_w) { buffer_write(m_screen[0], offset, data, mem_mask); }
+ DECLARE_READ32_MEMBER(buffer_r) { return buffer_read(m_gt[0], offset); }
+ DECLARE_WRITE32_MEMBER(buffer_w) { buffer_write(m_gt[0], offset, data, mem_mask); }
virtual const int get_screen_count() const override { return GT_SCREEN_COUNT; }
- virtual gt_screen_t &get_screen(const int number) override { return m_screen[number]; }
- virtual const gt_screen_t &active_screen() const override { return m_screen[0]; }
+ virtual gt_t &get_gt(const int number) override { return m_gt[number]; }
+ virtual const gt_t &active_gt() const override { return m_gt[0]; }
u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
private:
static const int GT_SCREEN_COUNT = 1;
- gt_screen_t m_screen[GT_SCREEN_COUNT];
+ gt_t m_gt[GT_SCREEN_COUNT];
};
class dual_gt_device_base : public gt_device_base
@@ -283,12 +280,12 @@ protected:
virtual DECLARE_WRITE32_MEMBER(blit_control_w) override;
- DECLARE_READ32_MEMBER(buffer_r) { return buffer_read(m_screen[(offset & 0x80000) ? 1 : 0], offset); }
- DECLARE_WRITE32_MEMBER(buffer_w) { buffer_write(m_screen[(offset & 0x80000) ? 1 : 0], offset, data, mem_mask); }
+ DECLARE_READ32_MEMBER(buffer_r) { return buffer_read(m_gt[(offset & 0x80000) ? 1 : 0], offset); }
+ DECLARE_WRITE32_MEMBER(buffer_w) { buffer_write(m_gt[(offset & 0x80000) ? 1 : 0], offset, data, mem_mask); }
virtual const int get_screen_count() const override { return GT_SCREEN_COUNT; }
- virtual gt_screen_t &get_screen(const int number) override { return m_screen[number]; }
- virtual const gt_screen_t &active_screen() const override { return m_screen[(m_control & GFX_SCR1_SEL) ? 1 : 0]; }
+ virtual gt_t &get_gt(const int number) override { return m_gt[number]; }
+ virtual const gt_t &active_gt() const override { return m_gt[(m_control & GFX_SCR1_SEL) ? 1 : 0]; }
u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -296,56 +293,84 @@ protected:
private:
static const int GT_SCREEN_COUNT = 2;
- gt_screen_t m_screen[GT_SCREEN_COUNT];
+ gt_t m_gt[GT_SCREEN_COUNT];
};
-class mpcb963_device : public single_gt_device_base
+class mpcb963_device : public single_gt_device_base, public cbus_card_device_base
{
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 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
+class mpcba79_device : public dual_gt_device_base, public cbus_card_device_base
{
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 const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class mpcb070_device : public single_gt_device_base
+class msmt070_device : public single_gt_device_base, public cbus_card_device_base
{
public:
- mpcb070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ 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 const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class mpcb071_device : public dual_gt_device_base
+class msmt071_device : public dual_gt_device_base, public cbus_card_device_base
{
public:
- mpcb071_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ 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 const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
-class mpcb081_device : public single_gt_device_base
+class msmt081_device : public single_gt_device_base, public cbus_card_device_base
{
public:
- mpcb081_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ 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 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
+{
+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 const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
};
@@ -353,8 +378,9 @@ protected:
// device type definition
DECLARE_DEVICE_TYPE(MPCB963, mpcb963_device)
DECLARE_DEVICE_TYPE(MPCBA79, mpcba79_device)
-DECLARE_DEVICE_TYPE(MPCB070, mpcb070_device)
-DECLARE_DEVICE_TYPE(MPCB071, mpcb071_device)
-DECLARE_DEVICE_TYPE(MPCB081, mpcb081_device)
+DECLARE_DEVICE_TYPE(MSMT070, msmt070_device)
+DECLARE_DEVICE_TYPE(MSMT071, msmt071_device)
+DECLARE_DEVICE_TYPE(MSMT081, msmt081_device)
+DECLARE_DEVICE_TYPE(MPCBB92, mpcbb92_device)
#endif // MAME_BUS_INTERPRO_SR_GT_H
diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp
index dda3c7f13b8..bc566911ee3 100644
--- a/src/devices/bus/interpro/sr/sr.cpp
+++ b/src/devices/bus/interpro/sr/sr.cpp
@@ -259,49 +259,52 @@
#define VERBOSE 0
#include "logmacro.h"
-DEFINE_DEVICE_TYPE(SR_SLOT, sr_slot_device, "sr_slot", "InterPro SR bus slot")
+DEFINE_DEVICE_TYPE(CBUS, cbus_device, "cbus", "InterPro CBUS")
+DEFINE_DEVICE_TYPE(CBUS_SLOT, cbus_slot_device, "cbus_slot", "InterPro CBUS slot")
-sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, SR_SLOT, tag, owner, clock)
+DEFINE_DEVICE_TYPE(SRX, srx_device, "srx", "InterPro SRX")
+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_sr_tag(nullptr)
- , m_sr_slot_tag(nullptr)
+ , m_bus_tag(nullptr)
+ , m_slot_tag(nullptr)
{
}
-void sr_slot_device::set_sr_slot(const char *tag, const char *slot_tag)
+void cbus_slot_device::set_tags(const char *bus_tag, const char *slot_tag)
{
- m_sr_tag = tag;
- m_sr_slot_tag = slot_tag;
+ m_bus_tag = bus_tag;
+ m_slot_tag = slot_tag;
}
-void sr_slot_device::device_start()
+void cbus_slot_device::device_start()
{
- device_sr_card_interface *dev = dynamic_cast<device_sr_card_interface *>(get_card_device());
+ device_cbus_card_interface *dev = dynamic_cast<device_cbus_card_interface *>(get_card_device());
if (dev)
- dev->set_sr_tag(m_sr_tag, m_sr_slot_tag);
+ dev->set_tags(m_bus_tag, m_slot_tag);
}
-DEFINE_DEVICE_TYPE(SR, sr_device, "sr", "InterPro SR bus")
-
-sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, SR, tag, owner, clock)
+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 sr_device::set_memory(const char *const tag, const int main_spacenum, const int io_spacenum)
+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 sr_device::device_start()
+void cbus_device::device_start()
{
assert_always(m_memory_tag != nullptr, "memory tag and address spaces must be configured");
@@ -315,52 +318,141 @@ void sr_device::device_start()
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
m_slot_count = 0;
- for (device_sr_card_interface *&slot : m_slot)
+ for (device_cbus_card_interface *&slot : m_slot)
slot = nullptr;
}
-void sr_device::device_reset()
+void cbus_device::device_reset()
{
}
-device_sr_card_interface::device_sr_card_interface(const machine_config &mconfig, device_t &device)
+device_cbus_card_interface::device_cbus_card_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device)
- , m_sr(nullptr)
- , m_sr_tag(nullptr)
- , m_sr_slot_tag(nullptr)
+ , m_bus(nullptr)
+ , m_bus_tag(nullptr)
+ , m_slot_tag(nullptr)
{
}
-device_sr_card_interface::~device_sr_card_interface()
+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);
}
-void device_sr_card_interface::set_sr_device()
+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)
{
- // get a reference to the bus
- m_sr = dynamic_cast<sr_device *>(device().machine().device(m_sr_tag));
+}
- // install the card in the next available slot
- m_sr->install_card(*this, &device_sr_card_interface::map);
+void cbus_card_device_base::map(address_map &map)
+{
+ // 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); });
+}
+
+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)
+{
+}
+
+void srx_slot_device::set_tags(const char *bus_tag, const char *slot_tag)
+{
+ m_bus_tag = bus_tag;
+ m_slot_tag = slot_tag;
+}
+
+void srx_slot_device::device_start()
+{
+ device_srx_card_interface *dev = dynamic_cast<device_srx_card_interface *>(get_card_device());
+
+ if (dev)
+ dev->set_tags(m_bus_tag, m_slot_tag);
+}
+
+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)
+{
+}
+
+void srx_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 srx_device::device_start()
+{
+ 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()
+{
+}
+
+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)
+{
}
-void device_sr_card_interface::irq(int state)
+void device_srx_card_interface::set_bus_device()
{
- // FIXME: hard-wire to irq0 for now
- m_sr->irq0_w(state);
+ // 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);
}
-sr_card_device_base::sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region)
- : device_t(mconfig, type, tag, owner, clock)
- , device_sr_card_interface(mconfig, *this)
+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 sr_card_device_base::device_start()
+void srx_card_device_base::map(address_map &map)
{
- set_sr_device();
+ // 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); });
}
diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h
index 9be58c9ac12..cf987dc19e7 100644
--- a/src/devices/bus/interpro/sr/sr.h
+++ b/src/devices/bus/interpro/sr/sr.h
@@ -6,69 +6,92 @@
#pragma once
-#define MCFG_SR_OUT_IRQ0_CB(_devcb) \
- devcb = &downcast<sr_device &>(*device).set_out_irq0_callback(DEVCB_##_devcb);
+#define MCFG_CBUS_OUT_IRQ0_CB(_devcb) \
+ devcb = &downcast<cbus_device &>(*device).set_out_irq0_callback(DEVCB_##_devcb);
-#define MCFG_SR_OUT_IRQ1_CB(_devcb) \
- devcb = &downcast<sr_device &>(*device).set_out_irq1_callback(DEVCB_##_devcb);
+#define MCFG_CBUS_OUT_IRQ1_CB(_devcb) \
+ devcb = &downcast<cbus_device &>(*device).set_out_irq1_callback(DEVCB_##_devcb);
-#define MCFG_SR_OUT_IRQ2_CB(_devcb) \
- devcb = &downcast<sr_device &>(*device).set_out_irq2_callback(DEVCB_##_devcb);
+#define MCFG_CBUS_OUT_IRQ2_CB(_devcb) \
+ devcb = &downcast<cbus_device &>(*device).set_out_irq2_callback(DEVCB_##_devcb);
-#define MCFG_SR_SLOT_ADD(_srtag, _tag, _slot_intf, _def_slot, _fixed) \
- MCFG_DEVICE_ADD(_tag, SR_SLOT, 0) \
+#define MCFG_CBUS_OUT_VBLANK_CB(_devcb) \
+ 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<sr_slot_device &>(*device).set_sr_slot(_srtag, _tag);
+ 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) \
+ devcb = &downcast<srx_device &>(*device).set_out_irq0_callback(DEVCB_##_devcb);
+
+#define MCFG_SRX_OUT_IRQ1_CB(_devcb) \
+ devcb = &downcast<srx_device &>(*device).set_out_irq1_callback(DEVCB_##_devcb);
+
+#define MCFG_SRX_OUT_IRQ2_CB(_devcb) \
+ devcb = &downcast<srx_device &>(*device).set_out_irq2_callback(DEVCB_##_devcb);
+
+#define MCFG_SRX_OUT_VBLANK_CB(_devcb) \
+ devcb = &downcast<srx_device &>(*device).set_out_vblank_callback(DEVCB_##_devcb);
-#define MCFG_SR_SLOT_REMOVE(_tag) \
- MCFG_DEVICE_REMOVE(_tag)
+#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_SR_MEMORY(_tag, _main_spacenum, _io_spacenum) \
- downcast<sr_device &>(*device).set_memory(_tag, _main_spacenum, _io_spacenum);
+#define MCFG_SRX_MEMORY(_tag, _main_spacenum, _io_spacenum) \
+ downcast<srx_device &>(*device).set_memory(_tag, _main_spacenum, _io_spacenum);
-class sr_slot_device : public device_t, public device_slot_interface
+class cbus_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
- sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ cbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// inline configuration
- void set_sr_slot(const char *tag, const char *slot_tag);
+ void set_tags(const char *bus_tag, const char *slot_tag);
protected:
- sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ cbus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device-level overrides
virtual void device_start() override;
// configuration
- const char *m_sr_tag;
- const char *m_sr_slot_tag;
+ const char *m_bus_tag;
+ const char *m_slot_tag;
};
-class device_sr_card_interface;
+class device_cbus_card_interface;
-class sr_device : public device_t
+class cbus_device : public device_t
{
public:
// construction/destruction
- sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ 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);
- static const u32 SR_BASE = 0x87000000;
- static const u32 SR_SIZE = 0x08000000;
- static const int SR_COUNT = 16;
+ static const u32 CBUS_BASE = 0x87000000;
+ static const u32 CBUS_SIZE = 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))
@@ -77,8 +100,8 @@ public:
m_slot[m_slot_count] = &device;
// compute slot base address
- offs_t start = SR_BASE + m_slot_count * SR_SIZE;
- offs_t end = start + (SR_SIZE - 1);
+ offs_t start = CBUS_BASE + m_slot_count * CBUS_SIZE;
+ offs_t end = start + (CBUS_SIZE - 1);
// install the device address map
m_main_space->install_device(start, end, device, map);
@@ -88,7 +111,7 @@ public:
}
protected:
- sr_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ 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;
@@ -101,9 +124,10 @@ protected:
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_sr_card_interface *m_slot[SR_COUNT];
+ device_cbus_card_interface *m_slot[CBUS_COUNT];
int m_slot_count;
const char *m_memory_tag;
@@ -111,45 +135,191 @@ private:
int m_io_spacenum;
};
-class device_sr_card_interface : public device_slot_card_interface
+class device_cbus_card_interface : public device_slot_card_interface
{
public:
- // construction/destruction
- virtual ~device_sr_card_interface();
-
- void set_sr_device();
- void irq(int state);
+ void set_bus_device();
// inline configuration
- void set_sr_tag(const char *tag, const char *slot_tag) { m_sr_tag = tag; m_sr_slot_tag = slot_tag; }
+ 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); }
protected:
- device_sr_card_interface(const machine_config &mconfig, device_t &device);
+ device_cbus_card_interface(const machine_config &mconfig, device_t &device);
virtual void map(address_map &map) = 0;
- sr_device *m_sr;
- const char *m_sr_tag;
- const char *m_sr_slot_tag;
+ cbus_device *m_bus;
+ const char *m_bus_tag;
+ const char *m_slot_tag;
};
-class sr_card_device_base : public device_t, public device_sr_card_interface
+class cbus_card_device_base : public device_cbus_card_interface
{
protected:
- sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region = "idprom");
+ cbus_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom");
+
+public:
+ const char *tag() { return device().tag(); }
+
+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:
- READ32_MEMBER(idprom_r) { return device().memregion(m_idprom_region)->as_u32(offset); }
+ // 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);
protected:
+ srx_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
// device-level overrides
virtual void device_start() override;
+ // configuration
+ const char *m_bus_tag;
+ const char *m_slot_tag;
+};
+
+class device_srx_card_interface;
+
+class srx_device : public device_t
+{
+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);
+
+ 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))
+ {
+ // record the device in the next free slot
+ m_slot[m_slot_count] = &device;
+
+ // compute slot base address
+ offs_t start = SRX_BASE + m_slot_count * SRX_SIZE;
+ offs_t end = start + (SRX_SIZE - 1);
+
+ // install the device address map
+ m_main_space->install_device(start, end, device, map);
+ m_io_space->install_device(start, end, device, map);
+
+ m_slot_count++;
+ }
+
+ template <typename T> T *get_card()
+ {
+ for (auto device : m_slot)
+ if (dynamic_cast<T *>(device) != nullptr)
+ return dynamic_cast<T *>(device);
+
+ return nullptr;
+ }
+
+ template <typename T> void install_map(T &device, offs_t start, offs_t end, void (T::*map)(address_map &map))
+ {
+ // install the device address map
+ m_main_space->install_device(start, end, device, map);
+ 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
+{
+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); }
+
+protected:
+ device_srx_card_interface(const machine_config &mconfig, device_t &device);
+
+ virtual void map(address_map &map) = 0;
+
+ srx_device *m_bus;
+ const char *m_bus_tag;
+ const char *m_slot_tag;
+};
+
+class srx_card_device_base : public device_srx_card_interface
+{
+protected:
+ srx_card_device_base(const machine_config &mconfig, device_t &device, const char *idprom_region = "idprom");
+
+public:
+ const char *tag() { return device().tag(); }
+
+protected:
+ virtual void map(address_map &map) override;
+
private:
const char *const m_idprom_region;
};
-DECLARE_DEVICE_TYPE(SR, sr_device)
-DECLARE_DEVICE_TYPE(SR_SLOT, sr_slot_device)
+DECLARE_DEVICE_TYPE(CBUS, cbus_device)
+DECLARE_DEVICE_TYPE(CBUS_SLOT, cbus_slot_device)
+DECLARE_DEVICE_TYPE(SRX, srx_device)
+DECLARE_DEVICE_TYPE(SRX_SLOT, srx_slot_device)
#endif // MAME_BUS_INTERPRO_SR_SR_H
diff --git a/src/devices/bus/interpro/sr/sr_cards.cpp b/src/devices/bus/interpro/sr/sr_cards.cpp
index 73a94821ad8..b87ade908f8 100644
--- a/src/devices/bus/interpro/sr/sr_cards.cpp
+++ b/src/devices/bus/interpro/sr/sr_cards.cpp
@@ -6,6 +6,7 @@
// video
#include "gt.h"
+#include "edge.h"
// storage
@@ -18,11 +19,22 @@
// other
-void sr_cards(device_slot_interface &device)
+void cbus_cards(device_slot_interface &device)
{
device.option_add("mpcb963", MPCB963);
device.option_add("mpcba79", MPCBA79);
- device.option_add("mpcb070", MPCB070);
- device.option_add("mpcb071", MPCB071);
- device.option_add("mpcb081", MPCB081);
+ device.option_add("msmt070", MSMT070);
+ device.option_add("msmt071", MSMT071);
+ device.option_add("msmt081", MSMT081);
+}
+
+void srx_cards(device_slot_interface &device)
+{
+ device.option_add("mpcb030", MPCB030);
+ device.option_add("mpcb828", MPCB828);
+ device.option_add("mpcb849", MPCB849);
+ device.option_add("mpcb896", MPCB896);
+ device.option_add("mpcba63", MPCBA63);
+ device.option_add("mpcbb92", MPCBB92);
+ device.option_add("msmt094", MSMT094);
}
diff --git a/src/devices/bus/interpro/sr/sr_cards.h b/src/devices/bus/interpro/sr/sr_cards.h
index f06c1d4e307..0244b3c3648 100644
--- a/src/devices/bus/interpro/sr/sr_cards.h
+++ b/src/devices/bus/interpro/sr/sr_cards.h
@@ -7,6 +7,7 @@
#pragma once
// supported devices
-void sr_cards(device_slot_interface &device);
+void cbus_cards(device_slot_interface &device);
+void srx_cards(device_slot_interface &device);
#endif // MAME_BUS_INTERPRO_SR_SR_CARDS_H
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index e334103260b..56c12ef53f2 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -61,12 +61,11 @@
*
* 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 bus is referred to as SR, SRX, SR Bus, CBUS and some
- * combinations of these in various places, but all appear to be compatible or
- * identical, possibly with SRX being an enhanced version. The bus supported a
- * range of add-in cards, ranging from expanded SCSI and serial controllers,
- * to specialised scanning and plotting controllers, a VME bridge, and most
- * importantly various single and dual-headed graphics boards.
+ * 6xxx systems. The 2xxx bus is referred to as CBUS, with the 6xxx bus known
+ * as SRX bus; SR (shared resource) bus is used to refer to either type. The
+ * bus supported a range of add-in cards, ranging from expanded SCSI and serial
+ * controllers, to specialised scanning and plotting controllers, a VME bridge,
+ * and most importantly various single and dual-headed graphics boards.
*
* The InterPro graphics options included the GT range, generally fitted to the
* desktops, and EDGE graphics for the 6xxx systems. Systems with no graphics
@@ -87,13 +86,14 @@
* GT graphics are also referred to in various places as Memory Mapped Graphics
* or MMG. EDGE stands for Extensible Display Geometry Engine.
*
- * This emulation currently supports the Turquoise and Sapphire desktop systems (i.e. models
- * 2000/2400/2500/2700/2800). Base GT graphics can be used with any of these models, or the
- * graphics and keyboard removed and the systems used with a serial terminal instead.
+ * This driver currently supports the Emerald, Turquoise and Sapphire systems
+ * (i.e. 2x00 and 6x00 models), but not all of the variants of the Emerald at
+ * this point. GT/GTDB or EDGE graphics can be used depending on model, or
+ * graphics and keyboard uninstalled and a serial terminal used instead.
*
* Key parts lists for the supported models are as follows.
*
- * 2000 Turquoise (C300 @ 50MHz?, main board PCB962)
+ * 2000 Turquoise (PCB962 rev A, PCB824 rev J)
*
* Ref Part Function
* U37 Intel 82072 Floppy drive controller
@@ -112,7 +112,7 @@
* U171 128 kB EPROM (MPRGM530E) Boot ROM MSB
* U172 128 kB EPROM (MPRGM540E) Boot ROM LSB
*
- * 2400 Sapphire (C400T @ 40MHz?, main board SMT047)
+ * 2400 Sapphire (SMT047 rev 0, SMT038?)
*
* Ref Part Function
* U31 Zilog Z85C30 SCC Keyboard and console serial controller
@@ -138,7 +138,7 @@
* U118? (MPRG X510R)
* U155 CYID21704 TC140G54AF
*
- * 2700 Sapphire (C400I @ 70MHz?, main board SMT128)
+ * 2700 Sapphire (SMT128 rev 0, SMT104 rev A)
*
* Ref Part Function
* U31 Zilog Z85C30 SCC Keyboard and console serial controller
@@ -149,7 +149,7 @@
* U44 Intel 82596SX-20 Ethernet controller
* U68 CYID21603 TC150G89AF
* U67 Intel N28F010 128Kx8 flash memory (Y226 0C30 4291)
- * U71 LSI L1A7374 CIDC094A3 Intergraph I/O gate array
+ * U71 LSI L1A7374 CICD094A3 Intergraph I/O gate array
* U76 Intel N28F010 128Kx8 flash memory (Y225 0C30 4220)
* U81 NCR 53C94 SCSI controller
* U86 24.0 MHz crystal Clock source for 82077
@@ -164,14 +164,60 @@
* U118? ()
* U155 CYID212?4 TC140G54AF?
*
+ * 6000 (PCB765 rev B, PCB82409 rev D)
+ *
+ * Ref Part Function
+ * U264 Xilinx XC3020-50 Plotter control FPGA?
+ * U294 4.9152 MHz crystal
+ * U287 Z8530H-6JC Serial controller
+ * U288 Z8530H-6JC Serial controller
+ * U318 24.0 MHz crystal
+ * U323 20.0 MHz crystal
+ * U324 Intel 82586-10 Ethernet controller
+ * U303 CICD84607 TC110G75CY
+ * U311 NCR 53C90A SCSI controller
+ * U336 27C010 (MPRGG360F) 128Kx8 Boot EPROM ?SB
+ * U341 Dallas DS1287 RTC and NVRAM
+ * U349 27C010 (MPRGG350F) 128Kx8 Boot EPROM ?SB
+ * U347 Intel 82072 Floppy drive controller
+ *
+ * 6400 (SMT046 rev B, SMT082)
+ *
+ * 6800 Sapphire (SMT127 rev B, SMT104 rev C)
+ *
+ * Ref Part Function
+ * U53 LSI L1A7751 CICD094A3 Intergraph I/O gate array
+ * U55 Xilinx XC3020-70 Plotter control FPGA?
+ * U57 CYID21704 TC140G54AF
+ * U69 CYID21603 TC150G89AF
+ * U73 20.0 MHz crystal Clock source for 82596?
+ * U78 29.0 MHz crystal
+ * U88 4.9152 MHz crystal Clock source for 8530s?
+ * U94 40.0 MHz crystal
+ * U95 CICD 89703 TC110G11AT
+ * U108 24.0 MHz crystal Clock source for 82077
+ * U117 Intel N28F010 128Kx8 flash memory (Y225 0C40 6010)
+ * U118 Zilog Z85C30 SCC Keyboard and console serial controller
+ * U119 Zilog Z85230 ESCC Serial controller for serial port 0 and 1
+ * U130 Intel N28F010 128Kx8 flash memory (Y226 0C40 6280)
+ * U136 NCR 53C94 SCSI controller
+ * U144 27C1024 (MPRGZ530A) 128Kx8 Boot EPROM
+ * U145 Dallas DS12887 RTC and NVRAM
+ * U159 Intel 82596SX-20 Ethernet controller
+ * U164 Intel N82077SL-1? Floppy drive controller
+ *
* CPU daughter-boards
- * PCB824 Rev J - 2000 (also has label MPCBA5507)
+ *
+ * PCB824 Rev J (MPCBA5507)
+ * CPCB82409 rev D (MPCB92108) - 6000 C311 + 2xC322 + 80MHz crystal
+ *
* SMT082 (MSMT0820B, 36MHz?) - 6400 (SMT046 "6400 36-MHz Series System Board")
* SMT03? 2400/6400 - (MSMT03804 -> rev 2 cammu, goes with "6400 36-MHz Series System Board", MSMT0380A eco 3+ use rev 3 cammu)
* SMT019 (MSMT019 C4E CPU Assembly)
* SMT104 Rev A - 2700/6700 (aka MSMT1040A "C4I CPU", C4 CPU REV 3 + C4 FPU REV 3 + C4I CAMMU)
*
* PCB962 2000 System Board MPCB824 C300
+ * PCB??? 6000 System Board w/?MB MPCB824 C300
* SMT046 6400 36-MHz Series System Board MSMT03804 rev 2 CAMMU/30MHz Kryptonite Rev 3 CAMMU/32MHz Kryptonite Rev 3 CAMMU/MSMT0820B(36MHz)
* SMT047 2400 Series System Board MSMT03804 rev 2 CAMMU/MSMT0380A eco 3+ Rev 3 CAMMU
* SMT098A 6400 32-MHz Sapphire System Board
@@ -208,6 +254,8 @@ void interpro_state::machine_start()
save_item(NAME(m_sreg_ctrl2));
save_item(NAME(m_sreg_ctrl3));
+
+ m_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_state::reset_timer), this));
}
void interpro_state::machine_reset()
@@ -216,6 +264,10 @@ void interpro_state::machine_reset()
m_sreg_error = 0;
m_sreg_status = 0x400;
m_sreg_ctrl1 = CTRL1_FLOPLOW;
+
+ // suspend the main cpu long enough for the keyboard to boot
+ m_maincpu->suspend(SUSPEND_REASON_RESET, false);
+ m_reset_timer->adjust(attotime::from_msec(750));
}
void interpro_state::init_common()
@@ -363,6 +415,39 @@ void interpro_state::interpro_common_map(address_map &map)
map(0x7f0fff00, 0x7f0fffff).m(m_ioga, FUNC(interpro_ioga_device::map));
}
+void emerald_state::emerald_base_map(address_map &map)
+{
+ interpro_common_map(map);
+
+ map(0x40000000, 0x4000003f).m(m_mcga, FUNC(interpro_mcga_device::map));
+
+ // scsi registers have unusual address mapping
+ map(0x7f000201, 0x7f000201).rw(m_scsi, FUNC(ncr53c90a_device::tcounter_lo_r), FUNC(ncr53c90a_device::tcount_lo_w));
+ map(0x7f000205, 0x7f000205).rw(m_scsi, FUNC(ncr53c90a_device::tcounter_hi_r), FUNC(ncr53c90a_device::tcount_hi_w));
+ map(0x7f000209, 0x7f000209).rw(m_scsi, FUNC(ncr53c90a_device::fifo_r), FUNC(ncr53c90a_device::fifo_w));
+ map(0x7f00020d, 0x7f00020d).rw(m_scsi, FUNC(ncr53c90a_device::command_r), FUNC(ncr53c90a_device::command_w));
+ map(0x7f000211, 0x7f000211).rw(m_scsi, FUNC(ncr53c90a_device::status_r), FUNC(ncr53c90a_device::bus_id_w));
+ map(0x7f000215, 0x7f000215).rw(m_scsi, FUNC(ncr53c90a_device::istatus_r), FUNC(ncr53c90a_device::timeout_w));
+ map(0x7f000219, 0x7f000219).rw(m_scsi, FUNC(ncr53c90a_device::seq_step_r), FUNC(ncr53c90a_device::sync_period_w));
+ map(0x7f00021d, 0x7f00021d).rw(m_scsi, FUNC(ncr53c90a_device::fifo_flags_r), FUNC(ncr53c90a_device::sync_offset_w));
+ map(0x7f000221, 0x7f000221).rw(m_scsi, FUNC(ncr53c90a_device::conf_r), FUNC(ncr53c90a_device::conf_w));
+ map(0x7f000225, 0x7f000225).w(m_scsi, FUNC(ncr53c90a_device::clock_w));
+ map(0x7f000229, 0x7f000229).w(m_scsi, FUNC(ncr53c90a_device::test_w));
+ map(0x7f00022d, 0x7f00022d).rw(m_scsi, FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
+
+ map(0x7f000300, 0x7f000300).w(this, FUNC(emerald_state::sreg_error_w));
+
+ map(0x7f000600, 0x7f00067f).rom().region(INTERPRO_NODEID_TAG, 0);
+}
+
+void emerald_state::emerald_main_map(address_map &map)
+{
+ emerald_base_map(map);
+
+ map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
+ map(0x7f100000, 0x7f13ffff).rom().region(INTERPRO_EPROM_TAG, 0);
+}
+
void turquoise_state::turquoise_base_map(address_map &map)
{
interpro_common_map(map);
@@ -424,12 +509,26 @@ void sapphire_state::sapphire_base_map(address_map &map)
void sapphire_state::sapphire_main_map(address_map &map)
{
+ //map(0x00000000, 0xffffffff).rw(this, FUNC(sapphire_state::unmapped_r), FUNC(sapphire_state::unmapped_w));
+
sapphire_base_map(map);
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
map(0x7f100000, 0x7f11ffff).rom().region(INTERPRO_EPROM_TAG, 0);
map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_lo", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0x00ff00ff).mask(0x3ffff);
map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_hi", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0xff00ff00).mask(0x3ffff);
+
+ // HACK: for SRX bus Sapphire only
+ //map(0x8f007f80, 0x8f007fff).rom().region(INTERPRO_IDPROM_TAG, 0);
+}
+
+void emerald_state::emerald_io_map(address_map &map)
+{
+ emerald_base_map(map);
+
+ map(0x00000800, 0x000009ff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map));
+ map(0x00000a00, 0x00000bff).m(INTERPRO_MMU_TAG "_i", FUNC(cammu_c3_device::map));
+ map(0x00000c00, 0x00000dff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map_global));
}
void turquoise_state::turquoise_io_map(address_map &map)
@@ -443,6 +542,8 @@ void turquoise_state::turquoise_io_map(address_map &map)
void sapphire_state::sapphire_io_map(address_map &map)
{
+ //map(0x00000000, 0xffffffff).rw(this, FUNC(sapphire_state::unmapped_r), FUNC(sapphire_state::unmapped_w));
+
sapphire_base_map(map);
map(0x00000000, 0x00001fff).m(m_mmu, FUNC(cammu_c4_device::map));
@@ -457,6 +558,11 @@ void interpro_state::interpro_boot_map(address_map &map)
map(0x00000000, 0x00001fff).ram();
}
+void emerald_state::interpro_82586_map(address_map &map)
+{
+ map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
+}
+
void turquoise_state::interpro_82586_map(address_map &map)
{
map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
@@ -473,7 +579,7 @@ FLOPPY_FORMATS_END
static void interpro_floppies(device_slot_interface &device)
{
- device.option_add("525dd", FLOPPY_525_DD);
+ device.option_add("525hd", FLOPPY_525_HD);
device.option_add("35hd", FLOPPY_35_HD);
}
@@ -518,6 +624,11 @@ static void interpro_scsi_devices(device_slot_interface &device)
device.option_add("cdrom", NSCSI_CDROM);
}
+static void emerald_scsi_devices(device_slot_interface &device)
+{
+ device.option_add_internal(INTERPRO_SCSI_ADAPTER_TAG, NCR53C90A);
+}
+
static void turquoise_scsi_devices(device_slot_interface &device)
{
device.option_add_internal(INTERPRO_SCSI_ADAPTER_TAG, NCR53C90A);
@@ -599,12 +710,6 @@ MACHINE_CONFIG_START(interpro_state::interpro)
MCFG_DEVICE_SLOT_INTERFACE(interpro_mouse_devices, "interpro_mouse", false)
MCFG_MOUSE_STATE_CB(WRITE32(INTERPRO_IOGA_TAG, interpro_ioga_device, mouse_status_w))
- // sr bus and slots
- MCFG_DEVICE_ADD(INTERPRO_SRBUS_TAG, SR, 0)
- MCFG_SR_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
- MCFG_SR_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":0", sr_cards, "mpcb963", false)
- MCFG_SR_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":1", sr_cards, nullptr, false)
-
// system layout
MCFG_DEFAULT_LAYOUT(layout_interpro)
@@ -612,6 +717,62 @@ MACHINE_CONFIG_START(interpro_state::interpro)
MCFG_SOFTWARE_LIST_ADD("softlist", "interpro")
MACHINE_CONFIG_END
+MACHINE_CONFIG_START(emerald_state::emerald)
+ interpro(config);
+
+ MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, XTAL(12'500'000))
+ MCFG_DEVICE_ADDRESS_MAP(0, emerald_main_map)
+ MCFG_DEVICE_ADDRESS_MAP(1, emerald_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(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+
+ MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
+
+ // boot fails memory test without this
+ MCFG_DEVICE_MODIFY(RAM_TAG)
+ MCFG_RAM_DEFAULT_VALUE(0x00)
+
+ // memory control gate array
+ MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_MCGA, 0)
+
+ // floppy controller
+ MCFG_I82072_ADD(INTERPRO_FDC_TAG, false)
+ MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
+ MCFG_UPD765_DRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
+
+ // connect a 5.25" drive at id 3
+ MCFG_DEVICE_ADD("fdc:0", FLOPPY_CONNECTOR, 0)
+ MCFG_DEVICE_ADD("fdc:1", FLOPPY_CONNECTOR, 0)
+ MCFG_DEVICE_ADD("fdc:2", FLOPPY_CONNECTOR, 0)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:3", interpro_floppies, "525hd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_SOUND(false)
+
+ // serial controllers and ports
+ MCFG_SCC85C30_ADD(INTERPRO_SCC1_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc1(config);
+ MCFG_SCC85C30_ADD(INTERPRO_SCC2_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc2(config);
+
+ // scsi controller
+ MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":7", emerald_scsi_devices, INTERPRO_SCSI_ADAPTER_TAG, true)
+ MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
+
+ // ethernet controller
+ MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82586, 10_MHz_XTAL)
+ MCFG_I82586_IRQ_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir12_w))
+ MCFG_DEVICE_ADDRESS_MAP(0, interpro_82586_map)
+
+ // i/o gate array
+ MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, TURQUOISE_IOGA, 0)
+ MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
+ ioga(config);
+MACHINE_CONFIG_END
+
MACHINE_CONFIG_START(turquoise_state::turquoise)
interpro(config);
MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, XTAL(12'500'000))
@@ -666,8 +827,15 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
- MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG)
- MCFG_SR_MEMORY(INTERPRO_CPU_TAG, 0, 1)
+ // 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(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
+ MCFG_CBUS_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
+ MCFG_CBUS_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
+ MCFG_CBUS_OUT_VBLANK_CB(WRITELINE(INTERPRO_IOGA_TAG, 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)
@@ -721,10 +889,6 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
// flash memory
MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_lo", INTEL_28F010, 0)
MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_hi", INTEL_28F010, 0)
-
- // sr bus address spaces
- MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG)
- MCFG_SR_MEMORY(INTERPRO_CPU_TAG, 0, 1)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::ip2000)
@@ -732,6 +896,10 @@ MACHINE_CONFIG_START(turquoise_state::ip2000)
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
//MCFG_DEVICE_CLOCK(XTAL(40'000'000))
+ // GT graphics (2020)
+ MCFG_DEVICE_MODIFY(INTERPRO_SLOT_TAG ":0")
+ MCFG_SLOT_DEFAULT_OPTION("mpcb963")
+
MCFG_SOFTWARE_LIST_FILTER("softlist", "2000")
MACHINE_CONFIG_END
@@ -743,8 +911,12 @@ MACHINE_CONFIG_START(sapphire_state::ip2400)
MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
- MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG ":0")
- MCFG_SLOT_DEFAULT_OPTION("mpcb070")
+ // 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(INTERPRO_IOGA_TAG, 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)
MCFG_SOFTWARE_LIST_FILTER("softlist", "2400")
MACHINE_CONFIG_END
@@ -754,6 +926,16 @@ MACHINE_CONFIG_START(sapphire_state::ip2500)
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
//MCFG_DEVICE_CLOCK(XTAL(?)
+ // 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(INTERPRO_IOGA_TAG, 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)
+
+ // GT II graphics?
+ //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+
// FIXME: don't know which cammu revision
MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
@@ -766,6 +948,16 @@ MACHINE_CONFIG_START(sapphire_state::ip2700)
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
//MCFG_DEVICE_CLOCK(?)
+ // 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(INTERPRO_IOGA_TAG, 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)
+
+ // GT II graphics?
+ //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+
MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
@@ -777,6 +969,16 @@ MACHINE_CONFIG_START(sapphire_state::ip2800)
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
//MCFG_DEVICE_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(INTERPRO_IOGA_TAG, 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)
+
+ // GT II graphics?
+ //MCFG_SLOT_DEFAULT_OPTION("msmt135")
+
// FIXME: don't know which cammu revision
MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
@@ -784,6 +986,96 @@ MACHINE_CONFIG_START(sapphire_state::ip2800)
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)
+
+ // 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(INTERPRO_IOGA_TAG, 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)
+
+ 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(XTAL(36'000'000))
+
+ 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(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_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)
+
+ // 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)
+
+ 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(?)
+
+ // 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(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_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)
+
+ 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(?)
+
+ // FIXME: don't know which cammu revision
+ MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
+ MCFG_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(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
+ MCFG_SRX_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
+ MCFG_SRX_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, 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)
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "6800")
+MACHINE_CONFIG_END
+
ROM_START(ip2000)
ROM_REGION(0x80, INTERPRO_NODEID_TAG, 0)
ROM_LOAD32_BYTE("nodeid.bin", 0x0, 0x20, CRC(a38397a6) SHA1(9f45fb932bbe231c95b3d5470dcd1fa1c846486f))
@@ -791,7 +1083,7 @@ ROM_START(ip2000)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
ROM_LOAD32_BYTE("mpcb962a.bin", 0x0, 0x20, CRC(e391342c) SHA1(02e03aad760b6651b8599c3a41c7c457983ee97d))
- ROM_REGION(0x0040000, INTERPRO_EPROM_TAG, 0)
+ ROM_REGION(0x40000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2000", "InterPro 2000 EPROM")
ROMX_LOAD("mprgm530e__26_apr_91k.u171", 0x00001, 0x20000, CRC(e4c470cb) SHA1(ff1917bfa963988d739a9dbf0b8f034fe49f2f8c), ROM_SKIP(1) | ROM_BIOS(1))
ROMX_LOAD("mprgm540e__06_may_91k.u172", 0x00000, 0x20000, CRC(03225843) SHA1(03cfcd5b8ae0057240ef808a40108cb5d082eb63), ROM_SKIP(1) | ROM_BIOS(1))
@@ -801,7 +1093,7 @@ ROM_START(ip2400)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
ROM_LOAD32_BYTE("msmt0470.bin", 0x0, 0x20, CRC(498c80df) SHA1(18a49732ac9d04b20a77747c1b946c2e88abb087))
- ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2400", "InterPro 2400 EPROM")
ROMX_LOAD("mprgw510b__05_16_92.u35", 0x00000, 0x20000, CRC(3b2c4545) SHA1(4e4c98d1cd1035a04be8527223f44d0b687ec3ef), ROM_BIOS(1))
@@ -816,7 +1108,7 @@ ROM_START(ip2500)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
ROM_LOAD32_BYTE("msmt1000.bin", 0x0, 0x20, CRC(548046c0) SHA1(ce7646e868f3aa35642d7f9348f6b9e91693918e))
- ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2500", "InterPro 2500 EPROM")
ROMX_LOAD("ip2500_eprom.bin", 0x00000, 0x20000, NO_DUMP, ROM_BIOS(1))
@@ -831,7 +1123,7 @@ ROM_START(ip2700)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
ROM_LOAD32_BYTE("msmt1280.bin", 0x0, 0x20, CRC(32d833af) SHA1(7225c5f5670fe49d86556a2cb453ae6fe09e3e19))
- ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2700", "InterPro 2700 EPROM")
ROMX_LOAD("mprgz530a__9405181.u35", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1))
@@ -846,7 +1138,7 @@ ROM_START(ip2800)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
ROM_LOAD32_BYTE("msmt1450.bin", 0x0, 0x20, CRC(61c7a305) SHA1(efcd045cbdfda8df44eaad761b0ba99367973cd7))
- ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2800", "InterPro 2800 EPROM")
ROMX_LOAD("ip2800_eprom.bin", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1))
@@ -857,9 +1149,74 @@ ROM_START(ip2800)
ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
+ROM_START(ip6000)
+ ROM_REGION(0x80, INTERPRO_NODEID_TAG, 0)
+ ROM_LOAD32_BYTE("nodeid.bin", 0x0, 0x20, CRC(a38397a6) SHA1(9f45fb932bbe231c95b3d5470dcd1fa1c846486f))
+
+ ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
+ ROM_LOAD32_BYTE("mpcb765b.bin", 0x0, 0x20, CRC(d81bda5c) SHA1(27e6baffb13fa9f3118b7ff539c7e11b7e778416))
+
+ ROM_REGION(0x40000, INTERPRO_EPROM_TAG, 0)
+ ROM_SYSTEM_BIOS(0, "ip6000", "InterPro 6000 EPROM")
+ ROMX_LOAD("ip6000_lo.bin", 0x00001, 0x20000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(1))
+ ROMX_LOAD("ip6000_hi.bin", 0x00000, 0x20000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(1))
+ROM_END
+
+ROM_START(ip6400)
+ ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
+ ROM_LOAD32_BYTE("msmt046b.bin", 0x0, 0x20, CRC(3e8ffc77) SHA1(719a3f8b01bb506c9cb876506d63d167550bcd0a))
+
+ // FIXME: use 2400 eprom until we have a 6400 dump
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
+ ROM_SYSTEM_BIOS(0, "ip6400", "InterPro 6400 EPROM")
+ ROMX_LOAD("ip6400_eprom.bin", 0x00000, 0x20000, BAD_DUMP CRC(3b2c4545) SHA1(4e4c98d1cd1035a04be8527223f44d0b687ec3ef), ROM_BIOS(1))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_LOAD_OPTIONAL("flash.lo", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_LOAD_OPTIONAL("flash.hi", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
+ROM_END
+
+ROM_START(ip6700)
+ ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
+ ROM_LOAD32_BYTE("msmt127b.bin", 0x0, 0x20, CRC(cc112f65) SHA1(8533a31b4733fd91bb87effcd276fc93f2858629))
+
+ // FIXME: use 2800 eprom until we have a 6700 dump
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
+ ROM_SYSTEM_BIOS(0, "ip6700", "InterPro 6700 EPROM")
+ ROMX_LOAD("mprgz530a.u144", 0x00000, 0x20000, BAD_DUMP CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_LOAD_OPTIONAL("y225.u117", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_LOAD_OPTIONAL("y226.u130", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
+ROM_END
+
+ROM_START(ip6800)
+ ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
+ ROM_LOAD32_BYTE("msmt127b.bin", 0x0, 0x20, CRC(cc112f65) SHA1(8533a31b4733fd91bb87effcd276fc93f2858629))
+
+ // FIXME: use 2800 eprom until we have a 6800 dump
+ ROM_REGION(0x20000, INTERPRO_EPROM_TAG, 0)
+ ROM_SYSTEM_BIOS(0, "ip6800", "InterPro 6800 EPROM")
+ ROMX_LOAD("mprgz530a__9406270.u144", 0x00000, 0x20000, BAD_DUMP CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_LOAD_OPTIONAL("y225.u117", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
+
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_LOAD_OPTIONAL("y226.u130", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
+ROM_END
+
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1990, ip2000, 0, 0, ip2000, interpro, turquoise_state,init_common,"Intergraph", "InterPro 2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1992, ip2400, 0, 0, ip2400, interpro, sapphire_state, init_common,"Intergraph", "InterPro 2400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1993, ip2500, 0, 0, ip2500, interpro, sapphire_state, init_common,"Intergraph", "InterPro 2500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1993, ip2700, 0, 0, ip2700, interpro, sapphire_state, init_common,"Intergraph", "InterPro 2700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1994, ip2800, 0, 0, ip2800, interpro, sapphire_state, init_common,"Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1990, ip6000, 0, 0, ip6000, interpro, emerald_state, init_common,"Intergraph", "InterPro 6000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1992, ip6400, 0, 0, ip6400, interpro, sapphire_state, init_common,"Intergraph", "InterPro 6400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1993, ip6700, 0, 0, ip6700, interpro, sapphire_state, init_common,"Intergraph", "InterPro 6700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1993, ip6800, 0, 0, ip6800, interpro, sapphire_state, init_common,"Intergraph", "InterPro 6800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index 9cf7e20f494..9cb22d6b086 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -61,7 +61,7 @@
#define INTERPRO_EPROM_TAG "eprom"
#define INTERPRO_FLASH_TAG "flash"
-#define INTERPRO_SRBUS_TAG "sr"
+#define INTERPRO_SLOT_TAG "slot"
class interpro_state : public driver_device
{
@@ -171,7 +171,10 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
+ TIMER_CALLBACK_MEMBER(reset_timer) { m_maincpu->resume(SUSPEND_REASON_RESET); }
+
output_finder<> m_led;
+ emu_timer *m_reset_timer;
u16 m_sreg_error;
u16 m_sreg_status;
@@ -182,6 +185,31 @@ protected:
u16 m_sreg_ctrl3;
};
+class emerald_state : public interpro_state
+{
+public:
+ emerald_state(const machine_config &mconfig, device_type type, const char *tag)
+ : interpro_state(mconfig, type, tag)
+ , m_d_cammu(*this, INTERPRO_MMU_TAG "_d")
+ , m_i_cammu(*this, INTERPRO_MMU_TAG "_i")
+ , m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG)
+ {
+ }
+
+ DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
+
+ required_device<cammu_c3_device> m_d_cammu;
+ required_device<cammu_c3_device> m_i_cammu;
+ required_device<ncr53c90a_device> m_scsi;
+
+ void emerald(machine_config &config);
+ void ip6000(machine_config &config);
+ void interpro_82586_map(address_map &map);
+ void emerald_base_map(address_map &map);
+ void emerald_main_map(address_map &map);
+ void emerald_io_map(address_map &map);
+};
+
class turquoise_state : public interpro_state
{
public:
@@ -233,8 +261,12 @@ public:
void sapphire(machine_config &config);
void ip2500(machine_config &config);
void ip2400(machine_config &config);
- void ip2800(machine_config &config);
void ip2700(machine_config &config);
+ void ip2800(machine_config &config);
+ void ip6400(machine_config &config);
+ void ip6700(machine_config &config);
+ void ip6800(machine_config &config);
+
void interpro_82596_map(address_map &map);
void sapphire_base_map(address_map &map);
void sapphire_main_map(address_map &map);
diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp
index ff07e71c64b..ee620503745 100644
--- a/src/mame/machine/interpro_ioga.cpp
+++ b/src/mame/machine/interpro_ioga.cpp
@@ -70,7 +70,7 @@ const interpro_ioga_device::interrupt_data_t interpro_ioga_device::m_interrupt_d
{ INT_HARD_EX, IRQ_9, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 7", "?" },
{ INT_HARD_EX, IRQ_CBUS3, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 8", "cbus 3" },
{ INT_HARD_EX, IRQ_RTC, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 9", "clock/calendar" },
- { INT_HARD_EX, IRQ_12, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 10", "sga?" },
+ { INT_HARD_EX, IRQ_60HZ, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 10", "60Hz" },
{ INT_HARD_IN, IRQ_MOUSE, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 0", "mouse" },
{ INT_HARD_IN, IRQ_TIMER0, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 1", "timer 0" },
@@ -114,6 +114,7 @@ void interpro_ioga_device::map(address_map &map)
map(0x54, 0x57).rw(this, FUNC(interpro_ioga_device::serial_dma2_ctrl_r), FUNC(interpro_ioga_device::serial_dma2_ctrl_w));
// 5a - sib control?
+ //map(0x58, 0x5b).rw(this, FUNC(interpro_ioga_device::sib_r), FUNC(interpro_ioga_device::sib_w));
map(0x5c, 0x7f).rw(this, FUNC(interpro_ioga_device::icr_r), FUNC(interpro_ioga_device::icr_w));
map(0x80, 0x81).rw(this, FUNC(interpro_ioga_device::icr18_r), FUNC(interpro_ioga_device::icr18_w));
map(0x82, 0x82).rw(this, FUNC(interpro_ioga_device::softint_r), FUNC(interpro_ioga_device::softint_w));
@@ -125,7 +126,7 @@ void interpro_ioga_device::map(address_map &map)
map(0x94, 0x97).r(this, FUNC(interpro_ioga_device::error_address_r));
map(0x98, 0x9b).r(this, FUNC(interpro_ioga_device::error_businfo_r));
map(0x9c, 0x9d).rw(this, FUNC(interpro_ioga_device::arbctl_r), FUNC(interpro_ioga_device::arbctl_w));
- //AM_RANGE(0x9c, 0x9f) AM_READWRITE16(?, ?, 0xffff0000) // ip2000 boot code writes 0x7f18
+
map(0xa0, 0xa3).rw(this, FUNC(interpro_ioga_device::timer2_count_r), FUNC(interpro_ioga_device::timer2_count_w));
map(0xa4, 0xa7).rw(this, FUNC(interpro_ioga_device::timer2_value_r), FUNC(interpro_ioga_device::timer2_value_w));
map(0xa8, 0xab).rw(this, FUNC(interpro_ioga_device::timer3_r), FUNC(interpro_ioga_device::timer3_w));
@@ -141,6 +142,8 @@ void turquoise_ioga_device::map(address_map &map)
map(0x00, 0x03).rw(this, FUNC(turquoise_ioga_device::eth_base_r), FUNC(turquoise_ioga_device::eth_base_w));
map(0x04, 0x05).rw(this, FUNC(turquoise_ioga_device::eth_control_r), FUNC(turquoise_ioga_device::eth_control_w));
+
+ //map(0x9e, 0x9f).rw(this, FUNC(turquoise_ioga_device::?), FUNC(turquoise_ioga_device::?)); // ip2000 boot code writes 0x7f18
}
void sapphire_ioga_device::map(address_map &map)
@@ -165,9 +168,9 @@ interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, device
, m_fdc_tc_func(*this)
, m_eth_ca_func(*this)
, m_dma_channel{
- { 0,0,0,0,CLEAR_LINE,IDLE, {*this}, {*this}, ARBCTL_BGR_PLOT, DMA_PLOTTER, "plotter" },
- { 0,0,0,0,CLEAR_LINE,IDLE, {*this}, {*this}, ARBCTL_BGR_SCSI, DMA_SCSI, "scsi" },
- { 0,0,0,0,CLEAR_LINE,IDLE, {*this}, {*this}, ARBCTL_BGR_FDC, DMA_FLOPPY, "floppy" } }
+ { 0,0,0,0,CLEAR_LINE, {*this}, {*this}, ARBCTL_BGR_PLOT, DMA_PLOTTER, "plotter" },
+ { 0,0,0,0,CLEAR_LINE, {*this}, {*this}, ARBCTL_BGR_SCSI, DMA_SCSI, "scsi" },
+ { 0,0,0,0,CLEAR_LINE, {*this}, {*this}, ARBCTL_BGR_FDC, DMA_FLOPPY, "floppy" } }
, m_serial_dma_channel{
{ 0,0,CLEAR_LINE, {*this}, {*this}, ARBCTL_BGR_SER0, 0, "serial0" },
{ 0,0,CLEAR_LINE, {*this}, {*this}, ARBCTL_BGR_SER1, 1, "serial1" },
@@ -223,6 +226,8 @@ void interpro_ioga_device::device_start()
m_timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer2), this));
m_timer3 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer3), this));
+ m_timer_60hz = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer_60hz), this));
+
m_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::mouse_timer), this));
m_eth_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::eth_reset), this));
}
@@ -238,10 +243,7 @@ void interpro_ioga_device::device_reset()
// initialise dma state
for (dma_channel_t &dma_channel : m_dma_channel)
- {
dma_channel.drq_state = CLEAR_LINE;
- dma_channel.state = IDLE;
- }
for (serial_dma_channel_t &dma_channel : m_serial_dma_channel)
dma_channel.drq_state = CLEAR_LINE;
@@ -259,16 +261,14 @@ void interpro_ioga_device::device_reset()
m_mouse_timer->enable(false);
m_eth_reset_timer->enable(false);
- // configure timer 0 for 60Hz
m_timer0_count = 0;
- m_timer0_limit = 0;
- m_timer0->adjust(attotime::zero, 0, attotime::from_hz(60));
-
m_timer1_count = 0;
m_timer2_count = 0;
m_timer2_value = 0;
m_timer3_count = 0;
+ m_timer_60hz->adjust(attotime::zero, 0, attotime::from_hz(60));
+
m_prescaler = 0;
}
@@ -444,8 +444,8 @@ bool interpro_ioga_device::irq(int state, u8 ivec)
if (m_irq_state != state)
{
- LOGIRQ(m_active_interrupt->number, "%s %s number %d source %s (%s)\n",
- state ? "asserting" : "clearing", m_active_interrupt->name, m_active_interrupt->number, m_active_interrupt->source, machine().describe_context());
+ LOGIRQ(m_active_interrupt->number, "%s %s number %d source %s\n",
+ state ? "asserting" : "clearing", m_active_interrupt->name, m_active_interrupt->number, m_active_interrupt->source);
m_irq_state = state;
m_out_irq_func(state);
@@ -542,25 +542,21 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
{
for (dma_channel_t &dma_channel : m_dma_channel)
{
- // check if there's something to transfer
- if (dma_channel.transfer_count == 0 || (dma_channel.control & DMA_CTRL_BGR) == 0)
+ // check if the channel is enabled
+ if (!(dma_channel.control & DMA_CTRL_ENABLE))
continue;
// check if the device is requesting a transfer
if (dma_channel.drq_state == CLEAR_LINE)
continue;
- // check if the bus is available
- if ((m_arbctl & dma_channel.arb_mask) == 0)
- {
- // set bus wait flag and abort
- //dma_channel.control |= DMA_CTRL_WAIT;
+ // check if there's something to transfer
+ if (dma_channel.transfer_count == 0)
+ continue;
+ // check if the bus is available
+ if (!(m_arbctl & dma_channel.arb_mask))
continue;
- }
- //else
- // // clear bus wait flag
- // dma_channel.control &= ~DMA_CTRL_WAIT;
// translate address when DMA_CTRL_VIRTUAL is set
// FIXME: what happens when we span a page?
@@ -573,7 +569,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
dma_channel.real_address = (ptde & ~0xfff) | (dma_channel.real_address & 0xfff);
dma_channel.control &= ~DMA_CTRL_VIRTUAL;
- LOGDMA(dma_channel.channel, "dma: translated virtual address 0x%08x\n", dma_channel.real_address);
+ LOGDMA(dma_channel.channel, "dma: translated virtual 0x%08x real 0x%08x\n", dma_channel.virtual_address, dma_channel.real_address);
// FIXME: what about protection levels and system tags?
@@ -607,7 +603,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
dma_channel.transfer_count--;
// check for page wrap
- if (dma_channel.transfer_count && (dma_channel.real_address & 0xfff) == 0)
+ if ((dma_channel.real_address & 0xfff) == 0)
{
LOGDMA(dma_channel.channel, "dma: wrapped to next memory page\n");
@@ -633,11 +629,11 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
m_fdc_tc_func(CLEAR_LINE);
}
- // clear bus grant required
- dma_channel.control &= ~DMA_CTRL_BGR;
-
// set transfer count zero flag
dma_channel.control |= DMA_CTRL_TCZERO;
+
+ // disable the channel
+ dma_channel.control &= ~DMA_CTRL_ENABLE;
}
#if IOGA_DMA_DIAG_HACK
@@ -760,29 +756,31 @@ void interpro_ioga_device::dma_w(address_space &space, offs_t offset, u32 data,
break;
case 1:
- LOGDMA(channel, "dma: channel %d virtual address = 0x%08x mem_mask 0x%08x (%s)\n",
+ LOGDMA(channel, "dma: channel %d virtual address 0x%08x mem_mask 0x%08x (%s)\n",
channel, data, mem_mask, machine().describe_context());
COMBINE_DATA(&dma_channel.virtual_address);
+ dma_channel.virtual_address &= ~0x3;
+
+ dma_channel.control |= DMA_CTRL_VIRTUAL;
break;
case 2:
- LOGDMA(channel, "dma: channel %d transfer count = 0x%08x mem_mask 0x%08x (%s)\n",
+ LOGDMA(channel, "dma: channel %d transfer count 0x%08x mem_mask 0x%08x (%s)\n",
channel, data, mem_mask, machine().describe_context());
COMBINE_DATA(&dma_channel.transfer_count);
+
+ dma_channel.control &= ~DMA_CTRL_TCZERO;
break;
case 3:
- LOGDMA(channel, "dma: channel %d control = 0x%08x mem_mask 0x%08x (%s)\n",
- channel, data, mem_mask, machine().describe_context());
+ dma_channel.control = (data & mem_mask & DMA_CTRL_WMASK) | (dma_channel.control & (~mem_mask | ~DMA_CTRL_WMASK));
- COMBINE_DATA(&dma_channel.control);
- // (7.0272) if bus error flag is set, clear existing bus error (otherwise retain existing state)
- //if (data & DMA_CTRL_BERR)
- // dma_channel.control = data & DMA_CTRL_WMASK;
- //else
- // dma_channel.control = (data & DMA_CTRL_WMASK) | (dma_channel.control & DMA_CTRL_BERR);
+ // (7.0272) if bus error flag is written, clear existing bus error (otherwise retain existing state)
+ if (data & DMA_CTRL_BERR)
+ dma_channel.control &= ~DMA_CTRL_BERR;
- dma_channel.state = COMMAND;
+ LOGDMA(channel, "dma: channel %d control 0x%08x mem_mask 0x%08x result 0x%08x (%s)\n",
+ channel, data, mem_mask, dma_channel.control, machine().describe_context());
break;
}
}
@@ -910,23 +908,37 @@ READ32_MEMBER(interpro_ioga_device::timer0_r)
WRITE32_MEMBER(interpro_ioga_device::timer0_w)
{
- //m_timer0_limit = data;
- m_timer0_count = data;
+ LOGMASKED(LOG_TIMER0, "timer0_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n", data, mem_mask, m_prescaler, machine().describe_context());
- m_timer0->adjust(attotime::zero, 0, attotime::from_hz(60));
+ // store the timer count value
+ m_timer0_count = data;
- LOGMASKED(LOG_TIMER0, "timer0_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ // restart the timer
+ //if (m_prescaler & 0xffff)
+ // m_timer0->adjust(attotime::zero, 0, attotime::from_ticks(m_prescaler & 0xffff, 60_Hz_XTAL));
+ //else
+ m_timer0->adjust(attotime::zero, 0, attotime::from_hz(60_Hz_XTAL));
}
TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer0)
{
+ m_timer0_count++;
+
+ // check if the timer has expired
if (m_timer0_count == 0)
- set_int_line(INT_HARD_IN, IRQ_TIMER0, ASSERT_LINE);
- else
- m_timer0_count++;
+ {
+ // stop the timer
+ m_timer0->enable(false);
+
+ // raise an interrupt
+ if (m_hwicr[IRQ_TIMER0] & IRQ_ENABLE_EXTERNAL)
+ set_int_line(INT_HARD_IN, IRQ_TIMER0, ASSERT_LINE);
+ }
+}
- //m_hwicr[IRQ_VB] |= IRQ_PENDING; // this makes mouse diag countdown work (at half correct speed)
- set_int_line(INT_HARD_EX, IRQ_12, ASSERT_LINE); // FIXME: 60Hz timer on InterPro 2000
+TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer_60hz)
+{
+ set_int_line(INT_HARD_EX, IRQ_60HZ, ASSERT_LINE);
}
READ32_MEMBER(interpro_ioga_device::timer1_r)
@@ -955,11 +967,10 @@ WRITE32_MEMBER(interpro_ioga_device::timer1_w)
// start the timer if necessary
if (data & TIMER1_START)
{
- LOGMASKED(LOG_TIMER1, "timer1_w data 0x%08x mask 0x%08x prescaler 0x%04x (%s)\n", data, mem_mask, m_prescaler & 0x7fff, machine().describe_context());
+ LOGMASKED(LOG_TIMER1, "timer1_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n", data, mem_mask, m_prescaler, machine().describe_context());
- // theory: timer 1 is 10MHz (typical prescaler value of 1000 and timer value of 100 giving a delay of 100ms)
- // FIXME: division by 50 is sufficient to pass iogadiag timer 1 tests
- m_timer1->adjust(attotime::zero, false, attotime::from_usec((m_prescaler & 0x7fff) / 50));
+ // theory: timer 1 is 1MHz (typical prescaler value of 1000 and timer value of 100 giving a delay of 100ms)
+ m_timer1->adjust(attotime::zero, false, attotime::from_usec((m_prescaler & 0xffff) / 50));
}
}
@@ -978,7 +989,8 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer1)
m_timer1->set_param(true);
// throw an interrupt
- set_int_line(INT_HARD_IN, IRQ_TIMER1, ASSERT_LINE);
+ if (m_hwicr[IRQ_TIMER1] & IRQ_ENABLE_EXTERNAL)
+ set_int_line(INT_HARD_IN, IRQ_TIMER1, ASSERT_LINE);
}
}
@@ -1067,18 +1079,14 @@ READ32_MEMBER(interpro_ioga_device::prescaler_r)
// FIXME: prescaler only used with timer 1?
LOGMASKED(LOG_TIMERRD, "prescaler_r data 0x%08x mask 0x%08x (%s)\n", m_prescaler, mem_mask, machine().describe_context());
- return m_prescaler;
+ return (m_prescaler ^ 0xffff0000) - 0x10000;
}
WRITE32_MEMBER(interpro_ioga_device::prescaler_w)
{
- LOGMASKED(LOG_TIMER1, "prescaler_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMER0 | LOG_TIMER1, "prescaler_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
- // this logic satisfies prescaler tests, but fails timer prescaler tests
- if ((data & 0x7fff) < 0x100 && (data & 0x7fff) != 0)
- m_prescaler = (data ^ 0xffff0000);
- else
- m_prescaler = (data ^ 0xffff0000) - 0x10000;
+ COMBINE_DATA(&m_prescaler);
}
/*
diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h
index 15c777a7ea0..0a11de5f228 100644
--- a/src/mame/machine/interpro_ioga.h
+++ b/src/mame/machine/interpro_ioga.h
@@ -59,7 +59,7 @@ protected:
IRQ_9 = 9, // external int 7 (6e)
IRQ_CBUS3 = 10, // external int 8 (70)
IRQ_RTC = 11, // external int 9 (72)
- IRQ_12 = 12, // external int 10 (74) SGA?
+ IRQ_60HZ = 12, // external int 10 (74)
IRQ_MOUSE = 13, // internal int 0 (76)
IRQ_TIMER0 = 14, // internal int 1 (78)
IRQ_TIMER1 = 15, // internal int 2 (7a)
@@ -136,7 +136,7 @@ public:
DECLARE_WRITE_LINE_MEMBER(ir8_w) { set_int_line(INT_HARD_EX, IRQ_CBUS3, state); }
// FIXME: mc146818 inverts the normal irq state convention
DECLARE_WRITE_LINE_MEMBER(ir9_w) { set_int_line(INT_HARD_EX, IRQ_RTC, !state); }
- DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(INT_HARD_EX, IRQ_12, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(INT_HARD_EX, IRQ_60HZ, state); }
DECLARE_WRITE_LINE_MEMBER(ir11_w) { set_int_line(INT_HARD_EX, IRQ_SERIAL, state); }
DECLARE_WRITE_LINE_MEMBER(ir12_w) { set_int_line(INT_HARD_EX, IRQ_ETHERNET, state); }
@@ -195,14 +195,14 @@ public:
DMA_CTRL_BERR = 0x00400000, // bus error
DMA_CTRL_ERR = 0x00800000, // checked for in scsi isr
- DMA_CTRL_BGR = 0x01000000, // cleared when command complete (maybe bus grant required?)
+ DMA_CTRL_ENABLE = 0x01000000, // transfer enabled
DMA_CTRL_VIRTUAL = 0x02000000, // virtual address translation required
DMA_CTRL_DOUBLE = 0x04000000, // double transfer size (double or quad quad)
DMA_CTRL_WRITE = 0x40000000, // memory to device transfer
DMA_CTRL_QUAD = 0x80000000, // select quad transfer size (quad quad when combined with double)
- DMA_CTRL_WMASK = 0xfd000e00 // writable fields
+ DMA_CTRL_WMASK = 0xfd000e00 // writable fields (quad not writable for floppy/plotter?)
};
DECLARE_READ32_MEMBER(dma_plotter_r) { return dma_r(space, offset, mem_mask, DMA_PLOTTER); }
DECLARE_WRITE32_MEMBER(dma_plotter_w) { dma_w(space, offset, data, mem_mask, DMA_PLOTTER); }
@@ -340,6 +340,7 @@ protected:
TIMER_CALLBACK_MEMBER(timer1);
TIMER_CALLBACK_MEMBER(timer2) {}
TIMER_CALLBACK_MEMBER(timer3);
+ TIMER_CALLBACK_MEMBER(timer_60hz);
TIMER_CALLBACK_MEMBER(mouse_timer);
virtual TIMER_CALLBACK_MEMBER(eth_reset) = 0;
@@ -387,15 +388,6 @@ private:
// dma state
static const int DMA_CHANNEL_COUNT = 3;
- enum dma_state
- {
- IDLE,
- WAIT,
- COMMAND,
- TRANSFER,
- COMPLETE,
- FINAL
- };
struct dma_channel_t
{
u32 real_address;
@@ -404,7 +396,6 @@ private:
u32 control;
int drq_state;
- dma_state state;
devcb_read8 device_r;
devcb_write8 device_w;
@@ -432,7 +423,6 @@ private:
// timers
u8 m_timer0_count;
- u8 m_timer0_limit;
u16 m_timer1_count;
u32 m_timer2_count;
u32 m_timer2_value;
@@ -446,6 +436,7 @@ private:
emu_timer *m_timer1;
emu_timer *m_timer2;
emu_timer *m_timer3;
+ emu_timer *m_timer_60hz;
// bus arbitration and control
u16 m_arbctl;
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index ed5ae8a3159..4703cf3a13b 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -15473,6 +15473,10 @@ ip2400 // Intergraph InterPro/InterServe 24x0
ip2500 // Intergraph InterPro/InterServe 25x0
ip2700 // Intergraph InterPro/InterServe 27x0
ip2800 // Intergraph InterPro/InterServe 28x0
+ip6000 // Intergraph InterPro/InterServe 60x0
+ip6400 // Intergraph InterPro/InterServe 64x0
+ip6700 // Intergraph InterPro/InterServe 67x0
+ip6800 // Intergraph InterPro/InterServe 68x0
@source:intrscti.cpp
intrscti // ????