1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-11-04 00:16:26 +00:00

Compare commits

...

11 Commits
master ... Tube

Author SHA1 Message Date
Thomas Harte
ee6ac3b4a9 Restore build. 2025-11-03 17:47:22 -05:00
Thomas Harte
c8130f9d6f Begin FIFO wiring. 2025-11-03 17:27:48 -05:00
Thomas Harte
8abd837c8b Ths host is now possibly awaiting tube activity. 2025-11-03 13:33:26 -05:00
Thomas Harte
02ad080bb8 Apply clock multiplier. 2025-11-03 13:20:51 -05:00
Thomas Harte
5887e3e580 Provide ROM to second processor. 2025-11-03 13:17:35 -05:00
Thomas Harte
1994b2dc9f Pay for a second processor, even if disconnected. 2025-11-03 13:12:19 -05:00
Thomas Harte
0017bd6d0f Pull clock divider inside the loop. 2025-11-03 12:49:30 -05:00
Thomas Harte
15f30995b1 Promote tube processor to template parameter. 2025-11-03 09:26:31 -05:00
Thomas Harte
37ca0e4f81 Introduce one-directional FIFO. 2025-11-02 23:18:56 -05:00
Thomas Harte
e400aa200c Slightly clean-up spacing. 2025-11-02 23:18:56 -05:00
Thomas Harte
e168298aa0 Add Tube boot ROM. 2025-11-02 23:18:56 -05:00
10 changed files with 317 additions and 27 deletions

View File

@@ -9,6 +9,7 @@
#pragma once #pragma once
#include "Analyser/Static/StaticAnalyser.hpp" #include "Analyser/Static/StaticAnalyser.hpp"
#include "Reflection/Enum.hpp"
#include "Reflection/Struct.hpp" #include "Reflection/Struct.hpp"
#include <string> #include <string>
@@ -44,6 +45,9 @@ struct BBCMicroTarget: public ::Analyser::Static::Target, public Reflection::Str
bool has_adfs = false; bool has_adfs = false;
bool has_sideways_ram = true; bool has_sideways_ram = true;
ReflectableEnum(TubeProcessor, None, MOS6502);
TubeProcessor tube_processor = TubeProcessor::None;
BBCMicroTarget() : Analyser::Static::Target(Machine::BBCMicro) {} BBCMicroTarget() : Analyser::Static::Target(Machine::BBCMicro) {}
private: private:
@@ -52,6 +56,8 @@ private:
DeclareField(has_1770dfs); DeclareField(has_1770dfs);
DeclareField(has_adfs); DeclareField(has_adfs);
DeclareField(has_sideways_ram); DeclareField(has_sideways_ram);
AnnounceEnum(TubeProcessor);
DeclareField(tube_processor);
} }
}; };

View File

@@ -27,6 +27,15 @@ struct Video {
sound_(sound), sound_(sound),
ram_(ram), ram_(ram),
crt_(Outputs::Display::InputDataType::Red4Green4Blue4) { crt_(Outputs::Display::InputDataType::Red4Green4Blue4) {
const auto cycles_per_line = static_cast<int>(24'000'000 / (312 * 50));
crt_.set_new_timing(
cycles_per_line,
312, /* Height of display. */
Outputs::CRT::PAL::ColourSpace,
Outputs::CRT::PAL::ColourCycleNumerator,
Outputs::CRT::PAL::ColourCycleDenominator,
Outputs::CRT::PAL::VerticalSyncLength,
Outputs::CRT::PAL::AlternatesPhase);
set_clock_divider(3); set_clock_divider(3);
crt_.set_fixed_framing(Outputs::Display::Rect(0.041f, 0.04f, 0.95f, 0.95f)); crt_.set_fixed_framing(Outputs::Display::Rect(0.041f, 0.04f, 0.95f, 0.95f));
crt_.set_display_type(Outputs::Display::DisplayType::RGB); crt_.set_display_type(Outputs::Display::DisplayType::RGB);
@@ -210,7 +219,7 @@ struct Video {
case Phase::StartInterlacedSync: tick_horizontal<Phase::StartInterlacedSync>(); break; case Phase::StartInterlacedSync: tick_horizontal<Phase::StartInterlacedSync>(); break;
case Phase::EndInterlacedSync: tick_horizontal<Phase::EndInterlacedSync>(); break; case Phase::EndInterlacedSync: tick_horizontal<Phase::EndInterlacedSync>(); break;
} }
++time_in_phase_; time_in_phase_ += clock_divider_;
} }
/// @returns @c true if a vertical retrace interrupt has been signalled since the last call to @c interrupt(); @c false otherwise. /// @returns @c true if a vertical retrace interrupt has been signalled since the last call to @c interrupt(); @c false otherwise.
@@ -476,15 +485,6 @@ private:
} }
clock_divider_ = divider; clock_divider_ = divider;
const auto cycles_per_line = static_cast<int>(24'000'000 / (divider * 312 * 50));
crt_.set_new_timing(
cycles_per_line,
312, /* Height of display. */
Outputs::CRT::PAL::ColourSpace,
Outputs::CRT::PAL::ColourCycleNumerator,
Outputs::CRT::PAL::ColourCycleDenominator,
Outputs::CRT::PAL::VerticalSyncLength,
Outputs::CRT::PAL::AlternatesPhase);
clock_rate_observer_.update_clock_rates(); clock_rate_observer_.update_clock_rates();
} }

