Implementing Yellow and Gold/Silver Payloads

This commit is contained in:
Remnants of Forgotten Disney 2024-04-29 08:29:09 -05:00
parent f51a90e139
commit 5cb282c8a7
12 changed files with 1380 additions and 545 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build/
*.zip
.vscode/
source/payload_builder.exe
source/test_payload.txt

View File

@ -32,8 +32,8 @@
#define SLOW_SPEED 1000
void setup();
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Simplified_Pokemon *curr_simple_array);
int loop(byte *box_data_storage, byte *curr_payload, Simplified_Pokemon *curr_simple_array);
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array);
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, Simplified_Pokemon *curr_simple_array);
byte exchange_parties(byte curr_in, byte *curr_payload);
byte exchange_boxes(byte curr_in, byte *party_data);
byte exchange_remove_array(byte curr_in, Simplified_Pokemon *curr_simple_array);

View File

@ -2,13 +2,13 @@
#define PAYLOAD_H
// Redefine these because C++ doesn't like TONC
typedef unsigned char u8, byte, uchar, echar;
typedef unsigned char u8, byte, uchar, echar;
typedef unsigned short u16, hword, ushort, eshort;
typedef unsigned int u32, word, uint, eint;
typedef unsigned int u32, word, uint, eint;
typedef unsigned long long u64;
#define PAYLOAD_SIZE 637
#define NUM_PAYLOADS 1
#define PAYLOAD_SIZE 672
#define NUM_PAYLOADS 3
#define GB_TILE_WIDTH 20
@ -17,46 +17,52 @@ struct GB_ROM
public:
int language;
int version;
byte payload_array[PAYLOAD_SIZE];
int generation;
int method;
int payload_size;
int box_data_size;
hword print_string_start;
hword stack_overwrite_location;
byte short_pkmn_name; // The name of the Pokemon that moves us through RAM
byte pointer_pkmn_name; // The name of the Pokemon that corrupts the stack
byte custom_name[11];
// This can be a few different places:
// wSerialOtherGameboyRandomNumberListBlock:
// 0xCD81 to 0xCD8A
// wLinkEnemyTrainerName:
// 0xD887 to 0xDA2F
// wSerialEnemyMonsPatchList:
// 0xC5D0 to 0xC6E8
byte enter_vector_destination;
hword enter_vector_location;
hword clearScreen;
hword textBoarderUppLeft;
byte textBoarderWidth;
byte textBoarderHeight;
hword CableClub_TextBoxBoarder;
hword transferWaitString;
hword transferStringLocation;
hword print_string_start; // Start of where text is written in VRAM
hword stack_overwrite_location; // The part of the stack that we're overwriting
byte short_pkmn_name; // The name of the Pokemon that moves us through RAM
byte pointer_pkmn_name; // The name of the Pokemon that overwrites the stack
byte enter_vector_destination; // The location within the payload array where the jump should start
hword enter_vector_location; // Where we should jump to from the enter vector
// This can be a few different places:
// wSerialOtherGameboyRandomNumberListBlock:
// 0xCD81 to 0xCD8A
// wLinkEnemyTrainerName:
// 0xD887 to 0xDA2F
// wSerialEnemyMonsPatchList:
// 0xC5D0 to 0xC6E8
word clearScreen;
word CableClub_TextBoxBoarder;
hword placeString;
hword hSerialConnectionStatus;
hword wBoxDataStart;
hword wBoxDataEnd;
hword Serial_ExchangeBytes;
hword garbageDataLocation;
hword pkmnTransferArray;
hword wRemoveMonFromBox;
hword arrayCounter;
hword wBoxCount;
hword wWhichPokemon;
hword _RemovePokemon;
hword SaveSAVtoSRAM1;
word wRemoveMonFromBox;
word wBoxCount;
word wWhichPokemon;
word _RemovePokemon;
word SaveSAVtoSRAM1;
byte SaveSAVtoSRAM1_memBank;
hword Bankswitch;
hword SoftReset;
hword garbageDataLocation;
hword transferWaitString;
hword pkmnTransferArray;
hword arrayCounter;
byte transferString[30];
byte custom_name[11];
hword transferStringLocation;
hword textBoarderUppLeft;
byte textBoarderWidth;
byte textBoarderHeight;
};
#endif

