Jump to content
Gorf

Main Code revealed....sort of.

Recommended Posts

Im not one to like to give something as important as the main code workaround for

nothing, but if you are willing to work for it, I'll hint you all along. Play along and have

a bit of fun learning one of the possible finer points of coding the Jaguar.

 

 

Be forewarned....this is so simple it's embarrasing......

 

Ok, first what do we know about the GPU and The Jaguar?

 

Here are some clues.

 

The GPU is a RISC based processor as opposed to the 68k which is a CISC based processor.

 

For those that may not know:

 

RISC stands for Reduced Instruction Set Comupter.

CISC stands for Complex Instruction Set Comupter.

 

A CISC processor such as the 68k reads and executes ONE instruction at a time. Do not assume that

this is the case for ALL CISC based chips. However since this discussion is based around the Jaguar,

it will apply just fine.

 

A typical RISC has an instruction fetch pipeline. The J-RISC's are exactly such processors. This means

that it not only reads in the current instruction but looks ahead to a few others and loads them into what

is usually called an instruction prefetch. As the Atari Docs state, the J-RISCs when executing an instruction

like the JUMP/JR will CLEAR the pipe except for the instruction following the JUMP/JR. Usually a NOP instruction

is recommended but certain instructions that will always be executed can be placed there as an optimization.

 

Internally, the GPU operates on data at 32 bits wide. Externally it sees a 64 bit bus. Atari states in the docs

that because of an MMU bug, the GPU can not reliably jump around in main RAM. This is only half true. The

GPU cannot run code with jumps in main ram written the conventional way( as if it were intended for the local.)

 

The half lie of the half truth is this. The GPU CAN jump around quite reliably in main RAM as long as the jump/jr

addresses are PROPERLY aligned AND the jump/jr is sitting at the right place in memory. The GPU also sees the

external memory in pages of 256 bytes each(or 64 x 64bit phrases.) The issue here is that jumping over pages

is fine as long as everything is aligned. This includes the very instruction placement as well. The only bug here

is that the GPU runs differently out on a 64 bit bus. It has much to do with the pipeline being flushed at the right

time.

 

Since we have SMAC(and no one else seems to have bothered to find this out on there own....)

Here is a disassembly of some code I wrote to run some SMAC main code RAM tests.

 

Take a nice close look. Tell me what you find in common about the JUMP's(many) and

JR's(only two for now) being used in the code. This code is a shell of what might be the

weapon select in a Quake2 port to the Jaguar. This is not everything you need to know

but it will get your noggin's warmed up for the rest.

 

Anyone who has already been told, please stay out of this and give others a chance to figure it out on there own.

 

(In a RoboCop voice. )

"Thank you for your cooperation." :)

 

MAKE SURE YOU LOOK AT WHERE EVERYTHING IS STARTING FROM AND GOING TO!!!! :)

 

I will wait for some replies before we go on, but for now.....

 

Get ready!

Get Set!

GO!!!

 

:D

 

GPU_main.asm		 Page 1	   11:17:54 am 8-Jul-2009		SMAC 1.0.13 (Win32) 
Code by Steve Scavone, 3DSSS, (C) 2009

