Support CDDA auto-repeat

This commit is contained in:
Jaby 2024-05-09 14:13:28 +02:00
parent eba022bc10
commit 0618aa1fb7
4 changed files with 45 additions and 24 deletions

View File

@ -15,7 +15,7 @@ namespace JabyEngine {
TrackList get_tracks(); TrackList get_tracks();
void play(uint8_t track); void play(uint8_t track);
void pause(); void stop();
void push_play(); void push_play();
void pop_play(); void pop_play();

View File

@ -160,6 +160,7 @@ namespace JabyEngine {
static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge}; static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge};
static constexpr Desc GetLocP{0x11, Interrupt::Type::Acknowledge}; static constexpr Desc GetLocP{0x11, Interrupt::Type::Acknowledge};
static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge}; static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge};
static constexpr Desc GetTD{0x14, Interrupt::Type::Acknowledge};
}; };
static constexpr auto IORegister1Adr = 0x1F801801; static constexpr auto IORegister1Adr = 0x1F801801;

View File

@ -1,11 +1,11 @@
#include "../../internal-include/CD/cd_internal.hpp" #include "../../internal-include/CD/cd_internal.hpp"
#include <PSX/Audio/CDDA.hpp> #include <PSX/Audio/CDDA.hpp>
#include <stdio.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace CDDA { namespace CDDA {
namespace CD = JabyEngine::CD::internal; namespace CD = JabyEngine::CD::internal;
static CD::CDTimeStamp playing_track;
static CD::CDTimeStamp last_track; static CD::CDTimeStamp last_track;
TrackList get_tracks() { TrackList get_tracks() {
@ -28,16 +28,22 @@ namespace JabyEngine {
void play(uint8_t track) { void play(uint8_t track) {
CD::enable_CDDA(); // < Command waits CD::enable_CDDA(); // < Command waits
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetTD, track);
const auto stats = CD_IO::PortIndex0::ResponseFifo.read().raw;
playing_track.min = CD_IO::PortIndex0::ResponseFifo.read().raw;
playing_track.sec = CD_IO::PortIndex0::ResponseFifo.read().raw;
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play, track); CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play, track);
} }
void pause() { void stop() {
CD::Command::wait_completed(); CD::Command::wait_completed();
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Pause); CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Pause);
} }
void push_play() { void push_play() {
pause(); stop();
CD::Command::wait_completed(); CD::Command::wait_completed();
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetLocP); CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetLocP);
@ -53,8 +59,8 @@ namespace JabyEngine {
void pop_play() { void pop_play() {
CD::Command::wait_completed(); CD::Command::wait_completed();
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, last_track.min, last_track.sec, last_track.sector);
CD::enable_CDDA(); // < Command waits CD::enable_CDDA(); // < Command waits
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, last_track.min, last_track.sec, last_track.sector);
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play); CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play);
} }
} }

View File

@ -6,7 +6,7 @@
namespace JabyEngine { namespace JabyEngine {
namespace CD { namespace CD {
namespace internal { namespace internal {
static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::CDDA); 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 DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector);
static SysCall::InterruptVerifierResult interrupt_verifier(); static SysCall::InterruptVerifierResult interrupt_verifier();
@ -88,28 +88,42 @@ namespace JabyEngine {
CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag);
cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq);
if(cur_irq == CD_IO::Interrupt::DataReady) { switch(cur_irq) {
// Obtain sector content here case CD_IO::Interrupt::DataReady: {
auto* sector = sector_allocator.allocate_sector(); // Obtain sector content here
if(sector) { auto* sector = sector_allocator.allocate_sector();
//Now obtain sector if(sector) {
read_sector_to(*sector); //Now obtain sector
read_sector_to(*sector);
cur_lba++; cur_lba++;
if(cur_lba == dst_lba) { if(cur_lba == dst_lba) {
current_state = State::Done; current_state = State::Done;
pause_cd();
}
}
else {
current_state = State::BufferFull;
pause_cd(); pause_cd();
} }
} } break;
else { case CD_IO::Interrupt::DataEnd: {
current_state = State::BufferFull; CD_IO::PortIndex0::change_to();
pause_cd(); Command::send<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, static_cast<uint8_t>(0x0), static_cast<uint8_t>(0x09), static_cast<uint8_t>(0x0));
}
}
else if(cur_irq == CD_IO::Interrupt::DiskError) { CD_IO::PortIndex1::change_to();
current_state = State::Error; 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::PortIndex0>(CD_IO::Command::Play);
} break;
case CD_IO::Interrupt::DiskError: {
current_state = State::Error;
} break;
} }
// No masking required because we can only write bit 0 - 2 // No masking required because we can only write bit 0 - 2
@ -141,7 +155,7 @@ namespace JabyEngine {
void enable_CDDA() { void enable_CDDA() {
Command::wait_completed(); Command::wait_completed();
CD_IO::PortIndex0::change_to(); CD_IO::PortIndex0::change_to();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, AudioSectorMode); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, AudioSectorMode);
} }
} }
} }