Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - ISSOtm

Pages: [1] 2 3
Krys3000 asked me to take a look at "????? party overloading". Since that glitch has quite some potential, I figured it would be a good idea to check out how it works, to make developing techniques using it easier.

First, let's quickly recap how it's done :
- Have a ????? (species FF) at the top of a 6-Pokémon party (Example below)

- Use "Move Pkmn w/o Mail" to place a Pokémon on the first party slot
- Select "Withdraw" and start withdrawing Pokémon, which can be done even though there are more than 6.
Each Pokémon withdraw will overwrite an area of memory, such as roaming Pokémon structs, etc.

Now, I'm going to explain how it works, so you can get an idea on this glitch's internals.

I'll use Crystal as a reference because it's way more documented (disassembly-wise) than Gold/Silver, and the glitch works there too.
As to how the glitch works, there are two culprits :

The first culprit is CopyBoxmonSpecies. This function copies the target "box" (the party is considered a box there), and updates wBillsPC_NumMonsInBox to contain the correct number of Pokémon. Problem is, the function stops its copy as soon as it finds a $00 or $FF byte (I'm not sure why the programmers decided that both of these would be terminators, but... that's how it works !). Thus, only the $FF Pokémon's species is copied into the buffer, which tricks BillsPC_CheckSpaceInDestination into thinking there are exactly 0 Pokémon into our party.
Because this function is meant to allow or refuse transfers to our party, it will let us obtain a party containing more than 6 Pokémon. This lets us slide into part 2...
(I didn't investigate more "Move PkMn w/o Mail", and I don't think it would yield a very different corruption than Withdrawing. I may be wrong, though.)

