· 6 years ago · Mar 06, 2019, 08:38 PM
1Fire Red RAM Map:
2
30x02036DFC Current Map Header
40x0202271C
5Player
6
7X = [0x03005008] + 0x000
8Y = [0x03005008] + 0x002
9Map Number = [0x03005008] + 0x005
10Money
11
12Key = [0x0300500C] + 0x0F20
13Money_Hidden = [0x03005008] + 0x0218 (possibly + 0x0290)
14Money = Money XOR Key
15
16Standard:
170x02002D40 ? Start of data that apparently controls
18 the colors of the pixels inside of the
19 current box (menu, msgbox, etc.).
200x020204B4 12b Dialog box 1
210x020204C0 12b Dialog box 2
220x020204CC 12b Dialog box 3
230x020204D8 12b Dialog box 4
240x020204E4 12b Dialog box 5
250x020204F0 12b Dialog box 6
260x020204FC 12b Dialog box 7
270x02020508 12b Dialog box 8
280x02020514 12b Dialog box 9
290x02020520 12b Dialog box 10
300x0202052C 12b Dialog box 11
310x02020538 12b Dialog box 12
320x02020544 12b Dialog box 13
330x02020550 12b Dialog box 14
340x0202055C 12b Dialog box 15
350x02020568 12b Dialog box 16
360x02020574 12b Dialog box 17
370x02020580 12b Dialog box 18
380x0202058C 12b Dialog box 19
390x02020598 12b Dialog box 20
400x020205A4 12b Dialog box 21
410x020205B0 12b Dialog box 22
420x020205BC 12b Dialog box 23
430x020205C8 12b Dialog box 24
440x020205D4 12b Dialog box 25
450x020205E0 12b Dialog box 26
460x020205EC 12b Dialog box 27
470x020205F8 12b Dialog box 28
480x02020604 12b Dialog box 29
490x02020610 12b Dialog box 30
500x0202061C 12b Dialog box 31
510x02020628 12b Dialog box 32
520x02021CD0 32b String buffer 0
530x02021CF0 20b String buffer 1
540x02021D04 20b String buffer 2
55
560x02021D18 ? String to be displayed in a message box
570x02022B4B 1b Flags for current battle?
580x02022B4C 4b Flags for current battle? Set to 0x8 by repeattrainerbattle.
590x02023E8A 1b Repeattrainerbattle: Unknown. Loaded if battle type is 9.
600x02024029 1b Repeattrainerbattle: Unknown. Loaded if battle type is 9.
61
620x0202402C 100b Enemy Pokemon 1
630x02024090 100b Enemy Pokemon 2
640x020240F4 100b Enemy Pokemon 3
650x02024158 100b Enemy Pokemon 4
660x020241BC 100b Enemy Pokemon 5
670x02024220 100b Enemy Pokemon 6
68
690x02024284 100b Party Pokemon 1
700x020242E8 100b Party Pokemon 2
710x0202434C 100b Party Pokemon 3
720x020243B0 100b Party Pokemon 4
730x02024414 100b Party Pokemon 5
740x02024478 100b Party Pokemon 6
75
760x02031DB4 1b Previous map bank number
770x02031DB5 1b Previous map number
780x02031DB6 1b Warp through which the player entered the current map?
790x02031DB7 1b Padding?
800x02031DB8 2b X where player entered previous map, or 0xFFFF if unused.
81 (Only seems to be used when the warp was a door.)
820x02031DBA 2b Y where player entered previous map, or 0xFFFF if unused.
83 (Only seems to be used when the warp was a door.)
840x02031DBC 1b Current map bank number
850x02031DBD 1b Current map number
860x02031DBE 1b Warp through which the player entered the current map?
870x02031DBF 1b Padding?
880x02031DC0 2b X where player entered current map, or 0xFFFF if unused.
89 (Only seems to be used when the warp was a door.)
900x02031DC2 2b Y where player entered current map, or 0xFFFF if unused.
91 (Only seems to be used when the warp was a door.)
920x02031DC3 1b Padding?
930x02031DC4 1b Current2 map bank number
940x02031DC5 1b Current2 map number
950x02031DC6 1b Warp through which the player entered the current2 map?
960x02031DC7 1b Padding?
970x02031DC8 2b X where player entered current2 map, or 0xFFFF if unused.
98 (Only seems to be used when the warp was a door.)
990x02031DCA 2b Y where player entered current2 map, or 0xFFFF if unused.
100 (Only seems to be used when the warp was a door.)
1010x02031DCC 1b Current3 map bank number
1020x02031DCD 1b Current3 map number
1030x02031DCE 1b Warp through which the player entered the current3 map?
1040x02031DCF 1b Padding?
1050x02031DD0 2b X where player entered current3 map, or 0xFFFF if unused.
106 (Only seems to be used when the warp was a door.)
1070x02031DD2 2b Y where player entered current3 map, or 0xFFFF if unused.
108 (Only seems to be used when the warp was a door.)
1090x02031DD4 3b? Warping: Unknown. Always set to 01 01 00 when "warp" and
110 "warpmuted" finish, but not when "warp3" finishes. While
111 walking into a door warp, the second byte is 02.
1120x02031DD7 1b Warping: Unknown. Seems to always be 0x03.
1130x02031DD8 1b Warping: Unknown. If non-zero, "warp" fails to play a
114 sound.
1150x02031DDA 2b? Unknown. Changes every time you warp.
1160x02036E38 36b OW 00 (player)
1170x02036E5C 36b OW 01
1180x02036E80 36b OW 02
1190x02036EA4 36b OW 03
1200x02036EC8 36b OW 04
1210x02036EEC 36b OW 05
1220x02036F10 36b OW 06
1230x02036F34 36b OW 07
1240x02036F58 36b OW 08
1250x02036F7C 36b OW 09
1260x02036FA0 36b OW 10
1270x02036FC4 36b OW 11
1280x02036FE8 36b OW 12
1290x0203700C 36b OW 13
1300x02037030 36b OW 14
1310x02037054 36b OW 15
132
1330x02037078 1b Three least-significant bits control player speed.
1340x02037079 1b Something to do with switching into biking OW?
1350x0203707A 1b Is a D-pad button pressed (player attempting to move)?
1360x0203707B 1b Is the player actually moving?
1370x0203707C 1b Unknown.
1380x0203707D 1b Person number to be controlled by the D-pad.(mind control? hahaha)
1390x0203707E 1b If set to 0x01, all OW movement is locked. (lockall flag?)
140
1410x020370B8 2b Script variable 0x8000
1420x020370BA 2b Script variable 0x8001
1430x020370BC 2b Script variable 0x8002
1440x020370BE 2b Script variable 0x8003
1450x020370C0 2b Script variable 0x8004
1460x020370C2 2b Script variable 0x8005
1470x020370C4 2b Script variable 0x8006
1480x020370C6 2b Script variable 0x8007
1490x020370C8 2b Script variable 0x8008
1500x020370CA 2b Script variable 0x8009
1510x020370CC 2b Script variable 0x800A
1520x020370CE 2b Script variable 0x800B
1530x020370D0 2b Script variable 0x800D // there is no var 0x800C?
1540x020370D2 2b Script variable 0x800E // overwritten by "trainerbattle"?
1550x020370D4 2b Script variable 0x800F
156
1570x020386AC 2b Trainerbattle: Battle type.
1580x020386AE 2b Trainerbattle: Trainer flag.
1590x020386B0 2b Trainerbattle: Argument 3.
160 Some battle types save it into var 0x800E.
1610x020386B2 2b Unknown.
1620x020386B4 4b Trainerbattle: Arg4 (types 1, 2, 4, 6, 7, 8) or null (others).
1630x020386B8 4b Trainerbattle: A4 (0, 3, 5), A5 (1, 2, 4, 6, 7, 8, 9), or null.
1640x020386BC 4b Trainerbattle: Argument 5 (type 9) or null (others).
1650x020386C0 4b Trainerbattle: Argument 6 (types 6, 8) or null (others).
1660x020386C4 4b Trainerbattle: Offset of next script command byte.
1670x020386C8 4b Trainerbattle: A6 (types 1, 2), A7 (types 6, 8), or null.
1680x020386CC 2b Trainerbattle: Unknown.
169
170
171
1720x0203AAA8 4b Unknown. Written to by the "setbyte" command.
1730x0203ADFA 1b Unknown.
174 If equal to 0x2, "warp" fails to play a sound.
175 If lower than 0x04, "setworldmapflag" fails to set
176 the specified flag.
177 If equal to 1, trainerbattle types 5 and 7 will
178 clear this byte and then some sections of RAM.
179
180
1810x0203ADFC 4b Unknown. A pointer used by trainerbattle types 5 and 7.
1820x0203AE04 4b? Unknown. Cleared by "trainerbattle" (types 5, 7) if the byte
183 at 0x0203ADFA is 0x01.
1840x0203AE08 4b? Unknown. Used and cleared by "trainerbattle" (types 5, 7)
185 if the byte at 0x0203ADFA is 0x01.
1860x0203AE8C 4b? Unknown. Cleared by "trainerbattle" (types 5, 7) if the byte
187 at 0x0203ADFA is 0x01.
188
1890x0203AE98 ? Unknown.
1900x0203AF98 ? Unknown. A pointer used by trainerbattle types 5 and 7.
1910x0203B01E 2b Unknown. Read by a reused ASM routine in script commands'
192 code.
193
1940x0203B0EE 1b Help: Player's opened it before? Y / N, 0x00 / 0x01.
1950x0203B1A0 14291b Help: unknown. // to 0x0203E973
1960x0203E973 2050b Help: unknown. Cleared only when opening help for the 1st
197 time. // to 0x0203F175
1980x0203F176 1b Help: start of GUI state data.
1990x0203F194 1b Help: number of menu options.
2000x0203F195 1b Help: Unknown.
2010x0203F196 1b Help: number of menu options visible on-screen.
2020x0203F199 1b Help: Unknown. Apparently 0x04 for top-level menu or 0x15
203 for submenus.
2040x0203F19C 1b Help: scroll position in a menu.
2050x0203F19D 1b Help: cursor position in a menu (relative to scroll).
2060x0203F19E 1b Help: unknown. Apparently 0x00 for top-level menu, 0x03
207 for submenus, and 0x06 for static pages.
2080x0203F1AC ?b Help: start of menu data. String pointer (not aligned),
209 followed by menu item number. List is terminated with
210 0xFEFFFFFF
211
212
2130x0203E000 4096b Unused RAM found by JPAN (is used by D/N patch)
2140x0203F3C0 1856b RAM used in JPAN's Hacked Engine.
2150x03000EA8 1b Unknown. Set by (defunct?) "choosecontestpkmn" command, and
216 also set to 0x1 by "repeattrainerbattle".
217
218
219
220
2210x03000EB0 74b Script engine RAM
222
2230x03000F9C 1b 0x01 if the screen is fading, 0x00 otherwise.
2240x03000FC0 4b Music for the current map (truncated to 2b when read)
2250x03000FC4 1b Warping: Unknown.
2260x03005000 4b Current PRNG seed
227
2280x03005008 4b Pointer to a DMA-protected save block (map data)
2290x0300500C 4b Pointer to a DMA-protected save block (personal data)
2300x03005010 4b Pointer to a DMA-protected save block (box data)
231
2320x03005074 1b Trainerbattle: number of the OW we are battling, or 0x10 if
233 invalid. This offset is used by special 13A, which in turn
234 is called by some of the scripts (yes, scripts) that
235 trainerbattle calls.
2360x03005E88 1b? Unknown. Cleared by "trainerbattle" (types 5, 7) if the byte
237 at 0x0203ADFA is 0x01.
2380x03007324 2b Warping: Unknown. Related to the fade timer.
2390x03007326 2b Warping: Unknown. Related to the fade timer.
2400x03007328 2b Warping: Timer used for fades. Duration varies with type
241 of map being entered.
242
243DMA (Dynamic, exact address constantly changes)
244[0x03005008] + 0x0000 2b Camera X-position
245[0x03005008] + 0x0002 2b Camera Y-position
246[0x03005008] + 0x0004 1b Current map.
247[0x03005008] + 0x0005 1b Current map bank.
248[0x0300500C] + 0x0000 8b Character name including terminator, padded to end with 0xFFs
249[0x0300500C] + 0x0008 1b Gender (00/01 m/f)
250[0x0300500C] + 0x0009 1b Unknown
251[0x0300500C] + 0x000A 2b Trainer ID
252[0x0300500C] + 0x000C 2b Secret ID (halfword)
253[0x0300500C] + 0x000E 2b Playtime (hours)
254[0x0300500C] + 0x0010 1b Playtime (minutes)
255[0x0300500C] + 0x0011 1b Playtime (seconds)
256[0x0300500C] + 0x0012 1b Playtime (frames)
257[0x0300500C] + 0x0014 2b Options // this and above thanks to hackmew's asm tut pt. 1
258[0x0300500C] + 0x001A 1b If 0xDA, then National Dex is enabled.
259[0x0300500C] + 0x0028 52bytes Flags of Pokemon caught
260[0x0300500C] + 0x005c 52bytes Flags of Pokemon seen
261[0x0300500C] + 0x0F20 4b Unknown (encryption key for hidden vars)
262[0x0300500C] + 0x0F24 End (byte after)
263
264
265
266
267
268
269
270
271 JPAN JPAN is offline
272pokemon rom researcher
273
274
275Join Date: Dec 2008
276Posts: 104
277This post is about the RAM layout of the three DMA protected blocks, the same ones that are saved in the flash. We shall call them,
278-block 8
279-block C
280and
281-block 10
282 After the location of their access address
283 (0x3005008, 0x300500C and 0x3005010).
284 Here are the IDA structures that represent them:
285Code:
286
28700000000 SaveBlock8 struc ; (sizeof=0x3D68)
28800000000 player_map_x DCW ?
28900000002 Player_map_y DCW ?
29000000004 currentMap Warp_struct ?
2910000000C field_C Warp_struct ?
29200000014 last_used_empty_teleporter Warp_struct ? ; used for doors such as the trade center ones, to determine where
29300000014 ; the warp will go
2940000001C last_healing_spot Warp_struct ? ; used to determine where teleport and escape rope will lead you
2950000001C ; (may be useful to create alternate teleport locations)
29600000024 Last_used_warp Warp_struct ? ; last warp that caused a transition
2970000002C map_song DCW ?
2980000002E field_2E DCB ?
2990000002F current_weather DCB ?
30000000030 used_flash? DCB ?
30100000031 field_31 DCB ?
30200000032 map_footer_no DCW ?
30300000034 party_size DCD ?
304
30500000038 Poke1 Poke100Bytes ?
3060000009C Poke2 Poke100Bytes ?
30700000100 Poke3 Poke100Bytes ?
30800000164 Poke4 Poke100Bytes ?
309000001C8 Poke5 Poke100Bytes ?
3100000022C Poke6 Poke100Bytes ?
311
31200000290 money DCD ?
31300000294 coins DCW ?
31400000296 registered_item DCW ?
31500000298 Item_PC_storage Item_entry 30 dup(?) ; Only set of items that is not encrypted
316
31700000310 General_items Item_entry 40 dup(?) ; Items are encrypted with the other block 0xf20 key
318000003B0 key_Item Item_entry 32 dup(?)
31900000430 pokeBalls Item_entry 13 dup(?)
32000000464 TMs Item_entry 58 dup(?)
3210000054C Berries Item_entry 43 dup(?)
322000005F8 pokedex_seen_flags_1 DCB 52 dup(?) ; also on 28 and 5c of 300500c, and on 3a18 of this block
3230000062C unknown DCB 12 dup(?)
32400000638 VS_seeker_step_counter DCW ?
3250000063A rebattle_counter DCB 100 dup(?) ; if = 0, trainer is not rebattled. 1 = rebattle first time, 3=
3260000063A ; rebattle later times.
3270000063A ; Based on person number (not OW event number, from map structure),
3280000063A ; seem capable of up 100 people events on map
3290000069E field_69E DCW ?
330000006A0 OW_ram Ram_OW_struct 16 dup(?)
331000008E0 map_OW_copy MapOwData 64 dup(?) ; beggining of data structure holding current map OWs
332000008E0 ; (same structure as map, 20bytes per person, at least support
333000008E0 ; for 15 characters)
33400000EE0 flags DCB 288 dup(?) ; 0x900 flags
33500001000 variables DCW 256 dup(?) ; 0x4000->0x407f are all available variables
33600001200 encrypted_Counters DCD 64 dup(?) ; Encrypted counters. 64 word-sized encrypted counters.
33700001200 ; Count stuff such as number of saves, or splashes used
33800001300 previously_array Previously_save_block 4 dup(?)
33900002CA0 field_2CA0 DCB 48 dup(?) ; Quick chat words for the link function
34000002CA0 ; 2ca0 = 6 hwords (Default "I am a Pokemon friend!")
34100002CA0 ; 2cac = 6 hwords (Default "Are you ready? Here I come!")
34200002CA0 ; 2cb8 = 6 hwords (default empty)
34300002CA0 ; 2cc4 = 6 hwords (default empty)
34400002CA0 ; as extracted from 80BDD34
34500002CD0 party_mail mail 6 dup(?)
34600002DA8 pc_mail mail 10 dup(?)
34700002F10 field_2F10 DCB 112 dup(?) ; 2f10 = 40 bytes
34800002F10 ; 2f38+ = ??
34900002F80 breeding_center pokemon_daycare ?
3500000309C field_309C DCB 11 dup(?) ; no idea, but is 11 bytes, as used in some link function
351000030A7 DCB ? ; undefined
352000030A8 field_30A8 DCB 40 dup(?) ; unkown- not found
353000030D0 field_30D0 Roaming_legend ? ; a block containing information on the roaming legend.
354000030D0 ; C holds its level
355000030EC eReaderBerryStruct berry_struct ?
35600003108 field_3108 DCB 18 dup(?)
3570000311A e_berry_special DCB ? ; =26, allows enigma replacement to stone-evolve pokes
3580000311B field_311B DCB ?
3590000311C e_berry_checksum DCD ?
36000003120 field_3120 DCD ?
36100003124 field_3124 DCB 444 dup(?)
362000032E0 field_32E0 DCD ?
363000032E4 field_32E4 DCB 332 dup(?)
36400003430 field_3430 DCD ?
36500003434 field_3434 DCB 36 dup(?)
36600003458 field_3458 DCW 4 dup(?)
36700003460 field_3460 DCD ?
36800003464 field_3464 DCB 20 dup(?) ; see 8144790
36900003478 field_3478 DCD ?
3700000347C field_347C DCB 416 dup(?) ; unknown
3710000361C field_361C DCD ?
37200003620 field_3620 DCB 1000 dup(?)
37300003A08 field_3A08 DCB 16 dup(?) ; not found
37400003A18 pokedex_seen_flags_2 DCB 52 dup(?)
37500003A4C rival_name DCB 8 dup(?)
37600003A54 fame_checker_flags DCD 16 dup(?)
37700003A94 field_3A94 DCB 64 dup(?) ; unkonwn-not found
37800003AD4 field_3AD4 Greetings ? ; 21 byte strings *10
37900003BA6 field_3BA6 DCW ? ; padding?
38000003BA8 field_3BA8 DCB 240 dup(?) ; 12*20
38100003BA8 ; Seems to be related to the union room.
38200003C98 old_daycare daycare_pkmn ?
38300003D24 field_3D24 DCB 16 dup(?) ; seem unused
38400003D34 field_3D34 DCD ? ; used by trainer tower
38500003D38 key_struct_array key_struct 4 dup(?)
38600003D68 SaveBlock8 ends
38700003D68
38800000000 ; ---------------------------------------------------------------------------
38900000000
39000000000 SaveBlockC struc ; (sizeof=0xF24)
39100000000 PlayerName DCB 8 dup(?) ; FF terminated, so 7 character
39200000008 playerGender DCB ? ; 0 for male, 1,2,3 = female, >4 = null
39300000009 field_9 DCB ? ; used for someting, seems like a bitfield. bits 0,1,2,3 are
39400000009 ; used in some functions
3950000000A ID DCW ?
3960000000C SecretID DCW ?
3970000000E time Time ?
39800000013 LR_function DCB ? ; 0 = help, 1 = L=A , 2 = L = left
39900000014 Options DCW ? ; bit 0-1 = text speed (3 invalid)
40000000014 ; bit 2-6 = border num (border = options>>2&7f), valid only to 13
40100000014 ; bit 7 invalid
40200000014 ; bit 8 = sound channel (0= mono, 1 = stereo)
40300000014 ; bit 9 = battle switch (0 = switch, 1 = set)
40400000014 ; bit 10 = battle anim (0= on, 1 = off)
40500000014 ; bit 11-16 = unused
40600000016 field_16 DCB ?
40700000017 field_17 DCB ?
40800000018 field_18 DCB ?
40900000019 field_19 DCB ?
4100000001A field_1A DCB ? ; set as DA when a new game is started
4110000001B field_1B DCB ? ; value = b9 while var 0x404e = 0x6258 and flag 0x840 is set
4120000001B ; makes national dex active
4130000001C first_unown_PID DCD ?
41400000020 first_spinda_ID DCD ?
41500000024 field_24 DCD ?
41600000028 caught_flags DCB 52 dup(?)
4170000005C seen_flags DCB 52 dup(?)
41800000090 DCB ? ; undefined
41900000091 DCB ? ; undefined
42000000092 DCB ? ; undefined
42100000093 DCB ? ; undefined
42200000094 DCB ? ; undefined
42300000095 DCB ? ; undefined
42400000096 DCB ? ; undefined
42500000097 DCB ? ; undefined
42600000098 DCB ? ; undefined
42700000099 DCB ? ; undefined
4280000009A DCB ? ; undefined
4290000009B DCB ? ; undefined
4300000009C DCB ? ; undefined
4310000009D DCB ? ; undefined
4320000009E DCB ? ; undefined
4330000009F DCB ? ; undefined
434000000A0 DCB ? ; undefined
435000000A1 DCB ? ; undefined
436000000A2 DCB ? ; undefined
437000000A3 DCB ? ; undefined
438000000A4 DCB ? ; undefined
439000000A5 DCB ? ; undefined
440000000A6 DCB ? ; undefined
441000000A7 DCB ? ; undefined
442000000A8 field_A8 DCD ?
443000000AC field_AC DCB ?
444000000AD field_AD DCB ?
445000000AE DCB ? ; undefined
446000000AF DCB ? ; undefined
447000000B0 field_B0 DCB 1012 dup(?) ; cleaned at start, 1012 bytes
448000004A4 field_4A4 DCB 7 dup(?)
449000004AB field_4AB DCB ?
450000004AC field_4AC DCB 1604 dup(?) ; unknown
45100000AF0 field_AF0 DCB 32 dup(?) ; cleaned on start
45200000B10 field_B10 DCB 32 dup(?) ; cleaned on start
45300000B30 field_B30 DCB 1008 dup(?)
45400000F20 encryption_key DCD ?
45500000F24 SaveBlockC ends
45600000F24
45700000000 ; ---------------------------------------------------------------------------
45800000000
45900000000 SaveBlock10 struc ; (sizeof=0x83D0)
46000000000 current_box DCD ?
46100000004 box_data box 14 dup(?) ; 30*80-byte pokemon each box
46200008344 box_names DCB 126 dup(?) ; 9 bytes name * 14 boxes
463000083C2 box_wallpapers DCB 14 dup(?)
464000083D0 SaveBlock10 ends
465000083D0
466
46700000000 ; ---------------------------------------------------------------------------
46800000000
46900000000 Warp_struct struc ; (sizeof=0x8)
47000000000 map_bank DCB ?
47100000001 map_number DCB ?
47200000002 warp_number DCB ? ; FF = warp to given coordinates, regardless of warp
47300000003 padding DCB ?
47400000004 x_coord DCW ?
47500000006 y_coord DCW ?
47600000008 Warp_struct ends
47700000008
47800000000 ; ---------------------------------------------------------------------------
47900000000
48000000000 Item_entry struc ; (sizeof=0x4)
48100000000 item_ID DCW ?
48200000002 item_quantity DCW ?
48300000004 Item_entry ends
48400000004
48500000000 ; ---------------------------------------------------------------------------
48600000000
48700000000 Previously_save_block struc ; (sizeof=0x668)
48800000000 is_present_marker DCB ? ; 1 if present, 0 if not present
48900000000 ; Also affects camera position
49000000001 old_map_entry DCB ?
49100000002 old_map_bank DCB ?
49200000003 warp_no DCB ?
49300000004 map_x_pos DCW ?
49400000006 map_y_pos DCW ?
49500000008 person_resume_array DCB 320 dup(?) ; each person OW is stored in 20 bytes (total 20*16 = 320 bytes)
49600000148 old_flag_save_data DCB 144 dup(?) ; saves 144 bytes worth of flags, from flag 0 to flag 1152
497000001D8 field_1D8 DCB 144 dup(?)
49800000268 old_var_save_data DCB 256 dup(?) ; saves 256 bytes worth of variables, or variables 0x4000 to 0x407f
49900000368 field_368 DCB 256 dup(?)
50000000468 not_found DCW ?
5010000046A field_46A DCB ?
5020000046B not_yet_found_2 DCB ?
5030000046C not_yet_found DCB 252 dup(?)
50400000568 OW_movements DCB 256 dup(?) ; 8 bytes each, 32 slots total, sum for player and other npc movement
50500000668 Previously_save_block ends
50600000668
50700000000 ; ---------------------------------------------------------------------------
50800000000
50900000000 pokemon_daycare struc ; (sizeof=0x11C)
51000000000 slot_1 daycare_pkmn ?
5110000008C slot_2 daycare_pkmn ?
51200000118 egg_structure DCW ?
5130000011A Egg_steps_counter DCW ?
5140000011C pokemon_daycare ends
5150000011C
51600000000 ; ---------------------------------------------------------------------------
51700000000
51800000000 daycare_pkmn struc ; (sizeof=0x8C)
51900000000 pokemon Poke80Bytes ?
52000000050 poke_mail mail ?
52100000074 OT_Name DCB 8 dup(?)
5220000007C Poke_name DCB 12 dup(?)
52300000088 exp_counter DCD ?
5240000008C daycare_pkmn ends
5250000008C
52600000000 ; ---------------------------------------------------------------------------
52700000000
52800000000 mail struc ; (sizeof=0x24)
52900000000 words DCW 9 dup(?)
53000000012 sender_Name DCB 8 dup(?)
5310000001A OTID DCD ?
5320000001E species_ID DCW ? ; used for special mail that prints a pokemon icon below the mail
53300000020 itemID DCW ?
53400000022 padding DCW ?
53500000024 mail ends
53600000024
53700000000 ; ---------------------------------------------------------------------------
53800000000
53900000000 Roaming_legend struc ; (sizeof=0x1C)
54000000000 IVs DCD ?
54100000004 PID DCD ?
54200000008 legend_species DCW ?
5430000000A current_hp DCW ?
5440000000C legend_level DCB ?
5450000000D status DCB ?
5460000000E contest_stats DCB 5 dup(?)
54700000013 exists DCB ?
54800000014 field_14 DCB 8 dup(?)
5490000001C Roaming_legend ends
5500000001C
55100000000 ; ---------------------------------------------------------------------------
55200000000
55300000000 berry_struct struc ; (sizeof=0x1C)
55400000000 name DCB 7 dup(?)
55500000007 Hardness DCB ? ; 1= super soft, 5 = super hard
55600000008 size DCB ? ; in cm. 1 = 0.1 cm
55700000009 field_9 DCB ?
5580000000A field_A DCB ?
5590000000B field_B DCB ?
5600000000C field_C DCD ? ; offset (00000000)
56100000010 field_10 DCD ? ; offset (00000000)
56200000014 growth_time DCB ? ; hours per stage. 3 = 3h per stage = 12h total
56300000015 flavor DCB 5 dup(?) ; spicy, dry, sweet, bitter, sour
5640000001A feel DCB ?
5650000001B field_1B DCB ?
5660000001C berry_struct ends
5670000001C
56800000000 ; ---------------------------------------------------------------------------
56900000000
57000000000 Greetings struc ; (sizeof=0xD2)
57100000000 hello DCB 21 dup(?)
57200000015 pokemon DCB 21 dup(?)
5730000002A trade DCB 21 dup(?)
5740000003F battle DCB 21 dup(?)
57500000054 lets DCB 21 dup(?)
57600000069 ok DCB 21 dup(?)
5770000007E sorry DCB 21 dup(?)
57800000093 yay DCB 21 dup(?)
579000000A8 thank_you DCB 21 dup(?)
580000000BD bye_bye DCB 21 dup(?)
581000000D2 Greetings ends
582000000D2
58300000000 ; ---------------------------------------------------------------------------
58400000000
58500000000 key_struct struc ; (sizeof=0xC)
58600000000 field_0 DCD ?
58700000004 key DCD ?
58800000008 field_8 DCD ?
5890000000C key_struct ends
5900000000C
59100000000 ; ---------------------------------------------------------------------------
59200000000
59300000000 Time struc ; (sizeof=0x5)
59400000000 hours DCW ?
59500000002 minutes DCB ?
59600000003 seconds DCB ?
59700000004 ticks DCB ?
59800000005 Time ends
59900000005
600
601Block 10, the biggest block, is the simplest one to explain.
602It starts with one 32bit word tracking the last open pokemon box, followed by 14*30 pokemon in 80-byte format and ending with the box names and wallpapers.
603Block 10 can also be called the Box block.
604
605Block C is the most "mysterious" block, as most of its data is still undocumented.
606It starts with the player data such as name and IDs, followed by the in-game timer and options.
607It also stores the ID of the first seen spinda and unown, so the pokedex displays the same one every time, followed by the seen and caught flags.
608While the caught flags are the only set, the seen flags are also present in two locations on block 8. The remainder of the data is yet undiscovered, with the searching method for unknown fields yielding only the sizes of the memory areas, and not its function.
609
610Block 8 is the one with more to talk about, being almost completely documented. It can be roughly divided into several smaller blocks, starting with a Map block.
611The map sub block that contains the player position, the current map, last used warps, map information such as music being played and current weather, ending with the map footer id.
612The next sub block is the party sub block, containing a party count and 6 100bytes pokemon slots.
613The next sub block is the player belongings sub block. This block stores money, coins, items, the first of the pokedex seen flags and the data used by the VS Seeker.
614The next sub block is the OW sub block, containing the RAM structure of OWs for the maximum of 16 on-screen, and up to 64 OW in the same format as found in Advance Map.
615The next sub block is the story records sub block, containing 0x900 flags, 128 variables and 64 encrypted counters. Encrypted counters are used by the game to keep metrics, such as the ones shared via record mixing.
616The next sub block is the "Previously" sub block, containing 4 slides that store information needed to replicate the map event during the Previously slide show. Each slide contains the map, location, OWs present, a copy of the flags and variables section and 32 movements used during the cutscene, that is shared between NPCs and player.
617The next sub block is the quickchat sub block, containing some words that should be used by the link function and the mail storage for both party and PC.
618The next sub block is the breeding sub block, containing the breeding daycare center data, such as the 80 byte pokemon, held mail, nickname, OT name and a counter for experience earned. It also contains an egg seed and an egg step counter.
619The next sub block is unnamed, and ends with the data for creating and maintaining Roaming Legendary pokemon.
620The next sub block is tentatively called the E-reader sub block, since it contains the E-reader berry data and seems to keep the E-reader Trainer data for the battle tower. This block is big and mostly undocumented.
621The final sub block is also unnamed, and contains the second set of seen flags, the rival name, the Fame checker flags, a set of 20-character greetings and the Cerulean daycare data.
622
623That's it for the broad view of the save data RAM structure. I'll post more detailed information in subsequent posts.
624
625Two main methods were used to find this information: Breakpoints in VBA debugger and search the ROM for mov/ldr instructions for the block offsets.
626In order to do so, I developed a tool that searches the ROM for references to a given number, which might be an address or any other number.
627This tool can search for bl calls, byte references and, when selected, mov/shift combos that load the value onto the registers.
628I shall provide the tool as-is in order to facilitate this same research for Emerald.
629To start the tool, choose a rom by clicking the ... button. The tool remembers the last open ROM file.
630To search for an address, enter it in the "Offset to search for" box and press "Search".
631The address may be in the 0x80000000-0x9fffffff range or, if the "No offset Correct" box is not ticked, the address can be in the 0x0 to 0x1ffffff range and the program will shift it to the GBA address.
632To search for a number that is not an address, the "No offset Correct" must be ticked.
633If the "Mov/Shift Combo" is ticked, results will include mov/shift load combos.
634The tool also includes a jump calculator, that given two addresses, compiles the jump instruction that leads from the start to the finish.
635
636
637 *Disabling DMA
638We start the in-depth analyzis by addressing the DMA. Disabling the DMA shifting will provide several advantages:
639- Making the blocks static allow for breaks on read/write by the debugger;
640- Static blocks can be easily acessed from scripts;
641- Stopping the shift means the empty RAM space needed to cushion the changes can be used for storing
642custom data.
643To make the blocks static, in Fire Fed, go to 0x4C062 and change the byte to 0.
644In Emerald, change the byte at 0x76BEC to 0.
645
646This will make the blocks static, but not disable the DMA copy functions. The DMA will simply copy the blocks back to the same space.
647At the end of each block lies 0x80 bytes of free RAM. With a bit of work, these 3*0x80 bytes can be saved to the Flash.
648In Fire Red, simply go to 0x3FEC96 and write 0xA4 0xf, at 0x3FECa6 write 0x68 0x0f and at 0x3FECCA write 0x50 0x08.
649
650In Block 8, there are 5 warp structures. Each has its own meaning.
651At 0x4, currentMap indicates what the entrance taken into the current map. Positions of 0xffff indicate the entry point was a connection and not a warp.
652At 0x14, last_used_empty_teleporter is the structure that saves the destination for 0x7f warps, such as the one on the elevator and one the trading center. This field is modified by the setwarpplace command.
653At 0x1c, last_healing_spot is the structure that saves the destination for Teleport and where you go when you lose all pokemon. This field is set by the SethealingPlace command. Changing this field allows control over the destination of Teleport, but might break the fainting script.
654At 0x24, last_used_warp stores the last warp from where the player transitioned from an outside map to an indoors/cave map. It is set each time such transition occurs, and is used by Dig and Escape Rope to determine where to go. Changing this field allows control over the destination of Dig and Escape Rope.
655
656In order to expand the player maximum money to 999999999, the first change is allowing the money to add to that amount. at 0x9fdd4, place 0xFF 0xc9 0x9a 0x3b. Then we need to change the money display. At 0x09FE52 place 0x9 At 0x09FE62 place 0x9. This makes the showMoneyBox command display the full number. At 0x08A006 place 9. This makes the trainer card display the correct amount.
657The money paid after losing a battle is calculated at 0x054C04, using a table at 0x26D294. The table contains one entry per number of badges collected. Each entry is multiplied by 4 and then multiplied by the highest pokemon level in your party. For example, if you have 6 badges and the highest pokemon level is 60, the money to pay out is 60*4*20 = 4800.
658
659PC Items are the only set that is not encrypted. 0809A2A4 clears that space. 0809A304 gets the first free slot on the PC. 0809A33C countes the number of slots occupied. 0809A374 checks if an item (R0) exists with at least R1 quantity. This function is used by the checkPCItem command. 0809A3C8 adds R1 items R0 to the PC. 0809A460 removes r1 items r0 from the PC, if they exist. 0809A4E8 compacts the PC items, moving items into the empty slots above them.
660
661The bags are usually acessed from a table at 0203988C. Each entry consists of the bag address in the block and one word size of the bag. The entire bag is cleared by 0809A2DC.
662
663There are three sets of pokedex Seen flags, all of which must be set for a pokemon to be considered seen. The function that accesses and modifies the data is at 08104AB0, and receives r0 as the pokemon number, r1= 0 for get seen flag, 1 for get caught flag, 2 for set seem flag amd 3 for set capture flag, r2 = 0 if the pokemon number is not the dex number
664
665Field OW_ram contains 16 entries of Ram OW structure. Most of this structure is still undocumented, but is one of the three essential structures to display OWs on the map. OWs loaded in this structure are the ones to be displayed on screen. This field is a copy of the one really used at 02036E38. The 16 entry limitation makes it so that only 16 sprites (including player) can be displayed at once on screen.
666The field map_OW_copy contains an array copied from the Map OW structure. This is not just a copy, however. It is here that most OW functions fetch the Map OW structure, not from the ROM. Commands such as spriteBehave that modify OW behavior alter them on this field. This field size also determines the maximum number of OW on a single map, 64.
667The third important structure is the OAM RAM structure at 0202063C. This structure is used by the game engine to display sprite images such as the OWs or the battle HUD and battle sprites. It includes a direct copy of the OAM structure for that sprite, as well as pointers to images and animations. This structure (which is not included in the save files) also needs further study.
668
669
670
671
672
673
674
675
676
677
678 JPAN JPAN is offline
679pokemon rom researcher
680
681 *Disabling Flashback system
682Join Date: Dec 2008
683Posts: 104
684The "Previously" system is the collection of functions related to saving, loading and displaying the slide show that appears when continuing a saved game in Fire Red.
685Each scene in the show (and the data saved that generate it) is a slide.
686
687To save a slide, the function at 0x08110AEC is called.
688The function will write on the slide indicated by 0x0203ADF8,
689or on 0 if the slide indicated by 0x0203ADF8 is greater than 3.
690It begins by clearing the space on that slide slot, and then stores the map warp, the OWs present, map Footer, a copy of the variables and flags,
691and finally the 32 last movements the OWs (including player) made.
692
693The function at 0x08110F14 is in charge of loading the slides to show in the slide show.
694The function at 0x08111914 is responsible for determining the next slide to be loaded.
695If no more slides exist, prepares the game for normal load.
696Much is yet unknown about how the slides are generated and displayed.
697It is ingrained in the normal overworld loading routines,
698and it seems like the previously slide show is handled like the normal overworld.
699
700While interesting to study, it is a feature (much like the help system) that many wouldn't miss if it was gone.
701Disabling the previously system would allow us to use the memory associated with it in any way we wanted.
702The most tempting part is that this memory is acessible to flags and variables without altering the loading code.
703Flags from 0x2100 to 0x3fff and variables from 0x4180 to 0x4e4f fall within the previously slides range.
704
705To disable the previouly system, we need to disable both load and save functions.
706At 0x110f24, place 0x28 0xe0. This will cause a jump to 0x08110f78, skipping the loading function. The second loading function should now never be called, but better safe than sorry.
707At 0811192A place 0x04 0x20 (mov r0, 4) to trick it into thinking the slides were already loaded.
708At 08110AEC. Place a "bx lr" (0x70 0x47) to skip the save function entirely.
709The function at 81123BC, which moves the slides up if any was erased, is also problematic.
710Place "bx lr" (0x70 0x47) at that address to prevent the cleanup.
711
712You should now have safe access to thousands of new flags and variables.
713The new flags and variables have a slight overlap, so it would be recommended that certain variables wouldn't be used if using the flags.
714This small table shows what values are safe.
715Code:
716
717Flag |Total Flags |Variables |Total Variables
7180x2100 - 0x27ff |2048 |0x4200 - 0x4e4f |3152
7190x2100 - 0x30ff |4096 |0x4280 - 0x4e4f |3024
7200x2100 - 0x37ff |6144 |0x4300 - 0x4e4f |2944
7210x2100 - 0x3fff |7936 |0x4370 - 0x4e4f |2784
722
723Each quickword is composed of two parts: quickword & 0x1ff is the entry number, quickword>>9 is the table number.
724Tables 13 and 15 are special, as they load the names of moves and pokemon respectively straight from the source.
725The table at 083ECED4 contains the table for the quickword entries. Each entry in that table points to a list of entries containing the actual words.
726The entries at the 083ECED4 table represent a category of words (the ones presented during mail writing).
7270841E093 contains the default string for when a quickword is invalid ("???").
728
729The function that translate quickwords to actual strings is at 0x080BD7F8, and takes the quickword already split into category(r0) and entry(r1).
730Mail contains fields to store trainer name and OTID. While the name storing is obvious, the OTID being stored is not, as the mail doesn't seem to show it.
731The species of the pokemon holding the mail (or last holding the mail in the pc case) is stored for the mails that contain a small pokemon icon on the frame.
732The function at 080BD89C is responsible for loading the mail into display format.
733
734@TeamFail Your research is very interesting, and finding out where the E-reader data is hidden is only natural in its progression. Wish you luck with that research.