View File

@@ -14,9 +14,11 @@
#include "Machines/Utility/MemoryFuzzer.hpp" #include "Machines/Utility/MemoryFuzzer.hpp"
#include "Machines/Utility/Typer.hpp" #include "Machines/Utility/Typer.hpp"
#include "Processors/6502/6502.hpp"
#include "Processors/6502Mk2/6502Mk2.hpp" #include "Processors/6502Mk2/6502Mk2.hpp"
#include "Machines/Acorn/Tube/ULA.hpp"
#include "Machines/Acorn/Tube/Tube6502.hpp"
#include "Components/6522/6522.hpp" #include "Components/6522/6522.hpp"
#include "Components/6845/CRTC6845.hpp" #include "Components/6845/CRTC6845.hpp"
#include "Components/6850/6850.hpp" #include "Components/6850/6850.hpp"
@@ -46,6 +48,7 @@ namespace BBCMicro {
namespace { namespace {
using Logger = Log::Logger<Log::Source::BBCMicro>; using Logger = Log::Logger<Log::Source::BBCMicro>;
using TubeProcessor = Analyser::Static::Acorn::BBCMicroTarget::TubeProcessor;
/*! /*!
Provides an analogue joystick with a single fire button. Provides an analogue joystick with a single fire button.
@@ -671,7 +674,7 @@ using CRTC = Motorola::CRTC::CRTC6845<
Motorola::CRTC::CursorType::Native>; Motorola::CRTC::CursorType::Native>;
} }
template <bool has_1770> template <TubeProcessor tube_processor, bool has_1770>
class ConcreteMachine: class ConcreteMachine:
public Activity::Source, public Activity::Source,
public Configurable::Device, public Configurable::Device,
@@ -700,7 +703,8 @@ public:
crtc_bus_handler_(ram_.data(), system_via_), crtc_bus_handler_(ram_.data(), system_via_),
crtc_(crtc_bus_handler_), crtc_(crtc_bus_handler_),
acia_(HalfCycles(2'000'000)), // TODO: look up real ACIA clock rate. acia_(HalfCycles(2'000'000)), // TODO: look up real ACIA clock rate.
adc_(HalfCycles(2'000'000)) adc_(HalfCycles(2'000'000)),
tube_ula_(*this, tube6502_)
{ {
set_clock_rate(2'000'000); set_clock_rate(2'000'000);
@@ -724,6 +728,13 @@ public:
request = request && Request(Name::BBCMicroADFS130); request = request && Request(Name::BBCMicroADFS130);
} }
switch(tube_processor) {
default: break;
case TubeProcessor::MOS6502:
request = request && Request(Name::BBCMicroTube110);
break;
}
auto roms = rom_fetcher(request); auto roms = rom_fetcher(request);
if(!request.validate(roms)) { if(!request.validate(roms)) {
throw ROMMachine::Error::MissingROMs; throw ROMMachine::Error::MissingROMs;
@@ -744,6 +755,14 @@ public:
install_sideways(fs_slot--, roms.find(Name::BBCMicroADFS130)->second, false); install_sideways(fs_slot--, roms.find(Name::BBCMicroADFS130)->second, false);
} }
// Throw the tube ROM to its target.
switch(tube_processor) {
default: break;
case TubeProcessor::MOS6502:
tube6502_.set_rom(roms.find(Name::BBCMicroTube110)->second);
break;
}
// Install the ADT ROM if available, but don't error if it's missing. It's very optional. // Install the ADT ROM if available, but don't error if it's missing. It's very optional.
if(target.has_1770dfs || target.has_adfs) { if(target.has_1770dfs || target.has_adfs) {
const auto adt_rom = rom_fetcher(Request(Name::BBCMicroAdvancedDiscToolkit140)); const auto adt_rom = rom_fetcher(Request(Name::BBCMicroAdvancedDiscToolkit140));
@@ -831,11 +850,14 @@ public:
} }
adc_.run_for(duration); adc_.run_for(duration);
if constexpr (has_1770) { if constexpr (has_1770) {
// The WD1770 is nominally clocked at 8Mhz. // The WD1770 is nominally clocked at 8Mhz.
wd1770_.run_for(duration * 4); wd1770_.run_for(duration * 4);
} }
if constexpr (tube_processor == TubeProcessor::MOS6502) {
tube6502_.run_for(duration);
}
// //
// Questionably-clocked devices. // Questionably-clocked devices.
@@ -893,12 +915,19 @@ public:
break; break;
} }
} }
} else if(address == 0xfee0) { } else if(address >= 0xfee0 && address < 0xfee8) {
if(tube_processor == TubeProcessor::None) {
if constexpr (is_read(operation)) { if constexpr (is_read(operation)) {
Logger::info().append("Read tube status: 0"); value = address == 0xfee0 ? 0xfe : 0xff;
value = 0; }
} else { } else {
Logger::info().append("Wrote tube: %02x", value); if constexpr (is_read(operation)) {
Logger::info().append("Read tube status %04x: %02x", +address, tube_ula_.status());
value = tube_ula_.status();
} else {
Logger::info().append("Wrote tube %04x: %02x", +address, value);
tube_ula_.set_status(value);
}
} }
} else if(address >= 0xfe08 && address < 0xfe10) { } else if(address >= 0xfe08 && address < 0xfe10) {
if constexpr (is_read(operation)) { if constexpr (is_read(operation)) {
@@ -943,6 +972,7 @@ public:
return duration; return duration;
} }
// //
// ROM or RAM access. // ROM or RAM access.
// //
@@ -1136,7 +1166,11 @@ private:
void update_irq_line() { void update_irq_line() {
m6502_.template set<CPU::MOS6502Mk2::Line::IRQ>( m6502_.template set<CPU::MOS6502Mk2::Line::IRQ>(
user_via_.get_interrupt_line() || user_via_.get_interrupt_line() ||
system_via_.get_interrupt_line() system_via_.get_interrupt_line() ||
(
tube_processor != TubeProcessor::None &&
tube_ula_.has_host_irq()
)
); );
} }
@@ -1175,21 +1209,44 @@ private:
const auto options = dynamic_cast<Options *>(str.get()); const auto options = dynamic_cast<Options *>(str.get());
crtc_bus_handler_.set_dynamic_framing(options->dynamic_crop); crtc_bus_handler_.set_dynamic_framing(options->dynamic_crop);
} }
// MARK: - Tube.
// TODO: use templated coprocessor type, if any, optionally to include this storage.
Acorn::Tube::Tube6502 tube6502_;
Acorn::Tube::ULA<ConcreteMachine, Acorn::Tube::Tube6502> tube_ula_;
public:
void set_tube_irq() {
update_irq_line();
}
}; };
} }
using namespace BBCMicro; using namespace BBCMicro;
namespace {
using Target = Analyser::Static::Acorn::BBCMicroTarget;
template <Target::TubeProcessor processor>
std::unique_ptr<Machine> machine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) {
if(target.has_1770dfs || target.has_adfs) {
return std::make_unique<BBCMicro::ConcreteMachine<processor, true>>(target, rom_fetcher);
} else {
return std::make_unique<BBCMicro::ConcreteMachine<processor, false>>(target, rom_fetcher);
}
}
}
std::unique_ptr<Machine> Machine::BBCMicro( std::unique_ptr<Machine> Machine::BBCMicro(
const Analyser::Static::Target *target, const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher const ROMMachine::ROMFetcher &rom_fetcher
) { ) {
using Target = Analyser::Static::Acorn::BBCMicroTarget;
const Target *const acorn_target = dynamic_cast<const Target *>(target); const Target *const acorn_target = dynamic_cast<const Target *>(target);
if(acorn_target->has_1770dfs || acorn_target->has_adfs) { switch(acorn_target->tube_processor) {
return std::make_unique<BBCMicro::ConcreteMachine<true>>(*acorn_target, rom_fetcher); case TubeProcessor::None: /* return machine<TubeProcessor::None>(*acorn_target, rom_fetcher); */
} else { case TubeProcessor::MOS6502: return machine<TubeProcessor::MOS6502>(*acorn_target, rom_fetcher);
return std::make_unique<BBCMicro::ConcreteMachine<false>>(*acorn_target, rom_fetcher); default: return nullptr;
} }
} }

