fix crash on Windows + small performace improvement BUT breaks Donkey
Kong
This commit is contained in:
12
README.md
12
README.md
@@ -1,21 +1,21 @@
|
|||||||
# Gadolinium
|
# Gadolinium
|
||||||
|
|
||||||
[](https://www.codefactor.io/repository/github/cocosimone/Gadolinium/overview/master)
|
[](https://www.codefactor.io/repository/github/SimoneN64/Gadolinium/overview/master)
|
||||||
[](https://github.com/CocoSimone/Gadolinium/actions/workflows/build.yml)
|
[](https://github.com/SimoneN64/Gadolinium/actions/workflows/build.yml)
|
||||||
|
|
||||||
Rewrite of my Nintendo 64 emulator "[shibumi](https://github.com/CocoSimone/shibumi)".
|
Rewrite of my Nintendo 64 emulator "[shibumi](https://github.com/SimoneN64/shibumi)".
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Pre-built binaries
|
## Pre-built binaries
|
||||||
| Release |
|
| Release |
|
||||||
|---------------------------------------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------------------------------------|
|
||||||
| [Windows (Release)](https://nightly.link/CocoSimone/Gadolinium/workflows/build/master/gadolinium-windows.zip) |
|
| [Windows (Release)](https://nightly.link/SimoneN64/Gadolinium/workflows/build/master/gadolinium-windows.zip) |
|
||||||
| [Linux (Release)](https://nightly.link/CocoSimone/Gadolinium/workflows/build/master/gadolinium-linux.zip) |
|
| [Linux (Release)](https://nightly.link/SimoneN64/Gadolinium/workflows/build/master/gadolinium-linux.zip) |
|
||||||
|
|
||||||
|
|
||||||
## Build instructions:
|
## Build instructions:
|
||||||
First clone the repository: `git clone --recursive https://github.com/CocoSimone/Gadolinium`
|
First clone the repository: `git clone --recursive https://github.com/SimoneN64/Gadolinium`
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
|
|||||||
MMIO& mmio = cpu->mem.mmio;
|
MMIO& mmio = cpu->mem.mmio;
|
||||||
|
|
||||||
for (int field = 0; field < mmio.vi.numFields; field++) {
|
for (int field = 0; field < mmio.vi.numFields; field++) {
|
||||||
int frameCycles = 0;
|
|
||||||
if (!pause && romLoaded) {
|
if (!pause && romLoaded) {
|
||||||
|
int frameCycles = 0;
|
||||||
for (int i = 0; i < mmio.vi.numHalflines; i++) {
|
for (int i = 0; i < mmio.vi.numHalflines; i++) {
|
||||||
mmio.vi.current = (i << 1) + field;
|
mmio.vi.current = (i << 1) + field;
|
||||||
|
|
||||||
@@ -46,10 +46,8 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cpuCount = cpu->Run();
|
int cpuCount = cpu->Run();
|
||||||
|
cpu->RunRSP(cpuCount);
|
||||||
frameCycles += cpuCount;
|
frameCycles += cpuCount;
|
||||||
mmio.rsp.Run(cpuCount, cpu->regs, cpu->mem);
|
|
||||||
mmio.ai.Step(cpu->mem, cpu->regs, cpuCount, volumeL, volumeR);
|
|
||||||
scheduler.tick(cpuCount, cpu->mem, cpu->regs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
||||||
@@ -58,8 +56,8 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
|
|||||||
|
|
||||||
UpdateScreenParallelRdp(*this, window, GetVI());
|
UpdateScreenParallelRdp(*this, window, GetVI());
|
||||||
|
|
||||||
int missedCycles = N64_CYCLES_PER_FRAME(isPAL) - frameCycles;
|
mmio.ai.Step(cpu->mem, cpu->regs, frameCycles, volumeL, volumeR);
|
||||||
mmio.ai.Step(cpu->mem, cpu->regs, missedCycles, volumeL, volumeR);
|
scheduler.tick(frameCycles, cpu->mem, cpu->regs);
|
||||||
} else if (pause && romLoaded) {
|
} else if (pause && romLoaded) {
|
||||||
UpdateScreenParallelRdp(*this, window, GetVI());
|
UpdateScreenParallelRdp(*this, window, GetVI());
|
||||||
} else if (pause && !romLoaded) {
|
} else if (pause && !romLoaded) {
|
||||||
|
|||||||
@@ -58,6 +58,6 @@ constexpr u64 operator""_gb(unsigned long long int x) {
|
|||||||
return 1024_mb * x;
|
return 1024_mb * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADDRESS_RANGE_SIZE 4_gb
|
#define ADDRESS_RANGE_SIZE 0x80000000ull
|
||||||
#define PAGE_SIZE 4_kb
|
#define PAGE_SIZE 4_kb
|
||||||
#define PAGE_COUNT ((ADDRESS_RANGE_SIZE) / (PAGE_SIZE))
|
#define PAGE_COUNT ((ADDRESS_RANGE_SIZE) / (PAGE_SIZE))
|
||||||
@@ -6,6 +6,9 @@ struct BaseCPU {
|
|||||||
virtual ~BaseCPU() {}
|
virtual ~BaseCPU() {}
|
||||||
virtual void Reset() {}
|
virtual void Reset() {}
|
||||||
virtual int Run() {}
|
virtual int Run() {}
|
||||||
|
void RunRSP(int cpuCount) {
|
||||||
|
mem.mmio.rsp.Run(cpuCount, regs, mem);
|
||||||
|
}
|
||||||
Registers regs;
|
Registers regs;
|
||||||
Mem mem;
|
Mem mem;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ void Interpreter::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Interpreter::Run() {
|
int Interpreter::Run() {
|
||||||
int cycles = 0;
|
int cycles = 1;
|
||||||
for(; cycles <= mem.mmio.vi.cyclesPerHalfline; cycles++) {
|
for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++) {
|
||||||
CheckCompareInterrupt(mem.mmio.mi, regs);
|
CheckCompareInterrupt(mem.mmio.mi, regs);
|
||||||
|
|
||||||
regs.prevDelaySlot = regs.delaySlot;
|
regs.prevDelaySlot = regs.delaySlot;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
Mem::Mem() {
|
Mem::Mem() {
|
||||||
|
cart = (u8*)calloc(CART_SIZE, 1);
|
||||||
|
sram = (u8*)calloc(SRAM_SIZE, 1);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,16 +24,8 @@ void Mem::Reset() {
|
|||||||
writePages[i] = pointer;
|
writePages[i] = pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sram) {
|
memset(cart, 0, CART_SIZE);
|
||||||
free(sram);
|
memset(sram, 0, SRAM_SIZE);
|
||||||
}
|
|
||||||
|
|
||||||
if(cart) {
|
|
||||||
free(cart);
|
|
||||||
}
|
|
||||||
|
|
||||||
cart = (u8*)calloc(CART_SIZE, 1);
|
|
||||||
sram = (u8*)calloc(SRAM_SIZE, 1);
|
|
||||||
mmio.Reset();
|
mmio.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,13 @@
|
|||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
RDP::RDP() {
|
RDP::RDP() {
|
||||||
|
rdram = (u8*)calloc(RDRAM_SIZE, 1);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RDP::Reset() {
|
void RDP::Reset() {
|
||||||
dpc.status.raw = 0x80;
|
dpc.status.raw = 0x80;
|
||||||
if(rdram) {
|
memset(rdram, 0, RDRAM_SIZE);
|
||||||
free(rdram);
|
|
||||||
}
|
|
||||||
rdram = (u8*)calloc(RDRAM_SIZE, 1);
|
|
||||||
memset(cmd_buf, 0, 0x100000);
|
memset(cmd_buf, 0, 0x100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ struct RDP {
|
|||||||
RDP();
|
RDP();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
u8* rdram;
|
u8* rdram = nullptr;
|
||||||
[[nodiscard]] auto Read(u32 addr) const -> u32;
|
[[nodiscard]] auto Read(u32 addr) const -> u32;
|
||||||
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
|
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
|
||||||
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
|
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
|
||||||
|
|||||||
@@ -36,4 +36,5 @@ using m128i = __m128i;
|
|||||||
#define BYTE_INDEX(i) (15 - (i))
|
#define BYTE_INDEX(i) (15 - (i))
|
||||||
|
|
||||||
#define unlikely(exp) __builtin_expect(exp, 0)
|
#define unlikely(exp) __builtin_expect(exp, 0)
|
||||||
#define likely(exp) __builtin_expect(exp, 1)
|
#define likely(exp) __builtin_expect(exp, 1)
|
||||||
|
#define INLINE static inline __attribute__((always_inline))
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
namespace Util {
|
namespace Util {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T ReadAccess(u8 *data, u32 index) {
|
inline T ReadAccess(u8 *data, u32 index) {
|
||||||
if constexpr (sizeof(T) == 1) {
|
if constexpr (sizeof(T) == 1) { //
|
||||||
return data[index];
|
return data[index];
|
||||||
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
|
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
|
||||||
T result = 0;
|
T result = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user