erichenneke Posted February 13, 2016 Share Posted February 13, 2016 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! Quote Link to comment Share on other sites More sharing options...
+David_P Posted February 13, 2016 Share Posted February 13, 2016 You'll need to maintain a set of shadow registers for the sound routine. Quote Link to comment Share on other sites More sharing options...
analmux Posted February 13, 2016 Share Posted February 13, 2016 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) Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 13, 2016 Share Posted February 13, 2016 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. Quote Link to comment Share on other sites More sharing options...
erichenneke Posted February 14, 2016 Author Share Posted February 14, 2016 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! Quote Link to comment Share on other sites More sharing options...
erichenneke Posted February 14, 2016 Author Share Posted February 14, 2016 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. Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 14, 2016 Share Posted February 14, 2016 The trick is keep shadow copies - if you're doing music or sound effects you generally have variables or Ram locations dedicated to keeping track of what's going on anyway so it's not a big deal. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 14, 2016 Share Posted February 14, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 14, 2016 Share Posted February 14, 2016 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. Quote Link to comment Share on other sites More sharing options...
erichenneke Posted February 14, 2016 Author Share Posted February 14, 2016 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. Quote Link to comment Share on other sites More sharing options...
analmux Posted February 14, 2016 Share Posted February 14, 2016 thanks, but i kind of need the keyboard functionality to be able to resume from pause! Well, you can still use GTIA mode for the START/SELECT/OPTION keys. Anyway, my method only disables the keyboard interrupt, but the key code input still works then. Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 15, 2016 Share Posted February 15, 2016 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. Quote Link to comment Share on other sites More sharing options...
analmux Posted February 15, 2016 Share Posted February 15, 2016 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. Quote Link to comment Share on other sites More sharing options...
phaeron Posted February 16, 2016 Share Posted February 16, 2016 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. Quote Link to comment Share on other sites More sharing options...
pirx Posted February 16, 2016 Share Posted February 16, 2016 or you can screw shadowing and modify the mask in code: ;player routine ... ch1vol and #$ff sta AUDC1 ... ch2vol and #$ff sta AUDC2... ;pause ... lda #$f0 sta ch1vol+1 sta ch2vol+1 ... ;end of pause ... lda #$ff sta ch1vol+1 sta ch2vol+1 ... 1 Quote Link to comment Share on other sites More sharing options...
erichenneke Posted February 18, 2016 Author Share Posted February 18, 2016 or you can screw shadowing and modify the mask in code: ;player routine ... ch1vol and #$ff sta AUDC1 ... ch2vol and #$ff sta AUDC2... ;pause ... lda #$f0 sta ch1vol+1 sta ch2vol+1 ... ;end of pause ... lda #$ff sta ch1vol+1 sta ch2vol+1 ... in this example, what is ch1vol and ch2vol then ? Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted February 19, 2016 Share Posted February 19, 2016 in this example, what is ch1vol and ch2vol then ? That is self-modifying code. Works great in RAM, but the parts that get modified can't be in ROM. ch1vol and ch2vol point to the AND instruction, so ch1vol+1 and ch2vol+1 point to the mask which is modified to control sound output. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.