From c3a2f7717b4e443ad77ee217d19042f12ad23cbc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 8 May 2018 22:05:43 -0400 Subject: [PATCH 1/2] Makes attempt to implement support for the Pravetz 8D + 8DOS. i.e. the Disk II wired up to the Oric, with some ROM swaps. --- Analyser/Static/DiskII/StaticAnalyser.cpp | 6 +- Analyser/Static/Oric/StaticAnalyser.cpp | 12 +- Analyser/Static/Oric/Target.hpp | 16 +- Components/DiskII/DiskII.cpp | 36 +++ Components/DiskII/DiskII.hpp | 18 +- Machines/AppleII/DiskIICard.cpp | 39 +-- Machines/Oric/Oric.cpp | 224 ++++++++++++------ Machines/Oric/Oric.hpp | 3 +- Machines/Utility/MachineForTarget.cpp | 2 +- .../Machine/StaticAnalyser/CSStaticAnalyser.h | 11 +- .../StaticAnalyser/CSStaticAnalyser.mm | 14 +- .../New Group/Base.lproj/MachinePicker.xib | 88 ++++--- .../New Group/MachinePicker.swift | 24 +- ROMImages/Oric/readme.txt | 3 +- 14 files changed, 327 insertions(+), 169 deletions(-) diff --git a/Analyser/Static/DiskII/StaticAnalyser.cpp b/Analyser/Static/DiskII/StaticAnalyser.cpp index af0aa0781..e37a7758a 100644 --- a/Analyser/Static/DiskII/StaticAnalyser.cpp +++ b/Analyser/Static/DiskII/StaticAnalyser.cpp @@ -36,9 +36,9 @@ Analyser::Static::Target *OricTarget(const Storage::Encodings::AppleGCR::Sector using Target = Analyser::Static::Oric::Target; auto *target = new Target; target->machine = Analyser::Machine::Oric; - - // TODO: configure the Oric as a Pravetz 8D with 8DOS. - + target->rom = Target::ROM::Pravetz; + target->disk_interface = Target::DiskInterface::Pravetz; + target->loading_command = "call 800\n"; return target; } diff --git a/Analyser/Static/Oric/StaticAnalyser.cpp b/Analyser/Static/Oric/StaticAnalyser.cpp index 35cbae8c1..c40b117ae 100644 --- a/Analyser/Static/Oric/StaticAnalyser.cpp +++ b/Analyser/Static/Oric/StaticAnalyser.cpp @@ -134,17 +134,19 @@ Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &med for(auto &disk: media.disks) { Storage::Encodings::MFM::Parser parser(true, disk); if(IsMicrodisc(parser)) { - target->has_microdrive = true; + target->disk_interface = Target::DiskInterface::Microdisc; target->media.disks.push_back(disk); } } - } else { - target->has_microdrive = false; } + else + target->disk_interface = Target::DiskInterface::None; // TODO: really this should add two targets if not all votes agree - target->use_atmos_rom = basic11_votes >= basic10_votes; - if(target->has_microdrive) target->use_atmos_rom = true; + if(basic11_votes >= basic10_votes || target->disk_interface == Target::DiskInterface::Microdisc) + target->rom = Target::ROM::BASIC11; + else + target->rom = Target::ROM::BASIC10; TargetList targets; if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size()) diff --git a/Analyser/Static/Oric/Target.hpp b/Analyser/Static/Oric/Target.hpp index 36bc42c22..a1f82171b 100644 --- a/Analyser/Static/Oric/Target.hpp +++ b/Analyser/Static/Oric/Target.hpp @@ -17,8 +17,20 @@ namespace Static { namespace Oric { struct Target: public ::Analyser::Static::Target { - bool use_atmos_rom = false; - bool has_microdrive = false; + enum class ROM { + BASIC10, + BASIC11, + Pravetz + }; + + enum class DiskInterface { + Microdisc, + Pravetz, + None + }; + + ROM rom = ROM::BASIC11; + DiskInterface disk_interface = DiskInterface::None; std::string loading_command; }; diff --git a/Components/DiskII/DiskII.cpp b/Components/DiskII/DiskII.cpp index 3564e7a72..64bc9c7fd 100644 --- a/Components/DiskII/DiskII.cpp +++ b/Components/DiskII/DiskII.cpp @@ -184,3 +184,39 @@ void DiskII::set_component_is_sleeping(Sleeper *component, bool is_sleeping) { bool DiskII::is_sleeping() { return controller_can_sleep_ && drive_is_sleeping_[0] && drive_is_sleeping_[1]; } + +void DiskII::set_register(int address, uint8_t value) { + trigger_address(address, value); +} + +uint8_t DiskII::get_register(int address) { + return trigger_address(address, 0xff); +} + +uint8_t DiskII::trigger_address(int address, uint8_t value) { + switch(address & 0xf) { + default: + case 0x0: set_control(Control::P0, false); break; + case 0x1: set_control(Control::P0, true); break; + case 0x2: set_control(Control::P1, false); break; + case 0x3: set_control(Control::P1, true); break; + case 0x4: set_control(Control::P2, false); break; + case 0x5: set_control(Control::P2, true); break; + case 0x6: set_control(Control::P3, false); break; + case 0x7: set_control(Control::P3, true); break; + + case 0x8: set_control(Control::Motor, false); break; + case 0x9: set_control(Control::Motor, true); break; + + case 0xa: select_drive(0); break; + case 0xb: select_drive(1); break; + + case 0xc: return get_shift_register(); + case 0xd: set_data_register(value); break; + + case 0xe: set_mode(Mode::Read); break; + case 0xf: set_mode(Mode::Write); break; + } + return 0xff; +} + diff --git a/Components/DiskII/DiskII.hpp b/Components/DiskII/DiskII.hpp index 26f9d6adb..95697e6b8 100644 --- a/Components/DiskII/DiskII.hpp +++ b/Components/DiskII/DiskII.hpp @@ -30,6 +30,16 @@ class DiskII: public: DiskII(); + void set_register(int address, uint8_t value); + uint8_t get_register(int address); + + void run_for(const Cycles cycles); + void set_state_machine(const std::vector &); + + void set_disk(const std::shared_ptr &disk, int drive); + bool is_sleeping() override; + + private: enum class Control { P0, P1, P2, P3, Motor, @@ -43,13 +53,7 @@ class DiskII: void set_data_register(uint8_t value); uint8_t get_shift_register(); - void run_for(const Cycles cycles); - void set_state_machine(const std::vector &); - - void set_disk(const std::shared_ptr &disk, int drive); - bool is_sleeping() override; - - private: + uint8_t trigger_address(int address, uint8_t value); void process_event(const Storage::Disk::Track::Event &event) override; void set_component_is_sleeping(Sleeper *component, bool is_sleeping) override; diff --git a/Machines/AppleII/DiskIICard.cpp b/Machines/AppleII/DiskIICard.cpp index f61b18ffa..b0941b28e 100644 --- a/Machines/AppleII/DiskIICard.cpp +++ b/Machines/AppleII/DiskIICard.cpp @@ -22,40 +22,13 @@ DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sec } void DiskIICard::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { - if(isReadOperation(operation) && address < 0x100) { - *value &= boot_[address]; + if(address < 0x100) { + if(isReadOperation(operation)) *value &= boot_[address]; } else { - using Control = Apple::DiskII::Control; - using Mode = Apple::DiskII::Mode; - switch(address & 0xf) { - case 0x0: diskii_.set_control(Control::P0, false); break; - case 0x1: diskii_.set_control(Control::P0, true); break; - case 0x2: diskii_.set_control(Control::P1, false); break; - case 0x3: diskii_.set_control(Control::P1, true); break; - case 0x4: diskii_.set_control(Control::P2, false); break; - case 0x5: diskii_.set_control(Control::P2, true); break; - case 0x6: diskii_.set_control(Control::P3, false); break; - case 0x7: diskii_.set_control(Control::P3, true); break; - - case 0x8: diskii_.set_control(Control::Motor, false); break; - case 0x9: diskii_.set_control(Control::Motor, true); break; - - case 0xa: diskii_.select_drive(0); break; - case 0xb: diskii_.select_drive(1); break; - - case 0xc: { - /* shift register? */ - const uint8_t shift_value = diskii_.get_shift_register(); - if(isReadOperation(operation)) - *value = shift_value; - } break; - case 0xd: - /* data register? */ - diskii_.set_data_register(*value); - break; - - case 0xe: diskii_.set_mode(Mode::Read); break; - case 0xf: diskii_.set_mode(Mode::Write); break; + if(isReadOperation(operation)) { + *value = diskii_.get_register(address); + } else { + diskii_.set_register(address, *value); } } } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 1848dd312..0cbd28efa 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -22,6 +22,7 @@ #include "../../Processors/6502/6502.hpp" #include "../../Components/6522/6522.hpp" #include "../../Components/AY38910/AY38910.hpp" +#include "../../Components/DiskII/DiskII.hpp" #include "../../Storage/Tape/Tape.hpp" #include "../../Storage/Tape/Parsers/Oric.hpp" @@ -189,7 +190,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler { Keyboard &keyboard_; }; -class ConcreteMachine: +template class ConcreteMachine: public CRTMachine::Machine, public ConfigurationTarget::Machine, public KeyboardMachine::Machine, @@ -202,13 +203,13 @@ class ConcreteMachine: public Machine { public: - ConcreteMachine() : + ConcreteMachine(const Analyser::Static::Oric::Target *target) : m6502_(*this), + rom_type_(target ? target->rom : Analyser::Static::Oric::Target::ROM::BASIC10), ay8910_(audio_queue_), speaker_(ay8910_), via_port_handler_(audio_queue_, ay8910_, speaker_, tape_player_, keyboard_), - via_(via_port_handler_), - paged_rom_(rom_) { + via_(via_port_handler_) { set_clock_rate(1000000); via_port_handler_.set_interrupt_delegate(this); tape_player_.set_delegate(this); @@ -221,26 +222,46 @@ class ConcreteMachine: // Obtains the system ROMs. bool set_rom_fetcher(const ROMMachine::ROMFetcher &roms_with_names) override { - auto roms = roms_with_names( - "Oric", - { - "basic10.rom", "basic11.rom", - "microdisc.rom", "colour.rom" - }); + std::vector rom_names = {"colour.rom"}; + switch(rom_type_) { + case Analyser::Static::Oric::Target::ROM::BASIC10: rom_names.push_back("basic10.rom"); break; + case Analyser::Static::Oric::Target::ROM::BASIC11: rom_names.push_back("basic11.rom"); break; + case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.push_back("pravetz.rom"); break; + } + switch(disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: rom_names.push_back("microdisc.rom"); break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: rom_names.push_back("8dos.rom"); break; + } + + auto roms = roms_with_names("Oric", rom_names); for(std::size_t index = 0; index < roms.size(); ++index) { if(!roms[index]) return false; } - basic10_rom_ = std::move(*roms[0]); - basic11_rom_ = std::move(*roms[1]); - microdisc_rom_ = std::move(*roms[2]); - colour_rom_ = std::move(*roms[3]); + colour_rom_ = std::move(*roms[0]); + rom_ = std::move(*roms[1]); + + switch(disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: + microdisc_rom_ = std::move(*roms[2]); + microdisc_rom_.resize(8192); + break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: { + pravetz_rom_ = std::move(*roms[2]); + pravetz_rom_.resize(512); + + auto state_machine_rom = roms_with_names("DiskII", {"state-machine-16.rom"}); + if(!state_machine_rom[0]) return false; + diskii_.set_state_machine(*state_machine_rom[0]); + } break; + } - basic10_rom_.resize(16384); - basic11_rom_.resize(16384); - microdisc_rom_.resize(8192); colour_rom_.resize(128); + rom_.resize(16384); + paged_rom_ = rom_.data(); if(video_output_) video_output_->set_colour_rom(colour_rom_); @@ -267,47 +288,67 @@ class ConcreteMachine: void configure_as_target(const Analyser::Static::Target *target) override final { auto *const oric_target = dynamic_cast(target); - if(oric_target->has_microdrive) { - microdisc_is_enabled_ = true; - microdisc_did_change_paging_flags(µdisc_); - microdisc_.set_delegate(this); + switch(oric_target->disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: + microdisc_did_change_paging_flags(µdisc_); + microdisc_.set_delegate(this); + break; } if(!oric_target->loading_command.empty()) { type_string(oric_target->loading_command); } - if(oric_target->use_atmos_rom) { - std::memcpy(rom_, basic11_rom_.data(), std::min(basic11_rom_.size(), sizeof(rom_))); - - is_using_basic11_ = true; - tape_get_byte_address_ = 0xe6c9; - scan_keyboard_address_ = 0xf495; - tape_speed_address_ = 0x024d; - } else { - std::memcpy(rom_, basic10_rom_.data(), std::min(basic10_rom_.size(), sizeof(rom_))); - - is_using_basic11_ = false; - tape_get_byte_address_ = 0xe630; - scan_keyboard_address_ = 0xf43c; - tape_speed_address_ = 0x67; + switch(rom_type_) { + case Analyser::Static::Oric::Target::ROM::BASIC10: + tape_get_byte_address_ = 0xe630; + scan_keyboard_address_ = 0xf43c; + tape_speed_address_ = 0x67; + break; + case Analyser::Static::Oric::Target::ROM::BASIC11: + case Analyser::Static::Oric::Target::ROM::Pravetz: + tape_get_byte_address_ = 0xe6c9; + scan_keyboard_address_ = 0xf495; + tape_speed_address_ = 0x024d; + break; } insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { + bool inserted = false; + if(media.tapes.size()) { tape_player_.set_tape(media.tapes.front()); + inserted = true; } - int drive_index = 0; - for(auto &disk : media.disks) { - if(drive_index < 4) microdisc_.set_disk(disk, drive_index); - drive_index++; + if(!media.disks.empty()) { + switch(disk_interface) { + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: { + inserted = true; + int drive_index = 0; + for(auto &disk : media.disks) { + if(drive_index < 4) microdisc_.set_disk(disk, drive_index); + drive_index++; + } + } break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: { + inserted = true; + int drive_index = 0; + for(auto &disk : media.disks) { + if(drive_index < 2) diskii_.set_disk(disk, drive_index); + drive_index++; + } + } break; + + default: break; + } } - return !media.tapes.empty() || (!media.disks.empty() && microdisc_is_enabled_); + return inserted; } // to satisfy CPU::MOS6502::BusHandler @@ -318,7 +359,7 @@ class ConcreteMachine: // 024D = 0 => fast; otherwise slow // E6C9 = read byte: return byte in A if( address == tape_get_byte_address_ && - paged_rom_ == rom_ && + paged_rom_ == rom_.data() && use_fast_tape_hack_ && operation == CPU::MOS6502::BusOperation::ReadOpcode && tape_player_.has_tape() && @@ -331,23 +372,45 @@ class ConcreteMachine: } } else { if((address & 0xff00) == 0x0300) { - if(microdisc_is_enabled_ && address >= 0x0310) { - switch(address) { - case 0x0310: case 0x0311: case 0x0312: case 0x0313: - if(isReadOperation(operation)) *value = microdisc_.get_register(address); - else microdisc_.set_register(address, *value); - break; - case 0x314: case 0x315: case 0x316: case 0x317: - if(isReadOperation(operation)) *value = microdisc_.get_interrupt_request_register(); - else microdisc_.set_control_register(*value); - break; - case 0x318: case 0x319: case 0x31a: case 0x31b: - if(isReadOperation(operation)) *value = microdisc_.get_data_request_register(); - break; - } - } else { + if(address < 0x0310 || (disk_interface == Analyser::Static::Oric::Target::DiskInterface::None)) { if(isReadOperation(operation)) *value = via_.get_register(address); else via_.set_register(address, *value); + } else { + switch(disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: + switch(address) { + case 0x0310: case 0x0311: case 0x0312: case 0x0313: + if(isReadOperation(operation)) *value = microdisc_.get_register(address); + else microdisc_.set_register(address, *value); + break; + case 0x314: case 0x315: case 0x316: case 0x317: + if(isReadOperation(operation)) *value = microdisc_.get_interrupt_request_register(); + else microdisc_.set_control_register(*value); + break; + case 0x318: case 0x319: case 0x31a: case 0x31b: + if(isReadOperation(operation)) *value = microdisc_.get_data_request_register(); + break; + } + break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: + if(address >= 0x0320) { + if(isReadOperation(operation)) *value = pravetz_rom_[pravetz_rom_base_pointer_ + (address & 0xff)]; + else { + switch(address) { + case 0x380: case 0x381: case 0x382: case 0x383: + ram_top_ = (address&1) ? 0xffff : 0xbfff; + pravetz_rom_base_pointer_ = (address&2) ? 0x100 : 0x000; + break; + } + } + } else { + update_diskii(); + if(isReadOperation(operation)) *value = diskii_.get_register(address); + else diskii_.set_register(address, *value); + } + break; + } } } else { if(isReadOperation(operation)) @@ -372,7 +435,11 @@ class ConcreteMachine: via_.run_for(Cycles(1)); via_port_handler_.run_for(Cycles(1)); tape_player_.run_for(Cycles(1)); - if(microdisc_is_enabled_) microdisc_.run_for(Cycles(8)); + switch(disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: microdisc_.run_for(Cycles(8)); break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: cycles_since_diskii_update_ += 2; break; + } cycles_since_video_update_++; return Cycles(1); } @@ -380,6 +447,7 @@ class ConcreteMachine: forceinline void flush() { update_video(); via_port_handler_.flush(); + if(disk_interface == Analyser::Static::Oric::Target::DiskInterface::Pravetz) update_diskii(); } // to satisfy CRTMachine::Machine @@ -429,7 +497,7 @@ class ConcreteMachine: int flags = microdisc->get_paging_flags(); if(!(flags&Microdisc::PagingFlags::BASICDisable)) { ram_top_ = 0xbfff; - paged_rom_ = rom_; + paged_rom_ = rom_.data(); } else { if(flags&Microdisc::PagingFlags::MicrodscDisable) { ram_top_ = 0xffff; @@ -487,15 +555,15 @@ class ConcreteMachine: CPU::MOS6502::Processor m6502_; // RAM and ROM - std::vector basic11_rom_, basic10_rom_, microdisc_rom_, colour_rom_; - uint8_t ram_[65536], rom_[16384]; + Analyser::Static::Oric::Target::ROM rom_type_; + std::vector rom_, microdisc_rom_, colour_rom_; + uint8_t ram_[65536]; Cycles cycles_since_video_update_; inline void update_video() { video_output_->run_for(cycles_since_video_update_.flush()); } // ROM bookkeeping - bool is_using_basic11_ = false; uint16_t tape_get_byte_address_ = 0, scan_keyboard_address_ = 0, tape_speed_address_ = 0; int keyboard_read_count_ = 0; @@ -519,14 +587,26 @@ class ConcreteMachine: // the Microdisc, if in use class Microdisc microdisc_; - bool microdisc_is_enabled_ = false; - uint16_t ram_top_ = 0xbfff; - uint8_t *paged_rom_; + // the Pravetz/Disk II, if in use + Apple::DiskII diskii_; + std::vector pravetz_rom_; + std::size_t pravetz_rom_base_pointer_ = 0; + Cycles cycles_since_diskii_update_; + void update_diskii() { + diskii_.run_for(cycles_since_diskii_update_.flush()); + } + + // Overlay RAM + uint16_t ram_top_ = 0xbfff; + uint8_t *paged_rom_ = nullptr; + + // Helper to discern current IRQ state inline void set_interrupt_line() { - m6502_.set_irq_line( - via_.get_interrupt_line() || - (microdisc_is_enabled_ && microdisc_.get_interrupt_request_line())); + bool irq_line = via_.get_interrupt_line(); + if(disk_interface == Analyser::Static::Oric::Target::DiskInterface::Microdisc) + irq_line |= microdisc_.get_interrupt_request_line(); + m6502_.set_irq_line(irq_line); } }; @@ -534,8 +614,14 @@ class ConcreteMachine: using namespace Oric; -Machine *Machine::Oric() { - return new ConcreteMachine; +Machine *Machine::Oric(const Analyser::Static::Target *target_hint) { + auto *const oric_target = dynamic_cast(target_hint); + using DiskInterface = Analyser::Static::Oric::Target::DiskInterface; + switch(oric_target->disk_interface) { + default: return new ConcreteMachine(oric_target); + case DiskInterface::Microdisc: return new ConcreteMachine(oric_target); + case DiskInterface::Pravetz: return new ConcreteMachine(oric_target); + } } Machine::~Machine() {} diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index b4f8317d5..9b6e5505e 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -10,6 +10,7 @@ #define Oric_hpp #include "../../Configurable/Configurable.hpp" +#include "../../Analyser/Static/StaticAnalyser.hpp" namespace Oric { @@ -24,7 +25,7 @@ class Machine { virtual ~Machine(); /// Creates and returns an Oric. - static Machine *Oric(); + static Machine *Oric(const Analyser::Static::Target *target_hint); }; } diff --git a/Machines/Utility/MachineForTarget.cpp b/Machines/Utility/MachineForTarget.cpp index b601b2602..ccef9c5c2 100644 --- a/Machines/Utility/MachineForTarget.cpp +++ b/Machines/Utility/MachineForTarget.cpp @@ -33,7 +33,7 @@ namespace { case Analyser::Machine::ColecoVision: machine = new Machine::TypedDynamicMachine(Coleco::Vision::Machine::ColecoVision()); break; case Analyser::Machine::Electron: machine = new Machine::TypedDynamicMachine(Electron::Machine::Electron()); break; case Analyser::Machine::MSX: machine = new Machine::TypedDynamicMachine(MSX::Machine::MSX()); break; - case Analyser::Machine::Oric: machine = new Machine::TypedDynamicMachine(Oric::Machine::Oric()); break; + case Analyser::Machine::Oric: machine = new Machine::TypedDynamicMachine(Oric::Machine::Oric(target)); break; case Analyser::Machine::Vic20: machine = new Machine::TypedDynamicMachine(Commodore::Vic20::Machine::Vic20()); break; case Analyser::Machine::ZX8081: machine = new Machine::TypedDynamicMachine(ZX8081::Machine::ZX8081(target)); break; diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h index 6f453d581..dae609944 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h @@ -29,7 +29,14 @@ typedef NS_ENUM(NSInteger, CSMachineCPCModel) { typedef NS_ENUM(NSInteger, CSMachineOricModel) { CSMachineOricModelOric1, - CSMachineOricModelOricAtmos + CSMachineOricModelOricAtmos, + CSMachineOricModelPravetz +}; + +typedef NS_ENUM(NSInteger, CSMachineOricDiskInterface) { + CSMachineOricDiskInterfaceNone, + CSMachineOricDiskInterfaceMicrodisc, + CSMachineOricDiskInterfacePravetz }; typedef NS_ENUM(NSInteger, CSMachineVic20Region) { @@ -49,7 +56,7 @@ typedef int Kilobytes; - (instancetype)initWithElectronDFS:(BOOL)dfs adfs:(BOOL)adfs; - (instancetype)initWithAmstradCPCModel:(CSMachineCPCModel)model; - (instancetype)initWithMSXHasDiskDrive:(BOOL)hasDiskDrive; -- (instancetype)initWithOricModel:(CSMachineOricModel)model hasMicrodrive:(BOOL)hasMicrodrive; +- (instancetype)initWithOricModel:(CSMachineOricModel)model diskInterface:(CSMachineOricDiskInterface)diskInterface; - (instancetype)initWithVic20Region:(CSMachineVic20Region)region memorySize:(Kilobytes)memorySize hasC1540:(BOOL)hasC1540; - (instancetype)initWithZX80MemorySize:(Kilobytes)memorySize useZX81ROM:(BOOL)useZX81ROM; - (instancetype)initWithZX81MemorySize:(Kilobytes)memorySize; diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index bb9a1b6b1..74c19e7d8 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -81,14 +81,22 @@ return self; } -- (instancetype)initWithOricModel:(CSMachineOricModel)model hasMicrodrive:(BOOL)hasMicrodrive { +- (instancetype)initWithOricModel:(CSMachineOricModel)model diskInterface:(CSMachineOricDiskInterface)diskInterface { self = [super init]; if(self) { using Target = Analyser::Static::Oric::Target; std::unique_ptr target(new Target); target->machine = Analyser::Machine::Oric; - target->use_atmos_rom = (model == CSMachineOricModelOricAtmos); - target->has_microdrive = !!hasMicrodrive; + switch(model) { + case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break; + case CSMachineOricModelOricAtmos: target->rom = Target::ROM::BASIC11; break; + case CSMachineOricModelPravetz: target->rom = Target::ROM::Pravetz; break; + } + switch(diskInterface) { + case CSMachineOricDiskInterfaceNone: target->disk_interface = Target::DiskInterface::None; break; + case CSMachineOricDiskInterfaceMicrodisc: target->disk_interface = Target::DiskInterface::Microdisc; break; + case CSMachineOricDiskInterfacePravetz: target->disk_interface = Target::DiskInterface::Pravetz; break; + } _targets.push_back(std::move(target)); } return self; diff --git a/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib b/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib index 1898fc680..e21f6ecee 100644 --- a/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib +++ b/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib @@ -18,7 +18,7 @@ - + @@ -132,7 +132,7 @@ Gw - + @@ -146,8 +146,8 @@ Gw - - + + @@ -197,11 +197,11 @@ Gw - + - - + + - + @@ -245,21 +238,46 @@ Gw + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + @@ -269,7 +287,7 @@ Gw - + @@ -285,7 +303,7 @@ Gw - + @@ -299,16 +317,16 @@ Gw - - + + - - + + @@ -346,7 +364,7 @@ Gw - + @@ -360,8 +378,8 @@ Gw - - + + @@ -390,11 +408,11 @@ Gw - + - + @@ -408,8 +426,8 @@ Gw - - + + @@ -455,7 +473,7 @@ Gw - + diff --git a/OSBindings/Mac/Clock Signal/New Group/MachinePicker.swift b/OSBindings/Mac/Clock Signal/New Group/MachinePicker.swift index 57a54b4a4..084426ad8 100644 --- a/OSBindings/Mac/Clock Signal/New Group/MachinePicker.swift +++ b/OSBindings/Mac/Clock Signal/New Group/MachinePicker.swift @@ -27,7 +27,7 @@ class MachinePicker: NSObject { // MARK: - Oric properties @IBOutlet var oricModelTypeButton: NSPopUpButton? - @IBOutlet var oricHasMicrodriveButton: NSButton? + @IBOutlet var oricDiskInterfaceButton: NSPopUpButton? // MARK: - Vic-20 properties @IBOutlet var vic20RegionButton: NSPopUpButton? @@ -65,7 +65,7 @@ class MachinePicker: NSObject { msxHasDiskDriveButton?.state = standardUserDefaults.bool(forKey: "new.msxDiskDrive") ? .on : .off // Oric settings - oricHasMicrodriveButton?.state = standardUserDefaults.bool(forKey: "new.oricMicrodrive") ? .on : .off + oricDiskInterfaceButton?.selectItem(withTag: standardUserDefaults.integer(forKey: "new.oricDiskInterface")) oricModelTypeButton?.selectItem(withTag: standardUserDefaults.integer(forKey: "new.oricModel")) // Vic-20 settings @@ -102,7 +102,7 @@ class MachinePicker: NSObject { standardUserDefaults.set(msxHasDiskDriveButton?.state == .on, forKey: "new.msxDiskDrive") // Oric settings - standardUserDefaults.set(oricHasMicrodriveButton?.state == .on, forKey: "new.oricMicrodrive") + standardUserDefaults.set(oricDiskInterfaceButton!.selectedTag(), forKey: "new.oricDiskInterface") standardUserDefaults.set(oricModelTypeButton!.selectedTag(), forKey: "new.oricModel") // Vic-20 settings @@ -156,11 +156,21 @@ class MachinePicker: NSObject { return CSStaticAnalyser(msxHasDiskDrive: msxHasDiskDriveButton!.state == .on) case "oric": - let hasMicrodrive = oricHasMicrodriveButton!.state == .on - switch oricModelTypeButton!.selectedItem!.tag { - case 1: return CSStaticAnalyser(oricModel: .oric1, hasMicrodrive: hasMicrodrive) - default: return CSStaticAnalyser(oricModel: .oricAtmos, hasMicrodrive: hasMicrodrive) + var diskInterface: CSMachineOricDiskInterface = .none + switch oricDiskInterfaceButton!.selectedTag() { + case 1: diskInterface = .microdisc + case 2: diskInterface = .pravetz + default: break; + } + var model: CSMachineOricModel = .oric1 + switch oricModelTypeButton!.selectedItem!.tag { + case 1: model = .oricAtmos + case 2: model = .pravetz + default: break; + } + + return CSStaticAnalyser(oricModel: model, diskInterface: diskInterface) case "vic20": let memorySize = Kilobytes(vic20MemorySizeButton!.selectedItem!.tag) diff --git a/ROMImages/Oric/readme.txt b/ROMImages/Oric/readme.txt index 8e1fcc78c..de4b46be1 100644 --- a/ROMImages/Oric/readme.txt +++ b/ROMImages/Oric/readme.txt @@ -6,4 +6,5 @@ basic10.rom basic11.rom colour.rom microdisc.rom -8dos.rom \ No newline at end of file +8dos.rom +pravetz.rom \ No newline at end of file From 45bd24ada0ad1858eec6af679495ea43fcb0ecbe Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 8 May 2018 22:53:27 -0400 Subject: [PATCH 2/2] Corrects tags for Oric machine selection. --- .../New Group/Base.lproj/MachinePicker.xib | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib b/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib index e21f6ecee..4b2c13a83 100644 --- a/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib +++ b/OSBindings/Mac/Clock Signal/New Group/Base.lproj/MachinePicker.xib @@ -231,13 +231,13 @@ Gw - + - - + + @@ -245,13 +245,13 @@ Gw - + - - + +