From 90dc8100237508469cbd741dd8e3d9787c207878 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Tue, 15 May 2018 21:01:13 +0700 Subject: 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 --- scripts/src/bus.lua | 2 + src/devices/bus/interpro/sr/edge.cpp | 774 +++++++++++++++++++++++++++++++ src/devices/bus/interpro/sr/edge.h | 294 ++++++++++++ src/devices/bus/interpro/sr/gt.cpp | 357 ++++++++------ src/devices/bus/interpro/sr/gt.h | 96 ++-- src/devices/bus/interpro/sr/sr.cpp | 166 +++++-- src/devices/bus/interpro/sr/sr.h | 260 +++++++++-- src/devices/bus/interpro/sr/sr_cards.cpp | 20 +- src/devices/bus/interpro/sr/sr_cards.h | 3 +- src/mame/drivers/interpro.cpp | 425 +++++++++++++++-- src/mame/includes/interpro.h | 36 +- src/mame/machine/interpro_ioga.cpp | 132 +++--- src/mame/machine/interpro_ioga.h | 21 +- src/mame/mame.lst | 4 + 14 files changed, 2201 insertions(+), 389 deletions(-) create mode 100644 src/devices/bus/interpro/sr/edge.cpp create mode 100644 src/devices/bus/interpro/sr/edge.h 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(); + 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 m_screen; + required_device m_sram; + required_device m_vram; + required_device m_dsp; + required_device m_ramdac; + required_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 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 m_screen; + required_device m_sram; + required_device m_vram; + required_device_array 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 > = 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 >_screen = active_screen(); + const gt_t > = 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 > = 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 = >.buffer[src_address]; + const u8 *src_mask = >.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 = >.buffer[src_address]; + const u8 *src_mask = >.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) ? >.mask[dst_address] : >.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 = >.buffer[dst_address]; + const u8 *out_mask = >.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 = >.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 = >.buffer[src_address]; + const u8 *src_mask = >.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 = >.buffer[src_address]; + const u8 *src_mask = >.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) ? >.mask[dst_address] : >.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 = >.buffer[dst_address]; + const u8 *out_mask = >.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 >, 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 = >.buffer[src_address]; + const u8 *mask = >.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 >, 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 = >.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 = >.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 = >.mask[dst_address]; + u8 *dst_data = >.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 = >.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 >_screen = m_screen[0]; + const gt_t > = m_gt[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN0_DISP_BUF1 ? >_screen.buffer[GT_BUFFER_SIZE] : >_screen.buffer[0]); + gt.ramdac->screen_update(screen, bitmap, cliprect, + (m_control & GFX_SCREEN0_DISP_BUF1) ? >.buffer[GT_BUFFER_SIZE] : >.buffer[0]); return 0; } u32 dual_gt_device_base::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - const gt_screen_t >_screen = m_screen[0]; + const gt_t > = m_gt[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN0_DISP_BUF1 ? >_screen.buffer[GT_BUFFER_SIZE] : >_screen.buffer[0]); + gt.ramdac->screen_update(screen, bitmap, cliprect, + (m_control & GFX_SCREEN0_DISP_BUF1) ? >.buffer[GT_BUFFER_SIZE] : >.buffer[0]); return 0; } u32 dual_gt_device_base::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - const gt_screen_t >_screen = m_screen[1]; + const gt_t > = m_gt[1]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, m_control & GFX_SCREEN1_DISP_BUF1 ? >_screen.buffer[GT_BUFFER_SIZE] : >_screen.buffer[0]); + gt.ramdac->screen_update(screen, bitmap, cliprect, + (m_control & GFX_SCREEN1_DISP_BUF1) ? >.buffer[GT_BUFFER_SIZE] : >.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 >_screen = active_screen(); + const gt_t > = 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 >, 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; required_device ramdac; required_device bpu; std::unique_ptr buffer; std::unique_ptr 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 >, const offs_t offset) const; + void buffer_write(const gt_t >, 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 >, 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(get_card_device()); + device_cbus_card_interface *dev = dynamic_cast(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(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(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(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(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(*device).set_out_irq0_callback(DEVCB_##_devcb); +#define MCFG_CBUS_OUT_IRQ0_CB(_devcb) \ + devcb = &downcast(*device).set_out_irq0_callback(DEVCB_##_devcb); -#define MCFG_SR_OUT_IRQ1_CB(_devcb) \ - devcb = &downcast(*device).set_out_irq1_callback(DEVCB_##_devcb); +#define MCFG_CBUS_OUT_IRQ1_CB(_devcb) \ + devcb = &downcast(*device).set_out_irq1_callback(DEVCB_##_devcb); -#define MCFG_SR_OUT_IRQ2_CB(_devcb) \ - devcb = &downcast(*device).set_out_irq2_callback(DEVCB_##_devcb); +#define MCFG_CBUS_OUT_IRQ2_CB(_devcb) \ + devcb = &downcast(*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(*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(*device).set_sr_slot(_srtag, _tag); + downcast(*device).set_tags(_bus_tag, _slot_tag); + +#define MCFG_CBUS_MEMORY(_tag, _main_spacenum, _io_spacenum) \ + downcast(*device).set_memory(_tag, _main_spacenum, _io_spacenum); + + +#define MCFG_SRX_OUT_IRQ0_CB(_devcb) \ + devcb = &downcast(*device).set_out_irq0_callback(DEVCB_##_devcb); + +#define MCFG_SRX_OUT_IRQ1_CB(_devcb) \ + devcb = &downcast(*device).set_out_irq1_callback(DEVCB_##_devcb); + +#define MCFG_SRX_OUT_IRQ2_CB(_devcb) \ + devcb = &downcast(*device).set_out_irq2_callback(DEVCB_##_devcb); + +#define MCFG_SRX_OUT_VBLANK_CB(_devcb) \ + devcb = &downcast(*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(*device).set_tags(_bus_tag, _slot_tag); -#define MCFG_SR_MEMORY(_tag, _main_spacenum, _io_spacenum) \ - downcast(*device).set_memory(_tag, _main_spacenum, _io_spacenum); +#define MCFG_SRX_MEMORY(_tag, _main_spacenum, _io_spacenum) \ + downcast(*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 devcb_base &set_out_irq0_callback(Object &&cb) { return m_out_irq0_cb.set_callback(std::forward(cb)); } template devcb_base &set_out_irq1_callback(Object &&cb) { return m_out_irq1_cb.set_callback(std::forward(cb)); } template devcb_base &set_out_irq2_callback(Object &&cb) { return m_out_irq2_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_vblank_callback(Object &&cb) { return m_out_vblank_cb.set_callback(std::forward(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 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 devcb_base &set_out_irq0_callback(Object &&cb) { return m_out_irq0_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_irq1_callback(Object &&cb) { return m_out_irq1_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_irq2_callback(Object &&cb) { return m_out_irq2_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_vblank_callback(Object &&cb) { return m_out_vblank_cb.set_callback(std::forward(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 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 T *get_card() + { + for (auto device : m_slot) + if (dynamic_cast(device) != nullptr) + return dynamic_cast(device); + + return nullptr; + } + + template 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 m_d_cammu; + required_device m_i_cammu; + required_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 // ???? -- cgit v1.2.3