Previous Thread
Next Thread
Print Thread
Joined: Sep 2013
Posts: 5
S
Member
OP Offline
Member
S
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,079
Likes: 6
L
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,079
Likes: 6
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
Offline
Senior Member
C
Joined: Feb 2005
Posts: 449
I'm on it.


Link Copied to Clipboard
Who's Online Now
2 members (R. Belmont, 1 invisible), 205 guests, and 1 robot.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,328
Posts122,128
Members5,074
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
Forum hosted by www.retrogamesformac.com