|  | @@ -0,0 +1,217 @@
 | 
	
		
			
				|  |  | +.align 2
 | 
	
		
			
				|  |  | +.thumb
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*A very pertinent problem arose from the study of Variables. The fact is, we
 | 
	
		
			
				|  |  | +never knew much about them, and just used them. But in the end, those variables
 | 
	
		
			
				|  |  | +were, in fact, pieces of other program's memory. Solution is to find a location
 | 
	
		
			
				|  |  | +where we can lay our own variables, and use those to our advantage.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Every pokemon game accesses variables through the same mechanism every time.
 | 
	
		
			
				|  |  | +Variable is accessed by using a call to a specialized function, that because of
 | 
	
		
			
				|  |  | +its lack of boundaries, let us use every piece of code there as our own.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +The proposed solution is to find a large RAM address (0x1000 long) and use it to
 | 
	
		
			
				|  |  | +make a place for 0x800 variables (something like 0x5000 to 0x57ff.) This should
 | 
	
		
			
				|  |  | +be enough for most games, and they're perfectly safe. Then, during the Save and
 | 
	
		
			
				|  |  | +Load Routines, add a new module to load from 0xe01f000 (bank1, slot f), that is
 | 
	
		
			
				|  |  | +unused by the game, and can carry that much information.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Also proposed, to solve the problem, is to use any variable from 0x5800 to 0x5fff
 | 
	
		
			
				|  |  | +as a mirror to the first pair, any variable from 0x6000 to 0x6fff as a byte-load
 | 
	
		
			
				|  |  | +for the 0x5000 variables, and any from the 0x7000 as a word-load for the 0x5000
 | 
	
		
			
				|  |  | +variable family, and 0x7400-0x7fff as flag-load for some select few.*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*first, and most important, we need the 0x5000 flags stored somewhere, even if 
 | 
	
		
			
				|  |  | +the game didn't save them. That is where the Var-Decrypt come in.*/
 | 
	
		
			
				|  |  | +/*var decrypt is located at 0x0806E454. Because most of the code is harmless in
 | 
	
		
			
				|  |  | +its own, we will only change the part that loads variables above 0x4000 and below
 | 
	
		
			
				|  |  | +0x8000. That is located at 0x6e4f2. We change 0x6e4f4 to 0x10 47, and place the 
 | 
	
		
			
				|  |  | +pointer to this function at 0x6e508
 | 
	
		
			
				|  |  | +Even though Emerald code is different, it's in fact much simpler. As such all
 | 
	
		
			
				|  |  | +old rules apply. at 0809D682 place 10 47 and at 0809D690 the pointer*/
 | 
	
		
			
				|  |  | +/*begin*/
 | 
	
		
			
				|  |  | +Var_decrypt_change:		mov r1, #0x50
 | 
	
		
			
				|  |  | +						lsl r1, r1, #0x8
 | 
	
		
			
				|  |  | +						sub r1, r6, r1  /*if it is lower than 0x5000, it will be less than 0*/
 | 
	
		
			
				|  |  | +						cmp r1, #0x0
 | 
	
		
			
				|  |  | +						blt is_4xxx
 | 
	
		
			
				|  |  | +						mov r2, #0x80
 | 
	
		
			
				|  |  | +						lsl r2, r2, #0x4
 | 
	
		
			
				|  |  | +						cmp r1, r2		/*r2 = 0x800*/
 | 
	
		
			
				|  |  | +						blt load_5xxx
 | 
	
		
			
				|  |  | +						sub r1, r1, r2
 | 
	
		
			
				|  |  | +						cmp r1, r2     /*r2 = 0x800, this is the mirrored line*/
 | 
	
		
			
				|  |  | +						blt load_5xxx
 | 
	
		
			
				|  |  | +						sub r1, r1, r2
 | 
	
		
			
				|  |  | +						lsl r2, #0x1
 | 
	
		
			
				|  |  | +						cmp r1, r2
 | 
	
		
			
				|  |  | +						blt load_6xxx
 | 
	
		
			
				|  |  | +						sub r1, r1, r2
 | 
	
		
			
				|  |  | +						lsr r2, r2, #0x2
 | 
	
		
			
				|  |  | +						cmp r1, r2
 | 
	
		
			
				|  |  | +						blt load_7xxx
 | 
	
		
			
				|  |  | +						mov r0, #0x0
 | 
	
		
			
				|  |  | +						pop {r4-r6,pc}
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +is_4xxx:				ldr r2, mask_9x
 | 
	
		
			
				|  |  | +						lsl r1, r6, #0x1
 | 
	
		
			
				|  |  | +						add r1, r2, r1
 | 
	
		
			
				|  |  | +						ldr r0, [r0]
 | 
	
		
			
				|  |  | +						add r0, r0, r1
 | 
	
		
			
				|  |  | +						pop {r4-r6,pc}
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +load_7xxx:				lsl r1, r1, #0x1	/*r1<<2 = word address */
 | 
	
		
			
				|  |  | +load_5xxx:				lsl r1, r1, #0x1	/*r1 << 1 = halfword address*/
 | 
	
		
			
				|  |  | +load_6xxx:				ldr r0, new_var_location	/*no shift means byte address*/
 | 
	
		
			
				|  |  | +						add r0, r0, r1
 | 
	
		
			
				|  |  | +						pop {r4-r6,pc}
 | 
	
		
			
				|  |  | +.hword 0x0000
 | 
	
		
			
				|  |  | +mask_9x: .word 0xffff9000						/*for Emerald, it's 0xffff939c*/
 | 
	
		
			
				|  |  | +new_var_location:	.word 0x0203e000
 | 
	
		
			
				|  |  | +/*end*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*the other way to load variables is through the Variable Loader. But that raises
 | 
	
		
			
				|  |  | +a problem: It only loads halfwords. To solve that problem, at 0806e574, place
 | 
	
		
			
				|  |  | +0049 0847 pointer to this
 | 
	
		
			
				|  |  | +In Emerald, place at 0809d6a0 the 0049 0847 pointer to this
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +/*begin*/
 | 
	
		
			
				|  |  | +VarLoader_change:		cmp r0, #0x0
 | 
	
		
			
				|  |  | +						beq no_variable_loaded
 | 
	
		
			
				|  |  | +						mov r1, #0x60
 | 
	
		
			
				|  |  | +						lsl r1, r1, #0x8
 | 
	
		
			
				|  |  | +						sub r1, r4, r1
 | 
	
		
			
				|  |  | +						cmp r1, #0x0
 | 
	
		
			
				|  |  | +						blt var_load_hword
 | 
	
		
			
				|  |  | +						mov r2, #0x80
 | 
	
		
			
				|  |  | +						lsl	r2, r2, #0x8
 | 
	
		
			
				|  |  | +						cmp r4, r2
 | 
	
		
			
				|  |  | +						bge var_load_hword
 | 
	
		
			
				|  |  | +						lsr r2, r2, #0x3
 | 
	
		
			
				|  |  | +						sub r1, r1, r2
 | 
	
		
			
				|  |  | +						cmp r1, #0x0
 | 
	
		
			
				|  |  | +						blt var_load_byte
 | 
	
		
			
				|  |  | +						ldr r0, [r0]
 | 
	
		
			
				|  |  | +						pop {r4,pc}
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +no_variable_loaded:		add r0, r4, #0x0
 | 
	
		
			
				|  |  | +						pop {r4, pc}
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +var_load_byte:			ldrb r0, [r0]
 | 
	
		
			
				|  |  | +						pop {r4,pc}						
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +var_load_hword:			ldrh r0, [r0]
 | 
	
		
			
				|  |  | +						pop {r4,pc}
 | 
	
		
			
				|  |  | +.hword 0x0000						
 | 
	
		
			
				|  |  | +/*end*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*var store will be fixed for Storing only 0x4000-0x6fff.
 | 
	
		
			
				|  |  | +That way, you can have byte storage for variables
 | 
	
		
			
				|  |  | +In Fire Red, place at 0x0806E584 30 b5 05 04 28 0c
 | 
	
		
			
				|  |  | +				   at 0x0806E592 01 49 08 47 00 00 pointer
 | 
	
		
			
				|  |  | +In Emerald, place at 0x0809d6b0 30 b5 05 04 28 0c
 | 
	
		
			
				|  |  | +				  at 0x0809d6be 01 49 08 47 00 00 pointer
 | 
	
		
			
				|  |  | +				  */
 | 
	
		
			
				|  |  | +/*begin*/
 | 
	
		
			
				|  |  | +Var_store_cont:			cmp r0, #0x0
 | 
	
		
			
				|  |  | +						beq no_store
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +						mov r1, #0x60
 | 
	
		
			
				|  |  | +						lsl r1, r1, #0x8
 | 
	
		
			
				|  |  | +						sub r1, r5, r1
 | 
	
		
			
				|  |  | +						cmp r1, #0x0
 | 
	
		
			
				|  |  | +						blt var_store_hword
 | 
	
		
			
				|  |  | +						mov r2, #0x80
 | 
	
		
			
				|  |  | +						lsl	r2, r2, #0x8
 | 
	
		
			
				|  |  | +						cmp r5, r2
 | 
	
		
			
				|  |  | +						bge var_store_hword
 | 
	
		
			
				|  |  | +						lsr r2, r2, #0x3
 | 
	
		
			
				|  |  | +						sub r1, r1, r2
 | 
	
		
			
				|  |  | +						cmp r1, #0x0
 | 
	
		
			
				|  |  | +						blt var_store_byte
 | 
	
		
			
				|  |  | +no_store:				pop {r4-r5,pc}
 | 
	
		
			
				|  |  | +												
 | 
	
		
			
				|  |  | +var_store_byte:			strb r4, [r0]
 | 
	
		
			
				|  |  | +						pop {r4-r5,pc}						
 | 
	
		
			
				|  |  | +						
 | 
	
		
			
				|  |  | +var_store_hword:		strh r4, [r0]
 | 
	
		
			
				|  |  | +						pop {r4-r5,pc}									
 | 
	
		
			
				|  |  | +/*end*/
 | 
	
		
			
				|  |  | +/*finally, we need to save those variables from being purged at the end of the 
 | 
	
		
			
				|  |  | +game. So, we will modify the Save file to allow us to keep the variables 
 | 
	
		
			
				|  |  | +somewhere where nobody gets hurt (bank 0x1f)*/
 | 
	
		
			
				|  |  | +/*this first code is the save one, and allows us to save the new variable
 | 
	
		
			
				|  |  | +location at bank 0x1f. for that, we need to edit the code at 080D9838, right
 | 
	
		
			
				|  |  | +after the standart save is finished. Lucky, that is a load that has a pointer!
 | 
	
		
			
				|  |  | +Then, change 0x080d983a with 00 47 and 0x080D986C with the pointer to this.
 | 
	
		
			
				|  |  | +In Emerald, change 0x0815276a with 00 47 and 0x0815279C with the pointer */
 | 
	
		
			
				|  |  | +/*begin*/
 | 
	
		
			
				|  |  | +Save_vars:			mov r0, #0x1f
 | 
	
		
			
				|  |  | +					ldr r1, variable_new_addr
 | 
	
		
			
				|  |  | +					bl SetFlash4k
 | 
	
		
			
				|  |  | +					ldr r1, Save_ret
 | 
	
		
			
				|  |  | +					sub r6, #0x4
 | 
	
		
			
				|  |  | +					ldr r0, [r6]
 | 
	
		
			
				|  |  | +					add r6, #0x4
 | 
	
		
			
				|  |  | +					bx r1
 | 
	
		
			
				|  |  | +.hword 0x0000
 | 
	
		
			
				|  |  | +Save_ret: .word 0x080D983d /*in Emerald, change this to 0815276d*/
 | 
	
		
			
				|  |  | +				
 | 
	
		
			
				|  |  | +/*end*/
 | 
	
		
			
				|  |  | +/*then we also need the Load code. This one is more wordy, as we need to 
 | 
	
		
			
				|  |  | +load byte by byte the entire content we need from the Flash.
 | 
	
		
			
				|  |  | +In Emerald, the location to change is 0x08152ea0
 | 
	
		
			
				|  |  | +In fire red, the location to change is 0x080D9EE4
 | 
	
		
			
				|  |  | +place a 0048 0047 pointer. We'll take care of exiting the
 | 
	
		
			
				|  |  | +function*/
 | 
	
		
			
				|  |  | +/*begin*/
 | 
	
		
			
				|  |  | +Load_Vars:		bl SetSecondBank
 | 
	
		
			
				|  |  | +				ldr r0, variable_new_addr
 | 
	
		
			
				|  |  | +				mov r1, #0xf0
 | 
	
		
			
				|  |  | +				lsl r1, r1, #0x8
 | 
	
		
			
				|  |  | +				orr r3, r1
 | 
	
		
			
				|  |  | +				mov r2, #0x10
 | 
	
		
			
				|  |  | +				lsl r2, r2, #0x8
 | 
	
		
			
				|  |  | +byte_load_loop: ldrb r1, [r3]
 | 
	
		
			
				|  |  | +				strb r1, [r0]
 | 
	
		
			
				|  |  | +				add r0, #0x1
 | 
	
		
			
				|  |  | +				add r3, #0x1
 | 
	
		
			
				|  |  | +				sub r2, #0x1
 | 
	
		
			
				|  |  | +				cmp r2, #0x0
 | 
	
		
			
				|  |  | +				bgt byte_load_loop
 | 
	
		
			
				|  |  | +				add r0, r5, #0x0
 | 
	
		
			
				|  |  | +				pop {r1}
 | 
	
		
			
				|  |  | +				mov r8, r1
 | 
	
		
			
				|  |  | +				pop {r4-r7, pc}
 | 
	
		
			
				|  |  | +.hword 0x0000				
 | 
	
		
			
				|  |  | +/*end*/
 | 
	
		
			
				|  |  | +variable_new_addr:	.word 0x0203e000
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +SetFlash4k:		ldr r3, set_flash_addr
 | 
	
		
			
				|  |  | +				bx r3
 | 
	
		
			
				|  |  | +set_flash_addr: .word 0x081DF071 	/*for emerald, 0x082E20Ad*/				
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +SetSecondBank:	mov r3, #0x0e
 | 
	
		
			
				|  |  | +				mov r2, #0x55
 | 
	
		
			
				|  |  | +				lsl r3, r3, #0x18
 | 
	
		
			
				|  |  | +				lsl r1, r2, #0x8	/*r1 = 5500*/
 | 
	
		
			
				|  |  | +				orr r1, r3 			/*r1 = 0e005500*/
 | 
	
		
			
				|  |  | +				orr r1, r2 			/*r1 = 0e005555*/
 | 
	
		
			
				|  |  | +				mov r0, #0xAA
 | 
	
		
			
				|  |  | +				strb r0, [r1]
 | 
	
		
			
				|  |  | +				mov r2, #0x2a 
 | 
	
		
			
				|  |  | +				lsl r2, r2, #0x8	/*r2 = 2a00*/
 | 
	
		
			
				|  |  | +				orr r2, r0 			/*r2 = 2aaa*/
 | 
	
		
			
				|  |  | +				orr r2, r3 			/*r2 = 0e002aaa*/
 | 
	
		
			
				|  |  | +				mov r0, #0x55
 | 
	
		
			
				|  |  | +				strb r0, [r2]		
 | 
	
		
			
				|  |  | +				mov r0, #0xb0		
 | 
	
		
			
				|  |  | +				strb r0, [r1]
 | 
	
		
			
				|  |  | +				mov r0, #0x1
 | 
	
		
			
				|  |  | +				strb r0, [r3]
 | 
	
		
			
				|  |  | +				bx lr
 | 
	
		
			
				|  |  | +				
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 |