diff options
author | 2019-03-18 15:19:43 +0100 | |
---|---|---|
committer | 2019-03-18 15:20:08 +0100 | |
commit | b1d009c09014a1c3dd2487195712335244b78335 (patch) | |
tree | cae18cbe4968e85d161051346bd17c0e34b78cbf | |
parent | 21118d2446c4a1b23fdf4dc3f68424d38f4b3cb8 (diff) |
-astrohome: Various changes. [Ryan Holtz]
* Fixed cassette loading via 300-baud Bally BASIC tape interface.
* Added light-pen callback to controller slot device.
* Fixed spurious light pen interrupts being triggered every scanline.
* In particular, this fixes machine/tape sync on 2000-baud multi-part music tapes.
-rw-r--r-- | src/devices/bus/astrocde/cassette.cpp | 90 | ||||
-rw-r--r-- | src/devices/bus/astrocde/cassette.h | 16 | ||||
-rw-r--r-- | src/devices/bus/astrocde/ctrl.cpp | 11 | ||||
-rw-r--r-- | src/devices/bus/astrocde/ctrl.h | 57 | ||||
-rw-r--r-- | src/mame/drivers/astrohome.cpp | 19 | ||||
-rw-r--r-- | src/mame/includes/astrocde.h | 1 | ||||
-rw-r--r-- | src/mame/video/astrocde.cpp | 5 |
7 files changed, 158 insertions, 41 deletions
diff --git a/src/devices/bus/astrocde/cassette.cpp b/src/devices/bus/astrocde/cassette.cpp index 50c27f18b5a..3e4cc80deb8 100644 --- a/src/devices/bus/astrocde/cassette.cpp +++ b/src/devices/bus/astrocde/cassette.cpp @@ -1,10 +1,8 @@ // license:BSD-3-Clause // copyright-holders:Ryan Holtz // -// TODO: Emulation of the circuitry to convert 300-baud Kansas City Standard data into bits. -// // Decoding is done in hardware by an external box, and decoded bits are fed to bit 0 of the controller port, -// with sync bits being fed to bit 1. +// with sync bits being fed to bit 1. The current HLE is not remotely accurate to hardware, but works. #include "emu.h" #include "cassette.h" @@ -31,10 +29,33 @@ astrocade_cassette_device::~astrocade_cassette_device() { } +void astrocade_cassette_device::device_start() +{ + save_item(NAME(m_cass_wave)); + save_item(NAME(m_cass_delta)); + save_item(NAME(m_cass_wave_ticks)); + save_item(NAME(m_cass_cycles)); + save_item(NAME(m_cass_mark)); +} + +void astrocade_cassette_device::device_reset() +{ + m_cass_wave = 0.0; + m_cass_delta = 0.0; + m_cass_wave_ticks = 0; + m_cass_cycles = 0; + m_cass_mark = false; +} + uint8_t astrocade_cassette_device::read_handle() { - uint8_t data = m_cassette->input() > 0.0 ? 0 : 1; - return data; + if (m_cass_data.size()) + { + const uint8_t data = m_cass_data.front(); + m_cass_data.pop(); + return data; + } + return 0; } uint8_t astrocade_cassette_device::read_knob() @@ -42,9 +63,68 @@ uint8_t astrocade_cassette_device::read_knob() return 0; } +TIMER_DEVICE_CALLBACK_MEMBER(astrocade_cassette_device::check_cassette_wave) +{ + if (m_cassette->get_state() & CASSETTE_MOTOR_DISABLED) + return; + + double old_cass_wave = m_cass_wave; + m_cass_wave = m_cassette->input(); + + bool cycled = false; + if (old_cass_wave != m_cass_wave) + { + double old_delta = m_cass_delta; + m_cass_delta = m_cass_wave - old_cass_wave; + if (old_delta < 0.0 && m_cass_delta > 0.0) + { + cycled = true; + } + } + + if (cycled) + { + m_cass_mark = m_cass_wave_ticks <= 30; + + m_cass_wave_ticks = 0; + + m_cass_cycles++; + if (m_cass_mark) + { + if (m_cass_cycles >= 8) + { + m_cass_data.push(1); + m_cass_cycles = 0; + } + } + else + { + if (m_cass_cycles >= 4) + { + m_cass_data.push(0); + m_cass_cycles = 0; + } + } + } + + m_cass_wave_ticks++; +} + +TIMER_DEVICE_CALLBACK_MEMBER(astrocade_cassette_device::pulse_cassette_clock) +{ + if (m_cass_data.size()) + { + write_ltpen(1); + write_ltpen(0); + } +} + void astrocade_cassette_device::device_add_mconfig(machine_config &config) { CASSETTE(config, m_cassette); m_cassette->set_default_state(CASSETTE_STOPPED); m_cassette->set_interface("astrocade_cass"); + + TIMER(config, "kcs_hle").configure_periodic(FUNC(astrocade_cassette_device::check_cassette_wave), attotime::from_hz(48000)); + TIMER(config, "kcs_clk").configure_periodic(FUNC(astrocade_cassette_device::pulse_cassette_clock), attotime::from_hz(300)); } diff --git a/src/devices/bus/astrocde/cassette.h b/src/devices/bus/astrocde/cassette.h index bcbfd697a50..b9f086e449a 100644 --- a/src/devices/bus/astrocde/cassette.h +++ b/src/devices/bus/astrocde/cassette.h @@ -7,6 +7,10 @@ #include "ctrl.h" #include "imagedev/cassette.h" +#include "machine/timer.h" + +#include <queue> + /*************************************************************************** TYPE DEFINITIONS @@ -30,11 +34,21 @@ public: protected: // device_t implementation - virtual void device_start() override { } + virtual void device_start() override; + virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; + TIMER_DEVICE_CALLBACK_MEMBER(check_cassette_wave); + TIMER_DEVICE_CALLBACK_MEMBER(pulse_cassette_clock); + private: required_device<cassette_image_device> m_cassette; + double m_cass_wave; + double m_cass_delta; + uint32_t m_cass_wave_ticks; + uint32_t m_cass_cycles; + bool m_cass_mark; + std::queue<uint8_t> m_cass_data; }; diff --git a/src/devices/bus/astrocde/ctrl.cpp b/src/devices/bus/astrocde/ctrl.cpp index 16b8537eae4..89cd60ca6a5 100644 --- a/src/devices/bus/astrocde/ctrl.cpp +++ b/src/devices/bus/astrocde/ctrl.cpp @@ -54,6 +54,9 @@ void device_astrocade_ctrl_interface::interface_pre_start() astrocade_ctrl_port_device::astrocade_ctrl_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) : device_t(mconfig, ASTROCADE_CTRL_PORT, tag, owner, clock) , device_slot_interface(mconfig, *this) + , m_ltpen(0) + , m_ltpen_handler(*this) + , m_device(nullptr) { } @@ -75,6 +78,8 @@ void astrocade_ctrl_port_device::device_resolve_objects() device_astrocade_ctrl_interface *const card(dynamic_cast<device_astrocade_ctrl_interface *>(get_card_device())); if (card) m_device = card; + + m_ltpen_handler.resolve_safe(); } void astrocade_ctrl_port_device::device_start() @@ -87,6 +92,12 @@ void astrocade_ctrl_port_device::device_start() throw emu_fatalerror("astrocade_ctrl_port_device: card device %s (%s) does not implement device_astrocade_ctrl_interface\n", card->tag(), card->name()); } } + + save_item(NAME(m_ltpen)); + + m_ltpen = 0; + + m_ltpen_handler(0); } uint8_t astrocade_ctrl_port_device::read_handle() diff --git a/src/devices/bus/astrocde/ctrl.h b/src/devices/bus/astrocde/ctrl.h index 7ff8acbde52..0cc34ea4dcc 100644 --- a/src/devices/bus/astrocde/ctrl.h +++ b/src/devices/bus/astrocde/ctrl.h @@ -10,37 +10,13 @@ FORWARD DECLARATIONS ***************************************************************************/ -class astrocade_ctrl_port_device; +class device_astrocade_ctrl_interface; /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ -// ======================> device_astrocade_ctrl_interface - -class device_astrocade_ctrl_interface : public device_slot_card_interface -{ -public: - virtual ~device_astrocade_ctrl_interface(); - - virtual uint8_t read_handle() { return 0; } - virtual uint8_t read_knob() { return 0; } - -protected: - device_astrocade_ctrl_interface(machine_config const &mconfig, device_t &device); - - // device_interface implementation - virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD; - virtual void interface_pre_start() override; - -private: - astrocade_ctrl_port_device *const m_port; - - friend class astrocade_ctrl_port_device; -}; - - // ======================> astrocade_ctrl_port_device class astrocade_ctrl_port_device : public device_t, public device_slot_interface @@ -59,6 +35,8 @@ public: astrocade_ctrl_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U); virtual ~astrocade_ctrl_port_device(); + auto ltpen_handler() { return m_ltpen_handler.bind(); } + uint8_t read_handle(); uint8_t read_knob(); @@ -68,6 +46,9 @@ protected: virtual void device_resolve_objects() override; virtual void device_start() override; + int m_ltpen; + devcb_write_line m_ltpen_handler; + private: device_astrocade_ctrl_interface *m_device; @@ -75,6 +56,32 @@ private: }; +// ======================> device_astrocade_ctrl_interface + +class device_astrocade_ctrl_interface : public device_slot_card_interface +{ +public: + virtual ~device_astrocade_ctrl_interface(); + + virtual uint8_t read_handle() { return 0; } + virtual uint8_t read_knob() { return 0; } + + DECLARE_WRITE_LINE_MEMBER( write_ltpen ) { m_port->m_ltpen = state; m_port->m_ltpen_handler(state); } + +protected: + device_astrocade_ctrl_interface(machine_config const &mconfig, device_t &device); + + // device_interface implementation + virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD; + virtual void interface_pre_start() override; + +private: + astrocade_ctrl_port_device *const m_port; + + friend class astrocade_ctrl_port_device; +}; + + /*************************************************************************** FUNCTIONS ***************************************************************************/ diff --git a/src/mame/drivers/astrohome.cpp b/src/mame/drivers/astrohome.cpp index 9cd36b55b8e..89baf17bfdf 100644 --- a/src/mame/drivers/astrohome.cpp +++ b/src/mame/drivers/astrohome.cpp @@ -107,11 +107,7 @@ READ8_MEMBER(astrocde_home_state::inputs_r) if (BIT(offset, 2)) return m_keypad[offset & 3]->read(); else - { - uint8_t data = m_ctrl[offset & 3]->read_handle(); - //printf("%d", BIT(data, 0)); - return data; - } + return m_ctrl[offset & 3]->read_handle(); } static INPUT_PORTS_START( astrocde ) @@ -185,6 +181,8 @@ void astrocde_home_state::astrocde(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &astrocde_home_state::astrocade_mem); m_maincpu->set_addrmap(AS_IO, &astrocde_home_state::astrocade_io); + config.m_perfect_cpu_quantum = subtag("maincpu"); + MCFG_MACHINE_START_OVERRIDE(astrocde_home_state, astrocde) /* video hardware */ @@ -196,10 +194,11 @@ void astrocde_home_state::astrocde(machine_config &config) PALETTE(config, "palette", FUNC(astrocde_home_state::astrocade_palette), 512); /* control ports */ - ASTROCADE_CTRL_PORT(config, m_ctrl[0], astrocade_controllers, "joy"); - ASTROCADE_CTRL_PORT(config, m_ctrl[1], astrocade_controllers, nullptr); - ASTROCADE_CTRL_PORT(config, m_ctrl[2], astrocade_controllers, nullptr); - ASTROCADE_CTRL_PORT(config, m_ctrl[3], astrocade_controllers, nullptr); + for (uint32_t port = 0; port < 4; port++) + { + ASTROCADE_CTRL_PORT(config, m_ctrl[port], astrocade_controllers, port == 0 ? "joy" : nullptr); + m_ctrl[port]->ltpen_handler().set(FUNC(astrocde_home_state::lightpen_trigger_w)); + } /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -251,7 +250,7 @@ ROM_END void astrocde_state::init_astrocde() { - m_video_config = AC_SOUND_PRESENT | AC_LIGHTPEN_INTS; + m_video_config = AC_SOUND_PRESENT; } MACHINE_START_MEMBER(astrocde_home_state, astrocde) diff --git a/src/mame/includes/astrocde.h b/src/mame/includes/astrocde.h index 9d5d437d627..9b1301b3897 100644 --- a/src/mame/includes/astrocde.h +++ b/src/mame/includes/astrocde.h @@ -129,6 +129,7 @@ public: DECLARE_READ8_MEMBER(profpac_videoram_r); DECLARE_WRITE8_MEMBER(profpac_videoram_w); DECLARE_INPUT_CHANGED_MEMBER(spacezap_monitor); + DECLARE_WRITE_LINE_MEMBER(lightpen_trigger_w); void init_profpac(); void init_spacezap(); void init_robby(); diff --git a/src/mame/video/astrocde.cpp b/src/mame/video/astrocde.cpp index 63e35e6184c..18df30ed108 100644 --- a/src/mame/video/astrocde.cpp +++ b/src/mame/video/astrocde.cpp @@ -395,6 +395,11 @@ void astrocde_state::device_timer(emu_timer &timer, device_timer_id id, int para } } +WRITE_LINE_MEMBER(astrocde_state::lightpen_trigger_w) +{ + if (state) + astrocade_trigger_lightpen(m_screen->vpos(), m_screen->hpos()); +} void astrocde_state::astrocade_trigger_lightpen(uint8_t vfeedback, uint8_t hfeedback) { |