GroovyBee Posted July 5, 2009 Share Posted July 5, 2009 I've been experimenting with POKEY in my latest game Apple Snaffle and I wanted a short reliable method to detect if POKEY was in the memory map. I came up with this :- .proc DetectPokey ; Reset/initialise POKEY. lda #0 sta gamePokeyDetected sta PAUDCTL sta PSKCTL ; Short delay before RANDOM is valid. nop nop nop ; Read the RANDOM register (should return 0xFF when POKEY is in reset) lda PRANDOM cmp #$FF bne @NoPokeyDetected ; Take POKEY out of reset. lda #3 sta PSKCTL ; Short delay before RANDOM is valid. nop nop nop ; Read RANDOM 4 times and junk the first read. lda PRANDOM ; Should yield 0x00 - Junked. lda PRANDOM ; Should yield 0x80 ldx PRANDOM ; Should yield 0xF8 ldy PRANDOM ; Should yield 0x0F ; See if POKEY is there. cmp #$80 ; Expected value? bne @NoPokeyDetected ; No... POKEY *NOT* detected. cpx #$F8 ; Expected value? bne @NoPokeyDetected ; No... POKEY *NOT* detected. cpy #$0F ; Expected value? bne @NoPokeyDetected ; No... POKEY *NOT* detected. rts ; POKEY not detected. @NoPokeyDetected: dec gamePokeyDetected ; Switch off POKEY sound rts .endproc Its in CC65 assembler format and is easily converted to DASM etc. The variable gamePokeyDetected is 0xFF if POKEY isn't detected or 0x00 if it is. The basic theory of operation is that it relies on reading POKEY's RANDOM register several times to get known values after the 17 bit polynomial counter is reset to all 1's. Hopefully this will avoid false positives caused by bus float problems. I've tested it on my CC2 with:- 7800_32K - POKEY not detected (as expected). 78POKEY - POKEY detected (as expected). It doesn't detect POKEY in the ProSystem emulator because the RANDOM register is not emulated . Feel free to use it but don't add/subtract code to the function otherwise you will change the values read back from RANDOM. Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 6, 2009 Share Posted July 6, 2009 (edited) Maybe use one of the methods from the computer to detect a second (stereo) Pokey. I suppose the IRQ line isn't connected on the 7800 to Pokey, if so that rules out that option. An issue with your method is that DMA accesses can affect the timing, although you could take action to ensure you're in a known state so far as that goes. IIRC, two other methods we've discussed/implemented are: - setup a Timer IRQ and see if it triggers (generally run with "I" set, then just check IRQST after the interval expires) - set Fast Potscan mode then trigger the Pot Scan. The Paddle values should increment upwards shortly after at the rate of 1 per cycle. Best to test on Paddle4, 5, 6 or 7 since they're not connected on anything other than the 400/800 or 4-port 5200. Edited July 6, 2009 by Rybags Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted July 6, 2009 Author Share Posted July 6, 2009 (edited) I suppose the IRQ line isn't connected on the 7800 to Pokey, if so that rules out that option. Correct! POKEY isn't connected to the IRQ line of the processor in a 7800. An issue with your method is that DMA accesses can affect the timing, although you could take action to ensure you're in a known state so far as that goes. Good call! I'm doing the detection during the cart's CPU/RAM/peripheral initialisation phase so video isn't enabled at POKEY detection time. IIRC, two other methods we've discussed/implemented are:- setup a Timer IRQ and see if it triggers (generally run with "I" set, then just check IRQST after the interval expires) I'd thought about doing that but decided against it. I just wanted a simple approach that didn't use any loops. - set Fast Potscan mode then trigger the Pot Scan. The Paddle values should increment upwards shortly after at the rate of 1 per cycle. Best to test on Paddle4, 5, 6 or 7 since they're not connected on anything other than the 400/800 or 4-port 5200. Thanks for that. I'd not considered using the paddle interface, but again it involves loops which I wanted to avoid. EDIT: For spelling Edited July 6, 2009 by GroovyBee Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 6, 2009 Share Posted July 6, 2009 The IRQ could be a valid approach - doesn't matter that it's not connected because you can just operate in polling mode anyway. Another one - I think the Keycode value might = 00 when Pokey is in Init State (?) Might have to test that one out. Or, it might have been RANDOM = 00 when in Init State. Of course, if keycode = 00 during normal operation of the 7800, then it kinda rules that option out. I suppose the other consideration is that you want all this to work in emulation as well, and not all emus will necessarily reflect these seldom looked at qualities. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted July 6, 2009 Author Share Posted July 6, 2009 The IRQ could be a valid approach - doesn't matter that it's not connected because you can just operate in polling mode anyway. Agreed! Another one - I think the Keycode value might = 00 when Pokey is in Init State (?)Might have to test that one out. Or, it might have been RANDOM = 00 when in Init State. I wanted to avoid the situation where the bus floating (POKEY not present) would cause false positives. On some 7800s there are pull downs on the data bus, so reading a single value of 0x00 isn't a good idea. RANDOM returns 0xFF when POKEY is in its init state and that is tested in the code above. I suppose the other consideration is that you want all this to work in emulation as well, and not all emus will necessarily reflect these seldom looked at qualities. ProSystem doesn't emulate the RANDOM register at all . Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted June 18, 2011 Share Posted June 18, 2011 Just wanted to post and say that the detection works *wonderfully* (at least in the CCII). Thanks, GroovyBee Quote Link to comment Share on other sites More sharing options...
DEBRO Posted June 19, 2011 Share Posted June 19, 2011 I thought Ken Siders had a routine for detecting POKEY. Am I wrong? What was wrong with that one? Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted June 20, 2011 Share Posted June 20, 2011 I didn't know there was another one... Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted June 21, 2011 Author Share Posted June 21, 2011 From what I remember Ken's routine puts POKEY into reset and checks that it can read 0xFF from the RANDOM register. Then it takes POKEY out of reset and checks that the values read from RANDOM are all different. Apologies if I've got that wrong its a while since I looked at the Beef Drop code. 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.