| |
Copyfault
Registered: Dec 2001 Posts: 475 |
Sprite data fetch in sideborder
I'm playing around with sprites in the sideborder. Usually the ypos for a sprite is one less than the rasterline it should actually show up, e.g. if you want to see a sprite in rasterline $33, you have to put $32 in its ypos-reg.
Now if a sprite has xpos >= $164, the sprite display is turned on in the very same line. For sprite 0, this behaviour can be exploited as the sprite data is read in the cycles directly before. This was done e.g. to get 9 sprites in one rasterline.
If we put any other sprite at this position (xpos >= $164), the display will also start immediatly on the same rasterline (not on the following one). But the sprite data that was fetched looks like a [$ff $00 $ff]-pattern.
I found out that the '$00' in the middle comes from the last byte of the active vic bank (ghostbyte) and that it can be changed accordingly.
Still not clear is the origin of the other $ff-bytes. Are they hardwired just like the $ff-bytes the vic reads as vram on fli-lines? Are they coupled to the adress/data bus somehow?
Maybe someone has already examined this and could explain the behaviour. |
|
... 22 posts hidden. Click here to view all posts.... |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
Quote: Quoting tlr...
Those $ff bytes come from whatever is on the internal VIC-II bus at the cycles when the sprite fetch should have occured.
To change the value from the default pulled up state, perform a write (or read) access that generates the desired byte on the internal bus on the right cycles.
Thanks for the hint! I already tried that but I wasn't able to change the bit pattern. Maybe I have to do smth else than senseful placements of "lda #<bitpattern>"???
Placing a value on the internal bus is done by writing or reading a vic-ii register. As there is no dma going on it is possible to do this in the right spot. If you want to do this for both ff's go for a rmw instruction. Having independent arbitrary data for both ff's may prove tricky though.
One use for this is just to hide the upper bogus line even though the border is open. That's how it works in hcl's starion intro remake, intentional or not. Compare between x64 and x64sc.
Edit: arbitrary might be possible by preloading a vic register with the first byte then doing sta <vicreg>,x with the second byte. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Just a curiosity:
what happens if, in the same frame, you use a sprite in a "normal" way, then you try to use as you want in the border?
Still have same $3FFF/$FF pattern (should be tested on RH...)? |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
The pattern should be the same. The VIC-II fetches sprite data but doesn't have the bus. It's still a proper fetch. If there was no fetch happening the line would have been empty as the data from the previous sprite was already shifted out.
If you do a test program, please contribute it for inclusion in the vice test program repository. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Quote: The pattern should be the same. The VIC-II fetches sprite data but doesn't have the bus. It's still a proper fetch. If there was no fetch happening the line would have been empty as the data from the previous sprite was already shifted out.
If you do a test program, please contribute it for inclusion in the vice test program repository.
There is one thing that i can't understand.
The sprite data fetching cycles are "hardwired" in some precise cycles in rasterline.
If vic start display a sprite before these fetching cycle, it should paint data that just he don't have.
It's a strange thing...
Or sprites data fetching mean just set some ram pointers used -just in time- to read and show data where sprite is visualized... |
| |
Copyfault
Registered: Dec 2001 Posts: 475 |
Quoting tlrPlacing a value on the internal bus is done by writing or reading a vic-ii register. As there is no dma going on it is possible to do this in the right spot. If you want to do this for both ff's go for a rmw instruction. Having independent arbitrary data for both ff's may prove tricky though.
One use for this is just to hide the upper bogus line even though the border is open. That's how it works in hcl's starion intro remake, intentional or not. Compare between x64 and x64sc.
Edit: arbitrary might be possible by preloading a vic register with the first byte then doing sta <vicreg>,x with the second byte.
It works just like you said by using a
sta abs,x
where abs must be a vicreg! By correctly placing the read/write-cycles of this command, the first $ff-byte is read from "abs+x (w/o hi-byte correction)" whereas the 2nd $ff-byte is exactly what's written to the adress (content of the accu in this case).
Thanks a lot for helping me understand this vic-behaviour! |
| |
Copyfault
Registered: Dec 2001 Posts: 475 |
Quoting FlaviowebThere is one thing that i can't understand.
The sprite data fetching cycles are "hardwired" in some precise cycles in rasterline.
If vic start display a sprite before these fetching cycle, it should paint data that just he don't have.
It's a strange thing...
Or sprites data fetching mean just set some ram pointers used -just in time- to read and show data where sprite is visualized...
This is what tlr pointed out: the sprite data fetch will be done on the hardwired cycles belongig to that sprite even if display is not active! If we have e.g. sprite3 at xpos=$164, we will see the data that was fetched at cycles 1 and 2 of the very same rasline! But as the sprite dma was not active yet during these fetch cycles, the sprite data buffer for sprite no.3 is filled with the data the vic "sees" during those fetch (half)cycles (e.g. vic-bus-data during 2nd halfcycle of cycle 1 for first buffer byte, ghostbyte for second buffer byte and vic-bus-data during 2nd halfcycle of cycle 2 for third buffer byte).
What a nice gfx chip we have in our machine ;) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11354 |
now make a minimal test program that demonstrates this behaviour pretty please - so we can throw it into the testprograms repository :) |
| |
Oswald
Registered: Apr 2002 Posts: 5086 |
why are you so sure that the "$ff" bytes can be changed? it pretty much looks like the fli bug -> VIC tries to read from unconnected bus lines.
Are we sure that the internal bus is capable of holding earlier data without being connected to memory ? It's not a register but a "mechanism" to R/W the memory, right?
And even if its capable to hold the data, wont the failed memory read (when the cpu has the bus) overwrite it to $ff?
if this would be possible, why noone ever could change the color of the FLI bug?
Not that I know anything about such low levels, just wondering.
have you tried to change that $ff without precise timing? fill all vic bank with one value, all vic registers with another, open sideborders, etc ? it should be possible if the internal bus is capable of holding last read data. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Quoting OswaldAre we sure that the internal bus is capable of holding earlier data without being connected to memory ? It's not a register but a "mechanism" to R/W the memory, right?
If you read my previous post on how to write RAM addresses $00/$01 and then read the values, you can say "yes, bus can hold data."
Quoting Oswaldif this would be possible, why noone ever could change the color of the FLI bug?
May be that no one has seen it from this perspective so far... |
| |
Oswald
Registered: Apr 2002 Posts: 5086 |
I dont agree/understand on how your $00/$01 trick works internally.
Writing: you are using that VIC reads the same byte for a longer period($3fff), think you can do the same inside the valid screen, just make sure VIC reads the byte in the cycle before the bus write... I guess. How would idle read contribute to the effect ? This is just speculation, but I guess on idle read adresses are not set, and the nmos $ff arises as adress, thats the reason. everything else on the bus is normal.
Reading: the cpu has its own read accesses while performing lda $01 ldx $de00, so why should the "unconnected bus line" contain the data from about 4 read cycles before ? what does exactly happen when reading from $de00 ? how does the value from the lda gets preserved on the bus, when there's more read accesses for performing ldx ?
most importantly, from my prvs post: wont the failed memory read (when the cpu has the bus) overwrite the "internal vic bus" to $ff? |
Previous - 1 | 2 | 3 | 4 - Next |