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: 466
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-08 08:55
Ninja

Registered: Jan 2002
Posts: 404
@Cybernator: Stupid me, of course rasterline $000 has 63 cycles, otherwise my routine with raster-irq and one timer wouldn't work as well. It is just that the IRQ is triggered one cycle later. I should really start thinking before using the keyboard :)
2004-01-08 09:49
Cybernator

Registered: Jun 2002
Posts: 154
The idea is to make the timer have values from 0-7 at the moment when you access it! How do we do that? First I recommend that you write the sync routine. Supposing we are using the one I mentioned above, we have:

(Assume the value is in $dc04)

lda #7
sec
sbc $dc04

The access to $dc04 occurs at the last (4th) cycle of SBC. Now the important thing is to find out where's this cycle in the rasterline. An IRQ condition is given in cycle 1 (with exception to the first rasterline). The processor first needs to finish the current instruction. The smallest nr. of cycles an instruction takes is 2 (eg. NOP). If the IRQ occurs in the first cycle of NOP, there will be 2 cycles delay. If it occurs in the second cycle, there will be 3 cycles delay! So the minimum delay is 2 cycles to finish the current instruction. Then the CPU needs 7 cycles to store the PC and flags to stack and jump to the IRQ routine. So cycle 1 + 2 + 7 = 10. The first possible cycle in which the first instruction of the IRQ will execute is 10.

If there're sprites active, the first possible cycle will happen somewhere later. Let's assume there're 8 sprites active: sprites 0,1,2 are processed at the right border, so they are irrelevant. But the rest of them are. :) I recommend the diagram shown in 'Pal Timing'. You'll see that the CPU is halted until cycle 11. So 10 + 11 = 21 (what a math-dude I am, eh? ;-P)

The first instr. (lda #7) will take cycles 21 and 22. Sec will take 23 and 24. Sbc takes 25, 26, 27 and 28. (or a few cycles later, do to jitter).

Oops! At cycle 28, the timer should have value 7! It's up to you to achieve this. As I mentioned, I noticed delay between the activation of the timer, and the actual countdown.
CCS may be helpful here, unless you really hate MUs. :)

@Ninja: Thinking is better when you have company. :)
2004-01-08 15:55
Copyfault

Registered: Dec 2001
Posts: 466
@Cybernator: Hmmm, I always thought that the max. delay that occurs with a NOP is 1?!? I mean, if the IRQ occurs in the first cycle of the NOP (let's call it c_1), there is one cycle delay and the IRQ starts at c_1 + 2. If it occurs in the second cycle, there is no delay and the IRQ also starts at c_1 + 2 (it can't start earlier as the instruction has to be finished!). So your calculations should be altered by -1 I assume...

I also observed that the timers do not start immediatly after the start instruction(e.g. STA $DC0E). A closer look at the inner workings of the CIA would really be nice...

Another observation: the timers never give value 0 - at least not in continous mode (that's what I've tried so far;))! Instead they give the max.value!So a stabilization routine like

LDA #$07
SEC
SBC $DC04
<appropriate branch>

should not work correctly!
2004-01-08 18:33
Cybernator

Registered: Jun 2002
Posts: 154
If the IRQ occurs in the _last_ cycle of any instruction, the CPU will also execute the next one! So if we have two NOPs in succession, there will be 3 cycles delay if the IRQ occured in the second cycle of the NOP!

As for the routine, it will work if there's 7 cycle variance. But with the 8 cycle variance you have shown, it won't. So yes, make it:

lda #8
sec
sbc $dc04

But the first possible cycle in which $dc04 is accessed, should be when $dc04 = 8.
2004-01-08 23:53
Copyfault

Registered: Dec 2001
Posts: 466
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). But how does an IRQ behave when triggered during a fulfilled branch condition? When does the processor check the condition? Possibly a branch is internally always 2 cycles long, and if the condition is fulfilled, there will be an extracycle which ofcourse cannot be interrupted, too! This way you have a maximal delay of 9 cycles (e.g. LDA #$00 : BEQ *+2 : INC adr,X). But I guess I'm wrong with this assumption - how could I correctly test it?
2004-01-09 01:26
Stryyker

Registered: Dec 2001
Posts: 465
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: 5018
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: 466
@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: 465
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.
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
Frida Katarina
WVL/Xenon
niallquinn
Knut Clausen/SHAPE/F..
hedning/G★P
Grue/Extend
Guests online: 128
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 Memento Mori  (9.6)
10 Bromance  (9.5)
Top onefile Demos
1 It's More Fun to Com..  (9.7)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 TRSAC, Gabber & Pebe..  (9.5)
6 Rainbow Connection  (9.5)
7 Wafer Demo  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Nostalgia  (9.3)
2 Oxyron  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Fullscreen Graphicians
1 Carrion  (9.8)
2 Joe  (9.8)
3 Duce  (9.8)
4 Mirage  (9.7)
5 Facet  (9.7)

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