#pragma once #include "cd_types.hpp" #include #include #include namespace JabyEngine { namespace CD { 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(); } bool done_processing() { this->cur_lba++; return this->cur_lba == this->dst_lba; } }; enum struct State { Ready = 0, Done = 0, XAMode, Reading, BufferFull, Error, }; extern State current_state; extern uint8_t irq_bit_pending; struct Command { static void wait_completed() { while(const_cast(irq_bit_pending)); } template static void send_no_wait(CD_IO::Command::Desc cmd, ARGS...args) { while(CD_IO::IndexStatus.read().is_set(CD_IO_Values::IndexStatus::IsTransmissionBusy)); irq_bit_pending = bit::set(irq_bit_pending, cmd.complete_irq); CD_IO::PortIndex0::change_to(); ((CD_IO::PortIndex0::ParameterFifo.write(CD_IO_Values::ParameterFifo{args})),...); CD_IO::PortIndex0::CommandFifo.write(CD_IO_Values::CommandFifo{cmd.id}); } template static void send(CD_IO::Command::Desc cmd, ARGS...args) { Command::wait_completed(); Command::send_no_wait(cmd, args...); } template static void send_wait_response(CD_IO::Command::Desc cmd, ARGS...args) { Command::send(cmd, args...); Command::wait_completed(); } }; static State read_current_state() { return const_cast(current_state); } void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator); void end_read_file(); void continue_reading(); void copy_from_sector(uint32_t* dst, size_t bytes); template T copy_from_sector() { T data; copy_from_sector(reinterpret_cast(&data), sizeof(T)); return data; } BCDTimeStamp get_loc(); BCDTimeStamp get_locL(); void enable_CD(); void enable_CDDA(); void enable_CDXA(bool double_speed); static void set_loc(const BCDTimeStamp& cd_time) { Command::send_no_wait(CD_IO::Command::SetLoc, cd_time.min, cd_time.sec, cd_time.sector); } static void pause() { Command::send(CD_IO::Command::Pause); } } } }