Interrupt routine for Vortex Tracker

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Interrupt routine for Vortex Tracker

Post by sludge »

I'm looking for an interrupt routine for vtplayer that plays the music in the background allows you to turn the music on/off by pressing the M key.

The routine I use at the minute doesnt seem to work with Vortex Trackers vtplayer.

I've changed the CALL 49158 to 49157 which gets it playing but the game constantly crashes.

Music data will be at 40000 and the vtplayer at 49152.

Code: Select all

LD HL, 40000
LD BC, 32765
LD A, 22
OUT (C), A
LD (49153), HL
CALL 49152
LD BC, 32765
LD A, 16
OUT (C), A
LD HL, 46336
LD DE, 46337
LD BC, 256
LD (HL), 182
LDIR
LD A, 195
LD (46774), A
LD HL, 46065
LD (46775), HL
DI
LD A, 181
LD I, A
IM 2
EI
RET
DI
IM 1
EI
JP 46133
NOP
INC B
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
LD A, (46063)
AND A
JR Z, 46094
LD BC, 32765
LD A, 22
OUT (C), A
CALL 49158
LD BC, 32765
LD A, 16
OUT (C), A
LD A, (46064)
LD D, A
LD BC, 32766
IN A, (C)
AND 4
LD (46064), A
JR NZ, 46124
CP D
JR Z, 46124
LD A, (46063)
XOR 1
LD (46063), A
CALL Z, 46133
POP IX
POP HL
POP DE
POP BC
POP AF
JP 56
LD A, 0
LD C, 253
LD D, 0
LD B, 255
OUT (C), A
LD B, 191
OUT (C), D
INC A
CP 14
JR NZ, 46139
RET
User avatar
bobs
Microbot
Posts: 107
Joined: Thu Dec 28, 2017 8:26 am
Location: UK
Contact:

Re: Interrupt routine for Vortex Tracker

Post by bobs »

What’s the “JP 56” instruction 11 lines from the bottom for ?
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Interrupt routine for Vortex Tracker

Post by sludge »

I'm not entirely sure, someone (Gasman I think) knocked the routine up for me back in 2016.

There is a vector table located at 46336 which made up of bytes all with the value of 182.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

I know that one ;)

It calls the default interrupt service routine which updates frames and the current pressed key.

https://skoolkid.github.io/rom/dec/asm/56.html

Can't help with your interrupt though. Might help if you posted where the source code lives since that will have labels etc. probably.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

257 bytes of 182 for your ISR vector table will call $B6B6 = 46744 in decimal whenever the interrupt goes off.

Is your ISR located at that address? Or does that point to an instruction that jumps to your ISR?

You should probably put a breakpoint in your ISR routine and step through to see that it is called and works as expected. If it's called, put a breakpoint on the line where it detects the key being pressed? That's assuming your are using an emulator of course.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Are you sure you should JP 56 though? The ROM ISR is supposed to be called and not jumped to, since it ends with EI and RET? Once you CALL 56 none of the lines afterwards will get executed (unless you push a fake return address onto the stack before JP 56). I can see a fake return address is not pushed so that looks like a bug there.

JP 56 might work if it is the last instruction in your ISR and you don't expect to do anything else (since it enables interrrupts and returns to the point it was interrupted at). You don't need a RET then of course.
Last edited by ParadigmShifter on Tue Feb 27, 2024 3:41 pm, edited 1 time in total.
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Interrupt routine for Vortex Tracker

Post by AndyC »

ParadigmShifter wrote: Tue Feb 27, 2024 3:34 pm Are you sure you should JP 56 though? The ROM ISR is supposed to be called and not jumped to, since it ends with EI and RET? Once you CALL 56 none of the lines afterwards will get executed (unless you push a fake return address onto the stack before JP 56). I can see a fake return address is not pushed so that looks like a bug there.
I imagine the code after JP 56 is used by the CALL Z just above that bit (although a sample like this is a perfect demonstration of why you should always use labels rather than hard coded addresses) and therefore it's a quicker way of doing:

CALL 56
RET

since you can just let the interrupt handler do the return for you.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Hmm ok. Anyway you should step through the ISR in the debugger to see what it is doing.
I've changed the CALL 49158 to 49157 which gets it playing but the game constantly crashes.
That sounds a bit dodgy anyway.

Did the code work as expected before you tried to add a check for pressing M?

If all the addresses are hardcoded adding new code can easily bugger things up since addresses will likely change?

Not using labels probably means they dumped the code direct from the memory when the code was running :/

EDIT: So you may want to "label it up" i.e. change all occurrences of JP NNNN (and CALL NNNN) to use a label instead (e.g. instead of call 30000 do call L30000 and put a label to where it expects to jump to).
Last edited by ParadigmShifter on Tue Feb 27, 2024 3:53 pm, edited 1 time in total.
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Interrupt routine for Vortex Tracker

Post by sludge »

Is this any help?

Code: Select all

	ld hl, 40000		 ; 46000 33     64	 156 10ts
	ld bc, 32765		 ; 46003 1     253 127 10ts
	ld a, 22		 ; 46006 62     22	 7ts
	out (c), a		 ; 46008 237 121 12ts
	ld (49153), hl		 ; 46010 34     1	 192 16ts
	call 49152		 ; 46013 205 0	 192 17ts
	ld bc, 32765		 ; 46016 1     253 127 10ts
	ld a, 16		 ; 46019 62     16	 7ts
	out (c), a		 ; 46021 237 121 12ts
	ld hl, 46336		 ; 46023 33     0	 181 10ts
	ld de, 46337		 ; 46026 17     1	 181 10ts
	ld bc, 256		 ; 46029 1     0	 1     10ts
	ld (hl), 182		 ; 46032 54     182 10ts
	ldir			 ; 46034 237 176 16/21ts
	ld a, 195		 ; 46036 62     195 7ts
	ld (46774), a		 ; 46038 50     182 182 13ts
	ld hl, l46065		 ; 46041 33     241 179 10ts
	ld (46775), hl		 ; 46044 34     183 182 16ts
	di			 ; 46047 243 4ts
	ld a, 181		 ; 46048 62     181 7ts
	ld i, a			 ; 46050 237 71	 9ts
	im 2			 ; 46052 237 94	 8ts
	ei			 ; 46054 251 4ts
	ret			 ; 46055 201 10ts
	di			 ; 46056 243 4ts
	im 1			 ; 46057 237 86	 8ts
	ei			 ; 46059 251 4ts
	jp l_b435		 ; 46060 195 53	 180 10ts
l_b3ef: nop			 ; 46063 0     4ts
l_b3f0: inc b			 ; 46064 4     4ts
l_b3f1: push af			 ; 46065 245 11ts
	push bc			 ; 46066 197 11ts
	push de			 ; 46067 213 11ts
	push hl			 ; 46068 229 11ts
	push ix			 ; 46069 221 229 15ts
	ld a, (l46063)		 ; 46071 58     239 179 13ts
	and a			 ; 46074 167 4ts
	jr z, l_b40e		 ; 46075 40     17	 12/7ts
	ld bc, 32765		 ; 46077 1     253 127 10ts
	ld a, 22		 ; 46080 62     22	 7ts
	out (c), a		 ; 46082 237 121 12ts
	call 49158		 ; 46084 205 6	 192 17ts
	ld bc, 32765		 ; 46087 1     253 127 10ts
	ld a, 16		 ; 46090 62     16	 7ts
	out (c), a		 ; 46092 237 121 12ts
