More VIA decode questions

Modding and Technical Issues

Moderator: Moderators

Post Reply
User avatar
JonBrawn
Vic 20 Devotee
Posts: 296
Joined: Sat Sep 11, 2021 10:47 pm
Website: http://youtube.com/@vicenary
Location: Austin TX USA
Occupation: CPU design engineer

More VIA decode questions

Post by JonBrawn »

In Victor, I've added a set of 16 registers at $9100. These should be in a space that isn't decoded as VIC, VIA1 or VIA2, so I should be able to read and write these 16 locations without any issues.

However, I'm seeing something weird. One of the registers, at $9105, is a command/status register, bit 7 of which is supposed to be a 'busy' bit. In my test code I have a 'wait while busy' loop:

Code: Select all

00007Cr 1                  ; wait for not busy                                                                                                               
00007Cr 1               w2:                                                                                                                                     
00007Cr 1  AD 05 91        lda   GFX+COMMAND                                                                                                                    
00007Fr 1  30 FB           bmi   w2                                                                                                                             
If I comment out the 'bmi', then the program runs extremely quickly (but incorrectly). However, with the 'bmi', it runs excruciatingly slowly. The real thing of note is that the bmi loop synchronizes the code to the jiffy timer, so it completes the 64K iterations in 64K jiffies—exactly 64K jiffies (i.e., about 18 minutes instead of about 4 seconds).

I'm guessing that it somehow interacts with the VIA timer used for jiffies, but I don't see how that can be.

Any ideas anyone? I'm stumped.
Working on FPGA replacement for 6560/6561
https://youtube.com/@vicenary
tlr
Vic 20 Nerd
Posts: 594
Joined: Mon Oct 04, 2004 10:53 am

Re: More VIA decode questions

Post by tlr »

Doesn’t explain it, but may give a clue:
The VIA decoding is very trivially done so CA4 and CA5 are more or less directly selecting VIA1 and VIA2. This means that both can be selected in parallel. As these chip selects are active high this happens at $913x. At $910x none would be selected.

EDIT: maybe the VIC is mirrored at $910x? I don’t remember.
User avatar
Mike
Herr VC
Posts: 5134
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: More VIA decode questions

Post by Mike »

JonBrawn wrote:The real thing of note is that the bmi loop synchronizes the code to the jiffy timer, [...]
Just for my understanding: is that synchronization supposed to be expected behaviour, or do you suspect there is some sort of synchronization, with the jiffy clock in particular, which you think should not happen?
tlr wrote:maybe the VIC is mirrored at $910x?
During SΦ2=1, VIC-I selects itself for all addresses $10xx on the VA bus, which map to $90xx on the CA bus.
User avatar
JonBrawn
Vic 20 Devotee
Posts: 296
Joined: Sat Sep 11, 2021 10:47 pm
Website: http://youtube.com/@vicenary
Location: Austin TX USA
Occupation: CPU design engineer

Re: More VIA decode questions

Post by JonBrawn »

tlr wrote: Thu Jul 04, 2024 2:01 am Maybe the VIC is mirrored at $910x? I don’t remember.
In the real world, the VIC is definitely not mirrored at $910x—otherwise, it would be mirrored all the way from $9100 to $91FF, as it is pretty lazy about decoding the addresses itself. It is possible that Victor's decoding is enabling it on too many addresses, and it would collide with both VIAs, $9110 and $9120, but that wouldn't explain why reading $9105 gives me a value that isn't the one that is in the intended register but one where at least the top bit is synchronized to the jiffy timer.
Mike wrote: Thu Jul 04, 2024 8:05 am
JonBrawn wrote:The real thing of note is that the bmi loop synchronizes the code to the jiffy timer, [...]
Just for my understanding: is that synchronization supposed to be expected behaviour, or do you suspect there is some sort of synchronization, with the jiffy clock in particular, which you think should not happen?
The synchronisation to jiffies is definitely not supposed to happen, and it is very clear from a couple of experiments that it is totally linked - 65536 iterations take 65536 jiffies, 4096 iterations take 4096 jiffies.
Mike wrote:
tlr wrote:maybe the VIC is mirrored at $910x?
During SΦ2=1, VIC-I selects itself for all addresses $10xx on the VA bus, which map to $90xx on the CA bus.
Yes, that is the intended implementation, only the range $9000-$90ff should be responded to by the VIC and only the range $9100-$910F for GFX

I just realized that something else is tightly synchronized to the Jiffy timer—the Jiffy timer interrupt. It's time to break out the logic analyzer and see what's happening.
Last edited by Mike on Thu Jul 04, 2024 1:34 pm, edited 1 time in total.
Reason: quote repaired
Working on FPGA replacement for 6560/6561
https://youtube.com/@vicenary
User avatar
Mike
Herr VC
Posts: 5134
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: More VIA decode questions

