mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
-quizard: Replaced protection HLE with proper MCU hookup. Removed MUP flags. Re-promoted Quizard 1 and Quizard 2. [Ryan Holtz]
-scc68070: Improved UART Tx/Rx behavior, though it still functions in parallel rather than serial. [Ryan Holtz]
This commit is contained in:
parent
3ed842c01c
commit
04ed39a051
@ -32,9 +32,10 @@ TODO:
|
||||
#define LOG_MMU (1 << 5)
|
||||
#define LOG_IRQS (1 << 6)
|
||||
#define LOG_UNKNOWN (1 << 7)
|
||||
#define LOG_MORE_UART (1 << 8)
|
||||
#define LOG_ALL (LOG_I2C | LOG_UART | LOG_TIMERS | LOG_DMA | LOG_MMU | LOG_IRQS | LOG_UNKNOWN)
|
||||
|
||||
#define VERBOSE (LOG_UART)
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
@ -84,6 +85,7 @@ scc68070_device::scc68070_device(const machine_config &mconfig, const char *tag,
|
||||
, m_iack5_callback(*this)
|
||||
, m_iack7_callback(*this)
|
||||
, m_uart_tx_callback(*this)
|
||||
, m_uart_rtsn_callback(*this)
|
||||
, m_ipl(0)
|
||||
, m_in2_line(CLEAR_LINE)
|
||||
, m_in4_line(CLEAR_LINE)
|
||||
@ -110,6 +112,7 @@ void scc68070_device::device_resolve_objects()
|
||||
m_iack5_callback.resolve_safe(autovector(5));
|
||||
m_iack7_callback.resolve_safe(autovector(7));
|
||||
m_uart_tx_callback.resolve_safe();
|
||||
m_uart_rtsn_callback.resolve_safe();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -148,8 +151,13 @@ void scc68070_device::device_start()
|
||||
save_item(NAME(m_uart.status_register));
|
||||
save_item(NAME(m_uart.clock_select));
|
||||
save_item(NAME(m_uart.command_register));
|
||||
save_item(NAME(m_uart.transmit_holding_register));
|
||||
save_item(NAME(m_uart.receive_holding_register));
|
||||
save_item(NAME(m_uart.receive_pointer));
|
||||
save_item(NAME(m_uart.receive_buffer));
|
||||
save_item(NAME(m_uart.transmit_holding_register));
|
||||
save_item(NAME(m_uart.transmit_pointer));
|
||||
save_item(NAME(m_uart.transmit_buffer));
|
||||
save_item(NAME(m_uart.transmit_ctsn));
|
||||
|
||||
save_item(NAME(m_timers.timer_status_register));
|
||||
save_item(NAME(m_timers.timer_control_register));
|
||||
@ -175,13 +183,13 @@ void scc68070_device::device_start()
|
||||
save_item(STRUCT_MEMBER(m_mmu.desc, segment));
|
||||
save_item(STRUCT_MEMBER(m_mmu.desc, base));
|
||||
|
||||
m_timers.timer0_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scc68070_device::timer0_callback), this));
|
||||
m_timers.timer0_timer = timer_alloc(TIMER_TMR0);
|
||||
m_timers.timer0_timer->adjust(attotime::never);
|
||||
|
||||
m_uart.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scc68070_device::rx_callback), this));
|
||||
m_uart.rx_timer = timer_alloc(TIMER_UART_RX);
|
||||
m_uart.rx_timer->adjust(attotime::never);
|
||||
|
||||
m_uart.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scc68070_device::tx_callback), this));
|
||||
m_uart.tx_timer = timer_alloc(TIMER_UART_TX);
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
@ -216,6 +224,7 @@ void scc68070_device::device_reset()
|
||||
m_uart.receive_holding_register = 0;
|
||||
m_uart.receive_pointer = -1;
|
||||
m_uart.transmit_pointer = -1;
|
||||
m_uart.transmit_ctsn = true;
|
||||
|
||||
m_timers.timer_status_register = 0;
|
||||
m_timers.timer_control_register = 0;
|
||||
@ -248,6 +257,24 @@ void scc68070_device::device_reset()
|
||||
}
|
||||
|
||||
update_ipl();
|
||||
|
||||
m_uart.rx_timer->adjust(attotime::never);
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
m_timers.timer0_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - device-specific timer callback
|
||||
//-------------------------------------------------
|
||||
|
||||
void scc68070_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (id == TIMER_TMR0)
|
||||
timer0_callback();
|
||||
else if (id == TIMER_UART_RX)
|
||||
rx_callback();
|
||||
else if (id == TIMER_UART_TX)
|
||||
tx_callback();
|
||||
}
|
||||
|
||||
void scc68070_device::m68k_reset_peripherals()
|
||||
@ -275,6 +302,10 @@ void scc68070_device::m68k_reset_peripherals()
|
||||
m_timers.timer_status_register = 0;
|
||||
m_timers.timer_control_register = 0;
|
||||
|
||||
m_uart.rx_timer->adjust(attotime::never);
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
m_timers.timer0_timer->adjust(attotime::never);
|
||||
|
||||
update_ipl();
|
||||
}
|
||||
|
||||
@ -438,7 +469,7 @@ void scc68070_device::set_timer_callback(int channel)
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( scc68070_device::timer0_callback )
|
||||
void scc68070_device::timer0_callback()
|
||||
{
|
||||
m_timers.timer0 = m_timers.reload_register;
|
||||
m_timers.timer_status_register |= TSR_OV0;
|
||||
@ -451,60 +482,25 @@ TIMER_CALLBACK_MEMBER( scc68070_device::timer0_callback )
|
||||
set_timer_callback(0);
|
||||
}
|
||||
|
||||
void scc68070_device::uart_rx_check()
|
||||
void scc68070_device::uart_ctsn(int state)
|
||||
{
|
||||
if ((m_uart.command_register & 3) == 1)
|
||||
{
|
||||
uint32_t div = 0x10000 >> ((m_uart.clock_select >> 4) & 7);
|
||||
m_uart.rx_timer->adjust(attotime::from_hz((49152000 / div) / 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart.status_register &= ~USR_RXRDY;
|
||||
m_uart.rx_timer->adjust(attotime::never);
|
||||
}
|
||||
}
|
||||
|
||||
void scc68070_device::uart_tx_check()
|
||||
{
|
||||
if (((m_uart.command_register >> 2) & 3) == 1)
|
||||
{
|
||||
if (m_uart.transmit_pointer >= 0)
|
||||
{
|
||||
m_uart.status_register &= ~USR_TXRDY;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart.status_register |= USR_TXRDY;
|
||||
}
|
||||
|
||||
if (m_uart.tx_timer->remaining() == attotime::never)
|
||||
{
|
||||
uint32_t div = 0x10000 >> (m_uart.clock_select & 7);
|
||||
m_uart.tx_timer->adjust(attotime::from_hz((49152000 / div) / 8));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
}
|
||||
m_uart.transmit_ctsn = state ? true : false;
|
||||
}
|
||||
|
||||
void scc68070_device::uart_rx(uint8_t data)
|
||||
{
|
||||
m_uart.receive_pointer++;
|
||||
m_uart.receive_buffer[m_uart.receive_pointer] = data;
|
||||
uart_rx_check();
|
||||
}
|
||||
|
||||
void scc68070_device::uart_tx(uint8_t data)
|
||||
{
|
||||
m_uart.transmit_pointer++;
|
||||
m_uart.transmit_buffer[m_uart.transmit_pointer] = data;
|
||||
uart_tx_check();
|
||||
m_uart.status_register &= ~USR_TXEMT;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( scc68070_device::rx_callback )
|
||||
void scc68070_device::rx_callback()
|
||||
{
|
||||
if ((m_uart.command_register & 3) == 1)
|
||||
{
|
||||
@ -527,8 +523,6 @@ 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));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -539,43 +533,40 @@ TIMER_CALLBACK_MEMBER( scc68070_device::rx_callback )
|
||||
{
|
||||
m_uart.status_register &= ~USR_RXRDY;
|
||||
}
|
||||
|
||||
uart_rx_check();
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( scc68070_device::tx_callback )
|
||||
void scc68070_device::tx_callback()
|
||||
{
|
||||
if (((m_uart.command_register >> 2) & 3) == 1)
|
||||
{
|
||||
m_uart.status_register |= USR_TXRDY;
|
||||
|
||||
m_uart_tx_int = true;
|
||||
update_ipl();
|
||||
|
||||
if (m_uart.transmit_pointer > -1)
|
||||
{
|
||||
if (m_uart.transmit_ctsn && BIT(m_uart.mode_register, 4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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_MORE_UART, "tx_callback: Transmitting %02x\n", 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));
|
||||
}
|
||||
else
|
||||
|
||||
if (m_uart.transmit_pointer < 0)
|
||||
{
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
m_uart.status_register |= USR_TXEMT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart.tx_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
uart_tx_check();
|
||||
}
|
||||
|
||||
uint8_t scc68070_device::lir_r()
|
||||
@ -746,13 +737,13 @@ uint8_t scc68070_device::umr_r()
|
||||
{
|
||||
// UART mode register: 80002011
|
||||
if (!machine().side_effects_disabled())
|
||||
LOGMASKED(LOG_UART, "%s: UART Mode Register Read: %02x\n", machine().describe_context(), m_uart.mode_register);
|
||||
LOGMASKED(LOG_MORE_UART, "%s: UART Mode Register Read: %02x\n", machine().describe_context(), m_uart.mode_register);
|
||||
return m_uart.mode_register | 0x20;
|
||||
}
|
||||
|
||||
void scc68070_device::umr_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: UART Mode Register Write: %02x\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_MORE_UART, "%s: UART Mode Register Write: %02x\n", machine().describe_context(), data);
|
||||
m_uart.mode_register = data;
|
||||
}
|
||||
|
||||
@ -762,7 +753,7 @@ uint8_t scc68070_device::usr_r()
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
m_uart.status_register |= (1 << 1);
|
||||
LOGMASKED(LOG_UART, "%s: UART Status Register Read: %02x\n", machine().describe_context(), m_uart.status_register);
|
||||
LOGMASKED(LOG_MORE_UART, "%s: UART Status Register Read: %02x\n", machine().describe_context(), m_uart.status_register);
|
||||
}
|
||||
return m_uart.status_register | 0x08; // hack for magicard
|
||||
}
|
||||
@ -779,6 +770,13 @@ void scc68070_device::ucsr_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: UART Clock Select Write: %02x\n", machine().describe_context(), data);
|
||||
m_uart.clock_select = data;
|
||||
|
||||
static const uint32_t s_baud_divisors[8] = { 65536, 32768, 16384, 4096, 2048, 1024, 512, 256 };
|
||||
|
||||
attotime rx_rate = attotime::from_ticks(s_baud_divisors[(data >> 4) & 7] * 10, 49152000);
|
||||
attotime tx_rate = attotime::from_ticks(s_baud_divisors[data & 7] * 10, 49152000);
|
||||
m_uart.rx_timer->adjust(rx_rate, 0, rx_rate);
|
||||
m_uart.tx_timer->adjust(tx_rate, 0, tx_rate);
|
||||
}
|
||||
|
||||
uint8_t scc68070_device::ucr_r()
|
||||
@ -791,10 +789,36 @@ uint8_t scc68070_device::ucr_r()
|
||||
|
||||
void scc68070_device::ucr_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: UART Command Register Write: %02x\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_MORE_UART, "%s: UART Command Register Write: %02x\n", machine().describe_context(), data);
|
||||
m_uart.command_register = data;
|
||||
uart_rx_check();
|
||||
uart_tx_check();
|
||||
const uint8_t misc_command = (data & 0x70) >> 4;
|
||||
switch (misc_command)
|
||||
{
|
||||
case 0x2: // Reset receiver
|
||||
LOGMASKED(LOG_MORE_UART, "%s: Reset receiver\n", machine().describe_context());
|
||||
m_uart.receive_pointer = -1;
|
||||
m_uart.command_register &= 0xf0;
|
||||
m_uart.receive_holding_register = 0x00;
|
||||
break;
|
||||
case 0x3: // Reset transmitter
|
||||
LOGMASKED(LOG_MORE_UART, "%s: Reset transmitter\n", machine().describe_context());
|
||||
m_uart.transmit_pointer = -1;
|
||||
m_uart.status_register |= USR_TXEMT;
|
||||
m_uart.command_register &= 0xf0;
|
||||
m_uart.transmit_holding_register = 0x00;
|
||||
break;
|
||||
case 0x4: // Reset error status
|
||||
LOGMASKED(LOG_MORE_UART, "%s: Reset error status\n", machine().describe_context());
|
||||
m_uart.status_register &= 0x87; // Clear error bits in USR
|
||||
m_uart.command_register &= 0xf0;
|
||||
break;
|
||||
case 0x6: // Start break
|
||||
LOGMASKED(LOG_MORE_UART, "%s: Start break (not yet implemented)\n", machine().describe_context());
|
||||
break;
|
||||
case 0x7: // Stop break
|
||||
LOGMASKED(LOG_MORE_UART, "%s: Stop break (not yet implemented)\n", machine().describe_context());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t scc68070_device::uth_r()
|
||||
@ -807,7 +831,7 @@ 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 : ' ');
|
||||
LOGMASKED(LOG_MORE_UART, "%s: UART Transmit Holding Register Write: %02x ('%c')\n", machine().describe_context(), data, (data >= 0x20 && data < 0x7f) ? data : ' ');
|
||||
uart_tx(data);
|
||||
m_uart.transmit_holding_register = data;
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ public:
|
||||
auto iack5_callback() { return m_iack5_callback.bind(); }
|
||||
auto iack7_callback() { return m_iack7_callback.bind(); }
|
||||
auto uart_tx_callback() { return m_uart_tx_callback.bind(); }
|
||||
auto uart_rtsn_callback() { return m_uart_rtsn_callback.bind(); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(in2_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(in4_w);
|
||||
@ -150,10 +151,11 @@ public:
|
||||
|
||||
// external callbacks
|
||||
void uart_rx(uint8_t data);
|
||||
void uart_ctsn(int state);
|
||||
|
||||
TIMER_CALLBACK_MEMBER( timer0_callback );
|
||||
TIMER_CALLBACK_MEMBER( rx_callback );
|
||||
TIMER_CALLBACK_MEMBER( tx_callback );
|
||||
void timer0_callback();
|
||||
void rx_callback();
|
||||
void tx_callback();
|
||||
|
||||
// register structures
|
||||
struct i2c_regs_t
|
||||
@ -192,6 +194,7 @@ public:
|
||||
int16_t transmit_pointer;
|
||||
uint8_t transmit_buffer[32768];
|
||||
emu_timer* tx_timer;
|
||||
bool transmit_ctsn;
|
||||
};
|
||||
|
||||
struct timer_regs_t
|
||||
@ -261,6 +264,7 @@ protected:
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 2 - 1) / 2; }
|
||||
@ -273,6 +277,10 @@ private:
|
||||
void internal_map(address_map &map);
|
||||
void cpu_space_map(address_map &map);
|
||||
|
||||
static constexpr device_timer_id TIMER_TMR0 = 0;
|
||||
static constexpr device_timer_id TIMER_UART_RX = 1;
|
||||
static constexpr device_timer_id TIMER_UART_TX = 2;
|
||||
|
||||
void update_ipl();
|
||||
uint8_t iack_r(offs_t offset);
|
||||
|
||||
@ -323,6 +331,7 @@ private:
|
||||
void uart_rx_check();
|
||||
void uart_tx_check();
|
||||
void uart_tx(uint8_t data);
|
||||
void uart_do_tx();
|
||||
void set_timer_callback(int channel);
|
||||
|
||||
// callbacks
|
||||
@ -331,6 +340,7 @@ private:
|
||||
devcb_read8 m_iack5_callback;
|
||||
devcb_read8 m_iack7_callback;
|
||||
devcb_write8 m_uart_tx_callback;
|
||||
devcb_write_line m_uart_rtsn_callback;
|
||||
|
||||
// internal state
|
||||
uint8_t m_ipl;
|
||||
|
@ -31,14 +31,8 @@ STATUS:
|
||||
* PC85010 DSP
|
||||
|
||||
Quizard:
|
||||
- Quizard does not work due to MCU not being fully hooked up.
|
||||
|
||||
- The Quizard MCU makes use of both serial ports, the second of which is
|
||||
connected to the SCC68070's UART, and the first of which, which is connected
|
||||
to the RDI and TDO pins of the SLAVE MCU's UART. Thus the Quizard MCU cannot
|
||||
be hooked up fully until there is proper LLE of the SLAVE MCU, or input
|
||||
reading is decoupled from the high-level simulation so that arbitrary serial
|
||||
devices can be hooked up.
|
||||
- Quizard 3 and 4 fail when going in-game, presumably due to CD-i emulation
|
||||
faults.
|
||||
|
||||
TODO:
|
||||
|
||||
@ -69,7 +63,13 @@ TODO:
|
||||
// TODO: NTSC system clock is 30.2098 MHz; additional 4.9152 MHz XTAL provided for UART
|
||||
#define CLOCK_A 30_MHz_XTAL
|
||||
|
||||
#define VERBOSE (1)
|
||||
#define LOG_DVC (1 << 1)
|
||||
#define LOG_QUIZARD_READS (1 << 2)
|
||||
#define LOG_QUIZARD_WRITES (1 << 3)
|
||||
#define LOG_QUIZARD_OTHER (1 << 4)
|
||||
#define LOG_UART (1 << 5)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define ENABLE_UART_PRINTING (0)
|
||||
@ -144,52 +144,6 @@ void cdi_state::cdi910_mem(address_map &map)
|
||||
* Input ports *
|
||||
*************************/
|
||||
|
||||
INPUT_CHANGED_MEMBER(quizard_state::mcu_input)
|
||||
{
|
||||
bool send = false;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case 0x39:
|
||||
//if (m_input1.read_safe(0) & 0x01) send = true;
|
||||
break;
|
||||
case 0x37:
|
||||
//if (m_input1.read_safe(0) & 0x02) send = true;
|
||||
break;
|
||||
case 0x31:
|
||||
//if (m_input1.read_safe(0) & 0x04) send = true;
|
||||
break;
|
||||
case 0x32:
|
||||
//if (m_input1.read_safe(0) & 0x08) send = true;
|
||||
break;
|
||||
case 0x33:
|
||||
//if (m_input1.read_safe(0) & 0x10) send = true;
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
//if (m_input2.read_safe(0) & 0x01) send = true;
|
||||
break;
|
||||
case 0x38:
|
||||
//if (m_input2.read_safe(0) & 0x02) send = true;
|
||||
break;
|
||||
case 0x34:
|
||||
//if (m_input2.read_safe(0) & 0x04) send = true;
|
||||
break;
|
||||
case 0x35:
|
||||
//if (m_input2.read_safe(0) & 0x08) send = true;
|
||||
break;
|
||||
case 0x36:
|
||||
//if (m_input2.read_safe(0) & 0x10) send = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (send)
|
||||
{
|
||||
uint8_t data = uint8_t(param & 0x000000ff);
|
||||
mcu_hle_tx(data);
|
||||
}
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( cdi )
|
||||
PORT_START("DEBUG")
|
||||
PORT_CONFNAME( 0x01, 0x00, "Plane A Disable")
|
||||
@ -269,8 +223,7 @@ static INPUT_PORTS_START( quizard )
|
||||
PORT_BIT( 0xc8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("P1")
|
||||
PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x1f, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
|
||||
@ -283,10 +236,6 @@ static INPUT_PORTS_START( quizard )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Player 2 B")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("Player 2 C")
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("P3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Fake RTS from Console")
|
||||
PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -303,236 +252,103 @@ void cdi_state::machine_reset()
|
||||
|
||||
void quizard_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_seeds));
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_mcu_value));
|
||||
save_item(NAME(m_mcu_ack));
|
||||
save_item(NAME(m_mcu_rx_from_cpu));
|
||||
save_item(NAME(m_mcu_initial_byte));
|
||||
}
|
||||
|
||||
void quizard_state::machine_reset()
|
||||
{
|
||||
cdi_state::machine_reset();
|
||||
|
||||
memset(m_seeds, 0, 10 * sizeof(uint16_t));
|
||||
memset(m_state, 0, 8 * sizeof(uint8_t));
|
||||
m_mcu_rx_from_cpu = 0x00;
|
||||
m_mcu_initial_byte = true;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* Quizard Protection HLE *
|
||||
***************************/
|
||||
/**********************
|
||||
* Quizard Protection *
|
||||
**********************/
|
||||
|
||||
void quizard_state::set_mcu_ack(uint8_t ack)
|
||||
void quizard_state::mcu_rtsn_from_cpu(int state)
|
||||
{
|
||||
m_mcu_ack = ack;
|
||||
LOGMASKED(LOG_UART, "MCU receiving RTSN from CPU: %d\n", state);
|
||||
}
|
||||
|
||||
void quizard_state::set_mcu_value(uint16_t value)
|
||||
void quizard_state::mcu_rx_from_cpu(uint8_t data)
|
||||
{
|
||||
m_mcu_value = value;
|
||||
}
|
||||
|
||||
void quizard_state::mcu_hle_tx(uint8_t data)
|
||||
{
|
||||
m_maincpu->uart_rx(0x5a);
|
||||
m_maincpu->uart_rx(data);
|
||||
}
|
||||
|
||||
void quizard_state::mcu_set_seeds(uint8_t *rx)
|
||||
{
|
||||
m_seeds[0] = (rx[1] << 8) | rx[0];
|
||||
m_seeds[1] = (rx[3] << 8) | rx[2];
|
||||
m_seeds[2] = (rx[5] << 8) | rx[4];
|
||||
m_seeds[3] = (rx[7] << 8) | rx[6];
|
||||
m_seeds[4] = (rx[9] << 8) | rx[8];
|
||||
m_seeds[5] = (rx[11] << 8) | rx[10];
|
||||
m_seeds[6] = (rx[13] << 8) | rx[12];
|
||||
m_seeds[7] = (rx[15] << 8) | rx[14];
|
||||
m_seeds[8] = (rx[17] << 8) | rx[16];
|
||||
m_seeds[9] = (rx[19] << 8) | rx[18];
|
||||
}
|
||||
|
||||
void quizard_state::mcu_calculate_state()
|
||||
{
|
||||
//const uint16_t desired_bitfield = mcu_value;
|
||||
const uint16_t field0 = 0x00ff;
|
||||
const uint16_t field1 = m_mcu_value ^ 0x00ff;
|
||||
|
||||
uint16_t total0 = 0;
|
||||
uint16_t total1 = 0;
|
||||
|
||||
for(int index = 0; index < 10; index++)
|
||||
LOGMASKED(LOG_UART, "MCU receiving %02x from CPU\n", data);
|
||||
if (m_mcu_initial_byte)
|
||||
{
|
||||
if (field0 & (1 << index))
|
||||
{
|
||||
total0 += m_seeds[index];
|
||||
}
|
||||
if (field1 & (1 << index))
|
||||
{
|
||||
total1 += m_seeds[index];
|
||||
}
|
||||
m_mcu_initial_byte = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t hi0 = (total0 >> 8) + 0x40;
|
||||
m_state[2] = hi0 / 2;
|
||||
m_state[3] = hi0 - m_state[2];
|
||||
m_mcu_rx_from_cpu = data;
|
||||
|
||||
uint16_t lo0 = (total0 & 0x00ff) + 0x40;
|
||||
m_state[0] = lo0 / 2;
|
||||
m_state[1] = lo0 - m_state[0];
|
||||
|
||||
uint16_t hi1 = (total1 >> 8) + 0x40;
|
||||
m_state[6] = hi1 / 2;
|
||||
m_state[7] = hi1 - m_state[6];
|
||||
|
||||
uint16_t lo1 = (total1 & 0x00ff) + 0x40;
|
||||
m_state[4] = lo1 / 2;
|
||||
m_state[5] = lo1 - m_state[4];
|
||||
}
|
||||
|
||||
void quizard_state::mcu_hle_rx(uint8_t data)
|
||||
{
|
||||
static int state = 0;
|
||||
static uint8_t rx[0x100];
|
||||
static uint8_t rx_ptr = 0xff;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case 0: // Waiting for a leadoff byte
|
||||
if (data == m_mcu_ack) // Sequence end
|
||||
{
|
||||
//scc68070_uart_rx(machine, scc68070, 0x5a);
|
||||
//scc68070_uart_rx(machine, scc68070, 0x42);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0x44: // DATABASEPATH = **_DATABASE/
|
||||
rx[0] = 0x44;
|
||||
rx_ptr = 1;
|
||||
state = 3;
|
||||
break;
|
||||
case 0x2e: // Unknown; ignored
|
||||
break;
|
||||
case 0x56: // Seed start
|
||||
rx_ptr = 0;
|
||||
state = 1;
|
||||
break;
|
||||
default:
|
||||
//printf("Unknown leadoff byte: %02x\n", data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Receiving the seed
|
||||
rx[rx_ptr] = data;
|
||||
rx_ptr++;
|
||||
if (rx_ptr == 20)
|
||||
{
|
||||
//printf("Calculating seeds\n");
|
||||
mcu_set_seeds(rx);
|
||||
mcu_calculate_state();
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Receiving the seed acknowledge
|
||||
case 4:
|
||||
if (data == m_mcu_ack)
|
||||
{
|
||||
if (state == 2)
|
||||
{
|
||||
state = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 0;
|
||||
}
|
||||
//printf("Sending seed ack\n");
|
||||
m_maincpu->uart_rx(0x5a);
|
||||
m_maincpu->uart_rx(m_state[0]);
|
||||
m_maincpu->uart_rx(m_state[1]);
|
||||
m_maincpu->uart_rx(m_state[2]);
|
||||
m_maincpu->uart_rx(m_state[3]);
|
||||
m_maincpu->uart_rx(m_state[4]);
|
||||
m_maincpu->uart_rx(m_state[5]);
|
||||
m_maincpu->uart_rx(m_state[6]);
|
||||
m_maincpu->uart_rx(m_state[7]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // Receiving the database path
|
||||
rx[rx_ptr] = data;
|
||||
rx_ptr++;
|
||||
if (data == 0x0a)
|
||||
{
|
||||
/*rx[rx_ptr] = 0;
|
||||
//printf("Database path: %s\n", rx);
|
||||
scc68070_uart_rx(machine, scc68070, 0x5a);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[0]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[1]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[2]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[3]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[4]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[5]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[6]);
|
||||
scc68070_uart_rx(machine, scc68070, g_state[7]);*/
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_p0_r()
|
||||
{
|
||||
const uint8_t data = m_inputs[0]->read();
|
||||
LOG("%s: MCU Port 0 Read (%02x)\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 0 Read (%02x)\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_p1_r()
|
||||
{
|
||||
const uint8_t data = m_inputs[1]->read();
|
||||
LOG("%s: MCU Port 1 Read (%02x)\n", machine().describe_context(), data);
|
||||
uint8_t data = m_inputs[1]->read();
|
||||
if (BIT(~m_inputs[0]->read(), 4))
|
||||
data &= ~(1 << 4);
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 1 Read (%02x)\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_p2_r()
|
||||
{
|
||||
const uint8_t data = m_inputs[2]->read();
|
||||
LOG("%s: MCU Port 2 Read (%02x)\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 2 Read (%02x)\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_p3_r()
|
||||
{
|
||||
const uint8_t data = 0x04 | (m_inputs[3]->read() ? 0x80 : 0x00);
|
||||
LOG("%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), data);
|
||||
return data;
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), 0x04);
|
||||
return 0x04;
|
||||
}
|
||||
|
||||
void quizard_state::mcu_p0_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 0 Write (%02x)\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
void quizard_state::mcu_p1_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 1 Write (%02x)\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
void quizard_state::mcu_p2_w(uint8_t data)
|
||||
{
|
||||
LOG("%s: MCU Port 2 Write (%02x)\n", machine().describe_context(), data);
|
||||
m_mcu->set_input_line(MCS51_INT1_LINE, BIT(data, 7) ? ASSERT_LINE : CLEAR_LINE);
|
||||
LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 2 Write (%02x)\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
void quizard_state::mcu_p3_w(uint8_t data)
|
||||
{
|
||||
LOG("%s: MCU Port 3 Write (%02x)\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 3 Write (%02x)\n", machine().describe_context(), data);
|
||||
m_maincpu->uart_ctsn(BIT(data, 6));
|
||||
}
|
||||
|
||||
void quizard_state::mcu_tx(uint8_t data)
|
||||
{
|
||||
LOG("%s: MCU transmitting %02x\n", machine().describe_context(), data);
|
||||
LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU transmitting %02x\n", machine().describe_context(), data);
|
||||
m_maincpu->uart_rx(data);
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_rx()
|
||||
{
|
||||
uint8_t data = 0;
|
||||
LOG("%s: MCU receiving %02x\n", machine().describe_context(), data);
|
||||
uint8_t data = m_mcu_rx_from_cpu;
|
||||
LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU receiving %02x\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -542,13 +358,13 @@ uint8_t quizard_state::mcu_rx()
|
||||
|
||||
READ16_MEMBER( cdi_state::dvc_r )
|
||||
{
|
||||
logerror("%s: dvc_r: %08x = 0000 & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), mem_mask);
|
||||
LOGMASKED(LOG_DVC, "%s: dvc_r: %08x = 0000 & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( cdi_state::dvc_w )
|
||||
{
|
||||
logerror("%s: dvc_w: %08x = %04x & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), data, mem_mask);
|
||||
LOGMASKED(LOG_DVC, "%s: dvc_w: %08x = %04x & %04x\n", machine().describe_context(), 0xe80000 + (offset << 1), data, mem_mask);
|
||||
}
|
||||
|
||||
/*************************
|
||||
@ -794,13 +610,16 @@ void quizard_state::quizard(machine_config &config)
|
||||
{
|
||||
cdimono1_base(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &quizard_state::cdimono1_mem);
|
||||
m_maincpu->uart_tx_callback().set(FUNC(quizard_state::mcu_hle_rx));
|
||||
m_maincpu->uart_rtsn_callback().set(FUNC(quizard_state::mcu_rtsn_from_cpu));
|
||||
m_maincpu->uart_tx_callback().set(FUNC(quizard_state::mcu_rx_from_cpu));
|
||||
|
||||
I8751(config, m_mcu, 8000000);
|
||||
m_mcu->port_in_cb<0>().set(FUNC(quizard_state::mcu_p0_r));
|
||||
m_mcu->port_in_cb<1>().set(FUNC(quizard_state::mcu_p1_r));
|
||||
m_mcu->port_in_cb<2>().set(FUNC(quizard_state::mcu_p2_r));
|
||||
m_mcu->port_in_cb<3>().set(FUNC(quizard_state::mcu_p3_r));
|
||||
m_mcu->port_out_cb<0>().set(FUNC(quizard_state::mcu_p0_w));
|
||||
m_mcu->port_out_cb<1>().set(FUNC(quizard_state::mcu_p1_w));
|
||||
m_mcu->port_out_cb<2>().set(FUNC(quizard_state::mcu_p2_w));
|
||||
m_mcu->port_out_cb<3>().set(FUNC(quizard_state::mcu_p3_w));
|
||||
m_mcu->serial_tx_cb().set(FUNC(quizard_state::mcu_tx));
|
||||
@ -882,15 +701,15 @@ ROM_END
|
||||
/* Quizard notes
|
||||
|
||||
The MCU controls the protection sequence, which in turn controls the game display language.
|
||||
Each Quizard game (1,2,3,4) requires it's own MCU, you can upgrade between revisions by changing
|
||||
Each Quizard game (1,2,3,4) requires its own MCU, you can upgrade between revisions by changing
|
||||
just the CD, but not between games as a new MCU is required.
|
||||
|
||||
MCU Notes:
|
||||
i8751 MCU dumps confirmed good on original hardware
|
||||
German language MCUs for Quizard 1 through 4 are dumped
|
||||
Czechoslovakian language MCU for Quizard 4 is dumped
|
||||
Known to exist a Quizard 1 Italian language MCU IT 11 L2 (not dumped)
|
||||
Known to exist is an alternate Quizard 2 German language MCU DE 122 D3 (not dumped)
|
||||
Czech language MCU for Quizard 4 is dumped
|
||||
Italian language MCU for Quizard 1 is known to exist (IT 11 L2, not dumped)
|
||||
Alt. German language MCU for Quizard 2 is known to exist (DE 122 D3, not dumped)
|
||||
|
||||
*/
|
||||
|
||||
@ -1071,24 +890,24 @@ CONS( 1991, cdimono2, 0, 0, cdimono2, cdimono2, cdi_state, empty_init,
|
||||
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 )
|
||||
|
||||
// The Quizard games are RETAIL CD-i units, with additional JAMMA adapters & dongles for protection, hence being 'clones' of the system.
|
||||
// The Quizard games are retail CD-i units in a cabinet, with an additional JAMMA adapter and dongle for protection, hence being clones of the system.
|
||||
/* YEAR NAME PARENT MACHINE INPUT DEVICE INIT MONITOR COMPANY FULLNAME */
|
||||
GAME( 1995, cdibios, 0, cdimono1, quizard, cdi_state, empty_init, ROT0, "Philips", "CD-i (Mono-I) (PAL) BIOS", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IS_BIOS_ROOT )
|
||||
GAME( 1995, cdibios, 0, cdimono1, quizard, cdi_state, empty_init, ROT0, "Philips", "CD-i (Mono-I) (PAL) BIOS", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IS_BIOS_ROOT )
|
||||
|
||||
GAME( 1995, quizard, cdibios, quizard, quizard, quizard1_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.8, German, i8751 DE 11 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard_17, quizard, quizard, quizard, quizard1_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.7, German, i8751 DE 11 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard_12, quizard, quizard, quizard, quizard1_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.2, German, i8751 DE 11 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard_10, quizard, quizard, quizard, quizard1_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.0, German, i8751 DE 11 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.8, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1995, quizard_17, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.7, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1995, quizard_12, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.2, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1995, quizard_10, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.0, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
|
||||
GAME( 1995, quizard2, cdibios, quizard, quizard, quizard2_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.3, German, i8751 DN 122 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard2_22, quizard2, quizard, quizard, quizard2_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.2, German, i8751 DN 122 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard2, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.3, German, i8751 DN 122 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1995, quizard2_22, quizard2, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.2, German, i8751 DN 122 D3)", MACHINE_IMPERFECT_SOUND )
|
||||
|
||||
// Quizard 3 and 4 will hang after inserting a coin (incomplete protection sims?)
|
||||
GAME( 1995, quizard3, cdibios, quizard, quizard, quizard3_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1995, quizard3a, quizard3, quizard, quizard, quizard3_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 A1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1996, quizard3_32, quizard3, quizard, quizard, quizard3_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.2, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
// Quizard 3 and 4 will hang after starting a game (CDIC issues?)
|
||||
GAME( 1995, quizard3, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1995, quizard3a, quizard3, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 A1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1996, quizard3_32, quizard3, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.2, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
|
||||
GAME( 1998, quizard4, cdibios, quizard, quizard, quizard4_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1998, quizard4cz, quizard4, quizard, quizard, quizard4_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, Czech, i8751 TS142 CZ1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1998, quizard4_41, quizard4, quizard, quizard, quizard4_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.1, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1997, quizard4_40, quizard4, quizard, quizard, quizard4_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.0, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
|
||||
GAME( 1998, quizard4, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1998, quizard4cz, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, Czech, i8751 TS142 CZ1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1998, quizard4_41, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.1, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1997, quizard4_40, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.0, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
|
||||
|
@ -89,12 +89,6 @@ public:
|
||||
|
||||
void quizard(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(mcu_input);
|
||||
|
||||
protected:
|
||||
void set_mcu_value(uint16_t value);
|
||||
void set_mcu_ack(uint8_t ack);
|
||||
|
||||
private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
@ -103,71 +97,26 @@ private:
|
||||
uint8_t mcu_p1_r();
|
||||
uint8_t mcu_p2_r();
|
||||
uint8_t mcu_p3_r();
|
||||
void mcu_p0_w(uint8_t data);
|
||||
void mcu_p1_w(uint8_t data);
|
||||
void mcu_p2_w(uint8_t data);
|
||||
void mcu_p3_w(uint8_t data);
|
||||
void mcu_tx(uint8_t data);
|
||||
uint8_t mcu_rx();
|
||||
|
||||
void mcu_hle_tx(uint8_t data);
|
||||
void mcu_calculate_state();
|
||||
void mcu_set_seeds(uint8_t *rx);
|
||||
void mcu_hle_rx(uint8_t data);
|
||||
void mcu_rx_from_cpu(uint8_t data);
|
||||
void mcu_rtsn_from_cpu(int state);
|
||||
|
||||
required_device<i8751_device> m_mcu;
|
||||
required_ioport_array<4> m_inputs;
|
||||
required_ioport_array<3> m_inputs;
|
||||
|
||||
uint16_t m_seeds[10];
|
||||
uint8_t m_state[8];
|
||||
|
||||
uint16_t m_mcu_value;
|
||||
uint8_t m_mcu_ack;
|
||||
uint8_t m_mcu_rx_from_cpu;
|
||||
bool m_mcu_initial_byte;
|
||||
};
|
||||
|
||||
class quizard1_state : public quizard_state
|
||||
{
|
||||
public:
|
||||
quizard1_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: quizard_state(mconfig, type, tag)
|
||||
{
|
||||
set_mcu_value(0x021f);
|
||||
set_mcu_ack(0x5a);
|
||||
}
|
||||
};
|
||||
|
||||
class quizard2_state : public quizard_state
|
||||
{
|
||||
public:
|
||||
quizard2_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: quizard_state(mconfig, type, tag)
|
||||
{
|
||||
// 0x2b1: Italian
|
||||
// 0x001: French
|
||||
// 0x188: German
|
||||
set_mcu_value(0x0188);
|
||||
set_mcu_ack(0x59);
|
||||
}
|
||||
};
|
||||
|
||||
class quizard3_state : public quizard_state
|
||||
{
|
||||
public:
|
||||
quizard3_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: quizard_state(mconfig, type, tag)
|
||||
{
|
||||
set_mcu_value(0x00ae);
|
||||
set_mcu_ack(0x58);
|
||||
}
|
||||
};
|
||||
|
||||
class quizard4_state : public quizard_state
|
||||
{
|
||||
public:
|
||||
quizard4_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: quizard_state(mconfig, type, tag)
|
||||
{
|
||||
set_mcu_value(0x011f);
|
||||
set_mcu_ack(0x57);
|
||||
}
|
||||
};
|
||||
// Quizard 2 language values:
|
||||
// 0x2b1: Italian
|
||||
// 0x001: French
|
||||
// 0x188: German
|
||||
|
||||
#endif // MAME_INCLUDES_CDI_H
|
||||
|
@ -23,6 +23,7 @@ TODO:
|
||||
#define LOG_READS (1 << 2)
|
||||
#define LOG_WRITES (1 << 3)
|
||||
#define LOG_UNKNOWNS (1 << 4)
|
||||
#define LOG_ALL (LOG_IRQS | LOG_COMMANDS | LOG_READS | LOG_WRITES | LOG_UNKNOWNS)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
Loading…
Reference in New Issue
Block a user