diff --git a/README.md b/README.md index f7198a3..ea4b4e6 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,6 @@ Name | Return type | Description --- | --- | --- `sendRom(rom, romSize, cancel, [mode])` | **LinkCableMultiboot::Result** | Sends the `rom`. During the handshake process, the library will continuously invoke `cancel`, and abort the transfer if it returns `true`. The `romSize` must be a number between `448` and `262144`, and a multiple of `16`. The `mode` can be either `LinkCableMultiboot::TransferMode::MULTI_PLAY` for GBA cable (default value) or `LinkCableMultiboot::TransferMode::SPI` for GBC cable. Once completed, the return value should be `LinkCableMultiboot::Result::SUCCESS`. -⚠️ for better results, turn on the GBAs **after** calling the `sendRom` method! - ⚠️ stop DMA before sending the ROM! _(you might need to stop your audio player)_ # 🔧👾 LinkRawCable diff --git a/lib/LinkCableMultiboot.hpp b/lib/LinkCableMultiboot.hpp index 950e245..ffb5560 100644 --- a/lib/LinkCableMultiboot.hpp +++ b/lib/LinkCableMultiboot.hpp @@ -20,7 +20,6 @@ // // `result` should be LinkCableMultiboot::Result::SUCCESS // -------------------------------------------------------------------------- // considerations: -// - for better results, turn on the GBAs after calling the `sendRom` method! // - stop DMA before sending the ROM! (you might need to stop your audio player) // -------------------------------------------------------------------------- @@ -57,7 +56,7 @@ class LinkCableMultiboot { static constexpr int MIN_ROM_SIZE = 0x100 + 0xc0; static constexpr int MAX_ROM_SIZE = 256 * 1024; static constexpr int FRAME_LINES = 228; - static constexpr int WAIT_BEFORE_RETRY = (FRAME_LINES * 60) / 16; + static constexpr int WAIT_BEFORE_RETRY = FRAME_LINES * 4; static constexpr int DETECTION_TRIES = 16; static constexpr int CLIENTS = 3; static constexpr int CLIENT_NO_DATA = 0xff; @@ -112,7 +111,9 @@ class LinkCableMultiboot { retry: deactivate(); - wait(WAIT_BEFORE_RETRY); + + // (*) instead of 1/16s, waiting a random number of frames works better + wait(WAIT_BEFORE_RETRY + FRAME_LINES * _qran_range(1, 30)); // 1. Prepare a "Multiboot Parameter Structure" in RAM. PartialResult partialResult = NEEDS_RETRY; @@ -153,6 +154,7 @@ class LinkCableMultiboot { LinkRawCable* linkRawCable = new LinkRawCable(); LinkSPI* linkSPI = new LinkSPI(); TransferMode _mode; + int randomSeed = 123; enum PartialResult { NEEDS_RETRY, FINISHED, ABORTED }; @@ -169,7 +171,7 @@ class LinkCableMultiboot { // 3. Send the word 0x6200 repeatedly until all detected clients respond // with 0x720X, where X is their client number (1-3). If they fail to do - // this after 16 tries, delay 1/16s and go back to step 2. + // this after 16 tries, delay 1/16s and go back to step 2. (*) bool success = false; for (u32 t = 0; t < DETECTION_TRIES; t++) { auto response = transfer(HANDSHAKE, cancel); @@ -366,6 +368,15 @@ class LinkCableMultiboot { } }; } + + int _qran() { + randomSeed = 1664525 * randomSeed + 1013904223; + return (randomSeed >> 16) & 0x7FFF; + } + + int _qran_range(int min, int max) { + return (_qran() * (max - min) >> 15) + min; + } }; extern LinkCableMultiboot* linkCableMultiboot;