diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/cpu/sh/sh7604.cpp | 21 | ||||
| -rw-r--r-- | src/mame/namco/md8412b.cpp | 620 | ||||
| -rw-r--r-- | src/mame/namco/md8412b.h | 94 | ||||
| -rw-r--r-- | src/mame/namco/namco_settings.cpp | 5 | ||||
| -rw-r--r-- | src/mame/namco/namcos23.cpp | 1170 | ||||
| -rw-r--r-- | src/mame/namco/vpx3220a.cpp | 543 | ||||
| -rw-r--r-- | src/mame/namco/vpx3220a.h | 23 |
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) |