l_b40e: ld a, (l46064)		 ; 46094 58     240 179 13ts
	ld d, a			 ; 46097 87     4ts
	ld bc, 32766		 ; 46098 1     254 127 10ts
	in a, (c)		 ; 46101 237 120 12ts
	and 4			 ; 46103 230 4	 7ts
	ld (l46064), a		 ; 46105 50     240 179 13ts
	jr nz, l_b42c		 ; 46108 32     14	 7/12ts
	cp d			 ; 46110 186 4ts
	jr z, l_b42c		 ; 46111 40     11	 12/7ts
	ld a, (l46063)		 ; 46113 58     239 179 13ts
	xor 1			 ; 46116 238 1	 7ts
	ld (l46063), a		 ; 46118 50     239 179 13ts
	call z, l46133		 ; 46121 204 53	 180 17/10ts
l_b42c: pop ix			 ; 46124 221 225 14ts
	pop hl			 ; 46126 225 10ts
	pop de			 ; 46127 209 10ts
	pop bc			 ; 46128 193 10ts
	pop af			 ; 46129 241 10ts
	jp 56			 ; 46130 195 56	 0     10ts
l_b435: ld a, 0			 ; 46133 62     0	 7ts
	ld c, 253		 ; 46135 14     253 7ts
	ld d, 0			 ; 46137 22     0	 7ts
l_b43b: ld b, 255		 ; 46139 6     255 7ts
	out (c), a		 ; 46141 237 121 12ts
	ld b, 191		 ; 46143 6     191 7ts
	out (c), d		 ; 46145 237 81	 12ts
	inc a			 ; 46147 60     4ts
	cp 14			 ; 46148 254 14	 7ts
	jr nz, l_b43b		 ; 46150 32     243 7/12ts
	ret			 ; 46152 201 10t
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Yes... that's already been labelled as I suggested.

Is that the original working code?

You probably want to assemble that and see if it works. You also probably want to produce a symbol file so you know what lives where and what entry points to call.

If it doesn't work go back to a working version of the code and add stuff slowly, test regularly and if something does not work revert and try again.

EDIT: Although I can still see a hard coded CALL there (call 49152 and call 49158)... change that to a label as well?

EDIT again: Although you said those are the entry points to the player... may be OK I suppose.

EDIT2: Stuff like this

Code: Select all

	ld hl, l46065		 ; 46041 33     241 179 10ts
is not great either since a lower case L looks like the number 1 lol. Use uppercase L instead or use l_ as they do elsewhere.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Presumably the

call z, l46133 ; 46121 204 53 180 17/10ts

is CALL Z 46133 which looks like it will call this (so change it to CALL Z, l_b435 to be consistent I guess?). EDIT: Yup, the address in the opcode is $B435 there which is 46133

Code: Select all

l_b435: ld a, 0			 ; 46133 62     0	 7ts
	ld c, 253		 ; 46135 14     253 7ts
	ld d, 0			 ; 46137 22     0	 7ts
l_b43b: ld b, 255		 ; 46139 6     255 7ts
	out (c), a		 ; 46141 237 121 12ts
	ld b, 191		 ; 46143 6     191 7ts
	out (c), d		 ; 46145 237 81	 12ts
	inc a			 ; 46147 60     4ts
	cp 14			 ; 46148 254 14	 7ts
	jr nz, l_b43b		 ; 46150 32     243 7/12ts
	ret			 ; 46152 201 10t
Pretty sure you need to EI before you ret there (unless you have an EI before a HALT? - even so, I'd add an EI before the RET to be consistent with what the ROM ISR does). Otherwise the interrupts will stay off and the ISR will never be called again.

The CPU implicitly does a DI before calling the ISR... you need to manually turn them back on once you have serviced the interrupt.


EDIT: Nope, that's OK since that is returning to after the CALL Z... ignore that bit ;)
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

What is at address $B6B6 = 46744? Hopefully this or it does this very soon afterwards ;)

Code: Select all

 jp l_b3f1
which will jump to the first instruction of the ISR i.e.

l_b3f1: push af ; 46065 245 11ts

EDIT: Nevermind I can see it pokes the correct address after setting up the ISR vector (here)

