| | JackAsser
Registered: Jun 2002 Posts: 2038 |
Freely moving sprites over a triggered VSP?
The clock slide itself is not a problem since it's outside the sprite DMA area anywas, but we need to kick it off at a well known cycle, regardless of sprite DMA. Is it even possible?
Currently I do a hack by detecting if sprite 0 interfere and adjust appropriately. Double timer won't cut it since the first timer will trigger in the middle of the sprite fetches.
Only idea I have so far is to stabalize before the sprite fetches and the via sprite y-positions perform a series of compares to get a delay value via some table. I did something similar in The Wild Bunch for the sprite multiplexer balls over 4x4-fli, but there I knew the sprites always came in pairs, so the combinations were only 16. |
|
... 34 posts hidden. Click here to view all posts.... |
| | trident
Registered: May 2002 Posts: 101 |
in case someone comes to this forum thread looking for the number of cycles stolen by sprites during the border area, here are the raw bytes from the table as generated by the vic_sprcycles() function:
spritecyclestab:
.byte $00, $05, $05, $07, $05, $09, $07, $09, $05, $0a, $09, $0b, $07, $0b, $09, $0b
.byte $05, $0a, $0a, $0c, $09, $0d, $0b, $0d, $07, $0c, $0b, $0d, $09, $0d, $0b, $0d
.byte $05, $0a, $0a, $0c, $0a, $0e, $0c, $0e, $09, $0e, $0d, $0f, $0b, $0f, $0d, $0f
.byte $07, $0c, $0c, $0e, $0b, $0f, $0d, $0f, $09, $0e, $0d, $0f, $0b, $0f, $0d, $0f
.byte $05, $0a, $0a, $0c, $0a, $0e, $0c, $0e, $0a, $0f, $0e, $10, $0c, $10, $0e, $10
.byte $09, $0e, $0e, $10, $0d, $11, $0f, $11, $0b, $10, $0f, $11, $0d, $11, $0f, $11
.byte $07, $0c, $0c, $0e, $0c, $10, $0e, $10, $0b, $10, $0f, $11, $0d, $11, $0f, $11
.byte $09, $0e, $0e, $10, $0d, $11, $0f, $11, $0b, $10, $0f, $11, $0d, $11, $0f, $11
.byte $05, $0a, $0a, $0c, $0a, $0e, $0c, $0e, $0a, $0f, $0e, $10, $0c, $10, $0e, $10
.byte $0a, $0f, $0f, $11, $0e, $12, $10, $12, $0c, $11, $10, $12, $0e, $12, $10, $12
.byte $09, $0e, $0e, $10, $0e, $12, $10, $12, $0d, $12, $11, $13, $0f, $13, $11, $13
.byte $0b, $10, $10, $12, $0f, $13, $11, $13, $0d, $12, $11, $13, $0f, $13, $11, $13
.byte $07, $0c, $0c, $0e, $0c, $10, $0e, $10, $0c, $11, $10, $12, $0e, $12, $10, $12
.byte $0b, $10, $10, $12, $0f, $13, $11, $13, $0d, $12, $11, $13, $0f, $13, $11, $13
.byte $09, $0e, $0e, $10, $0e, $12, $10, $12, $0d, $12, $11, $13, $0f, $13, $11, $13
.byte $0b, $10, $10, $12, $0f, $13, $11, $13, $0d, $12, $11, $13, $0f, $13, $11, $13
|
| | Oswald
Registered: Apr 2002 Posts: 5127 |
@trident you can not state the nr of stolen cycles so explicitly, as RMW instructions can make the VIC steal less. also you throw in a function like everybody knows it, but probably its done by you ? |
| | JackAsser
Registered: Jun 2002 Posts: 2038 |
Quote: @trident you can not state the nr of stolen cycles so explicitly, as RMW instructions can make the VIC steal less. also you throw in a function like everybody knows it, but probably its done by you ?
In this case we now exactly what the CPU is executing and with such clock-slide we know it's only read cycles.
Also follow the reference link if you're interested in the original author who created this table. |
| | Oswald
Registered: Apr 2002 Posts: 5127 |
Quote: In this case we now exactly what the CPU is executing and with such clock-slide we know it's only read cycles.
Also follow the reference link if you're interested in the original author who created this table.
I see no link, and trident posted this as a general help for others not for "this case". it doesnt help for the beginners if they dont know about the DMA takeover mechanism. He just derailed the topic now we talk about it instead. |
| | JackAsser
Registered: Jun 2002 Posts: 2038 |
Quote: I see no link, and trident posted this as a general help for others not for "this case". it doesnt help for the beginners if they dont know about the DMA takeover mechanism. He just derailed the topic now we talk about it instead.
He's extremely on topic Oswald. :) And the topic to begin with is not for beginners anyway. Feel free to start another topic about how sprite DMA works, for beginners.
https://bumbershootsoft.wordpress.com/2016/02/05/sprites-and-ra.. |
| | Oswald
Registered: Apr 2002 Posts: 5127 |
Quote: He's extremely on topic Oswald. :) And the topic to begin with is not for beginners anyway. Feel free to start another topic about how sprite DMA works, for beginners.
https://bumbershootsoft.wordpress.com/2016/02/05/sprites-and-ra..
thanks and you are right nr of cycles stolen is ontopic. |
| | JackAsser
Registered: Jun 2002 Posts: 2038 |
I landed on a double IRQ/NMI method and then a clock-slide with calculated sprite DMA delay + VSP dma delay.
So I trigger a raster IRQ at the wanted line.
On the line I enable NMIs from timer A on CIA 2. (Running a continuous timed 63-cycle timer).
This will almost immediatly trigger an NMI on the current rasterline, but safely outside sprite fetches (main loop in the raster IRQ runs NOPs here).
Entering the NMI I know there's a 2c jitter so I fetch the current timer value and LSR, so that bit 0 enters the carry, effectively handle that 2c jitter in the clockslide.
Then I add the delay for the sprites (using the same approach as Trident), and add the delay for the VSP and jump into the clockslide to get the correct delay before manipulating $d011.
Profit! |
| | Krill
Registered: Apr 2002 Posts: 3098 |
Sounds complicated, but if it works. :)
How're you going to defeat the VSP bug?
Run it all from cartridge and avoid the dangerzones in RAM? |
| | JackAsser
Registered: Jun 2002 Posts: 2038 |
Quote: Sounds complicated, but if it works. :)
How're you going to defeat the VSP bug?
Run it all from cartridge and avoid the dangerzones in RAM?
I just ignore the VSP-bug tbh and assume people have SRAM-replacements. Most people use EMUs anyway.
But yeah, most of the code runs in ROM, but still, IRQs and stuff are in RAM due to their self-modding nature to safe cycles. Gamestate and shit also. A triggered VSP-bug will most likely kill the game. |
| | Copyfault
Registered: Dec 2001 Posts: 487 |
Hm, maybe I'm missing smth but couldn't you use the timer for the calculation of active sprites on that relevant line?
My thoughts are as follows: you usually have a 63-cycle-timer running, which is used for dejittering and stabilising. Now if we set up an IRQ to fire at the line before the relevant one, we can reach cycle#55 (starting cycle postions count with #1) in stable state. There we put a 19-cyc-sequence, ending with LDA timer, to effectively "bridge" the cycles in which the sprite accesses take place. E.g. we use smth like
nop
nop
nop
nop
nop
nop
nop $ea
lda timer
Now the last R-cycle of the LDA-command will end up at different cycle positions, depending on the no. of active sprites. You can directly use the read value to determine the no. of delay cycles needed for the sprites (by using LDX timer and then read a delay value from a table, or using SBC timer followed by STA bra+1 bra: BNE cycleslide, whatever suits your needs). However, the no. of delay cycles needed for the actual DMA-delay-neutralisation still needs to be added (might be solvable by a cycle slide cascade, in which the second branch-offset is set by the routine in which the DMA-delay at the top of the screen is done).
Another approach (which I couldn't really test, same with the idea above) could be to use the background collsion register. If my quick tests with VICE were correct, the collision register can be used rasterline-wise; so, clearing the collision register and reading it directly after the relevant line (which has to be filled with "invisible" foreground pixels ofc) should give you the active sprites on that line. However, for the delay now a 256-byte-table is needed...
Hope this is not completely off-
Cheers
CF |
Previous - 1 | 2 | 3 | 4 | 5 - Next | |