SearchForCheats.de.vu » Tutorials » Advanced User Tutorial #3 - Editing The Worldmap


Advanced User Tutorial #3 - Editing The Worldmap

En Taro Adun, coders!

So, I'm finally publishing the infos about the worldmap. Due to it's size, we'll have to step through a LOT of aspects until we've reached our goal. (Little annotation in advance: There will be a programme to change everything at once soon.)

Let's arrange our tasks a little bit:

  • Changing the pictures on the map:
    1. Understanding how the whole thing is displayed
    2. Finding the needed data
    3. Changing it
    4. Storing it back
  • Changing the 'data' itself
    1. Understanding how it works
    2. Changing routes / cities / towns
    3. Changing flightpoints
    4. Changing displayed names

Another note: To find all the needed bytes you will need basic ASM knowledge. Even though everything is commented out, you might be confused staring at all that opcodes.

Im working again with Fire Red US v1.0

Load up your ROM in the VBA. Choose any pokemon which has already learned HM2 Fly and open the menu to display the worldmap. In FR, there is more than one map, I'm using the main map of Kanto, which one you're using depends on which one you want to hack. (of course *rolleyes*)

Looks kinda familiar, doesn't it?
Let's investigate how the map is displayed. Therefore, you should open the Map Viewer.

To understand what is meant by all the defines and declarations, we'll have to open the Tile Viewer.

I hope I gave you an idea how the map is displayed. Take a dump of the tilebase. It starts at 0x0600F000 and its size amounts 0x800 bytes. Save the tiles too, they're at 0x06000000. Size is 0x1000 bytes. Let's now try to find them inside of the ROM.

For our changes, we need the 'tilebase' and the tiles themselves. Sadly they're both stored in the VRAM, which is a memory out of VBASDL's breakpoint range. Luckily, the VBA-H supports logging. *quite amazed*
What does that mean? - Well. We'll be able to do a first backtrace to EWRAM or IWRAM if we have a closer look to the things printed there. Prepare the process by quitting the worldmap. Select again the ability 'fly' but don't press the A-button! Open the 'Logging...' window instead. ("Tools" > "Logging")
BAM! You're seeing some checkboxes, labeled "SWI" or "DMA", now. We're only interested in the DMA 0 - 3 and the SWI. What do these abbreviations mean?

  • "DMA" stands for "Direct Memory Access". It's some kind of hardware in your GBA. To be precise: There are four of them, which can be used independently. Consider them all as little "stupid" CPUs, only able to copy large blocks of data from one location to another. The DMA is used to exonerate the main CPU. Setting a check to them loggs all the actions done by DMA.
  • "SWI" is a software interrupt. All the GBA's BIOS-functions are done by these SWI's. And since one of them is "LZ77UnCompWram" decompressing LZ77 data, we're really interested in them. Just in order to mention it: There are "CpuSet" and "CpuFastSet" as well. They do the same what DMA does with the simple difference that the data is copied by the CPU.

Returning to our concern, we set "SWI", "DMA 0", "DMA 1", "DMA 2" and "DMA 3". This slows down the emulation a lot. If your computer isn't fast enough, only check "SWI" and "DMA 3".
Okay. Give back the focus again to the main window and select "fly" by pressing A. Wait until the map is visible and afterwards click on the log-window. There appeared quite many lines. Copy them into a programme with search-function (e.g. notepad) and look for the latest appearing of "0600F000".

For FRUS, it's:

DMA3: s=020017ba d=0600f000 c=8000 count=00000800

The DMA3 copies 0x800 bytes from 0x020017BA to 0x0600F000. 0x020017BA is in the EWRAM and can be traced back with VBASDL later. If you're very lucky, you're able to find 0x020017BA anywhere above the current operation. This way it's possible to find the data in the ROM without using any debugger.
Okay, I said if you're lucky - I can't find 0x20017BA again, so I just write down the adress.

Now search your log for "06000000". You should come up with something like this:

DMA3: s=02007cb4 d=06000000 c=8000 count=00001000

Source (s=) is 0x02007CB4 and destination (d=) is 0x06000000. The size (count) is 0x1000 bytes. Note down 0x02007CB4 too.

Now, load up VBASDL-H to figure out how the data is written. Go to the pokemon menue, choose "Fly" without pressing A. Hit F11. Stick a breakpoint on write to 0x020017BA (the adress where the tilebase came from) by typing:

bpw 020017BA 1

Continue the execution. Press A and the game breaks.

Breakpoint (on write) address 020017b8 old:00000000 new:00000000
R00=03007df8 R04=000047c0 R08=00000000 R12=00000040
R01=02000024 R05=02000024 R09=00000000 R13=03007df8
R02=050011f0 R06=030030e4 R10=00000000 R14=08002b1d
R03=0001780c R07=030030f0 R11=00000000 R15=081e3b68
CPSR=0000003f (......T Mode: 1f)
081e3b66  4770 bx lr

0 was obviously changed to 0. Our tilebase was something with 00 20, so press c. The game breaks immediately again.

Breakpoint (on write) address 020017ba old:0000 new:2000
R00=020017ba R04=00000000 R08=020399d4 R12=020027ba
R01=00002000 R05=00000000 R09=00000000 R13=03007de4
R02=00000000 R06=020017ba R10=00000000 R14=080c019f
R03=00000000 R07=0200004a R11=00000000 R15=080c0d20
CPSR=0000003f (......T Mode: 1f)
080c0d1e  2180 mov r1, #0x80