1								   
2								   	.gpumain
3								   	.org		$40000
4								   	.include	'pads.inc'
1								   
6								;///////////////////////////////////////////////////////////////////////////////
7								;
8								   FireWeapon:
9								   
  10								; weapon variable equates
  11								   
  12		   =00000000			   BLASTER		.equ	0
  13		   =00000001			   SHOTGUN		.equ	1	
  14		   =00000002			   SUPERSHOTGUN	.equ	2
  15		   =00000003			   MACHINEGUN	.equ	3
  16		   =00000004			   CHAINGUN	.equ	4
  17		   =00000005			   HANDGRENADE	.equ	5
  18		   =00000006			   GRENADELANCHER	.equ	6
  19		   =00000007			   ROCKETLAUNCHER	.equ	7
  20		   =00000008			   HYPERBLASTER	.equ	8
  21		   =00000009			   RAILGUN		.equ	9
  22		   =0000000A			   BFG10K		.equ	10
  23								   			;
  36								   			;
  37								;register equates	;
  38								   			;
  39		   =80000080			   fire	.equr	r0; for current weapon
  40		   =80000081			   ammo	.equr	r1; weapon ammo type
  41		   =8000009C			   JMP	.equr	r28; to jump to Fire()
  42		   =8000009D			   RET	.equr	r29; return jump
  43								   			;
  44  00040000  9800xxxxxxxx		   	movei	#FIREWEAPON,fire; switch(WEAPON)	
  45  00040006  A400				   	load	(fire),fire; {
  46								   			;
  47  00040008  981Cxxxxxxxx		   	movei	#FireBlaster,JMP; set call address
  48  0004000E  7C00				   	cmpq	#BLASTER,fire;   case BLASTER:
  49								   			;
  50								   JMPLabel1:		;
  51  00040010  D382				   	jump	EQ,(JMP);	FireBlaster();
  52  00040012  E400				   	nop	;   break;			
  53  00040014  E400				   	nop	;			
  54  00040016  E400				   	nop	;			
  55								   			;
  56  00040018  981Cxxxxxxxx		   	movei	#FireShotGun,JMP; set call address
  57  0004001E  7C20				   	cmpq	#SHOTGUN,fire;   case SHOTGUN:	
  58								   			;
  59								   JMPLabel2:		;
  60  00040020  D382				   	jump	EQ,(JMP);	Fire(SHOTGUN);	
  61  00040022  E400				   	nop	;   break;			
  62  00040024  E400				   	nop	;			
  63  00040026  E400				   	nop	;			
  64								   			;
  65  00040028  981Cxxxxxxxx		   	movei	#FireSuperShotGun,JMP; set call address
  66  0004002E  7C40				   	cmpq	#SUPERSHOTGUN,fire;   case SUPERSHOTGUN:
  67								   			;
  68								   JMPLabel3:		;
  69  00040030  D382				   	jump	EQ,(JMP);	 Fire(SUPERSHOTGUN);
  70  00040032  E400				   	nop	;   break;			
  71  00040034  E400				   	nop	;			
  72  00040036  E400				   	nop	;			
  73								   			;	
  74  00040038  981Cxxxxxxxx		   	movei	#FireMachineGun,JMP; set call address
  75  0004003E  7C60				   	cmpq	#MACHINEGUN,fire;   case MACHINEGUN:
  76								   			;
  77								   JMPLabel4:		;
  78  00040040  D382				   	jump	EQ,(JMP); 	Fire(MACHINEGUN);
  79  00040042  E400				   	nop	;   break;			
  80  00040044  E400				   	nop	;			
  81  00040046  E400				   	nop	;			
  82								   			;
  83  00040048  981Cxxxxxxxx		   	movei	#FireChainGun,JMP; set call address
  84  0004004E  7C80				   	cmpq	#CHAINGUN,fire;   case CHAINGUN:
  85								   			;
  86								   JMPLabel5:		;
  87  00040050  D382				   	jump	EQ,(JMP);	   Fire(CHAINGUN):
  88  00040052  E400				   	nop	;   break;			
  89  00040054  E400				   	nop	;			
  90  00040056  E400				   	nop	;			
  91								   			;	
  92  00040058  981Cxxxxxxxx		   	movei	#FireHandGrenade,JMP; set call address
  93  0004005E  7CA0				   	cmpq	#HANDGRENADE,fire;
  94								   			;	
  95								   JMPLabel6:		;
  96  00040060  D382				   	jump	EQ,(JMP); Fire(HANDGRENADE)	
  97  00040062  E400				   	nop	; break;			
  98  00040064  E400				   	nop	;			
  99  00040066  E400				   	nop	;			
 100								   			;	
 101								   JMPLabel7:		;
 102  00040068  981Cxxxxxxxx		   	movei	#FireGrenadeLancher,JMP; set call address
 103  0004006E  7CC0				   	cmpq	#GRENADELANCHER,fire;
 104  00040070  D382				   	jump	EQ,(JMP); Fire(GRENADELANCHER)	
 105  00040072  E400				   	nop	; break;			
 106  00040074  E400				   	nop	;			
 107  00040076  E400				   	nop	;			
 108								   			;	
 109  00040078  981Cxxxxxxxx		   	movei	#FireRocketLauncher,JMP; set call address
 110  0004007E  7CE0				   	cmpq	#ROCKETLAUNCHER,fire;
 111								   			;	
 112								   JMPLabel8:		;
 113  00040080  D382				   	jump	EQ,(JMP); Fire(ROCKETLAUNCHER)	
 114  00040082  E400				   	nop	; break;			
 115  00040084  E400				   	nop	;			
 116  00040086  E400				   	nop	;			
 117								   			;	
 118  00040088  981Cxxxxxxxx		   	movei	#FireHyperBlaster,JMP; set call address
 119  0004008E  7D00				   	cmpq	#HYPERBLASTER,fire;
 120								   			;	
 121								   JMPLabel9:		;
 122  00040090  D382				   	jump	EQ,(JMP); Fire(HYPERBLASTER)	
 123  00040092  E400				   	nop	; break;			
 124  00040094  E400				   	nop	;			
 125  00040096  E400				   	nop	;			
 126								   			;	
 127  00040098  981Cxxxxxxxx		   	movei	#FireRailGun,JMP; set call address
 128  0004009E  7D20				   	cmpq	#RAILGUN,fire;
 129								   			;	
 130								   JMPLabel10:		;
 131  000400A0  D382				   	jump	EQ,(JMP); Fire(RAILGUN)	
 132  000400A2  E400				   	nop	; break;			
 133  000400A4  E400				   	nop	;			
 134  000400A6  E400				   	nop	;			
 135								   			;	
 136  000400A8  981Cxxxxxxxx		   	movei	#FireBFG10K,JMP; set call address
 137  000400AE  7D40				   	cmpq	#BFG10K,fire;
 138								   			;	
 139								   JMPLabel11:		;
 140  000400B0  D382				   	jump	EQ,(JMP); Fire(BFG10K)	
 141  000400B2  E400				   	nop	; break;			
 142  000400B4  E400				   	nop	;			
 143  000400B6  E400				   	nop	;			
 144								   			;	
 145								   DoneFireWeapon:	;
 146  000400B8  D3A0				   	jump	(RET);
 147  000400BA  E400				   	nop	;			
 148  000400BC  E400				   	nop	;			
 149  000400BE  E400				   	nop	;			
 150								   
 151								   EndFireWeapon:	;
 152								   
 153
 154
 155								;///////////////////////////////////////////////////////////////////////////////
 156								   
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169								;///////////////////////////////////////////////////////////////////////////////
 170								;
 171								   FireBlaster:
 172								   	
 173  00040100  xxxx				  W	jr	BlasterFire
 174  00040102  E400				   	nop
 175  00040104  E400				   	nop
 176								   
 177								   BlasterFire:
 178  00040106  E400				   	nop
 179								   
 180  00040108  D3A0				   	jump	(RET)	;
 181  0004010A  E400				   	nop		;			
 182  0004010C  E400				   	nop		;			
 183  0004010E  E400				   	nop		;			
 184								   
 185								;///////////////////////////////////////////////////////////////////////////////
 186								   
 187								;///////////////////////////////////////////////////////////////////////////////
 188								;
 189								   FireShotGun:
 190  00040110  D400					  jr	ShotGunFire
 191  00040112  E400				   	nop
 192  00040114  E400				   	nop
 193								   ShotGunFire:
 194  00040116  E400				   	nop
 195								   
 196								   
 197  00040118  D3A0				   	jump	(RET)	;
 198  0004011A  E400				   	nop		;			
 199  0004011C  E400				   	nop		;			
 200  0004011E  E400				   	nop		;			
 201								   
 202								;///////////////////////////////////////////////////////////////////////////////
 203								   
 204								;///////////////////////////////////////////////////////////////////////////////
 205								;
 206								   FireSuperShotGun:
 207  00040120  D3A0				   	jump	(RET)	;
 208  00040122  E400				   	nop		;			
 209  00040124  E400				   	nop		;			
 210  00040126  E400				   	nop		;			
 211								   
 212								;///////////////////////////////////////////////////////////////////////////////
 213								   
 214								;///////////////////////////////////////////////////////////////////////////////
 215								;
 216								   FireMachineGun:
 217  00040128  D3A0				   	jump	(RET)	;
 218  0004012A  E400				   	nop		;			
 219  0004012C  E400				   	nop		;			
 220  0004012E  E400				   	nop		;			
 221								   
 222								;///////////////////////////////////////////////////////////////////////////////
 223								   
 224								;///////////////////////////////////////////////////////////////////////////////
 225								;
 226								   FireChainGun:
 227  00040130  D3A0				   	jump	(RET)	;
 228  00040132  E400				   	nop		;			
 229  00040134  E400				   	nop		;			
 230  00040136  E400				   	nop		;			
 231								   
 232								;///////////////////////////////////////////////////////////////////////////////
 233								   
 234								;///////////////////////////////////////////////////////////////////////////////
 235								;
 236								   FireHandGrenade:
 237  00040138  D3A0				   	jump	(RET)	;
 238  0004013A  E400				   	nop		;			
 239  0004013C  E400				   	nop		;			
 240  0004013E  E400				   	nop		;			
 241								   
 242								;///////////////////////////////////////////////////////////////////////////////
 243								   
 244								;///////////////////////////////////////////////////////////////////////////////
 245								;
 246								   FireGrenadeLancher:
 247  00040140  D3A0				   	jump	(RET)	;
 248  00040142  E400				   	nop		;			
 249  00040144  E400				   	nop		;			
 250  00040146  E400				   	nop		;			
 251								   
 252								;///////////////////////////////////////////////////////////////////////////////
 253								   
 254								;///////////////////////////////////////////////////////////////////////////////
 255								;
 256								   FireRocketLauncher:
 257  00040148  D3A0				   	jump	(RET)	;
 258  0004014A  E400				   	nop		;			
 259  0004014C  E400				   	nop		;			
 260  0004014E  E400				   	nop		;			
 261								   
 262								;///////////////////////////////////////////////////////////////////////////////
 263								   
 264								;///////////////////////////////////////////////////////////////////////////////
 265								;
 266								   FireHyperBlaster:
 267  00040150  D3A0				   	jump	(RET)	;
 268  00040152  E400				   	nop		;			
 269  00040154  E400				   	nop		;			
 270  00040156  E400				   	nop		;			
 271								   
 272								;///////////////////////////////////////////////////////////////////////////////
 273								   
 274								;///////////////////////////////////////////////////////////////////////////////
 275								;
 276								   FireRailGun:
 277  00040158  D3A0				   	jump	(RET)	;
 278  0004015A  E400				   	nop		;			
 279  0004015C  E400				   	nop		;			
 280  0004015E  E400				   	nop		;			
 281								   
 282								;///////////////////////////////////////////////////////////////////////////////
 283								   
 284								;///////////////////////////////////////////////////////////////////////////////
 285								;
 286								   FireBFG10K:
 287  00040160  D3A0				   	jump	(RET)	;
 288  00040162  E400				   	nop		;			
 289  00040164  E400				   	nop		;			
 290  00040166  E400				   	nop		;			
 291								   
 292								   
 293								   
 294								;///////////////////////////////////////////////////////////////////////////////
 295								;///////////////////////////////////////////////////////////////////////////////
 296								   
 297								   	.phrase
 298								   
 299								   FIREWEAPON:
 300  00040168  00000000			   	dc.l	0


														 Page 8	   11:17:54 am 8-Jul-2009		SMAC 1.0.13 (Win32)
Symbol Table

DoneFireWeapon	000400B8  ag
EndFireWeapon	000400C0  a 
FIREWEAPON	00040168  a 
FireBFG10K	00040160  ag
FireBlaster		00040100  ag
FireChainGun	00040130  ag
FireGrenadeLancher	00040140  ag
FireHandGrenade	00040138  ag
FireHyperBlaster	00040150  ag
FireMachineGun	00040128  ag
FireRailGun	00040158  ag
FireRocketLauncher	00040148  ag
FireShotGun	00040110  ag
FireSuperShotGun	00040120  ag
FireWeapon	00040000  a 

BlasterFire		00040106  a 
ShotGunFire	00040116  a

Edited by Gorf
  • Thanks 1

Share this post


Link to post
Share on other sites

Gorf,

 

We have our huge philosophical differences of opinions that I doubt will ever get reconciled, but I applaud you for doing this :)

 