Code: Select all

	ld a, 195		 ; 46036 62     195 7ts ; OPCODE for JP NNNN
	ld (46774), a		 ; 46038 50     182 182 13ts
	ld hl, l46065		 ; 46041 33     241 179 10ts  ; address to jump to
	ld (46775), hl		 ; 46044 34     183 182 16ts
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Whoops, erroneous post deleted ;)

Anyway

the 2 bytes at 46063 are not really code. 46063 looks to be a flag to toggle the music on or off and 46064 looks to be something to do with what key to look for or something (yup, 4 is the code for key M being pressed on the in port you read from). The labels at those addresses should just be

db 0
db 4

instead of

NOP
INC B

cos otherwise this code would be nonsense on stilts

Code: Select all

	ld a, (l46063)		 ; 46071 58     239 179 13ts
	and a			 ; 46074 167 4ts
	jr z, l_b40e		 ; 46075 40     17	 12/7ts
	ld bc, 32765		 ; 46077 1     253 127 10ts
	ld a, 22		 ; 46080 62     22	 7ts
	out (c), a		 ; 46082 237 121 12ts
	call 49158		 ; 46084 205 6	 192 17ts
	ld bc, 32765		 ; 46087 1     253 127 10ts
	ld a, 16		 ; 46090 62     16	 7ts
	out (c), a		 ; 46092 237 121 12ts
l_b40e: ld a, (l46064)		 ; 46094 58     240 179 13ts
	ld d, a			 ; 46097 87     4ts
	ld bc, 32766		 ; 46098 1     254 127 10ts
	in a, (c)		 ; 46101 237 120 12ts
	and 4			 ; 46103 230 4	 7ts
	ld (l46064), a		 ; 46105 50     240 179 13ts
	jr nz, l_b42c		 ; 46108 32     14	 7/12ts
	cp d			 ; 46110 186 4ts
	jr z, l_b42c		 ; 46111 40     11	 12/7ts
	ld a, (l46063)		 ; 46113 58     239 179 13ts
	xor 1			 ; 46116 238 1	 7ts
	ld (l46063), a		 ; 46118 50     239 179 13ts
Yeah I understand what that code is doing. If 46063 holds 0 then it skips the call 49158 bit and just goes to the check the keyboard and returns. If you are pressing M it toggles the value at 46063 from 0 to 1 or vice versa. Something like that anyway ;)
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Anyway that code seems fairly sane, it's hard to tell what the routine it calls does though obviously.

Maybe it uses IY or AF' or the shadow registers and doesn't then restore them? And so does the rest of the game or whatever else you are doing?

To be 100% safe you have to push and pop everything on entering/leaving the ISR

Code: Select all

push af
push bc
push de
push hl
push ix
push iy
ex af, af'
push af
exx
push bc
push de
push hl

Code: Select all

pop hl
pop de
pop bc
exx
pop af
ex af, af'
pop iy
pop ix
pop hl
pop de
pop bc
pop af
should do that. (Not tested)

You definitely can't do a JP 56 if IY is not the magic value it usually has when Basic is running (since when it updates the frame counter and the currently pressed keyboard key it assumes IY points to the sysvars). Otherwise you will trash memory.

If you know that the routine you call only trashes IX, AF, BC, DE and HL what it is doing now (code you posted) is ok.

I had a look at some code for one version of vortex (I think) and it definitely uses AF'. It also modifies IY but there is a compile option Basic = 1 which looks like it restores it to the correct value (but if you turned that flag off, or it seems there may be an older version which did not do that, that would be bad).

You probably want to look in the debugger what the register values are on entry to the ISR (all registers and shadow registers, and the SP. Also check the top of the stack value because that is where it will return to once the ISR is finished). Then once you hit the JP 56 check they are all the same. Otherwise bad things (TM) will likely happen.

If the ISR does not save and restore everything random hard to debug weirdness is bound to happen depending on what the program was doing when the interrupt went off (usually could be doing absolutely anything).