Much better now. Disassemble the procedure with your favourite disassembler. (Or, if you're lazy, type dt 080c0d10) The important part is this one:

080c0d1a  8839 ldrh r1, [r7, #0x0]
080c0d1c  8001 strh r1, [r0, #0x0]     // This command triggered the bpw. r1 is written to r0+0
080c0d1e  2180 mov r1, #0x80

As you can see, the value in r1 is loaded from r7+0 one CPU-step earlier. The dump above says R07=0200004a. The data is copied from 0x0200004A to 0x020017BA. Hard as it may to believe - we have to find out how the data is written to 0x0200004A. Delete the current breakpoints by typing bpwc. Then execute the game and close the worldmap so that you're again on the "Fly" text. Press F11 and type:

bpw 0200004A 1

Resume the game and press A. After passing again the "write-zero" function @ 081e3b66 you find yourself at 081e3b72. Registers are (for me):

R00=083f089c R04=030030f0 R08=00000000 R12=0200a4c4
R01=0200004a R05=030030e4 R09=00000000 R13=03007e00
R02=000047a8 R06=030030e4 R10=00000000 R14=080c035b
R03=00000000 R07=030030f0 R11=00000000 R15=081e3b74

Disassemble the routine:

081e3b70  df11 swi $11
081e3b72  4770 bx lr

Nice one! Software interrupt $11 had activated the breakpoint. The parameters of SWI $11 are:

SWI 17 (11h) - LZ77UnCompWram

  r0   Source address
  r1   Destination address

The CPU looks for LZ77 compressed data @ r0 and moves it to r1. Apparentely, the compressed tilebase is located at 0x083F089C. Awesome!

Recover the first state of VBASDL-H and put a bpw to 02007CB4. Start the game, select "fly" and the window freezes immediately.

Breakpoint (on write) address 02007cb4 old:00 new:00
R00=083ef61c R04=02007cb4 R08=00000000 R12=00001f64
R01=02007cb4 R05=083ef61c R09=00000000 R13=03007dd0
R02=02000000 R06=0203ab5c R10=00000000 R14=080f6ac9
R03=00011b3c R07=00000000 R11=00000000 R15=081e3b74
CPSR=0000003f (......T Mode: 1f)
081e3b72  4770 bx lr

0x081E3B72... sounds familiar. ^^ We already know the SWI $11 at 0x081E3B70, so we're completely aware of the data being uncompressed and copied from 0x083EF61C (r0) to 0x02007CB4 (r1).

That wasn't that difficult, was it? :-P

Okay, since you're reading a "Advanced User Tutorial" I expect you to be able to do your desired changes on the pictures. Just to give you an approximate idea, you can:

  • Change the map using a programme called "Cyclone". The Tool won't work for FRLG!
  • Load the tiles in RAW format in "TileMolester" or "Tile Layer Pro". Dump the correct palette in VBA and import it in one of the both programmes. Change your tiles to whatever you want them to look like and don't forget updating the tilebase.

However, to compress back the tiles and the tilebase, use unLZ-GBA's "Load RAW" function. Hit "Write to ROM", enter a new adress to free space in your ROM, remove the "automatically fix pointers" option and unLZ compresses the data. Now you've only to repoint the adresses to tilebase and tiles. This can be done by searching the ROM for "1C F6 3E 08" and "9C 08 3F 08", the original adresses and changing it to your selected locations.

A further explanation how to change the worldmap pictures by zel:

OK, let's start this semi-tutorial for making new maps visually. When I reached the part where Mastermind_X said "change the map using a program called Cyclone. The tool won't work for FRLG", I thought, "but I heard Cyclone really works on FR", so why don't we give it a try?
And so, I went to Cyclone, made a map using the tileset I stored from the emulator (using the Tile Viewer when in the worldmap, and then using the button "Save", I stored the tileset on .bmp format), something like this:

-To the left, the loaded tileset (using File->Load Tileset), to the right, the map I drew-

So I saved the tilemap using File->Save TileMap (and I stored it on raw format, as MX talked something about it)
Once I stored my newly created map, I kept reading Mastermind's tutorial, found free space to store my map, and used UNLZ and repointed the pointer to the map (basically, read his tutorial again to know what I am talking about)
Everything seemed to be perfect, however once I started playing the worldmap was nothing like I drew on Cyclone.
Yes, it was using (most) of the tiles I used, but still, there were a lot of errors, and the tiles seemed to be in a wrong order (I'd like to show you how it looked, but I don't want to risk, as I now have everything perfectly on my maps)
In the end, we can say that Cyclone doesn't work perfectly for FR, but, it seems to at least work in some way... (Guess it's something related to sizes' differences between FRLG and RSE)
So, how could I fix that? Well, that's when I remembered about Coolboyman using hex to make the map on rijonAdventures, so I thought, "and what if I take an hex look on that stored tilemap I made with Cyclone?", you'll find something like this:

-That's the tilemap I drew on Cyclone, seeing on an hex editor O.o-

As you can see, the tilemap is using hex values for each of the tiles I drew (in my example, 07 00 means dark green and 05 00 means lighter green), so you could basically change every value and get different tiles shown on the map. Pretty simple, just change one of the values to something else, save the tilemap (it'll be stored as raw), then store it again using UNLZ, and, even though the map would still look odd, you should notice that one tile on the worldmap has changed. Cool!
Anyway, keep reading further, as I will try to help you a bit more...
So, that's the way to change the map. But, there are a few aspects to be kept in mind:
*You should remember that 00 00 means the "invisible tile", because the map is basically shown over other stuff (think as if, there are two levels, the map is on the upper level and the other stuff, like the scrolls of the map are on the lower level), so if you do not use the 00 00 where it must when creating the worldmap, then you could step over the stuff on the lower level.
*Remember that the tileset can make use of many palettes, if you want to use the palettes other than the "Palette1", according to Cyclone, then you'll have to remember that each tile has a different hex code (and the codes also change with each palette)
For example, if you'd like to use the red dot used on cities, which uses the second palette (Palette2 on Cyclone), as long as you don't move it if you create a new tileset, it has the hex code 01 10. There are not many other tiles using other palettes, but I guess that would depend on how cool you want your map to be...
In the end, whenever you want to experience with different tiles and palettes, just save the tile Map on Cyclone, open it on the hex editor, and see what has changed
Now, let's move onto some tips when creating the new worldmap using hex:
As long as you use the first palette with your tiles, their hex codes will start from 00 00 (the invisible tile) and will increase up to 3F 01, so a good idea would be to put your tiles on a kind of grid and put the numbers around so that you can identify them easily for when you start drawing the map on hex, something like this:

-So the first tile (the one dark blue), which is the invisible tile is 00 00, then the next one is 01 00, then the next (the dark green) is 02 00. Following the example, the first tile on the second row would be 20 00, hopefully you get the idea of how I did things (it helped me, you may follow your own way)-

So, once I had that "tile guide", I opened the map that I wanted to insert on my images editor...

-That's the map I made using all the tiles available on the tileset (forget about the black dots, that was an example map). I'd recommend you using an images editor that can show you a grid of 8x8 so you can see each tile easily. Mine is Paint Shop Pro-
So, you have the map, the "tile guide", and your tileMap that you'll be changing loaded on your hex editor, so you have all the necessary to start putting the proper hex codes to make your own map using hex!
By the way, you should also know that the tiles can also be modified, and the palettes can also be changed (the tiles can be found using UNLZ's Deep Scan function, it will be around the offset MX found them with his method), so basically, once you find the tiles, changing them is just like changing any other thing using UNLZ (I wouldn't recommend you changing the tiles unless you are a highly skilled rom hacker, though)

So far so good. Nothing new up to this point. The now occuring problem namely is that:

Don't worry about the German Emerald ROM in the picture, it is just an example. I'm still working with FRUS.

Second part: Changing the data

First of all, we look for an adapted entry point to start hacking. In my opinion, we should search the coordinates of the cursor to analyze them precisely.
Unfortunately, it's my opinion counting here in this tutorial and you have to follow my crazy ideas. :-P
So open the "SearchForCheats"-Window (yeah, I like it XD).
Since the map isn't that wide, unknown search for a u8 (unsigned 8bit) is enough for us. We begin with the x-coordinate. Move the cross to the right, then open the cheatsearcher again. The adress we're looking for now holds old value + 1. (it should, at least) Play a little bit with the values and you should come up with adress 0x02008130. Open the memviewer, activate automatic update and move the cursor. You'll notice the two bytes after the x-coordinate. They're behaving exactly like the y-coordinate. In fact, they ARE the y-coordinate. (wooow, who would have thought that? XD)

Now go to your "just before opening worldmap" position you already know in VBASDL-H. After putting a bpr on 0x02008130 there are some breaks you aren't interested in, since they only read some strange values. (e.g. 0xFFFF or 0x44) Ignore them completely and be happy about the breakpoint dealing with the right value. (e.g. 0x0004) For FRUS v1.0, 080c414a is what the debugger displays, so the breakpoint is @ 080c4148. Choose any disassembler to understand what is going on. If you are't familiar with ASM, try typing "n" in VBASDL-H after triggering the breakpoint. The full routine is here (commented out):

ROM:080C4142                 MOV     R3, #2
ROM:080C4144                 LDRSH   R2, [R1,R3]         // R2 = Y coordinate
ROM:080C4146                 MOV     R5, #0
ROM:080C4148                 LDRSH   R3, [R1,R5]         // R3 = X coordinate
ROM:080C414A                 MOV     R1, #0
ROM:080C414C                 BL      get_worldmap_value  // branch -------#
ROM:080C4150                 LDR     R1, [R4]                             ¦
ROM:080C4152                 LSL     R0, R0, #0x18                        ¦
ROM:080C4154                 LSR     R0, R0, #0x18                        ¦
ROM:080C4156                 STRH    R0, [R1,#0x14]                       ¦
ROM:080C4158                 POP     {R4,R5}                              ¦
ROM:080C415A                 POP     {R0}                                 ¦
ROM:080C415C                 BX      R0                                   ¦
                                                                          ¦
[ROM:XXXXXXXX                                                             ¦
ROM:XXXXXXXX                                                              ¦
ROM:XXXXXXXX                                                              ¦
ROM:XXXXXXXX]                                                             ¦
                                                                          ¦
                __________________________________________________________¦
                |  
                v  
ROM:080C4164 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:080C4164
ROM:080C4164
ROM:080C4164 get_worldmap_value                      ; CODE XREF: read_position_map+34p
ROM:080C4164                                         ; sub_80C3580+34p ...
ROM:080C4164                 PUSH    {R4,R5,LR}      ; save needed registers
ROM:080C4166                 LSL     R0, R0, #0x18
ROM:080C4168                 LSR     R0, R0, #0x18   ; prevent overflow
ROM:080C416A                 ADD     R5, R0, #0      ; R5 = R0
ROM:080C416C                 LSL     R1, R1, #0x18
ROM:080C416E                 LSR     R4, R1, #0x18   ; R4 = overflow secure R1
ROM:080C4170                 LSL     R2, R2, #0x10
ROM:080C4172                 LSR     R2, R2, #0x10   ; prevent overflow for R2 (Y)
ROM:080C4174                 LSL     R3, R3, #0x10
ROM:080C4176                 LSR     R1, R3, #0x10   ; R1 = overflow secure X coordinate
ROM:080C4178                 CMP     R0, #1          ; check if worldmap #1 is loaded
ROM:080C417A                 BEQ     load_map_1_offset
ROM:080C417C                 CMP     R0, #1
ROM:080C417E                 BGT     loc_80C4186     ; is it worldmap #2 or #3?
ROM:080C4180                 CMP     R0, #0          ; or maybe the main map?
ROM:080C4182                 BEQ     load_map_0_offset
ROM:080C4184                 B       invalid_input   ; in any other case exit sub
ROM:080C4186 ; ---------------------------------------------------------------------------
ROM:080C4186
ROM:080C4186 loc_80C4186                             ; CODE XREF: get_worldmap_value+1Aj
ROM:080C4186                 CMP     R5, #2          ; check for worldmap #2
ROM:080C4188                 BEQ     load_map_2_offset
ROM:080C418A                 CMP     R5, #3          ; last possibility: map #3 ...?
ROM:080C418C                 BEQ     load_map_3_offset
ROM:080C418E                 B       invalid_input   ; no match found? so please exit sub
ROM:080C4190 ; ---------------------------------------------------------------------------
ROM:080C4190
ROM:080C4190 load_map_0_offset                       ; CODE XREF: get_worldmap_value+1Ej
ROM:080C4190                 LDR     R3, =0x83F2490  ; load base for map #0
ROM:080C4192                 B       read_value      ; now, get the value
ROM:080C4192 ; ---------------------------------------------------------------------------
ROM:080C4194 map0_base                               ; DATA XREF: get_worldmap_value:load_map_0_offsetr
ROM:080C4194                 DCD 0x83F2490
ROM:080C4198 ; ---------------------------------------------------------------------------
ROM:080C4198
ROM:080C4198 load_map_1_offset                       ; CODE XREF: get_worldmap_value+16j
ROM:080C4198                 LDR     R3, =0x83F2724  ; load base for map #1
ROM:080C419A                 B       read_value      ; now, get the value
ROM:080C419A ; ---------------------------------------------------------------------------
ROM:080C419C map1_base                               ; DATA XREF: get_worldmap_value:load_map_1_offsetr
ROM:080C419C                 DCD 0x83F2724
ROM:080C41A0 ; ---------------------------------------------------------------------------
ROM:080C41A0
ROM:080C41A0 load_map_2_offset                       ; CODE XREF: get_worldmap_value+24j
ROM:080C41A0                 LDR     R3, =0x83F29B8  ; load base for map #2
ROM:080C41A2                 B       read_value      ; now, get the value
ROM:080C41A2 ; ---------------------------------------------------------------------------
ROM:080C41A4 map2_base                               ; DATA XREF: get_worldmap_value:load_map_2_offsetr
ROM:080C41A4                 DCD 0x83F29B8
ROM:080C41A8 ; ---------------------------------------------------------------------------
ROM:080C41A8
ROM:080C41A8 load_map_3_offset                       ; CODE XREF: get_worldmap_value+28j
ROM:080C41A8                 LDR     R3, =0x83F2C4C  ; load base for map #3
ROM:080C41AA
ROM:080C41AA read_value                              ; CODE XREF: get_worldmap_value+2Ej
ROM:080C41AA                                         ; get_worldmap_value+36j ...
ROM:080C41AA                 LSL     R1, R1, #0x10
ROM:080C41AC                 ASR     R1, R1, #0x10   ; prevent overflow again
ROM:080C41AE                 LSL     R0, R2, #0x10
ROM:080C41B0                 ASR     R0, R0, #0x10   ; R0 is the Y coordinate
ROM:080C41B0                                         ; and R1 is the X coordinate
ROM:080C41B2                 MOV     R2, #0x16
ROM:080C41B4                 MUL     R0, R2          ; multiply the Y coordinate by 22
ROM:080C41B4                                         ; why 22? the map's width is 21...
ROM:080C41B6                 ADD     R1, R1, R0      ; add the X coordinate to it
ROM:080C41B8                 LSL     R0, R4, #2      ; R0 = R4 * 4
ROM:080C41BA                 ADD     R0, R0, R4      ; R0 = R0 + R4
ROM:080C41BA                                         ; (R0 = R4 * 5)
ROM:080C41BC                 LSL     R2, R0, #5      ; R2 = R0 * 32
ROM:080C41BC                                         ; (R0 = R4 * 160)
ROM:080C41BE                 ADD     R0, R0, R2      ; R0 = R0 + R2
ROM:080C41BE                                         ; (R0 = R4 * 161)
ROM:080C41C0                 LSL     R0, R0, #1      ; R0 = R0 * 2
ROM:080C41C0                                         ; (R0 = R4 * 322)
ROM:080C41C2                 ADD     R1, R1, R0      ; add that strange (R4 * 322) to R1
ROM:080C41C4                 ADD     R1, R1, R3      ; add R1 to the base pointer
ROM:080C41C6                 LDRB    R0, [R1]        ; get the value!
ROM:080C41C8                 B       exit_function
ROM:080C41C8 ; ---------------------------------------------------------------------------
ROM:080C41CA                 DCW 0
ROM:080C41CC map3_base                               ; DATA XREF: get_worldmap_value:load_map_3_offsetr
ROM:080C41CC                 DCD 0x83F2C4C
ROM:080C41D0 ; ---------------------------------------------------------------------------
ROM:080C41D0
ROM:080C41D0 invalid_input                           ; CODE XREF: get_worldmap_value+20j
ROM:080C41D0                                         ; get_worldmap_value+2Aj
ROM:080C41D0                 MOV     R0, #0xC5       ; something has gone wrong, return 0xC5
ROM:080C41D2
ROM:080C41D2 exit_function                           ; CODE XREF: get_worldmap_value+64j
ROM:080C41D2                 POP     {R4,R5}
ROM:080C41D4                 POP     {R1}
ROM:080C41D6                 BX      R1              ; return to 080C4150
ROM:080C41D6 ; End of function get_worldmap_value
ROM:080C41D6
ROM:080C41D6 ; ---------------------------------------------------------------------------

I think, the whole calculation is quite evident. The routine is "simulating" the rectangle of the worldmap. It's base + (Y * (width - 1) + X). Sadly, I have no idea what the part with the * 322 is supposed to do, because R4 always seems to be zero when executing the opcodes. Due to the fact that I'm so nice and so cool, I've made a schema of the function for you (click to enlarge):

If you still don't have any clue what I'm talking about, please stop reading at this point. I simply just can't explain it better, it is overpowering me. XD

However, open the Hexviewer at the mapbase you want to change. Read the comments in the routine above to get the desired offset. I do use map_0, so I use the base from 0x83F2490 to 0x83F2724. If you "resize" them back to the original 22-tiles-width of the rectangle, you get the following:

C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 7C 7D 7D C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 7C C5 C5 C5 C5 C5 C5 C5 
C5 C5 61 C5 C5 C5 C5 C5 63 68 68 68 68 68 5B 6D 6D 6D 64 C5 C5 C5 
C5 C5 7B C5 5A 67 67 67 67 C5 C5 C5 C5 C5 69 C5 C5 C5 6E C5 C5 C5 
C5 C5 7B C5 66 C5 C5 C5 C5 C5 C5 C5 C5 C5 69 C5 C5 C5 6E C5 C5 C5 
C5 C5 7B C5 66 C5 C5 74 74 74 74 5E 6B 6B 62 6C 6C 6C 5C C5 C5 C5 
C5 C5 7B C5 66 C5 C5 75 C5 C5 C5 C5 C5 C5 6A C5 C5 C5 70 C5 C5 C5 
C5 C5 7A 7A 59 C5 C5 75 C5 C5 C5 C5 C5 C5 6A C5 C5 C5 70 C5 C5 C5 
C5 C5 C5 C5 65 C5 C5 75 C5 C5 C5 C5 C5 C5 5D 6F 6F 6F 70 C5 C5 C5 
C5 C5 C5 C5 65 C5 C5 75 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 70 C5 C5 C5 
C5 C5 C5 C5 58 C5 C5 75 C5 C5 C5 C5 C5 C5 C5 72 71 71 70 C5 C5 C5 
C5 C5 C5 C5 79 C5 C5 76 76 76 76 76 5F 73 73 72 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 79 C5 C5 C5 C5 C5 C5 C5 77 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 60 78 78 78 78 78 78 78 77 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 7F C5 C5 C5 C5 8D C5 C5 C5 8A C5 C5 C5 
C5 C5 84 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 8E C5 C5 C5 
C5 C5 C5 C5 83 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 7E C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 8C C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 83 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 88 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 
C5 C5 C5 C5 87 C5 C5 C5 8B C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5

Looks still confusing. =\
But I have an idea. (What a luck ^^) Do you remember the "invalid_input" part of the ASM function? Since it always returns "C5" for "invalid", we can obviously consider the "C5" as "blank". So let's replace the "C5" by " ".

AWESOME!!111
I think, everything is clear if you just have a look to the picture. The first part of the mapbase is used for the routes and cities while the second one represents the little blue points on the worldmap. I'm confident that you're able to change the mapbase like you want. Just think off a "virtual byte map" if you're working on it. That makes the thing easier for you.

After changing everything, an other problem appears: The cities don't change their position. Indeed they're blinking if the cursor is at the new location, but the sprite remains on the old position. To solve that issue, we need VBASDL-H again.

Put a breakpoint on read to any city and select it. E.g. I choose the byte representing Pallet Town at 0x083f2586. The game breaks.

Breakpoint (on read) address 083f2586 byte:58
R00=00000058 R04=00000000 R08=00000000 R12=00000040
R01=083f2586 R05=00000000 R09=00000000 R13=03007de0
R02=00000000 R06=030030e4 R10=00000000 R14=080c33b3
R03=083f2490 R07=030030f0 R11=00000000 R15=080c41ca
CPSR=0000003f (......T Mode: 1f)
080c41c8  e003 b $080c41d2

Let's investigate how the 0x58 is interpreted. 0x80c41c8 is in the routine we analyzed before. (of course...)
Type "n" until you reach the "bx" opcode. (Note: "bx rX" stands for "branch exchange" and switches the values of PC (=R15) and rX)

R00=00000058 R04=020399e4 R08=00000000 R12=00000040
R01=080c33b3 R05=00000000 R09=00000000 R13=03007dec
R02=00000000 R06=030030e4 R10=00000000 R14=080c33b3
R03=083f2490 R07=030030f0 R11=00000000 R15=080c41d8
CPSR=0000003f (......T Mode: 1f)
080c41d6  4708 bx r1
debugger> n
R00=00000058 R04=020399e4 R08=00000000 R12=00000040
R01=080c33b3 R05=00000000 R09=00000000 R13=03007dec
R02=00000000 R06=030030e4 R10=00000000 R14=080c33b3
R03=083f2490 R07=030030f0 R11=00000000 R15=080c33b4
CPSR=0000003f (......T Mode: 1f)
080c33b2  6821 ldr r1, [r4, #0x0]

The CPU returns to 0x080c33b2. Type "dt 080c33ae" in VBASDL-H to disassemble the thumb routine.

080c33ae  f000 bl $080c4164
080c33b2  6821 ldr r1, [r4, #0x0]
080c33b4  0600 lsl r0, r0, #0x18
080c33b6  0e00 lsr r0, r0, #0x18
080c33b8  8288 strh r0, [r1, #0x14]
080c33ba  f000 bl $080c35dc
080c33be  6821 ldr r1, [r4, #0x0]
080c33c0  0600 lsl r0, r0, #0x18
080c33c2  0e00 lsr r0, r0, #0x18
080c33c4  82c8 strh r0, [r1, #0x16]
080c33c6  f7fd bl $080c0e20
080c33ca  0600 lsl r0, r0, #0x18
080c33cc  0e00 lsr r0, r0, #0x18
080c33ce  6821 ldr r1, [r4, #0x0]
080c33d0  2302 mov r3, #0x2
080c33d2  5eca ldsh r2, [r1, r3]
080c33d4  2500 mov r5, #0x0
080c33d6  5f4b ldsh r3, [r1, r5]
080c33d8  2101 mov r1, #0x1
080c33da  f000 bl $080c4164
080c33de  0600 lsl r0, r0, #0x18
080c33e0  0e00 lsr r0, r0, #0x18
080c33e2  f000 bl $080c3878
080c33e6  6821 ldr r1, [r4, #0x0]
080c33e8  0600 lsl r0, r0, #0x18
080c33ea  0e00 lsr r0, r0, #0x18

Do you recognize all the "bl"s? Every "bl" is a "long branch with link" and is a jump-advice to the adress behind it. Since there are so many of them we can consider this routine as a kind of "major" event, steering a certain programm flow.

Put a thumb breakpoint on the first bl (bt 080c35dc) and type c.

Breakpoint 0 reached
R00=00000058 R04=020399e4 R08=00000000 R12=00000040
R01=02008130 R05=00000000 R09=00000000 R13=03007dec
R02=00000000 R06=030030e4 R10=00000000 R14=080c33bf
R03=083f2490 R07=030030f0 R11=00000000 R15=080c35de
CPSR=0000003f (......T Mode: 1f)
080c35dc  b500 push {lr}

Okay. I disassemble the whole thing for you (with comments).

ROM:080C35DC ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:080C35DC
ROM:080C35DC
ROM:080C35DC get_flagnr_towns                        ; CODE XREF: ROM:080C33BAp
ROM:080C35DC                                         ; sub_80C4614+90p ...
ROM:080C35DC                 PUSH    {LR}
ROM:080C35DE                 LSL     R0, R0, #0x18
ROM:080C35E0                 LSR     R0, R0, #0x18   ; input is only 1 byte!
ROM:080C35E2                 SUB     R0, #0x58       ; substract 0x58 from the worldmap value
ROM:080C35E4                 CMP     R0, #0x6D
ROM:080C35E6                 BLS     get_offset      ; biggest possible value was 0xC5
ROM:080C35E6                                         ; 0xC5 - 0x58 = 0x6D, so the routine only
ROM:080C35E6                                         ; has to check for 0x6D
ROM:080C35E8                 B       invalid_input
ROM:080C35EA ; ---------------------------------------------------------------------------
ROM:080C35EA
ROM:080C35EA get_offset                              ; CODE XREF: get_flagnr_towns+Aj
ROM:080C35EA                 LSL     R0, R0, #2      ; value * 4 (so every data block has a
ROM:080C35EA                                         ; size of 4 bytes)
ROM:080C35EC                 LDR     R1, =0x80C35F8  ; base adress is 0x080C35F8
ROM:080C35EE                 ADD     R0, R0, R1      ; add "offset" and base adress
ROM:080C35F0                 LDR     R0, [R0]        ; get the pointer!
ROM:080C35F2                 MOV     PC, R0          ; PC = programme counter (=R15) is set
ROM:080C35F2                                         ; to R0. The execution is continued from
ROM:080C35F2                                         ; there
ROM:080C35F2 ; ---------------------------------------------------------------------------
ROM:080C35F4 dword_80C35F4   DCD 0x80C35F8           ; DATA XREF: get_flagnr_towns+10r
ROM:080C35F8                 DCD loc_80C37B0         ; the pointertable goes here
ROM:080C35FC                 DCD loc_80C37B6         ; 0x01
ROM:080C3600                 DCD loc_80C37C0         ; 0x02
ROM:080C3604                 DCD loc_80C37C8         ; 0x03
ROM:080C3608                 DCD loc_80C37D0         ; 0x04
ROM:080C360C                 DCD loc_80C37D8         ; 0x05
ROM:080C3610                 DCD loc_80C37E0         ; 0x06
ROM:080C3614                 DCD loc_80C37E8         ; and so on...
ROM:080C3618                 DCD loc_80C37F0
ROM:080C361C                 DCD loc_80C37F8
ROM:080C3620                 DCD loc_80C3800
ROM:080C3624                 DCD loc_80C3840         ; this is a special routine...
ROM:080C3624                                         ; it's the square at mt. moon
ROM:080C3628                 DCD unk_80C3858
ROM:080C362C                 DCD invalid_input       ; all the pointers labeled "invalid_input" jump
ROM:080C362C                                         ; to 0x080C3870
ROM:080C3630                 DCD invalid_input
ROM:080C3634                 DCD invalid_input
ROM:080C3638                 DCD invalid_input
ROM:080C363C                 DCD invalid_input
ROM:080C3640                 DCD invalid_input
ROM:080C3644                 DCD invalid_input
ROM:080C3648                 DCD invalid_input
ROM:080C364C                 DCD invalid_input
ROM:080C3650                 DCD invalid_input
ROM:080C3654                 DCD invalid_input
ROM:080C3658                 DCD invalid_input
ROM:080C365C                 DCD invalid_input
ROM:080C3660                 DCD invalid_input
ROM:080C3664                 DCD invalid_input
ROM:080C3668                 DCD invalid_input
ROM:080C366C                 DCD invalid_input
ROM:080C3670                 DCD invalid_input
ROM:080C3674                 DCD invalid_input
ROM:080C3678                 DCD invalid_input
ROM:080C367C                 DCD invalid_input
ROM:080C3680                 DCD invalid_input
ROM:080C3684                 DCD invalid_input
ROM:080C3688                 DCD invalid_input
ROM:080C368C                 DCD invalid_input
ROM:080C3690                 DCD invalid_input
ROM:080C3694                 DCD invalid_input
ROM:080C3698                 DCD invalid_input
ROM:080C369C                 DCD invalid_input
ROM:080C36A0                 DCD invalid_input
ROM:080C36A4                 DCD invalid_input
ROM:080C36A8                 DCD invalid_input
ROM:080C36AC                 DCD invalid_input
ROM:080C36B0                 DCD invalid_input
ROM:080C36B4                 DCD invalid_input
ROM:080C36B8                 DCD invalid_input
ROM:080C36BC                 DCD invalid_input
ROM:080C36C0                 DCD invalid_input
ROM:080C36C4                 DCD invalid_input
ROM:080C36C8                 DCD invalid_input
ROM:080C36CC                 DCD invalid_input
ROM:080C36D0                 DCD invalid_input
ROM:080C36D4                 DCD loc_80C3808
ROM:080C36D8                 DCD loc_80C3810
ROM:080C36DC                 DCD loc_80C3818
ROM:080C36E0                 DCD loc_80C3820
ROM:080C36E4                 DCD loc_80C3828
ROM:080C36E8                 DCD loc_80C3830
ROM:080C36EC                 DCD loc_80C3836
ROM:080C36F0                 DCD invalid_input
ROM:080C36F4                 DCD invalid_input
ROM:080C36F8                 DCD invalid_input
ROM:080C36FC                 DCD invalid_input
ROM:080C3700                 DCD invalid_input
ROM:080C3704                 DCD invalid_input
ROM:080C3708                 DCD invalid_input
ROM:080C370C                 DCD invalid_input
ROM:080C3710                 DCD invalid_input
ROM:080C3714                 DCD invalid_input
ROM:080C3718                 DCD invalid_input
ROM:080C371C                 DCD invalid_input
ROM:080C3720                 DCD invalid_input
ROM:080C3724                 DCD invalid_input
ROM:080C3728                 DCD invalid_input
ROM:080C372C                 DCD invalid_input
ROM:080C3730                 DCD invalid_input
ROM:080C3734                 DCD invalid_input
ROM:080C3738                 DCD invalid_input
ROM:080C373C                 DCD invalid_input
ROM:080C3740                 DCD invalid_input
ROM:080C3744                 DCD invalid_input
ROM:080C3748                 DCD invalid_input
ROM:080C374C                 DCD invalid_input
ROM:080C3750                 DCD invalid_input
ROM:080C3754                 DCD invalid_input
ROM:080C3758                 DCD invalid_input
ROM:080C375C                 DCD invalid_input
ROM:080C3760                 DCD invalid_input
ROM:080C3764                 DCD invalid_input
ROM:080C3768                 DCD invalid_input
ROM:080C376C                 DCD invalid_input
ROM:080C3770                 DCD invalid_input
ROM:080C3774                 DCD invalid_input
ROM:080C3778                 DCD invalid_input
ROM:080C377C                 DCD invalid_input
ROM:080C3780                 DCD invalid_input
ROM:080C3784                 DCD invalid_input
ROM:080C3788                 DCD invalid_input
ROM:080C378C                 DCD invalid_input
ROM:080C3790                 DCD invalid_input
ROM:080C3794                 DCD invalid_input
ROM:080C3798                 DCD invalid_input
ROM:080C379C                 DCD invalid_input
ROM:080C37A0                 DCD invalid_input
ROM:080C37A4                 DCD invalid_input
ROM:080C37A8                 DCD invalid_input
ROM:080C37AC                 DCD no_mt_moon
ROM:080C37B0 ; ---------------------------------------------------------------------------
ROM:080C37B0
ROM:080C37B0 loc_80C37B0                             ; DATA XREF: get_flagnr_towns+1Co
ROM:080C37B0                 MOVL    R0, 0x890       ; 0x080C37B0 is the value the pointer hold
ROM:080C37B0                                         ; on the position of pallet town
ROM:080C37B0                                         ; ldr (0x080C35F8 + (0x58 - 0x58) * 4)
ROM:080C37B0                                         ;
ROM:080C37B0                                         ; r0 (= flag nr) is set to 0x890
ROM:080C37B0                                         ; so flag 0x890 defines whether you could
ROM:080C37B0                                         ; fly to new pallet town or whether you
ROM:080C37B0                                         ; couldn't
ROM:080C37B4                 B       check_flag
ROM:080C37B6 ; ---------------------------------------------------------------------------
ROM:080C37B6
ROM:080C37B6 loc_80C37B6                             ; DATA XREF: get_flagnr_towns+20o
ROM:080C37B6                 LDR     R0, =0x891      ; 0x59 is viridian city... 0x59 - 0x58 = 0x01
ROM:080C37B6                                         ; then the pointer is loaded and the cpu jumps to
ROM:080C37B6                                         ; this location.
ROM:080C37B6                                         ; flagnr for viridian goes here...
ROM:080C37B8                 B       check_flag
ROM:080C37B8 ; ---------------------------------------------------------------------------
ROM:080C37BA                 DCB    0
ROM:080C37BB                 DCB    0
ROM:080C37BC dword_80C37BC   DCD 0x891               ; DATA XREF: get_flagnr_towns:loc_80C37B6r
ROM:080C37C0 ; ---------------------------------------------------------------------------
ROM:080C37C0
ROM:080C37C0 loc_80C37C0                             ; DATA XREF: get_flagnr_towns+24o
ROM:080C37C0                 LDR     R0, =0x892      ; and so on...
ROM:080C37C2                 B       check_flag
ROM:080C37C2 ; ---------------------------------------------------------------------------
ROM:080C37C4 dword_80C37C4   DCD 0x892               ; DATA XREF: get_flagnr_towns:loc_80C37C0r
ROM:080C37C8 ; ---------------------------------------------------------------------------
ROM:080C37C8
ROM:080C37C8 loc_80C37C8                             ; DATA XREF: get_flagnr_towns+28o
ROM:080C37C8                 LDR     R0, =0x893
ROM:080C37CA                 B       check_flag
ROM:080C37CA ; ---------------------------------------------------------------------------
ROM:080C37CC dword_80C37CC   DCD 0x893               ; DATA XREF: get_flagnr_towns:loc_80C37C8r
ROM:080C37D0 ; ---------------------------------------------------------------------------
ROM:080C37D0
ROM:080C37D0 loc_80C37D0                             ; DATA XREF: get_flagnr_towns+2Co
ROM:080C37D0                 LDR     R0, =0x894
ROM:080C37D2                 B       check_flag
ROM:080C37D2 ; ---------------------------------------------------------------------------
ROM:080C37D4 dword_80C37D4   DCD 0x894               ; DATA XREF: get_flagnr_towns:loc_80C37D0r
ROM:080C37D8 ; ---------------------------------------------------------------------------
ROM:080C37D8
ROM:080C37D8 loc_80C37D8                             ; DATA XREF: get_flagnr_towns+30o
ROM:080C37D8                 LDR     R0, =0x895
ROM:080C37DA                 B       check_flag
ROM:080C37DA ; ---------------------------------------------------------------------------
ROM:080C37DC dword_80C37DC   DCD 0x895               ; DATA XREF: get_flagnr_towns:loc_80C37D8r
ROM:080C37E0 ; ---------------------------------------------------------------------------
ROM:080C37E0
ROM:080C37E0 loc_80C37E0                             ; DATA XREF: get_flagnr_towns+34o
ROM:080C37E0                 LDR     R0, =0x896
ROM:080C37E2                 B       check_flag
ROM:080C37E2 ; ---------------------------------------------------------------------------
ROM:080C37E4 dword_80C37E4   DCD 0x896               ; DATA XREF: get_flagnr_towns:loc_80C37E0r
ROM:080C37E8 ; ---------------------------------------------------------------------------
ROM:080C37E8
ROM:080C37E8 loc_80C37E8                             ; DATA XREF: get_flagnr_towns+38o
ROM:080C37E8                 LDR     R0, =0x897
ROM:080C37EA                 B       check_flag
ROM:080C37EA ; ---------------------------------------------------------------------------
ROM:080C37EC dword_80C37EC   DCD 0x897               ; DATA XREF: get_flagnr_towns:loc_80C37E8r
ROM:080C37F0 ; ---------------------------------------------------------------------------
ROM:080C37F0
ROM:080C37F0 loc_80C37F0                             ; DATA XREF: get_flagnr_towns+3Co
ROM:080C37F0                 LDR     R0, =0x898
ROM:080C37F2                 B       check_flag
ROM:080C37F2 ; ---------------------------------------------------------------------------
ROM:080C37F4 dword_80C37F4   DCD 0x898               ; DATA XREF: get_flagnr_towns:loc_80C37F0r
ROM:080C37F8 ; ---------------------------------------------------------------------------
ROM:080C37F8
ROM:080C37F8 loc_80C37F8                             ; DATA XREF: get_flagnr_towns+40o
ROM:080C37F8                 LDR     R0, =0x899
ROM:080C37FA                 B       check_flag
ROM:080C37FA ; ---------------------------------------------------------------------------
ROM:080C37FC dword_80C37FC   DCD 0x899               ; DATA XREF: get_flagnr_towns:loc_80C37F8r
ROM:080C3800 ; ---------------------------------------------------------------------------
ROM:080C3800
ROM:080C3800 loc_80C3800                             ; DATA XREF: get_flagnr_towns+44o
ROM:080C3800                 LDR     R0, =0x89A
ROM:080C3802                 B       check_flag
ROM:080C3802 ; ---------------------------------------------------------------------------
ROM:080C3804 dword_80C3804   DCD 0x89A               ; DATA XREF: get_flagnr_towns:loc_80C3800r
ROM:080C3808 ; ---------------------------------------------------------------------------
ROM:080C3808
ROM:080C3808 loc_80C3808                             ; DATA XREF: get_flagnr_towns+F8o
ROM:080C3808                 LDR     R0, =0x89B
ROM:080C380A                 B       check_flag
ROM:080C380A ; ---------------------------------------------------------------------------
ROM:080C380C dword_80C380C   DCD 0x89B               ; DATA XREF: get_flagnr_towns:loc_80C3808r
ROM:080C3810 ; ---------------------------------------------------------------------------
ROM:080C3810
ROM:080C3810 loc_80C3810                             ; DATA XREF: get_flagnr_towns+FCo
ROM:080C3810                 LDR     R0, word_80C3814
ROM:080C3812                 B       check_flag
ROM:080C3812 ; ---------------------------------------------------------------------------
ROM:080C3814 word_80C3814    DCW 0x89C               ; DATA XREF: get_flagnr_towns:loc_80C3810r
ROM:080C3816                 DCB    0
ROM:080C3817                 DCB    0
ROM:080C3818 ; ---------------------------------------------------------------------------
ROM:080C3818
ROM:080C3818 loc_80C3818                             ; DATA XREF: get_flagnr_towns+100o
ROM:080C3818                 LDR     R0, =0x89D
ROM:080C381A                 B       check_flag
ROM:080C381A ; ---------------------------------------------------------------------------
ROM:080C381C dword_80C381C   DCD 0x89D               ; DATA XREF: get_flagnr_towns:loc_80C3818r
ROM:080C3820 ; ---------------------------------------------------------------------------
ROM:080C3820
ROM:080C3820 loc_80C3820                             ; DATA XREF: get_flagnr_towns+104o
ROM:080C3820                 LDR     R0, =0x89E
ROM:080C3822                 B       check_flag
ROM:080C3822 ; ---------------------------------------------------------------------------
ROM:080C3824 dword_80C3824   DCD 0x89E               ; DATA XREF: get_flagnr_towns:loc_80C3820r
ROM:080C3828 ; ---------------------------------------------------------------------------
ROM:080C3828
ROM:080C3828 loc_80C3828                             ; DATA XREF: get_flagnr_towns+108o
ROM:080C3828                 LDR     R0, =0x89F
ROM:080C382A                 B       check_flag
ROM:080C382A ; ---------------------------------------------------------------------------
ROM:080C382C dword_80C382C   DCD 0x89F               ; DATA XREF: get_flagnr_towns:loc_80C3828r
ROM:080C3830 ; ---------------------------------------------------------------------------
ROM:080C3830
ROM:080C3830 loc_80C3830                             ; DATA XREF: get_flagnr_towns+10Co
ROM:080C3830                 MOVL    R0, 0x8A0
ROM:080C3834                 B       check_flag
ROM:080C3836 ; ---------------------------------------------------------------------------
ROM:080C3836
ROM:080C3836 loc_80C3836                             ; DATA XREF: get_flagnr_towns+110o
ROM:080C3836                 LDR     R0, =0x8A1
ROM:080C3838                 B       check_flag
ROM:080C3838 ; ---------------------------------------------------------------------------
ROM:080C383A                 DCB    0
ROM:080C383B                 DCB    0
ROM:080C383C dword_80C383C   DCD 0x8A1               ; DATA XREF: get_flagnr_towns:loc_80C3836r
ROM:080C3840 ; ---------------------------------------------------------------------------
ROM:080C3840
ROM:080C3840 loc_80C3840                             ; DATA XREF: get_flagnr_towns+48o
ROM:080C3840                 MOV     R0, #3
ROM:080C3842                 BL      get_flag_mt_moon
ROM:080C3846                 LSL     R0, R0, #0x18
ROM:080C3848                 CMP     R0, #0          ; check if you have already passed route 4
ROM:080C384A                 BNE     loc_80C3850
ROM:080C384C
ROM:080C384C no_mt_moon                              ; DATA XREF: get_flagnr_towns+1D0o
ROM:080C384C                 MOV     R0, #0
ROM:080C384E                 B       exit_function
ROM:080C3850 ; ---------------------------------------------------------------------------
ROM:080C3850
ROM:080C3850 loc_80C3850                             ; CODE XREF: get_flagnr_towns+26Ej
ROM:080C3850                 LDR     R0, =0x8A2      ; flagnr of mt. moon
ROM:080C3852                 B       check_flag
ROM:080C3852 ; ---------------------------------------------------------------------------
ROM:080C3854 dword_80C3854   DCD 0x8A2               ; DATA XREF: get_flagnr_towns:loc_80C3850r
ROM:080C3858 unk_80C3858     DCB    4                ; DATA XREF: get_flagnr_towns+4Co
ROM:080C3859                 DCB 0x48 ; H
ROM:080C385A ; ---------------------------------------------------------------------------
ROM:080C385A
ROM:080C385A check_flag                              ; CODE XREF: get_flagnr_towns+1D8j
ROM:080C385A                                         ; get_flagnr_towns+1DCj ...
ROM:080C385A                 BL      checkflag_r0    ; check flag. it's a branch to the 
ROM:080C385A                                         ; standard function, so I won't reverse 
ROM:080C385A                                         ; everything related to that flag... just accept 
ROM:080C385A                                         ; that a branch to 0806E6D0 checks flagnr stored 
ROM:080C385A                                         ; in r0
ROM:080C385E                 LSL     R0, R0, #0x18
ROM:080C3860                 MOV     R1, #3          ; return #3
ROM:080C3862                 CMP     R0, #0          ; compare flagvalue with 0
ROM:080C3864                 BEQ     loc_80C3868
ROM:080C3866                 MOV     R1, #2          ; if the flag is true then overwrite #3 by #2
ROM:080C3868
ROM:080C3868 loc_80C3868                             ; CODE XREF: get_flagnr_towns+288j
ROM:080C3868                 ADD     R0, R1, #0
ROM:080C386A                 B       exit_function
ROM:080C386A ; ---------------------------------------------------------------------------
ROM:080C386C                 DCB 0xA3 ; ú
ROM:080C386D                 DCB    8
ROM:080C386E                 DCB    0
ROM:080C386F                 DCB    0
ROM:080C3870 ; ---------------------------------------------------------------------------
ROM:080C3870
ROM:080C3870 invalid_input                           ; CODE XREF: get_flagnr_towns+Cj
ROM:080C3870                                         ; DATA XREF: get_flagnr_towns+50o ...
ROM:080C3870                 MOV     R0, #1          ; return #1
ROM:080C3872
ROM:080C3872 exit_function                           ; CODE XREF: get_flagnr_towns+272j
ROM:080C3872                                         ; get_flagnr_towns+28Ej
ROM:080C3872                 POP     {R1}
ROM:080C3874                 BX      R1
ROM:080C3874 ; End of function get_flagnr_towns

The picture of the function: (pls don't cry):

This function assigns a flag to every destination on the worldmap. Afterwards it is checked for true and if this is the case, it returns 0x03 in r0. If the flag is found but it's zero, the function returns 0x02. In any other case the output is 0x01.

To make the thingy clear, we'll do an example. Let's say, we want to be able to fly to Route 25. Therefore, we need to remove another location. In our case, Vermilion City doesn't exist animore. Route 25 is represented by the worldmap value 0x7D, while Vermilion City is 0x5D.

If you give 0x7D to the routine, it substracts 0x58 - we get 0x25. 0x25 is multiplied by 4 and the result is added to the base adress 0x080C35F8. So he calculates (0x25 * 4) + 0x080C35F8, which is 0x080C368C. Looking at our jumptable, we only find a "DCD invalid_input". And that's the point where we need to know where the handler usually jumps for Vermilion City (=0x5D). Do the same calculation and you'll result in 0x080C360C. The jump destination there is 0x080C37D8. So replace the 0x080C3870 (= jumpadress for "invalid input") at 0x080C368C by 0x080C37D8. Don't let confuse you, read the last lines several times and everything will seem logical to you.

If you recognize Vermilion's flag (0x895) already being used by some other events, just change the 0x00000895 at 0x080C37DC.

Back to our major event! Do you see the next long branch with link?

080c33c6  f7fd bl $080c0e20

This one is rather small. *assuaged* I explain what it does:

ROM:080C0E20 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:080C0E20
ROM:080C0E20
ROM:080C0E20 sub_80C0E20                             ; CODE XREF: ROM:loc_80C339Ap
ROM:080C0E20                                         ; ROM:080C33C6p ...
ROM:080C0E20                 LDR     R0, =0x20399D4  ; load pointer adress
ROM:080C0E22                 LDR     R0, [R0]        ; load pointer
ROM:080C0E24                 LDR     R1, =0x479B
ROM:080C0E26                 ADD     R0, R0, R1      ; add "offset" to it
ROM:080C0E28                 LDRB    R0, [R0]        ; get the byte from there
ROM:080C0E2A                 BX      LR
ROM:080C0E2A ; End of function sub_80C0E20

At this point, we discover a little problem: We don't know yet which pointer is at 0x020399D4. To solve that incredible difficult concern (<= irony), open the memviewer of VBA at position 0x020399D4.

Wh000t, there are only zeros?!? meh...

Uhm. Just a moment... activate the auto update and open the worldmap.

Wow! A pointer appears like magic! *astonished*

It's 0x02000024. The routine adds 0x479B to it as you can see above. Consequently, the byte at 020047bf is loaded and returned.

In principle that's enough to know for us. But due to my huge curiosity I open the memviewer again at 0x020047BF to figure out what it is.

To keep it short: It's the value declaring which worldmap should be loaded.

That's an important information. Note down that offset, we'll surely need it again!

Back to our routine. The next bl points to $080c4164 which is exactly the location of the first routine we analyzed together. bl $080c4164 returns the current world map value. (Annotation: That's a good example to show why debuggers are - in a way - inefficient. Why does the CPU read the value again instead of just taking care about not overwriting the register holding the value?)

The following branch executes a unknown function. We're gonna change that, so here is the next ASM routine for you: *hooraaaay*

ROM:080C3878 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:080C3878
ROM:080C3878
ROM:080C3878 get_flagnr_blue_points                  ; CODE XREF: ROM:080C33E2p
ROM:080C3878                                         ; sub_80C47F8+64p
ROM:080C3878                 PUSH    {LR}
ROM:080C387A                 LSL     R0, R0, #0x18   ; r0 = read data
ROM:080C387C                 LSR     R0, R0, #0x18
ROM:080C387E                 SUB     R0, #0x7E
ROM:080C3880                 CMP     R0, #0x47       ; is it a blue point?
ROM:080C3882                 BLS     loc_80C3886
ROM:080C3884                 B       invalid_input
ROM:080C3886 ; ---------------------------------------------------------------------------
ROM:080C3886
ROM:080C3886 loc_80C3886                             ; CODE XREF: get_flagnr_blue_points+Aj
ROM:080C3886                 LSL     R0, R0, #2      ; worldmap value * 4
ROM:080C3888                 LDR     R1, =off_80C3894 ; load the base of the table
ROM:080C388A                 ADD     R0, R0, R1
ROM:080C388C                 LDR     R0, [R0]        ; get pointer
ROM:080C388E                 MOV     PC, R0          ; continue execution from loaded position
ROM:080C388E ; ---------------------------------------------------------------------------
ROM:080C3890 off_80C3890     DCD off_80C3894         ; DATA XREF: get_flagnr_blue_points+10r
ROM:080C3894 off_80C3894     DCD loc_80C39B8         ; DATA XREF: get_flagnr_blue_points:off_80C3890o
ROM:080C3898                 DCD loc_80C39C0
ROM:080C389C                 DCD loc_80C39C8
ROM:080C38A0                 DCD loc_80C39D0
ROM:080C38A4                 DCD loc_80C39D8
ROM:080C38A8                 DCD loc_80C39E0
ROM:080C38AC                 DCD loc_80C39E8
ROM:080C38B0                 DCD loc_80C39F0
ROM:080C38B4                 DCD loc_80C39F8
ROM:080C38B8                 DCD loc_80C3A00
ROM:080C38BC                 DCD loc_80C3A08
ROM:080C38C0                 DCD loc_80C3A10
ROM:080C38C4                 DCD loc_80C3A18
ROM:080C38C8                 DCD loc_80C3A1E
ROM:080C38CC                 DCD loc_80C3A28
ROM:080C38D0                 DCD loc_80C3A30
ROM:080C38D4                 DCD loc_80C3A38
ROM:080C38D8                 DCD invalid_input
ROM:080C38DC                 DCD invalid_input
ROM:080C38E0                 DCD invalid_input
ROM:080C38E4                 DCD invalid_input
ROM:080C38E8                 DCD invalid_input
ROM:080C38EC                 DCD invalid_input
ROM:080C38F0                 DCD invalid_input
ROM:080C38F4                 DCD invalid_input
ROM:080C38F8                 DCD invalid_input
ROM:080C38FC                 DCD invalid_input
ROM:080C3900                 DCD invalid_input
ROM:080C3904                 DCD invalid_input
ROM:080C3908                 DCD invalid_input
ROM:080C390C                 DCD invalid_input
ROM:080C3910                 DCD invalid_input
ROM:080C3914                 DCD invalid_input
ROM:080C3918                 DCD invalid_input
ROM:080C391C                 DCD invalid_input
ROM:080C3920                 DCD invalid_input
ROM:080C3924                 DCD invalid_input
ROM:080C3928                 DCD invalid_input
ROM:080C392C                 DCD invalid_input
ROM:080C3930                 DCD invalid_input
ROM:080C3934                 DCD invalid_input
ROM:080C3938                 DCD invalid_input
ROM:080C393C                 DCD invalid_input
ROM:080C3940                 DCD invalid_input
ROM:080C3944                 DCD invalid_input
ROM:080C3948                 DCD invalid_input
ROM:080C394C                 DCD invalid_input
ROM:080C3950                 DCD invalid_input
ROM:080C3954                 DCD loc_80C3A40
ROM:080C3958                 DCD loc_80C3A48
ROM:080C395C                 DCD loc_80C3A50
ROM:080C3960                 DCD loc_80C3A58
ROM:080C3964                 DCD loc_80C3A60
ROM:080C3968                 DCD loc_80C3A68
ROM:080C396C                 DCD loc_80C3A70
ROM:080C3970                 DCD loc_80C3A78
ROM:080C3974                 DCD loc_80C3A80
ROM:080C3978                 DCD loc_80C3A88
ROM:080C397C                 DCD loc_80C3A90
ROM:080C3980                 DCD loc_80C3A98
ROM:080C3984                 DCD loc_80C3A9E
ROM:080C3988                 DCD loc_80C3AA8
ROM:080C398C                 DCD invalid_input
ROM:080C3990                 DCD invalid_input
ROM:080C3994                 DCD invalid_input
ROM:080C3998                 DCD invalid_input
ROM:080C399C                 DCD invalid_input
ROM:080C39A0                 DCD invalid_input
ROM:080C39A4                 DCD invalid_input
ROM:080C39A8                 DCD invalid_input
ROM:080C39AC                 DCD invalid_input
ROM:080C39B0                 DCD loc_80C39B4
ROM:080C39B4 ; ---------------------------------------------------------------------------
ROM:080C39B4
ROM:080C39B4 loc_80C39B4                             ; DATA XREF: get_flagnr_blue_points+138o
ROM:080C39B4                 MOV     R0, #0
ROM:080C39B6                 B       loc_80C3AC2
ROM:080C39B8 ; ---------------------------------------------------------------------------
ROM:080C39B8
ROM:080C39B8 loc_80C39B8                             ; DATA XREF: get_flagnr_blue_points:off_80C3894o
ROM:080C39B8                 LDR     R0, =0x8A4
ROM:080C39BA                 B       loc_80C3AAA
ROM:080C39BA ; ---------------------------------------------------------------------------
ROM:080C39BC dword_80C39BC   DCD 0x8A4               ; DATA XREF: get_flagnr_blue_points:loc_80C39B8r
ROM:080C39C0 ; ---------------------------------------------------------------------------
ROM:080C39C0
ROM:080C39C0 loc_80C39C0                             ; DATA XREF: get_flagnr_blue_points+20o
ROM:080C39C0                 LDR     R0, =0x8A5
ROM:080C39C2                 B       loc_80C3AAA
ROM:080C39C2 ; ---------------------------------------------------------------------------
ROM:080C39C4 dword_80C39C4   DCD 0x8A5               ; DATA XREF: get_flagnr_blue_points:loc_80C39C0r
ROM:080C39C8 ; ---------------------------------------------------------------------------
ROM:080C39C8
ROM:080C39C8 loc_80C39C8                             ; DATA XREF: get_flagnr_blue_points+24o
ROM:080C39C8                 LDR     R0, =0x8A6
ROM:080C39CA                 B       loc_80C3AAA
ROM:080C39CA ; ---------------------------------------------------------------------------
ROM:080C39CC dword_80C39CC   DCD 0x8A6               ; DATA XREF: get_flagnr_blue_points:loc_80C39C8r
ROM:080C39D0 ; ---------------------------------------------------------------------------
ROM:080C39D0
ROM:080C39D0 loc_80C39D0                             ; DATA XREF: get_flagnr_blue_points+28o
ROM:080C39D0                 LDR     R0, =0x8A7
ROM:080C39D2                 B       loc_80C3AAA
ROM:080C39D2 ; ---------------------------------------------------------------------------
ROM:080C39D4 dword_80C39D4   DCD 0x8A7               ; DATA XREF: get_flagnr_blue_points:loc_80C39D0r
ROM:080C39D8 ; ---------------------------------------------------------------------------
ROM:080C39D8
ROM:080C39D8 loc_80C39D8                             ; DATA XREF: get_flagnr_blue_points+2Co
ROM:080C39D8                 LDR     R0, =0x8A8
ROM:080C39DA                 B       loc_80C3AAA
ROM:080C39DA ; ---------------------------------------------------------------------------
ROM:080C39DC dword_80C39DC   DCD 0x8A8               ; DATA XREF: get_flagnr_blue_points:loc_80C39D8r
ROM:080C39E0 ; ---------------------------------------------------------------------------
ROM:080C39E0
ROM:080C39E0 loc_80C39E0                             ; DATA XREF: get_flagnr_blue_points+30o
ROM:080C39E0                 LDR     R0, =0x8A9
ROM:080C39E2                 B       loc_80C3AAA
ROM:080C39E2 ; ---------------------------------------------------------------------------
ROM:080C39E4 dword_80C39E4   DCD 0x8A9               ; DATA XREF: get_flagnr_blue_points:loc_80C39E0r
ROM:080C39E8 ; ---------------------------------------------------------------------------
ROM:080C39E8
ROM:080C39E8 loc_80C39E8                             ; DATA XREF: get_flagnr_blue_points+34o
ROM:080C39E8                 LDR     R0, =0x8AA
ROM:080C39EA                 B       loc_80C3AAA
ROM:080C39EA ; ---------------------------------------------------------------------------
ROM:080C39EC dword_80C39EC   DCD 0x8AA               ; DATA XREF: get_flagnr_blue_points:loc_80C39E8r
ROM:080C39F0 ; ---------------------------------------------------------------------------
ROM:080C39F0
ROM:080C39F0 loc_80C39F0                             ; DATA XREF: get_flagnr_blue_points+38o
ROM:080C39F0                 LDR     R0, =0x8AB
ROM:080C39F2                 B       loc_80C3AAA
ROM:080C39F2 ; ---------------------------------------------------------------------------
ROM:080C39F4 dword_80C39F4   DCD 0x8AB               ; DATA XREF: get_flagnr_blue_points:loc_80C39F0r
ROM:080C39F8 ; ---------------------------------------------------------------------------
ROM:080C39F8
ROM:080C39F8 loc_80C39F8                             ; DATA XREF: get_flagnr_blue_points+3Co
ROM:080C39F8                 LDR     R0, =0x8AC
ROM:080C39FA                 B       loc_80C3AAA
ROM:080C39FA ; ---------------------------------------------------------------------------
ROM:080C39FC dword_80C39FC   DCD 0x8AC               ; DATA XREF: get_flagnr_blue_points:loc_80C39F8r
ROM:080C3A00 ; ---------------------------------------------------------------------------
ROM:080C3A00
ROM:080C3A00 loc_80C3A00                             ; DATA XREF: get_flagnr_blue_points+40o
ROM:080C3A00                 LDR     R0, =0x8AD
ROM:080C3A02                 B       loc_80C3AAA
ROM:080C3A02 ; ---------------------------------------------------------------------------
ROM:080C3A04 dword_80C3A04   DCD 0x8AD               ; DATA XREF: get_flagnr_blue_points:loc_80C3A00r
ROM:080C3A08 ; ---------------------------------------------------------------------------
ROM:080C3A08
ROM:080C3A08 loc_80C3A08                             ; DATA XREF: get_flagnr_blue_points+44o
ROM:080C3A08                 LDR     R0, =0x8AE
ROM:080C3A0A                 B       loc_80C3AAA
ROM:080C3A0A ; ---------------------------------------------------------------------------
ROM:080C3A0C dword_80C3A0C   DCD 0x8AE               ; DATA XREF: get_flagnr_blue_points:loc_80C3A08r
ROM:080C3A10 ; ---------------------------------------------------------------------------
ROM:080C3A10
ROM:080C3A10 loc_80C3A10                             ; DATA XREF: get_flagnr_blue_points+48o
ROM:080C3A10                 LDR     R0, =0x8AF
ROM:080C3A12                 B       loc_80C3AAA
ROM:080C3A12 ; ---------------------------------------------------------------------------
ROM:080C3A14 dword_80C3A14   DCD 0x8AF               ; DATA XREF: get_flagnr_blue_points:loc_80C3A10r
ROM:080C3A18 ; ---------------------------------------------------------------------------
ROM:080C3A18
ROM:080C3A18 loc_80C3A18                             ; DATA XREF: get_flagnr_blue_points+4Co
ROM:080C3A18                 MOVL    R0, 0x8B0
ROM:080C3A1C                 B       loc_80C3AAA
ROM:080C3A1E ; ---------------------------------------------------------------------------
ROM:080C3A1E
ROM:080C3A1E loc_80C3A1E                             ; DATA XREF: get_flagnr_blue_points+50o
ROM:080C3A1E                 LDR     R0, =0x8B1
ROM:080C3A20                 B       loc_80C3AAA
ROM:080C3A20 ; ---------------------------------------------------------------------------
ROM:080C3A22 byte_80C3A22    DCB 0
ROM:080C3A23 byte_80C3A23    DCB 0
ROM:080C3A24 dword_80C3A24   DCD 0x8B1               ; DATA XREF: get_flagnr_blue_points:loc_80C3A1Er
ROM:080C3A28 ; ---------------------------------------------------------------------------
ROM:080C3A28
ROM:080C3A28 loc_80C3A28                             ; DATA XREF: get_flagnr_blue_points+54o
ROM:080C3A28                 LDR     R0, =0x8B2
ROM:080C3A2A                 B       loc_80C3AAA
ROM:080C3A2A ; ---------------------------------------------------------------------------
ROM:080C3A2C dword_80C3A2C   DCD 0x8B2               ; DATA XREF: get_flagnr_blue_points:loc_80C3A28r
ROM:080C3A30 ; ---------------------------------------------------------------------------
ROM:080C3A30
ROM:080C3A30 loc_80C3A30                             ; DATA XREF: get_flagnr_blue_points+58o
ROM:080C3A30                 LDR     R0, =0x8B3
ROM:080C3A32                 B       loc_80C3AAA
ROM:080C3A32 ; ---------------------------------------------------------------------------
ROM:080C3A34 dword_80C3A34   DCD 0x8B3               ; DATA XREF: get_flagnr_blue_points:loc_80C3A30r
ROM:080C3A38 ; ---------------------------------------------------------------------------
ROM:080C3A38
ROM:080C3A38 loc_80C3A38                             ; DATA XREF: get_flagnr_blue_points+5Co
ROM:080C3A38                 LDR     R0, =0x8B4
ROM:080C3A3A                 B       loc_80C3AAA
ROM:080C3A3A ; ---------------------------------------------------------------------------
ROM:080C3A3C dword_80C3A3C   DCD 0x8B4               ; DATA XREF: get_flagnr_blue_points:loc_80C3A38r
ROM:080C3A40 ; ---------------------------------------------------------------------------
ROM:080C3A40
ROM:080C3A40 loc_80C3A40                             ; DATA XREF: get_flagnr_blue_points+DCo
ROM:080C3A40                 LDR     R0, =0x8B5
ROM:080C3A42                 B       loc_80C3AAA
ROM:080C3A42 ; ---------------------------------------------------------------------------
ROM:080C3A44 dword_80C3A44   DCD 0x8B5               ; DATA XREF: get_flagnr_blue_points:loc_80C3A40r
ROM:080C3A48 ; ---------------------------------------------------------------------------
ROM:080C3A48
ROM:080C3A48 loc_80C3A48                             ; DATA XREF: get_flagnr_blue_points+E0o
ROM:080C3A48                 LDR     R0, =0x8B6
ROM:080C3A4A                 B       loc_80C3AAA
ROM:080C3A4A ; ---------------------------------------------------------------------------
ROM:080C3A4C dword_80C3A4C   DCD 0x8B6               ; DATA XREF: get_flagnr_blue_points:loc_80C3A48r
ROM:080C3A50 ; ---------------------------------------------------------------------------
ROM:080C3A50
ROM:080C3A50 loc_80C3A50                             ; DATA XREF: get_flagnr_blue_points+E4o
ROM:080C3A50                 LDR     R0, =0x8B7
ROM:080C3A52                 B       loc_80C3AAA
ROM:080C3A52 ; ---------------------------------------------------------------------------
ROM:080C3A54 dword_80C3A54   DCD 0x8B7               ; DATA XREF: get_flagnr_blue_points:loc_80C3A50r
ROM:080C3A58 ; ---------------------------------------------------------------------------
ROM:080C3A58
ROM:080C3A58 loc_80C3A58                             ; DATA XREF: get_flagnr_blue_points+E8o
ROM:080C3A58                 LDR     R0, =0x8B8
ROM:080C3A5A                 B       loc_80C3AAA
ROM:080C3A5A ; ---------------------------------------------------------------------------
ROM:080C3A5C dword_80C3A5C   DCD 0x8B8               ; DATA XREF: get_flagnr_blue_points:loc_80C3A58r
ROM:080C3A60 ; ---------------------------------------------------------------------------
ROM:080C3A60
ROM:080C3A60 loc_80C3A60                             ; DATA XREF: get_flagnr_blue_points+ECo
ROM:080C3A60                 LDR     R0, =0x8B9
ROM:080C3A62                 B       loc_80C3AAA
ROM:080C3A62 ; ---------------------------------------------------------------------------
ROM:080C3A64 dword_80C3A64   DCD 0x8B9               ; DATA XREF: get_flagnr_blue_points:loc_80C3A60r
ROM:080C3A68 ; ---------------------------------------------------------------------------
ROM:080C3A68
ROM:080C3A68 loc_80C3A68                             ; DATA XREF: get_flagnr_blue_points+F0o
ROM:080C3A68                 LDR     R0, =0x8BA
ROM:080C3A6A                 B       loc_80C3AAA
ROM:080C3A6A ; ---------------------------------------------------------------------------
ROM:080C3A6C dword_80C3A6C   DCD 0x8BA               ; DATA XREF: get_flagnr_blue_points:loc_80C3A68r
ROM:080C3A70 ; ---------------------------------------------------------------------------
ROM:080C3A70
ROM:080C3A70 loc_80C3A70                             ; DATA XREF: get_flagnr_blue_points+F4o
ROM:080C3A70                 LDR     R0, =0x8BB
ROM:080C3A72                 B       loc_80C3AAA
ROM:080C3A72 ; ---------------------------------------------------------------------------
ROM:080C3A74 dword_80C3A74   DCD 0x8BB               ; DATA XREF: get_flagnr_blue_points:loc_80C3A70r
ROM:080C3A78 ; ---------------------------------------------------------------------------
ROM:080C3A78
ROM:080C3A78 loc_80C3A78                             ; DATA XREF: get_flagnr_blue_points+F8o
ROM:080C3A78                 LDR     R0, =0x8BC
ROM:080C3A7A                 B       loc_80C3AAA
ROM:080C3A7A ; ---------------------------------------------------------------------------
ROM:080C3A7C dword_80C3A7C   DCD 0x8BC               ; DATA XREF: get_flagnr_blue_points:loc_80C3A78r
ROM:080C3A80 ; ---------------------------------------------------------------------------
ROM:080C3A80
ROM:080C3A80 loc_80C3A80                             ; DATA XREF: get_flagnr_blue_points+FCo
ROM:080C3A80                 LDR     R0, =0x8BD
ROM:080C3A82                 B       loc_80C3AAA
ROM:080C3A82 ; ---------------------------------------------------------------------------
ROM:080C3A84 dword_80C3A84   DCD 0x8BD               ; DATA XREF: get_flagnr_blue_points:loc_80C3A80r
ROM:080C3A88 ; ---------------------------------------------------------------------------
ROM:080C3A88
ROM:080C3A88 loc_80C3A88                             ; DATA XREF: get_flagnr_blue_points+100o
ROM:080C3A88                 LDR     R0, =0x8BE
ROM:080C3A8A                 B       loc_80C3AAA
ROM:080C3A8A ; ---------------------------------------------------------------------------
ROM:080C3A8C dword_80C3A8C   DCD 0x8BE               ; DATA XREF: get_flagnr_blue_points:loc_80C3A88r
ROM:080C3A90 ; ---------------------------------------------------------------------------
ROM:080C3A90
ROM:080C3A90 loc_80C3A90                             ; DATA XREF: get_flagnr_blue_points+104o
ROM:080C3A90                 LDR     R0, =0x8BF
ROM:080C3A92                 B       loc_80C3AAA
ROM:080C3A92 ; ---------------------------------------------------------------------------
ROM:080C3A94 dword_80C3A94   DCD 0x8BF               ; DATA XREF: get_flagnr_blue_points:loc_80C3A90r
ROM:080C3A98 ; ---------------------------------------------------------------------------
ROM:080C3A98
ROM:080C3A98 loc_80C3A98                             ; DATA XREF: get_flagnr_blue_points+108o
ROM:080C3A98                 MOVL    R0, 0x8C0
ROM:080C3A9C                 B       loc_80C3AAA
ROM:080C3A9E ; ---------------------------------------------------------------------------
ROM:080C3A9E
ROM:080C3A9E loc_80C3A9E                             ; DATA XREF: get_flagnr_blue_points+10Co
ROM:080C3A9E                 LDR     R0, =0x8C1
ROM:080C3AA0                 B       loc_80C3AAA
ROM:080C3AA0 ; ---------------------------------------------------------------------------
ROM:080C3AA2                 DCB    0
ROM:080C3AA3                 DCB    0
ROM:080C3AA4 dword_80C3AA4   DCD 0x8C1               ; DATA XREF: get_flagnr_blue_points:loc_80C3A9Er
ROM:080C3AA8 ; ---------------------------------------------------------------------------
ROM:080C3AA8
ROM:080C3AA8 loc_80C3AA8                             ; DATA XREF: get_flagnr_blue_points+110o
ROM:080C3AA8                 LDR     R0, =0x8C2
ROM:080C3AAA
ROM:080C3AAA loc_80C3AAA                             ; CODE XREF: get_flagnr_blue_points+142j
ROM:080C3AAA                                         ; get_flagnr_blue_points+14Aj ...
ROM:080C3AAA                 BL      checkflag_r0    ; check the associated flag
ROM:080C3AAE                 LSL     R0, R0, #0x18
ROM:080C3AB0                 MOV     R1, #3          ; return #3
ROM:080C3AB2                 CMP     R0, #0
ROM:080C3AB4                 BEQ     loc_80C3AB8
ROM:080C3AB6                 MOV     R1, #2          ; if flag is true, return #2
ROM:080C3AB8
ROM:080C3AB8 loc_80C3AB8                             ; CODE XREF: get_flagnr_blue_points+23Cj
ROM:080C3AB8                 ADD     R0, R1, #0
ROM:080C3ABA                 B       loc_80C3AC2
ROM:080C3ABA ; ---------------------------------------------------------------------------
ROM:080C3ABC dword_80C3ABC   DCD 0x8C2               ; DATA XREF: get_flagnr_blue_points:loc_80C3AA8r
ROM:080C3AC0 ; ---------------------------------------------------------------------------
ROM:080C3AC0
ROM:080C3AC0 invalid_input                           ; CODE XREF: get_flagnr_blue_points+Cj
ROM:080C3AC0                                         ; DATA XREF: get_flagnr_blue_points+60o ...
ROM:080C3AC0                 MOV     R0, #1          ; nothing found? - return #1
ROM:080C3AC2
ROM:080C3AC2 loc_80C3AC2                             ; CODE XREF: get_flagnr_blue_points+13Ej
ROM:080C3AC2                                         ; get_flagnr_blue_points+242j
ROM:080C3AC2                 POP     {R1}
ROM:080C3AC4                 BX      R1
ROM:080C3AC4 ; End of function get_flagnr_blue_points

This one is kinda similar to the routine connecting flags with towns/cities/routes with the only difference that the flags for the blue points are defined.
A pic - you should be familiar with this kind of routines, so I was rather canny with comments:

Therefore we've gone sucessfully through our big "bl"-routine. The next thing we have to change is the 'real' location of the cities etc... As you have maybe noticed, the towns and the little head representing your current whereabout aren't at the right position. I guess the data related to the stuff on the map is stored in some kind of "package". So we 'should' discover these 'coordinates' near the loaded name. Load up your ROM in VBA and mark Pallet Town. Convert the text to it's hexadecimal equivalent.

PALLET TOWN => CA BB C6 C6 BF CE 00 CE C9 D1 C8 

Do a 32bit search for 0xC6C6BBCA and you will result in adress 02000024. Let's trace it back via VBASDL-H.
Open the ROM, put a bpw on 0x02000024 and select Pallet Town. The game breaks.

Breakpoint (on write) address 02000024 old:ca new:ca
R00=000000ca R04=00000000 R08=00000000 R12=00000040
R01=083eecfc R05=00000000 R09=00000000 R13=03007dd0
R02=000000ca R06=02000024 R10=00000000 R14=080c4db3
R03=02000024 R07=030030f0 R11=00000000 R15=08008d8e
CPSR=8000003f (N.....T Mode: 1f)
08008d8c  3301 add r3, #0x1

The string was copied from 0x083EECFC. Open the ROM in a hexviewer at that position. There must be a pointer to this text, so look for the reversed pointer FC EC 3E 08. Luckily, we find a result at 0x083F1CAC. There are many pointers for all the other locations' texts. Remember that the first one represented Pallet Town. Scroll down a little bit and you'll see the folowing table.

003f1e60h: 04 00 0B 00 04 00 08 00 04 00 04 00 0E 00 03 00 ; ................
003f1e70h: 12 00 06 00 0E 00 09 00 0B 00 06 00 0C 00 0C 00 ; ................
003f1e80h: 04 00 0E 00 02 00 03 00 0E 00 06 00 08 00 03 00 ; ................
003f1e90h: 12 00 03 00 04 00 09 00 04 00 05 00 05 00 04 00 ; ................
003f1ea0h: 08 00 03 00 0E 00 04 00 0E 00 07 00 0C 00 06 00 ; ................
003f1eb0h: 0F 00 06 00 0F 00 03 00 12 00 03 00 0F 00 09 00 ; ................
003f1ec0h: 12 00 07 00 10 00 0B 00 0F 00 0B 00 0D 00 0C 00 ; ................
003f1ed0h: 07 00 06 00 07 00 07 00 07 00 0C 00 0C 00 0D 00 ; ................
003f1ee0h: 05 00 0E 00 04 00 0C 00 02 00 08 00 02 00 04 00 ; ................
003f1ef0h: 0E 00 01 00 0F 00 01 00 00 00 00 00 00 00 00 00 ; ................
003f1f00h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f1f10h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f1f20h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f1f30h: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 08 00 ; ................
003f1f40h: 09 00 09 00 12 00 0C 00 03 00 04 00 10 00 0B 00 ; ................
003f1f50h: 05 00 08 00 11 00 05 00 02 00 03 00 01 00 09 00 ; ................
003f1f60h: 09 00 07 00 0D 00 0C 00 12 00 0D 00 04 00 03 00 ; ................
003f1f70h: 05 00 04 00 01 00 04 00 04 00 05 00 10 00 09 00 ; ................
003f1f80h: 0E 00 0A 00 11 00 0A 00 12 00 0C 00 0F 00 00 00 ; ................
003f1f90h: 0F 00 03 00 12 00 03 00 10 00 07 00 05 00 06 00 ; ................
003f1fa0h: 05 00 09 00 06 00 09 00 03 00 0C 00 09 00 0C 00 ; ................
003f1fb0h: 03 00 0E 00 02 00 0C 00 0A 00 08 00 00 00 00 00 ; ................
003f1fc0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f1fd0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f1fe0h: 00 00 00 00 00 00 00 00 00 00 00 00 12 00 0D 00 ; ................
003f1ff0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2080h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2090h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20a0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20b0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20c0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20e0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f20f0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2100h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2110h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2120h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2130h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2140h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2150h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2160h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2170h: 00 00 00 00 00 00 00 00 01 00 01 00 01 00 01 00 ; ................
003f2180h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2190h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f21a0h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 02 00 ; ................
003f21b0h: 01 00 03 00 04 00 01 00 06 00 01 00 01 00 02 00 ; ................
003f21c0h: 01 00 02 00 02 00 01 00 03 00 01 00 03 00 01 00 ; ................
003f21d0h: 01 00 03 00 03 00 01 00 01 00 05 00 02 00 01 00 ; ................
003f21e0h: 01 00 02 00 02 00 01 00 04 00 01 00 01 00 05 00 ; ................
003f21f0h: 05 00 01 00 01 00 02 00 07 00 01 00 01 00 02 00 ; ................
003f2200h: 02 00 01 00 01 00 04 00 01 00 02 00 02 00 01 00 ; ................
003f2210h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2220h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2230h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2240h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2250h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2260h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2270h: 01 00 06 00 01 00 02 00 01 00 02 00 04 00 01 00 ; ................
003f2280h: 02 00 01 00 01 00 01 00 01 00 01 00 03 00 01 00 ; ................
003f2290h: 01 00 02 00 03 00 01 00 03 00 01 00 01 00 03 00 ; ................
003f22a0h: 01 00 03 00 01 00 03 00 03 00 01 00 01 00 05 00 ; ................
003f22b0h: 02 00 02 00 01 00 02 00 01 00 01 00 01 00 03 00 ; ................
003f22c0h: 07 00 01 00 01 00 03 00 06 00 01 00 01 00 03 00 ; ................
003f22d0h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f22e0h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f22f0h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2300h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2310h: 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; ................
003f2320h: 01 00 01 00 01 00 01 00 00 00 00 00 00 00 00 00 ; ................
003f2330h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2340h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2350h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2360h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2370h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2380h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2390h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23a0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23b0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23c0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23e0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f23f0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2400h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2410h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2420h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2430h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2440h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2450h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2460h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2470h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
003f2480h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................

The beginning is very interesting. 04 00 0B 00. This are exactly the coordinates of Pallet Town. If you compare the following values to the Towns (Viridian, Pewter, ...) you see that they represent their coordinates as well.

Huh? No crappy ASM stuff to get this information? No - The routine loading this data isn't as easy as the other ones. So I decided to take the "easy" way using the pointers.

That's it for now, I hope you liked my "small" excursion in the world of ASM and getting non-standard-data. As always any feedback would be appreciated. =)

"Pokémon" ist ein eingetragenes Warenzeichen der Firma Nintendo
"Action Replay" ist ein eingetragenes Warenzeichen von Datel Interact.
© www.SearchForCheats.de.vu by Mastermind_X
© 2006 - 2008