From 216aecf23481c0473b00d9b3519f482511d4e0e1 Mon Sep 17 00:00:00 2001 From: liuk7071 Date: Mon, 18 Sep 2023 22:23:40 +0200 Subject: [PATCH] [CDROM] SetLoc --- src/cdrom/cdrom.cpp | 57 +++++++++++++++++++- src/cdrom/cdrom.hpp | 5 ++ src/cpu/backends/interpreter/interpreter.cpp | 4 ++ src/memory/memory.cpp | 6 +++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom.cpp b/src/cdrom/cdrom.cpp index 5a74ee5..343fa9f 100644 --- a/src/cdrom/cdrom.cpp +++ b/src/cdrom/cdrom.cpp @@ -16,6 +16,18 @@ void CDROM::executeCommand(u8 data) { scheduler->push(&int3, scheduler->time + int3Delay, this); break; } + + case CDROMCommands::SetLoc: { + u8 mm = bcdToDec(getParamByte()); + u8 ss = bcdToDec(getParamByte()); + u8 ff = bcdToDec(getParamByte()); + + seekLoc = ff + (ss * 75) + (mm * 60 * 75); + + response.push(statusCode.raw); + scheduler->push(&int3, scheduler->time + int3Delay, this); + break; + } case CDROMCommands::Test: { u8 subFunc = getParamByte(); @@ -37,8 +49,31 @@ void CDROM::executeCommand(u8 data) { case CDROMCommands::GetID: { response.push(statusCode.raw); + + // No Disk + /*secondResponse.push(0x08); + secondResponse.push(0x40); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push(0x00); + INT5 !!! + */ + + // Modchip:Audio/Mode1 + secondResponse.push(0x02); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push(0x00); + secondResponse.push('C'); + secondResponse.push('H'); + secondResponse.push('S'); + secondResponse.push('T'); + scheduler->push(&int3, scheduler->time + int3Delay, this); - scheduler->push(&int5, scheduler->time + int3Delay + getIDDelay, this); + scheduler->push(&int2, scheduler->time + int3Delay + getIDDelay, this); break; } @@ -57,6 +92,21 @@ bool CDROM::shouldFireIRQ() { return intFlag & intEnable; } +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); + 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...?"); + cdrom->response = cdrom->secondResponse; + cdrom->statusReg.rslrrdy = 1; // Response fifo not empty + + while (cdrom->secondResponse.size()) cdrom->secondResponse.pop(); + } +} + 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); @@ -70,14 +120,17 @@ void CDROM::int5(void* classptr) { // Second response if (cdrom->secondResponse.size()) { + 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(); } } void CDROM::pushParam(u8 data) { - Helpers::debugAssert(params.size() <= 16, "[FATAL] Wrote more than 16 bytes to CDROM parameter fifo"); params.push(data); + 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 } diff --git a/src/cdrom/cdrom.hpp b/src/cdrom/cdrom.hpp index ed85f02..a43ac12 100644 --- a/src/cdrom/cdrom.hpp +++ b/src/cdrom/cdrom.hpp @@ -25,6 +25,7 @@ class CDROM { // INTs bool shouldFireIRQ(); + static void int2(void* classptr); static void int3(void* classptr); static void int5(void* classptr); @@ -47,6 +48,9 @@ class CDROM { std::queue params; u8 getParamByte(); + u32 seekLoc = 0; + u8 bcdToDec(u8 n) { return n - 6 * (n >> 4); } + std::queue response; std::queue secondResponse; @@ -77,6 +81,7 @@ class CDROM { namespace CDROMCommands { enum { GetStat = 0x01, + SetLoc = 0x02, Test = 0x19, GetID = 0x1A }; diff --git a/src/cpu/backends/interpreter/interpreter.cpp b/src/cpu/backends/interpreter/interpreter.cpp index be9924a..dcb1f0a 100644 --- a/src/cpu/backends/interpreter/interpreter.cpp +++ b/src/cpu/backends/interpreter/interpreter.cpp @@ -327,6 +327,10 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) { } break; } + case CpuOpcodes::Opcode::COP2: { + // TODO: GTE + break; + } case CpuOpcodes::Opcode::LB: { const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm; gprs[instr.rt] = (u32)(s8)mem->read(addr); diff --git a/src/memory/memory.cpp b/src/memory/memory.cpp index 27cf932..fa5ef40 100644 --- a/src/memory/memory.cpp +++ b/src/memory/memory.cpp @@ -80,6 +80,8 @@ u8 Memory::read(u32 vaddr) { Helpers::panic("[FATAL] Unhandled CDROM read8 0x1f801803.%d", cdrom->getIndex()); } } + // SIO + else if (Helpers::inRangeSized(paddr, (u32)MemoryBase::SIO, (u32)MemorySize::SIO)) return 0; else if (Helpers::inRangeSized(paddr, 0x1f000000, 0x400)) return 0xff; else Helpers::panic("[FATAL] Unhandled read8 0x%08x (virtual 0x%08x)\n", paddr, vaddr); @@ -100,6 +102,8 @@ u16 Memory::read(u32 vaddr) { // Interrupt if (paddr == 0x1f801070) return interrupt->readIstat(); else if (paddr == 0x1f801074) return interrupt->readImask(); + // SIO + else if (Helpers::inRangeSized(paddr, (u32)MemoryBase::SIO, (u32)MemorySize::SIO)) return 0; // SPU else if (Helpers::inRangeSized(paddr, (u32)MemoryBase::SPU, (u32)MemorySize::SPU)) return 0; else @@ -215,6 +219,8 @@ void Memory::write(u32 vaddr, u16 data) { // Interrupt if (paddr == 0x1f801070) interrupt->writeIstat(data); else if (paddr == 0x1f801074) interrupt->writeImask(data); + // SIO + else if (Helpers::inRangeSized(paddr, (u32)MemoryBase::SIO, (u32)MemorySize::SIO)) return; // SPU else if (Helpers::inRangeSized(paddr, (u32)MemoryBase::SPU, (u32)MemorySize::SPU)) return; // Timers