mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
commit
09c855a659
@ -919,10 +919,30 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
// See header; provides the system ROMs.
|
||||
void set_rom(ROMType type, std::vector<uint8_t> data) override final {
|
||||
void set_rom(ROMType type, const std::vector<uint8_t> &data) override final {
|
||||
roms_[static_cast<int>(type)] = data;
|
||||
}
|
||||
|
||||
// Obtains the system ROMs.
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"AmstradCPC",
|
||||
{
|
||||
"os464.rom", "basic464.rom",
|
||||
"os664.rom", "basic664.rom",
|
||||
"os6128.rom", "basic6128.rom",
|
||||
"amsdos.rom"
|
||||
});
|
||||
|
||||
for(size_t index = 0; index < roms.size(); ++index) {
|
||||
auto &data = roms[index];
|
||||
if(!data) return false;
|
||||
set_rom(static_cast<ROMType>(index), *data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_component_is_sleeping(void *component, bool is_sleeping) override final {
|
||||
fdc_is_sleeping_ = fdc_.is_sleeping();
|
||||
tape_player_is_sleeping_ = tape_player_.is_sleeping();
|
||||
|
@ -39,7 +39,7 @@ class Machine:
|
||||
static Machine *AmstradCPC();
|
||||
|
||||
/// Sets the contents of rom @c type to @c data. Assumed to be a setup step; has no effect once a machine is running.
|
||||
virtual void set_rom(ROMType type, std::vector<uint8_t> data) = 0;
|
||||
virtual void set_rom(ROMType type, const std::vector<uint8_t> &data) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -135,42 +135,27 @@ class TIA {
|
||||
// objects
|
||||
template<class T> struct Object {
|
||||
// the two programmer-set values
|
||||
int position;
|
||||
int motion;
|
||||
int position = 0;
|
||||
int motion = 0;
|
||||
|
||||
// motion_step_ is the current motion counter value; motion_time_ is the next time it will fire
|
||||
int motion_step;
|
||||
int motion_time;
|
||||
int motion_step = 0;
|
||||
int motion_time = 0;
|
||||
|
||||
// indicates whether this object is currently undergoing motion
|
||||
bool is_moving;
|
||||
|
||||
Object() : position(0), motion(0), motion_step(0), motion_time(0), is_moving(false) {};
|
||||
bool is_moving = false;
|
||||
};
|
||||
|
||||
// player state
|
||||
struct Player: public Object<Player> {
|
||||
Player() :
|
||||
adder(4),
|
||||
copy_flags(0),
|
||||
graphic{0, 0},
|
||||
reverse_mask(false),
|
||||
graphic_index(0),
|
||||
pixel_position(32),
|
||||
pixel_counter(0),
|
||||
latched_pixel4_time(-1),
|
||||
copy_index_(0),
|
||||
queue_read_pointer_(0),
|
||||
queue_write_pointer_(0) {}
|
||||
int adder = 4;
|
||||
int copy_flags = 0; // a bit field, corresponding to the first few values of NUSIZ
|
||||
uint8_t graphic[2] = {0, 0}; // the player graphic; 1 = new, 0 = current
|
||||
int reverse_mask = false; // 7 for a reflected player, 0 for normal
|
||||
int graphic_index = 0;
|
||||
|
||||
int adder;
|
||||
int copy_flags; // a bit field, corresponding to the first few values of NUSIZ
|
||||
uint8_t graphic[2]; // the player graphic; 1 = new, 0 = current
|
||||
int reverse_mask; // 7 for a reflected player, 0 for normal
|
||||
int graphic_index;
|
||||
|
||||
int pixel_position, pixel_counter;
|
||||
int latched_pixel4_time;
|
||||
int pixel_position = 32, pixel_counter = 0;
|
||||
int latched_pixel4_time = -1;
|
||||
const bool enqueues = true;
|
||||
|
||||
inline void skip_pixels(const int count, int from_horizontal_counter) {
|
||||
@ -219,15 +204,14 @@ class TIA {
|
||||
}
|
||||
|
||||
private:
|
||||
int copy_index_;
|
||||
int copy_index_ = 0;
|
||||
struct QueuedPixels {
|
||||
int start, end;
|
||||
int pixel_position;
|
||||
int adder;
|
||||
int reverse_mask;
|
||||
QueuedPixels() : start(0), end(0), pixel_position(0), adder(0), reverse_mask(false) {}
|
||||
int start = 0, end = 0;
|
||||
int pixel_position = 0;
|
||||
int adder = 0;
|
||||
int reverse_mask = false;
|
||||
} queue_[4];
|
||||
int queue_read_pointer_, queue_write_pointer_;
|
||||
int queue_read_pointer_ = 0, queue_write_pointer_ = 0;
|
||||
|
||||
inline void output_pixels(uint8_t *const target, const int count, const uint8_t collision_identity, int output_pixel_position, int output_adder, int output_reverse_mask) {
|
||||
if(output_pixel_position == 32 || !graphic[graphic_index]) return;
|
||||
@ -244,8 +228,8 @@ class TIA {
|
||||
|
||||
// common actor for things that appear as a horizontal run of pixels
|
||||
struct HorizontalRun: public Object<HorizontalRun> {
|
||||
int pixel_position;
|
||||
int size;
|
||||
int pixel_position = 0;
|
||||
int size = 1;
|
||||
const bool enqueues = false;
|
||||
|
||||
inline void skip_pixels(const int count, int from_horizontal_counter) {
|
||||
@ -268,16 +252,13 @@ class TIA {
|
||||
|
||||
void dequeue_pixels(uint8_t *const target, const uint8_t collision_identity, const int time_now) {}
|
||||
void enqueue_pixels(const int start, const int end, int from_horizontal_counter) {}
|
||||
|
||||
HorizontalRun() : pixel_position(0), size(1) {}
|
||||
};
|
||||
|
||||
|
||||
// missile state
|
||||
struct Missile: public HorizontalRun {
|
||||
bool enabled;
|
||||
bool locked_to_player;
|
||||
int copy_flags;
|
||||
bool enabled = false;
|
||||
bool locked_to_player = false;
|
||||
int copy_flags = 0;
|
||||
|
||||
inline void output_pixels(uint8_t *const target, const int count, const uint8_t collision_identity, int from_horizontal_counter) {
|
||||
if(!pixel_position) return;
|
||||
@ -287,14 +268,12 @@ class TIA {
|
||||
skip_pixels(count, from_horizontal_counter);
|
||||
}
|
||||
}
|
||||
|
||||
Missile() : enabled(false), copy_flags(0) {}
|
||||
} missile_[2];
|
||||
|
||||
// ball state
|
||||
struct Ball: public HorizontalRun {
|
||||
bool enabled[2];
|
||||
int enabled_index;
|
||||
bool enabled[2] = {false, false};
|
||||
int enabled_index = 0;
|
||||
const int copy_flags = 0;
|
||||
|
||||
inline void output_pixels(uint8_t *const target, const int count, const uint8_t collision_identity, int from_horizontal_counter) {
|
||||
@ -305,8 +284,6 @@ class TIA {
|
||||
skip_pixels(count, from_horizontal_counter);
|
||||
}
|
||||
}
|
||||
|
||||
Ball() : enabled{false, false}, enabled_index(0) {}
|
||||
} ball_;
|
||||
|
||||
// motion
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "../Outputs/CRT/CRT.hpp"
|
||||
#include "../Outputs/Speaker.hpp"
|
||||
#include "../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "ROMMachine.hpp"
|
||||
|
||||
namespace CRTMachine {
|
||||
|
||||
@ -20,7 +21,7 @@ namespace CRTMachine {
|
||||
that optionally provide a speaker, and that nominate a clock rate and can announce to a delegate
|
||||
should that clock rate change.
|
||||
*/
|
||||
class Machine {
|
||||
class Machine: public ROMMachine::Machine {
|
||||
public:
|
||||
Machine() : clock_is_unlimited_(false), delegate_(nullptr) {}
|
||||
|
||||
@ -35,7 +36,7 @@ class Machine {
|
||||
OpenGL context is bound.
|
||||
*/
|
||||
virtual void close_output() = 0;
|
||||
|
||||
|
||||
/// @returns The CRT this machine is drawing to. Should not be @c nullptr.
|
||||
virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() = 0;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define Commodore1540_hpp
|
||||
|
||||
#include "../SerialBus.hpp"
|
||||
#include "../../ROMMachine.hpp"
|
||||
#include "../../../Storage/Disk/Disk.hpp"
|
||||
#include "Implementation/C1540Base.hpp"
|
||||
|
||||
@ -19,12 +20,18 @@ namespace C1540 {
|
||||
/*!
|
||||
Provides an emulation of the C1540.
|
||||
*/
|
||||
class Machine: public MachineBase {
|
||||
class Machine: public MachineBase, public ROMMachine::Machine {
|
||||
public:
|
||||
enum Personality {
|
||||
C1540,
|
||||
C1541
|
||||
};
|
||||
Machine(Personality p);
|
||||
|
||||
/*!
|
||||
Sets the ROM image to use for this drive; it is asserted that the buffer provided is 16 kb in size.
|
||||
Sets the source for this drive's ROM image.
|
||||
*/
|
||||
void set_rom(const std::vector<uint8_t> &rom);
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names);
|
||||
|
||||
/*!
|
||||
Sets the serial bus to which this drive should attach itself.
|
||||
@ -36,6 +43,9 @@ class Machine: public MachineBase {
|
||||
|
||||
/// Inserts @c disk into the drive.
|
||||
void set_disk(std::shared_ptr<Storage::Disk::Disk> disk);
|
||||
|
||||
private:
|
||||
Personality personality_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ MachineBase::MachineBase() :
|
||||
set_drive(drive_);
|
||||
}
|
||||
|
||||
Machine::Machine(Commodore::C1540::Machine::Personality personality) : personality_(personality) {}
|
||||
|
||||
void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) {
|
||||
Commodore::Serial::AttachPortAndBus(serial_port_, serial_bus);
|
||||
}
|
||||
@ -80,9 +82,17 @@ Cycles MachineBase::perform_bus_operation(CPU::MOS6502::BusOperation operation,
|
||||
return Cycles(1);
|
||||
}
|
||||
|
||||
void Machine::set_rom(const std::vector<uint8_t> &rom) {
|
||||
assert(rom.size() == sizeof(rom_));
|
||||
memcpy(rom_, rom.data(), std::min(sizeof(rom_), rom.size()));
|
||||
bool Machine::set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) {
|
||||
std::string rom_name;
|
||||
switch(personality_) {
|
||||
case Personality::C1540: rom_name = "1540.bin"; break;
|
||||
case Personality::C1541: rom_name = "1541.bin"; break;
|
||||
}
|
||||
|
||||
auto roms = roms_with_names("Commodore1540", {rom_name});
|
||||
if(!roms[0]) return false;
|
||||
memcpy(rom_, roms[0]->data(), std::min(sizeof(rom_), roms[0]->size()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Machine::set_disk(std::shared_ptr<Storage::Disk::Disk> disk) {
|
||||
|
@ -37,6 +37,18 @@ enum JoystickInput {
|
||||
Fire = 0x20
|
||||
};
|
||||
|
||||
enum ROM {
|
||||
CharactersDanish = 0,
|
||||
CharactersEnglish,
|
||||
CharactersJapanese,
|
||||
CharactersSwedish,
|
||||
KernelDanish,
|
||||
KernelJapanese,
|
||||
KernelNTSC,
|
||||
KernelPAL,
|
||||
KernelSwedish
|
||||
};
|
||||
|
||||
/*!
|
||||
Models the user-port VIA, which is the Vic's connection point for controlling its tape recorder —
|
||||
sensing the presence or absence of a tape and controlling the tape motor — and reading the current
|
||||
@ -280,12 +292,6 @@ class ConcreteMachine:
|
||||
keyboard_via_port_handler_->set_interrupt_delegate(this);
|
||||
tape_->set_delegate(this);
|
||||
|
||||
// establish the memory maps
|
||||
set_memory_size(MemorySize::Default);
|
||||
|
||||
// set the NTSC clock rate
|
||||
set_region(NTSC);
|
||||
|
||||
// install a joystick
|
||||
joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_));
|
||||
}
|
||||
@ -294,24 +300,32 @@ class ConcreteMachine:
|
||||
delete[] rom_;
|
||||
}
|
||||
|
||||
void set_rom(ROMSlot slot, size_t length, const uint8_t *data) override final {
|
||||
uint8_t *target = nullptr;
|
||||
size_t max_length = 0x2000;
|
||||
switch(slot) {
|
||||
case Kernel: target = kernel_rom_; break;
|
||||
case Characters: target = character_rom_; max_length = 0x1000; break;
|
||||
case BASIC: target = basic_rom_; break;
|
||||
case Drive:
|
||||
drive_rom_.resize(length);
|
||||
memcpy(drive_rom_.data(), data, length);
|
||||
install_disk_rom();
|
||||
return;
|
||||
}
|
||||
void set_rom(ROMSlot slot, const std::vector<uint8_t> &data) override final {
|
||||
}
|
||||
|
||||
if(target) {
|
||||
size_t length_to_copy = std::min(max_length, length);
|
||||
memcpy(target, data, length_to_copy);
|
||||
// Obtains the system ROMs.
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"Vic20",
|
||||
{
|
||||
"characters-danish.bin",
|
||||
"characters-english.bin",
|
||||
"characters-japanese.bin",
|
||||
"characters-swedish.bin",
|
||||
"kernel-danish.bin",
|
||||
"kernel-japanese.bin",
|
||||
"kernel-ntsc.bin",
|
||||
"kernel-pal.bin",
|
||||
"kernel-swedish.bin",
|
||||
"basic.bin"
|
||||
});
|
||||
|
||||
for(size_t index = 0; index < roms.size(); ++index) {
|
||||
auto &data = roms[index];
|
||||
if(!data) return false;
|
||||
if(index < 9) roms_[index] = *data; else basic_rom_ = *data;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void configure_as_target(const StaticAnalyser::Target &target) override final {
|
||||
@ -333,13 +347,13 @@ class ConcreteMachine:
|
||||
|
||||
if(target.media.disks.size()) {
|
||||
// construct the 1540
|
||||
c1540_.reset(new ::Commodore::C1540::Machine);
|
||||
c1540_.reset(new ::Commodore::C1540::Machine(Commodore::C1540::Machine::C1540));
|
||||
|
||||
// attach it to the serial bus
|
||||
c1540_->set_serial_bus(serial_bus_);
|
||||
|
||||
// install the ROM if it was previously set
|
||||
install_disk_rom();
|
||||
// give it a means to obtain its ROM
|
||||
c1540_->set_rom_fetcher(rom_fetcher_);
|
||||
}
|
||||
|
||||
insert_media(target.media);
|
||||
@ -383,10 +397,38 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
void set_memory_size(MemorySize size) override final {
|
||||
memory_size_ = size;
|
||||
needs_configuration_ = true;
|
||||
}
|
||||
|
||||
void set_region(Region region) override final {
|
||||
region_ = region;
|
||||
needs_configuration_ = true;
|
||||
}
|
||||
|
||||
void configure_memory() {
|
||||
// Determine PAL/NTSC
|
||||
if(region_ == American || region_ == Japanese) {
|
||||
// NTSC
|
||||
set_clock_rate(1022727);
|
||||
if(mos6560_) {
|
||||
mos6560_->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::NTSC);
|
||||
mos6560_->set_clock_rate(1022727);
|
||||
}
|
||||
} else {
|
||||
// PAL
|
||||
set_clock_rate(1108404);
|
||||
if(mos6560_) {
|
||||
mos6560_->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::PAL);
|
||||
mos6560_->set_clock_rate(1108404);
|
||||
}
|
||||
}
|
||||
|
||||
memset(processor_read_memory_map_, 0, sizeof(processor_read_memory_map_));
|
||||
memset(processor_write_memory_map_, 0, sizeof(processor_write_memory_map_));
|
||||
memset(mos6560_->video_memory_map, 0, sizeof(mos6560_->video_memory_map));
|
||||
|
||||
switch(size) {
|
||||
switch(memory_size_) {
|
||||
default: break;
|
||||
case ThreeKB:
|
||||
write_to_map(processor_read_memory_map_, expansion_ram_, 0x0000, 0x1000);
|
||||
@ -402,40 +444,52 @@ class ConcreteMachine:
|
||||
write_to_map(processor_read_memory_map_, user_basic_memory_, 0x0000, sizeof(user_basic_memory_));
|
||||
write_to_map(processor_read_memory_map_, screen_memory_, 0x1000, sizeof(screen_memory_));
|
||||
write_to_map(processor_read_memory_map_, colour_memory_, 0x9400, sizeof(colour_memory_));
|
||||
write_to_map(processor_read_memory_map_, character_rom_, 0x8000, sizeof(character_rom_));
|
||||
write_to_map(processor_read_memory_map_, basic_rom_, 0xc000, sizeof(basic_rom_));
|
||||
write_to_map(processor_read_memory_map_, kernel_rom_, 0xe000, sizeof(kernel_rom_));
|
||||
|
||||
|
||||
write_to_map(processor_write_memory_map_, user_basic_memory_, 0x0000, sizeof(user_basic_memory_));
|
||||
write_to_map(processor_write_memory_map_, screen_memory_, 0x1000, sizeof(screen_memory_));
|
||||
write_to_map(processor_write_memory_map_, colour_memory_, 0x9400, sizeof(colour_memory_));
|
||||
|
||||
write_to_map(mos6560_->video_memory_map, user_basic_memory_, 0x2000, sizeof(user_basic_memory_));
|
||||
write_to_map(mos6560_->video_memory_map, screen_memory_, 0x3000, sizeof(screen_memory_));
|
||||
mos6560_->colour_memory = colour_memory_;
|
||||
|
||||
write_to_map(processor_read_memory_map_, basic_rom_.data(), 0xc000, basic_rom_.size());
|
||||
|
||||
ROM character_rom;
|
||||
ROM kernel_rom;
|
||||
switch(region_) {
|
||||
case American:
|
||||
character_rom = CharactersEnglish;
|
||||
kernel_rom = KernelNTSC;
|
||||
break;
|
||||
case Danish:
|
||||
character_rom = CharactersDanish;
|
||||
kernel_rom = KernelDanish;
|
||||
break;
|
||||
case Japanese:
|
||||
character_rom = CharactersJapanese;
|
||||
kernel_rom = KernelJapanese;
|
||||
break;
|
||||
case European:
|
||||
character_rom = CharactersEnglish;
|
||||
kernel_rom = KernelPAL;
|
||||
break;
|
||||
case Swedish:
|
||||
character_rom = CharactersSwedish;
|
||||
kernel_rom = KernelSwedish;
|
||||
break;
|
||||
}
|
||||
|
||||
write_to_map(processor_read_memory_map_, roms_[character_rom].data(), 0x8000, roms_[character_rom].size());
|
||||
write_to_map(mos6560_->video_memory_map, roms_[character_rom].data(), 0x0000, roms_[character_rom].size());
|
||||
write_to_map(processor_read_memory_map_, roms_[kernel_rom].data(), 0xe000, roms_[kernel_rom].size());
|
||||
|
||||
// install the inserted ROM if there is one
|
||||
if(rom_) {
|
||||
write_to_map(processor_read_memory_map_, rom_, rom_address_, rom_length_);
|
||||
}
|
||||
}
|
||||
|
||||
void set_region(Region region) override final {
|
||||
region_ = region;
|
||||
switch(region) {
|
||||
case PAL:
|
||||
set_clock_rate(1108404);
|
||||
if(mos6560_) {
|
||||
mos6560_->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::PAL);
|
||||
mos6560_->set_clock_rate(1108404);
|
||||
}
|
||||
break;
|
||||
case NTSC:
|
||||
set_clock_rate(1022727);
|
||||
if(mos6560_) {
|
||||
mos6560_->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::NTSC);
|
||||
mos6560_->set_clock_rate(1022727);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void set_use_fast_tape_hack(bool activate) override final {
|
||||
use_fast_tape_hack_ = activate;
|
||||
}
|
||||
@ -542,19 +596,16 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
void run_for(const Cycles cycles) override final {
|
||||
if(needs_configuration_) {
|
||||
needs_configuration_ = false;
|
||||
configure_memory();
|
||||
}
|
||||
m6502_.run_for(cycles);
|
||||
}
|
||||
|
||||
void setup_output(float aspect_ratio) override final {
|
||||
mos6560_.reset(new Vic6560());
|
||||
mos6560_->get_speaker()->set_high_frequency_cut_off(1600); // There is a 1.6Khz low-pass filter in the Vic-20.
|
||||
set_region(region_);
|
||||
|
||||
memset(mos6560_->video_memory_map, 0, sizeof(mos6560_->video_memory_map));
|
||||
write_to_map(mos6560_->video_memory_map, character_rom_, 0x0000, sizeof(character_rom_));
|
||||
write_to_map(mos6560_->video_memory_map, user_basic_memory_, 0x2000, sizeof(user_basic_memory_));
|
||||
write_to_map(mos6560_->video_memory_map, screen_memory_, 0x3000, sizeof(screen_memory_));
|
||||
mos6560_->colour_memory = colour_memory_;
|
||||
}
|
||||
|
||||
void close_output() override final {
|
||||
@ -590,9 +641,11 @@ class ConcreteMachine:
|
||||
private:
|
||||
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
|
||||
|
||||
uint8_t character_rom_[0x1000];
|
||||
uint8_t basic_rom_[0x2000];
|
||||
uint8_t kernel_rom_[0x2000];
|
||||
std::vector<uint8_t> roms_[9];
|
||||
|
||||
std::vector<uint8_t> character_rom_;
|
||||
std::vector<uint8_t> basic_rom_;
|
||||
std::vector<uint8_t> kernel_rom_;
|
||||
uint8_t expansion_ram_[0x8000];
|
||||
|
||||
uint8_t *rom_;
|
||||
@ -601,7 +654,8 @@ class ConcreteMachine:
|
||||
uint8_t user_basic_memory_[0x0400];
|
||||
uint8_t screen_memory_[0x1000];
|
||||
uint8_t colour_memory_[0x0400];
|
||||
std::vector<uint8_t> drive_rom_;
|
||||
|
||||
std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> rom_fetcher_;
|
||||
|
||||
uint8_t *processor_read_memory_map_[64];
|
||||
uint8_t *processor_write_memory_map_[64];
|
||||
@ -615,7 +669,10 @@ class ConcreteMachine:
|
||||
}
|
||||
}
|
||||
|
||||
Region region_;
|
||||
Region region_ = European;
|
||||
MemorySize memory_size_ = MemorySize::Default;
|
||||
bool needs_configuration_ = true;
|
||||
|
||||
Commodore::Vic20::KeyboardMapper keyboard_mapper_;
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
|
||||
|
||||
@ -635,13 +692,6 @@ class ConcreteMachine:
|
||||
|
||||
// Disk
|
||||
std::shared_ptr<::Commodore::C1540::Machine> c1540_;
|
||||
void install_disk_rom() {
|
||||
if(!drive_rom_.empty() && c1540_) {
|
||||
c1540_->set_rom(drive_rom_);
|
||||
c1540_->run_for(Cycles(2000000));
|
||||
drive_rom_.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Commodore {
|
||||
namespace Vic20 {
|
||||
|
||||
enum ROMSlot {
|
||||
Kernel,
|
||||
Kernel = 0,
|
||||
BASIC,
|
||||
Characters,
|
||||
Drive
|
||||
@ -33,8 +33,11 @@ enum MemorySize {
|
||||
};
|
||||
|
||||
enum Region {
|
||||
NTSC,
|
||||
PAL
|
||||
American,
|
||||
Danish,
|
||||
Japanese,
|
||||
European,
|
||||
Swedish
|
||||
};
|
||||
|
||||
class Machine:
|
||||
@ -49,8 +52,7 @@ class Machine:
|
||||
static Machine *Vic20();
|
||||
|
||||
/// Sets the contents of the rom in @c slot to the buffer @c data of length @c length.
|
||||
virtual void set_rom(ROMSlot slot, size_t length, const uint8_t *data) = 0;
|
||||
// TODO: take a std::vector<uint8_t> to collapse length and data.
|
||||
virtual void set_rom(ROMSlot slot, const std::vector<uint8_t> &data) = 0;
|
||||
|
||||
/// Sets the memory size of this Vic-20.
|
||||
virtual void set_memory_size(MemorySize size) = 0;
|
||||
|
@ -39,11 +39,12 @@ class ConcreteMachine:
|
||||
set_clock_rate(2000000);
|
||||
}
|
||||
|
||||
void set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable) override final {
|
||||
void set_rom(ROMSlot slot, const std::vector<uint8_t> &data, bool is_writeable) override final {
|
||||
uint8_t *target = nullptr;
|
||||
switch(slot) {
|
||||
case ROMSlotDFS: dfs_ = data; return;
|
||||
case ROMSlotADFS: adfs_ = data; return;
|
||||
case ROMSlotADFS1: adfs1_ = data; return;
|
||||
case ROMSlotADFS2: adfs2_ = data; return;
|
||||
|
||||
case ROMSlotOS: target = os_; break;
|
||||
default:
|
||||
@ -55,6 +56,30 @@ class ConcreteMachine:
|
||||
memcpy(target, &data[0], std::min(static_cast<size_t>(16384), data.size()));
|
||||
}
|
||||
|
||||
// Obtains the system ROMs.
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"Electron",
|
||||
{
|
||||
"DFS-1770-2.20.rom",
|
||||
"ADFS-E00_1.rom", "ADFS-E00_2.rom",
|
||||
"basic.rom", "os.rom"
|
||||
});
|
||||
ROMSlot slots[] = {
|
||||
ROMSlotDFS,
|
||||
ROMSlotADFS1, ROMSlotADFS2,
|
||||
ROMSlotBASIC, ROMSlotOS
|
||||
};
|
||||
|
||||
for(size_t index = 0; index < roms.size(); ++index) {
|
||||
auto &data = roms[index];
|
||||
if(!data) return false;
|
||||
set_rom(slots[index], *data, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_key_state(uint16_t key, bool isPressed) override final {
|
||||
if(key == KeyBreak) {
|
||||
m6502_.set_reset_line(isPressed);
|
||||
@ -91,8 +116,8 @@ class ConcreteMachine:
|
||||
set_rom(ROMSlot0, dfs_, true);
|
||||
}
|
||||
if(target.acorn.has_adfs) {
|
||||
set_rom(ROMSlot4, adfs_, true);
|
||||
set_rom(ROMSlot5, std::vector<uint8_t>(adfs_.begin() + 16384, adfs_.end()), true);
|
||||
set_rom(ROMSlot4, adfs1_, true);
|
||||
set_rom(ROMSlot5, adfs2_, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,7 +460,7 @@ class ConcreteMachine:
|
||||
uint8_t roms_[16][16384];
|
||||
bool rom_write_masks_[16] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
|
||||
uint8_t os_[16384], ram_[32768];
|
||||
std::vector<uint8_t> dfs_, adfs_;
|
||||
std::vector<uint8_t> dfs_, adfs1_, adfs2_;
|
||||
|
||||
// Paging
|
||||
ROMSlot active_rom_ = ROMSlot::ROMSlot0;
|
||||
|
@ -28,7 +28,8 @@ enum ROMSlot: uint8_t {
|
||||
|
||||
ROMSlot12, ROMSlot13, ROMSlot14, ROMSlot15,
|
||||
|
||||
ROMSlotOS, ROMSlotDFS, ROMSlotADFS
|
||||
ROMSlotOS, ROMSlotDFS,
|
||||
ROMSlotADFS1, ROMSlotADFS2
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -51,7 +52,7 @@ class Machine:
|
||||
Sets the contents of @c slot to @c data. If @c is_writeable is @c true then writing to the slot
|
||||
is enabled — it acts as if it were sideways RAM. Otherwise the slot is modelled as containing ROM.
|
||||
*/
|
||||
virtual void set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable) = 0;
|
||||
virtual void set_rom(ROMSlot slot, const std::vector<uint8_t> &data, bool is_writeable) = 0;
|
||||
|
||||
/// Enables or disables turbo-speed tape loading.
|
||||
virtual void set_use_fast_tape_hack(bool activate) = 0;
|
||||
|
@ -203,6 +203,24 @@ class ConcreteMachine:
|
||||
}
|
||||
}
|
||||
|
||||
// Obtains the system ROMs.
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"Oric",
|
||||
{
|
||||
"basic10.rom", "basic11.rom",
|
||||
"microdisc.rom", "colour.rom"
|
||||
});
|
||||
|
||||
for(size_t index = 0; index < roms.size(); ++index) {
|
||||
auto &data = roms[index];
|
||||
if(!data) return false;
|
||||
set_rom(static_cast<ROM>(index), *data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_key_state(uint16_t key, bool is_pressed) override final {
|
||||
if(key == KeyNMI) {
|
||||
m6502_.set_nmi_line(is_pressed);
|
||||
|
@ -19,7 +19,7 @@
|
||||
namespace Oric {
|
||||
|
||||
enum ROM {
|
||||
BASIC10, BASIC11, Microdisc, Colour
|
||||
BASIC10 = 0, BASIC11, Microdisc, Colour
|
||||
};
|
||||
|
||||
/*!
|
||||
|
27
Machines/ROMMachine.hpp
Normal file
27
Machines/ROMMachine.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// ROMMachine.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 07/11/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef ROMMachine_hpp
|
||||
#define ROMMachine_hpp
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace ROMMachine {
|
||||
|
||||
struct Machine {
|
||||
/*!
|
||||
Provides the machine with a way to obtain such ROMs as it needs.
|
||||
*/
|
||||
virtual bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &rom_with_name) { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* ROMMachine_h */
|
66
Machines/Utility/MachineForTarget.cpp
Normal file
66
Machines/Utility/MachineForTarget.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// MachineForTarget.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 04/11/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "MachineForTarget.hpp"
|
||||
|
||||
#include "../AmstradCPC/AmstradCPC.hpp"
|
||||
#include "../Atari2600/Atari2600.hpp"
|
||||
#include "../Commodore/Vic-20/Vic20.hpp"
|
||||
#include "../Electron/Electron.hpp"
|
||||
#include "../Oric/Oric.hpp"
|
||||
#include "../ZX8081/ZX8081.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T> class TypedDynamicMachine: public ::Machine::DynamicMachine {
|
||||
public:
|
||||
TypedDynamicMachine(T *machine) : machine_(machine) {}
|
||||
|
||||
ConfigurationTarget::Machine *configuration_target() {
|
||||
return dynamic_cast<ConfigurationTarget::Machine *>(machine_.get());
|
||||
}
|
||||
|
||||
CRTMachine::Machine *crt_machine() {
|
||||
return dynamic_cast<CRTMachine::Machine *>(machine_.get());
|
||||
}
|
||||
|
||||
JoystickMachine::Machine *joystick_machine() {
|
||||
return dynamic_cast<JoystickMachine::Machine *>(machine_.get());
|
||||
}
|
||||
|
||||
KeyboardMachine::Machine *keyboard_machine() {
|
||||
return dynamic_cast<KeyboardMachine::Machine *>(machine_.get());
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<T> machine_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
::Machine::DynamicMachine *::Machine::MachineForTarget(const StaticAnalyser::Target &target) {
|
||||
switch(target.machine) {
|
||||
case StaticAnalyser::Target::AmstradCPC: return new TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC());
|
||||
case StaticAnalyser::Target::Atari2600: return new TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600());
|
||||
case StaticAnalyser::Target::Electron: return new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron());
|
||||
case StaticAnalyser::Target::Oric: return new TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric());
|
||||
case StaticAnalyser::Target::Vic20: return new TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20());
|
||||
case StaticAnalyser::Target::ZX8081: return new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(target));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Machine::NameForTarget(const StaticAnalyser::Target &target) {
|
||||
switch(target.machine) {
|
||||
case StaticAnalyser::Target::AmstradCPC: return "AmstradCPC";
|
||||
case StaticAnalyser::Target::Atari2600: return "Atari2600";
|
||||
case StaticAnalyser::Target::Electron: return "Electron";
|
||||
case StaticAnalyser::Target::Oric: return "Oric";
|
||||
case StaticAnalyser::Target::Vic20: return "Vic20";
|
||||
case StaticAnalyser::Target::ZX8081: return "ZX8081";
|
||||
}
|
||||
}
|
50
Machines/Utility/MachineForTarget.hpp
Normal file
50
Machines/Utility/MachineForTarget.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// MachineForTarget.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 04/11/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef MachineForTarget_hpp
|
||||
#define MachineForTarget_hpp
|
||||
|
||||
#include "../../StaticAnalyser/StaticAnalyser.hpp"
|
||||
|
||||
#include "../ConfigurationTarget.hpp"
|
||||
#include "../CRTMachine.hpp"
|
||||
#include "../JoystickMachine.hpp"
|
||||
#include "../KeyboardMachine.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Machine {
|
||||
|
||||
/*!
|
||||
Provides the structure for owning a machine and dynamically casting it as desired without knowledge of
|
||||
the machine's parent class or, therefore, the need to establish a common one.
|
||||
*/
|
||||
struct DynamicMachine {
|
||||
virtual ConfigurationTarget::Machine *configuration_target() = 0;
|
||||
virtual CRTMachine::Machine *crt_machine() = 0;
|
||||
virtual JoystickMachine::Machine *joystick_machine() = 0;
|
||||
virtual KeyboardMachine::Machine *keyboard_machine() = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
Allocates an instance of DynamicMachine holding a machine that can
|
||||
receive the supplied target. The machine has been allocated on the heap.
|
||||
It is the caller's responsibility to delete the class when finished.
|
||||
*/
|
||||
DynamicMachine *MachineForTarget(const StaticAnalyser::Target &target);
|
||||
|
||||
/*!
|
||||
Returns a short string name for the machine identified by the target,
|
||||
which is guaranteed not to have any spaces or other potentially
|
||||
filesystem-bothering contents.
|
||||
*/
|
||||
std::string NameForTarget(const StaticAnalyser::Target &target);
|
||||
|
||||
}
|
||||
|
||||
#endif /* MachineForTarget_hpp */
|
@ -290,13 +290,30 @@ template<bool is_zx81> class ConcreteMachine:
|
||||
Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper));
|
||||
}
|
||||
|
||||
void set_rom(ROMType type, std::vector<uint8_t> data) override final {
|
||||
void set_rom(ROMType type, const std::vector<uint8_t> &data) override final {
|
||||
switch(type) {
|
||||
case ZX80: zx80_rom_ = data; break;
|
||||
case ZX81: zx81_rom_ = data; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtains the system ROMs.
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"ZX8081",
|
||||
{
|
||||
"zx80.rom", "zx81.rom",
|
||||
});
|
||||
|
||||
for(size_t index = 0; index < roms.size(); ++index) {
|
||||
auto &data = roms[index];
|
||||
if(!data) return false;
|
||||
set_rom(static_cast<ROMType>(index), *data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard
|
||||
|
||||
void set_key_state(uint16_t key, bool isPressed) override final {
|
||||
|
@ -19,7 +19,7 @@
|
||||
namespace ZX8081 {
|
||||
|
||||
enum ROMType: uint8_t {
|
||||
ZX80, ZX81
|
||||
ZX80 = 0, ZX81
|
||||
};
|
||||
|
||||
class Machine:
|
||||
@ -30,7 +30,7 @@ class Machine:
|
||||
static Machine *ZX8081(const StaticAnalyser::Target &target_hint);
|
||||
virtual ~Machine();
|
||||
|
||||
virtual void set_rom(ROMType type, std::vector<uint8_t> data) = 0;
|
||||
virtual void set_rom(ROMType type, const std::vector<uint8_t> &data) = 0;
|
||||
|
||||
virtual void set_use_fast_tape_hack(bool activate) = 0;
|
||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||
|
@ -9,6 +9,120 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; };
|
||||
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; };
|
||||
4B055A7A1FAE78A00060FFFF /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055A771FAE78210060FFFF /* SDL2.framework */; };
|
||||
4B055A7E1FAE84AA0060FFFF /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055A7C1FAE84A50060FFFF /* main.cpp */; };
|
||||
4B055A7F1FAE852F0060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1354A1D6D2C300054B2EA /* StaticAnalyser.cpp */; };
|
||||
4B055A801FAE85350060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA799931D8B656E0045123D /* StaticAnalyser.cpp */; };
|
||||
4B055A811FAE853A0060FFFF /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF829641D8F732B001BAE39 /* Disk.cpp */; };
|
||||
4B055A821FAE853D0060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD14B0F1D74627C0088EAD6 /* StaticAnalyser.cpp */; };
|
||||
4B055A831FAE85410060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B96F7201D75119A0058BB2D /* Tape.cpp */; };
|
||||
4B055A841FAE85450060FFFF /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA22B051D8817CE0008C640 /* Disk.cpp */; };
|
||||
4B055A851FAE85480060FFFF /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; };
|
||||
4B055A861FAE854C0060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC5E4901D7ED365008CF980 /* StaticAnalyser.cpp */; };
|
||||
4B055A871FAE854F0060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC830CF1D6E7C690000A26F /* Tape.cpp */; };
|
||||
4B055A881FAE85530060FFFF /* Disassembler6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A12551DD55862007A2231 /* Disassembler6502.cpp */; };
|
||||
4B055A891FAE85580060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA91DADD41B0039D2E7 /* StaticAnalyser.cpp */; };
|
||||
4B055A8A1FAE855B0060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805FC1DD02552003085B1 /* Tape.cpp */; };
|
||||
4B055A8B1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1497891EE4AC5E00CE2596 /* StaticAnalyser.cpp */; };
|
||||
4B055A8C1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3421F2EB3E900D9235D /* StaticAnalyser.cpp */; };
|
||||
4B055A8D1FAE85920060FFFF /* AsyncTaskQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */; };
|
||||
4B055A8E1FAE85920060FFFF /* BestEffortUpdater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80ACFE1F85CAC900176895 /* BestEffortUpdater.cpp */; };
|
||||
4B055A8F1FAE85A90060FFFF /* FileHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADB81DE3151600AEC565 /* FileHolder.cpp */; };
|
||||
4B055A901FAE85A90060FFFF /* TimedEventLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697C91D4B6D3E00248BDF /* TimedEventLoop.cpp */; };
|
||||
4B055A911FAE85B50060FFFF /* Cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */; };
|
||||
4B055A921FAE85B50060FFFF /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; };
|
||||
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */; };
|
||||
4B055A941FAE85B50060FFFF /* CommodoreROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCA6CC61D9DD9F000C2D7B2 /* CommodoreROM.cpp */; };
|
||||
4B055A951FAE85BB0060FFFF /* BitReverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1558BE1F844ECD006E9A97 /* BitReverse.cpp */; };
|
||||
4B055A961FAE85BB0060FFFF /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F51DCFF6C9003085B1 /* Commodore.cpp */; };
|
||||
4B055A971FAE85BB0060FFFF /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */; };
|
||||
4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512B1D989E2200B4FED8 /* Drive.cpp */; };
|
||||
4B055A991FAE85CB0060FFFF /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187A1F75E91900926311 /* DiskController.cpp */; };
|
||||
4B055A9A1FAE85CB0060FFFF /* MFMDiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187C1F75E91900926311 /* MFMDiskController.cpp */; };
|
||||
4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45188D1F75FD1B00926311 /* AcornADF.cpp */; };
|
||||
4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45188F1F75FD1B00926311 /* CPCDSK.cpp */; };
|
||||
4B055A9D1FAE85DA0060FFFF /* D64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518911F75FD1B00926311 /* D64.cpp */; };
|
||||
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518931F75FD1B00926311 /* G64.cpp */; };
|
||||
4B055A9F1FAE85DA0060FFFF /* HFE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518951F75FD1B00926311 /* HFE.cpp */; };
|
||||
4B055AA01FAE85DA0060FFFF /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */; };
|
||||
4B055AA11FAE85DA0060FFFF /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; };
|
||||
4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518991F75FD1B00926311 /* SSD.cpp */; };
|
||||
4B055AA31FAE85DF0060FFFF /* ImplicitSectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDD78B1F7F2DB4008579B9 /* ImplicitSectors.cpp */; };
|
||||
4B055AA41FAE85E50060FFFF /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187F1F75E91900926311 /* DigitalPhaseLockedLoop.cpp */; };
|
||||
4B055AA51FAE85EF0060FFFF /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136841F78724F008B8ED9 /* Encoder.cpp */; };
|
||||
4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B71368C1F788112008B8ED9 /* Parser.cpp */; };
|
||||
4B055AA71FAE85EF0060FFFF /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B71368F1F789C93008B8ED9 /* SegmentParser.cpp */; };
|
||||
4B055AA81FAE85EF0060FFFF /* Shifter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136871F78725F008B8ED9 /* Shifter.cpp */; };
|
||||
4B055AA91FAE85EF0060FFFF /* CommodoreGCR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697CC1D4BA44400248BDF /* CommodoreGCR.cpp */; };
|
||||
4B055AAA1FAE85F50060FFFF /* CPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */; };
|
||||
4B055AAB1FAE85FD0060FFFF /* PCMPatchedTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518711F75E91800926311 /* PCMPatchedTrack.cpp */; };
|
||||
4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518731F75E91800926311 /* PCMSegment.cpp */; };
|
||||
4B055AAD1FAE85FD0060FFFF /* PCMTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518751F75E91800926311 /* PCMTrack.cpp */; };
|
||||
4B055AAE1FAE85FD0060FFFF /* TrackSerialiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFFEE51F7B27F1005F3FEB /* TrackSerialiser.cpp */; };
|
||||
4B055AAF1FAE85FD0060FFFF /* UnformattedTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518771F75E91800926311 /* UnformattedTrack.cpp */; };
|
||||
4B055AB01FAE86070060FFFF /* PulseQueuedTape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */; };
|
||||
4B055AB11FAE86070060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; };
|
||||
4B055AB21FAE860F0060FFFF /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
|
||||
4B055AB31FAE860F0060FFFF /* CSW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BF5AE1F146264005B6C36 /* CSW.cpp */; };
|
||||
4B055AB41FAE860F0060FFFF /* OricTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B59199A1DAC6C46005BB85C /* OricTAP.cpp */; };
|
||||
4B055AB51FAE860F0060FFFF /* TapePRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */; };
|
||||
4B055AB61FAE860F0060FFFF /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; };
|
||||
4B055AB71FAE860F0060FFFF /* TZX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E7F1F1C45A00009ABD6 /* TZX.cpp */; };
|
||||
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1497861EE4A1DA00CE2596 /* ZX80O81P.cpp */; };
|
||||
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805EE1DCFC99C003085B1 /* Acorn.cpp */; };
|
||||
4B055ABA1FAE86170060FFFF /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F21DCFD22A003085B1 /* Commodore.cpp */; };
|
||||
4B055ABB1FAE86170060FFFF /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F91DCFF807003085B1 /* Oric.cpp */; };
|
||||
4B055ABC1FAE86170060FFFF /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */; };
|
||||
4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
|
||||
4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */; };
|
||||
4B055AC21FAE9AE30060FFFF /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; };
|
||||
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */; };
|
||||
4B055AC41FAE9AE80060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C11F8D91CD0050900F /* Keyboard.cpp */; };
|
||||
4B055AC51FAE9AEE0060FFFF /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; };
|
||||
4B055AC61FAE9AEE0060FFFF /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52641DF3472B007E74F2 /* Speaker.cpp */; };
|
||||
4B055AC71FAE9AEE0060FFFF /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE7C9161E3D397100A5496D /* TIA.cpp */; };
|
||||
4B055AC81FAE9AFB0060FFFF /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334941F5E25B60097E338 /* C1540.cpp */; };
|
||||
4B055AC91FAE9AFB0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C41F8D91D90050900F /* Keyboard.cpp */; };
|
||||
4B055ACA1FAE9AFB0060FFFF /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
|
||||
4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
|
||||
4B055ACC1FAE9B030060FFFF /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
|
||||
4B055ACD1FAE9B030060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C61F8D91E50050900F /* Keyboard.cpp */; };
|
||||
4B055ACE1FAE9B030060FFFF /* Plus3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512E1D98ACC600B4FED8 /* Plus3.cpp */; };
|
||||
4B055ACF1FAE9B030060FFFF /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* Speaker.cpp */; };
|
||||
4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; };
|
||||
4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7913CA1DFCD80E00175A82 /* Video.cpp */; };
|
||||
4B055AD21FAE9B0B0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; };
|
||||
4B055AD31FAE9B0B0060FFFF /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; };
|
||||
4B055AD41FAE9B0B0060FFFF /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */; };
|
||||
4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */; };
|
||||
4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */; };
|
||||
4B055AD71FAE9B180060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0CA1F8D92580050900F /* Keyboard.cpp */; };
|
||||
4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD3A3091EE755C800B5B501 /* Video.cpp */; };
|
||||
4B055AD91FAE9B180060FFFF /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1497901EE4B5A800CE2596 /* ZX8081.cpp */; };
|
||||
4B055ADA1FAE9B460060FFFF /* 1770.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD468F51D8DF41D0084958B /* 1770.cpp */; };
|
||||
4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
||||
4B055ADC1FAE9B460060FFFF /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; };
|
||||
4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC951C1F368D83008F4C34 /* i8272.cpp */; };
|
||||
4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B83348B1F5DB99C0097E338 /* 6522Base.cpp */; };
|
||||
4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334891F5DB94B0097E338 /* IRQDelegatePortHandler.cpp */; };
|
||||
4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
|
||||
4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; };
|
||||
4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */; };
|
||||
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */; };
|
||||
4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */; };
|
||||
4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */; };
|
||||
4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */; };
|
||||
4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; };
|
||||
4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
||||
4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; };
|
||||
4B055AEA1FAE9B990060FFFF /* 6502Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334851F5DA3780097E338 /* 6502Storage.cpp */; };
|
||||
4B055AEB1FAE9BA20060FFFF /* PartialMachineCycle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334811F5D9FF70097E338 /* PartialMachineCycle.cpp */; };
|
||||
4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322E031F5A2E3C004EB04C /* Z80Base.cpp */; };
|
||||
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334831F5DA0360097E338 /* Z80Storage.cpp */; };
|
||||
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B86E2591F8C628F006FAA45 /* Keyboard.cpp */; };
|
||||
4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; };
|
||||
4B055AF11FAE9C160060FFFF /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
|
||||
4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055AF01FAE9C080060FFFF /* OpenGL.framework */; };
|
||||
4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; };
|
||||
4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; };
|
||||
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
|
||||
@ -481,10 +595,28 @@
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
4B055A681FAE763F0060FFFF /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = "<group>"; };
|
||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
|
||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
|
||||
4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Clock Signal Kiosk"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4B055A771FAE78210060FFFF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../Library/Frameworks/SDL2.framework; sourceTree = SOURCE_ROOT; };
|
||||
4B055A7C1FAE84A50060FFFF /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MachineForTarget.cpp; sourceTree = "<group>"; };
|
||||
4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MachineForTarget.hpp; sourceTree = "<group>"; };
|
||||
4B055AF01FAE9C080060FFFF /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = "<group>"; };
|
||||
4B08A2761EE39306008B7065 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = "<group>"; };
|
||||
4B08A2771EE39306008B7065 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = "<group>"; };
|
||||
@ -1078,6 +1210,7 @@
|
||||
4BD5F1931D13528900631CD1 /* CSBestEffortUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSBestEffortUpdater.h; path = Updater/CSBestEffortUpdater.h; sourceTree = "<group>"; };
|
||||
4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CSBestEffortUpdater.mm; path = Updater/CSBestEffortUpdater.mm; sourceTree = "<group>"; };
|
||||
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
|
||||
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
||||
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
||||
4BE77A2C1D84ADFB00BC3827 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = File.cpp; path = ../../StaticAnalyser/Commodore/File.cpp; sourceTree = "<group>"; };
|
||||
4BE77A2D1D84ADFB00BC3827 /* File.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = File.hpp; path = ../../StaticAnalyser/Commodore/File.hpp; sourceTree = "<group>"; };
|
||||
@ -1134,6 +1267,17 @@
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
4B055A671FAE763F0060FFFF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */,
|
||||
4B055AF11FAE9C160060FFFF /* Accelerate.framework in Frameworks */,
|
||||
4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */,
|
||||
4B055A7A1FAE78A00060FFFF /* SDL2.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4BB73E9B1B587A5100552FC2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -1160,6 +1304,24 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
4B055A761FAE78210060FFFF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B055AF01FAE9C080060FFFF /* OpenGL.framework */,
|
||||
4B055A771FAE78210060FFFF /* SDL2.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B055A7B1FAE84A50060FFFF /* SDL */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B055A7C1FAE84A50060FFFF /* main.cpp */,
|
||||
);
|
||||
name = SDL;
|
||||
path = ../SDL;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B0CCC411C62D0B3001CAC5F /* CRT */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1300,6 +1462,8 @@
|
||||
4B2B3A461F9B8FA70062DABF /* Utility */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */,
|
||||
4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */,
|
||||
4B2B3A471F9B8FA70062DABF /* Typer.cpp */,
|
||||
4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */,
|
||||
4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */,
|
||||
@ -2095,12 +2259,14 @@
|
||||
4BF660691F281573002CB053 /* ClockReceiver */,
|
||||
4BC9DF4A1D04691600F44158 /* Components */,
|
||||
4B3940E81DA83C8700427841 /* Concurrency */,
|
||||
4B055A761FAE78210060FFFF /* Frameworks */,
|
||||
4B86E2581F8C628F006FAA45 /* Inputs */,
|
||||
4BB73EDC1B587CA500552FC2 /* Machines */,
|
||||
4BB697C81D4B559300248BDF /* NumberTheory */,
|
||||
4B366DFD1B5C165F0026627B /* Outputs */,
|
||||
4BB73EDD1B587CA500552FC2 /* Processors */,
|
||||
4BB73E9F1B587A5100552FC2 /* Products */,
|
||||
4B055A7B1FAE84A50060FFFF /* SDL */,
|
||||
4B2409591C45DF85004DA684 /* SignalProcessing */,
|
||||
4BF1354D1D6D2C360054B2EA /* StaticAnalyser */,
|
||||
4B69FB391C4D908A00B5F0AA /* Storage */,
|
||||
@ -2116,6 +2282,7 @@
|
||||
4BB73E9E1B587A5100552FC2 /* Clock Signal.app */,
|
||||
4BB73EB21B587A5100552FC2 /* Clock SignalTests.xctest */,
|
||||
4BB73EBD1B587A5100552FC2 /* Clock SignalUITests.xctest */,
|
||||
4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -2186,6 +2353,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */,
|
||||
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */,
|
||||
4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */,
|
||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */,
|
||||
4B7041271F92C26900735E45 /* JoystickMachine.hpp */,
|
||||
@ -2496,6 +2664,23 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
4B055A691FAE763F0060FFFF /* Clock Signal Kiosk */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 4B055A701FAE763F0060FFFF /* Build configuration list for PBXNativeTarget "Clock Signal Kiosk" */;
|
||||
buildPhases = (
|
||||
4B055A661FAE763F0060FFFF /* Sources */,
|
||||
4B055A671FAE763F0060FFFF /* Frameworks */,
|
||||
4B055A681FAE763F0060FFFF /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Clock Signal Kiosk";
|
||||
productName = "Clock Signal Kiosk";
|
||||
productReference = 4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
4BB73E9D1B587A5100552FC2 /* Clock Signal */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 4BB73EC61B587A5100552FC2 /* Build configuration list for PBXNativeTarget "Clock Signal" */;
|
||||
@ -2559,6 +2744,10 @@
|
||||
LastUpgradeCheck = 0900;
|
||||
ORGANIZATIONNAME = "Thomas Harte";
|
||||
TargetAttributes = {
|
||||
4B055A691FAE763F0060FFFF = {
|
||||
CreatedOnToolsVersion = 9.1;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
4BB73E9D1B587A5100552FC2 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
LastSwiftMigration = 0900;
|
||||
@ -2596,6 +2785,7 @@
|
||||
4BB73E9D1B587A5100552FC2 /* Clock Signal */,
|
||||
4BB73EB11B587A5100552FC2 /* Clock SignalTests */,
|
||||
4BB73EBC1B587A5100552FC2 /* Clock SignalUITests */,
|
||||
4B055A691FAE763F0060FFFF /* Clock Signal Kiosk */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -2913,6 +3103,123 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
4B055A661FAE763F0060FFFF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4B055AAA1FAE85F50060FFFF /* CPM.cpp in Sources */,
|
||||
4B055A9A1FAE85CB0060FFFF /* MFMDiskController.cpp in Sources */,
|
||||
4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */,
|
||||
4B055AA41FAE85E50060FFFF /* DigitalPhaseLockedLoop.cpp in Sources */,
|
||||
4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */,
|
||||
4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */,
|
||||
4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */,
|
||||
4B055A811FAE853A0060FFFF /* Disk.cpp in Sources */,
|
||||
4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */,
|
||||
4B055AA51FAE85EF0060FFFF /* Encoder.cpp in Sources */,
|
||||
4B055AEA1FAE9B990060FFFF /* 6502Storage.cpp in Sources */,
|
||||
4B055A8A1FAE855B0060FFFF /* Tape.cpp in Sources */,
|
||||
4B055AA71FAE85EF0060FFFF /* SegmentParser.cpp in Sources */,
|
||||
4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */,
|
||||
4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */,
|
||||
4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */,
|
||||
4B055A851FAE85480060FFFF /* File.cpp in Sources */,
|
||||
4B055AD31FAE9B0B0060FFFF /* Microdisc.cpp in Sources */,
|
||||
4B055AB41FAE860F0060FFFF /* OricTAP.cpp in Sources */,
|
||||
4B055AB71FAE860F0060FFFF /* TZX.cpp in Sources */,
|
||||
4B055A8C1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055ADA1FAE9B460060FFFF /* 1770.cpp in Sources */,
|
||||
4B055ADC1FAE9B460060FFFF /* AY38910.cpp in Sources */,
|
||||
4B055AD71FAE9B180060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055AB61FAE860F0060FFFF /* TapeUEF.cpp in Sources */,
|
||||
4B055A9D1FAE85DA0060FFFF /* D64.cpp in Sources */,
|
||||
4B055ABB1FAE86170060FFFF /* Oric.cpp in Sources */,
|
||||
4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */,
|
||||
4B055A901FAE85A90060FFFF /* TimedEventLoop.cpp in Sources */,
|
||||
4B055AAB1FAE85FD0060FFFF /* PCMPatchedTrack.cpp in Sources */,
|
||||
4B055AC71FAE9AEE0060FFFF /* TIA.cpp in Sources */,
|
||||
4B055AD21FAE9B0B0060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055AA31FAE85DF0060FFFF /* ImplicitSectors.cpp in Sources */,
|
||||
4B055AAE1FAE85FD0060FFFF /* TrackSerialiser.cpp in Sources */,
|
||||
4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */,
|
||||
4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */,
|
||||
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
|
||||
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
|
||||
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */,
|
||||
4B055A8E1FAE85920060FFFF /* BestEffortUpdater.cpp in Sources */,
|
||||
4B055AB01FAE86070060FFFF /* PulseQueuedTape.cpp in Sources */,
|
||||
4B055A801FAE85350060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */,
|
||||
4B055AB31FAE860F0060FFFF /* CSW.cpp in Sources */,
|
||||
4B055ACF1FAE9B030060FFFF /* Speaker.cpp in Sources */,
|
||||
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055A881FAE85530060FFFF /* Disassembler6502.cpp in Sources */,
|
||||
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
||||
4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */,
|
||||
4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */,
|
||||
4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */,
|
||||
4B055AC51FAE9AEE0060FFFF /* Atari2600.cpp in Sources */,
|
||||
4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */,
|
||||
4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */,
|
||||
4B055ABA1FAE86170060FFFF /* Commodore.cpp in Sources */,
|
||||
4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */,
|
||||
4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */,
|
||||
4B055A861FAE854C0060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */,
|
||||
4B055ACA1FAE9AFB0060FFFF /* Vic20.cpp in Sources */,
|
||||
4B055ABC1FAE86170060FFFF /* ZX8081.cpp in Sources */,
|
||||
4B055AC91FAE9AFB0060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055A991FAE85CB0060FFFF /* DiskController.cpp in Sources */,
|
||||
4B055ACC1FAE9B030060FFFF /* Electron.cpp in Sources */,
|
||||
4B055AB11FAE86070060FFFF /* Tape.cpp in Sources */,
|
||||
4B055AA91FAE85EF0060FFFF /* CommodoreGCR.cpp in Sources */,
|
||||
4B055A7F1FAE852F0060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */,
|
||||
4B055AA01FAE85DA0060FFFF /* MFMSectorDump.cpp in Sources */,
|
||||
4B055AA11FAE85DA0060FFFF /* OricMFMDSK.cpp in Sources */,
|
||||
4B055A951FAE85BB0060FFFF /* BitReverse.cpp in Sources */,
|
||||
4B055A891FAE85580060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055ACE1FAE9B030060FFFF /* Plus3.cpp in Sources */,
|
||||
4B055A8D1FAE85920060FFFF /* AsyncTaskQueue.cpp in Sources */,
|
||||
4B055AC41FAE9AE80060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055A941FAE85B50060FFFF /* CommodoreROM.cpp in Sources */,
|
||||
4B055A971FAE85BB0060FFFF /* ZX8081.cpp in Sources */,
|
||||
4B055AAD1FAE85FD0060FFFF /* PCMTrack.cpp in Sources */,
|
||||
4B055A841FAE85450060FFFF /* Disk.cpp in Sources */,
|
||||
4B055A831FAE85410060FFFF /* Tape.cpp in Sources */,
|
||||
4B055AC61FAE9AEE0060FFFF /* Speaker.cpp in Sources */,
|
||||
4B055AA81FAE85EF0060FFFF /* Shifter.cpp in Sources */,
|
||||
4B055AC81FAE9AFB0060FFFF /* C1540.cpp in Sources */,
|
||||
4B055A8F1FAE85A90060FFFF /* FileHolder.cpp in Sources */,
|
||||
4B055A911FAE85B50060FFFF /* Cartridge.cpp in Sources */,
|
||||
4B055ACD1FAE9B030060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055A8B1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055AB21FAE860F0060FFFF /* CommodoreTAP.cpp in Sources */,
|
||||
4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */,
|
||||
4B055AB51FAE860F0060FFFF /* TapePRG.cpp in Sources */,
|
||||
4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */,
|
||||
4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */,
|
||||
4B055A961FAE85BB0060FFFF /* Commodore.cpp in Sources */,
|
||||
4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */,
|
||||
4B055AD41FAE9B0B0060FFFF /* Oric.cpp in Sources */,
|
||||
4B055A821FAE853D0060FFFF /* StaticAnalyser.cpp in Sources */,
|
||||
4B055A921FAE85B50060FFFF /* PRG.cpp in Sources */,
|
||||
4B055AAF1FAE85FD0060FFFF /* UnformattedTrack.cpp in Sources */,
|
||||
4B055A7E1FAE84AA0060FFFF /* main.cpp in Sources */,
|
||||
4B055A9F1FAE85DA0060FFFF /* HFE.cpp in Sources */,
|
||||
4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */,
|
||||
4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */,
|
||||
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */,
|
||||
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */,
|
||||
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */,
|
||||
4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */,
|
||||
4B055AC21FAE9AE30060FFFF /* KeyboardMachine.cpp in Sources */,
|
||||
4B055AD91FAE9B180060FFFF /* ZX8081.cpp in Sources */,
|
||||
4B055AEB1FAE9BA20060FFFF /* PartialMachineCycle.cpp in Sources */,
|
||||
4B055A871FAE854F0060FFFF /* Tape.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4BB73E9A1B587A5100552FC2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -3182,6 +3489,44 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
4B055A6E1FAE763F0060FFFF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(USER_LIBRARY_DIR)/Frameworks",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
4B055A6F1FAE763F0060FFFF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(USER_LIBRARY_DIR)/Frameworks",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
4BB73EC41B587A5100552FC2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -3294,6 +3639,10 @@
|
||||
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(USER_LIBRARY_DIR)/Frameworks",
|
||||
);
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@ -3324,6 +3673,10 @@
|
||||
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(USER_LIBRARY_DIR)/Frameworks",
|
||||
);
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@ -3408,6 +3761,15 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
4B055A701FAE763F0060FFFF /* Build configuration list for PBXNativeTarget "Clock Signal Kiosk" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
4B055A6E1FAE763F0060FFFF /* Debug */,
|
||||
4B055A6F1FAE763F0060FFFF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
4BB73E991B587A5100552FC2 /* Build configuration list for PBXProject "Clock Signal" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
@ -72,7 +72,7 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
enableUBSanitizer = "YES"
|
||||
disableMainThreadChecker = "YES"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "JoystickMachine.hpp"
|
||||
#include "KeyboardMachine.hpp"
|
||||
|
||||
#import "NSBundle+DataResource.h"
|
||||
#import "NSData+StdVector.h"
|
||||
|
||||
@interface CSMachine()
|
||||
- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
||||
- (void)machineDidChangeClockRate;
|
||||
@ -69,6 +72,23 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
|
||||
_speakerDelegate.machineAccessLock = _delegateMachineAccessLock;
|
||||
|
||||
_machine->set_delegate(&_machineDelegate);
|
||||
_machine->set_rom_fetcher( [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
||||
NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]];
|
||||
std::vector<std::unique_ptr<std::vector<uint8_t>>> results;
|
||||
for(auto &name: names) {
|
||||
NSData *fileData = [[NSBundle mainBundle] dataForResource:[NSString stringWithUTF8String:name.c_str()] withExtension:nil subdirectory:subDirectory];
|
||||
|
||||
if(!fileData)
|
||||
results.emplace_back(nullptr);
|
||||
else {
|
||||
std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>);
|
||||
*data = fileData.stdVector8;
|
||||
results.emplace_back(std::move(data));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
});
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -10,10 +10,6 @@
|
||||
|
||||
#include "AmstradCPC.hpp"
|
||||
|
||||
#import "CSMachine+Subclassing.h"
|
||||
#import "NSData+StdVector.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
|
||||
@implementation CSAmstradCPC {
|
||||
std::unique_ptr<AmstradCPC::Machine> _amstradCPC;
|
||||
}
|
||||
@ -24,35 +20,10 @@
|
||||
self = [super initWithMachine:machine];
|
||||
if(self) {
|
||||
_amstradCPC.reset(machine);
|
||||
|
||||
NSDictionary *roms = @{
|
||||
@(AmstradCPC::ROMType::OS464) : @"os464",
|
||||
@(AmstradCPC::ROMType::OS664) : @"os664",
|
||||
@(AmstradCPC::ROMType::OS6128) : @"os6128",
|
||||
@(AmstradCPC::ROMType::BASIC464) : @"basic464",
|
||||
@(AmstradCPC::ROMType::BASIC664) : @"basic664",
|
||||
@(AmstradCPC::ROMType::BASIC6128) : @"basic6128",
|
||||
@(AmstradCPC::ROMType::AMSDOS) : @"amsdos",
|
||||
};
|
||||
|
||||
for(NSNumber *key in roms.allKeys) {
|
||||
AmstradCPC::ROMType type = (AmstradCPC::ROMType)key.integerValue;
|
||||
NSString *name = roms[key];
|
||||
NSData *data = [self rom:name];
|
||||
if(data) {
|
||||
_amstradCPC->set_rom(type, data.stdVector8);
|
||||
} else {
|
||||
NSLog(@"Amstrad CPC ROM missing: %@", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)rom:(NSString *)name {
|
||||
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/AmstradCPC"];
|
||||
}
|
||||
|
||||
- (NSString *)userDefaultsPrefix { return @"amstradCPC"; }
|
||||
|
||||
@end
|
||||
|
@ -9,11 +9,7 @@
|
||||
#import "CSElectron.h"
|
||||
|
||||
#include "Electron.hpp"
|
||||
#include "StaticAnalyser.hpp"
|
||||
|
||||
#import "CSMachine+Subclassing.h"
|
||||
#import "NSData+StdVector.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
|
||||
@implementation CSElectron {
|
||||
std::unique_ptr<Electron::Machine> _electron;
|
||||
@ -25,38 +21,12 @@
|
||||
self = [super initWithMachine:machine];
|
||||
if(self) {
|
||||
_electron.reset(machine);
|
||||
|
||||
[self setOSROM:[self rom:@"os"]];
|
||||
[self setBASICROM:[self rom:@"basic"]];
|
||||
[self setDFSROM:[self rom:@"DFS-1770-2.20"]];
|
||||
|
||||
NSMutableData *adfs = [[self rom:@"ADFS-E00_1"] mutableCopy];
|
||||
[adfs appendData:[self rom:@"ADFS-E00_2"]];
|
||||
[self setADFSROM:adfs];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)rom:(NSString *)name {
|
||||
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Electron"];
|
||||
}
|
||||
|
||||
#pragma mark - ROM setting
|
||||
|
||||
- (void)setOSROM:(nonnull NSData *)rom { [self setROM:rom slot:Electron::ROMSlotOS]; }
|
||||
- (void)setBASICROM:(nonnull NSData *)rom { [self setROM:rom slot:Electron::ROMSlotBASIC]; }
|
||||
- (void)setADFSROM:(nonnull NSData *)rom { [self setROM:rom slot:Electron::ROMSlotADFS]; }
|
||||
- (void)setDFSROM:(nonnull NSData *)rom { [self setROM:rom slot:Electron::ROMSlotDFS]; }
|
||||
|
||||
- (void)setROM:(nonnull NSData *)rom slot:(int)slot {
|
||||
if(rom)
|
||||
{
|
||||
@synchronized(self) {
|
||||
_electron->set_rom((Electron::ROMSlot)slot, rom.stdVector8, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)userDefaultsPrefix { return @"electron"; }
|
||||
|
||||
#pragma mark - Options
|
||||
|
@ -9,11 +9,6 @@
|
||||
#import "CSOric.h"
|
||||
|
||||
#include "Oric.hpp"
|
||||
#include "StaticAnalyser.hpp"
|
||||
|
||||
#import "CSMachine+Subclassing.h"
|
||||
#import "NSData+StdVector.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
|
||||
@implementation CSOric {
|
||||
std::unique_ptr<Oric::Machine> _oric;
|
||||
@ -25,24 +20,10 @@
|
||||
self = [super initWithMachine:machine];
|
||||
if(self) {
|
||||
_oric.reset(machine);
|
||||
|
||||
NSData *basic10 = [self rom:@"basic10"];
|
||||
NSData *basic11 = [self rom:@"basic11"];
|
||||
NSData *colour = [self rom:@"colour"];
|
||||
NSData *microdisc = [self rom:@"microdisc"];
|
||||
|
||||
if(basic10) _oric->set_rom(Oric::BASIC10, basic10.stdVector8);
|
||||
if(basic11) _oric->set_rom(Oric::BASIC11, basic11.stdVector8);
|
||||
if(colour) _oric->set_rom(Oric::Colour, colour.stdVector8);
|
||||
if(microdisc) _oric->set_rom(Oric::Microdisc, microdisc.stdVector8);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)rom:(NSString *)name {
|
||||
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Oric"];
|
||||
}
|
||||
|
||||
#pragma mark - Options
|
||||
|
||||
- (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {
|
||||
|
@ -11,11 +11,11 @@
|
||||
|
||||
typedef NS_ENUM(NSInteger, CSVic20Country)
|
||||
{
|
||||
CSVic20CountryAmerican,
|
||||
CSVic20CountryDanish,
|
||||
CSVic20CountryEuropean,
|
||||
CSVic20CountryJapanese,
|
||||
CSVic20CountrySwedish,
|
||||
CSVic20CountryAmerican
|
||||
CSVic20CountrySwedish
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, CSVic20MemorySize)
|
||||
|
@ -9,12 +9,6 @@
|
||||
#import "CSVic20.h"
|
||||
|
||||
#include "Vic20.hpp"
|
||||
#include "CommodoreTAP.hpp"
|
||||
#include "G64.hpp"
|
||||
#include "D64.hpp"
|
||||
|
||||
#import "CSmachine+Subclassing.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
|
||||
using namespace Commodore::Vic20;
|
||||
|
||||
@ -31,41 +25,11 @@ using namespace Commodore::Vic20;
|
||||
self = [super initWithMachine:machine];
|
||||
if(self) {
|
||||
_vic20.reset(machine);
|
||||
[self setDriveROM:[[NSBundle mainBundle] dataForResource:@"1540" withExtension:@"bin" subdirectory:@"ROMImages/Commodore1540"]];
|
||||
[self setBASICROM:[self rom:@"basic"]];
|
||||
[self setCountry:CSVic20CountryEuropean];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)rom:(NSString *)name {
|
||||
return [[NSBundle mainBundle] dataForResource:name withExtension:@"bin" subdirectory:@"ROMImages/Vic20"];
|
||||
}
|
||||
|
||||
#pragma mark - ROM setting
|
||||
|
||||
- (void)setROM:(nonnull NSData *)rom slot:(ROMSlot)slot {
|
||||
@synchronized(self) {
|
||||
_vic20->set_rom(slot, rom.length, (const uint8_t *)rom.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setKernelROM:(nonnull NSData *)rom {
|
||||
[self setROM:rom slot:Kernel];
|
||||
}
|
||||
|
||||
- (void)setBASICROM:(nonnull NSData *)rom {
|
||||
[self setROM:rom slot:BASIC];
|
||||
}
|
||||
|
||||
- (void)setCharactersROM:(nonnull NSData *)rom {
|
||||
[self setROM:rom slot:Characters];
|
||||
}
|
||||
|
||||
- (void)setDriveROM:(nonnull NSData *)rom {
|
||||
[self setROM:rom slot:Drive];
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard map
|
||||
|
||||
/*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
|
||||
@ -89,40 +53,17 @@ using namespace Commodore::Vic20;
|
||||
|
||||
- (void)setCountry:(CSVic20Country)country {
|
||||
_country = country;
|
||||
NSString *charactersROM, *kernelROM;
|
||||
Commodore::Vic20::Region region;
|
||||
switch(country) {
|
||||
case CSVic20CountryDanish:
|
||||
region = Commodore::Vic20::Region::PAL;
|
||||
charactersROM = @"characters-danish";
|
||||
kernelROM = @"kernel-danish";
|
||||
break;
|
||||
case CSVic20CountryEuropean:
|
||||
region = Commodore::Vic20::Region::PAL;
|
||||
charactersROM = @"characters-english";
|
||||
kernelROM = @"kernel-pal";
|
||||
break;
|
||||
case CSVic20CountryJapanese:
|
||||
region = Commodore::Vic20::Region::NTSC;
|
||||
charactersROM = @"characters-japanese";
|
||||
kernelROM = @"kernel-japanese";
|
||||
break;
|
||||
case CSVic20CountrySwedish:
|
||||
region = Commodore::Vic20::Region::PAL;
|
||||
charactersROM = @"characters-swedish";
|
||||
kernelROM = @"kernel-swedish";
|
||||
break;
|
||||
case CSVic20CountryAmerican:
|
||||
region = Commodore::Vic20::Region::NTSC;
|
||||
charactersROM = @"characters-english";
|
||||
kernelROM = @"kernel-ntsc";
|
||||
break;
|
||||
case CSVic20CountryDanish: region = Commodore::Vic20::Danish; break;
|
||||
case CSVic20CountryEuropean: region = Commodore::Vic20::European; break;
|
||||
case CSVic20CountryJapanese: region = Commodore::Vic20::Japanese; break;
|
||||
case CSVic20CountrySwedish: region = Commodore::Vic20::Swedish; break;
|
||||
case CSVic20CountryAmerican: region = Commodore::Vic20::American; break;
|
||||
}
|
||||
|
||||
@synchronized(self) {
|
||||
_vic20->set_region(region);
|
||||
[self setCharactersROM:[self rom:charactersROM]];
|
||||
[self setKernelROM:[self rom:kernelROM]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,10 +10,6 @@
|
||||
|
||||
#include "ZX8081.hpp"
|
||||
|
||||
#import "CSMachine+Subclassing.h"
|
||||
#import "NSData+StdVector.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
|
||||
@implementation CSZX8081 {
|
||||
std::unique_ptr<ZX8081::Machine> _zx8081;
|
||||
}
|
||||
@ -24,16 +20,10 @@
|
||||
self = [super initWithMachine:machine];
|
||||
if(self) {
|
||||
_zx8081.reset(machine);
|
||||
_zx8081->set_rom(ZX8081::ROMType::ZX80, [self rom:@"zx80"].stdVector8);
|
||||
_zx8081->set_rom(ZX8081::ROMType::ZX81, [self rom:@"zx81"].stdVector8);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)rom:(NSString *)name {
|
||||
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/ZX8081"];
|
||||
}
|
||||
|
||||
- (NSString *)userDefaultsPrefix { return @"zx8081"; }
|
||||
|
||||
#pragma mark - Options
|
||||
|
276
OSBindings/SDL/main.cpp
Normal file
276
OSBindings/SDL/main.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
//
|
||||
// main.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 04/11/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "../../StaticAnalyser/StaticAnalyser.hpp"
|
||||
#include "../../Machines/Utility/MachineForTarget.hpp"
|
||||
|
||||
#include "../../Machines/ConfigurationTarget.hpp"
|
||||
#include "../../Machines/CRTMachine.hpp"
|
||||
|
||||
#include "../../Concurrency/BestEffortUpdater.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
struct CRTMachineDelegate: public CRTMachine::Machine::Delegate {
|
||||
void machine_did_change_clock_rate(CRTMachine::Machine *machine) {
|
||||
best_effort_updater->set_clock_rate(machine->get_clock_rate());
|
||||
}
|
||||
|
||||
void machine_did_change_clock_is_unlimited(CRTMachine::Machine *machine) {
|
||||
}
|
||||
|
||||
Concurrency::BestEffortUpdater *best_effort_updater;
|
||||
};
|
||||
|
||||
struct BestEffortUpdaterDelegate: public Concurrency::BestEffortUpdater::Delegate {
|
||||
void update(Concurrency::BestEffortUpdater *updater, int cycles, bool did_skip_previous_update) {
|
||||
machine->crt_machine()->run_for(Cycles(cycles));
|
||||
}
|
||||
|
||||
Machine::DynamicMachine *machine;
|
||||
};
|
||||
|
||||
// This is set to a relatively large number for now.
|
||||
const int AudioBufferSize = 1024;
|
||||
|
||||
struct SpeakerDelegate: public Outputs::Speaker::Delegate {
|
||||
void speaker_did_complete_samples(Outputs::Speaker *speaker, const std::vector<int16_t> &buffer) {
|
||||
if(SDL_GetQueuedAudioSize(audio_device) < AudioBufferSize*3)
|
||||
SDL_QueueAudio(audio_device, reinterpret_cast<const void *>(buffer.data()), static_cast<Uint32>(buffer.size() * sizeof(uint16_t)));
|
||||
updater->update();
|
||||
}
|
||||
|
||||
SDL_AudioDeviceID audio_device;
|
||||
Concurrency::BestEffortUpdater *updater;
|
||||
};
|
||||
|
||||
bool KeyboardKeyForSDLScancode(SDL_Keycode scancode, Inputs::Keyboard::Key &key) {
|
||||
#define BIND(x, y) case SDL_SCANCODE_##x: key = Inputs::Keyboard::Key::y; break;
|
||||
switch(scancode) {
|
||||
default: return false;
|
||||
|
||||
BIND(F1, F1) BIND(F2, F2) BIND(F3, F3) BIND(F4, F4) BIND(F5, F5) BIND(F6, F6)
|
||||
BIND(F7, F7) BIND(F8, F8) BIND(F9, F9) BIND(F10, F10) BIND(F11, F11) BIND(F12, F12)
|
||||
|
||||
BIND(1, k1) BIND(2, k2) BIND(3, k3) BIND(4, k4) BIND(5, k5)
|
||||
BIND(6, k6) BIND(7, k7) BIND(8, k8) BIND(9, k9) BIND(0, k0)
|
||||
|
||||
BIND(Q, Q) BIND(W, W) BIND(E, E) BIND(R, R) BIND(T, T)
|
||||
BIND(Y, Y) BIND(U, U) BIND(I, I) BIND(O, O) BIND(P, P)
|
||||
BIND(A, A) BIND(S, S) BIND(D, D) BIND(F, F) BIND(G, G)
|
||||
BIND(H, H) BIND(J, J) BIND(K, K) BIND(L, L)
|
||||
BIND(Z, Z) BIND(X, X) BIND(C, C) BIND(V, V)
|
||||
BIND(B, B) BIND(N, N) BIND(M, M)
|
||||
|
||||
BIND(KP_7, KeyPad7) BIND(KP_8, KeyPad8) BIND(KP_9, KeyPad9)
|
||||
BIND(KP_4, KeyPad4) BIND(KP_5, KeyPad5) BIND(KP_6, KeyPad6)
|
||||
BIND(KP_1, KeyPad1) BIND(KP_2, KeyPad2) BIND(KP_3, KeyPad3)
|
||||
BIND(KP_0, KeyPad0)
|
||||
|
||||
BIND(ESCAPE, Escape)
|
||||
|
||||
BIND(PRINTSCREEN, PrintScreen) BIND(SCROLLLOCK, ScrollLock) BIND(PAUSE, Pause)
|
||||
|
||||
BIND(GRAVE, BackTick) BIND(MINUS, Hyphen) BIND(EQUALS, Equals) BIND(BACKSPACE, BackSpace)
|
||||
|
||||
BIND(TAB, Tab)
|
||||
BIND(LEFTBRACKET, OpenSquareBracket) BIND(RIGHTBRACKET, CloseSquareBracket)
|
||||
BIND(BACKSLASH, BackSlash)
|
||||
|
||||
BIND(CAPSLOCK, CapsLock) BIND(SEMICOLON, Semicolon)
|
||||
BIND(APOSTROPHE, Quote) BIND(RETURN, Enter)
|
||||
|
||||
BIND(LSHIFT, LeftShift) BIND(COMMA, Comma) BIND(PERIOD, FullStop)
|
||||
BIND(SLASH, ForwardSlash) BIND(RSHIFT, RightShift)
|
||||
|
||||
BIND(LCTRL, LeftControl) BIND(LALT, LeftOption) BIND(LGUI, LeftMeta)
|
||||
BIND(SPACE, Space)
|
||||
BIND(RCTRL, RightControl) BIND(RALT, RightOption) BIND(RGUI, RightMeta)
|
||||
|
||||
BIND(LEFT, Left) BIND(RIGHT, Right) BIND(UP, Up) BIND(DOWN, Down)
|
||||
|
||||
BIND(INSERT, Insert) BIND(HOME, Home) BIND(PAGEUP, PageUp)
|
||||
BIND(DELETE, Delete) BIND(END, End) BIND(PAGEDOWN, PageDown)
|
||||
|
||||
BIND(NUMLOCKCLEAR, NumLock) BIND(KP_DIVIDE, KeyPadSlash) BIND(KP_MULTIPLY, KeyPadAsterisk)
|
||||
BIND(KP_PLUS, KeyPadPlus) BIND(KP_MINUS, KeyPadMinus) BIND(KP_ENTER, KeyPadEnter)
|
||||
BIND(KP_DECIMAL, KeyPadDecimalPoint)
|
||||
BIND(KP_EQUALS, KeyPadEquals)
|
||||
BIND(HELP, Help)
|
||||
|
||||
// SDL doesn't seem to have scancodes for hash or keypad delete?
|
||||
}
|
||||
#undef BIND
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SDL_Window *window = nullptr;
|
||||
|
||||
// Perform a sanity check on arguments.
|
||||
if(argc < 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " [file]" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Determine the machine for the supplied file.
|
||||
std::list<StaticAnalyser::Target> targets = StaticAnalyser::GetTargets(argv[1]);
|
||||
if(targets.empty()) {
|
||||
std::cerr << "Cannot open " << argv[1] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Concurrency::BestEffortUpdater updater;
|
||||
BestEffortUpdaterDelegate best_effort_updater_delegate;
|
||||
CRTMachineDelegate crt_delegate;
|
||||
SpeakerDelegate speaker_delegate;
|
||||
|
||||
// Create and configure a machine.
|
||||
std::unique_ptr<::Machine::DynamicMachine> machine(::Machine::MachineForTarget(targets.front()));
|
||||
|
||||
updater.set_clock_rate(machine->crt_machine()->get_clock_rate());
|
||||
crt_delegate.best_effort_updater = &updater;
|
||||
best_effort_updater_delegate.machine = machine.get();
|
||||
speaker_delegate.updater = &updater;
|
||||
|
||||
machine->crt_machine()->set_delegate(&crt_delegate);
|
||||
updater.set_delegate(&best_effort_updater_delegate);
|
||||
|
||||
// Attempt to set up video and audio.
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ask for no depth buffer, a core profile and vsync-aligned rendering.
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
window = SDL_CreateWindow( "Clock Signal",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
400, 300,
|
||||
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if(!window)
|
||||
{
|
||||
std::cerr << "Could not create window" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
SDL_GL_MakeCurrent(window, gl_context);
|
||||
|
||||
// For vanilla SDL purposes, assume system ROMs can be found in one of:
|
||||
//
|
||||
// /usr/local/share/CLK/[system]; or
|
||||
// /usr/share/CLK/[system]
|
||||
bool roms_loaded = machine->crt_machine()->set_rom_fetcher( [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
||||
std::vector<std::unique_ptr<std::vector<uint8_t>>> results;
|
||||
for(auto &name: names) {
|
||||
std::string local_path = "/usr/local/share/CLK/" + machine + "/" + name;
|
||||
FILE *file = fopen(local_path.c_str(), "r");
|
||||
if(!file) {
|
||||
std::string path = "/usr/share/CLK/" + machine + "/" + name;
|
||||
file = fopen(path.c_str(), "r");
|
||||
}
|
||||
|
||||
if(!file) {
|
||||
results.emplace_back(nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>);
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
data->resize(ftell(file));
|
||||
fseek(file, 0, SEEK_SET);
|
||||
fread(data->data(), 1, data->size(), file);
|
||||
fclose(file);
|
||||
|
||||
results.emplace_back(std::move(data));
|
||||
}
|
||||
|
||||
return results;
|
||||
});
|
||||
|
||||
if(!roms_loaded) {
|
||||
std::cerr << "Could not find system ROMs; please install to /usr/local/share/CLK/ or /usr/share/CLK/" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
machine->configuration_target()->configure_as_target(targets.front());
|
||||
|
||||
// Setup output, assuming a CRT machine for now, and prepare a best-effort updater.
|
||||
machine->crt_machine()->setup_output(4.0 / 3.0);
|
||||
machine->crt_machine()->get_crt()->set_output_gamma(2.2f);
|
||||
|
||||
// For now, lie about audio output intentions.
|
||||
auto speaker = machine->crt_machine()->get_speaker();
|
||||
if(speaker) {
|
||||
// Create an audio pipe.
|
||||
SDL_AudioSpec desired_audio_spec;
|
||||
SDL_AudioSpec obtained_audio_spec;
|
||||
|
||||
SDL_zero(desired_audio_spec);
|
||||
desired_audio_spec.freq = 48000; // TODO: how can I get SDL to reveal the output rate of this machine?
|
||||
desired_audio_spec.format = AUDIO_S16;
|
||||
desired_audio_spec.channels = 1;
|
||||
desired_audio_spec.samples = AudioBufferSize;
|
||||
|
||||
speaker_delegate.audio_device = SDL_OpenAudioDevice(nullptr, 0, &desired_audio_spec, &obtained_audio_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
|
||||
speaker->set_output_rate(obtained_audio_spec.freq, obtained_audio_spec.samples);
|
||||
speaker->set_delegate(&speaker_delegate);
|
||||
SDL_PauseAudioDevice(speaker_delegate.audio_device, 0);
|
||||
}
|
||||
|
||||
// Run the main event loop until the OS tells us to quit.
|
||||
bool should_quit = false;
|
||||
while(!should_quit) {
|
||||
// Process all pending events.
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_QUIT: should_quit = true; break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
KeyboardMachine::Machine *keyboard_machine = machine->keyboard_machine();
|
||||
if(!keyboard_machine) break;
|
||||
|
||||
Inputs::Keyboard::Key key = Inputs::Keyboard::Key::Space;
|
||||
if(!KeyboardKeyForSDLScancode(event.key.keysym.scancode, key)) break;
|
||||
keyboard_machine->get_keyboard().set_key_pressed(key, event.type == SDL_KEYDOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Display a new frame and wait for vsync.
|
||||
updater.update();
|
||||
int width, height;
|
||||
SDL_GetWindowSize(window, &width, &height);
|
||||
machine->crt_machine()->get_crt()->draw_frame(static_cast<unsigned int>(width), static_cast<unsigned int>(height), false);
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
SDL_DestroyWindow( window );
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
@ -109,7 +109,7 @@ class Speaker {
|
||||
size_t buffer_in_progress_pointer_;
|
||||
size_t number_of_taps_, requested_number_of_taps_;
|
||||
bool coefficients_are_dirty_;
|
||||
Delegate *delegate_;
|
||||
Delegate *delegate_ = nullptr;
|
||||
|
||||
float input_cycles_per_second_, output_cycles_per_second_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user