mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Pia6821 improvements (#5254)
* 6821pia: fix method names in comments * zwackery: Remove PIA port A z_mask setting. This would only be relevant if the PIA was read while in output mode. These are inputs, and only read in input mode, so z_mask is not relevant. * thomson: move pia pullup resistors from z_mask to read handler. * 6821pia: remove unused set_port_a_z_mask calls. * dgn_beta: move pia pullup resistors from z_mask to read handler. * mpu3: Don't invert the VFD power on reset line. It doesn't go through an inverter. I believe this was done to work around a bug in the PIA port A implementation. * pia6821: remove m_port_a_z_mask variable. * 6821pia: For port A reads, only use the DDR for reading pins unless. Provide an override option when a device depends on slightly undefined behavior of an external device driving the pins and changing the value read. One board seems to need this (coinmstr). I don't have the schematics, but it seems it uses this to check its meter operation.
This commit is contained in:
parent
492a9e1b48
commit
2e0f4af6ee
@ -251,7 +251,7 @@ READ8_MEMBER(a2bus_mouse_device::mcu_port_a_r)
|
||||
|
||||
WRITE8_MEMBER(a2bus_mouse_device::mcu_port_a_w)
|
||||
{
|
||||
m_pia->set_a_input(data, ~mem_mask);
|
||||
m_pia->set_a_input(data);
|
||||
}
|
||||
|
||||
READ8_MEMBER(a2bus_mouse_device::mcu_port_b_r)
|
||||
|
@ -285,5 +285,5 @@ WRITE8_MEMBER(spectrum_opus_device::pia_out_b)
|
||||
|
||||
WRITE_LINE_MEMBER(spectrum_opus_device::busy_w)
|
||||
{
|
||||
m_pia->set_a_input(state << 6, 0xbf);
|
||||
m_pia->set_a_input(state << 6);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ void ss50_mpc_device::device_start()
|
||||
|
||||
WRITE_LINE_MEMBER(ss50_mpc_device::serial_input_w)
|
||||
{
|
||||
m_pia->set_a_input(state << 7, 0x7f);
|
||||
m_pia->set_a_input(state << 7);
|
||||
m_loopback->in_w<0>(state);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ pia6821_device::pia6821_device(const machine_config &mconfig, const char *tag, d
|
||||
m_cb2_handler(*this),
|
||||
m_irqa_handler(*this),
|
||||
m_irqb_handler(*this), m_in_a(0),
|
||||
m_in_ca1(0), m_in_ca2(0), m_out_a(0), m_out_ca2(0), m_port_a_z_mask(0), m_ddr_a(0),
|
||||
m_in_ca1(0), m_in_ca2(0), m_out_a(0), m_out_ca2(0), m_ddr_a(0),
|
||||
m_ctl_a(0), m_irq_a1(0), m_irq_a2(0),
|
||||
m_irq_a_state(0), m_in_b(0),
|
||||
m_in_cb1(0), m_in_cb2(0), m_out_b(0), m_out_cb2(0), m_last_out_cb2_z(0), m_ddr_b(0),
|
||||
@ -90,7 +90,6 @@ void pia6821_device::device_start()
|
||||
save_item(NAME(m_in_ca2));
|
||||
save_item(NAME(m_out_a));
|
||||
save_item(NAME(m_out_ca2));
|
||||
save_item(NAME(m_port_a_z_mask));
|
||||
save_item(NAME(m_ddr_a));
|
||||
save_item(NAME(m_ctl_a));
|
||||
save_item(NAME(m_irq_a1));
|
||||
@ -137,7 +136,6 @@ void pia6821_device::device_reset()
|
||||
m_in_ca2 = true;
|
||||
m_out_a = 0;
|
||||
m_out_ca2 = 0;
|
||||
m_port_a_z_mask = 0;
|
||||
m_ddr_a = 0;
|
||||
m_ctl_a = 0;
|
||||
m_irq_a1 = 0;
|
||||
@ -226,8 +224,8 @@ uint8_t pia6821_device::get_in_a_value()
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark all pins disconnected
|
||||
m_port_a_z_mask = 0xff;
|
||||
// assume pins are disconnected and simulate the internal pullups.
|
||||
port_a_data = 0xff;
|
||||
|
||||
if (!m_logged_port_a_not_connected && (m_ddr_a != 0xff))
|
||||
{
|
||||
@ -237,12 +235,12 @@ uint8_t pia6821_device::get_in_a_value()
|
||||
}
|
||||
}
|
||||
|
||||
// - connected pins are always read
|
||||
// - disconnected pins read the output buffer in output mode
|
||||
// - disconnected pins are HI in input mode
|
||||
ret = (~m_port_a_z_mask & port_a_data) |
|
||||
( m_port_a_z_mask & m_ddr_a & m_out_a) |
|
||||
( m_port_a_z_mask & ~m_ddr_a);
|
||||
// For port A, when the port is in output mode other devices can drive the
|
||||
// pins too. If the device pulls the voltage on the lines enough,a read of
|
||||
// the output register will show the external device value on the driven pins.
|
||||
ret = (~m_ddr_a & port_a_data) // input pins
|
||||
| (m_ddr_a & m_out_a & ~m_a_input_overrides_output_mask) // normal output pins
|
||||
| (m_ddr_a & port_a_data & m_a_input_overrides_output_mask); // overridden output pins
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -888,14 +886,13 @@ void pia6821_device::write(offs_t offset, uint8_t data)
|
||||
// set_a_input
|
||||
//-------------------------------------------------
|
||||
|
||||
void pia6821_device::set_a_input(uint8_t data, uint8_t z_mask)
|
||||
void pia6821_device::set_a_input(uint8_t data)
|
||||
{
|
||||
assert_always(m_in_a_handler.isnull(), "pia6821_device::set_a_input() called when m_in_a_handler set");
|
||||
|
||||
LOG("Set PIA input port A = %02X\n", data);
|
||||
|
||||
m_in_a = data;
|
||||
m_port_a_z_mask = z_mask;
|
||||
m_in_a_pushed = true;
|
||||
}
|
||||
|
||||
@ -906,7 +903,7 @@ void pia6821_device::set_a_input(uint8_t data, uint8_t z_mask)
|
||||
|
||||
void pia6821_device::write_porta(uint8_t data)
|
||||
{
|
||||
set_a_input(data, 0);
|
||||
set_a_input(data);
|
||||
}
|
||||
|
||||
|
||||
@ -916,14 +913,11 @@ void pia6821_device::write_porta(uint8_t data)
|
||||
|
||||
void pia6821_device::write_porta_line(int line, bool state)
|
||||
{
|
||||
if (!m_in_a_pushed)
|
||||
m_port_a_z_mask = 0xff;
|
||||
|
||||
uint8_t mask = 1 << line;
|
||||
if (state)
|
||||
set_a_input(m_in_a | mask, m_port_a_z_mask & ~mask);
|
||||
set_a_input(m_in_a | mask);
|
||||
else
|
||||
set_a_input(m_in_a & ~mask, m_port_a_z_mask & ~mask);
|
||||
set_a_input(m_in_a & ~mask);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,13 +5,10 @@
|
||||
Motorola 6821 PIA interface and emulation
|
||||
|
||||
Notes:
|
||||
* get_port_b_z_mask() gives the caller the bitmask that shows
|
||||
* port_b_z_mask() gives the caller the bitmask that shows
|
||||
which bits are high-impedance when reading port B, and thus
|
||||
neither 0 or 1. get_output_cb2_z() returns the same info
|
||||
neither 0 or 1. cb2_output_z() returns the same info
|
||||
for the CB2 pin.
|
||||
* set_port_a_z_mask allows the input callback to indicate
|
||||
which port A bits are disconnected. For these bits, the
|
||||
read operation will return the output buffer's contents.
|
||||
* The 'alt' interface functions are used when the A0 and A1
|
||||
address bits are swapped.
|
||||
* All 'int' data or return values are bool, and should be
|
||||
@ -61,13 +58,13 @@ public:
|
||||
void write_alt(offs_t offset, uint8_t data) { write(((offset << 1) & 0x02) | ((offset >> 1) & 0x01), data); }
|
||||
|
||||
uint8_t port_b_z_mask() const { return ~m_ddr_b; } // see first note in .c
|
||||
void set_port_a_z_mask(uint8_t data) { m_port_a_z_mask = data; }// see second note in .c
|
||||
|
||||
DECLARE_WRITE8_MEMBER( porta_w ) { write_porta(data); }
|
||||
void write_porta(uint8_t data);
|
||||
void write_porta_line(int line, bool state);
|
||||
void set_a_input(uint8_t data, uint8_t z_mask);
|
||||
void set_a_input(uint8_t data);
|
||||
uint8_t a_output();
|
||||
void set_port_a_input_overrides_output_mask(uint8_t mask) { m_a_input_overrides_output_mask = mask; }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( pa0_w ) { write_porta_line(0, state); }
|
||||
DECLARE_WRITE_LINE_MEMBER( pa1_w ) { write_porta_line(1, state); }
|
||||
@ -176,8 +173,8 @@ private:
|
||||
uint8_t m_in_ca1;
|
||||
uint8_t m_in_ca2;
|
||||
uint8_t m_out_a;
|
||||
uint8_t m_a_input_overrides_output_mask;
|
||||
uint8_t m_out_ca2;
|
||||
uint8_t m_port_a_z_mask;
|
||||
uint8_t m_ddr_a;
|
||||
uint8_t m_ctl_a;
|
||||
uint8_t m_irq_a1;
|
||||
|
@ -1254,7 +1254,6 @@ uint32_t coinmstr_state::screen_update_coinmstr(screen_device &screen, bitmap_rg
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void coinmstr_state::coinmstr(machine_config &config)
|
||||
{
|
||||
Z80(config, m_maincpu, CPU_CLOCK); // 7 MHz.
|
||||
@ -1267,6 +1266,7 @@ void coinmstr_state::coinmstr(machine_config &config)
|
||||
|
||||
pia6821_device &pia1(PIA6821(config, "pia1", 0));
|
||||
pia1.readpa_handler().set_ioport("PIA1.A");
|
||||
pia1.set_port_a_input_overrides_output_mask(0xff);
|
||||
pia1.readpb_handler().set_ioport("PIA1.B");
|
||||
|
||||
pia6821_device &pia2(PIA6821(config, "pia2", 0));
|
||||
|
@ -604,7 +604,7 @@ READ8_MEMBER(mpu3_state::pia_ic6_portb_r)
|
||||
WRITE8_MEMBER(mpu3_state::pia_ic6_porta_w)
|
||||
{
|
||||
LOG(("%s: IC6 PIA Port A Set to %2x (Alpha)\n", machine().describe_context(),data));
|
||||
m_vfd->por(!(data&0x08));
|
||||
m_vfd->por((data & 0x08));
|
||||
m_vfd->data((data & 0x20) >> 5);
|
||||
m_vfd->sclk((data & 0x10) >>4);
|
||||
}
|
||||
|
@ -441,10 +441,7 @@ WRITE_LINE_MEMBER(zwackery_state::pia0_irq_w)
|
||||
|
||||
READ8_MEMBER( zwackery_state::pia1_porta_r )
|
||||
{
|
||||
uint8_t data = ioport("IN1")->read();
|
||||
m_pia1->set_port_a_z_mask(data);
|
||||
|
||||
return data;
|
||||
return ioport("IN1")->read();
|
||||
}
|
||||
|
||||
READ8_MEMBER( zwackery_state::pia1_portb_r )
|
||||
@ -457,10 +454,7 @@ READ8_MEMBER( zwackery_state::pia1_portb_r )
|
||||
|
||||
READ8_MEMBER( zwackery_state::pia2_porta_r )
|
||||
{
|
||||
uint8_t data = ioport("IN3")->read();
|
||||
m_pia2->set_port_a_z_mask(data);
|
||||
|
||||
return data;
|
||||
return ioport("IN3")->read();
|
||||
}
|
||||
|
||||
|
||||
|
@ -159,7 +159,7 @@ protected:
|
||||
ram_device &ram() { return *m_ram; }
|
||||
|
||||
// miscellaneous
|
||||
virtual void update_keyboard_input(uint8_t value, uint8_t z);
|
||||
virtual void update_keyboard_input(uint8_t value);
|
||||
virtual void cart_w(bool state);
|
||||
virtual void update_cart_base(uint8_t *cart_base) { };
|
||||
|
||||
|
@ -62,7 +62,7 @@ protected:
|
||||
virtual bool irq_get_line(void) override;
|
||||
|
||||
// miscellaneous
|
||||
virtual void update_keyboard_input(uint8_t value, uint8_t z) override;
|
||||
virtual void update_keyboard_input(uint8_t value) override;
|
||||
virtual void cart_w(bool line) override;
|
||||
|
||||
private:
|
||||
|
@ -874,10 +874,8 @@ void coco_state::poll_joystick(bool *joyin, uint8_t *buttons)
|
||||
void coco_state::poll_keyboard(void)
|
||||
{
|
||||
uint8_t pia0_pb = pia_0().b_output();
|
||||
uint8_t pia0_pb_z = pia_0().port_b_z_mask();
|
||||
|
||||
uint8_t pia0_pa = 0x7F;
|
||||
uint8_t pia0_pa_z = 0x7F;
|
||||
|
||||
/* poll the keyboard, and update PA6-PA0 accordingly*/
|
||||
for (unsigned i = 0; i < m_keyboard.size(); i++)
|
||||
@ -887,10 +885,6 @@ void coco_state::poll_keyboard(void)
|
||||
{
|
||||
pia0_pa &= ~(0x01 << i);
|
||||
}
|
||||
if ((value | pia0_pb_z) != 0xFF)
|
||||
{
|
||||
pia0_pa_z &= ~(0x01 << i);
|
||||
}
|
||||
}
|
||||
|
||||
/* hires joystick */
|
||||
@ -906,10 +900,9 @@ void coco_state::poll_keyboard(void)
|
||||
|
||||
/* mask out the buttons */
|
||||
pia0_pa &= ~buttons;
|
||||
pia0_pa_z &= ~buttons;
|
||||
|
||||
/* and write the result to PIA0 */
|
||||
update_keyboard_input(pia0_pa, pia0_pa_z);
|
||||
update_keyboard_input(pia0_pa);
|
||||
}
|
||||
|
||||
|
||||
@ -919,9 +912,9 @@ void coco_state::poll_keyboard(void)
|
||||
// on the CoCo 3 controls a GIME input
|
||||
//-------------------------------------------------
|
||||
|
||||
void coco_state::update_keyboard_input(uint8_t value, uint8_t z)
|
||||
void coco_state::update_keyboard_input(uint8_t value)
|
||||
{
|
||||
pia_0().set_a_input(value, z);
|
||||
pia_0().set_a_input(value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,9 +112,9 @@ bool coco3_state::irq_get_line(void)
|
||||
// update_keyboard_input
|
||||
//-------------------------------------------------
|
||||
|
||||
void coco3_state::update_keyboard_input(uint8_t value, uint8_t z)
|
||||
void coco3_state::update_keyboard_input(uint8_t value)
|
||||
{
|
||||
coco_state::update_keyboard_input(value, z);
|
||||
coco_state::update_keyboard_input(value);
|
||||
m_gime->set_il1(value == 0xFF);
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,8 @@ int dgn_beta_state::GetKeyRow(dgn_beta_state *state, int RowNo)
|
||||
*/
|
||||
READ8_MEMBER(dgn_beta_state::d_pia0_pa_r)
|
||||
{
|
||||
return 0;
|
||||
// The hardware has pullup resistors on port A.
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(dgn_beta_state::d_pia0_pa_w)
|
||||
@ -558,7 +559,8 @@ WRITE_LINE_MEMBER(dgn_beta_state::d_pia0_irq_b)
|
||||
|
||||
READ8_MEMBER(dgn_beta_state::d_pia1_pa_r)
|
||||
{
|
||||
return 0;
|
||||
// The hardware has pullup resistors on port A.
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(dgn_beta_state::d_pia1_pa_w)
|
||||
@ -657,7 +659,8 @@ WRITE_LINE_MEMBER(dgn_beta_state::d_pia1_irq_b)
|
||||
*/
|
||||
READ8_MEMBER(dgn_beta_state::d_pia2_pa_r)
|
||||
{
|
||||
return 0;
|
||||
// The hardware has pullup resistors on port A.
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(dgn_beta_state::d_pia2_pa_w)
|
||||
@ -902,11 +905,6 @@ void dgn_beta_state::machine_reset()
|
||||
memset(m_PageRegs, 0, sizeof(m_PageRegs)); /* Reset page registers to 0 */
|
||||
SetDefaultTask();
|
||||
|
||||
/* Set pullups on all PIA port A, to match what hardware does */
|
||||
m_pia_0->set_port_a_z_mask(0xFF);
|
||||
m_pia_1->set_port_a_z_mask(0xFF);
|
||||
m_pia_2->set_port_a_z_mask(0xFF);
|
||||
|
||||
m_d_pia1_pa_last = 0x00;
|
||||
m_d_pia1_pb_last = 0x00;
|
||||
m_RowShifter = 0x00; /* shift register to select row */
|
||||
|
@ -1308,9 +1308,9 @@ WRITE8_MEMBER( thomson_state::mo5_sys_porta_out )
|
||||
READ8_MEMBER( thomson_state::mo5_sys_porta_in )
|
||||
{
|
||||
return
|
||||
(mo5_get_cassette() ? 0x80 : 0) | /* bit 7: cassette input */
|
||||
((m_io_lightpen_button->read() & 1) ? 0x20 : 0)
|
||||
/* bit 5: lightpen button */;
|
||||
((m_io_lightpen_button->read() & 1) ? 0x20 : 0) | /* bit 5: lightpen button */
|
||||
(mo5_get_cassette() ? 0x80 : 0) | /* bit 7: cassette input */
|
||||
0x5f; /* other bits are unconnected and pulled hi internally */
|
||||
}
|
||||
|
||||
|
||||
@ -1564,7 +1564,6 @@ MACHINE_RESET_MEMBER( thomson_state, mo5 )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask(0x5f );
|
||||
to7_game_reset();
|
||||
to7_floppy_reset();
|
||||
to7_modem_reset();
|
||||
@ -2445,16 +2444,14 @@ void thomson_state::to9_kbd_init()
|
||||
|
||||
/* ------------ system PIA 6821 ------------ */
|
||||
|
||||
/* afaik, P2-P7 are not connected, so, the warning about undefined 0xf0 can be safely ignored */
|
||||
|
||||
|
||||
READ8_MEMBER( thomson_state::to9_sys_porta_in )
|
||||
{
|
||||
uint8_t ktest = to9_kbd_ktest();
|
||||
|
||||
LOG_KBD(( "to9_sys_porta_in: ktest=%i\n", ktest ));
|
||||
|
||||
return ktest;
|
||||
// PB1-7 are not connected, and are pulled hi internally
|
||||
return ktest | 0xfe;
|
||||
}
|
||||
|
||||
|
||||
@ -2507,7 +2504,6 @@ MACHINE_RESET_MEMBER( thomson_state, to9 )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask( 0xfe );
|
||||
to7_game_reset();
|
||||
to9_floppy_reset();
|
||||
to9_kbd_reset();
|
||||
@ -3412,14 +3408,14 @@ WRITE8_MEMBER( thomson_state::to8_vreg_w )
|
||||
/* ------------ system PIA 6821 ------------ */
|
||||
|
||||
|
||||
|
||||
READ8_MEMBER( thomson_state::to8_sys_porta_in )
|
||||
{
|
||||
int ktest = to8_kbd_ktest();
|
||||
|
||||
LOG_KBD(( "$%04x %f: to8_sys_porta_in ktest=%i\n", m_maincpu->pc(), machine().time().as_double(), ktest ));
|
||||
|
||||
return ktest;
|
||||
// PB1-7 are not connected, and are pulled hi internally
|
||||
return ktest | 0xfe;
|
||||
}
|
||||
|
||||
|
||||
@ -3504,7 +3500,6 @@ MACHINE_RESET_MEMBER( thomson_state, to8 )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask( 0xfe );
|
||||
to7_game_reset();
|
||||
to8_floppy_reset();
|
||||
to8_kbd_reset();
|
||||
@ -3655,7 +3650,6 @@ MACHINE_RESET_MEMBER( thomson_state, to9p )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask( 0xfe );
|
||||
to7_game_reset();
|
||||
to8_floppy_reset();
|
||||
to9_kbd_reset();
|
||||
@ -4116,10 +4110,10 @@ void thomson_state::mo6_game_reset()
|
||||
READ8_MEMBER( thomson_state::mo6_sys_porta_in )
|
||||
{
|
||||
return
|
||||
(mo5_get_cassette() ? 0x80 : 0) | /* bit 7: cassette input */
|
||||
8 | /* bit 3: kbd-line float up to 1 */
|
||||
((m_io_lightpen_button->read() & 1) ? 2 : 0);
|
||||
/* bit 1: lightpen button */;
|
||||
((m_io_lightpen_button->read() & 1) ? 2 : 0) | /* bit 1: lightpen button */
|
||||
8 | /* bit 3: kbd-line float up to 1 */
|
||||
(mo5_get_cassette() ? 0x80 : 0) | /* bit 7: cassette input */
|
||||
0x75; /* other bits are unconnected and pulled hi internally */
|
||||
}
|
||||
|
||||
|
||||
@ -4345,7 +4339,6 @@ MACHINE_RESET_MEMBER( thomson_state, mo6 )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask( 0x75 );
|
||||
mo6_game_reset();
|
||||
to7_floppy_reset();
|
||||
to7_modem_reset();
|
||||
@ -4568,7 +4561,6 @@ MACHINE_RESET_MEMBER( thomson_state, mo5nr )
|
||||
|
||||
/* subsystems */
|
||||
thom_irq_reset();
|
||||
m_pia_sys->set_port_a_z_mask( 0x65 );
|
||||
mo5nr_game_reset();
|
||||
to7_floppy_reset();
|
||||
to7_modem_reset();
|
||||
|
Loading…
Reference in New Issue
Block a user