mirror of
https://github.com/liuk7071/ChonkyStation.git
synced 2024-05-20 12:57:52 -04:00
Added SeekL (might be broken atm) and sideloading of executables
This commit is contained in:
parent
fc2155a208
commit
ee070d73d4
|
@ -35,6 +35,25 @@ void CDROM::executeCommand(u8 data) {
|
|||
break;
|
||||
}
|
||||
|
||||
case CDROMCommands::SeekL: {
|
||||
// TODO: SeekL/P should stop ongoing reads
|
||||
|
||||
// First response doesn't have seeking bit set
|
||||
response.push(statusCode.raw);
|
||||
|
||||
statusCode.seeking = true;
|
||||
secondResponse.push(statusCode.raw);
|
||||
|
||||
scheduler->push(&int3, scheduler->time + int3Delay, this);
|
||||
scheduler->push(&int2, scheduler->time + int3Delay + int2Delay, this);
|
||||
|
||||
// Seek time is currently stubbed to 150k cycles
|
||||
scheduler->push(&stopSeeking, scheduler->time + seekTime, this);
|
||||
|
||||
log("SeekL\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case CDROMCommands::Test: {
|
||||
u8 subFunc = getParamByte();
|
||||
switch (subFunc) {
|
||||
|
@ -46,12 +65,12 @@ void CDROM::executeCommand(u8 data) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unimplemented CDROM test subfunc 0x%02x\n", subFunc);
|
||||
Helpers::panic("[ FATAL ] Unimplemented CDROM test subfunc 0x%02x\n", subFunc);
|
||||
}
|
||||
|
||||
scheduler->push(&int3, scheduler->time + int3Delay, this);
|
||||
|
||||
log("Test\n", statusCode.raw);
|
||||
log("Test\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -83,15 +102,15 @@ void CDROM::executeCommand(u8 data) {
|
|||
scheduler->push(&int3, scheduler->time + int3Delay, this);
|
||||
scheduler->push(&int2, scheduler->time + int3Delay + getIDDelay, this);
|
||||
|
||||
log("GetID\n", statusCode.raw);
|
||||
log("GetID\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unimplemented CDROM command 0x%02x\n", data);
|
||||
Helpers::panic("[ FATAL ] Unimplemented CDROM command 0x%02x\n", data);
|
||||
}
|
||||
|
||||
Helpers::debugAssert(params.size() == 0, "[FATAL] CDROM command did not use all parameters");
|
||||
Helpers::debugAssert(params.size() == 0, "[ FATAL ] CDROM command did not use all parameters");
|
||||
|
||||
statusReg.rslrrdy = 1; // Response fifo not empty
|
||||
statusReg.prmempt = 1; // Parameter fifo empty
|
||||
|
@ -104,43 +123,57 @@ bool CDROM::shouldFireIRQ() {
|
|||
|
||||
void CDROM::int2(void* classptr) {
|
||||
CDROM* cdrom = (CDROM*)classptr;
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[FATAL] CDROM INT2 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[ FATAL ] CDROM INT2 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
cdrom->intFlag |= 2;
|
||||
|
||||
// Second response
|
||||
if (cdrom->secondResponse.size()) {
|
||||
Helpers::debugAssert(!cdrom->response.size(), "[FATAL] CDROM INT2 before first response was read (probably not supposed to happen...?");
|
||||
Helpers::debugAssert(!cdrom->response.size(), "[ FATAL ] CDROM INT2 before first response was read (probably not supposed to happen...?");
|
||||
cdrom->response = cdrom->secondResponse;
|
||||
cdrom->statusReg.rslrrdy = 1; // Response fifo not empty
|
||||
|
||||
while (cdrom->secondResponse.size()) cdrom->secondResponse.pop();
|
||||
log("---INT2\n");
|
||||
}
|
||||
else
|
||||
log("INT2\n");
|
||||
}
|
||||
|
||||
void CDROM::int3(void* classptr) {
|
||||
CDROM* cdrom = (CDROM*)classptr;
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[FATAL] CDROM INT3 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[ FATAL ] CDROM INT3 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
cdrom->intFlag |= 3;
|
||||
|
||||
log("-INT3\n");
|
||||
}
|
||||
|
||||
void CDROM::int5(void* classptr) {
|
||||
CDROM* cdrom = (CDROM*)classptr;
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[FATAL] CDROM INT5 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
Helpers::debugAssert((cdrom->intFlag & 7) == 0, "[ FATAL ] CDROM INT5 was fired before previous INT%d was acknowledged in interrupt flag\n", cdrom->intFlag & 3);
|
||||
cdrom->intFlag |= 5;
|
||||
|
||||
// Second response
|
||||
if (cdrom->secondResponse.size()) {
|
||||
Helpers::debugAssert(!cdrom->response.size(), "[FATAL] CDROM INT5 before first response was read (probably not supposed to happen...?");
|
||||
Helpers::debugAssert(!cdrom->response.size(), "[ FATAL ] CDROM INT5 before first response was read (probably not supposed to happen...?");
|
||||
cdrom->response = cdrom->secondResponse;
|
||||
cdrom->statusReg.rslrrdy = 1; // Response fifo not empty
|
||||
|
||||
while (cdrom->secondResponse.size()) cdrom->secondResponse.pop();
|
||||
log("---INT5\n");
|
||||
}
|
||||
else
|
||||
log("INT5\n");
|
||||
}
|
||||
|
||||
void CDROM::stopSeeking(void* classptr) {
|
||||
CDROM* cdrom = (CDROM*)classptr;
|
||||
cdrom->statusCode.seeking = false;
|
||||
log("Seek ended\n");
|
||||
}
|
||||
|
||||
void CDROM::pushParam(u8 data) {
|
||||
params.push(data);
|
||||
Helpers::debugAssert(params.size() <= 16, "[FATAL] Wrote more than 16 bytes to CDROM parameter fifo");
|
||||
Helpers::debugAssert(params.size() <= 16, "[ FATAL ] Wrote more than 16 bytes to CDROM parameter fifo");
|
||||
if (params.size() == 16) {
|
||||
statusReg.prmwrdy = 0; // Parameter fifo full
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ constexpr u64 readDelayDoubleSpeed = readDelay / 2;
|
|||
|
||||
// I don't know if these are ok?????
|
||||
constexpr u64 int3Delay = cpuSpeed / 1000;
|
||||
constexpr u64 int2Delay = int3Delay * 2;
|
||||
constexpr u64 getIDDelay = 33868;
|
||||
|
||||
constexpr u64 seekTime = 150000; // Currently stubbed seeking time to this for all seeks
|
||||
|
||||
class CDROM {
|
||||
public:
|
||||
|
@ -30,6 +32,8 @@ public:
|
|||
static void int3(void* classptr);
|
||||
static void int5(void* classptr);
|
||||
|
||||
static void stopSeeking(void* classptr);
|
||||
|
||||
void pushParam(u8 data);
|
||||
|
||||
u8 readStatus();
|
||||
|
@ -83,6 +87,7 @@ namespace CDROMCommands {
|
|||
enum {
|
||||
GetStat = 0x01,
|
||||
SetLoc = 0x02,
|
||||
SeekL = 0x15,
|
||||
Test = 0x19,
|
||||
GetID = 0x1A
|
||||
};
|
||||
|
|
|
@ -188,7 +188,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unimplemented secondary instruction 0x%02x (raw: 0x%08x)\n", instr.secondaryOpc.Value(), instr.raw);
|
||||
Helpers::panic("[ FATAL ] Unimplemented secondary instruction 0x%02x (raw: 0x%08x)\n", instr.secondaryOpc.Value(), instr.raw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Invalid REGIMM instruction 0x%02x (raw: 0x%08x)\n", instr.regimmOpc.Value(), instr.raw);
|
||||
Helpers::panic("[ FATAL ] Invalid REGIMM instruction 0x%02x (raw: 0x%08x)\n", instr.regimmOpc.Value(), instr.raw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -318,12 +318,12 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Invalid cop0 instruction 0x%02 (raw:0x%08x)\n", instr.func.Value(), instr.raw);
|
||||
Helpers::panic("[ FATAL ] Invalid cop0 instruction 0x%02 (raw:0x%08x)\n", instr.func.Value(), instr.raw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unimplemented cop instruction 0x%02x (raw: 0x%08x)\n", instr.cop0Opc.Value(), instr.raw);
|
||||
Helpers::panic("[ FATAL ] Unimplemented cop instruction 0x%02x (raw: 0x%08x)\n", instr.cop0Opc.Value(), instr.raw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unimplemented primary instruction 0x%02x (raw: 0x%08x)\n", instr.primaryOpc.Value(), instr.raw);
|
||||
Helpers::panic("[ FATAL ] Unimplemented primary instruction 0x%02x (raw: 0x%08x)\n", instr.primaryOpc.Value(), instr.raw);
|
||||
}
|
||||
|
||||
core->isDelaySlot = false;
|
||||
|
|
|
@ -34,6 +34,9 @@ bool delay = false;
|
|||
#define log_kernel_tty
|
||||
|
||||
void OldInterpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
||||
// Handle interrupts
|
||||
core->checkInterrupt(mem->interrupt);
|
||||
|
||||
const auto instr = mem->read<u32>(core->pc);
|
||||
|
||||
disassembler->disassemble({ .raw = instr }, core);
|
||||
|
|
|
@ -82,6 +82,7 @@ struct COP0 {
|
|||
case (u32)COP0Reg::Status: return status.raw;
|
||||
case (u32)COP0Reg::Cause: return cause.raw;
|
||||
case (u32)COP0Reg::EPC: return epc;
|
||||
case (u32)COP0Reg::PRId: return 2;
|
||||
default:
|
||||
Helpers::panic("Unimplemented cop0 register read cop0r%d\n", cop0r);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ void DMA::gpuDMA(Memory* memory) {
|
|||
break;
|
||||
}
|
||||
case (u32)SyncMode::LinkedList: {
|
||||
Helpers::debugAssert(ch.chcr.dir == (u32)Direction::ToDevice, "[FATAL] GPU LinkedList with direction ToRam");
|
||||
Helpers::debugAssert(ch.chcr.dir == (u32)Direction::ToDevice, "[ FATAL ] GPU LinkedList with direction ToRam");
|
||||
|
||||
u32 header = 0;
|
||||
u32 words = 0;
|
||||
|
|
|
@ -10,17 +10,17 @@ class GPU;
|
|||
class GPUBackend {
|
||||
public:
|
||||
GPUBackend(GPU* gpu) : gpu(gpu) {}
|
||||
virtual void reset() { Helpers::panic("[FATAL] GPU Backend did not define reset function\n"); };
|
||||
virtual u8* getVRAM() { Helpers::panic("[FATAL] GPU Backend did not define getVRAM function\n"); };
|
||||
virtual void reset() { Helpers::panic("[ FATAL ] GPU Backend did not define reset function\n"); };
|
||||
virtual u8* getVRAM() { Helpers::panic("[ FATAL ] GPU Backend did not define getVRAM function\n"); };
|
||||
|
||||
// Drawing
|
||||
virtual void drawTriUntextured(Vertex v0, Vertex v1, Vertex v2) { Helpers::panic("[FATAL] GPU Backend did not define drawTriUntextured function\n"); }
|
||||
virtual void drawTriTextured(Vertex v0, Vertex v1, Vertex v2, u16 clut, u16 texpage) { Helpers::panic("[FATAL] GPU Backend did not define drawTriTextured function\n"); }
|
||||
virtual void drawTriUntextured(Vertex v0, Vertex v1, Vertex v2) { Helpers::panic("[ FATAL ] GPU Backend did not define drawTriUntextured function\n"); }
|
||||
virtual void drawTriTextured(Vertex v0, Vertex v1, Vertex v2, u16 clut, u16 texpage) { Helpers::panic("[ FATAL ] GPU Backend did not define drawTriTextured function\n"); }
|
||||
|
||||
// Textures
|
||||
virtual void beginTextureUpload(u16 x, u16 y, u16 width) { Helpers::panic("[FATAL] GPU Backend did not define beginTextureUpload function\n"); };
|
||||
virtual void textureUploadData(u16 data) { Helpers::panic("[FATAL] GPU Backend did not define textureUploadData function\n"); };
|
||||
virtual void endTextureUpload() { Helpers::panic("[FATAL] GPU Backend did not define endTextureUpload function\n"); }
|
||||
virtual void beginTextureUpload(u16 x, u16 y, u16 width) { Helpers::panic("[ FATAL ] GPU Backend did not define beginTextureUpload function\n"); };
|
||||
virtual void textureUploadData(u16 data) { Helpers::panic("[ FATAL ] GPU Backend did not define textureUploadData function\n"); };
|
||||
virtual void endTextureUpload() { Helpers::panic("[ FATAL ] GPU Backend did not define endTextureUpload function\n"); }
|
||||
|
||||
protected:
|
||||
GPU* gpu;
|
||||
|
|
|
@ -11,7 +11,7 @@ u8* GPUSoftware::getVRAM() {
|
|||
}
|
||||
|
||||
void GPUSoftware::beginTextureUpload(u16 x, u16 y, u16 width) {
|
||||
if (uploadingTexture) Helpers::panic("[FATAL] Attempted to start a GPU texture transfer before another transfer ended\n");
|
||||
if (uploadingTexture) Helpers::panic("[ FATAL ] Attempted to start a GPU texture transfer before another transfer ended\n");
|
||||
|
||||
textureUpload = { x, y, width };
|
||||
curX = x;
|
||||
|
@ -20,7 +20,7 @@ void GPUSoftware::beginTextureUpload(u16 x, u16 y, u16 width) {
|
|||
}
|
||||
|
||||
void GPUSoftware::textureUploadData(u16 data) {
|
||||
if (!uploadingTexture) Helpers::panic("[FATAL] Attempted to upload texture data before starting a texture transfer\n");
|
||||
if (!uploadingTexture) Helpers::panic("[ FATAL ] Attempted to upload texture data before starting a texture transfer\n");
|
||||
|
||||
writePixel(curX, curY, data);
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ int main(int argc, char** argv) {
|
|||
|
||||
PlayStation playstation = PlayStation(argv[1]);
|
||||
|
||||
if (argc >= 3) {
|
||||
playstation.sideloadExecutable(argv[2]);
|
||||
}
|
||||
|
||||
// SDL Window
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Window* window = SDL_CreateWindow("ChonkyStation", 100, 100, 1024, 512, 0);
|
||||
|
|
|
@ -70,21 +70,21 @@ u8 Memory::read(u32 vaddr) {
|
|||
switch (cdrom->getIndex()) {
|
||||
case 1: return cdrom->getResponseByte();
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unhandled CDROM read8 0x1f801801.%d", cdrom->getIndex());
|
||||
Helpers::panic("[ FATAL ] Unhandled CDROM read8 0x1f801801.%d", cdrom->getIndex());
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f801803) {
|
||||
switch (cdrom->getIndex()) {
|
||||
case 1: return cdrom->readIF();
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unhandled CDROM read8 0x1f801803.%d", cdrom->getIndex());
|
||||
Helpers::panic("[ FATAL ] Unhandled CDROM read8 0x1f801803.%d", cdrom->getIndex());
|
||||
}
|
||||
}
|
||||
// SIO
|
||||
else if (Helpers::inRangeSized<u32>(paddr, (u32)MemoryBase::SIO, (u32)MemorySize::SIO)) return 0;
|
||||
else if (Helpers::inRangeSized<u32>(paddr, 0x1f000000, 0x400)) return 0xff;
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled read8 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
Helpers::panic("[ FATAL ] Unhandled read8 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -107,7 +107,7 @@ u16 Memory::read(u32 vaddr) {
|
|||
// SPU
|
||||
else if (Helpers::inRangeSized<u32>(paddr, (u32)MemoryBase::SPU, (u32)MemorySize::SPU)) return 0;
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled read16 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
Helpers::panic("[ FATAL ] Unhandled read16 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -122,8 +122,14 @@ u32 Memory::read(u32 vaddr) {
|
|||
|
||||
u32 paddr = maskAddress(vaddr);
|
||||
|
||||
// Scratchpad
|
||||
if (Helpers::inRangeSized<u32>(paddr, 0x1f800000, 1_KB)) {
|
||||
u32 data = 0;
|
||||
std::memcpy(&data, &scratchpad[paddr - 0x1f800000], sizeof(u32));
|
||||
return data;
|
||||
}
|
||||
// GPU
|
||||
if (paddr == 0x1f801810) return gpu->gpuRead();
|
||||
else if (paddr == 0x1f801810) return gpu->gpuRead();
|
||||
else if (paddr == 0x1f801814) return gpu->getStat();
|
||||
// Interrupt
|
||||
else if (paddr == 0x1f801070) return interrupt->readIstat();
|
||||
|
@ -137,7 +143,7 @@ u32 Memory::read(u32 vaddr) {
|
|||
case 0x0: return dma->channels[channel].madr;
|
||||
case 0x4: return dma->channels[channel].bcr.raw;
|
||||
case 0x8: return dma->channels[channel].chcr.raw;
|
||||
default: Helpers::panic("[FATAL] Unhandled DMA read32 0x%08x\n", paddr);
|
||||
default: Helpers::panic("[ FATAL ] Unhandled DMA read32 0x%08x\n", paddr);
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f8010f0) return dma->dpcr;
|
||||
|
@ -145,7 +151,7 @@ u32 Memory::read(u32 vaddr) {
|
|||
// Timers
|
||||
else if (Helpers::inRangeSized<u32>(paddr, (u32)MemoryBase::Timer, (u32)MemorySize::Timer)) return 0;
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled read32 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
Helpers::panic("[ FATAL ] Unhandled read32 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -171,7 +177,7 @@ void Memory::write(u32 vaddr, u8 data) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unhandled CDROM write8 0x1f801801.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
Helpers::panic("[ FATAL ] Unhandled CDROM write8 0x1f801801.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f801802) {
|
||||
|
@ -185,7 +191,7 @@ void Memory::write(u32 vaddr, u8 data) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unhandled CDROM write8 0x1f801802.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
Helpers::panic("[ FATAL ] Unhandled CDROM write8 0x1f801802.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f801803) {
|
||||
|
@ -195,12 +201,12 @@ void Memory::write(u32 vaddr, u8 data) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[FATAL] Unhandled CDROM write8 0x1f801803.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
Helpers::panic("[ FATAL ] Unhandled CDROM write8 0x1f801803.%d <- 0x%02x\n", cdrom->getIndex(), data);
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f802041) return; // POST - External 7-segment Display (W)
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled write8 0x%08x (virtual 0x%08x) <- 0x%02x\n", paddr, vaddr, data);
|
||||
Helpers::panic("[ FATAL ] Unhandled write8 0x%08x (virtual 0x%08x) <- 0x%02x\n", paddr, vaddr, data);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -226,7 +232,7 @@ void Memory::write(u32 vaddr, u16 data) {
|
|||
// Timers
|
||||
else if (Helpers::inRangeSized<u32>(paddr, (u32)MemoryBase::Timer, (u32)MemorySize::Timer)) return;
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled write16 0x%08x (virtual 0x%08x) <- 0x%04x\n", paddr, vaddr, data);
|
||||
Helpers::panic("[ FATAL ] Unhandled write16 0x%08x (virtual 0x%08x) <- 0x%04x\n", paddr, vaddr, data);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -263,7 +269,7 @@ void Memory::write(u32 vaddr, u32 data) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
default: Helpers::panic("[FATAL] Unhandled DMA write32 0x%08x <- 0x%08x\n", paddr, data);
|
||||
default: Helpers::panic("[ FATAL ] Unhandled DMA write32 0x%08x <- 0x%08x\n", paddr, data);
|
||||
}
|
||||
}
|
||||
else if (paddr == 0x1f8010f0) dma->dpcr = data;
|
||||
|
@ -283,5 +289,5 @@ void Memory::write(u32 vaddr, u32 data) {
|
|||
else if (paddr == 0x1f801060) return; // RAM_SIZE (R/W) (usually 00000B88h) (or 00000888h)
|
||||
else if (paddr == 0xfffe0130) return; // Cache Control (R/W)
|
||||
else
|
||||
Helpers::panic("[FATAL] Unhandled write32 0x%08x (virtual 0x%08x) <- 0x%08x\n", paddr, vaddr, data);
|
||||
Helpers::panic("[ FATAL ] Unhandled write32 0x%08x (virtual 0x%08x) <- 0x%08x\n", paddr, vaddr, data);
|
||||
}
|
|
@ -32,6 +32,14 @@ public:
|
|||
if (cdrom.shouldFireIRQ()) {
|
||||
interrupt.raiseInterrupt(Interrupt::InterruptType::CDROM);
|
||||
}
|
||||
|
||||
if (cpu.core.pc == 0x80030000) {
|
||||
isKernelSetupDone = true;
|
||||
if (hasToLoadExecutable) {
|
||||
loadExecutable(executablePath);
|
||||
hasToLoadExecutable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 getPC() { return cpu.core.pc; }
|
||||
|
@ -44,6 +52,30 @@ public:
|
|||
}
|
||||
void VBLANK() { interrupt.raiseInterrupt(Interrupt::InterruptType::VBLANK); }
|
||||
bool isInBIOS() { return Helpers::inRangeSized<u32>(cpu.core.pc, (u32)Memory::MemoryBase::BIOS, (u32)Memory::MemorySize::BIOS); }
|
||||
|
||||
void loadExecutable(const fs::path path) {
|
||||
auto binary = Helpers::readBinary(path);
|
||||
|
||||
u32 entryPc = 0;
|
||||
u32 entryAddr = 0;
|
||||
u32 fileSize = 0;
|
||||
|
||||
memcpy(&entryPc, &binary[0x10], sizeof(u32));
|
||||
memcpy(&entryAddr, &binary[0x18], sizeof(u32));
|
||||
memcpy(&fileSize, &binary[0x1c], sizeof(u32));
|
||||
|
||||
for (int i = 0; i < (binary.size() - 2048); i++) {
|
||||
mem.write(entryAddr + i, binary[0x800 + i]);
|
||||
}
|
||||
|
||||
cpu.core.pc = entryPc;
|
||||
cpu.core.nextPc = cpu.core.pc + 4;
|
||||
}
|
||||
|
||||
void sideloadExecutable(const fs::path path) {
|
||||
hasToLoadExecutable = true;
|
||||
executablePath = path;
|
||||
}
|
||||
|
||||
private:
|
||||
Cpu cpu;
|
||||
|
@ -53,4 +85,9 @@ private:
|
|||
Interrupt interrupt;
|
||||
GPU gpu;
|
||||
CDROM cdrom;
|
||||
|
||||
bool hasToLoadExecutable = false;
|
||||
fs::path executablePath;
|
||||
|
||||
bool isKernelSetupDone = false;
|
||||
};
|
|
@ -14,7 +14,7 @@ void Scheduler::tick(u64 cycles) {
|
|||
}
|
||||
|
||||
void Scheduler::push(void (*functionPtr)(void*), u64 time, void* data) {
|
||||
Helpers::debugAssert(events.size() < schedulerMaxEntries, "[FATAL] Queued more than %d scheduler events\n", schedulerMaxEntries);
|
||||
Helpers::debugAssert(events.size() < schedulerMaxEntries, "[ FATAL ] Queued more than %d scheduler events\n", schedulerMaxEntries);
|
||||
|
||||
events.push({ .functionPtr = functionPtr, .data = data, .time = time });
|
||||
}
|
Loading…
Reference in a new issue