Jump to content
IGNORED

How to temporarily silence pokey and then resume


Recommended Posts

Is there a way to silence pokey and then resume where it left off?

 

For example, if I want to have a pause feature in a game that goes quiet while paused, and then resumes whatever sounds were already happening before the pause, is there an easy way to do that?

 

I was hoping I could just save the values of $D200 - $D209 before silencing all four channels, and then just put those values back in place after resuming.

 

I thought i was going crazy with the results of that attempt until i realized that $D200 - $D209 are write-only for POKEY usage, and that reading those locations give you the paddle position values. Ugh. So I was actually just moving paddles position values into my sound registers after the pause resumed. Definitely not the desired results!

 

So how should it be done then?

 

Thanks!

 

Link to comment
Share on other sites

Usually you don't want to lose the IRQs Pokey generates and in any case you'll usually want the keyboard functioning to be able to resume from pause.

 

In most cases you can simply store zeros to $D200-$D209 then as mentioned put the shadowed values back in at resume time.

But in a "purist" sense you lose the relationship between how notes were playing on each voice, though after a few seconds it doesn't exactly matter.

 

As alternative you could just mask out the volume bits with the shadow copies - if mute required, AND the AUDF values with $E0 (dec 224) before storing each one, just change the AND value to $FF on resume.

Link to comment
Share on other sites

It is easy to freeze PoKey temporarily.

 

POKE 53775,0 will turn off all voices (keyboard included!)

POKE 53775,3 to activate them again (together with keyboard function)

 

See SKCTL: $d20f (53775) and SSKCTL: $0232 (562)

thanks, but i kind of need the keyboard functionality to be able to resume from pause! :)

Link to comment
Share on other sites

Usually you don't want to lose the IRQs Pokey generates and in any case you'll usually want the keyboard functioning to be able to resume from pause.

 

In most cases you can simply store zeros to $D200-$D209 then as mentioned put the shadowed values back in at resume time.

But in a "purist" sense you lose the relationship between how notes were playing on each voice, though after a few seconds it doesn't exactly matter.

 

As alternative you could just mask out the volume bits with the shadow copies - if mute required, AND the AUDF values with $E0 (dec 224) before storing each one, just change the AND value to $FF on resume.

yes, that's what i am trying to do but the issue is i can't read what is in the AUDC values to store them before zeroing out the volume bits. I don't want to just resume to a default volume for everything because i definitely have varying levels of volume going into the pause (which could happen at any time of course ).

 

I think the solution you are describing would still require me to save off at least the volume bits for each channel in some shadow copies to be used to reload the AUDC volume bits after resuming from pause, right? I was hoping to avoid that if possible.

Link to comment
Share on other sites

I'll have a go at summarizing what Rybags is saying:

 

It is assumed you have a routine (perhaps updated in a VBI) that is writing frequency and volume values to the Pokey registers.

 

Therefore instead of writing to $D200->$D208 write to a reserved block, I'll give the example $100->$108.

At the end of your sound routine you can there copy direct $100->$108 to $D200->$D208 and you'll hear the same thing.

 

So Rybags has offered two solutions:

 

1) When pausing, clear the Pokey registers to end sound and so when paused, bypass the sound routine so that the shadow registered aren't progressed and copied to Pokey.

 

2) Still permit the sound routine to run but detect that pause is active and before copying the shadows to Pokey, set the volumes to zero.

 

This shadowing is common to music player routines (Hubbard, Whittaker et al) and so don't worry about avoiding the technique.

  • Like 1
Link to comment
Share on other sites

Another consideration - if you maintain each voice's volume seperately from the remainder of it's AUDC part, that then allows you to provide a master volume function which a few modern games also have.

You can implement it by simply shifting right each voice's volume by 0 to 3 times before ORing it with the remainder of the AUDC bits then storing to the register.

 

Doing that gives you a quick and easy full, half, quarter, mute master volume capability.

Link to comment
Share on other sites

I'll have a go at summarizing what Rybags is saying:

 

It is assumed you have a routine (perhaps updated in a VBI) that is writing frequency and volume values to the Pokey registers.

 

Therefore instead of writing to $D200->$D208 write to a reserved block, I'll give the example $100->$108.

At the end of your sound routine you can there copy direct $100->$108 to $D200->$D208 and you'll hear the same thing.

 

So Rybags has offered two solutions:

 

1) When pausing, clear the Pokey registers to end sound and so when paused, bypass the sound routine so that the shadow registered aren't progressed and copied to Pokey.

 

2) Still permit the sound routine to run but detect that pause is active and before copying the shadows to Pokey, set the volumes to zero.

 

This shadowing is common to music player routines (Hubbard, Whittaker et al) and so don't worry about avoiding the technique.

thanks for summarizing. I got it, and it makes perfect sense.

 

Its just not the way i had built up my sound routine in the project i am working on. Keeping shadow registers will be a little more work and take up a few more memory bytes to store it. That's okay though, again, makes perfect sense I just didn't think about approaching it that way from the beginning.

Link to comment
Share on other sites

Keyboard won't work properly unless the lower bits of SKCTL are both set. Some emulators don't properly mimic that behaviour.

 

If you're really tight on Ram you could just do the AUDCn only shadowing for 4 voices. The thing is the program code to copy it over becomes larger so you probably wouldn't benefit anyway.

Link to comment
Share on other sites

Anyway, my method only disables the keyboard interrupt, but the key code input still works then.

Just to correct myself: on the real machine the command POKE 53775,0 will stop the keyboard interrupt AND stop the SHIFT key and the keyboard input value itself. Altirra 2.60 acts differently. The START/SELECT/OPTION keys are still functioning.

Link to comment
Share on other sites

Just to correct myself: on the real machine the command POKE 53775,0 will stop the keyboard interrupt AND stop the SHIFT key and the keyboard input value itself. Altirra 2.60 acts differently. The START/SELECT/OPTION keys are still functioning.

 

This is emulated in Altirra 2.70.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...