Obviously all the addresses must be correct as well (i.e. the ISR must be at the address it expects, as must those variables which control the playing and reading the keyboard). You can debug that by putting a breakpoint on 46336 (should be the JP ISR it poked into memory) and seeing where that ends up.

Also verify that when you call the entry point it takes you to the expected place in the player. Otherwise you have assembled it to the wrong address.

Sometimes ISR bugs can stay hidden for a while if the code you run usually enters the ISR only while the CPU is doing a HALT instruction - everything looks fine then if you run at 50FPS but as soon as you drop a frame - BAM! - everything will break. As an added bonus, it will usually not break and crash immediately but quietly corrupt memory, end up looking at the wrong flag values, etc. which can take a while to become apparent, long after the problem actually started happening. Randomly occurring hard to reproduce bugs are usually a good sign there is something wrong with the ISR.

The reason the Z80 shadow register set was added in the first place was apparently to avoid pushing and popping things in the ISR as an option (say you are running on hardware with hardly any stack space available). If you never use AF' or EXX in your entire code you can just do an EX AF, AF' and EXX on entry to the ISR and the reverse (or the same, order does not matter) before you exit. Then you don't use any stack space apart from the ISR return address and it's also faster than all those pushes and pops - important for devices which must service interrupts as fast as possible when they go off (e.g. running a nuclear power station using a ZX81 as the reactor control system) :)

Then of course Spectrum programmers realised how fast and amazingly handy the EXX and EX AF, AF' instructions are so you can't do your ISR like that if you use them outside of the ISR :)

EDIT: It also goes without saying that if your code has modified IY at any point when the ISR goes off, and then you jump to the ROM ISR, it would be bad :)

I usually just define my own frame counter variable which I update in the ISR and you don't need to update the currently pressed key flag unless you use it in the rest of the code, since you are reading the keyboard port directly in that routine. Then I don't bother with any of the stuff it does in the ROM ISR since I don't need it.

If you never use ROM calls and never intend to return to basic except via CALL 0 you can even use the sysvars area for your own data if you want.
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Interrupt routine for Vortex Tracker

Post by sludge »

Heres the code for the music player that works with the interrupt.

I think it came from Yermyey or Gasman:

Code: Select all

	ld hl, 40000		 ; 49152 33     64	 156 10ts
	jp l_c009		 ; 49155 195 9	 192 10ts
	jp 49476		 ; 49158 195 68	 193 10ts
l_c009: di			 ; 49161 243 4ts
	ld a, (hl)		 ; 49162 126 7ts
	ld (49272), a		 ; 49163 50     120 192 13ts
	ld (49339), hl		 ; 49166 34     187 192 16ts
	inc hl			 ; 49169 35     6ts
	call 49333		 ; 49170 205 181 192 17ts
	ld a, (de)		 ; 49173 26     7ts
	inc de			 ; 49174 19     6ts
	inc a			 ; 49175 60     4ts
	ld (49274), a		 ; 49176 50     122 192 13ts
	ld (49264), de		 ; 49179 237 83	 112 192 20ts
	call 49333		 ; 49183 205 181 192 17ts
	ld (49266), de		 ; 49186 237 83	 114 192 20ts
	push de			 ; 49190 213 11ts
	call 49333		 ; 49191 205 181 192 17ts
	ld (49268), de		 ; 49194 237 83	 116 192 20ts
	ld hl, 27		 ; 49198 33     27	 0     10ts
	call 49338		 ; 49201 205 186 192 17ts
	ex de, hl		 ; 49204 235 4ts
	ld (49270), hl		 ; 49205 34     118 192 16ts
	ld hl, 49281		 ; 49208 33     129 192 10ts
	ld (49275), hl		 ; 49211 34     123 192 16ts
	ld hl, 49282		 ; 49214 33     130 192 10ts
	ld de, 49283		 ; 49217 17     131 192 10ts
	ld bc, 44		 ; 49220 1     44	 0     10ts
	ld (hl), b		 ; 49223 112 7ts
	ldir			 ; 49224 237 176 16/21ts
	pop hl			 ; 49226 225 10ts
	ld bc, 33		 ; 49227 1     33	 0     10ts
	xor a			 ; 49230 175 4ts
	call 49327		 ; 49231 205 175 192 17ts
	dec a			 ; 49234 61     4ts
	ld (49291), a		 ; 49235 50     139 192 13ts
	ld (49301), a		 ; 49238 50     149 192 13ts
	ld (49311), a		 ; 49241 50     159 192 13ts
	ld a, 1			 ; 49244 62     1	 7ts
	ld (49273), a		 ; 49246 50     121 192 13ts
	inc hl			 ; 49249 35     6ts
	ld (49289), hl		 ; 49250 34     137 192 16ts
	ld (49299), hl		 ; 49253 34     147 192 16ts
	ld (49309), hl		 ; 49256 34     157 192 16ts
	call 50207		 ; 49259 205 31	 196 17ts
	ei			 ; 49262 251 4ts
	ret			 ; 49263 201 10t
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Interrupt routine for Vortex Tracker

