jabyengine/src/Library/src/Audio/CDXA.cpp

83 lines
3.4 KiB
C++

#include "../../internal-include/CD/cd_internal.hpp"
#include "../../internal-include/CD/cd_types.hpp"
#include <PSX/Audio/CDXA.hpp>
namespace JabyEngine {
namespace CDXA {
namespace CD = JabyEngine::CD::internal;
static struct {
CD::BCDTimeStamp start_loc;
CD::BCDTimeStamp last_loc;
bool double_speed;
bool get_loc_functional; //< TODO: Really wanna use that?
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_IO::PortIndex0::change_to();
CD::IRQ::read_sector_to0(reinterpret_cast<uint32_t*>(&xa_file), sizeof(CD::RawXADataSector));
if(setting.channel == xa_file.sub_header.channel_number) {
CD::IRQ::resume_at0(setting.start_loc);
CD::Command::send(CD_IO::Command::ReadS);
}
else {
if(!setting.get_loc_functional) {
setting.last_loc.min = xa_file.header.minute;
setting.last_loc.sec = xa_file.header.second;
setting.last_loc.sector = xa_file.header.sector;
}
}
} 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;
setting.get_loc_functional = !CD::get_loc().is_zero();
CD::enable_CDXA(double_speed); //< Activates PortIndex0
set_channel(channel);printf("!!0-%X %X %X\n", setting.start_loc.min, setting.start_loc.sec, setting.start_loc.sector);
CD::Command::send(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() {
CD::pause();
}
void set_channel(uint8_t channel) {
static constexpr uint8_t File = 1;
CD::Command::send(CD_IO::Command::Filter, File, channel);
setting.channel = channel;
}
void push_play() {
stop();
if(setting.get_loc_functional) {
setting.last_loc = CD::get_loc();
}
CD::current_state = CD::State::Ready;
}
void pop_play() {
CD::enable_CDXA(setting.double_speed); //< Activates PortIndex0
set_channel(setting.channel);printf("!!1-%X %X %X\n", setting.last_loc.min, setting.last_loc.sec, setting.last_loc.sector);
CD::Command::send_wait_response(CD_IO::Command::SetLoc, setting.last_loc.min, setting.last_loc.sec, setting.last_loc.sector);
CD::Command::send(CD_IO::Command::ReadS);
}
}
}