mirror of
https://github.com/holub/mame
synced 2025-04-27 10:43:07 +03:00
cpu/upd7810/upd7810.cpp: Improve uPD7801 Mode C handling. (#12914)
Fixes banking in SCV Star Speeder.
This commit is contained in:
parent
99634a7e33
commit
fe7e897e56
@ -623,25 +623,7 @@ uint8_t upd7810_device::RP(offs_t port)
|
|||||||
data = (m_pb_in & m_mb) | (m_pb_out & ~m_mb);
|
data = (m_pb_in & m_mb) | (m_pb_out & ~m_mb);
|
||||||
break;
|
break;
|
||||||
case UPD7810_PORTC:
|
case UPD7810_PORTC:
|
||||||
if (m_mc && !m_pc_in_cb.isunset()) // NS20031301 no need to read if the port is set as output
|
data = read_pc();
|
||||||
m_pc_in = m_pc_in_cb(0, m_mc);
|
|
||||||
data = (m_pc_in & m_mc) | (m_pc_out & ~m_mc);
|
|
||||||
if (m_mcc & 0x01) /* PC0 = TxD output */
|
|
||||||
data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00);
|
|
||||||
if (m_mcc & 0x02) /* PC1 = RxD input */
|
|
||||||
data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00);
|
|
||||||
if (m_mcc & 0x04) /* PC2 = SCK input/output */
|
|
||||||
data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00);
|
|
||||||
if (m_mcc & 0x08) /* PC3 = TI/INT2 input */
|
|
||||||
data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00);
|
|
||||||
if (m_mcc & 0x10) /* PC4 = TO output */
|
|
||||||
data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00);
|
|
||||||
if (m_mcc & 0x20) /* PC5 = CI input */
|
|
||||||
data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00);
|
|
||||||
if (m_mcc & 0x40) /* PC6 = CO0 output */
|
|
||||||
data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00);
|
|
||||||
if (m_mcc & 0x80) /* PC7 = CO1 output */
|
|
||||||
data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00);
|
|
||||||
break;
|
break;
|
||||||
case UPD7810_PORTD:
|
case UPD7810_PORTD:
|
||||||
if (!m_pd_in_cb.isunset())
|
if (!m_pd_in_cb.isunset())
|
||||||
@ -689,23 +671,11 @@ uint8_t upd7810_device::RP(offs_t port)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void upd7810_device::WP(offs_t port, uint8_t data)
|
uint8_t upd7810_device::read_pc()
|
||||||
{
|
{
|
||||||
switch (port)
|
if (m_mc && !m_pc_in_cb.isunset()) // NS20031301 no need to read if the port is set as output
|
||||||
{
|
m_pc_in = m_pc_in_cb(0, m_mc);
|
||||||
case UPD7810_PORTA:
|
uint8_t data = (m_pc_in & m_mc) | (m_pc_out & ~m_mc);
|
||||||
m_pa_out = data;
|
|
||||||
data = (data & ~m_ma) | (m_pa_pullups & m_ma);
|
|
||||||
m_pa_out_cb(data);
|
|
||||||
break;
|
|
||||||
case UPD7810_PORTB:
|
|
||||||
m_pb_out = data;
|
|
||||||
data = (data & ~m_mb) | (m_pb_pullups & m_mb);
|
|
||||||
m_pb_out_cb(data);
|
|
||||||
break;
|
|
||||||
case UPD7810_PORTC:
|
|
||||||
m_pc_out = data;
|
|
||||||
data = (data & ~m_mc) | (m_pc_pullups & m_mc);
|
|
||||||
if (m_mcc & 0x01) /* PC0 = TxD output */
|
if (m_mcc & 0x01) /* PC0 = TxD output */
|
||||||
data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00);
|
data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00);
|
||||||
if (m_mcc & 0x02) /* PC1 = RxD input */
|
if (m_mcc & 0x02) /* PC1 = RxD input */
|
||||||
@ -722,7 +692,38 @@ void upd7810_device::WP(offs_t port, uint8_t data)
|
|||||||
data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00);
|
data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00);
|
||||||
if (m_mcc & 0x80) /* PC7 = CO1 output */
|
if (m_mcc & 0x80) /* PC7 = CO1 output */
|
||||||
data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00);
|
data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00);
|
||||||
m_pc_out_cb(data);
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t upd7801_device::read_pc()
|
||||||
|
{
|
||||||
|
if ((m_mc & 0x87) && !m_pc_in_cb.isunset()) // NS20031301 no need to read if the port is set as output
|
||||||
|
m_pc_in = m_pc_in_cb(0, 0x84 | (m_mc & 0x03));
|
||||||
|
uint8_t data = (m_pc_in & 0x87) | (m_pc_out & ~0x87);
|
||||||
|
if (!BIT(m_mc, 2)) /* TODO PC2 = -SCS input */
|
||||||
|
data = (data & ~0x04) | 0x04;
|
||||||
|
if (!BIT(m_mc, 7)) /* TODO PC7 = HOLD input */
|
||||||
|
data = (data & ~0x80);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void upd7810_device::WP(offs_t port, uint8_t data)
|
||||||
|
{
|
||||||
|
switch (port)
|
||||||
|
{
|
||||||
|
case UPD7810_PORTA:
|
||||||
|
m_pa_out = data;
|
||||||
|
data = (data & ~m_ma) | (m_pa_pullups & m_ma);
|
||||||
|
m_pa_out_cb(data);
|
||||||
|
break;
|
||||||
|
case UPD7810_PORTB:
|
||||||
|
m_pb_out = data;
|
||||||
|
data = (data & ~m_mb) | (m_pb_pullups & m_mb);
|
||||||
|
m_pb_out_cb(data);
|
||||||
|
break;
|
||||||
|
case UPD7810_PORTC:
|
||||||
|
m_pc_out = data;
|
||||||
|
write_pc(data);
|
||||||
break;
|
break;
|
||||||
case UPD7810_PORTD:
|
case UPD7810_PORTD:
|
||||||
m_pd_out = data;
|
m_pd_out = data;
|
||||||
@ -763,6 +764,42 @@ void upd7810_device::WP(offs_t port, uint8_t data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void upd7810_device::write_pc(uint8_t data)
|
||||||
|
{
|
||||||
|
data = (data & ~m_mc) | (m_pc_pullups & m_mc);
|
||||||
|
if (m_mcc & 0x01) /* PC0 = TxD output */
|
||||||
|
data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00);
|
||||||
|
if (m_mcc & 0x02) /* PC1 = RxD input */
|
||||||
|
data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00);
|
||||||
|
if (m_mcc & 0x04) /* PC2 = SCK input/output */
|
||||||
|
data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00);
|
||||||
|
if (m_mcc & 0x08) /* PC3 = TI/INT2 input */
|
||||||
|
data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00);
|
||||||
|
if (m_mcc & 0x10) /* PC4 = TO output */
|
||||||
|
data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00);
|
||||||
|
if (m_mcc & 0x20) /* PC5 = CI input */
|
||||||
|
data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00);
|
||||||
|
if (m_mcc & 0x40) /* PC6 = CO0 output */
|
||||||
|
data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00);
|
||||||
|
if (m_mcc & 0x80) /* PC7 = CO1 output */
|
||||||
|
data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00);
|
||||||
|
m_pc_out_cb(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void upd7801_device::write_pc(uint8_t data)
|
||||||
|
{
|
||||||
|
data = (data & 0x78) | (m_pc_pullups & ~0x78);
|
||||||
|
if (!BIT(m_mc, 3)) /* TODO PC3 = SAK output */
|
||||||
|
data = (data & ~0x08);
|
||||||
|
if (!BIT(m_mc, 4)) /* PC4 = TO output */
|
||||||
|
data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00);
|
||||||
|
if (!BIT(m_mc, 5)) /* TODO PC5 = IO/-M input */
|
||||||
|
data = (data & ~0x20);
|
||||||
|
if (!BIT(m_mc, 6)) /* TODO PC6 = HLDA output */
|
||||||
|
data = (data & ~0x40);
|
||||||
|
m_pc_out_cb(data);
|
||||||
|
}
|
||||||
|
|
||||||
void upd7810_device::upd7810_take_irq()
|
void upd7810_device::upd7810_take_irq()
|
||||||
{
|
{
|
||||||
uint16_t vector = 0;
|
uint16_t vector = 0;
|
||||||
|
@ -199,6 +199,8 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual void configure_ops();
|
virtual void configure_ops();
|
||||||
|
virtual uint8_t read_pc();
|
||||||
|
virtual void write_pc(uint8_t data);
|
||||||
|
|
||||||
static const struct opcode_s s_op48[256];
|
static const struct opcode_s s_op48[256];
|
||||||
static const struct opcode_s s_op4C[256];
|
static const struct opcode_s s_op4C[256];
|
||||||
@ -1410,6 +1412,8 @@ protected:
|
|||||||
virtual void handle_timers(int cycles) override;
|
virtual void handle_timers(int cycles) override;
|
||||||
virtual void upd7810_take_irq() override;
|
virtual void upd7810_take_irq() override;
|
||||||
virtual void configure_ops() override;
|
virtual void configure_ops() override;
|
||||||
|
virtual uint8_t read_pc() override;
|
||||||
|
virtual void write_pc(uint8_t data) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -9474,5 +9474,8 @@ void upd7810_device::MOV_MC_A_7801()
|
|||||||
/* PC5 Output IO/-M Output */
|
/* PC5 Output IO/-M Output */
|
||||||
/* PC6 Output HLDA Output */
|
/* PC6 Output HLDA Output */
|
||||||
/* PC7 Input HOLD Input */
|
/* PC7 Input HOLD Input */
|
||||||
MC = 0x84 | ( ( A & 0x02 ) ? 0x02 : 0x00 ) | ( ( A & 0x01 ) ? 0x01 : 0x00 );
|
if (MC == A)
|
||||||
|
return;
|
||||||
|
MC = A;
|
||||||
|
WP(UPD7810_PORTC, m_pc_out);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user