| |
Mixer
Registered: Apr 2008 Posts: 460 |
Relocatable music routine
There are plenty of music routines, which can be compiled from source or relocated by self modifying some of the code, but has anyone written a fully relocatable music routine?
Something that you can just load to any address and it'll work.(Obviously the complexity of the player is a factor, but let's say something like GT) |
|
... 15 posts hidden. Click here to view all posts.... |
| |
Stone
Registered: Oct 2006 Posts: 176 |
Maybe I'm missing something here, but ChristopherJam's trick won't really work if you want it to be completely self relocatable since the address operand to the JSR is an absolute address. Loading it to an arbitrary location will just make it crash.
I think Conrad's idea is that by looking at the stack, you find the return address and from that the address operand of the JSR at the call site. I have used this trick myself in the past.
init:
tsx
sec
lda $0101,x
sbc #$01
sta $02
lda $0102,x
sbc #$00
sta $03
ldy #$00
lda ($02),y ; low byte of init
tax
iny
lda ($02),y ; high byte of init
...
|
| |
ChristopherJam
Registered: Aug 2004 Posts: 1423 |
Oops, Stone is right. The target of the JSR itself would be wrong, and my code would crash.
Ok, I'm leaning towards ws's idea of writing an RTS to a set location and JSRing to that now.
You can then read that back with tsx
lda $0101,x
..
lda $0102,x
to get the address of the last byte of your JSR |
| |
Rastah Bar Account closed
Registered: Oct 2012 Posts: 336 |
Another possibility could be using the BRK instruction. |
| |
ws
Registered: Apr 2012 Posts: 251 |
How about putting this snippet to a fixed, known empty location, zp for instance:
$00f8: pla
tay
pla
tax
pha
tya
pha
rts
Result in x and y,
doesnt change stack.
setup: lda #$68
sta $f8
sta $fa
lda #$a8
sta $f9
lda #$aa
sta $fb
lda #$48
sta $fc
sta $fe
lda #$98
sta $fd
lda #$60
sta $ff
jsr $00f8
...
..
.
|
| |
tlr
Registered: Sep 2003 Posts: 1807 |
.org $02
tsx
rts
.org $xxxx
jsr $0002
txs
pla
…
pla
… |
| |
tlr
Registered: Sep 2003 Posts: 1807 |
…or if you consider the setup code, this is shorter: .org $xxxx
lda #$60
sta $02
jsr $0002
tsx
inx
inx
txs
pla
…
pla
… If you are ok with being naughty the jsr may be directed to a carefully selected rts in ROM, getting rid of the setup completely. |
| |
Flavioweb
Registered: Nov 2011 Posts: 466 |
.> c000 20 41 e0 jsr $e041
.> c003 bd 01 01 lda $0101,x
.> c006 8d 00 c1 sta $c100
.> c009 bd 02 01 lda $0102,x
.> c00c 8d 01 c1 sta $c101
.> c00f 60 rts Assuming that kernal is enabled, in $C100 we will have the return address -1. |
| |
Mixer
Registered: Apr 2008 Posts: 460 |
Then we must avoid jsr or jmp in the routine or they must be self modified on the fly with some offset value, as all the pointers to data. No wonder that the more modern processors have address registers and so forth. |
| |
tlr
Registered: Sep 2003 Posts: 1807 |
Quoting Flavioweb.> c000 20 41 e0 jsr $e041
.> c003 bd 01 01 lda $0101,x
.> c006 8d 00 c1 sta $c100
.> c009 bd 02 01 lda $0102,x
.> c00c 8d 01 c1 sta $c101
.> c00f 60 rts Assuming that kernal is enabled, in $C100 we will have the return address -1.
Nice, you found a TSX; RTS ! Then you can just apply the trick I posted earlier as: jsr $e041
txs
pla
sta $c100
pla
sta $c101 $E041 is part of BASIC, which is good because that part is hardly ever modified in aftermarket KERNALs. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1423 |
Quoting StoneI think Conrad's idea is that by looking at the stack, you find the return address and from that the address operand of the JSR at the call site. I have used this trick myself in the past.]
This is a little dangerous, as the JSR that pushed a return address onto the stack might not have directly targeted the music routine (for example, it could have gone to an 'update effects/game state' routine that ends with a JMP to the music).
All of the discussions here are of course something of an intellectual exercise - it would be cheaper for whatever code copied the play routine to a new location to also write that address to somewhere accessible by the player code (or even to call a relocate routine within the player code directly, with the new address passed in) |
Previous - 1 | 2 | 3 - Next |