- Considerably improved UART communications in the CD-i 68070 implementation, increasing Quizard stability as a result. [Harmony]

This commit is contained in:
Ryan Holtz 2010-10-14 22:02:16 +00:00
parent 8efa3ccf32
commit 41001a2ab3
4 changed files with 233 additions and 156 deletions

View File

@ -191,47 +191,6 @@ static MACHINE_START( cdi )
scc68070_register_globals(machine, &state->scc68070_regs); scc68070_register_globals(machine, &state->scc68070_regs);
} }
static DRIVER_INIT( quizrd12 )
{
scc68070_set_quizard_mcu_value(machine, 0x021f);
scc68070_set_quizard_mcu_ack(machine, 0x5a);
}
static DRIVER_INIT( quizrd17 )
{
scc68070_set_quizard_mcu_value(machine, 0x021f);
scc68070_set_quizard_mcu_ack(machine, 0x5a);
}
static DRIVER_INIT( quizrd22 )
{
// 0x2b1: Italian
// 0x001: French
// 0x188: German
scc68070_set_quizard_mcu_value(machine, 0x188);
scc68070_set_quizard_mcu_ack(machine, 0x59);
}
static DRIVER_INIT( quizrd32 )
{
scc68070_set_quizard_mcu_value(machine, 0x00ae);
scc68070_set_quizard_mcu_ack(machine, 0x58);
}
static DRIVER_INIT( quizrr41 )
{
scc68070_set_quizard_mcu_value(machine, 0x011f);
scc68070_set_quizard_mcu_ack(machine, 0x57);
}
static DRIVER_INIT( quizrr42 )
{
scc68070_set_quizard_mcu_value(machine, 0x011f);
scc68070_set_quizard_mcu_ack(machine, 0x57);
}
static MACHINE_RESET( cdi ) static MACHINE_RESET( cdi )
{ {
cdi_state *state = machine->driver_data<cdi_state>(); cdi_state *state = machine->driver_data<cdi_state>();
@ -248,6 +207,58 @@ static MACHINE_RESET( cdi )
state->dmadac[1] = machine->device<dmadac_sound_device>("dac2"); state->dmadac[1] = machine->device<dmadac_sound_device>("dac2");
} }
static MACHINE_RESET( quizrd12 )
{
MACHINE_RESET_CALL( cdi );
scc68070_set_quizard_mcu_value(machine, 0x021f);
scc68070_set_quizard_mcu_ack(machine, 0x5a);
}
static MACHINE_RESET( quizrd17 )
{
MACHINE_RESET_CALL( cdi );
scc68070_set_quizard_mcu_value(machine, 0x021f);
scc68070_set_quizard_mcu_ack(machine, 0x5a);
}
static MACHINE_RESET( quizrd22 )
{
MACHINE_RESET_CALL( cdi );
// 0x2b1: Italian
// 0x001: French
// 0x188: German
scc68070_set_quizard_mcu_value(machine, 0x188);
scc68070_set_quizard_mcu_ack(machine, 0x59);
}
static MACHINE_RESET( quizrd32 )
{
MACHINE_RESET_CALL( cdi );
scc68070_set_quizard_mcu_value(machine, 0x00ae);
scc68070_set_quizard_mcu_ack(machine, 0x58);
}
static MACHINE_RESET( quizrr41 )
{
MACHINE_RESET_CALL( cdi );
scc68070_set_quizard_mcu_value(machine, 0x0139);
scc68070_set_quizard_mcu_ack(machine, 0x57);
}
static MACHINE_RESET( quizrr42 )
{
MACHINE_RESET_CALL( cdi );
scc68070_set_quizard_mcu_value(machine, 0x011f);
scc68070_set_quizard_mcu_ack(machine, 0x57);
}
/************************* /*************************
* Machine Drivers * * Machine Drivers *
*************************/ *************************/
@ -256,6 +267,7 @@ static MACHINE_CONFIG_START( cdi, cdi_state )
MDRV_CPU_ADD("maincpu", SCC68070, CLOCK_A/2) MDRV_CPU_ADD("maincpu", SCC68070, CLOCK_A/2)
MDRV_CPU_PROGRAM_MAP(cdimono1_mem) MDRV_CPU_PROGRAM_MAP(cdimono1_mem)
MDRV_CPU_VBLANK_INT("screen", scc68070_mcu_frame)
MDRV_SCREEN_ADD("screen", RASTER) MDRV_SCREEN_ADD("screen", RASTER)
MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_REFRESH_RATE(60)
@ -278,7 +290,6 @@ static MACHINE_CONFIG_START( cdi, cdi_state )
MDRV_VIDEO_START(cdimono1) MDRV_VIDEO_START(cdimono1)
MDRV_VIDEO_UPDATE(cdimono1) MDRV_VIDEO_UPDATE(cdimono1)
MDRV_MACHINE_RESET(cdi)
MDRV_MACHINE_START(cdi) MDRV_MACHINE_START(cdi)
MDRV_CDICDIC_ADD( "cdic" ) MDRV_CDICDIC_ADD( "cdic" )
@ -300,6 +311,30 @@ static MACHINE_CONFIG_START( cdi, cdi_state )
MDRV_MK48T08_ADD( "mk48t08" ) MDRV_MK48T08_ADD( "mk48t08" )
MACHINE_CONFIG_END MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrd12, cdi )
MDRV_MACHINE_RESET( quizrd12 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrd17, cdi )
MDRV_MACHINE_RESET( quizrd17 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrd22, cdi )
MDRV_MACHINE_RESET( quizrd22 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrd32, cdi )
MDRV_MACHINE_RESET( quizrd32 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrr41, cdi )
MDRV_MACHINE_RESET( quizrr41 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizrr42, cdi )
MDRV_MACHINE_RESET( quizrr42 )
MACHINE_CONFIG_END
/************************* /*************************
* Rom Load * * Rom Load *
*************************/ *************************/
@ -404,14 +439,14 @@ ROM_END
*************************/ *************************/
// BIOS // BIOS
GAME( 1991, cdi, 0, cdi, cdi, 0, ROT0, "Philips", "CD-i (Mono-I) BIOS", GAME_IS_BIOS_ROOT ) GAME( 1991, cdi, 0, cdi, cdi, 0, ROT0, "Philips", "CD-i (Mono-I) BIOS", GAME_IS_BIOS_ROOT )
// Working // Working
GAME( 1995, quizrd12, cdi, cdi, cdi, quizrd12, ROT0, "TAB Austria", "Quizard 1.2", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1995, quizrd12, cdi, quizrd12, cdi, 0, ROT0, "TAB Austria", "Quizard 1.2", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )
GAME( 1995, quizrd17, cdi, cdi, cdi, quizrd17, ROT0, "TAB Austria", "Quizard 1.7", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1995, quizrd17, cdi, quizrd17, cdi, 0, ROT0, "TAB Austria", "Quizard 1.7", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )
GAME( 1995, quizrd22, cdi, cdi, cdi, quizrd22, ROT0, "TAB Austria", "Quizard 2.2", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1995, quizrd22, cdi, quizrd22, cdi, 0, ROT0, "TAB Austria", "Quizard 2.2", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )
// Partially working // Partially working
GAME( 1996, quizard, cdi, cdi, cdi, quizrd32, ROT0, "TAB Austria", "Quizard 3.2", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1996, quizard, cdi, quizrd32, cdi, 0, ROT0, "TAB Austria", "Quizard 3.2", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )
GAME( 1998, quizrr41, cdi, cdi, cdi, quizrr41, ROT0, "TAB Austria", "Quizard Rainbow 4.1", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1998, quizrr41, cdi, quizrr41, cdi, 0, ROT0, "TAB Austria", "Quizard Rainbow 4.1", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )
GAME( 1998, quizrr42, cdi, cdi, cdi, quizrr42, ROT0, "TAB Austria", "Quizard Rainbow 4.2", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION ) GAME( 1998, quizrr42, cdi, quizrr42, cdi, 0, ROT0, "TAB Austria", "Quizard Rainbow 4.2", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION )

View File

@ -33,9 +33,9 @@ public:
/*----------- debug defines -----------*/ /*----------- debug defines -----------*/
#define VERBOSE_LEVEL (5) #define VERBOSE_LEVEL (0)
#define ENABLE_VERBOSE_LOG (1) #define ENABLE_VERBOSE_LOG (0)
#define ENABLE_UART_PRINTING (0) #define ENABLE_UART_PRINTING (0)

View File

@ -24,8 +24,6 @@ TODO:
#include "machine/cdi070.h" #include "machine/cdi070.h"
#include "includes/cdi.h" #include "includes/cdi.h"
#define ENABLE_QUIZARD_HACK (1)
#if ENABLE_VERBOSE_LOG #if ENABLE_VERBOSE_LOG
INLINE void verboselog(running_machine *machine, int n_level, const char *s_fmt, ...) INLINE void verboselog(running_machine *machine, int n_level, const char *s_fmt, ...)
{ {
@ -43,6 +41,9 @@ INLINE void verboselog(running_machine *machine, int n_level, const char *s_fmt,
#define verboselog(x,y,z,...) #define verboselog(x,y,z,...)
#endif #endif
static UINT16 mcu_value = 0;
static UINT8 mcu_ack = 0;
static void scc68070_set_timer_callback(scc68070_regs_t *scc68070, int channel) static void scc68070_set_timer_callback(scc68070_regs_t *scc68070, int channel)
{ {
UINT32 compare = 0; UINT32 compare = 0;
@ -61,18 +62,12 @@ static void scc68070_set_timer_callback(scc68070_regs_t *scc68070, int channel)
void scc68070_set_quizard_mcu_ack(running_machine *machine, UINT8 ack) void scc68070_set_quizard_mcu_ack(running_machine *machine, UINT8 ack)
{ {
cdi_state *state = machine->driver_data<cdi_state>(); mcu_ack = ack;
scc68070_regs_t *scc68070 = &state->scc68070_regs;
scc68070->mcu_ack = ack;
} }
void scc68070_set_quizard_mcu_value(running_machine *machine, UINT16 value) void scc68070_set_quizard_mcu_value(running_machine *machine, UINT16 value)
{ {
cdi_state *state = machine->driver_data<cdi_state>(); mcu_value = value;
scc68070_regs_t *scc68070 = &state->scc68070_regs;
scc68070->mcu_value = value;
} }
TIMER_CALLBACK( scc68070_timer0_callback ) TIMER_CALLBACK( scc68070_timer0_callback )
@ -98,10 +93,8 @@ TIMER_CALLBACK( scc68070_timer0_callback )
static void scc68070_uart_rx_check(running_machine *machine, scc68070_regs_t *scc68070) static void scc68070_uart_rx_check(running_machine *machine, scc68070_regs_t *scc68070)
{ {
if((scc68070->uart.command_register & 3) == 1 && if((scc68070->uart.command_register & 3) == 1)
scc68070->uart.receive_pointer > -1)
{ {
scc68070->uart.status_register |= USR_RXRDY;
UINT32 div = 0x10000 >> ((scc68070->uart.clock_select >> 4) & 7); UINT32 div = 0x10000 >> ((scc68070->uart.clock_select >> 4) & 7);
timer_adjust_oneshot(scc68070->uart.rx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0); timer_adjust_oneshot(scc68070->uart.rx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0);
} }
@ -114,12 +107,22 @@ static void scc68070_uart_rx_check(running_machine *machine, scc68070_regs_t *sc
static void scc68070_uart_tx_check(running_machine *machine, scc68070_regs_t *scc68070) static void scc68070_uart_tx_check(running_machine *machine, scc68070_regs_t *scc68070)
{ {
if(((scc68070->uart.command_register >> 2) & 3) == 1 && if(((scc68070->uart.command_register >> 2) & 3) == 1)
scc68070->uart.transmit_pointer > -1 &&
attotime_compare(timer_timeleft(scc68070->uart.tx_timer), attotime_never) == 0)
{ {
UINT32 div = 0x10000 >> (scc68070->uart.clock_select & 7); if(scc68070->uart.transmit_pointer >= 0)
timer_adjust_oneshot(scc68070->uart.tx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0); {
scc68070->uart.status_register &= ~USR_TXRDY;
}
else
{
scc68070->uart.status_register |= USR_TXRDY;
}
if(attotime_compare(timer_timeleft(scc68070->uart.tx_timer), attotime_never) == 0)
{
UINT32 div = 0x10000 >> (scc68070->uart.clock_select & 7);
timer_adjust_oneshot(scc68070->uart.tx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0);
}
} }
else else
{ {
@ -129,9 +132,9 @@ static void scc68070_uart_tx_check(running_machine *machine, scc68070_regs_t *sc
void scc68070_uart_rx(running_machine *machine, scc68070_regs_t *scc68070, UINT8 data) void scc68070_uart_rx(running_machine *machine, scc68070_regs_t *scc68070, UINT8 data)
{ {
//printf("%d: %02x\n", scc68070->uart.receive_pointer + 1, data);
scc68070->uart.receive_pointer++; scc68070->uart.receive_pointer++;
scc68070->uart.receive_buffer[scc68070->uart.receive_pointer] = data; scc68070->uart.receive_buffer[scc68070->uart.receive_pointer] = data;
scc68070->uart.status_register |= USR_RXRDY;
scc68070_uart_rx_check(machine, scc68070); scc68070_uart_rx_check(machine, scc68070);
} }
@ -139,27 +142,30 @@ void scc68070_uart_tx(running_machine *machine, scc68070_regs_t *scc68070, UINT8
{ {
scc68070->uart.transmit_pointer++; scc68070->uart.transmit_pointer++;
scc68070->uart.transmit_buffer[scc68070->uart.transmit_pointer] = data; scc68070->uart.transmit_buffer[scc68070->uart.transmit_pointer] = data;
scc68070->uart.status_register |= USR_TXRDY;
scc68070_uart_tx_check(machine, scc68070); scc68070_uart_tx_check(machine, scc68070);
} }
TIMER_CALLBACK( scc68070_rx_callback ) TIMER_CALLBACK( scc68070_rx_callback )
{ {
bool clear_int = false;
cdi_state *state = machine->driver_data<cdi_state>(); cdi_state *state = machine->driver_data<cdi_state>();
scc68070_regs_t *scc68070 = &state->scc68070_regs; scc68070_regs_t *scc68070 = &state->scc68070_regs;
if((scc68070->uart.command_register & 3) == 1) if((scc68070->uart.command_register & 3) == 1)
{ {
if(scc68070->uart.receive_pointer >= 0)
{
scc68070->uart.status_register |= USR_RXRDY;
}
else
{
scc68070->uart.status_register &= ~USR_RXRDY;
}
scc68070->uart.receive_holding_register = scc68070->uart.receive_buffer[0]; scc68070->uart.receive_holding_register = scc68070->uart.receive_buffer[0];
if(scc68070->uart.receive_pointer > -1) if(scc68070->uart.receive_pointer > -1)
{ {
verboselog(machine, 2, "scc68070_rx_callback: Receiving %02x\n", scc68070->uart.receive_holding_register); verboselog(machine, 2, "scc68070_rx_callback: Receiving %02x\n", scc68070->uart.receive_holding_register);
for(int index = 0; index < scc68070->uart.receive_pointer; index++)
{
scc68070->uart.receive_buffer[index] = scc68070->uart.receive_buffer[index + 1];
}
scc68070->uart.receive_pointer--;
UINT8 interrupt = (scc68070->picr2 >> 4) & 7; UINT8 interrupt = (scc68070->picr2 >> 4) & 7;
if(interrupt) if(interrupt)
@ -167,10 +173,6 @@ TIMER_CALLBACK( scc68070_rx_callback )
cpu_set_input_line_vector(machine->device("maincpu"), M68K_IRQ_1 + (interrupt - 1), 56 + interrupt); cpu_set_input_line_vector(machine->device("maincpu"), M68K_IRQ_1 + (interrupt - 1), 56 + interrupt);
cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), ASSERT_LINE); cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), ASSERT_LINE);
} }
else
{
clear_int = true;
}
scc68070->uart.status_register |= USR_RXRDY; scc68070->uart.status_register |= USR_RXRDY;
UINT32 div = 0x10000 >> ((scc68070->uart.clock_select >> 4) & 7); UINT32 div = 0x10000 >> ((scc68070->uart.clock_select >> 4) & 7);
@ -178,34 +180,15 @@ TIMER_CALLBACK( scc68070_rx_callback )
} }
else else
{ {
clear_int = true;
scc68070->uart.status_register &= ~USR_RXRDY; scc68070->uart.status_register &= ~USR_RXRDY;
timer_adjust_oneshot(scc68070->uart.rx_timer, attotime_never, 0);
} }
} }
else else
{ {
clear_int = true;
scc68070->uart.status_register &= ~USR_RXRDY; scc68070->uart.status_register &= ~USR_RXRDY;
timer_adjust_oneshot(scc68070->uart.rx_timer, attotime_never, 0);
} }
if(clear_int) scc68070_uart_rx_check(machine, scc68070);
{
UINT8 interrupt = scc68070->picr2 & 7;
cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), CLEAR_LINE);
}
}
static void scc68070_tx_empty(running_machine *machine, scc68070_regs_t *scc68070)
{
UINT8 interrupt = scc68070->picr2 & 7;
scc68070->uart.status_register |= USR_TXRDY;
if(interrupt)
{
cpu_set_input_line_vector(machine->device("maincpu"), M68K_IRQ_1 + (interrupt - 1), 56 + interrupt);
cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), ASSERT_LINE);
}
} }
static UINT16 seeds[10] = { 0 }; static UINT16 seeds[10] = { 0 };
@ -216,7 +199,7 @@ void scc68070_quizard_rx(running_machine *machine, scc68070_regs_t *scc68070, UI
scc68070_uart_rx(machine, scc68070, 0x5a); scc68070_uart_rx(machine, scc68070, 0x5a);
for(int index = 0; index < 8; index++) for(int index = 0; index < 8; index++)
{ {
scc68070_uart_rx(machine, scc68070, 0); scc68070_uart_rx(machine, scc68070, g_state[index]);
} }
scc68070_uart_rx(machine, scc68070, data); scc68070_uart_rx(machine, scc68070, data);
} }
@ -237,7 +220,7 @@ static void quizard_set_seeds(UINT8 *rx)
static void quizard_calculate_state(running_machine *machine, scc68070_regs_t *scc68070) static void quizard_calculate_state(running_machine *machine, scc68070_regs_t *scc68070)
{ {
const UINT16 desired_bitfield = scc68070->mcu_value; const UINT16 desired_bitfield = mcu_value;
const UINT16 field0 = 0x00ff; const UINT16 field0 = 0x00ff;
const UINT16 field1 = desired_bitfield ^ field0; const UINT16 field1 = desired_bitfield ^ field0;
@ -273,52 +256,87 @@ static void quizard_calculate_state(running_machine *machine, scc68070_regs_t *s
g_state[5] = lo1 - g_state[4]; g_state[5] = lo1 - g_state[4];
} }
INTERRUPT_GEN( scc68070_mcu_frame )
{
cdi_state *state = device->machine->driver_data<cdi_state>();
scc68070_regs_t *scc68070 = &state->scc68070_regs;
if(0)//mcu_active)
{
quizard_calculate_state(device->machine, scc68070);
scc68070_uart_rx(device->machine, scc68070, 0x5a);
for(int index = 0; index < 8; index++)
{
scc68070_uart_rx(device->machine, scc68070, g_state[index]);
}
}
}
static void quizard_handle_byte_tx(running_machine *machine, scc68070_regs_t *scc68070) static void quizard_handle_byte_tx(running_machine *machine, scc68070_regs_t *scc68070)
{ {
static UINT8 rx[0x100]; static UINT8 rx[0x100];
static UINT8 rx_ptr = 0xff; static UINT8 rx_ptr = 0xff;
static UINT8 state = 0;
static UINT8 ack_count = 0; static UINT8 ack_count = 0;
UINT8 tx = scc68070->uart.transmit_holding_register; UINT8 tx = scc68070->uart.transmit_holding_register;
switch(state) /*
if((tx >= 0x20 && tx < 0x7f) || tx == 0x0d || tx == 0x0a)
{ {
case 0: printf("%c", tx);
if(tx == 0x56) }
{ else
state++; {
} printf("\n%02x? %02x\n", tx, mcu_ack);
break; }
*/
case 1: if(tx == 0x56)
if(tx == scc68070->mcu_ack) {
{ ack_count = 0;
ack_count++; rx_ptr = 0xff;
if(ack_count == 2) // We're about to lead off a sequence!
{ }
state++; else if(tx == 0x0d || tx == 0x0a)
quizard_set_seeds(rx); {
quizard_calculate_state(machine, scc68070); ack_count++;
scc68070_uart_rx(machine, scc68070, 0x5a); if(ack_count == 2)
for(int index = 0; index < 8; index++) {
{ scc68070_uart_rx(machine, scc68070, 0x5a);
scc68070_uart_rx(machine, scc68070, g_state[index]); 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]);
else scc68070_uart_rx(machine, scc68070, g_state[4]);
{ scc68070_uart_rx(machine, scc68070, g_state[5]);
rx_ptr++; scc68070_uart_rx(machine, scc68070, g_state[6]);
rx[rx_ptr] = tx; scc68070_uart_rx(machine, scc68070, g_state[7]);
} }
break; }
else if(tx == mcu_ack)
case 2: {
if(tx == 0x56) ack_count++;
{ if(ack_count == 2)
state = 1; {
} //printf("Calculating seeds\n");
break; quizard_set_seeds(rx);
quizard_calculate_state(machine, scc68070);
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]);
rx_ptr = 0xff;
}
}
else
{
ack_count = 0;
rx_ptr++;
rx[rx_ptr] = tx;
} }
} }
@ -329,17 +347,24 @@ TIMER_CALLBACK( scc68070_tx_callback )
if(((scc68070->uart.command_register >> 2) & 3) == 1) if(((scc68070->uart.command_register >> 2) & 3) == 1)
{ {
UINT8 interrupt = scc68070->picr2 & 7;
if(interrupt)
{
cpu_set_input_line_vector(machine->device("maincpu"), M68K_IRQ_1 + (interrupt - 1), 56 + interrupt);
cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), ASSERT_LINE);
}
if(scc68070->uart.transmit_pointer > -1) if(scc68070->uart.transmit_pointer > -1)
{ {
scc68070->uart.transmit_holding_register = scc68070->uart.transmit_buffer[0]; scc68070->uart.transmit_holding_register = scc68070->uart.transmit_buffer[0];
quizard_handle_byte_tx(machine, scc68070); quizard_handle_byte_tx(machine, scc68070);
verboselog(machine, 2, "scc68070_tx_callback: Transmitting %02x\n", scc68070->uart.transmit_holding_register); verboselog(machine, 2, "scc68070_tx_callback: Transmitting %02x\n", scc68070->uart.transmit_holding_register);
scc68070->uart.transmit_pointer--;
for(int index = 0; index < scc68070->uart.transmit_pointer; index++) for(int index = 0; index < scc68070->uart.transmit_pointer; index++)
{ {
scc68070->uart.transmit_buffer[index] = scc68070->uart.transmit_buffer[index+1]; scc68070->uart.transmit_buffer[index] = scc68070->uart.transmit_buffer[index+1];
} }
scc68070->uart.transmit_pointer--;
UINT32 div = 0x10000 >> (scc68070->uart.clock_select & 7); UINT32 div = 0x10000 >> (scc68070->uart.clock_select & 7);
timer_adjust_oneshot(scc68070->uart.tx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0); timer_adjust_oneshot(scc68070->uart.tx_timer, ATTOTIME_IN_HZ((49152000 / div) / 8), 0);
@ -347,18 +372,14 @@ TIMER_CALLBACK( scc68070_tx_callback )
else else
{ {
timer_adjust_oneshot(scc68070->uart.tx_timer, attotime_never, 0); timer_adjust_oneshot(scc68070->uart.tx_timer, attotime_never, 0);
scc68070_tx_empty(machine, scc68070);
} }
} }
else else
{ {
timer_adjust_oneshot(scc68070->uart.tx_timer, attotime_never, 0); timer_adjust_oneshot(scc68070->uart.tx_timer, attotime_never, 0);
UINT8 interrupt = (scc68070->picr2 >> 4) & 7;
if(interrupt)
{
cputag_set_input_line(machine, "maincpu", M68K_IRQ_1 + (interrupt - 1), CLEAR_LINE);
}
} }
scc68070_uart_tx_check(machine, scc68070);
} }
READ16_HANDLER( scc68070_periphs_r ) READ16_HANDLER( scc68070_periphs_r )
@ -425,7 +446,19 @@ READ16_HANDLER( scc68070_periphs_r )
{ {
verboselog(space->machine, 0, "scc68070_periphs_r: Unknown address: %04x & %04x\n", offset * 2, mem_mask); verboselog(space->machine, 0, "scc68070_periphs_r: Unknown address: %04x & %04x\n", offset * 2, mem_mask);
} }
if((scc68070->picr2 >> 4) & 7)
{
cputag_set_input_line(space->machine, "maincpu", M68K_IRQ_1 + (((scc68070->picr2 >> 4) & 7) - 1), ASSERT_LINE);
}
if(scc68070->picr2 & 7)
{
cputag_set_input_line(space->machine, "maincpu", M68K_IRQ_1 + ((scc68070->picr2 & 7) - 1), ASSERT_LINE);
}
return scc68070->uart.status_register; return scc68070->uart.status_register;
case 0x2014/2: case 0x2014/2:
if(ACCESSING_BITS_0_7) if(ACCESSING_BITS_0_7)
{ {
@ -465,6 +498,21 @@ READ16_HANDLER( scc68070_periphs_r )
{ {
verboselog(space->machine, 0, "scc68070_periphs_r: Unknown address: %04x & %04x\n", offset * 2, mem_mask); verboselog(space->machine, 0, "scc68070_periphs_r: Unknown address: %04x & %04x\n", offset * 2, mem_mask);
} }
if((scc68070->picr2 >> 4) & 7)
{
cputag_set_input_line(space->machine, "maincpu", M68K_IRQ_1 + (((scc68070->picr2 >> 4) & 7) - 1), CLEAR_LINE);
}
scc68070->uart.receive_holding_register = scc68070->uart.receive_buffer[0];
if(scc68070->uart.receive_pointer >= 0)
{
for(int index = 0; index < scc68070->uart.receive_pointer; index++)
{
scc68070->uart.receive_buffer[index] = scc68070->uart.receive_buffer[index + 1];
}
scc68070->uart.receive_pointer--;
}
//printf("R: %02x\n", scc68070->uart.receive_holding_register);
return scc68070->uart.receive_holding_register; return scc68070->uart.receive_holding_register;
// Timers: 80002020 to 80002029 // Timers: 80002020 to 80002029
@ -715,11 +763,6 @@ WRITE16_HANDLER( scc68070_periphs_w )
{ {
verboselog(space->machine, 2, "scc68070_periphs_w: UART Command Register: %04x & %04x\n", data, mem_mask); verboselog(space->machine, 2, "scc68070_periphs_w: UART Command Register: %04x & %04x\n", data, mem_mask);
scc68070->uart.command_register = data & 0x00ff; scc68070->uart.command_register = data & 0x00ff;
if(((scc68070->uart.command_register >> 2) & 3) == 1 &&
scc68070->uart.transmit_pointer == -1)
{
scc68070_tx_empty(space->machine, scc68070);
}
scc68070_uart_rx_check(space->machine, scc68070); scc68070_uart_rx_check(space->machine, scc68070);
scc68070_uart_tx_check(space->machine, scc68070); scc68070_uart_tx_check(space->machine, scc68070);
} }
@ -958,7 +1001,7 @@ void scc68070_init(running_machine *machine, scc68070_regs_t *scc68070)
scc68070->i2c.clock_control_register = 0; scc68070->i2c.clock_control_register = 0;
scc68070->uart.mode_register = 0; scc68070->uart.mode_register = 0;
scc68070->uart.status_register = 0; scc68070->uart.status_register = USR_TXRDY;
scc68070->uart.clock_select = 0; scc68070->uart.clock_select = 0;
scc68070->uart.command_register = 0; scc68070->uart.command_register = 0;
scc68070->uart.transmit_holding_register = 0; scc68070->uart.transmit_holding_register = 0;

View File

@ -228,9 +228,6 @@ typedef struct
scc68070_timer_regs_t timers; scc68070_timer_regs_t timers;
scc68070_dma_regs_t dma; scc68070_dma_regs_t dma;
scc68070_mmu_regs_t mmu; scc68070_mmu_regs_t mmu;
UINT16 mcu_value;
UINT8 mcu_ack;
} scc68070_regs_t; } scc68070_regs_t;
// Member functions // Member functions
@ -251,4 +248,6 @@ extern void scc68070_set_quizard_mcu_value(running_machine *machine, UINT16 valu
extern void scc68070_set_quizard_mcu_ack(running_machine *machine, UINT8 ack); extern void scc68070_set_quizard_mcu_ack(running_machine *machine, UINT8 ack);
extern void scc68070_quizard_rx(running_machine *machine, scc68070_regs_t *scc68070, UINT8 data); extern void scc68070_quizard_rx(running_machine *machine, scc68070_regs_t *scc68070, UINT8 data);
extern INTERRUPT_GEN( scc68070_mcu_frame );
#endif // _MACHINE_CDI070_H_ #endif // _MACHINE_CDI070_H_