From 5dd8c677f1c8979b2f916acbd9f72ab8c783eacf Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 14 Jan 2020 22:23:00 -0500 Subject: [PATCH] Factors out from the Jasmin the stuff that I'm going to need to repeat for the BD-500. --- Machines/Oric/BD500.cpp | 12 +++ Machines/Oric/BD500.hpp | 23 ++++++ Machines/Oric/DiskController.hpp | 78 +++++++++++++++++++ Machines/Oric/Jasmin.cpp | 26 ++----- Machines/Oric/Jasmin.hpp | 29 +------ Machines/Oric/Microdisc.hpp | 1 + Machines/Oric/Oric.cpp | 62 ++++++++------- .../Clock Signal.xcodeproj/project.pbxproj | 8 ++ 8 files changed, 165 insertions(+), 74 deletions(-) create mode 100644 Machines/Oric/BD500.cpp create mode 100644 Machines/Oric/BD500.hpp create mode 100644 Machines/Oric/DiskController.hpp diff --git a/Machines/Oric/BD500.cpp b/Machines/Oric/BD500.cpp new file mode 100644 index 000000000..ee4bc8f0c --- /dev/null +++ b/Machines/Oric/BD500.cpp @@ -0,0 +1,12 @@ +// +// Jasmin.cpp +// Clock Signal +// +// Created by Thomas Harte on 05/01/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#include "Jasmin.hpp" + +using namespace Oric; + diff --git a/Machines/Oric/BD500.hpp b/Machines/Oric/BD500.hpp new file mode 100644 index 000000000..a1f3cc0b4 --- /dev/null +++ b/Machines/Oric/BD500.hpp @@ -0,0 +1,23 @@ +// +// BD500.hpp +// Clock Signal +// +// Created by Thomas Harte on 14/01/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#ifndef BD500_hpp +#define BD500_hpp + +#include "../../Components/1770/1770.hpp" +#include "../../Activity/Observer.hpp" +#include "DiskController.hpp" + +#include +#include + +namespace Oric { + +}; + +#endif /* BD500_hpp */ diff --git a/Machines/Oric/DiskController.hpp b/Machines/Oric/DiskController.hpp new file mode 100644 index 000000000..420a6f3ee --- /dev/null +++ b/Machines/Oric/DiskController.hpp @@ -0,0 +1,78 @@ +// +// DiskController.hpp +// Clock Signal +// +// Created by Thomas Harte on 14/01/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#ifndef DiskController_h +#define DiskController_h + +namespace Oric { + +class DiskController: public WD::WD1770 { + public: + DiskController(WD::WD1770::Personality personality, int clock_rate) : + WD::WD1770(personality), clock_rate_(clock_rate) {} + + void set_disk(std::shared_ptr disk, int d) { + const size_t drive = size_t(d); + if(!drives_[drive]) { + drives_[drive] = std::make_unique(clock_rate_, 300, 2); + if(drive == selected_drive_) set_drive(drives_[drive]); + } + drives_[drive]->set_disk(disk); + } + + enum PagingFlags { + /// Indicates that overlay RAM is enabled, implying no ROM is visible. + OverlayRAMEnable = (1 << 0), + + /// Indicates that the BASIC ROM is disabled, implying that the disk + /// controller's ROM fills its space. + BASICDisable = (1 << 1) + }; + + struct Delegate: public WD1770::Delegate { + virtual void disk_controller_did_change_paging_flags(DiskController *controller) = 0; + }; + inline void set_delegate(Delegate *delegate) { + delegate_ = delegate; + WD1770::set_delegate(delegate); + if(delegate) delegate->disk_controller_did_change_paging_flags(this); + } + inline int get_paging_flags() { + return paging_flags_; + } + + protected: + inline void set_paging_flags(int new_flags) { + if(paging_flags_ == new_flags) return; + paging_flags_ = new_flags; + if(delegate_) { + delegate_->disk_controller_did_change_paging_flags(this); + } + } + + std::array, 4> drives_; + size_t selected_drive_; + void select_drive(size_t drive) { + if(drive != selected_drive_) { + selected_drive_ = drive; + set_drive(drives_[selected_drive_]); + } + } + + private: + int paging_flags_ = 0; + Delegate *delegate_ = nullptr; + int clock_rate_; + +}; + + +}; + + +#endif /* DiskController_h */ diff --git a/Machines/Oric/Jasmin.cpp b/Machines/Oric/Jasmin.cpp index 60220f685..3aee0aab7 100644 --- a/Machines/Oric/Jasmin.cpp +++ b/Machines/Oric/Jasmin.cpp @@ -12,19 +12,10 @@ using namespace Oric; // NB: there's some controversy here on WD1770 versus WD1772, but between those two I think // the only difference is stepping rates, and it says 1770 on the schematic I'm looking at. -Jasmin::Jasmin() : WD1770(P1770) { +Jasmin::Jasmin() : DiskController(P1770, 8000000) { set_is_double_density(true); } -void Jasmin::set_disk(std::shared_ptr disk, int d) { - const size_t drive = size_t(d); - if(!drives_[drive]) { - drives_[drive] = std::make_unique(8000000, 300, 2); - if(drive == selected_drive_) set_drive(drives_[drive]); - } - drives_[drive]->set_disk(disk); -} - void Jasmin::write(int address, uint8_t value) { switch(address) { // Set side. @@ -40,23 +31,18 @@ void Jasmin::write(int address, uint8_t value) { case 0x3fa: { // If b0, enable overlay RAM. - posit_paging_flags((paging_flags_ & BASICDisable) | ((value & 1) ? OverlayRAMEnable : 0)); + set_paging_flags((get_paging_flags() & BASICDisable) | ((value & 1) ? OverlayRAMEnable : 0)); } break; case 0x3fb: // If b0, disable BASIC ROM. - posit_paging_flags((paging_flags_ & OverlayRAMEnable) | ((value & 1) ? BASICDisable : 0)); + set_paging_flags((get_paging_flags() & OverlayRAMEnable) | ((value & 1) ? BASICDisable : 0)); break; case 0x3fc: case 0x3fd: case 0x3fe: case 0x3ff: { - const size_t new_selected_drive = size_t(address - 0x3fc); - - if(new_selected_drive != selected_drive_) { - if(drives_[selected_drive_]) drives_[selected_drive_]->set_motor_on(false); - selected_drive_ = new_selected_drive; - set_drive(drives_[selected_drive_]); - if(drives_[selected_drive_]) drives_[selected_drive_]->set_motor_on(motor_on_); - } + if(drives_[selected_drive_]) drives_[selected_drive_]->set_motor_on(false); + select_drive(size_t(address - 0x3fc)); + if(drives_[selected_drive_]) drives_[selected_drive_]->set_motor_on(motor_on_); } break; default: diff --git a/Machines/Oric/Jasmin.hpp b/Machines/Oric/Jasmin.hpp index 8b171a5a1..ecfc991e4 100644 --- a/Machines/Oric/Jasmin.hpp +++ b/Machines/Oric/Jasmin.hpp @@ -11,45 +11,20 @@ #include "../../Components/1770/1770.hpp" #include "../../Activity/Observer.hpp" +#include "DiskController.hpp" #include #include namespace Oric { -class Jasmin: public WD::WD1770 { +class Jasmin: public DiskController { public: Jasmin(); - void set_disk(std::shared_ptr disk, int drive); void write(int address, uint8_t value); - enum PagingFlags { - /// Indicates that overlay RAM is enabled, implying no ROM is visible. - OverlayRAMEnable = (1 << 0), - - /// Indicates that the BASIC ROM is disabled, implying that the JASMIN ROM - /// fills its space. - BASICDisable = (1 << 1) - }; - struct Delegate: public WD1770::Delegate { - virtual void jasmin_did_change_paging_flags(Jasmin *jasmin) = 0; - }; - inline void set_delegate(Delegate *delegate) { delegate_ = delegate; WD1770::set_delegate(delegate); } - inline int get_paging_flags() { return paging_flags_; } - private: - std::array, 4> drives_; - size_t selected_drive_; - int paging_flags_ = 0; - Delegate *delegate_ = nullptr; - - void posit_paging_flags(int new_flags) { - if(new_flags != paging_flags_) { - paging_flags_ = new_flags; - if(delegate_) delegate_->jasmin_did_change_paging_flags(this); - } - } void set_motor_on(bool on) final; bool motor_on_ = false; diff --git a/Machines/Oric/Microdisc.hpp b/Machines/Oric/Microdisc.hpp index b72e4cefc..9a5414f74 100644 --- a/Machines/Oric/Microdisc.hpp +++ b/Machines/Oric/Microdisc.hpp @@ -13,6 +13,7 @@ #include "../../Activity/Observer.hpp" #include +#include "DiskController.hpp" namespace Oric { diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index e53a1fe6b..4df2dec69 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -224,7 +224,7 @@ template class Co public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public Microdisc::Delegate, - public Jasmin::Delegate, + public DiskController::Delegate, public ClockingHint::Observer, public Activity::Source, public Machine, @@ -266,6 +266,9 @@ template class Co size_t diskii_state_machine_index = 0; switch(disk_interface) { default: break; + case DiskInterface::BD500: + rom_names.emplace_back(machine_name, "the ORIC Byte Drive 500 ROM", "bd500.rom", 8*1024, 0x61952e34); + break; case DiskInterface::Jasmin: rom_names.emplace_back(machine_name, "the ORIC Jasmin ROM", "jasmin.rom", 2*1024, 0x37220e89); break; @@ -293,13 +296,17 @@ template class Co switch(disk_interface) { default: break; + case DiskInterface::BD500: + disk_rom_ = std::move(*roms[2]); + disk_rom_.resize(8192); + break; case DiskInterface::Jasmin: - jasmin_rom_ = std::move(*roms[2]); - jasmin_rom_.resize(2048); + disk_rom_ = std::move(*roms[2]); + disk_rom_.resize(2048); break; case DiskInterface::Microdisc: - microdisc_rom_ = std::move(*roms[2]); - microdisc_rom_.resize(8192); + disk_rom_ = std::move(*roms[2]); + disk_rom_.resize(8192); break; case DiskInterface::Pravetz: { pravetz_rom_ = std::move(*roms[2]); @@ -319,7 +326,6 @@ template class Co microdisc_.set_delegate(this); break; case DiskInterface::Jasmin: - jasmin_did_change_paging_flags(&jasmin_); jasmin_.set_delegate(this); break; } @@ -353,7 +359,7 @@ template class Co audio_queue_.flush(); } - void set_key_state(uint16_t key, bool is_pressed) override final { + void set_key_state(uint16_t key, bool is_pressed) final { if(key == KeyNMI) { m6502_.set_nmi_line(is_pressed); } else { @@ -361,7 +367,7 @@ template class Co } } - void clear_all_keys() override final { + void clear_all_keys() final { keyboard_.clear_all_keys(); } @@ -380,7 +386,7 @@ template class Co return true; } - bool insert_media(const Analyser::Static::Media &media) override final { + bool insert_media(const Analyser::Static::Media &media) final { bool inserted = false; if(!media.tapes.empty()) { @@ -534,40 +540,40 @@ template class Co } // to satisfy CRTMachine::Machine - void set_scan_target(Outputs::Display::ScanTarget *scan_target) override final { + void set_scan_target(Outputs::Display::ScanTarget *scan_target) final { video_output_.set_scan_target(scan_target); } - void set_display_type(Outputs::Display::DisplayType display_type) override { + void set_display_type(Outputs::Display::DisplayType display_type) final { video_output_.set_display_type(display_type); } - Outputs::Speaker::Speaker *get_speaker() override final { + Outputs::Speaker::Speaker *get_speaker() final { return &speaker_; } - void run_for(const Cycles cycles) override final { + void run_for(const Cycles cycles) final { m6502_.run_for(cycles); } // to satisfy MOS::MOS6522IRQDelegate::Delegate - void mos6522_did_change_interrupt_status(void *mos6522) override final { + void mos6522_did_change_interrupt_status(void *mos6522) final { set_interrupt_line(); } // to satisfy Storage::Tape::BinaryTapePlayer::Delegate - void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape_player) override final { + void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape_player) final { // set CB1 via_.set_control_line_input(MOS::MOS6522::Port::B, MOS::MOS6522::Line::One, !tape_player->get_input()); } // for Utility::TypeRecipient::Delegate - void type_string(const std::string &string) override final { + void type_string(const std::string &string) final { string_serialiser_ = std::make_unique(string, true); } // for Microdisc::Delegate - void microdisc_did_change_paging_flags(class Microdisc *microdisc) override final { + void microdisc_did_change_paging_flags(class Microdisc *microdisc) final { const int flags = microdisc->get_paging_flags(); if(!(flags&Microdisc::PagingFlags::BASICDisable)) { ram_top_ = basic_visible_ram_top_; @@ -577,14 +583,15 @@ template class Co ram_top_ = basic_invisible_ram_top_; } else { ram_top_ = 0xdfff; - paged_rom_ = microdisc_rom_.data(); + paged_rom_ = disk_rom_.data(); } } } - // Jasmin::Delegate - void jasmin_did_change_paging_flags(Jasmin *jasmin) override final { - const int flags = jasmin->get_paging_flags(); + // DiskController::Delegate + void disk_controller_did_change_paging_flags(DiskController *controller) final { + const int flags = controller->get_paging_flags(); + switch(flags) { // BASIC enabled, overlay disabled. default: @@ -593,15 +600,15 @@ template class Co break; // Overlay RAM enabled, with or without BASIC. - case Jasmin::OverlayRAMEnable: - case Jasmin::OverlayRAMEnable | Jasmin::BASICDisable: + case DiskController::OverlayRAMEnable: + case DiskController::OverlayRAMEnable | DiskController::BASICDisable: ram_top_ = basic_invisible_ram_top_; break; // BASIC disabled, overlay disabled. - case Jasmin::BASICDisable: - ram_top_ = 0xf7ff; - paged_rom_ = jasmin_rom_.data(); + case DiskController::BASICDisable: + ram_top_ = uint16_t(0xffff - disk_rom_.size()); + paged_rom_ = disk_rom_.data(); break; } } @@ -669,7 +676,7 @@ template class Co CPU::MOS6502::Processor m6502_; // RAM and ROM - std::vector rom_, microdisc_rom_, jasmin_rom_; + std::vector rom_, disk_rom_; uint8_t ram_[65536]; Cycles cycles_since_video_update_; inline void update_video() { @@ -771,6 +778,7 @@ Machine *Machine::Oric(const Analyser::Static::Target *target_hint, const ROMMac case DiskInterface::Microdisc: return new ConcreteMachine(*oric_target, rom_fetcher); case DiskInterface::Pravetz: return new ConcreteMachine(*oric_target, rom_fetcher); case DiskInterface::Jasmin: return new ConcreteMachine(*oric_target, rom_fetcher); + case DiskInterface::BD500: return new ConcreteMachine(*oric_target, rom_fetcher); } } diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 47dd05872..24b9bb098 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -369,6 +369,7 @@ 4B7BA03023C2B19C00B98D9E /* Jasmin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA02E23C2B19B00B98D9E /* Jasmin.cpp */; }; 4B7BA03123C2B19C00B98D9E /* Jasmin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA02E23C2B19B00B98D9E /* Jasmin.cpp */; }; 4B7BA03423C58B1F00B98D9E /* STX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA03323C58B1E00B98D9E /* STX.cpp */; }; + 4B7BA03723CEB86000B98D9E /* BD500.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA03523CEB86000B98D9E /* BD500.cpp */; }; 4B7BC7F51F58F27800D1B1B4 /* 6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C911F58F09E00E3F787 /* 6502AllRAM.cpp */; }; 4B7F188E2154825E00388727 /* MasterSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F188C2154825D00388727 /* MasterSystem.cpp */; }; 4B7F188F2154825E00388727 /* MasterSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F188C2154825D00388727 /* MasterSystem.cpp */; }; @@ -1181,6 +1182,9 @@ 4B7BA02F23C2B19B00B98D9E /* Jasmin.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Jasmin.hpp; path = Oric/Jasmin.hpp; sourceTree = ""; }; 4B7BA03223C58B1E00B98D9E /* STX.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = STX.hpp; sourceTree = ""; }; 4B7BA03323C58B1E00B98D9E /* STX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STX.cpp; sourceTree = ""; }; + 4B7BA03523CEB86000B98D9E /* BD500.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BD500.cpp; path = Oric/BD500.cpp; sourceTree = ""; }; + 4B7BA03623CEB86000B98D9E /* BD500.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = BD500.hpp; path = Oric/BD500.hpp; sourceTree = ""; }; + 4B7BA03823CEB8D200B98D9E /* DiskController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = DiskController.hpp; path = Oric/DiskController.hpp; sourceTree = ""; }; 4B7F188C2154825D00388727 /* MasterSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MasterSystem.cpp; sourceTree = ""; }; 4B7F188D2154825D00388727 /* MasterSystem.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MasterSystem.hpp; sourceTree = ""; }; 4B7F1895215486A100388727 /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaticAnalyser.hpp; sourceTree = ""; }; @@ -3533,16 +3537,19 @@ 4BCF1FA51DADC3E10039D2E7 /* Oric */ = { isa = PBXGroup; children = ( + 4B7BA03523CEB86000B98D9E /* BD500.cpp */, 4B7BA02E23C2B19B00B98D9E /* Jasmin.cpp */, 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */, 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */, 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */, 4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */, + 4B7BA03623CEB86000B98D9E /* BD500.hpp */, 4B7BA02F23C2B19B00B98D9E /* Jasmin.hpp */, 4B54C0BE1F8D8F450050900F /* Keyboard.hpp */, 4B5FADBF1DE3BF2B00AEC565 /* Microdisc.hpp */, 4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */, 4B2BFDB11DAEF5FF001A68B8 /* Video.hpp */, + 4B7BA03823CEB8D200B98D9E /* DiskController.hpp */, ); name = Oric; sourceTree = ""; @@ -4455,6 +4462,7 @@ 4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4BD5D2682199148100DDF17D /* ScanTargetGLSLFragments.cpp in Sources */, 4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */, + 4B7BA03723CEB86000B98D9E /* BD500.cpp in Sources */, 4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */, 4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */, 4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,