Commit 559a6585 authored by Tim Allen's avatar Tim Allen

Update to v106r81 release.

byuu says:

First 32 instructions implemented in the TLCS900H disassembler. Only 992
to go!

I removed the use of anonymous namespaces in nall. It was something I
rarely used, because it rarely did what I wanted.

I updated all nested namespaces to use C++17-style namespace Foo::Bar {}
syntax instead of classic C++-style namespace Foo { namespace Bar {}}.

I updated ruby::Video::acquire() to return a struct, so we can use C++17
structured bindings. Long term, I want to get away from all functions
that take references for output only. Even though C++ botched structured
bindings by not allowing you to bind to existing variables, it's even
worse to have function calls that take arguments by reference and then
write to them. From the caller side, you can't tell the value is being
written, nor that the value passed in doesn't matter, which is terrible.
parent 25145f59
Pipeline #43501129 passed with stage
in 13 minutes and 15 seconds
......@@ -30,7 +30,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "106.80";
static const string Version = "106.81";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "https://byuu.org/";
......
auto TLCS900H::disassemble() -> string {
string output;
output.append(hex(r.pc.l.l0, 6L), " ");
output.append(disassembleInstruction());
output.size(-48);
output.append("I", r.iff);
output.append("R", r.rfp);
output.append(r.s ? "S" : "s");
output.append(r.z ? "Z" : "z");
output.append(r.h ? "H" : "h");
output.append(r.v ? "V" : "v");
output.append(r.n ? "N" : "n");
output.append(r.c ? "C" : "c");
return output;
}
auto TLCS900H::disassembleInstruction() -> string {
uint8 opcode[8] = {};
string opRegister;
string opSourceMemory;
string opTargetMemory;
auto pc = r.pc.l.l0;
auto fetch8n = [&]() -> uint8 {
return disassembleRead(pc++);
};
auto fetch16n = [&]() -> uint16 {
uint16 data = fetch8n() << 0;
return data | fetch8n() << 8;
};
auto fetch24n = [&]() -> uint24 {
uint24 data = fetch8n() << 0;
data |= fetch8n() << 8;
return data |= fetch8n() << 16;
};
auto fetch32n = [&]() -> uint32 {
uint32 data = fetch8n() << 0;
data |= fetch8n() << 8;
data |= fetch8n() << 16;
return data |= fetch8n() << 24;
};
auto fetch8i = [&]() -> int8 { return (int8)fetch8n(); };
auto fetch16i = [&]() -> int16 { return (int16)fetch16n(); };
auto direct16n = [&]() -> string {
return {"0x", hex(fetch16n(), 4L)};
};
auto direct24n = [&]() -> string {
return {"0x", hex(fetch24n(), 6L)};
};
auto displacement16i = [&]() -> string {
auto displacement = fetch16i();
if(displacement < 0) return {"-0x", hex(abs(displacement), 4L)};
return {"+0x", hex(displacement, 4L)};
};
auto displacementPC16i = [&]() -> string {
auto displacement = fetch16i();
return {"0x", hex(pc + displacement, 6L)};
};
auto immediate8n = [&]() -> string {
return {"#0x", hex(fetch8n(), 2L)};
};
auto immediate16n = [&]() -> string {
return {"#0x", hex(fetch16n(), 4L)};
};
auto indirect8n = [&]() -> string {
return {"(0x", hex(fetch8n(), 2L), ")"};
};
#define op(name, ...) return {pad(name, -6), vector<string>{__VA_ARGS__}.merge(",")}
#define bad() return {pad("???", -6), hex(opcode[0], 2L)}
switch(opcode[0] = fetch8n()) {
case 0x00: op("nop");
case 0x01: bad();
case 0x02: op("push", "sr");
case 0x03: op("pop", "sr");
case 0x04: bad();
case 0x05: op("halt");
case 0x06: {
uint3 immediate = fetch8n();
if(immediate == 7) op("di");
op("ei", {"#", immediate});
}
case 0x07: op("reti");
case 0x08: op("ld", indirect8n(), immediate8n());
case 0x09: op("push", immediate8n());
case 0x0a: op("ldw", indirect8n(), immediate16n());
case 0x0b: op("push", immediate16n());
case 0x0c: op("incf");
case 0x0d: op("decf");
case 0x0e: op("ret");
case 0x0f: op("retd", displacement16i());
case 0x10: op("rcf");
case 0x11: op("scf");
case 0x12: op("ccf");
case 0x13: op("zcf");
case 0x14: op("push", "a");
case 0x15: op("pop", "a");
case 0x16: op("ex", "f", "f'");
case 0x17: {
uint2 immediate = fetch8n();
op("ldf", {"#", immediate});
}
case 0x18: op("push", "f");
case 0x19: op("pop", "f");
case 0x1a: op("jp", direct16n());
case 0x1b: op("jp", direct24n());
case 0x1c: op("call", direct16n());
case 0x1d: op("call", direct24n());
case 0x1e: op("calr", displacementPC16i());
case 0x1f: bad();
default: bad();
}
#undef bad
#define bad() return {pad("???", -6), hex(opcode[0], 2L), " ", hex(opcode[1], 2L)}
if(opRegister) switch(opcode[1] = fetch8n()) {
default: bad();
}
#undef bad
#define bad() return {pad("???", -6), hex(opcode[0], 2L), " ", hex(opcode[1], 2L)}
if(opSourceMemory) switch(opcode[1] = fetch8n()) {
default: bad();
}
#undef bad
#define bad() return {pad("???", -6), hex(opcode[0], 2L), " ", hex(opcode[1], 2L)}
if(opTargetMemory) switch(opcode[1] = fetch8n()) {
default: bad();
}
#undef bad
#undef op
return {};
}
......@@ -23,6 +23,7 @@ namespace Processor {
#include "instruction.cpp"
#include "instructions.cpp"
#include "serialization.cpp"
#include "disassembler.cpp"
TLCS900H tlcs900h;
......
......@@ -262,6 +262,11 @@ struct TLCS900H {
static inline const uint4 True {0x08};
static inline const uint1 Undefined = 0;
//disassembler.cpp
virtual auto disassembleRead(uint24 address) -> uint8 { return rand(); }
auto disassemble() -> string;
auto disassembleInstruction() -> string;
};
}
......@@ -232,11 +232,9 @@ auto Presentation::clearViewport() -> void {
uint32_t opaqueBlack = 0xff000000;
if(settings.video.format == "RGB30") opaqueBlack = 0xc0000000;
uint32_t* output;
uint length;
uint width = 16;
uint height = 16;
if(video.acquire(output, length, width, height)) {
if(auto [output, length] = video.acquire(width, height); output) {
for(uint y : range(height)) {
auto line = output + y * (length >> 2);
for(uint x : range(width)) *line++ = opaqueBlack;
......
......@@ -208,9 +208,6 @@ auto Program::load(uint id, string name, string type, vector<string> options) ->
}
auto Program::videoFrame(const uint32* data, uint pitch, uint width, uint height) -> void {
uint32_t* output;
uint length;
//this relies on the UI only running between Emulator::Scheduler::Event::Frame events
//this will always be the case; so we can avoid an unnecessary copy or one-frame delay here
//if the core were to exit between a frame event, the next frame might've been only partially rendered
......@@ -225,7 +222,7 @@ auto Program::videoFrame(const uint32* data, uint pitch, uint width, uint height
if(height == 480) data += 16 * pitch, height -= 32;
}
if(video.acquire(output, length, width, height)) {
if(auto [output, length] = video.acquire(width, height); output) {
length >>= 2;
for(auto y : range(height)) {
......
......@@ -328,11 +328,9 @@ auto Presentation::clearViewport() -> void {
if(!emulator || !emulator->loaded()) viewportLayout.setPadding();
if(!visible() || !video) return;
uint32_t* output;
uint length = 0;
uint width = 16;
uint height = 16;
if(video->acquire(output, length, width, height)) {
if(auto [output, length] = video->acquire(width, height); output) {
for(uint y : range(height)) {
auto line = output + y * (length >> 2);
for(uint x : range(width)) *line++ = 0xff000000;
......
......@@ -51,9 +51,6 @@ auto Program::load(uint id, string name, string type, vector<string> options) ->
}
auto Program::videoFrame(const uint32* data, uint pitch, uint width, uint height) -> void {
uint32_t* output;
uint length;
pitch >>= 2;
if(!settings["View/Overscan"].boolean()) {
......@@ -69,7 +66,7 @@ auto Program::videoFrame(const uint32* data, uint pitch, uint width, uint height
}
}
if(video->acquire(output, length, width, height)) {
if(auto [output, length] = video->acquire(width, height); output) {
length >>= 2;
for(auto y : range(height)) {
......
......@@ -5,7 +5,7 @@
#undef min
#undef max
namespace nall { namespace {
namespace nall {
template<typename T, typename U> auto min(const T& t, const U& u) -> T {
return t < u ? t : (T)u;
......@@ -23,8 +23,4 @@ template<typename T, typename U, typename... P> auto max(const T& t, const U& u,
return t > u ? max(t, forward<P>(p)...) : max(u, forward<P>(p)...);
}
//template<typename T, typename U> auto ternary(bool test, const T& lhs, const U& rhs) -> T {
// return test ? lhs : (T)rhs;
//}
}}
}
......@@ -2,7 +2,7 @@
#include <nall/beat/archive/node.hpp>
namespace nall { namespace Beat { namespace Archive {
namespace nall::Beat::Archive {
struct Container {
Container(array_view<uint8_t> = {});
......@@ -197,4 +197,4 @@ auto Container::sort() -> void {
nodes.sort([&](auto& lhs, auto& rhs) { return string::icompare(lhs->name, rhs->name) < 0; });
}
}}}
}
......@@ -3,7 +3,7 @@
#include <nall/beat/archive/node.hpp>
#include <nall/beat/archive/container.hpp>
namespace nall { namespace Beat { namespace Archive {
namespace nall::Beat::Archive {
auto create(Container& container, string name) -> vector<uint8_t> {
auto& metadata = container.metadata;
......@@ -83,4 +83,4 @@ auto create(Container& container, string name) -> vector<uint8_t> {
return memory;
}
}}}
}
......@@ -3,7 +3,7 @@
#include <nall/beat/archive/node.hpp>
#include <nall/beat/archive/container.hpp>
namespace nall { namespace Beat { namespace Archive {
namespace nall::Beat::Archive {
auto extract(Container& container) -> bool {
function<void (Markup::Node)> extract = [&](auto metadata) {
......@@ -24,4 +24,4 @@ auto extract(Container& container) -> bool {
return true;
}
}}}
}
......@@ -10,7 +10,7 @@
#include <nall/decode/lzsa.hpp>
#include <nall/encode/lzsa.hpp>
namespace nall { namespace Beat { namespace Archive {
namespace nall::Beat::Archive {
struct Node {
static auto create(string name, string location) -> shared_pointer<Node>;
......@@ -329,4 +329,4 @@ auto Node::getGroup() const -> string {
return permission.group.name;
}
}}}
}
#pragma once
namespace nall { namespace Beat { namespace Single {
namespace nall::Beat::Single {
inline auto apply(array_view<uint8_t> source, array_view<uint8_t> beat, maybe<string&> manifest = {}, maybe<string&> result = {}) -> maybe<vector<uint8_t>> {
#define error(text) { if(result) *result = {"error: ", text}; return {}; }
......@@ -85,4 +85,4 @@ inline auto apply(array_view<uint8_t> source, array_view<uint8_t> beat, maybe<st
#undef success
}
}}}
}
......@@ -2,7 +2,7 @@
#include <nall/suffix-array.hpp>
namespace nall { namespace Beat { namespace Single {
namespace nall::Beat::Single {
inline auto create(array_view<uint8_t> source, array_view<uint8_t> target, string_view manifest = {}) -> vector<uint8_t> {
vector<uint8_t> beat;
......@@ -93,4 +93,4 @@ inline auto create(array_view<uint8_t> source, array_view<uint8_t> target, strin
return beat;
}
}}}
}
......@@ -3,21 +3,21 @@
#include <nall/function.hpp>
#include <nall/string.hpp>
namespace nall { namespace chrono { namespace {
namespace nall::chrono {
//passage of time functions (from unknown epoch)
auto nanosecond() -> uint64_t {
inline auto nanosecond() -> uint64_t {
timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
return tv.tv_sec * 1'000'000'000 + tv.tv_nsec;
}
auto microsecond() -> uint64_t { return nanosecond() / 1'000; }
auto millisecond() -> uint64_t { return nanosecond() / 1'000'000; }
auto second() -> uint64_t { return nanosecond() / 1'000'000'000; }
inline auto microsecond() -> uint64_t { return nanosecond() / 1'000; }
inline auto millisecond() -> uint64_t { return nanosecond() / 1'000'000; }
inline auto second() -> uint64_t { return nanosecond() / 1'000'000'000; }
auto benchmark(const function<void ()>& f, uint64_t times = 1) -> void {
inline auto benchmark(const function<void ()>& f, uint64_t times = 1) -> void {
auto start = nanosecond();
while(times--) f();
auto end = nanosecond();
......@@ -34,7 +34,7 @@ struct timeinfo {
hour(hour), minute(minute), second(second), weekday(weekday) {
}
explicit operator bool() const { return month; }
inline explicit operator bool() const { return month; }
uint year; //...
uint month; //1 - 12
......@@ -45,12 +45,12 @@ struct timeinfo {
uint weekday; //0 - 6
};
auto timestamp() -> uint64_t {
inline auto timestamp() -> uint64_t {
return ::time(nullptr);
}
namespace utc {
auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
inline auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
auto stamp = time ? (time_t)time : (time_t)timestamp();
auto info = gmtime(&stamp);
return {
......@@ -64,24 +64,24 @@ namespace utc {
};
}
auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
inline auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
inline auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
inline auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
inline auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
inline auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
inline auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
auto date(uint64_t timestamp = 0) -> string {
inline auto date(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
}
auto time(uint64_t timestamp = 0) -> string {
inline auto time(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
}
auto datetime(uint64_t timestamp = 0) -> string {
inline auto datetime(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {
pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
......@@ -91,7 +91,7 @@ namespace utc {
}
namespace local {
auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
inline auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
auto stamp = time ? (time_t)time : (time_t)timestamp();
auto info = localtime(&stamp);
return {
......@@ -105,24 +105,24 @@ namespace local {
};
}
auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
inline auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
inline auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
inline auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
inline auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
inline auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
inline auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
auto date(uint64_t timestamp = 0) -> string {
inline auto date(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
}
auto time(uint64_t timestamp = 0) -> string {
inline auto time(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
}
auto datetime(uint64_t timestamp = 0) -> string {
inline auto datetime(uint64_t timestamp = 0) -> string {
auto t = timeinfo(timestamp);
return {
pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
......@@ -131,4 +131,4 @@ namespace local {
}
}
}}}
}
......@@ -3,7 +3,7 @@
#include <nall/arithmetic.hpp>
#include <nall/array-view.hpp>
namespace nall { namespace Cipher {
namespace nall::Cipher {
//64-bit nonce; 64-bit x 64-byte (256GB) counter
struct ChaCha20 {
......@@ -106,4 +106,4 @@ struct XChaCha20 : ChaCha20 {
}
};
}}
}
#pragma once
//legacy code; no longer used
#include <nall/string.hpp>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
namespace nall { namespace Database {
namespace nall::Database {
struct ODBC {
struct Statement {
......@@ -294,4 +296,4 @@ private:
SQLRETURN _result = SQL_SUCCESS;
};
}}
}
......@@ -10,7 +10,7 @@
#include <nall/stdint.hpp>
#include <nall/string.hpp>
namespace nall { namespace Database {
namespace nall::Database {
struct SQLite3 {
struct Statement {
......@@ -200,4 +200,4 @@ protected:
sqlite3* _database = nullptr;
};
}}
}
......@@ -2,7 +2,7 @@
#include <nall/arithmetic.hpp>
namespace nall { namespace Decode {
namespace nall::Decode {
template<uint Bits, typename T> inline auto Base(const string& value) -> T {
static const string format =
......@@ -34,4 +34,4 @@ template<uint Bits, typename T> inline auto Base(const string& value) -> T {
return result;
}
}}
}
#pragma once
namespace nall { namespace Decode {
namespace nall::Decode {
inline auto Base64(const string& text) -> vector<uint8_t> {
static bool initialized = false;
......@@ -44,4 +44,4 @@ inline auto Base64(const string& text) -> vector<uint8_t> {
return result;
}
}}
}
#pragma once
namespace nall { namespace Decode {
namespace nall