summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2025-02-23 19:07:08 +0100
committer angelosa <lordkale4@gmail.com>2025-02-23 19:08:23 +0100
commitb9da31c7533696b99f79bde46a41ce9db72b5f62 (patch)
tree7a7629489bb6cc4a7183efc8eaf360e9c5d3d5b5 /src
parent2f7fc9004a382d2be6f56b53287a3897418ca09a (diff)
video/zr36060.cpp: hookup Codec and Video register handlers
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/pci/zr36057.cpp2
-rw-r--r--src/devices/video/zr36060.cpp617
-rw-r--r--src/devices/video/zr36060.h77
3 files changed, 671 insertions, 25 deletions
diff --git a/src/devices/bus/pci/zr36057.cpp b/src/devices/bus/pci/zr36057.cpp
index a286850b645..5e9d0ddc271 100644
--- a/src/devices/bus/pci/zr36057.cpp
+++ b/src/devices/bus/pci/zr36057.cpp
@@ -40,7 +40,7 @@ Known mix-ins:
#define LOG_WARN (1U << 1)
#define LOG_PO (1U << 2) // PostOffice interactions
-#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_PO)
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
//#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
diff --git a/src/devices/video/zr36060.cpp b/src/devices/video/zr36060.cpp
index 29c19dfdaad..8e406182737 100644
--- a/src/devices/video/zr36060.cpp
+++ b/src/devices/video/zr36060.cpp
@@ -5,6 +5,8 @@
#include "zr36060.h"
#define VERBOSE (LOG_GENERAL)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+
#include "logmacro.h"
DEFINE_DEVICE_TYPE(ZR36060, zr36060_device, "zr36060", "Zoran ZR36060 Integrated JPEG codec")
@@ -31,39 +33,606 @@ void zr36060_device::device_start()
void zr36060_device::device_reset()
{
+ m_load = false;
+ m_syncrst = false;
+ m_code_mstr = true;
+ m_codec_mode = 0x80;
}
void zr36060_device::regs_map(address_map &map)
{
-// map(0x000, 0x000) LOAD Parameters
-// map(0x001, 0x001) Code FIFO Status (r/o)
-// map(0x002, 0x002) Code Interface
-// map(0x003, 0x003) Codec Mode
-
-// map(0x005, 0x005) Maximum Block Code
-// map(0x006, 0x006) Markers Enable
-// map(0x007, 0x007) Interrupt Mask
-// map(0x008, 0x008) Interrupt Status (r/o)
-// map(0x009, 0x00c) Target Net Code Volume
-// map(0x00d, 0x010) Target Data Code Volume
-// map(0x011, 0x012) Scale Factor
-// map(0x013, 0x015) Allocation Factor
-// map(0x016, 0x019) Accumulated Code Volume
-// map(0x01a, 0x01d) Accumulated Total Activity
-// map(0x01e, 0x021) Accumulated Truncated Bits
+ // Codec Control Registers
+ map(0x000, 0x000).rw(FUNC(zr36060_device::load_r), FUNC(zr36060_device::load_w));
+ map(0x001, 0x001).r(FUNC(zr36060_device::code_fifo_status_r));
+ map(0x002, 0x002).rw(FUNC(zr36060_device::code_if_r), FUNC(zr36060_device::code_if_w));
+ map(0x003, 0x003).rw(FUNC(zr36060_device::codec_mode_r), FUNC(zr36060_device::codec_mode_w));
+
+ map(0x005, 0x005).rw(FUNC(zr36060_device::mbcv_r), FUNC(zr36060_device::mbcv_w));
+ map(0x006, 0x006).rw(FUNC(zr36060_device::markers_enable_r), FUNC(zr36060_device::markers_enable_w));
+ map(0x007, 0x007).rw(FUNC(zr36060_device::irq_mask_r), FUNC(zr36060_device::irq_mask_w));
+ map(0x008, 0x008).r(FUNC(zr36060_device::irq_status_r));
+ map(0x009, 0x00c).rw(FUNC(zr36060_device::tcv_net_r), FUNC(zr36060_device::tcv_net_w));
+ map(0x00d, 0x010).rw(FUNC(zr36060_device::tcv_data_r), FUNC(zr36060_device::tcv_data_w));
+ map(0x011, 0x012).rw(FUNC(zr36060_device::sf_r), FUNC(zr36060_device::sf_w));
+ map(0x013, 0x015).rw(FUNC(zr36060_device::af_r), FUNC(zr36060_device::af_w));
+
+ map(0x016, 0x019).rw(FUNC(zr36060_device::acv_r), FUNC(zr36060_device::acv_w));
+ map(0x01a, 0x01d).rw(FUNC(zr36060_device::act_r), FUNC(zr36060_device::act_w));
+ map(0x01e, 0x021).rw(FUNC(zr36060_device::acv_trun_r), FUNC(zr36060_device::acv_trun_w));
map(0x022, 0x022).lr8(NAME([this] (offs_t offset) { LOG("Read Device ID\n"); return 0x33; }));
map(0x023, 0x023).lr8(NAME([this] (offs_t offset) { LOG("Read Revision ID\n"); return 0x01; }));
// map(0x024, 0x025) Test Control
-// map(0x030, 0x030) Video Control
-// map(0x031, 0x031) Video Polarity
-// map(0x032, 0x032) Scaling
-// map(0x033, 0x035) Background Color
-// map(0x036, 0x041) Sync Generator
-// map(0x042, 0x049) Active Area
-// map(0x04a, 0x051) SUBIMG Window
+ // Video Registers
+ map(0x030, 0x030).rw(FUNC(zr36060_device::video_control_r), FUNC(zr36060_device::video_control_w));
+ map(0x031, 0x031).rw(FUNC(zr36060_device::video_polarity_r), FUNC(zr36060_device::video_polarity_w));
+ map(0x032, 0x032).rw(FUNC(zr36060_device::video_scaling_r), FUNC(zr36060_device::video_scaling_w));
+ // Background Color
+ map(0x033, 0x033).lrw8(
+ NAME([this] (offs_t offset) { return m_bg_color.y; }),
+ NAME([this] (offs_t offset, u8 data) { m_bg_color.y = data; LOG("Background Color Y %02x\n", data); })
+ );
+ map(0x034, 0x034).lrw8(
+ NAME([this] (offs_t offset) { return m_bg_color.u; }),
+ NAME([this] (offs_t offset, u8 data) { m_bg_color.u = data; LOG("Background Color U %02x\n", data); })
+ );
+ map(0x035, 0x035).lrw8(
+ NAME([this] (offs_t offset) { return m_bg_color.v; }),
+ NAME([this] (offs_t offset, u8 data) { m_bg_color.v = data; LOG("Background Color V %02x\n", data); })
+ );
+ // Sync Generator
+ map(0x036, 0x037).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_sync_gen.vtotal >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_sync_gen.vtotal &= offset ? 0xff00 : 0x00ff;
+ m_sync_gen.vtotal |= (data << shift);
+ LOG("Sync Generator: Vtotal [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_sync_gen.vtotal, m_sync_gen.vtotal + 1
+ );
+ })
+ );
+ map(0x038, 0x039).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_sync_gen.htotal >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_sync_gen.htotal &= offset ? 0x0300 : 0x00ff;
+ m_sync_gen.htotal |= (data << shift);
+ LOG("Sync Generator: Htotal [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_sync_gen.htotal, m_sync_gen.htotal + 1
+ );
+ })
+ );
+ map(0x03a, 0x03a).lrw8(
+ NAME([this] (offs_t offset) { return m_sync_gen.vsync_size; }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_sync_gen.vsync_size = data;
+ LOG("Sync Generator: VsyncSize %02x -> %d\n"
+ , data
+ , m_sync_gen.vsync_size + 1
+ );
+ })
+ );
+ map(0x03b, 0x03b).lrw8(
+ NAME([this] (offs_t offset) { return m_sync_gen.hsync_size; }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_sync_gen.hsync_size = data;
+ LOG("Sync Generator: HsyncSize %02x -> %d\n"
+ , data
+ , m_sync_gen.hsync_size + 1
+ );
+ })
+ );
+ map(0x03c, 0x03c).lrw8(
+ NAME([this] (offs_t offset) { return m_sync_gen.bvstart; }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_sync_gen.bvstart = data;
+ LOG("Sync Generator: BVstart %02x -> %d\n"
+ , data
+ , m_sync_gen.bvstart + 1
+ );
+ })
+ );
+ map(0x03d, 0x03d).lrw8(
+ NAME([this] (offs_t offset) { return m_sync_gen.bhstart; }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_sync_gen.bhstart = data;
+ LOG("Sync Generator: BHstart %02x -> %d\n"
+ , data
+ , m_sync_gen.bhstart + 1
+ );
+ })
+ );
+ map(0x03e, 0x03f).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_sync_gen.bvend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_sync_gen.bvend &= offset ? 0xff00 : 0x00ff;
+ m_sync_gen.bvend |= (data << shift);
+ LOG("Sync Generator: BVend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_sync_gen.bvend, m_sync_gen.bvend
+ );
+ })
+ );
+ map(0x040, 0x041).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_sync_gen.bhend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_sync_gen.bhend &= offset ? 0x0300 : 0x00ff;
+ m_sync_gen.bhend |= (data << shift);
+ LOG("Sync Generator: BHend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_sync_gen.bhend, m_sync_gen.bhend
+ );
+ })
+ );
+
+ // Active Area
+ map(0x042, 0x043).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_active_area.vstart >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_active_area.vstart &= offset ? 0xff00 : 0x00ff;
+ m_active_area.vstart |= (data << shift);
+ LOG("Active Area: Vstart [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_active_area.vstart, m_active_area.vstart + 1
+ );
+ })
+ );
+ map(0x044, 0x045).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_active_area.vend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_active_area.vend &= offset ? 0xff00 : 0x00ff;
+ m_active_area.vend |= (data << shift);
+ LOG("Active Area: Vend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_active_area.vend, m_active_area.vend
+ );
+ })
+ );
+ map(0x046, 0x047).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_active_area.hstart >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_active_area.hstart &= offset ? 0x0300 : 0x00ff;
+ m_active_area.hstart |= (data << shift);
+ LOG("Active Area: Hstart [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_active_area.hstart, m_active_area.hstart + 1
+ );
+ })
+ );
+ map(0x048, 0x049).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_active_area.hend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_active_area.hend &= offset ? 0x0300 : 0x00ff;
+ m_active_area.hend |= (data << shift);
+ LOG("Active Area: Hend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_active_area.hend, m_active_area.hend + 1
+ );
+ })
+ );
+
+ // SUBIMG Window
+ map(0x04a, 0x04b).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_subimg_window.svstart >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_subimg_window.svstart &= offset ? 0xff00 : 0x00ff;
+ m_subimg_window.svstart |= (data << shift);
+ LOG("SUBIMG Window: SVstart [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_subimg_window.svstart, m_subimg_window.svstart + 1
+ );
+ })
+ );
+ map(0x04c, 0x04d).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_subimg_window.svend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_subimg_window.svend &= offset ? 0xff00 : 0x00ff;
+ m_subimg_window.svend |= (data << shift);
+ LOG("SUBIMG Window: SVend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_subimg_window.svend, m_subimg_window.svend
+ );
+ })
+ );
+ map(0x04e, 0x04f).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_subimg_window.shstart >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_subimg_window.shstart &= offset ? 0x0300 : 0x00ff;
+ m_subimg_window.shstart |= (data << shift);
+ LOG("SUBIMG Window: SHstart [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_subimg_window.shstart, m_subimg_window.shstart + 1
+ );
+ })
+ );
+ map(0x050, 0x051).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_subimg_window.shend >> (offset ? 0 : 8)) & 0xff; }
+ ),
+ NAME([this] (offs_t offset, u8 data) {
+ const u8 shift = offset ? 0 : 8;
+ m_subimg_window.shend &= offset ? 0x0300 : 0x00ff;
+ m_subimg_window.shend |= (data << shift);
+ LOG("SUBIMG Window: SHend [%01x] %02x -> %04x %d\n"
+ , offset, data
+ , m_subimg_window.shend, m_subimg_window.shend + 1
+ );
+ })
+ );
+
+ // JPEG Markers Array
+ map(0x060, 0x3ff).ram();
+}
+
+/**************************************
+ *
+ * Codec Control Registers
+ *
+ *************************************/
+
+/*
+ * [0x000] LOAD Parameters
+ * x--- ---- LOAD parameters if 1
+ * ---- ---x SyncRst resets video sync generator if 1 (keeps h/vpos to 0,0 until goes off)
+ */
+u8 zr36060_device::load_r(offs_t offset)
+{
+ return (m_load << 7) | (m_syncrst << 0);
+}
+
+void zr36060_device::load_w(offs_t offset, u8 data)
+{
+ m_load = !!(BIT(data, 7));
+ m_syncrst = !!(BIT(data, 0));
+ LOG("LOAD Parameters %02x: LOAD %d SYNCRST %d\n", data, m_load, m_syncrst);
+}
+
+/*
+ * [0x001] Code FIFO status (r/o)
+ * x--- ---- Busy Status for LOAD operation (takes ~100ms to complete)
+ * ---- -x-- CBUSY Code FIFO empty/full condition (same as /CBUSY pin)
+ * ---- -0-- Code FIFO not full/not empty
+ * ---- -1-- Code FIFO full/empty
+ * ---- --xx CFIFO Code FIFO fullness state
+ * ---- --00 < 1/4
+ * ---- --01 >= 1/4 && < 1/2
+ * ---- --10 >= 1/2 && < 3/4
+ * ---- --11 >= 3/4
+ */
+u8 zr36060_device::code_fifo_status_r(offs_t offset)
+{
+ return 0;
+}
+
+/*
+ * [0x002] Code Interface
+ * x--- ---- Code16 code bus width, slave mode only
+ * 0--- ---- 8-bit code bus
+ * 1--- ---- 16-bit code bus
+ * -x-- ---- Endian, must be 0 in Master mode or 8-bit Slave
+ * ---- -x-- CFIS number of clocks in Master mode, must be 0 in Code Slave
+ * ---- ---x CodeMstr ZR36060 is Master or Slave of the Code bus
+ * ---- ---0 Code Slave mode
+ * ---- ---1 Code Master mode
+ */
+u8 zr36060_device::code_if_r(offs_t offset)
+{
+ return (m_code16 << 7) | (m_endian << 6) | (m_cfis << 2) | (m_code_mstr);
+}
+
+void zr36060_device::code_if_w(offs_t offset, u8 data)
+{
+ m_code16 = !!(BIT(data, 7));
+ m_endian = !!(BIT(data, 6));
+ m_cfis = !!(BIT(data, 2));
+ m_code_mstr = !!(BIT(data, 0));
+ LOG("Code Interface %02x:\n", data);
+ LOG("\tCODE16 %d-bit, Endian %d, CFIS %d VCLKx2, CodeMstr %s\n"
+ , m_code16 ? 16 : 8
+ , m_endian
+ , m_cfis + 1
+ , m_code_mstr ? "Code Master" : "Code Slave"
+ );
+}
+
+/*
+ * [0x003] Codec Mode
+ * x--- ---- COMP
+ * -x-- ---- ATP
+ * --x- ---- PASS2
+ * ---x ---- TLM
+ * ---- -x-- BRC
+ * ---- --x- FSF
+ * 1100 0100 Auto Two-Pass Compression
+ * 1000 0100 Statistical Compression Pass
+ * 1010 0100 Compression Pass with Variable Scale Factor
+ * 1010 0110 Compression Pass with Fixed Scale Factor
+ * 1011 0000 Tables-Only Compression Pass
+ * 0000 0000 Decompression Pass
+ * ???? ???? <any other value illegal>
+ */
+u8 zr36060_device::codec_mode_r(offs_t offset)
+{
+ return m_codec_mode;
+}
+
+void zr36060_device::codec_mode_w(offs_t offset, u8 data)
+{
+ m_codec_mode = data;
+ LOG("Codec Mode %02x\n", data);
+ LOG("\tCOMP %d, ATP %d, PASS2 %d, TLM %d, BRC %d, FSF %d\n"
+ , BIT(data, 7)
+ , BIT(data, 6)
+ , BIT(data, 5)
+ , BIT(data, 4)
+ , BIT(data, 2)
+ , BIT(data, 1)
+ );
+}
+
+/*
+ * [0x005] Maxiumum Block Code Volume
+ * xxxx xxxx value * 2
+ */
+u8 zr36060_device::mbcv_r(offs_t offset)
+{
+ return m_mbcv;
+}
+
+void zr36060_device::mbcv_w(offs_t offset, u8 data)
+{
+ m_mbcv = data;
+ LOG("Maximum Block Code Volume %02x -> %d\n", m_mbcv, m_mbcv * 2);
+}
+
+/*
+ * [0x006] Markers Enable [for Compression modes only]
+ * x--- ---- APP
+ * -x-- ---- COM
+ * --x- ---- DRI
+ * ---x ---- DQT
+ * ---- x--- DHT
+ * ---- ---? <unknown, used on HW test startup and discarded quickly afterwards>
+ */
+u8 zr36060_device::markers_enable_r(offs_t offset)
+{
+ return m_markers_enable;
+}
+
+void zr36060_device::markers_enable_w(offs_t offset, u8 data)
+{
+ m_markers_enable = data;
+ LOG("Markers Enable %02x\n", data);
+ LOG("\tAPP %d COM %d DRI %d DQT %d DHT %d\n"
+ , BIT(data, 7)
+ , BIT(data, 6)
+ , BIT(data, 5)
+ , BIT(data, 4)
+ , BIT(data, 3)
+ );
+}
+
+/*
+ * [0x007] Interrupt Mask
+ * ---- x--- EOAV End-Of-Active-Video
+ * ---- -x-- EOI
+ * ---- --x- END
+ * ---- ---x DATERR
+ */
+u8 zr36060_device::irq_mask_r(offs_t offset)
+{
+ return m_irq_mask;
+}
+
+void zr36060_device::irq_mask_w(offs_t offset, u8 data)
+{
+ m_irq_mask = data;
+ LOG("IRQ Mask %02x\n", data);
+}
+
+/*
+ * [0x008] Interrupt Status
+ * same as above plus
+ * xx-- ---- ProCnt 2-bit cyclic Process counter
+ */
+u8 zr36060_device::irq_status_r(offs_t offset)
+{
+ return m_irq_status;
+}
+
+/*
+ * [0x009 - 0x00c] Target Net Code Volume
+ */
+u8 zr36060_device::tcv_net_r(offs_t offset)
+{
+ return m_tcv_net[offset];
+}
+
+void zr36060_device::tcv_net_w(offs_t offset, u8 data)
+{
+ m_tcv_net[offset] = data;
+ LOG("Target Net Code Volume [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x00d - 0x010] Target Data Code Volume
+ */
+u8 zr36060_device::tcv_data_r(offs_t offset)
+{
+ return m_tcv_data[offset];
+}
+
+void zr36060_device::tcv_data_w(offs_t offset, u8 data)
+{
+ m_tcv_data[offset] = data;
+ LOG("Target Data Code Volume [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x011 - 0x012] Scale Factor
+ */
+ u8 zr36060_device::sf_r(offs_t offset)
+ {
+ return m_sf[offset];
+ }
+
+void zr36060_device::sf_w(offs_t offset, u8 data)
+{
+ m_sf[offset] = data;
+ LOG("Scale Factor [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x013 - 0x015] Allocation Factor
+ */
+u8 zr36060_device::af_r(offs_t offset)
+{
+ return m_af[offset];
+}
+
+void zr36060_device::af_w(offs_t offset, u8 data)
+{
+ m_af[offset] = data;
+ LOG("Allocation Factor [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x016 - 0x019] Accumulated Code Volume
+ */
+u8 zr36060_device::acv_r(offs_t offset)
+{
+ return m_acv[offset];
+}
+
+void zr36060_device::acv_w(offs_t offset, u8 data)
+{
+ m_acv[offset] = data;
+ LOG("Accumulated Code Volume [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x01a - 0x01d] Accumulated Total Activity
+ */
+u8 zr36060_device::act_r(offs_t offset)
+{
+ return m_act[offset];
+}
+
+void zr36060_device::act_w(offs_t offset, u8 data)
+{
+ m_act[offset] = data;
+ LOG("Accumulated Total Activity [%01x] %02x\n", offset, data);
+}
+
+/*
+ * [0x01e - 0x021] Accumulated Truncated Bits
+ */
+u8 zr36060_device::acv_trun_r(offs_t offset)
+{
+ return m_acv_trun[offset];
+}
+
+void zr36060_device::acv_trun_w(offs_t offset, u8 data)
+{
+ m_acv_trun[offset] = data;
+ LOG("Accumulated Truncated Bits [%01x] %02x\n", offset, data);
+}
- map(0x060, 0x3ff).ram(); // JPEG Markers Array
+/**************************************
+ *
+ * Video Registers
+ *
+ *************************************/
+
+u8 zr36060_device::video_control_r(offs_t offset)
+{
+ return m_video_control;
+}
+
+void zr36060_device::video_control_w(offs_t offset, u8 data)
+{
+ m_video_control = data;
+ LOG("Video Control %02x\n", data);
+ LOG("\tVideo8 %d, Range %s, FIDet %s, FIVedge %s, FIExt %d SyncMstr %s\n"
+ , BIT(data, 7) ? 8 : 16
+ , BIT(data, 6) ? "CCIR-601" : "Full scale"
+ , BIT(data, 3) ? "FI high/VSYNC latch middle of line" : "FI low/VSYNC latch HSYNC pulse"
+ , BIT(data, 2) ? "Trailing edge VSYNC" : "Leading edge VSYNC"
+ , BIT(data, 1) // uses FI pin if high
+ , BIT(data, 0) ? "Master" : "Slave"
+ );
+}
+
+u8 zr36060_device::video_polarity_r(offs_t offset)
+{
+ return m_video_polarity;
+}
+
+void zr36060_device::video_polarity_w(offs_t offset, u8 data)
+{
+ m_video_polarity = data;
+ LOG("Video Polarity %02x\n", data);
+ LOG("\tVCLKPol %d, PValPol %d, PoePol %d, SImgPol %d, BLPol %d, FIPol %d, HSPol %d, VSPol %d\n"
+ , BIT(data, 7)
+ , BIT(data, 6)
+ , BIT(data, 5)
+ , BIT(data, 4)
+ , BIT(data, 3)
+ , BIT(data, 2)
+ , BIT(data, 1)
+ , BIT(data, 0)
+ );
+}
+
+u8 zr36060_device::video_scaling_r(offs_t offset)
+{
+ return (m_vscale << 2) | (m_hscale);
+}
+
+void zr36060_device::video_scaling_w(offs_t offset, u8 data)
+{
+ m_vscale = BIT(data, 2);
+ m_hscale = data & 3;
+ LOG("Scaling %02x\n", data);
+ LOG("\tVScale %d:1 ratio, HScale %d:1 ratio\n"
+ , m_vscale + 1
+ // NOTE: 8:1 is illegal
+ , 1 << m_hscale
+ );
}
/**************************************
diff --git a/src/devices/video/zr36060.h b/src/devices/video/zr36060.h
index 86e3877b915..58267460c74 100644
--- a/src/devices/video/zr36060.h
+++ b/src/devices/video/zr36060.h
@@ -24,6 +24,83 @@ private:
u16 m_address;
address_space_config m_space_config;
+
+ // Codec Control
+ u8 load_r(offs_t offset);
+ void load_w(offs_t offset, u8 data);
+ u8 code_fifo_status_r(offs_t offset);
+ u8 code_if_r(offs_t offset);
+ void code_if_w(offs_t offset, u8 data);
+ u8 codec_mode_r(offs_t offset);
+ void codec_mode_w(offs_t offset, u8 data);
+ u8 mbcv_r(offs_t offset);
+ void mbcv_w(offs_t offset, u8 data);
+ u8 markers_enable_r(offs_t offset);
+ void markers_enable_w(offs_t offset, u8 data);
+ u8 irq_mask_r(offs_t offset);
+ void irq_mask_w(offs_t offset, u8 data);
+ u8 irq_status_r(offs_t offset);
+ u8 tcv_net_r(offs_t offset);
+ void tcv_net_w(offs_t offset, u8 data);
+ u8 tcv_data_r(offs_t offset);
+ void tcv_data_w(offs_t offset, u8 data);
+ u8 sf_r(offs_t offset);
+ void sf_w(offs_t offset, u8 data);
+ u8 af_r(offs_t offset);
+ void af_w(offs_t offset, u8 data);
+ u8 acv_r(offs_t offset);
+ void acv_w(offs_t offset, u8 data);
+ u8 act_r(offs_t offset);
+ void act_w(offs_t offset, u8 data);
+ u8 acv_trun_r(offs_t offset);
+ void acv_trun_w(offs_t offset, u8 data);
+
+ bool m_syncrst;
+ bool m_load;
+ bool m_code16;
+ bool m_endian;
+ bool m_cfis;
+ bool m_code_mstr;
+ u8 m_codec_mode;
+ u8 m_mbcv;
+ u8 m_markers_enable;
+ u8 m_irq_mask, m_irq_status;
+ // these are all forms of floating-point registers
+ u8 m_tcv_net[4], m_tcv_data[4];
+ u8 m_sf[2];
+ u8 m_af[3]; // 24-bits
+ u8 m_acv[4], m_act[4], m_acv_trun[4];
+
+ // Video Registers
+ u8 video_control_r(offs_t offset);
+ void video_control_w(offs_t offset, u8 data);
+ u8 video_polarity_r(offs_t offset);
+ void video_polarity_w(offs_t offset, u8 data);
+ u8 video_scaling_r(offs_t offset);
+ void video_scaling_w(offs_t offset, u8 data);
+
+ u8 m_video_control;
+ u8 m_video_polarity;
+ u8 m_hscale, m_vscale;
+
+ struct {
+ u8 y, u, v;
+ } m_bg_color;
+
+ struct {
+ u16 vtotal, htotal;
+ u8 vsync_size, hsync_size;
+ u8 bvstart, bhstart;
+ u16 bvend, bhend;
+ } m_sync_gen;
+
+ struct {
+ u16 vstart, vend, hstart, hend;
+ } m_active_area;
+
+ struct {
+ u16 svstart, svend, shstart, shend;
+ } m_subimg_window;
};
DECLARE_DEVICE_TYPE(ZR36060, zr36060_device)