| |
Narciso
Registered: Mar 2019 Posts: 10 |
change player speed externally
Good night, I have a question.
In the goattracker editor, the F0X function is used to set the speed of the music player.
It is possible to change the speed of the goattracker player from an external machine code program. Does anyone know the memory address to alter that parameter
Thank you |
|
| |
Karmic
Registered: Apr 2015 Posts: 66 |
Well, there is no one memory address. You have to dig into the code a bit to find the right one.
Hunt for this snippet:
jsr $xxxx
ldx #$07
jsr $xxxx
ldx #$0e
dec $xxxx,x
beq $xxxx
bpl $xxxx
lda $xxxx,x <- this instruction's operand is the tempo address
sta $xxxx,x
Note that since every channel has its own independent tempo counter, you will need to change that address, as well as the ones +7 and +$e. |
| |
TheRyk
Registered: Mar 2009 Posts: 2244 |
another variant, probably I'm gonna be bashed for it as it's rather the mallet method (German: Holzhammermethode), set a counter to leave out (slow down) or have extra (speed up) JSR $PLAY in every so-and-so-many-eth frame. Thus, you can pitch up/down almost every tune very exactly.
Example
play
jsr $1003; delete if you wanna slow down
dec counter+1
counter
lda #07
bne nothingspecial
lda #$07; whatever value you like
sta counter+1; reset counter for next round of counting
playcounterdependent
jsr $1003; extra call every 7th frame
nothingspecial
Of course pitching up costs double raster time, whereas pitching down grants extra rastertime in frames when nothing is played. |
| |
Zyron
Registered: Jan 2002 Posts: 2381 |
When it comes to using counters I find it really odd to decrease it before reading it, and that routine can be a bit shorter. ;)
jsr $1003
cnt ldx #$07
dex
bne j1
jsr $1003
ldx #$07
j1 stx cnt+1
|
| |
Karmic
Registered: Apr 2015 Posts: 66 |
Keep in mind, the above mentioned method has the potential to sometimes fuck up hard-restart timings..... if you can't find the tempo address or absolutely need sub-frame tempo then it certainly is valid. |
| |
Narciso
Registered: Mar 2019 Posts: 10 |
OK friends. Thanks for the answers. I will try the methods.
regards |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
decreasing can also read it at the same time, plus better on zp, and not destroying any registers while skipping:
dec counter
bne skip
lda #$07
sta counter
jsr $1003
skip |
| |
TheRyk
Registered: Mar 2009 Posts: 2244 |
Zyron wins! :)
I don't think that Karmic's concerns play a practical role apart from very few cases (if at all)
Oswald's got a point and might be right about accu and x/y regs but IF(!) those reg values matter, you normally move them on stack anyway before (PHA TXA PHA TYA PHA) and restore them from stack after (PLA TAY PLA TAX PLA). ZP regs are an option for counters however (be aware not to use ZP regs used by the .SID of course hehe) |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Another obvious type of strategy would be to call the player from a timer interrupt. A timer value of $4cc7 (if I remember correctly) corresponds to "once a frame", so other values than that would play the sid in a different speed. You would have quite precise control over the speed that way, and the calls to the player would be evenly spaced in time (in contrast to the counter method, that sometimes calls the player twice very quickly).
If a timer interrupt like that would be acceptable or not in your context I don't know.. |