diff options
Diffstat (limited to 'lib/nes')
| -rw-r--r-- | lib/nes/app/application.cc | 17 | ||||
| -rw-r--r-- | lib/nes/sys/cartridge.cc | 60 | ||||
| -rw-r--r-- | lib/nes/sys/cartridge.hh | 10 | ||||
| -rw-r--r-- | lib/nes/sys/nes.cc | 4 | ||||
| -rw-r--r-- | lib/nes/sys/nes.hh | 6 | ||||
| -rw-r--r-- | lib/nes/sys/types/status.hh | 3 |
6 files changed, 40 insertions, 60 deletions
diff --git a/lib/nes/app/application.cc b/lib/nes/app/application.cc index 0c1a4cb..264e07a 100644 --- a/lib/nes/app/application.cc +++ b/lib/nes/app/application.cc @@ -4,7 +4,7 @@ #include "nes/app/ui/screen.hh" #include "nes/app/graphics/renderer.hh" #include "ui/action.hh" - +#include <fstream> #include <iostream> namespace nes::app @@ -74,7 +74,20 @@ namespace nes::app } case action::load_game: { - console_.emplace(sys::cartridge::from_file(file), display_); + auto stream = std::ifstream{ file, std::ios::binary }; + if (!stream.good()) + { + std::cerr << "Unable to open cartridge file!" << std::endl; + std::abort(); + } + + stream.seekg(0, std::ios::end); + auto const length = stream.tellg(); + stream.seekg(0, std::ios::beg); + auto data = std::vector<u8>(static_cast<u32>(length)); + stream.read(reinterpret_cast<char*>(data.data()), length); + + console_.emplace(display_, data.data(), static_cast<u32>(length)); if (console_->get_status() != sys::status::success) { std::cerr << "Unable to load cartridge: " << to_string(console_->get_status()) << std::endl; diff --git a/lib/nes/sys/cartridge.cc b/lib/nes/sys/cartridge.cc index 43f9430..fcb7e84 100644 --- a/lib/nes/sys/cartridge.cc +++ b/lib/nes/sys/cartridge.cc @@ -5,68 +5,44 @@ namespace nes::sys { - cartridge::cartridge(status const status) - : status_{ status } - { - } - - auto cartridge::from_data(void const* data, u32 const length) -> cartridge + cartridge::cartridge(u8 const* data, u32 const length) { // See: https://www.nesdev.org/wiki/INES auto const bytes = static_cast<u8 const*>(data); - auto res = cartridge{ status::success }; // Parse header. - if (length < header_length) { return cartridge{ status::error_invalid_ines_data }; } + if (length < header_length) { return; } auto const h = header{ bytes }; if (h.get_magic_0() != 'N' || h.get_magic_1() != 'E' || h.get_magic_2() != 'S' || h.get_magic_3() != 0x1A) { - return cartridge{ status::error_invalid_ines_data }; + return; } auto const mapper_number = static_cast<u8>((h.get_mapper_high() << 4) | (h.get_mapper_low() << 0)); - res.mapper_ = &mapper::get(mapper_number); - res.name_table_arrangement_ = h.get_name_table_arrangement(); + mapper_ = &mapper::get(mapper_number); + name_table_arrangement_ = h.get_name_table_arrangement(); // Load program data. auto offset = u32{ 16 }; if (h.get_has_trainer()) { offset += 512; } - res.prg_rom_size_ = h.get_prg_rom_banks() * prg_rom_bank_size; - if (length < offset + res.prg_rom_size_) { return cartridge{ status::error_invalid_ines_data }; } - if (res.prg_rom_size_ > max_prg_rom_size) { return cartridge{ status::error_invalid_ines_data }; } - std::copy_n(&bytes[offset], res.prg_rom_size_, res.prg_rom_); + prg_rom_size_ = h.get_prg_rom_banks() * prg_rom_bank_size; + if (length < offset + prg_rom_size_) { return; } + if (prg_rom_size_ > max_prg_rom_size) { return; } + std::copy_n(&bytes[offset], prg_rom_size_, prg_rom_); - offset += res.prg_rom_size_; + offset += prg_rom_size_; - res.chr_rom_size_ = h.get_chr_rom_banks() * chr_rom_bank_size; - if (length < offset + res.chr_rom_size_) { return cartridge{ status::error_invalid_ines_data }; } - if (res.chr_rom_size_ > max_chr_rom_size) { return cartridge{ status::error_invalid_ines_data }; } - std::copy_n(&bytes[offset], res.chr_rom_size_, res.chr_rom_); - - res.ram_size_ = std::max(h.get_ram_banks(), 1u) * ram_bank_size; - if (res.ram_size_ > max_ram_size) { return cartridge{ status::error_invalid_ines_data }; } - - if (auto const status = res.get_mapper().validate(res); status != status::success) - { - return cartridge{ status }; - } - - return res; - } - - auto cartridge::from_file(std::string_view const path) -> cartridge - { - auto stream = std::ifstream{ path, std::ios::binary }; - if (!stream.good()) { return cartridge{ status::error_system_error }; } + chr_rom_size_ = h.get_chr_rom_banks() * chr_rom_bank_size; + if (length < offset + chr_rom_size_) { return; } + if (chr_rom_size_ > max_chr_rom_size) { return; } + std::copy_n(&bytes[offset], chr_rom_size_, chr_rom_); - stream.seekg(0, std::ios::end); - auto const length = stream.tellg(); - stream.seekg(0, std::ios::beg); - auto data = std::vector<u8>(static_cast<u32>(length)); - stream.read(reinterpret_cast<char*>(data.data()), length); + ram_size_ = std::max(h.get_ram_banks(), 1u) * ram_bank_size; + if (ram_size_ > max_ram_size) { return; } - return from_data(data.data(), static_cast<u32>(length)); + status_ = get_mapper().validate(*this); + if (status_ != status::success) { return; } } } // namespace nes::sys
\ No newline at end of file diff --git a/lib/nes/sys/cartridge.hh b/lib/nes/sys/cartridge.hh index f8c3c3b..2cfb114 100644 --- a/lib/nes/sys/cartridge.hh +++ b/lib/nes/sys/cartridge.hh @@ -51,7 +51,7 @@ namespace nes::sys } }; - status status_{ status::error_uninitialized }; + status status_{ status::error_invalid_ines_data }; u8 prg_rom_[max_prg_rom_size]{}; u8 chr_rom_[max_chr_rom_size]{}; u8 ram_[max_ram_size]{}; @@ -62,10 +62,7 @@ namespace nes::sys mapper* mapper_{ &mapper::invalid() }; public: - explicit cartridge() = default; - - static auto from_data(void const* data, u32 length) -> cartridge; - static auto from_file(std::string_view path) -> cartridge; + explicit cartridge(u8 const* data, u32 length); auto get_status() const -> status { return status_; } auto get_prg_rom() const -> u8 const* { return prg_rom_; } @@ -77,8 +74,5 @@ namespace nes::sys auto get_ram_length() const -> u32 { return ram_size_; } auto get_mapper() const -> mapper& { return *mapper_; } auto get_name_table_arrangement() const -> name_table_arrangement { return name_table_arrangement_; } - - private: - explicit cartridge(status); }; } // namespace nes::sys
\ No newline at end of file diff --git a/lib/nes/sys/nes.cc b/lib/nes/sys/nes.cc index a711f06..3195826 100644 --- a/lib/nes/sys/nes.cc +++ b/lib/nes/sys/nes.cc @@ -3,8 +3,8 @@ namespace nes::sys { - nes::nes(cartridge const& cartridge, display& display) - : cartridge_{ std::move(cartridge) } + nes::nes(display& display, u8 const* rom_data, u32 rom_length) + : cartridge_{ rom_data, rom_length } , display_{ display } , ppu_{ cpu_, cartridge_, display_ } , cpu_{ ppu_, cartridge_, controller_1_, controller_2_ } diff --git a/lib/nes/sys/nes.hh b/lib/nes/sys/nes.hh index 4150935..5e081b3 100644 --- a/lib/nes/sys/nes.hh +++ b/lib/nes/sys/nes.hh @@ -5,6 +5,7 @@ #include "nes/sys/controller.hh" #include "nes/sys/cpu.hh" #include "nes/sys/ppu.hh" +#include <string_view> namespace nes { @@ -25,11 +26,10 @@ namespace nes::sys ppu ppu_; cpu cpu_; cycle_count current_cycles_; - status status_{ status::success }; + status status_{ status::error_invalid_ines_data }; public: - // TODO: Don't copy cartridge - explicit nes(cartridge const&, display&); + explicit nes(display&, u8 const* rom_data, u32 rom_length); nes(nes const&) = delete; nes(nes&&) = delete; diff --git a/lib/nes/sys/types/status.hh b/lib/nes/sys/types/status.hh index c622ffb..9b1e824 100644 --- a/lib/nes/sys/types/status.hh +++ b/lib/nes/sys/types/status.hh @@ -6,7 +6,6 @@ namespace nes::sys enum class status { success, - error_uninitialized, error_system_error, error_invalid_ines_data, error_unsupported_mapper, @@ -19,8 +18,6 @@ namespace nes::sys { case status::success: return "Success"; - case status::error_uninitialized: - return "Uninitialized"; case status::error_system_error: return "System error"; case status::error_invalid_ines_data: |
