From 654710251104be73660cd3f85596ccb208d832e0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 4 Sep 2017 20:58:00 -0400 Subject: [PATCH] Attempts better to hide C1540 implementation details from the reader. In this case not from the compiler, as it's desireable to keep `run_for` as a non-virtual call, and therefore everything else comes alone for the ride. --- Machines/Commodore/1540/C1540.hpp | 140 +--------------- .../1540/{ => Implementation}/C1540.cpp | 26 +-- .../1540/Implementation/C1540Base.hpp | 157 ++++++++++++++++++ .../Clock Signal.xcodeproj/project.pbxproj | 18 +- 4 files changed, 193 insertions(+), 148 deletions(-) rename Machines/Commodore/1540/{ => Implementation}/C1540.cpp (91%) create mode 100644 Machines/Commodore/1540/Implementation/C1540Base.hpp diff --git a/Machines/Commodore/1540/C1540.hpp b/Machines/Commodore/1540/C1540.hpp index 012c5ed67..4c3954672 100644 --- a/Machines/Commodore/1540/C1540.hpp +++ b/Machines/Commodore/1540/C1540.hpp @@ -9,124 +9,20 @@ #ifndef Commodore1540_hpp #define Commodore1540_hpp -#include "../../../Processors/6502/6502.hpp" -#include "../../../Components/6522/6522.hpp" - #include "../SerialBus.hpp" - #include "../../../Storage/Disk/Disk.hpp" -#include "../../../Storage/Disk/DiskController.hpp" +#include "Implementation/C1540Base.hpp" namespace Commodore { namespace C1540 { -/*! - An implementation of the serial-port VIA in a Commodore 1540 — the VIA that facilitates all - IEC bus communications. - - It is wired up such that Port B contains: - Bit 0: data input; 1 if the line is low, 0 if it is high; - Bit 1: data output; 1 if the line should be low, 0 if it should be high; - Bit 2: clock input; 1 if the line is low, 0 if it is high; - Bit 3: clock output; 1 if the line is low, 0 if it is high; - Bit 4: attention acknowledge output; exclusive ORd with the attention input and ORd onto the data output; - Bits 5/6: device select input; the 1540 will act as device 8 + [value of bits] - Bit 7: attention input; 1 if the line is low, 0 if it is high - - The attention input is also connected to CA1, similarly inverted — the CA1 wire will be high when the bus is low and vice versa. -*/ -class SerialPortVIA: public MOS::MOS6522::IRQDelegatePortHandler { - public: - SerialPortVIA(MOS::MOS6522::MOS6522 &via); - - uint8_t get_port_input(MOS::MOS6522::Port); - - void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t mask); - void set_serial_line_state(::Commodore::Serial::Line, bool); - - void set_serial_port(const std::shared_ptr<::Commodore::Serial::Port> &); - - private: - MOS::MOS6522::MOS6522 via_; - uint8_t port_b_; - std::weak_ptr<::Commodore::Serial::Port> serial_port_; - bool attention_acknowledge_level_, attention_level_input_, data_level_output_; - - void update_data_line(); -}; - -/*! - An implementation of the drive VIA in a Commodore 1540 — the VIA that is used to interface with the disk. - - It is wired up such that Port B contains: - Bits 0/1: head step direction - Bit 2: motor control - Bit 3: LED control (TODO) - Bit 4: write protect photocell status (TODO) - Bits 5/6: read/write density - Bit 7: 0 if sync marks are currently being detected, 1 otherwise. - - ... and Port A contains the byte most recently read from the disk or the byte next to write to the disk, depending on data direction. - - It is implied that CA2 might be used to set processor overflow, CA1 a strobe for data input, and one of the CBs being definitive on - whether the disk head is being told to read or write, but it's unclear and I've yet to investigate. So, TODO. -*/ -class DriveVIA: public MOS::MOS6522::IRQDelegatePortHandler { - public: - class Delegate { - public: - virtual void drive_via_did_step_head(void *driveVIA, int direction) = 0; - virtual void drive_via_did_set_data_density(void *driveVIA, int density) = 0; - }; - void set_delegate(Delegate *); - - DriveVIA(); - - uint8_t get_port_input(MOS::MOS6522::Port port); - - void set_sync_detected(bool); - void set_data_input(uint8_t); - bool get_should_set_overflow(); - bool get_motor_enabled(); - - void set_control_line_output(MOS::MOS6522::Port, MOS::MOS6522::Line, bool value); - - void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t direction_mask); - - private: - uint8_t port_b_, port_a_; - bool should_set_overflow_; - bool drive_motor_; - uint8_t previous_port_b_output_; - Delegate *delegate_; -}; - -/*! - An implementation of the C1540's serial port; this connects incoming line levels to the serial-port VIA. -*/ -class SerialPort : public ::Commodore::Serial::Port { - public: - void set_input(::Commodore::Serial::Line, ::Commodore::Serial::LineLevel); - void set_serial_port_via(const std::shared_ptr &); - - private: - std::weak_ptr serial_port_VIA_; -}; - /*! Provides an emulation of the C1540. */ -class Machine: - public CPU::MOS6502::BusHandler, - public MOS::MOS6522::IRQDelegatePortHandler::Delegate, - public DriveVIA::Delegate, - public Storage::Disk::Controller { - +class Machine: public MachineBase { public: - Machine(); - /*! - Sets the ROM image to use for this drive; it is assumed that the buffer provided will be at least 16 kb in size. + Sets the ROM image to use for this drive; it is asserted that the buffer provided is 16 kb in size. */ void set_rom(const std::vector &rom); @@ -135,35 +31,11 @@ class Machine: */ void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus); + /// Advances time. void run_for(const Cycles cycles); + + /// Inserts @c disk into the drive. void set_disk(std::shared_ptr disk); - - // to satisfy CPU::MOS6502::Processor - Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value); - - // to satisfy MOS::MOS6522::Delegate - virtual void mos6522_did_change_interrupt_status(void *mos6522); - - // to satisfy DriveVIA::Delegate - void drive_via_did_step_head(void *driveVIA, int direction); - void drive_via_did_set_data_density(void *driveVIA, int density); - - private: - CPU::MOS6502::Processor m6502_; - - uint8_t ram_[0x800]; - uint8_t rom_[0x4000]; - - std::shared_ptr serial_port_VIA_port_handler_; - std::shared_ptr serial_port_; - DriveVIA drive_VIA_port_handler_; - - MOS::MOS6522::MOS6522 drive_VIA_; - MOS::MOS6522::MOS6522 serial_port_VIA_; - - int shift_register_, bit_window_offset_; - virtual void process_input_bit(int value, unsigned int cycles_since_index_hole); - virtual void process_index_hole(); }; } diff --git a/Machines/Commodore/1540/C1540.cpp b/Machines/Commodore/1540/Implementation/C1540.cpp similarity index 91% rename from Machines/Commodore/1540/C1540.cpp rename to Machines/Commodore/1540/Implementation/C1540.cpp index 011869cbd..d181aacf5 100644 --- a/Machines/Commodore/1540/C1540.cpp +++ b/Machines/Commodore/1540/Implementation/C1540.cpp @@ -7,12 +7,15 @@ // #include "C1540.hpp" + #include -#include "../../../Storage/Disk/Encodings/CommodoreGCR.hpp" +#include + +#include "../../../../Storage/Disk/Encodings/CommodoreGCR.hpp" using namespace Commodore::C1540; -Machine::Machine() : +MachineBase::MachineBase() : m6502_(*this), shift_register_(0), Storage::Disk::Controller(1000000, 4, 300), @@ -37,7 +40,7 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu Commodore::Serial::AttachPortAndBus(serial_port_, serial_bus); } -Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { +Cycles MachineBase::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { /* Memory map (given that I'm unsure yet on any potential mirroring): @@ -73,6 +76,7 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint } void Machine::set_rom(const std::vector &rom) { + assert(rom.size() == sizeof(rom_)); memcpy(rom_, rom.data(), std::min(sizeof(rom_), rom.size())); } @@ -84,21 +88,23 @@ void Machine::set_disk(std::shared_ptr disk) { void Machine::run_for(const Cycles cycles) { m6502_.run_for(cycles); - set_motor_on(drive_VIA_port_handler_.get_motor_enabled()); - if(drive_VIA_port_handler_.get_motor_enabled()) // TODO: motor speed up/down + + bool drive_motor = drive_VIA_port_handler_.get_motor_enabled(); + set_motor_on(drive_motor); + if(drive_motor) Storage::Disk::Controller::run_for(cycles); } #pragma mark - 6522 delegate -void Machine::mos6522_did_change_interrupt_status(void *mos6522) { +void MachineBase::mos6522_did_change_interrupt_status(void *mos6522) { // both VIAs are connected to the IRQ line m6502_.set_irq_line(serial_port_VIA_.get_interrupt_line() || drive_VIA_.get_interrupt_line()); } #pragma mark - Disk drive -void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole) { +void MachineBase::process_input_bit(int value, unsigned int cycles_since_index_hole) { shift_register_ = (shift_register_ << 1) | value; if((shift_register_ & 0x3ff) == 0x3ff) { drive_VIA_port_handler_.set_sync_detected(true); @@ -118,15 +124,15 @@ void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole) } // the 1540 does not recognise index holes -void Machine::process_index_hole() {} +void MachineBase::process_index_hole() {} #pragma mak - Drive VIA delegate -void Machine::drive_via_did_step_head(void *driveVIA, int direction) { +void MachineBase::drive_via_did_step_head(void *driveVIA, int direction) { step(direction); } -void Machine::drive_via_did_set_data_density(void *driveVIA, int density) { +void MachineBase::drive_via_did_set_data_density(void *driveVIA, int density) { set_expected_bit_length(Storage::Encodings::CommodoreGCR::length_of_a_bit_in_time_zone((unsigned int)density)); } diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp new file mode 100644 index 000000000..6d17e5afa --- /dev/null +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -0,0 +1,157 @@ +// +// C1540Base.hpp +// Clock Signal +// +// Created by Thomas Harte on 04/09/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#ifndef C1540Base_hpp +#define C1540Base_hpp + +#include "../../../../Processors/6502/6502.hpp" +#include "../../../../Components/6522/6522.hpp" + +#include "../../SerialBus.hpp" + +#include "../../../../Storage/Disk/Disk.hpp" + +#include "../../../../Storage/Disk/DiskController.hpp" + +namespace Commodore { +namespace C1540 { + +/*! + An implementation of the serial-port VIA in a Commodore 1540 — the VIA that facilitates all + IEC bus communications. + + It is wired up such that Port B contains: + Bit 0: data input; 1 if the line is low, 0 if it is high; + Bit 1: data output; 1 if the line should be low, 0 if it should be high; + Bit 2: clock input; 1 if the line is low, 0 if it is high; + Bit 3: clock output; 1 if the line is low, 0 if it is high; + Bit 4: attention acknowledge output; exclusive ORd with the attention input and ORd onto the data output; + Bits 5/6: device select input; the 1540 will act as device 8 + [value of bits] + Bit 7: attention input; 1 if the line is low, 0 if it is high + + The attention input is also connected to CA1, similarly inverted — the CA1 wire will be high when the bus is low and vice versa. +*/ +class SerialPortVIA: public MOS::MOS6522::IRQDelegatePortHandler { + public: + SerialPortVIA(MOS::MOS6522::MOS6522 &via); + + uint8_t get_port_input(MOS::MOS6522::Port); + + void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t mask); + void set_serial_line_state(::Commodore::Serial::Line, bool); + + void set_serial_port(const std::shared_ptr<::Commodore::Serial::Port> &); + + private: + MOS::MOS6522::MOS6522 via_; + uint8_t port_b_; + std::weak_ptr<::Commodore::Serial::Port> serial_port_; + bool attention_acknowledge_level_, attention_level_input_, data_level_output_; + + void update_data_line(); +}; + +/*! + An implementation of the drive VIA in a Commodore 1540 — the VIA that is used to interface with the disk. + + It is wired up such that Port B contains: + Bits 0/1: head step direction + Bit 2: motor control + Bit 3: LED control (TODO) + Bit 4: write protect photocell status (TODO) + Bits 5/6: read/write density + Bit 7: 0 if sync marks are currently being detected, 1 otherwise. + + ... and Port A contains the byte most recently read from the disk or the byte next to write to the disk, depending on data direction. + + It is implied that CA2 might be used to set processor overflow, CA1 a strobe for data input, and one of the CBs being definitive on + whether the disk head is being told to read or write, but it's unclear and I've yet to investigate. So, TODO. +*/ +class DriveVIA: public MOS::MOS6522::IRQDelegatePortHandler { + public: + class Delegate { + public: + virtual void drive_via_did_step_head(void *driveVIA, int direction) = 0; + virtual void drive_via_did_set_data_density(void *driveVIA, int density) = 0; + }; + void set_delegate(Delegate *); + + DriveVIA(); + + uint8_t get_port_input(MOS::MOS6522::Port port); + + void set_sync_detected(bool); + void set_data_input(uint8_t); + bool get_should_set_overflow(); + bool get_motor_enabled(); + + void set_control_line_output(MOS::MOS6522::Port, MOS::MOS6522::Line, bool value); + + void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t direction_mask); + + private: + uint8_t port_b_, port_a_; + bool should_set_overflow_; + bool drive_motor_; + uint8_t previous_port_b_output_; + Delegate *delegate_; +}; + +/*! + An implementation of the C1540's serial port; this connects incoming line levels to the serial-port VIA. +*/ +class SerialPort : public ::Commodore::Serial::Port { + public: + void set_input(::Commodore::Serial::Line, ::Commodore::Serial::LineLevel); + void set_serial_port_via(const std::shared_ptr &); + + private: + std::weak_ptr serial_port_VIA_; +}; + +class MachineBase: + public CPU::MOS6502::BusHandler, + public MOS::MOS6522::IRQDelegatePortHandler::Delegate, + public DriveVIA::Delegate, + public Storage::Disk::Controller { + + public: + MachineBase(); + + // to satisfy CPU::MOS6502::Processor + Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value); + + // to satisfy MOS::MOS6522::Delegate + virtual void mos6522_did_change_interrupt_status(void *mos6522); + + // to satisfy DriveVIA::Delegate + void drive_via_did_step_head(void *driveVIA, int direction); + void drive_via_did_set_data_density(void *driveVIA, int density); + + protected: + CPU::MOS6502::Processor m6502_; + + uint8_t ram_[0x800]; + uint8_t rom_[0x4000]; + + std::shared_ptr serial_port_VIA_port_handler_; + std::shared_ptr serial_port_; + DriveVIA drive_VIA_port_handler_; + + MOS::MOS6522::MOS6522 drive_VIA_; + MOS::MOS6522::MOS6522 serial_port_VIA_; + + int shift_register_, bit_window_offset_; + virtual void process_input_bit(int value, unsigned int cycles_since_index_hole); + virtual void process_index_hole(); +}; + +} +} + +#endif /* C1540Base_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index fbc0231ff..f34b69870 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -66,7 +66,6 @@ 4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; }; 4B4C83701D4F623200CD541F /* D64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4C836E1D4F623200CD541F /* D64.cpp */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; - 4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; 4B5073071DDD3B9400C48FBD /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; }; 4B50730A1DDFCFDF00C48FBD /* ArrayBuilderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */; }; @@ -95,6 +94,7 @@ 4B8334861F5DA3780097E338 /* 6502Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334851F5DA3780097E338 /* 6502Storage.cpp */; }; 4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334891F5DB94B0097E338 /* IRQDelegatePortHandler.cpp */; }; 4B83348C1F5DB99C0097E338 /* 6522Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B83348B1F5DB99C0097E338 /* 6522Base.cpp */; }; + 4B8334951F5E25B60097E338 /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334941F5E25B60097E338 /* C1540.cpp */; }; 4B8378DC1F336631005CA9E4 /* CharacterMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8378DA1F336631005CA9E4 /* CharacterMapper.cpp */; }; 4B8378DF1F33675F005CA9E4 /* CharacterMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8378DD1F33675F005CA9E4 /* CharacterMapper.cpp */; }; 4B8378E21F336920005CA9E4 /* CharacterMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8378E01F336920005CA9E4 /* CharacterMapper.cpp */; }; @@ -589,7 +589,6 @@ 4B4C836F1D4F623200CD541F /* D64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = D64.hpp; sourceTree = ""; }; 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = ""; }; 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; - 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = C1540.cpp; sourceTree = ""; }; 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = ""; }; 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = ""; }; 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = ""; }; @@ -637,6 +636,8 @@ 4B8334891F5DB94B0097E338 /* IRQDelegatePortHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRQDelegatePortHandler.cpp; path = Implementation/IRQDelegatePortHandler.cpp; sourceTree = ""; }; 4B83348B1F5DB99C0097E338 /* 6522Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = 6522Base.cpp; path = Implementation/6522Base.cpp; sourceTree = ""; }; 4B83348E1F5DBA6E0097E338 /* 6522Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = 6522Storage.hpp; path = Implementation/6522Storage.hpp; sourceTree = ""; }; + 4B8334911F5E24FF0097E338 /* C1540Base.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = C1540Base.hpp; path = Implementation/C1540Base.hpp; sourceTree = ""; }; + 4B8334941F5E25B60097E338 /* C1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = C1540.cpp; path = Implementation/C1540.cpp; sourceTree = ""; }; 4B8378DA1F336631005CA9E4 /* CharacterMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterMapper.cpp; path = Electron/CharacterMapper.cpp; sourceTree = ""; }; 4B8378DB1F336631005CA9E4 /* CharacterMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CharacterMapper.hpp; path = Electron/CharacterMapper.hpp; sourceTree = ""; }; 4B8378DD1F33675F005CA9E4 /* CharacterMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterMapper.cpp; path = ZX8081/CharacterMapper.cpp; sourceTree = ""; }; @@ -1429,8 +1430,8 @@ 4B4DC8251D2C2470003C5BF8 /* 1540 */ = { isa = PBXGroup; children = ( - 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */, 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */, + 4B8334931F5E25030097E338 /* Implementation */, ); path = 1540; sourceTree = ""; @@ -1585,6 +1586,15 @@ name = Implementation; sourceTree = ""; }; + 4B8334931F5E25030097E338 /* Implementation */ = { + isa = PBXGroup; + children = ( + 4B8334941F5E25B60097E338 /* C1540.cpp */, + 4B8334911F5E24FF0097E338 /* C1540Base.hpp */, + ); + name = Implementation; + sourceTree = ""; + }; 4B8805F11DCFC9A2003085B1 /* Parsers */ = { isa = PBXGroup; children = ( @@ -2802,6 +2812,7 @@ 4B8378E21F336920005CA9E4 /* CharacterMapper.cpp in Sources */, 4BCF1FA41DADC3DD0039D2E7 /* Oric.cpp in Sources */, 4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */, + 4B8334951F5E25B60097E338 /* C1540.cpp in Sources */, 4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */, 4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */, 4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */, @@ -2850,7 +2861,6 @@ 4B6C73BD1D387AE500AFCFCA /* DiskController.cpp in Sources */, 4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */, 4B1497881EE4A1DA00CE2596 /* ZX80O81P.cpp in Sources */, - 4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */, 4B5A12571DD55862007A2231 /* Disassembler6502.cpp in Sources */, 4BE7C9181E3D397100A5496D /* TIA.cpp in Sources */, 4B1E85751D170228001EF87D /* Typer.cpp in Sources */,