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 > Free cycles in raster line..
2005-09-16 11:32
Ben
Account closed

Registered: Feb 2003
Posts: 163
Free cycles in raster line..


Is there some sort of stable, line dense raster leaving some cycles per line free which can then be filled with instructions executed outside the IRQ?
2005-09-16 13:53
WVL

Registered: Mar 2002
Posts: 902
you can make an nmi that you trigger each 63 cycles maybe.. then you have to take care of turning the nmi's on/off by yourself though (or you have to make 200 separate nmi's ;)

for some examples, look at some nmi sample players.
2005-09-16 15:39
yago

Registered: May 2002
Posts: 333
Some hints when using nmis for rasters:
nmis should be turned on with stable irq
only use accumulator inside nmi-routine

so that only

pha
;some routine
pla
rti

is neccesary.

To turn the nmis off, a normal raster-irq is sufficient.

And to spare some additional cycles, ROM should be turned off.

2005-09-16 16:02
WVL

Registered: Mar 2002
Posts: 902
Quote: Some hints when using nmis for rasters:
nmis should be turned on with stable irq
only use accumulator inside nmi-routine

so that only

pha
;some routine
pla
rti

is neccesary.

To turn the nmis off, a normal raster-irq is sufficient.

And to spare some additional cycles, ROM should be turned off.



and yago is wasting cycles immediately! ;)

better not to use pha/pla, that costs you 7 cycles! rather put the code in the 0page, and do

sta loada
;some routine
loada=*+1
lda #$00
rti

which is only 5 cycles for saving & restoring the accumulator.. 2 cycles profit of the max 63 available. You can buy me a beer at PS.

cycles, my precioussssss
2005-09-16 16:05
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: and yago is wasting cycles immediately! ;)

better not to use pha/pla, that costs you 7 cycles! rather put the code in the 0page, and do

sta loada
;some routine
loada=*+1
lda #$00
rti

which is only 5 cycles for saving & restoring the accumulator.. 2 cycles profit of the max 63 available. You can buy me a beer at PS.

cycles, my precioussssss


Since beer is for free at PS, I will just go and fetch you one then :)
2005-09-16 17:22
tlr

Registered: Sep 2003
Posts: 1790
Quote: you can make an nmi that you trigger each 63 cycles maybe.. then you have to take care of turning the nmi's on/off by yourself though (or you have to make 200 separate nmi's ;)

for some examples, look at some nmi sample players.


We did this in 6566+. There is an interrupt on each raster line, even though we decided on colors that doesn't change at every line.
It won't be more stable than within roughly 7 cycles depending on what code you run in the background, but it will always stay around the desired point.
If you want it on the exact same cycle every time you will have to waste cycles to take up the jitter every interrupt.
2005-09-16 18:33
yago

Registered: May 2002
Posts: 333
Marko Makela described this Technique in C=Hacking #10.

http://www.ffd2.com/fridge/chacking/

@WVL: OK, I'll give you a Karlsquell.
2005-09-16 19:35
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: We did this in 6566+. There is an interrupt on each raster line, even though we decided on colors that doesn't change at every line.
It won't be more stable than within roughly 7 cycles depending on what code you run in the background, but it will always stay around the desired point.
If you want it on the exact same cycle every time you will have to waste cycles to take up the jitter every interrupt.


I see you are using:

thing pha
lda $dd0d
inc foo+1
foo lda $0800
sta $d021
sta $d020
pla
rti

You however seem to destroy the initialization of the interrupts on purpose :)

I reckon you do something like
lda #<thing
ldx #>thing
sta $0316
stx $0317
to launch the NMI

7 cycles jitter is quite a blow.. is there any mechanism allowing one to stabilize the raster in any fashion, e.g. to appropriate the routine for open sideborder?
2005-09-16 19:37
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: Marko Makela described this Technique in C=Hacking #10.

http://www.ffd2.com/fridge/chacking/