View File

@ -17,188 +17,36 @@
#define GOLD_SILVER_ID 4
#define CRYSTAL_ID 5
#define METHOD_NEWLINE 0
#define METHOD_MEW 1
#define METHOD_GEN2 2
#include "gb_rom_values/base_gb_rom_struct.h"
const struct GB_ROM ENG_RED_BLUE = {
.language = ENG_ID,
.version = RED_BLUE_ID,
.payload_array = {
.generation = 1,
.method = METHOD_NEWLINE,
.payload_size = 637,
.box_data_size = 0x462,
// RNG Seed
0, 0, 0, 0, 0, 0xCD, 0x87, 0xD8, 184, 165,
// Preamble
253, 253, 253, 253, 253, 253, 253, 253,
// Party (bootstrap)
//// Rival name
248, 0, 54, 253, 1, 62, 88, 197, 195, 214, 197,
// num of Pokemon
6,
// Pokemon list
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 252, 0xE3, 0xE3, 255,
// Code
33, 160, 195, 1, 136, 1, 62, 0, 205, 224, 54, 17, 24, 218, 33, 89, 196, 205, 85, 25, 195, 21, 218, 139, 142, 128, 131, 136, 141, 134, 232, 232, 232, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 64, 0, 0,
// Patchlist preamble
253, 253, 253, 253, 253, 255, 255,
// Patchlist (code storage)
// Empty spacing
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
// Write transferring message to screen
// call ClearScreen
0xCD, 0x0F, 0x19,
// ld hl, $C42E
0x21, 0x2E, 0xC4,
// ld b, 3 [height]
0x06, 0x03,
// ld c, 14 [width]
0x0E, 0x0E,
// call CableClub_TextBoxBoarder
0xCD, 0xB3, 0x5A,
// ld hl, $C443
0x21, 0x43, 0xC4,
// ld de, TransferWaitString
0x11, 0x7A, 0xC6,
// call PlaceString
0xCD, 0x55, 0x19,
// Transfer box data
// ld hl, hSerialConnectionStatus
0x21, 0xAA, 0xFF,
// ld [hl], 0x01 [Make sure GB is the slave]
0x36, 0x01,
// ld hl, (wBoxDataStart - 1) [data to send]
0x21, 0x7F, 0xDA,
// ld [hl], 0xFD [set the start of the data to 0xFD so Serial_ExchangeBytes is happy]
0x36, 0xFD,
// ld de, (wBoxDataStart - 3) [location to put stored data]
0x11, 0x7D, 0xDA,
// ld bc, (wBoxDataEnd - wBoxDataStart) + 2
0x01, 0x64, 0x04,
// call Serial_ExchangeBytes [Send the box data]
0xCD, 0x6F, 0x21,
// Recieve the Pokemon to remove
// ld hl, hSerialConnectionStatus
0x21, 0xAA, 0xFF,
// ld [hl], 0x01 [Make sure GB is the slave]
0x36, 0x01,
// ld hl, 0xC613 [data to send, garbage data]
0x21, 0x16, 0x03,
// ld de, 0xC651 [data to recieve]
0x11, 0x51, 0xC6,
// ld bc, 0x001E [size of data]
0x01, 0x27, 0x00,
// call Serial_ExchangeBytes [Recieve the removal array]
0xCD, 0x6F, 0x21,
// Remove the transfered Pokemon
// ld hl, wRemoveMonFromBox
0x21, 0x95, 0xCF,
// ld [hl], [!= 0x00 specifies the current box]
0x36, 0x01,
// ld a, [arrayCounter]
0xFA, 0x50, 0xC6,
// ld e, a
0x5F,
// ld d, 0x00
0x16, 0x00,
// ld hl, [removalArray]
0x21, 0x51, 0xC6,
// add hl, de
0x19,
// inc a
0x3C,
// ld [arrayCounter], a
0xEA, 0x50, 0xC6,
// ld a, [wBoxCount]
0xFA, 0x80, 0xDA,
// ld b, a
0x47,
// ld a, [hl]
0x2A,
// cp a, 0xFF
0xFE, 0xFF,
// jr z, 12
0x28, 0x0C,
// cp a, b
0xB8,
// jr nc, -26
0x30, 0xE6,
// ld hl, wWhichPokemon
0x21, 0x92, 0xCF,
// ld [hl], a
0x77,
// call _RemovePokemon
0xCD, 0x68, 0x7B,
// jr, -35
0x18, 0xDD,
// Save the current box
// ld hl, SaveSAVtoSRAM1
0x21, 0xE2, 0x77,
// ld b, 0x1C [memory bank of SaveSAVtoSRAM1]
0x06, 0x1C,
// call Bankswitch [which will jump to what's loaded in HL]
0xCD, 0xD6, 0x35,
// jp SoftReset
0xC3, 0x49, 0x1F,
// 1 byte to store the current array counter
// $C650
0x00,
// 40 byte storage for list of Pokemon to remove
// $C651
0xFD, 0xFD, 0xFD, 0xFD, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A,
0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// permanent array terminator, just in case
// $C679
0xFF,
// TransferWaitString
// $C67A
// TRANSFERRING..\n
// PLEASE WAIT!
0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E,
0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50,
// This payload works by placing Pokemon ID 0xFC's name in the stack, and causing a return to CD8E,
// which is part of the RNG seed. From there we can jump anywhere- and we choose to jump to D887,
// which is the rival's name. This code fixes the stack and jumps to the patchlist, which is where
// our final code is.
},
.print_string_start = 0xC456,
.stack_overwrite_location = 0xDFDD,
.short_pkmn_name = 0xE3,
.pointer_pkmn_name = 0xFC,
.custom_name = {0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50},
.enter_vector_destination = 0x05,
.enter_vector_location = 0xC5D6,
.clearScreen = 0x190F,
.textBoarderUppLeft = 0xC42E,
.textBoarderWidth = 3,
.textBoarderHeight = 14,
.CableClub_TextBoxBoarder = 0x5AB3,
.transferWaitString = 0xC67A,
.transferStringLocation = 0xC443,
.placeString = 0x1955,
.hSerialConnectionStatus = 0xFFAA,
.wBoxDataStart = 0xDA80,
.wBoxDataEnd = 0xDEE2,
.Serial_ExchangeBytes = 0x216F,
.garbageDataLocation = 0x0316, // Starts with 0xFD
.pkmnTransferArray = 0xC651,
.wRemoveMonFromBox = 0xCF95,
.arrayCounter = 0xC650,
.wBoxCount = 0xDA80,
.wWhichPokemon = 0xCF92,
._RemovePokemon = 0x7B68,
@ -206,10 +54,119 @@ const struct GB_ROM ENG_RED_BLUE = {
.SaveSAVtoSRAM1_memBank = 0x1C,
.Bankswitch = 0x35D6,
.SoftReset = 0x1F49,
.transferString = { // TRANSFERRING..\n
// PLEASE WAIT!
0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E,
0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50}
};
.garbageDataLocation = 0x0316, // Starts with 0xFD
.transferWaitString = 0xC67A, // Enter vector + A4
.pkmnTransferArray = 0xC651, // Enter vector + 7B
.arrayCounter = 0xC650, // Enter vector + 7A
.transferString = { // TRANSFERRING..\n
// PLEASE WAIT!
0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E,
0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50},
.custom_name = {0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50},
.transferStringLocation = 0xC443,
.textBoarderUppLeft = 0xC42E,
.textBoarderWidth = 3,
.textBoarderHeight = 14,
};
const struct GB_ROM ENG_YELLOW = {
.language = ENG_ID,
.version = YELLOW_ID,
.generation = 1,
.method = METHOD_MEW,
.payload_size = 637,
.box_data_size = 0x462,
.print_string_start = 0xC456,
.stack_overwrite_location = 0xDFDD,
.short_pkmn_name = 0x15,
.pointer_pkmn_name = 0xE3,
//.enter_vector_destination = 0x05,
//.enter_vector_location = 0xC5D6,
.clearScreen = 0x16DD,
.CableClub_TextBoxBoarder = 0x5B67,
.placeString = 0x1723,
.hSerialConnectionStatus = 0xFFAA,
.wBoxDataStart = 0xDA7F,
.wBoxDataEnd = 0xDEE1,
.Serial_ExchangeBytes = 0x1FCB,
.wRemoveMonFromBox = 0xCF94,
.wBoxCount = 0xDA7F,
.wWhichPokemon = 0xCF91,
._RemovePokemon = 0x7A0F,
.SaveSAVtoSRAM1 = 0x1B32,
.SaveSAVtoSRAM1_memBank = 0x1C,
.Bankswitch = 0x3E84,
.SoftReset = 0x1D05,
.garbageDataLocation = 0x0161, // Starts with 0xFD
.transferWaitString = 0xC67A, // Enter vector + A4
.pkmnTransferArray = 0xC651, // Enter vector + 7B
.arrayCounter = 0xC650, // Enter vector + 7A
.transferString = { // TRANSFERRING..\n
// PLEASE WAIT!
0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E,
0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50},
.custom_name = {0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50},
.transferStringLocation = 0xC443,
.textBoarderUppLeft = 0xC42E,
.textBoarderWidth = 3,
.textBoarderHeight = 14,
};
const struct GB_ROM ENG_GOLD_SILVER = {
.language = ENG_ID,
.version = GOLD_SILVER_ID,
.generation = 2,
.method = METHOD_GEN2,
.payload_size = 672,
.box_data_size = 0x44E,
/**/
.print_string_start = 0xC442,
.stack_overwrite_location = 0xDFCB, // Found by seeing where 772C is stored in the stack, 772C is the code that calls PlaceString
.short_pkmn_name = 0x4E,
//.pointer_pkmn_name = 0xFC,
//.enter_vector_destination = 0x05,
.enter_vector_location = 0xC5D6,
.clearScreen = 0x000EE2,
.CableClub_TextBoxBoarder = 0x0A4D88, // LinkTextboxAtHL
.placeString = 0x000F74,
.hSerialConnectionStatus = 0xFFCD,
.wBoxDataStart = 0xAD6C, // sBoxStart
.wBoxDataEnd = 0xB1BA, // sBoxEnd
.Serial_ExchangeBytes = 0x0710,
.wRemoveMonFromBox = 0x01D008, // wPokemonWithdrawDepositParameter, bank 1
.wBoxCount = 0x01AD6C, // sBoxCount, bank 1
.wWhichPokemon = 0x01D005, // wCurPartyMon, bank 1
._RemovePokemon = 0x03603F - 2, // RemoveMonFromPartyOrBox, bank 3
.SaveSAVtoSRAM1 = 0x0577E2, // ? 0x4DF6
.SaveSAVtoSRAM1_memBank = 0x5,
//.Bankswitch = 0x0010,
.SoftReset = 0x05B0, // ?
.garbageDataLocation = 0x0654, // ? Starts with 0xFD
.transferWaitString = 0xC67A, // Enter vector +
.pkmnTransferArray = 0xC651, // Enter vector +
.arrayCounter = 0xC650, // Enter vector +
.transferString = { // TRANSFERRING..\n
// PLEASE WAIT!
0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E,
0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50},
.custom_name = {0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50},
.transferStringLocation = 0xC443, // ?
.textBoarderUppLeft = 0xC42E, // ?
.textBoarderWidth = 3, // ?
.textBoarderHeight = 14, // ?
};
#endif

