Merge branch 'master' of github.com:gtalent/nostalgia

This commit is contained in:
Gary Talent 2020-02-15 11:53:52 -06:00
commit 0abc07e31b
32 changed files with 237 additions and 140 deletions

View File

@ -5,14 +5,13 @@ project(nostalgia)
set(NOSTALGIA_BUILD_TYPE "Native" CACHE STRING "The type of build to produce(Native/GBA)") set(NOSTALGIA_BUILD_TYPE "Native" CACHE STRING "The type of build to produce(Native/GBA)")
set(NOSTALGIA_IDE_BUILD ON CACHE STRING "Build for IDE's to run") set(NOSTALGIA_IDE_BUILD ON CACHE STRING "Build for IDE's to run")
set(NOSTALGIA_QT_PATH "" CACHE STRING "Path to Qt Libraries") set(NOSTALGIA_QT_PATH "" CACHE STRING "Path to Qt Libraries")
set(NOSTALGIA_BUILD_STUDIO ON CACHE STRING "Build Studio") set(NOSTALGIA_BUILD_STUDIO ON CACHE BOOL "Build Studio")
if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
set(NOSTALGIA_BUILD_STUDIO OFF) set(NOSTALGIA_BUILD_STUDIO OFF)
set(OX_BARE_METAL ON) set(OX_BARE_METAL ON)
set(OX_USE_STDLIB OFF) set(OX_USE_STDLIB OFF)
else() else()
set(NOSTALGIA_BUILD_STUDIO ON)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${NOSTALGIA_QT_PATH}) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${NOSTALGIA_QT_PATH})
endif() endif()

1
Jenkinsfile vendored
View File

