Thanks for the hard work!
From the context of emulating the VIA in VICE, I will have to try to remember what questions I had a few months ago when I was actively looking the the VIA emulation code. Two things I remember right now:
- When the timer toggles Port B pin 7 (PB7), you write in 16b:
PB7_T1 is the signal which goes into the PB7 output driver when Timer 1 emits a pulse
or a square wave on PB7. //In this case, PB7 = PB7_T1.
It is generated by a toggle flipflop, which is cleared runing a T1H counter write,
set when ACR7=0 (when Timer 1 does not use PB7),
and it toggles during PHI2 after a Timer 1 underflow when the "Timer 1 active" RS flipflop is set.
For this we have actual test cases in VICE, and we model setting this flipflop as "set it when the ACR is written into, and ACR7 changes from 0 to 1".
The test cases we have, pass with this emulation.
Thinking about it for a few seconds, I realise that the emulation isn't even really wrong (just possibly slightly more complicated than needed). If we set the flipflop under this condition, ACR7 WAS 0. But as long as it is 0, it has no visible effect on PB7 yet; that only happens after it gets set to 1. So in practice, the result is correct.
*some time passes while I experiment with a change in VICE*
Unfortunately, the changed VICE does not pass the test in VICE's "testprogs/VIC20/via_pb7" any more.
I'll need to think a bit on this, I guess.
The other thing is about the shift register while shifting IN. I don't think we have any test cases here, so our emulation is a bit uncertain.
For example, I'm unclear about the following scenario:
- the SR is shifting in under external clock (CB1) control
- 8 bits have been shifted in and the SR flag in the IFR is set
- CB1 keeps toggling, trying to clock in more bits, before the CPU reads from the shift register (which would clear the IFR bit).
Does the shift register shift in more data, if the IFR bit is still set?
There are two possibilities but both lead to data loss (which isn't unexpected, if the cpu is too slow).
- yes, more bits shift in, and the first byte is lost
- no, there is no more shifting, and the next byte is lost.
In VICE the shift counter is implemented as a counter from 0 to 16, where 0-15 are "shifting is active" (and even and odd states correspond to different levels of the clock, i.e. for a bit to shift, the counter changes by 2). And 16 is the state where shifting is finished, inactive, etc. And in several cases, there is the matter, "under which conditions do we change from 'finished' (16) to 'shifting' (0)". I'm sure the emulation is wrong in some cases, but with lack of test cases this is hard to check.
That were my musings so far...
Edit: ah, another one: writing to (or reading from) the shift register starts the shift counter. But what if that is done while there is a byte in/output still going on? Does it reset the shift counter to the start again, or not?
Current emulation code mostly wants the shifting to be finished before resetting the counter; but there are some suggestions here and there that this is wrong. But the few tests pass, so maybe they aren't good enough.