1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Merge pull request #264 from TomHarte/SDLKiosk

SDL kiosk
This commit is contained in:
Thomas Harte 2017-11-07 22:44:48 -05:00 committed by GitHub
commit 09c855a659
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1084 additions and 299 deletions

View File

@ -919,10 +919,30 @@ class ConcreteMachine:
} }
// See header; provides the system ROMs. // 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; 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 { void set_component_is_sleeping(void *component, bool is_sleeping) override final {
fdc_is_sleeping_ = fdc_.is_sleeping(); fdc_is_sleeping_ = fdc_.is_sleeping();
tape_player_is_sleeping_ = tape_player_.is_sleeping(); tape_player_is_sleeping_ = tape_player_.is_sleeping();

View File

@ -39,7 +39,7 @@ class Machine:
static Machine *AmstradCPC(); 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. /// 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;
}; };
} }

View File

@ -135,42 +135,27 @@ class TIA {
// objects // objects
template<class T> struct Object { template<class T> struct Object {
// the two programmer-set values // the two programmer-set values
int position; int position = 0;
int motion; int motion = 0;
// motion_step_ is the current motion counter value; motion_time_ is the next time it will fire // motion_step_ is the current motion counter value; motion_time_ is the next time it will fire
int motion_step; int motion_step = 0;
int motion_time; int motion_time = 0;
// indicates whether this object is currently undergoing motion // indicates whether this object is currently undergoing motion
bool is_moving; bool is_moving = false;
Object() : position(0), motion(0), motion_step(0), motion_time(0), is_moving(false) {};
}; };
// player state // player state
struct Player: public Object<Player> { struct Player: public Object<Player> {
Player() : int adder = 4;
adder(4), int copy_flags = 0; // a bit field, corresponding to the first few values of NUSIZ
copy_flags(0), uint8_t graphic[2] = {0, 0}; // the player graphic; 1 = new, 0 = current
graphic{0, 0}, int reverse_mask = false; // 7 for a reflected player, 0 for normal
reverse_mask(false), int graphic_index = 0;
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; int pixel_position = 32, pixel_counter = 0;
int copy_flags; // a bit field, corresponding to the first few values of NUSIZ int latched_pixel4_time = -1;
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;
const bool enqueues = true; const bool enqueues = true;
inline void skip_pixels(const int count, int from_horizontal_counter) { inline void skip_pixels(const int count, int from_horizontal_counter) {
@ -219,15 +204,14 @@ class TIA {
} }
private: private:
int copy_index_; int copy_index_ = 0;
struct QueuedPixels { struct QueuedPixels {
int start, end; int start = 0, end = 0;
int pixel_position; int pixel_position = 0;
int adder; int adder = 0;
int reverse_mask; int reverse_mask = false;
QueuedPixels() : start(0), end(0), pixel_position(0), adder(0), reverse_mask(false) {}
} queue_[4]; } 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) { 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; 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 // common actor for things that appear as a horizontal run of pixels
struct HorizontalRun: public Object<HorizontalRun> { struct HorizontalRun: public Object<HorizontalRun> {
int pixel_position; int pixel_position = 0;
int size; int size = 1;
const bool enqueues = false; const bool enqueues = false;
inline void skip_pixels(const int count, int from_horizontal_counter) { 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 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) {} void enqueue_pixels(const int start, const int end, int from_horizontal_counter) {}
HorizontalRun() : pixel_position(0), size(1) {}
}; };
// missile state // missile state
struct Missile: public HorizontalRun { struct Missile: public HorizontalRun {
bool enabled; bool enabled = false;
bool locked_to_player; bool locked_to_player = false;
int copy_flags; int copy_flags = 0;
inline void output_pixels(uint8_t *const target, const int count, const uint8_t collision_identity, int from_horizontal_counter) { inline void output_pixels(uint8_t *const target, const int count, const uint8_t collision_identity, int from_horizontal_counter) {
if(!pixel_position) return; if(!pixel_position) return;
@ -287,14 +268,12 @@ class TIA {
skip_pixels(count, from_horizontal_counter); skip_pixels(count, from_horizontal_counter);
} }
} }
Missile() : enabled(false), copy_flags(0) {}
} missile_[2]; } missile_[2];
// ball state // ball state
struct Ball: public HorizontalRun { struct Ball: public HorizontalRun {
bool enabled[2]; bool enabled[2] = {false, false};
int enabled_index; int enabled_index = 0;
const int copy_flags = 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) { 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); skip_pixels(count, from_horizontal_counter);
} }
} }
Ball() : enabled{false, false}, enabled_index(0) {}
} ball_; } ball_;
// motion // motion

