6522VIA: Implemented CA2 pulse output mode, and output interrupt state only when it changes. [Curt Coder]

6532RIOT: Output interrupt state only when it changes. [Curt Coder]
This commit is contained in:
Curt Coder 2011-11-13 14:56:06 +00:00
parent a0eb72aea0
commit 35762c3186
4 changed files with 53 additions and 37 deletions

View File

@ -109,6 +109,15 @@
INLINE FUNCTIONS INLINE FUNCTIONS
***************************************************************************/ ***************************************************************************/
inline void via6522_device::set_irq_line(int state)
{
if (m_irq != state)
{
m_irq_func(state);
m_irq = state;
}
}
attotime via6522_device::cycles_to_time(int c) attotime via6522_device::cycles_to_time(int c)
{ {
return attotime::from_hz(clock()) * c; return attotime::from_hz(clock()) * c;
@ -150,7 +159,8 @@ const device_type VIA6522 = &device_creator<via6522_device>;
//------------------------------------------------- //-------------------------------------------------
via6522_device::via6522_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) via6522_device::via6522_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VIA6522, "6522 VIA", tag, owner, clock) : device_t(mconfig, VIA6522, "6522 VIA", tag, owner, clock),
m_irq(CLEAR_LINE)
{ {
} }
@ -214,6 +224,7 @@ void via6522_device::device_start()
m_time2 = m_time1 = machine().time(); m_time2 = m_time1 = machine().time();
m_t1 = timer_alloc(TIMER_T1); m_t1 = timer_alloc(TIMER_T1);
m_t2 = timer_alloc(TIMER_T2); m_t2 = timer_alloc(TIMER_T2);
m_ca2_timer = timer_alloc(TIMER_CA2);
m_shift_timer = timer_alloc(TIMER_SHIFT); m_shift_timer = timer_alloc(TIMER_SHIFT);
/* Default clock is from CPU1 */ /* Default clock is from CPU1 */
@ -248,6 +259,7 @@ void via6522_device::device_start()
save_item(NAME(m_acr)); save_item(NAME(m_acr));
save_item(NAME(m_ier)); save_item(NAME(m_ier));
save_item(NAME(m_ifr)); save_item(NAME(m_ifr));
save_item(NAME(m_irq));
save_item(NAME(m_t1_active)); save_item(NAME(m_t1_active));
save_item(NAME(m_t2_active)); save_item(NAME(m_t2_active));
save_item(NAME(m_shift_counter)); save_item(NAME(m_shift_counter));
@ -304,7 +316,7 @@ void via6522_device::set_int(int data)
if (m_ier & m_ifr) if (m_ier & m_ifr)
{ {
m_ifr |= INT_ANY; m_ifr |= INT_ANY;
m_irq_func(ASSERT_LINE); set_irq_line(ASSERT_LINE);
} }
} }
@ -328,7 +340,7 @@ void via6522_device::clear_int(int data)
} }
else else
{ {
m_irq_func(CLEAR_LINE); set_irq_line(CLEAR_LINE);
} }
} }
@ -459,6 +471,11 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
set_int(INT_T2); set_int(INT_T2);
} }
break; break;
case TIMER_CA2:
m_out_ca2_func(1);
m_out_ca2 = 1;
break;
} }
} }
@ -528,7 +545,17 @@ READ8_MEMBER( via6522_device::read )
/* If CA2 is configured as output and in pulse or handshake mode, /* If CA2 is configured as output and in pulse or handshake mode,
CA2 is set now */ CA2 is set now */
if (CA2_AUTO_HS(m_pcr)) if (CA2_PULSE_OUTPUT(m_pcr))
{
/* call the CA2 output function */
m_out_ca2_func(0);
m_out_ca2 = 0;
m_ca2_timer->adjust(cycles_to_time(1));
}
/* If CA2 is configured as output and in pulse or handshake mode,
CA2 is set now */
else if (CA2_AUTO_HS(m_pcr))
{ {
if (m_out_ca2) if (m_out_ca2)
{ {
@ -712,10 +739,9 @@ WRITE8_MEMBER( via6522_device::write )
{ {
/* call the CA2 output function */ /* call the CA2 output function */
m_out_ca2_func(0); m_out_ca2_func(0);
m_out_ca2_func(1); m_out_ca2 = 0;
/* set CA2 (shouldn't be needed) */ m_ca2_timer->adjust(cycles_to_time(1));
m_out_ca2 = 1;
} }
else if (CA2_AUTO_HS(m_pcr)) else if (CA2_AUTO_HS(m_pcr))
{ {
@ -902,7 +928,7 @@ WRITE8_MEMBER( via6522_device::write )
if (((m_ifr & m_ier) & 0x7f) == 0) if (((m_ifr & m_ier) & 0x7f) == 0)
{ {
m_ifr &= ~INT_ANY; m_ifr &= ~INT_ANY;
m_irq_func(CLEAR_LINE); set_irq_line(CLEAR_LINE);
} }
} }
else else
@ -910,7 +936,7 @@ WRITE8_MEMBER( via6522_device::write )
if ((m_ier & m_ifr) & 0x7f) if ((m_ier & m_ifr) & 0x7f)
{ {
m_ifr |= INT_ANY; m_ifr |= INT_ANY;
m_irq_func(ASSERT_LINE); set_irq_line(ASSERT_LINE);
} }
} }
break; break;

View File

@ -119,11 +119,13 @@ private:
static const device_timer_id TIMER_SHIFT = 0; static const device_timer_id TIMER_SHIFT = 0;
static const device_timer_id TIMER_T1 = 1; static const device_timer_id TIMER_T1 = 1;
static const device_timer_id TIMER_T2 = 2; static const device_timer_id TIMER_T2 = 2;
static const device_timer_id TIMER_CA2 = 3;
attotime cycles_to_time(int c); attotime cycles_to_time(int c);
UINT32 time_to_cycles(attotime t); UINT32 time_to_cycles(attotime t);
UINT16 get_counter1_value(); UINT16 get_counter1_value();
inline void set_irq_line(int state);
void set_int(int data); void set_int(int data);
void clear_int(int data); void clear_int(int data);
void shift(); void shift();
@ -170,6 +172,7 @@ private:
UINT8 m_acr; UINT8 m_acr;
UINT8 m_ier; UINT8 m_ier;
UINT8 m_ifr; UINT8 m_ifr;
int m_irq;
emu_timer *m_t1; emu_timer *m_t1;
attotime m_time1; attotime m_time1;
@ -177,6 +180,7 @@ private:
emu_timer *m_t2; emu_timer *m_t2;
attotime m_time2; attotime m_time2;
UINT8 m_t2_active; UINT8 m_t2_active;
emu_timer *m_ca2_timer;
emu_timer *m_shift_timer; emu_timer *m_shift_timer;
UINT8 m_shift_counter; UINT8 m_shift_counter;

View File

@ -46,15 +46,12 @@ enum
void riot6532_device::update_irqstate() void riot6532_device::update_irqstate()
{ {
int state = (m_irqstate & m_irqenable); int irq = (m_irqstate & m_irqenable) ? ASSERT_LINE : CLEAR_LINE;
if (!m_irq_func.isnull()) if (m_irq != irq)
{ {
m_irq_func((state != 0) ? ASSERT_LINE : CLEAR_LINE); m_irq_func(irq);
} m_irq = irq;
else
{
logerror("%s:6532RIOT chip #%d: no irq callback function\n", machine().describe_context(), m_index);
} }
} }
@ -229,14 +226,7 @@ void riot6532_device::reg_w(UINT8 offset, UINT8 data)
else else
{ {
port->m_out = data; port->m_out = data;
if (!port->m_out_func.isnull()) port->m_out_func(0, data);
{
port->m_out_func(0, data);
}
else
{
logerror("%s:6532RIOT chip %s: Port %c is being written to but has no handler. %02X\n", machine().describe_context(), tag(), 'A' + (offset & 1), data);
}
} }
/* writes to port A need to update the PA7 state */ /* writes to port A need to update the PA7 state */
@ -311,19 +301,12 @@ UINT8 riot6532_device::reg_r(UINT8 offset)
else else
{ {
/* call the input callback if it exists */ /* call the input callback if it exists */
if (!port->m_in_func.isnull()) port->m_in = port->m_in_func(0);
{
port->m_in = port->m_in_func(0);
/* changes to port A need to update the PA7 state */ /* changes to port A need to update the PA7 state */
if (port == &m_port[0]) if (port == &m_port[0])
{
update_pa7_state();
}
}
else
{ {
logerror("%s:6532RIOT chip %s: Port %c is being read but has no handler\n", machine().describe_context(), tag(), 'A' + (offset & 1)); update_pa7_state();
} }
/* apply the DDR to the result */ /* apply the DDR to the result */
@ -440,7 +423,8 @@ UINT8 riot6532_device::portb_out_get()
//------------------------------------------------- //-------------------------------------------------
riot6532_device::riot6532_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) riot6532_device::riot6532_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, RIOT6532, "6532 (RIOT)", tag, owner, clock) : device_t(mconfig, RIOT6532, "6532 (RIOT)", tag, owner, clock),
m_irq(CLEAR_LINE)
{ {
} }
@ -506,6 +490,7 @@ void riot6532_device::device_start()
save_item(NAME(m_irqstate)); save_item(NAME(m_irqstate));
save_item(NAME(m_irqenable)); save_item(NAME(m_irqenable));
save_item(NAME(m_irq));
save_item(NAME(m_pa7dir)); save_item(NAME(m_pa7dir));
save_item(NAME(m_pa7prev)); save_item(NAME(m_pa7prev));

View File

@ -98,6 +98,7 @@ private:
UINT8 m_irqstate; UINT8 m_irqstate;
UINT8 m_irqenable; UINT8 m_irqenable;
int m_irq;
UINT8 m_pa7dir; /* 0x80 = high-to-low, 0x00 = low-to-high */ UINT8 m_pa7dir; /* 0x80 = high-to-low, 0x00 = low-to-high */
UINT8 m_pa7prev; UINT8 m_pa7prev;