Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user tubesockor ! (Registered 2024-05-12) You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Most efficient (in cycles) 25Hz music player
2020-07-27 13:27
Frostbyte

Registered: Aug 2003
Posts: 172
Most efficient (in cycles) 25Hz music player

Last night, just for funsies and obviously inspired by the 25Hz music compo, I began wondering what is the fastest way to skip playing every 2nd frame. I came up with this.

First in the music init, I also init a toggle counter on zeropage address $02 to 00:
lda #$00
sta $02

Then, in the music play IRQ, I do this:
....
lda #$ff // 2 cycles - set accu to FF
eor $02 // 3 cycles - XOR with toggle: accu becomes 00 if toggle is FF, FF if 00
sta $02 // 3 cycles - update toggle counter to either FF or 00
bne end_irq // 2 cycles - skip playing if counter is not 00
jsr music.play
end_irq:
....

Of course it'd be much more efficient to use this or some other code to skip the music IRQ completely every 2nd frame, but you guys get the point. :)

This was a beginner's 10 cycle approach to the problem. Any faster solutions?
2020-07-27 14:11
chatGPZ

Registered: Dec 2001
Posts: 11136
A much better approach would be splitting the workload into two (more or less) equal portions that you call alternating. Unless you totally insist on calling the player at 25Hz for whatever reason :)
2020-07-27 14:19
Frostbyte

Registered: Aug 2003
Posts: 172
Quote: A much better approach would be splitting the workload into two (more or less) equal portions that you call alternating. Unless you totally insist on calling the player at 25Hz for whatever reason :)

Sorry I wasn't very clear in what I was after. I was thinking more in the lines of e.g. playing a Goattracker 25Hz tune, i.e. calling the unmodified GT playroutine every second frame. I'm guessing by splitting the workload you mean splitting the work a playrountine itself does? This would require modifying the playroutines of the tunes themselves. I'm just after an easy and fast solution to call e.g. $1003 every other frame. :)
2020-07-27 14:31
Conrad

Registered: Nov 2006
Posts: 833
Another approach? ... (won't work on raster-lines #$00-$7f, but that's not what this is about, right?)
This obviously includes the code for raster compare. Tested in vice monitor.

	lda #$00
	jsr music_init

play:
	lda #$80		<--  bit 7 MUST be set in accumulator, therefore rasterline has to be between #$80 and #$ff
!:	cmp $d012
	bne !-

play_25hz:
	anc #$aa		// 2 cycles / 2 bytes		(#$aa = #%10101010)
	rol play_25hz+1		// 4 cycles / 3 bytes
	bpl play_25hz_skip	// 2 cycles / 2 bytes
	
	jsr music_play

play_25hz_skip:
!:	bit $d012
	bmi !-
	bpl play



EDIT:
With this you could make use of other ANC #$-- bit values to do other things than just play every second frame:

#% 11111111 = Play every frame ("50hz")
#% 10101010 = Play every second frame ("25hz")
#% 10001000 = Play every fourth frame ("12.5hz")
#% 01110111 = "Skip" every fourth frame
#% 01111011 = "Skip" every 1st and 6th (out of 8th) frame :)
#% 10110110 = Experimental, etc. ;)
2020-07-27 23:34
Krill

Registered: Apr 2002
Posts: 2852
Set up a spare CIA timer. Deciding whether to call the player or not should then be just a matter of a CIA register read plus a branch. Bonus points for folding both into a JMP (CIAREG). But then, really... but why. =)
2020-07-27 23:52
Copyfault

Registered: Dec 2001
Posts: 466
Maybe I still didn't get the point, but wouldn't putting the music_play-call in a timer irq that is triggered every 312*63*2 cycles be the shortest way to do it?
2020-07-28 08:08
Oswald

Registered: Apr 2002
Posts: 5025
copyfault wins
2020-07-28 09:23
Krill

Registered: Apr 2002
Posts: 2852
Quoting Jojeli
or some other code to skip the music IRQ completely every 2nd frame, but you guys get the point. :)
Oswald didn't get the point. But i'm not sure anyone besides Jojeli did.
2020-07-28 09:33
Oswald

Registered: Apr 2002
Posts: 5025
he doesnt excludes irq :) his example happens in an irq in fact.
2020-07-28 12:23
Frostbyte

Registered: Aug 2003
Posts: 172
Apologies, even though the context of my question was very clear in my head, I completely failed to communicate that in my initial post. :)

So, in my head, the scenario is to play a 25Hz Goattracker (or some other tracker) tune in e.g. a demo. I was thinking of using a raster interrupt mainly because I haven't done any CIA timer based players, in fact as a n00b it didn't even cross my mind. Given this scenario, and the fact that I was using a raster interrupt which usually triggers 50 times per second, I wanted to come up with some piece of code that skips the jump to the music playroutine (or bypasses the music player IRQ completely) every second execution, with the least overhead compared to the 50Hz "jsr $1003 every time" player.

So in my example, the code is used to skip every 2nd jump to the playroutine within the player IRQ. I guess it could also be used in a previous IRQ to choose which IRQ gets executed next (that being either player IRQ, or the IRQ that comes after the player IRQ), but I'm guessing the overhead of the deciding/branching code itself would still be the same.

Anyway, a CIA timer IRQ (or just reading the CIA register in a raster IRQ, as Krill probably suggested? Some of this stuff goes already above my noob head...) seems like the least cycle-consuming way to get something done 25 times per second.

Sorry for this messy ramble... I know it is quite a pointless coding exercise anyway, given the benefits of maybe saving a few cycles per frame, but I just like this kind of tinkering. :) I was also inspired by the previous discussion about shortest code for stable raster timer setup, albeit a) it was perhaps a more useful coding exercise, and b) I admit I didn't understand half of it.
2020-07-28 12:56
Oswald

Registered: Apr 2002
Posts: 5025
its quite simple you can tell CIA to generate an interrupt at every xth cpu cycle, evey xth can be a 16 bit number, you can read in the manuals how exactly this have to be done.
 
... 10 posts hidden. Click here to view all posts....
 
Previous - 1 | 2 - 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
Apollyon/ALD
Harry/Alivers
Dave/SIDNIFY
kbs/Pht/Lxt
tubesockor
Asphodel
El Jefe/Slackers
trident
Sentinel/Excess/TREX
Robocop/Atlantis
rambo/Therapy/ Resou..
grennouille
rtiainen
DeMOSic/HF^MS^BCC^LSD
q0w/ATL
CopAss/Leader
Isildur/Samar
serato/Finnish Gold
Guests online: 168
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 Layers  (9.6)
4 Cubic Dream  (9.6)
5 Copper Booze  (9.5)
6 TRSAC, Gabber & Pebe..  (9.5)
7 Rainbow Connection  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Booze Design  (9.3)
3 Nostalgia  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Organizers
1 Burglar  (9.9)
2 Sixx  (9.8)
3 hedning  (9.7)
4 Irata  (9.7)
5 MWS  (9.6)

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