View File

@ -12,6 +12,7 @@
#include "../Outputs/CRT/CRT.hpp" #include "../Outputs/CRT/CRT.hpp"
#include "../Outputs/Speaker.hpp" #include "../Outputs/Speaker.hpp"
#include "../ClockReceiver/ClockReceiver.hpp" #include "../ClockReceiver/ClockReceiver.hpp"
#include "ROMMachine.hpp"
namespace CRTMachine { 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 that optionally provide a speaker, and that nominate a clock rate and can announce to a delegate
should that clock rate change. should that clock rate change.
*/ */
class Machine { class Machine: public ROMMachine::Machine {
public: public:
Machine() : clock_is_unlimited_(false), delegate_(nullptr) {} Machine() : clock_is_unlimited_(false), delegate_(nullptr) {}

View File

@ -10,6 +10,7 @@
#define Commodore1540_hpp #define Commodore1540_hpp
#include "../SerialBus.hpp" #include "../SerialBus.hpp"
#include "../../ROMMachine.hpp"
#include "../../../Storage/Disk/Disk.hpp" #include "../../../Storage/Disk/Disk.hpp"
#include "Implementation/C1540Base.hpp" #include "Implementation/C1540Base.hpp"
@ -19,12 +20,18 @@ namespace C1540 {
/*! /*!
Provides an emulation of the C1540. Provides an emulation of the C1540.
*/ */
class Machine: public MachineBase { class Machine: public MachineBase, public ROMMachine::Machine {
public: 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. 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. /// Inserts @c disk into the drive.
void set_disk(std::shared_ptr<Storage::Disk::Disk> disk); void set_disk(std::shared_ptr<Storage::Disk::Disk> disk);
private:
Personality personality_;
}; };
} }

View File

@ -40,6 +40,8 @@ MachineBase::MachineBase() :
set_drive(drive_); 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) { void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) {
Commodore::Serial::AttachPortAndBus(serial_port_, 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); return Cycles(1);
} }
void Machine::set_rom(const std::vector<uint8_t> &rom) { 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) {
assert(rom.size() == sizeof(rom_)); std::string rom_name;
memcpy(rom_, rom.data(), std::min(sizeof(rom_), rom.size())); 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) { void Machine::set_disk(std::shared_ptr<Storage::Disk::Disk> disk) {

View File

@ -37,6 +37,18 @@ enum JoystickInput {
Fire = 0x20 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 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 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); keyboard_via_port_handler_->set_interrupt_delegate(this);
tape_->set_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 // install a joystick
joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_)); joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_));
} }
@ -294,24 +300,32 @@ class ConcreteMachine:
delete[] rom_; delete[] rom_;
} }
void set_rom(ROMSlot slot, size_t length, const uint8_t *data) override final { void set_rom(ROMSlot slot, const std::vector<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;
} }
if(target) { // Obtains the system ROMs.
size_t length_to_copy = std::min(max_length, length); 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 {
memcpy(target, data, length_to_copy); 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 { void configure_as_target(const StaticAnalyser::Target &target) override final {
@ -333,13 +347,13 @@ class ConcreteMachine:
if(target.media.disks.size()) { if(target.media.disks.size()) {
// construct the 1540 // 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 // attach it to the serial bus
c1540_->set_serial_bus(serial_bus_); c1540_->set_serial_bus(serial_bus_);
// install the ROM if it was previously set // give it a means to obtain its ROM
install_disk_rom(); c1540_->set_rom_fetcher(rom_fetcher_);
} }
insert_media(target.media); insert_media(target.media);
@ -383,10 +397,38 @@ class ConcreteMachine:
} }
void set_memory_size(MemorySize size) override final { 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_read_memory_map_, 0, sizeof(processor_read_memory_map_));
memset(processor_write_memory_map_, 0, sizeof(processor_write_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; default: break;
case ThreeKB: case ThreeKB:
write_to_map(processor_read_memory_map_, expansion_ram_, 0x0000, 0x1000); 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_, 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_, 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_, 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_, 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_, screen_memory_, 0x1000, sizeof(screen_memory_));
write_to_map(processor_write_memory_map_, colour_memory_, 0x9400, sizeof(colour_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 // install the inserted ROM if there is one
if(rom_) { if(rom_) {
write_to_map(processor_read_memory_map_, rom_, rom_address_, rom_length_); 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 { void set_use_fast_tape_hack(bool activate) override final {
use_fast_tape_hack_ = activate; use_fast_tape_hack_ = activate;
} }
@ -542,19 +596,16 @@ class ConcreteMachine:
} }
void run_for(const Cycles cycles) override final { void run_for(const Cycles cycles) override final {
if(needs_configuration_) {
needs_configuration_ = false;
configure_memory();
}
m6502_.run_for(cycles); m6502_.run_for(cycles);
} }
void setup_output(float aspect_ratio) override final { void setup_output(float aspect_ratio) override final {
mos6560_.reset(new Vic6560()); 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. 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 { void close_output() override final {
@ -590,9 +641,11 @@ class ConcreteMachine:
private: private:
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_; CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
uint8_t character_rom_[0x1000]; std::vector<uint8_t> roms_[9];
uint8_t basic_rom_[0x2000];
uint8_t kernel_rom_[0x2000]; 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 expansion_ram_[0x8000];
uint8_t *rom_; uint8_t *rom_;
@ -601,7 +654,8 @@ class ConcreteMachine:
uint8_t user_basic_memory_[0x0400]; uint8_t user_basic_memory_[0x0400];
uint8_t screen_memory_[0x1000]; uint8_t screen_memory_[0x1000];
uint8_t colour_memory_[0x0400]; 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_read_memory_map_[64];
uint8_t *processor_write_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_; Commodore::Vic20::KeyboardMapper keyboard_mapper_;
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_; std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
@ -635,13 +692,6 @@ class ConcreteMachine:
// Disk // Disk
std::shared_ptr<::Commodore::C1540::Machine> c1540_; 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();
}
}
}; };
} }

View File

@ -20,7 +20,7 @@ namespace Commodore {
namespace Vic20 { namespace Vic20 {
enum ROMSlot { enum ROMSlot {
Kernel, Kernel = 0,
BASIC, BASIC,
Characters, Characters,
Drive Drive
@ -33,8 +33,11 @@ enum MemorySize {
}; };
enum Region { enum Region {
NTSC, American,
PAL Danish,
Japanese,
European,
Swedish
}; };
class Machine: class Machine:
@ -49,8 +52,7 @@ class Machine:
static Machine *Vic20(); static Machine *Vic20();
/// Sets the contents of the rom in @c slot to the buffer @c data of length @c length. /// 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; virtual void set_rom(ROMSlot slot, const std::vector<uint8_t> &data) = 0;
// TODO: take a std::vector<uint8_t> to collapse length and data.
/// Sets the memory size of this Vic-20. /// Sets the memory size of this Vic-20.
virtual void set_memory_size(MemorySize size) = 0; virtual void set_memory_size(MemorySize size) = 0;

View File

@ -39,11 +39,12 @@ class ConcreteMachine:
set_clock_rate(2000000); 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; uint8_t *target = nullptr;
switch(slot) { switch(slot) {
case ROMSlotDFS: dfs_ = data; return; 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; case ROMSlotOS: target = os_; break;
default: default:
@ -55,6 +56,30 @@ class ConcreteMachine:
memcpy(target, &data[0], std::min(static_cast<size_t>(16384), data.size())); 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 { void set_key_state(uint16_t key, bool isPressed) override final {
if(key == KeyBreak) { if(key == KeyBreak) {
m6502_.set_reset_line(isPressed); m6502_.set_reset_line(isPressed);
@ -91,8 +116,8 @@ class ConcreteMachine:
set_rom(ROMSlot0, dfs_, true); set_rom(ROMSlot0, dfs_, true);
} }
if(target.acorn.has_adfs) { if(target.acorn.has_adfs) {
set_rom(ROMSlot4, adfs_, true); set_rom(ROMSlot4, adfs1_, true);
set_rom(ROMSlot5, std::vector<uint8_t>(adfs_.begin() + 16384, adfs_.end()), true); set_rom(ROMSlot5, adfs2_, true);
} }
} }
@ -435,7 +460,7 @@ class ConcreteMachine:
uint8_t roms_[16][16384]; 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}; 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]; uint8_t os_[16384], ram_[32768];
std::vector<uint8_t> dfs_, adfs_; std::vector<uint8_t> dfs_, adfs1_, adfs2_;
// Paging // Paging
ROMSlot active_rom_ = ROMSlot::ROMSlot0; ROMSlot active_rom_ = ROMSlot::ROMSlot0;

View File

@ -28,7 +28,8 @@ enum ROMSlot: uint8_t {
ROMSlot12, ROMSlot13, ROMSlot14, ROMSlot15, 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 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. 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. /// Enables or disables turbo-speed tape loading.
virtual void set_use_fast_tape_hack(bool activate) = 0; virtual void set_use_fast_tape_hack(bool activate) = 0;

View File

@ -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 { void set_key_state(uint16_t key, bool is_pressed) override final {
if(key == KeyNMI) { if(key == KeyNMI) {
m6502_.set_nmi_line(is_pressed); m6502_.set_nmi_line(is_pressed);

View File

@ -19,7 +19,7 @@
namespace Oric { namespace Oric {
enum ROM { enum ROM {
BASIC10, BASIC11, Microdisc, Colour BASIC10 = 0, BASIC11, Microdisc, Colour
}; };
/*! /*!

27
Machines/ROMMachine.hpp Normal file
View 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 */

View 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";
}
}

View 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 */

View File

@ -290,13 +290,30 @@ template<bool is_zx81> class ConcreteMachine:
Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); 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) { switch(type) {
case ZX80: zx80_rom_ = data; break; case ZX80: zx80_rom_ = data; break;
case ZX81: zx81_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 #pragma mark - Keyboard
void set_key_state(uint16_t key, bool isPressed) override final { void set_key_state(uint16_t key, bool isPressed) override final {

View File

@ -19,7 +19,7 @@
namespace ZX8081 { namespace ZX8081 {
enum ROMType: uint8_t { enum ROMType: uint8_t {
ZX80, ZX81 ZX80 = 0, ZX81
}; };
class Machine: class Machine:
@ -30,7 +30,7 @@ class Machine:
static Machine *ZX8081(const StaticAnalyser::Target &target_hint); static Machine *ZX8081(const StaticAnalyser::Target &target_hint);
virtual ~Machine(); 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_use_fast_tape_hack(bool activate) = 0;
virtual void set_tape_is_playing(bool is_playing) = 0; virtual void set_tape_is_playing(bool is_playing) = 0;

View File

@ -9,6 +9,120 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; }; 4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; };
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.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 */; }; 4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; };
4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; }; 4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; };
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; }; 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
@ -481,10 +595,28 @@
}; };
/* End PBXContainerItemProxy section */ /* 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 */ /* Begin PBXFileReference section */
4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase 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 */ = { 4BB73E9B1B587A5100552FC2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -1160,6 +1304,24 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup 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 */ = { 4B0CCC411C62D0B3001CAC5F /* CRT */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1300,6 +1462,8 @@
4B2B3A461F9B8FA70062DABF /* Utility */ = { 4B2B3A461F9B8FA70062DABF /* Utility */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */,
4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */,
4B2B3A471F9B8FA70062DABF /* Typer.cpp */, 4B2B3A471F9B8FA70062DABF /* Typer.cpp */,
4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */, 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */,
4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */, 4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */,
@ -2095,12 +2259,14 @@
4BF660691F281573002CB053 /* ClockReceiver */, 4BF660691F281573002CB053 /* ClockReceiver */,
4BC9DF4A1D04691600F44158 /* Components */, 4BC9DF4A1D04691600F44158 /* Components */,
4B3940E81DA83C8700427841 /* Concurrency */, 4B3940E81DA83C8700427841 /* Concurrency */,
4B055A761FAE78210060FFFF /* Frameworks */,
4B86E2581F8C628F006FAA45 /* Inputs */, 4B86E2581F8C628F006FAA45 /* Inputs */,
4BB73EDC1B587CA500552FC2 /* Machines */, 4BB73EDC1B587CA500552FC2 /* Machines */,
4BB697C81D4B559300248BDF /* NumberTheory */, 4BB697C81D4B559300248BDF /* NumberTheory */,
4B366DFD1B5C165F0026627B /* Outputs */, 4B366DFD1B5C165F0026627B /* Outputs */,
4BB73EDD1B587CA500552FC2 /* Processors */, 4BB73EDD1B587CA500552FC2 /* Processors */,
4BB73E9F1B587A5100552FC2 /* Products */, 4BB73E9F1B587A5100552FC2 /* Products */,
4B055A7B1FAE84A50060FFFF /* SDL */,
4B2409591C45DF85004DA684 /* SignalProcessing */, 4B2409591C45DF85004DA684 /* SignalProcessing */,
4BF1354D1D6D2C360054B2EA /* StaticAnalyser */, 4BF1354D1D6D2C360054B2EA /* StaticAnalyser */,
4B69FB391C4D908A00B5F0AA /* Storage */, 4B69FB391C4D908A00B5F0AA /* Storage */,
@ -2116,6 +2282,7 @@
4BB73E9E1B587A5100552FC2 /* Clock Signal.app */, 4BB73E9E1B587A5100552FC2 /* Clock Signal.app */,
4BB73EB21B587A5100552FC2 /* Clock SignalTests.xctest */, 4BB73EB21B587A5100552FC2 /* Clock SignalTests.xctest */,
4BB73EBD1B587A5100552FC2 /* Clock SignalUITests.xctest */, 4BB73EBD1B587A5100552FC2 /* Clock SignalUITests.xctest */,
4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2186,6 +2353,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */, 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */,
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */,
4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */, 4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */,
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */, 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */,
4B7041271F92C26900735E45 /* JoystickMachine.hpp */, 4B7041271F92C26900735E45 /* JoystickMachine.hpp */,
@ -2496,6 +2664,23 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget 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 */ = { 4BB73E9D1B587A5100552FC2 /* Clock Signal */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 4BB73EC61B587A5100552FC2 /* Build configuration list for PBXNativeTarget "Clock Signal" */; buildConfigurationList = 4BB73EC61B587A5100552FC2 /* Build configuration list for PBXNativeTarget "Clock Signal" */;
@ -2559,6 +2744,10 @@
LastUpgradeCheck = 0900; LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Thomas Harte"; ORGANIZATIONNAME = "Thomas Harte";
TargetAttributes = { TargetAttributes = {
4B055A691FAE763F0060FFFF = {
CreatedOnToolsVersion = 9.1;
ProvisioningStyle = Automatic;
};
4BB73E9D1B587A5100552FC2 = { 4BB73E9D1B587A5100552FC2 = {
CreatedOnToolsVersion = 7.0; CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0900; LastSwiftMigration = 0900;
@ -2596,6 +2785,7 @@
4BB73E9D1B587A5100552FC2 /* Clock Signal */, 4BB73E9D1B587A5100552FC2 /* Clock Signal */,
4BB73EB11B587A5100552FC2 /* Clock SignalTests */, 4BB73EB11B587A5100552FC2 /* Clock SignalTests */,
4BB73EBC1B587A5100552FC2 /* Clock SignalUITests */, 4BB73EBC1B587A5100552FC2 /* Clock SignalUITests */,
4B055A691FAE763F0060FFFF /* Clock Signal Kiosk */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@ -2913,6 +3103,123 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase 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 */ = { 4BB73E9A1B587A5100552FC2 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -3182,6 +3489,44 @@
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration 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 */ = { 4BB73EC41B587A5100552FC2 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -3294,6 +3639,10 @@
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements"; CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements";
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Frameworks",
);
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
@ -3324,6 +3673,10 @@
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements"; CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements";
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Frameworks",
);
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
@ -3408,6 +3761,15 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList 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" */ = { 4BB73E991B587A5100552FC2 /* Build configuration list for PBXProject "Clock Signal" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (

View File

@ -72,7 +72,7 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableUBSanitizer = "YES" disableMainThreadChecker = "YES"
language = "" language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"

View File

@ -16,6 +16,9 @@
#include "JoystickMachine.hpp" #include "JoystickMachine.hpp"
#include "KeyboardMachine.hpp" #include "KeyboardMachine.hpp"
#import "NSBundle+DataResource.h"
#import "NSData+StdVector.h"
@interface CSMachine() @interface CSMachine()
- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length; - (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
- (void)machineDidChangeClockRate; - (void)machineDidChangeClockRate;
@ -69,6 +72,23 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
_speakerDelegate.machineAccessLock = _delegateMachineAccessLock; _speakerDelegate.machineAccessLock = _delegateMachineAccessLock;
_machine->set_delegate(&_machineDelegate); _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; return self;
} }

View File

@ -10,10 +10,6 @@
#include "AmstradCPC.hpp" #include "AmstradCPC.hpp"
#import "CSMachine+Subclassing.h"
#import "NSData+StdVector.h"
#import "NSBundle+DataResource.h"
@implementation CSAmstradCPC { @implementation CSAmstradCPC {
std::unique_ptr<AmstradCPC::Machine> _amstradCPC; std::unique_ptr<AmstradCPC::Machine> _amstradCPC;
} }
@ -24,35 +20,10 @@
self = [super initWithMachine:machine]; self = [super initWithMachine:machine];
if(self) { if(self) {
_amstradCPC.reset(machine); _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; return self;
} }
- (NSData *)rom:(NSString *)name {
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/AmstradCPC"];
}
- (NSString *)userDefaultsPrefix { return @"amstradCPC"; } - (NSString *)userDefaultsPrefix { return @"amstradCPC"; }
@end @end

View File

@ -9,11 +9,7 @@
#import "CSElectron.h" #import "CSElectron.h"
#include "Electron.hpp" #include "Electron.hpp"
#include "StaticAnalyser.hpp"
#import "CSMachine+Subclassing.h"
#import "NSData+StdVector.h"
#import "NSBundle+DataResource.h"
@implementation CSElectron { @implementation CSElectron {
std::unique_ptr<Electron::Machine> _electron; std::unique_ptr<Electron::Machine> _electron;
@ -25,38 +21,12 @@
self = [super initWithMachine:machine]; self = [super initWithMachine:machine];
if(self) { if(self) {
_electron.reset(machine); _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; return self;
} }
- (NSData *)rom:(NSString *)name {
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Electron"];
}
#pragma mark - ROM setting #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"; } - (NSString *)userDefaultsPrefix { return @"electron"; }
#pragma mark - Options #pragma mark - Options

View File

@ -9,11 +9,6 @@
#import "CSOric.h" #import "CSOric.h"
#include "Oric.hpp" #include "Oric.hpp"
#include "StaticAnalyser.hpp"
#import "CSMachine+Subclassing.h"
#import "NSData+StdVector.h"
#import "NSBundle+DataResource.h"
@implementation CSOric { @implementation CSOric {
std::unique_ptr<Oric::Machine> _oric; std::unique_ptr<Oric::Machine> _oric;
@ -25,24 +20,10 @@
self = [super initWithMachine:machine]; self = [super initWithMachine:machine];
if(self) { if(self) {
_oric.reset(machine); _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; return self;
} }
- (NSData *)rom:(NSString *)name {
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Oric"];
}
#pragma mark - Options #pragma mark - Options
- (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {

View File

@ -11,11 +11,11 @@
typedef NS_ENUM(NSInteger, CSVic20Country) typedef NS_ENUM(NSInteger, CSVic20Country)
{ {
CSVic20CountryAmerican,
CSVic20CountryDanish, CSVic20CountryDanish,
CSVic20CountryEuropean, CSVic20CountryEuropean,
CSVic20CountryJapanese, CSVic20CountryJapanese,
CSVic20CountrySwedish, CSVic20CountrySwedish
CSVic20CountryAmerican
}; };
typedef NS_ENUM(NSInteger, CSVic20MemorySize) typedef NS_ENUM(NSInteger, CSVic20MemorySize)

View File

@ -9,12 +9,6 @@
#import "CSVic20.h" #import "CSVic20.h"
#include "Vic20.hpp" #include "Vic20.hpp"
#include "CommodoreTAP.hpp"
#include "G64.hpp"
#include "D64.hpp"
#import "CSmachine+Subclassing.h"
#import "NSBundle+DataResource.h"
using namespace Commodore::Vic20; using namespace Commodore::Vic20;
@ -31,41 +25,11 @@ using namespace Commodore::Vic20;
self = [super initWithMachine:machine]; self = [super initWithMachine:machine];
if(self) { if(self) {
_vic20.reset(machine); _vic20.reset(machine);
[self setDriveROM:[[NSBundle mainBundle] dataForResource:@"1540" withExtension:@"bin" subdirectory:@"ROMImages/Commodore1540"]];
[self setBASICROM:[self rom:@"basic"]];
[self setCountry:CSVic20CountryEuropean]; [self setCountry:CSVic20CountryEuropean];
} }
return self; 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 #pragma mark - Keyboard map
/*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { /*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@ -89,40 +53,17 @@ using namespace Commodore::Vic20;
- (void)setCountry:(CSVic20Country)country { - (void)setCountry:(CSVic20Country)country {
_country = country; _country = country;
NSString *charactersROM, *kernelROM;
Commodore::Vic20::Region region; Commodore::Vic20::Region region;
switch(country) { switch(country) {
case CSVic20CountryDanish: case CSVic20CountryDanish: region = Commodore::Vic20::Danish; break;
region = Commodore::Vic20::Region::PAL; case CSVic20CountryEuropean: region = Commodore::Vic20::European; break;
charactersROM = @"characters-danish"; case CSVic20CountryJapanese: region = Commodore::Vic20::Japanese; break;
kernelROM = @"kernel-danish"; case CSVic20CountrySwedish: region = Commodore::Vic20::Swedish; break;
break; case CSVic20CountryAmerican: region = Commodore::Vic20::American; 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;
} }
@synchronized(self) { @synchronized(self) {
_vic20->set_region(region); _vic20->set_region(region);
[self setCharactersROM:[self rom:charactersROM]];
[self setKernelROM:[self rom:kernelROM]];
} }
} }

View File

@ -10,10 +10,6 @@
#include "ZX8081.hpp" #include "ZX8081.hpp"
#import "CSMachine+Subclassing.h"
#import "NSData+StdVector.h"
#import "NSBundle+DataResource.h"
@implementation CSZX8081 { @implementation CSZX8081 {
std::unique_ptr<ZX8081::Machine> _zx8081; std::unique_ptr<ZX8081::Machine> _zx8081;
} }
@ -24,16 +20,10 @@
self = [super initWithMachine:machine]; self = [super initWithMachine:machine];
if(self) { if(self) {
_zx8081.reset(machine); _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; return self;
} }
- (NSData *)rom:(NSString *)name {
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/ZX8081"];
}
- (NSString *)userDefaultsPrefix { return @"zx8081"; } - (NSString *)userDefaultsPrefix { return @"zx8081"; }
#pragma mark - Options #pragma mark - Options

276
OSBindings/SDL/main.cpp Normal file
View 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;
}

View File

@ -109,7 +109,7 @@ class Speaker {
size_t buffer_in_progress_pointer_; size_t buffer_in_progress_pointer_;
size_t number_of_taps_, requested_number_of_taps_; size_t number_of_taps_, requested_number_of_taps_;
bool coefficients_are_dirty_; bool coefficients_are_dirty_;
Delegate *delegate_; Delegate *delegate_ = nullptr;
float input_cycles_per_second_, output_cycles_per_second_; float input_cycles_per_second_, output_cycles_per_second_;