English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 17 July 2021, 22:49   #1
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Periodical code call, if level 2, 3 and 6 interrupts are occupied?

I have a small code snippet which i would like to run periodically during a (non-system-friendly) game, but the game uses all the interrupts i know they can be used for cyclical code calling. Is there any way to do this? Or the only way is to modify the game itself?

Edit: It seems, the game does not use level 7 interrupts, but even if i write my code's entry address into $7c, nothing happens. Can NMI be disabled?

Last edited by TCH; 17 July 2021 at 23:01. Reason: Level 7
TCH is offline  
Old 17 July 2021, 23:06   #2
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,162
level 7 interrupts can only be triggered by extra hardware (Action Replay, HRTMon extra button...). It seems that you have a lot to learn sorry to say it like this.

Just hook on the interrupt that interests you (level 3 check INTREQ for bit 5 set means vblank) and you have a 20ms (PAL) periodic routine. We do that all the time in whdload slaves to poll joypad buttons periodically.

Another idea is (68010+ only) set the VBR to non-zero and handle interrupts from there, then call the regular zero page interrupts (as the program cannot know the VBR base and assumes zero unless it sets it which is rare)
jotd is offline  
Old 17 July 2021, 23:21   #3
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Notice the label below my name...

Level 3 interrupts are used by the game. I've checked the Level 3 interrupt subroutine and it has fix
jsr
-s, so i managed to inject my address there and then from my subroutine i jump to the original address. But for this, i need the WinUAE debugger.

It's an AGA game, so VBR is present and indeed it is zero, according to the WinUAE debugger, but if i try to set it to anything, then the entire system is crashing which is not a surprise. How can this be done, before the game starts?

Level 1 seems to be unoccupied. Can i cause a Level 1 interrupt manually?

I tried to copy the VBR table and then set VBR in supervisor mode, but i get GURU $80000008:
Code:
		move.l		#$1ffb00,a2
		movea.l		#$0,a0
		move.l		a2,a1
		move.l		#$100,d0
VBRCopyLoop:	move.l		(a0)+,(a1)+
		dbra		d0,VBRCopyLoop
		move.l		#$1fff00,$1ffb6c
		move.w		sr,-(a7)
		ori.w		#$2700,sr
		movec.l		a2,vbr
		move.w		(a7)+,sr

Last edited by TCH; 18 July 2021 at 00:23. Reason: Level 3 expanded, Level 1, VBR
TCH is offline  
Old 18 July 2021, 00:56   #4
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
I'm not sure what you are trying to do, but when you get a Privilege Violation exception then you are certainly in user mode while writing to SR.

When the OS is still alive, use
Supervisor()
to call your VBR-setting code. Otherwise write the pointer to your supervisor code into any free trap-vector, like $80. Then run it with
trap #0
and return with
rte
.
phx is offline  
Old 18 July 2021, 01:33   #5
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
Quote:
Originally Posted by TCH View Post
Level 1 seems to be unoccupied. Can i cause a Level 1 interrupt manually?
Yes, you can do that. Easiest way to do this is probably by setting bit 2 in the INTREQ register (and of course setting INTENA to the proper mask and setting up the corresponding interrupt vector).
roondar is offline  
Old 18 July 2021, 01:40   #6
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Quote:
Originally Posted by phx View Post
When the OS is still alive, use
Supervisor()
to call your VBR-setting code.
How can i call
Supervisor()
from Assembly? Just write a subroutine,
lea
it's address into
a5
and then
jsr Supervisor(a4)
? I am using vasm (
-m68020 -Fhunkexe
), is Exec opened automatically into
a4
or i have to do that manually?
Quote:
Originally Posted by roondar View Post
Yes, you can do that. Easiest way to do this is probably by setting bit 2 in the INTREQ register (and of course setting INTENA to the proper mask and setting up the corresponding interrupt vector).
The problem is, that i lose the control, when the game starts; it's not a system-friendly game. How can i trigger that Level 1 interrupt afterwards, for example from keyboard?
TCH is offline  
Old 18 July 2021, 01:59   #7
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
Quote:
Originally Posted by TCH View Post
The problem is, that i lose the control, when the game starts; it's not a system-friendly game. How can i trigger that Level 1 interrupt afterwards, for example from keyboard?
Well, the issue with level 1 interrupts is that you need to trigger them 'manually' as it were. They don't trigger automatically. So one thing that I have done in the past is to have a level 3 interrupt trigger a level 1 interrupt so that it would run after the level 3 interrupt had finished (barring, naturally, interference from higher level interrupts).

So in effect, you'd have to create some sort of hook into the existing code that triggers the level 1 interrupt. But if you're doing that, you may as well just change the code so that f.ex. the level 3 interrupt jumps to your code at some point.

Honestly, I have little experience in changing existing games, but my guess would be that putting some sort of JSR or JMP (or even branch) into an existing interrupt would be best. You'd basically just have to find some space to put your code and then patch the address where your code resides at runtime into the pre-existing code (i.e. in the JSR/JMP you'd have to add).
roondar is offline  
Old 18 July 2021, 09:40   #8
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
In the meantime i've found that Exec is always open, but not at
(a4)
, but
4
...it was late and i confused it. :P
I wrote the following code:
Code:
		move.l		#$1ffb00,a2
		movea.l		#$000,a0
		move.l		a2,a1
		move.l		#$100,d0
