mirror of https://github.com/AxioDL/jbus.git
Add Doxygen comments
This commit is contained in:
parent
a3fe0a3a25
commit
4699542f93
|
@ -0,0 +1,9 @@
|
||||||
|
JBus Documentation {#mainpage}
|
||||||
|
==============================
|
||||||
|
|
||||||
|
JBus functions as a server for acceping connections from GBA emulator clients.
|
||||||
|
The jbus::Listener class may be constructed and [started](@ref jbus::Listener::start)
|
||||||
|
to enque incoming jbus::Endpoint instances.
|
||||||
|
|
||||||
|
Once an Endpoint has been [accepted](@ref jbus::Listener::accept), it's ready to use.
|
||||||
|
Refer to the jbus::Endpoint class for the main interface.
|
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016-2017 JBus Contributors
|
||||||
|
Original Authors: Jack Andersen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
11
README.md
11
README.md
|
@ -1,8 +1,17 @@
|
||||||
## JBus
|
## JBus
|
||||||
|
|
||||||
This is a library for communicating with emulated GameBoy Advance instances
|
This is a library for communicating with emulated GameBoy Advance instances
|
||||||
using the JoyBus protocol, linked over TCP.
|
using the JoyBus protocol linked over TCP.
|
||||||
|
|
||||||
Currently, only [VBA-M](https://github.com/visualboyadvance-m/visualboyadvance-m)
|
Currently, only [VBA-M](https://github.com/visualboyadvance-m/visualboyadvance-m)
|
||||||
is known to function. It uses the same networking method as the
|
is known to function. It uses the same networking method as the
|
||||||
[Dolphin](https://github.com/dolphin-emu/dolphin) GameCube emulator.
|
[Dolphin](https://github.com/dolphin-emu/dolphin) GameCube emulator.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
[Doxygen docs are available!](http://axiodl.github.io/jbus)
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
[Refer to the `joyboot.cpp`](https://github.com/AxioDL/jbus/blob/master/tools/joyboot.cpp)
|
||||||
|
implementation for a good usage example.
|
||||||
|
|
|
@ -17,6 +17,8 @@ using u32 = uint32_t;
|
||||||
using s64 = int64_t;
|
using s64 = int64_t;
|
||||||
using u64 = uint64_t;
|
using u64 = uint64_t;
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
#undef bswap16
|
#undef bswap16
|
||||||
#undef bswap32
|
#undef bswap32
|
||||||
#undef bswap64
|
#undef bswap64
|
||||||
|
@ -139,6 +141,8 @@ static inline double SBig(double val) {return val;}
|
||||||
class Endpoint;
|
class Endpoint;
|
||||||
class ThreadLocalEndpoint;
|
class ThreadLocalEndpoint;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
enum EJStatFlags
|
enum EJStatFlags
|
||||||
{
|
{
|
||||||
GBA_JSTAT_MASK = 0x3a,
|
GBA_JSTAT_MASK = 0x3a,
|
||||||
|
@ -159,11 +163,24 @@ enum EJoyReturn
|
||||||
GBA_JOYBOOT_ERR_INVALID = 4
|
GBA_JOYBOOT_ERR_INVALID = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @brief Standard callback for asynchronous jbus::Endpoint APIs.
|
||||||
|
* @param endpoint Thread-local Endpoint interface for optionally issuing next command in sequence.
|
||||||
|
* @param status GBA_READY if connection is still open, GBA_NOT_READY if connection lost. */
|
||||||
using FGBACallback = std::function<void(ThreadLocalEndpoint& endpoint, EJoyReturn status)>;
|
using FGBACallback = std::function<void(ThreadLocalEndpoint& endpoint, EJoyReturn status)>;
|
||||||
|
|
||||||
|
/** @brief Get host system's timebase scaled into Dolphin ticks.
|
||||||
|
* @return Scaled ticks from host timebase. */
|
||||||
u64 GetGCTicks();
|
u64 GetGCTicks();
|
||||||
|
|
||||||
|
/** @brief Wait an approximate Dolphin tick duration (avoid using, it's rather inaccurate).
|
||||||
|
* @param ticks CPU ticks to wait. */
|
||||||
void WaitGCTicks(u64 ticks);
|
void WaitGCTicks(u64 ticks);
|
||||||
|
|
||||||
|
/** @brief Obtain CPU ticks per second of Dolphin hardware (clock speed).
|
||||||
|
* @return 486Mhz - always. */
|
||||||
static constexpr u64 GetGCTicksPerSec() { return 486000000ull; }
|
static constexpr u64 GetGCTicksPerSec() { return 486000000ull; }
|
||||||
|
|
||||||
|
/** @brief Initialize platform specifics of JBus library */
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,18 @@
|
||||||
namespace jbus
|
namespace jbus
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Self-contained class for solving Kawasedo's GBA BootROM challenge.
|
/** Main class for performing JoyBoot and subsequent JoyBus I/O operations.
|
||||||
* GBA will boot client_pad.bin code on completion. */
|
* Instances should be obtained though the jbus::Listener::accept method. */
|
||||||
class KawasedoChallenge
|
class Endpoint
|
||||||
{
|
{
|
||||||
|
/** Self-contained class for solving Kawasedo's GBA BootROM challenge.
|
||||||
|
* GBA will boot client_pad.bin code on completion.
|
||||||
|
*
|
||||||
|
* This class shouldn't be used directly. JoyBoot operations are started
|
||||||
|
* via jbus::Endpoint::GBAJoyBootAsync. The JoyBoot status may be obtained
|
||||||
|
* via jbus::Endpoint::GBAGetProcessStatus. */
|
||||||
|
class KawasedoChallenge
|
||||||
|
{
|
||||||
/** DSP-hosted public-key unwrap and initial message crypt
|
/** DSP-hosted public-key unwrap and initial message crypt
|
||||||
* Reference: https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp */
|
* Reference: https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp */
|
||||||
struct DSPSecParms
|
struct DSPSecParms
|
||||||
|
@ -73,7 +81,7 @@ class KawasedoChallenge
|
||||||
|
|
||||||
s32 x0_pColor;
|
s32 x0_pColor;
|
||||||
s32 x4_pSpeed;
|
s32 x4_pSpeed;
|
||||||
u8* x8_progPtr;
|
const u8* x8_progPtr;
|
||||||
u32 xc_progLen;
|
u32 xc_progLen;
|
||||||
u8* x10_statusPtr;
|
u8* x10_statusPtr;
|
||||||
FGBACallback x14_callback;
|
FGBACallback x14_callback;
|
||||||
|
@ -91,26 +99,26 @@ class KawasedoChallenge
|
||||||
u32 x64_totalBytes;
|
u32 x64_totalBytes;
|
||||||
bool m_started = true;
|
bool m_started = true;
|
||||||
|
|
||||||
void F23(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _0Reset(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F25(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _1GetStatus(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F27(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _2ReadChallenge(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F29(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _3DSPCrypto(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void GBAX02();
|
void _DSPCryptoInit();
|
||||||
void GBAX01(ThreadLocalEndpoint& endpoint);
|
void _DSPCryptoDone(ThreadLocalEndpoint& endpoint);
|
||||||
void F31(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _4TransmitProgram(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F33(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _5StartBootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F35(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _6BootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F37(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _7BootAcknowledge(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
void F39(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
void _8BootDone(ThreadLocalEndpoint& endpoint, EJoyReturn status);
|
||||||
|
|
||||||
auto bindThis(void(KawasedoChallenge::*ptmf)(ThreadLocalEndpoint&, EJoyReturn))
|
auto bindThis(void(KawasedoChallenge::*ptmf)(ThreadLocalEndpoint&, EJoyReturn))
|
||||||
{
|
{
|
||||||
return std::bind(ptmf, this, std::placeholders::_1, std::placeholders::_2);
|
return std::bind(ptmf, this, std::placeholders::_1, std::placeholders::_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
|
KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
|
||||||
u8* programp, s32 length, u8* status, FGBACallback&& callback);
|
const u8* programp, s32 length, u8* status, FGBACallback&& callback);
|
||||||
bool started() const { return m_started; }
|
bool started() const { return m_started; }
|
||||||
u8 percentComplete() const
|
u8 percentComplete() const
|
||||||
{
|
{
|
||||||
|
@ -119,10 +127,8 @@ public:
|
||||||
return x34_bytesSent * 100 / x64_totalBytes;
|
return x34_bytesSent * 100 / x64_totalBytes;
|
||||||
}
|
}
|
||||||
bool isDone() const { return !x14_callback; }
|
bool isDone() const { return !x14_callback; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Endpoint
|
|
||||||
{
|
|
||||||
friend class ThreadLocalEndpoint;
|
friend class ThreadLocalEndpoint;
|
||||||
|
|
||||||
enum EJoybusCmds
|
enum EJoybusCmds
|
||||||
|
@ -154,7 +160,6 @@ class Endpoint
|
||||||
bool m_cmdIssued = false;
|
bool m_cmdIssued = false;
|
||||||
bool m_running = true;
|
bool m_running = true;
|
||||||
|
|
||||||
static u64 getTransferTime(u8 cmd);
|
|
||||||
void clockSync();
|
void clockSync();
|
||||||
void send(const u8* buffer);
|
void send(const u8* buffer);
|
||||||
size_t receive(u8* buffer);
|
size_t receive(u8* buffer);
|
||||||
|
@ -170,34 +175,122 @@ class Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** @brief Request stop of I/O thread and block until joined.
|
||||||
|
* Further use of this Endpoint is undefined behavior.
|
||||||
|
* The destructor calls this implicitly. */
|
||||||
void stop();
|
void stop();
|
||||||
EJoyReturn GBAGetProcessStatus(u8* percentp);
|
|
||||||
|
/** @brief Get status of last asynchronous operation.
|
||||||
|
* @param percentOut Reference to output transfer percent of GBAJoyBootAsync.
|
||||||
|
* @return GBA_READY when idle, or GBA_BUSY when operation in progress. */
|
||||||
|
EJoyReturn GBAGetProcessStatus(u8& percentOut);
|
||||||
|
|
||||||
|
/** @brief Get JOYSTAT register from GBA asynchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAGetStatusAsync(u8* status, FGBACallback&& callback);
|
EJoyReturn GBAGetStatusAsync(u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Get JOYSTAT register from GBA synchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAGetStatus(u8* status);
|
EJoyReturn GBAGetStatus(u8* status);
|
||||||
|
|
||||||
|
/** @brief Send RESET command to GBA asynchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAResetAsync(u8* status, FGBACallback&& callback);
|
EJoyReturn GBAResetAsync(u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send RESET command to GBA synchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAReset(u8* status);
|
EJoyReturn GBAReset(u8* status);
|
||||||
|
|
||||||
|
/** @brief Send READ command to GBA asynchronously.
|
||||||
|
* @param dst Destination pointer for 4-byte packet of data.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback);
|
EJoyReturn GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send READ command to GBA synchronously.
|
||||||
|
* @param dst Destination pointer for 4-byte packet of data.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBARead(u8* dst, u8* status);
|
EJoyReturn GBARead(u8* dst, u8* status);
|
||||||
|
|
||||||
|
/** @brief Send WRITE command to GBA asynchronously.
|
||||||
|
* @param src Source pointer for 4-byte packet of data. It is not required to keep resident.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback);
|
EJoyReturn GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send WRITE command to GBA synchronously.
|
||||||
|
* @param src Source pointer for 4-byte packet of data. It is not required to keep resident.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAWrite(const u8* src, u8* status);
|
EJoyReturn GBAWrite(const u8* src, u8* status);
|
||||||
|
|
||||||
|
/** @brief Initiate JoyBoot sequence on this endpoint.
|
||||||
|
* @param paletteColor Palette for displaying logo in ROM header [0,6].
|
||||||
|
* @param paletteSpeed Palette interpolation speed for displaying logo in ROM header [-4,4].
|
||||||
|
* @param programp Pointer to program ROM data.
|
||||||
|
* @param length Length of program ROM data.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed,
|
EJoyReturn GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed,
|
||||||
u8* programp, s32 length, u8* status,
|
const u8* programp, s32 length, u8* status,
|
||||||
FGBACallback&& callback);
|
FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Get virtual SI channel assigned to this endpoint.
|
||||||
|
* @return SI channel */
|
||||||
int GetChan() const { return m_chan; }
|
int GetChan() const { return m_chan; }
|
||||||
|
|
||||||
Endpoint(u8 chan, net::Socket&& data, net::Socket&& clock);
|
Endpoint(u8 chan, net::Socket&& data, net::Socket&& clock);
|
||||||
~Endpoint();
|
~Endpoint();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Lockless wrapper interface for jbus::Endpoint.
|
||||||
|
* This class is constructed internally and supplied as a callback argument.
|
||||||
|
* It should not be constructed directly. */
|
||||||
class ThreadLocalEndpoint
|
class ThreadLocalEndpoint
|
||||||
{
|
{
|
||||||
friend class Endpoint;
|
friend class Endpoint;
|
||||||
Endpoint& m_ep;
|
Endpoint& m_ep;
|
||||||
ThreadLocalEndpoint(Endpoint& ep) : m_ep(ep) {}
|
ThreadLocalEndpoint(Endpoint& ep) : m_ep(ep) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** @brief Get JOYSTAT register from GBA asynchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAGetStatusAsync(u8* status, FGBACallback&& callback);
|
EJoyReturn GBAGetStatusAsync(u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send RESET command to GBA asynchronously.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAResetAsync(u8* status, FGBACallback&& callback);
|
EJoyReturn GBAResetAsync(u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send READ command to GBA asynchronously.
|
||||||
|
* @param dst Destination pointer for 4-byte packet of data.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback);
|
EJoyReturn GBAReadAsync(u8* dst, u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Send WRITE command to GBA asynchronously.
|
||||||
|
* @param src Source pointer for 4-byte packet of data. It is not required to keep resident.
|
||||||
|
* @param status Destination pointer for EJStatFlags.
|
||||||
|
* @param callback Functor to execute when operation completes.
|
||||||
|
* @return GBA_READY if submitted, or GBA_NOT_READY if another operation in progress. */
|
||||||
EJoyReturn GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback);
|
EJoyReturn GBAWriteAsync(const u8* src, u8* status, FGBACallback&& callback);
|
||||||
|
|
||||||
|
/** @brief Get virtual SI channel assigned to this endpoint.
|
||||||
|
* @return SI channel */
|
||||||
int GetChan() const { return m_ep.GetChan(); }
|
int GetChan() const { return m_ep.GetChan(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
namespace jbus
|
namespace jbus
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** Server interface for accepting incoming connections from GBA emulator instances. */
|
||||||
class Listener
|
class Listener
|
||||||
{
|
{
|
||||||
net::Socket m_dataServer = {false};
|
net::Socket m_dataServer = {false};
|
||||||
|
@ -25,9 +26,16 @@ class Listener
|
||||||
void listenerProc();
|
void listenerProc();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** @brief Start listener thread. */
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
/** @brief Request stop of listener thread and block until joined. */
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
/** @brief Pop jbus::Endpoint off Listener's queue.
|
||||||
|
* @return Endpoint instance, ready to issue commands. */
|
||||||
std::unique_ptr<Endpoint> accept();
|
std::unique_ptr<Endpoint> accept();
|
||||||
|
|
||||||
~Listener();
|
~Listener();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
namespace jbus
|
namespace jbus
|
||||||
{
|
{
|
||||||
|
|
||||||
void KawasedoChallenge::F23(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_0Reset(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status != GBA_READY ||
|
if (status != GBA_READY ||
|
||||||
(status = endpoint.GBAResetAsync(x10_statusPtr,
|
(status = endpoint.GBAResetAsync(x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F25))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_1GetStatus))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -20,7 +20,7 @@ void KawasedoChallenge::F23(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_1GetStatus(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status == GBA_READY)
|
if (status == GBA_READY)
|
||||||
if (*x10_statusPtr != GBA_JSTAT_SEND)
|
if (*x10_statusPtr != GBA_JSTAT_SEND)
|
||||||
|
@ -28,7 +28,7 @@ void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
|
|
||||||
if (status != GBA_READY ||
|
if (status != GBA_READY ||
|
||||||
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F27))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_2ReadChallenge))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -39,7 +39,7 @@ void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_2ReadChallenge(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status == GBA_READY)
|
if (status == GBA_READY)
|
||||||
if (*x10_statusPtr != (GBA_JSTAT_PSF0 | GBA_JSTAT_SEND))
|
if (*x10_statusPtr != (GBA_JSTAT_PSF0 | GBA_JSTAT_SEND))
|
||||||
|
@ -47,7 +47,7 @@ void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
|
|
||||||
if (status != GBA_READY ||
|
if (status != GBA_READY ||
|
||||||
(status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
(status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F29))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_3DSPCrypto))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -58,7 +58,7 @@ void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F29(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_3DSPCrypto(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status != GBA_READY)
|
if (status != GBA_READY)
|
||||||
{
|
{
|
||||||
|
@ -71,12 +71,12 @@ void KawasedoChallenge::F29(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GBAX02();
|
_DSPCryptoInit();
|
||||||
GBAX01(endpoint);
|
_DSPCryptoDone(endpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::GBAX02()
|
void Endpoint::KawasedoChallenge::_DSPCryptoInit()
|
||||||
{
|
{
|
||||||
xf8_dspHmac.x0_gbaChallenge = reinterpret_cast<u32&>(x18_readBuf);
|
xf8_dspHmac.x0_gbaChallenge = reinterpret_cast<u32&>(x18_readBuf);
|
||||||
xf8_dspHmac.x4_logoPalette = x0_pColor;
|
xf8_dspHmac.x4_logoPalette = x0_pColor;
|
||||||
|
@ -85,7 +85,7 @@ void KawasedoChallenge::GBAX02()
|
||||||
xf8_dspHmac.ProcessGBACrypto();
|
xf8_dspHmac.ProcessGBACrypto();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
|
void Endpoint::KawasedoChallenge::_DSPCryptoDone(ThreadLocalEndpoint& endpoint)
|
||||||
{
|
{
|
||||||
x58_currentKey = xf8_dspHmac.x20_publicKey;
|
x58_currentKey = xf8_dspHmac.x20_publicKey;
|
||||||
x5c_initMessage = xf8_dspHmac.x24_authInitCode;
|
x5c_initMessage = xf8_dspHmac.x24_authInitCode;
|
||||||
|
@ -107,7 +107,7 @@ void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
|
||||||
|
|
||||||
EJoyReturn status;
|
EJoyReturn status;
|
||||||
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
|
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F31))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_4TransmitProgram))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -118,7 +118,7 @@ void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_4TransmitProgram(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status != GBA_READY)
|
if (status != GBA_READY)
|
||||||
{
|
{
|
||||||
|
@ -240,7 +240,7 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
|
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F31))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_4TransmitProgram))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -253,7 +253,7 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
else // x34_bytesWritten > x64_totalBytes
|
else // x34_bytesWritten > x64_totalBytes
|
||||||
{
|
{
|
||||||
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F33))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_5StartBootPoll))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -265,11 +265,11 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F33(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_5StartBootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status != GBA_READY ||
|
if (status != GBA_READY ||
|
||||||
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F35))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_6BootPoll))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -280,7 +280,7 @@ void KawasedoChallenge::F33(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_6BootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status == GBA_READY)
|
if (status == GBA_READY)
|
||||||
if (*x10_statusPtr & (GBA_JSTAT_FLAGS_MASK | GBA_JSTAT_RECV))
|
if (*x10_statusPtr & (GBA_JSTAT_FLAGS_MASK | GBA_JSTAT_RECV))
|
||||||
|
@ -300,7 +300,7 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
if (*x10_statusPtr != GBA_JSTAT_SEND)
|
if (*x10_statusPtr != GBA_JSTAT_SEND)
|
||||||
{
|
{
|
||||||
if ((status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
if ((status = endpoint.GBAGetStatusAsync(x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F35))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_6BootPoll))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -313,7 +313,7 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F37))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_7BootAcknowledge))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -324,11 +324,11 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F37(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_7BootAcknowledge(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status != GBA_READY ||
|
if (status != GBA_READY ||
|
||||||
(status = endpoint.GBAWriteAsync(x18_readBuf, x10_statusPtr,
|
(status = endpoint.GBAWriteAsync(x18_readBuf, x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F39))) != GBA_READY)
|
bindThis(&KawasedoChallenge::_8BootDone))) != GBA_READY)
|
||||||
{
|
{
|
||||||
x28_ticksAfterXf = 0;
|
x28_ticksAfterXf = 0;
|
||||||
if (x14_callback)
|
if (x14_callback)
|
||||||
|
@ -339,7 +339,7 @@ void KawasedoChallenge::F37(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KawasedoChallenge::F39(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
void Endpoint::KawasedoChallenge::_8BootDone(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
{
|
{
|
||||||
if (status == GBA_READY)
|
if (status == GBA_READY)
|
||||||
*x10_statusPtr = 0;
|
*x10_statusPtr = 0;
|
||||||
|
@ -353,50 +353,19 @@ void KawasedoChallenge::F39(ThreadLocalEndpoint& endpoint, EJoyReturn status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KawasedoChallenge::KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
|
Endpoint::KawasedoChallenge::KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
|
||||||
u8* programp, s32 length, u8* status, FGBACallback&& callback)
|
const u8* programp, s32 length, u8* status, FGBACallback&& callback)
|
||||||
: x0_pColor(paletteColor), x4_pSpeed(paletteSpeed), x8_progPtr(programp), xc_progLen(length),
|
: x0_pColor(paletteColor), x4_pSpeed(paletteSpeed), x8_progPtr(programp), xc_progLen(length),
|
||||||
x10_statusPtr(status), x14_callback(std::move(callback)), x34_bytesSent(0)
|
x10_statusPtr(status), x14_callback(std::move(callback)), x34_bytesSent(0)
|
||||||
{
|
{
|
||||||
if (endpoint.GBAGetStatusAsync(x10_statusPtr,
|
if (endpoint.GBAGetStatusAsync(x10_statusPtr,
|
||||||
bindThis(&KawasedoChallenge::F23)) != GBA_READY)
|
bindThis(&KawasedoChallenge::_0Reset)) != GBA_READY)
|
||||||
{
|
{
|
||||||
x14_callback = {};
|
x14_callback = {};
|
||||||
m_started = false;
|
m_started = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Endpoint::getTransferTime(u8 cmd)
|
|
||||||
{
|
|
||||||
u64 bytes = 0;
|
|
||||||
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case CMD_RESET:
|
|
||||||
case CMD_STATUS:
|
|
||||||
{
|
|
||||||
bytes = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CMD_READ:
|
|
||||||
{
|
|
||||||
bytes = 6;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CMD_WRITE:
|
|
||||||
{
|
|
||||||
bytes = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
bytes = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bytes * GetGCTicksPerSec() / BYTES_PER_SECOND;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Endpoint::clockSync()
|
void Endpoint::clockSync()
|
||||||
{
|
{
|
||||||
if (!m_clockSocket)
|
if (!m_clockSocket)
|
||||||
|
@ -598,12 +567,12 @@ void Endpoint::stop()
|
||||||
m_transferThread.join();
|
m_transferThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
EJoyReturn Endpoint::GBAGetProcessStatus(u8* percentp)
|
EJoyReturn Endpoint::GBAGetProcessStatus(u8& percentOut)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_syncLock);
|
std::unique_lock<std::mutex> lk(m_syncLock);
|
||||||
if (m_joyBoot)
|
if (m_joyBoot)
|
||||||
{
|
{
|
||||||
*percentp = m_joyBoot->percentComplete();
|
percentOut = m_joyBoot->percentComplete();
|
||||||
if (!m_joyBoot->isDone())
|
if (!m_joyBoot->isDone())
|
||||||
return GBA_BUSY;
|
return GBA_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -753,7 +722,7 @@ EJoyReturn Endpoint::GBAWrite(const u8* src, u8* status)
|
||||||
}
|
}
|
||||||
|
|
||||||
EJoyReturn Endpoint::GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed,
|
EJoyReturn Endpoint::GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed,
|
||||||
u8* programp, s32 length, u8* status,
|
const u8* programp, s32 length, u8* status,
|
||||||
FGBACallback&& callback)
|
FGBACallback&& callback)
|
||||||
{
|
{
|
||||||
if (m_chan > 3)
|
if (m_chan > 3)
|
||||||
|
|
|
@ -95,7 +95,7 @@ int main(int argc, char** argv)
|
||||||
jbus::s64 start = jbus::GetGCTicks();
|
jbus::s64 start = jbus::GetGCTicks();
|
||||||
jbus::u8 percent = 0;
|
jbus::u8 percent = 0;
|
||||||
jbus::u8 lastpercent = 0;
|
jbus::u8 lastpercent = 0;
|
||||||
while (endpoint->GBAGetProcessStatus(&percent) == jbus::GBA_BUSY)
|
while (endpoint->GBAGetProcessStatus(percent) == jbus::GBA_BUSY)
|
||||||
{
|
{
|
||||||
if (percent != lastpercent)
|
if (percent != lastpercent)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue