diff options
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 |
commit | 32703cfa5ae42c652cb62998106da267b2e97861 (patch) | |
tree | 34f1ce37a99b97d57063b349200fb0b8c04db3c3 | |
parent | 3b88c56063f25c50285f5ed2a9705349400e099a (diff) |
decstation: move SFB video chip to separate device for future AlphaAXP sharing [R. Belmont]
-rw-r--r-- | scripts/src/video.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/devices/video/decsfb.cpp | 175 | ||||
-rw-r--r-- | src/devices/video/decsfb.h | 38 | ||||
-rw-r--r-- | src/mame/drivers/decstation.cpp | 137 |
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)); |