From e1771fe1038ec48e2204a2bfab08a6d583bfcf67 Mon Sep 17 00:00:00 2001 From: Jaby Date: Fri, 31 May 2024 23:47:39 +0200 Subject: [PATCH] Start to move CDXA code around --- .../PoolBox/application/src/application.cpp | 10 +- .../internal-include/CD/cd_internal.hpp | 8 +- src/Library/internal-include/CD/cd_types.hpp | 22 ++-- src/Library/src/Audio/CDDA.cpp | 6 +- src/Library/src/Audio/CDXA.cpp | 55 ++++++++-- src/Library/src/CD/cd.cpp | 102 +++++++----------- 6 files changed, 101 insertions(+), 102 deletions(-) diff --git a/examples/PoolBox/application/src/application.cpp b/examples/PoolBox/application/src/application.cpp index 6825e1cf..96357e30 100644 --- a/examples/PoolBox/application/src/application.cpp +++ b/examples/PoolBox/application/src/application.cpp @@ -7,7 +7,6 @@ #include //#include #include -#include #include using namespace JabyEngine; @@ -149,7 +148,7 @@ namespace LoadingScene { static constexpr auto TitleLength = (sizeof(Title) - 1)*DefaultFont::Info.get_font_size().width; auto cursor = FontWriter::update(JabyEngine::Make::PositionI16((GPU::Display::Width-TitleLength)/2, (GPU::Display::Height-16)/2)); - FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Blue(0xD0)); + FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Blue(0xD0)); } static void render() { @@ -159,12 +158,8 @@ namespace LoadingScene { static void run() { if(old_state_changer != state_changer) { printf("Loading new state...\n"); - - Callback::VSyncCallback::install([]() { - // TODO: Use it or remove it!! - printf("Still loading...\n"); - }); + // TODO: Callback for file load? Locally? update(); GPU::swap_buffers_vsync(1); render(); @@ -175,7 +170,6 @@ namespace LoadingScene { state_changer.asset_load(); old_state_changer = state_changer; //CDDA::pop_play(); - Callback::VSyncCallback::uninstall(); } state_changer.main(); diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 95c044a2..e7121a8e 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -49,15 +49,19 @@ namespace JabyEngine { } }; + namespace IRQ { + void read_sector_to(uint32_t* dst, size_t bytes); + void resume_at(const BCDTimeStamp& cd_time); + } + static State read_current_state() { return const_cast(current_state); } void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator); - void read_xa(uint32_t lba, uint8_t channel); void continue_reading(); - CDTimeStamp get_lock(); + BCDTimeStamp get_loc(); void enable_CDDA(); void enable_CDXA(bool double_speed); diff --git a/src/Library/internal-include/CD/cd_types.hpp b/src/Library/internal-include/CD/cd_types.hpp index 27252172..19782f27 100644 --- a/src/Library/internal-include/CD/cd_types.hpp +++ b/src/Library/internal-include/CD/cd_types.hpp @@ -62,7 +62,7 @@ namespace JabyEngine { } }; - struct CDTimeStamp { + struct BCDTimeStamp { static constexpr size_t MaxSector = 75; static constexpr size_t MaxSeconds = 60; @@ -70,23 +70,15 @@ namespace JabyEngine { uint8_t sec; uint8_t sector; - static constexpr CDTimeStamp from(uint32_t lba) { + static constexpr BCDTimeStamp from_time(uint8_t min, uint8_t sec, uint8_t sectors) { + return BCDTimeStamp{.min = to_bcd(min), .sec = to_bcd(sec), .sector = to_bcd(sectors)}; + } + + static constexpr BCDTimeStamp from(uint32_t lba) { const auto [min, new_lba] = div_and_mod(lba, MaxSector*MaxSeconds); const auto [sec, sectors] = div_and_mod(new_lba, MaxSector); - return CDTimeStamp{static_cast(min), static_cast(sec), static_cast(sectors)}; - } - - constexpr uint8_t get_min_cd() const { - return to_bcd(this->min); - } - - constexpr uint8_t get_sec_cd() const { - return to_bcd(this->sec); - } - - constexpr uint8_t get_sector_cd() const { - return to_bcd(this->sector); + return BCDTimeStamp::from_time(min, sec, sectors); } }; } diff --git a/src/Library/src/Audio/CDDA.cpp b/src/Library/src/Audio/CDDA.cpp index 79b657fa..625968c6 100644 --- a/src/Library/src/Audio/CDDA.cpp +++ b/src/Library/src/Audio/CDDA.cpp @@ -5,8 +5,8 @@ namespace JabyEngine { namespace CDDA { namespace CD = JabyEngine::CD::internal; - static CD::CDTimeStamp playing_track; - static CD::CDTimeStamp last_track; + static CD::BCDTimeStamp playing_track; + static CD::BCDTimeStamp last_track; TrackList get_tracks() { CD::Command::wait_completed(); @@ -43,7 +43,7 @@ namespace JabyEngine { void push_play() { stop(); - last_track = CD::get_lock(); + last_track = CD::get_loc(); } void pop_play() { diff --git a/src/Library/src/Audio/CDXA.cpp b/src/Library/src/Audio/CDXA.cpp index 80d8cdc5..c116637e 100644 --- a/src/Library/src/Audio/CDXA.cpp +++ b/src/Library/src/Audio/CDXA.cpp @@ -1,33 +1,72 @@ #include "../../internal-include/CD/cd_internal.hpp" +#include "../../internal-include/CD/cd_types.hpp" #include namespace JabyEngine { namespace CDXA { namespace CD = JabyEngine::CD::internal; + static struct { + CD::BCDTimeStamp start_loc; + CD::BCDTimeStamp last_loc; + bool double_speed; + uint8_t channel; + } setting; + + CD::State interrupt_handler(uint8_t irq) { + switch(irq) { + case CD_IO::Interrupt::DataReady: { + // The IRQ stack is 0x1000 bytes large so this should fit + CD::RawXADataSector xa_file; + CD::IRQ::read_sector_to(reinterpret_cast(&xa_file), sizeof(CD::RawXADataSector)); + if(setting.channel == xa_file.sub_header.channel_number) { + CD::IRQ::resume_at(setting.start_loc); + CD::Command::send(CD_IO::Command::ReadS); + } + } break; + + case CD_IO::Interrupt::DiskError: + return CD::State::Error; + }; + return CD::State::XAMode; + } + void play(const volatile AutoLBAEntry* lba, uint8_t rel_lba_idx, uint8_t channel, bool double_speed) { + setting.start_loc = CD::BCDTimeStamp::from(lba[rel_lba_idx].get_lba()); + setting.double_speed = double_speed; + CD::enable_CDXA(double_speed); - CD::read_xa(lba[rel_lba_idx].get_lba(), channel); + set_channel(channel); + CD::Command::wait_completed(); + CD::Command::send_wait(CD_IO::Command::SetLoc, setting.start_loc.min, setting.start_loc.sec, setting.start_loc.sector); + CD::Command::send(CD_IO::Command::ReadS); } void stop() { + // TODO: Alias this? CD::pause(); } void set_channel(uint8_t channel) { - //CD::Command::send(CD_IO::Command::Filter, File, channel); + static constexpr uint8_t File = 1; + + CD::Command::send(CD_IO::Command::Filter, File, channel); + setting.channel = channel; } void push_play() { - /*stop(); - last_track = CD::get_lock();*/ + stop(); + setting.last_loc = CD::get_loc(); } void pop_play() { - /*CD::Command::wait_completed(); - CD::enable_CDDA(); // < Command waits - CD::Command::send_wait(CD_IO::Command::SetLoc, last_track.min, last_track.sec, last_track.sector); - CD::Command::send(CD_IO::Command::Play);*/ + CD::Command::wait_completed(); + CD::enable_CDXA(setting.double_speed); + + set_channel(setting.channel); + CD::Command::wait_completed(); + CD::Command::send_wait(CD_IO::Command::SetLoc, setting.last_loc.min, setting.last_loc.sec, setting.last_loc.sector); + CD::Command::send(CD_IO::Command::ReadS); } } } \ No newline at end of file diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 9d566e17..9924d6c2 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -5,31 +5,25 @@ #include namespace JabyEngine { + namespace CDXA { + CD::internal::State interrupt_handler(uint8_t irq); + } + namespace CD { - namespace internal { - union Configuration { - struct File { - uint32_t cur_lba; - uint32_t dst_lba; + namespace internal { + struct File { + uint32_t cur_lba; + uint32_t dst_lba; - void set_from(const AutoLBAEntry& file_info) { - this->cur_lba = file_info.get_lba(); - this->dst_lba = this->cur_lba + file_info.get_size_in_sectors(); - } + void set_from(const AutoLBAEntry& file_info) { + this->cur_lba = file_info.get_lba(); + this->dst_lba = this->cur_lba + file_info.get_size_in_sectors(); + } - bool done_processing() { - this->cur_lba++; - return this->cur_lba == this->dst_lba; - } - }; - - struct XA { - CDTimeStamp start_time; - uint8_t channel; - }; - - File file; - XA xa; + bool done_processing() { + this->cur_lba++; + return this->cur_lba == this->dst_lba; + } }; static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); @@ -42,7 +36,7 @@ namespace JabyEngine { } static SectorBufferAllocator sector_allocator; - static Configuration cur_cfg; + static File cur_file; uint8_t cmd_interrupt_bit = 0; State current_state = State::Ready; @@ -52,11 +46,10 @@ namespace JabyEngine { .verifier_function = IRQ::verifier }; - // Requires Index0 - static CDTimeStamp send_read_cmd(uint32_t lba, CD_IO::Command::Desc desc) { - const auto loc = CDTimeStamp::from(lba); + static BCDTimeStamp send_read_cmd(uint32_t lba, CD_IO::Command::Desc desc) { + const auto loc = BCDTimeStamp::from(lba); - Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); + Command::send_wait(CD_IO::Command::SetLoc, loc.min, loc.sec, loc.sector); Command::send(desc); return loc; } @@ -86,7 +79,7 @@ namespace JabyEngine { ReadSector(dst, bytes); } - static void read_sector_to(uint32_t* dst, size_t bytes) { + void read_sector_to(uint32_t* dst, size_t bytes) { CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data()); // We only support DMA rn @@ -96,8 +89,8 @@ namespace JabyEngine { // Doesn't seem to important when we can use DMA } - static void resume_at(const CDTimeStamp& cd_time) { - Command::send(CD_IO::Command::SetLoc, cd_time.get_min_cd(), cd_time.get_sec_cd(), cd_time.get_sector_cd()); + void resume_at(const BCDTimeStamp& cd_time) { + Command::send(CD_IO::Command::SetLoc, cd_time.min, cd_time.sec, cd_time.sector); CD_IO::PortIndex1::change_to(); while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); @@ -137,7 +130,7 @@ namespace JabyEngine { //Now obtain sector read_sector_to(sector->data, CD_IO::DataSector::SizeBytes); - if(cur_cfg.file.done_processing()) { + if(cur_file.done_processing()) { current_state = State::Done; pause(); } @@ -151,7 +144,7 @@ namespace JabyEngine { case CD_IO::Interrupt::DataEnd: { // TODO: Fix this!! This is a freaking static time - resume_at(CDTimeStamp{.min = 0, .sec = 9, .sector = 0}); + resume_at(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0}); Command::send(CD_IO::Command::Play); } break; @@ -162,22 +155,7 @@ namespace JabyEngine { } else { - switch(cur_irq) { - case CD_IO::Interrupt::DataReady: { - // The IRQ stack is 0x1000 bytes large so this should fit - RawXADataSector xa_file; - - read_sector_to(reinterpret_cast(&xa_file), sizeof(RawXADataSector)); - if(cur_cfg.xa.channel == xa_file.sub_header.channel_number) { - resume_at(cur_cfg.xa.start_time); - Command::send(CD_IO::Command::ReadS); - } - } break; - - case CD_IO::Interrupt::DiskError: { - current_state = State::Error; - } break; - }; + current_state = CDXA::interrupt_handler(cur_irq); } // No masking required because we can only write bit 0 - 2 @@ -190,33 +168,24 @@ namespace JabyEngine { } void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) { - cur_cfg.file.set_from(file_info); + cur_file.set_from(file_info); sector_allocator = buffer_allocator; Command::wait_completed(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); - send_read_n(cur_cfg.file.cur_lba); + send_read_n(cur_file.cur_lba); } - void read_xa(uint32_t lba, uint8_t channel) { - static constexpr uint8_t File = 1; - - cur_cfg.xa.channel = channel; - Command::send_wait(CD_IO::Command::Filter, File, channel); - - cur_cfg.xa.start_time = send_read_cmd(lba, CD_IO::Command::ReadS); - current_state = State::XAMode; - } void continue_reading() { if(current_state == State::BufferFull) { Command::wait_completed(); - send_read_n(cur_cfg.file.cur_lba); + send_read_n(cur_file.cur_lba); } } - CDTimeStamp get_lock() { + BCDTimeStamp get_loc() { Command::wait_completed(); Command::send_wait(CD_IO::Command::GetLocP); @@ -226,11 +195,11 @@ namespace JabyEngine { const auto ss = CD_IO::PortIndex0::ResponseFifo.read().raw; // second number within track (00h to 59h) const auto sect = CD_IO::PortIndex0::ResponseFifo.read().raw; // sector number within track (00h to 74h) - return CDTimeStamp{ - .min = CD_IO::PortIndex0::ResponseFifo.read().raw, // minute number on entire disk (00h and up) - .sec = CD_IO::PortIndex0::ResponseFifo.read().raw, // second number on entire disk (00h to 59h) - .sector = CD_IO::PortIndex0::ResponseFifo.read().raw, // sector number on entire disk (00h to 74h) - }; + return BCDTimeStamp::from_time( + CD_IO::PortIndex0::ResponseFifo.read().raw, // minute number on entire disk (00h and up) + CD_IO::PortIndex0::ResponseFifo.read().raw, // second number on entire disk (00h to 59h) + CD_IO::PortIndex0::ResponseFifo.read().raw // sector number on entire disk (00h to 74h) + ); } void enable_CDDA() { @@ -246,6 +215,7 @@ namespace JabyEngine { Command::wait_completed(); Command::send_wait(CD_IO::Command::SetMode, mode); + current_state = State::XAMode; } } }