summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/bus/nubus/laserview.cpp273
-rw-r--r--src/devices/bus/nubus/laserview.h40
2 files changed, 160 insertions, 153 deletions
diff --git a/src/devices/bus/nubus/laserview.cpp b/src/devices/bus/nubus/laserview.cpp
index 9e9d8ef131b..e4804b55547 100644
--- a/src/devices/bus/nubus/laserview.cpp
+++ b/src/devices/bus/nubus/laserview.cpp
@@ -3,48 +3,86 @@
/***************************************************************************
Sigma Designs fixed-resolution monochrome video card
- 1664x1200 or 832x600 according to the ad, can't find the 1664 mode.
+ 1664x1200 or 832x600 according to the ad, and exist as mode entries
+ in the declaration ROM.
VRAM at Fs000000, mirrored at Fs900000.
Fs0BFFEC: write 0x04 to enable VBL, 0x01 to ack VBL
+ Card has one ASIC, a Sigma Designs 53C280A. This is shared with the PC ISA
+ "LaserView Plus" card.
+
+ Crystals:
+ 160.00 MHz
+ 122.925 MHz
+ 99.108 MHz
+ 16.0 MHz
+
+ CRTC parameters are always programmed for 1664x1200, the card apparently
+ doubles up the output for the 832x600 mode.
+
+ TODO: Find what makes it sense the higher resolution mode.
+
***************************************************************************/
#include "emu.h"
+
#include "laserview.h"
+
+#include "emupal.h"
#include "screen.h"
#include <algorithm>
+static constexpr u32 VRAM_SIZE = 0x40000; // ROM tests for 512K, but card has 8x uPD41264 (64K x 4 bit) = 256 KiB
+namespace {
-#define LASERVIEW_SCREEN_NAME "laserview_screen"
-#define LASERVIEW_ROM_REGION "laserview_rom"
+ class nubus_laserview_device : public device_t,
+ public device_nubus_card_interface
+ {
+ public:
+ // construction/destruction
+ nubus_laserview_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-#define VRAM_SIZE (0x40000)
+ protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
-ROM_START( laserview )
- ROM_REGION(0x8000, LASERVIEW_ROM_REGION, 0)
- ROM_LOAD( "lva-m2-00020_v3.00.bin", 0x000000, 0x008000, CRC(569d1fb7) SHA1(fd505505226abb5fea7c10ed14e8841077ef1be6) )
-ROM_END
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
-//**************************************************************************
-// GLOBAL VARIABLES
-//**************************************************************************
+ private:
+ u8 regs_r(offs_t offset);
+ void regs_w(offs_t offset, u8 data);
-DEFINE_DEVICE_TYPE(NUBUS_LASERVIEW, nubus_laserview_device, "nb_laserview", "Sigma Designs LaserView video card")
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void vbl_w(int state);
-//-------------------------------------------------
-// device_add_mconfig - add device configuration
-//-------------------------------------------------
+ required_device<screen_device> m_screen;
+
+ std::unique_ptr<u32[]> m_vram;
+ u16 m_htotal, m_hvis, m_vtotal, m_vvis;
+ u32 m_vbl_disable;
+ u8 m_prot_latch;
+ };
+
+ROM_START( laserview )
+ ROM_REGION(0x8000, "declrom", 0)
+ ROM_LOAD( "lva-m2-00020_v3.00.bin", 0x000000, 0x008000, CRC(569d1fb7) SHA1(fd505505226abb5fea7c10ed14e8841077ef1be6) )
+ROM_END
void nubus_laserview_device::device_add_mconfig(machine_config &config)
{
- screen_device &screen(SCREEN(config, LASERVIEW_SCREEN_NAME, SCREEN_TYPE_RASTER));
- screen.set_screen_update(FUNC(nubus_laserview_device::screen_update));
- screen.set_size(832,600);
- screen.set_visarea(0, 832-1, 0, 600-1);
- screen.set_refresh_hz(70);
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_screen_update(FUNC(nubus_laserview_device::screen_update));
+ m_screen->set_raw(99108000/2, 1008, 0, 832, 622, 0, 600);
+ m_screen->set_palette("palette");
+ m_screen->screen_vblank().set(FUNC(nubus_laserview_device::vbl_w));
+
+ PALETTE(config, "palette", palette_device::MONOCHROME_INVERTED);
}
//-------------------------------------------------
@@ -56,109 +94,131 @@ const tiny_rom_entry *nubus_laserview_device::device_rom_region() const
return ROM_NAME( laserview );
}
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// nubus_laserview_device - constructor
-//-------------------------------------------------
-
-nubus_laserview_device::nubus_laserview_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- nubus_laserview_device(mconfig, NUBUS_LASERVIEW, tag, owner, clock)
-{
-}
-
-nubus_laserview_device::nubus_laserview_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, type, tag, owner, clock),
+nubus_laserview_device::nubus_laserview_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, NUBUS_LASERVIEW, tag, owner, clock),
device_nubus_card_interface(mconfig, *this),
- m_vbl_disable(0)
+ m_screen(*this, "screen"),
+ m_htotal(0), m_hvis(0), m_vtotal(0), m_vvis(0),
+ m_vbl_disable(1), m_prot_latch(0)
{
}
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
void nubus_laserview_device::device_start()
{
- uint32_t slotspace;
-
- install_declaration_rom(LASERVIEW_ROM_REGION, true);
-
- slotspace = get_slotspace();
+ const u32 slotspace = get_slotspace();
-// printf("[laserview %p] slotspace = %x\n", this, slotspace);
+ install_declaration_rom("declrom", true);
- m_vram.resize(VRAM_SIZE / sizeof(uint32_t));
- install_bank(slotspace, slotspace+VRAM_SIZE-1, &m_vram[0]);
+ m_vram = std::make_unique<u32[]>(VRAM_SIZE / sizeof(u32));
+ install_bank(slotspace, slotspace + VRAM_SIZE - 1, &m_vram[0]);
install_bank(slotspace+0x900000, slotspace+0x900000+VRAM_SIZE-1, &m_vram[0]);
- nubus().install_device(slotspace+0xB0000, slotspace+0xBFFFF, read32s_delegate(*this, FUNC(nubus_laserview_device::regs_r)), write32s_delegate(*this, FUNC(nubus_laserview_device::regs_w)));
-}
+ nubus().install_device(slotspace+0xB0000, slotspace+0xBFFFF, emu::rw_delegate(*this, FUNC(nubus_laserview_device::regs_r)), emu::rw_delegate(*this, FUNC(nubus_laserview_device::regs_w)));
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
+ save_item(NAME(m_htotal));
+ save_item(NAME(m_hvis));
+ save_item(NAME(m_vtotal));
+ save_item(NAME(m_vvis));
+ save_item(NAME(m_vbl_disable));
+ save_item(NAME(m_prot_latch));
+ save_pointer(NAME(m_vram), VRAM_SIZE / sizeof(u32));
+}
void nubus_laserview_device::device_reset()
{
m_vbl_disable = 1;
- m_prot_state = 0;
- m_toggle = 0;
- std::fill(m_vram.begin(), m_vram.end(), 0);
-
- m_palette[0] = rgb_t(255, 255, 255);
- m_palette[1] = rgb_t(0, 0, 0);
+ std::fill_n(&m_vram[0], VRAM_SIZE / sizeof(u32), 0);
}
-/***************************************************************************
-
- Viking 1024x768 B&W card section
-
-***************************************************************************/
-
-uint32_t nubus_laserview_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+u32 nubus_laserview_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- if (!m_vbl_disable)
- {
- raise_slot_irq();
- }
-
- auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]);
+ auto const vram8 = util::big_endian_cast<u8 const>(&m_vram[0]);
for (int y = 0; y < 600; y++)
{
- uint32_t *scanline = &bitmap.pix(y);
+ u16 *scanline = &bitmap.pix(y);
for (int x = 0; x < 832/8; x++)
{
- uint8_t const pixels = vram8[(y * 104) + x + 0x20];
-
- *scanline++ = m_palette[BIT(pixels, 7)];
- *scanline++ = m_palette[BIT(pixels, 6)];
- *scanline++ = m_palette[BIT(pixels, 5)];
- *scanline++ = m_palette[BIT(pixels, 4)];
- *scanline++ = m_palette[BIT(pixels, 3)];
- *scanline++ = m_palette[BIT(pixels, 2)];
- *scanline++ = m_palette[BIT(pixels, 1)];
- *scanline++ = m_palette[BIT(pixels, 0)];
+ u8 const pixels = vram8[(y * 104) + x + 0x20];
+
+ *scanline++ = BIT(pixels, 7);
+ *scanline++ = BIT(pixels, 6);
+ *scanline++ = BIT(pixels, 5);
+ *scanline++ = BIT(pixels, 4);
+ *scanline++ = BIT(pixels, 3);
+ *scanline++ = BIT(pixels, 2);
+ *scanline++ = BIT(pixels, 1);
+ *scanline++ = BIT(pixels, 0);
}
}
-
return 0;
}
-void nubus_laserview_device::regs_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+void nubus_laserview_device::vbl_w(int state)
{
-// printf("%08x to regs @ %x mask %08x\n", data, offset, mem_mask);
+ if ((state) && (!m_vbl_disable))
+ {
+ raise_slot_irq();
+ }
+}
+void nubus_laserview_device::regs_w(offs_t offset, u8 data)
+{
switch (offset)
{
- case 0x3ffb:
+ case 0x00f9:
+ m_prot_latch = ~data;
+ break;
+
+ case 0x0493:
+ m_vvis = (m_vvis & 0xff) | (data << 8);
+ break;
+
+ case 0x0687:
+ m_hvis = (m_hvis & 0xff) | (data << 8);
+ break;
+
+ case 0x078f:
+ m_vtotal = (m_vtotal & 0xff) | (data << 8);
+ break;
+
+ case 0x0883:
+ m_htotal = (m_htotal & 0xff) | (data<<8);
+ break;
+
+ case 0x08ff:
+ if (data == 0xc1)
+ {
+ const rectangle visarea(0, (m_hvis / 2) - 1, 0, (m_vvis / 2) - 1);
+ m_screen->configure(m_htotal / 2, m_vtotal / 2, visarea, attotime::from_ticks((m_htotal / 2) * (m_vtotal / 2), 160000000 / 2).as_attoseconds());
+ }
+ break;
+
+ case 0x20f9:
+ m_prot_latch = ~data ^ 0xff;
+ break;
+
+ case 0xb095:
+ m_vvis = (m_vvis & 0xff00) | data;
+ break;
+
+ case 0xdd91:
+ m_vtotal = (m_vtotal & 0xff00) | data;
+ break;
+
+ case 0x8085:
+ m_htotal = (m_htotal & 0xff00) | data;
+ break;
+
+ case 0x8089:
+ m_hvis = (m_hvis & 0xff00) | data;
+ break;
+
+ case 0xffef:
if ((data & 0xff) == 0x04)
{
m_vbl_disable = 0;
}
- else if ((data & 0xff) == 01)
+ else if ((data & 0xff) == 1)
{
lower_slot_irq();
}
@@ -172,38 +232,23 @@ void nubus_laserview_device::regs_w(offs_t offset, uint32_t data, uint32_t mem_m
}
-uint32_t nubus_laserview_device::regs_r(offs_t offset, uint32_t mem_mask)
+u8 nubus_laserview_device::regs_r(offs_t offset)
{
- //f (offset != 0x3fc1) printf("Read regs_r @ %x mask %08x\n", offset, mem_mask);
-
switch (offset)
{
- case 0x3fc1:
- m_toggle ^= 1;
- if (m_toggle)
- {
- return 0x01010101;
- }
- else
- {
- return 0;
- }
- machine().debug_break();
- break;
+ case 0xff04: // vblank status
+ return m_screen->vblank();
- case 0x3fc2:
- if (m_prot_state == 0)
- {
- m_prot_state = 1;
- return 0;
- }
- return 0x02000000;
+ case 0xff08:
+ return m_prot_latch;
- case 0x3fff:
- m_prot_state = 0;
- return 0xfeffffff;
+ case 0xfffc:
+ return 0xe4;
}
- return 0xffffffff;
+ return 0xff;
}
+} // anonymous namespace
+
+DEFINE_DEVICE_TYPE_PRIVATE(NUBUS_LASERVIEW, device_nubus_card_interface, nubus_laserview_device, "nb_laserview", "Sigma Designs LaserView video card")
diff --git a/src/devices/bus/nubus/laserview.h b/src/devices/bus/nubus/laserview.h
index a2d99227566..22e283c2391 100644
--- a/src/devices/bus/nubus/laserview.h
+++ b/src/devices/bus/nubus/laserview.h
@@ -7,44 +7,6 @@
#include "nubus.h"
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> nubus_laserview_device
-
-class nubus_laserview_device :
- public device_t,
- public device_nubus_card_interface
-{
-public:
- // construction/destruction
- nubus_laserview_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- nubus_laserview_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override;
- virtual const tiny_rom_entry *device_rom_region() const override;
-
-private:
- uint32_t regs_r(offs_t offset, uint32_t mem_mask = ~0);
- void regs_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
-
- uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
-
- std::vector<uint32_t> m_vram;
- uint32_t m_vbl_disable, m_palette[2];
- int m_prot_state;
- int m_toggle;
-};
-
-// device type definition
-DECLARE_DEVICE_TYPE(NUBUS_LASERVIEW, nubus_laserview_device)
+DECLARE_DEVICE_TYPE(NUBUS_LASERVIEW, device_nubus_card_interface)
#endif // MAME_BUS_NUBUS_LASERVIEW_H