The second culprit is SentGetPkmnIntoFromBox (names like that can't be made up), which is called by TryWithdrawPokemon.
This function is responsible for moving Pokémon around (party, boxes, Daycare). Here, it's called with wPokemonWithdrawDepositParameter being 0, which prompts it to check if the party isn't full. Unfortunately (for the programmers), the check only checks if there are EXACTLY 6 Pokémon in the party !
Because "part 1" allowed us to obtain a 7-Pokémon party, the check returns non-zero and we are allowed to nicely proceed.

For the rest of this explanation, I'll use a small shortcut : N will represent the number of Pokémon in the party prior to withdrawing.

So, what happens when we withdraw a Pokémon ?
First, the game writes the Pokémon's species at (DCD8 + N).
Then it writes a $FF at (DCD8 + N + 1) to properly terminate the list.
Then, it copies the boxed Pokémon's data (0x20 bytes) to (DCDF + N * 0x30)
[Aparté : a boxed Pokémon is 0x20 bytes large ; a party Pokémon is 0x30 bytes large, the first 0x20 being the same bytes as its boxed counterpart, with the remaining 0x10 bytes being the status, an unused byte, and the stats]
Then, it copies the Pokémon's OT name (11 bytes) to (DDFF + N * 11).
Then it copies the Pokémon nickname (11 bytes) to (DE41 + N * 11).
The game then calculates its level, resets its status, and writes its stats. It also sets its HP to its max HP (except if it's an egg, then it sets HP to 0).

SO ! Let's recap the corruption that occurs. Here's a handy list of all the writes that occur, by order of appearance (meaning some could override others !!) :
(Note : I'm not certain about endianness, but assume big-endian unless otherwise stated)
Start| End| Content
DCD8 + N| DCD8 + N| Species
DCD8 + N + 1| DCD8 + N + 1| $FF
DCDF + N * 0x30| DCDF + N * 0x30| Species
DCDF + N * 0x30 + 1| DCDF + N * 0x30 + 1| Held item
DCDF + N * 0x30 + 2| DCDF + N * 0x30 + 2| Move 1
DCDF + N * 0x30 + 3| DCDF + N * 0x30 + 3| Move 2
DCDF + N * 0x30 + 4| DCDF + N * 0x30 + 4| Move 3
DCDF + N * 0x30 + 5| DCDF + N * 0x30 + 5| Move 4
DCDF + N * 0x30 + 6| DCDF + N * 0x30 + 7| OT ID
DCDF + N * 0x30 + 8| DCDF + N * 0x30 + 10| Experience
DCDF + N * 0x30 + 11| DCDF + N * 0x30 + 12| HP stat experience
DCDF + N * 0x30 + 13| DCDF + N * 0x30 + 14| ATK stat experience
DCDF + N * 0x30 + 15| DCDF + N * 0x30 + 16| DEF stat experience
DCDF + N * 0x30 + 17| DCDF + N * 0x30 + 18| SPD stat experience
DCDF + N * 0x30 + 19| DCDF + N * 0x30 + 20| SPE stat experience
DCDF + N * 0x30 + 21| DCDF + N * 0x30 + 22| DVs
DCDF + N * 0x30 + 23| DCDF + N * 0x30 + 23| Move 1 PP
DCDF + N * 0x30 + 24| DCDF + N * 0x30 + 24| Move 2 PP
DCDF + N * 0x30 + 25| DCDF + N * 0x30 + 25| Move 3 PP
DCDF + N * 0x30 + 26| DCDF + N * 0x30 + 26| Move 4 PP
DCDF + N * 0x30 + 27| DCDF + N * 0x30 + 27| Happiness
DCDF + N * 0x30 + 28| DCDF + N * 0x30 + 28| Pokérus status
DCDF + N * 0x30 + 29| DCDF + N * 0x30 + 30| Caught data
DDFF + N * 11| DDFF + N * 11 + 10| OT name
DE41 + N * 11| DE41 + N * 11 + 10| Nickname
DCDF + N * 0x30 + 31| DCDF + N * 0x30 + 31| Level
DCDF + N * 0x30 + 32| DCDF + N * 0x30 + 32| Status
DCDF + N * 0x30 + 34| DCDF + N * 0x30 + 35| Max HP (or 0 if Egg)
DCDF + N * 0x30 + 36| DCDF + N * 0x30 + 37| Max HP
DCDF + N * 0x30 + 38| DCDF + N * 0x30 + 39| Attack stat
DCDF + N * 0x30 + 40| DCDF + N * 0x30 + 41| Defense stat
DCDF + N * 0x30 + 42| DCDF + N * 0x30 + 43| Speed stat
DCDF + N * 0x30 + 44| DCDF + N * 0x30 + 45| Special attack stat
DCDF + N * 0x30 + 46| DCDF + N * 0x30 + 47| Special def stat

This is quite interesting in Crystal, because these are located very near the end of WRAM, thus near the beginning of Echo RAM. At the beginning of Echo RAM is the stack, which could allow for another ACE method ! My next goal is to research ACE on Crystal using this.

Shoutouts to SMF for not allowing borders on their tables. Geniuses.
Welcome to the ACE Guide !

ACE is the most powerful and dangerous glitch of them all, and some questions come up often.
If you want to ask a question, please read this thread, if the answer is there please don't post about it.

NOTE : This guide is a WIP, I'm going to add new questions as they come up. Please don't post unless it's for this purpose :)
Emulation & ROM Hacking / Pokemon Red - Stryder7x edition
« on: April 27, 2017, 05:44:58 pm »
If you don't know Stryder7x, he makes videos about Paper Mario glitches. They generated a ton of memes, and this hack is a tribute to him. Now, it's not a ROM hack !

Teaser :
Download the save :
Open with English Pokemon Red or Blue (Should crash otherwise, so... :D)

Tech talk :
It's too long. Really too long.
Because why not :)
This is useful, for example, when making custom save files (poke @TheZZAZZGlitch :P). Or if you want to be an ugly troll to your friends ^^

This is based off DMA hijacking, a technique that allows "automatic" ACE on each frame.
First off, you will want to write this piece of code somewhere :
Code: [Select]
ld a, [$C3AA]
cp $79
jr nz, .ok
ld hl, $0014
add hl, sp
ld [hl], $E8
inc hl
ld [hl], $29
ld a, $C3
ld c, $46
And for those who want hex :
Code: [Select]
FAAAC3 FE79 2009 211400 39 36E8 23 3629 3EC3 0E46 C9
Then, you will want to write
Code: [Select]
CDYYXX E2at $FF80, where the address of the above function is $XXYY (be careful of the order, it's in reverse !)
For example, if NoStart is at $CAFE you will write
Code: [Select]
But be careful, those four bytes have to be written in one frame ! Otherwise you will almost certainly crash :D

Now, if everything is in place, the START menu will pop up when you press START, but will close immediately, without even printing any text inside
Until you reset the console, actually. This doesn't persist through resets :3 (although it is possible to make it permanent)
But this can make challenge runs where you aren't allowed to save (unless you change boxes), use items out of battle, re-order your Pokémon (outside of the PC). Or just have fun screwing around :P

How does it work ?

$C3AA is a part of the game's WRAM tilemap, and this is where tiles are written to before being copied to VRAM (because of access restrictions)
Specifically, the game writes a $79 there (top-left menu tile) when opening the START menu. As far as I know, no other text box in the game does this.
If such a tile is detected, the script knows the game is attempting to open the START menu. Specifically, due to how text boxes work, the game is processing the DisplayTextIDInit function, which consistently waits for a few frames.
What we do is manipulate this function's return address so instead of displaying the menu, it will directly go to the function that closes it.
Code: [Select]
ld hl, $0014
add hl, sp
makes hl point to the aforementioned return address, which we overwrite with $29E8 (CloseTextDisplay) which undoes everything. Pop :P
All that remains of the menu is the blank text box, which is displayed by DisplayTextIDInit. It would be possible to avoid it, but that would be heavier. Besides, if you want to troll a friend, he will probably freak out a bit more :D

Note that this doesn't affect any other text box ;)

I'd like to make a demonstration video but I don't have any working screen recorder.
Arbitrary Code Execution Discussion / Easy tool to make 8F setups
« on: February 25, 2017, 12:31:39 pm »
GBz80 to Items : Making 8F setups easier

GBz80 to Items is an online tool that allows you to write 8F item setups very easily.
You just type your code, click a button, and you get an item list. Easy as cake !
It's currently available online at

Knowledge of Gameboy assembly is required, this is only intended to replace using The Big HEX List and speed up the process of writing setups.

No problem ! I have you covered.
If you have a GitHub account, I suggest you go here and create a new issue.
Otherwise, just post your request in the thread. I visit the forums quite often, so I'll probably work on it shortly.

#002  "ld (mem16), a" throws "Line undefined : Invalid operand (mem16) !" Fixed in 3.0.1
#003  "ld a, (mem16)" throws "Line 1 : mem16 isn't a valid 16-bit number !" Fixed in 3.0.1
#004  ldh doesn't work and throws "memAccess is undefined" internal (!) errors Fixed in 3.0.1
#005  Bit rotation instructions throw "reg8.indexof is not a function !" Fixed in 3.0.1
#006  jp mem16 throws "invalid operand $36e0 !"

Legacy stuff :
This is the third version of the compiler I make, and the second I publish.
The old v2 version can be checked out at (version 2.1) and (version 2.2, never finished because shitty code)
Arbitrary Code Execution Discussion / Using 8F to ACE other games
« on: February 11, 2017, 10:52:57 am »
This is a method to perform ACE on each game frame - provided it uses OAM DMA. I guess all games use it, so, yeah.
It also has the bonus of being cartswap-friendly.
Need no more to be convinced ? Then here is the thing !

This works only on Pokémon Red or Blue.
You need to place the following hex data at the following locations.
Use your favorite emulator's (or BGB if you intend to do cartswap) memory viewer to do that.
Alternatively, you can use an in-game memory editor such as offgao's (see this thread)
Also, make sure all data at FF80 is not executed until it is complete. It's very sensitive data executed on each frame, and you don't wanna crash.
One way to do it is to write a $C9 at $FF80 first, and write the $CD last.

These two pieces of data don't persist after saving and resetting.
Code: [Select]
At DF00 : (WRITE FIRST !!)


Once both pieces of code are in place, go into any house, exit it and o surprise, Hall of Fame !
Tech details are below.

If you want to try the cartswap-based funky badass-showoff version (Pokémon Blue "cartswap wrong warp%"), then set up DF00 and FF80 as above, and then this.
Code: [Select]
At D163 :

At D31D :

At D53A :
Now, open your bag (surprise, there's 8F in there), use 8F. The game will then freeze, so use "Load ROM without reset" on BGB and load Pokémon Blue (or Red, works fine too).
Press any direction on the D-Pad, and the game will start. You can then choose to start a new game, and you will soon find out your house leads directly to the Hall of Fame ! Nice.

I attached a BGB save state to be tried on Pokémon Red that has all set up. This was hex edited, but is doable legitimately. You just have to load it in BGB, then use the above method or just close the menus and walk out of your house.

Tech stuff
On each LCD frame, the game has to run a small routine in RAM to transfer sprites from a temporary buffer to the location the GB uses. However, we hijack this routine to run custom code.
The trick is simple : hijack usual code flow, run our code, and make sure everything else goes as intended.

At $FF80 is this code :
Code: [Select]
ld a, $C3
ldh [$FF46], a
which we overwrite with
Code: [Select]
call $DF00
ld [hl], a

Pokémon R/B/Y allocate $DF00 to $DFFF to be stack space. However, during usual play, I never experienced the game using more than ~100 bytes at once. This leaves us with more than 128 bytes for code storage !
Code: [Select]
ld a, $76 ; Hall of Fame map ID
ld [$D365], a ; Door mats exit
ld hl, $FF46 ; OAM DMA
ld a, $C3
This code essentially sets all door mats exits to warp Red to the Hall of Fame. Pretty neato, huh ?
This is a half gameshark emulator, because it can't set a value mid-frame. However, it is cartswap-friendly, using for example the following setup :

The data at $D163 and $D31D set up 8F properly, I'll just skip explaining them.

The code at $D53B is a bigger deal.
Code: [Select]
PartialInit:: ; $D53B
  ld hl, Init
; Real init function. We copy it to RAM for patching.
  ld de, $DF0B
; Routine copy location.
  ld bc, $0049
; How large the target code is : 73 bytes !
; We will append a jump to end it later.
  call CopyData
  ld a, $10
  ldh [$FFFF], a
; Only enable joypad interrupt.
; It should pop instantly, but it doesn't crash, phew !
; a = $20
  ldh [$FF00], a
; Select Dpad
  dec a
; a = $1F
; Patch WRAM clear size to not clear $DF00 onwards.
  ld [$DF0B+$2B], a
; Write part of the "return" address.
  ld [$DF0B+$3F], a
  ld a, $8A
; Patch HRAM clear code to not clear patched DMA code.
  ld [$DF0B+$38], a
; It will clear past HRAM, but no problem.
  ld a, $C3
; JP instruction.
  ld [$DF0B+$3D], a
  ld a, $A1
  ld [$DF0B+$3E], a
; Patch DMA writing with returning to ROM code.
  jp $DF0B
; Jump to patched init. Cartswap is complete.
Generation I Glitch Discussion / WTW and battles
« on: January 26, 2017, 11:30:36 am »
The game actually checks whether you're being guided by the game before sending you into a battle, be it Trainer or wild.

The called function resides here :

Notes that it returns non-zero is bit 7 of $D730 is set.
This bit is used by the game when a sprite is following scripted movement.
But did you know the Pewter Museum and Brock Through Walls of activating NoClip actually set this flag ? Yeah, no kidding !
After testing (setting $CD38 to $FF, $CD3B to $FF and $D730 to $80 enables NoClip and makes you being controlled by the game unless you hold any button), I found out two interesting things.
First, wild battles do NOT trigger. Like when you enable bit 1 of $D732 and hold down B.
Second, Trainer battles... stuff. First, Trainers do notice you, and bring their text properly. They don't have to walk to you. However, when you close their text... no battles begins until $D730 bit 7 is zero, which happens when $CD38 hits zero.

tl;dr : using Pewter Museum Guy NoClip or Browk Through Walls disables wild battles as long as the glitch stays active (eg it cancels when entering any building). Trainers don't begin their battle until CD38 has hit 0, which may take a couple seconds, but you can't avoid Trainers that way. Too bad !
General Discussion / GCLf member sprites
« on: January 23, 2017, 10:00:25 am »
Anyone that wants to can submit here a 16x16 pixel image that represents them. 4 levels of grayscale are allowed (yep it's for gray GB). I accept anything that can be safely shown to anyone under 18.
Non-Core Game Glitch Discussion / Pokémon Stadium - N64 ACE HYPE !
« on: January 21, 2017, 07:34:10 am »
MrCheeze did it. Basically, attempting to use Pokémon Stadium to trade Pokémon to a Gen I cartridge with more than 20 Pokémon, you get a buffer overflow.
Demonstration video
Tech stuff

Get hyped guys, if we manage to make cartswap real on the N64, we basically pwn the fifth generation of consoles.

I'm going to send a R.O.B to Game Freak at this point. Via mail.
The Dumpster Out Back / Re: Who can approve wiki edits ?
« on: January 20, 2017, 01:39:09 am »
Bump, but I still can't approve edits :(

[EDIT] Thanks Torchickens !
Wiki Discussion / Improving the homepage
« on: January 20, 2017, 01:24:51 am »
The homepage doesn't link to wiki articles, except in the sidebar, which I find not that easy to browse.
I suggest we put some thing along the lines of "If you want to start browsing glitches, then here is the [[glitch list]]" right before "Want to help?"

[[glitch list]] should contain links to glitch categories, such as a "Browse per generation" section, a "Getting Mew" section, a "Catch'em all" section, etc.
I don't want to start working on the page unless it gets approved by the community.
Video Games / Routing a "Pokémon Red Playaround" TAS
« on: January 16, 2017, 12:03:56 pm »
The principle of a TAS, for those that don't know, is basically to program an emulator to play a game "perfectly". To do so, tools such as frame advance, rewind and save states are allowed, hence the name Tool-Assisted Speedrun. The goal is usually to finish the game as fast as possible, using glitches most of the time but not always.

Here, I would like the discuss a route for a TAS that doesn't aim at finishing Pokémon Red as fast as possible - others do that already and way better than me - but instead to showcase glitches in an entertaining way.

The goal I planned for this TAS is to obtain 8F ACE, use WTW to skip all Victory Road, then 8F-induced WTW to skip the whole Elite Four. I think winning by pure ACE or underflow somewhat sucks.

Here is the current planned route :
1. Maybe manipulate the female NPC to trigger the Oak softlock ?
2. Trigger the sprite overflow in the lab
3. Manipulate Charmander's stats for Brock Through Walls (BTW) later
4. Open the START menu after the Rival battle, just for fun
5. Go and heal in Viridian
6. Get and deliver the Parcel
6 1/2. Buy items to have 6 item slots filled. The highest-selling must be bought last
7. Set up the death Trainer-Fly in Viridian Forest
8. Battle the Rival
9. Get Oak's glitched text (pause on it for like a second, have slow text speed)
10. On the way back, get the level 3 Pidgey encounter, Growl 6 times
11. Capture Nidoking 8)
12. Level it up in the forest to speed future battles up
13. Heal at Pewter to set Teleport destination
14. Perform Brock Skip
15. Reload the map to respawn the NPC
16. Perform BTW
17. Reach Cerulean, skipping Mt. Moon
18. Catch an Abra for Teleport
19. Go to Celadon while making a detour through Lavender and Vermilion to add to the Fly list
20. Obtain Fly HM
21. Go back to Pewter using Teleport
22. Perform BTW again
23. Set up a Trainer-Fly on Route 24 using Teleport
24. Save at the PC then reset
25. Return to Cerulean by BTW
26. Engage the swimmer in Misty's Gym
27. Let Charmander against his second Pokémon to showcase the dumb AI
28. Obtain level 1 Mew, if possible we should remove Snorlax to save another BTW later
29. Set up another Teleport TFly
30. Save at the PC, then reset
31. Perform BTW still again
32. Beat Misty, levelling Mew up in the process. If not possible, it has to be levelled up ASAP since we need to deposit it later, and that crashes if it has negative XP
33. Encounter Missingno, rearrange items and catch it to make maximal profit
34. Teach Fly to Mew
35. Fly to Celadon
36. Sell the 256 cloned items
37. Buy a Water Stone and an X Special. The X Special should land in the inventory's sixth slot
38. Go to Cycling Road. If Snorlax cannot be removed by TFly, do another BTW
39. Bypass the bike requirement. If doing BTW, pass through the loading zone (described at the end of this post) and go on the road without a bike to showcase downwards movement being applied anyways, but go back to be forced on the (faster) bike
40. Go to Fuchsia to set on Fly list
41. Catch Ditto and set it up for Cooltrainer (faster item duplication than TFly)
42. Fly to Vermilion
43. Enter Diglett's Cave
44. Duplicate X Specials. Might as well dupe Water Stones if possible
45. Fly to Celadon
46. Obtain 8F. Deposit items in the PC instead of tossing (avoid wasting the Water Stone(s) and buy items to stabilize the inventory)
47. Fly to Cerulean
48. Deposit 8F, withdraw items to stabilize the inventory
49. Set up a Trainer-Fly, going to Lavender
50. Engage the guy that yields a Pidgey, Growl 6 times with Charmander and finish with Mew
51. Fly to Cerulean
52. Capture Pidgey at level 1, manipulating its stats so it will have 233 Max HP later
53. Teach Fly to Pidgey (can open START menu for TFly, teach then fly)
54. Get it to level 100 and cancel the evolution
55. Set up TFly again, going to Celadon
56. Go to the PC, deposit Abra, Nidoking and Mew, then save and reset
57. Set up another TFly using the famous Gambler, going to Pewter
58. Trigger BTW again
59. Fly to Fuchsia, this doesn't cancel the glitch
60. Go on the water to catch a Tentacool
61. Go east of Fuchsia and fight an Arbok-yielding Trainer
62. Fly back to Cerulean
63. Obtain Arbok through the warp
64. Battle the guy to the Gambler's left to get a Parasect yield (other Trainers may be faster, though, but I found none)
65. Go back to Cerulean to get it

Now what is left is :
- getting Onix (or another Pokémon to tweak where ACE will begin in the pack)
- getting the required items
- optimizing the route
- doing the thing
- being showcased at AGDQ

Removing Snorlax
TheZZAZZGlitch explained it in one of his videos. Basically we need to load Snorlax's map right before doing a TFly, and due to the glitch's properties, this will remove Snorlax.

Passing through loading zones
If a warp is triggered not by stepping on a door, it can be passed through. To do so, NoClip (aka WTW) is required. Then, the player must be on the title that he should stand on to trigger the warp, but not facing the warp. By pressing and holding towards the warp, he will pass right through.

An example will be given on the Cycling Road gate west of Celadon City. The player should stand one step north of where exiting the gate puts him, with NoClip active. Then, move one step down. Pressing and holding left will have the player step on the gate. Tapping left to turn, releasing then holding will have the player enter the gate, however.
Generation I Glitch Discussion / Trainer-Fly plus Cycling Road
« on: January 15, 2017, 06:02:30 pm »
I'm playing EU Pokémon Yellow, and I have triggered a Trainer-Fly using the Gambler we all know about. This doesn't seem important for what's next, but I say in case it might come in handy.
I flew to Celadon City for a match with a Cue Ball (I was aiming for a Kadabra), but when I entered the "sloped" area, I wasn't forced downwards ! All non-downwards movement is still slow, but Red doesn't move when not holding any button.
Both wild battles and Trainer battles cancel the glitch.

I assume this comes from that the game doesn't apply downwards movement when Red engages a battle, but the fact that wild battles also cancel the glitch proves that non-Trainer battles also unset a few flags. These flags might be worth researching.
Nintendo Switch live presentation : 13/01/2017, 4:00 GMT

Yeah, I know that was this morning, but whatevs.
Let's talk about it !

Did you watch the Switch presentation ?
Do you think it'll be better than the Wii U ?
Do you think it'll suxx way harder ?
Will you buy it ?
Y'know, stuff like that.

I love the features Nintendo added. The "HD vibration" thingy and this "Arms" game hype me near 0%, but the semi-portability rings a few bells for me.
I also give a kudo for Splatoon 2 (looks even better than the original ? Wah.), Mario Odyssey and MK8 Deluxe (just for the new characters and tracks. 0 f**k given about the engine being the same)
Plus, Skyrim and Breath of the Wild. FREAKING BREATH OF THE WILD AS A LAUNCH TITLE. If I was working hard enough for my ever-nearing terms, I'd pre-order all right now, but gotta work hard, heh.
Whatcha think 'bout it ?
Have you seen Pokémon plays Twitch ? If yes, you know that it is possible to gain SNES ACE "through" the SGB.
"Isn't that TAS-only ?" you might ask. Nope ! And here is how to do.

We are first going to write a tiny payload to feed the SNES some code.
Why not using items ? Because the code maps to invalid items ! So we can't use items to store the packet data and sending code :(
And I've thought of a somewhat original (I guess) storage solution. We're gonna use Pokédex flags. Hell. Yeah.
First, setup your pack ! But don't use 8F quite yet !! The items are actually fairly simple (and cheap) to acquire, and you don't need many duplications.
Code: [Select]
Any item x[any qty]
Awakening x[byte to write]
HP Up x175
Water Stone x4
Poké Ball x121
Great Ball x3
Burn Heal x3
X Accuracy x16
Antidote x34
Parlyz Heal x125
Ice Heal x46
Leaf Stone x34
TM01 x[any qty]
Lemonade x28
Guard Spec. x3
Super Repel x233
First, use 8F once. It's very important ! Then we're ready.

The setup has two modes : an "entering" mode and a "packet sending" mode.

Right now, the setup is in "entering" mode, but we will need to write a bit of code that is essential for the "packet sending" mode to function properly.
This will also corrupt your Pokédex flags. It makes the code simpler (and actually possible), and I guess when doing SGB to SNES ACE, Pokédex progression doesn't matter that much :D
If you messed up a byte write, toss an X Accuracy and try again. This is built to be fairly forgiving :)

So, we're going to 10 bytes of code to help send packets to the SGB.
The method is the following :
  • Toss as many Awakenings as indicated by the first number of the table
  • Use 8F
  • Repeat with the next number in the table.
Here goes the table :
51 | 68 | 203 | 149 | 51 | 21 | 161 | 61 | 51 | 203

Once finished, toss all X Accuracies but one. You are now ready to write all 16 bytes of the packet to be sent.
The usage is very simple : you just need to make the quantity of Awakenings match the value you're willing to write, and then you just use 8F.
Basically, when you use 8F while having "A" Awakenings and "X" X Accuracies, the "X"th byte of the packet will turn into "A". The quantity of X Accuracies will increment each time to target the next byte to write. Full automation, man !
(If you screwed up a write, toss one X Accuracy and do it again.)
Also, don't use 8F if you have 17 X Accuracies or more ! You will screw up the code you have previously written. At best the "packet sending" mode will just not work, at worst you''l get a crash. Be cautious !

Once you have written all 16 bytes, you should swap the Lemonades with the Awakenings, the Guard Spec.s with the HP Ups, and the Super Repels with the Water Stones. The setup will be in "packet sending" mode, so use 8F, and BAM ! The packet is sent.
Then you must swap the items again to be in "entering" mode again, toss all X Accuracies but one, and repeat !

Source code
Here is the code that builds the packets.
Code: [Select]
ld c, $byte
inc hl ; points to third item's quantity
xor a
ldi (hl), a ; reset it for next write
inc b
inc b
ld a, c
inc bc
inc bc
inc c
inc bc
ld l, $01
dec bc
ldi (hl), a
ld a, l
dec c
ld l, $2F
ldi (hl), a

Here is the code that prepares the packet send :
Code: [Select]
ld a, $1C
jr c, $D311 ; start of the second part of the packet sending payload

Here is the code appended to the packets :
Code: [Select]
; The caller made a = $1C, so we will switch to bank $1C, home of SendSGBPacket !
call BankswitchHome ; $35BC
ld l, e ; hl = $D301, start of packet
call SendSGBPacket ; $5FEB
jp BankswitchBack ; $35CD
Hex :
Code: [Select]
CD BC 35
C3 CD 35
This code would have been a pain to write using items, so instead it is jumped to when using 8F in "packet sending" mode.

One last thing : I'm going to write a program that gives packet building indications to help use this setup.
It should be done in a few days.
Pages: [1] 2 3