From 35dfa5372494e5f7485a0736cabf8f6e730b5dc1 Mon Sep 17 00:00:00 2001 From: mahlemiut Date: Thu, 12 Jul 2018 13:51:32 +1200 Subject: [PATCH] amstrad: create 8255 PPI clone based on the Amstrad Plus ASIC, and use it with the Plus and GX4000 drives. Fixes Plus detection in some games, breaks inputs in Barbarian (correct behaviour). --- src/devices/machine/i8255.cpp | 39 ++++++++++++++++++++++++++++++++--- src/devices/machine/i8255.h | 18 ++++++++++++++++ src/mame/drivers/amstrad.cpp | 6 ++++-- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/devices/machine/i8255.cpp b/src/devices/machine/i8255.cpp index 0ae0a9d24ac..8f91652875f 100644 --- a/src/devices/machine/i8255.cpp +++ b/src/devices/machine/i8255.cpp @@ -299,6 +299,10 @@ void i8255_device::device_start() save_item(NAME(m_inte1)); save_item(NAME(m_inte2)); save_item(NAME(m_intr)); + + m_force_portb_in = false; + m_force_portc_out = false; + m_dont_clear_output_latches = false; } @@ -651,8 +655,18 @@ void i8255_device::set_mode(uint8_t data) { m_control = data; + if(m_force_portb_in) + m_control = m_control | CONTROL_PORT_B_INPUT; + + if(m_force_portc_out) + { + m_control = m_control & ~CONTROL_PORT_C_UPPER_INPUT; + m_control = m_control & ~CONTROL_PORT_C_LOWER_INPUT; + } + // group A - m_output[PORT_A] = 0; + if(!m_dont_clear_output_latches) + m_output[PORT_A] = 0; m_input[PORT_A] = 0; m_ibf[PORT_A] = 0; m_obf[PORT_A] = 1; @@ -678,7 +692,8 @@ void i8255_device::set_mode(uint8_t data) LOG("I8255 Port C Lower Mode: %s\n", (port_c_lower_mode() == MODE_OUTPUT) ? "output" : "input"); // group B - m_output[PORT_B] = 0; + if(!m_dont_clear_output_latches) + m_output[PORT_B] = 0; m_input[PORT_B] = 0; m_ibf[PORT_B] = 0; m_obf[PORT_B] = 1; @@ -694,7 +709,8 @@ void i8255_device::set_mode(uint8_t data) m_out_pb_cb((offs_t)0, m_tri_pb_cb(0)); } - m_output[PORT_C] = 0; + if(!m_dont_clear_output_latches) + m_output[PORT_C] = 0; m_input[PORT_C] = 0; output_pc(); @@ -1000,3 +1016,20 @@ WRITE_LINE_MEMBER( i8255_device::pc6_w ) } } } + + +// AMS40489 (Amstrad Plus/GX4000 ASIC PPI implementation) +ams40489_ppi_device::ams40489_ppi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : i8255_device(mconfig,tag,owner,clock) +{} + +void ams40489_ppi_device::device_reset() { i8255_device::device_reset(); } + +void ams40489_ppi_device::device_start() +{ + i8255_device::device_start(); + + m_force_portb_in = true; + m_force_portc_out = true; + m_dont_clear_output_latches = true; +} diff --git a/src/devices/machine/i8255.h b/src/devices/machine/i8255.h index 3d7e1e0daa7..407a1cbef4e 100644 --- a/src/devices/machine/i8255.h +++ b/src/devices/machine/i8255.h @@ -111,6 +111,10 @@ protected: virtual void device_start() override; virtual void device_reset() override; + bool m_force_portb_in; + bool m_force_portc_out; + bool m_dont_clear_output_latches; + private: inline void check_interrupt(int port); inline void set_ibf(int port, int state); @@ -158,9 +162,23 @@ private: int m_intr[2]; // interrupt }; +// AMS40489 ASIC (Amstrad Plus/GX4000 PPI implementation) +class ams40489_ppi_device : public i8255_device +{ +public: + // construction/destruction + ams40489_ppi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +}; // device type definition DECLARE_DEVICE_TYPE(I8255, i8255_device) DECLARE_DEVICE_TYPE(I8255A, i8255_device) +DECLARE_DEVICE_TYPE(AMS40489_PPI, ams40489_ppi_device) #endif // MAME_MACHINE_I8255_H diff --git a/src/mame/drivers/amstrad.cpp b/src/mame/drivers/amstrad.cpp index 84bf75be645..8a04c5d358b 100644 --- a/src/mame/drivers/amstrad.cpp +++ b/src/mame/drivers/amstrad.cpp @@ -1047,7 +1047,7 @@ MACHINE_CONFIG_START(amstrad_state::cpcplus) MCFG_MACHINE_START_OVERRIDE(amstrad_state, plus ) MCFG_MACHINE_RESET_OVERRIDE(amstrad_state, plus ) - MCFG_DEVICE_ADD("ppi8255", I8255, 0) + MCFG_DEVICE_ADD("ppi8255", AMS40489_PPI, 0) MCFG_I8255_IN_PORTA_CB(READ8(*this, amstrad_state, amstrad_ppi_porta_r)) MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, amstrad_state, amstrad_ppi_porta_w)) MCFG_I8255_IN_PORTB_CB(READ8(*this, amstrad_state, amstrad_ppi_portb_r)) @@ -1091,6 +1091,7 @@ MACHINE_CONFIG_START(amstrad_state::cpcplus) MCFG_CASSETTE_FORMATS(cdt_cassette_formats) MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED) MCFG_CASSETTE_INTERFACE("cpc_cass") + MCFG_SOFTWARE_LIST_ADD("cass_list","cpc_cass") MCFG_UPD765A_ADD("upd765", true, true) @@ -1098,6 +1099,7 @@ MACHINE_CONFIG_START(amstrad_state::cpcplus) MCFG_FLOPPY_DRIVE_ADD("upd765:0", amstrad_floppies, "3ssdd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("upd765:1", amstrad_floppies, "35ssdd", floppy_image_device::default_floppy_formats) + MCFG_SOFTWARE_LIST_ADD("flop_list","cpc_flop") MCFG_DEVICE_ADD("exp", CPC_EXPANSION_SLOT, 0) MCFG_DEVICE_SLOT_INTERFACE(cpcplus_exp_cards, nullptr, false) @@ -1125,7 +1127,7 @@ MACHINE_CONFIG_START(amstrad_state::gx4000) MCFG_MACHINE_START_OVERRIDE(amstrad_state, gx4000 ) MCFG_MACHINE_RESET_OVERRIDE(amstrad_state, gx4000 ) - MCFG_DEVICE_ADD("ppi8255", I8255, 0) + MCFG_DEVICE_ADD("ppi8255", AMS40489_PPI, 0) MCFG_I8255_IN_PORTA_CB(READ8(*this, amstrad_state, amstrad_ppi_porta_r)) MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, amstrad_state, amstrad_ppi_porta_w)) MCFG_I8255_IN_PORTB_CB(READ8(*this, amstrad_state, amstrad_ppi_portb_r))