View File

@@ -0,0 +1,48 @@
//
// Header.hpp
// Clock Signal
//
// Created by Thomas Harte on 30/10/2025.
// Copyright © 2025 Thomas Harte. All rights reserved.
//
#pragma once
#include <array>
#include <cstdint>
namespace Acorn::Tube {
template <size_t length, typename ULAT>
struct FIFO {
FIFO(ULAT &ula, const uint8_t mask = 0x00) : ula_(ula), mask_(mask) {}
uint8_t status() const {
return
((read_ != write_) ? 0x80 : 0x00) |
((size_t(write_ - read_) < length) ? 0x40 : 0x00);
}
void write(const uint8_t value) {
if(write_ - read_ == length) return;
if(write_ == read_) {
ula_.fifo_has_data(mask_);
}
buffer_[write_++] = value;
}
uint8_t read() {
const uint8_t result = buffer_[read_ % length];
if(write_ != read_) ++read_;
return result;
}
private:
ULAT &ula_;
uint8_t mask_;
std::array<uint8_t, length> buffer_;
uint32_t read_ = 0;
uint32_t write_ = 0;
};
}

View File

@@ -0,0 +1,68 @@
//
// Tube6502.hpp
// Clock Signal
//
// Created by Thomas Harte on 03/11/2025.
// Copyright © 2025 Thomas Harte. All rights reserved.
//
#pragma once
#include "Processors/6502Mk2/6502Mk2.hpp"
#include <algorithm>
namespace Acorn::Tube {
struct Tube6502 {
public:
Tube6502() : m6502_(*this) {}
// By convention, these are cycles relative to the host's 2Mhz bus.
// Multiply by 3/2 to turn that into the tube 6502's usual 3Mhz bus.
void run_for(const Cycles cycles) {
cycles_modulo_ += cycles * 3;
m6502_.run_for(cycles_modulo_.divide(Cycles(2)));
}
template <CPU::MOS6502Mk2::BusOperation operation, typename AddressT>
Cycles perform(const AddressT address, CPU::MOS6502Mk2::data_t<operation> value) {
if(address >= 0xfef8 && address < 0xff00) {
// printf("TODO: second processor FIFO access @ %04x\n", +address);
}
if constexpr (is_read(operation)) {
value = ram_[address];
} else {
ram_[address] = value;
}
return Cycles(1);
}
void set_rom(const std::vector<uint8_t> &source) {
// TODO: verify the ROM is 2kb.
// TODO: determine whethe rthis really is ROM, or is ROM that should have copied itself to RAM, or is something else.
std::copy(source.begin(), source.end(), &ram_[65536 - 2048]);
}
void set_tube_irq() {
m6502_.set<CPU::MOS6502Mk2::Line::IRQ>(true);
}
void set_tube_nmi() {
m6502_.set<CPU::MOS6502Mk2::Line::NMI>(true);
}
private:
uint8_t ram_[65536];
Cycles cycles_modulo_;
struct M6502Traits {
static constexpr auto uses_ready_line = false;
static constexpr auto pause_precision = CPU::MOS6502Mk2::PausePrecision::AnyCycle;
using BusHandlerT = Tube6502;
};
CPU::MOS6502Mk2::Processor<CPU::MOS6502Mk2::Model::M6502, M6502Traits> m6502_;
};
};

