diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index ed8a044e..f981aaac 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -31,6 +31,18 @@ namespace JabyEngine { static constexpr uint8_t Max = 0xFF; }; + __declare_io_type(Mode, uint8_t, + static constexpr auto DoubleSpeed = Bit(7); + static constexpr auto SingleSpeed = !DoubleSpeed; + static constexpr auto XADPCM = Bit(6); + static constexpr auto WholeSector = Bit(5); + static constexpr auto DataSector = !WholeSector; + static constexpr auto UseXAFilter = Bit(3); + static constexpr auto AudioPlayIRQ = Bit(2); + static constexpr auto AutoPauseTrack = Bit(1); + static constexpr auto CDDA = Bit(0); + ); + __declare_io_type(IndexStatus, uint8_t, static constexpr auto PortIndex = BitRange::from_to(0, 1); static constexpr auto HasXAFifoData = Bit(2); diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 7c555d27..aab215c5 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -5,20 +5,13 @@ namespace JabyEngine { namespace CD { namespace internal { + extern State current_state; extern CD_IO::Interrupt::Type last_interrupt; - extern State current_state; - - static CD_IO::Interrupt::Type read_last_interrupt() { - return const_cast(last_interrupt); - } - - static State read_current_state() { - return const_cast(current_state); - } + extern uint8_t cmd_interrupt_bit; struct Command { - static void wait_until(CD_IO::Interrupt::Type irq) { - while(read_last_interrupt() != irq); + static void wait_completed() { + while(const_cast(cmd_interrupt_bit) > 0); } template @@ -26,7 +19,8 @@ namespace JabyEngine { while(CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::IsTransmissionBusy)); ((parameter_fifo = args),...); - cmd_fifo = cmd.id; + cmd_fifo = cmd.id; + cmd_interrupt_bit = bit::set(0, cmd.complete_irq); } template @@ -37,7 +31,7 @@ namespace JabyEngine { template static void send_wait(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { send(cmd_fifo, parameter_fifo, cmd, args...); - wait_until(cmd.complete_irq); + wait_completed(); } template @@ -46,6 +40,10 @@ namespace JabyEngine { } }; + static State read_current_state() { + return const_cast(current_state); + } + void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); void continue_reading(); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 963a98f3..66590264 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -3,28 +3,26 @@ #include #include -#include - namespace JabyEngine { namespace CD { namespace internal { - __declare_io_type(Mode, uint8_t, - static constexpr auto DoubleSpeed = Bit(7); - static constexpr auto SingleSpeed = !DoubleSpeed; - static constexpr auto XADPCM = Bit(6); - static constexpr auto WholeSector = Bit(5); - static constexpr auto DataSector = !WholeSector; - static constexpr auto UseXAFilter = Bit(3); - static constexpr auto AudioPlayIRQ = Bit(2); - static constexpr auto AutoPauseTrack = Bit(1); - static constexpr auto CDDA = Bit(0); - ); - - static constexpr auto DataSectorMode = Mode_t::from(Mode_t::DoubleSpeed, Mode_t::DataSector); + static constexpr auto DataSectorMode = CD_IO::Mode_t::from(CD_IO::Mode_t::DoubleSpeed, CD_IO::Mode_t::DataSector); + static InterruptVerifierResult interrupt_verifier(); + static void interrupt_handler(uint32_t); + static SectorBufferAllocator sector_allocator; static uint16_t cur_lba; static uint16_t dst_lba; + + CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; + uint8_t cmd_interrupt_bit = 0; + State current_state = State::Free; + InterrupCallback callback = { + .next = nullptr, + .handler_function = reinterpret_cast(interrupt_handler), + .verifier_function = interrupt_verifier + }; static void pause_cd() { CD_IO::PortIndex0::change_to(); @@ -33,13 +31,11 @@ namespace JabyEngine { // Requires Index0 static void read_cd(uint16_t lba) { - const auto loc = CDTimeStamp::from(lba); + const auto loc = CDTimeStamp::from(lba); Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); Command::send(CD_IO::Command::ReadN); current_state = State::Reading; - - printf("Now reading: %i(%i:%i:%i)\n", lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } static void read_sector_dma(CD_IO::DataSector& sector) { @@ -81,6 +77,7 @@ namespace JabyEngine { last_interrupt = cur_irq; CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlag); + cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); if(cur_irq == CD_IO::Interrupt::DataReady) { // Obtain sector content here auto* sector = sector_allocator.allocate_sector(); @@ -120,19 +117,12 @@ namespace JabyEngine { __syscall_ReturnFromException(); } - CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; - State current_state = State::Free; - InterrupCallback callback = { - .next = nullptr, - .handler_function = reinterpret_cast(interrupt_handler), - .verifier_function = interrupt_verifier - }; - void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { cur_lba = file_info.lba; dst_lba = file_info.lba + file_info.sectors; sector_allocator = buffer_allocator; + Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); @@ -141,6 +131,7 @@ namespace JabyEngine { void continue_reading() { if(current_state == State::BufferFull) { + Command::wait_completed(); read_cd(cur_lba); } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index ac4e0a31..c3ee2ab5 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -78,13 +78,16 @@ namespace JabyEngine { } Progress CDFileProcessor :: process() { + const auto cur_state = CD::internal::read_current_state(); + CDFileProcessor::process_data(); - switch(CD::internal::read_current_state()) { + switch(cur_state) { case CD::internal::State::Done: /* We are done now! The user decides if he wants the next value */ + //while(this->file_state.process(0) != Progress::Done); return Progress::Done; case CD::internal::State::BufferFull: