From ec8231785e96827c68ca1bdb500f240cfd6afade Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sun, 29 Sep 2024 20:01:41 -0700 Subject: [PATCH] Splitting cdrom-device.cpp up. --- src/mips/psyqo/src/cdrom-device-cdda.cpp | 176 ++++++ .../psyqo/src/cdrom-device-muteunmute.cpp | 108 ++++ .../psyqo/src/cdrom-device-readsectors.cpp | 146 +++++ src/mips/psyqo/src/cdrom-device-reset.cpp | 81 +++ src/mips/psyqo/src/cdrom-device-toc.cpp | 179 ++++++ src/mips/psyqo/src/cdrom-device.cpp | 522 ------------------ 6 files changed, 690 insertions(+), 522 deletions(-) create mode 100644 src/mips/psyqo/src/cdrom-device-cdda.cpp create mode 100644 src/mips/psyqo/src/cdrom-device-muteunmute.cpp create mode 100644 src/mips/psyqo/src/cdrom-device-readsectors.cpp create mode 100644 src/mips/psyqo/src/cdrom-device-reset.cpp create mode 100644 src/mips/psyqo/src/cdrom-device-toc.cpp diff --git a/src/mips/psyqo/src/cdrom-device-cdda.cpp b/src/mips/psyqo/src/cdrom-device-cdda.cpp new file mode 100644 index 000000000..91dca6e4c --- /dev/null +++ b/src/mips/psyqo/src/cdrom-device-cdda.cpp @@ -0,0 +1,176 @@ +/* + +MIT License + +Copyright (c) 2022 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "psyqo/cdrom-device.hh" + +#include + +#include "psyqo/hardware/cdrom.hh" +#include "psyqo/kernel.hh" +#include "psyqo/msf.hh" + +namespace { + +enum class PlayCDDAActionState : uint8_t { + IDLE, + GETTD, + SETMODE, + SETLOC, + SEEK, + SEEK_ACK, + PLAY, + // needs to stay unique across all actions, and + // will be hardcoded in the pause command + PLAYING = 100, + STOPPING = 101, + STOPPING_ACK, +}; + +class PlayCDDAAction : public psyqo::CDRomDevice::Action { + public: + PlayCDDAAction() : Action("PlayCDDAAction") {} + void start(psyqo::CDRomDevice *device, unsigned track, bool stopAtEndOfTrack, + eastl::function &&callback) { + psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, + "CDRomDevice::playCDDA() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(PlayCDDAActionState::GETTD); + m_stopAtEndOfTrack = stopAtEndOfTrack; + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, psyqo::itob(track)); + } + void start(psyqo::CDRomDevice *device, psyqo::MSF msf, bool stopAtEndOfTrack, + eastl::function &&callback) { + psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, + "CDRomDevice::playCDDA() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(PlayCDDAActionState::SEEK); + m_start = msf; + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, stopAtEndOfTrack ? 0x02 : 0); + } + void start(psyqo::CDRomDevice *device, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, + "CDRomDevice::playCDDA() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(PlayCDDAActionState::PLAY); + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PLAY); + } + bool complete(const psyqo::CDRomDevice::Response &) override { + switch (getState()) { + case PlayCDDAActionState::SEEK_ACK: + setState(PlayCDDAActionState::PLAY); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PLAY); + break; + case PlayCDDAActionState::STOPPING_ACK: + setSuccess(true); + return true; + default: + psyqo::Kernel::abort("PlayCDDAAction got CDROM complete in wrong state"); + break; + } + return false; + } + bool acknowledge(const psyqo::CDRomDevice::Response &response) override { + switch (getState()) { + case PlayCDDAActionState::GETTD: + m_start.m = psyqo::btoi(response[1]); + m_start.s = psyqo::btoi(response[2]); + m_start.f = 0; + setState(PlayCDDAActionState::SETMODE); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, + m_stopAtEndOfTrack ? 0x02 : 0); + break; + case PlayCDDAActionState::SETMODE: + setState(PlayCDDAActionState::SETLOC); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETLOC, m_start.m, m_start.s, + m_start.f); + break; + case PlayCDDAActionState::SETLOC: + setState(PlayCDDAActionState::SEEK); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SEEKP); + break; + case PlayCDDAActionState::SEEK: + setState(PlayCDDAActionState::SEEK_ACK); + break; + case PlayCDDAActionState::PLAY: + setState(PlayCDDAActionState::PLAYING); + queueCallbackFromISR(true); + break; + case PlayCDDAActionState::STOPPING: + setState(PlayCDDAActionState::STOPPING_ACK); + break; + default: + psyqo::Kernel::abort("PlayCDDAAction got CDROM acknowledge in wrong state"); + break; + } + return false; + } + bool end(const psyqo::CDRomDevice::Response &) override { + // We got raced to the end of the track and/or disc by the + // pause command, so we should just ignore this. + if (getState() == PlayCDDAActionState::STOPPING) return false; + psyqo::Kernel::assert(getState() == PlayCDDAActionState::PLAYING, + "PlayCDDAAction got CDROM end in wrong state"); + setSuccess(true); + return true; + } + psyqo::MSF m_start; + bool m_stopAtEndOfTrack = false; +}; + +PlayCDDAAction s_playCDDAAction; + +} // namespace + +void psyqo::CDRomDevice::playCDDATrack(unsigned track, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDATrack called with pending action"); + s_playCDDAAction.start(this, track, true, eastl::move(callback)); +} + +void psyqo::CDRomDevice::playCDDATrack(MSF start, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDATrack called with pending action"); + s_playCDDAAction.start(this, start, true, eastl::move(callback)); +} + +void psyqo::CDRomDevice::playCDDADisc(unsigned track, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDADisc called with pending action"); + s_playCDDAAction.start(this, track, false, eastl::move(callback)); +} + +void psyqo::CDRomDevice::playCDDADisc(MSF start, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDADisc called with pending action"); + s_playCDDAAction.start(this, start, false, eastl::move(callback)); +} + +void psyqo::CDRomDevice::resumeCDDA(eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::resumeCDDA called with pending action"); + s_playCDDAAction.start(this, eastl::move(callback)); +} diff --git a/src/mips/psyqo/src/cdrom-device-muteunmute.cpp b/src/mips/psyqo/src/cdrom-device-muteunmute.cpp new file mode 100644 index 000000000..47f53cedc --- /dev/null +++ b/src/mips/psyqo/src/cdrom-device-muteunmute.cpp @@ -0,0 +1,108 @@ +/* + +MIT License + +Copyright (c) 2022 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "psyqo/cdrom-device.hh" + +#include + +#include "psyqo/hardware/cdrom.hh" +#include "psyqo/kernel.hh" + +namespace { + +enum class MuteActionState : uint8_t { + IDLE, + MUTE, +}; + +class MuteAction : public psyqo::CDRomDevice::Action { + public: + MuteAction() : Action("MuteAction") {} + void start(psyqo::CDRomDevice *device, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == MuteActionState::IDLE, + "CDRomDevice::mute() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(MuteActionState::MUTE); + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::MUTE); + } + bool complete(const psyqo::CDRomDevice::Response &) override { + setSuccess(true); + return true; + } +}; + +MuteAction s_muteAction; + +} // namespace + +void psyqo::CDRomDevice::mute(eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::mute called with pending action"); + s_muteAction.start(this, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleMute() { + return TaskQueue::Task([this](auto task) { mute([task](bool success) { task->complete(success); }); }); +} + +namespace { + +enum class UnmuteActionState : uint8_t { + IDLE, + UNMUTE, +}; + +class UnmuteAction : public psyqo::CDRomDevice::Action { + public: + UnmuteAction() : Action("UnmuteAction") {} + void start(psyqo::CDRomDevice *device, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == UnmuteActionState::IDLE, + "CDRomDevice::unmute() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(UnmuteActionState::UNMUTE); + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::UNMUTE); + } + bool complete(const psyqo::CDRomDevice::Response &) override { + setSuccess(true); + return true; + } +}; + +UnmuteAction s_unmuteAction; + +} // namespace + +void psyqo::CDRomDevice::unmute(eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::unmute called with pending action"); + s_unmuteAction.start(this, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleUnmute() { + return TaskQueue::Task([this](auto task) { unmute([task](bool success) { task->complete(success); }); }); +} diff --git a/src/mips/psyqo/src/cdrom-device-readsectors.cpp b/src/mips/psyqo/src/cdrom-device-readsectors.cpp new file mode 100644 index 000000000..04bb7bb24 --- /dev/null +++ b/src/mips/psyqo/src/cdrom-device-readsectors.cpp @@ -0,0 +1,146 @@ +/* + +MIT License + +Copyright (c) 2022 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "psyqo/cdrom-device.hh" + +#include + +#include "common/hardware/dma.h" +#include "psyqo/hardware/cdrom.hh" +#include "psyqo/hardware/sbus.hh" +#include "psyqo/kernel.hh" +#include "psyqo/msf.hh" + + +namespace { + +enum class ReadSectorsActionState : uint8_t { + IDLE, + SETLOC, + SETMODE, + READ, + READ_ACK, + PAUSE, + PAUSE_ACK, +}; + +class ReadSectorsAction : public psyqo::CDRomDevice::Action { + public: + ReadSectorsAction() : Action("ReadSectorsAction") {} + void start(psyqo::CDRomDevice *device, uint32_t sector, uint32_t count, void *buffer, + eastl::function &&callback) { + psyqo::Kernel::assert(getState() == ReadSectorsActionState::IDLE, + "CDRomDevice::readSectors() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(ReadSectorsActionState::SETLOC); + m_count = count; + m_ptr = reinterpret_cast(buffer); + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::MSF msf(sector + 150); + uint8_t bcd[3]; + msf.toBCD(bcd); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETLOC, bcd[0], bcd[1], bcd[2]); + } + bool dataReady(const psyqo::CDRomDevice::Response &) override { + psyqo::Kernel::assert(getState() == ReadSectorsActionState::READ_ACK, + "ReadSectorsAction got CDROM dataReady in wrong state"); + psyqo::Hardware::CDRom::Ctrl.throwAway(); + psyqo::Hardware::CDRom::DataRequest = 0; + psyqo::Hardware::CDRom::InterruptControl.throwAway(); + psyqo::Hardware::CDRom::DataRequest = 0x80; + psyqo::Hardware::SBus::Dev5Ctrl = 0x20943; + psyqo::Hardware::SBus::ComCtrl = 0x132c; + eastl::atomic_signal_fence(eastl::memory_order_acquire); + DMA_CTRL[DMA_CDROM].MADR = reinterpret_cast(m_ptr); + DMA_CTRL[DMA_CDROM].BCR = 512 | 0x10000; + DMA_CTRL[DMA_CDROM].CHCR = 0x11000000; + m_ptr += 2048; + if (--m_count == 0) { + setState(ReadSectorsActionState::PAUSE); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PAUSE); + } + eastl::atomic_signal_fence(eastl::memory_order_release); + return false; + } + bool complete(const psyqo::CDRomDevice::Response &) override { + psyqo::Kernel::assert(getState() == ReadSectorsActionState::PAUSE_ACK, + "ReadSectorsAction got CDROM complete in wrong state"); + setSuccess(true); + return true; + } + bool acknowledge(const psyqo::CDRomDevice::Response &) override { + switch (getState()) { + case ReadSectorsActionState::SETLOC: + setState(ReadSectorsActionState::SETMODE); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, 0x80); + break; + case ReadSectorsActionState::SETMODE: + setState(ReadSectorsActionState::READ); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::READN); + break; + case ReadSectorsActionState::READ: + setState(ReadSectorsActionState::READ_ACK); + break; + case ReadSectorsActionState::PAUSE: + setState(ReadSectorsActionState::PAUSE_ACK); + break; + default: + psyqo::Kernel::abort("ReadSectorsAction got CDROM acknowledge in wrong state"); + break; + } + return false; + } + + private: + uint32_t m_count = 0; + uint8_t *m_ptr = nullptr; +}; + +ReadSectorsAction s_readSectorsAction; + +} // namespace + +void psyqo::CDRomDevice::readSectors(uint32_t sector, uint32_t count, void *buffer, + eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::readSectors called with pending action"); + s_readSectorsAction.start(this, sector, count, buffer, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReadSectors(uint32_t sector, uint32_t count, void *buffer) { + if (count == 0) { + return TaskQueue::Task([this](auto task) { task->complete(true); }); + } + uint32_t *storage = reinterpret_cast(buffer); + storage[0] = sector; + storage[1] = count; + return TaskQueue::Task([this, buffer](auto task) { + uint32_t *storage = reinterpret_cast(buffer); + uint32_t sector = storage[0]; + uint32_t count = storage[1]; + readSectors(sector, count, buffer, [task](bool success) { task->complete(success); }); + }); +} diff --git a/src/mips/psyqo/src/cdrom-device-reset.cpp b/src/mips/psyqo/src/cdrom-device-reset.cpp new file mode 100644 index 000000000..1562f4f7d --- /dev/null +++ b/src/mips/psyqo/src/cdrom-device-reset.cpp @@ -0,0 +1,81 @@ +/* + +MIT License + +Copyright (c) 2022 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "psyqo/cdrom-device.hh" + +#include + +#include "psyqo/hardware/cdrom.hh" +#include "psyqo/kernel.hh" + +namespace { + +enum class ResetActionState : uint8_t { + IDLE, + RESET, + RESET_ACK, +}; + +class ResetAction : public psyqo::CDRomDevice::Action { + public: + ResetAction() : Action("ResetAction") {} + void start(psyqo::CDRomDevice *device, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == ResetActionState::IDLE, + "CDRomDevice::reset() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(ResetActionState::RESET); + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Cause = 0x1f; + psyqo::Hardware::CDRom::CauseMask = 0x1f; + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::INIT); + } + bool complete(const psyqo::CDRomDevice::Response &) override { + psyqo::Kernel::assert(getState() == ResetActionState::RESET_ACK, + "ResetAction got CDROM complete in wrong state"); + setSuccess(true); + return true; + } + bool acknowledge(const psyqo::CDRomDevice::Response &) override { + psyqo::Kernel::assert(getState() == ResetActionState::RESET, + "ResetAction got CDROM acknowledge in wrong state"); + setState(ResetActionState::RESET_ACK); + return false; + } +}; + +ResetAction s_resetAction; + +} // namespace + +void psyqo::CDRomDevice::reset(eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::reset called with pending action"); + s_resetAction.start(this, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReset() { + return TaskQueue::Task([this](auto task) { reset([task](bool success) { task->complete(success); }); }); +} diff --git a/src/mips/psyqo/src/cdrom-device-toc.cpp b/src/mips/psyqo/src/cdrom-device-toc.cpp new file mode 100644 index 000000000..af06096c7 --- /dev/null +++ b/src/mips/psyqo/src/cdrom-device-toc.cpp @@ -0,0 +1,179 @@ +/* + +MIT License + +Copyright (c) 2022 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "psyqo/cdrom-device.hh" + +#include + +#include "psyqo/gpu.hh" +#include "psyqo/hardware/cdrom.hh" +#include "psyqo/kernel.hh" +#include "psyqo/msf.hh" + + +namespace { + +enum class GetTNActionEnum : uint8_t { + IDLE, + GETTN, +}; + +class GetTNAction : public psyqo::CDRomDevice::Action { + public: + GetTNAction() : Action("GetTNAction") {} + void start(psyqo::CDRomDevice *device, unsigned *size, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == GetTNActionEnum::IDLE, + "CDRomDevice::getTOCSize() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(GetTNActionEnum::GETTN); + m_size = size; + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTN); + } + bool acknowledge(const psyqo::CDRomDevice::Response &response) override { + *m_size = response[2]; + setSuccess(true); + return true; + } + + private: + unsigned *m_size = nullptr; +}; + +GetTNAction s_getTNAction; + +} // namespace + +void psyqo::CDRomDevice::getTOCSize(unsigned *size, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::getTOCSize called with pending action"); + s_getTNAction.start(this, size, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleGetTOCSize(unsigned *size) { + return TaskQueue::Task( + [this, size](auto task) { getTOCSize(size, [task](bool success) { task->complete(success); }); }); +} + +unsigned psyqo::CDRomDevice::getTOCSizeBlocking(GPU &gpu) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::getTOCSizeBlocking called with pending action"); + unsigned size = 0; + bool success = false; + { + BlockingAction blocking(this, gpu); + s_getTNAction.start(this, &size, [&success](bool success_) { success = success_; }); + } + if (!success) return 0; + return size; +} + +namespace { + +enum class ReadTOCActionState : uint8_t { + IDLE, + GETTN, + GETTD, +}; + +class ReadTOCAction : public psyqo::CDRomDevice::Action { + public: + ReadTOCAction() : Action("ReadTOCAction") {} + void start(psyqo::CDRomDevice *device, psyqo::MSF *toc, unsigned size, eastl::function &&callback) { + psyqo::Kernel::assert(getState() == ReadTOCActionState::IDLE, + "CDRomDevice::readTOC() called while another action is in progress"); + registerMe(device); + setCallback(eastl::move(callback)); + setState(ReadTOCActionState::GETTN); + m_toc = toc; + m_size = size; + eastl::atomic_signal_fence(eastl::memory_order_release); + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTN); + } + bool acknowledge(const psyqo::CDRomDevice::Response &response) override { + switch (getState()) { + case ReadTOCActionState::GETTN: + setState(ReadTOCActionState::GETTD); + m_currentTrack = response[1]; + m_lastTrack = response[2]; + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, psyqo::itob(1)); + break; + case ReadTOCActionState::GETTD: { + psyqo::MSF &msf = m_toc[m_currentTrack]; + msf.m = psyqo::btoi(response[1]); + msf.s = psyqo::btoi(response[2]); + msf.f = 0; + m_currentTrack++; + if ((m_currentTrack <= m_lastTrack) && (m_currentTrack < m_size)) { + psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, + psyqo::itob(m_currentTrack)); + } else { + setSuccess(true); + return true; + } + } break; + default: + psyqo::Kernel::abort("ReadTOCAction got CDROM acknowledge in wrong state"); + break; + } + return false; + } + psyqo::MSF *m_toc = nullptr; + unsigned m_size = 0; + uint8_t m_currentTrack = 0; + uint8_t m_lastTrack = 0; +}; + +ReadTOCAction s_readTOCAction; + +} // namespace + +void psyqo::CDRomDevice::readTOC(MSF *toc, unsigned size, eastl::function &&callback) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::readTOC called with pending action"); + s_readTOCAction.start(this, toc, size, eastl::move(callback)); +} + +psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReadTOC(MSF *toc, unsigned size) { + if (size == 0) { + return TaskQueue::Task([this](auto task) { task->complete(true); }); + } + size = eastl::min(size, 100u); + toc[0].m = size; + return TaskQueue::Task([this, toc](auto task) { + unsigned size = toc[0].m; + toc[0].m = 0; + readTOC(toc, size, [task](bool success) { task->complete(success); }); + }); +} + +bool psyqo::CDRomDevice::readTOCBlocking(MSF *toc, unsigned size, GPU &gpu) { + Kernel::assert(m_callback == nullptr, "CDRomDevice::readTOCBlocking called with pending action"); + bool success = false; + { + BlockingAction blocking(this, gpu); + readTOC(toc, size, [&success](bool success_) { success = success_; }); + } + return success; +} diff --git a/src/mips/psyqo/src/cdrom-device.cpp b/src/mips/psyqo/src/cdrom-device.cpp index 131fc054a..120b052e8 100644 --- a/src/mips/psyqo/src/cdrom-device.cpp +++ b/src/mips/psyqo/src/cdrom-device.cpp @@ -75,528 +75,6 @@ void psyqo::CDRomDevice::prepare() { psyqo::CDRomDevice::~CDRomDevice() { Kernel::abort("CDRomDevice can't be destroyed (yet)"); } -namespace { - -enum class ResetActionState : uint8_t { - IDLE, - RESET, - RESET_ACK, -}; - -class ResetAction : public psyqo::CDRomDevice::Action { - public: - ResetAction() : Action("ResetAction") {} - void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == ResetActionState::IDLE, - "CDRomDevice::reset() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(ResetActionState::RESET); - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Cause = 0x1f; - psyqo::Hardware::CDRom::CauseMask = 0x1f; - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::INIT); - } - bool complete(const psyqo::CDRomDevice::Response &) override { - psyqo::Kernel::assert(getState() == ResetActionState::RESET_ACK, - "ResetAction got CDROM complete in wrong state"); - setSuccess(true); - return true; - } - bool acknowledge(const psyqo::CDRomDevice::Response &) override { - psyqo::Kernel::assert(getState() == ResetActionState::RESET, - "ResetAction got CDROM acknowledge in wrong state"); - setState(ResetActionState::RESET_ACK); - return false; - } -}; - -ResetAction s_resetAction; - -} // namespace - -void psyqo::CDRomDevice::reset(eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::reset called with pending action"); - s_resetAction.start(this, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReset() { - return TaskQueue::Task([this](auto task) { reset([task](bool success) { task->complete(success); }); }); -} - -namespace { - -enum class ReadSectorsActionState : uint8_t { - IDLE, - SETLOC, - SETMODE, - READ, - READ_ACK, - PAUSE, - PAUSE_ACK, -}; - -class ReadSectorsAction : public psyqo::CDRomDevice::Action { - public: - ReadSectorsAction() : Action("ReadSectorsAction") {} - void start(psyqo::CDRomDevice *device, uint32_t sector, uint32_t count, void *buffer, - eastl::function &&callback) { - psyqo::Kernel::assert(getState() == ReadSectorsActionState::IDLE, - "CDRomDevice::readSectors() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(ReadSectorsActionState::SETLOC); - m_count = count; - m_ptr = reinterpret_cast(buffer); - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::MSF msf(sector + 150); - uint8_t bcd[3]; - msf.toBCD(bcd); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETLOC, bcd[0], bcd[1], bcd[2]); - } - bool dataReady(const psyqo::CDRomDevice::Response &) override { - psyqo::Kernel::assert(getState() == ReadSectorsActionState::READ_ACK, - "ReadSectorsAction got CDROM dataReady in wrong state"); - psyqo::Hardware::CDRom::Ctrl.throwAway(); - psyqo::Hardware::CDRom::DataRequest = 0; - psyqo::Hardware::CDRom::InterruptControl.throwAway(); - psyqo::Hardware::CDRom::DataRequest = 0x80; - psyqo::Hardware::SBus::Dev5Ctrl = 0x20943; - psyqo::Hardware::SBus::ComCtrl = 0x132c; - eastl::atomic_signal_fence(eastl::memory_order_acquire); - DMA_CTRL[DMA_CDROM].MADR = reinterpret_cast(m_ptr); - DMA_CTRL[DMA_CDROM].BCR = 512 | 0x10000; - DMA_CTRL[DMA_CDROM].CHCR = 0x11000000; - m_ptr += 2048; - if (--m_count == 0) { - setState(ReadSectorsActionState::PAUSE); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PAUSE); - } - eastl::atomic_signal_fence(eastl::memory_order_release); - return false; - } - bool complete(const psyqo::CDRomDevice::Response &) override { - psyqo::Kernel::assert(getState() == ReadSectorsActionState::PAUSE_ACK, - "ReadSectorsAction got CDROM complete in wrong state"); - setSuccess(true); - return true; - } - bool acknowledge(const psyqo::CDRomDevice::Response &) override { - switch (getState()) { - case ReadSectorsActionState::SETLOC: - setState(ReadSectorsActionState::SETMODE); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, 0x80); - break; - case ReadSectorsActionState::SETMODE: - setState(ReadSectorsActionState::READ); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::READN); - break; - case ReadSectorsActionState::READ: - setState(ReadSectorsActionState::READ_ACK); - break; - case ReadSectorsActionState::PAUSE: - setState(ReadSectorsActionState::PAUSE_ACK); - break; - default: - psyqo::Kernel::abort("ReadSectorsAction got CDROM acknowledge in wrong state"); - break; - } - return false; - } - - private: - uint32_t m_count = 0; - uint8_t *m_ptr = nullptr; -}; - -ReadSectorsAction s_readSectorsAction; - -} // namespace - -void psyqo::CDRomDevice::readSectors(uint32_t sector, uint32_t count, void *buffer, - eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::readSectors called with pending action"); - s_readSectorsAction.start(this, sector, count, buffer, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReadSectors(uint32_t sector, uint32_t count, void *buffer) { - if (count == 0) { - return TaskQueue::Task([this](auto task) { task->complete(true); }); - } - uint32_t *storage = reinterpret_cast(buffer); - storage[0] = sector; - storage[1] = count; - return TaskQueue::Task([this, buffer](auto task) { - uint32_t *storage = reinterpret_cast(buffer); - uint32_t sector = storage[0]; - uint32_t count = storage[1]; - readSectors(sector, count, buffer, [task](bool success) { task->complete(success); }); - }); -} - -namespace { - -enum class GetTNActionEnum : uint8_t { - IDLE, - GETTN, -}; - -class GetTNAction : public psyqo::CDRomDevice::Action { - public: - GetTNAction() : Action("GetTNAction") {} - void start(psyqo::CDRomDevice *device, unsigned *size, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == GetTNActionEnum::IDLE, - "CDRomDevice::getTOCSize() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(GetTNActionEnum::GETTN); - m_size = size; - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTN); - } - bool acknowledge(const psyqo::CDRomDevice::Response &response) override { - *m_size = response[2]; - setSuccess(true); - return true; - } - - private: - unsigned *m_size = nullptr; -}; - -GetTNAction s_getTNAction; - -} // namespace - -void psyqo::CDRomDevice::getTOCSize(unsigned *size, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::getTOCSize called with pending action"); - s_getTNAction.start(this, size, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleGetTOCSize(unsigned *size) { - return TaskQueue::Task( - [this, size](auto task) { getTOCSize(size, [task](bool success) { task->complete(success); }); }); -} - -unsigned psyqo::CDRomDevice::getTOCSizeBlocking(GPU &gpu) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::getTOCSizeBlocking called with pending action"); - unsigned size = 0; - bool success = false; - { - BlockingAction blocking(this, gpu); - s_getTNAction.start(this, &size, [&success](bool success_) { success = success_; }); - } - if (!success) return 0; - return size; -} - -namespace { - -enum class ReadTOCActionState : uint8_t { - IDLE, - GETTN, - GETTD, -}; - -class ReadTOCAction : public psyqo::CDRomDevice::Action { - public: - ReadTOCAction() : Action("ReadTOCAction") {} - void start(psyqo::CDRomDevice *device, psyqo::MSF *toc, unsigned size, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == ReadTOCActionState::IDLE, - "CDRomDevice::readTOC() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(ReadTOCActionState::GETTN); - m_toc = toc; - m_size = size; - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTN); - } - bool acknowledge(const psyqo::CDRomDevice::Response &response) override { - switch (getState()) { - case ReadTOCActionState::GETTN: - setState(ReadTOCActionState::GETTD); - m_currentTrack = response[1]; - m_lastTrack = response[2]; - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, psyqo::itob(1)); - break; - case ReadTOCActionState::GETTD: { - psyqo::MSF &msf = m_toc[m_currentTrack]; - msf.m = psyqo::btoi(response[1]); - msf.s = psyqo::btoi(response[2]); - msf.f = 0; - m_currentTrack++; - if ((m_currentTrack <= m_lastTrack) && (m_currentTrack < m_size)) { - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, - psyqo::itob(m_currentTrack)); - } else { - setSuccess(true); - return true; - } - } break; - default: - psyqo::Kernel::abort("ReadTOCAction got CDROM acknowledge in wrong state"); - break; - } - return false; - } - psyqo::MSF *m_toc = nullptr; - unsigned m_size = 0; - uint8_t m_currentTrack = 0; - uint8_t m_lastTrack = 0; -}; - -ReadTOCAction s_readTOCAction; - -} // namespace - -void psyqo::CDRomDevice::readTOC(MSF *toc, unsigned size, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::readTOC called with pending action"); - s_readTOCAction.start(this, toc, size, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleReadTOC(MSF *toc, unsigned size) { - if (size == 0) { - return TaskQueue::Task([this](auto task) { task->complete(true); }); - } - size = eastl::min(size, 100u); - toc[0].m = size; - return TaskQueue::Task([this, toc](auto task) { - unsigned size = toc[0].m; - toc[0].m = 0; - readTOC(toc, size, [task](bool success) { task->complete(success); }); - }); -} - -bool psyqo::CDRomDevice::readTOCBlocking(MSF *toc, unsigned size, GPU &gpu) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::readTOCBlocking called with pending action"); - bool success = false; - { - BlockingAction blocking(this, gpu); - readTOC(toc, size, [&success](bool success_) { success = success_; }); - } - return success; -} - -namespace { - -enum class MuteActionState : uint8_t { - IDLE, - MUTE, -}; - -class MuteAction : public psyqo::CDRomDevice::Action { - public: - MuteAction() : Action("MuteAction") {} - void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == MuteActionState::IDLE, - "CDRomDevice::mute() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(MuteActionState::MUTE); - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::MUTE); - } - bool complete(const psyqo::CDRomDevice::Response &) override { - setSuccess(true); - return true; - } -}; - -MuteAction s_muteAction; - -} // namespace - -void psyqo::CDRomDevice::mute(eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::mute called with pending action"); - s_muteAction.start(this, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleMute() { - return TaskQueue::Task([this](auto task) { mute([task](bool success) { task->complete(success); }); }); -} - -namespace { - -enum class UnmuteActionState : uint8_t { - IDLE, - UNMUTE, -}; - -class UnmuteAction : public psyqo::CDRomDevice::Action { - public: - UnmuteAction() : Action("UnmuteAction") {} - void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == UnmuteActionState::IDLE, - "CDRomDevice::unmute() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(UnmuteActionState::UNMUTE); - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::UNMUTE); - } - bool complete(const psyqo::CDRomDevice::Response &) override { - setSuccess(true); - return true; - } -}; - -UnmuteAction s_unmuteAction; - -} // namespace - -void psyqo::CDRomDevice::unmute(eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::unmute called with pending action"); - s_unmuteAction.start(this, eastl::move(callback)); -} - -psyqo::TaskQueue::Task psyqo::CDRomDevice::scheduleUnmute() { - return TaskQueue::Task([this](auto task) { unmute([task](bool success) { task->complete(success); }); }); -} - -namespace { - -enum class PlayCDDAActionState : uint8_t { - IDLE, - GETTD, - SETMODE, - SETLOC, - SEEK, - SEEK_ACK, - PLAY, - // needs to stay unique across all actions, and - // will be hardcoded in the pause command - PLAYING = 100, - STOPPING = 101, - STOPPING_ACK, -}; - -class PlayCDDAAction : public psyqo::CDRomDevice::Action { - public: - PlayCDDAAction() : Action("PlayCDDAAction") {} - void start(psyqo::CDRomDevice *device, unsigned track, bool stopAtEndOfTrack, - eastl::function &&callback) { - psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, - "CDRomDevice::playCDDA() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(PlayCDDAActionState::GETTD); - m_stopAtEndOfTrack = stopAtEndOfTrack; - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::GETTD, psyqo::itob(track)); - } - void start(psyqo::CDRomDevice *device, psyqo::MSF msf, bool stopAtEndOfTrack, - eastl::function &&callback) { - psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, - "CDRomDevice::playCDDA() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(PlayCDDAActionState::SEEK); - m_start = msf; - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, stopAtEndOfTrack ? 0x02 : 0); - } - void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(getState() == PlayCDDAActionState::IDLE, - "CDRomDevice::playCDDA() called while another action is in progress"); - registerMe(device); - setCallback(eastl::move(callback)); - setState(PlayCDDAActionState::PLAY); - eastl::atomic_signal_fence(eastl::memory_order_release); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PLAY); - } - bool complete(const psyqo::CDRomDevice::Response &) override { - switch (getState()) { - case PlayCDDAActionState::SEEK_ACK: - setState(PlayCDDAActionState::PLAY); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::PLAY); - break; - case PlayCDDAActionState::STOPPING_ACK: - setSuccess(true); - return true; - default: - psyqo::Kernel::abort("PlayCDDAAction got CDROM complete in wrong state"); - break; - } - return false; - } - bool acknowledge(const psyqo::CDRomDevice::Response &response) override { - switch (getState()) { - case PlayCDDAActionState::GETTD: - m_start.m = psyqo::btoi(response[1]); - m_start.s = psyqo::btoi(response[2]); - m_start.f = 0; - setState(PlayCDDAActionState::SETMODE); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, - m_stopAtEndOfTrack ? 0x02 : 0); - break; - case PlayCDDAActionState::SETMODE: - setState(PlayCDDAActionState::SETLOC); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETLOC, m_start.m, m_start.s, - m_start.f); - break; - case PlayCDDAActionState::SETLOC: - setState(PlayCDDAActionState::SEEK); - psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SEEKP); - break; - case PlayCDDAActionState::SEEK: - setState(PlayCDDAActionState::SEEK_ACK); - break; - case PlayCDDAActionState::PLAY: - setState(PlayCDDAActionState::PLAYING); - queueCallbackFromISR(true); - break; - case PlayCDDAActionState::STOPPING: - setState(PlayCDDAActionState::STOPPING_ACK); - break; - default: - psyqo::Kernel::abort("PlayCDDAAction got CDROM acknowledge in wrong state"); - break; - } - return false; - } - bool end(const psyqo::CDRomDevice::Response &) override { - // We got raced to the end of the track and/or disc by the - // pause command, so we should just ignore this. - if (getState() == PlayCDDAActionState::STOPPING) return false; - psyqo::Kernel::assert(getState() == PlayCDDAActionState::PLAYING, - "PlayCDDAAction got CDROM end in wrong state"); - setSuccess(true); - return true; - } - psyqo::MSF m_start; - bool m_stopAtEndOfTrack = false; -}; - -PlayCDDAAction s_playCDDAAction; - -} // namespace - -void psyqo::CDRomDevice::playCDDATrack(unsigned track, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDATrack called with pending action"); - s_playCDDAAction.start(this, track, true, eastl::move(callback)); -} - -void psyqo::CDRomDevice::playCDDATrack(MSF start, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDATrack called with pending action"); - s_playCDDAAction.start(this, start, true, eastl::move(callback)); -} - -void psyqo::CDRomDevice::playCDDADisc(unsigned track, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDADisc called with pending action"); - s_playCDDAAction.start(this, track, false, eastl::move(callback)); -} - -void psyqo::CDRomDevice::playCDDADisc(MSF start, eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::playCDDADisc called with pending action"); - s_playCDDAAction.start(this, start, false, eastl::move(callback)); -} - -void psyqo::CDRomDevice::resumeCDDA(eastl::function &&callback) { - Kernel::assert(m_callback == nullptr, "CDRomDevice::resumeCDDA called with pending action"); - s_playCDDAAction.start(this, eastl::move(callback)); -} - void psyqo::CDRomDevice::switchAction(ActionBase *action) { Kernel::assert(m_action == nullptr, "CDRomDevice can only have one action active at a given time"); m_action = action;