Support Push/Pop in DS

This commit is contained in:
jaby 2024-06-01 16:37:00 +02:00
parent 658eed7b46
commit 7dbc829fe8
6 changed files with 98 additions and 41 deletions

View File

@ -6,11 +6,44 @@
#include <FontWriter/fonts.hpp> #include <FontWriter/fonts.hpp>
#include <FontWriter/font_writer.hpp> #include <FontWriter/font_writer.hpp>
//#include <PSX/Audio/CDDA.hpp> //#include <PSX/Audio/CDDA.hpp>
#include <PSX/Audio/CDXA.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <stdio.hpp> #include <stdio.hpp>
using namespace JabyEngine; using namespace JabyEngine;
struct XAPlayer {
static constexpr auto MaxChannels = 2;
uint8_t channel;
static XAPlayer create() {
return XAPlayer{0};
}
void play() {
this->channel = 0;
Assets::XAAudio::play_fox();
}
void stop() {
CDXA::stop();
}
void change_channel(int8_t step) {
this->channel = (this->channel + step)%MaxChannels;
CDXA::set_channel(this->channel);
}
void push() {
CDXA::push_play();
}
void pop() {
CDXA::pop_play();
}
};
struct StateChange { struct StateChange {
void (*asset_load)(); void (*asset_load)();
void (*main)(); void (*main)();
@ -46,8 +79,7 @@ static const auto doener_fish = Make::SPRT(
GPU::Color24::Grey() GPU::Color24::Grey()
); );
// Do we want this namespace? static XAPlayer xa = XAPlayer::create();
// Do we want Paco to be HERE?!
static object::Paco paco; static object::Paco paco;
static Menu::SimpleMenu menu; static Menu::SimpleMenu menu;
static StateChange state_changer; static StateChange state_changer;
@ -108,17 +140,29 @@ static void setup() {
// const auto [first_track, last_track] = CDDA::get_tracks(); // const auto [first_track, last_track] = CDDA::get_tracks();
// CDDA::play(first_track); // CDDA::play(first_track);
Assets::XAAudio::play_fox(); xa.play();
} }
namespace NormalScene { namespace NormalScene {
static void update() { static void update() {
using DigitalButton = Periphery::GenericController::Button;
static const char Title[] = ">> Pool Box <<"; static const char Title[] = ">> Pool Box <<";
static const char Version[] = "Ver. 0.8.5"; static const char Version[] = "Ver. 0.8.5";
static constexpr auto TitleLength = DefaultFont::Info.estimate_str_render_length(Title); static constexpr auto TitleLength = DefaultFont::Info.estimate_str_render_length(Title);
static constexpr auto VersionLength = DefaultFont::Info.estimate_str_render_length(Version); static constexpr auto VersionLength = DefaultFont::Info.estimate_str_render_length(Version);
Periphery::query_controller(); Periphery::query_controller();
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(controller.button.went_down(DigitalButton::R1)) {
xa.change_channel(1);
}
if(controller.button.went_down(DigitalButton::L1)) {
xa.change_channel(-1);
}
auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width-TitleLength)/2, 16)); auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width-TitleLength)/2, 16));
paco.update(); paco.update();
@ -165,11 +209,10 @@ namespace LoadingScene {
render(); render();
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
// TODO: Enable push and pop xa.push();
//CDDA::push_play();
state_changer.asset_load(); state_changer.asset_load();
old_state_changer = state_changer; old_state_changer = state_changer;
//CDDA::pop_play(); xa.pop();
} }
state_changer.main(); state_changer.main();

View File

