The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > ROM Hacking > Tools, Tutorials & Resources
Sign Up Rules/FAQ Live Battle Blogs Mark Forums Read

Notices

Tools, Tutorials & Resources Various tools to help you develop your hacks can be found here.
New threads in this forum are to be approved by a moderator before they are displayed.


Advertise here

Reply
 
Thread Tools
  #1    
Old August 10th, 2014, 04:07 AM
NearEDGE
 
Join Date: Aug 2014
Gender: Male

Advertise here
Here's a fun one! Do you want to do something BIG in the second Gen pokemon games? Is the 2MB(minus original content) limit too small for you? Do you just want 2MB for your exclusive use? Well, expanding your ROM allows all of these things!

BE AWARE THAT INCREASING THE ROM SIZE FORCES THE RTC TO NO LONGER WORK. THE TIME OF DAY WILL NOT CHANGE UNLESS THE PLAYER CHANGES IT. THIS IS SLIGHTLY MORE USEFUL FOR GEN I ROMS WHO DID NOT HAVE AN RTC, ONLY AN MBC3.

SEE PART 4 FOR A METHOD OF SIMULATING THE RTC WITH AN IN-GAME CLOCK
.



You will need:
Code:
A Pokemon Gold, Silver, or Crystal ROM(Actually, I'm sure this works with Gen I roms as well)
A hex editor(Because PKSV won't let me do what I want!)
PKSV(We're going to abuse PKSV a teeny tiny bit.)
1. Open your ROM in a Hex Editor

Change the bytes 0x147 and 0x148 to 1B and 07 respectively.



2. Open PKSV by itself
In your untitled file write the following code:
Code:
#org 0x3FFFFD
2call 0x0000
3. Open ROM and Compile

Open your ROM in PKSV then click on Compile.


You are done! The above code causes PKSV to create a 4MB ROM with an extra 128 readable memory banks as long as you made the the changes to addresses 0x147 and 0x148.

Don't believe me? Try it out!

Quote:
Originally Posted by NewBarkFatMan.pks
'Written for Pokemon Gold
#org 0x12009B
'-----------------------------------
2jump 0x65B0

#org 0x1225B0
3jump 0x400080

#org 0x200000
loadfont
2writetext 0x400A
closetext
3jump 0x65B448

#org 0x1225B4
loadfont '0x1225B4
2writetext 0x65C0
closetext
jumptextfaceplayer 0x427E ' 0x12027E


#org 0x1225C0
= Test Output\nTest Output\lTest Output\nTest Output\pTest Output\e

#org 0x20000A
= Text read from:\n0x20000A\e

#org 0x12027E
= Yo, [PLAYER]!\pI hear PROF.ELM\ndiscovered some\lnew [POKé]MON.\e
In order to create an 8MB Pokemon ROM you simply need to change 0x3FFFFD to 0x7FFFFD and byte 0x148 inside the ROM to 0x08.
To access the upper 4MB of data you first need to create an assembly routine that writes 0x1 to 0x3000 to have the MBC 5 bank use the upper 0x400000 bytes available to it.

Here's a quick example:
Code:
; Access the lower 0x400000 bytes(0x000000 - 0x3FFFFF)
; F5 3E 00 EA 00 30 F1
push af
ld a,0x00
LD 3000,a
pop af

; Access the upper 0x400000 bytes(0x400000 - 0x7FFFFF)
; F5 3E 01 EA 00 30 F1
push af
ld a,0x01
LD 3000,a
pop af
4. RTC Simulation


So, lets say that you want to hack Gold, you need the extra space(or just want to work in completely new space), and you need the time of day to change and for time based events to be able to occur. What are you to do?

In-Game Clock!

This means that we'll make a faux RTC which will update based on the game timer(in my method, it actually is the game timer. It over-takes it and uses the second counter to count Minutes, Hours, and Days.

This has two parts. The first part is the write assembly, the second part is the read assembly.

The write assembly will be placed in the blank space at the beginning of the ROM (0x0064 specifically.
The read assembly will be placed at 0x047F, and will over-write the existing RTC check functions. The read assembly will also call the write assembly.

A quick note about this: Minutes show up 1-to-1, so it looks a little weird. Every 6 in-game minutes is one hour, and every 2:24 or 144 Minutes(2 hours and 24 minutes) is one in game day. You're free to change it to your liking if you'd prefer. Just change the minutes in the write assembly to affect the length of an hour;

Write assembly:
Code:
ROM0:0064 21 ED D1         ld   hl,D1ED
ROM0:0067 7E               ld   a,(hl)
ROM0:0068 FE 06            cp   a,06 ; Checks to see if the current number of minutes. Change this to effectively change the length of an hour.
ROM0:006A 30 01            jr   nc,006D
ROM0:006C C9               ret  
ROM0:006D 36 00            ld   (hl),00
ROM0:006F 2B               dec  hl
ROM0:0070 7E               ld   a,(hl)
ROM0:0071 3C               inc  a
ROM0:0072 77               ld   (hl),a
ROM0:0073 FE 18            cp   a,18
ROM0:0075 30 01            jr   nc,0078
ROM0:0077 C9               ret  
ROM0:0078 36 00            ld   (hl),00
ROM0:007A 2B               dec  hl
ROM0:007B 7E               ld   a,(hl)
ROM0:007C 3C               inc  a
ROM0:007D 77               ld   (hl),a
ROM0:007E FE 07            cp   a,07
ROM0:0080 30 01            jr   nc,0083
ROM0:0082 C9               ret  
ROM0:0083 36 00            ld   (hl),00
ROM0:0085 C9               ret  
Bytes, Length: 0x22:
Code:
21 ED D1 7E FE 06 30 01 C9 36 00 2B 7E 3C 77 FE 18 30 01 C9 36 00 2B 7E 3C 77 FE 07 30 01 C9 36 00 C9
Read Assembly:
Code:
ROM0:047F CD 64 00         call 0064
ROM0:0482 21 EE D1         ld   hl,D1EE
ROM0:0485 7E               ld   a,(hl)
ROM0:0486 E0 93            ld   (ff00+93),a
ROM0:0488 2B               dec  hl
ROM0:0489 7E               ld   a,(hl)
ROM0:048A E0 92            ld   (ff00+92),a
ROM0:048C 2B               dec  hl
ROM0:048D 7E               ld   a,(hl)
ROM0:048E E0 91            ld   (ff00+91),a
ROM0:0490 2B               dec  hl
ROM0:0491 7E               ld   a,(hl)
ROM0:0492 E0 90            ld   (ff00+90),a
ROM0:0494 CD F1 30         call 30F1
ROM0:0497 C9               ret  
ROM0:0498 00               nop  
ROM0:0499 00               nop  
ROM0:049A 00               nop  
ROM0:049B 00               nop  
ROM0:049C 00               nop  
ROM0:049D 00               nop  
ROM0:049E 00               nop  
ROM0:049F 00               nop  
ROM0:04A0 00               nop  
ROM0:04A1 00               nop  
ROM0:04A2 00               nop  
ROM0:04A3 00               nop  
ROM0:04A4 00               nop  
ROM0:04A5 00               nop  
ROM0:04A6 00               nop  
ROM0:04A7 00               nop  
Bytes, Length: 0x2A:
Code:
CD 64 00 21 EE D1 7E E0 93 2B 7E E0 92 2B 7E E0 91 2B 7E E0 90 CD F1 30 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0
With this method, I feel that the best way to go about it is to always set the clock in-game to 12:00 PM or 12:00 AM, and the day to Sunday, or Monday based on your start of the week preference. This makes changing the time very easy by editing them in memory through your emulator's memory editor, or by using Gameshark.

Gameshark:
Code:
01XXEBD1 - Set Day, replace XX with 00 - 06
01XXECD1 - Set Hour, replace XX with 00 - 17
01XXEDD1 - Set Minutes, replace XX with 00 - 05
01XXEED1 - Set Day, replace XX with 00 - 3B
Additionally, the time bytes are stored like this once you apply this patch:

Code:

0xD1EB - Day (0-6)
0xD1EC - Hour (0-23)
0xD1ED - Minutes (0-5)
0xD1EE - Seconds (0-59)
If you make any changes to the code, do NOT mess with 0xD1EA.
This byte controls whether or not the timer is running. Setting it to a value greater than 0 will disable it.
Attached Files
File Type: ips Pokemon Gold - Simulated RTC.ips‎ (85 Bytes, 1 views) (Save to Dropbox)

Last edited by NearEDGE; August 14th, 2014 at 10:51 PM.
Reply With Quote
  #2    
Old August 11th, 2014, 12:44 PM
~G0LD!'s Avatar
~G0LD!
Love me...or Die D:<
 
Join Date: Feb 2014
Location: Guatemala City
Age: 20
Gender: Female
Nature: Brave
Send a message via Skype™ to ~G0LD!
A little question ¿How calculate the pointer of a adress up to 0x3FFFFF? because when the Rom size is 4MB the last bank is 0xFF.
__________________
[Center]
Reply With Quote
  #3    
Old August 11th, 2014, 03:22 PM
NearEDGE
 
Join Date: Aug 2014
Gender: Male
Quote:
Originally Posted by ~G0LD! View Post
A little question ¿How calculate the pointer of a adress up to 0x3FFFFF? because when the Rom size is 4MB the last bank is 0xFF.
FF:7FFF = 0x3FFFFF
I'm not really sure what you're asking.

Did you mean 0x7FFFFF?
See the bottom part about writing to the MBC by using ASM.
Reply With Quote
  #4    
Old August 13th, 2014, 12:43 PM
pokenoobend's Avatar
pokenoobend
 
Join Date: Jan 2014
I have 3 questions:

Why does the RTC no longer work when doing this?

Is there a way to make the RTC work again after doing this?

If not, is there a way to reverse this so the RTC works again?

Thank You
Reply With Quote
  #5    
Old August 13th, 2014, 01:02 PM
miksy91's Avatar
miksy91
A GB/C Rom Hacker since 2010
 
Join Date: Oct 2008
Location: A small country in the North
Gender: Male
Nature: Relaxed
Quote:
Originally Posted by pokenoobend View Post
I have 3 questions:

Why does the RTC no longer work when doing this?

Is there a way to make the RTC work again after doing this?

If not, is there a way to reverse this so the RTC works again?

Thank You
The thing that you're supposed to write to rom addresses 0x147-0x148 defines both the rom size, and cartidge type (along with memory bank controller = "MBC") used in the game.
So by writing "1B" to 0x147, you automatically disable the real time clock from the game but at the same time, enable the usage of the rom data up to 8MB. So to answer to your question, no, it's not possible but reversing it back should work just fine.

More info here:
http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header
http://gbdev.gg8.se/wiki/articles/Me...nk_Controllers

P.S
Pokemon Gold and Silver roms contain quite a lot of free space as their own so if you want to hack them, and unless you do something crazy (like enter loads of new music tracks and graphics to the game), you won't even need to expand the rom data past 2MB.
__________________
My Rom Hack



Hacks I support





Learn how to hack GB/C games:

Check my GameBoy/Color hacking videos in Youtube
-The video set uses Pokemon Silver (U) rom for demonstrations
Reply With Quote
  #6    
Old August 14th, 2014, 12:50 PM
NearEDGE
 
Join Date: Aug 2014
Gender: Male
Quote:
Originally Posted by miksy91 View Post
The thing that you're supposed to write to rom addresses 0x147-0x148 defines both the rom size, and cartidge type (along with memory bank controller = "MBC") used in the game.
So by writing "1B" to 0x147, you automatically disable the real time clock from the game but at the same time, enable the usage of the rom data up to 8MB. So to answer to your question, no, it's not possible but reversing it back should work just fine.

More info here:
http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header
http://gbdev.gg8.se/wiki/articles/Me...nk_Controllers

P.S
Pokemon Gold and Silver roms contain quite a lot of free space as their own so if you want to hack them, and unless you do something crazy (like enter loads of new music tracks and graphics to the game), you won't even need to expand the rom data past 2MB.
That only applies to original hardware. Emulators do not have the same restriction. At the same time, you'd have a difficult time finding a real MBC5 cartridge to write to, so it's not much of an issue in 2014.

On top of that, the RTC can be modified(The functions accessing the RTC) to work using assembly to control the time value; however, it can't be used as a real clock without the emulator specifically supporting a custom MBC5+RAM+BATT+RTC cartridge.

My first idea was setting it so that every 1 minute of game time = 10 minutes on the RTC since game time and the RTC must be calculated separately, and the routines to check the RTC can be repointed and force to do whatever you want them to.

To help with this, the in-game timer can be found at 0xD1EB(Pokemon Gold) And looks like this:
Code:
0xD1EB - Hours (2 Byte)
0xD1ED - Minutes
0xD1EE - Seconds
0xD1EF - Frames (60/second)
It clears itself at 0xFFFF Hours, 0x3C Minutes, 0x3C Seconds, and 0x3C Frames.

Routine for accessing RTC:
Accessing RTC Pokemon Gold.png

Real simple routine. It shouldn't take much effort to have it read from D1EB-D1EE, then have it call a routine instead of reading the bytes for the day. Chances are that the bytes D1E9 and D1EA can be used for storing the day and you can just do (Hours % 24) and just start the game as whatever that day happens to be. My guess is that the game just applies a delta to the days anyways, so it shouldn't matter. Easy peasy.

EDIT: DO NOT USE 0xD1EA to store the day. 0xD1EA controls the timer. Setting it higher than 0 will disable it.

Last edited by NearEDGE; August 14th, 2014 at 10:53 PM.
Reply With Quote
  #7    
Old August 14th, 2014, 10:53 PM
NearEDGE
 
Join Date: Aug 2014
Gender: Male
BUMP: Added Part 4: RTC Simulation
Reply With Quote
Reply
Quick Reply

Sponsored Links


Advertise here
Thread Tools

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Minimum Characters Per Post: 25



All times are UTC -8. The time now is 02:29 AM.


Style by Nymphadora, artwork by Sa-Dui.
Like our Facebook Page Follow us on Twitter © 2002 - 2014 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2014 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.