So, i've set myself a challenge...

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
So, i've set myself a challenge...
by on (#204583)
Hi,

I'm usually a lurker in this forum but I thought some of you might get a kick out of this insane thing.

What I'm trying to do is finding an over complicated way to run code on a PAL SNES, with the ultimate goal being uploading something to the SPC... without using a flashcart

A few things:
- I have some, but limited knowledge of ‎65816 ASM, and very limited knowledge of Z80 ASM (I'll explain why this is important)
- I'm doing this for fun, not for piracy. I realize that games are larger than 128k RAM anyway.
- I'm not being too cheap for a flashcart, I already own a sd2snes, this is just for fun.


My current plan is to abuse ACE glitches on a Gameboy game to run code, which then uploads data to the SNES through a special command in the Super Gameboy (Look at Space Invaders GB for an example). Here's a more detailed rundown:

1. Make Arduino to Gameboy Link Cable interface
2. Abuse this link cable ACE glitch to get code running on the Gameboy
3. Uploading a small program that overwrites the save file with data streaming in from the link cable.
(This is so I can run code when the game starts, I need this since the Super Gameboy itself doesn't have a link port)
4. Make a custom save file that 1. contains the same uploader program to "reflash", 2. contains a program that uploads code (~2KB) to the SNES and instructs the SGB to jump to that code.
(5.) Not sure if this could work, but since the code is running in WRAM at this point, couldn't I perform a cartswap and have the code copy itself to SRAM of a SNES cart?
6. Make a TASBot-type device that basically streams data through the controller port to overwrite the whole 128k of memory (Maybe even a basic client-server thing where the code running on the SNES can request more data)
7. and finally: Upload music to the SPC and jam out in triumph.


This is how far I am:

I soldered a link cable to some jumper wires and hooked it up to my Arduino.
I successfully uploaded the hello world that was included with the ACE demo.
I successfully replaced the save file using the link cable. That's about 32kb of data. (Actually about 24kb since I left out the last unused bank because else it wouldn't fit on my Arduino Nano's flash)
I used the ASM code from the link in step 2, and made my own "server" for it on the Arduino. (It's actually not that hard to keep the Gameboy happy with the link, as long as you're responding within 5ms)
Lastly, I found a way to make the game jump to the code stored in SRAM. It's quite straightforward. There's a map script pointer that is normally used ingame to trigger cutscenes,
but you can point it at any address you want and it'll do an absolute jump to there. The pointer and everything else in that bank of memory gets copied from/to SRAM everytime the save gets saved/loaded.
Successfully tested all of this with a German Pokemon Blue cart and a Bootleg Pokemon "Cock" cart (It's a crappy immature ROM hack, based on American Pokemon Red. Don't judge me, it was a joke gift :P ).

And here's where the SNESdev part comes in.
Now that I have code running on the Super Gameboy, i'm trying to figure out how to actually break out,
I couldn't find any documentation on the command interface of the Super Gameboy.
Also, how would I sync the button-mashing Arduino to the SNES? is there a clock signal on the controller port?

If anyone is interested in this strange thing, I'll post some pictures, videos and maybe updates.
Re: So, i've set myself a challenge...
by on (#204584)
Nocash's fullsnes § SGB and Nocash's pandocs § SGB ?
Re: So, i've set myself a challenge...
by on (#204585)
Thank you!

The document linked to this: http://problemkaputt.de/pandocs.htm#sgbfunctions
Which is actually quite extensive. I just wished it was as easy as writing the packet to a memory location,
not having to manually transmit it bit by bit through the joypad register. Oh well, time to learn how to do bit shifting on z80.

Thanks for the help!

EDIT: Yup, saw the other one before you linked it.
Re: So, i've set myself a challenge...
by on (#204586)
binarycounter wrote:
4. Make a custom save file that 1. contains the same uploader program to "reflash", 2. contains a program that uploads code (~2KB) to the SNES and instructs the SGB to jump to that code.
(5.) Not sure if this could work, but since the code is running in WRAM at this point, couldn't I perform a cartswap and have the code copy itself to SRAM of a SNES cart?

This is possible, but cartswapping can potentially blow the SNES's fuse. The fuse is replaceable, but it's still best to be aware that this is not entirely safe to do.
Re: So, i've set myself a challenge...
by on (#204685)
This is one of those things that will leave people thinking "wow them hackers were too preoccupied with whether or not they could, that they didn't stop to think about whether or not they should"

But this is awesome though keep it up.
Re: So, i've set myself a challenge...
by on (#204810)
Quote:
This is one of those things that will leave people thinking "wow them hackers were too preoccupied with whether or not they could, that they didn't stop to think about whether or not they should"

Yup, that's basically the whole point of this. :lol:

Quote:
This is possible, but cartswapping can potentially blow the SNES's fuse. The fuse is replaceable, but it's still best to be aware that this is not entirely safe to do.

Yikes, there goes my dream of copying Sethbling's hex editor to my European Super Mario World cart.


So, I just had my first successful code execution on the SNES. It was nothing fancy, just a STP instruction (Hangs the SNES). But the code actually uploads 4KB of data to the SNES through the Super Gameboy VRAM, so all I need to do is actually code something for that. Instead of coding my own SGB comm. i just call the one that's already included in the ROM (It's used ingame to upload a border and palettes)

I've learned a few things along the way, mainly that bootlegs are strange.
1. The game would save despite having no battery
2. It would only save when saved from the Start Menu. Any other method of saving (Other Menu's, Trade Center, ACE) did not actually save.
3. When saving through the Start Menu, the game freezes (including music) for a good 2-5 seconds while the Power LED dims a bit.

I had the suspicion that the cart actually includes a microcontroller that flashes the SRAM content to the ROM/Flash on the cart.
So I wrote a little routine that dumps the ROM through the link cable (The dumping takes ~40 minutes), and ran the game in BGB.
The game loaded up my save file, despite having never dumped the SRAM. The save game is actually included in the ROM file.
I poked around the save function with BGB's debugger and it calls some addresses that should point into nowhere. Those calls crash the emulated GB,
but after adding them to the SRAM copy code it actually writes save files like I described above on my GBC. Wierd. I guess someone wanted to save a few cents on the battery.
The circuit board actually includes pads for a battery holder, connecting a battery to it did absolutely nothing.
Maybe these functions can be exploited to completely replace the Rom of Pokemon bootlegs without a Flasher.

If you want to try it out (e.g. in an emulated SGB), i've attached the save file to the post.

-You need a US version of Pokemon Red or Blue (Some Bootlegs may work, not sure about Pokemon Yellow)
Theoretically, it could work on any Pokemon Gen 1 cart, i'd just need to adjust the map pointer location.
-The main code is at 04A0 in the file, A4A0 when it's executed.
-The 4KB that get uploaded to SNES WRAM are at 1000-1FFF in the file (Look for a bunch of "DE AD BE EF")
-The code gets uploaded to 7F0000-7F0FFF in SNES WRAM then jumps to 7F0000.
-If you want to continue gameplay instead of executing the loader hold A+B while pressing continue in the menu.
That will reset the map pointer and return to the game's code. The save is in a poke center, right in front of the cable club, this is so i can easily "reflash" the code.
-If you disassemble the code, i'm sorry. It's absolute trash code, it barely works, i will fix it later when i'm ready to release everything ;)


So anyway, next step is to write a loader that polls the controller at high speed to overwrite the whole RAM, not just 4K.
Quick question, is there any way to make WLA-DX compile/link 65816 code, as if it was running in WRAM? So that absolute jumps and such match up with where it would be in RAM?

Thank you guys!