Setup CD drive
This commit is contained in:
parent
2250be6df9
commit
c07556895d
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue