summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2020-08-12 22:35:40 +0200
committer hap <happppp@users.noreply.github.com>2020-08-12 22:36:07 +0200
commit64d1d3a0f12d481fb00953836ea7e97e74e280f2 (patch)
tree39ffcd5b741c2a7f2e1fbca0106fee2dec67f19d
parent9d00d87dac0d4f606268f3eb43335eb81a58cad1 (diff)
odyssey2/homecomp: add cassette i/o
-rw-r--r--src/devices/bus/odyssey2/homecomp.cpp30
-rw-r--r--src/devices/imagedev/cassette.cpp18
-rw-r--r--src/devices/imagedev/cassette.h21
3 files changed, 46 insertions, 23 deletions
diff --git a/src/devices/bus/odyssey2/homecomp.cpp b/src/devices/bus/odyssey2/homecomp.cpp
index 829ecb35c86..167e3b1b549 100644
--- a/src/devices/bus/odyssey2/homecomp.cpp
+++ b/src/devices/bus/odyssey2/homecomp.cpp
@@ -14,7 +14,8 @@ Hardware notes:
TODO:
- lots of unacknowledged writes to latch 1, probably harmless
-- add cassette i/o
+- cassette data saved from MAME can be loaded fine, but other WAVs can't, even
+ when they are good quality, maybe a filter on the data input?
******************************************************************************/
@@ -66,6 +67,17 @@ u8 o2_homecomp_device::internal_io_r(offs_t offset)
{
// d0: latch 0 status
data |= m_latch[0]->pending_r() ^ 1;
+
+ if (m_cass->is_playing() && m_cass->motor_on())
+ {
+ // d6: cass clock
+ // d7: cass data
+ double level = m_cass->input();
+ if (level > 0.04)
+ data |= 0xc0;
+ else if (level < -0.04)
+ data |= 0x80;
+ }
}
return data;
@@ -76,6 +88,20 @@ void o2_homecomp_device::internal_io_w(offs_t offset, u8 data)
// A7: output latch
if (~offset & 0x80)
m_latch[0]->write(data);
+
+ // A6: other i/o
+ if (~offset & 0x40)
+ {
+ // d7: cass remote control (also with data)
+ m_cass->set_motor((data & 0x81) ? 1 : 0);
+
+ // d0: cass data
+ // d1: cass clock
+ double level = 0.0;
+ if (data & 1)
+ level = (data & 2) ? 0.8 : -0.8;
+ m_cass->output(level);
+ }
}
void o2_homecomp_device::homecomp_mem(address_map &map)
@@ -107,7 +133,7 @@ void o2_homecomp_device::device_add_mconfig(machine_config &config)
// cassette
CASSETTE(config, m_cass);
- m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED);
+ m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_DISABLED);
SPEAKER(config, "cass_output").front_center(); // on data recorder
m_cass->add_route(ALL_OUTPUTS, "cass_output", 0.05);
}
diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp
index 4e090b0e498..473dfe0ce7b 100644
--- a/src/devices/imagedev/cassette.cpp
+++ b/src/devices/imagedev/cassette.cpp
@@ -72,23 +72,11 @@ void cassette_image_device::device_config_complete()
cassette IO
*********************************************************************/
-bool cassette_image_device::is_motor_on()
-{
- if ((m_state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED)
- return false;
- if ((m_state & CASSETTE_MASK_MOTOR) != CASSETTE_MOTOR_ENABLED)
- return false;
- else
- return true;
-}
-
-
-
void cassette_image_device::update()
{
double cur_time = machine().time().as_double();
- if (is_motor_on())
+ if (!is_stopped() && motor_on())
{
double new_position = m_position + (cur_time - m_position_time)*m_speed*m_direction;
@@ -170,7 +158,7 @@ double cassette_image_device::get_position()
{
double position = m_position;
- if (is_motor_on())
+ if (!is_stopped() && motor_on())
position += (machine().time().as_double() - m_position_time)*m_speed*m_direction;
return position;
}
@@ -369,7 +357,7 @@ std::string cassette_image_device::call_display()
std::string result;
// only show the image when a cassette is loaded and the motor is on
- if (exists() && is_motor_on())
+ if (exists() && !is_stopped() && motor_on())
{
static char const *const shapes[] = { u8"\u2500", u8"\u2572", u8"\u2502", u8"\u2571" };
diff --git a/src/devices/imagedev/cassette.h b/src/devices/imagedev/cassette.h
index e5a67a10970..790b2e0d8c3 100644
--- a/src/devices/imagedev/cassette.h
+++ b/src/devices/imagedev/cassette.h
@@ -74,13 +74,23 @@ public:
virtual const char *image_interface() const noexcept override { return m_interface; }
virtual const char *file_extensions() const noexcept override { return m_extension_list; }
+ double input();
+ void output(double value);
+
// specific implementation
cassette_state get_state() { return m_state; }
void set_state(cassette_state state) { change_state(state, cassette_state(~0)); }
void change_state(cassette_state state, cassette_state mask);
- double input();
- void output(double value);
+ // state getters/setters
+ bool is_stopped() { return (m_state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED; }
+ bool is_playing() { return (m_state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY; }
+ bool is_recording() { return (m_state & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD; }
+
+ void set_motor(int state) { change_state(state ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); } // aka remote control
+ int motor_on() { return ((m_state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED) ? 1 : 0; }
+ void set_speaker(int state) { change_state(state ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER); }
+ int speaker_on() { return ((m_state & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_ENABLED) ? 1 : 0; }
cassette_image *get_image() { return m_cassette; }
double get_position();
@@ -96,9 +106,6 @@ public:
device_sound_interface& set_stereo() { m_stereo = true; return *this; }
protected:
- bool is_motor_on();
- void update();
-
// device-level overrides
virtual void device_config_complete() override;
virtual void device_start() override;
@@ -107,12 +114,14 @@ protected:
// device_image_interface implementation
virtual const software_list_loader &get_software_list_loader() const override { return image_software_list_loader::instance(); }
+ void update();
+
private:
cassette_image *m_cassette;
cassette_state m_state;
double m_position;
double m_position_time;
- int32_t m_value;
+ int32_t m_value;
int m_channel;
double m_speed; // speed multiplier for tape speeds other than standard 1.875ips (used in adam driver)
int m_direction; // direction select