VBRCopyLoop:	move.l		(a0)+,(a1)+
		dbra		d0,VBRCopyLoop
		move.l		#$1fff00,$1ffb6c
		movea.l		$4,a3
		lea		SetVBR(pc),a5
		jsr		-$1e(a3)

		moveq		#0,d0
		rts

SetVBR:		movec		a2,vbr
		rte
Now it dies with GURU 8000000B, which means unimplemented instruction. How is that possible? It's 68020, movec should be implemented, right? Edit: It's
$4
, not
#4
. /o\ Now it fails with GURU 80000004, which is division by zero.

@roondar:
That was i tried to do, inject my subroutine's address into the game's Level 3 interrupt subroutine which starts at $119d48 and has a
jsr $00118782
at $119d4c. With WinUAE i can do that (W 119d4e 1fff00) and then it will call my subroutine (which will do the overridden
jsr $00118782
manually at it's end), but for this, i have to do this manually in WinUAE.

The question is, how can i set up something which either can do a simple
move.l #$001fff00,$00119d4c
or do something else which call my subroutine after the game loaded (and took over all Level 2, 3 and 6 interrupts). Either by automatically, or manually, like triggering via a keystroke. If i am able to call my subroutine at least once after the game loaded, then the problem is solved.

Or is it impossible and i have to alter the game?

Last edited by TCH; 18 July 2021 at 11:52. Reason: #->$
TCH is offline  
Old 18 July 2021, 10:01   #9
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
When calling library functions, the library base has to be in a6. Supervisor() may not work correctly when that is not the case.
StingRay is offline  
Old 18 July 2021, 10:16   #10
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
It's still 80000004. I've checked the registers in the debugger.
a5
contains the address of
SetVBR
,
a6
the address which was under
$4
and
a2
has
$1ffb00
. It should work?

Edit: Never mind, it seems, that now the VBR is also set to the proper value, so the error now lies in the subroutine itself.

Edit 2: Or, maybe not in the subroutine, because even if it is only a single
jsr ($6c)
or a simple infinite loop, it is still 80000004. If i do not alter the new L3I vector at
$1ffb6c
, then the game works, although there is no music and sound. (Since nothing copies the L2 and L6 interrupt vectors and nothing calls the L3 one.)

Edit 3: The game seems to store data under the L6 interrupt vector (
$109688
), it's full of zeros and if i write something there, garbage pixels appear and after a while the location gets zeroed again.

Last edited by TCH; 18 July 2021 at 10:52. Reason: VBR too, set
TCH is offline  
Old 18 July 2021, 11:53   #11
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
I have the feeling you are overcomplicating things. As I understand you already found the solution, here:
Quote:
Originally Posted by TCH View Post
Level 3 interrupts are used by the game. I've checked the Level 3 interrupt subroutine and it has fix
jsr
-s, so i managed to inject my address there and then from my subroutine i jump to the original address. But for this, i need the WinUAE debugger.
Which is also what jotd suggested: hook your code into an existing interrupt of interrest. Just change the code as you need it and save the program to disk. Alternatively write a loader which patches that address.

Otherwise, please explain again in detail what you are trying to achieve.
phx is offline  
Old 18 July 2021, 12:39   #12
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
But which interrupt? AFAIK, only L2, L6 (CIA Timers) and L3 (VBlank) can be used for periodically called interrupts, which i can control and the rest are generated by events which will never happen during the game. And L2, L3 and L6 are used by the game.

The code i cannot change so easily, as it's a trackloader game using a HD loader and some kind of compression. I have no idea where is the actual code or how it is packed, but even if i would know and could decompress it, i also have to repack it afterwards and if the packed length will change (because i've changed the entropy with the changed address), then data consistency is annihilated.

Writing a loader which patches that address is what i am trying to do, but the code is periodically loaded and erased from the memory, so it can be only patched when the game is already running and it has to be patched periodically, but when the game is already running, then it has already occupied all the L2, L3 and L6 interrupts.

The question is, can i hook my code to an L1, L4 or L5 interrupt in a way it will be called either periodically or manually via keystroke, joystick/mouse event or any kind of user action.
TCH is offline  
Old 18 July 2021, 12:53   #13
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by TCH View Post
The code i cannot change so easily, as it's a trackloader game using a HD loader and some kind of compression. I have no idea where is the actual code or how it is packed, but even if i would know and could decompress it, i also have to repack it afterwards and if the packed length will change (because i've changed the entropy with the changed address), then data consistency is annihilated.
The code has to be decrunched at one point, find that piece of code, determine the entry point of the the decrunched code (i.e. the place where the decrunched code is executed), patch the code to call your code and you're done. As PHX already noticed, you're overcomplicating things.
StingRay is offline  
Old 18 July 2021, 13:11   #14
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
I see your problem. The optimal solution would be to analyze the decompression algorithm and the file structure, so you would be able to write the patched file back to disk.