@WVL: OK, I'll give you a Karlsquell.


Nice magazine :) Thanks for the link!
2005-09-16 20:11
tlr

Registered: Sep 2003
Posts: 1790
Quote: I see you are using:

thing pha
lda $dd0d
inc foo+1
foo lda $0800
sta $d021
sta $d020
pla
rti

You however seem to destroy the initialization of the interrupts on purpose :)

I reckon you do something like
lda #<thing
ldx #>thing
sta $0316
stx $0317
to launch the NMI

7 cycles jitter is quite a blow.. is there any mechanism allowing one to stabilize the raster in any fashion, e.g. to appropriate the routine for open sideborder?


We thought we were the first doing full screen rasters with sprites over them + music running, so we wanted to set the competition back a bit. ;) (also I was 14 years old)

The over writing is done when starting the code, but ironically I forgot the packed version at $8000. :P
Note that Rob Hubbards Zoolook was manually relocated to
$090d to get a contiguous block just for show off. :)

BTW: I still haven't found anyone doing this before us, does anyone here know an earlier example of this technique?
2005-09-16 20:37
tlr

Registered: Sep 2003
Posts: 1790
Quote: I see you are using:

thing pha
lda $dd0d
inc foo+1
foo lda $0800
sta $d021
sta $d020
pla
rti

You however seem to destroy the initialization of the interrupts on purpose :)

I reckon you do something like
lda #<thing
ldx #>thing
sta $0316
stx $0317
to launch the NMI

7 cycles jitter is quite a blow.. is there any mechanism allowing one to stabilize the raster in any fashion, e.g. to appropriate the routine for open sideborder?


That should be $0318/$0319, but it would be much better to use $fffa/$fffb.
Also the 7 cycles (or is it 6?) depend on the fact that the longest 6510 instruction is 7 cycles (eg "inc abs,x"). If you restrict which instructions you run, you will get less jitter. If you want it really stable you'll have to use the timer value to compensate, which won't leave many cycles at all for stuff to run in the background.
2005-09-16 21:50
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: That should be $0318/$0319, but it would be much better to use $fffa/$fffb.
Also the 7 cycles (or is it 6?) depend on the fact that the longest 6510 instruction is 7 cycles (eg "inc abs,x"). If you restrict which instructions you run, you will get less jitter. If you want it really stable you'll have to use the timer value to compensate, which won't leave many cycles at all for stuff to run in the background.


Damn.. I meant $0318/19 of course :: blush :: Where have I been with my mind!

Sure, I understand the source of the jitter.. Relying on $dc04/$dc05 would indeed get costly..
2005-09-16 21:58
WVL

Registered: Mar 2002
Posts: 902
also check out Ninja's routine from Real/The dreams+Resource. He wrote an article about it in some magazine. it's for a every-other-line-fli routine though, but you can use the basic ideas for your advantage!
2005-09-17 09:12
tlr

Registered: Sep 2003
Posts: 1790
Quote: Damn.. I meant $0318/19 of course :: blush :: Where have I been with my mind!

Sure, I understand the source of the jitter.. Relying on $dc04/$dc05 would indeed get costly..


Consider this: jmp ($dc04)
Set up one timer in cycle mode (presumably $3e cycles) to execute the jump. You might even be able to put $4c into $dc03 to run it from there.
Set up a separate timer that counts up. This will make the jump go to an address which will be one larger for every cycle you are late into the interrupt. You will have to restart this timer from each interrupt.
You could even try to start the up counting timer in the first raster line, and then layout one routine for each rasterline at addresses spaced $3e bytes appart. That way you wont have to restart the timer.
The penalty will be the jump + the 7-8 cycles of code to take up the jitter.
2005-09-17 09:39
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: Consider this: jmp ($dc04)
Set up one timer in cycle mode (presumably $3e cycles) to execute the jump. You might even be able to put $4c into $dc03 to run it from there.
Set up a separate timer that counts up. This will make the jump go to an address which will be one larger for every cycle you are late into the interrupt. You will have to restart this timer from each interrupt.
You could even try to start the up counting timer in the first raster line, and then layout one routine for each rasterline at addresses spaced $3e bytes appart. That way you wont have to restart the timer.
The penalty will be the jump + the 7-8 cycles of code to take up the jitter.


