diff options
author | 2020-08-12 22:35:40 +0200 | |
---|---|---|
committer | 2020-08-12 22:36:07 +0200 | |
commit | 64d1d3a0f12d481fb00953836ea7e97e74e280f2 (patch) | |
tree | 39ffcd5b741c2a7f2e1fbca0106fee2dec67f19d | |
parent | 9d00d87dac0d4f606268f3eb43335eb81a58cad1 (diff) |
odyssey2/homecomp: add cassette i/o
-rw-r--r-- | src/devices/bus/odyssey2/homecomp.cpp | 30 | ||||
-rw-r--r-- | src/devices/imagedev/cassette.cpp | 18 | ||||
-rw-r--r-- | src/devices/imagedev/cassette.h | 21 |
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 |