summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/bus/coleco/exp.c11
-rw-r--r--src/emu/bus/coleco/xin1.c71
-rw-r--r--src/emu/bus/coleco/xin1.h48
-rw-r--r--src/emu/emuopts.c2
-rw-r--r--src/emu/emuopts.h3
-rw-r--r--src/mess/drivers/coleco.c97
-rw-r--r--src/mess/includes/coleco.h62
-rw-r--r--src/mess/machine/coleco.c92
-rw-r--r--src/mess/machine/coleco.h3
9 files changed, 279 insertions, 110 deletions
diff --git a/src/emu/bus/coleco/exp.c b/src/emu/bus/coleco/exp.c
index e8be5dfe15d..c981406017e 100644
--- a/src/emu/bus/coleco/exp.c
+++ b/src/emu/bus/coleco/exp.c
@@ -114,6 +114,15 @@ bool colecovision_cartridge_slot_device::call_softlist_load(software_list_device
void colecovision_cartridge_slot_device::get_default_card_software(std::string &result)
{
+ if (open_image_file(mconfig().options()))
+ {
+ UINT32 length = core_fsize(m_file);
+ if (length == 0x100000 || length == 0x200000)
+ {
+ software_get_default_slot(result, "xin1");
+ return;
+ }
+ }
software_get_default_slot(result, "standard");
}
@@ -138,8 +147,10 @@ UINT8 colecovision_cartridge_slot_device::bd_r(address_space &space, offs_t offs
//-------------------------------------------------
#include "std.h"
+#include "xin1.h"
SLOT_INTERFACE_START( colecovision_cartridges )
// the following need ROMs from the software list
SLOT_INTERFACE_INTERNAL("standard", COLECOVISION_STANDARD)
+ SLOT_INTERFACE_INTERNAL("xin1", COLECOVISION_XIN1)
SLOT_INTERFACE_END
diff --git a/src/emu/bus/coleco/xin1.c b/src/emu/bus/coleco/xin1.c
new file mode 100644
index 00000000000..e46b65eeadd
--- /dev/null
+++ b/src/emu/bus/coleco/xin1.c
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/**********************************************************************
+
+ ColecoVision X-in-1 cartridge emulation
+
+**********************************************************************/
+
+#include "xin1.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type COLECOVISION_XIN1 = &device_creator<colecovision_xin1_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// colecovision_xin1_cartridge_device - constructor
+//-------------------------------------------------
+
+colecovision_xin1_cartridge_device::colecovision_xin1_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, COLECOVISION_XIN1, "ColecoVision X-in-1 cartridge", tag, owner, clock, "colecovision_xin1", __FILE__),
+ device_colecovision_cartridge_interface(mconfig, *this),
+ m_current_offset(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void colecovision_xin1_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void colecovision_xin1_cartridge_device::device_reset()
+{
+ m_current_offset = m_rom_size - 0x8000;
+}
+
+
+//-------------------------------------------------
+// read - cartridge data read
+//-------------------------------------------------
+
+UINT8 colecovision_xin1_cartridge_device::bd_r(address_space &space, offs_t offset, UINT8 data, int _8000, int _a000, int _c000, int _e000)
+{
+ if (!_8000 || !_a000 || !_c000 || !_e000)
+ {
+ data = m_rom[m_current_offset + offset];
+ if (!_e000 && offset >= 0x7fc0) {
+ m_current_offset = (0x8000 * (offset - 0x7fc0)) % m_rom_size;
+ }
+ }
+
+ return data;
+}
diff --git a/src/emu/bus/coleco/xin1.h b/src/emu/bus/coleco/xin1.h
new file mode 100644
index 00000000000..79a940c646f
--- /dev/null
+++ b/src/emu/bus/coleco/xin1.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/**********************************************************************
+
+ ColecoVision X-in-1 cartridge emulation
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __COLECOVISION_XIN1_CARTRIDGE__
+#define __COLECOVISION_XIN1_CARTRIDGE__
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> colecovision_xin1_cartridge_device
+
+class colecovision_xin1_cartridge_device : public device_t,
+ public device_colecovision_cartridge_interface
+{
+public:
+ // construction/destruction
+ colecovision_xin1_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_colecovision_expansion_card_interface overrides
+ virtual UINT8 bd_r(address_space &space, offs_t offset, UINT8 data, int _8000, int _a000, int _c000, int _e000);
+
+private:
+ UINT32 m_current_offset;
+};
+
+
+// device type definition
+extern const device_type COLECOVISION_XIN1;
+
+
+#endif
diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c
index 1816ea60517..ad955994899 100644
--- a/src/emu/emuopts.c
+++ b/src/emu/emuopts.c
@@ -203,6 +203,7 @@ const options_entry emu_options::s_option_entries[] =
emu_options::emu_options()
: core_options()
, m_coin_impulse(0)
+, m_joystick_contradictory(false)
, m_sleep(true)
, m_refresh_speed(false)
{
@@ -590,6 +591,7 @@ const char *emu_options::sub_value(std::string &buffer, const char *name, const
void emu_options::update_cached_options()
{
m_coin_impulse = int_value(OPTION_COIN_IMPULSE);
+ m_joystick_contradictory = bool_value(OPTION_JOYSTICK_CONTRADICTORY);
m_sleep = bool_value(OPTION_SLEEP);
m_refresh_speed = bool_value(OPTION_REFRESHSPEED);
}
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index 20d078626eb..45a4dab160f 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -327,7 +327,7 @@ public:
bool ui_active() const { return bool_value(OPTION_UI_ACTIVE); }
bool offscreen_reload() const { return bool_value(OPTION_OFFSCREEN_RELOAD); }
bool natural_keyboard() const { return bool_value(OPTION_NATURAL_KEYBOARD); }
- bool joystick_contradictory() const { return bool_value(OPTION_JOYSTICK_CONTRADICTORY); }
+ bool joystick_contradictory() const { return m_joystick_contradictory; }
int coin_impulse() const { return m_coin_impulse; }
// core debugging options
@@ -389,6 +389,7 @@ private:
// cached options
int m_coin_impulse;
+ bool m_joystick_contradictory;
bool m_sleep;
bool m_refresh_speed;
};
diff --git a/src/mess/drivers/coleco.c b/src/mess/drivers/coleco.c
index 7f8d4be28d8..5f6c020e33c 100644
--- a/src/mess/drivers/coleco.c
+++ b/src/mess/drivers/coleco.c
@@ -70,12 +70,12 @@
READ8_MEMBER( coleco_state::paddle_1_r )
{
- return m_joy_d7_state[0] | coleco_paddle_read(machine(), 0, m_joy_mode, m_joy_analog_state[0]);
+ return m_joy_d7_state[0] | coleco_paddle_read(0, m_joy_mode, m_joy_analog_state[0]);
}
READ8_MEMBER( coleco_state::paddle_2_r )
{
- return m_joy_d7_state[1] | coleco_paddle_read(machine(), 1, m_joy_mode, m_joy_analog_state[1]);
+ return m_joy_d7_state[1] | coleco_paddle_read(1, m_joy_mode, m_joy_analog_state[1]);
}
WRITE8_MEMBER( coleco_state::paddle_off_w )
@@ -206,7 +206,7 @@ TIMER_CALLBACK_MEMBER(coleco_state::paddle_pulse_callback)
TIMER_DEVICE_CALLBACK_MEMBER(coleco_state::paddle_update_callback)
{
// arbitrary timer for reading analog controls
- coleco_scan_paddles(machine(), &m_joy_analog_reload[0], &m_joy_analog_reload[1]);
+ coleco_scan_paddles(&m_joy_analog_reload[0], &m_joy_analog_reload[1]);
for (int port = 0; port < 2; port++)
{
@@ -229,6 +229,97 @@ READ8_MEMBER( coleco_state::cart_r )
return m_cart->bd_r(space, offset & 0x7fff, 0, 0, 0, 0, 0);
}
+UINT8 coleco_state::coleco_scan_paddles(UINT8 *joy_status0, UINT8 *joy_status1)
+{
+ UINT8 ctrl_sel = (m_ctrlsel != NULL) ? m_ctrlsel->read() : 0;
+
+ /* which controller shall we read? */
+ if ((ctrl_sel & 0x07) == 0x02) // Super Action Controller P1
+ *joy_status0 = (m_sac_slide1 != NULL) ? m_sac_slide1->read() : 0;
+ else if ((ctrl_sel & 0x07) == 0x03) // Driving Controller P1
+ *joy_status0 = (m_driv_wheel1 != NULL) ? m_driv_wheel1->read() : 0;
+
+ if ((ctrl_sel & 0x70) == 0x20) // Super Action Controller P2
+ *joy_status1 = (m_sac_slide2 != NULL) ? m_sac_slide2->read() : 0;
+ else if ((ctrl_sel & 0x70) == 0x30) // Driving Controller P2
+ *joy_status1 = (m_driv_wheel2 != NULL) ? m_driv_wheel2->read() : 0;
+
+ /* In principle, even if not supported by any game, I guess we could have two Super
+ Action Controllers plugged into the Roller controller ports. Since I found no info
+ about the behavior of sliders in such a configuration, we overwrite SAC sliders with
+ the Roller trackball inputs and actually use the latter ones, when both are selected. */
+ if (ctrl_sel & 0x80) // Roller controller
+ {
+ *joy_status0 = (m_roller_x != NULL) ? m_roller_x->read() : 0;
+ *joy_status1 = (m_roller_y != NULL) ? m_roller_y->read() : 0;
+ }
+
+ return *joy_status0 | *joy_status1;
+}
+
+
+UINT8 coleco_state::coleco_paddle_read(int port, int joy_mode, UINT8 joy_status)
+{
+ UINT8 ctrl_sel = (m_ctrlsel != NULL ) ? m_ctrlsel->read() : 0;
+ UINT8 ctrl_extra = ctrl_sel & 0x80;
+ ctrl_sel = ctrl_sel >> (port*4) & 7;
+
+ /* Keypad and fire 1 (SAC Yellow Button) */
+ if (joy_mode == 0)
+ {
+ /* No key pressed by default */
+ UINT8 data = 0x0f;
+ UINT16 ipt = 0xffff;
+
+ if (ctrl_sel == 0) // ColecoVision Controller
+ ipt = port ? m_std_keypad2->read() : m_std_keypad1->read();
+ else if (ctrl_sel == 2) // Super Action Controller
+ ipt = port ? m_sac_keypad2->read() : m_sac_keypad1->read();
+
+ /* Numeric pad buttons are not independent on a real ColecoVision, if you push more
+ than one, a real ColecoVision think that it is a third button, so we are going to emulate
+ the right behaviour */
+ /* Super Action Controller additional buttons are read in the same way */
+ if (!(ipt & 0x0001)) data &= 0x0a; /* 0 */
+ if (!(ipt & 0x0002)) data &= 0x0d; /* 1 */
+ if (!(ipt & 0x0004)) data &= 0x07; /* 2 */
+ if (!(ipt & 0x0008)) data &= 0x0c; /* 3 */
+ if (!(ipt & 0x0010)) data &= 0x02; /* 4 */
+ if (!(ipt & 0x0020)) data &= 0x03; /* 5 */
+ if (!(ipt & 0x0040)) data &= 0x0e; /* 6 */
+ if (!(ipt & 0x0080)) data &= 0x05; /* 7 */
+ if (!(ipt & 0x0100)) data &= 0x01; /* 8 */
+ if (!(ipt & 0x0200)) data &= 0x0b; /* 9 */
+ if (!(ipt & 0x0400)) data &= 0x06; /* # */
+ if (!(ipt & 0x0800)) data &= 0x09; /* * */
+ if (!(ipt & 0x1000)) data &= 0x04; /* Blue Action Button */
+ if (!(ipt & 0x2000)) data &= 0x08; /* Purple Action Button */
+
+ return ((ipt & 0x4000) >> 8) | 0x30 | data;
+ }
+ /* Joystick and fire 2 (SAC Red Button) */
+ else
+ {
+ UINT8 data = 0x7f;
+
+ if (ctrl_sel == 0) // ColecoVision Controller
+ data = port ? m_std_joy2->read() : m_std_joy1->read();
+ else if (ctrl_sel == 2) // Super Action Controller
+ data = port ? m_sac_joy2->read() : m_sac_joy1->read();
+ else if (ctrl_sel == 3) // Driving Controller
+ data = port ? m_driv_pedal2->read() : m_driv_pedal1->read();
+
+ /* If any extra analog contoller enabled */
+ if (ctrl_extra || ctrl_sel == 2 || ctrl_sel == 3)
+ {
+ if (joy_status & 0x80) data ^= 0x30;
+ else if (joy_status) data ^= 0x10;
+ }
+
+ return data & 0x7f;
+ }
+}
+
void coleco_state::machine_start()
{
memset(m_ram, 0xff, m_ram.bytes()); // initialize RAM
diff --git a/src/mess/includes/coleco.h b/src/mess/includes/coleco.h
index 7b91445e8e1..ab6e1379663 100644
--- a/src/mess/includes/coleco.h
+++ b/src/mess/includes/coleco.h
@@ -20,13 +20,26 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_cart(*this, COLECOVISION_CARTRIDGE_SLOT_TAG),
- m_ram(*this, "ram")
+ m_ram(*this, "ram"),
+ m_ctrlsel(*this, "CTRLSEL"),
+ m_std_keypad1(*this, "STD_KEYPAD1"),
+ m_std_joy1(*this, "STD_JOY1"),
+ m_std_keypad2(*this, "STD_KEYPAD2"),
+ m_std_joy2(*this, "STD_JOY2"),
+ m_sac_keypad1(*this, "SAC_KEYPAD1"),
+ m_sac_joy1(*this, "SAC_JOY1"),
+ m_sac_slide1(*this, "SAC_SLIDE1"),
+ m_sac_keypad2(*this, "SAC_KEYPAD2"),
+ m_sac_joy2(*this, "SAC_JOY2"),
+ m_sac_slide2(*this, "SAC_SLIDE2"),
+ m_driv_wheel1(*this, "DRIV_WHEEL1"),
+ m_driv_pedal1(*this, "DRIV_PEDAL1"),
+ m_driv_wheel2(*this, "DRIV_WHEEL2"),
+ m_driv_pedal2(*this, "DRIV_PEDAL2"),
+ m_roller_x(*this, "ROLLER_X"),
+ m_roller_y(*this, "ROLLER_Y")
{ }
- required_device<cpu_device> m_maincpu;
- required_device<colecovision_cartridge_slot_device> m_cart;
- required_shared_ptr<UINT8> m_ram;
-
virtual void machine_start();
virtual void machine_reset();
@@ -36,6 +49,21 @@ public:
DECLARE_WRITE8_MEMBER( paddle_off_w );
DECLARE_WRITE8_MEMBER( paddle_on_w );
+ TIMER_CALLBACK_MEMBER(paddle_d7reset_callback);
+ TIMER_CALLBACK_MEMBER(paddle_irqreset_callback);
+ TIMER_CALLBACK_MEMBER(paddle_pulse_callback);
+ TIMER_DEVICE_CALLBACK_MEMBER(paddle_update_callback);
+ DECLARE_WRITE_LINE_MEMBER(coleco_vdp_interrupt);
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(czz50_cart);
+
+ UINT8 coleco_paddle_read(int port, int joy_mode, UINT8 joy_status);
+ UINT8 coleco_scan_paddles(UINT8 *joy_status0, UINT8 *joy_status1);
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<colecovision_cartridge_slot_device> m_cart;
+ required_shared_ptr<UINT8> m_ram;
+
int m_joy_mode;
int m_last_nmi_state;
@@ -48,12 +76,24 @@ public:
int m_joy_d7_state[2];
UINT8 m_joy_analog_state[2];
UINT8 m_joy_analog_reload[2];
- TIMER_CALLBACK_MEMBER(paddle_d7reset_callback);
- TIMER_CALLBACK_MEMBER(paddle_irqreset_callback);
- TIMER_CALLBACK_MEMBER(paddle_pulse_callback);
- TIMER_DEVICE_CALLBACK_MEMBER(paddle_update_callback);
- DECLARE_WRITE_LINE_MEMBER(coleco_vdp_interrupt);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(czz50_cart);
+
+ optional_ioport m_ctrlsel;
+ required_ioport m_std_keypad1;
+ required_ioport m_std_joy1;
+ required_ioport m_std_keypad2;
+ required_ioport m_std_joy2;
+ optional_ioport m_sac_keypad1;
+ optional_ioport m_sac_joy1;
+ optional_ioport m_sac_slide1;
+ optional_ioport m_sac_keypad2;
+ optional_ioport m_sac_joy2;
+ optional_ioport m_sac_slide2;
+ optional_ioport m_driv_wheel1;
+ optional_ioport m_driv_pedal1;
+ optional_ioport m_driv_wheel2;
+ optional_ioport m_driv_pedal2;
+ optional_ioport m_roller_x;
+ optional_ioport m_roller_y;
};
#endif
diff --git a/src/mess/machine/coleco.c b/src/mess/machine/coleco.c
index 82deef9aa8e..e95e6786903 100644
--- a/src/mess/machine/coleco.c
+++ b/src/mess/machine/coleco.c
@@ -3,98 +3,6 @@
#include "emu.h"
#include "machine/coleco.h"
-UINT8 coleco_scan_paddles(running_machine &machine, UINT8 *joy_status0, UINT8 *joy_status1)
-{
- UINT8 ctrl_sel = machine.root_device().ioport("CTRLSEL")->read_safe(0);
-
- /* which controller shall we read? */
- if ((ctrl_sel & 0x07) == 0x02) // Super Action Controller P1
- *joy_status0 = machine.root_device().ioport("SAC_SLIDE1")->read_safe(0);
- else if ((ctrl_sel & 0x07) == 0x03) // Driving Controller P1
- *joy_status0 = machine.root_device().ioport("DRIV_WHEEL1")->read_safe(0);
-
- if ((ctrl_sel & 0x70) == 0x20) // Super Action Controller P2
- *joy_status1 = machine.root_device().ioport("SAC_SLIDE2")->read_safe(0);
- else if ((ctrl_sel & 0x70) == 0x30) // Driving Controller P2
- *joy_status1 = machine.root_device().ioport("DRIV_WHEEL2")->read_safe(0);
-
- /* In principle, even if not supported by any game, I guess we could have two Super
- Action Controllers plugged into the Roller controller ports. Since I found no info
- about the behavior of sliders in such a configuration, we overwrite SAC sliders with
- the Roller trackball inputs and actually use the latter ones, when both are selected. */
- if (ctrl_sel & 0x80) // Roller controller
- {
- *joy_status0 = machine.root_device().ioport("ROLLER_X")->read_safe(0);
- *joy_status1 = machine.root_device().ioport("ROLLER_Y")->read_safe(0);
- }
-
- return *joy_status0 | *joy_status1;
-}
-
-
-UINT8 coleco_paddle_read(running_machine &machine, int port, int joy_mode, UINT8 joy_status)
-{
- UINT8 ctrl_sel = machine.root_device().ioport("CTRLSEL")->read_safe(0);
- UINT8 ctrl_extra = ctrl_sel & 0x80;
- ctrl_sel = ctrl_sel >> (port*4) & 7;
-
- /* Keypad and fire 1 (SAC Yellow Button) */
- if (joy_mode == 0)
- {
- /* No key pressed by default */
- UINT8 data = 0x0f;
- UINT16 ipt = 0xffff;
-
- if (ctrl_sel == 0) // ColecoVision Controller
- ipt = machine.root_device().ioport(port ? "STD_KEYPAD2" : "STD_KEYPAD1")->read();
- else if (ctrl_sel == 2) // Super Action Controller
- ipt = machine.root_device().ioport(port ? "SAC_KEYPAD2" : "SAC_KEYPAD1")->read();
-
- /* Numeric pad buttons are not independent on a real ColecoVision, if you push more
- than one, a real ColecoVision think that it is a third button, so we are going to emulate
- the right behaviour */
- /* Super Action Controller additional buttons are read in the same way */
- if (!(ipt & 0x0001)) data &= 0x0a; /* 0 */
- if (!(ipt & 0x0002)) data &= 0x0d; /* 1 */
- if (!(ipt & 0x0004)) data &= 0x07; /* 2 */
- if (!(ipt & 0x0008)) data &= 0x0c; /* 3 */
- if (!(ipt & 0x0010)) data &= 0x02; /* 4 */
- if (!(ipt & 0x0020)) data &= 0x03; /* 5 */
- if (!(ipt & 0x0040)) data &= 0x0e; /* 6 */
- if (!(ipt & 0x0080)) data &= 0x05; /* 7 */
- if (!(ipt & 0x0100)) data &= 0x01; /* 8 */
- if (!(ipt & 0x0200)) data &= 0x0b; /* 9 */
- if (!(ipt & 0x0400)) data &= 0x06; /* # */
- if (!(ipt & 0x0800)) data &= 0x09; /* * */
- if (!(ipt & 0x1000)) data &= 0x04; /* Blue Action Button */
- if (!(ipt & 0x2000)) data &= 0x08; /* Purple Action Button */
-
- return ((ipt & 0x4000) >> 8) | 0x30 | data;
- }
- /* Joystick and fire 2 (SAC Red Button) */
- else
- {
- UINT8 data = 0x7f;
-
- if (ctrl_sel == 0) // ColecoVision Controller
- data = machine.root_device().ioport(port ? "STD_JOY2" : "STD_JOY1")->read();
- else if (ctrl_sel == 2) // Super Action Controller
- data = machine.root_device().ioport(port ? "SAC_JOY2" : "SAC_JOY1")->read();
- else if (ctrl_sel == 3) // Driving Controller
- data = machine.root_device().ioport(port ? "DRIV_PEDAL2" : "DRIV_PEDAL1")->read();
-
- /* If any extra analog contoller enabled */
- if (ctrl_extra || ctrl_sel == 2 || ctrl_sel == 3)
- {
- if (joy_status & 0x80) data ^= 0x30;
- else if (joy_status) data ^= 0x10;
- }
-
- return data & 0x7f;
- }
-}
-
-
// ColecoVision Controller
static INPUT_PORTS_START( ctrl1 )
PORT_START("STD_KEYPAD1")
diff --git a/src/mess/machine/coleco.h b/src/mess/machine/coleco.h
index b7874b9c576..b6022b164c9 100644
--- a/src/mess/machine/coleco.h
+++ b/src/mess/machine/coleco.h
@@ -5,9 +5,6 @@
#ifndef __COLECO_CONTROLLERS__
#define __COLECO_CONTROLLERS__
-UINT8 coleco_scan_paddles(running_machine &machine, UINT8 *joy_status0, UINT8 *joy_status1);
-UINT8 coleco_paddle_read(running_machine &machine, int port, int joy_mode, UINT8 joy_status);
-
INPUT_PORTS_EXTERN( coleco );
#endif