diff --git a/examples/PoolBox/application/include/asset_mgr.hpp b/examples/PoolBox/application/include/asset_mgr.hpp index fabff1c9..8997a262 100644 --- a/examples/PoolBox/application/include/asset_mgr.hpp +++ b/examples/PoolBox/application/include/asset_mgr.hpp @@ -27,4 +27,8 @@ namespace Assets { void load_font_cycler(); void load_screen_center(); } + + namespace XAAudio { + void play_fox(); + } } \ No newline at end of file diff --git a/examples/PoolBox/application/src/application.cpp b/examples/PoolBox/application/src/application.cpp index 902ca15e..6825e1cf 100644 --- a/examples/PoolBox/application/src/application.cpp +++ b/examples/PoolBox/application/src/application.cpp @@ -5,7 +5,7 @@ #include "Overlay/Overlays.hpp" #include #include -#include +//#include #include #include #include @@ -105,8 +105,11 @@ static void setup() { } },MenuEntries); - const auto [first_track, last_track] = CDDA::get_tracks(); - CDDA::play(first_track); + // TODO: CDDA? + // const auto [first_track, last_track] = CDDA::get_tracks(); + // CDDA::play(first_track); + + Assets::XAAudio::play_fox(); } namespace NormalScene { @@ -158,6 +161,7 @@ namespace LoadingScene { printf("Loading new state...\n"); Callback::VSyncCallback::install([]() { + // TODO: Use it or remove it!! printf("Still loading...\n"); }); @@ -166,10 +170,11 @@ namespace LoadingScene { render(); GPU::swap_buffers_vsync(1); - CDDA::push_play(); + // TODO: Enable push and pop + //CDDA::push_play(); state_changer.asset_load(); old_state_changer = state_changer; - CDDA::pop_play(); + //CDDA::pop_play(); Callback::VSyncCallback::uninstall(); } diff --git a/examples/PoolBox/application/src/asset_mgr.cpp b/examples/PoolBox/application/src/asset_mgr.cpp index 489ee14e..a2efde13 100644 --- a/examples/PoolBox/application/src/asset_mgr.cpp +++ b/examples/PoolBox/application/src/asset_mgr.cpp @@ -1,8 +1,9 @@ #include "../include/asset_mgr.hpp" #include "Overlay/Overlays.hpp" -#include +#include #include #include +#include #include extern "C" uint32_t __bios_info_start; @@ -15,6 +16,7 @@ namespace Assets { __jabyengine_start_lba_request __jabyengine_request_lba_for(PACO, "ASSETS/MAIN/PACO.BIN"), __jabyengine_request_lba_for(DFISH, "ASSETS/MAIN/DFISH.BIN"), + __jabyengine_request_lba_for(FOX_XA, "XAAUDIO/FOX.XA"), __jabyengine_request_lba_for(BIOS_INFO_OVL, "BIO.BIN"), __jabyengine_request_lba_for(GPU_TEST_OVL, "GTO.BIN"), __jabyengine_request_lba_for(GTE_TEST_OVL, "GTE.BIN"), @@ -106,4 +108,10 @@ namespace Assets { load(CDFileBuilder::overlay(LBA::SCREEN_CENT_OVL, &__screen_center_start)); } } + + namespace XAAudio { + void play_fox() { + CDXA::play(lba, CDXA::CDFile{FOX_XA}, 0); + } + } } \ No newline at end of file diff --git a/include/PSX/Audio/CDXA.hpp b/include/PSX/Audio/CDXA.hpp new file mode 100644 index 00000000..d89a506f --- /dev/null +++ b/include/PSX/Audio/CDXA.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "../AutoLBA/auto_lba.hpp" + +namespace JabyEngine { + namespace CDXA { + struct CDFile { + uint8_t rel_lba_idx; + }; + + void play(const volatile AutoLBAEntry* lba, const CDFile& file, uint8_t channel); + void stop(); + } +} \ No newline at end of file diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 1ea6ecf0..021ca914 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -157,10 +157,12 @@ namespace JabyEngine { static constexpr Desc ReadN{0x06, Interrupt::Type::DataReady}; static constexpr Desc Pause{0x09, Interrupt::Type::Complete}; static constexpr Desc Init{0x0A, Interrupt::Type::Complete}; + static constexpr Desc Filter{0x0D, Interrupt::Type::Acknowledge}; static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge}; static constexpr Desc GetLocP{0x11, Interrupt::Type::Acknowledge}; static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge}; static constexpr Desc GetTD{0x14, Interrupt::Type::Acknowledge}; + static constexpr Desc ReadS{0x1B, Interrupt::Type::DataReady}; }; static constexpr auto IORegister1Adr = 0x1F801801; diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 71ce373c..e6070ea4 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -45,7 +45,16 @@ namespace JabyEngine { void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator); void continue_reading(); + void read_n(uint32_t lba); + void read_s(uint32_t lba); + void enable_CDDA(); + void enable_CDXA(bool double_speed); + + static void pause() { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Pause); + } } } } \ No newline at end of file diff --git a/src/Library/internal-include/CD/cd_types.hpp b/src/Library/internal-include/CD/cd_types.hpp index f88fbc96..287e3748 100644 --- a/src/Library/internal-include/CD/cd_types.hpp +++ b/src/Library/internal-include/CD/cd_types.hpp @@ -8,8 +8,8 @@ namespace JabyEngine { namespace CD { namespace internal { enum struct State { - Free = 0, - Done = 0, + Ready = 0, + Done = 0, Reading, BufferFull, diff --git a/src/Library/src/Audio/CDDA.cpp b/src/Library/src/Audio/CDDA.cpp index 8888ae88..ed556bf5 100644 --- a/src/Library/src/Audio/CDDA.cpp +++ b/src/Library/src/Audio/CDDA.cpp @@ -38,8 +38,7 @@ namespace JabyEngine { } void stop() { - CD::Command::wait_completed(); - CD::Command::send(CD_IO::Command::Pause); + CD::pause(); } void push_play() { diff --git a/src/Library/src/Audio/CDXA.cpp b/src/Library/src/Audio/CDXA.cpp new file mode 100644 index 00000000..2c38cd6c --- /dev/null +++ b/src/Library/src/Audio/CDXA.cpp @@ -0,0 +1,20 @@ +#include "../../internal-include/CD/cd_internal.hpp" +#include + +namespace JabyEngine { + namespace CDXA { + namespace CD = JabyEngine::CD::internal; + + void play(const volatile AutoLBAEntry* lba, const CDFile& file, uint8_t channel) { + static constexpr uint8_t File = 0; + + CD::enable_CDXA(false); + CD::Command::send_wait(CD_IO::Command::Filter, File, channel); + CD::read_s(lba[file.rel_lba_idx].get_lba()); + } + + void stop() { + CD::pause(); + } + } +} \ No newline at end of file diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 39d3f992..0d62723c 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -7,8 +7,9 @@ namespace JabyEngine { namespace CD { namespace internal { - static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); - static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); + static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); + static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); + static constexpr auto XAAudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::XADPCM, CD_IO::Mode::WholeSector, CD_IO::Mode::UseXAFilter); static SysCall::InterruptVerifierResult interrupt_verifier(); static uint32_t interrupt_handler(uint32_t); @@ -18,25 +19,21 @@ namespace JabyEngine { static uint32_t dst_lba; uint8_t cmd_interrupt_bit = 0; - State current_state = State::Free; + State current_state = State::Ready; SysCall::InterrupCallback callback = { .next = nullptr, .handler_function = interrupt_handler, .verifier_function = interrupt_verifier }; - static void pause_cd() { - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Pause); - } - // Requires Index0 - static void read_cd(uint32_t lba) { + static void read_cd(uint32_t lba, CD_IO::Command::Desc desc) { 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); + Command::send(desc); current_state = State::Reading; + printf("Done??\n"); } static void read_sector_dma(CD_IO::DataSector& sector) { @@ -87,42 +84,49 @@ namespace JabyEngine { CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); - switch(cur_irq) { - case CD_IO::Interrupt::DataReady: { - // Obtain sector content here - auto* sector = sector_allocator.allocate_sector(); - if(sector) { - //Now obtain sector - read_sector_to(*sector); - cur_lba++; - if(cur_lba == dst_lba) { - current_state = State::Done; - pause_cd(); + if(!CD_IO::IndexStatus.read().is_set(CD_IO::IndexStatus::HasXAFifoData)) { + switch(cur_irq) { + case CD_IO::Interrupt::DataReady: { + // Obtain sector content here + auto* sector = sector_allocator.allocate_sector(); + if(sector) { + //Now obtain sector + read_sector_to(*sector); + + cur_lba++; + if(cur_lba == dst_lba) { + current_state = State::Done; + pause(); + } } - } - else { - current_state = State::BufferFull; - pause_cd(); - } - } break; + else { + current_state = State::BufferFull; + pause(); + } + } break; - case CD_IO::Interrupt::DataEnd: { - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); + case CD_IO::Interrupt::DataEnd: { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); - CD_IO::PortIndex1::change_to(); - while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + CD_IO::PortIndex1::change_to(); + while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Play); - } break; + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Play); + } break; - case CD_IO::Interrupt::DiskError: { - current_state = State::Error; - } break; + case CD_IO::Interrupt::DiskError: { + current_state = State::Error; + } break; + } + } + + else { + printf("Playing CDXA\n"); } // No masking required because we can only write bit 0 - 2 @@ -141,21 +145,41 @@ namespace JabyEngine { CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); - read_cd(cur_lba); + read_n(cur_lba); } void continue_reading() { if(current_state == State::BufferFull) { Command::wait_completed(); - read_cd(cur_lba); + read_n(cur_lba); } } + void read_n(uint32_t lba) { + read_cd(lba, CD_IO::Command::ReadN); + } + + void read_s(uint32_t lba) { + printf("Now ReadS %i\n", lba); + read_cd(lba, CD_IO::Command::ReadS); + } + void enable_CDDA() { Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); } + + void enable_CDXA(bool double_speed) { + static constexpr uint8_t SingleSpeedBit = 0x0; + static constexpr uint8_t DoubleSpeedBit = static_cast(CD_IO::Mode::DoubleSpeed); + + const uint8_t mode = XAAudioSectorMode.raw | (double_speed ? DoubleSpeedBit : SingleSpeedBit); + + Command::wait_completed(); + CD_IO::PortIndex0::change_to(); + Command::send_wait(CD_IO::Command::SetMode, mode); + } } } } \ No newline at end of file