diff --git a/examples/PoolBox/application/src/menu.cpp b/examples/PoolBox/application/src/menu.cpp index afe4b942..931ff4ec 100644 --- a/examples/PoolBox/application/src/menu.cpp +++ b/examples/PoolBox/application/src/menu.cpp @@ -1,4 +1,5 @@ #include "include/menu.hpp" +#include #include namespace Menu { @@ -41,6 +42,9 @@ namespace Menu { } void BackMenu :: setup(JabyEngine::FontWriter* font_writer) { + const auto [first_track, last_track] = CDDA::get_tracks(); + CDDA::play(first_track); + this->font_writer = font_writer; this->timeout.reset(); this->waiting = false; diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index fa2cc9af..66f7e8c1 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -33,4 +33,5 @@ ../assets/audio/Evacuation_cdda.wav + ../assets/audio/Evacuation_cdda.wav \ No newline at end of file diff --git a/include/PSX/Audio/CDDA.hpp b/include/PSX/Audio/CDDA.hpp new file mode 100644 index 00000000..8c6dfecd --- /dev/null +++ b/include/PSX/Audio/CDDA.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "../jabyengine_defines.hpp" + +namespace JabyEngine { + namespace CDDA { + struct TrackList { + uint8_t first_track; + uint8_t last_track; + + static constexpr TrackList empty() { + return TrackList{.first_track = 0, .last_track = 0}; + } + }; + + TrackList get_tracks(); + + void play(uint8_t track); + 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 f9dd6d5f..f4b8ee97 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -153,10 +153,12 @@ namespace JabyEngine { static constexpr Desc GetStat{0x01, Interrupt::Type::Acknowledge}; static constexpr Desc SetLoc{0x02, Interrupt::Type::Acknowledge}; + static constexpr Desc Play{0x03, Interrupt::Type::Acknowledge}; 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 SetMode{0x0E, Interrupt::Type::Acknowledge}; + static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge}; }; static constexpr auto IORegister1Adr = 0x1F801801; diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index 525fe5a4..afa9c3d7 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -1,5 +1,6 @@ #pragma once #include "ioport.hpp" +#include namespace JabyEngine { namespace SPU_IO { @@ -156,6 +157,10 @@ namespace JabyEngine { __declare_io_port_w_type(inline, Adr, WorkAreaAdr, 0x1F801DA2); }; + static constexpr SimpleVolume operator""_vol(long double fraction) { + return {static_cast(static_cast(I16_MAX)*fraction)}; + } + __declare_io_port(, ControlRegister, 0x1F801DAA); __declare_io_port(, DataTransferControl, 0x1F801DAC); __declare_io_port(, PMON, 0x1F801D90); diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 45602186..79e9efcc 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -45,6 +45,8 @@ namespace JabyEngine { void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator); void continue_reading(); + + void enable_CDDA(); } } } \ No newline at end of file diff --git a/src/Library/src/Audio/CDDA.cpp b/src/Library/src/Audio/CDDA.cpp new file mode 100644 index 00000000..92b1fc76 --- /dev/null +++ b/src/Library/src/Audio/CDDA.cpp @@ -0,0 +1,36 @@ +#include "../../internal-include/CD/cd_internal.hpp" +#include +#include + +namespace JabyEngine { + namespace CDDA { + namespace CD = JabyEngine::CD::internal; + + TrackList get_tracks() { + CD::Command::wait_completed(); + + CD_IO::PortIndex0::change_to(); + CD::Command::send_wait(CD_IO::Command::GetTN); + + const auto stat = CD_IO::PortIndex0::ResponseFifo.read(); + const auto first = CD_IO::PortIndex0::ResponseFifo.read().raw; + const auto end = CD_IO::PortIndex0::ResponseFifo.read().raw; + const auto last_track = (end - first) + 1; + + if(last_track == 1) { + return TrackList::empty(); + } + + return TrackList{.first_track = 2, .last_track = static_cast(last_track)}; + } + + void play(uint8_t track) { + CD::enable_CDDA(); // < Command waits + CD::Command::send(CD_IO::Command::Play, track); + } + + void stop() { + + } + } +} \ No newline at end of file diff --git a/src/Library/src/BootLoader/spu_boot.cpp b/src/Library/src/BootLoader/spu_boot.cpp index 5654b15f..fe4733fb 100644 --- a/src/Library/src/BootLoader/spu_boot.cpp +++ b/src/Library/src/BootLoader/spu_boot.cpp @@ -15,8 +15,8 @@ namespace JabyEngine { } static void clear_cd_and_ext_audio_volume() { - CDVolume::Left.write({0}); - CDVolume::Right.write({0}); + CDVolume::Left.write(0.5_vol); + CDVolume::Right.write(0.5_vol); ExternalAudioInputVolume::Left.write({0}); ExternalAudioInputVolume::Right.write({0}); diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 72ad2083..df38ae1f 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -6,7 +6,8 @@ namespace JabyEngine { namespace CD { namespace internal { - 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::CDDA); + static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); static SysCall::InterruptVerifierResult interrupt_verifier(); static uint32_t interrupt_handler(uint32_t); @@ -136,6 +137,12 @@ namespace JabyEngine { read_cd(cur_lba); } } + + void enable_CDDA() { + Command::wait_completed(); + CD_IO::PortIndex0::change_to(); + Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); + } } } } \ No newline at end of file