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 > Stable Raster via Timer
2003-12-28 19:40
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....
 
2004-01-09 01:26
Stryyker

Registered: Dec 2001
Posts: 468
There is something wrong with the NOP behaviour you describe then. The simple double raster interrupt then CMP $d012 relies on there being only 1 cycle jitter and normally padded with 2 cycle opcodes in the first raster interrupt. If you can get 3 cycle delay then how come much double interrupt only has 1 cycle jitter?
2004-01-09 08:12
Oswald

Registered: Apr 2002
Posts: 5086
if anyone is interested, here is how the src I have does fix the jitter:

LDA #$3F
SBC $DC04
AND #$07
STA JUMP+1
JUMP BCS JUMP

LDA #$A9
LDA #$A9
LDA #$A9
LDA $A5EA
NOP
2004-01-09 08:57
Copyfault

Registered: Dec 2001
Posts: 475
@Strykker: when you have a sequence of NOPs, the minimal delay is 2 and the maximal one is 3 (as Cybernator described above). So the jitter (which is difference of them) is 1, and there's no prob with the double irq thingie!

@Oswald: is this your altered version for "stable raster via timer on rasterlines with sprites enabled" ? You can achieve it "easier" (depends on the taste;)) by just starting the (second) timer as many cycles earlier as the sprites eat up! Then the usual sync routine like LDA #$08 : SEC : SBC timer should work...

Also thought about Mager Valp's comment... IF my timer initialization should still have a jitter of one cycle (which is absolutly impossible from my point of view;)), then this wouldn't explain a total of 8 variance values, would it? It would rather lead to 7 values, but the range they lie in would depenend on the jitter of the init routine. As I do get a steady interval, I am still wondering...
2004-01-09 10:43
Cybernator

Registered: Jun 2002
Posts: 154
Copyfault wrote:

> Ok, I see! This does not even contradict the max.of
> 7 different variance values, as you get some delay
> between 2 and 8 cycles(= 7 different states).

I considered this, as I stated in the email.

> But how does an IRQ behave when triggered during a
> fulfilled branch condition?

Never thought about this. Maybe that is the answer to the 8-cycle variance thingy.

Quote from 64doc:
<-->
"To process the
interrupt before the next instruction, the interrupt must occur
before the last cycle of the current instruction."
<-->

Does this make any sense to anyone:
<-->
Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

# address R/W description
--- --------- --- ---------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch operand, increment PC
3 PC R Fetch opcode of next instruction,
If branch is taken, add operand to PCL.
Otherwise increment PC.
4+ PC* R Fetch opcode of next instruction.
Fix PCH. If it did not change, increment PC.
5! PC R Fetch opcode of next instruction,
increment PC.

Notes: The opcode fetch of the next instruction is included to
this diagram for illustration purposes. When determining
real execution times, remember to subtract the last
cycle.

* The high byte of Program Counter (PCH) may be invalid
at this time, i.e. it may be smaller or bigger by $100.

+ If branch is taken, this cycle will be executed.

! If branch occurs to different page, this cycle will be
executed.
<-->

Anyway, the last cycle _may_ refer to the minimum nr. of cycles an opcode can have. (eg. when not taking a branch, or when there's no page-crossing). In that case, this is probably the answer:

inc $c000,x: 1234567
bpl loop : 123

If the IRQ occurs in the 2nd cycle of BPL, there will be 9 cycles delay. On the other hand, if it occurs in the 6th cycle of INC, there will be 2 cycles delay.

Let's count once again: 2, 3, 4, 5, 6, 7, 8, 9... Err... 8-cycle variance! Was this fermenting? :)

Anyway, nothing has been proved yet!
2004-01-09 11:39
Stryyker

Registered: Dec 2001
Posts: 468
You saying if we are currently processing the branch and on the last cycle when the IRQ is triggered then the CPU will do next instruction then perform interrupt? That would explain the 8, 1 for the current cycle and 7 for the inc. Would be nice if C64 address and data lines could be plugged into PC and trace all this.
2004-01-09 12:22
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...
2004-01-09 15:24
HCL

Registered: Feb 2003
Posts: 727
You guys are thinking too much ;)
2004-01-11 15:45
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.
2004-01-12 08:34
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 :)
2004-01-13 13:22
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. :)
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 - Next
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
Rodrigo Yeow../Hokut..
Guests online: 82
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Mojo  (9.6)
6 The Demo Coder  (9.6)
7 What Is The Matrix 2  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 Party Elk 2  (9.6)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.6)
5 Libertongo  (9.5)
6 Rainbow Connection  (9.5)
7 Onscreen 5k  (9.5)
8 Morph  (9.5)
9 Dawnfall V1.1  (9.5)
10 It's More Fun to Com..  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Nostalgia  (9.3)
5 Triad  (9.2)
Top Organizers
1 Burglar  (9.9)
2 Sixx  (9.8)
3 hedning  (9.7)
4 Irata  (9.7)
5 Tim  (9.7)

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