Start to move CDXA code around

This commit is contained in:
Jaby 2024-05-31 23:47:39 +02:00
parent 3eb2cc350f
commit fb79f6dc8b
6 changed files with 101 additions and 102 deletions

View File

@ -7,7 +7,6 @@
#include <FontWriter/font_writer.hpp>
//#include <PSX/Audio/CDDA.hpp>
#include <PSX/Periphery/periphery.hpp>
#include <PSX/System/callbacks.hpp>
#include <stdio.hpp>
using namespace JabyEngine;
@ -149,7 +148,7 @@ namespace LoadingScene {
static constexpr auto TitleLength = (sizeof(Title) - 1)*DefaultFont::Info.get_font_size().width;
auto cursor = FontWriter::update(JabyEngine::Make::PositionI16((GPU::Display::Width-TitleLength)/2, (GPU::Display::Height-16)/2));
FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Blue(0xD0));
FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Blue(0xD0));
}
static void render() {
@ -159,12 +158,8 @@ namespace LoadingScene {
static void run() {
if(old_state_changer != state_changer) {
printf("Loading new state...\n");
Callback::VSyncCallback::install([]() {
// TODO: Use it or remove it!!
printf("Still loading...\n");
});
// TODO: Callback for file load? Locally?
update();
GPU::swap_buffers_vsync(1);
render();
@ -175,7 +170,6 @@ namespace LoadingScene {
state_changer.asset_load();
old_state_changer = state_changer;
//CDDA::pop_play();
Callback::VSyncCallback::uninstall();
}
state_changer.main();

View File

@ -49,15 +49,19 @@ namespace JabyEngine {
}
};
namespace IRQ {
void read_sector_to(uint32_t* dst, size_t bytes);
void resume_at(const BCDTimeStamp& cd_time);
}
static State read_current_state() {
return const_cast<volatile State&>(current_state);
}
void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator);
void read_xa(uint32_t lba, uint8_t channel);
void continue_reading();
CDTimeStamp get_lock();
BCDTimeStamp get_loc();
void enable_CDDA();
void enable_CDXA(bool double_speed);

View File

@ -62,7 +62,7 @@ namespace JabyEngine {
}
};
struct CDTimeStamp {
struct BCDTimeStamp {
static constexpr size_t MaxSector = 75;
static constexpr size_t MaxSeconds = 60;
@ -70,23 +70,15 @@ namespace JabyEngine {
uint8_t sec;
uint8_t sector;
static constexpr CDTimeStamp from(uint32_t lba) {
static constexpr BCDTimeStamp from_time(uint8_t min, uint8_t sec, uint8_t sectors) {
return BCDTimeStamp{.min = to_bcd(min), .sec = to_bcd(sec), .sector = to_bcd(sectors)};
}
static constexpr BCDTimeStamp from(uint32_t lba) {
const auto [min, new_lba] = div_and_mod(lba, MaxSector*MaxSeconds);
const auto [sec, sectors] = div_and_mod(new_lba, MaxSector);
return CDTimeStamp{static_cast<uint8_t>(min), static_cast<uint8_t>(sec), static_cast<uint8_t>(sectors)};
}
constexpr uint8_t get_min_cd() const {
return to_bcd(this->min);
}
constexpr uint8_t get_sec_cd() const {
return to_bcd(this->sec);
}
constexpr uint8_t get_sector_cd() const {
return to_bcd(this->sector);
return BCDTimeStamp::from_time(min, sec, sectors);
}
};
}

View File

@ -5,8 +5,8 @@ namespace JabyEngine {
namespace CDDA {
namespace CD = JabyEngine::CD::internal;
static CD::CDTimeStamp playing_track;
static CD::CDTimeStamp last_track;
static CD::BCDTimeStamp playing_track;
static CD::BCDTimeStamp last_track;
TrackList get_tracks() {
CD::Command::wait_completed();
@ -43,7 +43,7 @@ namespace JabyEngine {
void push_play() {
stop();
last_track = CD::get_lock();
last_track = CD::get_loc();
}
void pop_play() {

View File

@ -1,33 +1,72 @@
#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;
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::IRQ::read_sector_to(reinterpret_cast<uint32_t*>(&xa_file), sizeof(CD::RawXADataSector));
if(setting.channel == xa_file.sub_header.channel_number) {
CD::IRQ::resume_at(setting.start_loc);
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS);
}
} 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;
CD::enable_CDXA(double_speed);
CD::read_xa(lba[rel_lba_idx].get_lba(), channel);
set_channel(channel);
CD::Command::wait_completed();
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, setting.start_loc.min, setting.start_loc.sec, setting.start_loc.sector);
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS);
}
void stop() {
// TODO: Alias this?
CD::pause();
}
void set_channel(uint8_t channel) {
//CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Filter, File, channel);
static constexpr uint8_t File = 1;
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Filter, File, channel);
setting.channel = channel;
}
void push_play() {
/*stop();
last_track = CD::get_lock();*/
stop();
setting.last_loc = CD::get_loc();
}
void pop_play() {
/*CD::Command::wait_completed();
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::wait_completed();
CD::enable_CDXA(setting.double_speed);
set_channel(setting.channel);
CD::Command::wait_completed();
CD::Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, setting.last_loc.min, setting.last_loc.sec, setting.last_loc.sector);
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS);
}
}
}

View File

@ -5,31 +5,25 @@
#include <stdio.hpp>
namespace JabyEngine {
namespace CDXA {
CD::internal::State interrupt_handler(uint8_t irq);
}
namespace CD {
namespace internal {
union Configuration {
struct File {
uint32_t cur_lba;
uint32_t dst_lba;
namespace internal {
struct File {
uint32_t cur_lba;
uint32_t dst_lba;
void set_from(const AutoLBAEntry& file_info) {
this->cur_lba = file_info.get_lba();
this->dst_lba = this->cur_lba + file_info.get_size_in_sectors();
}
void set_from(const AutoLBAEntry& file_info) {
this->cur_lba = file_info.get_lba();
this->dst_lba = this->cur_lba + file_info.get_size_in_sectors();
}
bool done_processing() {
this->cur_lba++;
return this->cur_lba == this->dst_lba;
}
};
struct XA {
CDTimeStamp start_time;
uint8_t channel;
};
File file;
XA xa;
bool done_processing() {
this->cur_lba++;
return this->cur_lba == this->dst_lba;
}
};
static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA);
@ -42,7 +36,7 @@ namespace JabyEngine {
}
static SectorBufferAllocator sector_allocator;
static Configuration cur_cfg;
static File cur_file;
uint8_t cmd_interrupt_bit = 0;
State current_state = State::Ready;
@ -52,11 +46,10 @@ namespace JabyEngine {
.verifier_function = IRQ::verifier
};
// Requires Index0
static CDTimeStamp send_read_cmd(uint32_t lba, CD_IO::Command::Desc desc) {
const auto loc = CDTimeStamp::from(lba);
static BCDTimeStamp send_read_cmd(uint32_t lba, CD_IO::Command::Desc desc) {
const auto loc = BCDTimeStamp::from(lba);
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd());
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.min, loc.sec, loc.sector);
Command::send<CD_IO::PortIndex0>(desc);
return loc;
}
@ -86,7 +79,7 @@ namespace JabyEngine {
ReadSector(dst, bytes);
}
static void read_sector_to(uint32_t* dst, size_t bytes) {
void read_sector_to(uint32_t* dst, size_t bytes) {
CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data());
// We only support DMA rn
@ -96,8 +89,8 @@ namespace JabyEngine {
// Doesn't seem to important when we can use DMA
}
static void resume_at(const CDTimeStamp& cd_time) {
Command::send<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, cd_time.get_min_cd(), cd_time.get_sec_cd(), cd_time.get_sector_cd());
void resume_at(const BCDTimeStamp& cd_time) {
Command::send<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, cd_time.min, cd_time.sec, cd_time.sector);
CD_IO::PortIndex1::change_to();
while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge);
@ -137,7 +130,7 @@ namespace JabyEngine {
//Now obtain sector
read_sector_to(sector->data, CD_IO::DataSector::SizeBytes);
if(cur_cfg.file.done_processing()) {
if(cur_file.done_processing()) {
current_state = State::Done;
pause();
}
@ -151,7 +144,7 @@ namespace JabyEngine {
case CD_IO::Interrupt::DataEnd: {
// TODO: Fix this!! This is a freaking static time
resume_at(CDTimeStamp{.min = 0, .sec = 9, .sector = 0});
resume_at(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0});
Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play);
} break;
@ -162,22 +155,7 @@ namespace JabyEngine {
}
else {
switch(cur_irq) {
case CD_IO::Interrupt::DataReady: {
// The IRQ stack is 0x1000 bytes large so this should fit
RawXADataSector xa_file;
read_sector_to(reinterpret_cast<uint32_t*>(&xa_file), sizeof(RawXADataSector));
if(cur_cfg.xa.channel == xa_file.sub_header.channel_number) {
resume_at(cur_cfg.xa.start_time);
Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS);
}
} break;
case CD_IO::Interrupt::DiskError: {
current_state = State::Error;
} break;
};
current_state = CDXA::interrupt_handler(cur_irq);
}
// No masking required because we can only write bit 0 - 2
@ -190,33 +168,24 @@ namespace JabyEngine {
}
void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) {
cur_cfg.file.set_from(file_info);
cur_file.set_from(file_info);
sector_allocator = buffer_allocator;
Command::wait_completed();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode);
send_read_n(cur_cfg.file.cur_lba);
send_read_n(cur_file.cur_lba);
}
void read_xa(uint32_t lba, uint8_t channel) {
static constexpr uint8_t File = 1;
cur_cfg.xa.channel = channel;
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::Filter, File, channel);
cur_cfg.xa.start_time = send_read_cmd(lba, CD_IO::Command::ReadS);
current_state = State::XAMode;
}
void continue_reading() {
if(current_state == State::BufferFull) {
Command::wait_completed();
send_read_n(cur_cfg.file.cur_lba);
send_read_n(cur_file.cur_lba);
}
}
CDTimeStamp get_lock() {
BCDTimeStamp get_loc() {
Command::wait_completed();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetLocP);
@ -226,11 +195,11 @@ namespace JabyEngine {
const auto ss = CD_IO::PortIndex0::ResponseFifo.read().raw; // second number within track (00h to 59h)
const auto sect = CD_IO::PortIndex0::ResponseFifo.read().raw; // sector number within track (00h to 74h)
return CDTimeStamp{
.min = CD_IO::PortIndex0::ResponseFifo.read().raw, // minute number on entire disk (00h and up)
.sec = CD_IO::PortIndex0::ResponseFifo.read().raw, // second number on entire disk (00h to 59h)
.sector = CD_IO::PortIndex0::ResponseFifo.read().raw, // sector number on entire disk (00h to 74h)
};
return BCDTimeStamp::from_time(
CD_IO::PortIndex0::ResponseFifo.read().raw, // minute number on entire disk (00h and up)
CD_IO::PortIndex0::ResponseFifo.read().raw, // second number on entire disk (00h to 59h)
CD_IO::PortIndex0::ResponseFifo.read().raw // sector number on entire disk (00h to 74h)
);
}
void enable_CDDA() {
@ -246,6 +215,7 @@ namespace JabyEngine {
Command::wait_completed();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, mode);
current_state = State::XAMode;
}
}
}