Support CDDA auto-repeat
This commit is contained in:
parent
eba022bc10
commit
0618aa1fb7
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue