| |
Copyfault
Registered: Dec 2001 Posts: 475 |
Stable Raster via Timer
Maybe some of you advanced coders can help me with the following oddity. I'll keep out the basic routine for stabilizing rasters with the timer method, as it is presumably known to everyone!
If we ignore Illegal Ops for the moment, the max. number of cycles occuring in the main prog is 7 (when executing an indexed RMW). When it comes to the different values the variance can take, there should also be 7 (0 to 6 cycles). I wrote some (working!) routines, but I always end up having 8 different variance values. Of course one can live with it, but I wonder where this 8th state comes from!
If necessary, I'll deliver more details. I'd be really happy to understand this behaviour!
Yours, Copyfault |
|
... 65 posts hidden. Click here to view all posts.... |
| |
Copyfault
Registered: Dec 2001 Posts: 475 |
Yes, Cybernator, this was exactly my thought! Thanks for presenting the details (thought they were clear to everone!).
*If* this is true, we should also get 9 different variance values, because a delay of 10 cycles should occur when the irq is triggered in the second cycle of a branch that _is_ taken _and_ goes over a page! And even worse, if you replace the INC adr,X by some Illegal-indexed-ZP-RMW (e.g. ISB (zp),Y), the delay should be 11 cycles long! I made some fast tests but didn't get any desired variance values... |
| |
HCL
Registered: Feb 2003 Posts: 727 |
You guys are thinking too much ;) |
| |
Cybernator
Registered: Jun 2002 Posts: 154 |
Since my post at CBM-Hackers received no replies, I took the liberty to contact Marko Makela. Here's what he says about the last cycle:
"By last cycle of an instruction, I meant the cycle that precedes the opcode
fetch cycle of the next instruction (which will be executed)."
If you check the table I copy-pasted above (it's completely messed up, take a look at 64doc instead), you'll see that branch instructions fetch the opcode of the next instruction. The first opcode fetch occurs at the 3rd cycle, so cycle 2 is the last one. If an IRQ occurs at cycle 2, there will be 9 cycles delay.
Simple, eh? :) Not really. What if the IRQ occurs at the first cycle? The first opcode of the IRQ should occur right after the branch. But the branch already fetches the opcode of the next instruction, and it increments PC! So the IRQ sequence would store PC+1 (after the opcode of the next instruction). Does this really happen? If so, there must be a way that the CPU remembers that is has already fetched the opcode. But does it really work this way? I'll have to do some experiments.
|
| |
Oswald
Registered: Apr 2002 Posts: 5086 |
copyfault: nope, this is taken from the routine without sprites :) Im doubt wether starting the timer earlier will work, but it really sounds as a good solution :) |
| |
Cybernator
Registered: Jun 2002 Posts: 154 |
Talked to Andreas Boose and he kindly explained the feature. I decided to upload his message on my site, because copy-pasting here would mess the graphs.
www.geocities.com/lazeristoski/cpu.html
After you have read his message, let's continue :)
About the "branch not allowing IRQ even if it occurred at cycle 1" thingy... I think it's not correct, as this would produce 9-cycle jitter with Copyfault's loop. I'm discussing this right now.
As you can see, it's correct that if IRQ occurs at cycle 2 of the branch, the following instruction will also be executed. This totally explains the 8-cycle jitter (and I guess this only happens with branch instructions). Now for the other feature (about the IRQ after fetching the opcode): obviously the IRQ occurs before this, ie. it blocks the last cycle of the branch (because branch really takes 3, 4 or 5 cycles, according to 64doc).
But I have another explanation about this: the opcode fetch of the last cycle of the branch is really part of the next instruction, but the branch is finishing its operation here (due to pipelining). Similar with 'eor #$nn', this instruction really needs 3 cycles, but due to pipelining it effectively takes 2 cycles.
This also explains why Copyfault couldn't produce 10-cycle jitter. :)
|
| |
Copyfault
Registered: Dec 2001 Posts: 475 |
I felt like putting some final words on this thread;)
Ok, I still wonder why Graham did never have 8 different timer values, but there are eight states. Like Cybernator stated in his last posts, this has something to do with the way a branch_instruction is carried out: normally an IRQ_Condition can be acknowledged while an instruction is being executed. But there are socalled "Opcode_fetch"-cycles which won't allow ack'ing! Let's simplify things and say these opcode_fetches are always done on the first cycle of each instruction - then ofcourse we will only get 7 different timer value, corresponding to 0-6 cycles variance, or 1-7 cycles delay resp. But if the IRQ_Condition occurs on the second cycle of a taken branch that does not cross a page, there will be no ACK in the third cycle of the branch instruction as it also is an "opcode_fetch"-cycle. In this rare case we will get a delay of 1 cycle (coming from this 3rd branch_cycle) _plus_ n cycles from the following opcode! If the following instruction is an indexed RMW, this gives us a delay of 1+7=8 cycles, explaining the 8th state I was always wondering about;))
Cybernator and me coded some fast routines to proof this. The progs allow to let the RASIRQ_condition occur on a selected cycle of our main_code. If you're interested in these programs, then just drop me a privat line here, ok?
A big thank to everyone here - you all helped to push things forward! Above all, I definatly have to thank Cybernator for all his activities and his motivation to find an answer to my question! Keep up the good work, guys! |
| |
White Flame
Registered: Sep 2002 Posts: 136 |
Regarding the differences in CIAs, could you guys run this program if you get a sec?
http://www.white-flame.com/cyclesperframe.prg
I get 17094 for my NTSC C128, and VICE's PAL mode gives 19655. I'm curious to see what the numbers would be with an older 6526; I'm guessing they'd be one less? The number reported is the CIA timer value that synchronizes with the screen refresh. |
| |
Fungus
Registered: Sep 2002 Posts: 680 |
This is all very interesting...
I get 9 cycles depending on if something is crossing a page boundary or not.
Also, I think ive experienced this irq on bxx bug, as I had a raster routine here somewhere which crashes for no reason, and the PC is way off...
Ill have a look.
|
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
FYI, I also get 8 different delays using copyfault's main loop.
After reading this thread I got inspired and also wanted to try to stabalize rasters using double timers since they have quite nice properties. I'm however a bit confused. How come the raster is stable at the exact the same spot on the screen every time I run the code. Shouldn't this be pretty random or has this something to do with VICE (since I autolaunch the code as fast as possible)?
As a follow up question, what method should I use to always be certain that the raster is stable on the exact same position on the screen each time run the code? My first idea was to use double rasters for the first time to lock the exact spot on the screen then use the timers but this seems a bit overkill.
What do you guys think / how do you usually do it?
For example in those 4x4 modes, what is the preferred method to use the timers here? (not that I like 4x4 modes, but hey...) =) |
| |
Cybernator
Registered: Jun 2002 Posts: 154 |
You have to use another method (eg. double IRQ) to sync the timer. It's not overkill as you only sync the timer once.
> For example in those 4x4 modes, what is the preferred
> method to use the timers here?
Preference is a subjective matter.
Whenever you have multiple IRQs close to each other, you might want to use a timer (eg. distorters). As for double timer, I don't know where else I'd use it except for 4x4.
@White Flame: Vice and CCS emulate the old CIA! I'll see what my commies say, asap.
|
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 - Next |