More source code, more knowledge, less politics. More games. More fun times please. Despite how things get "packaged and sold/distro'd" we all want to see more/better games. It might be the only thing we'll ever agree on, but it is something.

  • Like 1

Share this post


Link to post
Share on other sites
Gorf,

 

We have our huge philosophical differences of opinions that I doubt will ever get reconciled, but I applaud you for doing this :)

 

Thanks, but our 'rifts' are probably not nearly as wide as they may come across. I've had similar battles with Owl,

only to grow to respect and admire the man and his ability to code the Jag.

 

More source code, more knowledge, less politics. More games. More fun times please. Despite how things get "packaged and sold/distro'd" we all want to see more/better games. It might be the only thing we'll ever agree on, but it is something.

 

 

I've been doing all I know to contribute all of the above since I first got my JagServer many moons ago. The problem is most people don't

bother to look for that. They tend to look for all the ugly. Human nature I suppose....guilty as charged.

 

 

Oh and BTW, you did not tell me what I was looking for about the example. ;)

Edited by Gorf

Share this post


Link to post
Share on other sites
  173  00040100  xxxx				  W	jr	BlasterFire
 174  00040102  E400				   	nop
 175  00040104  E400				   	nop
 176								   
 177								   BlasterFire:
 178  00040106  E400				   	nop
 179								   
 180  00040108  D3A0				   	jump	(RET);
 181  0004010A  E400				   	nop	;			
 182  0004010C  E400				   	nop	;			
 183  0004010E  E400				   	nop	;			
 184

 

