From 46b397d67445629611252b1af7ef5cc18995727c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sun, 29 Dec 2024 00:11:01 -0800 Subject: [PATCH] Adding more coroutine glue, and cleaned up demo. --- src/mips/psyqo-paths/cdrom-loader.hh | 45 ++++++- src/mips/psyqo/cdrom-device.hh | 118 +++++++++++++++++- src/mips/psyqo/cdrom.hh | 40 ++++++ .../coroutine-demo-2/coroutine-demo-2.cpp | 3 +- .../coroutine-demo/coroutine-demo.cpp | 118 +++++++----------- src/mips/psyqo/gpu.hh | 27 ++-- src/mips/psyqo/iso9660-parser.hh | 41 ++++++ .../psyqo/src/cdrom-device-readsectors.cpp | 15 --- 8 files changed, 297 insertions(+), 110 deletions(-) diff --git a/src/mips/psyqo-paths/cdrom-loader.hh b/src/mips/psyqo-paths/cdrom-loader.hh index c0040d178..81bb830d2 100644 --- a/src/mips/psyqo-paths/cdrom-loader.hh +++ b/src/mips/psyqo-paths/cdrom-loader.hh @@ -30,6 +30,8 @@ SOFTWARE. #include #include +#include + #include "psyqo/gpu.hh" #include "psyqo/iso9660-parser.hh" #include "psyqo/task.hh" @@ -45,10 +47,34 @@ namespace psyqo::paths { * the data of the file, or an empty vector if the file could not be read. * This is going to allocate memory in different places. Only one file can * be read at a time, but it is safe to call readFile() again from the - * callback. + * callback. If preferred, the loader can be cascaded into another `TaskQueue`. + * Also, for convenience, readFile() can be awaited on using the co_await + * keyword in a coroutine. */ class CDRomLoader { + struct ReadFileAwaiter { + ReadFileAwaiter(eastl::string_view path, GPU &gpu, ISO9660Parser &parser, CDRomLoader &loader) + : m_path(path), m_gpu(gpu), m_parser(parser), m_loader(loader) {} + ~ReadFileAwaiter() {} + constexpr bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_loader.readFile(m_path, m_gpu, m_parser, [handle, this](eastl::vector &&data) { + m_data = eastl::move(data); + handle.resume(); + }); + } + eastl::vector await_resume() { return eastl::move(m_data); } + + private: + eastl::string_view m_path; + GPU &m_gpu; + ISO9660Parser &m_parser; + CDRomLoader &m_loader; + eastl::vector m_data; + }; + public: /** * @brief Reads a file from the CDRom. @@ -61,16 +87,23 @@ class CDRomLoader { * will be called with the data of the file, or an empty vector if the file * could not be read. */ - void readFile(eastl::string_view path, GPU& gpu, ISO9660Parser& parser, - eastl::function&&)>&& callback) { + void readFile(eastl::string_view path, GPU &gpu, ISO9660Parser &parser, + eastl::function &&)> &&callback) { setupQueue(path, gpu, parser, eastl::move(callback)); m_queue.run(); } + psyqo::TaskQueue::Task scheduleReadFile(eastl::string_view path, GPU &gpu, ISO9660Parser &parser) { + setupQueue(path, gpu, parser, {}); + return m_queue.schedule(); + } + ReadFileAwaiter readFile(eastl::string_view path, GPU &gpu, ISO9660Parser &parser) { + return {path, gpu, parser, *this}; + } private: - void setupQueue(eastl::string_view path, GPU& gpu, ISO9660Parser& parser, - eastl::function&&)>&& callback); - eastl::function&&)> m_callback; + void setupQueue(eastl::string_view path, GPU &gpu, ISO9660Parser &parser, + eastl::function &&)> &&callback); + eastl::function &&)> m_callback; psyqo::TaskQueue m_queue; ISO9660Parser::ReadRequest m_request; eastl::vector m_data; diff --git a/src/mips/psyqo/cdrom-device.hh b/src/mips/psyqo/cdrom-device.hh index c3027c742..c17e66e95 100644 --- a/src/mips/psyqo/cdrom-device.hh +++ b/src/mips/psyqo/cdrom-device.hh @@ -31,6 +31,7 @@ SOFTWARE. #include #include +#include #include #include @@ -69,7 +70,10 @@ concept IsCDRomDeviceStateEnum = * quickly, and should not be used in performance-critical code, as they * can still block the system for several milliseconds. The callbacks * will be called from the main thread, and have a boolean parameter - * that indicates whether the operation was successful. + * that indicates whether the operation was successful. Last but not + * least, the class provides a coroutine-friendly API, which allows + * the use of the `co_await` keyword to suspend the coroutine until + * the operation is complete. * */ class CDRomDevice final : public CDRom { @@ -82,6 +86,111 @@ class CDRomDevice final : public CDRom { unsigned index; }; + struct ResetAwaiter { + ResetAwaiter(CDRomDevice &device) : m_device(device) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.reset([handle, this](bool result) { + m_result = result; + handle.resume(); + }); + } + bool await_resume() { return m_result; } + + private: + CDRomDevice &m_device; + bool m_result; + }; + + struct GetTOCSizeAwaiter { + GetTOCSizeAwaiter(CDRomDevice &device) : m_device(device) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.getTOCSize(&m_result, [handle, this](bool success) { + m_success = success; + handle.resume(); + }); + } + unsigned await_resume() { return m_success ? m_result : 0; } + + private: + CDRomDevice &m_device; + unsigned m_result; + bool m_success; + }; + + struct ReadTOCAwaiter { + ReadTOCAwaiter(CDRomDevice &device, MSF *toc, unsigned size) : m_device(device), m_toc(toc), m_size(size) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.readTOC(m_toc, m_size, [handle, this](bool result) { + m_result = result; + handle.resume(); + }); + } + bool await_resume() { return m_result; } + + private: + CDRomDevice &m_device; + MSF *m_toc; + unsigned m_size; + bool m_result; + }; + + struct MuteAwaiter { + MuteAwaiter(CDRomDevice &device) : m_device(device) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.mute([handle, this](bool result) { + m_result = result; + handle.resume(); + }); + } + bool await_resume() { return m_result; } + + private: + CDRomDevice &m_device; + bool m_result; + }; + + struct UnmuteAwaiter { + UnmuteAwaiter(CDRomDevice &device) : m_device(device) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.unmute([handle, this](bool result) { + m_result = result; + handle.resume(); + }); + } + bool await_resume() { return m_result; } + + private: + CDRomDevice &m_device; + bool m_result; + }; + + struct GetPlaybackLocationAwaiter { + GetPlaybackLocationAwaiter(CDRomDevice &device) : m_device(device) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_device.getPlaybackLocation([handle, this](PlaybackLocation *location) { + m_location = location; + handle.resume(); + }); + } + PlaybackLocation *await_resume() { return m_location; } + + private: + CDRomDevice &m_device; + PlaybackLocation *m_location; + }; + private: struct ActionBase { const char *name() const { return m_name; } @@ -133,6 +242,7 @@ class CDRomDevice final : public CDRom { void reset(eastl::function &&callback); TaskQueue::Task scheduleReset(); bool resetBlocking(GPU &); + ResetAwaiter reset() { return {*this}; } /** * @brief Reads sectors from the CDRom. @@ -151,7 +261,6 @@ class CDRomDevice final : public CDRom { * */ void readSectors(uint32_t sector, uint32_t count, void *buffer, eastl::function &&callback) override; - TaskQueue::Task scheduleReadSectors(uint32_t sector, uint32_t count, void *buffer); bool readSectorsBlocking(uint32_t sector, uint32_t count, void *buffer, GPU &); /** @@ -166,6 +275,7 @@ class CDRomDevice final : public CDRom { void getTOCSize(unsigned *size, eastl::function &&callback); TaskQueue::Task scheduleGetTOCSize(unsigned *size); unsigned getTOCSizeBlocking(GPU &); + GetTOCSizeAwaiter getTOCSize() { return {*this}; } /** * @brief Reads the Table of Contents from the CDRom. @@ -187,6 +297,7 @@ class CDRomDevice final : public CDRom { void readTOC(MSF *toc, unsigned size, eastl::function &&callback); TaskQueue::Task scheduleReadTOC(MSF *toc, unsigned size); bool readTOCBlocking(MSF *toc, unsigned size, GPU &); + ReadTOCAwaiter readTOC(MSF *toc, unsigned size) { return {*this, toc, size}; } /** * @brief Mutes the CD audio for both CDDA and CDXA. @@ -196,6 +307,7 @@ class CDRomDevice final : public CDRom { void mute(eastl::function &&callback); TaskQueue::Task scheduleMute(); void muteBlocking(GPU &); + MuteAwaiter mute() { return MuteAwaiter(*this); } /** * @brief Unmutes the CD audio for both CDDA and CDXA. @@ -205,6 +317,7 @@ class CDRomDevice final : public CDRom { void unmute(eastl::function &&callback); TaskQueue::Task scheduleUnmute(); void unmuteBlocking(GPU &); + UnmuteAwaiter unmute() { return {*this}; } /** * @brief Begins playing CDDA audio from a given starting point. @@ -275,6 +388,7 @@ class CDRomDevice final : public CDRom { void getPlaybackLocation(PlaybackLocation *location, eastl::function &&callback); void getPlaybackLocation(eastl::function &&callback); TaskQueue::Task scheduleGetPlaybackLocation(PlaybackLocation *location); + GetPlaybackLocationAwaiter getPlaybackLocation() { return {*this}; } /** * @brief Set the Volume of the CDDA audio. diff --git a/src/mips/psyqo/cdrom.hh b/src/mips/psyqo/cdrom.hh index 0d332401a..cbe5aad42 100644 --- a/src/mips/psyqo/cdrom.hh +++ b/src/mips/psyqo/cdrom.hh @@ -29,6 +29,8 @@ SOFTWARE. #include #include +#include + #include "psyqo/task.hh" namespace psyqo { @@ -42,6 +44,28 @@ namespace psyqo { */ class CDRom { + struct ReadSectorsAwaiter { + ReadSectorsAwaiter(uint32_t sector, uint32_t count, void *buffer, CDRom &cdrom) + : m_sector(sector), m_count(count), m_buffer(buffer), m_cdrom(cdrom) {} + ~ReadSectorsAwaiter() {} + constexpr bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_cdrom.readSectors(m_sector, m_count, m_buffer, [handle, this](bool result) { + m_result = result; + handle.resume(); + }); + } + bool await_resume() { return m_result; } + + private: + uint32_t m_sector; + uint32_t m_count; + void *m_buffer; + CDRom &m_cdrom; + bool m_result; + }; + public: virtual ~CDRom() {} /** @@ -100,6 +124,22 @@ class CDRom { */ TaskQueue::Task scheduleReadRequest(ReadRequest *request); + /** + * @brief Wrapper around the readSectors method for coroutines. + * + * @details This method will return an `Awaiter` object that can be used to + * suspend the coroutine until the read operation is complete. This is + * meant to be used in conjunction with the `co_await` keyword, in a coroutine. + * + * @param sector The sector to read. + * @param count The number of sectors to read. + * @param buffer The buffer to read into. + * @return ReadSectorsAwaiter The awaitable object to be used with the `co_await` keyword. + */ + ReadSectorsAwaiter readSectorsForCoroutine(uint32_t sector, uint32_t count, void *buffer) { + return {sector, count, buffer, *this}; + } + private: ReadRequest m_readRequest; }; diff --git a/src/mips/psyqo/examples/coroutine-demo-2/coroutine-demo-2.cpp b/src/mips/psyqo/examples/coroutine-demo-2/coroutine-demo-2.cpp index 47a2c0549..29a1a218b 100644 --- a/src/mips/psyqo/examples/coroutine-demo-2/coroutine-demo-2.cpp +++ b/src/mips/psyqo/examples/coroutine-demo-2/coroutine-demo-2.cpp @@ -79,9 +79,8 @@ void CoroutineDemoScene::start(StartReason reason) { m_coroutine.resume(); } -using namespace psyqo::timer_literals; - psyqo::Coroutine<> CoroutineDemoScene::coroutine() { + using namespace psyqo::timer_literals; m_text = "Coroutine... sleeping for 2s"; co_await gpu().delay(2_s); m_text = "Waking up... sleeping for 1s"; diff --git a/src/mips/psyqo/examples/coroutine-demo/coroutine-demo.cpp b/src/mips/psyqo/examples/coroutine-demo/coroutine-demo.cpp index 42ea327ef..a9b4be01b 100644 --- a/src/mips/psyqo/examples/coroutine-demo/coroutine-demo.cpp +++ b/src/mips/psyqo/examples/coroutine-demo/coroutine-demo.cpp @@ -51,88 +51,76 @@ class CoroutineDemo final : public psyqo::Application { psyqo::Coroutine<> m_coroutine; uint8_t m_buffer[2048]; uint32_t m_systemCnfSize = 0; + + psyqo::Coroutine<> generalCoroutine(); + psyqo::Coroutine<> resetCDRomController(); }; -psyqo::Coroutine<> coroutine(CoroutineDemo *demo) { - syscall_puts("Starting CD-Rom coroutine...\n"); - auto *coroutine = &demo->m_coroutine; - psyqo::Coroutine<>::Awaiter awaiter = coroutine->awaiter(); - bool success = false; +class CoroutineDemoScene final : public psyqo::Scene { + void frame() override; +}; + +CoroutineDemo coroutineDemo; +CoroutineDemoScene coroutineDemoScene; + +} // namespace + +psyqo::Coroutine<> CoroutineDemo::resetCDRomController() { bool doneOnce = false; - using namespace psyqo::timer_literals; - while (!success) { - if (doneOnce) { - demo->gpu().armTimer(demo->gpu().now() + 1_s, [coroutine](auto) { coroutine->resume(); }); - co_await awaiter; - } + while (true) { + using namespace psyqo::timer_literals; + if (doneOnce) co_await gpu().delay(1_s); doneOnce = true; - demo->m_text = "Resetting CD-Rom controller..."; + m_text = "Resetting CD-Rom controller..."; syscall_puts("Resetting CD-Rom controller...\n"); - demo->m_cdrom.reset([coroutine, &success](bool s) { - success = s; - coroutine->resume(); - }); - co_await awaiter; - if (!success) { - demo->m_text = "Controller reset failed, retrying..."; + if (!co_await m_cdrom.reset()) { + m_text = "Controller reset failed, retrying..."; syscall_puts("Failed. Retrying...\n"); + continue; } + co_return; } +} + +psyqo::Coroutine<> CoroutineDemo::generalCoroutine() { + syscall_puts("Starting CD-Rom coroutine...\n"); + co_await resetCDRomController(); syscall_puts("Success. Initializing ISO9660 parser and looking for files.\n"); - success = false; - doneOnce = false; + bool doneOnce = false; while (true) { - if (doneOnce) { - demo->gpu().armTimer(demo->gpu().now() + 1_s, [coroutine](auto) { coroutine->resume(); }); - co_await awaiter; - } + using namespace psyqo::timer_literals; + if (doneOnce) co_await gpu().delay(1_s); doneOnce = true; - demo->m_text = "Reading CD-Rom..."; - demo->m_isoParser.initialize([coroutine, &success](bool s) { - success = s; - coroutine->resume(); - }); - co_await awaiter; - - if (!success) { - demo->m_text = "CD-Rom failed reading, retrying..."; + m_text = "Reading CD-Rom..."; + + if (!co_await m_isoParser.initialize()) { + m_text = "CD-Rom failed reading, retrying..."; syscall_puts("ISO9660 parser failed to initialize - wrong CD, damaged CD, or no CD present\n"); continue; } syscall_puts("ISO9660 parser initialized successfully, looking for SYSTEM.CNF;1...\n"); psyqo::ISO9660Parser::DirEntry entry; - demo->m_isoParser.getDirentry("SYSTEM.CNF;1", &entry, [coroutine, &success](bool s) { - success = s; - coroutine->resume(); - }); - co_await awaiter; - - if (!success) { - demo->m_text = "CD-Rom failed reading, retrying..."; + if (!co_await m_isoParser.getDirentry("SYSTEM.CNF;1", &entry)) { + m_text = "CD-Rom failed reading, retrying..."; syscall_puts("ISO9660 parser failed to read disc to locate SYSTEM.CNF;1 - damaged CD ?\n"); continue; } - demo->m_text = "Reading CD-Rom..."; + m_text = "Reading CD-Rom..."; eastl::fixed_string exename = "PSX.EXE;1"; if (entry.type != psyqo::ISO9660Parser::DirEntry::FILE) { syscall_puts("SYSTEM.CNF;1 file not found...\n"); - demo->m_systemCnfSize = 0; + m_systemCnfSize = 0; } else { syscall_puts("SYSTEM.CNF;1 file found, reading...\n"); - demo->m_cdrom.readSectors(entry.LBA, 1, demo->m_buffer, [coroutine, &success](bool s) { - success = s; - coroutine->resume(); - }); - co_await awaiter; - if (!success) { - demo->m_text = "CD-Rom failed reading, retrying..."; + if (!co_await m_cdrom.readSectorsForCoroutine(entry.LBA, 1, m_buffer)) { + m_text = "CD-Rom failed reading, retrying..."; syscall_puts("Failed to read system.cnf - damaged CD ?\n"); continue; } - demo->m_systemCnfSize = eastl::min(entry.size, uint32_t(2048u)); - eastl::string_view systemcnf{reinterpret_cast(demo->m_buffer), demo->m_systemCnfSize}; + m_systemCnfSize = eastl::min(entry.size, uint32_t(2048u)); + eastl::string_view systemcnf{reinterpret_cast(m_buffer), m_systemCnfSize}; syscall_puts("SYSTEM.CNF;1 file read, parsing...\n"); while (!systemcnf.empty()) { @@ -168,37 +156,23 @@ psyqo::Coroutine<> coroutine(CoroutineDemo *demo) { ramsyscall_printf("Looking for file %s\n", exename.c_str()); - demo->m_isoParser.getDirentry(exename, &entry, [coroutine, &success](bool s) { - success = s; - coroutine->resume(); - }); - co_await awaiter; - if (!success) { - demo->m_text = "CD-Rom failed reading, retrying..."; + if (!co_await m_isoParser.getDirentry(exename, &entry)) { + m_text = "CD-Rom failed reading, retrying..."; ramsyscall_printf("Failed to read iso9660 structure to locate %s - damaged CD ?\n", exename.c_str()); continue; } if (entry.type == psyqo::ISO9660Parser::DirEntry::FILE) { ramsyscall_printf("%s boot file found!\n", exename.c_str()); - demo->m_text = "Success!"; + m_text = "Success!"; co_return; } ramsyscall_printf("%s boot file not found... invalid CD-Rom?\n", exename.c_str()); - demo->m_text = "Invalid CD-Rom, retrying..."; + m_text = "Invalid CD-Rom, retrying..."; } } -class CoroutineDemoScene final : public psyqo::Scene { - void frame() override; -}; - -CoroutineDemo coroutineDemo; -CoroutineDemoScene coroutineDemoScene; - -} // namespace - void CoroutineDemo::prepare() { psyqo::GPU::Configuration config; config.set(psyqo::GPU::Resolution::W320) @@ -212,7 +186,7 @@ void CoroutineDemo::prepare() { void CoroutineDemo::createScene() { m_font.uploadSystemFont(gpu()); pushScene(&coroutineDemoScene); - m_coroutine = coroutine(this); + m_coroutine = generalCoroutine(); m_coroutine.resume(); } diff --git a/src/mips/psyqo/gpu.hh b/src/mips/psyqo/gpu.hh index b1bbafe35..ca3381daf 100644 --- a/src/mips/psyqo/gpu.hh +++ b/src/mips/psyqo/gpu.hh @@ -85,6 +85,18 @@ consteval uint32_t operator""_s(long double value) { return value * 1'000'000; } */ class GPU { + struct TimerAwaiter { + TimerAwaiter(GPU &gpu, uint32_t deadline) : m_gpu(gpu), m_deadline(deadline) {} + ~TimerAwaiter() {} + constexpr bool await_ready() const { return false; } + void await_suspend(std::coroutine_handle<> handle) { + m_gpu.armTimer(m_deadline, [handle](uint32_t) { handle.resume(); }); + } + void await_resume() {} + GPU &m_gpu; + uintptr_t m_deadline; + }; + public: struct Configuration; enum class Resolution { W256, W320, W368, W512, W640 }; @@ -424,17 +436,6 @@ class GPU { */ uintptr_t armTimer(uint32_t deadline, eastl::function &&callback); - struct TimerAwaitable { - TimerAwaitable(GPU &gpu, uint32_t deadline) : m_gpu(gpu), m_deadline(deadline) {} - ~TimerAwaitable() {} - constexpr bool await_ready() const { return false; } - void await_suspend(std::coroutine_handle<> handle) { - m_gpu.armTimer(m_deadline, [handle](uint32_t) { handle.resume(); }); - } - void await_resume() {} - GPU &m_gpu; - uintptr_t m_deadline; - }; /** * @brief Delays the coroutine for a specified amount of time. * @@ -444,9 +445,9 @@ class GPU { * the timer literals can be used to specify the delay. The function can only be called * from within a coroutine, and is meant to be used with the `co_await` keyword. * @param amount The amount of time to delay the coroutine in microseconds. - * @return TimerAwaitable The awaitable object to be used with the `co_await` keyword. + * @return TimerAwaiter The awaitable object to be used with the `co_await` keyword. */ - TimerAwaitable delay(uint32_t microseconds) { return TimerAwaitable(*this, now() + microseconds); } + TimerAwaiter delay(uint32_t microseconds) { return {*this, now() + microseconds}; } /** * @brief Creates a periodic timer. diff --git a/src/mips/psyqo/iso9660-parser.hh b/src/mips/psyqo/iso9660-parser.hh index 4898b91aa..ec4d9e166 100644 --- a/src/mips/psyqo/iso9660-parser.hh +++ b/src/mips/psyqo/iso9660-parser.hh @@ -26,6 +26,8 @@ SOFTWARE. #pragma once +#include + #include #include #include @@ -95,6 +97,23 @@ class ISO9660Parser { */ void initialize(eastl::function callback); TaskQueue::Task scheduleInitialize(); + struct InitializeAwaiter { + InitializeAwaiter(ISO9660Parser& parser) : m_parser(parser) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_parser.initialize([handle, this](bool success) { + m_success = success; + handle.resume(); + }); + } + bool await_resume() { return m_success; } + + private: + ISO9660Parser& m_parser; + bool m_success; + }; + InitializeAwaiter initialize() { return InitializeAwaiter(*this); } /** * @brief Get the Direntry object for a given path. @@ -109,6 +128,28 @@ class ISO9660Parser { */ void getDirentry(eastl::string_view path, DirEntry* entry, eastl::function callback); TaskQueue::Task scheduleGetDirentry(eastl::string_view path, DirEntry* entry); + struct GetDirentryAwaiter { + GetDirentryAwaiter(ISO9660Parser& parser, eastl::string_view path, DirEntry* entry) + : m_parser(parser), m_path(path), m_entry(entry) {} + bool await_ready() const { return false; } + template + void await_suspend(std::coroutine_handle handle) { + m_parser.getDirentry(m_path, m_entry, [handle, this](bool success) { + m_success = success; + handle.resume(); + }); + } + bool await_resume() { return m_success; } + + private: + ISO9660Parser& m_parser; + eastl::string_view m_path; + DirEntry* m_entry; + bool m_success; + }; + GetDirentryAwaiter getDirentry(eastl::string_view path, DirEntry* entry) { + return GetDirentryAwaiter(*this, path, entry); + } /** * @brief Read a file asynchronously. diff --git a/src/mips/psyqo/src/cdrom-device-readsectors.cpp b/src/mips/psyqo/src/cdrom-device-readsectors.cpp index c60ec5eea..b37e20987 100644 --- a/src/mips/psyqo/src/cdrom-device-readsectors.cpp +++ b/src/mips/psyqo/src/cdrom-device-readsectors.cpp @@ -128,21 +128,6 @@ void psyqo::CDRomDevice::readSectors(uint32_t sector, uint32_t count, void *buff 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); }); - }); -} - bool psyqo::CDRomDevice::readSectorsBlocking(uint32_t sector, uint32_t count, void *buffer, GPU &gpu) { Kernel::assert(m_callback == nullptr, "CDRomDevice::readSectorsBlocking called with pending action"); bool success = false;