Raster split and $9002
Moderator: Moderators
Re: Raster split and $9002
Addendum: the "add $010" bit only afects the second nibble, so e.g. $0F0 will turn into $000, not $100.
This can be seen if you set sx to 36, when VM will increase 32 ($020) times each line.
Then the top of the screen will be repeated further down.
This can be seen if you set sx to 36, when VM will increase 32 ($020) times each line.
Then the top of the screen will be repeated further down.
Re: Raster split and $9002
Excellent analysis! Just playing around with your findings a little to see which portion of the video-RAM gets displayed. This seems to be just VM/2, right?
In your example above for $9000 = 36 and $9002 = 22 (standard) the value for VM goes from $000 to $020 because only 16 (of the 22) chars of 2 cycles each can be displayed before the line ends (or the new line starts), am I correct?
So, VM runs through these values:
$000-$020 (1 lines)
(false carry bit set be $020)
$030-$050 (7 lines)
(the false set carry-bit of $050 i repeated for 6 lines).
$050-$070 (8 lines)
$080-$0a0 (8 lines)
$0b0-$0d0 (8 lines)
$0e0-$000 (8 lines)
$000-$020 (8 lines)
Why doesn't the same thing happen here as at the beginning? Is this because the "false carry" is still set? As I understand it this is only reset once the VM-counter does not end on a 0.
Interesting effect to say the least. Would be interesting to force this by switchting $9002 every second line so this effect is forced/unforced. Also with the method in your second post it is possible to re-display video-RAM-areas later on the screen.
In your example above for $9000 = 36 and $9002 = 22 (standard) the value for VM goes from $000 to $020 because only 16 (of the 22) chars of 2 cycles each can be displayed before the line ends (or the new line starts), am I correct?
So, VM runs through these values:
$000-$020 (1 lines)
(false carry bit set be $020)
$030-$050 (7 lines)
(the false set carry-bit of $050 i repeated for 6 lines).
$050-$070 (8 lines)
$080-$0a0 (8 lines)
$0b0-$0d0 (8 lines)
$0e0-$000 (8 lines)
$000-$020 (8 lines)
Why doesn't the same thing happen here as at the beginning? Is this because the "false carry" is still set? As I understand it this is only reset once the VM-counter does not end on a 0.
Interesting effect to say the least. Would be interesting to force this by switchting $9002 every second line so this effect is forced/unforced. Also with the method in your second post it is possible to re-display video-RAM-areas later on the screen.
Re: Raster split and $9002
One more addendum ; if lower bits 8 of VM are zero, then it gets "increased" (per group of 4) by $110, not $100 as alluded earlier.
This also simplifies things a bit, as demonstrated in the following python script.
This will print the values of the character address in octal of the first column of each line for all possible increments.
I did this in octal, because you can then use this output to use this to verify it on a slightly modified charflow program on a real VIC,
where, instead of displaying characters, you display colors that correspond to the lower 3, middle 3, and upper 3 bits of the (addressable part of the ) address bus, like this: lower 3 bits middle 3 bits upper 3 bits 9 bits of the first column photoshopped together
corresponding part of the python output: (incr=44)
This also simplifies things a bit, as demonstrated in the following python script.
Code: Select all
#!/usr/bin/env python3
def main():
for i in range(68):
incr = 68 - i
print(f"incr={incr}\n")
vb = 0
carry4 = False
carry8 = False
for row in range(23):
for line in range(8):
vm = vb
if carry8:
vm = (vm & 0x0ff) | (((vm & 0xf00) + 0x100) & 0xf00)
if carry4:
vm = (vm & 0xf0f) | (((vm & 0x0f0) + 0x010) & 0x0f0)
a = (vm + 1) >> 1
print(f"{a:04o}")
vm += incr
if line == 7:
vb = vm
carry8 = (vm & 0x0ff) == 0
carry4 = (vm & 0x00f) == 0
print("")
if __name__ == "__main__":
main()
I did this in octal, because you can then use this output to use this to verify it on a slightly modified charflow program on a real VIC,
where, instead of displaying characters, you display colors that correspond to the lower 3, middle 3, and upper 3 bits of the (addressable part of the ) address bus, like this: lower 3 bits middle 3 bits upper 3 bits 9 bits of the first column photoshopped together
corresponding part of the python output: (incr=44)
Code: Select all
0000
0000
0000
0000
0000
0000
0000
0000
0026
0026
0026
0026
0026
0026
0026
0026
0054
0054
0054
0054
0054
0054
0054
0054
0102
0112
0112
0112
0112
0112
0112
0112
0150
0140
0140
0140
0140
0140
0140
0140
0166
0166
0166
0166
0166
0166
0166
0166
0214
0214
0214
0214
0214
0214
0214
0214
0242
0252
0252
0252
0252
0252
0252
0252
0310
0300
0300
0300
0300
0300
0300
0300
0326
0326
0326
0326
0326
0326
0326
0326
0354
0354
0354
0354
0354
0354
0354
0354
0402
0412
0412
0412
0412
0412
0412
0412
0450
0440
0440
0440
0440
0440
0440
0440
0466
0466
0466
0466
0466
0466
0466
0466
0514
0514
0514
0514
0514
0514
0514
0514
0542
0552
0752
0752
0752
0752
0752
0752
1210
1000
1000
1000
1000
1000
1000
1000
1026
1026
1026
1026
1026
1026
1026
1026
1054
1054
1054
1054
1054
1054
1054
1054
1102
1112
1112
1112
1112
1112
1112
1112
1150
1140
1140
1140
1140
1140
1140
1140
1166
1166
1166
1166
1166
1166
1166
1166
1214
1214
1214
1214
1214
1214
1214
1214
Re: Raster split and $9002
The address is (vm+1)/2, not vm/2.tokra wrote: ↑Sun Feb 27, 2022 6:01 am Excellent analysis! Just playing around with your findings a little to see which portion of the video-RAM gets displayed. This seems to be just VM/2, right?
In your example above for $9000 = 36 and $9002 = 22 (standard) the value for VM goes from $000 to $020 because only 16 (of the 22) chars of 2 cycles each can be displayed before the line ends (or the new line starts), am I correct?
So, VM runs through these values:
$000-$020 (1 lines)
(false carry bit set be $020)
$030-$050 (7 lines)
(the false set carry-bit of $050 i repeated for 6 lines).
$050-$070 (8 lines)
$080-$0a0 (8 lines)
$0b0-$0d0 (8 lines)
$0e0-$000 (8 lines)
$000-$020 (8 lines)
Why doesn't the same thing happen here as at the beginning? Is this because the "false carry" is still set? As I understand it this is only reset once the VM-counter does not end on a 0.
Interesting effect to say the least. Would be interesting to force this by switchting $9002 every second line so this effect is forced/unforced. Also with the method in your second post it is possible to re-display video-RAM-areas later on the screen.
In the "$9000 = 36 and $9002 = 22" case, vb is $000 at the top of the screen, so vm runs from $000 to $020 for one line, then at the end of the line/beginning of the next line the carry is set.
But the carry will be applied to the value of vb as it is transferred into vm, which at this point is still $000. The carry and the "load vb into vm" happen at the same time.
(I'm still trying to figure this out.)
So on the next line vm will run from $010 to $030, not from $030 to $050.
Then at the end of the 8th line the current value of vm is saved in vb (in fact I believe the "save" and "load" and "carry" all happen at the same time, like I said, I'm still figuring this out.)
So now the carry will 'stick' as it were, and at the next line will run from $040 to $060, and continue to do so for the next 7 lines as well.
I believe the sequence in this case goes like this
1 line vb=$000, vm goes from $000 to $020
7 lines vb=$000, $010..$030
8 lines vb=$040, $040..$060
8 lines vb=$060, $070..$090
8 lines vb=$090, $0A0..$0C0
8 lines vb=$0C0, $0D0..$0F0
8 lines vb=$0F0, $000..$020
8 lines vb=$020, $030..$050
8 lines vb=$050, $060..$080
8 lines vb=$080, $090..$0B0
8 lines vb=$0B0, $0C0..$0E0
8 lines vb=$0E0, $0F0..$110
8 lines vb=$110, $120..$140
8 lines vb=$140, $150..$170
8 lines vb=$170, $180..$1A0
8 lines vb=$1A0, $1B0..$1D0
1 line vb=$1D0, $1E0..$200
7 lines vb=$1D0, $2E0..$300 (note that vb/vm was increased by $110, not $100 as I initially thought)
1 line vb=$300, $410..$430
7 lines vb=$300, $310..$330
8 lines $vb=$330, $340..$360
etc.
Re: Raster split and $9002
When sx ($9000) is zero and m ($9002) is 34 or more, an additional bug/feature comes into play. In this case there is an extra vm fetch at X=2 which adds an extra increment to vm on each line. More on this later hopefully. This is also the cause of the odd display you get when sx=0 and m=34 (see picture below)
- Mike
- Herr VC
- Posts: 4870
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: Raster split and $9002
This colouring method with its base-8 encoding is a very good idea!
I had discussed this with tokra quite some time ago. Normal operation of VIC commences as follows:
In a nutshell, what I think happens with an 'overlength line' is this: at one point in the raster, VIC puts both incremented offset and value to reload onto an internal bus, and what gets recognised/stored as new offset (or possibly gets latched) is the wired-AND of both values.
Of course that results in a bewildering mess of possibilities, including a way to 'restart' the screen display from top (the limit of text-lines-to-display still applies, though).
Lance highlighted the function of the offset (or video matrix counter) here: viewtopic.php?t=8733&start=92
Sigh. It would be much easier to understand what really happens, if the die shot explorations would continue ...
I had discussed this with tokra quite some time ago. Normal operation of VIC commences as follows:
- There is a running offset into the text screen, which is incremented after every character fetch,
- Likewise, these is a number of remaining columns to display, which is decremented by 1 after each character access. When this one reaches 0, the right border is displayed and fetches are stopped.
- At the begin of each new text line, the current offset is latched.
- If a raster is not the begin of a new text line, the latched offset is reloaded.
In a nutshell, what I think happens with an 'overlength line' is this: at one point in the raster, VIC puts both incremented offset and value to reload onto an internal bus, and what gets recognised/stored as new offset (or possibly gets latched) is the wired-AND of both values.
Of course that results in a bewildering mess of possibilities, including a way to 'restart' the screen display from top (the limit of text-lines-to-display still applies, though).
Lance highlighted the function of the offset (or video matrix counter) here: viewtopic.php?t=8733&start=92
Sigh. It would be much easier to understand what really happens, if the die shot explorations would continue ...
Re: Raster split and $9002
I think what happens is this. Please excuse the crudeness of the drawings.
The VM counter is a 12-bit counter.
The output of each counter is clocked by phi2.
The output of the counter can then optionally be saved back into a register (if we're on the last line of the character.)
This is governed by the 'save' signal.
The counter can be loaded by the 'load' signal - this happens when x=0
The counter can be stepped by the 'refresh' signal ('ref' in the pictures below). This happens at other times.
Depending on whether the 'carry in' signal is set this will increase the counter (and set a carry out on overflow) or it will do nothing (and clear carry out.)
The save, load and refresh signals are only active when phi2 is low.
Also load and refresh are never active at the same time. This is essential in what follows.
Finally there is a reset signal ('rst' in the pictures) that will reset the register. This is done each field during vsync. Now normally you would expect the carry output from one bit to directly enter the next bit. This is not done however, the carry is only 'carried over' in groups of four bits. So bits vm11..vm8, vm7..vm4 and vm3..vm0 form three four-bit nibbles.
Then the carry out of vm3 is not fed into vm4, and similarly for vm8. Instead there is this circuit. The carries for vm4 and vm8 are clocked by the 'refresh' signal. But this signal is not active when 'load' is also set!
What happens in this case is that the value of the carry input will be the same as it was during the previous clock cycle.
The carry for vm0 is fed directly, so there this problem does not occur.
The result is then that if there was a carry during the last cycle of the previous line (x=70) the carry will persist in the next cycle, and this is where the +$10 or +$110 comes from.
[edit] re the last picture - there should be an inverter between the leftmost NOR-gate and the pass transistor. And vm3 is also inverted obviously.
The VM counter is a 12-bit counter.
The output of each counter is clocked by phi2.
The output of the counter can then optionally be saved back into a register (if we're on the last line of the character.)
This is governed by the 'save' signal.
The counter can be loaded by the 'load' signal - this happens when x=0
The counter can be stepped by the 'refresh' signal ('ref' in the pictures below). This happens at other times.
Depending on whether the 'carry in' signal is set this will increase the counter (and set a carry out on overflow) or it will do nothing (and clear carry out.)
The save, load and refresh signals are only active when phi2 is low.
Also load and refresh are never active at the same time. This is essential in what follows.
Finally there is a reset signal ('rst' in the pictures) that will reset the register. This is done each field during vsync. Now normally you would expect the carry output from one bit to directly enter the next bit. This is not done however, the carry is only 'carried over' in groups of four bits. So bits vm11..vm8, vm7..vm4 and vm3..vm0 form three four-bit nibbles.
Then the carry out of vm3 is not fed into vm4, and similarly for vm8. Instead there is this circuit. The carries for vm4 and vm8 are clocked by the 'refresh' signal. But this signal is not active when 'load' is also set!
What happens in this case is that the value of the carry input will be the same as it was during the previous clock cycle.
The carry for vm0 is fed directly, so there this problem does not occur.
The result is then that if there was a carry during the last cycle of the previous line (x=70) the carry will persist in the next cycle, and this is where the +$10 or +$110 comes from.
[edit] re the last picture - there should be an inverter between the leftmost NOR-gate and the pass transistor. And vm3 is also inverted obviously.
Re: Raster split and $9002
Really interesting stuff, mathop! Thanks for all the research and hypothesizing!
Re: Raster split and $9002
Another interesting find is that there is actually circuitry on the VIC chip that does this multi-nibble carry correctly, even in corner cases.
Take for example the 'horizontal cell counter', that counts down (or up, depending how you look at it) based on the contents of $9002.
This is a 8-bit counter with a 'reset' gate which more or initializes it with values derived from $9002.
It has the same structure as the vm counter, where the carry of the first 4 bits is fed indirectly through a 'refresh' (or 'tick', of whatever you want to call it) pass transistor.
Again 'refresh' and 'reset' are mutually exclusive. But the horizontal cell counter actually has a gate that makes sure that the carry into bit 4 is always on during a reset, which means it won't increment bit 4, since the carry bit is inverted for even cells. horizontal cell counter horizontal cell counter zoomed in
Compare this with the VM counter vm counter (bits 0..3 and carry into bit 4) vm counter zoomed in
Note that the vm counter does not have a gate that sets !carry to one during load, but there is actually room on the chip for such a thing.
Take for example the 'horizontal cell counter', that counts down (or up, depending how you look at it) based on the contents of $9002.
This is a 8-bit counter with a 'reset' gate which more or initializes it with values derived from $9002.
It has the same structure as the vm counter, where the carry of the first 4 bits is fed indirectly through a 'refresh' (or 'tick', of whatever you want to call it) pass transistor.
Again 'refresh' and 'reset' are mutually exclusive. But the horizontal cell counter actually has a gate that makes sure that the carry into bit 4 is always on during a reset, which means it won't increment bit 4, since the carry bit is inverted for even cells. horizontal cell counter horizontal cell counter zoomed in
Compare this with the VM counter vm counter (bits 0..3 and carry into bit 4) vm counter zoomed in
Note that the vm counter does not have a gate that sets !carry to one during load, but there is actually room on the chip for such a thing.
Re: Raster split and $9002
Not sure if this was posted somewhere, but Bill Herd just had a discussion with Albert Charpentier. Super interesting and they talk (a little more abstractly) about the VIC fundamentals.
https://youtu.be/JeGCC2Kgqik
https://youtu.be/JeGCC2Kgqik
Re: Raster split and $9002
The remaining edge case is when sx ($9000) is zero, i.e. the display is moved entirely to the left, and m ($9002) is 34 or greater.
Then there are actually two things going on here. The one about the vm counter getting messed up I explained earlier, this still applies.
But now also another thing happens: if the display is turned off for one cycle and then immediately turned on again, the VIC does an extra memory fetch during the 'phi1' phase when X=2, and also increments vm/hc more than it should have done.
This is due to a bug in the circuit that generates the enable signal for the vm/hc counter.
See the circuit below. This is essentially the same as what was described in
viewtopic.php?f=11&t=8733&start=150#p99007
X denotes the horizontal counter, HC is the 'horizontal cell counter' (that counts down from 2*m).
X and HC are clocked by phi2. The enable signal is denoted by 'out' in the above diagram. (Referred to as 'i_in_matrix' in the post mentioned.)
Now take the situation where sx is zero, and the X latch has been active for the entire line, and only gets reset when X becomes 0.
Then at the next phi2 clock the X latch will get set again, since the x==sx signal would have been fired during the previous cycle.
This causes the following behaviour of the out signal
Here we have an extra 'out' when X=2, which causes an additional increment of hc and vm.
Now if m was 34 on the next line the hc will actually run all the way down to zero before X is reset. So you get this alternating effect, where the odd lines are at the correct position and the even lines are shifted 1 cycle to the left.
If m is 35 or greater, the first line will be correct, but every line following that will be shifted to the left.
Then there are actually two things going on here. The one about the vm counter getting messed up I explained earlier, this still applies.
But now also another thing happens: if the display is turned off for one cycle and then immediately turned on again, the VIC does an extra memory fetch during the 'phi1' phase when X=2, and also increments vm/hc more than it should have done.
This is due to a bug in the circuit that generates the enable signal for the vm/hc counter.
See the circuit below. This is essentially the same as what was described in
viewtopic.php?f=11&t=8733&start=150#p99007
X denotes the horizontal counter, HC is the 'horizontal cell counter' (that counts down from 2*m).
X and HC are clocked by phi2. The enable signal is denoted by 'out' in the above diagram. (Referred to as 'i_in_matrix' in the post mentioned.)
Now take the situation where sx is zero, and the X latch has been active for the entire line, and only gets reset when X becomes 0.
Then at the next phi2 clock the X latch will get set again, since the x==sx signal would have been fired during the previous cycle.
This causes the following behaviour of the out signal
Code: Select all
12121212121 phi
-0011223344 X
10011111111 x latch
11001111111 phi1
11100111111 phi1,phi2
11110011111 phi1,phi2,phi1
11111001111 phi1,phi2,phi1,phi2
11111100111 phi1,phi2,phi1,phi2,phi1
00110011000 !out
^^
bogus
Now if m was 34 on the next line the hc will actually run all the way down to zero before X is reset. So you get this alternating effect, where the odd lines are at the correct position and the even lines are shifted 1 cycle to the left.
If m is 35 or greater, the first line will be correct, but every line following that will be shifted to the left.
Re: Raster split and $9002
Thanks for that, really interesting to hear from the designer of the Vic chip (Albert Charpentier) I never knew who that was before. Perhaps we should direct him to this forum threadWilson wrote: ↑Wed Mar 09, 2022 1:14 pm Not sure if this was posted somewhere, but Bill Herd just had a discussion with Albert Charpentier. Super interesting and they talk (a little more abstractly) about the VIC fundamentals.
https://youtu.be/JeGCC2Kgqik
- JonBrawn
- Vic 20 Devotee
- Posts: 225
- Joined: Sat Sep 11, 2021 10:47 pm
- Website: http://youtube.com/@vicenary
- Location: Austin TX USA
- Occupation: CPU design engineer
Re: Raster split and $9002
What do you mean by "turned off" - there isn't a "turn off the display bit" in the 6560/6561 that I'm aware of.
Working on FPGA replacement for 6560/6561
https://youtube.com/@vicenary
https://youtube.com/@vicenary
Re: Raster split and $9002
Yes, I apologize, that was not the most appropriate description.
I meant that turning off the X latch (see circuit diagram) for 1 cycle only causes an erroneous data fetch, as I hopefully demonstrated.