diff options
author | mooglyguy <therealmogminer@gmail.com> | 2019-12-26 00:19:58 +0100 |
---|---|---|
committer | mooglyguy <therealmogminer@gmail.com> | 2019-12-26 00:19:58 +0100 |
commit | d9b46ec794a5d466226ffee99a464c59e6e0fe51 (patch) | |
tree | ca61be434a13e1c9b9c96f47df21840fffa5e9d8 | |
parent | 5158e9d91617bd96883bc74603d1059e3c757ee8 (diff) |
-cdi: cdimono2 WIP. Added UART and SPI to 68HC05. Moved COP from the HC05 to HC705. nw
-rw-r--r-- | src/devices/cpu/m6805/m68hc05.cpp | 526 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68hc05.h | 131 | ||||
-rw-r--r-- | src/devices/machine/scc68070.cpp | 60 | ||||
-rw-r--r-- | src/mame/drivers/cdi.cpp | 280 | ||||
-rw-r--r-- | src/mame/includes/cdi.h | 66 | ||||
-rw-r--r-- | src/mame/video/mcd212.cpp | 423 | ||||
-rw-r--r-- | src/mame/video/mcd212.h | 3 |
7 files changed, 1100 insertions, 389 deletions
diff --git a/src/devices/cpu/m6805/m68hc05.cpp b/src/devices/cpu/m6805/m68hc05.cpp index 362c297da8e..cab71263867 100644 --- a/src/devices/cpu/m6805/m68hc05.cpp +++ b/src/devices/cpu/m6805/m68hc05.cpp @@ -33,8 +33,10 @@ determines both the COP watchdog timeout and the real-time interrupt rate #define LOG_IOPORT (1U << 2) #define LOG_TIMER (1U << 3) #define LOG_COP (1U << 4) +#define LOG_UART (1U << 5) +#define LOG_SPI (1U << 6) -//#define VERBOSE (LOG_GENERAL | LOG_INT | LOG_IOPORT | LOG_TIMER | LOG_COP) +#define VERBOSE (LOG_GENERAL | LOG_INT | LOG_IOPORT | LOG_COP | LOG_UART | LOG_SPI) //#define LOG_OUTPUT_FUNC printf #include "logmacro.h" @@ -42,6 +44,8 @@ determines both the COP watchdog timeout and the real-time interrupt rate #define LOGIOPORT(...) LOGMASKED(LOG_IOPORT, __VA_ARGS__) #define LOGTIMER(...) LOGMASKED(LOG_TIMER, __VA_ARGS__) #define LOGCOP(...) LOGMASKED(LOG_COP, __VA_ARGS__) +#define LOGUART(...) LOGMASKED(LOG_UART, __VA_ARGS__) +#define LOGSPI(...) LOGMASKED(LOG_SPI, __VA_ARGS__) namespace { @@ -94,8 +98,8 @@ ROM_START( m68hc705c8a ) ROM_END -//constexpr u16 M68HC05_VECTOR_SPI = 0xfff4; -//constexpr u16 M68HC05_VECTOR_SCI = 0xfff6; +constexpr u16 M68HC05_VECTOR_SPI = 0xfff4; +constexpr u16 M68HC05_VECTOR_SCI = 0xfff6; constexpr u16 M68HC05_VECTOR_TIMER = 0xfff8; constexpr u16 M68HC05_VECTOR_IRQ = 0xfffa; constexpr u16 M68HC05_VECTOR_SWI = 0xfffc; @@ -103,8 +107,10 @@ constexpr u16 M68HC05_VECTOR_SWI = 0xfffc; constexpr u16 M68HC05_INT_IRQ = u16(1) << 0; constexpr u16 M68HC05_INT_TIMER = u16(1) << 1; +constexpr u16 M68HC05_INT_SCI = u16(1) << 2; +constexpr u16 M68HC05_INT_SPI = u16(1) << 3; -constexpr u16 M68HC05_INT_MASK = M68HC05_INT_IRQ | M68HC05_INT_TIMER; +constexpr u16 M68HC05_INT_MASK = M68HC05_INT_IRQ | M68HC05_INT_TIMER | M68HC05_INT_SCI | M68HC05_INT_SPI; } // anonymous namespace @@ -154,6 +160,9 @@ m68hc05_device::m68hc05_device( , m_port_irq_state(false) , m_irq_line_state(false) , m_irq_latch(0) + , m_uart_tx_cb(*this) + , m_sck_out_cb(*this) + , m_sda_out_cb(*this) , m_tcmp_cb(*this) , m_tcap_state(false) , m_tcr(0x00) @@ -163,11 +172,6 @@ m68hc05_device::m68hc05_device( , m_inhibit_cap(false), m_inhibit_cmp(false) , m_trl_buf{ 0xfc, 0xfc } , m_trl_latched{ false, false } - , m_pcop_cnt(0) - , m_ncop_cnt(0) - , m_coprst(0x00) - , m_copcr(0x00) - , m_ncope(0) { } @@ -261,6 +265,203 @@ WRITE8_MEMBER(m68hc05_device::port_ddr_w) } } +u8 m68hc05_device::spcr_spr_divider() const +{ + static const uint32_t s_rate_values[4] = { 2, 4, 16, 32 }; + return s_rate_values[spcr_spr()]; +} + +READ8_MEMBER(m68hc05_device::spcr_r) +{ + return m_spcr; +} + +WRITE8_MEMBER(m68hc05_device::spcr_w) +{ + data &= 0xdf; + m_spcr = data; + LOGSPI("write SPCR: SPIE=%u SPE=%u MSTR=%u CPOL=%u CPHA=%u SPR=%u (divider %u)\n", + spcr_spie(), spcr_spe(), spcr_mstr(), spcr_cpol(), spcr_cpha(), spcr_spr(), spcr_spr_divider()); + if (m_spi_tx_clocks == ~0U) + { + m_sck = spcr_cpol() ? 1 : 0; + } +} + +READ8_MEMBER(m68hc05_device::spsr_r) +{ + return m_spsr; +} + +WRITE8_MEMBER(m68hc05_device::spsr_w) +{ + LOGSPI("write SPSR (ignored): %02x\n", data); +} + +READ8_MEMBER(m68hc05_device::spdr_r) +{ + LOGSPI("%s: read SPDR: %02x\n", machine().describe_context(), m_spdr); + m_spsr &= ~0xd0; + return m_spdr; +} + +WRITE8_MEMBER(m68hc05_device::spdr_w) +{ + LOGSPI("%s: write SPDR: %02x\n", machine().describe_context(), data); + m_spdr = data; + if (spcr_spe()) + { + if (m_spi_tx_clocks != ~0U) + { + // flag write collision + m_spsr |= 0x40; + } + else + { + m_spi_tx_clocks = spcr_spr_divider() >> 1; + m_spi_tx_cnt = 8; + m_spi_run_clocks = 0; + } + } +} + +WRITE_LINE_MEMBER(m68hc05_device::sck_in) +{ + LOGSPI("sck_in: %d\n", state); + u8 old = m_sck; + m_sck = state; + if (spcr_spe()) + { + if (old != m_sck && m_sck != spcr_cpol()) + { + if (m_spi_rx_cnt == 0) + { + m_spdr = 0; + } + m_spdr |= (m_sda ? 1 : 0) << m_spi_rx_cnt; + m_spi_rx_cnt++; + if (m_spi_rx_cnt == 8) + { + m_spi_rx_cnt = 0; + m_spsr |= 0x80; + if (spsr_spif() && spcr_spie()) + { + m_pending_interrupts |= M68HC05_INT_SPI; + } + else + { + m_pending_interrupts &= ~M68HC05_INT_SPI; + } + } + } + } +} + +WRITE_LINE_MEMBER(m68hc05_device::sda_in) +{ + LOGSPI("sda_in: %d\n", state); + m_sda = state; +} + +u8 m68hc05_device::baud_scp_count() const +{ + static const uint32_t s_prescale_values[4] = { 1, 3, 4, 13 }; + return s_prescale_values[baud_scp()]; +} + +READ8_MEMBER(m68hc05_device::baud_r) +{ + return m_baud; +} + +WRITE8_MEMBER(m68hc05_device::baud_w) +{ + data &= 0x37; + m_baud = data; + LOGUART("write BAUD: SCP=%u SCR=%u (prescale=%u clocks, rate=%u clocks)\n", + baud_scp(), baud_scr(), baud_scp_count(), baud_scr_count()); +} + +READ8_MEMBER(m68hc05_device::sccr1_r) +{ + return m_sccr1; +} + +WRITE8_MEMBER(m68hc05_device::sccr1_w) +{ + data &= 0xd8; + m_sccr1 = data; + LOGUART("write SCCR1: R8=%u T8=%u M=%u WAKE=%u\n", + sccr1_r8(), sccr1_t8(), sccr1_m(), sccr1_wake()); +} + +READ8_MEMBER(m68hc05_device::sccr2_r) +{ + return m_sccr2; +} + +WRITE8_MEMBER(m68hc05_device::sccr2_w) +{ + m_sccr2 = data; + LOGUART("write SCCR2: TIE=%u TCIE=%u RIE=%u ILIE=%u TE=%u RE=%u RWU=%u SBK=%u\n", + sccr2_tie(), sccr2_tcie(), sccr2_rie(), sccr2_ilie(), sccr2_te(), sccr2_re(), sccr2_rwu(), sccr2_sbk()); + if (sccr2_te() && m_tdr_pending) + { + m_uart_tx_clocks = 32 * baud_scp_count() * baud_scr_count(); + } + if (sccr2_re() && m_rdr_pending) + { + m_uart_rx_clocks = 32 * baud_scp_count() * baud_scr_count(); + } +} + +READ8_MEMBER(m68hc05_device::scsr_r) +{ + return m_scsr; +} + +READ8_MEMBER(m68hc05_device::rdr_r) +{ + m_scsr &= ~0x20; + if (m_scsr & m_sccr2 & 0xf0) + m_pending_interrupts |= M68HC05_INT_SCI; + else + m_pending_interrupts &= ~M68HC05_INT_SCI; + LOGUART("%s: read RDR: %02x\n", machine().describe_context(), m_rdr); + return m_rdr; +} + +void m68hc05_device::uart_rx(u8 data) +{ + m_rdr = data; + if (sccr2_re()) + { + m_uart_rx_clocks = 32 * baud_scp_count() * baud_scr_count(); + } + else + { + m_rdr_pending = true; + } +} + +WRITE8_MEMBER(m68hc05_device::tdr_w) +{ + m_tdr = data; + LOGUART("write TDR: %02x\n", data); + m_scsr &= ~0xc0; + if (m_scsr & m_sccr2 & 0xf0) + m_pending_interrupts |= M68HC05_INT_SCI; + else + m_pending_interrupts &= ~M68HC05_INT_SCI; + if (sccr2_te()) + { + m_uart_tx_clocks = 32 * baud_scp_count() * baud_scr_count(); + } + else + { + m_tdr_pending = true; + } +} READ8_MEMBER(m68hc05_device::tcr_r) { @@ -405,7 +606,7 @@ READ8_MEMBER(m68hc05_device::timer_r) } -WRITE8_MEMBER(m68hc05_device::coprst_w) +WRITE8_MEMBER(m68hc705_device::coprst_w) { LOGCOP("write COPRST=%02x%s\n", data, ((0xaa == data) && (0x55 == m_coprst)) ? ", reset" : ""); if (0x55 == data) @@ -419,7 +620,7 @@ WRITE8_MEMBER(m68hc05_device::coprst_w) } } -READ8_MEMBER(m68hc05_device::copcr_r) +READ8_MEMBER(m68hc705_device::copcr_r) { if (copcr_copf()) LOGCOP("read COPCR, clear COPF\n"); u8 const result(m_copcr); @@ -427,14 +628,14 @@ READ8_MEMBER(m68hc05_device::copcr_r) return result; } -WRITE8_MEMBER(m68hc05_device::copcr_w) +WRITE8_MEMBER(m68hc705_device::copcr_w) { LOGCOP("write COPCR: CME=%u PCOPE=%u [%s] CM=%u\n", BIT(data, 3), BIT(data, 2), (!copcr_pcope() && BIT(data, 2)) ? "set" : "ignored", data & 0x03); m_copcr = (m_copcr & 0xf4) | (data & 0x0f); // PCOPE is set-only, hence the mask overlap } -WRITE8_MEMBER(m68hc05_device::copr_w) +WRITE8_MEMBER(m68hc705_device::copr_w) { LOGCOP("write COPR: COPC=%u\n", BIT(data, 0)); if (!BIT(data, 0)) m_ncop_cnt = 0; @@ -448,6 +649,9 @@ void m68hc05_device::device_start() // resolve callbacks for (devcb_read8 &cb : m_port_cb_r) cb.resolve(); for (devcb_write8 &cb : m_port_cb_w) cb.resolve_safe(); + m_uart_tx_cb.resolve_safe(); + m_sck_out_cb.resolve_safe(); + m_sda_out_cb.resolve_safe(); m_tcmp_cb.resolve_safe(); // save digital I/O @@ -459,6 +663,29 @@ void m68hc05_device::device_start() save_item(NAME(m_irq_line_state)); save_item(NAME(m_irq_latch)); + // save UART + save_item(NAME(m_baud)); + save_item(NAME(m_sccr1)); + save_item(NAME(m_sccr2)); + save_item(NAME(m_scsr)); + save_item(NAME(m_rdr)); + save_item(NAME(m_tdr)); + save_item(NAME(m_rdr_pending)); + save_item(NAME(m_tdr_pending)); + save_item(NAME(m_uart_tx_clocks)); + save_item(NAME(m_uart_rx_clocks)); + + // save SPI + save_item(NAME(m_spcr)); + save_item(NAME(m_spsr)); + save_item(NAME(m_spdr)); + save_item(NAME(m_spi_rx_cnt)); + save_item(NAME(m_spi_tx_cnt)); + save_item(NAME(m_spi_tx_clocks)); + save_item(NAME(m_spi_run_clocks)); + save_item(NAME(m_sck)); + save_item(NAME(m_sda)); + // save timer/counter save_item(NAME(m_tcap_state)); save_item(NAME(m_tcr)); @@ -473,19 +700,35 @@ void m68hc05_device::device_start() save_item(NAME(m_trl_buf)); save_item(NAME(m_trl_latched)); - // save COP watchdogs - save_item(NAME(m_pcop_cnt)); - save_item(NAME(m_ncop_cnt)); - save_item(NAME(m_coprst)); - save_item(NAME(m_copcr)); - save_item(NAME(m_ncope)); - // digital I/O state unaffected by reset std::fill(std::begin(m_port_interrupt), std::end(m_port_interrupt), 0x00); std::fill(std::begin(m_port_input), std::end(m_port_input), 0xff); std::fill(std::begin(m_port_latch), std::end(m_port_latch), 0xff); m_irq_line_state = false; + // some UART state unaffected by reset + m_baud = 0x00; + m_sccr1 = 0x00; + m_sccr2 = 0x00; + m_scsr = 0x00; + m_rdr = 0x00; + m_tdr = 0x00; + m_rdr_pending = false; + m_tdr_pending = false; + m_uart_tx_clocks = ~0U; + m_uart_rx_clocks = ~0U; + + // some SPI sate unaffected by reset + m_spcr = 0x00; + m_spsr = 0x00; + m_spdr = 0x00; + m_spi_rx_cnt = 0; + m_spi_tx_cnt = 0; + m_spi_tx_clocks = ~0U; + m_spi_run_clocks = 0; + m_sck = 0x00; + m_sda = 0x00; + // timer state unaffected by reset m_tcap_state = false; m_tcr = 0x00; @@ -493,12 +736,6 @@ void m68hc05_device::device_start() m_icr = 0x0000; m_ocr = 0x0000; - // COP watchdog state unaffected by reset - m_pcop_cnt = 0; - m_coprst = 0x00; - m_copcr = 0x00; - m_ncope = 0; - // expose most basic state to debugger state_add(M68HC05_IRQLATCH, "IRQLATCH", m_irq_latch).mask(0x01); } @@ -512,6 +749,23 @@ void m68hc05_device::device_reset() m_irq_latch = 0; update_port_irq(); + // UART reset + m_baud &= 0x07; + m_sccr2 = 0x00; + m_scsr = 0xc0; + m_uart_tx_clocks = ~0U; + m_uart_rx_clocks = ~0U; + + // SPI reset + m_spcr &= 0x2f; + m_spsr &= 0x2f; + m_spi_rx_cnt = 0; + m_spi_tx_cnt = 0; + m_spi_tx_clocks = ~0U; + m_spi_run_clocks = 0; + m_sck = 0x00; + m_sda = 0x00; + // timer reset m_tcr &= 0x02; m_tsr_seen = 0x00; @@ -520,6 +774,29 @@ void m68hc05_device::device_reset() m_inhibit_cap = m_inhibit_cmp = false; m_trl_buf[0] = m_trl_buf[1] = u8(m_counter); m_trl_latched[0] = m_trl_latched[1] = false; +} + +void m68hc705_device::device_start() +{ + m68hc05_device::device_start(); + + // save COP watchdogs + save_item(NAME(m_pcop_cnt)); + save_item(NAME(m_ncop_cnt)); + save_item(NAME(m_coprst)); + save_item(NAME(m_copcr)); + save_item(NAME(m_ncope)); + + // COP watchdog state unaffected by reset + m_pcop_cnt = 0; + m_coprst = 0x00; + m_copcr = 0x00; + m_ncope = 0; +} + +void m68hc705_device::device_reset() +{ + m68hc05_device::device_reset(); // COP watchdog reset m_ncop_cnt = 0; @@ -600,6 +877,16 @@ void m68hc05_device::interrupt() LOGINT("servicing timer interrupt\n"); rm16(M68HC05_VECTOR_TIMER & m_params.m_vector_mask, m_pc); } + else if (m_pending_interrupts & M68HC05_INT_SCI) + { + LOGINT("servicing SCI interrupt\n"); + rm16(M68HC05_VECTOR_SCI & m_params.m_vector_mask, m_pc); + } + else if (m_pending_interrupts & M68HC05_INT_SPI) + { + LOGINT("servicing SPI interrupt\n"); + rm16(M68HC05_VECTOR_SPI & m_params.m_vector_mask, m_pc); + } else { fatalerror("m68hc05[%s]: unknown pending interrupt(s) %x", tag(), m_pending_interrupts); @@ -614,6 +901,33 @@ bool m68hc05_device::test_il() return m_irq_line_state; } +void m68hc05_device::run_cop(unsigned count) +{ + // C4 and C8 devices don't have a COP or watchdog +} + +void m68hc705_device::run_cop(unsigned count) +{ + // run programmable COP + u32 const pcop_timeout(u32(1) << ((copcr_cm() << 1) + 15)); + if (copcr_pcope() && (pcop_timeout <= ((m_pcop_cnt & (pcop_timeout - 1)) + count))) + { + LOGCOP("PCOP reset\n"); + m_copcr |= 0x10; + pulse_input_line(INPUT_LINE_RESET, attotime::zero); + } + m_pcop_cnt = (m_pcop_cnt + count) & ((u32(1) << 21) - 1); + + // run non-programmable COP + m_ncop_cnt += count; + if ((u32(1) << 17) <= m_ncop_cnt) + { + pulse_input_line(INPUT_LINE_RESET, attotime::zero); + LOGCOP("NCOP reset\n"); + } + m_ncop_cnt &= (u32(1) << 17) - 1; +} + void m68hc05_device::burn_cycles(unsigned count) { // calculate new timer values (fixed prescaler of four) @@ -641,24 +955,81 @@ void m68hc05_device::burn_cycles(unsigned count) } if (m_tcr & m_tsr & 0xe0) m_pending_interrupts |= M68HC05_INT_TIMER; - // run programmable COP - u32 const pcop_timeout(u32(1) << ((copcr_cm() << 1) + 15)); - if (copcr_pcope() && (pcop_timeout <= ((m_pcop_cnt & (pcop_timeout - 1)) + count))) + run_cop(count); + + // run SPI Tx + if (m_spi_tx_clocks != ~0U) { - LOGCOP("PCOP reset\n"); - m_copcr |= 0x10; - pulse_input_line(INPUT_LINE_RESET, attotime::zero); + m_spi_run_clocks += count * ps_opt; + while (m_spi_run_clocks > m_spi_tx_clocks && m_spi_tx_cnt > 0) + { + m_spi_run_clocks -= m_spi_tx_clocks; + + if (m_sck == !spcr_cpol()) + { + logerror("Transmitting SPI bit %u: %u\n", 8 - m_spi_tx_cnt, BIT(m_spdr, 8 - m_spi_tx_cnt)); + m_sda_out_cb(BIT(m_spdr, 8 - m_spi_tx_cnt)); + m_spi_tx_cnt--; + if (m_spi_tx_cnt == 0) + { + m_spi_tx_clocks = ~0U; + m_spi_run_clocks = 0; + m_spsr |= 0x80; + if (spsr_spif() && spcr_spie()) + { + m_pending_interrupts |= M68HC05_INT_SPI; + } + else + { + m_pending_interrupts &= ~M68HC05_INT_SPI; + } + } + } + m_sck_out_cb(m_sck); + m_sck = 1 - m_sck; + } } - m_pcop_cnt = (m_pcop_cnt + count) & ((u32(1) << 21) - 1); - // run non-programmable COP - m_ncop_cnt += count; - if ((u32(1) << 17) <= m_ncop_cnt) + // run UART Tx + if (m_uart_tx_clocks != ~0U) { - pulse_input_line(INPUT_LINE_RESET, attotime::zero); - LOGCOP("NCOP reset\n"); + if (m_uart_tx_clocks > count * ps_opt) + { + m_uart_tx_clocks -= count * ps_opt; + } + else + { + logerror("Transmitting %02x\n", m_tdr); + m_tdr_pending = false; + m_uart_tx_clocks = ~0U; + m_scsr |= 0xc0; + m_uart_tx_cb(m_tdr); + if (m_scsr & m_sccr2 & 0xf0) + m_pending_interrupts |= M68HC05_INT_SCI; + else + m_pending_interrupts &= ~M68HC05_INT_SCI; + } + } + + // run UART Rx + if (m_uart_rx_clocks != ~0U && sccr2_re()) + { + if (m_uart_rx_clocks > count * ps_opt) + { + m_uart_rx_clocks -= count * ps_opt; + } + else + { + logerror("Receiving %02x\n", m_rdr); + m_rdr_pending = false; + m_uart_rx_clocks = ~0U; + m_scsr |= 0x20; + if (m_scsr & m_sccr2 & 0xf0) + m_pending_interrupts |= M68HC05_INT_SCI; + else + m_pending_interrupts &= ~M68HC05_INT_SCI; + } } - m_ncop_cnt &= (u32(1) << 17) - 1; } @@ -686,14 +1057,14 @@ void m68hc05_device::add_timer_state() state_add(M68HC05_TR, "TR", m_counter).mask(0xffff); } -void m68hc05_device::add_pcop_state() +void m68hc705_device::add_pcop_state() { state_add(M68HC05_COPRST, "COPRST", m_coprst).mask(0xff); state_add(M68HC05_COPCR, "COPCR", m_copcr).mask(0x1f); state_add(M68HC05_PCOP, "PCOP", m_pcop_cnt).mask(0x001fffff); } -void m68hc05_device::add_ncop_state() +void m68hc705_device::add_ncop_state() { state_add(M68HC05_NCOPE, "NCOPE", m_ncope).mask(0x01); state_add(M68HC05_NCOP, "NCOP", m_ncop_cnt).mask(0x0001ffff); @@ -739,6 +1110,11 @@ m68hc705_device::m68hc705_device( u32 addr_width, address_map_constructor internal_map) : m68hc05_device(mconfig, tag, owner, clock, type, addr_width, (1U << addr_width) - 1, internal_map) + , m_pcop_cnt(0) + , m_ncop_cnt(0) + , m_coprst(0x00) + , m_copcr(0x00) + , m_ncope(0) { } @@ -756,14 +1132,14 @@ void m68hc05c4_device::c4_map(address_map &map) map(0x0000, 0x0003).rw(FUNC(m68hc05c4_device::port_read), FUNC(m68hc05c4_device::port_latch_w)); map(0x0004, 0x0006).rw(FUNC(m68hc05c4_device::port_ddr_r), FUNC(m68hc05c4_device::port_ddr_w)); // 0x0007-0x0009 unused - // 0x000a SPCR - // 0x000b SPSR - // 0x000c SPDR - // 0x000d BAUD - // 0x000e SCCR1 - // 0x000f SCCR2 - // 0x0010 SCSR - // 0x0011 SCDR + map(0x000a, 0x000a).rw(FUNC(m68hc05c4_device::spcr_r), FUNC(m68hc05c4_device::spcr_w)); + map(0x000b, 0x000b).rw(FUNC(m68hc05c4_device::spsr_r), FUNC(m68hc05c4_device::spsr_w)); + map(0x000c, 0x000c).rw(FUNC(m68hc05c4_device::spdr_r), FUNC(m68hc05c4_device::spdr_w)); + map(0x000d, 0x000d).rw(FUNC(m68hc05c4_device::baud_r), FUNC(m68hc05c4_device::baud_w)); + map(0x000e, 0x000e).rw(FUNC(m68hc05c4_device::sccr1_r), FUNC(m68hc05c4_device::sccr1_w)); + map(0x000f, 0x000f).rw(FUNC(m68hc05c4_device::sccr2_r), FUNC(m68hc05c4_device::sccr2_w)); + map(0x0010, 0x0010).r(FUNC(m68hc05c4_device::scsr_r)); + map(0x0011, 0x0011).rw(FUNC(m68hc05c4_device::rdr_r), FUNC(m68hc05c4_device::tdr_w)); map(0x0012, 0x0012).rw(FUNC(m68hc05c4_device::tcr_r), FUNC(m68hc05c4_device::tcr_w)); map(0x0013, 0x0013).r(FUNC(m68hc05c4_device::tsr_r)); map(0x0014, 0x0015).r(FUNC(m68hc05c4_device::icr_r)); @@ -824,14 +1200,14 @@ void m68hc05c8_device::c8_map(address_map &map) map(0x0000, 0x0003).rw(FUNC(m68hc05c8_device::port_read), FUNC(m68hc05c8_device::port_latch_w)); map(0x0004, 0x0006).rw(FUNC(m68hc05c8_device::port_ddr_r), FUNC(m68hc05c8_device::port_ddr_w)); // 0x0007-0x0009 unused - // 0x000a SPCR - // 0x000b SPSR - // 0x000c SPDR - // 0x000d BAUD - // 0x000e SCCR1 - // 0x000f SCCR2 - // 0x0010 SCSR - // 0x0011 SCDR + map(0x000a, 0x000a).rw(FUNC(m68hc05c8_device::spcr_r), FUNC(m68hc05c8_device::spcr_w)); + map(0x000b, 0x000b).rw(FUNC(m68hc05c8_device::spsr_r), FUNC(m68hc05c8_device::spsr_w)); + map(0x000c, 0x000c).rw(FUNC(m68hc05c8_device::spdr_r), FUNC(m68hc05c8_device::spdr_w)); + map(0x000d, 0x000d).rw(FUNC(m68hc05c8_device::baud_r), FUNC(m68hc05c8_device::baud_w)); + map(0x000e, 0x000e).rw(FUNC(m68hc05c8_device::sccr1_r), FUNC(m68hc05c8_device::sccr1_w)); + map(0x000f, 0x000f).rw(FUNC(m68hc05c8_device::sccr2_r), FUNC(m68hc05c8_device::sccr2_w)); + map(0x0010, 0x0010).r(FUNC(m68hc05c8_device::scsr_r)); + map(0x0011, 0x0011).rw(FUNC(m68hc05c8_device::rdr_r), FUNC(m68hc05c8_device::tdr_w)); map(0x0012, 0x0012).rw(FUNC(m68hc05c8_device::tcr_r), FUNC(m68hc05c8_device::tcr_w)); map(0x0013, 0x0013).r(FUNC(m68hc05c8_device::tsr_r)); map(0x0014, 0x0015).r(FUNC(m68hc05c8_device::icr_r)); @@ -891,14 +1267,14 @@ void m68hc705c8a_device::c8a_map(address_map &map) map(0x0000, 0x0003).rw(FUNC(m68hc705c8a_device::port_read), FUNC(m68hc705c8a_device::port_latch_w)); map(0x0004, 0x0006).rw(FUNC(m68hc705c8a_device::port_ddr_r), FUNC(m68hc705c8a_device::port_ddr_w)); // 0x0007-0x0009 unused - // 0x000a SPCR - // 0x000b SPSR - // 0x000c SPDR - // 0x000d BAUD - // 0x000e SCCR1 - // 0x000f SCCR2 - // 0x0010 SCSR - // 0x0011 SCDR + map(0x000a, 0x000a).rw(FUNC(m68hc705c8a_device::spcr_r), FUNC(m68hc705c8a_device::spcr_w)); + map(0x000b, 0x000b).rw(FUNC(m68hc705c8a_device::spsr_r), FUNC(m68hc705c8a_device::spsr_w)); + map(0x000c, 0x000c).rw(FUNC(m68hc705c8a_device::spdr_r), FUNC(m68hc705c8a_device::spdr_w)); + map(0x000d, 0x000d).rw(FUNC(m68hc705c8a_device::baud_r), FUNC(m68hc705c8a_device::baud_w)); + map(0x000e, 0x000e).rw(FUNC(m68hc705c8a_device::sccr1_r), FUNC(m68hc705c8a_device::sccr1_w)); + map(0x000f, 0x000f).rw(FUNC(m68hc705c8a_device::sccr2_r), FUNC(m68hc705c8a_device::sccr2_w)); + map(0x0010, 0x0010).r(FUNC(m68hc705c8a_device::scsr_r)); + map(0x0011, 0x0011).rw(FUNC(m68hc705c8a_device::rdr_r), FUNC(m68hc705c8a_device::tdr_w)); map(0x0012, 0x0012).rw(FUNC(m68hc705c8a_device::tcr_r), FUNC(m68hc705c8a_device::tcr_w)); map(0x0013, 0x0013).r(FUNC(m68hc705c8a_device::tsr_r)); map(0x0014, 0x0015).r(FUNC(m68hc705c8a_device::icr_r)); @@ -1048,11 +1424,11 @@ void m68hc05l9_device::l9_map(address_map &map) // 0x0009-0x000a configuration // 0x000b minute alarm // 0x000c hour alarm - // 0x000d BAUD - // 0x000e SCCR1 - // 0x000f SCCR2 - // 0x0010 SCSR - // 0x0011 SCDR + map(0x000d, 0x000d).rw(FUNC(m68hc05l9_device::baud_r), FUNC(m68hc05l9_device::baud_w)); + map(0x000e, 0x000e).rw(FUNC(m68hc05l9_device::sccr1_r), FUNC(m68hc05l9_device::sccr1_w)); + map(0x000f, 0x000f).rw(FUNC(m68hc05l9_device::sccr2_r), FUNC(m68hc05l9_device::sccr2_w)); + map(0x0010, 0x0010).r(FUNC(m68hc05l9_device::scsr_r)); + map(0x0011, 0x0011).rw(FUNC(m68hc05l9_device::rdr_r), FUNC(m68hc05l9_device::tdr_w)); map(0x0012, 0x0012).rw(FUNC(m68hc05l9_device::tcr_r), FUNC(m68hc05l9_device::tcr_w)); map(0x0013, 0x0013).r(FUNC(m68hc05l9_device::tsr_r)); map(0x0014, 0x0015).r(FUNC(m68hc05l9_device::icr_r)); @@ -1121,11 +1497,11 @@ void m68hc05l11_device::l11_map(address_map &map) // 0x000a port F direction // 0x000b minute alarm // 0x000c hour alarm - // 0x000d BAUD - // 0x000e SCCR1 - // 0x000f SCCR2 - // 0x0010 SCSR - // 0x0011 SCDR + map(0x000d, 0x000d).rw(FUNC(m68hc05l11_device::baud_r), FUNC(m68hc05l11_device::baud_w)); + map(0x000e, 0x000e).rw(FUNC(m68hc05l11_device::sccr1_r), FUNC(m68hc05l11_device::sccr1_w)); + map(0x000f, 0x000f).rw(FUNC(m68hc05l11_device::sccr2_r), FUNC(m68hc05l11_device::sccr2_w)); + map(0x0010, 0x0010).r(FUNC(m68hc05l11_device::scsr_r)); + map(0x0011, 0x0011).rw(FUNC(m68hc05l11_device::rdr_r), FUNC(m68hc05l11_device::tdr_w)); map(0x0012, 0x0012).rw(FUNC(m68hc05l11_device::tcr_r), FUNC(m68hc05l11_device::tcr_w)); map(0x0013, 0x0013).r(FUNC(m68hc05l11_device::tsr_r)); map(0x0014, 0x0015).r(FUNC(m68hc05l11_device::icr_r)); diff --git a/src/devices/cpu/m6805/m68hc05.h b/src/devices/cpu/m6805/m68hc05.h index b853c95df95..8fccb87e7c7 100644 --- a/src/devices/cpu/m6805/m68hc05.h +++ b/src/devices/cpu/m6805/m68hc05.h @@ -41,6 +41,13 @@ public: auto portc_w() { return m_port_cb_w[2].bind(); } auto portd_w() { return m_port_cb_w[3].bind(); } auto tcmp() { return m_tcmp_cb.bind(); } + auto uart_tx() { return m_uart_tx_cb.bind(); } + void uart_rx(u8 data); + + auto sck_out() { return m_sck_out_cb.bind(); } + auto sda_out() { return m_sda_out_cb.bind(); } + DECLARE_WRITE_LINE_MEMBER(sck_in); + DECLARE_WRITE_LINE_MEMBER(sda_in); protected: // state index constants @@ -97,6 +104,23 @@ protected: DECLARE_READ8_MEMBER(port_ddr_r); DECLARE_WRITE8_MEMBER(port_ddr_w); + DECLARE_READ8_MEMBER(baud_r); + DECLARE_WRITE8_MEMBER(baud_w); + DECLARE_READ8_MEMBER(sccr1_r); + DECLARE_WRITE8_MEMBER(sccr1_w); + DECLARE_READ8_MEMBER(sccr2_r); + DECLARE_WRITE8_MEMBER(sccr2_w); + DECLARE_READ8_MEMBER(scsr_r); + DECLARE_READ8_MEMBER(rdr_r); + DECLARE_WRITE8_MEMBER(tdr_w); + + DECLARE_READ8_MEMBER(spcr_r); + DECLARE_WRITE8_MEMBER(spcr_w); + DECLARE_READ8_MEMBER(spsr_r); + DECLARE_WRITE8_MEMBER(spsr_w); + DECLARE_READ8_MEMBER(spdr_r); + DECLARE_WRITE8_MEMBER(spdr_w); + DECLARE_READ8_MEMBER(tcr_r); DECLARE_WRITE8_MEMBER(tcr_w); DECLARE_READ8_MEMBER(tsr_r); @@ -105,12 +129,6 @@ protected: DECLARE_WRITE8_MEMBER(ocr_w); DECLARE_READ8_MEMBER(timer_r); - void set_ncope(bool state) { m_ncope = state ? 1 : 0; } - DECLARE_WRITE8_MEMBER(coprst_w); - DECLARE_READ8_MEMBER(copcr_r); - DECLARE_WRITE8_MEMBER(copcr_w); - DECLARE_WRITE8_MEMBER(copr_w); - virtual void device_start() override; virtual void device_reset() override; @@ -126,13 +144,50 @@ protected: void add_port_state(std::array<bool, PORT_COUNT> const &ddr); void add_timer_state(); - void add_pcop_state(); - void add_ncop_state(); + + virtual void run_cop(unsigned count); private: u8 port_value(unsigned offset) const; void update_port_irq(); + bool sccr1_r8() const { return BIT(m_sccr1, 7); } + bool sccr1_t8() const { return BIT(m_sccr1, 6); } + bool sccr1_m() const { return BIT(m_sccr1, 4); } + bool sccr1_wake() const { return BIT(m_sccr1, 3); } + + bool sccr2_tie() const { return BIT(m_sccr2, 7); } + bool sccr2_tcie() const { return BIT(m_sccr2, 6); } + bool sccr2_rie() const { return BIT(m_sccr2, 5); } + bool sccr2_ilie() const { return BIT(m_sccr2, 4); } + bool sccr2_te() const { return BIT(m_sccr2, 3); } + bool sccr2_re() const { return BIT(m_sccr2, 2); } + bool sccr2_rwu() const { return BIT(m_sccr2, 1); } + bool sccr2_sbk() const { return BIT(m_sccr2, 0); } + + bool scsr_tdre() const { return BIT(m_scsr, 7); } + bool scsr_tc() const { return BIT(m_scsr, 6); } + bool scsr_rdrf() const { return BIT(m_scsr, 5); } + bool scsr_idle() const { return BIT(m_scsr, 4); } + bool scsr_or() const { return BIT(m_scsr, 3); } + bool scsr_nf() const { return BIT(m_scsr, 2); } + bool scsr_fe() const { return BIT(m_scsr, 1); } + + u8 baud_scp() const { return (m_baud >> 4) & 0x03; } + u8 baud_scr() const { return m_baud & 0x07; } + u8 baud_scp_count() const; + u8 baud_scr_count() const { return 1U << baud_scr(); } + + bool spcr_spie() const { return BIT(m_spcr, 7); } + bool spcr_spe() const { return BIT(m_spcr, 6); } + bool spcr_mstr() const { return BIT(m_spcr, 4); } + bool spcr_cpol() const { return BIT(m_spcr, 3); } + bool spcr_cpha() const { return BIT(m_spcr, 2); } + u8 spcr_spr() const { return m_spcr & 0x03; } + u8 spcr_spr_divider() const; + + bool spsr_spif() const { return BIT(m_spsr, 7); } + bool tcr_icie() const { return BIT(m_tcr, 7); } bool tcr_ocie() const { return BIT(m_tcr, 6); } bool tcr_toie() const { return BIT(m_tcr, 5); } @@ -143,11 +198,6 @@ private: bool tsr_ocf() const { return BIT(m_tsr, 6); } bool tsr_tof() const { return BIT(m_tsr, 5); } - bool copcr_copf() const { return BIT(m_copcr, 4); } - bool copcr_cme() const { return BIT(m_copcr, 3); } - bool copcr_pcope() const { return BIT(m_copcr, 2); } - u8 copcr_cm() const { return m_copcr & 0x03; } - // digital I/O devcb_read8 m_port_cb_r[PORT_COUNT]; devcb_write8 m_port_cb_w[PORT_COUNT]; @@ -159,6 +209,32 @@ private: bool m_port_irq_state, m_irq_line_state; u8 m_irq_latch; + // UART + u8 m_baud; + u8 m_sccr1; + u8 m_sccr2; + u8 m_scsr; + u8 m_rdr; + u8 m_tdr; + bool m_rdr_pending; + bool m_tdr_pending; + u32 m_uart_tx_clocks; + u32 m_uart_rx_clocks; + devcb_write8 m_uart_tx_cb; + + // SPI + u8 m_spcr; + u8 m_spsr; + u8 m_spdr; + u8 m_spi_rx_cnt; + u8 m_spi_tx_cnt; + u32 m_spi_tx_clocks; + u32 m_spi_run_clocks; + u8 m_sck; + u8 m_sda; + devcb_write_line m_sck_out_cb; + devcb_write_line m_sda_out_cb; + // timer/counter devcb_write_line m_tcmp_cb; bool m_tcap_state; @@ -169,11 +245,6 @@ private: bool m_inhibit_cap, m_inhibit_cmp; u8 m_trl_buf[2]; bool m_trl_latched[2]; - - // COP watchdogs - u32 m_pcop_cnt, m_ncop_cnt; - u8 m_coprst, m_copcr; - u8 m_ncope; }; @@ -190,6 +261,30 @@ protected: device_type type, u32 addr_width, address_map_constructor internal_map); + + virtual void device_start() override; + virtual void device_reset() override; + + virtual void run_cop(unsigned count) override; + + void add_pcop_state(); + void add_ncop_state(); + + void set_ncope(bool state) { m_ncope = state ? 1 : 0; } + DECLARE_WRITE8_MEMBER(coprst_w); + DECLARE_READ8_MEMBER(copcr_r); + DECLARE_WRITE8_MEMBER(copcr_w); + DECLARE_WRITE8_MEMBER(copr_w); + + bool copcr_copf() const { return BIT(m_copcr, 4); } + bool copcr_cme() const { return BIT(m_copcr, 3); } + bool copcr_pcope() const { return BIT(m_copcr, 2); } + u8 copcr_cm() const { return m_copcr & 0x03; } + + // COP watchdogs + u32 m_pcop_cnt, m_ncop_cnt; + u8 m_coprst, m_copcr; + u8 m_ncope; }; diff --git a/src/devices/machine/scc68070.cpp b/src/devices/machine/scc68070.cpp index 1eb91c6c93d..4dcf3ae4965 100644 --- a/src/devices/machine/scc68070.cpp +++ b/src/devices/machine/scc68070.cpp @@ -38,8 +38,6 @@ TODO: #include "logmacro.h" -#define ENABLE_UART_PRINTING (0) - // device type definition DEFINE_DEVICE_TYPE(SCC68070, scc68070_device, "scc68070", "Philips SCC68070") @@ -453,7 +451,7 @@ TIMER_CALLBACK_MEMBER( scc68070_device::timer0_callback ) void scc68070_device::uart_rx_check() { - if ((m_uart.command_register & 3) == 1) + if ((m_uart.command_register & 3) == 1 && m_uart.receive_pointer >= 0) { uint32_t div = 0x10000 >> ((m_uart.clock_select >> 4) & 7); m_uart.rx_timer->adjust(attotime::from_hz((49152000 / div) / 8)); @@ -494,6 +492,7 @@ void scc68070_device::uart_rx(uint8_t data) { m_uart.receive_pointer++; m_uart.receive_buffer[m_uart.receive_pointer] = data; + logerror("scc68070 uart_rx: %02x\n", data); uart_rx_check(); } @@ -527,20 +526,33 @@ TIMER_CALLBACK_MEMBER( scc68070_device::rx_callback ) update_ipl(); m_uart.status_register |= USR_RXRDY; - uint32_t div = 0x10000 >> ((m_uart.clock_select >> 4) & 7); - m_uart.rx_timer->adjust(attotime::from_hz((49152000 / div) / 8)); + + for (int index = 0; index < m_uart.receive_pointer; index++) + { + m_uart.receive_buffer[index] = m_uart.receive_buffer[index + 1]; + } + m_uart.receive_pointer--; + if (m_uart.receive_pointer < 0) + { + m_uart.rx_timer->adjust(attotime::never); + } + else + { + uint32_t div = 0x10000 >> ((m_uart.clock_select >> 4) & 7); + m_uart.rx_timer->adjust(attotime::from_hz((49152000 / div) / 8)); + } } else { + m_uart.rx_timer->adjust(attotime::never); m_uart.status_register &= ~USR_RXRDY; } } else { + m_uart.rx_timer->adjust(attotime::never); m_uart.status_register &= ~USR_RXRDY; } - - uart_rx_check(); } TIMER_CALLBACK_MEMBER( scc68070_device::tx_callback ) @@ -555,15 +567,22 @@ TIMER_CALLBACK_MEMBER( scc68070_device::tx_callback ) m_uart.transmit_holding_register = m_uart.transmit_buffer[0]; m_uart_tx_callback(m_uart.transmit_holding_register); - LOGMASKED(LOG_UART, "tx_callback: Transmitting %02x\n", machine().describe_context(), m_uart.transmit_holding_register); + LOGMASKED(LOG_UART, "%s: tx_callback: Transmitting %02x\n", machine().describe_context(), m_uart.transmit_holding_register); for(int index = 0; index < m_uart.transmit_pointer; index++) { m_uart.transmit_buffer[index] = m_uart.transmit_buffer[index+1]; } m_uart.transmit_pointer--; - uint32_t div = 0x10000 >> (m_uart.clock_select & 7); - m_uart.tx_timer->adjust(attotime::from_hz((49152000 / div) / 8)); + if (m_uart.receive_pointer < 0) + { + m_uart.rx_timer->adjust(attotime::never); + } + else + { + uint32_t div = 0x10000 >> (m_uart.clock_select & 7); + m_uart.tx_timer->adjust(attotime::from_hz((49152000 / div) / 8)); + } } else { @@ -808,6 +827,8 @@ uint8_t scc68070_device::uth_r() void scc68070_device::uth_w(uint8_t data) { LOGMASKED(LOG_UART, "%s: UART Transmit Holding Register Write: %02x ('%c')\n", machine().describe_context(), data, (data >= 0x20 && data < 0x7f) ? data : ' '); + if ((data >= 0x20 && data < 0x7f) || data == 0x0a || data == 0x0d) + printf("%c", data); uart_tx(data); m_uart.transmit_holding_register = data; } @@ -817,8 +838,6 @@ uint8_t scc68070_device::urh_r() // UART receive holding register: 8000201b if (!machine().side_effects_disabled()) { - LOGMASKED(LOG_UART, "%s: UART Receive Holding Register Read: %02x\n", machine().describe_context(), m_uart.receive_holding_register); - if (m_uart_rx_int) { m_uart_rx_int = false; @@ -826,14 +845,8 @@ uint8_t scc68070_device::urh_r() } m_uart.receive_holding_register = m_uart.receive_buffer[0]; - if (m_uart.receive_pointer >= 0) - { - for(int index = 0; index < m_uart.receive_pointer; index++) - { - m_uart.receive_buffer[index] = m_uart.receive_buffer[index + 1]; - } - m_uart.receive_pointer--; - } + + LOGMASKED(LOG_UART, "%s: UART Receive Holding Register Read: %02x\n", machine().describe_context(), m_uart.receive_holding_register); } return m_uart.receive_holding_register; } @@ -1215,10 +1228,3 @@ void scc68070_device::mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask) break; } } - -#if ENABLE_UART_PRINTING -READ16_MEMBER( scc68070_device::uart_loopback_enable ) -{ - return 0x1234; -} -#endif diff --git a/src/mame/drivers/cdi.cpp b/src/mame/drivers/cdi.cpp index a1f850bfc41..1a9c7c6a683 100644 --- a/src/mame/drivers/cdi.cpp +++ b/src/mame/drivers/cdi.cpp @@ -18,11 +18,9 @@ Quizard does not work for unknown reasons. TODO: -- Proper abstraction of the 68070's internal devices (UART,DMA,Timers etc.) -- Mono-I: Full emulation of the CDIC, SLAVE and/or MCD212 customs -- Mono-II: SERVO and SLAVE I/O device hookup +- Mono-I: Low-level emulation of the CDIC custom and SLAVE MCU +- Mono-II: More complete SERVO and SLAVE MCU hookup - Mono-II: DSP56k hookup -- Mono-II: Move 68HC05 I/O device hookup into CPU core *******************************************************************************/ @@ -53,7 +51,7 @@ TODO: #define VERBOSE (LOG_ALL) #include "logmacro.h" -#define ENABLE_UART_PRINTING (0) +#define ENABLE_UART_PRINTING (1) /************************* * Memory maps * @@ -65,7 +63,7 @@ void cdi_state::cdimono1_mem(address_map &map) map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb"); map(0x00300000, 0x00303bff).rw(m_cdic, FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w)); #if ENABLE_UART_PRINTING - map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable)); + map(0x00301400, 0x00301403).r(FUNC(cdi_state::uart_loopback_enable)); #endif map(0x00303c00, 0x00303fff).rw(m_cdic, FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w)); map(0x00310000, 0x00317fff).rw(m_slave_hle, FUNC(cdislave_device::slave_r), FUNC(cdislave_device::slave_w)); @@ -75,23 +73,29 @@ void cdi_state::cdimono1_mem(address_map &map) map(0x004fffe0, 0x004fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w)); map(0x00500000, 0x0057ffff).ram(); map(0x00580000, 0x00cfffff).noprw(); + map(0x00d00000, 0x00ffffff).noprw(); +} + +void cdi_state::cdimono1_dvc_mem(address_map &map) +{ map(0x00d00000, 0x00dfffff).ram(); // DVC RAM block 1 - map(0x00e00000, 0x00e7ffff).rw(FUNC(cdi_state::dvc_r), FUNC(cdi_state::dvc_w)); + map(0x00e00000, 0x00e3ffff).rw(FUNC(cdi_state::dvc_r), FUNC(cdi_state::dvc_w)); + map(0x00e40000, 0x00e7ffff).rom().region("dvc", 0); map(0x00e80000, 0x00efffff).ram(); // DVC RAM block 2 map(0x00f00000, 0x00ffffff).noprw(); } -void cdi_state::cdimono2_mem(address_map &map) +void cdimono2_state::cdimono2_mem(address_map &map) { map(0x00000000, 0x0007ffff).ram().share("mcd212:planea"); map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb"); + map(0x00300000, 0x0030ffff).rw(FUNC(cdimono2_state::dsp_r), FUNC(cdimono2_state::dsp_w)); #if ENABLE_UART_PRINTING - map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable)); + map(0x00300006, 0x00300007).r(FUNC(cdimono2_state::uart_loopback_enable2)); #endif - //map(0x00300000, 0x00303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w)); //map(0x00303c00, 0x00303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w)); - //map(0x00310000, 0x00317fff).rw("slave", FUNC(cdislave_device::slave_r), FUNC(cdicdic_device::slave_w)); - //map(0x00318000, 0x0031ffff).noprw(); + map(0x00310000, 0x00317fff).rw(FUNC(cdimono2_state::slave_glue_r), FUNC(cdimono2_state::slave_glue_w)); + map(0x00318000, 0x0031ffff).noprw(); map(0x00320000, 0x00323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */ map(0x00400000, 0x0047ffff).rom().region("maincpu", 0); map(0x004fffe0, 0x004fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w)); @@ -100,14 +104,14 @@ void cdi_state::cdimono2_mem(address_map &map) //map(0x00e00000, 0x00efffff).ram(); } -void cdi_state::cdi910_mem(address_map &map) +void cdimono2_state::cdi910_mem(address_map &map) { map(0x00000000, 0x0007ffff).ram().share("mcd212:planea"); map(0x00180000, 0x001fffff).rom().region("maincpu", 0); // boot vectors point here map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb"); #if ENABLE_UART_PRINTING - map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable)); + map(0x00301400, 0x00301403).r(FUNC(cdimono2_state::uart_loopback_enable)); #endif // map(0x00300000, 0x00303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w)); // map(0x00303c00, 0x00303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w)); @@ -122,6 +126,73 @@ void cdi_state::cdi910_mem(address_map &map) /************************* +* Debug ports * +*************************/ + +READ16_MEMBER( cdi_state::uart_loopback_enable ) +{ + return 0x1234; +} + +READ16_MEMBER( cdimono2_state::uart_loopback_enable2 ) +{ + return 0xffaa; +} + +/************************* +* SLAVE MCU logic * +*************************/ + +READ8_MEMBER(cdimono2_state::slave_glue_r) +{ + m_portd_data |= 0x80; + logerror("%s: slave_glue_r: %02x = %02x\n", machine().describe_context(), offset, m_porta_data); + m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); + m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + return m_porta_data; +} + +WRITE8_MEMBER(cdimono2_state::slave_glue_w) +{ + logerror("%s: slave_glue_w: %02x = %02x\n", machine().describe_context(), offset, data); + m_portc_data = 0xfc | ((offset >> 1) & 3); + m_porta_data = data & 0xff; + m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); + m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); + m_portd_data &= ~0x80; + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); +} + +WRITE8_MEMBER(cdimono2_state::controller_tx) +{ + logerror("%s: controller_tx: %02x\n", machine().describe_context(), data); + m_slave->uart_rx(0x55); +} + +/************************* +* DSP logic * +*************************/ + +READ8_MEMBER(cdimono2_state::dsp_r) +{ + uint8_t data = 0; + switch (offset) + { + case 5: + data = 3; + break; + } + logerror("%s: dsp_r: %04x = %02x\n", machine().describe_context(), offset << 1, data); + return data; +} + +WRITE8_MEMBER(cdimono2_state::dsp_w) +{ + logerror("%s: dsp_w: %04x = %02x\n", machine().describe_context(), offset << 1, data); +} + +/************************* * Input ports * *************************/ @@ -257,6 +328,14 @@ INPUT_PORTS_END * Machine Initialization * ***************************/ +void cdimono2_state::machine_start() +{ + save_item(NAME(m_porta_data)); + save_item(NAME(m_portb_data)); + save_item(NAME(m_portc_data)); + save_item(NAME(m_portd_data)); +} + void cdi_state::machine_reset() { uint16_t *src = (uint16_t*)memregion("maincpu")->base(); @@ -264,6 +343,15 @@ void cdi_state::machine_reset() memcpy(dst, src, 0x8); } +void cdimono2_state::machine_reset() +{ + cdi_state::machine_reset(); + m_porta_data = 0x00; + m_portb_data = 0x00; + m_portc_data = 0xfc; + m_portd_data = 0x20; +} + void quizard_state::machine_start() { save_item(NAME(m_seeds)); @@ -461,13 +549,18 @@ READ8_MEMBER(quizard_state::mcu_p1_r) READ16_MEMBER( cdi_state::dvc_r ) { - logerror("%s: dvc_r: %08x = 0000 & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), mem_mask); - return 0; + uint16_t data = 0; + if (offset == 0x3018/2) + { + data = 1; + } + logerror("%s: dvc_r: %08x = %04x & %04x\n", machine().describe_context(), 0xe00000 + (offset << 1), data, mem_mask); + return data; } WRITE16_MEMBER( cdi_state::dvc_w ) { - logerror("%s: dvc_w: %08x = %04x & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), data, mem_mask); + logerror("%s: dvc_w: %08x = %04x & %04x\n", machine().describe_context(), 0xe00000 + (offset << 1), data, mem_mask); } /************************* @@ -537,6 +630,70 @@ uint32_t cdi_state::screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb return 0; } +READ8_MEMBER(cdimono2_state::slave_porta_r) +{ + logerror("%s: slave_porta_r: %02x & %02x\n", machine().describe_context(), m_porta_data, mem_mask); + return m_porta_data & mem_mask; +} + +READ8_MEMBER(cdimono2_state::slave_portb_r) +{ + logerror("%s: slave_portb_r: %02x & %02x\n", machine().describe_context(), m_portb_data, mem_mask); + return m_portb_data & mem_mask; +} + +READ8_MEMBER(cdimono2_state::slave_portc_r) +{ + logerror("%s: slave_portc_r: %02x & %02x\n", machine().describe_context(), m_portc_data, mem_mask); + return m_portc_data & mem_mask; +} + +READ8_MEMBER(cdimono2_state::slave_portd_r) +{ + logerror("%s: slave_portd_r: %02x & %02x\n", machine().describe_context(), m_portd_data, mem_mask); + return m_portd_data & mem_mask; +} + +WRITE8_MEMBER(cdimono2_state::slave_porta_w) +{ + logerror("%s: slave_porta_w: %02x\n", machine().describe_context(), data); + m_porta_data &= ~mem_mask; + m_porta_data |= data & mem_mask; +} + +WRITE8_MEMBER(cdimono2_state::slave_portb_w) +{ + const uint8_t old = m_portb_data; + m_portb_data = data; + logerror("%s: slave_portb_w: %02x\n", machine().describe_context(), data); + if (!(old & 0x40) && (data & 0x40)) + { + m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + } +} + +WRITE8_MEMBER(cdimono2_state::servo_portb_w) +{ + logerror("%s: servo_portb_w: %02x\n", machine().describe_context(), data); + if (BIT(data, 7)) + m_portd_data &= ~0x20; + else + m_portd_data |= 0x20; +} + +WRITE8_MEMBER(cdimono2_state::slave_portc_w) +{ + logerror("%s: slave_portc_w: %02x DISDAT=%u DISCLK=%u DISEN=%u RTSUART=%u\n", machine().describe_context(), data, 1-BIT(data,3), 1-BIT(data,4), 1-BIT(data,5), 1-BIT(data,6)); + m_portc_data &= ~mem_mask; + m_portc_data |= data & mem_mask; + m_portc_data |= 0x80; +} + +WRITE8_MEMBER(cdimono2_state::slave_portd_w) +{ + logerror("%s: slave_portd_w: %02x\n", machine().describe_context(), data); +} + /************************* * Machine Drivers * *************************/ @@ -551,14 +708,15 @@ void cdi_state::cdimono1_base(machine_config &config) MCD212(config, m_mcd212, CLOCK_A); m_mcd212->set_screen("screen"); m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); - m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(384, 302); - screen.set_visarea(0, 384-1, 22, 302-1); // TODO: dynamic resolution + screen.set_size(384, 262); + screen.set_visarea(0, 384-1, 0, 262-1); // TODO: dynamic resolution screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update)); + screen.scanline().set(m_mcd212, FUNC(mcd212_device::scanline_cb)); + screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::vblank_cb)); SCREEN(config, m_lcd, SCREEN_TYPE_RASTER); m_lcd->set_refresh_hz(60); @@ -598,36 +756,53 @@ void cdi_state::cdimono1_base(machine_config &config) } // CD-i model 220 (Mono-II, NTSC) -void cdi_state::cdimono2(machine_config &config) +void cdimono2_state::cdimono2(machine_config &config) { SCC68070(config, m_maincpu, CLOCK_A); - m_maincpu->set_addrmap(AS_PROGRAM, &cdi_state::cdimono2_mem); + m_maincpu->set_addrmap(AS_PROGRAM, &cdimono2_state::cdimono2_mem); MCD212(config, m_mcd212, CLOCK_A); m_mcd212->set_screen("screen"); m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); - m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd)); + m_mcd212->set_scanline_callback(FUNC(cdimono2_state::draw_lcd)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(384, 302); - screen.set_visarea(0, 384-1, 22, 302-1); // TODO: dynamic resolution + screen.set_size(384, 262); + screen.set_visarea(0, 384-1, 0, 262-1); // TODO: dynamic resolution screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update)); + screen.scanline().set(m_mcd212, FUNC(mcd212_device::scanline_cb)); + screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::vblank_cb)); SCREEN(config, m_lcd, SCREEN_TYPE_RASTER); m_lcd->set_refresh_hz(60); m_lcd->set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_lcd->set_size(192, 22); m_lcd->set_visarea(0, 192-1, 0, 22-1); - m_lcd->set_screen_update(FUNC(cdi_state::screen_update_cdimono1_lcd)); + m_lcd->set_screen_update(FUNC(cdimono2_state::screen_update_cdimono1_lcd)); PALETTE(config, "palette").set_entries(0x100); config.set_default_layout(layout_cdi); M68HC05C8(config, m_servo, 4_MHz_XTAL); + m_servo->portb_w().set(FUNC(cdimono2_state::servo_portb_w)); + m_servo->sck_out().set(m_slave, FUNC(m68hc05c8_device::sck_in)); + m_servo->sda_out().set(m_slave, FUNC(m68hc05c8_device::sda_in)); + M68HC05C8(config, m_slave, 4_MHz_XTAL); + m_slave->uart_tx().set(FUNC(cdimono2_state::controller_tx)); + m_slave->porta_r().set(FUNC(cdimono2_state::slave_porta_r)); + m_slave->portb_r().set(FUNC(cdimono2_state::slave_portb_r)); + m_slave->portc_r().set(FUNC(cdimono2_state::slave_portc_r)); + m_slave->portd_r().set(FUNC(cdimono2_state::slave_portd_r)); + m_slave->porta_w().set(FUNC(cdimono2_state::slave_porta_w)); + m_slave->portb_w().set(FUNC(cdimono2_state::slave_portb_w)); + m_slave->portc_w().set(FUNC(cdimono2_state::slave_portc_w)); + m_slave->portd_w().set(FUNC(cdimono2_state::slave_portd_w)); + m_slave->sck_out().set(m_servo, FUNC(m68hc05c8_device::sck_in)); + m_slave->sda_out().set(m_servo, FUNC(m68hc05c8_device::sda_in)); CDROM(config, "cdrom").set_interface("cdi_cdrom"); SOFTWARE_LIST(config, "cd_list").set_original("cdi").set_filter("!DVC"); @@ -649,29 +824,31 @@ void cdi_state::cdimono2(machine_config &config) MK48T08(config, "mk48t08"); } -void cdi_state::cdi910(machine_config &config) +void cdimono2_state::cdi910(machine_config &config) { SCC68070(config, m_maincpu, CLOCK_A); - m_maincpu->set_addrmap(AS_PROGRAM, &cdi_state::cdi910_mem); + m_maincpu->set_addrmap(AS_PROGRAM, &cdimono2_state::cdi910_mem); MCD212(config, m_mcd212, CLOCK_A); m_mcd212->set_screen("screen"); m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); - m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd)); + m_mcd212->set_scanline_callback(FUNC(cdimono2_state::draw_lcd)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(384, 302); - screen.set_visarea(0, 384-1, 22, 302-1); // TODO: dynamic resolution + screen.set_size(384, 262); + screen.set_visarea(0, 384-1, 0, 262-1); // TODO: dynamic resolution screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update)); + screen.scanline().set(m_mcd212, FUNC(mcd212_device::scanline_cb)); + screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::vblank_cb)); SCREEN(config, m_lcd, SCREEN_TYPE_RASTER); m_lcd->set_refresh_hz(60); m_lcd->set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_lcd->set_size(192, 22); m_lcd->set_visarea(0, 192-1, 0, 22-1); - m_lcd->set_screen_update(FUNC(cdi_state::screen_update_cdimono1_lcd)); + m_lcd->set_screen_update(FUNC(cdimono2_state::screen_update_cdimono1_lcd)); PALETTE(config, "palette").set_entries(0x100); @@ -709,6 +886,16 @@ void cdi_state::cdimono1(machine_config &config) SOFTWARE_LIST(config, "cd_list").set_original("cdi").set_filter("!DVC"); } +// CD-i Mono-I, with DVC cartridge and images +void cdi_state::cdimono1_dvc(machine_config &config) +{ + cdimono1_base(config); + m_maincpu->set_addrmap(AS_PROGRAM, &cdi_state::cdimono1_dvc_mem); + + CDROM(config, "cdrom").set_interface("cdi_cdrom"); + SOFTWARE_LIST(config, "cd_list").set_original("cdi"); +} + void quizard_state::quizard(machine_config &config) { cdimono1_base(config); @@ -739,7 +926,25 @@ ROM_START( cdimono1 ) ROM_LOAD( "slave.bin", 0x0000, 0x2000, NO_DUMP ) // Undumped 68HC05 microcontroller, might need decapping ROM_END +ROM_START( cdimono1_dvc ) + ROM_REGION(0x80000, "maincpu", 0) // these roms need byteswapping + ROM_SYSTEM_BIOS( 0, "mcdi200", "Magnavox CD-i 200" ) + ROMX_LOAD( "cdi200.rom", 0x000000, 0x80000, CRC(40c4e6b9) SHA1(d961de803c89b3d1902d656ceb9ce7c02dccb40a), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "pcdi220", "Philips CD-i 220 F2" ) + ROMX_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 2, "pcdi220_alt", "Philips CD-i 220?" ) // doesn't boot + ROMX_LOAD( "cdi220.rom", 0x000000, 0x80000, CRC(584c0af8) SHA1(5d757ab46b8c8fc36361555d978d7af768342d47), ROM_BIOS(2) ) + + ROM_REGION(0x2000, "cdic", 0) + ROM_LOAD( "cdic.bin", 0x0000, 0x2000, NO_DUMP ) // Undumped 68HC05 microcontroller, might need decapping + + ROM_REGION(0x2000, "slave", 0) + ROM_LOAD( "slave.bin", 0x0000, 0x2000, NO_DUMP ) // Undumped 68HC05 microcontroller, might need decapping + ROM_REGION16_BE(0x40000, "dvc", 0) + ROM_LOAD16_BYTE( "cdi-fmv1.bin", 0x00000, 0x10000, CRC(12345678) SHA1(1234567812345678123456781234567812345678) ) + ROM_LOAD16_BYTE( "cdi-fmv2.bin", 0x00001, 0x10000, CRC(12345678) SHA1(1234567812345678123456781234567812345678) ) +ROM_END ROM_START( cdi910 ) ROM_REGION(0x80000, "maincpu", 0) @@ -1016,12 +1221,13 @@ ROM_END * Game driver(s) * *************************/ -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ // BIOS / System -CONS( 1991, cdimono1, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i (Mono-I) (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -CONS( 1991, cdimono2, 0, 0, cdimono2, cdimono2, cdi_state, empty_init, "Philips", "CD-i (Mono-II) (NTSC)", MACHINE_NOT_WORKING ) -CONS( 1991, cdi910, 0, 0, cdi910, cdimono2, cdi_state, empty_init, "Philips", "CD-i 910-17P Mini-MMC (PAL)", MACHINE_NOT_WORKING ) -CONS( 1991, cdi490a, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i 490", MACHINE_NOT_WORKING ) +CONS( 1991, cdimono1, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i (Mono-I) (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +CONS( 1991, cdimono1_dvc, cdimono1, cdimono1, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i (Mono-I) (PAL) (w/ DVC)", MACHINE_NOT_WORKING ) +CONS( 1991, cdimono2, 0, 0, cdimono2, cdimono2, cdimono2_state, empty_init, "Philips", "CD-i (Mono-II) (NTSC)", MACHINE_NOT_WORKING ) +CONS( 1991, cdi910, 0, 0, cdi910, cdimono2, cdimono2_state, empty_init, "Philips", "CD-i 910-17P Mini-MMC (PAL)", MACHINE_NOT_WORKING ) +CONS( 1991, cdi490a, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i 490", MACHINE_NOT_WORKING ) // The Quizard games are RETAIL CD-i units, with additional JAMMA adapters & dongles for protection, hence being 'clones' of the system. /* YEAR NAME PARENT MACHINE INPUT DEVICE INIT MONITOR COMPANY FULLNAME */ diff --git a/src/mame/includes/cdi.h b/src/mame/includes/cdi.h index a6f0d03713e..f8c40130cc1 100644 --- a/src/mame/includes/cdi.h +++ b/src/mame/includes/cdi.h @@ -23,8 +23,6 @@ public: , m_maincpu(*this, "maincpu") , m_planea(*this, "mcd212:planea") , m_slave_hle(*this, "slave_hle") - , m_servo(*this, "servo") - , m_slave(*this, "slave") , m_cdic(*this, "cdic") , m_cdda(*this, "cdda") , m_mcd212(*this, "mcd212") @@ -34,18 +32,19 @@ public: void cdimono1_base(machine_config &config); void cdimono1(machine_config &config); - void cdimono2(machine_config &config); - void cdi910(machine_config &config); + void cdimono1_dvc(machine_config &config); protected: + virtual void machine_start() override { } virtual void machine_reset() override; + virtual void video_start() override; void cdimono1_mem(address_map &map); + void cdimono1_dvc_mem(address_map &map); required_device<scc68070_device> m_maincpu; -private: - virtual void video_start() override; + DECLARE_READ16_MEMBER(uart_loopback_enable); enum servo_portc_bit_t { @@ -57,17 +56,11 @@ private: void draw_lcd(int y); uint32_t screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void cdi910_mem(address_map &map); - void cdimono2_mem(address_map &map); - void cdi070_cpuspace(address_map &map); - DECLARE_READ16_MEMBER(dvc_r); DECLARE_WRITE16_MEMBER(dvc_w); required_shared_ptr<uint16_t> m_planea; optional_device<cdislave_device> m_slave_hle; - optional_device<m68hc05c8_device> m_servo; - optional_device<m68hc05c8_device> m_slave; optional_device<cdicdic_device> m_cdic; required_device<cdda_device> m_cdda; required_device<mcd212_device> m_mcd212; @@ -78,6 +71,55 @@ private: bitmap_rgb32 m_lcdbitmap; }; +class cdimono2_state : public cdi_state +{ +public: + cdimono2_state(const machine_config &mconfig, device_type type, const char *tag) + : cdi_state(mconfig, type, tag) + , m_servo(*this, "servo") + , m_slave(*this, "slave") + { } + + void cdimono2(machine_config &config); + void cdi910(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + void cdi910_mem(address_map &map); + void cdimono2_mem(address_map &map); + + DECLARE_READ8_MEMBER(slave_porta_r); + DECLARE_READ8_MEMBER(slave_portb_r); + DECLARE_READ8_MEMBER(slave_portc_r); + DECLARE_READ8_MEMBER(slave_portd_r); + DECLARE_WRITE8_MEMBER(slave_porta_w); + DECLARE_WRITE8_MEMBER(slave_portb_w); + DECLARE_WRITE8_MEMBER(slave_portc_w); + DECLARE_WRITE8_MEMBER(slave_portd_w); + DECLARE_WRITE8_MEMBER(servo_portb_w); + + DECLARE_READ8_MEMBER(slave_glue_r); + DECLARE_WRITE8_MEMBER(slave_glue_w); + + DECLARE_READ8_MEMBER(dsp_r); + DECLARE_WRITE8_MEMBER(dsp_w); + + DECLARE_WRITE8_MEMBER(controller_tx); + + DECLARE_READ16_MEMBER(uart_loopback_enable2); + + required_device<m68hc05c8_device> m_servo; + required_device<m68hc05c8_device> m_slave; + + uint8_t m_porta_data; + uint8_t m_portb_data; + uint8_t m_portc_data; + uint8_t m_portd_data; +}; + class quizard_state : public cdi_state { public: diff --git a/src/mame/video/mcd212.cpp b/src/mame/video/mcd212.cpp index a6c394a40cb..9e6e7d365fc 100644 --- a/src/mame/video/mcd212.cpp +++ b/src/mame/video/mcd212.cpp @@ -26,29 +26,23 @@ TODO: #include "screen.h" -#define ENABLE_VERBOSE_LOG 0 - +#define LOG_UNKNOWNS (1 << 0) +#define LOG_CLUT (1 << 1) +#define LOG_ICA (1 << 2) +#define LOG_DCA (1 << 3) +#define LOG_STATUS (1 << 4) +#define LOG_READS (1 << 5) +#define LOG_WRITES (1 << 6) +#define LOG_FRAMES (1 << 7) +#define LOG_SCANLINES (1 << 8) +#define LOG_ALL (LOG_UNKNOWNS | LOG_CLUT | LOG_ICA | LOG_DCA | LOG_STATUS | LOG_READS | LOG_WRITES | LOG_FRAMES | LOG_SCANLINES) + +#define VERBOSE (0) +#include "logmacro.h" // device type definition DEFINE_DEVICE_TYPE(MCD212, mcd212_device, "mcd212", "MCD212 VDSC") -#if ENABLE_VERBOSE_LOG -static inline void ATTR_PRINTF(3,4) verboselog(device_t& device, int n_level, const char *s_fmt, ...) -{ - if( VERBOSE_LEVEL >= n_level ) - { - va_list v; - char buf[ 32768 ]; - va_start( v, s_fmt ); - vsprintf( buf, s_fmt, v ); - va_end( v ); - device.logerror("%s: %s", device.machine().describe_context(), buf ); - } -} -#else -#define verboselog(x,y,z, ...) -#endif - void mcd212_device::update_region_arrays() { int latched_rf0 = 0; @@ -57,21 +51,21 @@ void mcd212_device::update_region_arrays() int latched_wfb = m_channel[1].weight_factor_b[0]; int reg = 0; - for(int x = 0; x < 768; x++) + for (int x = 0; x < 768; x++) { - if(m_channel[0].image_coding_method & MCD212_ICM_NR) + if (m_channel[0].image_coding_method & MCD212_ICM_NR) { - for(int flag = 0; flag < 2; flag++) + for (int flag = 0; flag < 2; flag++) { - for(int reg_ = 0; reg_ < 4; reg_++) + for (int reg_ = 0; reg_ < 4; reg_++) { - if(m_channel[0].region_control[reg_] == 0) + if (m_channel[0].region_control[reg_] == 0) { break; } - if(x == (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_X)) + if (x == (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_X)) { - switch((m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) + switch ((m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) { case 0: // End of region control for line break; @@ -90,7 +84,7 @@ void mcd212_device::update_region_arrays() case 7: // Not used break; case 8: // Reset region flag - if(flag) + if (flag) { latched_rf1 = 0; } @@ -100,7 +94,7 @@ void mcd212_device::update_region_arrays() } break; case 9: // Set region flag - if(flag) + if (flag) { latched_rf1 = 1; } @@ -114,7 +108,7 @@ void mcd212_device::update_region_arrays() break; case 12: // Reset region flag and change weight of plane A latched_wfa = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 0; } @@ -125,7 +119,7 @@ void mcd212_device::update_region_arrays() break; case 13: // Set region flag and change weight of plane A latched_wfa = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 1; } @@ -136,7 +130,7 @@ void mcd212_device::update_region_arrays() break; case 14: // Reset region flag and change weight of plane B latched_wfb = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 0; } @@ -147,7 +141,7 @@ void mcd212_device::update_region_arrays() break; case 15: // Set region flag and change weight of plane B latched_wfb = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 1; } @@ -163,12 +157,12 @@ void mcd212_device::update_region_arrays() } else { - if(reg < 8) + if (reg < 8) { int flag = (m_channel[0].region_control[reg] & MCD212_RC_RF) >> MCD212_RC_RF_SHIFT; - if(!(m_channel[0].region_control[reg] & MCD212_RC_OP)) + if (!(m_channel[0].region_control[reg] & MCD212_RC_OP)) { - for(; x < 768; x++) + for (; x < 768; x++) { m_channel[0].weight_factor_a[x] = latched_wfa; m_channel[1].weight_factor_b[x] = latched_wfb; @@ -177,9 +171,9 @@ void mcd212_device::update_region_arrays() } break; } - if(x == (m_channel[0].region_control[reg] & MCD212_RC_X)) + if (x == (m_channel[0].region_control[reg] & MCD212_RC_X)) { - switch((m_channel[0].region_control[reg] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) + switch ((m_channel[0].region_control[reg] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) { case 0: // End of region control for line break; @@ -198,7 +192,7 @@ void mcd212_device::update_region_arrays() case 7: // Not used break; case 8: // Reset region flag - if(flag) + if (flag) { latched_rf1 = 0; } @@ -208,7 +202,7 @@ void mcd212_device::update_region_arrays() } break; case 9: // Set region flag - if(flag) + if (flag) { latched_rf1 = 1; } @@ -222,7 +216,7 @@ void mcd212_device::update_region_arrays() break; case 12: // Reset region flag and change weight of plane A latched_wfa = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 0; } @@ -233,7 +227,7 @@ void mcd212_device::update_region_arrays() break; case 13: // Set region flag and change weight of plane A latched_wfa = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 1; } @@ -244,7 +238,7 @@ void mcd212_device::update_region_arrays() break; case 14: // Reset region flag and change weight of plane B latched_wfb = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 0; } @@ -255,7 +249,7 @@ void mcd212_device::update_region_arrays() break; case 15: // Set region flag and change weight of plane B latched_wfb = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; - if(flag) + if (flag) { latched_rf1 = 1; } @@ -285,7 +279,7 @@ void mcd212_device::set_vsr(int channel, uint32_t value) void mcd212_device::set_register(int channel, uint8_t reg, uint32_t value) { - switch(reg) + switch (reg) { case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: // CLUT 0 - 63 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: @@ -295,96 +289,96 @@ void mcd212_device::set_register(int channel, uint8_t reg, uint32_t value) case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - verboselog(*this, 11, " %04xxxxx: %d: CLUT[%d] = %08x\n", channel * 0x20, channel, m_channel[channel].clut_bank * 0x40 + (reg - 0x80), value ); + LOGMASKED(LOG_CLUT, "%04xxxxx: %d: CLUT[%d] = %08x\n", channel * 0x20, channel, m_channel[channel].clut_bank * 0x40 + (reg - 0x80), value ); m_channel[0].clut_r[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (uint8_t)(value >> 16) & 0xfc; m_channel[0].clut_g[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (uint8_t)(value >> 8) & 0xfc; m_channel[0].clut_b[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (uint8_t)(value >> 0) & 0xfc; break; case 0xc0: // Image Coding Method - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Image Coding Method = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Image Coding Method = %08x\n", channel * 0x20, channel, value ); m_channel[channel].image_coding_method = value; } break; case 0xc1: // Transparency Control - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Transparency Control = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Transparency Control = %08x\n", channel * 0x20, channel, value ); m_channel[channel].transparency_control = value; } break; case 0xc2: // Plane Order - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Plane Order = %08x\n", channel * 0x20, channel, value & 7); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Plane Order = %08x\n", channel * 0x20, channel, value & 7); m_channel[channel].plane_order = value & 0x00000007; } break; case 0xc3: // CLUT Bank Register - verboselog(*this, 6, " %04xxxxx: %d: CLUT Bank Register = %08x\n", channel * 0x20, channel, value & 3); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: CLUT Bank Register = %08x\n", channel * 0x20, channel, value & 3); m_channel[channel].clut_bank = channel ? (2 | (value & 0x00000001)) : (value & 0x00000003); break; case 0xc4: // Transparent Color A - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Transparent Color A = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Transparent Color A = %08x\n", channel * 0x20, channel, value ); m_channel[channel].transparent_color_a = value & 0xfcfcfc; } break; case 0xc6: // Transparent Color B - if(channel == 1) + if (channel == 1) { - verboselog(*this, 6, " %04xxxxx: %d: Transparent Color B = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Transparent Color B = %08x\n", channel * 0x20, channel, value ); m_channel[channel].transparent_color_b = value & 0xfcfcfc; } break; case 0xc7: // Mask Color A - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Mask Color A = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Mask Color A = %08x\n", channel * 0x20, channel, value ); m_channel[channel].mask_color_a = value & 0xfcfcfc; } break; case 0xc9: // Mask Color B - if(channel == 1) + if (channel == 1) { - verboselog(*this, 6, " %04xxxxx: %d: Mask Color B = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Mask Color B = %08x\n", channel * 0x20, channel, value ); m_channel[channel].mask_color_b = value & 0xfcfcfc; } break; case 0xca: // Delta YUV Absolute Start Value A - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Delta YUV Absolute Start Value A = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Delta YUV Absolute Start Value A = %08x\n", channel * 0x20, channel, value ); m_channel[channel].dyuv_abs_start_a = value; } break; case 0xcb: // Delta YUV Absolute Start Value B - if(channel == 1) + if (channel == 1) { - verboselog(*this, 6, " %04xxxxx: %d: Delta YUV Absolute Start Value B = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Delta YUV Absolute Start Value B = %08x\n", channel * 0x20, channel, value ); m_channel[channel].dyuv_abs_start_b = value; } break; case 0xcd: // Cursor Position - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Cursor Position = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Cursor Position = %08x\n", channel * 0x20, channel, value ); m_channel[channel].cursor_position = value; } break; case 0xce: // Cursor Control - if(channel == 0) + if (channel == 0) { - verboselog(*this, 11, " %04xxxxx: %d: Cursor Control = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Cursor Control = %08x\n", channel * 0x20, channel, value ); m_channel[channel].cursor_control = value; } break; case 0xcf: // Cursor Pattern - if(channel == 0) + if (channel == 0) { - verboselog(*this, 11, " %04xxxxx: %d: Cursor Pattern[%d] = %04x\n", channel * 0x20, channel, (value >> 16) & 0x000f, value & 0x0000ffff); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Cursor Pattern[%d] = %04x\n", channel * 0x20, channel, (value >> 16) & 0x000f, value & 0x0000ffff); m_channel[channel].cursor_pattern[(value >> 16) & 0x000f] = value & 0x0000ffff; } break; @@ -396,43 +390,43 @@ void mcd212_device::set_register(int channel, uint8_t reg, uint32_t value) case 0xd5: case 0xd6: case 0xd7: - verboselog(*this, 6, " %04xxxxx: %d: Region Control %d = %08x\n", channel * 0x20, channel, reg & 7, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Region Control %d = %08x\n", channel * 0x20, channel, reg & 7, value ); m_channel[0].region_control[reg & 7] = value; update_region_arrays(); break; case 0xd8: // Backdrop Color - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Backdrop Color = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Backdrop Color = %08x\n", channel * 0x20, channel, value ); m_channel[channel].backdrop_color = value; } break; case 0xd9: // Mosaic Pixel Hold Factor A - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Mosaic Pixel Hold Factor A = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Mosaic Pixel Hold Factor A = %08x\n", channel * 0x20, channel, value ); m_channel[channel].mosaic_hold_a = value; } break; case 0xda: // Mosaic Pixel Hold Factor B - if(channel == 1) + if (channel == 1) { - verboselog(*this, 6, " %04xxxxx: %d: Mosaic Pixel Hold Factor B = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Mosaic Pixel Hold Factor B = %08x\n", channel * 0x20, channel, value ); m_channel[channel].mosaic_hold_b = value; } break; case 0xdb: // Weight Factor A - if(channel == 0) + if (channel == 0) { - verboselog(*this, 6, " %04xxxxx: %d: Weight Factor A = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Weight Factor A = %08x\n", channel * 0x20, channel, value ); memset(m_channel[channel].weight_factor_a, value & 0x000000ff, 768); update_region_arrays(); } break; case 0xdc: // Weight Factor B - if(channel == 1) + if (channel == 1) { - verboselog(*this, 6, " %04xxxxx: %d: Weight Factor B = %08x\n", channel * 0x20, channel, value ); + LOGMASKED(LOG_WRITES, " %04xxxxx: %d: Weight Factor B = %08x\n", channel * 0x20, channel, value ); memset(m_channel[channel].weight_factor_b, value & 0x000000ff, 768); update_region_arrays(); } @@ -472,7 +466,7 @@ void mcd212_device::update_visible_area() attoseconds_t period = screen().frame_period().attoseconds(); int width = 0; - if((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) + if ((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) { width = 360; } @@ -491,7 +485,7 @@ void mcd212_device::update_visible_area() uint32_t mcd212_device::get_screen_width() { - if((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) + if ((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) { return 720; } @@ -508,55 +502,55 @@ void mcd212_device::process_ica(int channel) uint8_t stop = 0; cmd = ica[addr++] << 16; cmd |= ica[addr++]; - switch((cmd & 0xff000000) >> 24) + switch ((cmd & 0xff000000) >> 24) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // STOP case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - verboselog(*this, 11, "%08x: %08x: ICA %d: STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); stop = 1; break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: // NOP case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - verboselog(*this, 12, "%08x: %08x: ICA %d: NOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: NOP\n", addr * 2 + channel * 0x200000, cmd, channel ); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // RELOAD DCP case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - verboselog(*this, 11, "%08x: %08x: ICA %d: RELOAD DCP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP\n", addr * 2 + channel * 0x200000, cmd, channel ); set_dcp(channel, cmd & 0x001fffff); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - verboselog(*this, 11, "%08x: %08x: ICA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); set_dcp(channel, cmd & 0x001fffff); stop = 1; break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD ICA case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - verboselog(*this, 11, "%08x: %08x: ICA %d: RELOAD ICA\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD ICA\n", addr * 2 + channel * 0x200000, cmd, channel ); addr = (cmd & 0x001fffff) / 2; break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - verboselog(*this, 11, "%08x: %08x: ICA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); set_vsr(channel, cmd & 0x001fffff); stop = 1; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - verboselog(*this, 11, "%08x: %08x: ICA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); m_channel[1].csrr |= 1 << (2 - channel); - if(m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) + if (m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) m_int_callback(ASSERT_LINE); break; case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS - verboselog(*this, 6, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); set_display_parameters(channel, cmd & 0x1f); break; default: set_register(channel, cmd >> 24, cmd & 0x00ffffff); break; } - if(stop) + if (stop) { break; } @@ -578,24 +572,24 @@ void mcd212_device::process_dca(int channel) cmd = dca[addr++] << 16; cmd |= dca[addr++]; count += 4; - switch((cmd & 0xff000000) >> 24) + switch ((cmd & 0xff000000) >> 24) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // STOP case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - verboselog(*this, 11, "%08x: %08x: DCA %d: STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); stop = 1; break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: // NOP case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - verboselog(*this, 12, "%08x: %08x: DCA %d: NOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: NOP\n", addr * 2 + channel * 0x200000, cmd, channel ); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // RELOAD DCP case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - verboselog(*this, 11, "%08x: %08x: DCA %d: RELOAD DCP (NOP)\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP (NOP)\n", addr * 2 + channel * 0x200000, cmd, channel ); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - verboselog(*this, 11, "%08x: %08x: DCA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); set_dcp(channel, cmd & 0x001fffff); addr = (cmd & 0x0007ffff) / 2; addr_changed = 1; @@ -603,38 +597,38 @@ void mcd212_device::process_dca(int channel) break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD VSR case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - verboselog(*this, 11, "%08x: %08x: DCA %d: RELOAD VSR\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR\n", addr * 2 + channel * 0x200000, cmd, channel ); set_vsr(channel, cmd & 0x001fffff); break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - verboselog(*this, 11, "%08x: %08x: DCA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); set_vsr(channel, cmd & 0x001fffff); stop = 1; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - verboselog(*this, 11, "%08x: %08x: DCA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); m_channel[1].csrr |= 1 << (2 - channel); - if(m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) + if (m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) m_int_callback(ASSERT_LINE); break; case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS - verboselog(*this, 6, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); set_display_parameters(channel, cmd & 0x1f); break; default: set_register(channel, cmd >> 24, cmd & 0x00ffffff); break; } - if(stop != 0 || count == max) + if (stop != 0 || count == max) { break; } } - if(!addr_changed) + if (!addr_changed) { - if(count < max) + if (count < max) { addr += (max - count) >> 1; } @@ -644,11 +638,11 @@ void mcd212_device::process_dca(int channel) static inline uint8_t MCD212_LIM(int32_t in) { - if(in < 0) + if (in < 0) { return 0; } - else if(in > 255) + else if (in > 255) { return 255; } @@ -657,12 +651,12 @@ static inline uint8_t MCD212_LIM(int32_t in) static inline uint8_t BYTE_TO_CLUT(int channel, int icm, uint8_t byte) { - switch(icm) + switch (icm) { case 1: return byte; case 3: - if(channel) + if (channel) { return 0x80 + (byte & 0x7f); } @@ -671,13 +665,13 @@ static inline uint8_t BYTE_TO_CLUT(int channel, int icm, uint8_t byte) return byte & 0x7f; } case 4: - if(!channel) + if (!channel) { return byte & 0x7f; } break; case 11: - if(channel) + if (channel) { return 0x80 + (byte & 0x0f); } @@ -711,7 +705,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ //printf( "vsr before: %08x: ", vsr ); //fflush(stdout); - if(!icm || !vsr) + if (!icm || !vsr) { memset(pixels_r, 0x10, width); memset(pixels_g, 0x10, width); @@ -723,25 +717,25 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ { uint8_t byte = data[(vsr & 0x0007ffff) ^ 1]; vsr++; - switch(m_channel[channel].ddr & MCD212_DDR_FT) + switch (m_channel[channel].ddr & MCD212_DDR_FT) { case MCD212_DDR_FT_BMP: case MCD212_DDR_FT_BMP2: case MCD212_DDR_FT_MOSAIC: - if(m_channel[channel].dcr & MCD212_DCR_CM) + if (m_channel[channel].dcr & MCD212_DCR_CM) { // 4-bit Bitmap - verboselog(*this, 0, "%s", "Unsupported display mode: 4-bit Bitmap\n" ); + LOGMASKED(LOG_UNKNOWNS, "%s", "Unsupported display mode: 4-bit Bitmap\n" ); } else { // 8-bit Bitmap - if(icm == 5) + if (icm == 5) { BYTE68K bY; BYTE68K bU; BYTE68K bV; - switch(channel) + switch (channel) { case 0: bY = (m_channel[0].dyuv_abs_start_a >> 16) & 0x000000ff; @@ -757,7 +751,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ bY = bU = bV = 0x80; break; } - for(; x < width; x += 2) + for (; x < width; x += 2) { BYTE68K b0 = byte; BYTE68K bU1 = bU + m_ab.deltaUV[b0]; @@ -784,9 +778,9 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[m_ab.matrixUG[bU] + m_ab.matrixVG[bV]]; pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[m_ab.matrixUB[bU]]; - if(mosaic_enable) + if (mosaic_enable) { - for(mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) + for (mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) { pixels_r[x + 0 + mosaic_index*2] = pixels_r[x + 0]; pixels_g[x + 0 + mosaic_index*2] = pixels_g[x + 0]; @@ -812,9 +806,9 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[m_ab.matrixUG[bU] + m_ab.matrixVG[bV]]; pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[m_ab.matrixUB[bU]]; - if(mosaic_enable) + if (mosaic_enable) { - for(mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) + for (mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) { pixels_r[x + 0 + mosaic_index*2] = pixels_r[x + 0]; pixels_g[x + 0 + mosaic_index*2] = pixels_g[x + 0]; @@ -832,9 +826,9 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ } set_vsr(channel, (vsr - 1) & 0x0007ffff); } - else if(icm == 1 || icm == 3 || icm == 4) + else if (icm == 1 || icm == 3 || icm == 4) { - for(; x < width; x += 2) + for (; x < width; x += 2) { uint8_t clut_entry = BYTE_TO_CLUT(channel, icm, byte); pixels_r[x + 0] = clut_r[clut_entry]; @@ -843,9 +837,9 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ pixels_r[x + 1] = clut_r[clut_entry]; pixels_g[x + 1] = clut_g[clut_entry]; pixels_b[x + 1] = clut_b[clut_entry]; - if(mosaic_enable) + if (mosaic_enable) { - for(mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) + for (mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) { pixels_r[x + 0 + mosaic_index*2] = pixels_r[x + 0]; pixels_g[x + 0 + mosaic_index*2] = pixels_g[x + 0]; @@ -861,21 +855,21 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ } set_vsr(channel, (vsr - 1) & 0x0007ffff); } - else if(icm == 11) + else if (icm == 11) { - for(; x < width; x += 2) + for (; x < width; x += 2) { uint8_t even_entry = BYTE_TO_CLUT(channel, icm, byte >> 4); uint8_t odd_entry = BYTE_TO_CLUT(channel, icm, byte); - if(mosaic_enable) + if (mosaic_enable) { - for(mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) + for (mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) { pixels_r[x + mosaic_index] = clut_r[even_entry]; pixels_g[x + mosaic_index] = clut_g[even_entry]; pixels_b[x + mosaic_index] = clut_b[even_entry]; } - for(mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) + for (mosaic_index = 0; mosaic_index < mosaic_factor; mosaic_index++) { pixels_r[x + mosaic_factor + mosaic_index] = clut_r[odd_entry]; pixels_g[x + mosaic_factor + mosaic_index] = clut_g[odd_entry]; @@ -899,7 +893,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ } else { - for(; x < width; x++) + for (; x < width; x++) { pixels_r[x] = 0x10; pixels_g[x] = 0x10; @@ -910,25 +904,25 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ done = 1; break; case MCD212_DDR_FT_RLE: - if(m_channel[channel].dcr & MCD212_DCR_CM) + if (m_channel[channel].dcr & MCD212_DCR_CM) { - verboselog(*this, 0, "%s", "Unsupported display mode: 4-bit RLE\n" ); + LOGMASKED(LOG_UNKNOWNS, "%s", "Unsupported display mode: 4-bit RLE\n" ); done = 1; } else { - if(byte & 0x80) + if (byte & 0x80) { // Run length uint8_t length = data[((vsr++) & 0x0007ffff) ^ 1]; - if(!length) + if (!length) { uint8_t clut_entry = BYTE_TO_CLUT(channel, icm, byte); uint8_t r = clut_r[clut_entry]; uint8_t g = clut_g[clut_entry]; uint8_t b = clut_b[clut_entry]; // Go to the end of the line - for(; x < width; x++) + for (; x < width; x++) { pixels_r[x] = r; pixels_g[x] = g; @@ -948,7 +942,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ uint8_t r = clut_r[clut_entry]; uint8_t g = clut_g[clut_entry]; uint8_t b = clut_b[clut_entry]; - for(; x < end && x < width; x++) + for (; x < end && x < width; x++) { pixels_r[x] = r; pixels_g[x] = g; @@ -958,7 +952,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ pixels_g[x] = g; pixels_b[x] = b; } - if(x >= width) + if (x >= width) { done = 1; set_vsr(channel, vsr); @@ -977,7 +971,7 @@ void mcd212_device::process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_ pixels_g[x] = clut_g[clut_entry]; pixels_b[x] = clut_b[clut_entry]; x++; - if(x >= width) + if (x >= width) { done = 1; set_vsr(channel, vsr); @@ -1022,10 +1016,10 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p uint8_t mosaic_enable_b = (m_channel[1].mosaic_hold_b & 0x800000) >> 23; uint8_t mosaic_count_a = (m_channel[0].mosaic_hold_a & 0x0000ff) << 1; uint8_t mosaic_count_b = (m_channel[1].mosaic_hold_b & 0x0000ff) << 1; - for(int x = 0; x < 768; x++) + for (int x = 0; x < 768; x++) { out[x] = backdrop; - if(!(m_channel[0].transparency_control & MCD212_TCR_DISABLE_MX)) + if (!(m_channel[0].transparency_control & MCD212_TCR_DISABLE_MX)) { uint8_t abr = MCD212_LIM(((MCD212_LIM((int32_t)plane_a_r[x] - 16) * m_channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((int32_t)plane_b_r[x] - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); uint8_t abg = MCD212_LIM(((MCD212_LIM((int32_t)plane_a_g[x] - 16) * m_channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((int32_t)plane_b_g[x] - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); @@ -1042,7 +1036,7 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p uint8_t plane_b_r_cur = mosaic_enable_b ? plane_b_r[x - (x % mosaic_count_b)] : plane_b_r[x]; uint8_t plane_b_g_cur = mosaic_enable_b ? plane_b_g[x - (x % mosaic_count_b)] : plane_b_g[x]; uint8_t plane_b_b_cur = mosaic_enable_b ? plane_b_b[x - (x % mosaic_count_b)] : plane_b_b[x]; - switch(transparency_mode_a) + switch (transparency_mode_a) { case 0: plane_enable_a = 0; @@ -1081,11 +1075,11 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b) || dyuv_enable_a || m_region_flag_1[x] == 1; break; default: - verboselog(*this, 0, "Unhandled transparency mode for plane A: %d\n", transparency_mode_a); + LOGMASKED(LOG_UNKNOWNS, "Unhandled transparency mode for plane A: %d\n", transparency_mode_a); plane_enable_a = 1; break; } - switch(transparency_mode_b) + switch (transparency_mode_b) { case 0: plane_enable_b = 0; @@ -1124,15 +1118,15 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b) || dyuv_enable_b || m_region_flag_1[x] == 1; break; default: - verboselog(*this, 0, "Unhandled transparency mode for plane B: %d\n", transparency_mode_b); + LOGMASKED(LOG_UNKNOWNS, "Unhandled transparency mode for plane B: %d\n", transparency_mode_b); plane_enable_b = 1; break; } - if(global_plane_a_disable) + if (global_plane_a_disable) { plane_enable_a = 0; } - if(global_plane_b_disable) + if (global_plane_b_disable) { plane_enable_b = 0; } @@ -1142,24 +1136,24 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p plane_b_r_cur = MCD212_LIM(((MCD212_LIM((int32_t)plane_b_r_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); plane_b_g_cur = MCD212_LIM(((MCD212_LIM((int32_t)plane_b_g_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); plane_b_b_cur = MCD212_LIM(((MCD212_LIM((int32_t)plane_b_b_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); - switch(m_channel[0].plane_order) + switch (m_channel[0].plane_order) { case MCD212_POR_AB: - if(plane_enable_a) + if (plane_enable_a) { out[x] = (plane_a_r_cur << 16) | (plane_a_g_cur << 8) | plane_a_b_cur; } - else if(plane_enable_b) + else if (plane_enable_b) { out[x] = (plane_b_r_cur << 16) | (plane_b_g_cur << 8) | plane_b_b_cur; } break; case MCD212_POR_BA: - if(plane_enable_b) + if (plane_enable_b) { out[x] = (plane_b_r_cur << 16) | (plane_b_g_cur << 8) | plane_b_b_cur; } - else if(plane_enable_a) + else if (plane_enable_a) { out[x] = (plane_a_r_cur << 16) | (plane_a_g_cur << 8) | plane_a_b_cur; } @@ -1171,19 +1165,19 @@ void mcd212_device::mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *p void mcd212_device::draw_cursor(uint32_t *scanline, int y) { - if(m_channel[0].cursor_control & MCD212_CURCNT_EN) + if (m_channel[0].cursor_control & MCD212_CURCNT_EN) { uint16_t curx = m_channel[0].cursor_position & 0x3ff; uint16_t cury = ((m_channel[0].cursor_position >> 12) & 0x3ff) + 22; - if(y >= cury && y < (cury + 16)) + if (y >= cury && y < (cury + 16)) { uint32_t color = s_4bpp_color[m_channel[0].cursor_control & MCD212_CURCNT_COLOR]; y -= cury; - if(m_channel[0].cursor_control & MCD212_CURCNT_CUW) + if (m_channel[0].cursor_control & MCD212_CURCNT_CUW) { - for(int x = curx; x < curx + 64 && x < 768; x++) + for (int x = curx; x < curx + 64 && x < 768; x++) { - if(m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 2)))) + if (m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 2)))) { scanline[(x++)/2] = color; scanline[(x++)/2] = color; @@ -1197,9 +1191,9 @@ void mcd212_device::draw_cursor(uint32_t *scanline, int y) } else { - for(int x = curx; x < curx + 32 && x < 768; x++) + for (int x = curx; x < curx + 32 && x < 768; x++) { - if(m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 1)))) + if (m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 1)))) { scanline[(x++)/2] = color; scanline[x/2] = color; @@ -1216,14 +1210,13 @@ void mcd212_device::draw_scanline(int y) uint8_t plane_b_r[768], plane_b_g[768], plane_b_b[768]; uint32_t out[768]; uint32_t *scanline = &m_bitmap.pix32(y); - int x; process_vsr(0, plane_a_r, plane_a_g, plane_a_b); process_vsr(1, plane_b_r, plane_b_g, plane_b_b); mix_lines(plane_a_r, plane_a_g, plane_a_b, plane_b_r, plane_b_g, plane_b_b, out); - for(x = 0; x < 384; x++) + for (int x = 0; x < 384; x++) { scanline[x] = out[x*2]; } @@ -1231,18 +1224,19 @@ void mcd212_device::draw_scanline(int y) draw_cursor(scanline, y); } + READ16_MEMBER( mcd212_device::regs_r ) { uint8_t channel = 1 - (offset / 8); - switch(offset) + switch (offset) { case 0x00/2: case 0x10/2: - if(ACCESSING_BITS_0_7) + if (ACCESSING_BITS_0_7) { - verboselog(*this, 12, "mcd212_r: Status Register %d: %02x & %04x\n", channel + 1, m_channel[1 - (offset / 8)].csrr, mem_mask); - if(channel == 0 || machine().side_effects_disabled()) + LOGMASKED(LOG_STATUS, "mcd212_r: Status Register %d: %02x & %04x\n", channel + 1, m_channel[1 - (offset / 8)].csrr, mem_mask); + if (channel == 0 || machine().side_effects_disabled()) { return m_channel[channel].csrr; } @@ -1257,27 +1251,27 @@ READ16_MEMBER( mcd212_device::regs_r ) } else { - verboselog(*this, 2, "mcd212_r: Unknown Register %d: %04x\n", channel + 1, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: Unknown Register %d: %04x\n", channel + 1, mem_mask); } break; case 0x02/2: case 0x12/2: - verboselog(*this, 2, "mcd212_r: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcr, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcr, mem_mask); return m_channel[1 - (offset / 8)].dcr; case 0x04/2: case 0x14/2: - verboselog(*this, 2, "mcd212_r: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].vsr, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].vsr, mem_mask); return m_channel[1 - (offset / 8)].vsr; case 0x08/2: case 0x18/2: - verboselog(*this, 2, "mcd212_r: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].ddr, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].ddr, mem_mask); return m_channel[1 - (offset / 8)].ddr; case 0x0a/2: case 0x1a/2: - verboselog(*this, 2, "mcd212_r: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcp, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcp, mem_mask); return m_channel[1 - (offset / 8)].dcp; default: - verboselog(*this, 2, "mcd212_r: Unknown Register %d & %04x\n", (1 - (offset / 8)) + 1, mem_mask); + LOGMASKED(LOG_READS, "mcd212_r: Unknown Register %d & %04x\n", (1 - (offset / 8)) + 1, mem_mask); break; } @@ -1286,92 +1280,86 @@ READ16_MEMBER( mcd212_device::regs_r ) WRITE16_MEMBER( mcd212_device::regs_w ) { - switch(offset) + switch (offset) { case 0x00/2: case 0x10/2: - verboselog(*this, 2, "mcd212_w: Status Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: Status Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); COMBINE_DATA(&m_channel[1 - (offset / 8)].csrw); update_visible_area(); break; case 0x02/2: case 0x12/2: - verboselog(*this, 2, "mcd212_w: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); COMBINE_DATA(&m_channel[1 - (offset / 8)].dcr); update_visible_area(); break; case 0x04/2: case 0x14/2: - verboselog(*this, 2, "mcd212_w: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); COMBINE_DATA(&m_channel[1 - (offset / 8)].vsr); break; case 0x08/2: case 0x18/2: - verboselog(*this, 2, "mcd212_w: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); COMBINE_DATA(&m_channel[1 - (offset / 8)].ddr); break; case 0x0a/2: case 0x1a/2: - verboselog(*this, 2, "mcd212_w: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); COMBINE_DATA(&m_channel[1 - (offset / 8)].dcp); break; default: - verboselog(*this, 2, "mcd212_w: Unknown Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); + LOGMASKED(LOG_WRITES, "mcd212_w: Unknown Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); break; } } -TIMER_CALLBACK_MEMBER( mcd212_device::perform_scan ) +WRITE_LINE_MEMBER(mcd212_device::vblank_cb) { - int scanline = screen().vpos(); + // Process ICA + LOGMASKED(LOG_FRAMES, "%s", "Frame Start\n" ); + m_channel[0].csrr &= 0x7f; + for (int index = 0; index < 2; index++) + { + if (m_channel[index].dcr & MCD212_DCR_ICA) + { + process_ica(index); + } + } +} - if(1) +WRITE32_MEMBER(mcd212_device::scanline_cb) +{ + if (data < 262) { - if(scanline == 0) + LOGMASKED(LOG_SCANLINES, "Drawing scanline %d\n", data); + m_channel[0].csrr |= 0x80; + // Process VSR + draw_scanline(data); + // Process DCA + for (int index = 0; index < 2; index++) { - // Process ICA - verboselog(*this, 6, "%s", "Frame Start\n" ); - m_channel[0].csrr &= 0x7f; - for(int index = 0; index < 2; index++) + if (m_channel[index].dcr & MCD212_DCR_DCA) { - if(m_channel[index].dcr & MCD212_DCR_ICA) + if (data == 0) { - process_ica(index); + m_channel[index].dca = get_dcp(index); } + process_dca(index); } } - else if(scanline >= 22) + if (data == 261) { - m_channel[0].csrr |= 0x80; - // Process VSR - draw_scanline(scanline); - // Process DCA - for(int index = 0; index < 2; index++) - { - if(m_channel[index].dcr & MCD212_DCR_DCA) - { - if(scanline == 22) - { - m_channel[index].dca = get_dcp(index); - } - process_dca(index); - } - } - if(scanline == 301) - { - m_channel[0].csrr ^= 0x20; - } + LOGMASKED(LOG_FRAMES, "Frame end\n", data); + m_channel[0].csrr ^= 0x20; } - - if (!m_scanline_callback.isnull()) - m_scanline_callback(scanline); } - m_scan_timer->adjust(screen().time_until_pos(( scanline + 1 ) % 302, 0)); } void mcd212_device::device_reset() { - for(auto & elem : m_channel) + for (auto & elem : m_channel) { elem.csrr = 0; elem.csrw = 0; @@ -1445,9 +1433,6 @@ void mcd212_device::device_start() screen().register_screen_bitmap(m_bitmap); - m_scan_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mcd212_device::perform_scan), this)); - m_scan_timer->adjust(screen().time_until_pos(0, 0)); - save_item(NAME(m_region_flag_0)); save_item(NAME(m_region_flag_1)); save_item(NAME(m_channel[0].csrr)); diff --git a/src/mame/video/mcd212.h b/src/mame/video/mcd212.h index bc5ed25a163..869e0c00b24 100644 --- a/src/mame/video/mcd212.h +++ b/src/mame/video/mcd212.h @@ -131,7 +131,8 @@ public: // device members DECLARE_READ16_MEMBER( regs_r ); DECLARE_WRITE16_MEMBER( regs_w ); - TIMER_CALLBACK_MEMBER( perform_scan ); + DECLARE_WRITE32_MEMBER( scanline_cb ); + DECLARE_WRITE_LINE_MEMBER( vblank_cb ); bitmap_rgb32& get_bitmap() { return m_bitmap; } |