One question?

 

Why you jump to a relative jump? if you remove jr Blasterfire it's just the same, or maybe is just a small template?

Share this post


Link to post
Share on other sites
  173  00040100  xxxx				  W	jr	BlasterFire
 174  00040102  E400				   	nop
 175  00040104  E400				   	nop
 176								   
 177								   BlasterFire:
 178  00040106  E400				   	nop
 179								   
 180  00040108  D3A0				   	jump	(RET);
 181  0004010A  E400				   	nop;			
 182  0004010C  E400				   	nop;			
 183  0004010E  E400				   	nop;			
 184

 

One question?

 

Why you jump to a relative jump? if you remove jr Blasterfire it's just the same, or maybe is just a small template?

 

Again it's just a shell of code. The code does not actually do anything so a NOP is just as appropriate....pretend it's

something useful. The more important issue here is where it is jumping to.

Share this post


Link to post
Share on other sites

Great move Gorf!

 

I do the exercise:

 

So the jump/jr are all aligned on 8 bytes (ie a phrase) boundary.

 

The target labels of jump instructions are also aligned on 8 bytes boundary.

 

On the contrary, the target labels of jr instructions do not seem to be especially aligned.

Share this post


Link to post
Share on other sites

I don't know anything about programming, but it's very nice to see this kind of things happening :)

