mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 03:32:01 +00:00
Attempts to bring audio to the Apple II.
By factoring the audio toggle out from the MSX.
This commit is contained in:
parent
a07c99d778
commit
f22c23cb4c
38
Components/AudioToggle/AudioToggle.cpp
Normal file
38
Components/AudioToggle/AudioToggle.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// AudioToggle.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 17/04/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AudioToggle.hpp"
|
||||||
|
|
||||||
|
using namespace Audio;
|
||||||
|
|
||||||
|
Audio::Toggle::Toggle(Concurrency::DeferringAsyncTaskQueue &audio_queue) :
|
||||||
|
audio_queue_(audio_queue) {}
|
||||||
|
|
||||||
|
void Toggle::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||||
|
for(std::size_t sample = 0; sample < number_of_samples; ++sample) {
|
||||||
|
target[sample] = level_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toggle::set_sample_volume_range(std::int16_t range) {
|
||||||
|
volume_ = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toggle::skip_samples(const std::size_t number_of_samples) {}
|
||||||
|
|
||||||
|
void Toggle::set_output(bool enabled) {
|
||||||
|
if(is_enabled_ == enabled) return;
|
||||||
|
is_enabled_ = enabled;
|
||||||
|
audio_queue_.defer([=] {
|
||||||
|
level_ = enabled ? volume_ : 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Toggle::get_output() {
|
||||||
|
return is_enabled_;
|
||||||
|
}
|
39
Components/AudioToggle/AudioToggle.hpp
Normal file
39
Components/AudioToggle/AudioToggle.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// AudioToggle.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 17/04/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AudioToggle_hpp
|
||||||
|
#define AudioToggle_hpp
|
||||||
|
|
||||||
|
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||||
|
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||||
|
|
||||||
|
namespace Audio {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Provides a sample source that can programmatically be set to one of two values.
|
||||||
|
*/
|
||||||
|
class Toggle: public Outputs::Speaker::SampleSource {
|
||||||
|
public:
|
||||||
|
Toggle(Concurrency::DeferringAsyncTaskQueue &audio_queue);
|
||||||
|
|
||||||
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||||
|
void set_sample_volume_range(std::int16_t range);
|
||||||
|
void skip_samples(const std::size_t number_of_samples);
|
||||||
|
|
||||||
|
void set_output(bool enabled);
|
||||||
|
bool get_output();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_enabled_ = false;
|
||||||
|
int16_t level_ = 0, volume_ = 0;
|
||||||
|
Concurrency::DeferringAsyncTaskQueue &audio_queue_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AudioToggle_hpp */
|
@ -13,6 +13,9 @@
|
|||||||
#include "../Utility/MemoryFuzzer.hpp"
|
#include "../Utility/MemoryFuzzer.hpp"
|
||||||
|
|
||||||
#include "../../Processors/6502/6502.hpp"
|
#include "../../Processors/6502/6502.hpp"
|
||||||
|
#include "../../Components/AudioToggle/AudioToggle.hpp"
|
||||||
|
|
||||||
|
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||||
|
|
||||||
#include "Video.hpp"
|
#include "Video.hpp"
|
||||||
|
|
||||||
@ -48,6 +51,9 @@ class ConcreteMachine:
|
|||||||
void update_video() {
|
void update_video() {
|
||||||
video_->run_for(cycles_since_video_update_.flush());
|
video_->run_for(cycles_since_video_update_.flush());
|
||||||
}
|
}
|
||||||
|
void update_audio() {
|
||||||
|
speaker_.run_for(cycles_since_audio_update_.divide(Cycles(16)));
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ram_[48*1024];
|
uint8_t ram_[48*1024];
|
||||||
std::vector<uint8_t> rom_;
|
std::vector<uint8_t> rom_;
|
||||||
@ -55,11 +61,19 @@ class ConcreteMachine:
|
|||||||
uint16_t rom_start_address_;
|
uint16_t rom_start_address_;
|
||||||
uint8_t keyboard_input_ = 0x00;
|
uint8_t keyboard_input_ = 0x00;
|
||||||
|
|
||||||
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
|
Audio::Toggle audio_toggle_;
|
||||||
|
Outputs::Speaker::LowpassSpeaker<Audio::Toggle> speaker_;
|
||||||
|
Cycles cycles_since_audio_update_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcreteMachine():
|
ConcreteMachine():
|
||||||
m6502_(*this),
|
m6502_(*this),
|
||||||
video_bus_handler_(ram_) {
|
video_bus_handler_(ram_),
|
||||||
|
audio_toggle_(audio_queue_),
|
||||||
|
speaker_(audio_toggle_) {
|
||||||
set_clock_rate(1022727);
|
set_clock_rate(1022727);
|
||||||
|
speaker_.set_input_rate(7159089.0f / 16.0f);
|
||||||
Memory::Fuzz(ram_, sizeof(ram_));
|
Memory::Fuzz(ram_, sizeof(ram_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,11 +91,12 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Outputs::Speaker::Speaker *get_speaker() override {
|
Outputs::Speaker::Speaker *get_speaker() override {
|
||||||
return nullptr;
|
return &speaker_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
||||||
++ cycles_since_video_update_;
|
++ cycles_since_video_update_;
|
||||||
|
cycles_since_audio_update_ += Cycles(7);
|
||||||
|
|
||||||
switch(address) {
|
switch(address) {
|
||||||
default:
|
default:
|
||||||
@ -109,7 +124,6 @@ class ConcreteMachine:
|
|||||||
update_video();
|
update_video();
|
||||||
}
|
}
|
||||||
ram_[address] = *value;
|
ram_[address] = *value;
|
||||||
// printf("%04x <- %02x\n", address, *value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -126,16 +140,22 @@ class ConcreteMachine:
|
|||||||
case 0xc010:
|
case 0xc010:
|
||||||
keyboard_input_ &= 0x7f;
|
keyboard_input_ &= 0x7f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xc030:
|
||||||
|
update_audio();
|
||||||
|
audio_toggle_.set_output(!audio_toggle_.get_output());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Apple II has a slightly weird timing pattern: every 65th CPU cycle is stretched
|
// The Apple II has a slightly weird timing pattern: every 65th CPU cycle is stretched
|
||||||
// by an extra 1/7th. That's because one cycle lasts 3.5 NTSC colour clocks, so after
|
// by an extra 1/7th. That's because one cycle lasts 3.5 NTSC colour clocks, so after
|
||||||
// 65 cycles a full line of 227.5 colour clocks have passed. But the high-rate binary
|
// 65 cycles a full line of 227.5 colour clocks have passed. But the high-rate binary
|
||||||
// signal approximation that produces colour needs to be in phase, so a stretch of exactly
|
// signal approximation that produces colour needs to be in phase, so a stretch of exactly
|
||||||
// 0.5 further colour cycles is added.
|
// 0.5 further colour cycles is added. The video class handles that implicitly, but it
|
||||||
|
// needs to be accumulated here for the audio.
|
||||||
cycles_into_current_line_ = (cycles_into_current_line_ + 1) % 65;
|
cycles_into_current_line_ = (cycles_into_current_line_ + 1) % 65;
|
||||||
if(!cycles_into_current_line_) {
|
if(!cycles_into_current_line_) {
|
||||||
// Do something. Do something else.
|
++ cycles_since_audio_update_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Cycles(1);
|
return Cycles(1);
|
||||||
@ -143,6 +163,8 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
update_video();
|
update_video();
|
||||||
|
update_audio();
|
||||||
|
audio_queue_.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
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 {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "../../Components/1770/1770.hpp"
|
#include "../../Components/1770/1770.hpp"
|
||||||
#include "../../Components/9918/9918.hpp"
|
#include "../../Components/9918/9918.hpp"
|
||||||
#include "../../Components/8255/i8255.hpp"
|
#include "../../Components/8255/i8255.hpp"
|
||||||
|
#include "../../Components/AudioToggle/AudioToggle.hpp"
|
||||||
#include "../../Components/AY38910/AY38910.hpp"
|
#include "../../Components/AY38910/AY38910.hpp"
|
||||||
#include "../../Components/KonamiSCC/KonamiSCC.hpp"
|
#include "../../Components/KonamiSCC/KonamiSCC.hpp"
|
||||||
|
|
||||||
@ -50,44 +51,6 @@ std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Provides a sample source that can programmatically be set to one of two values.
|
|
||||||
*/
|
|
||||||
class AudioToggle: public Outputs::Speaker::SampleSource {
|
|
||||||
public:
|
|
||||||
AudioToggle(Concurrency::DeferringAsyncTaskQueue &audio_queue) :
|
|
||||||
audio_queue_(audio_queue) {}
|
|
||||||
|
|
||||||
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
|
||||||
for(std::size_t sample = 0; sample < number_of_samples; ++sample) {
|
|
||||||
target[sample] = level_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_sample_volume_range(std::int16_t range) {
|
|
||||||
volume_ = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
void skip_samples(const std::size_t number_of_samples) {}
|
|
||||||
|
|
||||||
void set_output(bool enabled) {
|
|
||||||
if(is_enabled_ == enabled) return;
|
|
||||||
is_enabled_ = enabled;
|
|
||||||
audio_queue_.defer([=] {
|
|
||||||
level_ = enabled ? volume_ : 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get_output() {
|
|
||||||
return is_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool is_enabled_ = false;
|
|
||||||
int16_t level_ = 0, volume_ = 0;
|
|
||||||
Concurrency::DeferringAsyncTaskQueue &audio_queue_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AYPortHandler: public GI::AY38910::PortHandler {
|
class AYPortHandler: public GI::AY38910::PortHandler {
|
||||||
public:
|
public:
|
||||||
AYPortHandler(Storage::Tape::BinaryTapePlayer &tape_player) : tape_player_(tape_player) {}
|
AYPortHandler(Storage::Tape::BinaryTapePlayer &tape_player) : tape_player_(tape_player) {}
|
||||||
@ -600,7 +563,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
class i8255PortHandler: public Intel::i8255::PortHandler {
|
class i8255PortHandler: public Intel::i8255::PortHandler {
|
||||||
public:
|
public:
|
||||||
i8255PortHandler(ConcreteMachine &machine, AudioToggle &audio_toggle, Storage::Tape::BinaryTapePlayer &tape_player) :
|
i8255PortHandler(ConcreteMachine &machine, Audio::Toggle &audio_toggle, Storage::Tape::BinaryTapePlayer &tape_player) :
|
||||||
machine_(machine), audio_toggle_(audio_toggle), tape_player_(tape_player) {}
|
machine_(machine), audio_toggle_(audio_toggle), tape_player_(tape_player) {}
|
||||||
|
|
||||||
void set_value(int port, uint8_t value) {
|
void set_value(int port, uint8_t value) {
|
||||||
@ -637,7 +600,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ConcreteMachine &machine_;
|
ConcreteMachine &machine_;
|
||||||
AudioToggle &audio_toggle_;
|
Audio::Toggle &audio_toggle_;
|
||||||
Storage::Tape::BinaryTapePlayer &tape_player_;
|
Storage::Tape::BinaryTapePlayer &tape_player_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -647,10 +610,10 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
GI::AY38910::AY38910 ay_;
|
GI::AY38910::AY38910 ay_;
|
||||||
AudioToggle audio_toggle_;
|
Audio::Toggle audio_toggle_;
|
||||||
Konami::SCC scc_;
|
Konami::SCC scc_;
|
||||||
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC> mixer_;
|
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, Audio::Toggle, Konami::SCC> mixer_;
|
||||||
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC>> speaker_;
|
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, Audio::Toggle, Konami::SCC>> speaker_;
|
||||||
|
|
||||||
Storage::Tape::BinaryTapePlayer tape_player_;
|
Storage::Tape::BinaryTapePlayer tape_player_;
|
||||||
bool tape_player_is_sleeping_ = false;
|
bool tape_player_is_sleeping_ = false;
|
||||||
|
@ -208,6 +208,8 @@
|
|||||||
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */; };
|
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */; };
|
||||||
4B58601E1F806AB200AEE2E3 /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */; };
|
4B58601E1F806AB200AEE2E3 /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */; };
|
||||||
4B59199C1DAC6C46005BB85C /* OricTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B59199A1DAC6C46005BB85C /* OricTAP.cpp */; };
|
4B59199C1DAC6C46005BB85C /* OricTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B59199A1DAC6C46005BB85C /* OricTAP.cpp */; };
|
||||||
|
4B595FAD2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */; };
|
||||||
|
4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */; };
|
||||||
4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADB81DE3151600AEC565 /* FileHolder.cpp */; };
|
4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADB81DE3151600AEC565 /* FileHolder.cpp */; };
|
||||||
4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; };
|
4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; };
|
||||||
4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */; };
|
4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */; };
|
||||||
@ -856,6 +858,8 @@
|
|||||||
4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MFMSectorDump.hpp; sourceTree = "<group>"; };
|
4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MFMSectorDump.hpp; sourceTree = "<group>"; };
|
||||||
4B59199A1DAC6C46005BB85C /* OricTAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OricTAP.cpp; sourceTree = "<group>"; };
|
4B59199A1DAC6C46005BB85C /* OricTAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OricTAP.cpp; sourceTree = "<group>"; };
|
||||||
4B59199B1DAC6C46005BB85C /* OricTAP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OricTAP.hpp; sourceTree = "<group>"; };
|
4B59199B1DAC6C46005BB85C /* OricTAP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OricTAP.hpp; sourceTree = "<group>"; };
|
||||||
|
4B595FAB2086DFBA0083CAA8 /* AudioToggle.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AudioToggle.hpp; sourceTree = "<group>"; };
|
||||||
|
4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioToggle.cpp; sourceTree = "<group>"; };
|
||||||
4B5FADB81DE3151600AEC565 /* FileHolder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileHolder.cpp; sourceTree = "<group>"; };
|
4B5FADB81DE3151600AEC565 /* FileHolder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileHolder.cpp; sourceTree = "<group>"; };
|
||||||
4B5FADB91DE3151600AEC565 /* FileHolder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileHolder.hpp; sourceTree = "<group>"; };
|
4B5FADB91DE3151600AEC565 /* FileHolder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileHolder.hpp; sourceTree = "<group>"; };
|
||||||
4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Microdisc.cpp; path = Oric/Microdisc.cpp; sourceTree = "<group>"; };
|
4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Microdisc.cpp; path = Oric/Microdisc.cpp; sourceTree = "<group>"; };
|
||||||
@ -1929,6 +1933,15 @@
|
|||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4B595FAA2086DFBA0083CAA8 /* AudioToggle */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4B595FAB2086DFBA0083CAA8 /* AudioToggle.hpp */,
|
||||||
|
4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */,
|
||||||
|
);
|
||||||
|
path = AudioToggle;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4B643F3B1D77AD6D00D431D6 /* StaticAnalyser */ = {
|
4B643F3B1D77AD6D00D431D6 /* StaticAnalyser */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -2837,6 +2850,7 @@
|
|||||||
4BC9DF4A1D04691600F44158 /* Components */ = {
|
4BC9DF4A1D04691600F44158 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4B595FAA2086DFBA0083CAA8 /* AudioToggle */,
|
||||||
4BD468F81D8DF4290084958B /* 1770 */,
|
4BD468F81D8DF4290084958B /* 1770 */,
|
||||||
4BC9DF4B1D04691600F44158 /* 6522 */,
|
4BC9DF4B1D04691600F44158 /* 6522 */,
|
||||||
4B1E85791D174DEC001EF87D /* 6532 */,
|
4B1E85791D174DEC001EF87D /* 6532 */,
|
||||||
@ -3607,6 +3621,7 @@
|
|||||||
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */,
|
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */,
|
||||||
4BB0A65D2045009000FB3688 /* ColecoVision.cpp in Sources */,
|
4BB0A65D2045009000FB3688 /* ColecoVision.cpp in Sources */,
|
||||||
4BB0A65C2044FD3000FB3688 /* SN76489.cpp in Sources */,
|
4BB0A65C2044FD3000FB3688 /* SN76489.cpp in Sources */,
|
||||||
|
4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
|
||||||
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */,
|
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */,
|
||||||
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */,
|
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */,
|
||||||
4B89452D201967B4007DE474 /* Tape.cpp in Sources */,
|
4B89452D201967B4007DE474 /* Tape.cpp in Sources */,
|
||||||
@ -3652,6 +3667,7 @@
|
|||||||
4B07835A1FC11D10001D12BB /* Configurable.cpp in Sources */,
|
4B07835A1FC11D10001D12BB /* Configurable.cpp in Sources */,
|
||||||
4B8334951F5E25B60097E338 /* C1540.cpp in Sources */,
|
4B8334951F5E25B60097E338 /* C1540.cpp in Sources */,
|
||||||
4B89453C201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
4B89453C201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
||||||
|
4B595FAD2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
|
||||||
4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */,
|
4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */,
|
||||||
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
||||||
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */,
|
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */,
|
||||||
|
Loading…
Reference in New Issue
Block a user