summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/sed1375.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/sed1375.cpp')
-rw-r--r--src/devices/video/sed1375.cpp549
1 files changed, 549 insertions, 0 deletions
diff --git a/src/devices/video/sed1375.cpp b/src/devices/video/sed1375.cpp
new file mode 100644
index 00000000000..9271ad8d754
--- /dev/null
+++ b/src/devices/video/sed1375.cpp
@@ -0,0 +1,549 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ Epson SED1375 LCD Controller emulation skeleton
+
+ - Currently hard-coded for use with the Palm IIIc driver.
+ - TODO: Find more test-case systems.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "sed1375.h"
+#include "screen.h"
+
+#define LOG_REG_READ (1U << 1)
+#define LOG_REG_WRITE (1U << 2)
+#define LOG_VRAM_READ (1U << 3)
+#define LOG_VRAM_WRITE (1U << 4)
+#define LOG_LUT_READ (1U << 5)
+#define LOG_LUT_WRITE (1U << 6)
+#define LOG_VBL_READ (1U << 7)
+#define LOG_ALL (LOG_REG_READ | LOG_REG_WRITE | LOG_VRAM_READ | LOG_VRAM_WRITE | LOG_LUT_READ | LOG_LUT_WRITE | LOG_VBL_READ)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(SED1375, sed1375_device, "sed1375", "Epson SED1375")
+
+sed1375_device::sed1375_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, SED1375, tag, owner, clock)
+ , device_video_interface(mconfig, *this)
+ , m_vram(*this, "vram", 80 * 1024, ENDIANNESS_BIG)
+{
+}
+
+void sed1375_device::device_start()
+{
+ save_item(NAME(m_revision));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_panel_hsize));
+ save_item(NAME(m_panel_vsize));
+ save_item(NAME(m_fpline_start));
+ save_item(NAME(m_hblank_period));
+ save_item(NAME(m_fpframe_start));
+ save_item(NAME(m_vblank_period));
+ save_item(NAME(m_mod_rate));
+ save_item(NAME(m_screen_start));
+ save_item(NAME(m_screen_start_ovf));
+ save_item(NAME(m_mem_addr_offset));
+ save_item(NAME(m_screen1_vsize));
+ save_item(NAME(m_lut_addr));
+ save_item(NAME(m_lut_index));
+ save_item(NAME(m_red_lut));
+ save_item(NAME(m_green_lut));
+ save_item(NAME(m_blue_lut));
+ save_item(NAME(m_gpio_config));
+ save_item(NAME(m_gpio_status));
+ save_item(NAME(m_scratch));
+ save_item(NAME(m_swivel_mode));
+ save_item(NAME(m_swivel_bytecnt));
+}
+
+void sed1375_device::device_reset()
+{
+ m_revision = 0x24;
+ std::fill(std::begin(m_mode), std::end(m_mode), 0);
+ m_panel_hsize = 0x03;
+ m_panel_vsize = 0;
+ m_fpline_start = 0;
+ m_hblank_period = 0;
+ m_fpframe_start = 0;
+ m_vblank_period = 0;
+ m_mod_rate = 0;
+ std::fill(std::begin(m_screen_start), std::end(m_screen_start), 0);
+ m_screen_start_ovf = 0;
+ m_mem_addr_offset = 0;
+ m_screen1_vsize = 0;
+ m_lut_addr = 0;
+ m_lut_index = 0;
+ std::fill(std::begin(m_red_lut), std::end(m_red_lut), 0);
+ std::fill(std::begin(m_green_lut), std::end(m_green_lut), 0);
+ std::fill(std::begin(m_blue_lut), std::end(m_blue_lut), 0);
+ m_gpio_config = 0;
+ m_gpio_status = 0;
+ m_scratch = 0;
+ m_swivel_mode = 0;
+ m_swivel_bytecnt = 0;
+}
+
+void sed1375_device::map(address_map &map)
+{
+ map(0x00000, 0x13fff).rw(FUNC(sed1375_device::vram_r), FUNC(sed1375_device::vram_w));
+ map(0x1ffe0, 0x1ffe0).r(FUNC(sed1375_device::revision_r));
+ map(0x1ffe1, 0x1ffe1).rw(FUNC(sed1375_device::mode0_r), FUNC(sed1375_device::mode0_w));
+ map(0x1ffe2, 0x1ffe2).rw(FUNC(sed1375_device::mode1_r), FUNC(sed1375_device::mode1_w));
+ map(0x1ffe3, 0x1ffe3).rw(FUNC(sed1375_device::mode2_r), FUNC(sed1375_device::mode2_w));
+ map(0x1ffe4, 0x1ffe4).rw(FUNC(sed1375_device::panel_hsize_r), FUNC(sed1375_device::panel_hsize_w));
+ map(0x1ffe5, 0x1ffe5).rw(FUNC(sed1375_device::panel_vsize_lsb_r), FUNC(sed1375_device::panel_vsize_lsb_w));
+ map(0x1ffe6, 0x1ffe6).rw(FUNC(sed1375_device::panel_vsize_msb_r), FUNC(sed1375_device::panel_vsize_msb_w));
+ map(0x1ffe7, 0x1ffe7).rw(FUNC(sed1375_device::fpline_start_r), FUNC(sed1375_device::fpline_start_w));
+ map(0x1ffe8, 0x1ffe8).rw(FUNC(sed1375_device::hblank_r), FUNC(sed1375_device::hblank_w));
+ map(0x1ffe9, 0x1ffe9).rw(FUNC(sed1375_device::fpframe_start_r), FUNC(sed1375_device::fpframe_start_w));
+ map(0x1ffea, 0x1ffea).rw(FUNC(sed1375_device::vblank_r), FUNC(sed1375_device::vblank_w));
+ map(0x1ffeb, 0x1ffeb).rw(FUNC(sed1375_device::mod_rate_r), FUNC(sed1375_device::mod_rate_w));
+ map(0x1ffec, 0x1ffec).rw(FUNC(sed1375_device::screen1_start_lsb_r), FUNC(sed1375_device::screen1_start_lsb_w));
+ map(0x1ffed, 0x1ffed).rw(FUNC(sed1375_device::screen1_start_msb_r), FUNC(sed1375_device::screen1_start_msb_w));
+ map(0x1ffee, 0x1ffee).rw(FUNC(sed1375_device::screen2_start_lsb_r), FUNC(sed1375_device::screen2_start_lsb_w));
+ map(0x1ffef, 0x1ffef).rw(FUNC(sed1375_device::screen2_start_msb_r), FUNC(sed1375_device::screen2_start_msb_w));
+ map(0x1fff0, 0x1fff0).rw(FUNC(sed1375_device::screen1_start_ovf_r), FUNC(sed1375_device::screen1_start_ovf_w));
+ map(0x1fff1, 0x1fff1).rw(FUNC(sed1375_device::mem_addr_offset_r), FUNC(sed1375_device::mem_addr_offset_w));
+ map(0x1fff2, 0x1fff2).rw(FUNC(sed1375_device::screen1_vsize_lsb_r), FUNC(sed1375_device::screen1_vsize_lsb_w));
+ map(0x1fff3, 0x1fff3).rw(FUNC(sed1375_device::screen1_vsize_msb_r), FUNC(sed1375_device::screen1_vsize_msb_w));
+ map(0x1fff5, 0x1fff5).rw(FUNC(sed1375_device::lut_addr_r), FUNC(sed1375_device::lut_addr_w));
+ map(0x1fff7, 0x1fff7).rw(FUNC(sed1375_device::lut_data_r), FUNC(sed1375_device::lut_data_w));
+ map(0x1fff8, 0x1fff8).rw(FUNC(sed1375_device::gpio_config_r), FUNC(sed1375_device::gpio_config_w));
+ map(0x1fff9, 0x1fff9).rw(FUNC(sed1375_device::gpio_r), FUNC(sed1375_device::gpio_w));
+ map(0x1fffa, 0x1fffa).rw(FUNC(sed1375_device::scratch_r), FUNC(sed1375_device::scratch_w));
+ map(0x1fffb, 0x1fffb).rw(FUNC(sed1375_device::swivel_mode_r), FUNC(sed1375_device::swivel_mode_w));
+ map(0x1fffc, 0x1fffc).rw(FUNC(sed1375_device::swivel_bytecnt_r), FUNC(sed1375_device::swivel_bytecnt_w));
+}
+
+u32 sed1375_device::get_pixel(int screen_idx, int x, int y)
+{
+ const u32 pixels_per_line = (m_panel_hsize + 1) * 8;
+ const u32 bpp = 1 << ((m_mode[1] & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT);
+ const u32 pixel_index = y * pixels_per_line + x;
+ const u32 byte_index = (pixel_index * bpp) / 8;
+ const u32 bit_index = x % (8 / bpp);
+ const u8 bpp_mask = (1 << bpp) - 1;
+ return (m_vram[(m_screen_start[screen_idx] << 1) + byte_index] >> (bit_index * bpp)) & bpp_mask;
+}
+
+u32 sed1375_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ if (BIT(m_mode[1], MODE1_BLANK_BIT))
+ {
+ bitmap.fill(0xff000000, cliprect);
+ return 0;
+ }
+
+ for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ u32 *dst = &bitmap.pix(y);
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ u32 pix = get_pixel(0, x, y);
+ if (BIT(m_mode[0], MODE0_TFT_BIT) || BIT(m_mode[0], MODE0_COLOR_BIT))
+ {
+ const u8 r = m_red_lut[pix];
+ const u8 g = m_green_lut[pix];
+ const u8 b = m_blue_lut[pix];
+ *dst++ = 0xff000000 | (((r << 4) | r) << 16) | (((g << 4) | g) << 8) | ((b << 4) | b);
+ }
+ else
+ {
+ switch ((m_mode[1] & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT)
+ {
+ case 0: // 1bpp
+ *dst++ = 0xff000000 | (pix * 0xffffff);
+ break;
+ case 1: // 2bpp
+ *dst++ = 0xff000000 | (pix * 0x555555);
+ break;
+ case 2: // 4bpp
+ *dst++ = 0xff000000 | (pix * 0x111111);
+ break;
+ case 3: // 8bpp
+ *dst++ = 0xff000000 | (pix * 0x010101);
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void sed1375_device::vram_w(offs_t offset, u8 data)
+{
+ LOGMASKED(LOG_VRAM_WRITE, "%s: vram_w: VRAM Write[%05x] = %02x\n", machine().describe_context(), offset, data);
+ m_vram[offset] = data;
+}
+
+u8 sed1375_device::vram_r(offs_t offset)
+{
+ LOGMASKED(LOG_VRAM_READ, "%s: vram_r: VRAM Read[%05x]: %02x\n", machine().describe_context(), offset, m_vram[offset]);
+ return m_vram[offset];
+}
+
+u8 sed1375_device::revision_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: revision_r: %02x\n", machine().describe_context(), m_revision);
+ return m_revision;
+}
+
+void sed1375_device::mode0_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: mode0_w: Mode Register 0 = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s Data Width Bits: %d\n", machine().describe_context(), data & MODE0_WIDTH_MASK);
+ LOGMASKED(LOG_REG_WRITE, "%s Mask FPSHIFT: %d\n", machine().describe_context(), BIT(data, MODE0_FPSHIFT_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s FPFRAME Polarity: %s\n", machine().describe_context(), BIT(data, MODE0_FPFRAME_POL_BIT) ? "Active-High" : "Active-Low");
+ LOGMASKED(LOG_REG_WRITE, "%s FPLINE Polarity: %s\n", machine().describe_context(), BIT(data, MODE0_FPLINE_POL_BIT) ? "Active-High" : "Active-Low");
+ LOGMASKED(LOG_REG_WRITE, "%s Color/Mono: %s\n", machine().describe_context(), BIT(data, MODE0_COLOR_BIT) ? "Color" : "Mono");
+ LOGMASKED(LOG_REG_WRITE, "%s Dual/Single: %s\n", machine().describe_context(), BIT(data, MODE0_DUAL_BIT) ? "Dual" : "Single");
+ LOGMASKED(LOG_REG_WRITE, "%s TFT/STN: %s\n", machine().describe_context(), BIT(data, MODE0_TFT_BIT) ? "TFT" : "STN");
+ m_mode[0] = data & MODE0_MASK;
+}
+
+u8 sed1375_device::mode0_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: mode0_r: Mode Register 0: %02x\n", machine().describe_context(), m_mode[0]);
+ return m_mode[0];
+}
+
+void sed1375_device::mode1_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: mode1_w: Mode Register 1 = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s Software Video Invert: %d\n", machine().describe_context(), BIT(data, MODE1_SWINVERT_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s Hardware Video Invert: %d\n", machine().describe_context(), BIT(data, MODE1_HWINVERT_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s Frame Repeat: %d\n", machine().describe_context(), BIT(data, MODE1_FRREPEAT_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s Display Blank: %d\n", machine().describe_context(), BIT(data, MODE1_BLANK_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s Input Clock Divider: %d\n", machine().describe_context(), BIT(data, MODE1_CLKDIV_BIT) + 1);
+ LOGMASKED(LOG_REG_WRITE, "%s High Performance: %d\n", machine().describe_context(), BIT(data, MODE1_HIPERF_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s Bits Per Pixel: %d\n", machine().describe_context(), 1 << ((data & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT));
+ m_mode[1] = data & MODE1_MASK;
+}
+
+u8 sed1375_device::mode1_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: mode1_r: Mode Register 1: %02x\n", machine().describe_context(), m_mode[1]);
+ return m_mode[1];
+}
+
+void sed1375_device::mode2_w(u8 data)
+{
+ static const char *const SWPWRSAVE_NAMES[4] = { "Software Power Save", "Reserved (1)", "Reserved (2)", "Normal Operation" };
+ LOGMASKED(LOG_REG_WRITE, "%s: mode2_w: Mode Register 2 = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s Software Power Save Mode: %s\n", machine().describe_context(), SWPWRSAVE_NAMES[data & MODE2_SWPWRSAVE_MASK]);
+ LOGMASKED(LOG_REG_WRITE, "%s Hardware Power Save: %d\n", machine().describe_context(), BIT(data, MODE2_HWPWRSAVE_BIT));
+ LOGMASKED(LOG_REG_WRITE, "%s LCDPWR Override: %d\n", machine().describe_context(), BIT(data, MODE2_LCDPWR_OVR_BIT));
+ m_mode[2] = data & MODE2_MASK;
+}
+
+u8 sed1375_device::mode2_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: mode2_r: Mode Register 2: %02x\n", machine().describe_context(), m_mode[2]);
+ return m_mode[2];
+}
+
+void sed1375_device::panel_hsize_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: panel_hsize_w: Panel Horizontal Size = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & PANEL_HSIZE_MASK) + 1) * 8);
+ m_panel_hsize = data & PANEL_HSIZE_MASK;
+}
+
+u8 sed1375_device::panel_hsize_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: panel_hsize_r: Panel Horizontal Size: %02x\n", machine().describe_context(), m_panel_hsize);
+ return m_panel_hsize;
+}
+
+void sed1375_device::panel_vsize_lsb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: panel_vsize_lsb_w: Panel Vertical Size (LSB) = %02x\n", machine().describe_context(), data);
+ m_panel_vsize = ((m_panel_vsize & 0xff00) | data) & PANEL_VSIZE_MASK;
+}
+
+u8 sed1375_device::panel_vsize_lsb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: panel_vsize_lsb_r: Panel Vertical Size (LSB): %02x\n", machine().describe_context(), m_panel_vsize & 0x00ff);
+ return m_panel_vsize;
+}
+
+void sed1375_device::panel_vsize_msb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: panel_vsize_msb_w: Panel Vertical Size (MSB) = %02x\n", machine().describe_context(), data);
+ m_panel_vsize = ((m_panel_vsize & 0x00ff) | (data << 8)) & PANEL_VSIZE_MASK;
+}
+
+u8 sed1375_device::panel_vsize_msb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: panel_vsize_msb_r: Panel Vertical Size (MSB): %02x\n", machine().describe_context(), m_panel_vsize >> 8);
+ return m_panel_vsize >> 8;
+}
+
+void sed1375_device::fpline_start_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: fpline_start_w: FPLINE Start Position = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & FPLINE_START_MASK) + 2) * 8);
+ m_fpline_start = data & FPLINE_START_MASK;
+}
+
+u8 sed1375_device::fpline_start_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: fpline_start_r: FPLINE Start Position: %02x\n", machine().describe_context(), m_fpline_start);
+ return m_fpline_start;
+}
+
+void sed1375_device::hblank_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: hblank_w: Horizontal Blanking Period = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & HBLANK_MASK) + 4) * 8);
+ m_hblank_period = data & HBLANK_MASK;
+}
+
+u8 sed1375_device::hblank_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: hblank_r: Horizontal Blanking Period: %02x\n", machine().describe_context(), m_hblank_period);
+ return m_hblank_period;
+}
+
+void sed1375_device::fpframe_start_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: fpline_start_w: FPFRAME Start Position = %02x\n", machine().describe_context(), data);
+ m_fpframe_start = data & FPFRAME_START_MASK;
+}
+
+u8 sed1375_device::fpframe_start_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: fpframe_start_r: FPFRAME Start Position: %02x\n", machine().describe_context(), m_fpframe_start);
+ return m_fpframe_start;
+}
+
+void sed1375_device::vblank_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: vblank_w: Vertical Blanking Period = %02x\n", machine().describe_context(), data);
+ m_vblank_period = data & VBLANK_MASK;
+}
+
+u8 sed1375_device::vblank_r()
+{
+ const u8 data = m_vblank_period | (screen().vblank() ? (1 << VBLANK_VBL_BIT) : 0);
+ LOGMASKED(LOG_VBL_READ, "%s: vblank_r: Vertical Blanking Period/Status: %02x\n", machine().describe_context(), data);
+ return data;
+}
+
+void sed1375_device::mod_rate_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: mod_rate_w: MOD Rate Register = %02x\n", machine().describe_context(), data);
+ m_mod_rate = data & MODRATE_MASK;
+}
+
+u8 sed1375_device::mod_rate_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: mod_rate_r: MOD Rate Register: %02x\n", machine().describe_context(), m_mod_rate);
+ return m_mod_rate;
+}
+
+void sed1375_device::screen2_start_lsb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen2_start_w: Screen 2 Start Address (LSB) = %02x\n", machine().describe_context(), data);
+ m_screen_start[1] = ((m_screen_start[1] & 0xff00) | data) & SCREEN2_START_MASK;
+}
+
+u8 sed1375_device::screen2_start_lsb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen2_start_r: Screen 2 Start Address (LSB): %02x\n", machine().describe_context(), (u8)m_screen_start[1]);
+ return (u8)m_screen_start[1];
+}
+
+void sed1375_device::screen1_start_msb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_w: Screen 1 Start Address (MSB) = %02x\n", machine().describe_context(), data);
+ m_screen_start[0] = ((m_screen_start[0] & 0x00ff) | (data << 8)) & SCREEN1_START_MASK;
+}
+
+u8 sed1375_device::screen1_start_msb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen1_start_r: Screen 1 Start Address (MSB): %02x\n", machine().describe_context(), (u8)(m_screen_start[0] >> 8));
+ return (u8)(m_screen_start[0] >> 8);
+}
+
+void sed1375_device::screen1_start_lsb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_w: Screen 1 Start Address (LSB) = %02x\n", machine().describe_context(), data);
+ m_screen_start[0] = ((m_screen_start[0] & 0xff00) | data) & SCREEN1_START_MASK;
+}
+
+u8 sed1375_device::screen1_start_lsb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen1_start_r: Screen 1 Start Address (LSB): %02x\n", machine().describe_context(), (u8)m_screen_start[0]);
+ return (u8)m_screen_start[0];
+}
+
+void sed1375_device::screen2_start_msb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen2_start_w: Screen 2 Start Address (MSB) = %02x\n", machine().describe_context(), data);
+ m_screen_start[1] = ((m_screen_start[1] & 0x00ff) | (data << 8)) & SCREEN2_START_MASK;
+}
+
+u8 sed1375_device::screen2_start_msb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen2_start_r: Screen 2 Start Address (MSB): %02x\n", machine().describe_context(), (u8)(m_screen_start[1] >> 8));
+ return (u8)(m_screen_start[1] >> 8);
+}
+
+void sed1375_device::screen1_start_ovf_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_ovf_w: Screen Start Address Overflow Register = %02x\n", machine().describe_context(), data);
+ m_screen_start_ovf = data & START_OVF_MASK;
+}
+
+u8 sed1375_device::screen1_start_ovf_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen1_start_ovf_r: Screen Start Address Overflow Register: %02x\n", machine().describe_context(), m_screen_start_ovf);
+ return m_screen_start_ovf;
+}
+
+void sed1375_device::mem_addr_offset_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: mem_addr_offset_w: Memory Address Offset Register = %02x\n", machine().describe_context(), data);
+ m_mem_addr_offset = data & MEM_ADDR_OFFSET_MASK;
+}
+
+u8 sed1375_device::mem_addr_offset_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: mem_addr_offset_r: Memory Address Offset Register: %02x\n", machine().describe_context(), m_mem_addr_offset);
+ return m_mem_addr_offset;
+}
+
+void sed1375_device::screen1_vsize_lsb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen1_vsize_lsb_w: Screen 1 Vertical Size Register (LSB) = %02x\n", machine().describe_context(), data);
+ m_screen1_vsize = ((m_screen1_vsize & 0xff00) | data) & SCREEN1_VSIZE_MASK;
+}
+
+u8 sed1375_device::screen1_vsize_lsb_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: screen1_vsize_lsb_r: Screen 1 Vertical Size Register (LSB): %02x\n", machine().describe_context(), (u8)m_screen1_vsize);
+ return (u8)m_screen1_vsize;
+}
+
+void sed1375_device::screen1_vsize_msb_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: screen1_vsize_msb_w: Screen 1 Vertical Size Register (MSB) = %02x\n", machine().describe_context(), data);
+ m_screen1_vsize = ((m_screen1_vsize & 0x00ff) | (data << 8)) & SCREEN1_VSIZE_MASK;
+}
+
+u8 sed1375_device::screen1_vsize_msb_r()
+{
+ LOGMASKED(LOG_LUT_READ, "%s: screen1_vsize_msb_r: Screen 1 Vertical Size Register (MSB): %02x\n", machine().describe_context(), (u8)(m_screen1_vsize >> 8));
+ return (u8)(m_screen1_vsize >> 8);
+}
+
+void sed1375_device::lut_addr_w(u8 data)
+{
+ LOGMASKED(LOG_LUT_WRITE, "%s: lut_addr_w: LUT Address Register = %02x\n", machine().describe_context(), data);
+ m_lut_addr = data & LUT_ADDR_MASK;
+ m_lut_index = 0;
+}
+
+u8 sed1375_device::lut_addr_r()
+{
+ LOGMASKED(LOG_LUT_READ, "%s: lut_addr_r: LUT Address Register: %02x\n", machine().describe_context(), m_lut_addr);
+ return m_lut_addr;
+}
+
+void sed1375_device::lut_data_w(u8 data)
+{
+ static const char *const LUT_INDEX_NAMES[3] = { "Red", "Green", "Blue" };
+ LOGMASKED(LOG_LUT_WRITE, "%s: lut_data_w: LUT Data[%d] = %02x (%s)\n", machine().describe_context(), (u32)m_lut_addr, data, LUT_INDEX_NAMES[m_lut_index]);
+
+ u8 *lut_data[3] = { m_red_lut, m_green_lut, m_blue_lut };
+ lut_data[m_lut_index++][m_lut_addr] = (data & LUT_DATA_MASK) >> LUT_DATA_SHIFT;
+ if (m_lut_index >= 3)
+ {
+ m_lut_addr++;
+ m_lut_index = 0;
+ }
+}
+
+u8 sed1375_device::lut_data_r()
+{
+ static const char *const LUT_INDEX_NAMES[3] = { "Red", "Green", "Blue" };
+ u8 *lut_data[3] = { m_red_lut, m_green_lut, m_blue_lut };
+ const u8 data = lut_data[m_lut_index++][m_lut_addr];
+ LOGMASKED(LOG_REG_READ, "%s: lut_data_r: LUT Data[%d]: %02x (%s)\n", machine().describe_context(), (u32)m_lut_addr, data, LUT_INDEX_NAMES[m_lut_index]);
+ if (m_lut_index >= 3)
+ {
+ m_lut_addr++;
+ m_lut_index = 0;
+ }
+ return data;
+}
+
+void sed1375_device::gpio_config_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: gpio_config_w: GPIO Config Register = %02x\n", machine().describe_context(), data);
+ m_gpio_config = data & GPIO_CONFIG_MASK;
+}
+
+u8 sed1375_device::gpio_config_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: gpio_config_r: GPIO Config Register: %02x\n", machine().describe_context(), m_gpio_config);
+ return m_gpio_config;
+}
+
+void sed1375_device::gpio_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: gpio_w: GPIO Output = %02x\n", machine().describe_context(), data);
+ m_gpio_status = data & GPIO_STATUS_MASK;
+}
+
+u8 sed1375_device::gpio_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: gpio_r: GPIO Input: %02x\n", machine().describe_context(), m_gpio_status);
+ return m_gpio_status;
+}
+
+void sed1375_device::scratch_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: scratch_w: Scratch Pad Register = %02x\n", machine().describe_context(), data);
+ m_scratch = data & SCRATCH_MASK;
+}
+
+u8 sed1375_device::scratch_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: scratch_r: Scratch Pad Register: %02x\n", machine().describe_context(), m_scratch);
+ return m_scratch;
+}
+
+void sed1375_device::swivel_mode_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: swivel_mode_w: SwivelView Mode Register = %02x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_REG_WRITE, "%s: Pixel Clock Select Bits: %d\n", machine().describe_context(), data & SWIVEL_CLKSEL_MASK);
+ LOGMASKED(LOG_REG_WRITE, "%s: SwivelView Mode Select: %d\n", machine().describe_context(),
+ !BIT(data, SWIVEL_ENABLE_BIT) ? "Landscape" : (BIT(data, SWIVEL_MODE_BIT) ? "Alternate" : "Default"));
+ LOGMASKED(LOG_REG_WRITE, "%s: SwivelView Mode Enable: %d\n", machine().describe_context(), BIT(data, SWIVEL_ENABLE_BIT));
+ m_swivel_mode = data & SWIVEL_MODE_MASK;
+}
+
+u8 sed1375_device::swivel_mode_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: swivel_mode_r: SwivelView Mode Register: %02x\n", machine().describe_context(), m_swivel_mode);
+ return m_swivel_mode;
+}
+
+void sed1375_device::swivel_bytecnt_w(u8 data)
+{
+ LOGMASKED(LOG_REG_WRITE, "%s: swivel_bytecnt_w: SwivelView Line Byte Count = %02x\n", machine().describe_context(), data);
+ m_swivel_bytecnt = data & SWIVEL_BYTECNT_MASK;
+}
+
+u8 sed1375_device::swivel_bytecnt_r()
+{
+ LOGMASKED(LOG_REG_READ, "%s: swivel_bytecnt_r: SwivelView Line Byte Count: %02x\n", machine().describe_context(), m_swivel_bytecnt);
+ return m_swivel_bytecnt;
+}