View File

@@ -0,0 +1,84 @@
//
// ULA.hpp
// Clock Signal
//
// Created by Thomas Harte on 03/11/2025.
// Copyright © 2025 Thomas Harte. All rights reserved.
//
#pragma once
#include "FIFO.hpp"
namespace Acorn::Tube {
/*!
The non-FIFO section of the tube ULA.
*/
template <typename HostT, typename ParasiteT>
struct ULA {
ULA(HostT &host, ParasiteT &parasite) :
host_(host),
parasite_(parasite),
to_parasite1_(*this, 0x02),
to_parasite2_(*this),
to_parasite3_(*this, 0x08),
to_parasite4_(*this, 0x04),
to_host1_(*this),
to_host2_(*this),
to_host3_(*this),
to_host4_(*this, 0x01)
{}
uint8_t status() const {
return flags_;
}
void set_status(const uint8_t value) {
const uint8_t bits = value & 0x3f;
if(value & 0x80) {
flags_ |= bits;
} else {
flags_ &= ~bits;
}
}
void fifo_has_data(const uint8_t mask) {
if(!(flags_ & mask)) return;
switch(mask) {
default: __builtin_unreachable();
case 0x01:
host_.set_tube_irq();
break;
case 0x02:
case 0x04:
parasite_.set_tube_irq();
break;
case 0x08:
parasite_.set_tube_nmi();
break;
}
}
bool has_host_irq() const {
return (flags_ & 0x01) && (to_host1_.status() & 0x80);
}
private:
HostT &host_;
ParasiteT &parasite_;
uint8_t flags_ = 0x3f;
FIFO<1, ULA> to_parasite1_;
FIFO<1, ULA> to_parasite2_;
FIFO<2, ULA> to_parasite3_;
FIFO<1, ULA> to_parasite4_;
FIFO<24, ULA> to_host1_;
FIFO<1, ULA> to_host2_;
FIFO<2, ULA> to_host3_;
FIFO<1, ULA> to_host4_;
};
}

