Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Sprite synchronisation
2008-10-06 17:36
Barbarossa

Registered: May 2007
Posts: 31
Sprite synchronisation

I am trying to get a stable raster with the help of sprite timing. I've read the articles in C=hacking about it, but it is not explained in full detail there. That is, when I look at the examples Missing Cycles and TechTech, I don't quite get it.

I've tried the timing of those examples in an emulator. I have found out that when the INC ends within the cycles that BA goes low, the intruction ends exactly after the sprite fetch. This would mean that the interrupt cannot be more off than 3 cycles and we all know that we have to deal with 2-9 cycles (7 cycles variance). So how can this trick be stable?

If someone could explain this to me (an article about this in Codebase would be really neat) I would be very grateful.

John
2008-10-06 17:44
chatGPZ

Registered: Dec 2001
Posts: 11386
if i recall correctly, put 4 sprites on same Y position, put rasterirq on same position, then do a few INC there and the irq will be magically stable after one line or so :)
2008-10-06 17:55
tlr

Registered: Sep 2003
Posts: 1790
With 8 sprites and INC/DEC or DEC/INC $d016 timed to 46 cycles it will syncronize automatically in a few lines.
This was frequently used to implement sideborder stuff in the early days when double IRQ stable rasters weren't as common.
2008-10-06 17:59
Zaz
Account closed

Registered: Mar 2004
Posts: 33
If you know what kind of instructions will be used when the interrupt triggers, it becomes easier. E.g. if your non-interrupt code does this:
forever:
           jmp forever

the variance should be 0-3 cycles, right?
2008-10-06 18:01
chatGPZ

Registered: Dec 2001
Posts: 11386
with a mainloop like this you dont need a irq in the first place =D
2008-10-06 18:05
Barbarossa

Registered: May 2007
Posts: 31
When I use more sprites or more INC/DEC's I can probably get it to work, but how can the following code from C=hacking work then? It only uses one sprite and one INC.

irq:
lda #$13 // open the bottom border (top border will open too)
sta $d011
nop
bit $11
ldy #111 // reduce for ntsc ?
inc dummy // do the timing with a sprite
bit $ea // wait a bit (add a nop for ntsc)
loop3:
lda tech,y // do the x-shift
sta $d016
...

The raster is stable from loop3.
2008-10-06 18:06
Barbarossa

Registered: May 2007
Posts: 31
Quote: If you know what kind of instructions will be used when the interrupt triggers, it becomes easier. E.g. if your non-interrupt code does this:
forever:
           jmp forever

the variance should be 0-3 cycles, right?


LOL, yeah unfortunately it isn't that simple.
2008-10-06 18:22
Oswald

Registered: Apr 2002
Posts: 5094
try this instead:

http://codebase64.org/doku.php?id=base:double_irq

shortly: the first irq it initiates a 2nd one, while the 1st irq executes nops the 2nd one will hit => only 1 cycle jitter left which is ironed by watching $d012 wether its in the current or the next line.
2008-10-06 18:31
chatGPZ

Registered: Dec 2001
Posts: 11386
somehow i get the impression that he knew that already when he explicitly asked about how to do it with sprites (which indeed can be better in some cases)
2008-10-06 18:31
Danzig

Registered: Jun 2002
Posts: 440
Quote: If you know what kind of instructions will be used when the interrupt triggers, it becomes easier. E.g. if your non-interrupt code does this:
forever:
           jmp forever

the variance should be 0-3 cycles, right?


not to forget the magic "jsr *" resulting in stable raster.
2008-10-06 20:46
JackAsser

Registered: Jun 2002
Posts: 2014
Quote: not to forget the magic "jsr *" resulting in stable raster.

I see a corrupt stack... Please enlighten me. :D
2008-10-06 21:00
Barbarossa

Registered: May 2007
Posts: 31
Quote: try this instead:

http://codebase64.org/doku.php?id=base:double_irq

shortly: the first irq it initiates a 2nd one, while the 1st irq executes nops the 2nd one will hit => only 1 cycle jitter left which is ironed by watching $d012 wether its in the current or the next line.


Oswald,

I already know and understand the double IRQ methode. It is the sprite synchronisation I don't understand.
2008-10-06 21:16
QuasaR

Registered: Dec 2001
Posts: 145
Try this one: http://codebase64.org/doku.php?id=magazines:chacking3#the_demo_..
And no, just one sprite instead of all eight is enough to make the raster stable.
2008-10-06 21:19
chatGPZ

Registered: Dec 2001
Posts: 11386
the theory on how it works is pretty simple... as you probably know sprites steal cycles from the cpu (for details check the vic article). now the basic idea is to execute RMW instructions in the rasterline(s) where said sprites are displayed. the "missing" cycles will force those instructions to get executed in the "gaps" left by the sprites, which in turn will magically stabilize the whole thing. now how many sprites you use and what kind of instructions you execute in what order to stabilize is up to you (there are many ways to make this work).
2008-10-06 22:04
Cybernator

Registered: Jun 2002
Posts: 154
@Barbarossa: As far as I can tell, you know how the method works, but you don't understand how it is possible to achieve this with just a single sprite and a single INC instruction.

This is Pasi Ojala's border routine, no? I think it just happens by accident that the jitter is small. Try scrolling the screen by hold crsr-down for a while and watch that strange flicker in the letters. :)
2008-10-06 22:11
chatGPZ

Registered: Dec 2001
Posts: 11386
yeah with sprites you often get stable behaviour "by accident" ... like tlr said, this was quite common on the old days when coders often didnt quite exactly know what they were doing =)
2008-10-07 00:55
Krill

Registered: Apr 2002
Posts: 2980
I guess the main question here is, is it actually possible to achieve a stable raster within one scanline using only one sprite? I'm skeptical. If so, somebody please explain thoroughly. :)
2008-10-07 05:18
Radiant

Registered: Sep 2004
Posts: 639
Krill: I've done it, but only with deterministic jitter (jmp *). Makes it kinda pointless. :-)
2008-10-07 06:12
Oswald

Registered: Apr 2002
Posts: 5094
hmm maybe it is possible to make faster stabilization with sprites than with cia? :)
2008-10-07 06:49
Radiant

Registered: Sep 2004
Posts: 639
Krill: Of course, if by "within one line" you mean "within the same line as the raster IRQ occurs", then it's impossible (no possible write cycle when BA is low until cycle 59 or something).

Now, if you use timer IRQ's...
2008-10-07 07:52
Barbarossa

Registered: May 2007
Posts: 31
Quote: @Barbarossa: As far as I can tell, you know how the method works, but you don't understand how it is possible to achieve this with just a single sprite and a single INC instruction.

This is Pasi Ojala's border routine, no? I think it just happens by accident that the jitter is small. Try scrolling the screen by hold crsr-down for a while and watch that strange flicker in the letters. :)


Yes, I already noticed that. :-)
But this was on CCS64. I got real sinuses there instead of letters. When I tried it in Vice it was a lot more stable so I blamed the emulator. :-)
I also noticed that the IRQ-entry was always around the same point, which make sense since the only activity in the demo is a blinking cursor. But I thought Pasi would have taken more jitter into account of his routine (I thought it was a universal routine).

@Quasar
I have read that article. My question is based upon it. Although it is clear theoretically. He is not clear in explaining his own program.

So basically it is not possible to get a stable raster with one sprite on one line? You need more than one sprite and several rasterlines.
2008-10-07 08:26
Frantic

Registered: Mar 2003
Posts: 1648
Btw... What IS the *fastest* (and preferablly reasonably generally applicable - with any kind of "main loop" running etc) way of achieving a stable interrupt?

Is it to use a Timer and JMP/branch depending on the value of the timer? Are there other methods which are faster? No?
2008-10-07 08:36
Krill

Registered: Apr 2002
Posts: 2980
Oswald: I don't think so, because that one sprite alone already eats at least 3*21 cycles - if you can use it for your actual raster routine, it may pay off though.. maybe :) But as groepaz already said, with a mainloop like jmp * irq's are pretty much nonsense.

Radiantx: Only if it's a raster irq. Different if it's a timer irq firing somewhere in the middle of a rasterline.

Frantic: According to my experience, the fastest way is a raster irq, followed by an indirect jump through one of the timer registers, with 8 differently timed routines to branch to.
2008-10-07 09:03
Oswald

Registered: Apr 2002
Posts: 5094
well, what if someone would write a code which makes sure to only use max 4 cycle long instructions :) just a funny idea ;)
2008-10-07 09:05
Radiant

Registered: Sep 2004
Posts: 639
Krill: Yeah, as I hinted at. :-) But it's a dead end really.
2008-10-07 09:27
Cruzer

Registered: Dec 2001
Posts: 1048
Wonder what's the fastest (least cycle-consuming) way of getting a stable raster, if you don't have anything to do outside the IRQ (i.e. the jmp * scenario) and there's no use for any sprites that might be used for stabilizing it.

Also, I don't get all the talk about IRQ's being useless if you're jmping to * outside. Wouldn't you have to do cmp $d012 then, which leaves you in a more jittering condition than a raster IRQ with a jmp *, which if I recall correctly will jitter 0-2 cycles.
2008-10-07 09:31
Ninja

Registered: Jan 2002
Posts: 411
@Krill: Why indirect? Direct is faster, no?

@Oswald: Instead of limiting to 4 cycles, better generate parts, which have constant timing per frame :) (wasn't S:T Lars Meeting III - Invite something like it, Jackie?)
2008-10-07 10:21
JackAsser

Registered: Jun 2002
Posts: 2014
Quote: @Krill: Why indirect? Direct is faster, no?

@Oswald: Instead of limiting to 4 cycles, better generate parts, which have constant timing per frame :) (wasn't S:T Lars Meeting III - Invite something like it, Jackie?)


Direct is ofcourse faster but require code in IO-space, ofcourse totally ok.

S:T Lars Meeting III - Invite did not use constant timing per frame... (how else could I have music?!? =D)

However, the 4x4 speed code had constant timing per 4x4-pixel and thus was multiplexable with the raster code to remove the sideborder.

I still used a timer to sync the cpu to the raster beam each frame.
2008-10-07 12:10
chatGPZ

Registered: Dec 2001
Posts: 11386
Quote:
Also, I don't get all the talk about IRQ's being useless if you're jmping to * outside. Wouldn't you have to do cmp $d012 then, which leaves you in a more jittering condition than a raster IRQ with a jmp *, which if I recall correctly will jitter 0-2 cycles.


yes, but a) when irq is switched off everything becomes a lot more predictable b) the cycles which would be spent in the irq overhead can be used for another compare that removes the jitter :)
2008-10-07 17:30
Danzig

Registered: Jun 2002
Posts: 440
Quote: I see a corrupt stack... Please enlighten me. :D

just take a look at the intro from one year crest... i was expecting corrupt stack aswell *G* i tried the trick myself years ago and it worked...
EDIT: iirc not very stable solution at all!
2008-10-07 19:06
Ninja

Registered: Jan 2002
Posts: 411
Jackie: That qualifies as "something like it" in my terms :) If you have to get a stable raster just once per frame, then you can spare a dozen cycles on that.
2008-10-07 20:20
Krill

Registered: Apr 2002
Posts: 2980
Ninja: Yes of course, totally forgot that in the morning haze :)
2008-12-11 08:04
Devia

Registered: Oct 2004
Posts: 401
Perfect sync with only one sprite is impossible. There're only 3 write cycles to do it with and only 1 instruction using 3 consecutive writes: BRK.
So it would seem that you can only account for a maximum of 2 cycles of jitter using 1 sprite, unless you do some NMI trickery, then maybe 3 cycles.
The fact that it works in various IRQ cases is due to the nature of the code being interrupted.

Perfect sync seems possible using 3 sprites like 3, 6 and 0 as that would give you 9 BA+RDY low cycles in one line.
But even with more sprites it seems pointless, unless you're already utilizing those sprites for something else. Why? because, either you have to keep the sprite on for at least 21 lines or you have to set it up 20 lines before.. So if we're talking interrupts, you'd end up with a double interrupt 20-21 lines apart instead of a "normal" double-irq eating 2 lines. Maybe usefull in cases where you need to do stuff every other line, but then again, use the bloody timers!

In the case of JSR * - this works because JSR is a R/W instruction and because of the badlines. JSR * is executing so fast that it is bound to have one of its 2 writecycles hit the 3 BA+RDY low cycles just before every badline, thus gaining 1-2 cycles. Stack corruption is just an added bonus which is irrelevant in this case.
It's the same as doing INC $xxxx;JMP *-3 or even sta/jmp or the like.. as long as some write cycles hit the BA+RDY low cycles, it's bound to get in sync within 1 or maybe a couple of frames.
- Disable bit 4 of $d011 (DEN) and your magic JSR * stable will become unstable, depending on the length of your interrupt of course, hehe :)
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
morphfrog
Slator/Arsenic/Stone..
Thierry
Guests online: 124
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 X-Mas Demo 2024  (9.5)
7 Dawnfall V1.1  (9.5)
8 Rainbow Connection  (9.5)
9 Onscreen 5k  (9.5)
10 Morph  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Swappers
1 Derbyshire Ram  (10)
2 Jerry  (9.8)
3 Violator  (9.7)
4 Acidchild  (9.7)
5 Cash  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.082 sec.