Post by Mike »

Edit: Do you use the VIA Timer1 at its nominal rate, or perhaps - because of trying out my stable raster routine - reprogrammed to the same rate as the vertical sync?

Background: on 8-bit CBMs, the jiffy clock is defined to count 1/60s of a second from 00:00:00 to 23:59:59, regardless which TV norm is in use - on the VIC-20 there exist different initialisation values for the VIA #2 Timer1, for PAL or NTSC, in the KERNAL (see $FE3E..$FE45): $4826 for PAL and $4289 for NTSC. As the Timer1 values run from their (latched) init value down to $0000 and(!) $FFFF, the period of Timer1 actually is $4828 (=18472) CPU ticks for PAL and $428B (=17035) CPU ticks for NTSC. Both periods are clearly distinct from their respective number of cycles per display frame, 71x312 = 22152 for PAL; 65x261 = 16965 for NTSC (non-interlaced).

At the nominal CPU clock rate, 1.108405 MHz for PAL, 1.022727 MHz for NTSC, these timer values result in an interrupt frequency of 60.0046 Hz for PAL, 60.0368 Hz for NTSC, neither of which is especially accurate.

Quite a lot of custom IRQ routines (including my stable raster routine) repurpose the VIA #2 Timer1 interrupt for own processing. When these routines also reprogram the Timer1 latch values, they accept the jiffy clock keeps bad time.

(There's also a blunder in the jiffy clock update routine, which results in a day period of 24x60x60x60+1 jiffies, and TI$ shows "240000" for 1/60 of a second)

The above could actually explain why your code is sensitive to bit 7 when it is 'unmasked' as per tlr's explanation below for just one clock cycle: not only might there be a bus conflict, the loop above possibly runs in lock step to the (changed) VIA period.
tlr
Vic 20 Nerd
Posts: 594
Joined: Mon Oct 04, 2004 10:53 am

Re: More VIA decode questions

Post by tlr »

JonBrawn wrote: Thu Jul 04, 2024 10:39 am
tlr wrote: Thu Jul 04, 2024 2:01 am Maybe the VIC is mirrored at $910x? I don’t remember.
In the real world, the VIC is definitely not mirrored at $910x—otherwise, it would be mirrored all the way from $9100 to $91FF, as it is pretty lazy about decoding the addresses itself. It is possible that Victor's decoding is enabling it on too many addresses, and it would collide with both VIAs, $9110 and $9120, but that wouldn't explain why reading $9105 gives me a value that isn't the one that is in the intended register but one where at least the top bit is synchronized to the jiffy timer.
$9115/$9125 would be the MSB of the VIA timer 1 counter. When a timer wraps it will briefly become $ff. Only for a cycle though IIRC. Assuming you have a bus conflict here, the VIA reading 0 could force the bus low depending on how hard you try to drive the signal high. This would be consistent with nothing happening until a jiffy, although I can't explain why such a short $ff would trigger every time.
User avatar
JonBrawn
Vic 20 Devotee
Posts: 296
Joined: Sat Sep 11, 2021 10:47 pm
Website: http://youtube.com/@vicenary
Location: Austin TX USA
Occupation: CPU design engineer

Re: More VIA decode questions

Post by JonBrawn »

That was an interesting voyage of discovery!

Here's what was going on:
The way I had the graphics engine setup was that your write the coordinates for the operation, the colour to use and finally the command to execute into consecutive locations starting at $9100, which isn't decoded by anything other than the graphics engine.

When you write the command, it sets a 'valid' flag, which tells the graphics engine to draw the line or fill the circle or whatever the operation is supposed to be, and off it goes.

However, I got the code for resetting the valid flag wrong; it's supposed to be cleared down when the graphics engine starts processing the command, but I'd got the code wrong so that it would only clear down the command if there were a write to a location in IO0 space (VIC & VIAs) and the command had been picked up.

In the scenario I was seeing, the command would be written then I'd start polling the busy bit waiting for it to be not busy so I could start the next command. All that's happening now are reads, no writes, so the valid bit remains set, and on every fast clock cycle the graphics command gets restarted (because as far as the code is aware there is a new valid command). It spins there forever, until a write occurs to one of the VIAs, that happens every 1/60th of a second - hence the sync to the jiffy clock!

Fix was to add a fast reset to the valid flag from the graphics code. I have no idea what possessed me to put in the 'reset valid on the next write' code.
Working on FPGA replacement for 6560/6561
https://youtube.com/@vicenary
Post Reply