mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
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'.
This commit is contained in:
parent
42b5b66305
commit
06e31f5102
@ -10,18 +10,18 @@
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
#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<uint8_t> &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<Cartridge::ActivisionStack>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge<Cartridge::CBSRAMPlus>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge<Cartridge::CommaVid>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge<Cartridge::MegaBoy>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge<Cartridge::MNetwork>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::None: bus_.reset(new Cartridge::Cartridge<Cartridge::Unpaged>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge<Cartridge::ParkerBros>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge<Cartridge::Pitfall2>(rom)); break;
|
||||
case StaticAnalyser::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge<Cartridge::Tigervision>(rom)); break;
|
||||
|
||||
case StaticAnalyser::Atari2600PagingModel::Atari8k:
|
||||
if(target.atari.uses_superchip) {
|
||||
bus_.reset(new Cartridge::CartridgeAtari8kSuperChip(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8kSuperChip>(rom));
|
||||
} else {
|
||||
bus_.reset(new Cartridge::CartridgeAtari8k(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8k>(rom));
|
||||
}
|
||||
break;
|
||||
case StaticAnalyser::Atari2600PagingModel::Atari16k:
|
||||
if(target.atari.uses_superchip) {
|
||||
bus_.reset(new Cartridge::CartridgeAtari16kSuperChip(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16kSuperChip>(rom));
|
||||
} else {
|
||||
bus_.reset(new Cartridge::CartridgeAtari16k(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16k>(rom));
|
||||
}
|
||||
break;
|
||||
case StaticAnalyser::Atari2600PagingModel::Atari32k:
|
||||
if(target.atari.uses_superchip) {
|
||||
bus_.reset(new Cartridge::CartridgeAtari32kSuperChip(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32kSuperChip>(rom));
|
||||
} else {
|
||||
bus_.reset(new Cartridge::CartridgeAtari32k(rom));
|
||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32k>(rom));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -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<CartridgeActivisionStack> {
|
||||
class ActivisionStack: public BusExtender {
|
||||
public:
|
||||
CartridgeActivisionStack(const std::vector<uint8_t> &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<CartridgeActivisionStack> {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -14,18 +14,17 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeAtari16k: public Cartridge<CartridgeAtari16k> {
|
||||
class Atari16k: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari16k(const std::vector<uint8_t> &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<CartridgeAtari16k> {
|
||||
uint8_t *rom_ptr_;
|
||||
};
|
||||
|
||||
class CartridgeAtari16kSuperChip: public Cartridge<CartridgeAtari16kSuperChip> {
|
||||
class Atari16kSuperChip: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari16kSuperChip(const std::vector<uint8_t> &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];
|
@ -14,18 +14,15 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeAtari32k: public Cartridge<CartridgeAtari32k> {
|
||||
class Atari32k: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari32k(const std::vector<uint8_t> &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<CartridgeAtari32k> {
|
||||
uint8_t *rom_ptr_;
|
||||
};
|
||||
|
||||
class CartridgeAtari32kSuperChip: public Cartridge<CartridgeAtari32kSuperChip> {
|
||||
class Atari32kSuperChip: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari32kSuperChip(const std::vector<uint8_t> &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];
|
@ -14,19 +14,16 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeAtari8k: public Cartridge<CartridgeAtari8k> {
|
||||
class Atari8k: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari8k(const std::vector<uint8_t> &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<CartridgeAtari8k> {
|
||||
uint8_t *rom_ptr_;
|
||||
};
|
||||
|
||||
class CartridgeAtari8kSuperChip: public Cartridge<CartridgeAtari8kSuperChip> {
|
||||
class Atari8kSuperChip: public BusExtender {
|
||||
public:
|
||||
CartridgeAtari8kSuperChip(const std::vector<uint8_t> &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];
|
@ -14,18 +14,15 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeCBSRAMPlus: public Cartridge<CartridgeCBSRAMPlus> {
|
||||
class CBSRAMPlus: public BusExtender {
|
||||
public:
|
||||
CartridgeCBSRAMPlus(const std::vector<uint8_t> &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];
|
@ -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 T> class Cartridge:
|
||||
public CPU::MOS6502::BusHandler,
|
||||
public Bus {
|
||||
@ -22,11 +33,14 @@ template<class T> class Cartridge:
|
||||
public:
|
||||
Cartridge(const std::vector<uint8_t> &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 T> 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<T *>(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<T *>(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 T> class Cartridge:
|
||||
protected:
|
||||
CPU::MOS6502::Processor<Cartridge<T>> m6502_;
|
||||
std::vector<uint8_t> rom_;
|
||||
|
||||
private:
|
||||
BusExtender bus_extender_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,11 +12,8 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeCommaVid: public Cartridge<CartridgeCommaVid> {
|
||||
class CommaVid: public BusExtender {
|
||||
public:
|
||||
CartridgeCommaVid(const std::vector<uint8_t> &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<CartridgeCommaVid> {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isReadOperation(operation)) *value = rom_[address & 2047];
|
||||
if(isReadOperation(operation)) *value = rom_base_[address & 2047];
|
||||
}
|
||||
|
||||
private:
|
@ -14,11 +14,11 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeMNetwork: public Cartridge<CartridgeMNetwork> {
|
||||
class MNetwork: public BusExtender {
|
||||
public:
|
||||
CartridgeMNetwork(const std::vector<uint8_t> &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<CartridgeMNetwork> {
|
||||
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<CartridgeMNetwork> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
@ -14,12 +14,12 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeMegaBoy: public Cartridge<CartridgeMegaBoy> {
|
||||
class MegaBoy: public BusExtender {
|
||||
public:
|
||||
CartridgeMegaBoy(const std::vector<uint8_t> &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<CartridgeMegaBoy> {
|
||||
|
||||
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)) {
|
@ -14,11 +14,11 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeParkerBros: public Cartridge<CartridgeParkerBros> {
|
||||
class ParkerBros: public BusExtender {
|
||||
public:
|
||||
CartridgeParkerBros(const std::vector<uint8_t> &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<CartridgeParkerBros> {
|
||||
|
||||
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)) {
|
@ -12,16 +12,15 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgePitfall2: public Cartridge<CartridgePitfall2> {
|
||||
class Pitfall2: public BusExtender {
|
||||
public:
|
||||
CartridgePitfall2(const std::vector<uint8_t> &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<CartridgePitfall2> {
|
||||
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<CartridgePitfall2> {
|
||||
|
||||
#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
|
||||
|
@ -14,18 +14,18 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeTigervision: public Cartridge<CartridgeTigervision> {
|
||||
class Tigervision: public BusExtender {
|
||||
public:
|
||||
CartridgeTigervision(const std::vector<uint8_t> &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];
|
@ -14,14 +14,13 @@
|
||||
namespace Atari2600 {
|
||||
namespace Cartridge {
|
||||
|
||||
class CartridgeUnpaged: public Cartridge<CartridgeUnpaged> {
|
||||
class Unpaged: public BusExtender {
|
||||
public:
|
||||
CartridgeUnpaged(const std::vector<uint8_t> &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);
|
||||
}
|
||||
}
|
||||
};
|
@ -1036,19 +1036,19 @@
|
||||
4BEA52651DF3472B007E74F2 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = "<group>"; };
|
||||
4BEA52671DF34909007E74F2 /* PIA.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PIA.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0811E7E0DF800EE56B2 /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0821E7E0DF800EE56B2 /* CartridgeActivisionStack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeActivisionStack.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0831E7E0DF800EE56B2 /* CartridgeAtari16k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari16k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0841E7E0DF800EE56B2 /* CartridgeAtari32k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari32k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0851E7E0DF800EE56B2 /* CartridgeAtari8k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeAtari8k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0861E7E0DF800EE56B2 /* CartridgeCBSRAMPlus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeCBSRAMPlus.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0871E7E0DF800EE56B2 /* CartridgeCommaVid.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeCommaVid.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0881E7E0DF800EE56B2 /* CartridgeMegaBoy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeMegaBoy.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0891E7E0DF800EE56B2 /* CartridgeMNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeMNetwork.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08A1E7E0DF800EE56B2 /* CartridgeParkerBros.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeParkerBros.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08B1E7E0DF800EE56B2 /* CartridgeTigervision.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeTigervision.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08C1E7E0DF800EE56B2 /* CartridgeUnpaged.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartridgeUnpaged.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0821E7E0DF800EE56B2 /* ActivisionStack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ActivisionStack.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0831E7E0DF800EE56B2 /* Atari16k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari16k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0841E7E0DF800EE56B2 /* Atari32k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari32k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0851E7E0DF800EE56B2 /* Atari8k.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari8k.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0861E7E0DF800EE56B2 /* CBSRAMPlus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CBSRAMPlus.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0871E7E0DF800EE56B2 /* CommaVid.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommaVid.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0881E7E0DF800EE56B2 /* MegaBoy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MegaBoy.hpp; sourceTree = "<group>"; };
|
||||
4BEAC0891E7E0DF800EE56B2 /* MNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MNetwork.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08A1E7E0DF800EE56B2 /* ParkerBros.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkerBros.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08B1E7E0DF800EE56B2 /* Tigervision.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tigervision.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08C1E7E0DF800EE56B2 /* Unpaged.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Unpaged.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08D1E7E0E1A00EE56B2 /* Bus.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Bus.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08E1E7E110500EE56B2 /* CartridgePitfall2.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CartridgePitfall2.hpp; sourceTree = "<group>"; };
|
||||
4BEAC08E1E7E110500EE56B2 /* Pitfall2.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Pitfall2.hpp; sourceTree = "<group>"; };
|
||||
4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = "<group>"; };
|
||||
4BEE0A6B1D72496600532C7B /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
|
||||
4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = "<group>"; };
|
||||
@ -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 = "<group>";
|
||||
|
Loading…
x
Reference in New Issue
Block a user