VIA Timers
Moderator: Moderators
VIA Timers
Hi
I'm new here, I'm writing a VIC 20 emulator for ARM platforms and this seems a great place to come for advice.
I'm trying to understand exactly what happens when a free running Timer 1 reaches zero. Currently I have it loading in the latch value and continuing to count down however some programs seem to expect a different implementation:
Skyhawk contains the following code:
203A: LDA $9125
203D: CMP #$FF
203F: BNE $203A
The latch in $9126/$9127 is set to $4289 and the ACR in $912B is set to $40.
This means that as soon as the timer drops below zero the latch value of $4289 is loaded and $9125 never contains $FF.
I can only assume that a real VIA has a delay in loading the latch value and the timer wraps around to $FFFF and counts a bit further before the latch is actually loaded. Either that or I've missed something else quite fundamental.
Grateful for any advice anyone has on this, none of the documentation I can find on the web gives this detail.
Thanks
Dave
I'm new here, I'm writing a VIC 20 emulator for ARM platforms and this seems a great place to come for advice.
I'm trying to understand exactly what happens when a free running Timer 1 reaches zero. Currently I have it loading in the latch value and continuing to count down however some programs seem to expect a different implementation:
Skyhawk contains the following code:
203A: LDA $9125
203D: CMP #$FF
203F: BNE $203A
The latch in $9126/$9127 is set to $4289 and the ACR in $912B is set to $40.
This means that as soon as the timer drops below zero the latch value of $4289 is loaded and $9125 never contains $FF.
I can only assume that a real VIA has a delay in loading the latch value and the timer wraps around to $FFFF and counts a bit further before the latch is actually loaded. Either that or I've missed something else quite fundamental.
Grateful for any advice anyone has on this, none of the documentation I can find on the web gives this detail.
Thanks
Dave
Yes, the timer will go to $ffff before resetting. IIRC that is described in the 6522 datasheet.
For a demonstration try via_wrap2.prg from here: http://vice-emu.svn.sourceforge.net/vie ... /via_wrap/
There are a few more tests in the parent directory. Feel free to contribute!
For a demonstration try via_wrap2.prg from here: http://vice-emu.svn.sourceforge.net/vie ... /via_wrap/
There are a few more tests in the parent directory. Feel free to contribute!
Thanks for the answer, I suspected the timer was wrapping.
I'm still struggling to find information on the timings though. The datasheet at this link http://www.applevault.com/twiki/Main/Mo ... d/6522.pdf says 'However, instead of continuing to decrement from zero after a time-out, the timer automatically transfers the contents of the latch into the counter (16 bits) and continues to decrement from there.' so doesn't mention the wrapping effect.
I've tried delaying the loading of the latches by one opcode so the timer does reach $FFFF but this is not long enough for the program to read the value from $9125. I could keep increasing the delay until things work but I'd rather know what specification to work to.
Are there any links to documents that describe this process, I've googled but not found anything.
Thanks
Dave
I'm still struggling to find information on the timings though. The datasheet at this link http://www.applevault.com/twiki/Main/Mo ... d/6522.pdf says 'However, instead of continuing to decrement from zero after a time-out, the timer automatically transfers the contents of the latch into the counter (16 bits) and continues to decrement from there.' so doesn't mention the wrapping effect.
I've tried delaying the loading of the latches by one opcode so the timer does reach $FFFF but this is not long enough for the program to read the value from $9125. I could keep increasing the delay until things work but I'd rather know what specification to work to.
Are there any links to documents that describe this process, I've googled but not found anything.
Thanks
Dave
There are some documents here: http://www.zimmers.net/anonftp/pub/cbm/ ... /chipdata/
There is some info on the wrapping in page 05 of the sy6522 datasheet. The $ffff is only present for a single 1 MHz cycle as with all other values.
Note that most datasheets do not tell the full story. This is because the datasheet usually tries to explain how the chip was intended to be used, not how it actually turned out. You need to piece together information from different sources.
See also here: http://www.6502.org/documents/datasheets/ specifically http://www.6502.org/documents/datasheets/mos/
There is some info on the wrapping in page 05 of the sy6522 datasheet. The $ffff is only present for a single 1 MHz cycle as with all other values.
Note that most datasheets do not tell the full story. This is because the datasheet usually tries to explain how the chip was intended to be used, not how it actually turned out. You need to piece together information from different sources.
See also here: http://www.6502.org/documents/datasheets/ specifically http://www.6502.org/documents/datasheets/mos/
- e5frog
- Vic 20 Nerd
- Posts: 551
- Joined: Sat Feb 17, 2007 5:46 pm
- Website: http://channelf.se
- Location: Sweden
- Occupation: Service Engineer
I wonder how much software would work if you made an emulator according to how the chips were intended to work instead of how they really work.
My other interest: http://channelf.se
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
I started drawing out how I think it works internally last week, you can view it here.
https://docs.google.com/drawings/d/1l8J ... t?hl=en_US
Basically everything happens internally on a falling edge.
i.e. Dec happens on the clock falling edge that passes zero and makes a carry, the carry is a rising edge hence does nothing on that cycle, but on the next cycle the carry falls which causes a latch. Now as for the interrupt, it does get latched on the clocks rising edge so there must be a bit missing in the diagram.
Edit: Ah crap, you need a google account to view it.
Here's an image for those without google.
https://docs.google.com/drawings/d/1l8J ... t?hl=en_US
Basically everything happens internally on a falling edge.
i.e. Dec happens on the clock falling edge that passes zero and makes a carry, the carry is a rising edge hence does nothing on that cycle, but on the next cycle the carry falls which causes a latch. Now as for the interrupt, it does get latched on the clocks rising edge so there must be a bit missing in the diagram.
Edit: Ah crap, you need a google account to view it.
Here's an image for those without google.
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
Look at figure 9 of this:
http://archive.6502.org/datasheets/synertek_sy6522.pdf
showing the count values.
http://archive.6502.org/datasheets/synertek_sy6522.pdf
showing the count values.
Thanks for all the info. Although I struggle to interpret some of the timing diagrams it appears that in continuous mode it take 6 cycles to write the latches. So even though it only reads $FFFF for 1 cycle it will count down even further before the latches are written, ie it will hit zero and then read:
$FFFF
$FFFE
$FFFD
$FFFC
$FFFB
$FFFA
Latch Value
or would the last value before latch is written be $FFFB if latch is actually written on the sixth cycle after timer hits zero? (or have I misunderstood completely).
Thanks
Dave
$FFFF
$FFFE
$FFFD
$FFFC
$FFFB
$FFFA
Latch Value
or would the last value before latch is written be $FFFB if latch is actually written on the sixth cycle after timer hits zero? (or have I misunderstood completely).
Thanks
Dave
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
If I set a breakpoint at $203A in VICE and load and run Skyhawk the routine is called as soon as refulling is complete. At this point the latch is set to $4826 and this is causing a problem as with the counter only being set to $FFFF for one cycle the routine never gets to read it (obviously not for VICE though!).
edit: Interestingly, once the routine exits for the first time, the latch is still set to $4826 and the counter itself is reading $4822. The instructions executed after LDAing $9125 are:
$203D - CMP #$FF - 2 cycles
$203F - BNE $203A - 2 cycles
so
$4822 + 4 cycles = $4826 suggesting the on a real VIC this routine would manage to read the VIA wrapping to $FFFF for just one cycle.
Once you take off the latch is changed to $FF26 which wouldn't cause a problem.
I'm clearly missing something as, based on the information you've kindly provided, the routine probably should hang if the latch is set to $4826 yet no other emulator seems to have this problem.
Thanks
Dave
edit: Interestingly, once the routine exits for the first time, the latch is still set to $4826 and the counter itself is reading $4822. The instructions executed after LDAing $9125 are:
$203D - CMP #$FF - 2 cycles
$203F - BNE $203A - 2 cycles
so
$4822 + 4 cycles = $4826 suggesting the on a real VIC this routine would manage to read the VIA wrapping to $FFFF for just one cycle.
Once you take off the latch is changed to $FF26 which wouldn't cause a problem.
I'm clearly missing something as, based on the information you've kindly provided, the routine probably should hang if the latch is set to $4826 yet no other emulator seems to have this problem.
Thanks
Dave
- e5frog
- Vic 20 Nerd
- Posts: 551
- Joined: Sat Feb 17, 2007 5:46 pm
- Website: http://channelf.se
- Location: Sweden
- Occupation: Service Engineer
I did look at the VICE source to try and work out how it handled the VIA Timers and embarrassingly I can't find any source related to them. I assumed it would be in the vic20via2.c file in the vic20 sub-directory but couldn't see anything. Also tried the interrupt.c file in the main source directory but couldn't see anything obvious.
Will have a search through the rest of the source when I get time (unless anyone fancies pointing me in the right direction .
Cheers
Dave
Will have a search through the rest of the source when I get time (unless anyone fancies pointing me in the right direction .
Cheers
Dave
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
If this is the case, then there's probably a 1 in 9 chance of catching the FF roll over. The roll over happens about 60 times a second at the $4822 value, so bound to not notice the wait.dave18 wrote:If I set a breakpoint at $203A in VICE and load and run Skyhawk the routine is called as soon as refulling is complete. At this point the latch is set to $4826 and this is causing a problem as with the counter only being set to $FFFF for one cycle the routine never gets to read it (obviously not for VICE though!).
edit: Interestingly, once the routine exits for the first time, the latch is still set to $4826 and the counter itself is reading $4822. The instructions executed after LDAing $9125 are:
$203D - CMP #$FF - 2 cycles
$203F - BNE $203A - 2 cycles
so
$4822 + 4 cycles = $4826 suggesting the on a real VIC this routine would manage to read the VIA wrapping to $FFFF for just one cycle.
Once you take off the latch is changed to $FF26 which wouldn't cause a problem.
I'm clearly missing something as, based on the information you've kindly provided, the routine probably should hang if the latch is set to $4826 yet no other emulator seems to have this problem.
Thanks
Dave