Post by sludge »

And heres the code for the player that comes with VT, as you can see the players are different.

Code: Select all

	ld hl, 40000		 ; 49152 33     64	 156 10ts
	jr l_c03f		 ; 49155 24     58	 12ts
	jp 50361		 ; 49157 195 185 196 10ts
	jr l_c033		 ; 49160 24     41	 12ts
l_c00a: nop			 ; 49162 0     4ts
l_c00b: dec c			 ; 49163 13     4ts
	sbc a, l		 ; 49164 157 4ts
	dec a			 ; 49165 61     4ts
	ld d, (hl)		 ; 49166 86     7ts
	ld d, h			 ; 49167 84     4ts
	ld c, c			 ; 49168 73     4ts
	ld c, c			 ; 49169 73     4ts
	jr nz, l_c064		 ; 49170 32     80	 7/12ts
	ld d, h			 ; 49172 84     4ts
	inc sp			 ; 49173 51     6ts
	jr nz, l_c068		 ; 49174 32     80	 7/12ts
	ld l, h			 ; 49176 108 4ts
	ld h, c			 ; 49177 97     4ts
	ld a, c			 ; 49178 121 4ts
	ld h, l			 ; 49179 101 4ts
	ld (hl), d		 ; 49180 114 7ts
	jr nz, 49297		 ; 49181 32     114 7/12ts
	ld l, 55		 ; 49183 46     55	 7ts
	dec a			 ; 49185 61     4ts
	ld hl, l49162		 ; 49186 33     10	 192 10ts
	set 7, (hl)		 ; 49189 203 254 15ts
	bit 0, (hl)		 ; 49191 203 70	 12ts
	ret z			 ; 49193 200 11/5ts
	pop hl			 ; 49194 225 10ts
	ld hl, 50856		 ; 49195 33     168 198 10ts
	inc (hl)		 ; 49198 52     11ts
	ld hl, 50796		 ; 49199 33     108 198 10ts
	inc (hl)		 ; 49202 52     11ts
l_c033: xor a			 ; 49203 175 4ts
	ld h, a			 ; 49204 103 4ts
	ld l, a			 ; 49205 111 4ts
	ld (50870), a		 ; 49206 50     182 198 13ts
	ld (50871), hl		 ; 49209 34     183 198 16ts
	jp 50603		 ; 49212 195 171 197 10ts
l_c03f: ld (49576), hl		 ; 49215 34     168 193 16ts
	ld (49982), hl		 ; 49218 34     62	 195 16ts
	push hl			 ; 49221 229 11ts
	ld de, 100		 ; 49222 17     100 0     10ts
	add hl, de		 ; 49225 25     11ts
	ld a, (hl)		 ; 49226 126 7ts
	ld (50501), a		 ; 49227 50     69	 197 13ts
	push hl			 ; 49230 229 11ts
	pop ix			 ; 49231 221 225 14ts
	add hl, de		 ; 49233 25     11ts
	ld (l49163), hl		 ; 49234 34     11	 192 16ts
	ld e, (ix+2)		 ; 49237 221 94	 2     19ts
	add hl, de		 ; 49240 25     11ts
	inc hl			 ; 49241 35     6ts
	ld (50407), hl		 ; 49242 34     231 196 16ts
	pop de			 ; 49245 209 10ts
	ld l, (ix+3)		 ; 49246 221 110 3     19ts
	ld h, (ix+4)		 ; 49249 221 102 4     19ts
