Jump to content
IGNORED

Dual-POKEY and IRQs


Recommended Posts

Hi,

 

the A8 is missing raster interrupts. We have of course the DLIs, however, in some cases a raster IRQ would be easier to use.

For example, you could trigger an interrupt with (almost) pixel precision. In a DLI you have to put (hopefully useful) instructions in until you reach the desired position. One solution could be to use the POKEY timer IRQs, when POKEY is clocked at 15KHz. I did not tried it till now, but I read it in AA that it should be possible.

However, then at least one channel for sound is lost, and that is inacceptable, as we need all channels to make cool tunes (with filtering and so on).

 

The solution could be to use a stereo-POKEY setup. Then there would be enuff channels. I never wanted to use (demand) stereo POKEY, but if that would open the possibility to have a raster IRQ at my disposal I would do it.

 

Any opinions or even better: has anybody already done experiments with timer IRQs simulating a raster IRQ?

Link to comment
Share on other sites

Timer IRQs, I started playing with years ago.

 

These days it's pretty much accepted that using Timers is the best way to do sample playback (e.g. Super Harrier). You're using the voice anyway so there's no loss in this instance.

 

I believe NRV is still using Timers for Project M. The other advantage of Pokey Timers is you can adjust them to whatever cycle you need on the scanline (in 15 KHz mode).

 

The problem with Stereo Pokey IRQ - plenty of people have stereo Pokey, but virtually nobody has the second IRQ line connected.

 

So it's kind of an opportunity lost there. Then again, the Pots, keyboard scan and serial capability of 2nd Pokey is generally not in use either.

 

The other use of Pokey Timers - you can also use them in polling mode, run with IRQs disabled (SEI), then just periodically check the status register. There are some instances where this is a more desirable way to use them.

Link to comment
Share on other sites

Timer IRQs, I started playing with years ago.

Oh oh.. now i will fill your inbox :)

 

I believe NRV is still using Timers for Project M. The other advantage of Pokey Timers is you can adjust them to whatever cycle you need on the scanline (in 15 KHz mode).

 

The problem with Stereo Pokey IRQ - plenty of people have stereo Pokey, but virtually nobody has the second IRQ line connected.

 

The other use of Pokey Timers - you can also use them in polling mode, run with IRQs disabled (SEI), then just periodically check the status register. There are some instances where this is a more desirable way to use them.

 

Do I have to care if the 2nd POKEY has an IRQ line? I would use one timer of the 1st POKEY.

The 2nd would only be used for sound. What I imagine is that the users of a single POKEY will only get a worse music experience. Sound fx and timers for everyone :)

I started playing around with polling POT0 in the main loop. Works like a charm. However, when I want to combine that with, say, soft sprites or any other CPU intensive stuff, then it isn't reliable anymore.

 

Can/have you published your experiments? Setting the timer I have done years ago, but to get the timing right (combination of VCOUNT, WSYNC and NOPs?) can be fiddly :)

 

BTW, is AUDCTL handled the same with all stereo extensions? And can the freq-divider (1.79MHz, 65KHz, 15KHz) be set independently for each POKEY? As I need the 15KHz divider for scanline stuff.

Link to comment
Share on other sites

have a look here:

 

 

http://www.atariage.com/forums/topic/39806-pm-multiplexor/page__st__250

 

Andy is using Pokey Timers for Sprite Multiplexing. Not sure if the example is somewhere in the thread. But the C64 guys are more used to have a "flexible" raster interrupt than a DLI which is based on the DL.

Link to comment
Share on other sites

I've posted a thread or two, search for "Timers" in subject would probably find it/them.

 

Second Pokey is totally independant, no settings are shared.

 

Reasonable idea to use second one for sound only, of course that means many miss out, but I guess it's an incentive for us all to upgrade anyhow.

 

Don't worry about VCount, NOPs etc. You can put Pokey into a deterministic state so a 15 KHz IRQ can occur at any cycle you want on the scanline.

 

Fairly sure that putting Pokey into INIT state is the only way, there is STIMER that is useful in some instances, not sure if it resets the internal divisors properly though.

 

The other thing - don't rely in any way on the OS IRQ processing to help you out. Pokey Timers are very low on the priority chain.

It's best to at least use the Immediate IRQ Vector ($216) - one easy method is to just mask all other IRQs so that the Timer IRQ you're using is the only possible source.

 

Method #2 if you're really time-critical is to switch out the OS and use the hardware IRQ vector directly, that saves those few cycles if e.g. you wanted an IRQ every scanline or two.

Disadvantage there of course is that means 64K XL becomes the minimum spec machine.

 

 

Other thing to note - the hardware docs from Atari weren't exactly comprehensive on this subject. Forget STIMER, you don't need to touch it within your IRQ routine. Pokey Timers operate in continuous mode, you don't need to do anything other than the usual IRQEN disable/re-enable stuff as per any other Pokey IRQ type.

Edited by Rybags
Link to comment
Share on other sites

I've posted a thread or two, search for "Timers" in subject would probably find it/them.

 

Second Pokey is totally independant, no settings are shared.

 

Reasonable idea to use second one for sound only, of course that means many miss out, but I guess it's an incentive for us all to upgrade anyhow.

 

Don't worry about VCount, NOPs etc. You can put Pokey into a deterministic state so a 15 KHz IRQ can occur at any cycle you want on the scanline.

 

Thank you for your tips and hints. Really appreciated.

The NOPs and such I meant were for the pixel-precision timing. When I understood it correctly, 15KHz means one IRQ per scan line. So when I start the timer at, say, pixel 60 on line 8 with the value of 24, I get the interrupt at pixel 60 (+IRQ overhead as you mentioned) in line 32. So I need WSYNC and NOPs to find pixel 60 in line 8, right? But, for a start I will be aiming for scan line precision. Should be enuff anyway.

 

As for docu, since some months I only rely on the Altirra HW-doc :)

 

@Heaven: thanks for the multiplexer-thread-hint. I think I got the idea of using POTx from one of Andy's post. didn't remember, there was talk about POKEY timers as well :)

Link to comment
Share on other sites

You have to consider, regardless of DLI or Timer IRQ that you get the jitter because of indeterminate instruction length before the IRQ gets serviced.

 

So, you still either have to use WSync or do your changes such that they're either invisible or not noticable.

 

A good strategy might be to just put Pokey into INIT, do a WSync, have a controllable # of cycles delay before taking Pokey out of INIT, then run the timers.

Then just take note of the offset that gives the results you need.

 

A handy strategy also is to have some code in the background that runs long instructions so that you experience the worst case jitter.

Link to comment
Share on other sites

& don't forget to check some of the other pages:

 

http://www.atariage.com/forums/topic/39806-pm-multiplexor/page__st__150

http://www.atariage.com/forums/topic/39806-pm-multiplexor/page__st__175

 

Here's some more explanation of using the timer IRQs, acting like sort of raster IRQs.

 

& indeed, reset pokey will help to get 15khz divisor into the desired state, thus into the desired cycle of one scanline:

 

- clear bits 0 & 1 of SKCTL ($d20f) right before a divisor reset is needed

- again set bits 0 & 1 of SKCTL at the cycle / moment the 15khz divisor needs to fire

Edited by analmux
Link to comment
Share on other sites

This is the code that I'm using right now in P.M to initialize things:

 

.if .def IRQ_15KHz
; "init irq timer 4 and general clock"
lda #0		; volume = 0
sta AUDC4
lda #1		; 0 ==> count one scan line (minimum resolution!), 1 ==> count two
sta AUDF4
lda #1		; 15khz mode
sta AUDCTL

; "sync IRQs start (to an odd or even scan line)"
sta WSYNC
sta WSYNC

lda VCOUNT
Sync_irq_15KHz
sta WSYNC
cmp VCOUNT
beq Sync_irq_15KHz

sta WSYNC
sta WSYNC

; "do the final fine tuning sync"
lda #0
sta SKCTL

:10 nop
lda $00	; 23 cycles lost to sync to a position "before a specific pixel"

lda #3
sta SKCTL

	lda #1		; just need to be different than 0 ?
	sta STIMER	; is this really necessary ??

.endif

 

I use the 15 Khz mode and probably I'm doing some useless things, but it works :).

This is for my method of one IRQ every 2 scan lines, if one want to sync to an odd or even line (I don't remember which one).

 

Probably too many "sta WSYNC" at the start is overkill, but I wanted to be sure.

I really don't know if the set to STIMER needs to be there.

 

Also I don't need to start the IRQs always at the same exact position, just before certain pixel, so I just need to account for the worst case scenario. I suppose that case are the instructions that use 7 cycles: BRK; ASL, LSR, ROL and ROR $FFFF,X; INC and DEC $FFFF,X.. maybe we can avoid those instructions if you want that the worst case is only 6 cycles..

 

I start the sequence of 64 IRQs, every frame, inside a DLI with the next code:

 

.if .def IRQ_15KHz
lda #4
.else
lda #1
.endif
sta IRQEN

 

The sequence of IRQs ends of "natural death" because the last IRQ doesn't set IRQEN again, but I would like to terminate the IRQs inside another DLI, so to not have to use a counter (but, that never worked when I tried one year ago).

 

Regards!

 

(I hate using ' or " to mark comments in the code segments :D, I miss the old syntax coloring!).

Link to comment
Share on other sites

IRQ means you can trigger it when you want, and not have wasted cycles with WSYNC etc.

 

Also, not totally sure here, but would a DLI occur soon enough to do a PRIOR change before the start of a Narrow DMA display?

 

Yes that's the main reason. We talked about this before and is not possible to use DLI's without wasting too much time (by the use of WSYNC). You can only trigger the change before the start of a line, only in narrow modes (32 bytes) and sacrificing a register like X or Y (preloaded with the PRIOR value), I believe.

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...