From 363db695e85d38fb9871f1f43e068b6899263358 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Tue, 22 Nov 2016 08:12:53 +0800
Subject: [PATCH] Started implementation of the Microdisc selection logic.

---
 Machines/Oric/Microdisc.cpp                   | 62 +++++++++++++++++++
 Machines/Oric/Microdisc.hpp                   | 35 +++++++++++
 .../Clock Signal.xcodeproj/project.pbxproj    |  6 ++
 3 files changed, 103 insertions(+)
 create mode 100644 Machines/Oric/Microdisc.cpp
 create mode 100644 Machines/Oric/Microdisc.hpp

diff --git a/Machines/Oric/Microdisc.cpp b/Machines/Oric/Microdisc.cpp
new file mode 100644
index 000000000..00454cd19
--- /dev/null
+++ b/Machines/Oric/Microdisc.cpp
@@ -0,0 +1,62 @@
+//
+//  Microdisc.cpp
+//  Clock Signal
+//
+//  Created by Thomas Harte on 22/11/2016.
+//  Copyright © 2016 Thomas Harte. All rights reserved.
+//
+
+#include "Microdisc.hpp"
+
+using namespace Oric;
+
+Microdisc::Microdisc() : irq_enable_(false)
+{}
+
+void Microdisc::set_disk(std::shared_ptr<Storage::Disk::Disk> disk, int drive)
+{
+	if(!drives_[drive])
+	{
+		drives_[drive].reset(new Storage::Disk::Drive);
+		if(drive == selected_drive_) set_drive(drives_[drive]);
+	}
+	drives_[drive]->set_disk(disk);
+}
+
+void Microdisc::set_control_register(uint8_t control)
+{
+	// b7: EPROM select (0 = select)
+	// b2: data separator clock rate select (1 = double)
+	// b1: ROM disable (0 = disable)
+
+	// b65: drive select
+	selected_drive_ = (control >> 5)&3;
+	set_drive(drives_[selected_drive_]);
+
+	// b4: side select
+	for(int c = 0; c < 4; c++)
+	{
+		if(drives_[c]) drives_[c]->set_head((control & 0x10) ? 1 : 0);
+	}
+
+	// b3: double density select (0 = double)
+	set_is_double_density(!(control & 0x08));
+
+	// b0: IRQ enable
+	irq_enable_ = !(control & 0x01);
+}
+
+bool Microdisc::get_interrupt_request_line()
+{
+	return irq_enable_ && WD1770::get_interrupt_request_line();
+}
+
+uint8_t Microdisc::get_interrupt_request_register()
+{
+	return get_interrupt_request_line() ? 0x00 : 0x80;
+}
+
+uint8_t Microdisc::get_data_request_register()
+{
+	return get_data_request_line() ? 0x00 : 0x80;
+}
diff --git a/Machines/Oric/Microdisc.hpp b/Machines/Oric/Microdisc.hpp
new file mode 100644
index 000000000..ec728c48e
--- /dev/null
+++ b/Machines/Oric/Microdisc.hpp
@@ -0,0 +1,35 @@
+//
+//  Microdisc.hpp
+//  Clock Signal
+//
+//  Created by Thomas Harte on 22/11/2016.
+//  Copyright © 2016 Thomas Harte. All rights reserved.
+//
+
+#ifndef Microdisc_hpp
+#define Microdisc_hpp
+
+#include "../../Components/1770/1770.hpp"
+
+namespace Oric {
+
+class Microdisc: public WD::WD1770 {
+	public:
+		Microdisc();
+
+		void set_disk(std::shared_ptr<Storage::Disk::Disk> disk, int drive);
+		void set_control_register(uint8_t control);
+		uint8_t get_interrupt_request_register();
+		uint8_t get_data_request_register();
+
+		bool get_interrupt_request_line();
+
+	private:
+		std::shared_ptr<Storage::Disk::Drive> drives_[4];
+		int selected_drive_;
+		bool irq_enable_;
+};
+
+}
+
+#endif /* Microdisc_hpp */
diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj
index 7d87faa4b..11eccdc41 100644
--- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj	
+++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj	
@@ -55,6 +55,7 @@
 		4B5A12571DD55862007A2231 /* Disassembler6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A12551DD55862007A2231 /* Disassembler6502.cpp */; };
 		4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADB81DE3151600AEC565 /* FileHolder.cpp */; };
 		4B5FADBD1DE31D1500AEC565 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBB1DE31D1500AEC565 /* OricMFMDSK.cpp */; };
+		4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; };
 		4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */; };
 		4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F3E1D77B88000D431D6 /* DocumentController.swift */; };
 		4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; };
@@ -505,6 +506,8 @@
 		4B5FADB91DE3151600AEC565 /* FileHolder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileHolder.hpp; sourceTree = "<group>"; };
 		4B5FADBB1DE31D1500AEC565 /* OricMFMDSK.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OricMFMDSK.cpp; sourceTree = "<group>"; };
 		4B5FADBC1DE31D1500AEC565 /* OricMFMDSK.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OricMFMDSK.hpp; sourceTree = "<group>"; };
+		4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Microdisc.cpp; path = Oric/Microdisc.cpp; sourceTree = "<group>"; };
+		4B5FADBF1DE3BF2B00AEC565 /* Microdisc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Microdisc.hpp; path = Oric/Microdisc.hpp; sourceTree = "<group>"; };
 		4B643F381D77AD1900D431D6 /* CSStaticAnalyser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSStaticAnalyser.h; path = StaticAnalyser/CSStaticAnalyser.h; sourceTree = "<group>"; };
 		4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CSStaticAnalyser.mm; path = StaticAnalyser/CSStaticAnalyser.mm; sourceTree = "<group>"; };
 		4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSMachine+Target.h"; sourceTree = "<group>"; };
@@ -1791,6 +1794,8 @@
 		4BCF1FA51DADC3E10039D2E7 /* Oric */ = {
 			isa = PBXGroup;
 			children = (
+				4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */,
+				4B5FADBF1DE3BF2B00AEC565 /* Microdisc.hpp */,
 				4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */,
 				4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */,
 				4BC8A6291DCE4F2700DAC693 /* Typer.cpp */,
@@ -2379,6 +2384,7 @@
 				4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */,
 				4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */,
 				4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */,
+				4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */,
 				4BEE0A701D72496600532C7B /* PRG.cpp in Sources */,
 				4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */,
 				4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,