1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Factors out from the Jasmin the stuff that I'm going to need to repeat for the BD-500.

This commit is contained in:
Thomas Harte 2020-01-14 22:23:00 -05:00
parent 1cbcd5355f
commit 5dd8c677f1
8 changed files with 165 additions and 74 deletions

12
Machines/Oric/BD500.cpp Normal file
View File

@ -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;

23
Machines/Oric/BD500.hpp Normal file
View File

@ -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 <array>
#include <memory>
namespace Oric {
};
#endif /* BD500_hpp */

View File

@ -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<Storage::Disk::Disk> disk, int d) {
const size_t drive = size_t(d);
if(!drives_[drive]) {
drives_[drive] = std::make_unique<Storage::Disk::Drive>(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<std::shared_ptr<Storage::Disk::Drive>, 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 */

View File

@ -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<Storage::Disk::Disk> disk, int d) {
const size_t drive = size_t(d);
if(!drives_[drive]) {
drives_[drive] = std::make_unique<Storage::Disk::Drive>(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:

View File

@ -11,45 +11,20 @@
#include "../../Components/1770/1770.hpp"
#include "../../Activity/Observer.hpp"
#include "DiskController.hpp"
#include <array>
#include <memory>
namespace Oric {
class Jasmin: public WD::WD1770 {
class Jasmin: public DiskController {
public:
Jasmin();
void set_disk(std::shared_ptr<Storage::Disk::Disk> 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<std::shared_ptr<Storage::Disk::Drive>, 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;

View File

@ -13,6 +13,7 @@
#include "../../Activity/Observer.hpp"
#include <array>
#include "DiskController.hpp"
namespace Oric {

View File

@ -224,7 +224,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
}
}
void clear_all_keys() override final {
void clear_all_keys() final {
keyboard_.clear_all_keys();
}
@ -380,7 +386,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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<Utility::StringSerialiser>(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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
CPU::MOS6502::Processor<CPU::MOS6502::Personality::P6502, ConcreteMachine, false> m6502_;
// RAM and ROM
std::vector<uint8_t> rom_, microdisc_rom_, jasmin_rom_;
std::vector<uint8_t> 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<DiskInterface::Microdisc>(*oric_target, rom_fetcher);
case DiskInterface::Pravetz: return new ConcreteMachine<DiskInterface::Pravetz>(*oric_target, rom_fetcher);
case DiskInterface::Jasmin: return new ConcreteMachine<DiskInterface::Jasmin>(*oric_target, rom_fetcher);
case DiskInterface::BD500: return new ConcreteMachine<DiskInterface::BD500>(*oric_target, rom_fetcher);
}
}

View File

@ -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 = "<group>"; };
4B7BA03223C58B1E00B98D9E /* STX.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = STX.hpp; sourceTree = "<group>"; };
4B7BA03323C58B1E00B98D9E /* STX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STX.cpp; sourceTree = "<group>"; };
4B7BA03523CEB86000B98D9E /* BD500.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BD500.cpp; path = Oric/BD500.cpp; sourceTree = "<group>"; };
4B7BA03623CEB86000B98D9E /* BD500.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = BD500.hpp; path = Oric/BD500.hpp; sourceTree = "<group>"; };
4B7BA03823CEB8D200B98D9E /* DiskController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = DiskController.hpp; path = Oric/DiskController.hpp; sourceTree = "<group>"; };
4B7F188C2154825D00388727 /* MasterSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MasterSystem.cpp; sourceTree = "<group>"; };
4B7F188D2154825D00388727 /* MasterSystem.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MasterSystem.hpp; sourceTree = "<group>"; };
4B7F1895215486A100388727 /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaticAnalyser.hpp; sourceTree = "<group>"; };
@ -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 = "<group>";
@ -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 */,