diff --git a/include/link_handler.h b/include/link_handler.h index 608f69e..c212a4a 100644 --- a/include/link_handler.h +++ b/include/link_handler.h @@ -229,8 +229,8 @@ enum LinkState SOFT_RESET, PACKET_EXCHANGE = 0x10, - BYTE_EXCHANGE, - PRINT_LAST_PACKET, + PACKET_EXCHANGE_BYTES, + PACKET_END, END = 0xFF, }; @@ -249,12 +249,13 @@ enum LinkConnectionError enum PayloadCommand { CMD_NONE = -1, - CMD_ReloadCurrentBox, // no arguments used. Reloads the current box from SRAM. Use this as the first command byte before performing other commands. - CMD_TransferPokemon, // 1st argument = secondary payload size, 2nd argument = box that should be transferred from. This command uses a secondary payload. The size of this secondary payload needs to be declared beforehand. Prior to requesting a secondary payload, the program will use the second argument to load a specific box from SRAM. Box numbers are 0-indexed and range from 0x00 (box 1) to 0x0B(box 12). This load procedure currently cannot be skipped. Once the secondary payload arrives, the program will verify its integrity and align the payload. Afterwards, it will use the information within this payload to remove pokémon from the current box. Once all transferred pokémon have been removed, the program will save the current box. - CMD_SoftReset, // no arguments used. Instantly soft resets the game. - CMD_ModifySRAMAccess, // 1st argument = SRAM dis/enable. set to 0x0A to open access, set to 0x00 to close access. Second argument = SRAM bank. When closing SRAM access, set to 0x00. SRAM remains open until closed by this command or until closed by CMD_TransferPokemon/CMD_ReloadCurrentBox. - CMD_RunSecondaryPayload, // 1st argument = secondary payload size. This command uses a secondary payload. The size of this secondary payload needs to be declared beforehand. Once the secondary payload arrives, the program will verify its integrity and align the payload. Afterwards, it will jump to the secondary payload and execute it. IMPORTANT: if you want to report an error when executing this secondary payload, return with carry flag set. IMPORTANT: if you want to report that the payload was executed safely, return with carry flag reset.*/ - CMD_ReadDataRequest, // a request to read data starting from the address defined by the 16-bit pointer. + CMD_ReloadCurrentBox, // no arguments used. Reloads the current box from SRAM. Use this as the first command byte before performing other commands. + CMD_TransferPokemon, // 1st argument = secondary payload size, 2nd argument = box that should be transferred from. This command uses a secondary payload. The size of this secondary payload needs to be declared beforehand. Prior to requesting a secondary payload, the program will use the second argument to load a specific box from SRAM. Box numbers are 0-indexed and range from 0x00 (box 1) to 0x0B(box 12). This load procedure currently cannot be skipped. Once the secondary payload arrives, the program will verify its integrity and align the payload. Afterwards, it will use the information within this payload to remove pokémon from the current box. Once all transferred pokémon have been removed, the program will save the current box. + CMD_SoftReset, // no arguments used. Instantly soft resets the game. + CMD_ModifySRAMAccess, // 1st argument = SRAM dis/enable. set to 0x0A to open access, set to 0x00 to close access. Second argument = SRAM bank. When closing SRAM access, set to 0x00. SRAM remains open until closed by this command or until closed by CMD_TransferPokemon/CMD_ReloadCurrentBox. + CMD_RunSecondaryPayload, // 1st argument = secondary payload size. This command uses a secondary payload. The size of this secondary payload needs to be declared beforehand. Once the secondary payload arrives, the program will verify its integrity and align the payload. Afterwards, it will jump to the secondary payload and execute it. IMPORTANT: if you want to report an error when executing this secondary payload, return with carry flag set. IMPORTANT: if you want to report that the payload was executed safely, return with carry flag reset.*/ + CMD_ReadDataRequest, // a request to read data starting from the address defined by the 16-bit pointer. + CMD_SecondaryPayload = 0xFF, // Used whenever a packet is for a secondary payload. }; #define OUTP_PREAMBLE_INDEX 0 @@ -288,15 +289,14 @@ struct LinkPacket LinkConnectionError latestError = NO_ERROR; byte recievedData[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + // Secondary payload + byte *secondaryPayloadData = nullptr; + int secondaryPayloadDataSize = 0; + byte secondaryPayloadSizeChecksum = 0; + LinkPacket() {}; - LinkPacket(PayloadCommand cmd, byte arg1, byte arg2, u16 addr) - { - command = cmd; - argument[0] = arg1; - argument[1] = arg2; - pointer = addr; - inUse = true; - }; + LinkPacket(PayloadCommand cmd, byte arg1, byte arg2, u16 addr); + LinkPacket(byte *payload, int payloadSize); }; class LinkConnection diff --git a/source/link_handler.cpp b/source/link_handler.cpp index 5fdf4fa..7543a7e 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -69,6 +69,27 @@ void linkCableIRQ() } } +LinkPacket::LinkPacket(PayloadCommand cmd, byte arg1, byte arg2, u16 addr) +{ + command = cmd; + argument[0] = arg1; + argument[1] = arg2; + pointer = addr; + inUse = true; +}; + +LinkPacket::LinkPacket(byte *payload, int payloadSize) +{ + command = CMD_SecondaryPayload; + secondaryPayloadData = payload; + secondaryPayloadDataSize = payloadSize + 1; + for (int i = 0; i < payloadSize; i++) + { + secondaryPayloadSizeChecksum += payload[i]; + } + secondaryPayloadSizeChecksum = 0x100 - secondaryPayloadSizeChecksum; +} + void LinkConnection::setup(const u16 *debug_charset) { link_cable_memory_section_index = 0; @@ -503,77 +524,104 @@ void LinkConnection::handleStateLogic() case PACKET_EXCHANGE: nextOutData = 0xFF; - exitState = BYTE_EXCHANGE; + exitState = PACKET_EXCHANGE_BYTES; break; - case BYTE_EXCHANGE: + case PACKET_EXCHANGE_BYTES: { LinkPacket &currPacket = linkPacketArr[linkPacketArrIndex % LINK_PACKET_ARRAY_SIZE]; - switch (subStateCounter % TOTAL_PACKET_LENGTH) + + if (currPacket.command != CMD_SecondaryPayload) { - case 0: - nextOutData = 0xFD; - break; - case 1: - nextOutData = linkPacketArrIndex; - currPacket.packetID = linkPacketArrIndex; - break; - case 2: - nextOutData = currPacket.command; - if (currPacket.command == CMD_SoftReset) + switch (subStateCounter) { - // Immedaitely remove the Soft Reset packet from in use, it will not get a response. - currPacket.inUse = false; + case 0: + nextOutData = 0xFD; + break; + case 1: + nextOutData = linkPacketArrIndex; + currPacket.packetID = linkPacketArrIndex; + break; + case 2: + nextOutData = currPacket.command; + if (currPacket.command == CMD_SoftReset) + { + // Immedaitely remove the Soft Reset packet from in use, it will not get a response. + currPacket.inUse = false; + } + break; + case 3: + nextOutData = currPacket.argument[0]; + break; + case 4: + nextOutData = currPacket.argument[1]; + break; + case 5: + nextOutData = currPacket.pointer >> 0; + break; + case 6: + nextOutData = currPacket.pointer >> 8; + break; + case TOTAL_PACKET_LENGTH - 1: + exitState = PACKET_END; + default: + nextOutData = 0xFF; + break; } - break; - case 3: - nextOutData = currPacket.argument[0]; - break; - case 4: - nextOutData = currPacket.argument[1]; - break; - case 5: - nextOutData = currPacket.pointer >> 0; - break; - case 6: - nextOutData = currPacket.pointer >> 8; - break; - case TOTAL_PACKET_LENGTH - 1: - if (currPacket.command == CMD_SoftReset) + } + else // This packet is a secondary payload. Send that instead. + { + switch (subStateCounter) { - // There's no response to be had, so just end the connection. - // exitState = PRINT_LAST_PACKET; + case 0: + nextOutData = 0xFD; + break; + case 1: + nextOutData = linkPacketArrIndex; + currPacket.packetID = linkPacketArrIndex; + break; + case 2: + // The command ID matches the saftey byte (0xFF) + nextOutData = currPacket.command; + break; + case 3: + nextOutData = currPacket.secondaryPayloadDataSize; + break; + default: + // We're through all the constant values, let's do the rest. + if ((subStateCounter - 4) < currPacket.secondaryPayloadDataSize) + { + nextOutData = currPacket.secondaryPayloadData[subStateCounter - 4]; + } + else if ((subStateCounter - 4) == currPacket.secondaryPayloadDataSize) + { + // Add the checksum and we're done with the packet. + nextOutData = currPacket.secondaryPayloadSizeChecksum; + exitState = PACKET_END; + } + break; } - linkPacketArrIndex = (linkPacketArrIndex + 1) & 0x7F; - default: - nextOutData = 0xFF; - break; } - if (subStateCounter % TOTAL_PACKET_LENGTH == 0) - { - newPacket = true; - if (subStateCounter != 0) - { - processPacket(); - } - if (allPacketsProcessed()) - { - exitState = END; - } - } - else - { - newPacket = false; - } - - dataOutBuffer[subStateCounter % TOTAL_PACKET_LENGTH] = inData; + dataOutBuffer[subStateCounter] = inData; } break; - case PRINT_LAST_PACKET: - nextOutData = 0xFF; - exitState = END; + case PACKET_END: + newPacket = true; + // if (subStateCounter != 0) + { + processPacket(); + } + if (allPacketsProcessed()) + { + exitState = END; + } + else + { + linkPacketArrIndex = (linkPacketArrIndex + 1) & 0x7F; + exitState = PACKET_EXCHANGE_BYTES; + } break; case END: @@ -902,11 +950,6 @@ bool LinkConnection::LinkCommand_SoftReset(bool waitForCompletion) linkPacketArr[0] = LinkPacket(CMD_SoftReset, 0x00, 0x00, 0xC6DC); - // linkPacketArr[1] = LinkPacket(CMD_SoftReset, 0x00, 0x00, 0xC6DC); - - // This is used to flush the Soft Reset packet to be run. - // linkPacketArr[0] = LinkPacket(CMD_ReadDataRequest, 0x00, 0x00, 0xC6DC); - globalLinkCable.startConnection(PACKET_EXCHANGE); if (waitForCompletion) { @@ -944,7 +987,11 @@ bool LinkConnection::LinkCommand_RunSecondaryPayload(bool waitForCompletion) { resetLinkPackets(); - linkPacketArr[0] = LinkPacket(CMD_ReloadCurrentBox, 0x00, 0x00, 0xC6DC); + byte tempPayload[] = {0x21, 0xA0, 0xC3, 0x75, 0xC9}; + byte size = 5; + + linkPacketArr[0] = LinkPacket(CMD_RunSecondaryPayload, size, 0x00, 0xC6DC); + linkPacketArr[1] = LinkPacket(tempPayload, size); globalLinkCable.startConnection(PACKET_EXCHANGE); if (waitForCompletion) diff --git a/source/script_array.cpp b/source/script_array.cpp index 51932fc..c943345 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -792,16 +792,11 @@ bool run_conditional(int index) obj_unhide(gb_flag, 0); obj_set_pos(gb_flag, 1.5 * 8, 14 * 8); - globalLinkCable.LinkCommand_ReadMemorySection(0xDA80, party_data.box_data_array, 1122); + //globalLinkCable.LinkCommand_ReadMemorySection(0xDA80, party_data.box_data_array, 1122); - if (g_debug_options.print_link_packets) - { - globalLinkCable.skipPrint = false; - globalLinkCable.pauseOnPacket = true; - } - globalLinkCable.LinkCommand_ModifySRAMAccess(true, 3); - globalLinkCable.LinkCommand_SoftReset(); + //globalLinkCable.LinkCommand_SoftReset(); + globalLinkCable.LinkCommand_RunSecondaryPayload(); party_data.box.loadData(globalLinkCable.gen, globalLinkCable.lang, party_data.box_data_array); }