summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2019-01-20 21:29:32 -0500
committer arbee <rb6502@users.noreply.github.com>2019-01-20 21:29:32 -0500
commit32703cfa5ae42c652cb62998106da267b2e97861 (patch)
tree34f1ce37a99b97d57063b349200fb0b8c04db3c3
parent3b88c56063f25c50285f5ed2a9705349400e099a (diff)
decstation: move SFB video chip to separate device for future AlphaAXP sharing [R. Belmont]
-rw-r--r--scripts/src/video.lua12
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/video/decsfb.cpp175
-rw-r--r--src/devices/video/decsfb.h38
-rw-r--r--src/mame/drivers/decstation.cpp137
5 files changed, 240 insertions, 123 deletions
diff --git a/scripts/src/video.lua b/scripts/src/video.lua
index 6db6cd104e1..3f78a2a154a 100644
--- a/scripts/src/video.lua
+++ b/scripts/src/video.lua
@@ -1148,3 +1148,15 @@ if (VIDEOS["PS2GS"]~=null) then
MAME_DIR .. "src/devices/video/ps2gs.h",
}
end
+
+--------------------------------------------------
+--
+--@src/devices/video/decsfb.h,VIDEOS["DECSFB"] = true
+--------------------------------------------------
+if (VIDEOS["DECSFB"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/video/decsfb.cpp",
+ MAME_DIR .. "src/devices/video/decsfb.h",
+ }
+end
+
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index d0abd8b8c0d..2b08275346e 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -374,6 +374,7 @@ VIDEOS["DP8510"] = true
VIDEOS["MB88303"] = true
VIDEOS["PS2GS"] = true
VIDEOS["PS2GIF"] = true
+VIDEOS["DECSFB"] = true
--------------------------------------------------
-- specify available machine cores
diff --git a/src/devices/video/decsfb.cpp b/src/devices/video/decsfb.cpp
new file mode 100644
index 00000000000..166cc98f62b
--- /dev/null
+++ b/src/devices/video/decsfb.cpp
@@ -0,0 +1,175 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+
+/*
+ * An emulation of the Digital Equipment Corporation SFB "Smart Frame Buffer" chip
+ *
+ * Used in:
+ *
+ * Accelerated TURBOChannel video cards for DECstations and AlphaStations
+ * On-board on some DECstations
+ * On-board on many AlphaStations
+ *
+ * Sources:
+ *
+ * http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-93-1.pdf
+ *
+ */
+
+#include "emu.h"
+#include "decsfb.h"
+
+#define MODE_SIMPLE 0
+#define MODE_OPAQUESTIPPLE 1
+#define MODE_OPAQUELINE 2
+#define MODE_TRANSPARENTSTIPPLE 5
+#define MODE_TRANSPARENTLINE 6
+#define MODE_COPY 7
+
+#define LOG_GENERAL (1U << 0)
+#define LOG_REG (1U << 1)
+#define LOG_IRQ (1U << 2)
+
+//#define VERBOSE (LOG_GENERAL|LOG_REG||LOG_IRQ)
+
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(DECSFB, decsfb_device, "decsfb", "Digital Equipment Corporation Smart Frame Buffer")
+
+decsfb_device::decsfb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, DECSFB, tag, owner, clock),
+ m_int_cb(*this)
+{
+}
+
+void decsfb_device::device_start()
+{
+ m_int_cb.resolve_safe();
+
+ save_item(NAME(m_vram));
+ save_item(NAME(m_regs));
+ save_item(NAME(m_copy_src));
+}
+
+void decsfb_device::device_reset()
+{
+ m_copy_src = 1;
+}
+
+/*
+ 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
+*/
+
+READ32_MEMBER(decsfb_device::read)
+{
+ return m_regs[offset];
+}
+
+WRITE32_MEMBER(decsfb_device::write)
+{
+ COMBINE_DATA(&m_regs[offset]);
+
+ if ((offset == (0x30/4)) && (data = 7))
+ {
+ m_copy_src = 1;
+ }
+}
+
+READ32_MEMBER(decsfb_device::vram_r)
+{
+ return m_vram[offset];
+}
+
+WRITE32_MEMBER(decsfb_device::vram_w)
+{
+ switch (m_regs[0x30/4])
+ {
+ case MODE_SIMPLE: // simple
+ COMBINE_DATA(&m_vram[offset]);
+ break;
+
+ case MODE_TRANSPARENTSTIPPLE:
+ {
+ uint8_t *pVRAM = (uint8_t *)&m_vram[offset];
+ uint8_t fgs[4];
+
+ fgs[0] = m_regs[0x20/4] >> 24;
+ fgs[1] = (m_regs[0x20/4] >> 16) & 0xff;
+ fgs[2] = (m_regs[0x20/4] >> 8) & 0xff;
+ fgs[3] = m_regs[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];
+ uint8_t *pBuffer = (uint8_t *)&m_regs[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_regs[0x30/4]);
+ break;
+ }
+}
diff --git a/src/devices/video/decsfb.h b/src/devices/video/decsfb.h
new file mode 100644
index 00000000000..52e6687ea40
--- /dev/null
+++ b/src/devices/video/decsfb.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+
+#ifndef MAME_VIDEO_DECSFB_H
+#define MAME_VIDEO_DECSFB_H
+
+#pragma once
+
+class decsfb_device : public device_t
+{
+public:
+ decsfb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto int_cb() { return m_int_cb.bind(); }
+
+ DECLARE_READ32_MEMBER( read );
+ DECLARE_WRITE32_MEMBER( write );
+ DECLARE_READ32_MEMBER( vram_r );
+ DECLARE_WRITE32_MEMBER( vram_w );
+
+ u32 *get_vram() { return m_vram; }
+
+protected:
+ // standard device_interface overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ devcb_write_line m_int_cb;
+
+private:
+ u32 m_vram[0x200000/4];
+ u32 m_regs[0x80];
+ int m_copy_src;
+};
+
+DECLARE_DEVICE_TYPE(DECSFB, decsfb_device)
+
+#endif // MAME_VIDEO_DECSFB_H
diff --git a/src/mame/drivers/decstation.cpp b/src/mame/drivers/decstation.cpp
index 02ea55b3b86..a9a1f3f5db7 100644
--- a/src/mame/drivers/decstation.cpp
+++ b/src/mame/drivers/decstation.cpp
@@ -73,6 +73,7 @@
#include "bus/rs232/rs232.h"
#include "screen.h"
#include "video/bt459.h"
+#include "video/decsfb.h"
class decstation_state : public driver_device
{
@@ -82,6 +83,7 @@ public:
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
m_scantimer(*this, "scantimer"),
+ m_sfb(*this, "sfb"),
m_lk201(*this, "lk201"),
m_ioga(*this, "ioga"),
m_rtc(*this, "rtc"),
@@ -134,6 +136,7 @@ private:
required_device<mips1core_device_base> m_maincpu;
required_device<screen_device> m_screen;
optional_device<timer_device> m_scantimer;
+ optional_device<decsfb_device> m_sfb;
optional_device<lk201_device> m_lk201;
optional_device<dec_ioga_device> m_ioga;
required_device<mc146818_device> m_rtc;
@@ -149,9 +152,6 @@ private:
void threemin_map(address_map &map);
u8 *m_vrom_ptr;
- u32 m_vram[0x200000/4];
- u32 m_sfb[0x80];
- int m_copy_src;
u32 m_kn01_control, m_kn01_status;
u32 m_palette[256], m_overlay[256];
@@ -191,50 +191,10 @@ uint32_t decstation_state::kn01_screen_update(screen_device &screen, bitmap_rgb3
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]);
+ m_bt459->screen_update(screen, bitmap, cliprect, (uint8_t *)m_sfb->get_vram());
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)
{
uint32_t addr = offset << 2;
@@ -248,12 +208,10 @@ READ32_MEMBER(decstation_state::cfb_r)
if ((addr >= 0x100000) && (addr < 0x100200))
{
- return m_sfb[offset-(0x100000/4)];
}
if ((addr >= 0x200000) && (addr < 0x400000))
{
- return m_vram[offset-(0x200000/4)];
}
return 0xffffffff;
@@ -265,13 +223,6 @@ WRITE32_MEMBER(decstation_state::cfb_w)
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;
}
@@ -283,70 +234,6 @@ WRITE32_MEMBER(decstation_state::cfb_w)
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;
}
}
@@ -561,16 +448,15 @@ void decstation_state::machine_start()
{
if (m_vrom)
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_ioga->set_dma_space(&m_maincpu->space(AS_PROGRAM));
+ if (m_ioga)
+ {
+ m_ioga->set_dma_space(&m_maincpu->space(AS_PROGRAM));
+ }
- m_copy_src = 1;
m_entry = 0;
m_stage = 0;
m_r = m_g = m_b = 0;
@@ -620,8 +506,10 @@ void decstation_state::kn01_map(address_map &map)
void decstation_state::threemin_map(address_map &map)
{
map(0x00000000, 0x07ffffff).ram(); // full 128 MB
- map(0x10000000, 0x13ffffff).rw(FUNC(decstation_state::cfb_r), FUNC(decstation_state::cfb_w));
+ map(0x10000000, 0x1007ffff).rw(FUNC(decstation_state::cfb_r), FUNC(decstation_state::cfb_w));
+ map(0x10100000, 0x101001ff).rw(m_sfb, FUNC(decsfb_device::read), FUNC(decsfb_device::write));
map(0x101c0000, 0x101c000f).m("bt459", FUNC(bt459_device::map)).umask32(0x000000ff);
+ map(0x10200000, 0x103fffff).rw(m_sfb, FUNC(decsfb_device::vram_r), FUNC(decsfb_device::vram_w));
map(0x1c000000, 0x1c07ffff).m(m_ioga, FUNC(dec_ioga_device::map));
map(0x1c0c0000, 0x1c0c0007).rw(m_lance, FUNC(am79c90_device::regs_r), FUNC(am79c90_device::regs_w)).umask32(0x0000ffff);
map(0x1c100000, 0x1c100003).rw(m_scc0, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w)).umask32(0x0000ff00);
@@ -690,6 +578,9 @@ MACHINE_CONFIG_START(decstation_state::kn02ba)
m_screen->set_raw(130000000, 1704, 32, (1280+32), 1064, 3, (1024+3));
m_screen->set_screen_update(FUNC(decstation_state::screen_update));
+ DECSFB(config, m_sfb, 25'000'000); // clock based on white paper which quotes "40ns" gate array cycle times
+// m_sfb->int_cb().set(FUNC(dec_ioga_device::slot0_irq_w));
+
BT459(config, m_bt459, 83'020'800);
AM79C90(config, m_lance, XTAL(12'500'000));