| |
Shadow Account closed
Registered: Apr 2002 Posts: 355 |
How can this code work???
I'm using a bit of FPP-code I wrote a while ago. It seems to work like a charm, but now when I look at it, I can't figure out why it is, because if I count correctly, my code per line is 20 cycles, while a badline should be 23, correct?
This means that my code should be badly out of sync after some lines, but somehow it seems to work!
lda #$32
!wait:
cmp $d012
bne !wait-
ldy #$03
!delay:
dey
bne !delay-
.for(var i=0;i<200;i++)
{
lda #$18+[[i+$32]&7]
sta $d011
ldy fpptable+i
lda fpporig,y
sta $d018
nop
}
(both fpptable and fpptable are page-aligned, non-ZP memory locations. I have no sprites enabled) |
|
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Short answer: BA before AEC.
Long answer:
As soon as $D011 gets the right value the VIC puts BA low and waits 3 cycles to use the buses.
These 3 cycles can only be used for WRITING, they have been put for the cpu to end a possibly long rmw instruction (INC, DEC etc..).
In your case the first thing the cpu does (with BA low) is READING next instruction opcode (LDY): this freezes the processor, that's why you 'lose' three more cycles.
This behavior, while sensible (bus accesses must be tidy), is one of the worst nightmares of all c64 coders. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Another maybe more "common sense" answer... If you have a routine that uses 23 cycles to create badlines each line it produces normal FLI with a 3 char bug. If you use more cycles, the bug is moved right, and if you use less it's moved left, "under the border" and the gfx starts stretching.
|
| |
Skate
Registered: Jul 2003 Posts: 494 |
@Cruzer: Nice and clear explanation but I think this part can be confusing for some ppl.
"If you use more cycles, the bug is moved right, and if you use less it's moved left"
You don't mean spending more/less cycles each line, just the beginning of the interrupt, right? Since Shadow was talking about 20 available cycles, this part might be understood incorrectly. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
nah, he means more or less per line. VIC will consume as many cycles are left over, but you need to occupy at least 23 to avoid stretching. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
What Christopher said. That's the nice thing about FLI - it's auto-jittercorrecting. For each cycle extra you use, the VIC will just use one less for badline DMA fetching, and vice-versa. For FPP without a FLI bug it needs 40 for DMA + 3 for waiting, so that's why you only have 64-40-3 = 20 left for the code each line. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
...which should obviously be read as 63-40-3 = 20. It would have been so much nicer if a raster line was actually 64 cycles on the C64. Damnit! :) |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Oops! :) |
| |
Digger
Registered: Mar 2005 Posts: 437 |
Hah, that's why, I was never quite too sure where all these missing cycles were gone... :) |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
Am I the only one finding Freshness79's explaination simple to follow and the "common sense answer" impossible to understand? |
| |
Skate
Registered: Jul 2003 Posts: 494 |
@radiantx: Freshness79's explaination was correct but wasn't the answer why FPP-code works in 20 cycles and not in 23 cycles. he explained why by using 20 cycles we still have the correct timing alignment. Cruzer explained why FPP occurs in less then 23 cycles. So two answers complete each other i guess.
I admit that I usually add/remove a few cycles to catch the effect i'm looking for instead of counting cycles. :) |
... 2 posts hidden. Click here to view all posts.... |
Previous - 1 | 2 - Next |