summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mahlemiut <bsr@xnet.co.nz>2018-07-12 13:51:32 +1200
committer mahlemiut <bsr@xnet.co.nz>2018-07-12 13:51:32 +1200
commit35dfa5372494e5f7485a0736cabf8f6e730b5dc1 (patch)
tree2b6e82ccad93d824cb68112dc3c8779f7d472879
parent1ee5c62a21bcc8c9a16093c7d53de2765518ad14 (diff)
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).
-rw-r--r--src/devices/machine/i8255.cpp39
-rw-r--r--src/devices/machine/i8255.h18
-rw-r--r--src/mame/drivers/amstrad.cpp6
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))