Myles Busig 67f16364ec Change debug::puts to use raw char* and copy
In order to handle the self-assign case, string::operator= moves the
string, which may copy the string in reverse. The MGBA string register
does not allow this I believe. In order to avoid this, it now uses a raw
character buffer and is copied using string_view::copy.
string_view::copy will always copy the string forward.
2024-03-07 15:58:51 -07:00

57 lines
1.3 KiB
C++

#include "debug.hpp"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <tonc.h>
#include <mtl/string.hpp>
#include <mtl/string_view.hpp>
namespace debug {
/**
* \brief MGBA debug registers and constants
*/
namespace reg {
/**
* \brief MGBA debug enable register.
*
* When 0xC0DE is written to the register, debug output is enabled.
* When 0 is written to the register, debug output is disabled.
* Will be set to 0x1DEA when successfully enabled.
*/
static volatile uint16_t& enable = *reinterpret_cast<uint16_t*>(0x4FFF780);
/**
* \brief MGBA debug flags register.
*/
static volatile uint16_t& flags = *reinterpret_cast<uint16_t*>(0x4FFF700);
/**
* \brief MGBA debug string register.
*
* Max length of 0x100 (256) including null terminator.
*/
static char* string = reinterpret_cast<char*>(0x4FFF600);
constexpr static size_t string_len = 255;
}; // namespace reg
void puts(const mtl::string_view& msg, level lvl) {
size_t count = msg.length();
if (count > reg::string_len) { count = reg::string_len; }
// Must be copied manually because the MGBA string register does
// not allow copying in reverse (I think)
msg.copy(reg::string, count);
reg::flags = lvl | 0x100;
}
bool open() {
reg::enable = 0xC0DE;
return reg::enable == 0x1DEA;
}
void close() {
reg::enable = 0;
}
}; // namespace debug