Share this post


Link to post
Share on other sites
Great move Gorf!

 

I do the exercise:

 

So the jump/jr are all aligned on 8 bytes (ie a phrase) boundary.

 

The target labels of jump instructions are also aligned on 8 bytes boundary.

 

On the contrary, the target labels of jr instructions do not seem to be especially aligned.

 

Yes, the jumps are indeed aligned on 8 byte boundaries, however, that is only a result of

the necessary instructions between them. We know that 8 bytes are a phrase in Jaguar

terminology. You are geting warm though. Here is a hint: You are correct x 2. I know I

said the GPU sees memory externally at 64 bits but it does still 'understand' smaller data.

 

Keep in mind the host processor determines some limitations for the GPU as well.

 

The JR instructions DESTINATIONS are also very much aligned. But first you need to reconcile

the above JUMP issues.

 

Seb is getting warmer though folks.

Edited by Gorf

Share this post


Link to post
Share on other sites

That facts is, the example does not show everything. In fact as I look at it, it lacks a few things.

I will post yet another example but this one was to get you thinking. The wonderful thing about

the bug is it is consistant. There is no random failure. That is a mis-diagnosis.

 

I can sum up the entire workaround in four simple rules. All four rules involve alignment. All

four rules are consistant. The fact is BUG in main is almost not accurate. It's better to look

at it as a more of a difference of operation between internal and external. An oversite in

design is better. The code never fails as long as the rules are followed. One wrong jump

and its 'Coytin's Rocky! See? Coytin's '...."aw...they're adorable!" Little Bugs humor there. ;)

Edited by Gorf

Share this post


Link to post
Share on other sites

The following is perfectly valid code. Again observe the jump placement and destinations...

 

Ship .equr r14

JMP .equr r28

FNRT .equr r29

 

4000000 movei #CenterShip,JMP

4000006 movei #PlayerShip,Ship

400000C jump (JMP)

400000E nop

BackHome:

4000010 nop

...

...

...

...

 

CenterShip:

4000100 moveq #0,r0 ; center ship

4000102 store r0,(Ship+XPOSI) ; set x position

4000104 store r0,(Ship+ZPOSI) ; set z position

4000106 movei #BackHome,FNRT ; return address

 

400010C jump (FNRT) ; return to caller

400010E nop ;

4000110 nop ;

...

...

...

...

 

 

Seb,

 

Compare this jump and what you said about the jumps before I posted this and try again. :)

Also there is one other thing common to both JR and JUMP...not so much them but what follows.

Here's a hint: Double a known jump rule.

Edited by Gorf

Share this post


Link to post
Share on other sites
Great move Gorf!

 

I do the exercise:

 

So the jump/jr are all aligned on 8 bytes (ie a phrase) boundary.

 

The target labels of jump instructions are also aligned on 8 bytes boundary.

 

On the contrary, the target labels of jr instructions do not seem to be especially aligned.

 

Yes, the jumps are indeed aligned on 8 byte boundaries, however, that is only a result of

the necessary instructions between them. We know that 8 bytes are a phrase in Jaguar

terminology. You are geting warm though. Here is a hint: You are correct x 2. I know I

said the GPU sees memory externally at 64 bits but it does still 'understand' smaller data.

 

Keep in mind the host processor determines some limitations for the GPU as well.

 

The JR instructions DESTINATIONS are also very much aligned. But first you need to reconcile

the above JUMP issues.

 

Seb is getting warmer though folks.

 

Ok, so if I understand, it is sufficient that everything (jump instructions as well as target labels) are aligned on four bytes (ie just a long word)?

 

For relative jumps, I need to examine closely again your piece of code.

 

Also, I am not sure I have understood the memory page issue...

Edited by SebRmv

Share this post


Link to post
Share on other sites

Are we headed toward a relationship between the JMP, state of the pipeline, and memory alignment, or are there other factors I'm missing, or not yet revealed?

 

I'm following this with interest.

Edited by potatohead

Share this post


Link to post
Share on other sites
Ok, so if I understand, it is sufficient that everything (jump instructions as well as target labels) are aligned on four bytes (ie just a long word)?

 

 

The last part of this is right, so far you have one half of one rule correct. The first part is

half correct and depends on where it is your are jumping to....I did mention pages.....

 

Also, I am not sure I have understood the memory page issue...

 

You will need to so the best way to illustrate pages is as follows.

 

A page externally to the GPU is 256 byte boundaries starting from $00000000

 

$00000100 page 1

$00000200 page 2

$00000300 page 3

$00000400 page 4

$00000500 page 5

$00000600 page 6

and so on

Share this post


Link to post
Share on other sites
Are we headed toward a relationship between the JMP, state of the pipeline, and memory alignment, or are there other factors I'm missing, or not yet revealed?

 

Yes, but I do not intend to give a lesson on common knowledge about pipelines. The docs cover this.

Consider the docs your study guide, keeping in mind it has a few flaws. This excersize corrects that

particular flaw. I certainly is a good place to studdy concering this though. You wont find the answers

directly however.

 

I'm following this with interest.

 

Good. Im glad to see that. :)

Share this post


Link to post
Share on other sites

One more strong piece of code for you.

 

Here is actual code from one of my main code based games.

This pretty much shows all the rules of main.

 

Called from the main loop at address 00040084

 

 

 

MoveCannon:
movei #AimCannonRET,RET
store r1,(r0)
movei #_AIMTIMER,r2
load (r2),r3
cmpq #0,r3
jr EQ,CannonMove
nop
nop

subqt #1,r3
store r3,(r2)

MoveCannonJ1:
jump (RET)
nop
nop