@ -3,6 +3,7 @@ pipeline {
stages { stages {
stage('Build') { stage('Build') {
steps { steps {
sh 'make conan'
sh 'make configure-debug configure-release' sh 'make configure-debug configure-release'
sh 'make' sh 'make'
} }

View File

@ -1,3 +1,10 @@
/*
* Copyright 2016 - 2020 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic" #pragma GCC diagnostic ignored "-Wpedantic"
@ -7,6 +14,13 @@ extern void (*__preinit_array_end[]) (void);
extern void (*__init_array_start[]) (void); extern void (*__init_array_start[]) (void);
extern void (*__init_array_end[]) (void); extern void (*__init_array_end[]) (void);
namespace nostalgia::core {
void initHeap();
}
extern "C" { extern "C" {
void __libc_init_array() { void __libc_init_array() {
@ -24,6 +38,7 @@ int main(int argc, const char **argv);
int c_start() { int c_start() {
const char *args[2] = {"", "rom.oxfs"}; const char *args[2] = {"", "rom.oxfs"};
nostalgia::core::initHeap();
return main(2, args); return main(2, args);
} }

View File

@ -122,7 +122,7 @@ class FileStoreTemplate {
[[nodiscard]] InodeId_t available(); [[nodiscard]] InodeId_t available();
[[nodiscard]] uint8_t *buff(); [[nodiscard]] char *buff();
[[nodiscard]] Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t)); [[nodiscard]] Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t));
@ -464,8 +464,8 @@ typename FileStoreTemplate<size_t>::InodeId_t FileStoreTemplate<size_t>::availab
} }
template<typename size_t> template<typename size_t>
uint8_t *FileStoreTemplate<size_t>::buff() { char *FileStoreTemplate<size_t>::buff() {
return reinterpret_cast<uint8_t*>(m_buffer); return reinterpret_cast<char*>(m_buffer);
} }
template<typename size_t> template<typename size_t>

View File

@ -70,7 +70,7 @@ class FileSystem {
[[nodiscard]] virtual uint64_t size() const = 0; [[nodiscard]] virtual uint64_t size() const = 0;
[[nodiscard]] virtual uint8_t *buff() = 0; [[nodiscard]] virtual char *buff() = 0;
[[nodiscard]] virtual ox::Error walk(ox::Error(*cb)(uint8_t, uint64_t, uint64_t)) = 0; [[nodiscard]] virtual ox::Error walk(ox::Error(*cb)(uint8_t, uint64_t, uint64_t)) = 0;
@ -94,12 +94,12 @@ class FileSystemTemplate: public FileSystem {
}; };
FileStore m_fs; FileStore m_fs;
void(*m_freeBuffer)(uint8_t*) = nullptr; void(*m_freeBuffer)(char*) = nullptr;
public: public:
FileSystemTemplate() = default; FileSystemTemplate() = default;
FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(uint8_t*) = [] (uint8_t *buff) { delete buff; }); FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(char*) = [] (char *buff) { delete buff; });
FileSystemTemplate(FileStore fs); FileSystemTemplate(FileStore fs);
@ -147,7 +147,7 @@ class FileSystemTemplate: public FileSystem {
uint64_t size() const override; uint64_t size() const override;
uint8_t *buff() override; char *buff() override;
[[nodiscard]] ox::Error walk(ox::Error(*cb)(uint8_t, uint64_t, uint64_t)) override; [[nodiscard]] ox::Error walk(ox::Error(*cb)(uint8_t, uint64_t, uint64_t)) override;
@ -171,7 +171,7 @@ FileSystemTemplate<FileStore, Directory>::FileSystemTemplate(FileStore fs) {
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
FileSystemTemplate<FileStore, Directory>::FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(uint8_t*)): FileSystemTemplate<FileStore, Directory>::FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(char*)):
m_fs(buffer, bufferSize), m_fs(buffer, bufferSize),
m_freeBuffer(freeBuffer) { m_freeBuffer(freeBuffer) {
} }
@ -363,7 +363,7 @@ uint64_t FileSystemTemplate<FileStore, Directory>::size() const {
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
uint8_t *FileSystemTemplate<FileStore, Directory>::buff() { char *FileSystemTemplate<FileStore, Directory>::buff() {
return m_fs.buff(); return m_fs.buff();
} }

View File

@ -28,7 +28,8 @@ std::string PassThroughFS::basePath() {
Error PassThroughFS::mkdir(const char *path, bool recursive) { Error PassThroughFS::mkdir(const char *path, bool recursive) {
bool success = false; bool success = false;
const auto p = m_path / stripSlash(path); const auto p = m_path / stripSlash(path);
oxTrace("ox::fs::PassThroughFS::mkdir") << p.c_str(); const auto u8p = p.u8string();
oxTrace("ox::fs::PassThroughFS::mkdir") << u8p.c_str();
if (recursive) { if (recursive) {
success = std::filesystem::create_directories(p); success = std::filesystem::create_directories(p);
} else { } else {
@ -140,7 +141,7 @@ uint64_t PassThroughFS::size() const {
return s.capacity; return s.capacity;
} }
uint8_t *PassThroughFS::buff() { char *PassThroughFS::buff() {
return nullptr; return nullptr;
} }

View File

@ -72,7 +72,7 @@ class PassThroughFS: public FileSystem {
uint64_t size() const override; uint64_t size() const override;
uint8_t *buff() override; char *buff() override;
ox::Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) override; ox::Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) override;
@ -89,9 +89,8 @@ class PassThroughFS: public FileSystem {
template<typename F> template<typename F>
ox::Error PassThroughFS::ls(const char *dir, F cb) { ox::Error PassThroughFS::ls(const char *dir, F cb) {
for (auto &p : std::filesystem::directory_iterator(m_path / stripSlash(dir))) { for (auto &p : std::filesystem::directory_iterator(m_path / stripSlash(dir))) {
if (auto err = cb(p.path().filename().c_str(), 0); err) { auto u8p = p.path().filename().u8string();
return err; oxReturnError(cb(u8p.c_str(), 0));
}
} }
return OxError(0); return OxError(0);
} }

View File

@ -17,7 +17,7 @@ FieldPresenceIndicator::FieldPresenceIndicator(uint8_t *mask, std::size_t maxLen
m_maskLen = maxLen; m_maskLen = maxLen;
} }
ValErr<bool> FieldPresenceIndicator::get(int i) const { ValErr<bool> FieldPresenceIndicator::get(std::size_t i) const {
if (i / 8 < m_maskLen) { if (i / 8 < m_maskLen) {
return (m_mask[i / 8] >> (i % 8)) & 1; return (m_mask[i / 8] >> (i % 8)) & 1;
} else { } else {
@ -25,7 +25,7 @@ ValErr<bool> FieldPresenceIndicator::get(int i) const {
} }
} }
Error FieldPresenceIndicator::set(int i, bool on) { Error FieldPresenceIndicator::set(std::size_t i, bool on) {
if (i / 8 < m_maskLen) { if (i / 8 < m_maskLen) {
if (on) { if (on) {
m_mask[i / 8] |= 1 << (i % 8); m_mask[i / 8] |= 1 << (i % 8);

View File

@ -16,15 +16,15 @@ namespace ox {
class FieldPresenceIndicator { class FieldPresenceIndicator {
private: private:
uint8_t *m_mask = nullptr; uint8_t *m_mask = nullptr;
int m_maskLen = 0; std::size_t m_maskLen = 0;
int m_fields = 0; std::size_t m_fields = 0;
public: public:
FieldPresenceIndicator(uint8_t *mask, std::size_t maxLen); FieldPresenceIndicator(uint8_t *mask, std::size_t maxLen);
ValErr<bool> get(int i) const; ValErr<bool> get(std::size_t i) const;
Error set(int i, bool on); Error set(std::size_t i, bool on);
void setFields(int) noexcept; void setFields(int) noexcept;

View File

@ -34,12 +34,12 @@ void assertFunc<bool>([[maybe_unused]]const char *file, [[maybe_unused]]int line
template<> template<>
void assertFunc<Error>(const char *file, int line, Error err, const char *msg) { void assertFunc<Error>(const char *file, int line, Error err, const char *msg) {
if (err) { if (err) {
panic(file, line, err, msg); panic(file, line, msg, err);
} }
} }
void panic([[maybe_unused]]const char *file, [[maybe_unused]]int line, [[maybe_unused]]Error err, [[maybe_unused]]const char *msg) {
#if defined(OX_USE_STDLIB) #if defined(OX_USE_STDLIB)
void panic(const char *file, int line, const char *msg, Error err) {
std::cerr << "\033[31;1;1mPANIC:\033[0m (" << file << ':' << line << "): " << msg << '\n'; std::cerr << "\033[31;1;1mPANIC:\033[0m (" << file << ':' << line << "): " << msg << '\n';
std::cerr << "\tError Code:\t" << err << '\n'; std::cerr << "\tError Code:\t" << err << '\n';
if (err.file != nullptr) { if (err.file != nullptr) {
@ -48,7 +48,7 @@ void panic([[maybe_unused]]const char *file, [[maybe_unused]]int line, [[maybe_u
printStackTrace(2); printStackTrace(2);
oxTrace("assert").del("") << "Failed assert: " << msg << " (" << file << ":" << line << ")"; oxTrace("assert").del("") << "Failed assert: " << msg << " (" << file << ":" << line << ")";
std::abort(); std::abort();
#endif
} }
#endif
} }

View File

@ -23,14 +23,14 @@ void assertFunc<bool>(const char *file, int line, bool pass, const char *msg);
template<> template<>
void assertFunc<Error>(const char *file, int line, Error err, const char*); void assertFunc<Error>(const char *file, int line, Error err, const char*);
void panic([[maybe_unused]]const char *file, [[maybe_unused]]int line, [[maybe_unused]]Error err, [[maybe_unused]]const char *msg); void panic([[maybe_unused]]const char *file, [[maybe_unused]]int line, [[maybe_unused]]const char *msg, [[maybe_unused]]Error err = OxError(0));
} }
#define oxPanic(pass, msg) ox::panic(__FILE__, __LINE__, pass, msg)
#ifndef NDEBUG #ifndef NDEBUG
#define oxAssert(pass, msg) ox::assertFunc<decltype(pass)>(__FILE__, __LINE__, pass, msg) #define oxAssert(pass, msg) ox::assertFunc<decltype(pass)>(__FILE__, __LINE__, pass, msg)
#define oxPanic(pass, msg) ox::panic(__FILE__, __LINE__, pass, msg)
#else #else
#define oxAssert(pass, msg) inline void oxAssert(bool, const char*) {}
#define oxPanic(pass, msg) inline void oxAssert(ox::Error, const char*) {}
#endif #endif

View File

@ -18,10 +18,6 @@
#define OxError(x) static_cast<ox::Error>(x) #define OxError(x) static_cast<ox::Error>(x)
#endif #endif
#define oxIgnoreError(x)
#define oxReturnError(x) if (const auto _ox_error = ox::error::toError(x)) return _ox_error
#define oxThrowError(x) if (const auto _ox_error = ox::error::toError(x)) throw _ox_error
namespace ox { namespace ox {
struct BaseError { struct BaseError {
@ -95,3 +91,7 @@ template<typename T>
} }
inline void oxIgnoreError(ox::Error) {}
#define oxReturnError(x) if (const auto _ox_error = ox::error::toError(x)) return _ox_error
#define oxThrowError(x) if (const auto _ox_error = ox::error::toError(x)) throw _ox_error

View File

@ -22,7 +22,7 @@
#else #else
#warn "Undefined hardware" #error "Undefined hardware"
#endif #endif

View File

@ -8,7 +8,7 @@
#pragma once #pragma once
#if OX_USE_STDLIB #ifdef OX_USE_STDLIB
#include <cstddef> #include <cstddef>
#else #else
#define offsetof(type, member) __builtin_offsetof(type, member) #define offsetof(type, member) __builtin_offsetof(type, member)

View File

@ -96,7 +96,7 @@ template<typename T1, typename T2>
int retval = -1; int retval = -1;
for (std::size_t i = 0; i < maxLen && str[i]; i++) { for (std::size_t i = 0; i < maxLen && str[i]; i++) {
if (str[i] == character) { if (str[i] == character) {
retval = i; retval = static_cast<int>(i);
} }
} }
return retval; return retval;
@ -106,7 +106,7 @@ template<typename T1, typename T2>
int retval = -1; int retval = -1;
for (std::size_t i = 0; i < maxLen && str[i]; i++) { for (std::size_t i = 0; i < maxLen && str[i]; i++) {
if (str[i] == character) { if (str[i] == character) {
retval = i; retval = static_cast<int>(i);
} }
} }
return retval; return retval;

View File

@ -10,7 +10,6 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#endif #endif
#include "trace.hpp" #include "trace.hpp"

View File

@ -2,6 +2,7 @@
#setup libraries #setup libraries
if(NOSTALGIA_BUILD_TYPE STREQUAL "Native") if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
find_package(SDL2 CONFIG REQUIRED)
if(NOSTALGIA_BUILD_STUDIO) if(NOSTALGIA_BUILD_STUDIO)
find_package(Qt5Widgets REQUIRED) find_package(Qt5Widgets REQUIRED)
find_package(Qt5QuickWidgets REQUIRED) find_package(Qt5QuickWidgets REQUIRED)

View File

@ -2,6 +2,7 @@ add_library(
NostalgiaCore NostalgiaCore
core.cpp core.cpp
gfx.cpp gfx.cpp
media.cpp
) )
target_link_libraries( target_link_libraries(
@ -9,9 +10,8 @@ target_link_libraries(
OxFS OxFS
) )
if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") add_subdirectory(gba)
add_subdirectory(gba) if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
add_subdirectory(sdl) add_subdirectory(sdl)
add_subdirectory(userland) add_subdirectory(userland)
endif() endif()

View File

@ -12,10 +12,7 @@
namespace nostalgia::core { namespace nostalgia::core {
ox::Error init(Context *ctx) { ox::Error init(Context *ctx) {
auto err = OxError(0); return initGfx(ctx);
err = initGfx(ctx);
initHeap(); // this does nothing in userland builds
return err;
} }
} }

View File

@ -1,23 +1,35 @@
add_library( if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
NostalgiaCore-GBA add_library(
core.cpp
gfx.cpp
media.cpp
mem.cpp
panic.cpp
)
target_link_libraries(
NostalgiaCore-GBA PUBLIC
NostalgiaCore
GbaStartup
OxFS
OxStd
)
install(
TARGETS
NostalgiaCore-GBA NostalgiaCore-GBA
DESTINATION core.cpp
include/nostalgia/core gfx.cpp
) media.cpp
mem.cpp
panic.cpp
)
target_link_libraries(
NostalgiaCore-GBA PUBLIC
NostalgiaCore
GbaStartup
OxFS
OxStd
)
install(
TARGETS
NostalgiaCore-GBA
DESTINATION
include/nostalgia/core
)
endif()
# tests
if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
add_executable(NostalgiaCore-GBA_Test
tests.cpp
mem.cpp
)
target_link_libraries(NostalgiaCore-GBA_Test NostalgiaCore)
add_test("NostalgiaCore-GBA\\ Test\\ malloc" NostalgiaCore-GBA_Test malloc)
endif()

View File

@ -45,7 +45,7 @@
typedef uint16_t BgMapTile[1024]; typedef uint16_t BgMapTile[1024];
#define MEM_BG_MAP reinterpret_cast<BgMapTile*>(0x06000000) #define MEM_BG_MAP reinterpret_cast<BgMapTile*>(0x06000000)
#define MEM_ROM *reinterpret_cast<char*>(0x08000000) #define MEM_ROM reinterpret_cast<char*>(0x08000000)
#define MEM_WRAM_BEGIN reinterpret_cast<uint8_t*>(0x02000000) #define MEM_WRAM_BEGIN reinterpret_cast<uint8_t*>(0x02000000)
#define MEM_WRAM_END reinterpret_cast<uint8_t*>(0x0203FFFF) #define MEM_WRAM_END reinterpret_cast<uint8_t*>(0x0203FFFF)

View File

@ -14,7 +14,6 @@
#include <nostalgia/core/gfx.hpp> #include <nostalgia/core/gfx.hpp>
#include "addresses.hpp" #include "addresses.hpp"
#include "panic.hpp"
namespace nostalgia::core { namespace nostalgia::core {
@ -102,7 +101,7 @@ ox::Error shutdownGfx() {
case 3: case 3:
return REG_BG3CNT; return REG_BG3CNT;
default: default:
panic("Looking up non-existent register"); oxPanic("Looking up non-existent register", OxError(1));
return REG_BG0CNT; return REG_BG0CNT;
} }
} }

View File

@ -23,7 +23,7 @@ char *loadRom(const char*) {
constexpr auto headerP2Len = 16; constexpr auto headerP2Len = 16;
constexpr auto headerLen = headerP1Len + headerP2Len + 1; constexpr auto headerLen = headerP1Len + headerP2Len + 1;
for (auto current = &MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) { for (auto current = MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
if (ox_memcmp(current, headerP1, headerP1Len) == 0 && if (ox_memcmp(current, headerP1, headerP1Len) == 0 &&
ox_memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) { ox_memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) {
return current + headerLen; return current + headerLen;

View File

@ -7,11 +7,9 @@
*/ */
#include "addresses.hpp" #include "addresses.hpp"
#include "ox/std/bit.hpp"
#include "ox/std/types.hpp"
#include "panic.hpp"
#include <ox/std/std.hpp> #include <ox/std/assert.hpp>
#include <ox/std/bit.hpp>
// this warning is too dumb to realize that it can actually confirm the hard // this warning is too dumb to realize that it can actually confirm the hard
// coded address aligns with the requirement of HeapSegment, so it must be // coded address aligns with the requirement of HeapSegment, so it must be
@ -25,6 +23,10 @@
namespace nostalgia::core { namespace nostalgia::core {
static class HeapSegment *volatile g_heapBegin = nullptr;
static class HeapSegment *volatile g_heapEnd = nullptr;
static class HeapSegment *volatile heapIdx = nullptr;
static constexpr std::size_t alignedSize(std::size_t sz) { static constexpr std::size_t alignedSize(std::size_t sz) {
return sz + (sz & 7); return sz + (sz & 7);
} }
@ -38,39 +40,35 @@ struct HeapSegment {
std::size_t size; std::size_t size;
uint8_t inUse; uint8_t inUse;
void init(std::size_t maxSize = ox::bit_cast<std::size_t>(HEAP_END)) { void init(std::size_t maxSize = ox::bit_cast<std::size_t>(g_heapEnd)) {
this->size = maxSize - reinterpret_cast<std::size_t>(this); this->size = maxSize - ox::bit_cast<std::size_t>(this);
this->inUse = false; this->inUse = false;
} }
template<typename T> template<typename T>
T *data() { T *data() {
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(this) + alignedSize(this)); return ox::bit_cast<T*>(ox::bit_cast<uint8_t*>(this) + alignedSize(this));
} }
template<typename T = uint8_t> template<typename T = uint8_t>
T *end() { T *end() {
const auto size = alignedSize(this) + alignedSize(this->size); const auto size = alignedSize(this) + alignedSize(this->size);
auto e = reinterpret_cast<uintptr_t>(reinterpret_cast<uint8_t*>(this) + size); auto e = ox::bit_cast<uintptr_t>(ox::bit_cast<uint8_t*>(this) + size);
return reinterpret_cast<T*>(e); return ox::bit_cast<T*>(e);
} }
}; };
static HeapSegment *volatile heapIdx = nullptr; void initHeap(char *heapBegin, char *heapEnd) {
g_heapBegin = ox::bit_cast<HeapSegment*>(heapBegin);
void initHeap() { g_heapEnd = ox::bit_cast<HeapSegment*>(heapEnd);
heapIdx = HEAP_BEGIN; heapIdx = g_heapBegin;
heapIdx->init(); heapIdx->size = ox::bit_cast<std::size_t>(heapEnd) - ox::bit_cast<std::size_t>(heapIdx);
heapIdx->inUse = false;
} }
static HeapSegment *findSegmentFor(std::size_t sz) { void initHeap() {
for (auto s = HEAP_BEGIN; s + sz < HEAP_END; s = s->end<HeapSegment>()) { initHeap(ox::bit_cast<char*>(HEAP_BEGIN), ox::bit_cast<char*>(HEAP_END));
if (s->size >= sz && !s->inUse) {
return s;
}
}
return nullptr;
} }
struct SegmentPair { struct SegmentPair {
@ -90,6 +88,16 @@ static SegmentPair findSegmentOf(void *ptr) {
return {}; return {};
} }
static HeapSegment *findSegmentFor(std::size_t sz) {
for (auto s = g_heapBegin; s <= g_heapEnd; s = s->end<HeapSegment>()) {
if (s->size >= sz && !s->inUse) {
return s;
}
}
oxPanic("malloc: could not find segment", OxError(1));
return nullptr;
}
[[nodiscard]] void *malloc(std::size_t allocSize) { [[nodiscard]] void *malloc(std::size_t allocSize) {
const auto targetSize = alignedSize(sizeof(HeapSegment)) + alignedSize(allocSize); const auto targetSize = alignedSize(sizeof(HeapSegment)) + alignedSize(allocSize);
auto seg = findSegmentFor(targetSize); auto seg = findSegmentFor(targetSize);
@ -99,9 +107,8 @@ static SegmentPair findSegmentOf(void *ptr) {
const auto bytesRemaining = seg->size - targetSize; const auto bytesRemaining = seg->size - targetSize;
seg->size = targetSize; seg->size = targetSize;
seg->inUse = true; seg->inUse = true;
auto out = seg->data<void>();
seg->end<HeapSegment>()->init(bytesRemaining); seg->end<HeapSegment>()->init(bytesRemaining);
return out; return seg->data<void>();
} }
void free(void *ptr) { void free(void *ptr) {
@ -111,12 +118,14 @@ void free(void *ptr) {
} else if (p.segment) { } else if (p.segment) {
p.segment->inUse = false; p.segment->inUse = false;
} else { } else {
panic("Bad heap free"); oxPanic("Bad heap free", OxError(1));
} }
} }
} }
#ifndef OX_USE_STDLIB
using namespace nostalgia; using namespace nostalgia;
void *operator new(std::size_t allocSize) { void *operator new(std::size_t allocSize) {
@ -142,3 +151,13 @@ void operator delete(void *ptr, unsigned) {
void operator delete[](void *ptr, unsigned) { void operator delete[](void *ptr, unsigned) {
core::free(ptr); core::free(ptr);
} }
void operator delete(void *ptr, unsigned long int) {
core::free(ptr);
}
void operator delete[](void *ptr, unsigned long int) {
core::free(ptr);
}
#endif

View File

@ -7,15 +7,21 @@
*/ */
#include "../core.hpp" #include "../core.hpp"
#include "panic.hpp" #include "../gfx.hpp"
namespace nostalgia::core { namespace ox {
void panic(const char *msg) { using namespace nostalgia::core;
void panic(const char*, int, const char *msg, ox::Error err) {
oxIgnoreError(initGfx(nullptr));
oxIgnoreError(initConsole(nullptr)); oxIgnoreError(initConsole(nullptr));
ox::BString<23> serr = "Error code: ";
serr += err;
puts(nullptr, 32 + 0, 1, "SADNESS..."); puts(nullptr, 32 + 0, 1, "SADNESS...");
puts(nullptr, 32 + 0, 4, "UNEXPECTED STATE:"); puts(nullptr, 32 + 0, 4, "UNEXPECTED STATE:");
puts(nullptr, 32 + 2, 6, msg); puts(nullptr, 32 + 2, 6, msg);
puts(nullptr, 32 + 2, 7, serr.c_str());
puts(nullptr, 32 + 0, 10, "PLEASE RESTART THE SYSTEM"); puts(nullptr, 32 + 0, 10, "PLEASE RESTART THE SYSTEM");
// TODO: properly end program execution, this wastes power // TODO: properly end program execution, this wastes power
while (1); while (1);

View File

@ -1,16 +0,0 @@
/*
* Copyright 2016 - 2019 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
namespace nostalgia::core {
void panic(const char *msg);
}

View File

@ -0,0 +1,50 @@
#include <map>
#include <string>
#include <vector>
#include <ox/std/std.hpp>
#include <nostalgia/core/mem.hpp>
namespace nostalgia::core {
[[nodiscard]] void *malloc(std::size_t allocSize);
void free(void *ptr);
void initHeap(char *heapBegin, char *heapEnd);
}
using namespace nostalgia;
int testMalloc(std::string) {
std::vector<char> buff(ox::units::MB);
core::initHeap(&buff.front(), &buff.back());
oxAssert(core::malloc(5) != nullptr, "malloc is broken");
oxAssert(core::malloc(5) != nullptr, "malloc is broken");
return 0;
}
std::map<std::string, int(*)(std::string)> tests = {
{
{ "malloc", testMalloc },
}
};
int main(int argc, const char **args) {
int retval = -1;
if (argc > 1) {
auto testName = args[1];
std::string testArg = "";
if (args[2]) {
testArg = args[2];
}
if (tests.find(testName) != tests.end()) {
retval = tests[testName](testArg);
}
}
return retval;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2016 - 2020 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "media.hpp"
namespace nostalgia::core {
ox::FileSystem *loadRomFs(const char *path) {
const auto lastDot = ox_lastIndexOf(path, '.');
const auto fsExt = lastDot != -1 ? path + lastDot : "";
if (ox_strcmp(fsExt, ".oxfs") == 0) {
auto rom = core::loadRom(path);
if (!rom) {
return nullptr;
}
return new ox::FileSystem32(rom, 32 * ox::units::MB, unloadRom);
} else {
#ifdef OX_HAS_PASSTHROUGHFS
return new ox::PassThroughFS(path);
#else
return nullptr;
#endif
}
}
}

View File

@ -8,10 +8,12 @@
#pragma once #pragma once
#include <ox/std/types.hpp> #include <ox/fs/fs.hpp>
namespace nostalgia::core { namespace nostalgia::core {
ox::FileSystem *loadRomFs(const char *path);
char *loadRom(const char *path = ""); char *loadRom(const char *path = "");
void unloadRom(char*); void unloadRom(char*);

View File

@ -8,6 +8,7 @@
#include <ox/fs/fs.hpp> #include <ox/fs/fs.hpp>
#include <ox/std/units.hpp> #include <ox/std/units.hpp>
#include <nostalgia/core/core.hpp>
#include <nostalgia/world/world.hpp> #include <nostalgia/world/world.hpp>
using namespace nostalgia; using namespace nostalgia;
@ -28,29 +29,12 @@ ox::Error run(ox::FileSystem *fs) {
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
if (argc > 1) { if (argc > 1) {
ox::FileSystem *fs = nullptr;
char *rom = nullptr;
auto path = argv[1]; auto path = argv[1];
const auto lastDot = ox_lastIndexOf(path, '.'); auto fs = core::loadRomFs(path);
const auto fsExt = lastDot != -1 ? path + lastDot : "";
if (ox_strcmp(fsExt, ".oxfs") == 0) {
rom = core::loadRom(path);
if (!rom) {
return 1;
}
fs = new (ox_alloca(sizeof(ox::FileStore32))) ox::FileSystem32(ox::FileStore32(rom, 32 * ox::units::MB));
} else {
#ifdef OX_HAS_PASSTHROUGHFS
fs = new (ox_alloca(sizeof(ox::PassThroughFS))) ox::PassThroughFS(path);
#else
return 2;
#endif
}
auto err = run(fs); auto err = run(fs);
oxAssert(err, "Something went wrong..."); oxAssert(err, "Something went wrong...");
fs->~FileSystem(); delete fs;
core::unloadRom(rom);
return err; return err;
} }
return 3; return 1;
} }

View File

@ -6,8 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <stdio.h>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
@ -54,7 +52,7 @@ int main(int argc, const char **args) {
try { try {
run(ox::ClArgs(argc, args)); run(ox::ClArgs(argc, args));
} catch (const ox::Error &err) { } catch (const ox::Error &err) {
oxPanic(err, "pack failed"); oxPanic("pack failed", err);
std::cerr << "pack failed...\n"; std::cerr << "pack failed...\n";
return static_cast<int>(err); return static_cast<int>(err);
} }

View File

@ -78,7 +78,7 @@ struct VerificationPair {
std::cout << "copying directory: " << path << '\n'; std::cout << "copying directory: " << path << '\n';
std::vector<VerificationPair> verficationPairs; std::vector<VerificationPair> verficationPairs;
// copy // copy
oxReturnError(src->ls(path.c_str(), [&verficationPairs, src, dest, path](const char *name, ox::InodeId_t) { oxReturnError(src->ls(path.c_str(), [&verficationPairs, src, dest, path](std::string name, ox::InodeId_t) {
std::cout << "reading " << name << '\n'; std::cout << "reading " << name << '\n';
auto currentFile = path + name; auto currentFile = path + name;
auto [stat, err] = src->stat((currentFile).c_str()); auto [stat, err] = src->stat((currentFile).c_str());