VIA Timers

You need an actual VIC.

Moderator: Moderators

dave18
Vic 20 Newbie
Posts: 7
Joined: Mon Sep 05, 2011 1:38 pm

VIA Timers

Post by dave18 »

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
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Post by tlr »

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!
dave18
Vic 20 Newbie
Posts: 7
Joined: Mon Sep 05, 2011 1:38 pm

Post by dave18 »

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
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Post by tlr »

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/
User avatar
e5frog
Vic 20 Nerd
Posts: 551
Joined: Sat Feb 17, 2007 5:46 pm
Website: http://channelf.se
Location: Sweden
Occupation: Service Engineer

Post by e5frog »

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
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

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.

Image
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

Look at figure 9 of this:
http://archive.6502.org/datasheets/synertek_sy6522.pdf

showing the count values.
dave18
Vic 20 Newbie
Posts: 7
Joined: Mon Sep 05, 2011 1:38 pm

Post by dave18 »

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
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

No, in continuous mode, if the latch value is 1, it will go 0001 0000 FFFF 0001 etc...
The interrupt will be raised in the middle of the FFFF cycle on the rising edge.

In one shot mode, it will continue to count 0001 0000 FFFF FFFE etc...
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

$9125 is the T1 counter high byte. If the timer is set to continuous it would be rare for it to catch the timer when it hit $FF. So it seems to be a strange bit of code. Maybe it's trying to sync the code to the timer. But the game itself doesn't look like it needs to do anything fancy like that.
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

I notice the bit of code your looking at doesn't get executed until you start moving left and right, and at that point the latch is set to $FF89, which would mean that code would work if it executed within the $89 cycle window. (or the $FFFF overflow window)
dave18
Vic 20 Newbie
Posts: 7
Joined: Mon Sep 05, 2011 1:38 pm

Post by dave18 »

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
User avatar
e5frog
Vic 20 Nerd
Posts: 551
Joined: Sat Feb 17, 2007 5:46 pm
Website: http://channelf.se
Location: Sweden
Occupation: Service Engineer

Post by e5frog »

Maybe looking at the source code of VICE would help.
My other interest: http://channelf.se
dave18
Vic 20 Newbie
Posts: 7
Joined: Mon Sep 05, 2011 1:38 pm

Post by dave18 »

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
matsondawson
The Most Noble Order of Denial
Posts: 343
Joined: Fri May 01, 2009 4:44 pm

Post by matsondawson »

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