summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/sh/sh7604.cpp21
-rw-r--r--src/mame/namco/md8412b.cpp620
-rw-r--r--src/mame/namco/md8412b.h94
-rw-r--r--src/mame/namco/namco_settings.cpp5
-rw-r--r--src/mame/namco/namcos23.cpp1170
-rw-r--r--src/mame/namco/vpx3220a.cpp543
-rw-r--r--src/mame/namco/vpx3220a.h23
7 files changed, 2198 insertions, 278 deletions
diff --git a/src/devices/cpu/sh/sh7604.cpp b/src/devices/cpu/sh/sh7604.cpp
index 7841c578c07..5d597117fbd 100644
--- a/src/devices/cpu/sh/sh7604.cpp
+++ b/src/devices/cpu/sh/sh7604.cpp
@@ -20,7 +20,9 @@ TODO: Test and use sh7604_wdt_device, sh7604_sci_device, and sh7604_bus_device a
#include "sh7604.h"
-//#define VERBOSE 1
+#define LOG_DMA (1U << 1)
+
+#define VERBOSE (LOG_DMA)
#include "logmacro.h"
@@ -727,7 +729,7 @@ void sh7604_device::sh2_do_dma(int dmach)
resume(SUSPEND_REASON_HALT);
}
- LOG("SH2: DMA %d complete\n", dmach);
+ LOGMASKED(LOG_DMA, "SH2: DMA %d complete\n", dmach);
m_dmac[dmach].tcr = 0;
m_dmac[dmach].chcr |= 2;
m_dma_timer_active[dmach] = 0;
@@ -756,7 +758,7 @@ void sh7604_device::sh2_dmac_check(int dmach)
if (m_active_dma_incd[dmach] == 3 || m_active_dma_incs[dmach] == 3)
{
- LOG("SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", m_active_dma_incd[dmach], m_active_dma_incs[dmach], m_active_dma_size[dmach], m_dmac[dmach].chcr);
+ LOGMASKED(LOG_DMA, "SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", m_active_dma_incd[dmach], m_active_dma_incs[dmach], m_active_dma_size[dmach], m_dmac[dmach].chcr);
return;
}
m_active_dma_src[dmach] = m_dmac[dmach].sar;
@@ -765,7 +767,7 @@ void sh7604_device::sh2_dmac_check(int dmach)
if (!m_active_dma_count[dmach])
m_active_dma_count[dmach] = 0x1000000;
- LOG("SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dmach, m_active_dma_src[dmach], m_active_dma_dst[dmach], m_active_dma_count[dmach], m_dmac[dmach].chcr, m_active_dma_incs[dmach], m_active_dma_incd[dmach], m_active_dma_size[dmach]);
+ LOGMASKED(LOG_DMA, "SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dmach, m_active_dma_src[dmach], m_active_dma_dst[dmach], m_active_dma_count[dmach], m_dmac[dmach].chcr, m_active_dma_incs[dmach], m_active_dma_incd[dmach], m_active_dma_size[dmach]);
m_dma_timer_active[dmach] = 1;
@@ -807,7 +809,7 @@ void sh7604_device::sh2_dmac_check(int dmach)
{
if (m_dma_timer_active[dmach])
{
- LOG("SH2: DMA %d cancelled in-flight\n", dmach);
+ LOGMASKED(LOG_DMA, "SH2: DMA %d cancelled in-flight\n", dmach);
//m_dma_complete_timer[dmach]->adjust(attotime::never);
m_dma_current_active_timer[dmach]->adjust(attotime::never, dmach);
@@ -859,7 +861,7 @@ uint8_t sh7604_device::tdr_r()
void sh7604_device::tdr_w(uint8_t data)
{
m_tdr = data;
- //printf("%c", data & 0xff);
+ printf("%c", data & 0xff);
}
uint8_t sh7604_device::ssr_r()
@@ -1548,6 +1550,7 @@ uint32_t sh7604_device::vcrdma_r()
template <int Channel>
void sh7604_device::vcrdma_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA VCRDMA%d write: %08x & %08x\n", machine().describe_context(), Channel, data, mem_mask);
COMBINE_DATA(&m_vcrdma[Channel]);
m_irq_vector.dmac[Channel] = m_vcrdma[Channel] & 0x7f;
sh2_recalc_irq();
@@ -1562,6 +1565,7 @@ uint8_t sh7604_device::drcr_r()
template <int Channel>
void sh7604_device::drcr_w(uint8_t data)
{
+ LOGMASKED(LOG_DMA, "%s: DMA DRCR%d write: %02x\n", machine().describe_context(), Channel, data);
m_dmac[Channel].drcr = data & 3;
sh2_recalc_irq();
}
@@ -1575,6 +1579,7 @@ uint32_t sh7604_device::sar_r()
template <int Channel>
void sh7604_device::sar_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA SAR%d write: %08x & %08x\n", machine().describe_context(), Channel, data, mem_mask);
COMBINE_DATA(&m_dmac[Channel].sar);
}
@@ -1587,6 +1592,7 @@ uint32_t sh7604_device::dar_r()
template <int Channel>
void sh7604_device::dar_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA DAR%d write: %08x & %08x\n", machine().describe_context(), Channel, data, mem_mask);
COMBINE_DATA(&m_dmac[Channel].dar);
}
@@ -1599,6 +1605,7 @@ uint32_t sh7604_device::dmac_tcr_r()
template <int Channel>
void sh7604_device::dmac_tcr_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA TCR%d write: %08x & %08x\n", machine().describe_context(), Channel, data, mem_mask);
COMBINE_DATA(&m_dmac[Channel].tcr);
m_dmac[Channel].tcr &= 0xffffff;
}
@@ -1612,6 +1619,7 @@ uint32_t sh7604_device::chcr_r()
template <int Channel>
void sh7604_device::chcr_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA CHCR%d write: %08x & %08x\n", machine().describe_context(), Channel, data, mem_mask);
uint32_t old;
old = m_dmac[Channel].chcr;
COMBINE_DATA(&m_dmac[Channel].chcr);
@@ -1626,6 +1634,7 @@ uint32_t sh7604_device::dmaor_r()
void sh7604_device::dmaor_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_DMA, "%s: DMA DMAOR write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (ACCESSING_BITS_0_7)
{
uint8_t old = m_dmaor & 0xf;
diff --git a/src/mame/namco/md8412b.cpp b/src/mame/namco/md8412b.cpp
index 7df688c0427..fa901a4f6ec 100644
--- a/src/mame/namco/md8412b.cpp
+++ b/src/mame/namco/md8412b.cpp
@@ -11,28 +11,35 @@
#include "emu.h"
#include "md8412b.h"
-#define VERBOSE (0)
+#define VERBOSE ( 0 )
#include "logmacro.h"
DEFINE_DEVICE_TYPE(MD8412B, md8412b_device, "md8412b", "Fujifilm MD8412B IEEE-1394 LLC")
-md8412b_device::md8412b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, MD8412B, tag, owner, clock)
- , m_ctrl(0)
- , m_node_id(0)
- , m_async_bufsize(0)
- , m_sync_bufsize(0)
- , m_packet_ctrl(0)
- , m_phy_ctrl(0)
- , m_at_retries_ctrl(0)
- , m_cycle_timer(0)
- , m_sync_packet_len(0)
- , m_buf_status_ctrl(0)
- , m_interrupt(0)
- , m_interrupt_mask(0)
- , m_tgo(0)
- , m_bus_time(0)
- , m_at_retries(0)
+md8412b_device::md8412b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, MD8412B, tag, owner, clock),
+ m_int_cb(*this),
+ m_int_active(false),
+ m_cycle_timer(nullptr),
+ m_async_active(false),
+ m_cycle_started(false),
+ m_iso_going(false),
+ m_ctrl(0),
+ m_node_id(0),
+ m_async_bufsize(0),
+ m_sync_bufsize(0),
+ m_packet_ctrl(0),
+ m_diag_status(0),
+ m_phy_ctrl(0),
+ m_at_retries_ctrl(0),
+ m_cycle_timer_reg(0),
+ m_sync_packet_len(0),
+ m_buf_status_ctrl(0),
+ m_interrupt(0),
+ m_interrupt_mask(0),
+ m_tgo(0),
+ m_bus_time(0),
+ m_at_retries(0)
{
memset(m_phy_regs, 0, sizeof(m_phy_regs));
memset(m_sync_config, 0, sizeof(m_sync_config));
@@ -40,15 +47,40 @@ md8412b_device::md8412b_device(const machine_config &mconfig, const char *tag, d
void md8412b_device::device_start()
{
+ save_item(NAME(m_int_active));
+ save_item(NAME(m_async_active));
+ save_item(NAME(m_cycle_started));
+ save_item(NAME(m_iso_going));
+ save_item(NAME(m_async_rx.buf));
+ save_item(NAME(m_async_rx.wr_idx));
+ save_item(NAME(m_async_rx.rd_idx));
+ save_item(NAME(m_async_rx.count));
+ save_item(NAME(m_async_rx.limit));
+ save_item(NAME(m_async_tx.buf));
+ save_item(NAME(m_async_tx.wr_idx));
+ save_item(NAME(m_async_tx.rd_idx));
+ save_item(NAME(m_async_tx.count));
+ save_item(NAME(m_async_tx.limit));
+ save_item(NAME(m_iso_rx.buf));
+ save_item(NAME(m_iso_rx.wr_idx));
+ save_item(NAME(m_iso_rx.rd_idx));
+ save_item(NAME(m_iso_rx.count));
+ save_item(NAME(m_iso_rx.limit));
+ save_item(NAME(m_iso_tx.buf));
+ save_item(NAME(m_iso_tx.wr_idx));
+ save_item(NAME(m_iso_tx.rd_idx));
+ save_item(NAME(m_iso_tx.count));
+ save_item(NAME(m_iso_tx.limit));
save_item(NAME(m_ctrl));
save_item(NAME(m_node_id));
save_item(NAME(m_async_bufsize));
save_item(NAME(m_sync_bufsize));
save_item(NAME(m_packet_ctrl));
+ save_item(NAME(m_diag_status));
save_item(NAME(m_phy_ctrl));
save_item(NAME(m_phy_regs));
save_item(NAME(m_at_retries_ctrl));
- save_item(NAME(m_cycle_timer));
+ save_item(NAME(m_cycle_timer_reg));
save_item(NAME(m_sync_packet_len));
save_item(NAME(m_sync_config));
save_item(NAME(m_buf_status_ctrl));
@@ -57,25 +89,38 @@ void md8412b_device::device_start()
save_item(NAME(m_tgo));
save_item(NAME(m_bus_time));
save_item(NAME(m_at_retries));
+
+ m_cycle_timer = timer_alloc(FUNC(md8412b_device::cycle_tick), this);
}
void md8412b_device::device_reset()
{
+ m_int_active = false;
+ m_async_active = false;
+ m_cycle_started = false;
+ m_iso_going = false;
+
+ m_async_rx.init(0x7f);
+ m_async_tx.init(0x80);
+ m_iso_rx.init(0x7f);
+ m_iso_tx.init(0x80);
+
m_ctrl = 0x00030001;
m_node_id = 0x0000ffff;
m_async_bufsize = 0x007f00ff;
m_sync_bufsize = 0x007f00ff;
m_packet_ctrl = 0x00001020;
+ m_diag_status = 0;
m_phy_ctrl = 0;
- m_phy_regs[0] = 0x00;
- m_phy_regs[1] = 0x3f;
- m_phy_regs[2] = 0x43;
- m_phy_regs[3] = 0x00;
- m_phy_regs[4] = 0x00;
- m_phy_regs[5] = 0x00;
- m_phy_regs[6] = 0x00;
+ m_phy_regs[0] = 0x03; // Physical ID 00, root, cable powered
+ m_phy_regs[1] = 0x3f; // Gap count 0x3f
+ m_phy_regs[2] = 0x43; // 3 ports, 200/100 speed supported
+ m_phy_regs[3] = 0xf4; // Port 0 connected
+ m_phy_regs[4] = 0xf0; // Port 1 disconnected
+ m_phy_regs[5] = 0xf0; // Port 2 disconnected
+ m_phy_regs[6] = 0x20; // Cable is powered
m_at_retries_ctrl = 0x00000001;
- m_cycle_timer = 0x00000000;
+ m_cycle_timer_reg = 0x00000000;
m_sync_packet_len = 0x00040000;
m_sync_config[0] = 0x00000000;
m_sync_config[1] = 0x00000000;
@@ -83,10 +128,14 @@ void md8412b_device::device_reset()
m_sync_config[3] = 0x00000000;
m_buf_status_ctrl = 0x00000055;
m_interrupt = 0x00000000;
- m_interrupt_mask = 0x00000000;
+ m_interrupt_mask = 0xffffffff;
m_tgo = 0x00000000;
m_bus_time = 0x00000000;
m_at_retries = 0x00c80000;
+
+ m_int_cb(0);
+
+ m_cycle_timer->adjust(attotime::from_hz(16000), 0, attotime::from_hz(16000));
}
void md8412b_device::map(address_map &map)
@@ -106,7 +155,7 @@ void md8412b_device::map(address_map &map)
map(0x30, 0x3f).rw(FUNC(md8412b_device::sync_config_r), FUNC(md8412b_device::sync_config_w));
map(0x40, 0x43).w(FUNC(md8412b_device::atf_data_w));
map(0x44, 0x47).r(FUNC(md8412b_device::arf_data_r));
- map(0x48, 0x4b).rw(FUNC(md8412b_device::sync_data_r), FUNC(md8412b_device::sync_data_w));
+ map(0x48, 0x4b).rw(FUNC(md8412b_device::itrf_data_r), FUNC(md8412b_device::itf_data_w));
map(0x4c, 0x4f).r(FUNC(md8412b_device::irf_data_r));
map(0x50, 0x53).rw(FUNC(md8412b_device::buf_status_ctrl_r), FUNC(md8412b_device::buf_status_ctrl_w));
map(0x54, 0x57).rw(FUNC(md8412b_device::interrupt_r), FUNC(md8412b_device::interrupt_w));
@@ -116,6 +165,406 @@ void md8412b_device::map(address_map &map)
map(0x68, 0x6b).rw(FUNC(md8412b_device::at_retries_r), FUNC(md8412b_device::at_retries_w));
}
+void md8412b_device::update_interrupt()
+{
+ const bool was_int_active = m_int_active;
+ m_int_active = m_interrupt & ~m_interrupt_mask;
+ if (was_int_active == m_int_active)
+ return;
+
+ //if (m_int_active)
+ //printf("Yoinking FW IRQ\n");
+ m_int_cb((int)m_int_active);
+}
+
+void md8412b_device::cycle_tick(s32 param)
+{
+ m_async_active = !m_async_active;
+ if (!m_async_active)
+ {
+ const u32 old_count = m_cycle_timer_reg;
+ m_cycle_timer_reg += 0x00001000;
+
+ if ((m_cycle_timer_reg & 0xfe000000) != (old_count & 0xfe000000))
+ {
+ LOG("Flagging interrupt for CYCLE_SECONDS\n");
+ m_interrupt |= 1 << INTERRUPT_CYCLE_SECONDS;
+ }
+
+ if (BIT(m_ctrl, CTRL_CYCLE_MASTER) && BIT(m_ctrl, CTRL_LPS_ON))
+ {
+ LOG("Flagging interrupt for CYCLE_START\n");
+ m_interrupt |= 1 << INTERRUPT_CYCLE_START;
+ m_cycle_started = true;
+ }
+
+ if (m_iso_going)
+ {
+ while (m_iso_tx.count > 0)
+ {
+ const u32 header = m_iso_tx.peek();
+ const u32 length = (BIT(header, 16, 16) + 3) / 4 + 1;
+ if (m_iso_tx.count >= length)
+ {
+ handle_iso_tx();
+ m_diag_status &= ~(1 << DIAG_STATUS_IT_BUSY);
+ m_iso_going = false;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (m_iso_tx.count == 0)
+ {
+ m_tgo &= ~(1 << TGO_IT_GO);
+ }
+ }
+ }
+ else
+ {
+ if (m_async_tx.count > 0)
+ {
+ static const s32 MIN_LENGTHS[16] = { 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ const u32 tx_type = BIT(m_async_tx.peek(), 4, 4);
+ if (MIN_LENGTHS[tx_type] < 0)
+ {
+ LOG("Unhandled async-tx packet type: %x\n", tx_type);
+ }
+ else if (m_async_tx.count >= MIN_LENGTHS[tx_type])
+ {
+ if (!m_cycle_started)
+ {
+ m_interrupt |= 1 << INTERRUPT_CYCLE_START;
+ m_cycle_started = true;
+ }
+ handle_async_tx();
+ }
+ m_diag_status &= ~(1 << DIAG_STATUS_AT_BUSY);
+ if (m_async_tx.count == 0)
+ {
+ m_tgo &= ~(1 << TGO_AT_GO);
+ }
+ }
+
+ if (m_cycle_started)
+ {
+ LOG("Flagging interrupt for CYCLE_DONE\n");
+ m_interrupt |= 1 << INTERRUPT_CYCLE_DONE;
+ }
+ }
+
+ update_interrupt();
+}
+
+void md8412b_device::handle_async_tx()
+{
+ switch (BIT(m_async_tx.peek(), 4, 4))
+ {
+ case 0x0: // Write request for data quadlet
+ {
+ if (m_async_tx.count < 4)
+ return;
+
+ LOG("Performing async-tx for packet type: Write request for data quadlet\n");
+ const u32 word0 = pop_async_tx_word();
+ const u32 word1 = pop_async_tx_word();
+ const u32 word2 = pop_async_tx_word();
+ const u32 word3 = pop_async_tx_word();
+ if (word0 == 0x0000ac00 && (word1 & 0x0000ffff) == 0x00000a00)
+ {
+ const u32 recv_word0 = 0xffc0ac00;
+ const u32 recv_word1 = 0xffc10a00;
+ const u32 recv_word2 = 0;
+ const u32 recv_word3 = 0x01000100;
+ const u32 recv_word4 = (word0 & 0x00030000) | 0x01; // ack_complete
+
+ LOG("Transmitter-request packet from host %08x %08x %08x %08x, sending back transmitter ID (%08x, %08x, %08x, %08x)\n", word0, word1, word2, word3, recv_word0, recv_word1, recv_word2, recv_word3);
+
+ push_async_rx_word(recv_word0);
+ push_async_rx_word(recv_word1);
+ push_async_rx_word(recv_word2);
+ push_async_rx_word(recv_word3);
+ push_async_rx_word(recv_word4);
+
+ m_diag_status &= ~DIAG_STATUS_AT_ACK_MASK;
+ m_diag_status |= 0x01 << DIAG_STATUS_AT_ACK; // ack_complete
+ LOG("Flagging interrupt for ARX_END and ATX_END\n");
+ m_interrupt |= 1 << INTERRUPT_ARX_END;
+ m_interrupt |= 1 << INTERRUPT_ATX_END;
+ }
+ else if (word0 == 0x0000bc00 && (word1 & 0x0000ffff) == 0x00000b00)
+ {
+ const u32 recv_word0 = 0xffc0bc00;
+ const u32 recv_word1 = 0xffff0b00;
+ const u32 recv_word2 = 0;
+ const u32 recv_word3 = 0x01010000;
+ const u32 host_word0 = 0xffc1bc00;
+ const u32 host_word1 = 0xffff0b00;
+ const u32 host_word2 = 0;
+ const u32 host_word3 = 0x00000100;
+ const u32 resp_word4 = (word0 & 0x00030000) | 0x01; // ack_complete
+
+ LOG("Receiver-request packet from host %08x %08x %08x %08x, sending back receiver ID 0->1 (%08x, %08x, %08x, %08x) and 1->0 (%08x, %08x, %08x, %08x)\n",
+ word0, word1, word2, word3, recv_word0, recv_word1, recv_word2, recv_word3, host_word0, host_word1, host_word2, host_word3);
+
+ push_async_rx_word(recv_word0);
+ push_async_rx_word(recv_word1);
+ push_async_rx_word(recv_word2);
+ push_async_rx_word(recv_word3);
+ push_async_rx_word(resp_word4);
+
+ push_async_rx_word(host_word0);
+ push_async_rx_word(host_word1);
+ push_async_rx_word(host_word2);
+ push_async_rx_word(host_word3);
+ push_async_rx_word(resp_word4);
+
+ m_diag_status &= ~DIAG_STATUS_AT_ACK_MASK;
+ m_diag_status |= 0x01 << DIAG_STATUS_AT_ACK; // ack_complete
+ LOG("Flagging interrupt for ARX_END and ATX_END\n");
+ m_interrupt |= 1 << INTERRUPT_ARX_END;
+ m_interrupt |= 1 << INTERRUPT_ATX_END;
+ }
+ else if (word0 == 0x00008c00 && (word1 & 0x0000ffff) == 0x00000800)
+ {
+ const u32 recv_word0 = 0xffc09c00;
+ const u32 recv_word1 = 0xffc10900;
+ const u32 recv_word2 = 0;
+ const u32 recv_word3 = 0;
+ const u32 recv_word4 = (word0 & 0x00030000) | 0x01; // ack_complete
+
+ LOG("Wake-up packet from host %08x %08x %08x %08x, sending back wakeup acknowledge (%08x, %08x)\n", word0, word1, word2, word3, recv_word0, recv_word1);
+
+ push_async_rx_word(recv_word0);
+ push_async_rx_word(recv_word1);
+ push_async_rx_word(recv_word2);
+ push_async_rx_word(recv_word3);
+ push_async_rx_word(recv_word4);
+
+ m_diag_status &= ~DIAG_STATUS_AT_ACK_MASK;
+ m_diag_status |= 0x01 << DIAG_STATUS_AT_ACK; // ack_complete
+ LOG("Flagging interrupt for ARX_END and ATX_END\n");
+ m_interrupt |= 1 << INTERRUPT_ARX_END;
+ m_interrupt |= 1 << INTERRUPT_ATX_END;
+ }
+ else
+ {
+ //LOG("Unhandled async-tx destination ID for data quadlet: %04x (only local broadcast supported)\n", BIT(word1, 16, 16));
+ const u32 recv_word4 = (word0 & 0x00030000) | 0x01; // ack_complete
+
+ push_async_rx_word(0xffc00000 | (word0 & 0x0000fcff));
+ //push_async_rx_word(0xffc00000 | (word0 & 0x0000fcff));
+ push_async_rx_word(0xffc10000 | (word1 & 0x0000ffff));
+ push_async_rx_word(word2);
+ push_async_rx_word(word3);
+ push_async_rx_word(recv_word4);
+
+ m_diag_status &= ~DIAG_STATUS_AT_ACK_MASK;
+ m_diag_status |= 0x01 << DIAG_STATUS_AT_ACK; // ack_complete
+ LOG("Flagging interrupt for ARX_END and ATX_END\n");
+ m_interrupt |= 1 << INTERRUPT_ARX_END;
+ m_interrupt |= 1 << INTERRUPT_ATX_END;
+ }
+ return;
+ }
+ default:
+ LOG("Unhandled async-tx packet type in async-tx timer: %x (how did we get here?)\n", BIT(m_async_tx.peek(), 4, 4));
+ break;
+ }
+}
+
+void md8412b_device::handle_iso_tx()
+{
+ const u32 header = pop_iso_tx_word();
+ const u32 channel = BIT(header, 8, 6);
+
+ bool channel_found = false;
+ for (u32 i = 0; i < 4 && !channel_found; i++)
+ {
+ if (!BIT(m_sync_config[i], SYNC_CONFIG_ISO_RX_EN))
+ continue;
+ if (BIT(m_sync_config[i], SYNC_CONFIG_CHANNEL, SYNC_CONFIG_CHANNEL_WIDTH) != channel)
+ continue;
+ channel_found = true;
+ }
+
+ if (!channel_found)
+ {
+ // TODO: Handle lack of isochronous recipient channel
+ LOG("Channel not found for isochronous recipient\n");
+ printf("N");
+ return;
+ }
+
+ LOG("Flagging interrupt for ITX_END\n");
+ m_interrupt |= 1 << INTERRUPT_ITX_END;
+
+ std::vector<u32> recv_words((BIT(header, 16, 16) + 3) / 4);
+ //printf("%08x\n", header);
+ for (u32 i = 0; i < (BIT(header, 16, 16) + 3) / 4; i++)
+ {
+ recv_words[i] = pop_iso_tx_word();
+ //printf("%08x\n", recv_words[i]);
+ }
+ //printf("\n");
+
+ if (header == 0x000c3010 && recv_words[0] == 0x00000001)
+ {
+ push_iso_rx_word((header & 0xffffff0f) | 0x000000a0);
+ push_iso_rx_word(0x00000001); // Keepalive response
+ push_iso_rx_word(0x00020001); // Child unit -> parent unit response
+ push_iso_rx_word(recv_words[2]); // Sequence number
+ push_iso_rx_word(0x00000001); // Acknowledge
+
+ LOG("Flagging interrupt for IRF_RX_END\n");
+ m_interrupt |= 1 << INTERRUPT_IRF_RX_END;
+ }
+}
+
+void md8412b_device::push_async_rx_word(const u32 data)
+{
+ if (m_async_rx.count == m_async_rx.limit)
+ {
+ // TODO: Set overrun flags
+ return;
+ }
+
+ m_async_rx.push(data);
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_ARF_EMPTY);
+}
+
+u32 md8412b_device::pop_async_rx_word()
+{
+ const u32 data = m_async_rx.pop();
+ if (m_async_rx.count == 0)
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_ARF_EMPTY;
+ return data;
+}
+
+void md8412b_device::push_async_tx_word(const u32 data)
+{
+ if (m_async_tx.count == m_async_tx.limit)
+ {
+ // TODO: Set overrun flags
+ return;
+ }
+
+ m_async_tx.push(data);
+ if (m_async_tx.count == m_async_tx.limit)
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_ATF_FULL;
+
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_ATF_EMPTY);
+}
+
+u32 md8412b_device::pop_async_tx_word()
+{
+ const u32 data = m_async_tx.pop();
+ if (m_async_tx.count == 0)
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_ATF_EMPTY;
+ else
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_ATF_FULL);
+ return data;
+}
+
+void md8412b_device::push_iso_rx_word(const u32 data)
+{
+ if (m_iso_rx.count == m_iso_rx.limit)
+ {
+ // TODO: Set overrun flags
+ return;
+ }
+
+ m_iso_rx.push(data);
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_IRF_EMPTY);
+}
+
+u32 md8412b_device::pop_iso_rx_word()
+{
+ const u32 data = m_iso_rx.pop();
+ if (m_iso_rx.count == 0)
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_IRF_EMPTY;
+ return data;
+}
+
+void md8412b_device::push_iso_tx_word(const u32 data)
+{
+ if (m_iso_tx.count == m_iso_tx.limit)
+ {
+ // TODO: Set overrun flags
+ return;
+ }
+
+ m_iso_tx.push(data);
+ if (m_iso_tx.count == m_iso_tx.limit)
+ {
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_ITRF_FULL;
+ }
+
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_ITRF_EMPTY);
+}
+
+u32 md8412b_device::pop_iso_tx_word()
+{
+ const u32 data = m_iso_tx.pop();
+ if (m_iso_tx.count == 0)
+ m_buf_status_ctrl |= 1 << BUF_STAT_CTRL_ITRF_EMPTY;
+ else
+ m_buf_status_ctrl &= ~(1 << BUF_STAT_CTRL_ITRF_FULL);
+ return data;
+}
+
+void md8412b_device::recv_self_id()
+{
+ m_phy_regs[0] = 0x03; // PHY ID 00, Root, Cable Power
+ m_phy_regs[3] = 0xfc; // PHY Connector 0 is connected as a parent
+ m_phy_regs[6] |= 0x10; // This PHY initiated a bus reset
+
+ u32 packet0 = 0x80000000; // PHY ID 00
+ packet0 |= 0x01 << 22; // Link active
+ packet0 |= (m_phy_regs[1] & 0x3f) << 16; // Gap count
+ packet0 |= 0x01 << 14; // PHY speed, MD8402 supports 100/200mbit
+ packet0 |= 0x00 << 12; // Default PHY_DELAY value of <= 144ns
+ packet0 |= 0x01 << 11; // This node can be a bus or isochronous resource manager
+ packet0 |= 0x00 << 8; // This node does not require external power
+ packet0 |= 0x03 << 6; // Port 0 is not connected to another PHY as a parent node
+ packet0 |= 0x01 << 4; // Port 1 is not connected to another PHY
+ packet0 |= 0x01 << 2; // Port 2 is not connected to another PHY
+ packet0 |= 0x01 << 1; // This was the originating node of the bus reset
+
+ push_async_rx_word(0x000000e0); // SelfID packet
+ push_async_rx_word(packet0);
+ push_async_rx_word(~packet0);
+ push_async_rx_word(0x00000001);
+ packet0 = 0x81000000; // PHY ID 01
+ packet0 |= 0x01 << 22; // Link active
+ packet0 |= (m_phy_regs[1] & 0x3f) << 16; // Gap count
+ packet0 |= 0x01 << 14; // PHY speed, MD8402 supports 100/200mbit
+ packet0 |= 0x00 << 12; // Default PHY_DELAY value of <= 144ns
+ packet0 |= 0x01 << 11; // This node can be a bus or isochronous resource manager
+ packet0 |= 0x00 << 8; // This node does not require external power
+ packet0 |= 0x02 << 6; // Port 0 is connected to another PHY as a child node
+ packet0 |= 0x01 << 4; // Port 1 is not connected to another PHY
+ packet0 |= 0x01 << 2; // Port 2 is not connected to another PHY
+ packet0 |= 0x00 << 1; // This was not the originating node of the bus reset
+ push_async_rx_word(0x000000e0); // SelfID packet
+ push_async_rx_word(packet0);
+ push_async_rx_word(~packet0);
+ push_async_rx_word(0x00000001);
+ //push_async_rx_word(0x000000e0);
+ //packet0 &= ~0x3f000003;
+ //packet0 |= 0x3e000000;
+ //push_async_rx_word(packet0);
+ //push_async_rx_word(~packet0);
+ //push_async_rx_word(0x81800000); // Ports 3..10 disconnected
+ //push_async_rx_word(~0x81800000);
+ //push_async_rx_word(0x81900000); // Ports 11..18 disconnected
+ //push_async_rx_word(~0x81900000);
+ //push_async_rx_word(0x81a00000); // Ports 19..26 disconnected
+ //push_async_rx_word(~0x81a00000);
+ //push_async_rx_word(0x00000001); // ack_complete
+}
+
u32 md8412b_device::version_r()
{
const u32 data = 0x00010002;
@@ -270,7 +719,7 @@ void md8412b_device::packet_ctrl_w(offs_t offset, u32 data, u32 mem_mask)
u32 md8412b_device::diag_status_r()
{
- const u32 data = 0x00000000;
+ const u32 data = m_diag_status;
LOG("%s: diag_status_r: %08x\n", machine().describe_context(), data);
return data;
}
@@ -300,6 +749,16 @@ void md8412b_device::phy_ctrl_w(offs_t offset, u32 data, u32 mem_mask)
LOG("%s: Gap Count: %02x\n", machine().describe_context(), m_phy_regs[1] & 0x3f);
LOG("%s: Bus Reset: %d\n", machine().describe_context(), BIT(m_phy_regs[1], 6));
LOG("%s: Root Hold: %d\n", machine().describe_context(), BIT(m_phy_regs[1], 7));
+ if (BIT(m_phy_regs[1], 6))
+ {
+ //m_interrupt |= 1 << INTERRUPT_PHY_REG_RCVD;
+ m_interrupt |= 1 << INTERRUPT_BUS_RESET;
+ m_interrupt |= 1 << INTERRUPT_BUS_RESET_FIN;
+ update_interrupt();
+
+ if (BIT(m_packet_ctrl, PACKET_CTRL_RX_SELF_ID))
+ recv_self_id();
+ }
break;
case 6:
m_phy_regs[6] = BIT(data, PHY_CTRL_REG_DATA, PHY_CTRL_REG_DATA_WIDTH) & ~(1 << 5);
@@ -319,13 +778,13 @@ void md8412b_device::phy_ctrl_w(offs_t offset, u32 data, u32 mem_mask)
{
phy_data = m_phy_regs[addr];
}
- LOG("%s: Register %2d: %02x\n", machine().describe_context(), phy_data);
+ LOG("%s: Register %2d: %02x\n", machine().describe_context(), addr, phy_data);
m_phy_ctrl &= ~PHY_CTRL_REG_DATA_MASK;
m_phy_ctrl |= phy_data;
+ m_phy_ctrl |= 1 << PHY_CTRL_REG_RCVD;
+ m_interrupt |= 1 << INTERRUPT_PHY_REG_RCVD;
+ update_interrupt();
}
- m_phy_ctrl |= (1 << PHY_CTRL_REG_RCVD);
- m_interrupt |= (1 << INTERRUPT_PHY_REG_RCVD);
- m_interrupt &= m_interrupt_mask;
}
u32 md8412b_device::at_retries_ctrl_r()
@@ -348,7 +807,9 @@ void md8412b_device::at_retries_ctrl_w(offs_t offset, u32 data, u32 mem_mask)
u32 md8412b_device::cycle_timer_r()
{
- const u32 data = machine().rand();//m_cycle_timer;
+ const u64 ticks = machine().scheduler().time().as_ticks(24576000);
+ const u32 cycle_offset = (u32)(ticks % 3072);
+ const u32 data = (m_cycle_timer_reg & (CYCLE_TIMER_SECONDS_MASK | CYCLE_TIMER_COUNT_MASK)) | (cycle_offset << CYCLE_TIMER_OFFSET);
LOG("%s: cycle_timer_r: %08x\n", machine().describe_context(), data);
return data;
}
@@ -360,7 +821,7 @@ void md8412b_device::cycle_timer_w(offs_t offset, u32 data, u32 mem_mask)
LOG("%s: Cycle Count: %03x\n", machine().describe_context(), BIT(data, CYCLE_TIMER_COUNT, CYCLE_TIMER_COUNT_WIDTH));
LOG("%s: Cycle Seconds: %02x\n", machine().describe_context(), BIT(data, CYCLE_TIMER_SECONDS, CYCLE_TIMER_SECONDS_WIDTH));
- COMBINE_DATA(&m_cycle_timer);
+ COMBINE_DATA(&m_cycle_timer_reg);
}
u32 md8412b_device::sync_packet_len_r()
@@ -396,7 +857,7 @@ void md8412b_device::sync_config_w(offs_t offset, u32 data, u32 mem_mask)
"11 (Reserved)"
};
- LOG("%s: sync_config_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOG("%s: sync_config_w[%d]: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask);
LOG("%s: Sync Enable: %d\n", machine().describe_context(), BIT(data, SYNC_CONFIG_SYNC_EN));
LOG("%s: Isochronous Rx Enable: %d\n", machine().describe_context(), BIT(data, SYNC_CONFIG_ISO_RX_EN));
LOG("%s: Stop Sync: %02x\n", machine().describe_context(), BIT(data, SYNC_CONFIG_STOP_SYNC, SYNC_CONFIG_STOP_SYNC_WIDTH));
@@ -413,30 +874,32 @@ void md8412b_device::sync_config_w(offs_t offset, u32 data, u32 mem_mask)
void md8412b_device::atf_data_w(offs_t offset, u32 data, u32 mem_mask)
{
LOG("%s: atf_data_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ push_async_tx_word(data);
}
u32 md8412b_device::arf_data_r()
{
- const u32 data = 0x00000000;
+ const u32 data = pop_async_rx_word();
LOG("%s: arf_data_r: %08x\n", machine().describe_context(), data);
return data;
}
-u32 md8412b_device::sync_data_r()
+u32 md8412b_device::itrf_data_r()
{
- const u32 data = 0x00000000;
- LOG("%s: sync_data_r: %08x\n", machine().describe_context(), data);
+ const u32 data = pop_iso_rx_word();
+ LOG("%s: itrf_data_r: %08x\n", machine().describe_context(), data);
return data;
}
-void md8412b_device::sync_data_w(offs_t offset, u32 data, u32 mem_mask)
+void md8412b_device::itf_data_w(offs_t offset, u32 data, u32 mem_mask)
{
- LOG("%s: sync_data_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOG("%s: itf_data_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ push_iso_tx_word(data);
}
u32 md8412b_device::irf_data_r()
{
- const u32 data = 0x00000000;
+ const u32 data = pop_iso_rx_word();
LOG("%s: irf_data_r: %08x\n", machine().describe_context(), data);
return data;
}
@@ -475,39 +938,44 @@ void md8412b_device::buf_status_ctrl_w(offs_t offset, u32 data, u32 mem_mask)
u32 md8412b_device::interrupt_r()
{
+ static u32 old_data = 0;
const u32 data = m_interrupt;
- LOG("%s: interrupt_r: %08x\n", machine().describe_context(), data);
- LOG("%s: Command Reset: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CMD_RESET));
- LOG("%s: Cycle Lost: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_LOST));
- LOG("%s: Cycle Done: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_DONE));
- LOG("%s: Cycle Start: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_START));
- LOG("%s: Cycle Seconds: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_SECONDS));
- LOG("%s: Sent Reject: %d\n", machine().describe_context(), BIT(data, INTERRUPT_SENT_REJECT));
- LOG("%s: Header Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_HEADER_ERR));
- LOG("%s: TCode Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_TCODE_ERR));
- LOG("%s: Ack Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ACK_ERR));
- LOG("%s: PHY Reg Received: %d\n", machine().describe_context(), BIT(data, INTERRUPT_PHY_REG_RCVD));
- LOG("%s: Bus Reset Finish: %d\n", machine().describe_context(), BIT(data, INTERRUPT_BUS_RESET_FIN));
- LOG("%s: Bus Reset: %d\n", machine().describe_context(), BIT(data, INTERRUPT_BUS_RESET));
- LOG("%s: PHY Interrupt: %d\n", machine().describe_context(), BIT(data, INTERRUPT_PHY_INT));
- LOG("%s: ITF/IRF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITRF_FLUSH));
- LOG("%s: IRF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_IRF_FLUSH));
- LOG("%s: Iso No-Tx: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITF_NO_TX));
- LOG("%s: Iso Tx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITX_END));
- LOG("%s: Async Rx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ARX_END));
- LOG("%s: Iso Rx End (ITF/IRF): %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITRF_RX_END));
- LOG("%s: Iso Rx End (IRF): %d\n", machine().describe_context(), BIT(data, INTERRUPT_IRF_RX_END));
- LOG("%s: Async Tx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ATX_END));
- LOG("%s: ARF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ARF_FLUSH));
+ const bool logit = (old_data != m_interrupt);
+ old_data = m_interrupt;
+ if (logit)
+ {
+ LOG("%s: interrupt_r: %08x\n", machine().describe_context(), data);
+ LOG("%s: Command Reset: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CMD_RESET));
+ LOG("%s: Cycle Lost: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_LOST));
+ LOG("%s: Cycle Done: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_DONE));
+ LOG("%s: Cycle Start: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_START));
+ LOG("%s: Cycle Seconds: %d\n", machine().describe_context(), BIT(data, INTERRUPT_CYCLE_SECONDS));
+ LOG("%s: Sent Reject: %d\n", machine().describe_context(), BIT(data, INTERRUPT_SENT_REJECT));
+ LOG("%s: Header Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_HEADER_ERR));
+ LOG("%s: TCode Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_TCODE_ERR));
+ LOG("%s: Ack Error: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ACK_ERR));
+ LOG("%s: PHY Reg Received: %d\n", machine().describe_context(), BIT(data, INTERRUPT_PHY_REG_RCVD));
+ LOG("%s: Bus Reset Finish: %d\n", machine().describe_context(), BIT(data, INTERRUPT_BUS_RESET_FIN));
+ LOG("%s: Bus Reset: %d\n", machine().describe_context(), BIT(data, INTERRUPT_BUS_RESET));
+ LOG("%s: PHY Interrupt: %d\n", machine().describe_context(), BIT(data, INTERRUPT_PHY_INT));
+ LOG("%s: ITF/IRF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITRF_FLUSH));
+ LOG("%s: IRF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_IRF_FLUSH));
+ LOG("%s: Iso No-Tx: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITF_NO_TX));
+ LOG("%s: Iso Tx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITX_END));
+ LOG("%s: Async Rx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ARX_END));
+ LOG("%s: Iso Rx End (ITF/IRF): %d\n", machine().describe_context(), BIT(data, INTERRUPT_ITRF_RX_END));
+ LOG("%s: Iso Rx End (IRF): %d\n", machine().describe_context(), BIT(data, INTERRUPT_IRF_RX_END));
+ LOG("%s: Async Tx End: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ATX_END));
+ LOG("%s: ARF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ARF_FLUSH));
+ }
return data;
}
void md8412b_device::interrupt_w(offs_t offset, u32 data, u32 mem_mask)
{
LOG("%s: interrupt_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- mem_mask &= ~data;
- mem_mask &= INTERRUPT_MASK;
- COMBINE_DATA(&m_interrupt);
+ m_interrupt &= ~data & (mem_mask & INTERRUPT_MASK);
+ update_interrupt();
}
u32 md8412b_device::interrupt_mask_r()
@@ -544,6 +1012,7 @@ void md8412b_device::interrupt_mask_w(offs_t offset, u32 data, u32 mem_mask)
LOG("%s: ARF Flush: %d\n", machine().describe_context(), BIT(data, INTERRUPT_ARF_FLUSH));
mem_mask &= INTERRUPT_MASK;
COMBINE_DATA(&m_interrupt_mask);
+ update_interrupt();
}
u32 md8412b_device::tgo_r()
@@ -561,6 +1030,17 @@ void md8412b_device::tgo_w(offs_t offset, u32 data, u32 mem_mask)
LOG("%s: IT Start: %d\n", machine().describe_context(), BIT(data, TGO_IT_START));
mem_mask &= TGO_MASK;
COMBINE_DATA(&m_tgo);
+
+ if (!BIT(m_diag_status, DIAG_STATUS_AT_BUSY) && BIT(m_tgo, TGO_AT_GO))
+ {
+ m_diag_status |= 1 << DIAG_STATUS_AT_BUSY;
+ }
+
+ if (!BIT(m_diag_status, DIAG_STATUS_IT_BUSY) && BIT(m_tgo, TGO_IT_GO) && BIT(m_ctrl, CTRL_ISOMODE, CTRL_ISOMODE_WIDTH) == 0)
+ {
+ m_diag_status |= 1 << DIAG_STATUS_IT_BUSY;
+ m_iso_going = true;
+ }
}
u32 md8412b_device::bus_time_r()
diff --git a/src/mame/namco/md8412b.h b/src/mame/namco/md8412b.h
index 67295d18df6..68e20a1f0c9 100644
--- a/src/mame/namco/md8412b.h
+++ b/src/mame/namco/md8412b.h
@@ -20,6 +20,8 @@ public:
void map(address_map &map);
+ auto int_callback() { return m_int_cb.bind(); }
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
@@ -50,8 +52,8 @@ protected:
void sync_config_w(offs_t offset, u32 data, u32 mem_mask = ~0);
void atf_data_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 arf_data_r();
- u32 sync_data_r();
- void sync_data_w(offs_t offset, u32 data, u32 mem_mask = ~0);
+ u32 itrf_data_r();
+ void itf_data_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 irf_data_r();
u32 buf_status_ctrl_r();
void buf_status_ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0);
@@ -118,6 +120,15 @@ protected:
PACKET_CTRL_BUSYCTRL_WIDTH = 3,
PACKET_CTRL_WRITE_PEND = 12,
+ DIAG_STATUS_BUSY_STATE = 2,
+ DIAG_STATUS_AT_ACK = 8,
+ DIAG_STATUS_AT_ACK_MASK = 0x00000f00,
+ DIAG_STATUS_ACK_STATUS = 12,
+ DIAG_STATUS_ACK_STATUS_MASK = 0x00003000,
+ DIAG_STATUS_RETRY_TIME_MAX = 15,
+ DIAG_STATUS_AT_BUSY = 24,
+ DIAG_STATUS_IT_BUSY = 25,
+
PHY_CTRL_MASK = 0x00000fff,
PHY_CTRL_REG_DATA = 0,
PHY_CTRL_REG_DATA_WIDTH = 8,
@@ -139,8 +150,10 @@ protected:
CYCLE_TIMER_OFFSET_WIDTH = 12,
CYCLE_TIMER_COUNT = 12,
CYCLE_TIMER_COUNT_WIDTH = 13,
+ CYCLE_TIMER_COUNT_MASK = 0x01fff000,
CYCLE_TIMER_SECONDS = 25,
CYCLE_TIMER_SECONDS_WIDTH = 7,
+ CYCLE_TIMER_SECONDS_MASK = 0xfe000000,
SYNC_LENGTH_MASK = 0x0fff0000,
SYNC_LENGTH_VAL = 16,
@@ -222,15 +235,90 @@ protected:
};
private:
+ void update_interrupt();
+
+ void cycle_tick(s32 param);
+
+ void handle_async_tx();
+ void handle_iso_tx();
+
+ void push_async_rx_word(const u32 data);
+ u32 pop_async_rx_word();
+ void push_async_tx_word(const u32 data);
+ u32 pop_async_tx_word();
+ void push_iso_rx_word(const u32 data);
+ u32 pop_iso_rx_word();
+ void push_iso_tx_word(const u32 data);
+ u32 pop_iso_tx_word();
+ void push_iso_flight_word(const u32 data);
+ u32 pop_iso_flight_word();
+
+ void recv_self_id();
+
+ devcb_write_line m_int_cb;
+ bool m_int_active;
+
+ emu_timer *m_cycle_timer;
+ bool m_async_active;
+ bool m_cycle_started;
+ bool m_iso_going;
+
+ struct fifo_t
+ {
+ void init(const u32 _limit)
+ {
+ std::fill_n(buf, std::size(buf), 0);
+ wr_idx = 0;
+ rd_idx = 0;
+ count = 0;
+ limit = _limit;
+ }
+
+ void push(const u32 data)
+ {
+ buf[wr_idx] = data;
+ wr_idx = (wr_idx + 1) % limit;
+ count++;
+ }
+
+ u32 pop()
+ {
+ if (count == 0)
+ return 0;
+
+ const u32 data = buf[rd_idx];
+ rd_idx = (rd_idx + 1) % limit;
+ count--;
+ return data;
+ }
+
+ u32 peek()
+ {
+ return buf[rd_idx];
+ }
+
+ u32 buf[512];
+ u32 wr_idx;
+ u32 rd_idx;
+ u32 count;
+ u32 limit;
+ };
+
+ fifo_t m_async_rx;
+ fifo_t m_async_tx;
+ fifo_t m_iso_rx;
+ fifo_t m_iso_tx;
+
u32 m_ctrl;
u32 m_node_id;
u32 m_async_bufsize;
u32 m_sync_bufsize;
u32 m_packet_ctrl;
+ u32 m_diag_status;
u32 m_phy_ctrl;
u8 m_phy_regs[7];
u32 m_at_retries_ctrl;
- u32 m_cycle_timer;
+ u32 m_cycle_timer_reg;
u32 m_sync_packet_len;
u32 m_sync_config[4];
u32 m_buf_status_ctrl;
diff --git a/src/mame/namco/namco_settings.cpp b/src/mame/namco/namco_settings.cpp
index e2d6b16c556..0adb143b28f 100644
--- a/src/mame/namco/namco_settings.cpp
+++ b/src/mame/namco/namco_settings.cpp
@@ -3,6 +3,9 @@
#include "emu.h"
#include "namco_settings.h"
+#define VERBOSE ( 0 )
+#include "logmacro.h"
+
DEFINE_DEVICE_TYPE(NAMCO_SETTINGS, namco_settings_device, "namco_settings", "Namco Settings")
namco_settings_device::namco_settings_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
@@ -31,7 +34,7 @@ void namco_settings_device::clk_w(int state)
cur_bit++;
if(cur_bit == 16) {
cur_bit = 0;
- logerror("%s: %02x = %02x\n", tag(), adr, value);
+ LOG("%s: %02x = %02x\n", tag(), adr, value);
}
}
}
diff --git a/src/mame/namco/namcos23.cpp b/src/mame/namco/namcos23.cpp
index 8eff31be923..9a80b50d64b 100644
--- a/src/mame/namco/namcos23.cpp
+++ b/src/mame/namco/namcos23.cpp
@@ -1242,6 +1242,7 @@ It can also be used with Final Furlong when wired correctly.
#include "machine/rtc4543.h"
#include "sound/c352.h"
#include "video/poly.h"
+#include "video/rgbutil.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
@@ -1299,15 +1300,346 @@ It can also be used with Final Furlong when wired correctly.
#define LOG_RS232 (1ULL << 44)
#define LOG_IRQ_STATUS (1ULL << 45)
#define LOG_C451 (1ULL << 46)
+#define LOG_SH2_VPX (1ULL << 47)
+#define LOG_DIRECT (1ULL << 48)
#define LOG_ALL ( LOG_PROJ_MAT | LOG_3D_STATE_ERR | LOG_3D_STATE_UNK | LOG_VEC_ERR | LOG_VEC_UNK | LOG_RENDER_ERR | LOG_RENDER_INFO | LOG_MODEL_ERR | \
LOG_MODEL_INFO | LOG_MODELS | LOG_C435_PIO_UNK | LOG_C435_UNK | LOG_C417_UNK | LOG_C417_ACK | LOG_C412_UNK | LOG_C421_UNK | \
LOG_C422_IRQ | LOG_C422_UNK | LOG_C361_UNK | LOG_CTL_UNK | LOG_C417_IRQ | LOG_C361_IRQ | LOG_MATRIX_INFO | LOG_VEC_INFO | \
LOG_CTL_REG | LOG_C435_REG | LOG_C361_REG | LOG_C417_REG | LOG_C412_RAM | LOG_C421_RAM | LOG_C404_REGS | LOG_C404_RAM | LOG_GMEN | \
- LOG_GENERAL | LOG_RS232 | LOG_IRQ_STATUS | LOG_C451 | LOG_MATRIX_UNK | LOG_VEC_UNK | LOG_MCU_PORTS )
+ LOG_GENERAL | LOG_RS232 | LOG_IRQ_STATUS | LOG_C451 | LOG_MATRIX_UNK | LOG_VEC_UNK | LOG_MCU_PORTS | LOG_DIRECT )
-#define VERBOSE ( 0 )
+#define VERBOSE ( LOG_ALL & ~( LOG_MCU_PORTS | LOG_IRQ_STATUS | LOG_RS232 | LOG_GMEN ) )
#include "logmacro.h"
+class PixxiiiPacket
+{
+public:
+ PixxiiiPacket(const char *fourcc)
+ {
+ size_t length = strlen(fourcc);
+ memset(m_fourcc, 0, 4);
+ for (size_t i = 0; i < length && i < 4; i++)
+ {
+ m_fourcc[i] = fourcc[i];
+ }
+ m_size = 8;
+ }
+ PixxiiiPacket(FILE *input)
+ {
+ deserialize(input);
+ }
+ PixxiiiPacket(const u8 *data)
+ {
+ memcpy(m_fourcc, data, 4);
+ m_size = ((u32)data[4] << 24) | ((u32)data[5] << 16) | ((u32)data[6] << 8) | data[7];
+ for (u32 i = 0; i < m_size - 8; i++)
+ {
+ m_data.push_back(data[8 + i]);
+ }
+ }
+ PixxiiiPacket()
+ {
+ clear();
+ }
+
+ ~PixxiiiPacket()
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ memset(m_fourcc, 0, 4);
+ m_size = 8;
+ m_data.clear();
+ }
+
+ void set_fourcc(const char *fourcc)
+ {
+ memset(m_fourcc, 0, 4);
+ const size_t length = strlen(fourcc);
+ for (size_t i = 0; i < 4 && i < length; i++)
+ {
+ m_fourcc[i] = fourcc[i];
+ }
+ }
+
+ u32 get_size()
+ {
+ return m_size;
+ }
+
+ const u8 *get_data()
+ {
+ return &m_data[0];
+ }
+
+ void add_string(const char *str, size_t max_length = SIZE_MAX)
+ {
+ size_t length = strlen(str);
+ for (size_t i = 0; i < length && i < max_length - 1; i++)
+ {
+ m_data.push_back((u8)str[i]);
+ }
+ m_data.push_back(0);
+ m_size += std::min(length, max_length);
+ m_size++;
+ }
+
+ void add_u8(const u8 data)
+ {
+ m_data.push_back(data);
+ m_size++;
+ }
+
+ void add_u8_buffer(const u8 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ m_data.push_back(data[i]);
+ }
+ m_size += (u32)length;
+ }
+
+ void add_s8(const s8 data)
+ {
+ add_u8((u8)data);
+ }
+
+ void add_s8_buffer(const s8 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ m_data.push_back((u8)data[i]);
+ }
+ m_size += (u32)length;
+ }
+
+ void add_u16(const u16 data)
+ {
+ m_data.push_back((u8)(data >> 8));
+ m_data.push_back((u8)data);
+ m_size += 2;
+ }
+
+ void add_u16_buffer(const u16 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u16(data[i]);
+ }
+ }
+
+ void add_s16(const s16 data)
+ {
+ add_u16((u16)data);
+ }
+
+ void add_s16_buffer(const s16 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u16((u16)data[i]);
+ }
+ }
+
+ void add_matrix(const s16 *matrix)
+ {
+ add_s16_buffer(matrix, 9);
+ }
+
+ void add_u32(const u32 data)
+ {
+ m_data.push_back((u8)(data >> 24));
+ m_data.push_back((u8)(data >> 16));
+ m_data.push_back((u8)(data >> 8));
+ m_data.push_back((u8)data);
+ m_size += 4;
+ }
+
+ void add_u32_buffer(const u32 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u32(data[i]);
+ }
+ }
+
+ void add_s32(const s32 data)
+ {
+ add_u32((u32)data);
+ }
+
+ void add_s32_buffer(const s32 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u32((u32)data[i]);
+ }
+ }
+
+ void add_vector(const s32 *vec)
+ {
+ add_s32_buffer(vec, 3);
+ }
+
+ void add_float(float data)
+ {
+ u32 &val = reinterpret_cast<u32&>(data);
+ add_u32(val);
+ }
+
+ void add_float_buffer(float *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ u32 &val = reinterpret_cast<u32&>(data[i]);
+ add_u32(val);
+ }
+ }
+
+ void add_u64(const u64 data)
+ {
+ m_data.push_back((u8)(data >> 56));
+ m_data.push_back((u8)(data >> 48));
+ m_data.push_back((u8)(data >> 40));
+ m_data.push_back((u8)(data >> 32));
+ m_data.push_back((u8)(data >> 24));
+ m_data.push_back((u8)(data >> 16));
+ m_data.push_back((u8)(data >> 8));
+ m_data.push_back((u8)data);
+ m_size += 8;
+ }
+
+ void add_u64_buffer(const u64 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u64(data[i]);
+ }
+ }
+
+ void add_s64(const s64 data)
+ {
+ add_u64((u64)data);
+ }
+
+ void add_s64_buffer(const s64 *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ add_u64((u64)data[i]);
+ }
+ }
+
+ void add_double(double data)
+ {
+ u64 &val = reinterpret_cast<u64&>(data);
+ add_u64(val);
+ }
+
+ void add_double_buffer(double *data, size_t length)
+ {
+ for (size_t i = 0; i < length; i++)
+ {
+ u64 &val = reinterpret_cast<u64&>(data[i]);
+ add_u64(val);
+ }
+ }
+
+ void serialize(FILE *output)
+ {
+ fwrite(m_fourcc, 1, 4, output);
+ u8 size[4] =
+ {
+ (u8)(m_size >> 24), (u8)(m_size >> 16), (u8)(m_size >> 8), (u8)m_size
+ };
+ fwrite(size, 1, 4, output);
+ fwrite(&m_data[0], 1, m_data.size(), output);
+ }
+
+ void deserialize(FILE *input)
+ {
+ fread(m_fourcc, 1, 4, input);
+ u8 size[4];
+ fread(size, 1, 4, input);
+ m_size = ((u32)size[0] << 24) | ((u32)size[1] << 16) | ((u32)size[2] << 8) | size[3];
+ u8 value = 0;
+ for (u32 i = 0; i < m_size; i++)
+ {
+ fread(&value, 1, 1, input);
+ m_data.push_back(value);
+ }
+ }
+
+private:
+ u8 m_fourcc[4];
+ u32 m_size;
+ std::vector<u8> m_data;
+};
+
+static std::vector<PixxiiiPacket> s_packets;
+static bool s_capturing = false;
+
+static void start_capture()
+{
+ s_capturing = true;
+}
+
+static void finish_capture(const char *driver_name)
+{
+ size_t total_size = 8;
+ for (size_t i = 0; i < s_packets.size(); i++)
+ {
+ total_size += s_packets[i].get_size();
+ }
+
+ FILE *output = nullptr;
+ int output_index = 0;
+ char output_name[256];
+ do
+ {
+ if (output != nullptr)
+ fclose(output);
+ sprintf(output_name, "%s_%04x.p23", driver_name, output_index);
+ output = fopen(output_name, "rb");
+ output_index++;
+ } while (output != nullptr);
+ output = fopen(output_name, "wb");
+
+ static const char *const CAPTURE_FOURCC = "P23C";
+ fwrite(CAPTURE_FOURCC, 1, 4, output);
+
+ const u32 truncated_size = (u32)total_size;
+ u8 size_bytes[4];
+ size_bytes[0] = (u8)(truncated_size >> 24);
+ size_bytes[1] = (u8)(truncated_size >> 16);
+ size_bytes[2] = (u8)(truncated_size >> 8);
+ size_bytes[3] = (u8)truncated_size;
+ fwrite(size_bytes, 1, 4, output);
+
+ for (size_t i = 0; i < s_packets.size(); i++)
+ {
+ s_packets[i].serialize(output);
+ }
+ fclose(output);
+
+ for (size_t i = 0; i < s_packets.size(); i++)
+ {
+ s_packets[i].clear();
+ }
+ s_packets.clear();
+ s_capturing = false;
+
+ printf("PIXXIII capture saved to %s\n", output_name);
+}
+
+static PixxiiiPacket &log_packet(const char *fourcc)
+{
+ s_packets.push_back(PixxiiiPacket(fourcc));
+ return s_packets[s_packets.size() - 1];
+}
+
namespace
{
@@ -1441,8 +1773,8 @@ struct namcos23_render_entry
u16 tx;
u16 ty;
u16 model_blend_factor;
- u16 camera_power;
- u16 camera_ambient;
+ u16 light_power;
+ u16 light_ambient;
u8 poly_fade_r;
u8 poly_fade_g;
u8 poly_fade_b;
@@ -1553,6 +1885,8 @@ struct c417_t
struct c412_t
{
+ u16 unk0;
+ u16 unk1;
u16 sdram_a[0x100000]; // Framebuffers, probably
u16 sdram_b[0x100000];
u16 sram[0x20000]; // Ram-based tiles for alpha-cutout drawing
@@ -1691,8 +2025,8 @@ public:
m_tx(0),
m_ty(0),
m_model_blend_factor(0x4000),
- m_camera_power(0),
- m_camera_ambient(0),
+ m_light_power(0),
+ m_light_ambient(0),
m_proj_matrix_line(0),
m_scaling(0x4000),
m_c361_irqnum(0),
@@ -1779,11 +2113,15 @@ protected:
u16 c417_ptrom_lsw_r();
void c417_irq_ack_w(offs_t offset, u16 data);
+ u16 c412_unk0_r();
+ u16 c412_unk1_r();
u16 c412_flags_r(); // offset 0x06
u16 c412_addr_lsw_r(); // offset 0x10
u16 c412_addr_msw_r(); // offset 0x12
u16 c412_ram_r(); // offset 0x14
u16 c412_status_r(); // offset 0x18
+ void c412_unk0_w(offs_t offset, u16 data, u16 mem_mask = ~0);
+ void c412_unk1_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void c412_flags_w(offs_t offset, u16 data, u16 mem_mask = ~0); // offset 0x04
void c412_addr_lsw_w(offs_t offset, u16 data, u16 mem_mask = ~0); // offset 0x10
void c412_addr_msw_w(offs_t offset, u16 data, u16 mem_mask = ~0); // offset 0x12
@@ -1848,13 +2186,15 @@ protected:
void c435_matrix_set();
void c435_vector_set();
void c435_state_set();
- void c435_scaling_set();
- void c435_model_blend_factor_set();
+ void c435_unk_set0();
void c435_absolute_priority_set();
void c435_tx_set();
void c435_ty_set();
- void c435_camera_power_set();
- void c435_camera_ambient_set();
+ void c435_scaling_set();
+ void c435_model_blend_factor_set();
+ void c435_unk_set6();
+ void c435_light_power_set();
+ void c435_light_ambient_set();
void c435_render();
void c435_flush();
@@ -1877,6 +2217,7 @@ protected:
TILE_GET_INFO_MEMBER(text_tilemap_get_info);
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void check_pixxiii_trigger();
TIMER_CALLBACK_MEMBER(subcpu_scanline_on_tick);
TIMER_CALLBACK_MEMBER(subcpu_scanline_off_tick);
virtual void vblank(int state);
@@ -1940,6 +2281,7 @@ protected:
u32 m_main_irqcause;
+ bool m_odd_frame;
bool m_ctl_vbl_active;
u8 m_ctl_led;
u16 m_ctl_inp_buffer[2];
@@ -1956,8 +2298,8 @@ protected:
u16 m_tx;
u16 m_ty;
u16 m_model_blend_factor;
- u16 m_camera_power;
- u16 m_camera_ambient;
+ u16 m_light_power;
+ u16 m_light_ambient;
float m_proj_matrix[8*3];
u8 m_proj_matrix_line;
@@ -2172,20 +2514,18 @@ protected:
u32 sh2_trigger_r();
u32 sh2_shared_r(offs_t offset, u32 mem_mask = ~0);
void sh2_shared_w(offs_t offset, u32 data, u32 mem_mask = ~0);
+ u32 mips_to_sh2_shared_r(offs_t offset, u32 mem_mask = ~0);
+ void mips_to_sh2_shared_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 sh2_dsw_r(offs_t offset, u32 mem_mask = ~0);
u32 mips_sh2_unk_r(offs_t offset, u32 mem_mask = ~0);
- u32 sh2_unk_r(offs_t offset, u32 mem_mask = ~0);
- void sh2_unk_w(offs_t offset, u32 data, u32 mem_mask = ~0);
+ u32 sh2_vpxstate_r(offs_t offset, u32 mem_mask = ~0);
+ void sh2_vpxstate_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 sh2_unk6200000_r(offs_t offset, u32 mem_mask = ~0);
- u32 sh2_kludge_r();
+ u32 vpx_line_r(offs_t offset, u32 mem_mask = ~0);
void vpx_i2c_sdao_w(int state);
u8 vpx_i2c_r();
void vpx_i2c_w(u8 data);
- TIMER_CALLBACK_MEMBER(sh2_irq_off);
- int m_sh2_irq;
- emu_timer *m_sh2_irq_timer;
-
private:
void mips_map(address_map &map) ATTR_COLD;
void sh2_map(address_map &map) ATTR_COLD;
@@ -2373,10 +2713,20 @@ void namcos23_state::c435_state_set_projection_matrix_line(const u16 *param)
}
buf2 << "\n";
LOGMASKED(LOG_PROJ_MAT, "%s: %s", machine().describe_context(), std::move(buf2).str());
+
+ if (s_capturing)
+ {
+ PixxiiiPacket &cspl = log_packet("CSPL");
+ cspl.add_u16_buffer(param, 17);
+ }
}
void namcos23_state::c435_state_reset_w(u16 data)
{
+ if (s_capturing)
+ {
+ log_packet("CRST");
+ }
m_c435.buffer_pos = 0;
}
@@ -2446,6 +2796,12 @@ void namcos23_state::c435_matrix_matrix_mul() // 0.0
s16 m1[9];
s16 m2[9];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cmm_ = log_packet("CMM_");
+ cmm_.add_u16_buffer(m_c435.buffer, 5);
+ }
+
memcpy(m2, c435_getm(m_c435.buffer[2]), sizeof(s16) * 9);
if (transpose)
transpose_matrix(m2);
@@ -2481,6 +2837,12 @@ void namcos23_state::c435_matrix_vector_mul() // 0.1
return;
}
+ if (s_capturing)
+ {
+ PixxiiiPacket &cmv_ = log_packet("CMV_");
+ cmv_.add_u16_buffer(m_c435.buffer, 5);
+ }
+
bool extra_logging = false;
if (m_c435.buffer[0] != 0x0814 && m_c435.buffer[0] != 0x1014 && m_c435.buffer[0] != 0x0414)
{
@@ -2565,6 +2927,12 @@ void namcos23_state::c435_matrix_matrix_immed_mul() // 0.2
s16 m1[9];
s16 m2[9];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cmmi = log_packet("CMMI");
+ cmmi.add_u16_buffer(m_c435.buffer, 13);
+ }
+
memcpy(m1, &m_c435.buffer[4], sizeof(s16) * 9);
memcpy(m2, c435_getm(m_c435.buffer[2]), sizeof(s16) * 9);
LOGMASKED(LOG_MATRIX_INFO, " m1: %04x %04x %04x\n", (u16)m1[0], (u16)m1[1], (u16)m1[2]);
@@ -2601,6 +2969,12 @@ void namcos23_state::c435_matrix_vector_immed_mul() // 0.3
return;
}
+ if (s_capturing)
+ {
+ PixxiiiPacket &cmvi = log_packet("CMVI");
+ cmvi.add_u16_buffer(m_c435.buffer, 10);
+ }
+
bool extra_logging = false;
if (m_c435.buffer[0] != 0x0839 && m_c435.buffer[0] != 0x1039 && m_c435.buffer[0] != 0x0439)
{
@@ -2671,6 +3045,12 @@ void namcos23_state::c435_matrix_set() // 0.4
return;
}
+ if (s_capturing)
+ {
+ PixxiiiPacket &cms_ = log_packet("CMS_");
+ cms_.add_u16_buffer(m_c435.buffer, 11);
+ }
+
if (m_c435.buffer[0] != 0x004a)
LOGMASKED(LOG_MATRIX_UNK, "%s: WARNING: c435_matrix_set header %04x\n", machine().describe_context(), m_c435.buffer[0]);
@@ -2693,6 +3073,12 @@ void namcos23_state::c435_vector_set() // 0.5
if (m_c435.buffer[0] != 0x057)
LOGMASKED(LOG_VEC_UNK, "%s: WARNING: c435_vector_set header %04x\n", machine().describe_context(), m_c435.buffer[0]);
+ if (s_capturing)
+ {
+ PixxiiiPacket &cvs_ = log_packet("CVS_");
+ cvs_.add_u16_buffer(m_c435.buffer, 8);
+ }
+
s32 *t = c435_getv(m_c435.buffer[1]);
for (int i = 0; i < 3; i++)
t[i] = u32_to_s24((m_c435.buffer[2 * i + 2] << 16) | m_c435.buffer[2 * i + 3]);
@@ -2700,18 +3086,6 @@ void namcos23_state::c435_vector_set() // 0.5
LOGMASKED(LOG_VEC_INFO, "c435_vector_set (%04x): Vector %d = %08x %08x %08x\n", m_c435.buffer[0], m_c435.buffer[1], t[0], t[1], t[2]);
}
-void namcos23_state::c435_scaling_set() // 4.4
-{
- if ((m_c435.buffer[0] & 0xff) != 1)
- {
- LOGMASKED(LOG_VEC_ERR, "%s: WARNING: c435_scaling_set with size %d\n", machine().describe_context(), m_c435.buffer[0] & 0xff);
- return;
- }
-
- LOGMASKED(LOG_MATRIX_INFO, "c435_scaling_set (%04x): %04x\n", m_c435.buffer[0], m_c435.buffer[1]);
- m_scaling = m_c435.buffer[1];
-}
-
void namcos23_state::c435_state_set(u16 type, const u16 *param)
{
LOGMASKED(LOG_3D_STATE_UNK, "%s: c435_state_set, type %04x, header %04x\n", machine().describe_context(), type, m_c435.buffer[0]);
@@ -2737,10 +3111,17 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
re->model_blend_factor = 0;
re->tx = 0;
re->ty = 0;
- re->camera_power = m_camera_power;
- re->camera_ambient = m_camera_ambient;
+ re->light_power = m_light_power;
+ re->light_ambient = m_light_ambient;
if (m_c435.buffer[0] == 0x4f38)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &cimm = log_packet("CIMM");
+ cimm.add_u16(m_c435.buffer[0]);
+ cimm.add_u16(type);
+ cimm.add_u16_buffer(param, 55);
+ }
re->immediate.type = param[ 0];
re->immediate.h = (param[ 1] << 16) | param[ 2];
re->immediate.pal = (param[ 3] << 16) | param[ 4];
@@ -2772,6 +3153,13 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
}
else
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &cimm = log_packet("CIMM");
+ cimm.add_u16(m_c435.buffer[0]);
+ cimm.add_u16(type);
+ cimm.add_u16_buffer(param, 43);
+ }
re->immediate.type = param[ 0];
re->immediate.h = (param[ 1] << 16) | param[ 2];
re->immediate.pal = (param[ 3] << 16) | param[ 4];
@@ -2802,6 +3190,13 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
{
render_t &render = m_render;
namcos23_render_entry *re = render.entries[render.cur] + render.count[render.cur];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cimm = log_packet("CIMM");
+ cimm.add_u16(m_c435.buffer[0]);
+ cimm.add_u16(type);
+ cimm.add_u16_buffer(param, c435_get_state_entry_size(type));
+ }
re->poly_fade_r = m_c404.poly_fade_r;
re->poly_fade_g = m_c404.poly_fade_g;
re->poly_fade_b = m_c404.poly_fade_b;
@@ -2818,8 +3213,8 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
re->model_blend_factor = 0;
re->tx = 0;
re->ty = 0;
- re->camera_power = m_camera_power;
- re->camera_ambient = m_camera_ambient;
+ re->light_power = m_light_power;
+ re->light_ambient = m_light_ambient;
/*
3-e0: 1110 0000, has shade+tex+pos
3-a0: 1010 0000, has tex+pos
@@ -2884,6 +3279,13 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
{
render_t &render = m_render;
namcos23_render_entry *re = render.entries[render.cur] + render.count[render.cur];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cimm = log_packet("CIMM");
+ cimm.add_u16(m_c435.buffer[0]);
+ cimm.add_u16(type);
+ cimm.add_u16_buffer(param, c435_get_state_entry_size(type));
+ }
re->poly_fade_r = m_c404.poly_fade_r;
re->poly_fade_g = m_c404.poly_fade_g;
re->poly_fade_b = m_c404.poly_fade_b;
@@ -2900,8 +3302,8 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
re->model_blend_factor = 0;
re->tx = 0;
re->ty = 0;
- re->camera_power = m_camera_power;
- re->camera_ambient = m_camera_ambient;
+ re->light_power = m_light_power;
+ re->light_ambient = m_light_ambient;
re->immediate.type = param[ 0];
re->immediate.h = (param[ 1] << 16) | param[ 2];
re->immediate.pal = (param[ 3] << 16) | param[ 4];
@@ -2931,16 +3333,37 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
}
case 0x0001:
c435_state_set_interrupt(param);
+ if (s_capturing)
+ {
+ PixxiiiPacket &csiq = log_packet("CSIQ");
+ csiq.add_u16(m_c435.buffer[0]);
+ csiq.add_u16(type);
+ csiq.add_u16(param[0]);
+ }
break;
case 0x0036:
LOGMASKED(LOG_3D_STATE_UNK, "%s: unknown state set (%04x)\n", machine().describe_context(), m_c435.buffer[0]);
for (int i = 0; i < (m_c435.buffer[0] & 0xff); i++)
LOGMASKED(LOG_3D_STATE_UNK, "%s: Word %02x: %04x\n", machine().describe_context(), i, m_c435.buffer[1 + i]);
+ if (s_capturing)
+ {
+ PixxiiiPacket &cs36 = log_packet("CS36");
+ cs36.add_u16(m_c435.buffer[0]);
+ cs36.add_u16(type);
+ cs36.add_u16(param[0]);
+ }
break;
case 0x0046:
LOGMASKED(LOG_3D_STATE_UNK, "%s: unknown matrix(?) set (type 46) (%04x)\n", machine().describe_context(), m_c435.buffer[0]);
for (int i = 0; i < (m_c435.buffer[0] & 0xff); i++)
LOGMASKED(LOG_3D_STATE_UNK, "%s: Word %02x: %04x\n", machine().describe_context(), i, m_c435.buffer[1 + i]);
+ if (s_capturing)
+ {
+ PixxiiiPacket &cs46 = log_packet("CS46");
+ cs46.add_u16(m_c435.buffer[0]);
+ cs46.add_u16(type);
+ cs46.add_u16_buffer(param, 13);
+ }
break;
case 0x00c8:
c435_state_set_projection_matrix_line(param);
@@ -2949,6 +3372,13 @@ void namcos23_state::c435_state_set(u16 type, const u16 *param)
LOGMASKED(LOG_3D_STATE_UNK, "%s: unknown state type (%04x, %04x)\n", machine().describe_context(), m_c435.buffer[0], m_c435.buffer[1]);
for (int i = 0; i < (m_c435.buffer[0] & 0xff); i++)
LOGMASKED(LOG_3D_STATE_UNK, "%s: Word %02x: %04x\n", machine().describe_context(), i, m_c435.buffer[1 + i]);
+ if (s_capturing)
+ {
+ PixxiiiPacket &cssu = log_packet("CSSU");
+ cssu.add_u16(m_c435.buffer[0]);
+ cssu.add_u16(type);
+ cssu.add_u16_buffer(param, c435_get_state_entry_size(type));
+ }
break;
}
}
@@ -2975,34 +3405,94 @@ void namcos23_state::c435_state_set() // 4.f
c435_state_set(m_c435.buffer[1], m_c435.buffer + 2);
}
+void namcos23_state::c435_unk_set0() // 4.0
+{
+ if (s_capturing)
+ {
+ PixxiiiPacket &cu40 = log_packet("CU40");
+ cu40.add_u16_buffer(m_c435.buffer, 2);
+ }
+}
+
void namcos23_state::c435_absolute_priority_set() // 4.1
{
m_absolute_priority = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cabs = log_packet("CABS");
+ cabs.add_u16_buffer(m_c435.buffer, 2);
+ }
}
void namcos23_state::c435_tx_set() // 4.2
{
m_tx = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &ctxs = log_packet("CTXS");
+ ctxs.add_u16_buffer(m_c435.buffer, 2);
+ }
}
void namcos23_state::c435_ty_set() // 4.3
{
m_ty = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &ctys = log_packet("CTYS");
+ ctys.add_u16_buffer(m_c435.buffer, 2);
+ }
+}
+
+void namcos23_state::c435_scaling_set() // 4.4
+{
+ if ((m_c435.buffer[0] & 0xff) != 1)
+ {
+ LOGMASKED(LOG_VEC_ERR, "%s: WARNING: c435_scaling_set with size %d\n", machine().describe_context(), m_c435.buffer[0] & 0xff);
+ return;
+ }
+
+ LOGMASKED(LOG_MATRIX_INFO, "c435_scaling_set (%04x): %04x\n", m_c435.buffer[0], m_c435.buffer[1]);
+ m_scaling = m_c435.buffer[1];
}
void namcos23_state::c435_model_blend_factor_set() // 4.5
{
m_model_blend_factor = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &cblf = log_packet("CBLF");
+ cblf.add_u16_buffer(m_c435.buffer, 2);
+ }
+}
+
+void namcos23_state::c435_unk_set6() // 4.6
+{
+ if (s_capturing)
+ {
+ PixxiiiPacket &cu46 = log_packet("CU46");
+ cu46.add_u16_buffer(m_c435.buffer, 2);
+ }
}
-void namcos23_state::c435_camera_power_set() // 4.7
+void namcos23_state::c435_light_power_set() // 4.7
{
- m_camera_power = m_c435.buffer[1];
+ m_light_power = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &clpw = log_packet("CLPW");
+ clpw.add_u16_buffer(m_c435.buffer, 2);
+ }
}
-void namcos23_state::c435_camera_ambient_set() // 4.8
+void namcos23_state::c435_light_ambient_set() // 4.8
{
- m_camera_ambient = m_c435.buffer[1];
+ m_light_ambient = m_c435.buffer[1];
+ if (s_capturing)
+ {
+ PixxiiiPacket &clam = log_packet("CLAM");
+ clam.add_u16_buffer(m_c435.buffer, 2);
+ }
}
void namcos23_state::c435_render() // 8
@@ -3011,6 +3501,12 @@ void namcos23_state::c435_render() // 8
if (size != 3)
LOGMASKED(LOG_RENDER_ERR, "%04x %04x %04x %04x %04x\n", m_c435.buffer[0], m_c435.buffer[1], m_c435.buffer[2], m_c435.buffer[3], m_c435.buffer[4]);
+ if (s_capturing)
+ {
+ PixxiiiPacket &cren = log_packet("CREN");
+ cren.add_u16_buffer(m_c435.buffer, size + 1);
+ }
+
render_t &render = m_render;
const bool scroll = BIT(m_c435.buffer[0], 9);
const bool use_scaling = BIT(m_c435.buffer[0], 7);
@@ -3035,8 +3531,8 @@ void namcos23_state::c435_render() // 8
re->model_blend_factor = m_model_blend_factor;
re->tx = scroll ? m_tx : 0;
re->ty = scroll ? m_ty : 0;
- re->camera_power = m_camera_power;
- re->camera_ambient = m_camera_ambient;
+ re->light_power = m_light_power;
+ re->light_ambient = m_light_ambient;
re->model.light_vector[0] = m_light_vector[0];
re->model.light_vector[1] = m_light_vector[1];
re->model.light_vector[2] = m_light_vector[2];
@@ -3068,6 +3564,12 @@ void namcos23_state::c435_flush() // c
return;
}
+ if (s_capturing)
+ {
+ PixxiiiPacket &cfls = log_packet("CFLS");
+ cfls.add_u16(m_c435.buffer[0]);
+ }
+
if (BIT(m_c435.buffer[0], 13))
irq_update(m_main_irqcause | MAIN_C451_IRQ);
else
@@ -3076,6 +3578,12 @@ void namcos23_state::c435_flush() // c
void namcos23_state::c435_sprite_w(u16 data)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &sprw = log_packet("SPRW");
+ sprw.add_u16(data);
+ }
+
// Ignore the first two values
if (m_c435.buffer_pos >= 2)
{
@@ -3139,6 +3647,9 @@ void namcos23_state::c435_pio_w(offs_t offset, u16 data)
case 0x4000:
switch (h & 0x3f00)
{
+ case 0x0000:
+ c435_unk_set0();
+ break;
case 0x0100:
c435_absolute_priority_set();
break;
@@ -3154,11 +3665,14 @@ void namcos23_state::c435_pio_w(offs_t offset, u16 data)
case 0x0500:
c435_model_blend_factor_set();
break;
+ case 0x0600:
+ c435_unk_set6();
+ break;
case 0x0700:
- c435_camera_power_set();
+ c435_light_power_set();
break;
case 0x0800:
- c435_camera_ambient_set();
+ c435_light_ambient_set();
break;
case 0x0f00:
c435_state_set();
@@ -3179,6 +3693,12 @@ void namcos23_state::c435_pio_w(offs_t offset, u16 data)
if (!known)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &cunk = log_packet("CUNK");
+ cunk.add_u16_buffer(m_c435.buffer, m_c435.buffer_pos);
+ }
+
std::ostringstream buf;
buf << "Unknown c435 -";
for (int i = 0; i < m_c435.buffer_pos; i++)
@@ -3333,12 +3853,22 @@ void namcos23_state::c435_dma_addr_w(offs_t offset, u32 data, u32 mem_mask)
{
LOGMASKED(LOG_C435_REG, "%s: c435 write address: %08x & %08x\n", machine().describe_context(), data, mem_mask);
COMBINE_DATA(&m_c435.address);
+ if (s_capturing)
+ {
+ PixxiiiPacket &a435 = log_packet("A435");
+ a435.add_u32(m_c435.address);
+ }
}
void namcos23_state::c435_dma_size_w(offs_t offset, u32 data, u32 mem_mask)
{
LOGMASKED(LOG_C435_REG, "%s: c435 write size: %08x & %08x\n", machine().describe_context(), data, mem_mask);
COMBINE_DATA(&m_c435.size);
+ if (s_capturing)
+ {
+ PixxiiiPacket &s435 = log_packet("S435");
+ s435.add_u32(m_c435.size);
+ }
}
void namcos23_state::c435_dma_start_w(address_space &space, offs_t offset, u32 data, u32 mem_mask)
@@ -3352,12 +3882,21 @@ void gorgon_state::c435_pio_mode_w(offs_t offset, u32 data, u32 mem_mask)
{
LOGMASKED(LOG_C435_REG, "%s: PIO mode write: %08x & %08x (%s mode)\n", machine().describe_context(), data, mem_mask, BIT(data, 0) ? "sprite" : "command");
COMBINE_DATA(&m_c435.pio_mode);
+ if (s_capturing)
+ {
+ PixxiiiPacket &piom = log_packet("PIOM");
+ piom.add_u16(m_c435.pio_mode);
+ }
m_c435.buffer_pos = 0;
}
void namcos23_state::c435_clear_bufpos_w(offs_t offset, u32 data, u32 mem_mask)
{
LOGMASKED(LOG_C435_REG, "%s: clear buffer pos: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ if (s_capturing)
+ {
+ log_packet("CRST");
+ }
m_c435.buffer_pos = 0;
}
@@ -4037,7 +4576,7 @@ void namcos23_state::render_model(const namcos23_render_entry *re)
if (lsi < 0)
lsi = 0;
- pv[i].p[3] = std::clamp(re->camera_ambient + re->camera_power * lsi, 0.f, 64.f);
+ pv[i].p[3] = std::clamp(re->light_ambient + re->light_power * lsi, 0.f, 64.f);
} break;
}
}
@@ -4435,16 +4974,32 @@ void namcos23_state::sprites_idx_w(offs_t offset, u16 data, u16 mem_mask)
{
m_c404.spritedata_idx = data >> 1;
LOGMASKED(LOG_SPRITES, "%s: sprites_idx_w: %d = %04x\n", machine().describe_context(), offset, data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &spis = log_packet("SPIS");
+ spis.add_u16(m_c404.spritedata_idx);
+ }
}
void namcos23_state::sprites_data_w(offs_t offset, u16 data, u16 mem_mask)
{
m_c404.sprites[(m_c404.spritedata_idx >> 2) % 0x280].d[m_c404.spritedata_idx & 3] = data;
m_c404.spritedata_idx++;
+ if (s_capturing)
+ {
+ PixxiiiPacket &spds = log_packet("SPDS");
+ spds.add_u16(data);
+ }
}
void namcos23_state::paletteram_w(offs_t offset, u32 data, u32 mem_mask)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &palw = log_packet("PALW");
+ palw.add_u32((u32)offset);
+ palw.add_u32(data);
+ }
COMBINE_DATA(&m_generic_paletteram_32[offset]);
// each LONGWORD is 2 colors, each OFFSET is 2 colors
@@ -4475,6 +5030,13 @@ TILE_GET_INFO_MEMBER(namcos23_state::text_tilemap_get_info)
void namcos23_state::textram_w(offs_t offset, u32 data, u32 mem_mask)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &txtw = log_packet("TXTW");
+ txtw.add_u32((u32)offset);
+ txtw.add_u32(data);
+ txtw.add_u32(mem_mask);
+ }
COMBINE_DATA(&m_textram[offset]);
m_bgtilemap->mark_tile_dirty(offset*2);
m_bgtilemap->mark_tile_dirty((offset*2)+1);
@@ -4482,6 +5044,13 @@ void namcos23_state::textram_w(offs_t offset, u32 data, u32 mem_mask)
void namcos23_state::textchar_w(offs_t offset, u32 data, u32 mem_mask)
{
+ if (s_capturing)
+ {
+ PixxiiiPacket &chrw = log_packet("CHRW");
+ chrw.add_u32((u32)offset);
+ chrw.add_u32(data);
+ chrw.add_u32(mem_mask);
+ }
COMBINE_DATA(&m_charram[offset]);
m_gfxdecode->gfx(0)->mark_dirty(offset/32);
}
@@ -4497,48 +5066,104 @@ u16 namcos23_state::c404_ram_r(offs_t offset)
void namcos23_state::c404_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
LOGMASKED(LOG_C404_RAM, "%s: c404_ram_w[%04x] = %04x & %04x\n", machine().describe_context(), offset, data, mem_mask);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)offset);
+ gamw.add_u32(data);
+ gamw.add_u32(mem_mask);
+ }
COMBINE_DATA(&m_c404.ram[offset]);
}
void namcos23_state::c404_poly_fade_red_w(offs_t offset, u16 data) // 0
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_fade_red_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)0);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.poly_fade_r = m_c404.ram[0x00] = data;
}
void namcos23_state::c404_poly_fade_green_w(offs_t offset, u16 data) // 1
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_fade_green_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)0);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.poly_fade_g = m_c404.ram[0x01] = data;
}
void namcos23_state::c404_poly_fade_blue_w(offs_t offset, u16 data) // 2
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_fade_blue_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)1);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.poly_fade_b = m_c404.ram[0x02] = data;
}
void namcos23_state::c404_fog_red_w(offs_t offset, u16 data) // 5
{
LOGMASKED(LOG_C404_REGS, "%s: c404_fog_red_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)2);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.fog_r = m_c404.ram[0x05] = data;
}
void namcos23_state::c404_fog_green_w(offs_t offset, u16 data) // 6
{
LOGMASKED(LOG_C404_REGS, "%s: c404_fog_green_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)3);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.fog_g = m_c404.ram[0x06] = data;
}
void namcos23_state::c404_fog_blue_w(offs_t offset, u16 data) // 7
{
LOGMASKED(LOG_C404_REGS, "%s: c404_fog_blue_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)3);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.fog_b = m_c404.ram[0x07] = data;
}
void namcos23_state::c404_bg_red_w(offs_t offset, u16 data) // 8
{
LOGMASKED(LOG_C404_REGS, "%s: c404_bg_red_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)4);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.ram[0x08] = data;
m_c404.bgcolor_r = data & 0x00ff;
}
@@ -4546,6 +5171,13 @@ void namcos23_state::c404_bg_red_w(offs_t offset, u16 data) // 8
void namcos23_state::c404_bg_green_w(offs_t offset, u16 data) // 9
{
LOGMASKED(LOG_C404_REGS, "%s: c404_bg_green_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)4);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.ram[0x09] = data;
m_c404.bgcolor_g = data & 0x00ff;
}
@@ -4553,6 +5185,13 @@ void namcos23_state::c404_bg_green_w(offs_t offset, u16 data) // 9
void namcos23_state::c404_bg_blue_w(offs_t offset, u16 data) // a
{
LOGMASKED(LOG_C404_REGS, "%s: c404_bg_blue_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)5);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.ram[0x0a] = data;
m_c404.bgcolor_b = data & 0x00ff;
}
@@ -4560,6 +5199,13 @@ void namcos23_state::c404_bg_blue_w(offs_t offset, u16 data) // a
void namcos23_state::c404_spot_lsb_w(offs_t offset, u16 data) // d
{
LOGMASKED(LOG_C404_REGS, "%s: c404_spot_lsb_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)6);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.ram[0x0d] = data;
m_c404.spot_factor &= 0xff00;
m_c404.spot_factor |= data & 0x00ff;
@@ -4568,6 +5214,13 @@ void namcos23_state::c404_spot_lsb_w(offs_t offset, u16 data) // d
void namcos23_state::c404_spot_msb_w(offs_t offset, u16 data) // e
{
LOGMASKED(LOG_C404_REGS, "%s: c404_spot_msb_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)7);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.ram[0x0e] = data;
m_c404.spot_factor &= 0x00ff;
m_c404.spot_factor |= (data & 0x00ff) << 8;
@@ -4576,78 +5229,169 @@ void namcos23_state::c404_spot_msb_w(offs_t offset, u16 data) // e
void namcos23_state::c404_poly_alpha_color_w(offs_t offset, u16 data) // f
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_alpha_color_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)7);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.poly_alpha_color = m_c404.ram[0x0f] = data;
}
void namcos23_state::c404_poly_alpha_pen_w(offs_t offset, u16 data) // 10
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_alpha_pen_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)8);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.poly_alpha_pen = m_c404.ram[0x10] = data;
}
void namcos23_state::c404_poly_alpha_w(offs_t offset, u16 data) // 11
{
LOGMASKED(LOG_C404_REGS, "%s: c404_poly_alpha_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)8);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.poly_alpha = m_c404.ram[0x11] = data;
}
void namcos23_state::c404_alpha_check12_w(offs_t offset, u16 data) // 12
{
LOGMASKED(LOG_C404_REGS, "%s: c404_alpha_check12_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)9);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.alpha_check12 = m_c404.ram[0x12] = data;
}
void namcos23_state::c404_alpha_check13_w(offs_t offset, u16 data) // 13
{
LOGMASKED(LOG_C404_REGS, "%s: c404_alpha_check13_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)9);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.alpha_check13 = m_c404.ram[0x13] = data;
}
void namcos23_state::c404_text_alpha_mask_w(offs_t offset, u16 data) // 14
{
LOGMASKED(LOG_C404_REGS, "%s: c404_text_alpha_mask_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)10);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.alpha_mask = m_c404.ram[0x14] = data;
}
void namcos23_state::c404_text_alpha_factor_w(offs_t offset, u16 data) // 15
{
LOGMASKED(LOG_C404_REGS, "%s: c404_text_alpha_factor_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)10);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.alpha_factor = m_c404.ram[0x15] = data;
}
void namcos23_state::c404_screen_fade_red_w(offs_t offset, u16 data) // 16
{
LOGMASKED(LOG_C404_REGS, "%s: c404_screen_fade_red_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)11);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.screen_fade_r = m_c404.ram[0x16] = data;
}
void namcos23_state::c404_screen_fade_green_w(offs_t offset, u16 data) // 17
{
LOGMASKED(LOG_C404_REGS, "%s: c404_screen_fade_green_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)11);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.screen_fade_g = m_c404.ram[0x17] = data;
}
void namcos23_state::c404_screen_fade_blue_w(offs_t offset, u16 data) // 18
{
LOGMASKED(LOG_C404_REGS, "%s: c404_screen_fade_blue_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)12);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.screen_fade_b = m_c404.ram[0x18] = data;
}
void namcos23_state::c404_screen_fade_factor_w(offs_t offset, u16 data) // 19
{
LOGMASKED(LOG_C404_REGS, "%s: c404_screen_fade_factor_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)12);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.screen_fade_factor = m_c404.ram[0x19] = data;
}
void namcos23_state::c404_fade_flags_w(offs_t offset, u16 data) // 1a
{
LOGMASKED(LOG_C404_REGS, "%s: c404_fade_flags_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)13);
+ gamw.add_u32((u32)data << 16);
+ gamw.add_u32(0xffff0000);
+ }
m_c404.fade_flags = m_c404.ram[0x1a] = data;
}
void namcos23_state::c404_palette_base_w(offs_t offset, u16 data) // 1b
{
LOGMASKED(LOG_C404_REGS, "%s: c404_palette_base_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)13);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.ram[0x1b] = data;
m_c404.palbase = (data << 8) & 0x7f00;
}
@@ -4655,6 +5399,13 @@ void namcos23_state::c404_palette_base_w(offs_t offset, u16 data) // 1b
void namcos23_state::c404_layer_flags_w(offs_t offset, u16 data) // 1f
{
LOGMASKED(LOG_C404_REGS, "%s: c404_layer_flags_w: %04x\n", machine().describe_context(), data);
+ if (s_capturing)
+ {
+ PixxiiiPacket &gamw = log_packet("GAMW");
+ gamw.add_u32((u32)15);
+ gamw.add_u32((u32)data);
+ gamw.add_u32(0x0000ffff);
+ }
m_c404.layer_flags = m_c404.ram[0x1f] = data;
}
@@ -4690,6 +5441,168 @@ void gorgon_state::video_start()
m_sprrom = memregion("sprites")->base();
}
+void namcos23_state::check_pixxiii_trigger()
+{
+ if (machine().input().code_pressed_once(KEYCODE_Q))
+ {
+ start_capture();
+
+ PixxiiiPacket &prjm = log_packet("PRJM");
+ prjm.add_float_buffer(m_proj_matrix, 24);
+
+ PixxiiiPacket &mats = log_packet("MATS");
+ for (int i = 0; i < 256; i++)
+ {
+ mats.add_matrix(m_matrices[i]);
+ }
+
+ PixxiiiPacket &vecs = log_packet("VECS");
+ for (int i = 0; i < 256; i++)
+ {
+ vecs.add_vector(m_vectors[i]);
+ }
+
+ PixxiiiPacket &lvec = log_packet("LVEC");
+ lvec.add_vector(m_light_vector);
+
+ PixxiiiPacket &scal = log_packet("SCAL");
+ scal.add_u16(m_scaling);
+
+ PixxiiiPacket &spm_ = log_packet("SPM_");
+ spm_.add_matrix(m_spm);
+
+ PixxiiiPacket &spv_ = log_packet("SPV_");
+ spv_.add_vector(m_spv);
+
+ PixxiiiPacket &ptrl = log_packet("PTRL");
+ ptrl.add_u32(m_ptrom_limit);
+
+ PixxiiiPacket &ptrm = log_packet("PTRM");
+ ptrm.add_u32_buffer(m_ptrom, m_ptrom_limit);
+
+ PixxiiiPacket &pensp = log_packet("PENS");
+ const pen_t *pens = m_palette->pens();
+ for (int i = 0; i < 0x8000; i++)
+ {
+ rgbaint_t rgb(pens[i]);
+ pensp.add_u8(rgb.get_r());
+ pensp.add_u8(rgb.get_g());
+ pensp.add_u8(rgb.get_b());
+ pensp.add_u8(rgb.get_a());
+ }
+
+ PixxiiiPacket &palr = log_packet("PALR");
+ palr.add_u32_buffer(&m_generic_paletteram_32[0], 0x30000 / 4);
+
+ PixxiiiPacket &sprh = log_packet("SPRH");
+ sprh.add_u8((u8)1);
+
+ PixxiiiPacket &a435 = log_packet("A435");
+ a435.add_u32(m_c435.address);
+
+ PixxiiiPacket &s435 = log_packet("S435");
+ s435.add_u32(m_c435.size);
+
+ PixxiiiPacket &dbuf = log_packet("DBUF");
+ dbuf.add_u16_buffer(m_c435.direct_buf, 28);
+ dbuf.add_u16_buffer(m_c435.direct_vertex, 6);
+ dbuf.add_u16(m_c435.direct_vert_pos);
+ dbuf.add_u16(m_c435.direct_buf_pos);
+ dbuf.add_u8((u8)m_c435.direct_buf_nonempty);
+
+ PixxiiiPacket &piom = log_packet("PIOM");
+ piom.add_u16(m_c435.pio_mode);
+
+ PixxiiiPacket &sprd = log_packet("SPRD");
+ sprd.add_u16_buffer(m_c435.spritedata, 0x10000);
+ sprd.add_u16(m_c435.sprite_target);
+
+ PixxiiiPacket &sprt = log_packet("SPRT");
+ for (int i = 0; i < 0x280; i++)
+ {
+ sprt.add_u16_buffer(m_c404.sprites[i].d, 4);
+ }
+
+ PixxiiiPacket &spri = log_packet("SPRI");
+ spri.add_u16(m_c404.spritedata_idx);
+
+ PixxiiiPacket &txrm = log_packet("TXRM");
+ txrm.add_u16_buffer(&m_texram[0], 0x20000);
+
+ PixxiiiPacket &txtr = log_packet("TXTR");
+ txtr.add_u32_buffer(&m_textram[0], 0x2000 / 4);
+
+ PixxiiiPacket &chrr = log_packet("CHRR");
+ chrr.add_u32_buffer(&m_charram[0], 0x1e000 / 4);
+
+ PixxiiiPacket &gamr = log_packet("GAMR");
+ gamr.add_u16_buffer(&m_c404.ram[0], 0x400);
+
+ if (m_sprrom != nullptr)
+ {
+ u32 sprite_mask = memregion("sprites")->bytes() - 1;
+ PixxiiiPacket &sprr = log_packet("SPRR");
+ sprr.add_u8_buffer(m_sprrom, sprite_mask + 1);
+
+ PixxiiiPacket &sprm = log_packet("SPRM");
+ sprm.add_u32(sprite_mask);
+ }
+
+ PixxiiiPacket &tmhr = log_packet("TMHR");
+ tmhr.add_u8_buffer(m_tmhrom, memregion("textilemaph")->bytes());
+
+ PixxiiiPacket &tmlr = log_packet("TMLR");
+ tmlr.add_u16_buffer(m_tmlrom, memregion("textilemapl")->bytes() / 2);
+
+ PixxiiiPacket &tidm = log_packet("TIDM");
+ tidm.add_u32(m_tileid_mask);
+
+ PixxiiiPacket &texr = log_packet("TEXR");
+ texr.add_u8_buffer(m_texrom, memregion("textile")->bytes());
+
+ PixxiiiPacket &tilm = log_packet("TILM");
+ tilm.add_u32(m_tile_mask);
+
+ PixxiiiPacket &cmdb = log_packet("CMDB");
+ cmdb.add_u16_buffer(m_c435.buffer, 256);
+
+ PixxiiiPacket &cmdp = log_packet("CMDP");
+ cmdp.add_s32(m_c435.buffer_pos);
+
+ PixxiiiPacket &cabs = log_packet("CABS");
+ cabs.add_u16(0);
+ cabs.add_u16(m_absolute_priority);
+
+ PixxiiiPacket &cu40 = log_packet("CU40");
+ cu40.add_u16(0);
+ cu40.add_u16(0);
+
+ PixxiiiPacket &ctxs = log_packet("CTXS");
+ ctxs.add_u16(0);
+ ctxs.add_u16(m_tx);
+
+ PixxiiiPacket &ctys = log_packet("CTYS");
+ ctys.add_u16(0);
+ ctys.add_u16(m_ty);
+
+ PixxiiiPacket &clpw = log_packet("CLPW");
+ clpw.add_u16(0);
+ clpw.add_u16(m_light_power);
+
+ PixxiiiPacket &clam = log_packet("CLAM");
+ clam.add_u16(0);
+ clam.add_u16(m_light_ambient);
+
+ PixxiiiPacket &cblf = log_packet("CBLF");
+ cblf.add_u16(0);
+ cblf.add_u16(m_model_blend_factor);
+ }
+ else if (s_capturing)
+ {
+ finish_capture(machine().system().name);
+ }
+}
+
void namcos23_state::mix_text_layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int prival)
{
const pen_t *pens = m_palette->pens();
@@ -4758,6 +5671,8 @@ u32 gorgon_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, con
u32 namcos23_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ check_pixxiii_trigger();
+
if (machine().video().skip_this_frame())
{
m_render.cur = !m_render.cur;
@@ -4939,6 +5854,7 @@ void namcos23_state::subcpu_irq1_update(int state)
void namcos23_state::vblank(int state)
{
+ m_odd_frame = !m_odd_frame;
if (state)
{
m_ctl_vbl_active = true;
@@ -5089,18 +6005,52 @@ void crszone_state::c450_dma_addr_w(address_space &space, offs_t offset, u32 dat
{
LOGMASKED(LOG_C435_REG, "%s: c450 write DMA address @%08x: %08x & %08x\n", machine().describe_context(), 0x10400000, data, mem_mask);
COMBINE_DATA(&m_c435.address);
+ if (s_capturing)
+ {
+ PixxiiiPacket &a435 = log_packet("A435");
+ a435.add_u32(m_c435.address);
+ }
}
void crszone_state::c450_dma_size_w(address_space &space, offs_t offset, u32 data, u32 mem_mask)
{
LOGMASKED(LOG_C435_REG, "%s: c450 write DMA size @%08x: %08x & %08x (kicking DMA from %08x)\n", machine().describe_context(), 0x1040000c, data, mem_mask, m_c435.address);
COMBINE_DATA(&m_c435.size);
+ if (s_capturing)
+ {
+ PixxiiiPacket &s435 = log_packet("S435");
+ s435.add_u32(m_c435.size);
+ }
c435_dma(space, m_c435.address, m_c435.size);
irq_update(m_main_irqcause | MAIN_C450_IRQ);
}
// C412
+u16 namcos23_state::c412_unk0_r()
+{
+ LOGMASKED(LOG_C412_UNK, "%s: c412_unk0_r: %04x\n", machine().describe_context(), m_c412.unk0);
+ return m_c412.unk0;
+}
+
+void namcos23_state::c412_unk0_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ LOGMASKED(LOG_C412_UNK, "%s: c412_unk0_w: %04x\n", machine().describe_context(), data);
+ m_c412.unk0 = data;
+}
+
+u16 namcos23_state::c412_unk1_r()
+{
+ LOGMASKED(LOG_C412_UNK, "%s: c412_unk1_r: %04x\n", machine().describe_context(), m_c412.unk1);
+ return m_c412.unk1;
+}
+
+void namcos23_state::c412_unk1_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ LOGMASKED(LOG_C412_UNK, "%s: c412_unk1_w: %04x\n", machine().describe_context(), data);
+ m_c412.unk1 = data;
+}
+
u16 namcos23_state::c412_flags_r() // offset 0x06
{
LOGMASKED(LOG_C412_UNK, "%s: c412_flags_r: %04x\n", machine().describe_context(), 0x0002);
@@ -5121,7 +6071,7 @@ u16 namcos23_state::c412_addr_msw_r() // offset 0x12
u16 namcos23_state::c412_ram_r() // offset 0x14
{
- // logerror("c412_ram_r %06x\n", m_c412.adr);
+ LOGMASKED(LOG_C412_UNK, "%s: c412_ram_r: %06x\n", machine().describe_context(), m_c412.adr);
if (m_c412.adr < 0x100000)
return m_c412.sdram_a[m_c412.adr & 0xfffff];
else if (m_c412.adr < 0x200000)
@@ -5139,6 +6089,7 @@ u16 namcos23_state::c412_status_r() // offset 0x18
// unknown status, 500gp reads it and waits for a transition
// no other games use it?
m_c412.status_c ^= 1;
+ LOGMASKED(LOG_C412_UNK, "%s: c412_status_r: %06x\n", machine().describe_context(), m_c412.status_c);
return m_c412.status_c;
}
@@ -5194,6 +6145,7 @@ void namcos23_state::c412_ram_w(offs_t offset, u16 data, u16 mem_mask)
u16 namcos23_state::c421_ram_r()
{
offs_t offset = m_c421.adr & 0xfffff;
+ LOGMASKED(LOG_C412_UNK, "%s: c421_ram_r: %06x\n", machine().describe_context(), offset);
if (offset < 0x40000)
return m_c421.dram_a[offset & 0x3ffff];
else if (offset < 0x80000)
@@ -5367,6 +6319,7 @@ u16 namcos23_state::c361_vblank_r()
void namcos23_state::direct_buf_start_w(offs_t offset, u16 data, u16 mem_mask)
{
+ LOGMASKED(LOG_DIRECT, "%s: direct_buf_start_w: %04x\n", machine().describe_context(), data);
m_c435.direct_buf_open = (bool)data;
m_c435.direct_buf_pos = 0;
return;
@@ -5377,6 +6330,7 @@ void namcos23_state::direct_buf_w(offs_t offset, u16 data, u16 mem_mask)
if (!m_c435.direct_buf_open)
return;
+ LOGMASKED(LOG_DIRECT, "%s: direct_buf_w: %04x\n", machine().describe_context(), data);
if (m_c435.direct_buf_pos == 0)
{
m_c435.direct_buf_pos++;
@@ -5409,6 +6363,11 @@ void namcos23_state::direct_buf_w(offs_t offset, u16 data, u16 mem_mask)
memcpy(re->direct.d, m_c435.direct_buf, sizeof(m_c435.direct_buf));
render.count[render.cur]++;
+ if (s_capturing)
+ {
+ PixxiiiPacket &cdir = log_packet("CDIR");
+ cdir.add_u16_buffer(m_c435.direct_buf, 28);
+ }
m_c435.direct_buf_nonempty = false;
m_c435.direct_buf_pos = 0;
}
@@ -5470,6 +6429,7 @@ void namcos23_state::ctl_vbl_ack_w(offs_t offset, u16 data)
void namcos23_state::ctl_direct_poly_w(offs_t offset, u16 data)
{
// gmen wars spams this heavily with 0 prior to starting the GMEN board test
+ LOGMASKED(LOG_DIRECT, "%s: ctl_direct_poly_w: %04x\n", machine().describe_context(), data);
m_c435.direct_buf[m_c435.direct_buf_pos++] = data;
if (data)
m_c435.direct_buf_nonempty = true;
@@ -5499,6 +6459,12 @@ void namcos23_state::ctl_direct_poly_w(offs_t offset, u16 data)
re->ty = 0;
memcpy(re->direct.d, m_c435.direct_buf, sizeof(m_c435.direct_buf));
render.count[render.cur]++;
+
+ if (s_capturing)
+ {
+ PixxiiiPacket &cdir = log_packet("CDIR");
+ cdir.add_u16_buffer(m_c435.direct_buf, 28);
+ }
}
}
m_c435.direct_buf_nonempty = false;
@@ -5725,6 +6691,8 @@ void namcos23_state::mips_map(address_map &map)
map(0x08000000, 0x08ffffff).rom().region("data", 0x0000000).mirror(0x1000000); // data ROMs
map(0x0a000000, 0x0affffff).rom().region("data", 0x1000000).mirror(0x1000000);
+ map(0x0c000000, 0x0c000001).rw(FUNC(namcos23_state::c412_unk0_r), FUNC(namcos23_state::c412_unk0_w));
+ map(0x0c000002, 0x0c000003).rw(FUNC(namcos23_state::c412_unk1_r), FUNC(namcos23_state::c412_unk1_w));
map(0x0c000004, 0x0c000005).w(FUNC(namcos23_state::c412_flags_w));
map(0x0c000006, 0x0c000007).r(FUNC(namcos23_state::c412_flags_r));
map(0x0c000010, 0x0c000011).rw(FUNC(namcos23_state::c412_addr_lsw_r), FUNC(namcos23_state::c412_addr_lsw_w));
@@ -5867,12 +6835,36 @@ u32 namcoss23_gmen_state::sh2_trigger_r()
u32 namcoss23_gmen_state::sh2_shared_r(offs_t offset, u32 mem_mask)
{
- return m_sh2_shared[offset];
+ const u32 data = m_sh2_shared[offset];
+ if ((offset << 2) == 0x20 && (mem_mask & 0xffff0000) == 0xffff0000 && (data & 0xffff0000) < 0x01000000)
+ {
+ logerror("%s: sh2_shared_r: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ }
+ return data;
}
void namcoss23_gmen_state::sh2_shared_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_sh2_shared[offset]);
+ if ((offset << 2) == 0x20 && (mem_mask & 0xffff0000) == 0xffff0000 && (data & 0xffff0000) == 0)
+ {
+ m_sh2->set_input_line(6, CLEAR_LINE);
+ }
+}
+
+u32 namcoss23_gmen_state::mips_to_sh2_shared_r(offs_t offset, u32 mem_mask)
+{
+ return m_sh2_shared[offset];
+}
+
+void namcoss23_gmen_state::mips_to_sh2_shared_w(offs_t offset, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_sh2_shared[offset]);
+ if ((offset << 2) == 0x20 && (mem_mask & 0xffff0000) == 0xffff0000 && (data & 0xffff0000) < 0x01000000)
+ {
+ logerror("%s: mips_to_sh2_shared_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_sh2->set_input_line(6, ASSERT_LINE);
+ }
}
u32 namcoss23_gmen_state::sh2_dsw_r(offs_t offset, u32 mem_mask)
@@ -5882,17 +6874,21 @@ u32 namcoss23_gmen_state::sh2_dsw_r(offs_t offset, u32 mem_mask)
u32 namcoss23_gmen_state::mips_sh2_unk_r(offs_t offset, u32 mem_mask)
{
- logerror("%s: mips_sh2_unk_r: %08x & %08x\n", machine().describe_context().c_str(), m_sh2_unk, mem_mask);
- return m_sh2_unk;
+ //logerror("%s: mips_sh2_unk_r: %08x & %08x\n", machine().describe_context().c_str(), 0x00000001, mem_mask);
+ return 0x00000001;
}
-u32 namcoss23_gmen_state::sh2_unk_r(offs_t offset, u32 mem_mask)
+u32 namcoss23_gmen_state::sh2_vpxstate_r(offs_t offset, u32 mem_mask)
{
- return 0;
+ //const u32 data = 0x01000000 | (m_odd_frame ? 0x00000100 : 0x00000000);
+ const u32 data = m_sh2_unk;//0x02000300;
+ //LOGMASKED(LOG_SH2_VPX, "%s: sh2_vpxstate_r: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ return data;
}
-void namcoss23_gmen_state::sh2_unk_w(offs_t offset, u32 data, u32 mem_mask)
+void namcoss23_gmen_state::sh2_vpxstate_w(offs_t offset, u32 data, u32 mem_mask)
{
+ //LOGMASKED(LOG_SH2_VPX, "%s: sh2_vpxstate_w: %08x & %08x\n", machine().describe_context(), data, mem_mask);
COMBINE_DATA(&m_sh2_unk);
}
@@ -5901,6 +6897,12 @@ u32 namcoss23_gmen_state::sh2_unk6200000_r(offs_t offset, u32 mem_mask)
return 0x04000000;
}
+u32 namcoss23_gmen_state::vpx_line_r(offs_t offset, u32 mem_mask)
+{
+ //return 0x7fff0000;
+ return rand();
+}
+
void namcoss23_gmen_state::vpx_i2c_sdao_w(int state)
{
m_vpx_sdao = state;
@@ -5908,41 +6910,38 @@ void namcoss23_gmen_state::vpx_i2c_sdao_w(int state)
u8 namcoss23_gmen_state::vpx_i2c_r()
{
- //LOGMASKED(LOG_GMEN, "%s: vpx_i2c_r: %02x\n", machine().describe_context().c_str(), m_vpx_sdao);
+ LOGMASKED(LOG_GMEN, "%s: vpx_i2c_r: %02x\n", machine().describe_context().c_str(), m_vpx_sdao);
return m_vpx_sdao;
}
void namcoss23_gmen_state::vpx_i2c_w(u8 data)
{
- //LOGMASKED(LOG_GMEN, "%s: vpx_i2c_w: %02x\n", machine().describe_context().c_str(), data);
+ LOGMASKED(LOG_GMEN, "%s: vpx_i2c_w: %02x\n", machine().describe_context().c_str(), data);
m_vpx->sda_write(BIT(data, 0));
m_vpx->scl_write(BIT(data, 1));
}
-u32 namcoss23_gmen_state::sh2_kludge_r()
-{
- return 0x22115566;
-}
-
void namcoss23_gmen_state::mips_map(address_map &map)
{
namcoss23_state::mips_map(map);
map(0x0e400000, 0x0e400003).r(FUNC(namcoss23_gmen_state::sh2_trigger_r));
map(0x0e600000, 0x0e600003).r(FUNC(namcoss23_gmen_state::mips_sh2_unk_r));
- map(0x0e700000, 0x0e70ffff).rw(FUNC(namcoss23_gmen_state::sh2_shared_r), FUNC(namcoss23_gmen_state::sh2_shared_w));
- map(0x0e70c000, 0x0e70c003).r(FUNC(namcoss23_gmen_state::sh2_kludge_r));
+ map(0x0e700000, 0x0e70ffff).rw(FUNC(namcoss23_gmen_state::mips_to_sh2_shared_r), FUNC(namcoss23_gmen_state::mips_to_sh2_shared_w));
}
void namcoss23_gmen_state::sh2_map(address_map &map)
{
map(0x00000000, 0x0000ffff).mirror(0x01000000).rw(FUNC(namcoss23_gmen_state::sh2_shared_r), FUNC(namcoss23_gmen_state::sh2_shared_w));
- map(0x04000000, 0x043fffff).ram(); // SH-2 main work RAM (SDRAM)
+ map(0x01400000, 0x014003ff).r(FUNC(namcoss23_gmen_state::vpx_line_r));
map(0x01800000, 0x01bfffff).ram();
- map(0x02800000, 0x02800003).rw(FUNC(namcoss23_gmen_state::sh2_unk_r), FUNC(namcoss23_gmen_state::sh2_unk_w));
+ map(0x02800000, 0x02800003).rw(FUNC(namcoss23_gmen_state::sh2_vpxstate_r), FUNC(namcoss23_gmen_state::sh2_vpxstate_w));
map(0x03000000, 0x03000003).r(FUNC(namcoss23_gmen_state::sh2_dsw_r));
+ map(0x04000000, 0x043fffff).ram(); // SH-2 main work RAM (SDRAM)
map(0x06000000, 0x06000003).umask32(0xff000000).rw(FUNC(namcoss23_gmen_state::vpx_i2c_r), FUNC(namcoss23_gmen_state::vpx_i2c_w));
map(0x06200000, 0x06200003).r(FUNC(namcoss23_gmen_state::sh2_unk6200000_r));
- //map(0x06600000, 0x06600003).nopw();
+ map(0x06200000, 0x06200003).nopw();
+ map(0x06600000, 0x06600003).nopw();
+ map(0x06a00000, 0x06a00003).nopw();
map(0x00c00000, 0x00c0006b).m(m_firewire, FUNC(md8412b_device::map));
}
@@ -6191,6 +7190,8 @@ void namcos23_state::machine_start()
save_item(NAME(m_c417.pointrom_adr));
save_item(NAME(m_c417.test_mode));
+ save_item(NAME(m_c412.unk0));
+ save_item(NAME(m_c412.unk1));
save_item(NAME(m_c412.sdram_a));
save_item(NAME(m_c412.sdram_b));
save_item(NAME(m_c412.sram));
@@ -6208,6 +7209,7 @@ void namcos23_state::machine_start()
save_item(NAME(m_jvs_sense));
save_item(NAME(m_main_irqcause));
+ save_item(NAME(m_odd_frame));
save_item(NAME(m_ctl_vbl_active));
save_item(NAME(m_ctl_led));
save_item(NAME(m_ctl_inp_buffer));
@@ -6236,8 +7238,8 @@ void namcos23_state::machine_start()
save_item(NAME(m_tx));
save_item(NAME(m_ty));
save_item(NAME(m_model_blend_factor));
- save_item(NAME(m_camera_power));
- save_item(NAME(m_camera_ambient));
+ save_item(NAME(m_light_power));
+ save_item(NAME(m_light_ambient));
save_item(NAME(m_matrices));
save_item(NAME(m_vectors));
save_item(NAME(m_light_vector));
@@ -6307,8 +7309,8 @@ void namcos23_state::machine_reset()
m_tx = 0;
m_ty = 0;
m_model_blend_factor = 0x4000;
- m_camera_power = 0;
- m_camera_ambient = 0;
+ m_light_power = 0;
+ m_light_ambient = 0;
memset(m_proj_matrix, 0, sizeof(m_proj_matrix));
m_proj_matrix_line = 0;
@@ -6338,6 +7340,7 @@ void namcos23_state::machine_reset()
m_jvs_sense = 1;
m_main_irqcause = 0;
+ m_odd_frame = false;
m_ctl_vbl_active = false;
m_ctl_led = 0;
m_ctl_inp_buffer[0] = m_ctl_inp_buffer[1] = 0;
@@ -6361,7 +7364,6 @@ void namcoss23_gmen_state::machine_start()
{
namcos23_state::machine_start();
- m_sh2_irq_timer = timer_alloc(FUNC(namcoss23_gmen_state::sh2_irq_off), this);
save_item(NAME(m_vpx_sdao));
}
@@ -6371,19 +7373,11 @@ void namcoss23_gmen_state::machine_reset()
// halt the SH-2 until we need it
m_sh2->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_sh2_irq_timer->adjust(attotime::never);
- m_sh2_irq = -1;
m_sh2_unk = 0;
m_vpx_sdao = 0;
}
-TIMER_CALLBACK_MEMBER(namcoss23_gmen_state::sh2_irq_off)
-{
- m_sh2->set_input_line(m_sh2_irq, CLEAR_LINE);
- m_sh2_irq = -1;
-}
-
#define XOR(a) WORD2_XOR_BE(a)
@@ -6626,13 +7620,15 @@ void namcoss23_gmen_state::gmen(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &namcoss23_gmen_state::mips_map);
- SH7604(config, m_sh2, XTAL(28'700'000));
+ SH7604(config, m_sh2, XTAL(20'000'000));
m_sh2->set_addrmap(AS_PROGRAM, &namcoss23_gmen_state::sh2_map);
VPX3220A(config, m_vpx, 0);
m_vpx->sda_callback().set(FUNC(namcoss23_gmen_state::vpx_i2c_sdao_w));
+ m_vpx->vref_callback().set_inputline(m_sh2, 4);
MD8412B(config, m_firewire, 0);
+ m_firewire->int_callback().set_inputline(m_sh2, 8);
}
void namcoss23_gmen_state::gunwars(machine_config &config)
@@ -6829,28 +7825,28 @@ static INPUT_PORTS_START(gmen)
PORT_INCLUDE(s23)
PORT_START("GMENDSW")
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x01, 0x01, "SH-2 DIP Bit 0" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x02, 0x02, "SH-2 DIP Bit 1" )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x04, 0x04, "SH-2 DIP Bit 2" )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x08, 0x08, "SH-2 DIP Bit 3" )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x10, 0x10, "SH-2 DIP Bit 4" )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x20, 0x20, "SH-2 DIP Bit 5" )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x40, 0x40, "SH-2 DIP Bit 6" )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x80, 0x80, "SH-2 DIP Bit 7" )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
diff --git a/src/mame/namco/vpx3220a.cpp b/src/mame/namco/vpx3220a.cpp
index 81d4ee8132a..2b2aaf8b21e 100644
--- a/src/mame/namco/vpx3220a.cpp
+++ b/src/mame/namco/vpx3220a.cpp
@@ -78,48 +78,55 @@ enum vpx3220a_device::fpaddr_t : u16
};
vpx3220a_device::vpx3220a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, VPX3220A, tag, owner, clock)
- , i2c_hle_interface(mconfig, *this, 0x43)
- , m_ifc(0)
- , m_afend(0)
- , m_unk_34(0)
- , m_unk_3a(0)
- , m_refsig(0)
- , m_ymax(0)
- , m_ymin(0)
- , m_umax(0)
- , m_umin(0)
- , m_vmax(0)
- , m_vmin(0)
- , m_cbm_bri(0)
- , m_cbm_con(0)
- , m_format(0)
- , m_misc(0)
- , m_ofifo(0)
- , m_omux(0)
- , m_oena(0)
- , m_driver_a(0)
- , m_driver_b(0)
- , m_fpaddr(0)
- , m_fpsta(0)
- , m_fp_lsb(false)
- , m_fp_tint(0)
- , m_fp_gain(0)
- , m_fp_xlg(0)
- , m_fp_hpll(0)
- , m_fp_dvco(0)
- , m_fp_adjust(0)
- , m_fp_accref(0)
- , m_fp_accr(0)
- , m_fp_accb(0)
- , m_fp_kilvl(0)
- , m_fp_agcref(0)
- , m_fp_sgain(0)
- , m_fp_vsdt(0)
- , m_fp_cmdwd(0)
- , m_fp_infowd(0)
- , m_fp_tvstndwr(0)
- , m_fp_tvstndrd(0)
+ : device_t(mconfig, VPX3220A, tag, owner, clock),
+ i2c_hle_interface(mconfig, *this, 0x43),
+ m_href_cb(*this),
+ m_vref_cb(*this),
+ m_href_timer(nullptr),
+ m_vref_timer(nullptr),
+ m_href(0),
+ m_vref(0),
+ m_ifc(0),
+ m_afend(0),
+ m_unk_34(0),
+ m_unk_3a(0),
+ m_refsig(0),
+ m_ymax(0),
+ m_ymin(0),
+ m_umax(0),
+ m_umin(0),
+ m_vmax(0),
+ m_vmin(0),
+ m_cbm_bri(0),
+ m_cbm_con(0),
+ m_format(0),
+ m_misc(0),
+ m_ofifo(0),
+ m_omux(0),
+ m_oena(0),
+ m_driver_a(0),
+ m_driver_b(0),
+ m_fpdata(0),
+ m_fpaddr(0),
+ m_fpsta(0),
+ m_want_fp_lsb(false),
+ m_accessing_fp(false),
+ m_want_fp_data_lsb(false),
+ m_fp_tint(0),
+ m_fp_gain(0),
+ m_fp_xlg(0),
+ m_fp_hpll(0),
+ m_fp_dvco(0),
+ m_fp_adjust(0),
+ m_fp_accref(0),
+ m_fp_accr(0),
+ m_fp_accb(0),
+ m_fp_kilvl(0),
+ m_fp_agcref(0),
+ m_fp_sgain(0),
+ m_fp_vsdt(0),
+ m_fp_cmdwd(0),
+ m_fp_tvstndwr(0)
{
memset(m_fp_vbeg, 0, sizeof(m_fp_vbeg));
memset(m_fp_vlinei, 0, sizeof(m_fp_vlinei));
@@ -131,6 +138,9 @@ vpx3220a_device::vpx3220a_device(const machine_config &mconfig, const char *tag,
void vpx3220a_device::device_start()
{
+ save_item(NAME(m_href));
+ save_item(NAME(m_vref));
+
save_item(NAME(m_ifc));
save_item(NAME(m_afend));
save_item(NAME(m_unk_34));
@@ -152,9 +162,12 @@ void vpx3220a_device::device_start()
save_item(NAME(m_driver_a));
save_item(NAME(m_driver_b));
+ save_item(NAME(m_fpdata));
save_item(NAME(m_fpaddr));
save_item(NAME(m_fpsta));
- save_item(NAME(m_fp_lsb));
+ save_item(NAME(m_want_fp_lsb));
+ save_item(NAME(m_accessing_fp));
+ save_item(NAME(m_want_fp_data_lsb));
save_item(NAME(m_fp_tint));
save_item(NAME(m_fp_gain));
@@ -176,13 +189,16 @@ void vpx3220a_device::device_start()
save_item(NAME(m_fp_sgain));
save_item(NAME(m_fp_vsdt));
save_item(NAME(m_fp_cmdwd));
- save_item(NAME(m_fp_infowd));
save_item(NAME(m_fp_tvstndwr));
- save_item(NAME(m_fp_tvstndrd));
+
+ m_href_timer = timer_alloc(FUNC(vpx3220a_device::href_tick), this);
+ m_vref_timer = timer_alloc(FUNC(vpx3220a_device::vref_tick), this);
}
void vpx3220a_device::device_reset()
{
+ m_href = 0;
+ m_vref = 0;
m_ifc = 0x03;
m_afend = 0x0d;
m_unk_34 = 0x00;
@@ -203,9 +219,13 @@ void vpx3220a_device::device_reset()
m_oena = 0x00;
m_driver_a = 0x12;
m_driver_b = 0x24;
+
+ m_fpdata = 0;
m_fpaddr = 0;
m_fpsta = 0;
- m_fp_lsb = false;
+ m_want_fp_lsb = false;
+ m_accessing_fp = false;
+ m_want_fp_data_lsb = false;
m_fp_tint = 0;
m_fp_gain = 0;
@@ -233,13 +253,36 @@ void vpx3220a_device::device_reset()
m_fp_sgain = 27;
m_fp_vsdt = 523;
m_fp_cmdwd = 114;
- m_fp_infowd = 0;
m_fp_tvstndwr = 979;
- m_fp_tvstndrd = 0;
+
+ m_href_timer->adjust(attotime::never);
+ m_vref_timer->adjust(attotime::never);
+}
+
+TIMER_CALLBACK_MEMBER(vpx3220a_device::href_tick)
+{
+ m_href = !m_href;
+ m_href_cb(m_href);
+ m_href_timer->adjust(m_href ? attotime::from_usec(52) : (attotime::from_hz(15734) - attotime::from_usec(52)), 0);
+}
+
+TIMER_CALLBACK_MEMBER(vpx3220a_device::vref_tick)
+{
+ m_vref = !m_vref;
+ m_vref_cb(m_vref);
+ m_vref_timer->adjust(attotime::from_hz(15734) * (m_vref ? 45 : 480), 0);
}
u8 vpx3220a_device::read_data(u16 offset)
{
+ if (m_want_fp_data_lsb)
+ {
+ LOG("%s: Fast Processor Data Read (LSB): %02x\n", machine().describe_context(), (u8)m_fpdata);
+ m_accessing_fp = false;
+ m_want_fp_data_lsb = false;
+ return (u8)m_fpdata;
+ }
+
switch (offset)
{
case FORMAT:
@@ -247,63 +290,13 @@ u8 vpx3220a_device::read_data(u16 offset)
return m_format;
case FPDAT:
- switch (m_fpaddr)
+ if (!m_want_fp_data_lsb)
{
- default:
- LOG("%s: Unknown Fast Processor Register Read: %04x\n", machine().describe_context(), m_fpaddr);
- return 0;
-
- case TVSTNDWR: {
- static char const *const STANDARD_NAMES[8] =
- {
- "PAL B/G/H/I",
- "NTSC M",
- "SECAM",
- "NTSC 44",
- "PAL M",
- "PAL N",
- "PAL 60",
- "NTSC Comb"
- };
- LOG("%s: TV Standard (Write) Read: %04x\n", machine().describe_context(), m_fp_tvstndwr);
- LOG("%s: Manual/Automatic: %s\n", machine().describe_context(), BIT(m_fp_tvstndwr, 0) ? "Manual" : "Automatic");
- LOG("%s: TV Standard for Manual Selection: %s\n", machine().describe_context(), STANDARD_NAMES[BIT(m_fp_tvstndwr, 1, 3)]);
- LOG("%s: Manual TV Standard Latch: %d\n", machine().describe_context(), BIT(m_fp_tvstndwr, 4));
- LOG("%s: Composite/S-VHS Select: %s\n", machine().describe_context(), BIT(m_fp_tvstndwr, 5) ? "S-HVS" : "Composite");
- LOG("%s: Search-Result Threshold: %d\n", machine().describe_context(), BIT(m_fp_tvstndwr, 6, 4));
- return m_fp_tvstndwr;
- } break;
- /*case TINT:
- case GAIN:
- case XLG:
- case HPLL:
- case DVCO:
- case ADJUST:
- case VBEG1:
- case VLINEI1:
- case VLINEO1:
- case HBEG1:
- case HLEN1:
- case NPIX1:
- case VBEG2:
- case VLINEI2:
- case VLINEO2:
- case HBEG2:
- case HLEN2:
- case NPIX2:
- case ACCREF:
- case ACCR:
- case ACCB:
- case KILVL:
- case AGCREF:
- case SGAIN:
- case VSDT:
- case CMDWD:
- case INFOWD:
- case TVSTNDWR:
- case TVSTNDRD:*/
+ LOG("%s: Fast Processor Data Read (MSB): %02x\n", machine().describe_context(), m_fpdata >> 8);
+ m_want_fp_data_lsb = true;
+ return (u8)(m_fpdata >> 8);
}
- break;
+ return 0;
case FPSTA:
return m_fpsta;
@@ -316,6 +309,51 @@ u8 vpx3220a_device::read_data(u16 offset)
void vpx3220a_device::write_data(u16 offset, u8 data)
{
+ if (m_want_fp_lsb)
+ {
+ m_fpaddr <<= 8;
+ m_fpaddr |= data;
+ if (BIT(m_fpsta, 0))
+ {
+ LOG("%s: Write Fast Processor Register Write Address (LSB): %02x\n", machine().describe_context(), data);
+ }
+ else if (BIT(m_fpsta, 1))
+ {
+ LOG("%s: Write Fast Processor Register Read Address (LSB): %02x\n", machine().describe_context(), data);
+ m_fpdata = get_fp_reg();
+ }
+ m_want_fp_lsb = false;
+ m_accessing_fp = true;
+ m_want_fp_data_lsb = false;
+ return;
+ }
+
+ if (m_accessing_fp)
+ {
+ if (!m_want_fp_data_lsb)
+ {
+ if (BIT(m_fpsta, 0))
+ {
+ LOG("%s: Write Fast Processor Data MSB: %02x\n", machine().describe_context(), data);
+ m_fpdata <<= 8;
+ m_fpdata |= data;
+ }
+ m_want_fp_data_lsb = true;
+ }
+ else
+ {
+ if (BIT(m_fpsta, 0))
+ {
+ m_fpdata <<= 8;
+ m_fpdata |= data;
+ set_fp_reg();
+ }
+ m_accessing_fp = false;
+ m_want_fp_data_lsb = false;
+ }
+ return;
+ }
+
switch (offset)
{
case IFC: {
@@ -325,19 +363,19 @@ void vpx3220a_device::write_data(u16 offset, u8 data)
} break;
case FPRD:
- LOG("%s: Write Fast Processor Register Read: %02x\n", machine().describe_context(), data);
+ LOG("%s: Write Fast Processor Register Read Address (MSB): %02x\n", machine().describe_context(), data);
m_fpaddr <<= 8;
m_fpaddr |= data;
m_fpsta = (1 << 1);
- m_fp_lsb = !m_fp_lsb;
+ m_want_fp_lsb = true;
break;
case FPWR:
- LOG("%s: Write Fast Processor Register Write: %02x\n", machine().describe_context(), data);
+ LOG("%s: Write Fast Processor Register Write Address (MSB): %02x\n", machine().describe_context(), data);
m_fpaddr <<= 8;
m_fpaddr |= data;
m_fpsta = (1 << 0);
- m_fp_lsb = !m_fp_lsb;
+ m_want_fp_lsb = true;
break;
case AFEND: {
@@ -485,7 +523,296 @@ void vpx3220a_device::write_data(u16 offset, u8 data)
break;
default:
- LOG("%s: Write Unknown Sub-Address: %02x\n", machine().describe_context(), data);
+ LOG("%s: Write Unknown Sub-Address: %02x = %02x\n", machine().describe_context(), offset, data);
+ break;
+ }
+}
+
+u16 vpx3220a_device::get_fp_reg()
+{
+ switch (m_fpaddr)
+ {
+ default:
+ LOG("%s: Unknown Fast Processor Register Read: %04x\n", machine().describe_context(), m_fpaddr);
+ return 0;
+ case TINT:
+ {
+ static const float VAL2DEG = (1.f / 1024.f) * (180.f / 3.14159265f);
+ LOG("%s: NTSC Tint Angle Read: %04x (%d)\n", machine().describe_context(), m_fp_tint, (int)(m_fp_tint * VAL2DEG));
+ return m_fp_tint;
+ }
+ case GAIN:
+ LOG("%s: AGC Gain Value Read: %04x\n", machine().describe_context(), m_fp_sgain);
+ return m_fp_sgain;
+ case XLG:
+ {
+ const u16 data = (m_fp_xlg == 100) ? 0x0fff : 0x0000;
+ LOG("%s: Line-Locked Mode Status Read: %04x\n", machine().describe_context(), data);
+ return data;
+ }
+ case HPLL:
+ LOG("%s: Horizontal PLL Gain Read: %04x\n", machine().describe_context(), m_fp_hpll);
+ LOG("%s: Integrating Gain: %02x\n", machine().describe_context(), BIT(m_fp_hpll, 0, 5));
+ LOG("%s: Proportional Gain: %02x\n", machine().describe_context(), BIT(m_fp_hpll, 5, 5));
+ return m_fp_hpll;
+ case DVCO:
+ LOG("%s: Oscillator Frequency Center Adjust Read: %04x\n", machine().describe_context(), m_fp_dvco);
+ return m_fp_dvco;
+ case ADJUST:
+ LOG("%s: Oscillator Frequency Center Auto-Adjustment Read: %04x\n", machine().describe_context(), m_fp_dvco);
+ return m_fp_dvco;
+ case VBEG1:
+ LOG("%s: Window #1 Vertical Begin Read: %04x\n", machine().describe_context(), m_fp_vbeg[0]);
+ LOG("%s: Field Line Number: %d\n", machine().describe_context(), BIT(m_fp_vbeg[0], 0, 9));
+ LOG("%s: Sharpness Control: %d%d%d\n", machine().describe_context(), BIT(m_fp_vbeg[0], 11), BIT(m_fp_vbeg[0], 10), BIT(m_fp_vbeg[0], 9));
+ return m_fp_vbeg[0];
+ case VLINEI1:
+ {
+ static const char *const FIELD_NAMES[4] = { "Window Disabled", "Window Odd Only", "Window Even Only", "Window Both" };
+ LOG("%s: Window #1 Vertical Lines In Read: %04x\n", machine().describe_context(), m_fp_vlinei[0]);
+ LOG("%s: Number of Input Lines: %d\n", machine().describe_context(), BIT(m_fp_vlinei[0], 0, 9));
+ LOG("%s: Field Flag: %s\n", machine().describe_context(), FIELD_NAMES[BIT(m_fp_vlinei[0], 10, 2)]);
+ return m_fp_vlinei[0];
+ }
+ case VLINEO1:
+ LOG("%s: Window #1 Vertical Lines Out Read: %04x (%d)\n", machine().describe_context(), m_fp_vlineo[0], BIT(m_fp_vlineo[0], 0, 9));
+ return m_fp_vlineo[0];
+ case HBEG1:
+ LOG("%s: Window #1 Horizontal Window Start Read: %04x (%d)\n", machine().describe_context(), m_fp_hbeg[0], BIT(m_fp_hbeg[0], 0, 11));
+ return m_fp_hbeg[0];
+ case HLEN1:
+ LOG("%s: Window #1 Horizontal Window Length Read: %04x (%d)\n", machine().describe_context(), m_fp_hlen[0], BIT(m_fp_hlen[0], 0, 11));
+ return m_fp_hlen[0];
+ case NPIX1:
+ LOG("%s: Window #1 Active Pixels Per Line Read: %04x (%d)\n", machine().describe_context(), m_fp_npix[0], BIT(m_fp_npix[0], 0, 11));
+ return m_fp_npix[0];
+ case VBEG2:
+ LOG("%s: Window #2 Vertical Begin Read: %04x\n", machine().describe_context(), m_fp_vbeg[1]);
+ LOG("%s: Field Line Number: %d\n", machine().describe_context(), BIT(m_fp_vbeg[1], 0, 9));
+ LOG("%s: Sharpness Control: %d%d%d\n", machine().describe_context(), BIT(m_fp_vbeg[1], 11), BIT(m_fp_vbeg[1], 10), BIT(m_fp_vbeg[1], 9));
+ return m_fp_vbeg[1];
+ case VLINEI2:
+ {
+ static const char *const FIELD_NAMES[4] = { "Window Disabled", "Window Odd Only", "Window Even Only", "Window Both" };
+ LOG("%s: Window #2 Vertical Lines In Read: %04x\n", machine().describe_context(), m_fp_vlinei[1]);
+ LOG("%s: Number of Input Lines: %d\n", machine().describe_context(), BIT(m_fp_vlinei[1], 0, 9));
+ LOG("%s: Field Flag: %s\n", machine().describe_context(), FIELD_NAMES[BIT(m_fp_vlinei[1], 10, 2)]);
+ return m_fp_vlinei[1];
+ }
+ case VLINEO2:
+ LOG("%s: Window #2 Vertical Lines Out Read: %04x (%d)\n", machine().describe_context(), m_fp_vlineo[1], BIT(m_fp_vlineo[1], 0, 9));
+ return m_fp_vlineo[1];
+ case HBEG2:
+ LOG("%s: Window #2 Horizontal Window Start Read: %04x (%d)\n", machine().describe_context(), m_fp_hbeg[1], BIT(m_fp_hbeg[1], 0, 11));
+ return m_fp_hbeg[1];
+ case HLEN2:
+ LOG("%s: Window #2 Horizontal Window Length Read: %04x (%d)\n", machine().describe_context(), m_fp_hlen[1], BIT(m_fp_hlen[1], 0, 11));
+ return m_fp_hlen[1];
+ case NPIX2:
+ LOG("%s: Window #2 Active Pixels Per Line Read: %04x (%d)\n", machine().describe_context(), m_fp_npix[1], BIT(m_fp_npix[1], 0, 11));
+ return m_fp_npix[1];
+ case ACCREF:
+ LOG("%s: ACC Reference/Saturation Control Write: %04x\n", machine().describe_context(), m_fp_accref);
+ return m_fp_accref;
+ case ACCR:
+ LOG("%s: ACC Multiplier for SECAM Dr Adjust Read: %04x\n", machine().describe_context(), m_fp_accr);
+ return m_fp_accr;
+ case ACCB:
+ LOG("%s: ACC Multiplier for SECAM Db Adjust Read: %04x\n", machine().describe_context(), m_fp_accb);
+ return m_fp_accb;
+ case KILVL:
+ LOG("%s: Amplitude Color Killer Level Read: %04x\n", machine().describe_context(), m_fp_kilvl);
+ return m_fp_kilvl;
+ case AGCREF:
+ LOG("%s: AGC Sync Amplitude Reference Read: %04x\n", machine().describe_context(), m_fp_agcref);
+ return m_fp_agcref;
+ case SGAIN:
+ LOG("%s: AGC Start Value for Vertical Lock Read: %04x\n", machine().describe_context(), m_fp_sgain);
+ return m_fp_sgain;
+ case VSDT:
+ LOG("%s: Vertical Locking Standard Read: %04x\n", machine().describe_context(), m_fp_vsdt);
+ LOG("%s: Vertical Standard Lock Enable: %d\n", machine().describe_context(), BIT(m_fp_vsdt, 0));
+ LOG("%s: Expected Lines Per Field: %d\n", machine().describe_context(), BIT(m_fp_vsdt, 1, 11));
+ return m_fp_vsdt;
+ case CMDWD:
+ LOG("%s: Control/Latching Register Read: %04x\n", machine().describe_context(), m_fp_cmdwd & 0x100);
+ return m_fp_cmdwd & 0x100;
+ case INFOWD:
+ LOG("%s: Internal Info Word Read: %04x\n", machine().describe_context(), 0x038);
+ LOG("%s: TV Standard: NTSC Comb\n", machine().describe_context());
+ LOG("%s: Line Standard: 525/60\n", machine().describe_context());
+ return 0x038;
+ case TVSTNDRD:
+ LOG("%s: TV Standard Read: %04x\n", machine().describe_context(), 0x7de);
+ LOG("%s: VACT Suppress: Enabled\n", machine().describe_context());
+ LOG("%s: Recognition Routine: Running\n", machine().describe_context());
+ LOG("%s: TV Standard: NTSC Comb\n", machine().describe_context());
+ LOG("%s: Video: Present\n", machine().describe_context());
+ LOG("%s: Video Recognition Confidence: Maximum\n", machine().describe_context());
+ LOG("%s: Line Standard: 525/60\n", machine().describe_context());
+ return 0x7de;
+ }
+}
+
+void vpx3220a_device::set_fp_reg()
+{
+ switch (m_fpaddr)
+ {
+ case TINT:
+ {
+ static const float VAL2DEG = (1.f / 1024.f) * (180.f / 3.14159265f);
+ LOG("%s: NTSC Tint Angle Write: %04x (%d)\n", machine().describe_context(), m_fpdata, (int)(m_fpdata * VAL2DEG));
+ m_fp_tint = m_fpdata;
+ break;
+ }
+ case GAIN:
+ LOG("%s: AGC Gain Value Write (Read-Only): %04x\n", machine().describe_context(), m_fpdata);
+ break;
+ case XLG:
+ LOG("%s: Line-Locked Mode Command Write: %04x (%s Lock)\n", machine().describe_context(), m_fpdata, m_fpdata == 100 ? "Enable" : "Disable");
+ m_fp_xlg = m_fpdata;
+ break;
+ case HPLL:
+ LOG("%s: Horizontal PLL Gain Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Integrating Gain: %02x\n", machine().describe_context(), BIT(m_fpdata, 0, 5));
+ LOG("%s: Proportional Gain: %02x\n", machine().describe_context(), BIT(m_fpdata, 5, 5));
+ m_fp_hpll = m_fpdata;
+ break;
+ case DVCO:
+ LOG("%s: Oscillator Frequency Center Adjust Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_dvco = m_fpdata;
+ break;
+ case ADJUST:
+ LOG("%s: Oscillator Frequency Center Adjust for Line-Locked Write (Read-Only): %04x\n", machine().describe_context(), m_fpdata);
+ break;
+ case VBEG1:
+ LOG("%s: Window #1 Vertical Begin Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Field Line Number: %d\n", machine().describe_context(), BIT(m_fpdata, 0, 9));
+ LOG("%s: Sharpness Control: %d%d%d\n", machine().describe_context(), BIT(m_fpdata, 11), BIT(m_fpdata, 10), BIT(m_fpdata, 9));
+ m_fp_vbeg[0] = m_fpdata;
+ break;
+ case VLINEI1:
+ {
+ static const char *const FIELD_NAMES[4] = { "Window Disabled", "Window Odd Only", "Window Even Only", "Window Both" };
+ LOG("%s: Window #1 Vertical Lines In Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Number of Input Lines: %d\n", machine().describe_context(), BIT(m_fpdata, 0, 9));
+ LOG("%s: Field Flag: %s\n", machine().describe_context(), FIELD_NAMES[BIT(m_fpdata, 10, 2)]);
+ m_fp_vlinei[0] = m_fpdata;
+ break;
+ }
+ case VLINEO1:
+ LOG("%s: Window #1 Vertical Lines Out Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 9));
+ m_fp_vlineo[0] = m_fpdata;
+ break;
+ case HBEG1:
+ LOG("%s: Window #1 Horizontal Window Start Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_hbeg[0] = m_fpdata;
+ break;
+ case HLEN1:
+ LOG("%s: Window #1 Horizontal Window Length Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_hlen[0] = m_fpdata;
+ break;
+ case NPIX1:
+ LOG("%s: Window #1 Active Pixels Per Line Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_npix[0] = m_fpdata;
+ break;
+ case VBEG2:
+ LOG("%s: Window #2 Vertical Begin Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Field Line Number: %d\n", machine().describe_context(), BIT(m_fpdata, 0, 9));
+ LOG("%s: Sharpness Control: %d%d%d\n", machine().describe_context(), BIT(m_fpdata, 11), BIT(m_fpdata, 10), BIT(m_fpdata, 9));
+ m_fp_vbeg[1] = m_fpdata;
+ break;
+ case VLINEI2: {
+ static const char *const FIELD_NAMES[4] = { "Window Disabled", "Window Odd Only", "Window Even Only", "Window Both" };
+ LOG("%s: Window #2 Vertical Lines In Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Number of Input Lines: %d\n", machine().describe_context(), BIT(m_fpdata, 0, 9));
+ LOG("%s: Field Flag: %s\n", machine().describe_context(), FIELD_NAMES[BIT(m_fpdata, 10, 2)]);
+ m_fp_vlinei[1] = m_fpdata;
+ } break;
+ case VLINEO2:
+ LOG("%s: Window #2 Vertical Lines Out Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 9));
+ m_fp_vlineo[1] = m_fpdata;
+ break;
+ case HBEG2:
+ LOG("%s: Window #2 Horizontal Window Start Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_hbeg[1] = m_fpdata;
+ break;
+ case HLEN2:
+ LOG("%s: Window #2 Horizontal Window Length Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_hlen[1] = m_fpdata;
+ break;
+ case NPIX2:
+ LOG("%s: Window #2 Active Pixels Per Line Write: %04x (%d)\n", machine().describe_context(), m_fpdata, BIT(m_fpdata, 0, 11));
+ m_fp_npix[1] = m_fpdata;
+ break;
+ case ACCREF:
+ LOG("%s: ACC Reference/Saturation Control Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_accref = m_fpdata;
+ break;
+ case ACCR:
+ LOG("%s: ACC Multiplier for SECAM Dr Adjust Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_accr = m_fpdata;
+ break;
+ case ACCB:
+ LOG("%s: ACC Multiplier for SECAM Db Adjust Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_accb = m_fpdata;
+ break;
+ case KILVL:
+ LOG("%s: Amplitude Color Killer Level Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_kilvl = m_fpdata;
+ break;
+ case AGCREF:
+ LOG("%s: AGC Sync Amplitude Reference Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_agcref = m_fpdata;
+ break;
+ case SGAIN:
+ LOG("%s: AGC Start Value for Vertical Lock Write: %04x\n", machine().describe_context(), m_fpdata);
+ m_fp_sgain = m_fpdata;
+ break;
+ case VSDT:
+ LOG("%s: Vertical Locking Standard Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Vertical Standard Lock Enable: %d\n", machine().describe_context(), BIT(m_fpdata, 0));
+ LOG("%s: Expected Lines Per Field: %d\n", machine().describe_context(), BIT(m_fpdata, 1, 11));
+ m_fp_vsdt = m_fpdata;
+ break;
+ case CMDWD: {
+ static const char *const SYNC_TIMING_NAMES[4] = { "Open", "Forced", "Scan [2]", "Scan [3]" };
+ LOG("%s: Control/Latching Register Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Transport Rate: %s\n", machine().describe_context(), BIT(m_fpdata, 0) ? "13.5 MHz" : "20.25 MHz");
+ LOG("%s: Latch Transport Rate: %d\n", machine().describe_context(), BIT(m_fpdata, 1));
+ LOG("%s: Sync Timing Mode: %s\n", machine().describe_context(), SYNC_TIMING_NAMES[BIT(m_fpdata, 2, 2)]);
+ LOG("%s: Latch Timing Mode: %d\n", machine().describe_context(), BIT(m_fpdata, 4));
+ LOG("%s: Latch Window #1: %d\n", machine().describe_context(), BIT(m_fpdata, 5));
+ LOG("%s: Latch Window #2: %d\n", machine().describe_context(), BIT(m_fpdata, 6));
+ LOG("%s: Odd/Even Mode: %s\n", machine().describe_context(), BIT(m_fpdata, 8) ? "Follow Input" : "Always Toggle");
+ const u32 old_cmdwd = m_fp_cmdwd;
+ m_fp_cmdwd = m_fpdata & 0x018e;
+ if (BIT(old_cmdwd, 2, 2) == 0 && BIT(m_fp_cmdwd, 2, 2) != 0)
+ {
+ m_href_timer->adjust(attotime::never);
+ m_vref_timer->adjust(attotime::never);
+ }
+ else if (BIT(m_fp_cmdwd, 2, 2) == 0 && (BIT(old_cmdwd, 2, 2) != 0 || m_href_timer->remaining() == attotime::never || m_vref_timer->remaining() == attotime::never))
+ {
+ m_href_timer->adjust(attotime::from_hz(15734) - attotime::from_usec(52), 0);
+ m_vref_timer->adjust(attotime::from_hz(15734) * 480, 0);
+ }
+ } break;
+ case INFOWD:
+ LOG("%s: Info Word Write (Read-Only): %04x\n", machine().describe_context(), m_fpdata);
+ break;
+ case TVSTNDWR:
+ static const char *const STANDARD_NAMES[8] = { "PAL B,G,H,I", "NTSC M", "SECAM", "NTSC 44", "PAL M", "PAL N", "PAL 60", "NTSC Comb" };
+ LOG("%s: TV Standard Write: %04x\n", machine().describe_context(), m_fpdata);
+ LOG("%s: Selection Mode: %s\n", machine().describe_context(), BIT(m_fpdata, 0) ? "Manual" : "Automatic");
+ LOG("%s: TV Standard: %s\n", machine().describe_context(), STANDARD_NAMES[BIT(m_fpdata, 1, 3)]);
+ LOG("%s: Latch Standard: %d\n", machine().describe_context(), BIT(m_fpdata, 4));
+ LOG("%s: Mode Select: %d\n", machine().describe_context(), BIT(m_fpdata, 5) ? "S-VHS" : "Composite");
+ LOG("%s: Search Threshold: %d%d%d%d\n", machine().describe_context(), BIT(m_fpdata, 9), BIT(m_fpdata, 8), BIT(m_fpdata, 7), BIT(m_fpdata, 6));
+ m_fp_tvstndwr = m_fpdata & 0x03ef;
+ break;
+ case TVSTNDRD:
+ LOG("%s: TV Standard Info Write (Read-Only): %04x\n", machine().describe_context(), m_fpdata);
break;
}
}
diff --git a/src/mame/namco/vpx3220a.h b/src/mame/namco/vpx3220a.h
index 3132aa1530e..4a1b090ca27 100644
--- a/src/mame/namco/vpx3220a.h
+++ b/src/mame/namco/vpx3220a.h
@@ -20,6 +20,9 @@ class vpx3220a_device : public device_t, public i2c_hle_interface
public:
vpx3220a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ auto href_callback() { return m_href_cb.bind(); }
+ auto vref_callback() { return m_vref_cb.bind(); }
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
@@ -28,9 +31,22 @@ protected:
virtual void write_data(u16 offset, u8 data) override;
private:
+ TIMER_CALLBACK_MEMBER(href_tick);
+ TIMER_CALLBACK_MEMBER(vref_tick);
+
+ u16 get_fp_reg();
+ void set_fp_reg();
+
enum subaddr_t : u8;
enum fpaddr_t : u16;
+ devcb_write_line m_href_cb;
+ devcb_write_line m_vref_cb;
+ emu_timer *m_href_timer;
+ emu_timer *m_vref_timer;
+ int m_href;
+ int m_vref;
+
u8 m_ifc;
u8 m_afend;
u8 m_unk_34;
@@ -52,9 +68,12 @@ private:
u8 m_driver_a;
u8 m_driver_b;
+ u16 m_fpdata;
u16 m_fpaddr;
u8 m_fpsta;
- bool m_fp_lsb;
+ bool m_want_fp_lsb;
+ bool m_accessing_fp;
+ bool m_want_fp_data_lsb;
u16 m_fp_tint;
u16 m_fp_gain;
@@ -76,9 +95,7 @@ private:
u16 m_fp_sgain;
u16 m_fp_vsdt;
u16 m_fp_cmdwd;
- u16 m_fp_infowd;
u16 m_fp_tvstndwr;
- u16 m_fp_tvstndrd;
};
DECLARE_DEVICE_TYPE(VPX3220A, vpx3220a_device)