Merge ares v134
|
@ -746,7 +746,7 @@ static u8 PeekFunc(u64 address)
|
|||
}
|
||||
|
||||
ares::Nintendo64::Thread unused;
|
||||
return ares::Nintendo64::bus.read<ares::Nintendo64::Byte>(addr, unused);
|
||||
return ares::Nintendo64::bus.read<ares::Nintendo64::Byte>(addr, unused, nullptr);
|
||||
}
|
||||
|
||||
static void SysBusAccess(u8* buffer, u64 address, u64 count, bool write)
|
||||
|
@ -755,7 +755,7 @@ static void SysBusAccess(u8* buffer, u64 address, u64 count, bool write)
|
|||
{
|
||||
ares::Nintendo64::Thread unused;
|
||||
while (count--)
|
||||
ares::Nintendo64::bus.write<ares::Nintendo64::Byte>(address++, *buffer++, unused);
|
||||
ares::Nintendo64::bus.write<ares::Nintendo64::Byte>(address++, *buffer++, unused, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <ares/ares.hpp>
|
||||
#include <ares/debug/debug.cpp>
|
||||
#include <nall/gdb/server.cpp>
|
||||
#include <ares/node/node.cpp>
|
||||
#include <ares/resource/resource.cpp>
|
||||
|
||||
|
@ -8,4 +9,13 @@ namespace ares {
|
|||
Platform* platform = nullptr;
|
||||
bool _runAhead = false;
|
||||
|
||||
const string Name = "ares";
|
||||
const string Version = "138";
|
||||
const string Copyright = "ares team, Near";
|
||||
const string License = "ISC";
|
||||
const string LicenseURI = "https://opensource.org/licenses/ISC";
|
||||
const string Website = "ares-emu.net";
|
||||
const string WebsiteURI = "https://ares-emu.net/";
|
||||
const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <emulibc.h>
|
||||
#include <libco.h>
|
||||
|
||||
#include <sljit.h>
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
|
@ -42,16 +41,14 @@ using namespace nall;
|
|||
using namespace nall::primitives;
|
||||
|
||||
namespace ares {
|
||||
static const string Name = "ares";
|
||||
static const string Version = "133";
|
||||
static const string Copyright = "ares team, Near";
|
||||
static const string License = "ISC";
|
||||
static const string LicenseURI = "https://opensource.org/licenses/ISC";
|
||||
static const string Website = "ares-emu.net";
|
||||
static const string WebsiteURI = "https://ares-emu.net/";
|
||||
|
||||
//incremented only when serialization format changes
|
||||
static const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
|
||||
extern const string Name;
|
||||
extern const string Version;
|
||||
extern const string Copyright;
|
||||
extern const string License;
|
||||
extern const string LicenseURI;
|
||||
extern const string Website;
|
||||
extern const string WebsiteURI;
|
||||
extern const u32 SerializerSignature;
|
||||
|
||||
namespace VFS {
|
||||
using Pak = shared_pointer<vfs::directory>;
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
#include <ares/ares.hpp>
|
||||
|
||||
#if !defined(PLATFORM_MACOS)
|
||||
#define STATIC_ALLOCATION
|
||||
#endif
|
||||
|
||||
namespace ares::Memory {
|
||||
|
||||
constexpr u32 fixedBufferSize = 8_MiB;
|
||||
|
||||
#if defined(PLATFORM_MACOS)
|
||||
//dynamic allocation for unsupported platforms
|
||||
FixedAllocator::FixedAllocator() {
|
||||
_allocator.resize(fixedBufferSize, bump_allocator::executable);
|
||||
}
|
||||
#else
|
||||
alignas(4096) u8 fixedBuffer[fixedBufferSize];
|
||||
#if defined(STATIC_ALLOCATION)
|
||||
u8 fixedBuffer[fixedBufferSize + 64_KiB];
|
||||
#endif
|
||||
|
||||
FixedAllocator::FixedAllocator() {
|
||||
_allocator.resize(sizeof(fixedBuffer), 0, fixedBuffer);
|
||||
u8* buffer = nullptr;
|
||||
|
||||
#if defined(STATIC_ALLOCATION)
|
||||
//align to 64 KiB (maximum page size of any supported OS)
|
||||
auto offset = -(uintptr)fixedBuffer % 64_KiB;
|
||||
//set protection to executable
|
||||
if(memory::protect(fixedBuffer + offset, fixedBufferSize, true)) {
|
||||
//use static allocation
|
||||
buffer = fixedBuffer + offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
_allocator.resize(fixedBufferSize, bump_allocator::executable, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto FixedAllocator::get() -> bump_allocator& {
|
||||
static FixedAllocator allocator;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
namespace ares::Memory {
|
||||
|
||||
struct FixedAllocator {
|
||||
static auto get() -> bump_allocator&;
|
||||
|
||||
private:
|
||||
FixedAllocator();
|
||||
|
||||
bump_allocator _allocator;
|
||||
};
|
||||
|
||||
}
|
||||
#pragma once
|
||||
|
||||
namespace ares::Memory {
|
||||
|
||||
struct FixedAllocator {
|
||||
static auto get() -> bump_allocator&;
|
||||
|
||||
private:
|
||||
FixedAllocator();
|
||||
|
||||
bump_allocator _allocator;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -71,9 +71,7 @@ struct Instruction : Tracer {
|
|||
if(!enabled()) return;
|
||||
|
||||
if(_omitted) {
|
||||
PlatformLog({
|
||||
"[Omitted: ", _omitted, "]\n"}
|
||||
);
|
||||
PlatformLog(shared(), {"[Omitted: ", _omitted, "]"});
|
||||
_omitted = 0;
|
||||
}
|
||||
|
||||
|
@ -84,7 +82,7 @@ struct Instruction : Tracer {
|
|||
context, " ",
|
||||
extra
|
||||
};
|
||||
PlatformLog({output.strip(), "\n"});
|
||||
PlatformLog(shared(), {output.strip()});
|
||||
}
|
||||
|
||||
auto serialize(string& output, string depth) -> void override {
|
||||
|
|
7
waterbox/ares64/ares/ares/ares/node/debugger/tracer/notification.hpp
Normal file → Executable file
|
@ -6,12 +6,7 @@ struct Notification : Tracer {
|
|||
|
||||
auto notify(const string& message = {}) -> void {
|
||||
if(!enabled()) return;
|
||||
|
||||
if(message) {
|
||||
PlatformLog({_component, " ", _name, ": ", message, "\n"});
|
||||
} else {
|
||||
PlatformLog({_component, " ", _name, "\n"});
|
||||
}
|
||||
PlatformLog(shared(), message);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -6,24 +6,40 @@ struct Tracer : Debugger {
|
|||
}
|
||||
|
||||
auto component() const -> string { return _component; }
|
||||
auto enabled() const -> bool { return _enabled; }
|
||||
auto enabled() const -> bool { return file() || terminal(); }
|
||||
auto prefix() const -> bool { return _prefix; }
|
||||
auto terminal() const -> bool { return _terminal; }
|
||||
auto file() const -> bool { return _file; }
|
||||
auto autoLineBreak() const -> bool { return _autoLineBreak; }
|
||||
|
||||
auto setToggle(function<void ()> toggle) -> void { _toggle = toggle; }
|
||||
auto setComponent(string component) -> void { _component = component; }
|
||||
auto setEnabled(bool enabled) -> void { _enabled = enabled; }
|
||||
auto setPrefix(bool prefix) -> void { _prefix = prefix; }
|
||||
auto setTerminal(bool terminal) -> void { _terminal = terminal; if(_toggle) _toggle(); }
|
||||
auto setFile(bool file) -> void { _file = file; if(_toggle) _toggle(); }
|
||||
auto setAutoLineBreak(bool autoLineBreak) -> void { _autoLineBreak = autoLineBreak; }
|
||||
|
||||
auto serialize(string& output, string depth) -> void override {
|
||||
Debugger::serialize(output, depth);
|
||||
output.append(depth, " component: ", _component, "\n");
|
||||
output.append(depth, " enabled: ", _enabled, "\n");
|
||||
output.append(depth, " prefix: ", _prefix, "\n");
|
||||
output.append(depth, " terminal: ", _terminal, "\n");
|
||||
output.append(depth, " file: ", _file, "\n");
|
||||
}
|
||||
|
||||
auto unserialize(Markup::Node node) -> void override {
|
||||
Debugger::unserialize(node);
|
||||
_component = node["component"].string();
|
||||
_enabled = node["enabled"].boolean();
|
||||
_prefix = node["prefix"].boolean();
|
||||
_terminal = node["terminal"].boolean();
|
||||
_file = node["file"].boolean();
|
||||
}
|
||||
|
||||
protected:
|
||||
function<void ()> _toggle;
|
||||
string _component;
|
||||
bool _enabled = false;
|
||||
bool _prefix = false;
|
||||
bool _terminal = false;
|
||||
bool _file = false;
|
||||
bool _autoLineBreak = true;
|
||||
};
|
||||
|
|
|
@ -5,7 +5,9 @@ struct Rumble : Input {
|
|||
auto weakValue() const -> u16 { return _weak; }
|
||||
auto strongValue() const -> u16 { return _strong; }
|
||||
|
||||
auto setValues(u16 weak, u16 strong) -> void { _weak = weak; _strong = strong; }
|
||||
auto setValues(u16 strong, u16 weak) -> void { _weak = weak; _strong = strong; }
|
||||
auto setWeak(u16 weak) -> void { _weak = weak; }
|
||||
auto setStrong(u16 strong) -> void { _strong = strong; }
|
||||
|
||||
// For systems with binary motors
|
||||
auto enable() const -> bool { return _weak > 0 || _strong > 0; }
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace ares::Core {
|
|||
// <ares/platform.hpp> forward declarations
|
||||
static auto PlatformAttach(Node::Object) -> void;
|
||||
static auto PlatformDetach(Node::Object) -> void;
|
||||
static auto PlatformLog(string_view) -> void;
|
||||
static auto PlatformLog(Node::Debugger::Tracer::Tracer tracer, string_view) -> void;
|
||||
|
||||
#include <ares/node/attribute.hpp>
|
||||
#include <ares/node/class.hpp>
|
||||
|
|
|
@ -25,11 +25,15 @@ Screen::~Screen() {
|
|||
|
||||
auto Screen::main(uintptr_t) -> void {
|
||||
while(!_kill) {
|
||||
usleep(1);
|
||||
if(_frame) {
|
||||
unique_lock<mutex> lock(_frameMutex);
|
||||
|
||||
auto timeout = std::chrono::milliseconds(10);
|
||||
if(_frameCondition.wait_for(lock, timeout, [&] { return _frame.load(); })) {
|
||||
refresh();
|
||||
_frame = false;
|
||||
}
|
||||
|
||||
if(_kill) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +72,15 @@ auto Screen::setRefresh(function<void ()> refresh) -> void {
|
|||
_refresh = refresh;
|
||||
}
|
||||
|
||||
auto Screen::refreshRateHint(double pixelFrequency, int dotsPerLine, int linesPerFrame) -> void {
|
||||
refreshRateHint(1.0f / ((double)(dotsPerLine * linesPerFrame) / pixelFrequency));
|
||||
}
|
||||
|
||||
auto Screen::refreshRateHint(double refreshRate) -> void {
|
||||
lock_guard<recursive_mutex> lock(_mutex);
|
||||
platform->refreshRateHint(refreshRate);
|
||||
}
|
||||
|
||||
auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
|
||||
lock_guard<recursive_mutex> lock(_mutex);
|
||||
_viewportX = x;
|
||||
|
@ -76,6 +89,11 @@ auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
|
|||
_viewportHeight = height;
|
||||
}
|
||||
|
||||
auto Screen::setOverscan(bool overscan) -> void {
|
||||
lock_guard<recursive_mutex> lock(_mutex);
|
||||
_overscan = overscan;
|
||||
}
|
||||
|
||||
auto Screen::setSize(u32 width, u32 height) -> void {
|
||||
lock_guard<recursive_mutex> lock(_mutex);
|
||||
_width = width;
|
||||
|
@ -171,10 +189,12 @@ auto Screen::frame() -> void {
|
|||
|
||||
lock_guard<recursive_mutex> lock(_mutex);
|
||||
_inputA.swap(_inputB);
|
||||
_frame = true;
|
||||
if constexpr(!ares::Video::Threaded) {
|
||||
refresh();
|
||||
_frame = false;
|
||||
} else {
|
||||
_frame = true;
|
||||
_frameCondition.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,14 +248,18 @@ auto Screen::refresh() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
if(_colorBleed) {
|
||||
if (_colorBleed) {
|
||||
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
|
||||
for(u32 y : range(height)) {
|
||||
for (u32 y : range(height)) {
|
||||
auto target = output + y * width;
|
||||
for(u32 x : range(width)) {
|
||||
auto a = target[x];
|
||||
auto b = target[x + (x != width - 1)];
|
||||
target[x] = (a + b - ((a ^ b) & mask)) >> 1;
|
||||
for (u32 x : range(0, width, _colorBleedWidth)) {
|
||||
for (u32 offset = 0; offset < _colorBleedWidth && (x + offset) < width; ++offset) {
|
||||
u32 next = x + _colorBleedWidth;
|
||||
if (next + offset >= width) next = x;
|
||||
auto a = target[x + offset];
|
||||
auto b = target[next + offset];
|
||||
target[x + offset] = (a + b - ((a ^ b) & mask)) >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ struct Screen : Video {
|
|||
auto scaleY() const -> f64 { return _scaleY; }
|
||||
auto aspectX() const -> f64 { return _aspectX; }
|
||||
auto aspectY() const -> f64 { return _aspectY; }
|
||||
auto overscan() const -> bool { return _overscan; }
|
||||
auto colors() const -> u32 { return _colors; }
|
||||
auto pixels(bool frame = 0) -> array_span<u32>;
|
||||
|
||||
|
@ -33,10 +34,13 @@ struct Screen : Video {
|
|||
|
||||
auto setRefresh(function<void ()> refresh) -> void;
|
||||
auto setViewport(u32 x, u32 y, u32 width, u32 height) -> void;
|
||||
auto refreshRateHint(double refreshRate) -> void;
|
||||
auto refreshRateHint(double pixelFrequency, int dotsPerLine, int linesPerFrame) -> void;
|
||||
|
||||
auto setSize(u32 width, u32 height) -> void;
|
||||
auto setScale(f64 scaleX, f64 scaleY) -> void;
|
||||
auto setAspect(f64 aspectX, f64 aspectY) -> void;
|
||||
auto setOverscan(bool overscan) -> void;
|
||||
|
||||
auto setSaturation(f64 saturation) -> void;
|
||||
auto setGamma(f64 gamma) -> void;
|
||||
|
@ -44,6 +48,7 @@ struct Screen : Video {
|
|||
|
||||
auto setFillColor(u32 fillColor) -> void;
|
||||
auto setColorBleed(bool colorBleed) -> void;
|
||||
auto setColorBleedWidth(u32 width) -> void;
|
||||
auto setInterframeBlending(bool interframeBlending) -> void;
|
||||
auto setRotation(u32 rotation) -> void;
|
||||
|
||||
|
@ -78,7 +83,9 @@ protected:
|
|||
f64 _luminance = 1.0;
|
||||
u32 _fillColor = 0;
|
||||
bool _colorBleed = false;
|
||||
bool _colorBleedWidth = 1;
|
||||
bool _interframeBlending = false;
|
||||
bool _overscan = true;
|
||||
u32 _rotation = 0; //counter-clockwise (90 = left, 270 = right)
|
||||
|
||||
function<n64 (n32)> _color;
|
||||
|
@ -92,6 +99,8 @@ protected:
|
|||
//unserialized:
|
||||
nall::thread _thread;
|
||||
recursive_mutex _mutex;
|
||||
mutex _frameMutex;
|
||||
condition_variable _frameCondition;
|
||||
atomic<bool> _kill = false;
|
||||
atomic<bool> _frame = false;
|
||||
function<void ()> _refresh;
|
||||
|
|
|
@ -15,11 +15,13 @@ struct Platform {
|
|||
virtual auto detach(Node::Object) -> void {}
|
||||
virtual auto pak(Node::Object) -> shared_pointer<vfs::directory> { return {}; }
|
||||
virtual auto event(Event) -> void {}
|
||||
virtual auto log(string_view message) -> void {}
|
||||
virtual auto log(Node::Debugger::Tracer::Tracer, string_view message) -> void {}
|
||||
virtual auto status(string_view message) -> void {}
|
||||
virtual auto video(Node::Video::Screen, const u32* data, u32 pitch, u32 width, u32 height) -> void {}
|
||||
virtual auto refreshRateHint(double refreshRate) -> void {}
|
||||
virtual auto audio(Node::Audio::Stream) -> void {}
|
||||
virtual auto input(Node::Input::Input) -> void {}
|
||||
virtual auto cheat(u32 addr) -> maybe<u32> { return nothing; }
|
||||
virtual auto time() -> n64 { return ::time(0); }
|
||||
};
|
||||
|
||||
|
@ -31,5 +33,5 @@ namespace ares::Core {
|
|||
// <ares/node/node.hpp> forward declarations
|
||||
auto PlatformAttach(Node::Object node) -> void { if(platform && node->name()) platform->attach(node); }
|
||||
auto PlatformDetach(Node::Object node) -> void { if(platform && node->name()) platform->detach(node); }
|
||||
auto PlatformLog(string_view text) -> void { if(platform) platform->log(text); }
|
||||
auto PlatformLog(Node::Debugger::Tracer::Tracer node, string_view text) -> void { if(platform) platform->log(node, text); }
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
0
waterbox/ares64/ares/ares/ares/resource/sprite/sfc/crosshair-blue.png
Normal file → Executable file
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
0
waterbox/ares64/ares/ares/ares/resource/sprite/sfc/crosshair-green.png
Normal file → Executable file
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 329 B |
0
waterbox/ares64/ares/ares/ares/resource/sprite/sfc/crosshair-red.png
Normal file → Executable file
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 117 B |
Before Width: | Height: | Size: 134 B After Width: | Height: | Size: 134 B |
Before Width: | Height: | Size: 136 B After Width: | Height: | Size: 136 B |
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 136 B After Width: | Height: | Size: 136 B |
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 150 B After Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 155 B |
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 129 B |
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 125 B |
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 153 B After Width: | Height: | Size: 153 B |
|
@ -41,7 +41,7 @@ private:
|
|||
vector<Thread*> _threads;
|
||||
bool _synchronize = false;
|
||||
|
||||
friend class Thread;
|
||||
friend struct Thread;
|
||||
};
|
||||
|
||||
extern Scheduler scheduler;
|
||||
|
|
|
@ -46,5 +46,5 @@ protected:
|
|||
u64 _scalar = 0;
|
||||
u64 _clock = 0;
|
||||
|
||||
friend class Scheduler;
|
||||
friend struct Scheduler;
|
||||
};
|
||||
|
|
0
waterbox/ares64/ares/ares/component/processor/sm5k/serialization.cpp
Normal file → Executable file
|
@ -38,7 +38,7 @@ auto AI::sample(f64& left, f64& right) -> void {
|
|||
|
||||
if(io.dmaLength[0] && io.dmaEnable) {
|
||||
io.dmaAddress[0].bit(13,23) += io.dmaAddressCarry;
|
||||
auto data = rdram.ram.read<Word>(io.dmaAddress[0]);
|
||||
auto data = rdram.ram.read<Word>(io.dmaAddress[0], "AI");
|
||||
auto l = s16(data >> 16);
|
||||
auto r = s16(data >> 0);
|
||||
left = l / 32768.0;
|
||||
|
@ -50,8 +50,9 @@ auto AI::sample(f64& left, f64& right) -> void {
|
|||
}
|
||||
if(!io.dmaLength[0]) {
|
||||
if(--io.dmaCount) {
|
||||
io.dmaAddress[0] = io.dmaAddress[1];
|
||||
io.dmaLength [0] = io.dmaLength [1];
|
||||
io.dmaAddress[0] = io.dmaAddress[1];
|
||||
io.dmaLength [0] = io.dmaLength [1];
|
||||
io.dmaOriginPc[0] = io.dmaOriginPc[1];
|
||||
mi.raise(MI::IRQ::AI);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ struct AI : Thread, Memory::RCP<AI> {
|
|||
n1 dmaAddressCarry;
|
||||
n18 dmaLength[2];
|
||||
n2 dmaCount;
|
||||
u64 dmaOriginPc[2];
|
||||
n14 dacRate;
|
||||
n4 bitRate;
|
||||
} io;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
auto AI::readWord(u32 address, Thread& thread) -> u32 {
|
||||
address = (address & 0xfffff) >> 2;
|
||||
address = (address & 0x1f) >> 2;
|
||||
n32 data;
|
||||
|
||||
if(address != 3) {
|
||||
|
@ -22,7 +22,7 @@ auto AI::readWord(u32 address, Thread& thread) -> u32 {
|
|||
}
|
||||
|
||||
auto AI::writeWord(u32 address, u32 data_, Thread& thread) -> void {
|
||||
address = (address & 0xfffff) >> 2;
|
||||
address = (address & 0x1f) >> 2;
|
||||
n32 data = data_;
|
||||
|
||||
if(address == 0) {
|
||||
|
@ -38,6 +38,7 @@ auto AI::writeWord(u32 address, u32 data_, Thread& thread) -> void {
|
|||
if(io.dmaCount < 2) {
|
||||
if(io.dmaCount == 0) mi.raise(MI::IRQ::AI);
|
||||
io.dmaLength[io.dmaCount] = length;
|
||||
io.dmaOriginPc[io.dmaCount] = cpu.ipu.pc;
|
||||
io.dmaCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,12 @@ auto Cartridge::connect() -> void {
|
|||
|
||||
rtc.load();
|
||||
|
||||
isviewer.ram.allocate(64_KiB);
|
||||
if(rom.size <= 0x03fe'ffff) {
|
||||
isviewer.ram.allocate(64_KiB);
|
||||
isviewer.tracer = node->append<Node::Debugger::Tracer::Notification>("ISViewer", "Cartridge");
|
||||
isviewer.tracer->setAutoLineBreak(false);
|
||||
isviewer.tracer->setTerminal(true);
|
||||
}
|
||||
|
||||
debugger.load(node);
|
||||
|
||||
|
|