From 42b5b66305b96b89f2bf4fa92c4517076c7b313c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 16 Aug 2017 11:56:52 -0400 Subject: [PATCH 1/4] Remove the 6502's use of runtime polymorphism in favour of ordinary templating. --- Machines/Atari2600/Atari2600.cpp | 30 +++++++-------- Machines/Atari2600/Cartridges/Cartridge.hpp | 14 ++++--- .../Cartridges/CartridgeActivisionStack.hpp | 2 + .../Cartridges/CartridgeAtari16k.hpp | 2 + .../Cartridges/CartridgeAtari32k.hpp | 2 + .../Atari2600/Cartridges/CartridgeAtari8k.hpp | 2 + .../Cartridges/CartridgeCBSRAMPlus.hpp | 2 + .../Cartridges/CartridgeCommaVid.hpp | 2 + .../Cartridges/CartridgeMNetwork.hpp | 2 + .../Atari2600/Cartridges/CartridgeMegaBoy.hpp | 2 + .../Cartridges/CartridgeParkerBros.hpp | 2 + .../Cartridges/CartridgePitfall2.hpp | 2 + .../Cartridges/CartridgeTigervision.hpp | 2 + .../Atari2600/Cartridges/CartridgeUnpaged.hpp | 2 + Machines/Commodore/1540/C1540.cpp | 9 +++-- Machines/Commodore/1540/C1540.hpp | 4 +- Machines/Commodore/Vic-20/Vic20.cpp | 17 ++++++--- Machines/Commodore/Vic-20/Vic20.hpp | 6 ++- Machines/Electron/Electron.cpp | 19 ++++++---- Machines/Electron/Electron.hpp | 6 ++- Machines/Oric/Oric.cpp | 11 +++--- Machines/Oric/Oric.hpp | 4 +- Processors/6502/6502.hpp | 37 +++++++++++-------- 23 files changed, 117 insertions(+), 64 deletions(-) diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index e3d732b9e..0d705ed45 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -83,35 +83,35 @@ void Machine::set_switch_is_enabled(Atari2600Switch input, bool state) { void Machine::configure_as_target(const StaticAnalyser::Target &target) { const std::vector &rom = target.cartridges.front()->get_segments().front().data; switch(target.atari.paging_model) { - case StaticAnalyser::Atari2600PagingModel::ActivisionStack: bus_.reset(new CartridgeActivisionStack(rom)); break; - case StaticAnalyser::Atari2600PagingModel::CBSRamPlus: bus_.reset(new CartridgeCBSRAMPlus(rom)); break; - case StaticAnalyser::Atari2600PagingModel::CommaVid: bus_.reset(new CartridgeCommaVid(rom)); break; - case StaticAnalyser::Atari2600PagingModel::MegaBoy: bus_.reset(new CartridgeMegaBoy(rom)); break; - case StaticAnalyser::Atari2600PagingModel::MNetwork: bus_.reset(new CartridgeMNetwork(rom)); break; - case StaticAnalyser::Atari2600PagingModel::None: bus_.reset(new CartridgeUnpaged(rom)); break; - case StaticAnalyser::Atari2600PagingModel::ParkerBros: bus_.reset(new CartridgeParkerBros(rom)); break; - case StaticAnalyser::Atari2600PagingModel::Pitfall2: bus_.reset(new CartridgePitfall2(rom)); break; - case StaticAnalyser::Atari2600PagingModel::Tigervision: bus_.reset(new CartridgeTigervision(rom)); break; + case StaticAnalyser::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::CartridgeActivisionStack(rom)); break; + case StaticAnalyser::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::CartridgeCBSRAMPlus(rom)); break; + case StaticAnalyser::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::CartridgeCommaVid(rom)); break; + case StaticAnalyser::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::CartridgeMegaBoy(rom)); break; + case StaticAnalyser::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::CartridgeMNetwork(rom)); break; + case StaticAnalyser::Atari2600PagingModel::None: bus_.reset(new Cartridge::CartridgeUnpaged(rom)); break; + case StaticAnalyser::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::CartridgeParkerBros(rom)); break; + case StaticAnalyser::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::CartridgePitfall2(rom)); break; + case StaticAnalyser::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::CartridgeTigervision(rom)); break; case StaticAnalyser::Atari2600PagingModel::Atari8k: if(target.atari.uses_superchip) { - bus_.reset(new CartridgeAtari8kSuperChip(rom)); + bus_.reset(new Cartridge::CartridgeAtari8kSuperChip(rom)); } else { - bus_.reset(new CartridgeAtari8k(rom)); + bus_.reset(new Cartridge::CartridgeAtari8k(rom)); } break; case StaticAnalyser::Atari2600PagingModel::Atari16k: if(target.atari.uses_superchip) { - bus_.reset(new CartridgeAtari16kSuperChip(rom)); + bus_.reset(new Cartridge::CartridgeAtari16kSuperChip(rom)); } else { - bus_.reset(new CartridgeAtari16k(rom)); + bus_.reset(new Cartridge::CartridgeAtari16k(rom)); } break; case StaticAnalyser::Atari2600PagingModel::Atari32k: if(target.atari.uses_superchip) { - bus_.reset(new CartridgeAtari32kSuperChip(rom)); + bus_.reset(new Cartridge::CartridgeAtari32kSuperChip(rom)); } else { - bus_.reset(new CartridgeAtari32k(rom)); + bus_.reset(new Cartridge::CartridgeAtari32k(rom)); } break; } diff --git a/Machines/Atari2600/Cartridges/Cartridge.hpp b/Machines/Atari2600/Cartridges/Cartridge.hpp index 638964fe8..059ae3915 100644 --- a/Machines/Atari2600/Cartridges/Cartridge.hpp +++ b/Machines/Atari2600/Cartridges/Cartridge.hpp @@ -13,17 +13,19 @@ #include "../Bus.hpp" namespace Atari2600 { +namespace Cartridge { template class Cartridge: - public CPU::MOS6502::Processor>, + public CPU::MOS6502::BusHandler, public Bus { public: Cartridge(const std::vector &rom) : + m6502_(*this), rom_(rom) {} - void run_for(const Cycles cycles) { CPU::MOS6502::Processor>::run_for(cycles); } - void set_reset_line(bool state) { CPU::MOS6502::Processor>::set_reset_line(state); } + void run_for(const Cycles cycles) { m6502_.run_for(cycles); } + void set_reset_line(bool state) { m6502_.set_reset_line(state); } void advance_cycles(int cycles) {} // to satisfy CPU::MOS6502::Processor @@ -91,7 +93,7 @@ template class Cartridge: case 0x00: update_video(); tia_->set_sync(*value & 0x02); break; case 0x01: update_video(); tia_->set_blank(*value & 0x02); break; - case 0x02: CPU::MOS6502::Processor>::set_ready_line(true); break; + case 0x02: m6502_.set_ready_line(true); break; case 0x03: update_video(); tia_->reset_horizontal_counter(); break; // TODO: audio will now be out of synchronisation — fix @@ -156,7 +158,7 @@ template class Cartridge: } } - if(!tia_->get_cycles_until_horizontal_blank(cycles_since_video_update_)) CPU::MOS6502::Processor>::set_ready_line(false); + if(!tia_->get_cycles_until_horizontal_blank(cycles_since_video_update_)) m6502_.set_ready_line(false); return Cycles(cycles_run_for / 3); } @@ -168,9 +170,11 @@ template class Cartridge: } protected: + CPU::MOS6502::Processor> m6502_; std::vector rom_; }; +} } #endif /* Atari2600_Cartridge_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp b/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp index 6f26074f9..b79807470 100644 --- a/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp @@ -10,6 +10,7 @@ #define Atari2600_CartridgeActivisionStack_hpp namespace Atari2600 { +namespace Cartridge { class CartridgeActivisionStack: public Cartridge { public: @@ -45,6 +46,7 @@ class CartridgeActivisionStack: public Cartridge { uint8_t last_opcode_; }; +} } #endif /* Atari2600_CartridgeActivisionStack_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp b/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp index 383fd449d..c109d76e4 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeAtari16k: public Cartridge { public: @@ -61,6 +62,7 @@ class CartridgeAtari16kSuperChip: public Cartridge { uint8_t ram_[128]; }; +} } #endif /* Atari2600_CartridgeAtari16k_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp b/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp index 6d3a2cab7..3ae85f052 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeAtari32k: public Cartridge { public: @@ -61,6 +62,7 @@ class CartridgeAtari32kSuperChip: public Cartridge { uint8_t ram_[128]; }; +} } #endif /* Atari2600_CartridgeAtari32k_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp b/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp index e753277ae..04e489c91 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeAtari8k: public Cartridge { public: @@ -63,6 +64,7 @@ class CartridgeAtari8kSuperChip: public Cartridge { uint8_t ram_[128]; }; +} } #endif /* Atari2600_CartridgeAtari8k_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp b/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp index 88b1277f4..ffde1af7b 100644 --- a/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeCBSRAMPlus: public Cartridge { public: @@ -39,6 +40,7 @@ class CartridgeCBSRAMPlus: public Cartridge { uint8_t ram_[256]; }; +} } #endif /* Atari2600_CartridgeCBSRAMPlus_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp b/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp index d547f8da2..26c8e89ce 100644 --- a/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp @@ -10,6 +10,7 @@ #define Atari2600_CartridgeCommaVid_hpp namespace Atari2600 { +namespace Cartridge { class CartridgeCommaVid: public Cartridge { public: @@ -37,6 +38,7 @@ class CartridgeCommaVid: public Cartridge { uint8_t ram_[1024]; }; +} } #endif /* Atari2600_CartridgeCommaVid_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp b/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp index 0d3305847..b759e70db 100644 --- a/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeMNetwork: public Cartridge { public: @@ -63,6 +64,7 @@ class CartridgeMNetwork: public Cartridge { uint8_t low_ram_[1024], high_ram_[1024]; }; +} } #endif /* Atari2600_CartridgeMNetwork_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp b/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp index 03997d4fc..1d2a09e73 100644 --- a/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeMegaBoy: public Cartridge { public: @@ -40,6 +41,7 @@ class CartridgeMegaBoy: public Cartridge { uint8_t current_page_; }; +} } #endif /* CartridgeMegaBoy_h */ diff --git a/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp b/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp index 184a75cc2..4138991ba 100644 --- a/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeParkerBros: public Cartridge { public: @@ -41,6 +42,7 @@ class CartridgeParkerBros: public Cartridge { uint8_t *rom_ptr_[4]; }; +} } #endif /* Atari2600_CartridgeParkerBros_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp b/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp index 7921a918a..c77239113 100644 --- a/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp +++ b/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp @@ -10,6 +10,7 @@ #define Atari2600_CartridgePitfall2_hpp namespace Atari2600 { +namespace Cartridge { class CartridgePitfall2: public Cartridge { public: @@ -128,6 +129,7 @@ class CartridgePitfall2: public Cartridge { Cycles cycles_since_audio_update_; }; +} } #endif /* Atari2600_CartridgePitfall2_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp b/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp index 12b12abef..1abcedac5 100644 --- a/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeTigervision: public Cartridge { public: @@ -35,6 +36,7 @@ class CartridgeTigervision: public Cartridge { uint8_t *rom_ptr_[2]; }; +} } #endif /* Atari2600_CartridgeTigervision_hpp */ diff --git a/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp b/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp index 542c458c8..cc09b5a53 100644 --- a/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp +++ b/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp @@ -12,6 +12,7 @@ #include "Cartridge.hpp" namespace Atari2600 { +namespace Cartridge { class CartridgeUnpaged: public Cartridge { public: @@ -25,6 +26,7 @@ class CartridgeUnpaged: public Cartridge { } }; +} } #endif /* Atari2600_CartridgeUnpaged_hpp */ diff --git a/Machines/Commodore/1540/C1540.cpp b/Machines/Commodore/1540/C1540.cpp index e996b73c4..fe74bd13b 100644 --- a/Machines/Commodore/1540/C1540.cpp +++ b/Machines/Commodore/1540/C1540.cpp @@ -13,6 +13,7 @@ using namespace Commodore::C1540; Machine::Machine() : + m6502_(*this), shift_register_(0), Storage::Disk::Controller(1000000, 4, 300), serial_port_(new SerialPort), @@ -80,7 +81,7 @@ void Machine::set_disk(std::shared_ptr disk) { } void Machine::run_for(const Cycles cycles) { - CPU::MOS6502::Processor::run_for(cycles); + m6502_.run_for(cycles); set_motor_on(drive_VIA_.get_motor_enabled()); if(drive_VIA_.get_motor_enabled()) // TODO: motor speed up/down Storage::Disk::Controller::run_for(cycles); @@ -90,7 +91,7 @@ void Machine::run_for(const Cycles cycles) { void Machine::mos6522_did_change_interrupt_status(void *mos6522) { // both VIAs are connected to the IRQ line - set_irq_line(serial_port_VIA_->get_interrupt_line() || drive_VIA_.get_interrupt_line()); + m6502_.set_irq_line(serial_port_VIA_->get_interrupt_line() || drive_VIA_.get_interrupt_line()); } #pragma mark - Disk drive @@ -108,10 +109,10 @@ void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole) drive_VIA_.set_data_input((uint8_t)shift_register_); bit_window_offset_ = 0; if(drive_VIA_.get_should_set_overflow()) { - set_overflow_line(true); + m6502_.set_overflow_line(true); } } - else set_overflow_line(false); + else m6502_.set_overflow_line(false); } // the 1540 does not recognise index holes diff --git a/Machines/Commodore/1540/C1540.hpp b/Machines/Commodore/1540/C1540.hpp index 4fdf87322..59b1ba745 100644 --- a/Machines/Commodore/1540/C1540.hpp +++ b/Machines/Commodore/1540/C1540.hpp @@ -120,7 +120,7 @@ class SerialPort : public ::Commodore::Serial::Port { Provides an emulation of the C1540. */ class Machine: - public CPU::MOS6502::Processor, + public CPU::MOS6502::BusHandler, public MOS::MOS6522IRQDelegate::Delegate, public DriveVIA::Delegate, public Storage::Disk::Controller { @@ -152,6 +152,8 @@ class Machine: void drive_via_did_set_data_density(void *driveVIA, int density); private: + CPU::MOS6502::Processor m6502_; + uint8_t ram_[0x800]; uint8_t rom_[0x4000]; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 2c748af0e..794310ba2 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -17,6 +17,7 @@ using namespace Commodore::Vic20; Machine::Machine() : + m6502_(*this), rom_(nullptr), is_running_at_zero_cost_(false), tape_(new Storage::Tape::BinaryTapePlayer(1022727)), @@ -138,7 +139,7 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint *value = 0x0c; // i.e. NOP abs } else if(address == 0xf90b) { - uint8_t x = (uint8_t)get_value_of_register(CPU::MOS6502::Register::X); + uint8_t x = (uint8_t)m6502_.get_value_of_register(CPU::MOS6502::Register::X); if(x == 0xe) { Storage::Tape::Commodore::Parser parser; std::unique_ptr data = parser.get_next_data(tape_->get_tape()); @@ -159,13 +160,13 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint // set tape status, carry and flag user_basic_memory_[0x90] |= 0x40; - uint8_t flags = (uint8_t)get_value_of_register(CPU::MOS6502::Register::Flags); + uint8_t flags = (uint8_t)m6502_.get_value_of_register(CPU::MOS6502::Register::Flags); flags &= ~(uint8_t)(CPU::MOS6502::Flag::Carry | CPU::MOS6502::Flag::Interrupt); - set_value_of_register(CPU::MOS6502::Register::Flags, flags); + m6502_.set_value_of_register(CPU::MOS6502::Register::Flags, flags); // to ensure that execution proceeds to 0xfccf, pretend a NOP was here and // ensure that the PC leaps to 0xfccf - set_value_of_register(CPU::MOS6502::Register::ProgramCounter, 0xfccf); + m6502_.set_value_of_register(CPU::MOS6502::Register::ProgramCounter, 0xfccf); *value = 0xea; // i.e. NOP implied } } @@ -194,11 +195,15 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint return Cycles(1); } +void Machine::run_for(const Cycles cycles) { + m6502_.run_for(cycles); +} + #pragma mark - 6522 delegate void Machine::mos6522_did_change_interrupt_status(void *mos6522) { - set_nmi_line(user_port_via_->get_interrupt_line()); - set_irq_line(keyboard_via_->get_interrupt_line()); + m6502_.set_nmi_line(user_port_via_->get_interrupt_line()); + m6502_.set_irq_line(keyboard_via_->get_interrupt_line()); } #pragma mark - Setup diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 6e459a976..957ed58da 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -139,7 +139,7 @@ class Vic6560: public MOS::MOS6560 { }; class Machine: - public CPU::MOS6502::Processor, + public CPU::MOS6502::BusHandler, public CRTMachine::Machine, public MOS::MOS6522IRQDelegate::Delegate, public Utility::TypeRecipient, @@ -174,7 +174,7 @@ class Machine: virtual void close_output(); virtual std::shared_ptr get_crt() { return mos6560_->get_crt(); } virtual std::shared_ptr get_speaker() { return mos6560_->get_speaker(); } - virtual void run_for(const Cycles cycles) { CPU::MOS6502::Processor::run_for(cycles); } + virtual void run_for(const Cycles cycles); // to satisfy MOS::MOS6522::Delegate virtual void mos6522_did_change_interrupt_status(void *mos6522); @@ -187,6 +187,8 @@ class Machine: virtual void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape); private: + CPU::MOS6502::Processor m6502_; + uint8_t character_rom_[0x1000]; uint8_t basic_rom_[0x2000]; uint8_t kernel_rom_[0x2000]; diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index a3f578b63..adf3c4571 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -15,6 +15,7 @@ using namespace Electron; #pragma mark - Lifecycle Machine::Machine() : + m6502_(*this), interrupt_control_(0), interrupt_status_(Interrupt::PowerOnReset | Interrupt::TransmitDataEmpty | 0x80), cycles_since_audio_update_(0), @@ -61,7 +62,7 @@ void Machine::clear_all_keys() { void Machine::set_key_state(uint16_t key, bool isPressed) { if(key == KeyBreak) { - set_reset_line(isPressed); + m6502_.set_reset_line(isPressed); } else { if(isPressed) key_states_[key >> 4] |= key&0xf; @@ -269,7 +270,7 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint // allow the PC read to return an RTS. ) ) { - uint8_t service_call = (uint8_t)get_value_of_register(CPU::MOS6502::Register::X); + uint8_t service_call = (uint8_t)m6502_.get_value_of_register(CPU::MOS6502::Register::X); if(address == 0xf0a8) { if(!ram_[0x247] && service_call == 14) { tape_.set_delegate(nullptr); @@ -291,8 +292,8 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint interrupt_status_ |= tape_.get_interrupt_status(); fast_load_is_in_data_ = true; - set_value_of_register(CPU::MOS6502::Register::A, 0); - set_value_of_register(CPU::MOS6502::Register::Y, tape_.get_data_register()); + m6502_.set_value_of_register(CPU::MOS6502::Register::A, 0); + m6502_.set_value_of_register(CPU::MOS6502::Register::Y, tape_.get_data_register()); *value = 0x60; // 0x60 is RTS } else *value = os_[address & 16383]; @@ -340,7 +341,7 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint shift_restart_counter_ -= cycles; if(shift_restart_counter_ <= 0) { shift_restart_counter_ = 0; - set_power_on(true); + m6502_.set_power_on(true); set_key_state(KeyShift, true); is_holding_shift_ = true; } @@ -355,6 +356,10 @@ void Machine::flush() { speaker_->flush(); } +void Machine::run_for(const Cycles cycles) { + m6502_.run_for(cycles); +} + #pragma mark - Deferred scheduling inline void Machine::update_display() { @@ -393,7 +398,7 @@ inline void Machine::evaluate_interrupts() { } else { interrupt_status_ &= ~1; } - set_irq_line(interrupt_status_ & 1); + m6502_.set_irq_line(interrupt_status_ & 1); } #pragma mark - Tape::Delegate @@ -406,7 +411,7 @@ void Machine::tape_did_change_interrupt_status(Tape *tape) { #pragma mark - Typer timing HalfCycles Electron::Machine::get_typer_delay() { - return get_is_resetting() ? Cycles(625*25*128) : Cycles(0); // wait one second if resetting + return m6502_.get_is_resetting() ? Cycles(625*25*128) : Cycles(0); // wait one second if resetting } HalfCycles Electron::Machine::get_typer_frequency() { diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index 8ce40b044..b99398b5f 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -67,7 +67,7 @@ enum Key: uint16_t { Acorn Electron. */ class Machine: - public CPU::MOS6502::Processor, + public CPU::MOS6502::BusHandler, public CRTMachine::Machine, public Tape::Delegate, public Utility::TypeRecipient, @@ -95,7 +95,7 @@ class Machine: virtual void close_output(); virtual std::shared_ptr get_crt(); virtual std::shared_ptr get_speaker(); - virtual void run_for(const Cycles cycles) { CPU::MOS6502::Processor::run_for(cycles); } + virtual void run_for(const Cycles cycles); // to satisfy Tape::Delegate virtual void tape_did_change_interrupt_status(Tape *tape); @@ -114,6 +114,8 @@ class Machine: inline void clear_interrupt(Interrupt interrupt); inline void evaluate_interrupts(); + CPU::MOS6502::Processor m6502_; + // Things that directly constitute the memory map. uint8_t roms_[16][16384]; bool rom_write_masks_[16]; diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 11038a440..bf90d3fd1 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -16,6 +16,7 @@ using namespace Oric; Machine::Machine() : + m6502_(*this), use_fast_tape_hack_(false), typer_delay_(2500000), keyboard_read_count_(0), @@ -94,8 +95,8 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint // E6C9 = read byte: return byte in A if(address == tape_get_byte_address_ && paged_rom_ == rom_ && use_fast_tape_hack_ && operation == CPU::MOS6502::BusOperation::ReadOpcode && via_.tape->has_tape() && !via_.tape->get_tape()->is_at_end()) { uint8_t next_byte = via_.tape->get_next_byte(!ram_[tape_speed_address_]); - set_value_of_register(CPU::MOS6502::A, next_byte); - set_value_of_register(CPU::MOS6502::Flags, next_byte ? 0 : CPU::MOS6502::Flag::Zero); + m6502_.set_value_of_register(CPU::MOS6502::A, next_byte); + m6502_.set_value_of_register(CPU::MOS6502::Flags, next_byte ? 0 : CPU::MOS6502::Flag::Zero); *value = 0x60; // i.e. RTS } } else { @@ -171,7 +172,7 @@ void Machine::mos6522_did_change_interrupt_status(void *mos6522) { void Machine::set_key_state(uint16_t key, bool isPressed) { if(key == KeyNMI) { - set_nmi_line(isPressed); + m6502_.set_nmi_line(isPressed); } else { if(isPressed) keyboard_->rows[key >> 8] |= (key & 0xff); @@ -206,7 +207,7 @@ std::shared_ptr Machine::get_speaker() { } void Machine::run_for(const Cycles cycles) { - CPU::MOS6502::Processor::run_for(cycles); + m6502_.run_for(cycles); } #pragma mark - The 6522 @@ -287,7 +288,7 @@ void Machine::wd1770_did_change_output(WD::WD1770 *wd1770) { } void Machine::set_interrupt_line() { - set_irq_line( + m6502_.set_irq_line( via_.get_interrupt_line() || (microdisc_is_enabled_ && microdisc_.get_interrupt_request_line())); } diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index 4da1a312e..7aefbb8a9 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -55,7 +55,7 @@ enum ROM { }; class Machine: - public CPU::MOS6502::Processor, + public CPU::MOS6502::BusHandler, public CRTMachine::Machine, public ConfigurationTarget::Machine, public MOS::MOS6522IRQDelegate::Delegate, @@ -101,6 +101,8 @@ class Machine: void wd1770_did_change_output(WD::WD1770 *wd1770); private: + CPU::MOS6502::Processor m6502_; + // RAM and ROM std::vector basic11_rom_, basic10_rom_, microdisc_rom_, colour_rom_; uint8_t ram_[65536], rom_[16384]; diff --git a/Processors/6502/6502.hpp b/Processors/6502/6502.hpp index b2a06fa72..e1f9706e2 100644 --- a/Processors/6502/6502.hpp +++ b/Processors/6502/6502.hpp @@ -117,6 +117,14 @@ class ProcessorBase { static const MicroOp operations[256][10]; }; +class BusHandler { + public: + void flush() {} + Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { + return Cycles(0); + } +}; + /*! @abstact An abstract base class for emulation of a 6502 processor via the curiously recurring template pattern/f-bounded polymorphism. @@ -130,6 +138,7 @@ class ProcessorBase { */ template class Processor: public ProcessorBase { private: + T &bus_handler_; const MicroOp *scheduled_program_counter_; /* @@ -261,8 +270,11 @@ template class Processor: public ProcessorBase { return reset; } - protected: - Processor() : + public: + /*! + Constructs an instance of the 6502 that will use @c bus_handler for all bus communications. + */ + Processor(T &bus_handler) : is_jammed_(false), ready_line_is_enabled_(false), ready_is_active_(false), @@ -274,7 +286,8 @@ template class Processor: public ProcessorBase { irq_line_(0), nmi_line_is_enabled_(false), set_overflow_line_is_enabled_(false), - scheduled_program_counter_(nullptr) { + scheduled_program_counter_(nullptr), + bus_handler_(bus_handler) { // only the interrupt flag is defined upon reset but get_flags isn't going to // mask the other flags so we need to do that, at least carry_flag_ &= Flag::Carry; @@ -282,7 +295,6 @@ template class Processor: public ProcessorBase { overflow_flag_ &= Flag::Overflow; } - public: /*! Runs the 6502 for a supplied number of cycles. @@ -334,7 +346,7 @@ template class Processor: public ProcessorBase { #define bus_access() \ interrupt_requests_ = (interrupt_requests_ & ~InterruptRequestFlags::IRQ) | irq_request_history_; \ irq_request_history_ = irq_line_ & inverse_interrupt_flag_; \ - number_of_cycles -= static_cast(this)->perform_bus_operation(nextBusOperation, busAddress, busValue); \ + number_of_cycles -= bus_handler_.perform_bus_operation(nextBusOperation, busAddress, busValue); \ nextBusOperation = BusOperation::None; \ if(number_of_cycles <= Cycles(0)) break; @@ -344,7 +356,7 @@ template class Processor: public ProcessorBase { while(number_of_cycles > Cycles(0)) { while (ready_is_active_ && number_of_cycles > Cycles(0)) { - number_of_cycles -= static_cast(this)->perform_bus_operation(BusOperation::Ready, busAddress, busValue); + number_of_cycles -= bus_handler_.perform_bus_operation(BusOperation::Ready, busAddress, busValue); } if(!ready_is_active_) { @@ -825,16 +837,9 @@ template class Processor: public ProcessorBase { bus_address_ = busAddress; bus_value_ = busValue; - static_cast(this)->flush(); + bus_handler_.flush(); } - /*! - Called to announce the end of a run_for period, allowing deferred work to take place. - - Users of the 6502 template may override this. - */ - void flush() {} - /*! Gets the value of a register. @@ -884,8 +889,8 @@ template class Processor: public ProcessorBase { */ void return_from_subroutine() { s_++; - static_cast(this)->perform_bus_operation(MOS6502::BusOperation::Read, 0x100 | s_, &pc_.bytes.low); s_++; - static_cast(this)->perform_bus_operation(MOS6502::BusOperation::Read, 0x100 | s_, &pc_.bytes.high); + bus_handler_.perform_bus_operation(MOS6502::BusOperation::Read, 0x100 | s_, &pc_.bytes.low); s_++; + bus_handler_.perform_bus_operation(MOS6502::BusOperation::Read, 0x100 | s_, &pc_.bytes.high); pc_.full++; if(is_jammed_) { From 06e31f51024e58b50bc107495242e7104599b995 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 16 Aug 2017 12:39:15 -0400 Subject: [PATCH 2/4] Consequential to the 6502 change, severs the Atari 2600's cartridge container from its former attempt at runtime polymorphism, in favour of each cartridge's specific hardware being defined as a 'bus extender'. --- Machines/Atari2600/Atari2600.cpp | 54 +++++++++---------- ...ctivisionStack.hpp => ActivisionStack.hpp} | 19 ++++--- .../{CartridgeAtari16k.hpp => Atari16k.hpp} | 22 ++++---- .../{CartridgeAtari32k.hpp => Atari32k.hpp} | 18 +++---- .../{CartridgeAtari8k.hpp => Atari8k.hpp} | 22 +++----- ...CartridgeCBSRAMPlus.hpp => CBSRAMPlus.hpp} | 9 ++-- Machines/Atari2600/Cartridges/Cartridge.hpp | 29 +++++++--- .../{CartridgeCommaVid.hpp => CommaVid.hpp} | 7 +-- .../{CartridgeMNetwork.hpp => MNetwork.hpp} | 11 ++-- .../{CartridgeMegaBoy.hpp => MegaBoy.hpp} | 10 ++-- ...CartridgeParkerBros.hpp => ParkerBros.hpp} | 10 ++-- .../{CartridgePitfall2.hpp => Pitfall2.hpp} | 19 ++++--- ...rtridgeTigervision.hpp => Tigervision.hpp} | 12 ++--- .../{CartridgeUnpaged.hpp => Unpaged.hpp} | 7 ++- .../Clock Signal.xcodeproj/project.pbxproj | 48 ++++++++--------- 15 files changed, 145 insertions(+), 152 deletions(-) rename Machines/Atari2600/Cartridges/{CartridgeActivisionStack.hpp => ActivisionStack.hpp} (73%) rename Machines/Atari2600/Cartridges/{CartridgeAtari16k.hpp => Atari16k.hpp} (66%) rename Machines/Atari2600/Cartridges/{CartridgeAtari32k.hpp => Atari32k.hpp} (66%) rename Machines/Atari2600/Cartridges/{CartridgeAtari8k.hpp => Atari8k.hpp} (65%) rename Machines/Atari2600/Cartridges/{CartridgeCBSRAMPlus.hpp => CBSRAMPlus.hpp} (75%) rename Machines/Atari2600/Cartridges/{CartridgeCommaVid.hpp => CommaVid.hpp} (78%) rename Machines/Atari2600/Cartridges/{CartridgeMNetwork.hpp => MNetwork.hpp} (86%) rename Machines/Atari2600/Cartridges/{CartridgeMegaBoy.hpp => MegaBoy.hpp} (78%) rename Machines/Atari2600/Cartridges/{CartridgeParkerBros.hpp => ParkerBros.hpp} (78%) rename Machines/Atari2600/Cartridges/{CartridgePitfall2.hpp => Pitfall2.hpp} (89%) rename Machines/Atari2600/Cartridges/{CartridgeTigervision.hpp => Tigervision.hpp} (71%) rename Machines/Atari2600/Cartridges/{CartridgeUnpaged.hpp => Unpaged.hpp} (74%) diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index 0d705ed45..c640dc91b 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -10,18 +10,18 @@ #include #include -#include "Cartridges/CartridgeAtari8k.hpp" -#include "Cartridges/CartridgeAtari16k.hpp" -#include "Cartridges/CartridgeAtari32k.hpp" -#include "Cartridges/CartridgeActivisionStack.hpp" -#include "Cartridges/CartridgeCBSRAMPlus.hpp" -#include "Cartridges/CartridgeCommaVid.hpp" -#include "Cartridges/CartridgeMegaBoy.hpp" -#include "Cartridges/CartridgeMNetwork.hpp" -#include "Cartridges/CartridgeParkerBros.hpp" -#include "Cartridges/CartridgePitfall2.hpp" -#include "Cartridges/CartridgeTigervision.hpp" -#include "Cartridges/CartridgeUnpaged.hpp" +#include "Cartridges/Atari8k.hpp" +#include "Cartridges/Atari16k.hpp" +#include "Cartridges/Atari32k.hpp" +#include "Cartridges/ActivisionStack.hpp" +#include "Cartridges/CBSRAMPlus.hpp" +#include "Cartridges/CommaVid.hpp" +#include "Cartridges/MegaBoy.hpp" +#include "Cartridges/MNetwork.hpp" +#include "Cartridges/ParkerBros.hpp" +#include "Cartridges/Pitfall2.hpp" +#include "Cartridges/Tigervision.hpp" +#include "Cartridges/Unpaged.hpp" using namespace Atari2600; namespace { @@ -83,35 +83,35 @@ void Machine::set_switch_is_enabled(Atari2600Switch input, bool state) { void Machine::configure_as_target(const StaticAnalyser::Target &target) { const std::vector &rom = target.cartridges.front()->get_segments().front().data; switch(target.atari.paging_model) { - case StaticAnalyser::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::CartridgeActivisionStack(rom)); break; - case StaticAnalyser::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::CartridgeCBSRAMPlus(rom)); break; - case StaticAnalyser::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::CartridgeCommaVid(rom)); break; - case StaticAnalyser::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::CartridgeMegaBoy(rom)); break; - case StaticAnalyser::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::CartridgeMNetwork(rom)); break; - case StaticAnalyser::Atari2600PagingModel::None: bus_.reset(new Cartridge::CartridgeUnpaged(rom)); break; - case StaticAnalyser::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::CartridgeParkerBros(rom)); break; - case StaticAnalyser::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::CartridgePitfall2(rom)); break; - case StaticAnalyser::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::CartridgeTigervision(rom)); break; + case StaticAnalyser::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::None: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge(rom)); break; + case StaticAnalyser::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge(rom)); break; case StaticAnalyser::Atari2600PagingModel::Atari8k: if(target.atari.uses_superchip) { - bus_.reset(new Cartridge::CartridgeAtari8kSuperChip(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } else { - bus_.reset(new Cartridge::CartridgeAtari8k(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } break; case StaticAnalyser::Atari2600PagingModel::Atari16k: if(target.atari.uses_superchip) { - bus_.reset(new Cartridge::CartridgeAtari16kSuperChip(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } else { - bus_.reset(new Cartridge::CartridgeAtari16k(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } break; case StaticAnalyser::Atari2600PagingModel::Atari32k: if(target.atari.uses_superchip) { - bus_.reset(new Cartridge::CartridgeAtari32kSuperChip(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } else { - bus_.reset(new Cartridge::CartridgeAtari32k(rom)); + bus_.reset(new Cartridge::Cartridge(rom)); } break; } diff --git a/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp b/Machines/Atari2600/Cartridges/ActivisionStack.hpp similarity index 73% rename from Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp rename to Machines/Atari2600/Cartridges/ActivisionStack.hpp index b79807470..4083bd15c 100644 --- a/Machines/Atari2600/Cartridges/CartridgeActivisionStack.hpp +++ b/Machines/Atari2600/Cartridges/ActivisionStack.hpp @@ -6,19 +6,18 @@ // Copyright © 2017 Thomas Harte. All rights reserved. // -#ifndef Atari2600_CartridgeActivisionStack_hpp -#define Atari2600_CartridgeActivisionStack_hpp +#ifndef Atari2600_ActivisionStack_hpp +#define Atari2600_ActivisionStack_hpp namespace Atari2600 { namespace Cartridge { -class CartridgeActivisionStack: public Cartridge { +class ActivisionStack: public BusExtender { public: - CartridgeActivisionStack(const std::vector &rom) : - Cartridge(rom), - last_opcode_(0x00) { - rom_ptr_ = rom_.data(); - } + ActivisionStack(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size), + rom_ptr_(rom_base), + last_opcode_(0x00) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if(!(address & 0x1000)) return; @@ -28,9 +27,9 @@ class CartridgeActivisionStack: public Cartridge { // RST or JSR. if(operation == CPU::MOS6502::BusOperation::ReadOpcode && (last_opcode_ == 0x20 || last_opcode_ == 0x60)) { if(address & 0x2000) { - rom_ptr_ = rom_.data(); + rom_ptr_ = rom_base_; } else { - rom_ptr_ = rom_.data() + 4096; + rom_ptr_ = rom_base_ + 4096; } } diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp b/Machines/Atari2600/Cartridges/Atari16k.hpp similarity index 66% rename from Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp rename to Machines/Atari2600/Cartridges/Atari16k.hpp index c109d76e4..c6559426c 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari16k.hpp +++ b/Machines/Atari2600/Cartridges/Atari16k.hpp @@ -14,18 +14,17 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeAtari16k: public Cartridge { +class Atari16k: public BusExtender { public: - CartridgeAtari16k(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari16k(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size), + rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address >= 0x1ff6 && address <= 0x1ff9) rom_ptr_ = rom_.data() + (address - 0x1ff6) * 4096; + if(address >= 0x1ff6 && address <= 0x1ff9) rom_ptr_ = rom_base_ + (address - 0x1ff6) * 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; @@ -36,18 +35,17 @@ class CartridgeAtari16k: public Cartridge { uint8_t *rom_ptr_; }; -class CartridgeAtari16kSuperChip: public Cartridge { +class Atari16kSuperChip: public BusExtender { public: - CartridgeAtari16kSuperChip(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari16kSuperChip(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size), + rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address >= 0x1ff6 && address <= 0x1ff9) rom_ptr_ = rom_.data() + (address - 0x1ff6) * 4096; + if(address >= 0x1ff6 && address <= 0x1ff9) rom_ptr_ = rom_base_ + (address - 0x1ff6) * 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp b/Machines/Atari2600/Cartridges/Atari32k.hpp similarity index 66% rename from Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp rename to Machines/Atari2600/Cartridges/Atari32k.hpp index 3ae85f052..facc56e70 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari32k.hpp +++ b/Machines/Atari2600/Cartridges/Atari32k.hpp @@ -14,18 +14,15 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeAtari32k: public Cartridge { +class Atari32k: public BusExtender { public: - CartridgeAtari32k(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari32k(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size), rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address >= 0x1ff4 && address <= 0x1ffb) rom_ptr_ = rom_.data() + (address - 0x1ff4) * 4096; + if(address >= 0x1ff4 && address <= 0x1ffb) rom_ptr_ = rom_base_ + (address - 0x1ff4) * 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; @@ -36,18 +33,15 @@ class CartridgeAtari32k: public Cartridge { uint8_t *rom_ptr_; }; -class CartridgeAtari32kSuperChip: public Cartridge { +class Atari32kSuperChip: public BusExtender { public: - CartridgeAtari32kSuperChip(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari32kSuperChip(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size), rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address >= 0x1ff4 && address <= 0x1ffb) rom_ptr_ = rom_.data() + (address - 0x1ff4) * 4096; + if(address >= 0x1ff4 && address <= 0x1ffb) rom_ptr_ = rom_base_ + (address - 0x1ff4) * 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; diff --git a/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp b/Machines/Atari2600/Cartridges/Atari8k.hpp similarity index 65% rename from Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp rename to Machines/Atari2600/Cartridges/Atari8k.hpp index 04e489c91..ffaa79433 100644 --- a/Machines/Atari2600/Cartridges/CartridgeAtari8k.hpp +++ b/Machines/Atari2600/Cartridges/Atari8k.hpp @@ -14,19 +14,16 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeAtari8k: public Cartridge { +class Atari8k: public BusExtender { public: - CartridgeAtari8k(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari8k(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size), rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address == 0x1ff8) rom_ptr_ = rom_.data(); - else if(address == 0x1ff9) rom_ptr_ = rom_.data() + 4096; + if(address == 0x1ff8) rom_ptr_ = rom_base_; + else if(address == 0x1ff9) rom_ptr_ = rom_base_ + 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; @@ -37,19 +34,16 @@ class CartridgeAtari8k: public Cartridge { uint8_t *rom_ptr_; }; -class CartridgeAtari8kSuperChip: public Cartridge { +class Atari8kSuperChip: public BusExtender { public: - CartridgeAtari8kSuperChip(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + Atari8kSuperChip(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size), rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address == 0x1ff8) rom_ptr_ = rom_.data(); - if(address == 0x1ff9) rom_ptr_ = rom_.data() + 4096; + if(address == 0x1ff8) rom_ptr_ = rom_base_; + if(address == 0x1ff9) rom_ptr_ = rom_base_ + 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; diff --git a/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp b/Machines/Atari2600/Cartridges/CBSRAMPlus.hpp similarity index 75% rename from Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp rename to Machines/Atari2600/Cartridges/CBSRAMPlus.hpp index ffde1af7b..1ea652a1b 100644 --- a/Machines/Atari2600/Cartridges/CartridgeCBSRAMPlus.hpp +++ b/Machines/Atari2600/Cartridges/CBSRAMPlus.hpp @@ -14,18 +14,15 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeCBSRAMPlus: public Cartridge { +class CBSRAMPlus: public BusExtender { public: - CartridgeCBSRAMPlus(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_ = rom_.data(); - } + CBSRAMPlus(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size), rom_ptr_(rom_base) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { address &= 0x1fff; if(!(address & 0x1000)) return; - if(address >= 0x1ff8 && address <= 0x1ffa) rom_ptr_ = rom_.data() + (address - 0x1ff8) * 4096; + if(address >= 0x1ff8 && address <= 0x1ffa) rom_ptr_ = rom_base_ + (address - 0x1ff8) * 4096; if(isReadOperation(operation)) { *value = rom_ptr_[address & 4095]; diff --git a/Machines/Atari2600/Cartridges/Cartridge.hpp b/Machines/Atari2600/Cartridges/Cartridge.hpp index 059ae3915..8d49f9f58 100644 --- a/Machines/Atari2600/Cartridges/Cartridge.hpp +++ b/Machines/Atari2600/Cartridges/Cartridge.hpp @@ -15,6 +15,17 @@ namespace Atari2600 { namespace Cartridge { +class BusExtender: public CPU::MOS6502::BusHandler { + public: + BusExtender(uint8_t *rom_base, size_t rom_size) : rom_base_(rom_base), rom_size_(rom_size) {} + + void advance_cycles(int cycles) {} + + protected: + uint8_t *rom_base_; + size_t rom_size_; +}; + template class Cartridge: public CPU::MOS6502::BusHandler, public Bus { @@ -22,11 +33,14 @@ template class Cartridge: public: Cartridge(const std::vector &rom) : m6502_(*this), - rom_(rom) {} + rom_(rom), + bus_extender_(rom_.data(), rom.size()) { + // The above works because bus_extender_ is declared after rom_ in the instance storage list; + // consider doing something less fragile. + } - void run_for(const Cycles cycles) { m6502_.run_for(cycles); } - void set_reset_line(bool state) { m6502_.set_reset_line(state); } - void advance_cycles(int cycles) {} + void run_for(const Cycles cycles) { m6502_.run_for(cycles); } + void set_reset_line(bool state) { m6502_.set_reset_line(state); } // to satisfy CPU::MOS6502::Processor Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { @@ -43,11 +57,11 @@ template class Cartridge: cycles_since_speaker_update_ += Cycles(cycles_run_for); cycles_since_video_update_ += Cycles(cycles_run_for); cycles_since_6532_update_ += Cycles(cycles_run_for / 3); - static_cast(this)->advance_cycles(cycles_run_for / 3); + bus_extender_.advance_cycles(cycles_run_for / 3); if(operation != CPU::MOS6502::BusOperation::Ready) { // give the cartridge a chance to respond to the bus access - static_cast(this)->perform_bus_operation(operation, address, value); + bus_extender_.perform_bus_operation(operation, address, value); // check for a RIOT RAM access if((address&0x1280) == 0x80) { @@ -172,6 +186,9 @@ template class Cartridge: protected: CPU::MOS6502::Processor> m6502_; std::vector rom_; + + private: + BusExtender bus_extender_; }; } diff --git a/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp b/Machines/Atari2600/Cartridges/CommaVid.hpp similarity index 78% rename from Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp rename to Machines/Atari2600/Cartridges/CommaVid.hpp index 26c8e89ce..9a389b43f 100644 --- a/Machines/Atari2600/Cartridges/CartridgeCommaVid.hpp +++ b/Machines/Atari2600/Cartridges/CommaVid.hpp @@ -12,11 +12,8 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeCommaVid: public Cartridge { +class CommaVid: public BusExtender { public: - CartridgeCommaVid(const std::vector &rom) : - Cartridge(rom) {} - void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if(!(address & 0x1000)) return; address &= 0x1fff; @@ -31,7 +28,7 @@ class CartridgeCommaVid: public Cartridge { return; } - if(isReadOperation(operation)) *value = rom_[address & 2047]; + if(isReadOperation(operation)) *value = rom_base_[address & 2047]; } private: diff --git a/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp b/Machines/Atari2600/Cartridges/MNetwork.hpp similarity index 86% rename from Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp rename to Machines/Atari2600/Cartridges/MNetwork.hpp index b759e70db..187787389 100644 --- a/Machines/Atari2600/Cartridges/CartridgeMNetwork.hpp +++ b/Machines/Atari2600/Cartridges/MNetwork.hpp @@ -14,11 +14,11 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeMNetwork: public Cartridge { +class MNetwork: public BusExtender { public: - CartridgeMNetwork(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_[0] = rom_.data() + rom_.size() - 4096; + MNetwork(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size) { + rom_ptr_[0] = rom_base + rom_size_ - 4096; rom_ptr_[1] = rom_ptr_[0] + 2048; high_ram_ptr_ = high_ram_; } @@ -28,7 +28,7 @@ class CartridgeMNetwork: public Cartridge { if(!(address & 0x1000)) return; if(address >= 0x1fe0 && address <= 0x1fe6) { - rom_ptr_[0] = rom_.data() + (address - 0x1fe0) * 2048; + rom_ptr_[0] = rom_base_ + (address - 0x1fe0) * 2048; } else if(address == 0x1fe7) { rom_ptr_[0] = nullptr; } else if(address >= 0x1ff8 && address <= 0x1ffb) { @@ -55,7 +55,6 @@ class CartridgeMNetwork: public Cartridge { } } } - } private: diff --git a/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp b/Machines/Atari2600/Cartridges/MegaBoy.hpp similarity index 78% rename from Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp rename to Machines/Atari2600/Cartridges/MegaBoy.hpp index 1d2a09e73..5ef7da21d 100644 --- a/Machines/Atari2600/Cartridges/CartridgeMegaBoy.hpp +++ b/Machines/Atari2600/Cartridges/MegaBoy.hpp @@ -14,12 +14,12 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeMegaBoy: public Cartridge { +class MegaBoy: public BusExtender { public: - CartridgeMegaBoy(const std::vector &rom) : - Cartridge(rom), + MegaBoy(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size), + rom_ptr_(rom_base), current_page_(0) { - rom_ptr_ = rom_.data(); } void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { @@ -28,7 +28,7 @@ class CartridgeMegaBoy: public Cartridge { if(address == 0x1ff0) { current_page_ = (current_page_ + 1) & 15; - rom_ptr_ = rom_.data() + current_page_ * 4096; + rom_ptr_ = rom_base_ + current_page_ * 4096; } if(isReadOperation(operation)) { diff --git a/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp b/Machines/Atari2600/Cartridges/ParkerBros.hpp similarity index 78% rename from Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp rename to Machines/Atari2600/Cartridges/ParkerBros.hpp index 4138991ba..8a2647460 100644 --- a/Machines/Atari2600/Cartridges/CartridgeParkerBros.hpp +++ b/Machines/Atari2600/Cartridges/ParkerBros.hpp @@ -14,11 +14,11 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeParkerBros: public Cartridge { +class ParkerBros: public BusExtender { public: - CartridgeParkerBros(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_[0] = rom_.data() + 4096; + ParkerBros(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size) { + rom_ptr_[0] = rom_base + 4096; rom_ptr_[1] = rom_ptr_[0] + 1024; rom_ptr_[2] = rom_ptr_[1] + 1024; rom_ptr_[3] = rom_ptr_[2] + 1024; @@ -30,7 +30,7 @@ class CartridgeParkerBros: public Cartridge { if(address >= 0x1fe0 && address < 0x1ff8) { int slot = (address >> 3)&3; - rom_ptr_[slot] = rom_.data() + ((address & 7) * 1024); + rom_ptr_[slot] = rom_base_ + ((address & 7) * 1024); } if(isReadOperation(operation)) { diff --git a/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp b/Machines/Atari2600/Cartridges/Pitfall2.hpp similarity index 89% rename from Machines/Atari2600/Cartridges/CartridgePitfall2.hpp rename to Machines/Atari2600/Cartridges/Pitfall2.hpp index c77239113..f383a453f 100644 --- a/Machines/Atari2600/Cartridges/CartridgePitfall2.hpp +++ b/Machines/Atari2600/Cartridges/Pitfall2.hpp @@ -12,16 +12,15 @@ namespace Atari2600 { namespace Cartridge { -class CartridgePitfall2: public Cartridge { +class Pitfall2: public BusExtender { public: - CartridgePitfall2(const std::vector &rom) : - Cartridge(rom), + Pitfall2(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size), + rom_ptr_(rom_base), random_number_generator_(0), featcher_address_{0, 0, 0, 0, 0, 0, 0, 0}, mask_{0, 0, 0, 0, 0, 0, 0, 0}, - cycles_since_audio_update_(0) { - rom_ptr_ = rom_.data(); - } + cycles_since_audio_update_(0) {} void advance_cycles(int cycles) { cycles_since_audio_update_ += cycles; @@ -54,11 +53,11 @@ class CartridgePitfall2: public Cartridge { break; case 0x1008: case 0x1009: case 0x100a: case 0x100b: case 0x100c: case 0x100d: case 0x100e: case 0x100f: - *value = rom_[8192 + address_for_counter(address & 7)]; + *value = rom_base_[8192 + address_for_counter(address & 7)]; break; case 0x1010: case 0x1011: case 0x1012: case 0x1013: case 0x1014: case 0x1015: case 0x1016: case 0x1017: - *value = rom_[8192 + address_for_counter(address & 7)] & mask_[address & 7]; + *value = rom_base_[8192 + address_for_counter(address & 7)] & mask_[address & 7]; break; #pragma mark - Writes @@ -82,8 +81,8 @@ class CartridgePitfall2: public Cartridge { #pragma mark - Paging - case 0x1ff8: rom_ptr_ = rom_.data(); break; - case 0x1ff9: rom_ptr_ = rom_.data() + 4096; break; + case 0x1ff8: rom_ptr_ = rom_base_; break; + case 0x1ff9: rom_ptr_ = rom_base_ + 4096; break; #pragma mark - Business as usual diff --git a/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp b/Machines/Atari2600/Cartridges/Tigervision.hpp similarity index 71% rename from Machines/Atari2600/Cartridges/CartridgeTigervision.hpp rename to Machines/Atari2600/Cartridges/Tigervision.hpp index 1abcedac5..4c8e8959f 100644 --- a/Machines/Atari2600/Cartridges/CartridgeTigervision.hpp +++ b/Machines/Atari2600/Cartridges/Tigervision.hpp @@ -14,18 +14,18 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeTigervision: public Cartridge { +class Tigervision: public BusExtender { public: - CartridgeTigervision(const std::vector &rom) : - Cartridge(rom) { - rom_ptr_[0] = rom_.data() + rom_.size() - 4096; + Tigervision(uint8_t *rom_base, size_t rom_size) : + BusExtender(rom_base, rom_size) { + rom_ptr_[0] = rom_base + rom_size - 4096; rom_ptr_[1] = rom_ptr_[0] + 2048; } void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if((address&0x1fff) == 0x3f) { - int offset = ((*value) * 2048) & (rom_.size() - 1); - rom_ptr_[0] = rom_.data() + offset; + int offset = ((*value) * 2048) & (rom_size_ - 1); + rom_ptr_[0] = rom_base_ + offset; return; } else if((address&0x1000) && isReadOperation(operation)) { *value = rom_ptr_[(address >> 11)&1][address & 2047]; diff --git a/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp b/Machines/Atari2600/Cartridges/Unpaged.hpp similarity index 74% rename from Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp rename to Machines/Atari2600/Cartridges/Unpaged.hpp index cc09b5a53..8761d72f5 100644 --- a/Machines/Atari2600/Cartridges/CartridgeUnpaged.hpp +++ b/Machines/Atari2600/Cartridges/Unpaged.hpp @@ -14,14 +14,13 @@ namespace Atari2600 { namespace Cartridge { -class CartridgeUnpaged: public Cartridge { +class Unpaged: public BusExtender { public: - CartridgeUnpaged(const std::vector &rom) : - Cartridge(rom) {} + Unpaged(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size) {} void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if(isReadOperation(operation) && (address & 0x1000)) { - *value = rom_[address & (rom_.size() - 1)]; + *value = rom_base_[address] & (rom_size_ - 1); } } }; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 10b16ea4c..ac8083b5e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1036,19 +1036,19 @@ 4BEA52651DF3472B007E74F2 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = ""; }; 4BEA52671DF34909007E74F2 /* PIA.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PIA.hpp; sourceTree = ""; }; 4BEAC0811E7E0DF800EE56B2 /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = ""; }; - 4BEAC0821E7E0DF800EE56B2 /* CartridgeActivisionStack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeActivisionStack.hpp; sourceTree = ""; }; - 4BEAC0831E7E0DF800EE56B2 /* CartridgeAtari16k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari16k.hpp; sourceTree = ""; }; - 4BEAC0841E7E0DF800EE56B2 /* CartridgeAtari32k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari32k.hpp; sourceTree = ""; }; - 4BEAC0851E7E0DF800EE56B2 /* CartridgeAtari8k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari8k.hpp; sourceTree = ""; }; - 4BEAC0861E7E0DF800EE56B2 /* CartridgeCBSRAMPlus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeCBSRAMPlus.hpp; sourceTree = ""; }; - 4BEAC0871E7E0DF800EE56B2 /* CartridgeCommaVid.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeCommaVid.hpp; sourceTree = ""; }; - 4BEAC0881E7E0DF800EE56B2 /* CartridgeMegaBoy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeMegaBoy.hpp; sourceTree = ""; }; - 4BEAC0891E7E0DF800EE56B2 /* CartridgeMNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeMNetwork.hpp; sourceTree = ""; }; - 4BEAC08A1E7E0DF800EE56B2 /* CartridgeParkerBros.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeParkerBros.hpp; sourceTree = ""; }; - 4BEAC08B1E7E0DF800EE56B2 /* CartridgeTigervision.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeTigervision.hpp; sourceTree = ""; }; - 4BEAC08C1E7E0DF800EE56B2 /* CartridgeUnpaged.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeUnpaged.hpp; sourceTree = ""; }; + 4BEAC0821E7E0DF800EE56B2 /* ActivisionStack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ActivisionStack.hpp; sourceTree = ""; }; + 4BEAC0831E7E0DF800EE56B2 /* Atari16k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari16k.hpp; sourceTree = ""; }; + 4BEAC0841E7E0DF800EE56B2 /* Atari32k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari32k.hpp; sourceTree = ""; }; + 4BEAC0851E7E0DF800EE56B2 /* Atari8k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari8k.hpp; sourceTree = ""; }; + 4BEAC0861E7E0DF800EE56B2 /* CBSRAMPlus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CBSRAMPlus.hpp; sourceTree = ""; }; + 4BEAC0871E7E0DF800EE56B2 /* CommaVid.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommaVid.hpp; sourceTree = ""; }; + 4BEAC0881E7E0DF800EE56B2 /* MegaBoy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MegaBoy.hpp; sourceTree = ""; }; + 4BEAC0891E7E0DF800EE56B2 /* MNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MNetwork.hpp; sourceTree = ""; }; + 4BEAC08A1E7E0DF800EE56B2 /* ParkerBros.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkerBros.hpp; sourceTree = ""; }; + 4BEAC08B1E7E0DF800EE56B2 /* Tigervision.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tigervision.hpp; sourceTree = ""; }; + 4BEAC08C1E7E0DF800EE56B2 /* Unpaged.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Unpaged.hpp; sourceTree = ""; }; 4BEAC08D1E7E0E1A00EE56B2 /* Bus.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Bus.hpp; sourceTree = ""; }; - 4BEAC08E1E7E110500EE56B2 /* CartridgePitfall2.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CartridgePitfall2.hpp; sourceTree = ""; }; + 4BEAC08E1E7E110500EE56B2 /* Pitfall2.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Pitfall2.hpp; sourceTree = ""; }; 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = ""; }; 4BEE0A6B1D72496600532C7B /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = ""; }; 4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = ""; }; @@ -2216,18 +2216,18 @@ isa = PBXGroup; children = ( 4BEAC0811E7E0DF800EE56B2 /* Cartridge.hpp */, - 4BEAC0821E7E0DF800EE56B2 /* CartridgeActivisionStack.hpp */, - 4BEAC0831E7E0DF800EE56B2 /* CartridgeAtari16k.hpp */, - 4BEAC0841E7E0DF800EE56B2 /* CartridgeAtari32k.hpp */, - 4BEAC0851E7E0DF800EE56B2 /* CartridgeAtari8k.hpp */, - 4BEAC0861E7E0DF800EE56B2 /* CartridgeCBSRAMPlus.hpp */, - 4BEAC0871E7E0DF800EE56B2 /* CartridgeCommaVid.hpp */, - 4BEAC0881E7E0DF800EE56B2 /* CartridgeMegaBoy.hpp */, - 4BEAC0891E7E0DF800EE56B2 /* CartridgeMNetwork.hpp */, - 4BEAC08A1E7E0DF800EE56B2 /* CartridgeParkerBros.hpp */, - 4BEAC08B1E7E0DF800EE56B2 /* CartridgeTigervision.hpp */, - 4BEAC08C1E7E0DF800EE56B2 /* CartridgeUnpaged.hpp */, - 4BEAC08E1E7E110500EE56B2 /* CartridgePitfall2.hpp */, + 4BEAC0821E7E0DF800EE56B2 /* ActivisionStack.hpp */, + 4BEAC0851E7E0DF800EE56B2 /* Atari8k.hpp */, + 4BEAC0831E7E0DF800EE56B2 /* Atari16k.hpp */, + 4BEAC0841E7E0DF800EE56B2 /* Atari32k.hpp */, + 4BEAC0861E7E0DF800EE56B2 /* CBSRAMPlus.hpp */, + 4BEAC0871E7E0DF800EE56B2 /* CommaVid.hpp */, + 4BEAC0881E7E0DF800EE56B2 /* MegaBoy.hpp */, + 4BEAC0891E7E0DF800EE56B2 /* MNetwork.hpp */, + 4BEAC08A1E7E0DF800EE56B2 /* ParkerBros.hpp */, + 4BEAC08E1E7E110500EE56B2 /* Pitfall2.hpp */, + 4BEAC08B1E7E0DF800EE56B2 /* Tigervision.hpp */, + 4BEAC08C1E7E0DF800EE56B2 /* Unpaged.hpp */, ); path = Cartridges; sourceTree = ""; From 360c8a99a3473dc3bcf280c1cdb20541149d3281 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 16 Aug 2017 12:57:32 -0400 Subject: [PATCH 3/4] Adjusted Atari2600 actually to use the nominated type of bus extender. --- Machines/Atari2600/Cartridges/Cartridge.hpp | 2 +- Machines/Atari2600/Cartridges/CommaVid.hpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Machines/Atari2600/Cartridges/Cartridge.hpp b/Machines/Atari2600/Cartridges/Cartridge.hpp index 8d49f9f58..20f52c9a9 100644 --- a/Machines/Atari2600/Cartridges/Cartridge.hpp +++ b/Machines/Atari2600/Cartridges/Cartridge.hpp @@ -188,7 +188,7 @@ template class Cartridge: std::vector rom_; private: - BusExtender bus_extender_; + T bus_extender_; }; } diff --git a/Machines/Atari2600/Cartridges/CommaVid.hpp b/Machines/Atari2600/Cartridges/CommaVid.hpp index 9a389b43f..79bee917b 100644 --- a/Machines/Atari2600/Cartridges/CommaVid.hpp +++ b/Machines/Atari2600/Cartridges/CommaVid.hpp @@ -9,11 +9,15 @@ #ifndef Atari2600_CartridgeCommaVid_hpp #define Atari2600_CartridgeCommaVid_hpp +#include "Cartridge.hpp" + namespace Atari2600 { namespace Cartridge { class CommaVid: public BusExtender { public: + CommaVid(uint8_t *rom_base, size_t rom_size) : BusExtender(rom_base, rom_size) {} + void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if(!(address & 0x1000)) return; address &= 0x1fff; From 3c148f57216eb163ec85ec6c545297dafc39e9d2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 16 Aug 2017 14:02:46 -0400 Subject: [PATCH 4/4] Fixed clanger of an error. --- Machines/Atari2600/Cartridges/Unpaged.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Machines/Atari2600/Cartridges/Unpaged.hpp b/Machines/Atari2600/Cartridges/Unpaged.hpp index 8761d72f5..0974f0d8c 100644 --- a/Machines/Atari2600/Cartridges/Unpaged.hpp +++ b/Machines/Atari2600/Cartridges/Unpaged.hpp @@ -20,7 +20,7 @@ class Unpaged: public BusExtender { void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { if(isReadOperation(operation) && (address & 0x1000)) { - *value = rom_base_[address] & (rom_size_ - 1); + *value = rom_base_[address & (rom_size_ - 1)]; } } };