Previous Thread
Next Thread
Print Thread
Joined: Sep 2013
Posts: 5
S
Member
Member
S Offline
Joined: Sep 2013
Posts: 5
MESS's C64 driver is able to load tapes sampled into WAV files.

However, the feature has some problems.

Here's a sequence of steps to reproduce the problem.

  • Start MESS c64p driver (Commodore 64 PAL)
  • type LOAD(Enter) in the emulated C64
  • press Scroll Lock to enter partial keyboard emulation
  • press TAB to enter the menu
  • Choose File Manager
  • Choose Cassette (cass)
  • Select a WAV file with a sampled C64 tape
  • Press ESC to get back to the main menu
  • Choose Tape Control
  • Choose Play


The cassette will go into playing state, then immediately to stopped state. You need to choose Play once (sometimes twice) more to have the cassette running.

After a while, the emulated C64 will show the FOUND message and stop the motor of the emulated cassette player. After a few seconds, the motor of the emulated cassette player will restart. At that point, the cassette will go into stopped state, and rewind to zero.

I investigated the problem a bit. c2n_device sets a timer (m_read_timer) that goes off 44100 times a second, and, every time, updates the state of the cassette input line with the WAV sample. When the C64 stops the motor of the cassette player, c2n_device::m_read_timer is disabled, so its timer does not go off. When the C64 restarts the motor of the cassette player, c2n_device::m_read_timer.m_expire still has the value of when the motor was stopped. When the timer is enabled again, the line

m_callback_timer_expire_time = timer.m_expire;

in schedule.c changes the current time, setting it backwards (because timer.m_expire was not progressing while the cassette motor was stopped).

The next time cassette_image_device::update() is called,
cur_time = device().machine().time().as_double();
assigns cur_time the new current time, while m_position_time still contains the value of the current time at the previous call. The line

double new_position = m_position + (cur_time - m_position_time)*m_speed*m_direction;

assigns a negative value to new_position (since cur_time < m_position_time), and, a few lines below,

else if (new_position < 0)
{
m_state = (cassette_state)(( m_state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
new_position = 0;
}

stops the cassette.

Joined: Mar 2006
Posts: 1,082
Likes: 7
L
Very Senior Member
Very Senior Member
L Offline
Joined: Mar 2006
Posts: 1,082
Likes: 7
This is actually a really really nice bug report. Hopefully it isn't too hard for the driver maintainer to fix it.

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Joined: Feb 2005
Posts: 449
C
Senior Member
Senior Member
C Offline
Joined: Feb 2005
Posts: 449
I'm on it.


Link Copied to Clipboard
Who's Online Now
1 members (Dam0), 98 guests, and 6 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,364
Posts122,482
Members5,082
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Powered by UBB.threads™ PHP Forum Software 8.0.0