Sounds like a clever piece of code. I really have to give this some thought :)
2005-09-17 09:44
tlr

Registered: Sep 2003
Posts: 1790
Quote: Sounds like a clever piece of code. I really have to give this some thought :)

I can't seem to find how to make the timer count upwards though, so maybe I mixed something up here. :P I'm pretty sure I saw someone do this using a jmp ($dc04) though.

2005-09-17 09:55
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: I can't seem to find how to make the timer count upwards though, so maybe I mixed something up here. :P I'm pretty sure I saw someone do this using a jmp ($dc04) though.



Will (and if so when) $dc05 be reset?
I reckon that if the code you are executing is dynamic, you'd have to repeat this trick each line (rather than synchronizing it once for the whole raster).


2005-09-17 10:07
tlr

Registered: Sep 2003
Posts: 1790
Quote: Will (and if so when) $dc05 be reset?
I reckon that if the code you are executing is dynamic, you'd have to repeat this trick each line (rather than synchronizing it once for the whole raster).




Or duplicating your code for every rasterline evenly spaced in memory, which I was trying to say above.
But I'm not sure you can make it count upwards.
You could ofcourse do it with just one NMI timer set to cycle mode ($3e), and make a jump to ($dd03). This way you will get to a routine in a separate page depending on how late you are.
$dd03 is the data direction register for the user port, setting it to $00 would be safe because '0' means input.
Putting $4c into $dd02 could work also, but you will mess up stuff with the serial bus.
2005-09-17 10:58
Copyfault

Registered: Dec 2001
Posts: 478
Like Werner said: check out Ninja's 2x2-FLI-Routine in his and Oswalds Demo "Real". Ninja wrote some details about it in VN issue 43. The basic idea is to put $04/$dc in $fffe/$ffff and set timer A to lo=$4c hi=$xx. Then let Timer B trigger the NMI continously, starting with $3e. When the IRQ is called, the CPU reads some jmp $($3e-jitter)xx; now you just have to put 8 different jitter_correction_routines at the appropriate mem_areas. This way you get around the prob that timers do ALWAYS decrease; counting upwards sounds very new to me;)) And, ofcourse, it's the cheapest you can get concerning the "penalty cycles".

Check out VN#43 for details!
2005-09-17 11:06
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: Like Werner said: check out Ninja's 2x2-FLI-Routine in his and Oswalds Demo "Real". Ninja wrote some details about it in VN issue 43. The basic idea is to put $04/$dc in $fffe/$ffff and set timer A to lo=$4c hi=$xx. Then let Timer B trigger the NMI continously, starting with $3e. When the IRQ is called, the CPU reads some jmp $($3e-jitter)xx; now you just have to put 8 different jitter_correction_routines at the appropriate mem_areas. This way you get around the prob that timers do ALWAYS decrease; counting upwards sounds very new to me;)) And, ofcourse, it's the cheapest you can get concerning the "penalty cycles".

Check out VN#43 for details!


Will do! Thanks!
2005-09-17 11:21
tlr

Registered: Sep 2003
Posts: 1790
Quote: Like Werner said: check out Ninja's 2x2-FLI-Routine in his and Oswalds Demo "Real". Ninja wrote some details about it in VN issue 43. The basic idea is to put $04/$dc in $fffe/$ffff and set timer A to lo=$4c hi=$xx. Then let Timer B trigger the NMI continously, starting with $3e. When the IRQ is called, the CPU reads some jmp $($3e-jitter)xx; now you just have to put 8 different jitter_correction_routines at the appropriate mem_areas. This way you get around the prob that timers do ALWAYS decrease; counting upwards sounds very new to me;)) And, ofcourse, it's the cheapest you can get concerning the "penalty cycles".