CannonMove:
moveq #3,r3
store r3,(r2)
nop
movei #_HOTSPOT,r0
load (r0),r2
cmp r1,r2
jr NE,SubCannon
nop
nop

MoveCannonJ2:
jump (RET)
nop
nop

SubCannon:
sub r1,r2
moveq #15,r3
and r3,r2
cmpq #8,r2
jr PL,IncHotSpot
nop
nop

load (r0),r2
subqt #1,r2
jr DecHotSpot
nop
nop

IncHotSpot:
load (r0),r2
addqt #1,r2

DecHotSpot:
moveq #15,r3
and r3,r2
store r2,(r0)

movei #CannonAngles,r1
shlq #2,r2
movefa KVECT,Cannon 
add r2,r1
load (r1),r0	
store r0,(Cannon+YBETA)		

DoneMoveCannon:	 
jump (RET)	
nop	 
nop	 
nop	 

Label table

MoveCannon		   = 00041000
MoveCannonJ1		 = 0004101C
MoveCannonJ2		 = 00041038
DoneMoveCannon	   = 00041070

CannonMove		   = 00041022
SubCannon			= 0004103E
IncHotSpot		   = 00041056
DecHotSpot		   = 0004105A

AimCannonRET   = 0004008C

 

You are on your own from this point on.... ;)

Share this post


Link to post
Share on other sites

Gorf's doing well showing allthis so i'll leave it up to him.

 

All i'll add is that there is an extra consideration concerning pipelines for jumps between main and local

Share this post


Link to post
Share on other sites
Gorf's doing well showing allthis so i'll leave it up to him.

 

All i'll add is that there is an extra consideration concerning pipelines for jumps between main and local

 

 

Since it is your discovery, I'll leave the main to local and reverse to you to hint at. ;)

Share this post


Link to post
Share on other sites

Here is a better detailed version with addresses to make it even easier.

 

 

Called from loop at  = 00040084 
AimCannonRET		 = 0004008C 

MoveCannon		   = 00041000
MoveCannonJ1		 = 0004101C
MoveCannonJ2		 = 00041038
DoneMoveCannon	   = 00041070

CannonMove		   = 00041022
SubCannon			= 0004103E
IncHotSpot		   = 00041056
DecHotSpot		   = 0004105A


MoveCannon:
41000	movei	#AimCannonRET,RET
41006	store	r1,(r0)

41008	movei	#_AIMTIMER,r2
4100E	load	(r2),r3
41010	cmpq	#0,r3
41012	jr	EQ,CannonMove
41014	nop
41016	nop

41018	subqt	#1,r3
4101A	store	r3,(r2)

MoveCannonJ1:
4101C	jump	(RET)
4101E	nop
41020	nop

CannonMove:
41022	nop
41024	moveq	#3,r3
41026	store	r3,(r2)

41028	movei	#_HOTSPOT,r0
4102E	load	(r0),r2
41030	cmp	r1,r2
41032	jr	NE,SubCannon
41034	nop
41036	nop

MoveCannonJ2:
41038	jump	(RET)
4103A	nop
4103C	nop

SubCannon:
4103E	sub	r1,r2
41040	moveq	#15,r3
41042	and	r3,r2
41044	cmpq	#8,r2
41046	jr	PL,IncHotSpot
41048	nop
4104A	nop

4104C	load	(r0),r2
4104E	subqt	#1,r2
41050	jr	DecHotSpot
41052	nop
41054	nop

IncHotSpot:
41056	load	(r0),r2
41058	addqt	#1,r2

DecHotSpot:
4105A	moveq	#15,r3
4105C	and	r3,r2
4105E	store	r2,(r0)

41060	movei	#CannonAngles,r1
41066	shlq	#2,r2
41068	movefa	KVECT,Cannon
4106A	add	r2,r1
4106C	load	(r1),r0
4106E	store	r0,(Cannon+YBETA)

DoneMoveCannon:
41070	jump	(RET)
41072	nop
41074	nop

Share this post


Link to post
Share on other sites

Oh....alright.......Im practically giving it away here but I think this might trigger it for some of you.

I'll break it down even further.

 

 

Page $40000

Called from loop at = 00040084

AimCannonRET = 0004008C

 

page $41000

 