View File

@@ -453,6 +453,14 @@ const std::vector<Description> &Description::all_roms() {
16_kb, 16_kb,
0x8314fed0u 0x8314fed0u
}, },
{
BBCMicroTube110,
"BBCMicro",
"the Tube 1.10 Boot ROM",
"TUBE110.rom",
2_kb,
0x9ec2dbd0u
},
// //
// ColecoVision. // ColecoVision.

View File

@@ -85,6 +85,7 @@ enum Name {
BBCMicroDFS226, BBCMicroDFS226,
BBCMicroADFS130, BBCMicroADFS130,
BBCMicroAdvancedDiscToolkit140, BBCMicroAdvancedDiscToolkit140,
BBCMicroTube110,
// ColecoVision. // ColecoVision.
ColecoVisionBIOS, ColecoVisionBIOS,

View File

@@ -1561,6 +1561,8 @@
4B3FCC3F201EC24200960631 /* MultiMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiMachine.cpp; sourceTree = "<group>"; }; 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiMachine.cpp; sourceTree = "<group>"; };
4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPM.cpp; path = Parsers/CPM.cpp; sourceTree = "<group>"; }; 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPM.cpp; path = Parsers/CPM.cpp; sourceTree = "<group>"; };
4B3FE75D1F3CF68B00448EE4 /* CPM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPM.hpp; path = Parsers/CPM.hpp; sourceTree = "<group>"; }; 4B3FE75D1F3CF68B00448EE4 /* CPM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPM.hpp; path = Parsers/CPM.hpp; sourceTree = "<group>"; };
4B4195F42EB8F061001C966D /* ULA.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ULA.hpp; sourceTree = "<group>"; };
4B4195F52EB92630001C966D /* Tube6502.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Tube6502.hpp; sourceTree = "<group>"; };
4B43983829620FB1006B0BFC /* 9918.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = 9918.cpp; sourceTree = "<group>"; }; 4B43983829620FB1006B0BFC /* 9918.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = 9918.cpp; sourceTree = "<group>"; };
4B43983C29621024006B0BFC /* ClockConverter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ClockConverter.hpp; sourceTree = "<group>"; }; 4B43983C29621024006B0BFC /* ClockConverter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ClockConverter.hpp; sourceTree = "<group>"; };
4B43983E29628538006B0BFC /* Fetch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Fetch.hpp; sourceTree = "<group>"; }; 4B43983E29628538006B0BFC /* Fetch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Fetch.hpp; sourceTree = "<group>"; };
@@ -1612,6 +1614,7 @@
4B49F0A823346F7A0045E6A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MacintoshOptions.xib"; sourceTree = SOURCE_ROOT; }; 4B49F0A823346F7A0045E6A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MacintoshOptions.xib"; sourceTree = SOURCE_ROOT; };
4B4A75BC2EB2C55100EA398F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CompositeDynamicCropOptions.xib; sourceTree = "<group>"; }; 4B4A75BC2EB2C55100EA398F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CompositeDynamicCropOptions.xib; sourceTree = "<group>"; };
4B4A75BF2EB399D700EA398F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/DynamicCropOptions.xib; sourceTree = "<group>"; }; 4B4A75BF2EB399D700EA398F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/DynamicCropOptions.xib; sourceTree = "<group>"; };
4B4A75C22EB43F1C00EA398F /* FIFO.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FIFO.hpp; sourceTree = "<group>"; };
4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AY38910.cpp; sourceTree = "<group>"; }; 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AY38910.cpp; sourceTree = "<group>"; };
4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AY38910.hpp; sourceTree = "<group>"; }; 4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AY38910.hpp; sourceTree = "<group>"; };
4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KonamiSCC.cpp; sourceTree = "<group>"; }; 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KonamiSCC.cpp; sourceTree = "<group>"; };
@@ -2547,10 +2550,10 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
4B0150262D71286B00F270C7 /* SDL2.framework in Frameworks */,
4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */, 4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */,
4BB8617224E22F5A00A00E03 /* Accelerate.framework in Frameworks */, 4BB8617224E22F5A00A00E03 /* Accelerate.framework in Frameworks */,
4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */, 4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */,
4B0150262D71286B00F270C7 /* SDL2.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -3354,6 +3357,16 @@
path = uPD7002; path = uPD7002;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
4B4A75C32EB43F1C00EA398F /* Tube */ = {
isa = PBXGroup;
children = (
4B4A75C22EB43F1C00EA398F /* FIFO.hpp */,
4B4195F42EB8F061001C966D /* ULA.hpp */,
4B4195F52EB92630001C966D /* Tube6502.hpp */,
);
path = Tube;
sourceTree = "<group>";
};
4B4A762D1DB1A35C007AAE2E /* AY38910 */ = { 4B4A762D1DB1A35C007AAE2E /* AY38910 */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -4673,6 +4686,7 @@
4BB505682B962DDF0031C43C /* Acorn */ = { 4BB505682B962DDF0031C43C /* Acorn */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B4A75C32EB43F1C00EA398F /* Tube */,
4BB505692B962DDF0031C43C /* Archimedes */, 4BB505692B962DDF0031C43C /* Archimedes */,
4B710C8C2E77A3B20056BDF4 /* BBCMicro */, 4B710C8C2E77A3B20056BDF4 /* BBCMicro */,
4BB5056A2B962DDF0031C43C /* Electron */, 4BB5056A2B962DDF0031C43C /* Electron */,

View File

@@ -57,9 +57,13 @@
isEnabled = "NO"> isEnabled = "NO">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--new=archimedes" argument = "&quot;/Users/thomasharte/Library/Mobile\ Documents/com\~apple\~CloudDocs/Soft/Archimedes/Lemmings.adf&quot;"
isEnabled = "YES"> isEnabled = "YES">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument
argument = "--new=archimedes"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "/Users/thomasharte/Downloads/Program/Program.prg" argument = "/Users/thomasharte/Downloads/Program/Program.prg"
isEnabled = "NO"> isEnabled = "NO">