What StingRay suggests is that there must be a resident piece of code, which loads and decrunches other code loaded from disk, like the one you're interrested in. You should have a better chance to patch this loader instead, which is hopefully only loaded once the game is booted from disk.

Do that by finding a kind of signature which identifies your file. Like a start address and/or the first bytes of the file. Maybe there is even a kind of file-index in the trackloader based custom file system. When it matches, patch the code after loading and decrunching.
phx is offline  
Old 18 July 2021, 13:15   #15
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
@StingRay:
The decruncher which is responsible for putting the code onto it's place is itself on one of the disk images, compressed. There are four NDOS disk images and a 2.4 kB loader which only does load the main program/intro from disk0. I don't know where is the actual code stored.

Just to test it, i made a snapshot of the ChipRAM (
S dump.map 0 200000
), then tried to find anything which references the L3 interrupt vector ($00119d48).
I found only one at $1170AE. Disassembly (
dg 1170ae
) and i got the code
move.l #$00119d48,$0000006c
, so it is just the one which moves the address to the vector table. There are no more references to this address, so the decrunching starts from another address.

Edit: (The forum really should alert on quick posting, if another post arrived since i started writing...)
@phx:
The loader only loads the main program, not the actual code needed to be patched. The code at $119d48 is loaded in the options, but replaced during in game. I have no idea how to find the decruncher.


Edit 2: I made a snapshot during the intro/loading, but no references of $119d48 are found. The bytes of $00 $11 $9d $48 are not exists in the memory during loading.

Last edited by TCH; 18 July 2021 at 13:23. Reason: new post, answer
TCH is offline  
Old 18 July 2021, 13:34   #16
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
It can get tricky, depending on how the loader works. It's not that unlikely they may have implemented some form of relocation instead of relying on fixed addresses.
roondar is offline  
Old 18 July 2021, 15:22   #17
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by TCH View Post
@StingRay:
The decruncher which is responsible for putting the code onto it's place is itself on one of the disk images, compressed. There are four NDOS disk images and a 2.4 kB loader which only does load the main program/intro from disk0. I don't know where is the actual code stored.
Disassemble the loader and understand what the code does. The decruncher code MUST be called at one point, there is no other way. This may happen in the 2.4k loader or in one of the files that gets loaded. If you understand the loader code, you'll be successful in applying your code patch. At the moment it just looks to me like you're trying a lot of things without any real knowledge why something happens or what happens at all. This will not work in the long run.
StingRay is offline  
Old 18 July 2021, 15:31   #18
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Okay, so, the answer to the original question: no, it's not possible to do periodical calls without L2, L3 or L6 interrupts, i have to modify the game itself. Thanks.
TCH is offline  
Old 18 July 2021, 18:53   #19
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by TCH View Post
Okay, so, the answer to the original question: no, it's not possible to do periodical calls without L2, L3 or L6 interrupts, i have to modify the game itself. Thanks.
It's possible but very hard (so it's MUCH better to tweak the game, even for a newbie ).

1) similar to what jotd suggested to you: move your vector table somewhere and insert your own timed routine (the easiest way is with VBI IRQ3)
At that point, however, you have to monitor at each call the changes that are made in the table of vectors at location $0 by the game (not only for the IRQs but also for all the others!*) and report the changes in your relocated table (logically by chaining the game IRQ3 to your code since you cannot 'substitute' yourself, otherwise you lose control of your routine)

2) use MMU to 'grab' the changes to the IRQ3 vector and hook your routine to it

*EDIT: there is a big flaw here.
Suppose the game modifies a trap vector and calls it immediately: you notice the change only in VBI and the code probably crashes.
Many games only change the IRQ vectors and rarely their call is immediate or must be perfectly synchronized, but also in this case it could happen.
So in any case it is absolutely recommended to modify the game code, even if only to understand what actually happens.

Last edited by ross; 18 July 2021 at 19:40.
ross is offline  
Old 18 July 2021, 22:11   #20
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
I tried to move the vector table. It worked, but the game lost sound and whenever i tried to supersede the original L3 routine the system has crashed.
MMU is not present.

I have no idea how to modify the game's code. The way the loader access the files and loads the data requires heavy Amiga related knowledge. Perhaps i can debug where the program unpacks stuff, but i cannot patch the live code, if the game occupies all usable interrupts.
TCH is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Wizzy's Quest (PD) Level codes - and [Request] for Level editor Dan support.Games 30 25 August 2023 00:30
Interrupts, doing it low level, but properly. deimos Coders. General 7 25 September 2019 19:45
WinUAE Bug/Issue Source Code Function Call Audiorulz4u support.WinUAE 6 11 October 2017 17:40
New Independent Periodical "in the style of" Amiga Power Anakirob Retrogaming General Discussion 14 29 June 2017 12:58
Akira's periodical quest for Amiga hardware Amiga1992 MarketPlace 10 02 February 2005 01:10

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 01:38.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.14367 seconds with 15 queries