entry address....hint: Called from another page.

MoveCannon = 00041000

 

alignment labels to assure jumps are in the right spot (not really needed with SMAC but it helps to visualize.)

MoveCannonJ1 = 0004101C

MoveCannonJ2 = 00041038

 

Aligned jump back to caller page.

DoneMoveCannon = 00041070

 

jumps within same page.

CannonMove = 00041022

SubCannon = 0004103E

IncHotSpot = 00041056

DecHotSpot = 0004105A

 

 

If someone does not get this now, Im going to scream. :)

Share this post


Link to post
Share on other sites
If someone does not get this now, Im going to scream. :)
Sorry dude, I haven't had the time to trace through it all yet ;)

Share this post


Link to post
Share on other sites
If someone does not get this now, Im going to scream. :)
Sorry dude, I haven't had the time to trace through it all yet ;)

 

I here you but it's so right in front of you now. That last post is screaming "HERE I AM!!! THE WORKAROUND!!!".

Look at the to and from addresses. It's were the entire workaround lies.

 

Four rules. That is all. :) Three are obvious and one not so obvious but can be understood from the others.

Actually five rules. The other important thing is what always follows the jump/jr's.

Share this post


Link to post
Share on other sites

Member Rdemming From JSII is the first to figure out my riddles of main

code. He has figured out all four(five actually) rules. Come on guys, you

can do this.

Edited by Gorf

Share this post


Link to post
Share on other sites

I'm not surprised Robert did, he's a clever guy

 

 

All i really have to add to the threads is that for the switch between local and mainits of course not inpage and its useful sometimes to purge the pipeline

Share this post


Link to post
Share on other sites

Finally fot some time to analyse a bit further.

 

First recapitulate the labels (actually you gave this)

 

Called from loop at = 00040084 
AimCannonRET		 = 0004008C 

MoveCannon		   = 00041000
MoveCannonJ1		 = 0004101C
MoveCannonJ2		 = 00041038
DoneMoveCannon	   = 00041070

CannonMove		   = 00041022
SubCannon			= 0004103E
IncHotSpot		   = 00041056
DecHotSpot		   = 0004105A

 

The jumps

41012	jr	EQ,CannonMove
4101C	jump	(RET)
41032	jr	NE,SubCannon
41038	jump	(RET)
41046	jr	PL,IncHotSpot
41050	jr	DecHotSpot
41070	jump	(RET)

 

Regarding the absolute jumps.

 

They are all aligned on 4 bytes.

Target labels are also aligned on 4 bytes.

They are followed by at least two nops, is it intended?

 

Regarding the relative jumps.

 

I don't really see a rule here, apart from the fact that they are always followed by two nops.

 

--

 

My guess was that:

- for intra-page jumps, jump and target are aligned on 4 bytes.

- for inter-page jumps, same rule applies but the pipeline should be emptied to the next phrase boundary before the jump occurs (ie add sufficiently enough nops to prevent unexpected results).

Share this post


Link to post
Share on other sites
They are all aligned on 4 bytes.

 

Which instruction? JUMP, JR or both.....look at the example carefully before you answer.

 

 

Target labels are also aligned on 4 bytes.

 

When are they aligned on a long address? And are they always? Again,

look carefully.

 

 

They are followed by at least two nops, is it intended?

 

Ok so far you have rule five correct. :) Yes Two nops are quite necessary

after either a JUMP or JR.

 

 

So far we have one out of five rules solid. Come folks! 4 more to go and Seb

is really close to the rest of them.

 

 

They are all aligned on 4 bytes

My guess was that:

- for intra-page jumps, jump and target are aligned on 4 bytes.

 

What do you mean by intra page jumps? Either you are local to the page(256 bytes) or you are not local.

Alignments to local or external are different.

 

They are all aligned on 4 bytes

- for inter-page jumps, same rule applies but the pipeline should be emptied to the next phrase boundary before the jump occurs (ie add sufficiently enough nops to prevent unexpected results).

 

It's not so much you making sure the pipeline gets emptied. It's more a question of when the instruction WILL empty the pipeline.

 

But this is over analyzing still. The pipeline plays and important part but not an overly complicated part. You really do not need to

know that to get the alignments right.

Edited by Gorf

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...