Raster split and $9002

Basic and Machine Language

Moderator: Moderators

mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.
avg.png
User avatar
tokra
Vic 20 Scientist
Posts: 1123
Joined: Tue Apr 27, 2010 5:32 pm
Location: Scheessel, Germany

Re: Raster split and $9002

Post by tokra »

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.
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.

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()
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:
24-0.png
lower 3 bits
24-3.png
middle 3 bits
24-6.png
upper 3 bits
24.png
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

mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.
The address is (vm+1)/2, not vm/2.

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.
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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)
00001.png
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Raster split and $9002

Post by Mike »

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:
  • 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.
mathop, this should be in line with your explanations. I wrote a similar round-up concerning tokra's 104x256 FLI mode quite some ago, see here: viewtopic.php?t=7225&start=11&hilit=off ... ny+effects, and also here: viewtopic.php?t=8733&start=16&hilit=offset

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 ...
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.
even_counter.jpg
even_counter.jpg (28.08 KiB) Viewed 734 times
odd_counter.jpg
odd_counter.jpg (17.34 KiB) Viewed 734 times
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.
carry.jpg
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.
User avatar
Wilson
Vic 20 Enthusiast
Posts: 190
Joined: Mon Sep 28, 2009 7:19 am
Location: Brooklyn, NY

Re: Raster split and $9002

Post by Wilson »

Really interesting stuff, mathop! Thanks for all the research and hypothesizing!
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.
hcellcounter1.png
horizontal cell counter
hcellcounter2.png
horizontal cell counter zoomed in

Compare this with the VM counter
vmc1.png
vm counter (bits 0..3 and carry into bit 4)
vmc2.png
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.
User avatar
Wilson
Vic 20 Enthusiast
Posts: 190
Joined: Mon Sep 28, 2009 7:19 am
Location: Brooklyn, NY

Re: Raster split and $9002

Post by Wilson »

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
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

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.
xlatch.png
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
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.
User avatar
beamrider
Vic 20 Scientist
Posts: 1452
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Raster split and $9002

Post by beamrider »

Wilson 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
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 thread :D
User avatar
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

Post by JonBrawn »

mathop wrote: Sun Mar 20, 2022 6:38 amif the display is turned off for one cycle and then immediately turned on again
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
mathop
Vic 20 Amateur
Posts: 40
Joined: Thu Aug 12, 2021 3:13 pm

Re: Raster split and $9002

Post by mathop »

JonBrawn wrote: Wed Oct 05, 2022 7:45 pm
mathop wrote: Sun Mar 20, 2022 6:38 amif the display is turned off for one cycle and then immediately turned on again
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.
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.
Post Reply