View File

@ -4,5 +4,6 @@
#include "gb_rom_values/base_gb_rom_struct.h"
byte *generate_payload(GB_ROM curr_rom, bool debug);
void write_call(int generation, byte array_data[], int& offset, word call_location);
#endif

View File

@ -5,8 +5,6 @@
#include "pokemon.h"
#include "gb_rom_values/eng_gb_rom_values.h"
#define BOX_DATA_ARRAY_SIZE 0x462
class Pokemon_Party
{
public:
@ -20,7 +18,7 @@ public:
void set_lang(int nLang);
int get_lang();
bool load_payload();
GB_ROM curr_rom;
GB_ROM curr_gb_rom;
void show_sprites();
Simplified_Pokemon simple_pkmn_array[30];
Simplified_Pokemon get_simple_pkmn(int index);

View File

@ -32,6 +32,8 @@
#define remove_array_preamble 13
#define send_remove_array 14
#define end2 15
#define wait_to_resend 16
#define resend_payload 17
const int MODE = 1; // mode=0 will transfer pokemon data from pokemon.h
// mode=1 will copy pokemon party data being received
@ -54,7 +56,7 @@ int FF_count;
int zero_count;
int state;
int mosi_delay = 16; // inital delay, speeds up once sending PKMN
int mosi_delay = 4; // inital delay, speeds up once sending PKMN
std::string out_array[10];
@ -108,11 +110,17 @@ void setup()
}
}
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Simplified_Pokemon *curr_simple_array)
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array)
{
// TODO: Change to a switch statement
if (state == hs)
{
if (curr_gb_rom->generation == 2)
{
state = ack;
// mosi_delay = 1;
return 0x00;
}
if (in == 0x00)
{
state = ack;
@ -122,26 +130,38 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Sim
else if (state == ack)
{
if (in == 0x00)
if (curr_gb_rom->generation == 2)
{
state = menu;
return 0x00;
if (in == 0x61)
{
state = menu;
return 0x61;
}
return 0x01;
}
else if (in == 0x02)
else
{
state = hs;
return 0x02;
if (in == 0x00)
{
state = menu;
return 0x00;
}
else if (in == 0x02)
{
state = hs;
return 0x02;
}
}
}
else if (state == menu)
{
if (in == 0x60)
if (in == 0x60 || in == 0x61)
{
tte_erase_screen();
tte_write("Connected to Game Boy.");
state = pretrade;
return 0x60;
return in;
}
else if (in == 0x02)
{
@ -156,10 +176,15 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Sim
else if (state == pretrade)
{
if (in == 0xd0)
if (in == 0xD0)
{
state = trade;
return 0xd4;
return 0xD4;
}
else if (in == 0xD1)
{
state = trade;
return 0xD1;
}
return in;
}
@ -186,9 +211,20 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Sim
else if (state == trade_data)
{
if (data_counter >= PAYLOAD_SIZE && in == 0xFD)
if (data_counter >= curr_gb_rom->payload_size)
{
state = box_preamble;
if (in == 0xFD)
{
state = box_preamble;
}
else if ((curr_gb_rom->method == METHOD_MEW) && (in == 0xFE))
{
state = wait_to_resend;
}
else
{
return 0x00;
}
}
return exchange_parties(in, curr_payload);
}
@ -206,13 +242,34 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Sim
else if (state == box_data)
{
if (data_counter >= BOX_DATA_ARRAY_SIZE)
if (data_counter >= curr_gb_rom->box_data_size)
{
state = end1;
}
return exchange_boxes(in, box_data_storage);
}
else if (state == wait_to_resend)
{
if (in != 0xFE)
{
state = resend_payload;
data_counter = 0x1B4;
}
return 0x00;
}
else if (state == resend_payload)
{
if (data_counter >= (0x1B4 + 0xC2 + 0x07)) // Offset + size + preamble
{
state = box_preamble;
data_counter = curr_gb_rom->payload_size;
mosi_delay = 1;
}
return exchange_parties(in, curr_payload);
}
else if (state == reboot)
{
data_counter = 0;
@ -244,7 +301,7 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, Sim
return in;
}
int loop(byte *box_data_storage, byte *curr_payload, Simplified_Pokemon *curr_simple_array)
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array)
{
int counter = 0;
while (true)
@ -261,7 +318,7 @@ int loop(byte *box_data_storage, byte *curr_payload, Simplified_Pokemon *curr_si
std::to_string(in_data) + "][" +
std::to_string(out_data) + "]\n");
}
out_data = handleIncomingByte(in_data, box_data_storage, curr_payload, curr_simple_array);
out_data = handleIncomingByte(in_data, box_data_storage, curr_payload, curr_gb_rom, curr_simple_array);
if (FF_count > 25)
{

View File

@ -32,11 +32,10 @@
/*
TODO:
- Implement patch list (as described here: https://web.archive.org/web/20180508011842/https://vaguilar.js.org/posts/1/)
But this isn't going to be relevant after the ACE is implemented, since we will be pulling directly from the box... right?
is 0xFE being a terminator part of the SPI function or is it implemented specifically in the trade/battle code?
- Rename to PokeTransporter GB
- Implement global next frame
- Add in putting item from Pkmn to bag in gen 2
- Stablize link cable (switch between slave and master)
- Fix double transfer glitch
- Remove global variables
- Better custom sprites (Progress, Fennel, Title)
- Add a % or x/250 for the Dream Dex

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@ void Pokemon::load_data(int index, byte *party_data, int game, int lang)
case GOLD_SILVER_ID:
case CRYSTAL_ID:
gen = 2;
pkmn_size = 48;
pkmn_size = 32;
ot_size = 6;
nickname_size = 6;
box_size = 30;
@ -56,7 +56,7 @@ void Pokemon::load_data(int index, byte *party_data, int game, int lang)
case GOLD_SILVER_ID:
case CRYSTAL_ID:
gen = 2;
pkmn_size = 48;
pkmn_size = 32;
ot_size = 11;
nickname_size = 11;
box_size = 20;

View File

@ -10,13 +10,13 @@
#include "payload_builder.h"
const GB_ROM *list_of_gb_roms[NUM_PAYLOADS] = {
&ENG_RED_BLUE
&ENG_RED_BLUE,
&ENG_YELLOW,
&ENG_GOLD_SILVER,
};
byte debug_box_data[0x462] = {
// Preamble
//0x00, 0x00, 0xFD, 0xFD, 0xFD,
// num of Pokemon
byte gen1_debug_box_data[0x462] = {
// Num of Pokemon
0x14,
// Pokemon 1-20
//0x02, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x7B, 0x71, 0x71, 0x7C, 0x71, 0x71, 0x71, 0x71, 0x24, 0x24, 0xA5, 0x15, 0xFF,
@ -85,27 +85,97 @@ byte debug_box_data[0x462] = {
0x91, 0x80, 0x93, 0x93, 0x80, 0x93, 0x80, 0x50, 0x50, 0x50, 0x50,
0x8F, 0x88, 0x83, 0x86, 0x84, 0x98, 0x50, 0x50, 0x50, 0x50, 0x50,
};
byte gen2_debug_box_data[0x44E] = {
// Num of Pokemon
0x14,
// Pokemon 1-20
0xD5, 0x7B, 0xE3, 0x9D, 0xC3, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xFF,
// Pokemon list
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0x7B, 0x00, 0x62, 0x2B, 0x74, 0xE4, 0xBB, 0x4C, 0x00, 0x08, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0xF9, 0x1E, 0x1E, 0x1E, 0x14, 0x46, 0x00, 0x00, 0x00, 0x0D,
0xE3, 0x00, 0x13, 0xA8, 0x81, 0x61, 0xBB, 0x4C, 0x01, 0xC5, 0x71, 0x17, 0x99, 0x1D, 0x33, 0x1B, 0x77, 0x19, 0x7F, 0x18, 0xB9, 0xDF, 0x87, 0x0F, 0x0A, 0x14, 0x1E, 0xFF, 0x00, 0x00, 0x00, 0x2D,
0x9D, 0x00, 0xAC, 0x09, 0x59, 0x46, 0xBB, 0x4C, 0x01, 0xAA, 0xDE, 0x23, 0xE8, 0x2C, 0xCF, 0x29, 0x00, 0x2C, 0xD4, 0x28, 0x55, 0xF6, 0xD7, 0x19, 0x0F, 0x0A, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x30,
0xC3, 0x1B, 0xD6, 0x27, 0x15, 0x37, 0xBB, 0x4C, 0x00, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x10, 0x0A, 0x1E, 0x14, 0x19, 0x4C, 0x00, 0x00, 0x00, 0x14,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10,
// Trainer names
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00,
// Nicknames
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x82, 0x98, 0x93, 0x87, 0x84, 0x91, 0x50, 0x50, 0x50, 0x50,
0x82, 0x80, 0x8C, 0x84, 0x8B, 0x8E, 0x93, 0x50, 0x50, 0x50, 0x50,
0x93, 0x88, 0x8C, 0x8D, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
0x90, 0xF3, 0x80, 0x9B, 0xE6, 0x9C, 0x91, 0x9E, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50
};
Pokemon_Party::Pokemon_Party(){};
void Pokemon_Party::start_link()
{
if (IGNORE_LINK_CABLE)
{
for (int i = 0; i < BOX_DATA_ARRAY_SIZE; i++)
for (int i = 0; i < 0x44E; i++)
{
box_data_array[i] = debug_box_data[i];
box_data_array[i] = gen2_debug_box_data[i];
}
}
else
{
setup();
last_error = loop(&box_data_array[0], generate_payload(curr_rom, false), simple_pkmn_array);
last_error = loop(&box_data_array[0], generate_payload(curr_gb_rom, false), &curr_gb_rom, simple_pkmn_array);
}
}
void Pokemon_Party::continue_link(){
if (!IGNORE_LINK_CABLE){
last_error = loop(&box_data_array[0], generate_payload(curr_rom, false), simple_pkmn_array);
last_error = loop(&box_data_array[0], generate_payload(curr_gb_rom, false), &curr_gb_rom, simple_pkmn_array);
}
}
@ -158,7 +228,7 @@ bool Pokemon_Party::load_payload(){
if (lang == list_of_gb_roms[i]->language &&
game == list_of_gb_roms[i]->version)
{
curr_rom = *list_of_gb_roms[i];
curr_gb_rom = *list_of_gb_roms[i];
return true;
}
}

View File

@ -1,51 +1,51 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xD6, 0xC5, 0x00, 0x00, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
# 0x10
0xFD, 0xFD, 0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50, 0x06, 0xE3, 0xE3,
0xFD, 0xFD, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x20
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x30
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x40
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x50
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x60
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x70
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x80
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0x90
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0xA0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
# 0xB0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
# 0xC0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x80, 0x80, 0x80, 0xD6, 0xC5, 0xFF, 0xFF, 0xFF, 0x3E, 0x03, 0xD7, 0xCD, 0xD8, 0x63, 0x3E, 0x05,
# 0xD0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0xD7, 0xCD, 0xF6, 0x4D, 0xC3, 0xB0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0xE0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0xF0
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x100
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x110
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x120
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x130
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x140
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x150
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x160
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x170
0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xFC, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x180
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x190
@ -53,28 +53,33 @@
# 0x1A0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x1B0
0x00, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFF, 0xFF, 0xCD, 0x0F, 0x19, 0x21, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x1C0
0xC4, 0x06, 0x03, 0x0E, 0x0E, 0xCD, 0xB3, 0x5A, 0x21, 0x43, 0xC4, 0x11, 0x7A, 0xC6, 0xCD, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# 0x1D0
0x19, 0x21, 0xAA, 0xFF, 0x36, 0x02, 0x21, 0x7F, 0xDA, 0x36, 0xFD, 0x11, 0x7E, 0xDA, 0x01, 0x64,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFF, 0xFF, 0xCD, 0xE2,
# 0x1E0
0x04, 0xCD, 0x6F, 0x21, 0x21, 0xAA, 0xFF, 0x36, 0x02, 0x21, 0x16, 0x03, 0x11, 0x51, 0xC6, 0x01,
0x0E, 0x21, 0x2E, 0xC4, 0x06, 0x03, 0x0E, 0x0E, 0x3E, 0x0A, 0xD7, 0xCD, 0x88, 0x4D, 0x21, 0x43,
# 0x1F0
0x1E, 0x00, 0x00, 0x00, 0x00, 0x21, 0x95, 0xCF, 0x36, 0x01, 0xFA, 0x50, 0xC6, 0x5F, 0x16, 0x00,
0xC4, 0x11, 0x7A, 0xC6, 0xCD, 0x74, 0x0F, 0x21, 0xCD, 0xFF, 0x36, 0x02, 0x3E, 0x01, 0xCD, 0xE1,
# 0x200
0x21, 0x51, 0xC6, 0x19, 0x3C, 0xEA, 0x50, 0xC6, 0xFA, 0x80, 0xDA, 0x47, 0x2A, 0xFE, 0xFF, 0x28,
0x30, 0x21, 0x6B, 0xAD, 0x36, 0xFD, 0x11, 0x6A, 0xAD, 0x01, 0x50, 0x04, 0xCD, 0x10, 0x07, 0x21,
# 0x210
0x0C, 0xB8, 0x30, 0xE6, 0x21, 0x92, 0xCF, 0x77, 0xCD, 0x68, 0x7B, 0x18, 0xDD, 0x21, 0xE2, 0x77,
0xCD, 0xFF, 0x36, 0x02, 0x21, 0x54, 0x06, 0x11, 0x51, 0xC6, 0x01, 0x1E, 0x00, 0x00, 0x00, 0x00,
# 0x220
0x06, 0x1C, 0xCD, 0xD6, 0x35, 0xC3, 0x49, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x21, 0x08, 0xD0, 0x36, 0x01, 0xFA, 0x50, 0xC6, 0x5F, 0x16, 0x00, 0x21, 0x51, 0xC6, 0x19, 0x3C,
# 0x230
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14,
0xEA, 0x50, 0xC6, 0xFA, 0x6C, 0xAD, 0x47, 0x2A, 0xFE, 0xFF, 0x28, 0x0F, 0xB8, 0x30, 0xE6, 0x21,
# 0x240
0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
0x05, 0xD0, 0x77, 0x3E, 0x03, 0xD7, 0xCD, 0x3F, 0x60, 0x18, 0xDA, 0xC3, 0xB6, 0xC7, 0x00, 0x00,
# 0x250
0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x93,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17,
# 0x260
0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2, 0x4E, 0x7F, 0x8F,
0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07,
# 0x270
0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50,
0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
# 0x280
0xFF, 0xFF, 0x93, 0x91, 0x80, 0x8D, 0x92, 0x85, 0x84, 0x91, 0x91, 0x88, 0x8D, 0x86, 0xF2, 0xF2,
# 0x290
0x4E, 0x7F, 0x8F, 0x8B, 0x84, 0x80, 0x92, 0x84, 0x7F, 0x96, 0x80, 0x88, 0x93, 0xE7, 0x7F, 0x50,
# 0x2A0