summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <MooglyGuy@users.noreply.github.com>2019-01-31 17:07:25 +0100
committer GitHub <noreply@github.com>2019-01-31 17:07:25 +0100
commit3add98785790f4d4b3585c714f55767f1149817b (patch)
treecd9647e36987227ed181ff6f75afe46f5a321a57
parentedf3b55b78cd220537b1c403af5cb3a15d893cf2 (diff)
parentb5937ea0e8c9702cea998f7e522169dffa3f4545 (diff)
Merge pull request #4574 from tyfighter/master
Indigo: move LG1 "Light" graphics support out to its own device for future sharing
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/mame/drivers/indigo.cpp385
-rw-r--r--src/mame/video/light.cpp381
-rw-r--r--src/mame/video/light.h75
4 files changed, 464 insertions, 379 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 5cae6e3dc38..6e268930be3 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -3056,6 +3056,8 @@ files {
MAME_DIR .. "src/mame/drivers/4dpi.cpp",
MAME_DIR .. "src/mame/drivers/indigo.cpp",
MAME_DIR .. "src/mame/drivers/indy_indigo2.cpp",
+ MAME_DIR .. "src/mame/video/light.cpp",
+ MAME_DIR .. "src/mame/video/light.h",
MAME_DIR .. "src/mame/video/newport.cpp",
MAME_DIR .. "src/mame/video/newport.h",
MAME_DIR .. "src/mame/video/crime.cpp",
diff --git a/src/mame/drivers/indigo.cpp b/src/mame/drivers/indigo.cpp
index e58056fce37..f5ceae47718 100644
--- a/src/mame/drivers/indigo.cpp
+++ b/src/mame/drivers/indigo.cpp
@@ -22,17 +22,12 @@
#include "machine/eepromser.h"
#include "machine/hpc1.h"
#include "machine/sgi.h"
-#include "emupal.h"
-#include "screen.h"
-
-#define ENABLE_ENTRY_GFX (1)
+#include "video/light.h"
#define LOG_UNKNOWN (1 << 0)
#define LOG_INT (1 << 1)
#define LOG_DSP (1 << 2)
-#define LOG_GFX (1 << 3)
-#define LOG_GFX_CMD (1 << 4)
-#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_DSP | LOG_GFX | LOG_GFX_CMD)
+#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_DSP)
#define VERBOSE (LOG_UNKNOWN)
#include "logmacro.h"
@@ -44,7 +39,7 @@ public:
: driver_device(mconfig, type, tag)
, m_hpc(*this, "hpc")
, m_eeprom(*this, "eeprom")
- , m_palette(*this, "palette")
+ , m_light(*this, "lg1")
{
}
@@ -58,96 +53,14 @@ protected:
DECLARE_WRITE32_MEMBER(int_w);
DECLARE_READ32_MEMBER(dsp_ram_r);
DECLARE_WRITE32_MEMBER(dsp_ram_w);
- DECLARE_READ32_MEMBER(entry_r);
- DECLARE_WRITE32_MEMBER(entry_w);
-
- void do_rex_command();
void indigo_map(address_map &map);
- uint32_t screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect);
-
- enum
- {
- REX15_PAGE0_SET = 0x00000000,
- REX15_PAGE0_GO = 0x00000800,
- REX15_PAGE1_SET = 0x00004790,
- REX15_PAGE1_GO = 0x00004f90,
-
- REX15_P0REG_COMMAND = 0x00000000,
- REX15_P0REG_XSTARTI = 0x0000000c,
- REX15_P0REG_YSTARTI = 0x0000001c,
- REX15_P0REG_XYMOVE = 0x00000034,
- REX15_P0REG_COLORREDI = 0x00000038,
- REX15_P0REG_COLORGREENI = 0x00000040,
- REX15_P0REG_COLORBLUEI = 0x00000048,
- REX15_P0REG_COLORBACK = 0x0000005c,
- REX15_P0REG_ZPATTERN = 0x00000060,
- REX15_P0REG_XENDI = 0x00000084,
- REX15_P0REG_YENDI = 0x00000088,
-
- REX15_P1REG_WCLOCKREV = 0x00000054,
- REX15_P1REG_CFGDATA = 0x00000058,
- REX15_P1REG_CFGSEL = 0x0000005c,
- REX15_P1REG_VC1_ADDRDATA = 0x00000060,
- REX15_P1REG_CFGMODE = 0x00000068,
- REX15_P1REG_XYOFFSET = 0x0000006c,
-
- REX15_OP_NOP = 0x00000000,
- REX15_OP_DRAW = 0x00000001,
-
- REX15_OP_FLAG_BLOCK = 0x00000008,
- REX15_OP_FLAG_LENGTH32 = 0x00000010,
- REX15_OP_FLAG_QUADMODE = 0x00000020,
- REX15_OP_FLAG_XYCONTINUE = 0x00000080,
- REX15_OP_FLAG_STOPONX = 0x00000100,
- REX15_OP_FLAG_STOPONY = 0x00000200,
- REX15_OP_FLAG_ENZPATTERN = 0x00000400,
- REX15_OP_FLAG_LOGICSRC = 0x00080000,
- REX15_OP_FLAG_ZOPAQUE = 0x00800000,
- REX15_OP_FLAG_ZCONTINUE = 0x01000000,
-
- REX15_WRITE_ADDR = 0x00,
- REX15_PALETTE_RAM = 0x01,
- REX15_PIXEL_READ_MASK = 0x02,
- REX15_CONTROL = 0x06
- };
-
- struct lg1_t
- {
- uint32_t m_config_sel;
- uint32_t m_write_addr;
- uint32_t m_control;
-
- uint32_t m_command;
- uint32_t m_x_start_i;
- uint32_t m_y_start_i;
- uint32_t m_xy_move;
- uint32_t m_color_red_i;
- uint32_t m_color_green_i;
- uint32_t m_color_blue_i;
- uint32_t m_color_back;
- uint32_t m_z_pattern;
- uint32_t m_x_end_i;
- uint32_t m_y_end_i;
- uint32_t m_x_curr_i;
- uint32_t m_y_curr_i;
-
- uint8_t m_palette_idx;
- uint8_t m_palette_channel;
- uint8_t m_palette_entry[3];
- uint8_t m_pix_read_mask[256];
- };
-
required_device<hpc1_device> m_hpc;
required_device<eeprom_serial_93cxx_device> m_eeprom;
- required_device<palette_device> m_palette;
std::unique_ptr<uint32_t[]> m_dsp_ram;
-
+ required_device<light_video_device> m_light;
address_space *m_space;
-
- lg1_t m_lg1;
- std::unique_ptr<uint8_t[]> m_framebuffer;
};
class indigo3k_state : public indigo_state
@@ -195,37 +108,11 @@ protected:
void indigo_state::machine_start()
{
m_dsp_ram = std::make_unique<uint32_t[]>(0x8000);
- m_framebuffer = std::make_unique<uint8_t[]>(1024*768);
-
- save_item(NAME(m_lg1.m_config_sel));
- save_item(NAME(m_lg1.m_write_addr));
- save_item(NAME(m_lg1.m_control));
- save_item(NAME(m_lg1.m_command));
- save_item(NAME(m_lg1.m_x_start_i));
- save_item(NAME(m_lg1.m_y_start_i));
- save_item(NAME(m_lg1.m_xy_move));
- save_item(NAME(m_lg1.m_color_red_i));
- save_item(NAME(m_lg1.m_color_green_i));
- save_item(NAME(m_lg1.m_color_blue_i));
- save_item(NAME(m_lg1.m_color_back));
- save_item(NAME(m_lg1.m_z_pattern));
- save_item(NAME(m_lg1.m_x_end_i));
- save_item(NAME(m_lg1.m_y_end_i));
- save_item(NAME(m_lg1.m_x_curr_i));
- save_item(NAME(m_lg1.m_y_curr_i));
- save_item(NAME(m_lg1.m_palette_idx));
- save_item(NAME(m_lg1.m_palette_channel));
- save_item(NAME(m_lg1.m_palette_entry));
- save_item(NAME(m_lg1.m_pix_read_mask));
-
save_pointer(NAME(&m_dsp_ram[0]), 0x8000);
- save_pointer(NAME(&m_framebuffer[0]), 1024*768);
}
void indigo_state::machine_reset()
{
- memset(&m_lg1, 0, sizeof(lg1_t));
- memset(&m_framebuffer[0], 0, 1024*768);
}
void indigo4k_state::machine_reset()
@@ -259,262 +146,10 @@ WRITE32_MEMBER(indigo_state::dsp_ram_w)
m_dsp_ram[offset] = data;
}
-READ32_MEMBER(indigo_state::entry_r)
-{
- uint32_t ret = 0;
- switch (offset)
- {
- case REX15_PAGE0_GO/4:
- LOGMASKED(LOG_GFX, "%s: LG1 Read: Status(?) (Go) %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
- do_rex_command();
- break;
- case 0x0014/4:
- ret = 0x033c0000;
- LOGMASKED(LOG_GFX, "%s: LG1 Read: Presence Detect(?) %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
- break;
- default:
- LOGMASKED(LOG_GFX, "%s: Unknown LG1 Read: %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
- break;
- }
- return ret;
-}
-
-void indigo_state::do_rex_command()
-{
- if (m_lg1.m_command == 0)
- {
- return;
- }
- if (m_lg1.m_command == 0x30080329)
- {
- bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
- bool copy = (m_lg1.m_command & REX15_OP_FLAG_LOGICSRC);
- const uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
- const uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
- const uint32_t end_x = m_lg1.m_x_end_i;
- const uint32_t end_y = m_lg1.m_y_end_i;
- const uint32_t src_start_x = start_x + (m_lg1.m_xy_move >> 16);
- const uint32_t src_start_y = start_y + (uint16_t)m_lg1.m_xy_move;;
-
- LOGMASKED(LOG_GFX, "LG1: Command %08x: Block copy from %d,%d-%d,%d inclusive.\n", m_lg1.m_command, start_x, start_y, end_x, end_y);
- if (copy)
- {
- for (uint32_t y = start_y, src_y = src_start_y; y <= end_y; y++, src_y++)
- for (uint32_t x = start_x, src_x = src_start_x; x <= end_x; x++, src_x++)
- m_framebuffer[y*1024 + x] = m_framebuffer[src_y*1024 + src_x];
- }
- else
- {
- for (uint32_t y = start_y; y <= end_y; y++)
- for (uint32_t x = start_x; x <= end_x; x++)
- m_framebuffer[y*1024 + x] = m_lg1.m_color_red_i;
- }
- }
- else if (m_lg1.m_command == 0x30000329)
- {
- bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
- uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
- uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
- uint32_t end_x = m_lg1.m_x_end_i;
- uint32_t end_y = m_lg1.m_y_end_i;
-
- LOGMASKED(LOG_GFX, "LG1: Command %08x: Block draw from %d,%d-%d,%d inclusive.\n", m_lg1.m_command, start_x, start_y, end_x, end_y);
- for (uint32_t y = start_y; y <= end_y; y++)
- {
- for (uint32_t x = start_x; x <= end_x; x++)
- {
- m_framebuffer[y*1024 + x] = m_lg1.m_color_red_i;
- }
- }
- }
- else if (m_lg1.m_command == 0x300005a1 ||
- m_lg1.m_command == 0x300005a9 ||
- m_lg1.m_command == 0x300005b9)
- {
- bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
- uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
- uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
- uint32_t end_x = m_lg1.m_x_end_i;
- LOGMASKED(LOG_GFX, "LG1: Command %08x: Pattern draw from %d-%d at %d\n", m_lg1.m_command, start_x, end_x, start_y);
- for (uint32_t x = start_x; x <= end_x && x < (start_x + 32); x++)
- {
- if (BIT(m_lg1.m_z_pattern, 31 - (x - start_x)))
- {
- m_framebuffer[start_y*1024 + x] = m_lg1.m_color_red_i;
- }
- m_lg1.m_x_curr_i++;
- }
-
- if (m_lg1.m_command & REX15_OP_FLAG_BLOCK)
- {
- if (m_lg1.m_x_curr_i > m_lg1.m_x_end_i)
- {
- m_lg1.m_y_curr_i--;
- m_lg1.m_x_curr_i = m_lg1.m_x_start_i;
- }
- }
- }
- else
- {
- LOGMASKED(LOG_GFX_CMD | LOG_UNKNOWN, "%s: Unknown LG1 command: %08x\n", machine().describe_context(), m_lg1.m_command);
- }
-}
-
-WRITE32_MEMBER(indigo_state::entry_w)
-{
- bool go = (offset >= REX15_PAGE1_GO/4) || (offset >= REX15_PAGE0_GO/4 && offset < REX15_PAGE1_SET/4);
-
- switch (offset)
- {
- case (REX15_PAGE0_SET+REX15_P0REG_COMMAND)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_COMMAND)/4:
- m_lg1.m_command = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 Command Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- if (go)
- do_rex_command();
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_XSTARTI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_XSTARTI)/4:
- m_lg1.m_x_start_i = data;
- m_lg1.m_x_curr_i = m_lg1.m_x_start_i;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 XStartI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_YSTARTI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_YSTARTI)/4:
- m_lg1.m_y_start_i = data;
- m_lg1.m_y_curr_i = m_lg1.m_y_start_i;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 YStartI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_XYMOVE)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_XYMOVE)/4:
- m_lg1.m_xy_move = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 XYMove Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- if (go)
- do_rex_command();
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_COLORREDI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_COLORREDI)/4:
- m_lg1.m_color_red_i = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 ColorRedI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_COLORGREENI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_COLORGREENI)/4:
- m_lg1.m_color_green_i = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 ColorGreenI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_COLORBLUEI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_COLORBLUEI)/4:
- m_lg1.m_color_blue_i = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 ColorBlueI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_COLORBACK)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_COLORBACK)/4:
- m_lg1.m_color_back = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 ColorBlueI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_ZPATTERN)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_ZPATTERN)/4:
- m_lg1.m_z_pattern = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 ZPattern Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- if (go)
- do_rex_command();
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_XENDI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_XENDI)/4:
- m_lg1.m_x_end_i = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 XEndI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
- case (REX15_PAGE0_SET+REX15_P0REG_YENDI)/4:
- case (REX15_PAGE0_GO+REX15_P0REG_YENDI)/4:
- m_lg1.m_y_end_i = data;
- LOGMASKED(LOG_GFX, "%s: LG1 REX1.5 YEndI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
- break;
-
- case (REX15_PAGE1_SET+REX15_P1REG_CFGSEL)/4:
- case (REX15_PAGE1_GO+REX15_P1REG_CFGSEL)/4:
- m_lg1.m_config_sel = data;
- switch (data)
- {
- case REX15_WRITE_ADDR:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Write Addr)\n", machine().describe_context(), data);
- break;
- case REX15_PALETTE_RAM:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Palette RAM)\n", machine().describe_context(), data);
- break;
- case REX15_CONTROL:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Control)\n", machine().describe_context(), data);
- break;
- case REX15_PIXEL_READ_MASK:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Pixel Read Mask)\n", machine().describe_context(), data);
- break;
- default:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Unknown)\n", machine().describe_context(), data);
- break;
- }
- break;
- case (REX15_PAGE1_SET+REX15_P1REG_CFGDATA)/4:
- case (REX15_PAGE1_GO+REX15_P1REG_CFGDATA)/4:
- if (go) // Ignore 'Go' writes for now, unsure what they do
- break;
- switch (m_lg1.m_config_sel)
- {
- case REX15_WRITE_ADDR:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write: Setting WriteAddr to %08x\n", machine().describe_context(), data);
- m_lg1.m_write_addr = data;
- if (m_lg1.m_control == 0xf)
- {
- LOGMASKED(LOG_GFX, "%s: LG1 about to set palette entry %02x\n", machine().describe_context(), (uint8_t)data);
- m_lg1.m_palette_idx = (uint8_t)data;
- m_lg1.m_palette_channel = 0;
- }
- break;
- case REX15_PALETTE_RAM:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write: Setting Palette RAM %02x entry %d to %02x\n", machine().describe_context(),
- m_lg1.m_palette_idx, m_lg1.m_palette_channel, (uint8_t)data);
- m_lg1.m_palette_entry[m_lg1.m_palette_channel++] = (uint8_t)data;
- if (m_lg1.m_palette_channel == 3)
- {
- m_palette->set_pen_color(m_lg1.m_palette_idx, m_lg1.m_palette_entry[0], m_lg1.m_palette_entry[1], m_lg1.m_palette_entry[2]);
- }
- break;
- case REX15_CONTROL:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write: Setting Control to %08x\n", machine().describe_context(), data);
- m_lg1.m_control = data;
- break;
- case REX15_PIXEL_READ_MASK:
- LOGMASKED(LOG_GFX, "%s: LG1 ConfigSel Write = %08x (Pixel Read Mask, entry %02x)\n", machine().describe_context(), data, m_lg1.m_palette_idx);
- m_lg1.m_pix_read_mask[m_lg1.m_palette_idx] = (uint8_t)data;
- break;
- default:
- LOGMASKED(LOG_GFX, "%s: LG1 Unknown ConfigData Write = %08x\n", machine().describe_context(), data);
- break;
- }
- break;
- default:
- LOGMASKED(LOG_GFX, "%s: Unknown LG1 Write: %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, data, mem_mask);
- break;
- }
-}
-
-uint32_t indigo_state::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- const rgb_t *pens = m_palette->palette()->entry_list_raw();
-
- for (int y = 0; y < 768; y++)
- {
- uint32_t *dst = &bitmap.pix32(y);
- uint8_t *src = &m_framebuffer[y*1024];
- for (int x = 0; x < 1024; x++)
- {
- *dst++ = pens[*src++];
- }
- }
- return 0;
-}
void indigo_state::indigo_map(address_map &map)
{
- map(0x1f3f0000, 0x1f3fffff).rw(FUNC(indigo_state::entry_r), FUNC(indigo_state::entry_w));
+ map(0x1f3f0000, 0x1f3fffff).rw(m_light, FUNC(light_video_device::entry_r), FUNC(light_video_device::entry_w));
map(0x1fb80000, 0x1fb8ffff).rw(m_hpc, FUNC(hpc1_device::read), FUNC(hpc1_device::write));
map(0x1fbd9000, 0x1fbd903f).rw(FUNC(indigo_state::int_r), FUNC(indigo_state::int_w));
map(0x1fbe0000, 0x1fbfffff).rw(FUNC(indigo_state::dsp_ram_r), FUNC(indigo_state::dsp_ram_w));
@@ -559,15 +194,7 @@ INPUT_PORTS_END
void indigo_state::indigo_base(machine_config &config)
{
- /* video hardware */
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
- screen.set_size(1024, 768);
- screen.set_visarea(0, 1024-1, 0, 768-1);
- screen.set_screen_update(FUNC(indigo_state::screen_update));
-
- PALETTE(config, m_palette).set_entries(256);
+ LIGHT_VIDEO(config, m_light);
EEPROM_93C56_16BIT(config, m_eeprom);
}
diff --git a/src/mame/video/light.cpp b/src/mame/video/light.cpp
new file mode 100644
index 00000000000..719113a9447
--- /dev/null
+++ b/src/mame/video/light.cpp
@@ -0,0 +1,381 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz, Tyson Smith
+/*
+ Silicon Graphics LG1 "Light" graphics board used as
+ entry level graphics in the Indigo and IRIS Crimson.
+*/
+
+#include "emu.h"
+#include "video/light.h"
+#include "screen.h"
+
+#define LOG_REX (1 << 0)
+#define LOG_ALL (LOG_REX)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+enum
+{
+ REX15_PAGE0_SET = 0x00000000,
+ REX15_PAGE0_GO = 0x00000800,
+ REX15_PAGE1_SET = 0x00004790,
+ REX15_PAGE1_GO = 0x00004f90,
+
+ REX15_P0REG_COMMAND = 0x00000000,
+ REX15_P0REG_XSTARTI = 0x0000000c,
+ REX15_P0REG_YSTARTI = 0x0000001c,
+ REX15_P0REG_XYMOVE = 0x00000034,
+ REX15_P0REG_COLORREDI = 0x00000038,
+ REX15_P0REG_COLORGREENI = 0x00000040,
+ REX15_P0REG_COLORBLUEI = 0x00000048,
+ REX15_P0REG_COLORBACK = 0x0000005c,
+ REX15_P0REG_ZPATTERN = 0x00000060,
+ REX15_P0REG_XENDI = 0x00000084,
+ REX15_P0REG_YENDI = 0x00000088,
+
+ REX15_P1REG_WCLOCKREV = 0x00000054,
+ REX15_P1REG_CFGDATA = 0x00000058,
+ REX15_P1REG_CFGSEL = 0x0000005c,
+ REX15_P1REG_VC1_ADDRDATA = 0x00000060,
+ REX15_P1REG_CFGMODE = 0x00000068,
+ REX15_P1REG_XYOFFSET = 0x0000006c,
+
+ REX15_OP_NOP = 0x00000000,
+ REX15_OP_DRAW = 0x00000001,
+
+ REX15_OP_FLAG_BLOCK = 0x00000008,
+ REX15_OP_FLAG_LENGTH32 = 0x00000010,
+ REX15_OP_FLAG_QUADMODE = 0x00000020,
+ REX15_OP_FLAG_XYCONTINUE = 0x00000080,
+ REX15_OP_FLAG_STOPONX = 0x00000100,
+ REX15_OP_FLAG_STOPONY = 0x00000200,
+ REX15_OP_FLAG_ENZPATTERN = 0x00000400,
+ REX15_OP_FLAG_LOGICSRC = 0x00080000,
+ REX15_OP_FLAG_ZOPAQUE = 0x00800000,
+ REX15_OP_FLAG_ZCONTINUE = 0x01000000,
+
+ REX15_WRITE_ADDR = 0x00,
+ REX15_PALETTE_RAM = 0x01,
+ REX15_PIXEL_READ_MASK = 0x02,
+ REX15_CONTROL = 0x06
+};
+
+DEFINE_DEVICE_TYPE(LIGHT_VIDEO, light_video_device, "light_video", "SGI Light graphics board")
+
+
+light_video_device::light_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, LIGHT_VIDEO, tag, owner, clock)
+ , m_palette(*this, "palette")
+{
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - device-specific machine configuration
+//-------------------------------------------------
+
+void light_video_device::device_add_mconfig(machine_config &config)
+{
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_refresh_hz(60);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
+ screen.set_size(x_res, y_res);
+ screen.set_visarea(0, x_res-1, 0, y_res-1);
+ screen.set_screen_update(FUNC(light_video_device::screen_update));
+
+ PALETTE(config, m_palette).set_entries(256);
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void light_video_device::device_start()
+{
+ m_framebuffer = std::make_unique<uint8_t[]>(x_res*y_res);
+
+ save_item(NAME(m_lg1.m_config_sel));
+ save_item(NAME(m_lg1.m_write_addr));
+ save_item(NAME(m_lg1.m_control));
+ save_item(NAME(m_lg1.m_command));
+ save_item(NAME(m_lg1.m_x_start_i));
+ save_item(NAME(m_lg1.m_y_start_i));
+ save_item(NAME(m_lg1.m_xy_move));
+ save_item(NAME(m_lg1.m_color_red_i));
+ save_item(NAME(m_lg1.m_color_green_i));
+ save_item(NAME(m_lg1.m_color_blue_i));
+ save_item(NAME(m_lg1.m_color_back));
+ save_item(NAME(m_lg1.m_z_pattern));
+ save_item(NAME(m_lg1.m_x_end_i));
+ save_item(NAME(m_lg1.m_y_end_i));
+ save_item(NAME(m_lg1.m_x_curr_i));
+ save_item(NAME(m_lg1.m_y_curr_i));
+ save_item(NAME(m_lg1.m_palette_idx));
+ save_item(NAME(m_lg1.m_palette_channel));
+ save_item(NAME(m_lg1.m_palette_entry));
+ save_item(NAME(m_lg1.m_pix_read_mask));
+
+ save_pointer(NAME(&m_framebuffer[0]), x_res*y_res);
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void light_video_device::device_reset()
+{
+ memset(&m_lg1, 0, sizeof(lg1_t));
+ memset(&m_framebuffer[0], 0, x_res*y_res);
+}
+
+uint32_t light_video_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ const rgb_t *pens = m_palette->palette()->entry_list_raw();
+ const uint8_t *src = &m_framebuffer[0];
+ for (uint32_t y = 0; y < y_res; y++) {
+ uint32_t *dst = &bitmap.pix32(y);
+ for (uint32_t x = 0; x < x_res; x++) {
+ *dst++ = pens[*src++];
+ }
+ }
+ return 0;
+}
+
+READ32_MEMBER(light_video_device::entry_r)
+{
+ uint32_t ret = 0;
+ switch (offset)
+ {
+ case REX15_PAGE0_GO/4:
+ LOGMASKED(LOG_REX, "%s: LG1 Read: Status(?) (Go) %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
+ do_rex_command();
+ break;
+ case 0x0014/4:
+ ret = 0x033c0000;
+ LOGMASKED(LOG_REX, "%s: LG1 Read: Presence Detect(?) %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
+ break;
+ default:
+ LOGMASKED(LOG_REX, "%s: Unknown LG1 Read: %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, ret, mem_mask);
+ break;
+ }
+ return ret;
+}
+
+WRITE32_MEMBER(light_video_device::entry_w)
+{
+ bool go = (offset >= REX15_PAGE1_GO/4) || (offset >= REX15_PAGE0_GO/4 && offset < REX15_PAGE1_SET/4);
+
+ switch (offset)
+ {
+ case (REX15_PAGE0_SET+REX15_P0REG_COMMAND)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_COMMAND)/4:
+ m_lg1.m_command = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 Command Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ if (go)
+ do_rex_command();
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_XSTARTI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_XSTARTI)/4:
+ m_lg1.m_x_start_i = data;
+ m_lg1.m_x_curr_i = m_lg1.m_x_start_i;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 XStartI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_YSTARTI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_YSTARTI)/4:
+ m_lg1.m_y_start_i = data;
+ m_lg1.m_y_curr_i = m_lg1.m_y_start_i;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 YStartI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_XYMOVE)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_XYMOVE)/4:
+ m_lg1.m_xy_move = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 XYMove Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ if (go)
+ do_rex_command();
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_COLORREDI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_COLORREDI)/4:
+ m_lg1.m_color_red_i = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 ColorRedI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_COLORGREENI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_COLORGREENI)/4:
+ m_lg1.m_color_green_i = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 ColorGreenI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_COLORBLUEI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_COLORBLUEI)/4:
+ m_lg1.m_color_blue_i = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 ColorBlueI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_COLORBACK)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_COLORBACK)/4:
+ m_lg1.m_color_back = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 ColorBlueI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_ZPATTERN)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_ZPATTERN)/4:
+ m_lg1.m_z_pattern = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 ZPattern Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ if (go)
+ do_rex_command();
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_XENDI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_XENDI)/4:
+ m_lg1.m_x_end_i = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 XEndI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+ case (REX15_PAGE0_SET+REX15_P0REG_YENDI)/4:
+ case (REX15_PAGE0_GO+REX15_P0REG_YENDI)/4:
+ m_lg1.m_y_end_i = data;
+ LOGMASKED(LOG_REX, "%s: LG1 REX1.5 YEndI Write (%s) = %08x\n", machine().describe_context(), (offset & 0x200) ? "Go" : "Set", data);
+ break;
+
+ case (REX15_PAGE1_SET+REX15_P1REG_CFGSEL)/4:
+ case (REX15_PAGE1_GO+REX15_P1REG_CFGSEL)/4:
+ m_lg1.m_config_sel = data;
+ switch (data)
+ {
+ case REX15_WRITE_ADDR:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Write Addr)\n", machine().describe_context(), data);
+ break;
+ case REX15_PALETTE_RAM:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Palette RAM)\n", machine().describe_context(), data);
+ break;
+ case REX15_CONTROL:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Control)\n", machine().describe_context(), data);
+ break;
+ case REX15_PIXEL_READ_MASK:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Pixel Read Mask)\n", machine().describe_context(), data);
+ break;
+ default:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Unknown)\n", machine().describe_context(), data);
+ break;
+ }
+ break;
+ case (REX15_PAGE1_SET+REX15_P1REG_CFGDATA)/4:
+ case (REX15_PAGE1_GO+REX15_P1REG_CFGDATA)/4:
+ if (go) // Ignore 'Go' writes for now, unsure what they do
+ break;
+ switch (m_lg1.m_config_sel)
+ {
+ case REX15_WRITE_ADDR:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write: Setting WriteAddr to %08x\n", machine().describe_context(), data);
+ m_lg1.m_write_addr = data;
+ if (m_lg1.m_control == 0xf)
+ {
+ LOGMASKED(LOG_REX, "%s: LG1 about to set palette entry %02x\n", machine().describe_context(), (uint8_t)data);
+ m_lg1.m_palette_idx = (uint8_t)data;
+ m_lg1.m_palette_channel = 0;
+ }
+ break;
+ case REX15_PALETTE_RAM:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write: Setting Palette RAM %02x entry %d to %02x\n", machine().describe_context(),
+ m_lg1.m_palette_idx, m_lg1.m_palette_channel, (uint8_t)data);
+ m_lg1.m_palette_entry[m_lg1.m_palette_channel++] = (uint8_t)data;
+ if (m_lg1.m_palette_channel == 3)
+ {
+ m_palette->set_pen_color(m_lg1.m_palette_idx, m_lg1.m_palette_entry[0], m_lg1.m_palette_entry[1], m_lg1.m_palette_entry[2]);
+ }
+ break;
+ case REX15_CONTROL:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write: Setting Control to %08x\n", machine().describe_context(), data);
+ m_lg1.m_control = data;
+ break;
+ case REX15_PIXEL_READ_MASK:
+ LOGMASKED(LOG_REX, "%s: LG1 ConfigSel Write = %08x (Pixel Read Mask, entry %02x)\n", machine().describe_context(), data, m_lg1.m_palette_idx);
+ m_lg1.m_pix_read_mask[m_lg1.m_palette_idx] = (uint8_t)data;
+ break;
+ default:
+ LOGMASKED(LOG_REX, "%s: LG1 Unknown ConfigData Write = %08x\n", machine().describe_context(), data);
+ break;
+ }
+ break;
+ default:
+ LOGMASKED(LOG_REX, "%s: Unknown LG1 Write: %08x = %08x & %08x\n", machine().describe_context(), 0x1f3f0000 + offset*4, data, mem_mask);
+ break;
+ }
+}
+
+void light_video_device::do_rex_command()
+{
+ if (m_lg1.m_command == 0)
+ {
+ return;
+ }
+ if (m_lg1.m_command == 0x30080329)
+ {
+ bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
+ bool copy = (m_lg1.m_command & REX15_OP_FLAG_LOGICSRC);
+ const uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
+ const uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
+ const uint32_t end_x = m_lg1.m_x_end_i;
+ const uint32_t end_y = m_lg1.m_y_end_i;
+ const uint32_t src_start_x = start_x + (m_lg1.m_xy_move >> 16);
+ const uint32_t src_start_y = start_y + (uint16_t)m_lg1.m_xy_move;;
+
+ LOGMASKED(LOG_REX, "LG1: Command %08x: Block copy from %d,%d-%d,%d inclusive.\n", m_lg1.m_command, start_x, start_y, end_x, end_y);
+ if (copy)
+ {
+ for (uint32_t y = start_y, src_y = src_start_y; y <= end_y; y++, src_y++)
+ for (uint32_t x = start_x, src_x = src_start_x; x <= end_x; x++, src_x++)
+ m_framebuffer[y*x_res + x] = m_framebuffer[src_y*x_res + src_x];
+ }
+ else
+ {
+ for (uint32_t y = start_y; y <= end_y; y++)
+ for (uint32_t x = start_x; x <= end_x; x++)
+ m_framebuffer[y*x_res + x] = m_lg1.m_color_red_i;
+ }
+ }
+ else if (m_lg1.m_command == 0x30000329)
+ {
+ bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
+ uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
+ uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
+ uint32_t end_x = m_lg1.m_x_end_i;
+ uint32_t end_y = m_lg1.m_y_end_i;
+
+ LOGMASKED(LOG_REX, "LG1: Command %08x: Block draw from %d,%d-%d,%d inclusive.\n", m_lg1.m_command, start_x, start_y, end_x, end_y);
+ for (uint32_t y = start_y; y <= end_y; y++)
+ {
+ for (uint32_t x = start_x; x <= end_x; x++)
+ {
+ m_framebuffer[y*x_res + x] = m_lg1.m_color_red_i;
+ }
+ }
+ }
+ else if (m_lg1.m_command == 0x300005a1 ||
+ m_lg1.m_command == 0x300005a9 ||
+ m_lg1.m_command == 0x300005b9)
+ {
+ bool xycontinue = (m_lg1.m_command & REX15_OP_FLAG_XYCONTINUE);
+ uint32_t start_x = xycontinue ? m_lg1.m_x_curr_i : m_lg1.m_x_start_i;
+ uint32_t start_y = xycontinue ? m_lg1.m_y_curr_i : m_lg1.m_y_start_i;
+ uint32_t end_x = m_lg1.m_x_end_i;
+ LOGMASKED(LOG_REX, "LG1: Command %08x: Pattern draw from %d-%d at %d\n", m_lg1.m_command, start_x, end_x, start_y);
+ for (uint32_t x = start_x; x <= end_x && x < (start_x + 32); x++)
+ {
+ if (BIT(m_lg1.m_z_pattern, 31 - (x - start_x)))
+ {
+ m_framebuffer[start_y*x_res + x] = m_lg1.m_color_red_i;
+ }
+ m_lg1.m_x_curr_i++;
+ }
+
+ if (m_lg1.m_command & REX15_OP_FLAG_BLOCK)
+ {
+ if (m_lg1.m_x_curr_i > m_lg1.m_x_end_i)
+ {
+ m_lg1.m_y_curr_i--;
+ m_lg1.m_x_curr_i = m_lg1.m_x_start_i;
+ }
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_REX, "%s: Unknown LG1 command: %08x\n", machine().describe_context(), m_lg1.m_command);
+ }
+}
diff --git a/src/mame/video/light.h b/src/mame/video/light.h
new file mode 100644
index 00000000000..ffc9932d02e
--- /dev/null
+++ b/src/mame/video/light.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz, Tyson Smith
+/*
+ Silicon Graphics LG1 "Light" graphics board used as
+ entry level graphics in the Indigo and IRIS Crimson.
+*/
+
+#ifndef MAME_VIDEO_LIGHT_H
+#define MAME_VIDEO_LIGHT_H
+
+#pragma once
+
+#include "emupal.h"
+
+class light_video_device : public device_t
+{
+public:
+ light_video_device(const machine_config &mconfig, const char *tag, device_t *owner)
+ : light_video_device(mconfig, tag, owner, (uint32_t)0)
+ {
+ }
+
+ light_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ uint32_t screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+ DECLARE_READ32_MEMBER(entry_r);
+ DECLARE_WRITE32_MEMBER(entry_w);
+
+ static constexpr uint32_t x_res = 1024;
+ static constexpr uint32_t y_res = 768;
+
+protected:
+ void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ void do_rex_command();
+
+ struct lg1_t
+ {
+ uint32_t m_config_sel;
+ uint32_t m_write_addr;
+ uint32_t m_control;
+
+ uint32_t m_command;
+ uint32_t m_x_start_i;
+ uint32_t m_y_start_i;
+ uint32_t m_xy_move;
+ uint32_t m_color_red_i;
+ uint32_t m_color_green_i;
+ uint32_t m_color_blue_i;
+ uint32_t m_color_back;
+ uint32_t m_z_pattern;
+ uint32_t m_x_end_i;
+ uint32_t m_y_end_i;
+ uint32_t m_x_curr_i;
+ uint32_t m_y_curr_i;
+
+ uint8_t m_palette_idx;
+ uint8_t m_palette_channel;
+ uint8_t m_palette_entry[3];
+ uint8_t m_pix_read_mask[256];
+ };
+ lg1_t m_lg1;
+
+ required_device<palette_device> m_palette;
+ std::unique_ptr<uint8_t[]> m_framebuffer;
+};
+
+DECLARE_DEVICE_TYPE(LIGHT_VIDEO, light_video_device)
+
+
+#endif // MAME_VIDEO_LIGHT_H