The smallest SNES program I could come up with is 22 bytes long. Thus, we need to send multiple packets to the SNES. I think it would be better to make 8F a SNES packet sender, and have it send several DATA_SND packets before sending a final JUMP packet and crash the game (because SO LONG WE DON'T NEED YOU
Now, here is a full guide on how to send appropriate packets to Weegee-fy the Super Game Boy as well !
(And even if this doesn't work, it's still a way to do SNES ACE via Pokémon Red ^^)Tutorial
We are first going to write a packet and a tiny payload to feed the SNES some code.
But then we're in hell. Why ? Because the bytes we gotta send map to invalid items !
So we can't use items to store the packet data
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.
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 x1 (Will change)
Parlyz Heal x125
Ice Heal x46
Leaf Stone x34
TM01 x[any qty]
Guard Spec. x3
Super Repel x233
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.
The quantity of X Accuracies will increment each time. Basically, when you use 8F while having "A" Awakenings and "X" X Accuracies, the "X"th byte of the packet will turn into "A".BIG FAT NOTE : NEVER USE 8F IF YOU HAVE MORE THAN 28 X ACCURACIES !!!! YOU WILL CORRUPT PARTY DATA AND MAKE 8F POTENTIALLY UNUSABLE !!!!
This will also corrupt your Pokédex flags. I made this because it makes the code simpler, and I guess when doing SGB to SNES ACE, Pokédex progression doesn't matter that
You can toss some X Accuracies to write some bytes you may have screwed up. This is built to be fairly forgiving
So, we're going to write a packet (they are 16-byte long), and then 10 bytes of code to help send them to the SGB.
Use 8F once, and toss the extra X Accuracy.
Now, we're going to toss a certain number of Awakenings, use 8F, and repeat. For quantities greater than 99, I recommend doing multiple tosses to avoid mistakes : to toss 135, you can toss 99 then 36. For 245, you can toss 99 then 99 then 47.
Here goes the table :
135 | 0 | 0 | 0 | 245 | 30 | 224 | 87 | 255 (you can just press Down twice, that's faster) | 115 | 0 | 190 | 136 | 83 | 230 | 190 | 51 | 68 | 203 | 149 | 51 | 21 | 161 | 61 | 51 | 203
Now, you should swap the Lemonades with the Awakenings, the Guard Spec.s with the HP Ups, and the Super Repels with the Water Stones.
Use 8F. Congrats, you've successfully sent 11 bytes of code in the SNES's RAM !
I know it doesn't look like it's much, but don't-cha worry : you did 40% of the work, huzzah !
Now, do the item swaps again, and toss all X Accuracies but two
You're going to build another packet ! Do the same as above, with this table this time :
245 | 0 | 0 | 245 | 182 | 112 | 6 | 83 | 51 | 203 | 240 | 11 | 148 | 4 | 129
Swap the items again, and use 8F.
You have successfully poked 22 bytes of code in the SNES's RAM ! Congrats, because now you're going to write one final packet. And it will be like, super easy.
Swap the items again, toss 111 Awakenings, toss all X Accuracies but one
, use 8F. Then use 8F 15 more times without tossing anything.
Swap the items one last time, and I recommend that you save
. When you feel ready, plug a controller into SNES port 2, make sure the A button is NOT held, and simply use 8F.
Now, control has been removed from the SGB ! The SNES CPU is patiently waiting that you press the A button on controller 2Source code
Here is the code that builds the packets.
ld c, $byte
inc hl ; points to third item's quantity
ldi (hl), a ; reset it for next write
ld a, c
ld l, $01
ldi (hl), a
ld a, l
ld l, $2F
ldi (hl), a
Here is the code that prepares the packet send :
ld a, $1C
jr c, $D311 ; start of the second payload
Here is the code appended to the packets :
; 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
CD BC 35
CD EB 5F
C3 CD 35
This code would have been a pain to write using items, so instead it is jumped to when using 8F.
Here are the three packets, in hexadecimal :
$79 $00 $00 $00 $0B $E2 $20 $A9 $01 $8D $00 $42 $78 $AD $1A $42
$79 $0B $00 $00 $0B $4A $90 $FA $AD $1A $42 $10 $F5 $6C $FC $7F
$91 $00 $00 $00 $00 $00 $00
Note that for the second packet, we don't rewrite the first byte, since it is the same.
I built these packets to contain as many $00 bytes as possible (they are more convenient to write)
This is the SNES program I wrote and that is sent in the two 11-byte wide packets.
E2 20 SEP #$20 ; Make A 8-bit.
A9 01 LDA #$01
8D 00 42 STA $4200 ; Enable autopolling.
78 SEI ; Kill interrupts (IRQ) while game cart is removed.
; NMI is alreay disabled by the SGB.
AD 1A 42 LDA $4212 ; Status register.
4A LSR A ; Pushes bit 0 into C.
90 FA BCC .WaitForPlayer ; C = 0 ? Joypad not ready :(
AD 1A 42 LDA $421A ; Joypad #2 status register, low byte.
10 F5 BPL .WaitForPlayer ; Bit 7 set ? A pressed ! This means GET DAT MOFO!!!1!!11!
; At this point, we have ACE on the new cart.
6C FC 7F JSR ($7FFC) ; This just restarts the cart as a PoC.
; So replace this with whatever you want.
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.