summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2019-03-18 15:19:43 +0100
committer MooglyGuy <therealmogminer@gmail.com>2019-03-18 15:20:08 +0100
commitb1d009c09014a1c3dd2487195712335244b78335 (patch)
treecae18cbe4968e85d161051346bd17c0e34b78cbf
parent21118d2446c4a1b23fdf4dc3f68424d38f4b3cb8 (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.cpp90
-rw-r--r--src/devices/bus/astrocde/cassette.h16
-rw-r--r--src/devices/bus/astrocde/ctrl.cpp11
-rw-r--r--src/devices/bus/astrocde/ctrl.h57
-rw-r--r--src/mame/drivers/astrohome.cpp19
-rw-r--r--src/mame/includes/astrocde.h1
-rw-r--r--src/mame/video/astrocde.cpp5
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)
{