diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/bus/coleco/exp.c | 11 | ||||
-rw-r--r-- | src/emu/bus/coleco/xin1.c | 71 | ||||
-rw-r--r-- | src/emu/bus/coleco/xin1.h | 48 | ||||
-rw-r--r-- | src/emu/emuopts.c | 2 | ||||
-rw-r--r-- | src/emu/emuopts.h | 3 | ||||
-rw-r--r-- | src/mess/drivers/coleco.c | 97 | ||||
-rw-r--r-- | src/mess/includes/coleco.h | 62 | ||||
-rw-r--r-- | src/mess/machine/coleco.c | 92 | ||||
-rw-r--r-- | src/mess/machine/coleco.h | 3 |
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 |