@ -3,6 +3,10 @@
namespace JabyEngine { namespace JabyEngine {
struct Thread { struct Thread {
static uintptr_t get_pic() {
return table_of_tables.processes->current_tcb->epc;
}
static constexpr uint32_t idx_from_handle(SysCall::ThreadHandle thread) { static constexpr uint32_t idx_from_handle(SysCall::ThreadHandle thread) {
return thread & 0xFFFF; return thread & 0xFFFF;
} }
@ -25,6 +29,10 @@ namespace JabyEngine {
}; };
struct MainThread { struct MainThread {
static uintptr_t get_pic() {
return table_of_tables.threads[0].epc;
}
static void prepare_if_main(SysCall::ThreadHandle handle) { static void prepare_if_main(SysCall::ThreadHandle handle) {
if(table_of_tables.processes->current_tcb == &table_of_tables.threads[0]) { if(table_of_tables.processes->current_tcb == &table_of_tables.threads[0]) {
Thread::prepare_next(handle); Thread::prepare_next(handle);

View File

@ -50,8 +50,8 @@ namespace JabyEngine {
}; };
namespace IRQ { namespace IRQ {
void read_sector_to(uint32_t* dst, size_t bytes); void read_sector_to0(uint32_t* dst, size_t bytes);
void resume_at(const BCDTimeStamp& cd_time); void resume_at0(const BCDTimeStamp& cd_time);
} }
static State read_current_state() { static State read_current_state() {
@ -67,6 +67,7 @@ namespace JabyEngine {
void enable_CDXA(bool double_speed); void enable_CDXA(bool double_speed);
static void pause() { static void pause() {
CD_IO::PortIndex0::change_to();
Command::send<CD_IO::PortIndex0>(CD_IO::Command::Pause); Command::send<CD_IO::PortIndex0>(CD_IO::Command::Pause);
} }
} }

View File

@ -18,9 +18,11 @@ namespace JabyEngine {
case CD_IO::Interrupt::DataReady: { case CD_IO::Interrupt::DataReady: {
// The IRQ stack is 0x1000 bytes large so this should fit // The IRQ stack is 0x1000 bytes large so this should fit
CD::RawXADataSector xa_file; CD::RawXADataSector xa_file;
CD::IRQ::read_sector_to(reinterpret_cast<uint32_t*>(&xa_file), sizeof(CD::RawXADataSector));
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) { if(setting.channel == xa_file.sub_header.channel_number) {
CD::IRQ::resume_at(setting.start_loc); CD::IRQ::resume_at0(setting.start_loc);
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS); CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadS);
} }
} break; } break;
@ -35,7 +37,8 @@ namespace JabyEngine {
setting.start_loc = CD::BCDTimeStamp::from(lba[rel_lba_idx].get_lba()); setting.start_loc = CD::BCDTimeStamp::from(lba[rel_lba_idx].get_lba());
setting.double_speed = double_speed; setting.double_speed = double_speed;
CD::enable_CDXA(double_speed); CD::current_state = CD::State::XAMode;
CD::enable_CDXA(double_speed); //< Activates PortIndex0
set_channel(channel); set_channel(channel);
CD::Command::wait_completed(); 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_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, setting.start_loc.min, setting.start_loc.sec, setting.start_loc.sector);
@ -43,13 +46,13 @@ namespace JabyEngine {
} }
void stop() { void stop() {
// TODO: Alias this?
CD::pause(); CD::pause();
} }
void set_channel(uint8_t channel) { void set_channel(uint8_t channel) {
static constexpr uint8_t File = 1; static constexpr uint8_t File = 1;
CD_IO::PortIndex0::change_to();
CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Filter, File, channel); CD::Command::send<CD_IO::PortIndex0>(CD_IO::Command::Filter, File, channel);
setting.channel = channel; setting.channel = channel;
} }
@ -61,7 +64,8 @@ namespace JabyEngine {
void pop_play() { void pop_play() {
CD::Command::wait_completed(); CD::Command::wait_completed();
CD::enable_CDXA(setting.double_speed); CD::current_state = CD::State::XAMode;
CD::enable_CDXA(setting.double_speed); //< Activates PortIndex0
set_channel(setting.channel); set_channel(setting.channel);
CD::Command::wait_completed(); CD::Command::wait_completed();

View File

@ -40,12 +40,12 @@ namespace JabyEngine {
__debug_boot_color_at(::JabyEngine::GPU::Color24::Red(), DebugX, DebugY, DebugScale); __debug_boot_color_at(::JabyEngine::GPU::Color24::Red(), DebugX, DebugY, DebugScale);
CD_IO::PortIndex0::change_to(); CD_IO::PortIndex0::change_to();
__debug_boot_color_at(::JabyEngine::GPU::Color24::Green(), DebugX, DebugY, DebugScale); /* __debug_boot_color_at(::JabyEngine::GPU::Color24::Green(), DebugX, DebugY, DebugScale);
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat);
__debug_boot_color_at(::JabyEngine::GPU::Color24::Blue(), DebugX, DebugY, DebugScale); __debug_boot_color_at(::JabyEngine::GPU::Color24::Blue(), DebugX, DebugY, DebugScale);
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat);
__debug_boot_color_at(::JabyEngine::GPU::Color24::Yellow(), DebugX, DebugY, DebugScale); __debug_boot_color_at(::JabyEngine::GPU::Color24::Yellow(), DebugX, DebugY, DebugScale);
Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::Init); Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::Init);*/
Command::send<CD_IO::PortIndex0>(CD_IO::Command::Demute); Command::send<CD_IO::PortIndex0>(CD_IO::Command::Demute);
} }

View File

@ -46,21 +46,21 @@ namespace JabyEngine {
.verifier_function = IRQ::verifier .verifier_function = IRQ::verifier
}; };
static BCDTimeStamp send_read_cmd(uint32_t lba, CD_IO::Command::Desc desc) { static BCDTimeStamp send_read_cmd0(uint32_t lba, CD_IO::Command::Desc desc) {
const auto loc = BCDTimeStamp::from(lba); const auto loc = BCDTimeStamp::from(lba);
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.min, loc.sec, loc.sector); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.min, loc.sec, loc.sector);
Command::send<CD_IO::PortIndex0>(desc); Command::send<CD_IO::PortIndex0>(desc);
return loc; return loc;
} }
static void send_read_n(uint32_t lba) { static void send_read_n0(uint32_t lba) {
send_read_cmd(lba, CD_IO::Command::ReadN); send_read_cmd0(lba, CD_IO::Command::ReadN);
current_state = State::Reading; current_state = State::Reading;
} }
namespace IRQ { namespace IRQ {
static void read_sector_dma(uint32_t* dst, size_t bytes) { static void read_sector_dma0(uint32_t* dst, size_t bytes) {
static const auto WaitSectorReady = []() { static const auto WaitSectorReady = []() {
while(!CD_IO::IndexStatus.read().is_set(CD_IO::IndexStatus::HasDataFifoData)); while(!CD_IO::IndexStatus.read().is_set(CD_IO::IndexStatus::HasDataFifoData));
}; };
@ -79,23 +79,22 @@ namespace JabyEngine {
ReadSector(dst, bytes); ReadSector(dst, bytes);
} }
void read_sector_to(uint32_t* dst, size_t bytes) { void read_sector_to0(uint32_t* dst, size_t bytes) {
CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data()); CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data());
// We only support DMA rn // We only support DMA rn
read_sector_dma(dst, bytes); read_sector_dma0(dst, bytes);
// Do we ever want to support reading via IO Port? // Do we ever want to support reading via IO Port?
// Doesn't seem to important when we can use DMA // Doesn't seem to important when we can use DMA
} }
void resume_at(const BCDTimeStamp& cd_time) { void resume_at0(const BCDTimeStamp& cd_time) {
Command::send<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, cd_time.min, cd_time.sec, cd_time.sector); Command::send<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, cd_time.min, cd_time.sec, cd_time.sector);
CD_IO::PortIndex1::change_to(); CD_IO::PortIndex1::change_to();
while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); 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::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag);
CD_IO::PortIndex0::change_to(); CD_IO::PortIndex0::change_to();
} }
@ -128,7 +127,7 @@ namespace JabyEngine {
auto* sector = sector_allocator.allocate_sector(); auto* sector = sector_allocator.allocate_sector();
if(sector) { if(sector) {
//Now obtain sector //Now obtain sector
read_sector_to(sector->data, CD_IO::DataSector::SizeBytes); read_sector_to0(sector->data, CD_IO::DataSector::SizeBytes);
if(cur_file.done_processing()) { if(cur_file.done_processing()) {
current_state = State::Done; current_state = State::Done;
@ -144,7 +143,7 @@ namespace JabyEngine {
case CD_IO::Interrupt::DataEnd: { case CD_IO::Interrupt::DataEnd: {
// TODO: Fix this!! This is a freaking static time // TODO: Fix this!! This is a freaking static time
resume_at(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0}); resume_at0(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0});
Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play); Command::send<CD_IO::PortIndex0>(CD_IO::Command::Play);
} break; } break;
@ -172,38 +171,40 @@ namespace JabyEngine {
sector_allocator = buffer_allocator; sector_allocator = buffer_allocator;
Command::wait_completed(); Command::wait_completed();
CD_IO::PortIndex0::change_to();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode);
send_read_n0(cur_file.cur_lba);
send_read_n(cur_file.cur_lba);
} }
void continue_reading() { void continue_reading() {
if(current_state == State::BufferFull) { if(current_state == State::BufferFull) {
Command::wait_completed(); Command::wait_completed();
send_read_n(cur_file.cur_lba); CD_IO::PortIndex0::change_to();
send_read_n0(cur_file.cur_lba);
} }
} }
BCDTimeStamp get_loc() { BCDTimeStamp get_loc() {
Command::wait_completed(); Command::wait_completed();
CD_IO::PortIndex0::change_to();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetLocP); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::GetLocP);
const auto track = CD_IO::PortIndex0::ResponseFifo.read().raw; // track number (AAh=Lead-out area) (FFh=unknown, toc, none?) const auto track = CD_IO::PortIndex0::ResponseFifo.read().raw; // track number (AAh=Lead-out area) (FFh=unknown, toc, none?)
const auto index = CD_IO::PortIndex0::ResponseFifo.read().raw; // index number (Usually 01h) const auto index = CD_IO::PortIndex0::ResponseFifo.read().raw; // index number (Usually 01h)
const auto mm = CD_IO::PortIndex0::ResponseFifo.read().raw; // minute number within track (00h and up) const auto mm = CD_IO::PortIndex0::ResponseFifo.read().raw; // minute number within track (00h and up)
const auto ss = CD_IO::PortIndex0::ResponseFifo.read().raw; // second number within track (00h to 59h) 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) const auto sect = CD_IO::PortIndex0::ResponseFifo.read().raw; // sector number within track (00h to 74h)
return BCDTimeStamp::from_time( const auto min = CD_IO::PortIndex0::ResponseFifo.read().raw; // minute number on entire disk (00h and up)
CD_IO::PortIndex0::ResponseFifo.read().raw, // minute number on entire disk (00h and up) const auto sec = CD_IO::PortIndex0::ResponseFifo.read().raw; // second number on entire disk (00h to 59h)
CD_IO::PortIndex0::ResponseFifo.read().raw, // second number on entire disk (00h to 59h) const auto sectors = CD_IO::PortIndex0::ResponseFifo.read().raw; // sector number on entire disk (00h to 74h)
CD_IO::PortIndex0::ResponseFifo.read().raw // sector number on entire disk (00h to 74h) return BCDTimeStamp{min, sec, sectors};
);
} }
void enable_CDDA() { void enable_CDDA() {
Command::wait_completed(); Command::wait_completed();
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);
} }
@ -214,8 +215,8 @@ namespace JabyEngine {
const uint8_t mode = XAAudioSectorMode.raw | (double_speed ? DoubleSpeedBit : SingleSpeedBit); const uint8_t mode = XAAudioSectorMode.raw | (double_speed ? DoubleSpeedBit : SingleSpeedBit);
Command::wait_completed(); Command::wait_completed();
CD_IO::PortIndex0::change_to();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, mode); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, mode);
current_state = State::XAMode;
} }
} }
} }