Heaven/TQA Posted September 2, 2009 Share Posted September 2, 2009 it always was a miracle for me how I can setup pokey timers or so to say IRQs as rasters instead of DLIs? can f.e. Analmux write a small tutorial how I can setup the freq values to use them as DLIs? I am too stupid to understand the clock settings plus cycle things... thanks! Quote Link to comment Share on other sites More sharing options...
PeteD Posted September 2, 2009 Share Posted September 2, 2009 Yeah, a good tutorial on this with some of the info from the NMI/Timers thread would be useful. This is the type of stuff that needs to go in a wiki somewhere. afaik it's like this 15khz timer 1 "count" = 1 line, 64khz around 4 counts = 1 line and the 1.79 timer you should in theory be able to time to any colour clock on the screen. If you just want an equivalent of C64s rasters then the 15khz one is fine. Pete Quote Link to comment Share on other sites More sharing options...
analmux Posted September 2, 2009 Share Posted September 2, 2009 (edited) I'm not 100% sure, and I'd need to do some little tests then. But setting up the timer IRQs involves the following: (suppose we use timer 4) -initialize timer (f.e. start at scanline n) -activate a timer pattern, f.e. at scanline n, n+50, n+100 Initialization is done, not by the timer itself, but by syncing to a display event. Therefore, at start of 'game' (or other action), we'd need to do init code ONE TIME....f.e. antic 4 screen, n=42, then do DLI at top-line, and do 2 (or 3) wsyncs. Then we are on the desired scanline. Now we do initialize IRQ timer. The next timer IRQ is on line n+50, thus (n+50)-n = 50, subtract 1 = 49, store into $D206 (AUDF4) Then do pokey init (LDA 0 STA $D20F LDA 3 STA $D20F), and then a countdown timer reset (STA $D209 (="STIMER")). Redefine timer4 IRQ vector ...wait for next interrupt... again 49 into $D206, pokey init, countdown timer init, redefine timer4 vector ...wait for next interrupt... now we need to 'close the circle'. scanline n+100+212 (=n+312) is the same as scanline n, but then 1 frame later. store 211 into $D206, etc. (And we must not forget to activate timer IRQ somewhere, which means bit 2 of IRQEN ($D20E) must be put to 1) Edited September 2, 2009 by analmux Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 2, 2009 Author Share Posted September 2, 2009 15khz reminds me somehow of my amiga monitor 1084? Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 2, 2009 Author Share Posted September 2, 2009 I'm not 100% sure, and I'd need to do some little tests then. But setting up the timer IRQs involves the following: (suppose we use timer 4) -initialize timer (f.e. start at scanline n) -activate a timer pattern, f.e. at scanline n, n+50, n+100 Initialization is done, not by the timer itself, but by syncing to a display event. Therefore, at start of 'game' (or other action), we'd need to do init code ONE TIME....f.e. antic 4 screen, n=42, then do DLI at top-line, and do 2 (or 3) wsyncs. Then we are on the desired scanline. Now we do initialize IRQ timer. The next timer IRQ is on line n+50, thus (n+50)-n = 50, subtract 1 = 49, store into $D206 (AUDF4) Then do pokey init (LDA 0 STA $D20F LDA 3 STA $D20F), and then a countdown timer reset (STA $D209 (="STIMER")). Redefine timer4 IRQ vector ...wait for next interrupt... again 49 into $D206, pokey init, countdown timer init, redefine timer4 vector ...wait for next interrupt... now we need to 'close the circle'. scanline n+100+212 (=n+312) is the same as scanline n, but then 1 frame later. store 211 into $D206, etc. (And we must not forget to activate timer IRQ somewhere, which means bit 2 of IRQEN ($D20E) must be put to 1) ok. understood... but a real life example would be usefull... I am completly new to all the setting IRQs up with pokey.... that's why I am stucked with the speech samples in Gridrunner... oops... that should be kept as a suprise... Quote Link to comment Share on other sites More sharing options...
atariksi Posted September 3, 2009 Share Posted September 3, 2009 Yeah, a good tutorial on this with some of the info from the NMI/Timers thread would be useful. This is the type of stuff that needs to go in a wiki somewhere. afaik it's like this 15khz timer 1 "count" = 1 line, 64khz around 4 counts = 1 line and the 1.79 timer you should in theory be able to time to any colour clock on the screen. If you just want an equivalent of C64s rasters then the 15khz one is fine. Pete Mostly right. However, 4 counts at 64Khz doesn't give one scanline. It's 1789790Hz, 1789790/114 (15Khz), and 1789790/28 (64Khz). So 28*4 = 112 not 114 which is number of CPU cycles per scanline. Quote Link to comment Share on other sites More sharing options...
NRV Posted September 3, 2009 Share Posted September 3, 2009 To analmux.. one question In the "other" thread you said that "Maybe the most flexible way to do this is to use timer4 (the other timers: timer1 & timer 2 might be needed for more flexible pokey features for the music). Then clocking pokey at 15khz, channel 1&3 can be individually clocked. Then we'd have sawtooth wave if needed, or distortion 2 @ 1.79mhz to have high notes in tune.".. I prefer to use a timer in channel one, clocked at 1.79mhz, then you can have almost the same options, but with access to the 64khz clock (for voices 2, 3 and 4). With your option you can have 2 channels clocked at 1.79mhz, but I don't know what is better from a "music" standpoint.. what do you think? To PeteD.. yeah, you cannot use the timer channel for music because you need the AUDF register to set the timer value.. but if that frequency value is useful to your music composition maybe you can use it . You can change the volume and the distortion of the channel.. and you can play samples with that channel (because that uses only the volume part). One example, that I know works in real hardware and in the last Altirra emulator (1.3pre10, posted somewhere in this forum), from project-M: using the 15khz, timer 4.. // start disabling IRQs sei lda #0 sta IRQEN // I dont use the OS code, so I hijack the IRQ vector lda #<IRQ1_address sta IRQH_VECTOR lda #>IRQ1_address sta IRQH_VECTOR+1 // 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 After that, you need some code to sync the start of the IRQ to a specific horizontal position (you need to do this only once in your game). In my case I wanted to sync to a point near the start of the line. There is jitter here! your entry point is not the same every time. You can only be sure that you are starting BEFORE a given position. This code isn't necessarily the optimal one and maybe is doing some unnecessary things.. Also this thing is syncing to an odd or even scan line (I don't remember which), because I'm doing one IRQ every 2 scan lines. If you want one IRQ every scan line, or every 3 or 4, or another value, you may need to change this code. // 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 lda #0 sta SKCTL :10 nop // dummy cycles.. add more or less to start at a different x position in the line lda 0 lda #3 sta SKCTL lda #1 // just need to be different than 0 sta STIMER cli // enable IRQ's But we still need to enable IRQEN with the number of the timer that we are going to use (1, 2 or 4). I do that on a DLI at the start of the screen with just: lda #4 sta IRQEN and the last IRQ in the chain in that frame does: lda #0 sta IRQEN to disable the IRQ's.. The general IRQ code does something like this: IRQ1_address sta m_irqSaveA // reset the timer lda #0 sta IRQEN lda #4 sta IRQEN // IRQ code.. // exit lda m_irqSaveA rti Anyway I think that the way to go is the 1.79mhz timer (only in channel 1), specially if you need to sync to different horizontal positions, in different scan lines.. Hope that helps Quote Link to comment Share on other sites More sharing options...
atariksi Posted September 3, 2009 Share Posted September 3, 2009 To analmux.. one question In the "other" thread you said that "Maybe the most flexible way to do this is to use timer4 (the other timers: timer1 & timer 2 might be needed for more flexible pokey features for the music). Then clocking pokey at 15khz, channel 1&3 can be individually clocked. Then we'd have sawtooth wave if needed, or distortion 2 @ 1.79mhz to have high notes in tune.".. I prefer to use a timer in channel one, clocked at 1.79mhz, then you can have almost the same options, but with access to the 64khz clock (for voices 2, 3 and 4). With your option you can have 2 channels clocked at 1.79mhz, but I don't know what is better from a "music" standpoint.. what do you think? To PeteD.. yeah, you cannot use the timer channel for music because you need the AUDF register to set the timer value.. but if that frequency value is useful to your music composition maybe you can use it . You can change the volume and the distortion of the channel.. and you can play samples with that channel (because that uses only the volume part). One example, that I know works in real hardware and in the last Altirra emulator (1.3pre10, posted somewhere in this forum), from project-M: using the 15khz, timer 4.. // start disabling IRQs sei lda #0 sta IRQEN // I dont use the OS code, so I hijack the IRQ vector lda #<IRQ1_address sta IRQH_VECTOR lda #>IRQ1_address sta IRQH_VECTOR+1 // 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 After that, you need some code to sync the start of the IRQ to a specific horizontal position (you need to do this only once in your game). In my case I wanted to sync to a point near the start of the line. There is jitter here! your entry point is not the same every time. You can only be sure that you are starting BEFORE a given position. This code isn't necessarily the optimal one and maybe is doing some unnecessary things.. Also this thing is syncing to an odd or even scan line (I don't remember which), because I'm doing one IRQ every 2 scan lines. If you want one IRQ every scan line, or every 3 or 4, or another value, you may need to change this code. // 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 lda #0 sta SKCTL :10 nop // dummy cycles.. add more or less to start at a different x position in the line lda 0 lda #3 sta SKCTL lda #1 // just need to be different than 0 sta STIMER cli // enable IRQ's But we still need to enable IRQEN with the number of the timer that we are going to use (1, 2 or 4). I do that on a DLI at the start of the screen with just: lda #4 sta IRQEN and the last IRQ in the chain in that frame does: lda #0 sta IRQEN to disable the IRQ's.. The general IRQ code does something like this: IRQ1_address sta m_irqSaveA // reset the timer lda #0 sta IRQEN lda #4 sta IRQEN // IRQ code.. // exit lda m_irqSaveA rti Anyway I think that the way to go is the 1.79mhz timer (only in channel 1), specially if you need to sync to different horizontal positions, in different scan lines.. Hope that helps I think you made it more complex than it is. You don't need to keep enabling IRQ. You only have to enable it once. STA STIMER will reset the counter not enabling/disabling IRQEN. You are actually acknowledging IRQ in the interrupt service routine so that another IRQ occurs, but the counting has already reset and begun counting as it's a periodic interrupt. You can prove that by moving around the acknowledgement code within the IRQ and use 1.79Mhz timer and you will see that number of cycles to IRQ remains constant... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 3, 2009 Author Share Posted September 3, 2009 thx NRV helps... will go through the code and maybe one of missing knowledge is gone then... btw. in some of the famous c= hacking issues theer is enough code snippets how to avoid the the jitter with 6502 code... esp. on vic-20 or c64 where you don't have a wsync register. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 3, 2009 Share Posted September 3, 2009 For Project M, I wouldn't worry about jitter... it only means you have an indeterminate delay from 0 to 6 cycles, that equates to all of 3 character positions. In most cases, especially Narrow-screen mode, you can easily cope with that. Quote Link to comment Share on other sites More sharing options...
analmux Posted September 3, 2009 Share Posted September 3, 2009 To analmux.. one question In the "other" thread you said that "Maybe the most flexible way to do this is to use timer4 (the other timers: timer1 & timer 2 might be needed for more flexible pokey features for the music). Then clocking pokey at 15khz, channel 1&3 can be individually clocked. Then we'd have sawtooth wave if needed, or distortion 2 @ 1.79mhz to have high notes in tune.".. I prefer to use a timer in channel one, clocked at 1.79mhz, then you can have almost the same options, but with access to the 64khz clock (for voices 2, 3 and 4). With your option you can have 2 channels clocked at 1.79mhz, but I don't know what is better from a "music" standpoint.. what do you think? If you want to include a tune written in 64khz mode, then the 1.79mhz clock is the best solution. Then you must use timer 1. Only thing is: timer 1(&3) is needed for sawtooth waveform, so no sawtooth instruments then. (By accident I'm writing a new RMT hack (#4) which supports sawtooth + dist.2@1.79mhz in 64khz mode ). Note: sawtooth needs ch.1 AND 3 (both channels occupied, no chance for IRQ), dist2@1.79mhz needs 1 OR 3. When 1 is occupied by IRQ, then 3 is still free. On the other hand, if you change your mind, and go using 15khz mode tunes, then you can choose any timer (1,2 or 4) you like. Then I'd do timer 4. But, from a music standpoint: 64khz mode is best for 'highpitched' tunes. The tuning of the higher notes are just acceptible. If real basses are needed (instead of the genC/E basses), then we'd need 15khz mode. Then dist2@1.79mhz setting can give 2 channels with in-tune high notes. Quote Link to comment Share on other sites More sharing options...
ivop Posted September 3, 2009 Share Posted September 3, 2009 Something I have been wondering lately (but were too lazy to check the schematics yet ) is whether a dual-pokey upgrade also doubles the timers? i.e. is the /IRQ line connected? Quote Link to comment Share on other sites More sharing options...
Bryan Posted September 3, 2009 Share Posted September 3, 2009 (edited) Something I have been wondering lately (but were too lazy to check the schematics yet ) is whether a dual-pokey upgrade also doubles the timers? i.e. is the /IRQ line connected? So far, the practice has been NOT to connect the IRQ lines together. In fact, some stereo software won't work properly if you do. Perhaps the lack of IRQ response is used to detect the 2nd Pokey in some cases. This seems like a shame to me, since it's easy to disable all IRQ's from the 2nd Pokey but still leave them available to use. Edited September 3, 2009 by Bryan Quote Link to comment Share on other sites More sharing options...
ivop Posted September 3, 2009 Share Posted September 3, 2009 So far, the practice has been NOT to connect the IRQ lines together. In fact, some stereo software won't work properly if you do. Perhaps the lack of IRQ response is used to detect the 2nd Pokey in some cases. This seems like a shame to me, since it's easy to disable all IRQ's from the 2nd Pokey but still leave them available to use. That's a pity. It would be great to have three extra timers for something I have in mind. Perhaps future upgrades could have a hardware switch for old (not connected) and new (connected) mode operation. Quote Link to comment Share on other sites More sharing options...
atariksi Posted September 4, 2009 Share Posted September 4, 2009 So far, the practice has been NOT to connect the IRQ lines together. In fact, some stereo software won't work properly if you do. Perhaps the lack of IRQ response is used to detect the 2nd Pokey in some cases. This seems like a shame to me, since it's easy to disable all IRQ's from the 2nd Pokey but still leave them available to use. That's a pity. It would be great to have three extra timers for something I have in mind. Perhaps future upgrades could have a hardware switch for old (not connected) and new (connected) mode operation. One of the reasons I never upgraded to dual/quad POKEY although you can use the timer IRQs in the first POKEY and use the other POKEYs for the sound channels. However, I am more into timing stuff so I had to employ more of a software solution and have my PC interface cable to trigger off Proceed/Interrupt lines on the SIO to generate the extra timer interrupts. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 29, 2014 Author Share Posted September 29, 2014 bump.... anybody has a complete ready to assemble example? Quote Link to comment Share on other sites More sharing options...
Xuel Posted September 29, 2014 Share Posted September 29, 2014 I just gave it a shot. irqsplits.xex (Source on github). I left sound enabled so you can see how the sound channel signal toggles correspond to IRQ frame locations when you pull up the Altirra audio monitor. 1 Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 30, 2014 Author Share Posted September 30, 2014 thx.... first I thought that on the left corner is a raster split too less coffe Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 30, 2014 Share Posted September 30, 2014 The downside to Timer IRQs is the "scanline-friendly" method requires using 16 KHz mode, which affects all voices if not otherwise forced to 1.79 MHz mode. 16 KHz gives the handy 114 divisor rather than 28 in normal 64 KHz mode. Example - I had those ones I posted years ago, probably before anyone was using them commonly. No idea where it is now. The other downside to Timers is the duration available. If you do the maths, in 16 or 64 KHz mode you can't cover the entire screen, you need multiple instances to keep in sync. Possibly the best usage might be to have a DLI first. Use voice 3, put it in 1.79 MHz mode with AUDF3=00. Wait a short time to ensure the divisor has counted down then set back to 64 KHz mode and do the maths to work out what AUDF value is needed. The other thing is that under emulation your results will vary - modern Altirra and probably Atari800 versions should be pretty spot on, Atari800Win+ is only scanline accurate. Quote Link to comment Share on other sites More sharing options...
phaeron Posted September 30, 2014 Share Posted September 30, 2014 Atari800 3.1.0 appears to still be scanline-based for IRQs -- just tested it with the Cup of Tea demo. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 30, 2014 Author Share Posted September 30, 2014 is Atari only machine where timer IRQs affect sound? does the c64 have additional PIA chips to handle that? Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 30, 2014 Share Posted September 30, 2014 C64, hardware timers are by the CIAs, raster IRQ by VIC. SID has no part in such stuff, in fact the machine will operate otherwise normally without one even present. Most other computers, the sound hardware plays little part in the remainder - although sound chip in use by ST, BBC, Spectrum etc does have general purpose IO bits. 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.