diff options
Diffstat (limited to 'src/devices/bus/interpro/sr/edge.cpp')
-rw-r--r-- | src/devices/bus/interpro/sr/edge.cpp | 774 |
1 files changed, 774 insertions, 0 deletions
diff --git a/src/devices/bus/interpro/sr/edge.cpp b/src/devices/bus/interpro/sr/edge.cpp new file mode 100644 index 00000000000..80c8fc6e0f9 --- /dev/null +++ b/src/devices/bus/interpro/sr/edge.cpp @@ -0,0 +1,774 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An emulation of Extensible Display Geometry Engine (EDGE) graphics, for + * Intergraph InterPro systems. + * + * TODO + * - this is a WIP checkpoint, very little is working + * - dumb framebuffer is working in 8bpp mode + * - missing dumps for EDGE-2 EPROMs + * + * List of EDGE graphics cards: + * + * 004 EDGE-2 Processor f/2 2Mp-FB's + * 009 EDGE II Frame Buffer for ImageStation + * 030 EDGE-2 Processor f/1 or 2 1Mp-FB's + * 031 EDGE-2 Processor f/1 2Mp-FB + * 093 EDGE-2 Plus Processor f/1 or 2 1Mp-FB's + * 094 EDGE-2 Plus Processor f/1 2Mp-FB + * 095 EDGE-2 Plus Processor f/2 2Mp-FB's + * 096 EDGE-2 Plus Frame Buffer f/1Mp Monitor + * 828 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) + * 849 EDGE-1 Graphics f/1 2Mp Monitor (55K/60) + * 896 EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60) + * 897 EDGE-2 Processor f/1 2Mp-FB + * 904 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) + * 965 EDGE-1 Graphics f/1 1Mp Monitor (66K/72) + * 966 EDGE-1 Graphics f/2 1Mp Monitors (66K/72) + * A63 EDGE-2 Frame Buffer f/1Mp Monitor (55K/60) + * B15 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) -T + * B16 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) -T + * + * EDGE-1 (PCB828) + * + * Ref Part Function + * U126 TMS320C30GBL DSP + * U173 ST D9026 SRX bus interface? + * MKJF03WG-00 C + * CICD7140A + * U214 Z8530H-6JC Keyboard/tablet serial controller + * U212 DP8510V Bitblt unit + * U229 DP8510V Bitblt unit + * U221 Bt 458KG110 RAMDAC + * U247 80.0208 MHz crystal Pixel clock source + * Y1 30.0 MHz crystal DSP clock source + * Y2 4.9152 MHz crystal SCC clock source + * TC55417P-25H 16Kx4 static RAM (16 parts, total 128KiB) + * Am7202-25RC 1024x9 FIFO (4 parts) + * TC524258AZ-10 256Kx4 VRAM (20 parts, total 2560KiB) + * + * EDGE-2 Plus Processor (SMT094) + * + * Ref Part Function + * U45 Zilog Z0853006VSC SCC Serial controller + * U49 Intergraph CICD87307 + * 202100 + * U94 NS SCX6B64ABM/NU6 + * U107 VLSI CICD93708 + * VGT8203C4588 + * U132 VLSI CICD93809 + * 8207C4587 + * U133 TMS320C30GBL DSP + * U134 ST ZDD0J131 SRX bus interface? + * MKJF03WG-00 C + * CICD7140A + * Z104463BA + * U191 NS SCX6B86ABN/NU6 + * U201 TMX320C30GEL40 DSP + * U206? MPRGP020A 31 MAR 92 EPROM + * U207? MPRGP010A 04 01 92 EPROM + * U222 MPRGP060B 16 MAR 92 EPROM + * U239 MPRGP050B APR 02 92 EPROM + * U306 MPRGP080B APR 02 92 EPROM + * U310 MPRGP070B APR 02 92 EPROM + * U313 MPRGP040B APR 02 92 EPROM + * U303 TMX320C30GEL40 DSP + * Y1 4.915200MHz crystal + * Y2 66.666700MHz crystal + * Y3 33.3333MHz crystal + * Y4? 40.0MHz crystal + * + * EDGE-2 Plus Frame Buffer (PCB896) + * + * Ref Part Function + * U11 CICD87408 TC110G14AY + * U336 Brooktree PS045701-165 Single-channel RAMDAC (blue) + * U337 Brooktree PS045701-165 Single-channel RAMDAC (green) + * U338 Brooktree PS045701-165 Single-channel RAMDAC (red) + * U340 Brooktree Bt439KC Clock generator and synchronizer + * U360 164.609300MHz crystal Pixel clock + * + * MCM6294P20 16Kx4 Bit Synchronous Static RAM (total 256KiB) + * U233-240 group 1, 8 parts = 16Kx32 + * U300-323 group 2, 24 parts = 16Kx32x3 + * + * Processor board idprom feature byte 0 contains various flags: + * + * if ((id->i_feature[0] & 0x04) == 0) + * EDGctrl.c_flag |= EDGEII_PLUS; + * + * On the frame buffer: + * if (id->i_feature[0] & 3 == 0) EDGE_M2_1MPIX else EDGE_M2_2MPIX + */ + +/* + * Work in progress notes (EDGE-2 Plus) + * + * processor board: 0x8f008000 + * 000 mouse/interrupt + * + * 008 mouse X + * 00c mouse Y + * 010 scc chan B control (tablet) + * 014 scc chan A control (keyboard) + * 018 scc chan B data (tablet) + * 01c scc chan A data (keyboard) + * + * SRX bus registers + * 100 system control + * 104 system status + * 108 SRX input fifo (W/O) + * 10c SRX kernel + * 110 SRX mapping (W/O) + * 114 SRX attention + * + * 130 ififo low water mark (W/O) + * 134 ififo high water mark (W/O) + * + * ff80 idprom + * + * SRX region 4 + * SRreg4 = 0x90000000 // Emerald uses 0xbf000000-0xffffffff + * SRreg4 + 0x02028298 - virtual contrast register + * SRreg4 + 0x02028088 - base address/fb enable? + * SRreg4 += 0x04000000 // 64M - 32M memory, 32M regs? + + * 0x90000000 256kB static ram (end address 0x9003ffff) + * video ram? + * + * 0x91000000-0x91ffffff == 16 megabytes, probably video ram, where is the remaining 2M? + * + * 0x92028000 + * 084 <- 0 + * 088 base address/fb enable <- 0, 8, 9, a, b (typically reads from 92028300 after writing)? + * bottom 2 bits are board select? + * 098 <- 0x00ffffff + * 0x92028100 + * 0x92028200 - framebuffer board + * 200 idprom + * 280 RAMDAC addr reg + * 284 RAMDAC CPAL reg - colour palette + * 288 RAMDAC ctrl reg + * 28c RAMDAC OPAL reg - overlay palette + * 290 lookup table select reg + * 294 pixel tag LUT context reg + * 298 contrast reg + * + * 0x92028300 - ? + * 300 = 1, r/w + * 304 read in a loop waiting for value & 0x1000 == 0 + * 354 = ff + * + * 0x92028400 - processor board (P-bus?) + * 400 P-bus status (maybe shifted attention bits?), 0x1000 == KREG IN FULL + * 404 pipeline ctrl/sts + * 408 kernel + * 40c IFIFO (integer) + * 500 SRX master data + * 504 SRX master addr + * 508 SRX master attn/ctrl + * 50c IFIFO (floating point) + * + * 0x92030000 - unknown at least 256 dwords + * + * RE - render engine + * ILUT - inverse LUT? + * ISQLUT - inverse square root LUT + * + * FIFO 2, FIFO 3, render FIFO + * P-bus, S-bus, R-bus + * static RAM + * + * P-bus == TMS320C30 peripheral/primary bus? + * C30 has primary (24 bit address) and expansion (13 bit address) bus, both 32 bit data + * + * peripheral bus is internal (serial and timers) + * + * sram test at 5a76ec, sub_5a765c, sub_5a76b0(ram size in dwords) + * video ram test at sub_5a7ad0 + * address 5a33de, 5a2dbc + */ + +#include "emu.h" +#include "edge.h" + +#define LOG_GENERAL (1U << 0) + +#define VERBOSE (LOG_GENERAL) + +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(MPCB828, mpcb828_device, "mpcb828", "EDGE-1 Graphics f/1 1Mp Monitor (55K/60)") +DEFINE_DEVICE_TYPE(MPCB849, mpcb849_device, "mpcb849", "EDGE-1 Graphics f/1 2Mp Monitor (55K/60)") +DEFINE_DEVICE_TYPE(MPCB030, mpcb030_device, "mpcb030", "EDGE-2 Processor f/1 or 2 1Mp-FB's") +DEFINE_DEVICE_TYPE(MPCBA63, mpcba63_device, "mpcba63", "EDGE-2 Frame Buffer f/1Mp Monitor (55K/60)") +DEFINE_DEVICE_TYPE(MSMT094, msmt094_device, "msmt094", "EDGE-2 Plus Processor f/1 2Mp-FB") +DEFINE_DEVICE_TYPE(MPCB896, mpcb896_device, "mpcb896", "EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60)") + +void edge1_device_base::map(address_map &map) +{ + srx_card_device_base::map(map); + + /* + * ODT reports + * 000 user 1 mouse/interrupt + * 008 user 1 mouse X counter + * 00c user 1 mouse Y counter + * 020 user 2 mouse/interrupt + * 028 user 2 mouse X counter + * 02c user 2 mouse Y counter + * 100 system control + * 104 system status + * 108 input FIFO (W/O) + * 10c kernel + * 110 mapping (W/O) + * 114 attention + */ + map(0x000, 0x003).rw(this, FUNC(edge1_device_base::reg0_r), FUNC(edge1_device_base::reg0_w)); + + map(0x010, 0x01f).rw("scc", FUNC(z80scc_device::cd_ab_r), FUNC(z80scc_device::cd_ab_w)).umask32(0x000000ff); + + map(0x100, 0x103).rw(this, FUNC(edge1_device_base::control_r), FUNC(edge1_device_base::control_w)); + map(0x104, 0x107).rw(this, FUNC(edge1_device_base::status_r), FUNC(edge1_device_base::status_w)); + map(0x108, 0x10b).rw(this, FUNC(edge1_device_base::fifo_r), FUNC(edge1_device_base::fifo_w)); + map(0x10c, 0x10f).rw(this, FUNC(edge1_device_base::kernel_r), FUNC(edge1_device_base::kernel_w)); + + map(0x114, 0x117).rw(this, FUNC(edge1_device_base::attention_r), FUNC(edge1_device_base::attention_w)); + + map(0x130, 0x133).w(this, FUNC(edge1_device_base::ififo_lwm_w)); + map(0x134, 0x137).w(this, FUNC(edge1_device_base::ififo_hwm_w)); +} + +void edge1_device_base::map_dynamic(address_map &map) +{ + // TODO: map using lambdas until mixed-size submaps work + map(0x00000000, 0x0001ffff).lrw8("sram", + [this](address_space &space, offs_t offset, u8 mem_mask) { return m_sram->read(offset); }, + [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_sram->write(offset, data); }); + + map(0x01000000, 0x013fffff).lrw8("vram", + [this](address_space &space, offs_t offset, u8 mem_mask) { return m_vram->read((offset >> 2) | (offset & 0x3)); }, + [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_vram->write((offset >> 2) | (offset & 0x3), data); }); + + //map(0x02028200, 0x0202827f).lr32("idprom", + // [this](address_space &space, offs_t offset, u8 mem_mask) { return memregion("idprom")->as_u32(offset); }); + + map(0x02410000, 0x0241000f).m("ramdac", FUNC(bt458_device::map)).umask32(0x000000ff); + + // 0x02400004 + // 0x02400088 + // 0x0240008c + // 0x02400008 + // 0x02400098 - contrast + + // 0x02410014 + // 0x02410018 - ramdac/screen/buffer select? + // 0x02410040 - reg0? +} + +void edge2_processor_device_base::map(address_map &map) +{ + srx_card_device_base::map(map); + + map(0x100, 0x103).nopr(); // control + map(0x104, 0x107).nopr(); // status/attention + map(0x108, 0x10b).nopr(); // fifo + map(0x10c, 0x10f).nopr(); // kreg + + map(0x114, 0x117).nopr(); // status/interrupt + + map(0x130, 0x133).nopr(); // fifo low water mark + map(0x134, 0x137).nopr(); // fifo high water mark + + // SRreg4 = 0x90000000 + // SRreg4 + 0x02028298 - virtual contrast register + // SRreg4 + 0x02028088 - base address/fb enable? +} + +void edge2plus_processor_device_base::map(address_map &map) +{ + srx_card_device_base::map(map); + + map(0x000, 0x003).rw(this, FUNC(edge2plus_processor_device_base::reg0_r), FUNC(edge2plus_processor_device_base::reg0_w)); + + map(0x010, 0x01f).rw("scc", FUNC(z80scc_device::cd_ab_r), FUNC(z80scc_device::cd_ab_w)).umask32(0x000000ff); + + map(0x100, 0x103).rw(this, FUNC(edge2plus_processor_device_base::control_r), FUNC(edge2plus_processor_device_base::control_w)); + map(0x104, 0x107).rw(this, FUNC(edge2plus_processor_device_base::status_r), FUNC(edge2plus_processor_device_base::status_w)); + + map(0x10c, 0x10f).rw(this, FUNC(edge2plus_processor_device_base::kernel_r), FUNC(edge2plus_processor_device_base::kernel_w)); + map(0x110, 0x113).w(this, FUNC(edge2plus_processor_device_base::mapping_w)); + map(0x114, 0x117).rw(this, FUNC(edge2plus_processor_device_base::attention_r), FUNC(edge2plus_processor_device_base::attention_w)); + + map(0x130, 0x133).w(this, FUNC(edge2plus_processor_device_base::ififo_lwm_w)); + map(0x134, 0x137).w(this, FUNC(edge2plus_processor_device_base::ififo_hwm_w)); + + // 0x300 fifo + + + // scnxdiag only on II+ +} + +// NOTE: at boot, boards 0-3 are selected, and the idprom mirror probed - each valid idprom +// is identified as being an additional board. +void edge2plus_framebuffer_device_base::map_dynamic(address_map &map) +{ + // TODO: map using lambdas until mixed-size submaps work + + map(0x00000000, 0x0003ffff).lrw8("sram", + [this](address_space &space, offs_t offset, u8 mem_mask) { return m_sram->read(offset); }, + [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_sram->write(offset, data); }); + + map(0x01000000, 0x01ffffff).lrw8("vram", + [this](address_space &space, offs_t offset, u8 mem_mask) { return m_vram->read(offset); }, + [this](address_space &space, offs_t offset, u8 data, u8 mem_mask) { m_vram->write(offset, data); }); + + map(0x02028088, 0x0202808b).w(this, FUNC(edge2plus_framebuffer_device_base::select_w)); + + map(0x02028200, 0x0202827f).lr32("idprom", + [this](address_space &space, offs_t offset, u8 mem_mask) { return m_select == 0 ? memregion("idprom")->as_u32(offset) : space.unmap(); }); + + map(0x02028290, 0x02028293).w(this, FUNC(edge2plus_framebuffer_device_base::lut_select_w)); + map(0x02028300, 0x02028303).w(this, FUNC(edge2plus_framebuffer_device_base::unk_300_w)); + map(0x02028304, 0x02028307).r(this, FUNC(edge2plus_framebuffer_device_base::unk_304_r)); +} + +void edge2_framebuffer_device_base::map(address_map &map) +{ + srx_card_device_base::map(map); +} + +void edge2plus_framebuffer_device_base::map(address_map &map) +{ + srx_card_device_base::map(map); +} + +ROM_START(mpcb828) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb828d.bin", 0x0, 0x20, CRC(997c09f1) SHA1(5378e33ef62309bc0c8cbe9ccbd87fd871bdc195)) +ROM_END + +ROM_START(mpcb849) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb849a.bin", 0x0, 0x20, NO_DUMP) +ROM_END + +ROM_START(mpcb030) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb030a.bin", 0x0, 0x20, NO_DUMP) +ROM_END + +ROM_START(mpcba63) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcba63b.bin", 0x0, 0x20, NO_DUMP) +ROM_END + +ROM_START(msmt094) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("msmt0940.bin", 0x0, 0x20, CRC(55493b9e) SHA1(6e0668f7e85e1bb5b2ecc6e5a5ab53e5281f22e9)) +ROM_END + +ROM_START(mpcb896) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb896b.bin", 0x0, 0x20, CRC(c8d60037) SHA1(550aab8b0c8d85c9a69fe94ae042b6bb9f9d7db1)) +ROM_END + +/* +* MPCB828: EDGE-1 graphics, 1 megapixel, single screen, 60Hz refresh. +* +* Screen timings to match PCB963. +* +* "9 planes (1 for highlights) of double-buffered graphics, 256 colours from 16.7 million" +* 1024x1024x10x2 == 2621440 bytes == 2560KiB == 2.5MiB +* FIXME: diag reports 128KiB static ram, 1MiB video ram, 4 screens, 1 user, z-buffer absent +* +*/ +MACHINE_CONFIG_START(mpcb828_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + 20, 1184 + 296 + 20, 920, 34, 884 + 34) + //MCFG_SCREEN_RAW_PARAMS(83'020'800, 1184, 0, 1184, 884, 0, 884) + MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb828_device, screen_update) + MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank)) + + MCFG_DEVICE_ADD("sram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("128KiB") + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("vram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("2560KiB") + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("dsp", TMS32030, 1) // 30_MHz_XTAL + MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, mpcb828_device, holda)) + + MCFG_DEVICE_ADD("ramdac", BT458, 83'020'800) + + MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0) + MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, mpcb828_device, scc_irq)) + MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd)) + + MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us") + MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w)) +MACHINE_CONFIG_END + +/* + * MPCB849: EDGE-1 graphics, 2 megapixels, single screen, 60Hz refresh. + * + * System software gives visible pixels 1664x1248. Vertical refresh is assumed to + * be 60Hz, horizontal sync ~55kHz. + * + * Inputs htotal=? (1664+?) and vtotal=? (1248+?) give hsync=?kHz. + */ +MACHINE_CONFIG_START(mpcb849_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(164'609'300, 2112, 0, 1664, 1299, 0, 1248) + MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb849_device, screen_update) + MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank)) + + MCFG_DEVICE_ADD("sram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("128KiB") + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("vram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("5120KiB") // guess + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("dsp", TMS32030, 1) // 30_MHz_XTAL + MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, mpcb828_device, holda)) + + MCFG_DEVICE_ADD("ramdac", BT458, 0) // unconfirmed clock + + MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0) + MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, mpcb849_device, scc_irq)) + MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd)) + + MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us") + MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w)) +MACHINE_CONFIG_END + +/* + * MPCB030/MPCBA63: EDGE-2 graphics, 1 megapixel, single/dual screen, 60Hz refresh. + * + * System software gives visible pixels 1184x884. Vertical refresh is assumed to + * be 60Hz, horizontal sync ~55kHz. + * + * Inputs htotal=? (1184+?) and vtotal=? (884+?) give hsync=?kHz. + */ +MACHINE_CONFIG_START(mpcb030_device::device_add_mconfig) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(mpcba63_device::device_add_mconfig) + //MCFG_SCREEN_ADD("screen", RASTER) + // screen params copied from GT + //MCFG_SCREEN_RAW_PARAMS(83'020'800, 1504, 296 + 20, 1184 + 296 + 20, 920, 34, 884 + 34) + //MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcba63_device, screen_update) + //MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(?, vblank)) + //MCFG_DEVICE_ADD("ramdac0", BT457, 0) // PS045701-165 + //MCFG_DEVICE_ADD("ramdac0", BT457, 0) + //MCFG_DEVICE_ADD("ramdac0", BT457, 0) +MACHINE_CONFIG_END + +/* + * MSMT094/MPCB896: EDGE-2 Plus graphics, 2 megapixels, single screen, 60Hz refresh. + * + * System software gives visible pixels 1664x1248. Board documentation gives + * pixel clock 164.6093MHz. Vertical refresh is assumed to be 60Hz. + * + * Inputs htotal=2112 (1664+448) and vtotal=1299 (1248+51) give hsync=77.940kHz. + */ +MACHINE_CONFIG_START(msmt094_device::device_add_mconfig) + // FIXME: actually 33.333_MHz_XTAL + MCFG_DEVICE_ADD("dsp1", TMS32030, 1) + MCFG_TMS3203X_HOLDA_CB(WRITELINE(DEVICE_SELF, msmt094_device, holda)) + //MCFG_DEVICE_ADD("dsp2", TMS32030, 40_MHz_XTAL) + //MCFG_DEVICE_ADD("dsp3", TMS32030, 40_MHz_XTAL) + + // FIXME: actually Z0853006VSC + MCFG_SCC8530_ADD("scc", 4.9152_MHz_XTAL, 0, 0, 0, 0) + MCFG_Z80SCC_OUT_INT_CB(WRITELINE(DEVICE_SELF, msmt094_device, scc_irq)) + MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE("kbd", interpro_keyboard_port_device, write_txd)) + + MCFG_INTERPRO_KEYBOARD_PORT_ADD("kbd", interpro_keyboard_devices, "hle_en_us") + MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE("scc", z80scc_device, rxa_w)) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(mpcb896_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(164'609'300, 2112, 0, 1664, 1299, 0, 1248) + MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, mpcb896_device, screen_update) + MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(DEVICE_SELF, device_srx_card_interface, vblank)) + + MCFG_DEVICE_ADD("sram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("256KiB") + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("vram", RAM, 0) + MCFG_RAM_DEFAULT_SIZE("18MiB") + MCFG_RAM_DEFAULT_VALUE(0) + + MCFG_DEVICE_ADD("ramdac0", BT457, 164'609'300) + MCFG_DEVICE_ADD("ramdac1", BT457, 164'609'300) + MCFG_DEVICE_ADD("ramdac2", BT457, 164'609'300) +MACHINE_CONFIG_END + +edge1_device_base::edge1_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , srx_card_device_base(mconfig, *this) + , m_screen(*this, "screen") + , m_sram(*this, "sram") + , m_vram(*this, "vram") + , m_dsp(*this, "dsp") + , m_ramdac(*this, "ramdac") + , m_scc(*this, "scc") +{ +} + +edge2_processor_device_base::edge2_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , srx_card_device_base(mconfig, *this) +{ +} + +edge2plus_processor_device_base::edge2plus_processor_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , srx_card_device_base(mconfig, *this) + , m_dsp1(*this, "dsp1") + , m_screen(nullptr) +{ +} + +edge2_framebuffer_device_base::edge2_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , srx_card_device_base(mconfig, *this) +{ +} + +edge2plus_framebuffer_device_base::edge2plus_framebuffer_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , srx_card_device_base(mconfig, *this) + , m_screen(*this, "screen") + , m_sram(*this, "sram") + , m_vram(*this, "vram") + , m_ramdac(*this, "ramdac%u", 0U) +{ +} + +mpcb828_device::mpcb828_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge1_device_base(mconfig, MPCB828, tag, owner, clock) +{ +} + +mpcb849_device::mpcb849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge1_device_base(mconfig, MPCB849, tag, owner, clock) +{ +} + +mpcb030_device::mpcb030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge2_processor_device_base(mconfig, MPCB030, tag, owner, clock) +{ +} + +mpcba63_device::mpcba63_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge2_framebuffer_device_base(mconfig, MPCBA63, tag, owner, clock) +{ +} + +msmt094_device::msmt094_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge2plus_processor_device_base(mconfig, MSMT094, tag, owner, clock) +{ +} + +mpcb896_device::mpcb896_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : edge2plus_framebuffer_device_base(mconfig, MPCB896, tag, owner, clock) +{ +} + +const tiny_rom_entry *mpcb828_device::device_rom_region() const +{ + return ROM_NAME(mpcb828); +} + +const tiny_rom_entry *mpcb849_device::device_rom_region() const +{ + return ROM_NAME(mpcb849); +} + +const tiny_rom_entry *mpcb030_device::device_rom_region() const +{ + return ROM_NAME(mpcb030); +} + +const tiny_rom_entry *mpcba63_device::device_rom_region() const +{ + return ROM_NAME(mpcba63); +} + +const tiny_rom_entry *msmt094_device::device_rom_region() const +{ + return ROM_NAME(msmt094); +} + +const tiny_rom_entry *mpcb896_device::device_rom_region() const +{ + return ROM_NAME(mpcb896); +} + +void edge1_device_base::device_start() +{ + set_bus_device(); + + // FIXME: dynamically allocate SR region 4 + m_bus->install_map(*this, 0x90000000, 0x93ffffff, &edge1_device_base::map_dynamic); +} + +void edge2_processor_device_base::device_start() +{ + set_bus_device(); +} + +void edge2plus_processor_device_base::device_start() +{ + set_bus_device(); +} + +void edge2_framebuffer_device_base::device_start() +{ + set_bus_device(); +} + +void edge2plus_framebuffer_device_base::device_start() +{ + set_bus_device(); + + // find the processor board and notify it of our screen + edge2plus_processor_device_base *processor = m_bus->get_card<edge2plus_processor_device_base>(); + if (processor != nullptr) + { + LOG("found processor device %s\n", processor->tag()); + + processor->register_screen(m_screen); + } + + // FIXME: dynamically allocate SR region 4 + m_bus->install_map(*this, 0x90000000, 0x93ffffff, &edge2plus_framebuffer_device_base::map_dynamic); +} + +u32 mpcb849_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +u32 mpcba63_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +u32 edge1_device_base::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + u8 *pixel_data = m_vram->pointer(); + + // 8bpp mode + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = m_ramdac->pen_color(*pixel_data++); + + return 0; +} + +u32 edge2plus_framebuffer_device_base::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + u8 *pixel_data = m_vram->pointer(); + + // 8bpp mode + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + { + const u8 index = *pixel_data++; + + bitmap.pix(y, x) = rgb_t( + m_ramdac[0]->palette_lookup(index), + m_ramdac[1]->palette_lookup(index), + m_ramdac[2]->palette_lookup(index)); + } + + return 0; +} + +WRITE32_MEMBER(edge1_device_base::control_w) +{ + COMBINE_DATA(&m_control); + + // release dsp 1 hold + if (data & NO_HOLD) + m_dsp->set_input_line(TMS3203X_HOLD, CLEAR_LINE); + + // hold dsp 1 + if (!(data & DSP_1_HOLD_L)) + m_dsp->set_input_line(TMS3203X_HOLD, ASSERT_LINE); +} + +WRITE_LINE_MEMBER(edge1_device_base::holda) +{ + LOG("hold acknowledge %d\n", state); + + if (state) + { + m_status |= DSP_1_HOLDA_H; + + if (m_control & HOLD_ENB) + { + m_control |= HOLDA_INT_H; + + irq0(ASSERT_LINE); + } + } + else + m_status &= ~DSP_1_HOLDA_H; +} + +WRITE32_MEMBER(edge2plus_processor_device_base::control_w) +{ + COMBINE_DATA(&m_control); + + // release dsp 1 hold + if (data & NO_HOLD) + m_dsp1->set_input_line(TMS3203X_HOLD, CLEAR_LINE); + + // hold dsp 1 + if (!(data & DSP_1_HOLD_L)) + m_dsp1->set_input_line(TMS3203X_HOLD, ASSERT_LINE); +} + +WRITE_LINE_MEMBER(edge2plus_processor_device_base::holda) +{ + LOG("hold acknowledge %d\n", state); + + if (state) + { + m_status |= DSP_1_HOLDA_H; + + if (m_control & HOLD_ENB) + { + m_control |= HOLDA_INT_H; + irq0(ASSERT_LINE); + } + } + else + m_status &= ~DSP_1_HOLDA_H; +} + +WRITE32_MEMBER(edge2plus_framebuffer_device_base::lut_select_w) +{ + LOG("select ramdac %d\n", data); + + void (bt457_device::*map)(address_map &) = &bt457_device::map; + + // TODO: not sure what should happen for values > 2 + // FIXME: this should probably be some kind of bank device, including the idprom + m_bus->main_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8); + m_bus->io_space()->install_device(0x92028280U, 0x9202828fU, *m_ramdac[data % 3], map, 0xff, 8); + + // lookup table 3 enables address range 92030000-92030fff, written with zeroes +} |