From 809a58d21d26b1e2035d04ad2f5a4dfb71593481 Mon Sep 17 00:00:00 2001 From: arbee Date: Sat, 8 Sep 2018 12:05:10 -0400 Subject: decstation: Emulated accelerated quasi-blitter enough to get a working console [R. Belmont] --- src/mame/drivers/decstation.cpp | 270 +++++++++++++++++++++++++++++++--------- 1 file changed, 210 insertions(+), 60 deletions(-) diff --git a/src/mame/drivers/decstation.cpp b/src/mame/drivers/decstation.cpp index b7316cd3314..a1e5d6a7834 100644 --- a/src/mame/drivers/decstation.cpp +++ b/src/mame/drivers/decstation.cpp @@ -4,10 +4,10 @@ decstation.cpp: MIPS-based DECstation family - WANTED: all boot ROM dumps except 5000/133, all TURBOchannel card ROM dumps + WANTED: boot ROM dumps for KN02CA/KN04CA (MAXine) systems. - NOTE: after all the spew of failing tests (it really wants a VT102 terminal), - press 'q' at the MORE prompt and wait a few seconds for the PROM monitor to appear. + NOTE: after all the spew of failing tests, press 'q' at the MORE prompt and + wait a few seconds for the PROM monitor to appear. Type 'ls' for a list of commands (this is a very UNIX-flavored PROM monitor). Machine types: @@ -19,9 +19,9 @@ Ethernet: AMD7990 "LANCE" controller Monochrome or color video on-board PMIN/KN01: - Cheaper PMAX, 12.5 MHz R2000, same as PMAX + Cheaper PMAX, 12.5 MHz R2000, othersame as PMAX - Personal DECstation 5000/xx (MAXine/KN02BA): + Personal DECstation 5000/xx (MAXine/KN02CA for R3000, KN04CA? for R4000) 20, 25, or 33 MHz R3000 or 100 MHz R4000 40 MiB max RAM Serial: DEC "DZ" quad-UART for keyboard/mouse, SCC8530 for modem/printer @@ -31,7 +31,7 @@ Color 1024x768 8bpp video on-board 2 TURBOchannel slots - DECstation 5000/1xx: (3MIN/KN02DA): + DECstation 5000/1xx: (3MIN/KN02BA, KN04BA? for R4000): 20, 25, or 33 MHz R3000 or 100 MHz R4000 128 MiB max RAM Serial: 2x SCC8530 @@ -47,7 +47,7 @@ SCSI: NCR53C94 Ethernet: AMD7990 "LANCE" controllor - DECstation 5000/240, 5000/261 (3MAX+/KN03) + DECstation 5000/240 (3MAX+/KN03AA), 5000/260 (3MAX+/KN05) 40 MHz R3400, or 120 MHz R4400. 480 MiB max RAM Serial: 2x SCC8530 @@ -58,6 +58,7 @@ #include "emu.h" #include "cpu/mips/r3000.h" +#include "cpu/mips/mips3.h" #include "machine/decioga.h" #include "machine/mc146818.h" #include "machine/z80scc.h" @@ -65,7 +66,10 @@ #include "machine/nscsi_bus.h" #include "machine/nscsi_cd.h" #include "machine/nscsi_hd.h" +#include "machine/dec_lk201.h" #include "bus/rs232/rs232.h" +#include "screen.h" +#include "video/bt459.h" class decstation_state : public driver_device { @@ -73,14 +77,18 @@ public: decstation_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_lk201(*this, "lk201"), m_ioga(*this, "ioga"), m_rtc(*this, "rtc"), m_scc0(*this, "scc0"), m_scc1(*this, "scc1"), - m_asc(*this, "scsibus:7:asc") + m_asc(*this, "scsibus:7:asc"), + m_vrom(*this, "gfx"), + m_bt459(*this, "bt459") { } - void kn02da(machine_config &config); + void kn02ba(machine_config &config); void init_decstation(); @@ -95,65 +103,101 @@ protected: private: virtual void machine_start() override; virtual void machine_reset() override; + virtual void video_start() override; + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); required_device m_maincpu; + required_device m_screen; + required_device m_lk201; required_device m_ioga; required_device m_rtc; required_device m_scc0, m_scc1; required_device m_asc; + required_memory_region m_vrom; + required_device m_bt459; + + void threemin_map(address_map &map); - void decstation_map(address_map &map); + uint8_t *m_vrom_ptr; + uint32_t m_vram[0x200000/4]; + uint32_t m_sfb[0x80]; + int m_copy_src; }; /*************************************************************************** VIDEO HARDWARE ***************************************************************************/ +void decstation_state::video_start() +{ +} + +uint32_t decstation_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + m_bt459->screen_update(screen, bitmap, cliprect, (uint8_t *)&m_vram[0]); + return 0; +} + +/* + 0x100000 copy register 0 + 0x100004 copy register 1 + 0x100008 copy register 2 + 0x10000C copy register 3 + 0x100010 copy register 4 + 0x100014 copy register 5 + 0x100018 copy register 6 + 0x10001C copy register 7 + 0x100020 foreground register + 0x100024 background register + 0x100028 plane mask + 0x10002C pixel mask + 0x100030 cxt mode + 0x100034 boolean operation + 0x100038 pixel shift + 0x10003C line address + 0x100040 bresh 1 + 0x100044 bresh 2 + 0x100048 bresh 3 + 0x10004C bresh continue + 0x100050 deep register + 0x100054 start register + 0x100058 Clear Interrupt + 0x10005C reserved 2 + 0x100060 refresh count + 0x100064 video horiz + 0x100068 video vertical + 0x10006C refresh base + 0x100070 video valid + 0x100074 Interrupt Enable +*/ + +#define MODE_SIMPLE 0 +#define MODE_OPAQUESTIPPLE 1 +#define MODE_OPAQUELINE 2 +#define MODE_TRANSPARENTSTIPPLE 5 +#define MODE_TRANSPARENTLINE 6 +#define MODE_COPY 7 + READ32_MEMBER(decstation_state::cfb_r) { - static const char fwver[8] = "V5.3a "; - static const char fwvendor[8] = "DEC "; - static const char fwmodule[8] = "PMAG-BA"; - static const char fwtype[8] = "TCF0 "; - static const char fwinfo[8] = "CX - D8"; uint32_t addr = offset << 2; - logerror("cfb_r: reading at %x\n", addr); +// logerror("cfb_r: reading at %x\n", addr); - // attempt to fake the ROM ID bytes of a PMAG-BA - // color framebuffer card. doesn't work for unknown reasons. - if ((addr >= 0x3c0400) && (addr < 0x3c0420)) - { - return fwver[(addr>>2)&0x7]; - } - if ((addr >= 0x3c0420) && (addr < 0x3c0440)) - { - return fwvendor[(addr>>2)&0x7]; - } - if ((addr >= 0x3c0440) && (addr < 0x3c0460)) - { - return fwmodule[(addr>>2)&0x7]; - } - if ((addr >= 0x3c0460) && (addr < 0x3c0480)) + if (addr < 0x800000) { - return fwtype[(addr>>2)&0x7]; + return m_vrom_ptr[addr>>2] & 0xff; } - if ((addr >= 0x3c0480) && (addr < 0x3c04a0)) + + if ((addr >= 0x100000) && (addr < 0x100200)) { - return fwinfo[(addr>>2)&0x7]; + return m_sfb[offset-(0x100000/4)]; } - switch (addr) + if ((addr >= 0x200000) && (addr < 0x400000)) { - case 0x3c03e0: return 1; // ROM width - case 0x3c03e4: return 4; // ROM stride - case 0x3c03e8: return 1; // ROM size in 8 KiB units - case 0x3c03ec: return 1; // card address space in 4 MiB units - case 0x3c03f0: return 0x55555555; // TURBOchannel ID bytes - case 0x3c03f4: return 0x00000000; - case 0x3c03f8: return 0xaaaaaaaa; - case 0x3c03fc: return 0xffffffff; - case 0x3c0470: return 0; // does card support parity? + return m_vram[offset-(0x200000/4)]; } return 0xffffffff; @@ -161,7 +205,93 @@ READ32_MEMBER(decstation_state::cfb_r) WRITE32_MEMBER(decstation_state::cfb_w) { - logerror("cfb: %08x (mask %08x) @ %x\n", data, mem_mask, offset); + uint32_t addr = offset << 2; + + if ((addr >= 0x100000) && (addr < 0x100200)) + { + //printf("SFB: %08x (mask %08x) @ %x\n", data, mem_mask, offset<<2); + COMBINE_DATA(&m_sfb[offset-(0x100000/4)]); + + if ((addr == 0x100030) && (data = 7)) + { + m_copy_src = 1; + } + return; + } + + if ((addr >= 0x1c0000) && (addr < 0x200000)) + { + //printf("Bt459: %08x (mask %08x) @ %x\n", data, mem_mask, offset<<2); + return; + } + + if ((addr >= 0x200000) && (addr < 0x400000)) + { + //printf("FB: %08x (mask %08x) @ %x\n", data, mem_mask, offset<<2); + + switch (m_sfb[0x30/4]) + { + case MODE_SIMPLE: // simple + COMBINE_DATA(&m_vram[offset-(0x200000/4)]); + break; + + case MODE_TRANSPARENTSTIPPLE: + { + uint8_t *pVRAM = (uint8_t *)&m_vram[offset-(0x200000/4)]; + uint8_t fgs[4]; + + fgs[0] = m_sfb[0x20/4] >> 24; + fgs[1] = (m_sfb[0x20/4] >> 16) & 0xff; + fgs[2] = (m_sfb[0x20/4] >> 8) & 0xff; + fgs[3] = m_sfb[0x20/4] & 0xff; + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pVRAM[x] = fgs[x & 3]; + } + } + } + break; + + case MODE_COPY: + { + uint8_t *pVRAM = (uint8_t *)&m_vram[offset-(0x200000/4)]; + uint8_t *pBuffer = (uint8_t *)&m_sfb[0]; // first 8 32-bit regs are the copy buffer + + if (m_copy_src) + { + m_copy_src = 0; + + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pBuffer[x] = pVRAM[x]; + } + } + } + else + { + m_copy_src = 1; + + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pVRAM[x] = pBuffer[x]; + } + } + } + } + break; + + default: + logerror("SFB: Unsupported VRAM write %08x (mask %08x) at %08x in mode %x\n", data, mem_mask, offset<<2, m_sfb[0x30/4]); + break; + } + return; + } } /*************************************************************************** @@ -170,20 +300,26 @@ WRITE32_MEMBER(decstation_state::cfb_w) void decstation_state::machine_start() { + m_vrom_ptr = m_vrom->base(); + save_item(NAME(m_vram)); + save_item(NAME(m_sfb)); + save_item(NAME(m_copy_src)); } void decstation_state::machine_reset() { + m_copy_src = 1; } /*************************************************************************** ADDRESS MAPS ***************************************************************************/ -void decstation_state::decstation_map(address_map &map) +void decstation_state::threemin_map(address_map &map) { map(0x00000000, 0x07ffffff).ram(); // full 128 MB - map(0x10000000, 0x103cffff).rw(FUNC(decstation_state::cfb_r), FUNC(decstation_state::cfb_w)); + map(0x10000000, 0x13ffffff).rw(FUNC(decstation_state::cfb_r), FUNC(decstation_state::cfb_w)); + map(0x101c0000, 0x101c000f).m("bt459", FUNC(bt459_device::map)).umask32(0x000000ff); map(0x1c000000, 0x1c07ffff).m(m_ioga, FUNC(dec_ioga_device::map)); map(0x1c100000, 0x1c100003).rw(m_scc0, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w)).umask32(0x0000ff00); map(0x1c100004, 0x1c100007).rw(m_scc0, FUNC(z80scc_device::da_r), FUNC(z80scc_device::da_w)).umask32(0x0000ff00); @@ -216,13 +352,19 @@ static void dec_scsi_devices(device_slot_interface &device) device.option_add_internal("asc", NCR53C94); } -MACHINE_CONFIG_START(decstation_state::kn02da) +MACHINE_CONFIG_START(decstation_state::kn02ba) MCFG_DEVICE_ADD( "maincpu", R3041, 33000000 ) // FIXME: Should be R3000A MCFG_R3000_ENDIANNESS(ENDIANNESS_LITTLE) MCFG_R3000_BRCOND0_INPUT(READLINE(*this, decstation_state, brcond0_r)) - MCFG_DEVICE_PROGRAM_MAP( decstation_map ) + MCFG_DEVICE_PROGRAM_MAP( threemin_map ) + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(130000000, 1704, 32, (1280+32), 1064, 3, (1024+3)); + m_screen->set_screen_update(FUNC(decstation_state::screen_update)); - MCFG_DEVICE_ADD("ioga", DECSTATION_IOGA, XTAL(12'500'000)) + BT459(config, m_bt459, 83'020'800); + + DECSTATION_IOGA(config, m_ioga, XTAL(12'500'000)); MC146818(config, m_rtc, XTAL(32'768)); m_rtc->irq().set("ioga", FUNC(dec_ioga_device::rtc_irq_w)); @@ -230,21 +372,25 @@ MACHINE_CONFIG_START(decstation_state::kn02da) SCC85C30(config, m_scc0, XTAL(14'745'600)/2); //m_scc0->out_int_callback().set("ioga", FUNC(dec_ioga_device::scc0_irq_w)); + m_scc0->out_txda_callback().set("rs232a", FUNC(rs232_port_device::write_txd)); + m_scc0->out_txdb_callback().set("rs232b", FUNC(rs232_port_device::write_txd)); SCC85C30(config, m_scc1, XTAL(14'745'600)/2); //m_scc1->out_int_callback().set("ioga", FUNC(dec_ioga_device::scc1_irq_w)); - m_scc1->out_txda_callback().set("rs232a", FUNC(rs232_port_device::write_txd)); - m_scc1->out_txdb_callback().set("rs232b", FUNC(rs232_port_device::write_txd)); + m_scc1->out_txdb_callback().set("lk201", FUNC(lk201_device::rx_w)); + + MCFG_DEVICE_ADD("lk201", LK201, 0) + MCFG_LK201_TX_HANDLER(WRITELINE("scc1", z80scc_device, rxb_w)) - MCFG_DEVICE_ADD("rs232a", RS232_PORT, default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(WRITELINE("scc1", z80scc_device, rxa_w)) - MCFG_RS232_DCD_HANDLER(WRITELINE("scc1", z80scc_device, dcda_w)) - MCFG_RS232_CTS_HANDLER(WRITELINE("scc1", z80scc_device, ctsa_w)) + MCFG_DEVICE_ADD("rs232a", RS232_PORT, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(WRITELINE("scc0", z80scc_device, rxa_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("scc0", z80scc_device, dcda_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("scc0", z80scc_device, ctsa_w)) MCFG_DEVICE_ADD("rs232b", RS232_PORT, default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(WRITELINE("scc1", z80scc_device, rxb_w)) - MCFG_RS232_DCD_HANDLER(WRITELINE("scc1", z80scc_device, dcdb_w)) - MCFG_RS232_CTS_HANDLER(WRITELINE("scc1", z80scc_device, ctsb_w)) + MCFG_RS232_RXD_HANDLER(WRITELINE("scc0", z80scc_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("scc0", z80scc_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("scc0", z80scc_device, ctsb_w)) MCFG_NSCSI_BUS_ADD("scsibus") MCFG_NSCSI_ADD("scsibus:0", dec_scsi_devices, "harddisk", false) @@ -275,8 +421,12 @@ void decstation_state::init_decstation() ROM_START( ds5k133 ) ROM_REGION32_LE( 0x40000, "user1", 0 ) + // 5.7j sx ROM_LOAD( "ds5000-133_005eb.bin", 0x000000, 0x040000, CRC(76a91d29) SHA1(140fcdb4fd2327daf764a35006d05fabfbee8da6) ) + + ROM_REGION32_LE( 0x20000, "gfx", 0 ) + ROM_LOAD( "pmagb-ba-rom.img", 0x000000, 0x020000, CRC(91f40ab0) SHA1(a39ce6ed52697a513f0fb2300a1a6cf9e2eabe33) ) ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1992, ds5k133, 0, 0, kn02da, decstation, decstation_state, init_decstation, "Digital Equipment Corporation", "DECstation 5000/133", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1992, ds5k133, 0, 0, kn02ba, decstation, decstation_state, init_decstation, "Digital Equipment Corporation", "DECstation 5000/133", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -- cgit v1.2.3