VIA Timer 1 or Timer 2?
Moderator: Moderators
VIA Timer 1 or Timer 2?
Hi folks,
inspired by Mike's 'TI$ in the border' project, I sought after and found a program based for a generic 6502 chip that uses timer 1 on a 6522 chip to generate an NMI interrupt for an accurate timer.. amazing thing the internet, it seems whatever you want is out there, somewhere..
The program is here, I haven't sought permission to republish it so just a link - it's really easy to convert to the VIC, though as I don't have a real VIC I can't verify what the correct timing should be for the (approx) 1 mhz 6522 on the VIC..
http://www.6502.org/tutorials/interrupts.html
Look under 2.1 for the program.
My question is, on the VIC 20, which timer is better to use? Ie I'm assuming the cassette deck uses one of the timers, as would a serial disk drive, so can someone tell me which timers these particular devices use?
Also, would it even be possible for this wedge to be run while a disk or cassette operation was taking place? Or would the NMI call disrupt data transfer?
I know this is somewhere between a hardware and a software question, but it's really to solve a programming problem I have in trying to generate an alarm clock on the VIC that is accurate and 'uninterruptable' if that makes sense..
Cheers
-G
inspired by Mike's 'TI$ in the border' project, I sought after and found a program based for a generic 6502 chip that uses timer 1 on a 6522 chip to generate an NMI interrupt for an accurate timer.. amazing thing the internet, it seems whatever you want is out there, somewhere..
The program is here, I haven't sought permission to republish it so just a link - it's really easy to convert to the VIC, though as I don't have a real VIC I can't verify what the correct timing should be for the (approx) 1 mhz 6522 on the VIC..
http://www.6502.org/tutorials/interrupts.html
Look under 2.1 for the program.
My question is, on the VIC 20, which timer is better to use? Ie I'm assuming the cassette deck uses one of the timers, as would a serial disk drive, so can someone tell me which timers these particular devices use?
Also, would it even be possible for this wedge to be run while a disk or cassette operation was taking place? Or would the NMI call disrupt data transfer?
I know this is somewhere between a hardware and a software question, but it's really to solve a programming problem I have in trying to generate an alarm clock on the VIC that is accurate and 'uninterruptable' if that makes sense..
Cheers
-G
3^4 is 81.0000001
- Mike
- Herr VC
- Posts: 4839
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
If you're going to use an NMI to update the clock, the only option is VIA 1, which controls the RS 232 interface. Here, timer 1 is shared with tape operation, so you'd stick with timer 2. VIA 2 is connected to the IRQ line, and controls keyboard, cassette, and disc drive.
The most sensible solution would be, to put only the jiffy clock update into the NMI routine. This needs to be called every 1/60's of a second. The corresponding values to put in the timer *are* different for PAL and NTSC machines. As long as you keep the NMI routine short, I don't expect big troubles with tape and/or disc access.
You could then still use my display routine in the IRQ. But you'd: a) skip the original jiffy clock update, and b) instead include the 'check for RUN STOP' code, that I've pointed to in an earlier post.
Greetings,
Michael
The most sensible solution would be, to put only the jiffy clock update into the NMI routine. This needs to be called every 1/60's of a second. The corresponding values to put in the timer *are* different for PAL and NTSC machines. As long as you keep the NMI routine short, I don't expect big troubles with tape and/or disc access.
You could then still use my display routine in the IRQ. But you'd: a) skip the original jiffy clock update, and b) instead include the 'check for RUN STOP' code, that I've pointed to in an earlier post.
Greetings,
Michael
Thanks Michael,
VIA 1 Timer 2 - got it.
So, I assume my wedge just needs to
1) Check the Interrupt Flag Register for the Timer 2 time-out flag
2) If not set, continue to $FEAD
3) If set, increment the clock and then continue to $FEAD
Seems simple enough, now to get the right timing..
I may actually make my own timer independent of the jiffy clock so that it isn't affected by changes to TI$.. good thing about that would be I could put it in a more friendly format, ie 1/60th of a second (or 1/20th of a second I guess in order to reduce NMI calls), and just store those variables on the screen directly to fall within the character codes 48-57.. TOD, effectively, rather than TI$..
Cheers, all good fun..
-Glen
VIA 1 Timer 2 - got it.
So, I assume my wedge just needs to
1) Check the Interrupt Flag Register for the Timer 2 time-out flag
2) If not set, continue to $FEAD
3) If set, increment the clock and then continue to $FEAD
Seems simple enough, now to get the right timing..
I may actually make my own timer independent of the jiffy clock so that it isn't affected by changes to TI$.. good thing about that would be I could put it in a more friendly format, ie 1/60th of a second (or 1/20th of a second I guess in order to reduce NMI calls), and just store those variables on the screen directly to fall within the character codes 48-57.. TOD, effectively, rather than TI$..
Cheers, all good fun..
-Glen
3^4 is 81.0000001
- Kweepa
- Vic 20 Scientist
- Posts: 1315
- Joined: Fri Jan 04, 2008 5:11 pm
- Location: Austin, Texas
- Occupation: Game maker
Hi,
I'm trying to do something similar, with cc65.
As you might guess from the name, I'm attempting to play sounds at 140Hz. Everything seems to work except that the sounds play much slower than I'd expect - it seems more like 50Hz. I tried changing the hi byte to #$b instead of #$1b but it didn't seem to affect the timing.
My first thought is that perhaps cc65's runtime also uses timer 2 for something, but if I don't start the timer in the initialize, I don't get any interrupts from timer 2 at all. I also did a quick search of the cc65 sources and didn't find any references to $9119, VIA1 + 9, or the t2_hi member of __6522.
Please help a confused Kweepa.
I'm trying to do something similar, with cc65.
Code: Select all
.proc playSoundIrq
; check it's from timer 2
lda $911d
and #$20
beq end
; do some stuff here
restartTimer2:
lda #$e6
sta $9118
lda #$1b
sta $9119
end:
jmp $eabf
.endproc
.proc _playSoundInitialize
sei
lda $911b
and #$df ; set timer 2 to one-shot mode
sta $911b
lda #$a0 ; set timer 2 enable
sta $911e
; trigger every 7143=$1BE6 cycles (1000000/140)
lda #$e6
sta $9118
lda #$1b
sta $9119
; insert irq into chain
lda #<playSoundIrq
sta $314
lda #>playSoundIrq
sta $315
cli
rts
.endproc
My first thought is that perhaps cc65's runtime also uses timer 2 for something, but if I don't start the timer in the initialize, I don't get any interrupts from timer 2 at all. I also did a quick search of the cc65 sources and didn't find any references to $9119, VIA1 + 9, or the t2_hi member of __6522.
Please help a confused Kweepa.
- Mike
- Herr VC
- Posts: 4839
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
O.K., more elaborated answer:
The topic of the thread was to do an interrupt, preferably an NMI, that should be independent of the keyscan/jiffy IRQ.
Inthusfar your request of doing a 140 Hz interrupt for your soundplayer fits the topic.
But while your routine sets up timer 2 in VIA #1 correctly, causing an NMI, you're putting your ISR into the standard ($0314) IRQ vector, which of course is still executed at 60 Hz. If you're going to correct that error, don't forget, that the end of your ISR:
... also should jump elsewhere.
The topic of the thread was to do an interrupt, preferably an NMI, that should be independent of the keyscan/jiffy IRQ.
Inthusfar your request of doing a 140 Hz interrupt for your soundplayer fits the topic.
But while your routine sets up timer 2 in VIA #1 correctly, causing an NMI, you're putting your ISR into the standard ($0314) IRQ vector, which of course is still executed at 60 Hz. If you're going to correct that error, don't forget, that the end of your ISR:
Code: Select all
end:
jmp $eabf
Combining two via timers
Hello everyone enjoing retro coding on vic20,
years ago I started coding for fun on speccy48K and C64 and created a sample trackers using 4bit samples at around 20Khz hear frequency. I could collect some experience in ml coding on this different systems, which are from some points of view similar but also very different.
These trackers produces some nice techno beats or similar style direction. Samplesets can be changed, as the bpm too. The looping patterns can be updated in real time, what makes the most of the fun.
Anyway, I thought this time, keeping in mind the limited ressouces of a vic20, accepting the challenge about a new approach. Instead of using real samples one could create maybee similar sounds in realtime, on a stock machine?
So I experimented coding an consulting me online, on denial of course, how it could possible to create soundwaves on the fly, apart from using the vic voices. I must confess that the viznut waveforms sounds pretty nice, but are hard to handle, and are to loud in comparison to $900E waves.
BTW, I found some interessant topics, of course on denial too, which combining with my own ideas an experience, I should be able to realize something to that idea.
So I coded a sort of (beta) tracker, able to create pwm waves through $900E, with dynamic modifications as pulse wide, pulse fx, different volumes per sample, pitch modify, changable note duration....on a stock vic 20 . Sounds like a c64 but not near so bad as sid vicious = good idea but ear piercing :\ .
By playing with the parameters a variety of sounds can be created: pwm tones, analog sounding bass drums or core distorted bass drums, snares, toms, and strange sfx similar sounding like ring modulated, sometimes remembering voices, as again, knowed from the big brother c64.
Back to this topic, of course one is able to change the beat in real time by typing in proper value to patterns, for each sound 10 bytes wide.
Unfortunatelly here is also the limit of this approach, changing parameters involves a change in the duration of a loop from the beat.
So the tempo variates from for example 4/4 to 3/4 or around. It's of course possible to fix the tempo but this takes a while, playing with the parameters. It would be nice not to worry about that.
Currently the routine runs in irq 0314-15, the beat driven by $9124-25. The irq will only be exit, as the by the parameters generates sample, play is done.
This behavoir causes the changes in beat duration.
So my reflections suggested me to think inverse. Instead of driving the output of a sample through an irq, the irq should drive how long cycles the sample have to play, and then "interrupt" acts, as the function suggestes, breaking playback and fetching an new (virtual) sample.
A constant timer interrupt should guarantee this, so no matter which pitch the tone is played, the beat stays even.
My tests to this, using and endless loop of "INC$900F JMP BACK", showed to me that a timer interrupt, even feeded with 9124-25=FFFF, too fast is to play a sample. I was not able to figure out how this could be done slower, because I never thought before about this "inverse" idea of handling irqs.
Here is the question: is it possible to combine two via timers to count, for example to 1 second intervall and then trigger an interrupt to stop the endless loop (sample play) at a regular interval, even again?
Thanx in advance for all you out there and your support
years ago I started coding for fun on speccy48K and C64 and created a sample trackers using 4bit samples at around 20Khz hear frequency. I could collect some experience in ml coding on this different systems, which are from some points of view similar but also very different.
These trackers produces some nice techno beats or similar style direction. Samplesets can be changed, as the bpm too. The looping patterns can be updated in real time, what makes the most of the fun.
Anyway, I thought this time, keeping in mind the limited ressouces of a vic20, accepting the challenge about a new approach. Instead of using real samples one could create maybee similar sounds in realtime, on a stock machine?
So I experimented coding an consulting me online, on denial of course, how it could possible to create soundwaves on the fly, apart from using the vic voices. I must confess that the viznut waveforms sounds pretty nice, but are hard to handle, and are to loud in comparison to $900E waves.
BTW, I found some interessant topics, of course on denial too, which combining with my own ideas an experience, I should be able to realize something to that idea.
So I coded a sort of (beta) tracker, able to create pwm waves through $900E, with dynamic modifications as pulse wide, pulse fx, different volumes per sample, pitch modify, changable note duration....on a stock vic 20 . Sounds like a c64 but not near so bad as sid vicious = good idea but ear piercing :\ .
By playing with the parameters a variety of sounds can be created: pwm tones, analog sounding bass drums or core distorted bass drums, snares, toms, and strange sfx similar sounding like ring modulated, sometimes remembering voices, as again, knowed from the big brother c64.
Back to this topic, of course one is able to change the beat in real time by typing in proper value to patterns, for each sound 10 bytes wide.
Unfortunatelly here is also the limit of this approach, changing parameters involves a change in the duration of a loop from the beat.
So the tempo variates from for example 4/4 to 3/4 or around. It's of course possible to fix the tempo but this takes a while, playing with the parameters. It would be nice not to worry about that.
Currently the routine runs in irq 0314-15, the beat driven by $9124-25. The irq will only be exit, as the by the parameters generates sample, play is done.
This behavoir causes the changes in beat duration.
So my reflections suggested me to think inverse. Instead of driving the output of a sample through an irq, the irq should drive how long cycles the sample have to play, and then "interrupt" acts, as the function suggestes, breaking playback and fetching an new (virtual) sample.
A constant timer interrupt should guarantee this, so no matter which pitch the tone is played, the beat stays even.
My tests to this, using and endless loop of "INC$900F JMP BACK", showed to me that a timer interrupt, even feeded with 9124-25=FFFF, too fast is to play a sample. I was not able to figure out how this could be done slower, because I never thought before about this "inverse" idea of handling irqs.
Here is the question: is it possible to combine two via timers to count, for example to 1 second intervall and then trigger an interrupt to stop the endless loop (sample play) at a regular interval, even again?
Thanx in advance for all you out there and your support
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
-._/classes instead of masses\_.-
- Mike
- Herr VC
- Posts: 4839
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: Combining two via timers
Hi, Noizer!
Unlike the CIAs in the C64, the VIA timers don't provide to concatenate, i.e. for example count underflows of timer #1 with timer #2 (and then, as I suppose you want) let timer #2 make an interrupt on that one's underflow.
One thing you should be wary of: in continuous mode, the timers underflow to $FFFF before they are reloaded from the latches. If you need the longest possible period, you need to load the latches with $FFFE.
That being said, the normal modus operandi for trackers still is to use IRQ with a "slow" timer to advance along the patterns; for samples an NMI is used with enable flags, possibly two buffers with an init, (re-)start and end pointer. That idea is of course taken to the extreme with SID Vicious, which *only* plays a totally synthezised sample from the three emulated SID voices in the NMI, at ~6 kHz, and the IRQ routine executes the patched tracker routine. Whatever time is left for the CPU to run in the foreground - non-IRQ/non-NMI - executes the RNG for the noise waveform.
IMO, SID Vicious does a pretty good job at the whole thing. Filters, etc., are of course beyond reach, but many SID tunes can be played back quite faithfully. So I'd be interested where you'd pinpoint the ear-screeching sounds.
...
Oh, and welcome to Denial! Here's the real deal!
Michael
P.S. feel free to post any relevant executable program from your experiments. Makes it easier for the Programming section to discuss details.
Unlike the CIAs in the C64, the VIA timers don't provide to concatenate, i.e. for example count underflows of timer #1 with timer #2 (and then, as I suppose you want) let timer #2 make an interrupt on that one's underflow.
One thing you should be wary of: in continuous mode, the timers underflow to $FFFF before they are reloaded from the latches. If you need the longest possible period, you need to load the latches with $FFFE.
That being said, the normal modus operandi for trackers still is to use IRQ with a "slow" timer to advance along the patterns; for samples an NMI is used with enable flags, possibly two buffers with an init, (re-)start and end pointer. That idea is of course taken to the extreme with SID Vicious, which *only* plays a totally synthezised sample from the three emulated SID voices in the NMI, at ~6 kHz, and the IRQ routine executes the patched tracker routine. Whatever time is left for the CPU to run in the foreground - non-IRQ/non-NMI - executes the RNG for the noise waveform.
IMO, SID Vicious does a pretty good job at the whole thing. Filters, etc., are of course beyond reach, but many SID tunes can be played back quite faithfully. So I'd be interested where you'd pinpoint the ear-screeching sounds.
...
Oh, and welcome to Denial! Here's the real deal!
Michael
P.S. feel free to post any relevant executable program from your experiments. Makes it easier for the Programming section to discuss details.
Re: VIA Timer 1 or Timer 2?
Hello everybody,
I'm not sure if it is allowed to continue so an old entry like this, but the topic in this blog is similar to my last topic "combining two timers".
Due I'm not that crack, especially with nmi coding, still searching for working examples, I tried to figure out how the code posted here works... but it doesn't work at all.
Shift+comm. seems to toggle case mode, but i don't got a Cursor...
Got Someone an idea why not?
Probably i should post the modified code here in future...
I'm not sure if it is allowed to continue so an old entry like this, but the topic in this blog is similar to my last topic "combining two timers".
Due I'm not that crack, especially with nmi coding, still searching for working examples, I tried to figure out how the code posted here works... but it doesn't work at all.
Shift+comm. seems to toggle case mode, but i don't got a Cursor...
Got Someone an idea why not?
Probably i should post the modified code here in future...
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
-._/classes instead of masses\_.-
- Mike
- Herr VC
- Posts: 4839
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: VIA Timer 1 or Timer 2?
Since you chose to reply in the thread here, I merged the other thread, "combining two timers" into this one here.Noizer wrote:I'm not sure if it is allowed to continue so an old entry like this, but the topic in this blog is similar to my last topic "combining two timers".
Two things to note here: Kweepa's code most probably went its way in experimental state - as you see the thread wasn't followed-up as such there was no real conclusion. No wonders the code doesn't work as is.especially with nmi coding, still searching for working examples, I tried to figure out how the code posted here works...
Second: timer #2 in the VIAs is one-shot only. I was in error suggesting its use here. Simple as that.
...
Nonetheless, you find a working example of an NMI interrupt handler for example with my Paddlescope. The thread over there also features source.
Re: VIA Timer 1 or Timer 2?
OK Mike, thank for your supporting. I'll check for sure your code in the spare time.
So I understood that it's not possible to generate a wide interval irq with vic20.
But what's about some additional hardware which could externally interrupt the sample playing at a constant rate, for example connected to userport?
Probably I'm getting a little out of this topic...
So I understood that it's not possible to generate a wide interval irq with vic20.
But what's about some additional hardware which could externally interrupt the sample playing at a constant rate, for example connected to userport?
Probably I'm getting a little out of this topic...
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
-._/classes instead of masses\_.-