l_c064: add hl, de		 ; 49252 25     11ts
	ld (50420), hl		 ; 49253 34     244 196 16ts
l_c068: ld hl, 169		 ; 49256 33     169 0     10ts
	add hl, de		 ; 49259 25     11ts
	ld (49975), hl		 ; 49260 34     55	 195 16ts
	ld hl, 105		 ; 49263 
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Ok well you can't poke stuff into the variables you use to check for a key/toggle music then if they have different addresses, they have to match the player address variables.

Maybe it's the address of the NOP that is the address of the toggle music on off flag, hard to tell. And then the keyboard mask thing (or previous key pressed mask, didn't look to hard at the code) was afterwards in the old one.

Also check all the functions it calls for use of registers other than IX, AF, BC, DE, HL as well (so any use of IY or EXX or EXX AF, AF' is not good).

Look for an IN instruction which is where it will read the keyboard. See what addresses it uses there.

You can't use an ISR with hard coded addresses for variables with a different version obvs.

You probably really need the source code it looks like it's just ripped from memory when running there.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Interrupt routine for Vortex Tracker

Post by ParadigmShifter »

Code: Select all

	ld hl, 40000		 ; 49152 33     64	 156 10ts
	jr l_c03f		 ; 49155 24     58	 12ts
	jp 50361		 ; 49157 195 185 196 10ts
	jr l_c033		 ; 49160 24     41	 12ts
49157 looks like it may be an entry point (strange to do a JP at the entry point though - so I suspect it might be data or a variables there instead). All of that could be data instead of code meant to be executed, impossible to tell. Find out where the working code has its entry points (i.e. anything called or jumped to) and disassemble from each of those addresses. If you disassemble from 49158 does it look sensible?

If they mix data in with the code the disassembler will get very confused, since it does not know the difference between code and data obvs.

If you start disassembling in the middle of a multibyte instruction obviously it will give nonsense for everything that follows.

When you reverse engineer code it's important to work out what parts are executable code and what parts are data. Never disassemble data as code, that would be madness. Always start disassembling at a valid instruction that is called or jumped to.
User avatar
R-Tape
Site Admin
Posts: 6409
Joined: Thu Nov 09, 2017 11:46 am

Re: Interrupt routine for Vortex Tracker

Post by R-Tape »

sludge wrote: Tue Feb 27, 2024 11:41 am Music data will be at 40000 and the vtplayer at 49152.
If you haven't already, check that the music data isn't being expanded over other code. It gets bigger when you start using it - I always put it after the player and leave a gap after that.

I can't check the code in detail right now, but can help with a routine later in the week if no-one beats me to it.
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Interrupt routine for Vortex Tracker

Post by AndyC »

ParadigmShifter wrote: Wed Feb 28, 2024 12:23 am
49157 looks like it may be an entry point (strange to do a JP at the entry point though - so I suspect it might be data or a variables there instead).
A common thing amongst AY players (at least back in the day) was to have three entry points right at the start - one to initialize the routine, one to be called on each frame and one to stop all sound. They were typically at start, start+3 and start+6 and implemented as JPs to the real entry points (making them invariant if the routine is swapped). So I expect that's what they are.

But I'm curious. Is this disassembled code rather than the original source? There is a confusing mix of literal addresses and badly named labels (that look auto generated from addresses). Working with code like that is unnecessarily difficult and you're much better off taking the time to replace them all with well named labels or defined constants before trying to adapt (or relocate) the routine.
Post Reply