mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
decstation: Emulated accelerated quasi-blitter enough to get a working console [R. Belmont]
This commit is contained in:
parent
a24d9ab6ae
commit
809a58d21d
@ -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<cpu_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<lk201_device> m_lk201;
|
||||
required_device<dec_ioga_device> m_ioga;
|
||||
required_device<mc146818_device> m_rtc;
|
||||
required_device<z80scc_device> m_scc0, m_scc1;
|
||||
required_device<ncr53c94_device> m_asc;
|
||||
required_memory_region m_vrom;
|
||||
required_device<bt459_device> m_bt459;
|
||||
|
||||
void decstation_map(address_map &map);
|
||||
void threemin_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))
|
||||
if (addr < 0x800000)
|
||||
{
|
||||
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))
|
||||
{
|
||||
return fwtype[(addr>>2)&0x7];
|
||||
}
|
||||
if ((addr >= 0x3c0480) && (addr < 0x3c04a0))
|
||||
{
|
||||
return fwinfo[(addr>>2)&0x7];
|
||||
return m_vrom_ptr[addr>>2] & 0xff;
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
if ((addr >= 0x100000) && (addr < 0x100200))
|
||||
{
|
||||
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_sfb[offset-(0x100000/4)];
|
||||
}
|
||||
|
||||
if ((addr >= 0x200000) && (addr < 0x400000))
|
||||
{
|
||||
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 )
|
||||
|
||||
MCFG_DEVICE_ADD("ioga", DECSTATION_IOGA, XTAL(12'500'000))
|
||||
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));
|
||||
|
||||
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("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("lk201", LK201, 0)
|
||||
MCFG_LK201_TX_HANDLER(WRITELINE("scc1", z80scc_device, rxb_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 )
|
||||
|
Loading…
Reference in New Issue
Block a user