Setup CD drive

This commit is contained in:
Jaby 2023-01-22 14:07:58 +01:00
parent aae1d3e066
commit d452a022cf
4 changed files with 119 additions and 32 deletions

View File

@ -57,34 +57,6 @@ namespace JabyEngine {
static constexpr auto ApplyChanges = Bit<uint8_t>(5);
};
struct Interrupt {
static void enable(VolatileBitMapPOD<InterruptEnable>& port) {
port.write(InterruptEnable::InterruptTypValue.max());
}
static void enable_extended(VolatileBitMapPOD<InterruptEnable>& port) {
port.write({InterruptEnable::with(InterruptEnable::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)});
}
static uint8_t get_type(const VolatileBitMapPOD<InterruptFlag>& port) {
return port.read().get_value(InterruptFlag::InterruptTypValue);
}
static void ack(VolatileBitMapPOD<InterruptFlag>& port) {
port.write(InterruptFlag::InterruptTypValue.max());
}
static void ack_extended(VolatileBitMapPOD<InterruptFlag>& port) {
port.write({InterruptFlag::with(InterruptFlag::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)});
}
};
__declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800);
static constexpr auto IORegister1Adr = 0x1F801801;
static constexpr auto IORegister2Adr = 0x1F801802;
static constexpr auto IORegister3Adr = 0x1F801803;
typedef VolatilePOD<uint8_t> ResponseFifo_t;
typedef VolatilePOD<uint8_t> CommandFifo_t;
typedef VolatilePOD<uint8_t> DataFifo_t;
@ -98,6 +70,53 @@ namespace JabyEngine {
typedef VolatileBitMapPOD<SoundMapCoding> SoundMapCodingInfo_t;
typedef VolatileBitMapPOD<AudioVolumeApply> AudioVolumeApplyChange_t;
struct Interrupt {
enum Type : uint8_t {
None = 0,
DataReady = 1,
Complete = 2,
Acknowledge = 3,
DataEnd = 4,
DiskError = 5
};
static void enable(InterruptEnableRegister_t& port) {
port.write(InterruptEnable::InterruptTypValue.max());
}
static void enable_extended(InterruptEnableRegister_t& port) {
port.write({InterruptEnable::with(InterruptEnable::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)});
}
static Type get_type(const InterruptFlagRegister_t& port) {
return static_cast<Type>(port.read().get_value(InterruptFlag::InterruptTypValue));
}
static void ack(InterruptFlagRegister_t& port) {
port.write(InterruptFlag::InterruptTypValue.max());
}
static void ack_extended(InterruptFlagRegister_t& port) {
port.write({InterruptFlag::with(InterruptFlag::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)});
}
};
struct Command {
struct Info {
uint8_t id;
Interrupt::Type complete_irq;
};
static constexpr Info GetStat{0x1, Interrupt::Type::Acknowledge};
static constexpr Info Init{0xA, Interrupt::Type::Complete};
};
static constexpr auto IORegister1Adr = 0x1F801801;
static constexpr auto IORegister2Adr = 0x1F801802;
static constexpr auto IORegister3Adr = 0x1F801803;
__declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800);
#define __declare_index_io_port(type, name, adr) __cast_io_adr_with_type(inline, type, name, adr)
#define __declare_index_io_port_const(type, name, adr) __cast_io_adr_with_type(const inline, type, name, adr)

View File

@ -1,11 +1,31 @@
#ifndef __JABYENGINE_CD_INTERNAL_HPP__
#define __JABYENGINE_CD_INTERNAL_HPP__
#include <stdint.h>
#include <PSX/System/IOPorts/cd_io.hpp>
namespace JabyEngine {
namespace CD {
namespace internal {
extern VolatilePOD<CD_IO::Interrupt::Type> last_interrupt;
struct Command {
static void wait_until(CD_IO::Interrupt::Type irq) {
while(last_interrupt.read() != irq);
}
template<typename...ARGS>
static void send(CD_IO::CommandFifo_t& cmd_fifo, CD_IO::ParameterFifo_t& parameter_fifo, CD_IO::Command::Info cmd, ARGS...args) {
while(CD_IO::IndexStatus.read().is_bit_set(CD_IO::IndexStatus::IsTransmissionBusy));
(parameter_fifo.write(static_cast<uint8_t>(args)), ...);
cmd_fifo.write(cmd.id);
}
template<typename...ARGS>
static void send_wait(CD_IO::CommandFifo_t& cmd_fifo, CD_IO::ParameterFifo_t& parameter_fifo, CD_IO::Command::Info cmd, ARGS...args) {
send(cmd_fifo, parameter_fifo, cmd, args...);
wait_until(cmd.complete_irq);
}
};
}
}
}

View File

@ -1,18 +1,25 @@
#include "../../include/BootLoader/boot_loader.hpp"
#include <PSX/System/IOPorts/cd_io.hpp>
#include "../../include/CD/cd_internal.hpp"
#include <PSX/System/IOPorts/interrupt_io.hpp>
#include <PSX/System/IOPorts/memory_io.hpp>
#include <PSX/System/syscalls.h>
namespace JabyEngine {
namespace CD {
namespace internal {
extern InterrupCallback callback;
}
}
namespace boot {
namespace CD {
using JabyEngine::CD::internal::Command;
void setup() {
__syscall_EnterCriticalSection();
Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::SetupValue);
Memory_IO::CD_DELAY.write(Memory_IO::CD_DELAY::SetupValue);
//Equeue Callback?
__syscall_SysEnqIntRP(CdromIoIrq, &::JabyEngine::CD::internal::callback);
CD_IO::PortIndex1::change_to();
CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlagRegister);
@ -21,6 +28,15 @@ namespace JabyEngine {
Interrupt::ack_irq(Interrupt::CDROM);
Interrupt::enable_irq(Interrupt::CDROM);
__syscall_ExitCriticalSection();
CD_IO::PortIndex0::change_to();
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat);
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat);
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::Init);
// Demute?
}
}
}

View File

@ -1,8 +1,40 @@
#include "../../include/CD/cd_internal.hpp"
#include <PSX/System/IOPorts/interrupt_io.hpp>
#include <PSX/System/syscalls.h>
namespace JabyEngine {
namespace CD {
namespace internal {
VolatilePOD<CD_IO::Interrupt::Type> last_interrupt{CD_IO::Interrupt::Type::None};
static InterruptVerifierResult interrupt_verifier() {
if(Interrupt::is_irq(Interrupt::CDROM)) {
const uint8_t old_idx = (CD_IO::IndexStatus.read() & 0x3);
CD_IO::PortIndex1::change_to();
last_interrupt.write(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlagRegister));
CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlagRegister);
CD_IO::IndexStatus.write({old_idx});
return InterruptVerifierResult::ExecuteHandler;
}
else {
return InterruptVerifierResult::SkipHandler;
}
}
static void interrupt_handler(uint32_t) {
Interrupt::ack_irq(Interrupt::CDROM);
__syscall_ReturnFromException();
}
InterrupCallback callback = {
.next = nullptr,
.handler_function = reinterpret_cast<InterruptHandler>(interrupt_handler),
.verifier_function = interrupt_verifier
};
}
}
}