summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/decsfb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/decsfb.cpp')
-rw-r--r--src/devices/video/decsfb.cpp175
1 files changed, 175 insertions, 0 deletions
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;
+ }
+}