Check out VN#43 for details!


Putting the jump into $dc04/05 and trigger using timer B was a neat trick. Otherwise basically what I said in my last post.
Timers counting up... sorry for that. :P
It's been a really long time since I messed with this.
2005-09-17 11:23
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: Putting the jump into $dc04/05 and trigger using timer B was a neat trick. Otherwise basically what I said in my last post.
Timers counting up... sorry for that. :P
It's been a really long time since I messed with this.


TLR, thanks for your advice!
2005-09-17 19:00
Krill

Registered: Apr 2002
Posts: 2980
Also consider putting the rti instruction to $dd0c, then jmp $dd0c (the worthless serial shift register) at the end of your nmi handler. Since the cpu fetches at least 2 bytes for _every_ instruction (just that the 2nd byte is dismissed for 1-byte commands), the cpu acks the nmi by this implicit $dd0d read. Saves one (1) cycle comparing to lda $dd0d:rti :D Don't forget to do lda #$bf:and $dd0e:sta $dd0e to set the serial shift reg to input and use it as actual data storage to read and write. This technique is described in http://www.ffd2.com/fridge/chacking/c=hacking7.txt
2005-09-17 23:15
Ben
Account closed

Registered: Feb 2003
Posts: 163
Quote: Also consider putting the rti instruction to $dd0c, then jmp $dd0c (the worthless serial shift register) at the end of your nmi handler. Since the cpu fetches at least 2 bytes for _every_ instruction (just that the 2nd byte is dismissed for 1-byte commands), the cpu acks the nmi by this implicit $dd0d read. Saves one (1) cycle comparing to lda $dd0d:rti :D Don't forget to do lda #$bf:and $dd0e:sta $dd0e to set the serial shift reg to input and use it as actual data storage to read and write. This technique is described in http://www.ffd2.com/fridge/chacking/c=hacking7.txt

Good idea!

(To be frank with you all: I am not working on something at the moment (too busy with other stuff, regretfully), but I am intrigued by the technology.. )
2005-09-18 11:38
WVL

Registered: Mar 2002
Posts: 902
Quote: Also consider putting the rti instruction to $dd0c, then jmp $dd0c (the worthless serial shift register) at the end of your nmi handler. Since the cpu fetches at least 2 bytes for _every_ instruction (just that the 2nd byte is dismissed for 1-byte commands), the cpu acks the nmi by this implicit $dd0d read. Saves one (1) cycle comparing to lda $dd0d:rti :D Don't forget to do lda #$bf:and $dd0e:sta $dd0e to set the serial shift reg to input and use it as actual data storage to read and write. This technique is described in http://www.ffd2.com/fridge/chacking/c=hacking7.txt

hey! I didnt know this one yet :)

have to check if ninja also used this (but i think that's very probable..)
2005-09-18 17:09
Ninja

Registered: Jan 2002
Posts: 411
Well, I know this trick, but I didn't use it in the 2x2-routine. Simply didn't think of it at that time, hehe, you can't remember 'em all, I guess :) Wouldn't save too many cycles anyway, as in most cases the BIT $DD0D is executed before the badline. Still, I think it's worth implementing it.
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
Andy/AEG
Smasher/F4CG
Hydrogen/Glance
leonofsgr/Singular C..
Scrap/Genesis Project
Asphodel
Guests online: 100
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 The Demo Coder  (9.6)
6 Edge of Disgrace  (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 No Listen  (9.7)
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 Fullscreen Graphicians
1 Joe  (9.7)
2 Sulevi  (9.6)
3 The Sarge  (9.6)
4 Veto  (9.6)
5 Facet  (9.6)

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