1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-08 10:52:58 +00:00

Adds a class to contain the Disk II and begins Apple GCR conversion routines.

This commit is contained in:
Thomas Harte 2018-04-21 14:33:42 -07:00
parent 0a0d81cd5a
commit 72bc5f8d7b
9 changed files with 184 additions and 3 deletions

View File

@ -0,0 +1,9 @@
//
// DiskII.cpp
// Clock Signal
//
// Created by Thomas Harte on 20/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "DiskII.hpp"

View File

@ -0,0 +1,40 @@
//
// DiskII.hpp
// Clock Signal
//
// Created by Thomas Harte on 20/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef DiskII_hpp
#define DiskII_hpp
#include "../../ClockReceiver/ClockReceiver.hpp"
#include <cstdint>
namespace Apple {
/*!
Provides an emulation of the Apple Disk II.
*/
class DiskII {
public:
enum class Control {
P0, P1, P2, P3,
Motor,
};
enum class Mode {
Read, Write
};
void set_control(Control control, bool on);
void set_mode(Mode mode);
void select_drive(int drive);
void set_shift_register(uint8_t value);
uint8_t get_shift_register();
void run_for(const Cycles cycles);
};
}
#endif /* DiskII_hpp */

View File

@ -157,6 +157,8 @@
4B2C45421E3C3896002A2389 /* cartridge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B2C45411E3C3896002A2389 /* cartridge.png */; };
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; };
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
4B302184208A550100773308 /* DiskII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B302183208A550100773308 /* DiskII.cpp */; };
4B302185208A550100773308 /* DiskII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B302183208A550100773308 /* DiskII.cpp */; };
4B30512D1D989E2200B4FED8 /* Drive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512B1D989E2200B4FED8 /* Drive.cpp */; };
4B3051301D98ACC600B4FED8 /* Plus3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512E1D98ACC600B4FED8 /* Plus3.cpp */; };
4B322E011F5A2990004EB04C /* Z80AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322DFD1F5A2981004EB04C /* Z80AllRAM.cpp */; };
@ -579,6 +581,8 @@
4BB299F81B587D8400A49093 /* txsn in Resources */ = {isa = PBXBuildFile; fileRef = 4BB298EC1B587D8400A49093 /* txsn */; };
4BB299F91B587D8400A49093 /* tyan in Resources */ = {isa = PBXBuildFile; fileRef = 4BB298ED1B587D8400A49093 /* tyan */; };
4BB2A9AF1E13367E001A5C23 /* CRCTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */; };
4BB2CB2A208BDDCF00FD192E /* AppleGCR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB2CB28208BDDCF00FD192E /* AppleGCR.cpp */; };
4BB2CB2B208BDDCF00FD192E /* AppleGCR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB2CB28208BDDCF00FD192E /* AppleGCR.cpp */; };
4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697C91D4B6D3E00248BDF /* TimedEventLoop.cpp */; };
4BB697CE1D4BA44400248BDF /* CommodoreGCR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697CC1D4BA44400248BDF /* CommodoreGCR.cpp */; };
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EA11B587A5100552FC2 /* AppDelegate.swift */; };
@ -754,6 +758,8 @@
4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = "<group>"; };
4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = "<group>"; };
4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = "<group>"; };
4B302182208A550100773308 /* DiskII.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiskII.hpp; sourceTree = "<group>"; };
4B302183208A550100773308 /* DiskII.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiskII.cpp; sourceTree = "<group>"; };
4B30512B1D989E2200B4FED8 /* Drive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drive.cpp; sourceTree = "<group>"; };
4B30512C1D989E2200B4FED8 /* Drive.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Drive.hpp; sourceTree = "<group>"; };
4B30512E1D98ACC600B4FED8 /* Plus3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Plus3.cpp; path = Electron/Plus3.cpp; sourceTree = "<group>"; };
@ -1275,6 +1281,8 @@
4BB298EC1B587D8400A49093 /* txsn */ = {isa = PBXFileReference; lastKnownFileType = file; path = txsn; sourceTree = "<group>"; };
4BB298ED1B587D8400A49093 /* tyan */ = {isa = PBXFileReference; lastKnownFileType = file; path = tyan; sourceTree = "<group>"; };
4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CRCTests.mm; sourceTree = "<group>"; };
4BB2CB28208BDDCF00FD192E /* AppleGCR.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AppleGCR.cpp; path = Encodings/AppleGCR.cpp; sourceTree = "<group>"; };
4BB2CB29208BDDCF00FD192E /* AppleGCR.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = AppleGCR.hpp; path = Encodings/AppleGCR.hpp; sourceTree = "<group>"; };
4BB697C61D4B558F00248BDF /* Factors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Factors.hpp; path = ../../NumberTheory/Factors.hpp; sourceTree = "<group>"; };
4BB697C91D4B6D3E00248BDF /* TimedEventLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimedEventLoop.cpp; sourceTree = "<group>"; };
4BB697CA1D4B6D3E00248BDF /* TimedEventLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TimedEventLoop.hpp; sourceTree = "<group>"; };
@ -1674,6 +1682,15 @@
name = Electron;
sourceTree = "<group>";
};
4B302181208A550100773308 /* DiskII */ = {
isa = PBXGroup;
children = (
4B302182208A550100773308 /* DiskII.hpp */,
4B302183208A550100773308 /* DiskII.cpp */,
);
path = DiskII;
sourceTree = "<group>";
};
4B31B88E1FBFBCD800C140D5 /* Configurable */ = {
isa = PBXGroup;
children = (
@ -2630,9 +2647,11 @@
4BB697CF1D4BA44900248BDF /* Encodings */ = {
isa = PBXGroup;
children = (
4B7136831F78724F008B8ED9 /* MFM */,
4BB2CB28208BDDCF00FD192E /* AppleGCR.cpp */,
4BB697CC1D4BA44400248BDF /* CommodoreGCR.cpp */,
4BB2CB29208BDDCF00FD192E /* AppleGCR.hpp */,
4BB697CD1D4BA44400248BDF /* CommodoreGCR.hpp */,
4B7136831F78724F008B8ED9 /* MFM */,
);
name = Encodings;
sourceTree = "<group>";
@ -2850,6 +2869,7 @@
4BC9DF4A1D04691600F44158 /* Components */ = {
isa = PBXGroup;
children = (
4B302181208A550100773308 /* DiskII */,
4B595FAA2086DFBA0083CAA8 /* AudioToggle */,
4BD468F81D8DF4290084958B /* 1770 */,
4BC9DF4B1D04691600F44158 /* 6522 */,
@ -3598,6 +3618,7 @@
4B894525201967B4007DE474 /* Tape.cpp in Sources */,
4B055ACD1FAE9B030060FFFF /* Keyboard.cpp in Sources */,
4B055AB21FAE860F0060FFFF /* CommodoreTAP.cpp in Sources */,
4BB2CB2B208BDDCF00FD192E /* AppleGCR.cpp in Sources */,
4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */,
4B055AB51FAE860F0060FFFF /* TapePRG.cpp in Sources */,
4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */,
@ -3623,6 +3644,7 @@
4BB0A65C2044FD3000FB3688 /* SN76489.cpp in Sources */,
4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */,
4B302185208A550100773308 /* DiskII.cpp in Sources */,
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */,
4B89452D201967B4007DE474 /* Tape.cpp in Sources */,
4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */,
@ -3654,6 +3676,7 @@
4B4518A01F75FD1C00926311 /* CPCDSK.cpp in Sources */,
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
4B322E041F5A2E3C004EB04C /* Z80Base.cpp in Sources */,
4BB2CB2A208BDDCF00FD192E /* AppleGCR.cpp in Sources */,
4B894530201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B4518A31F75FD1C00926311 /* HFE.cpp in Sources */,
4B1B88BB202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */,
@ -3707,6 +3730,7 @@
4B448E811F1C45A00009ABD6 /* TZX.cpp in Sources */,
4BEBFB512002DB30000708CC /* DiskROM.cpp in Sources */,
4B89451C201967B4007DE474 /* Disk.cpp in Sources */,
4B302184208A550100773308 /* DiskII.cpp in Sources */,
4BEA52631DF339D7007E74F2 /* SoundGenerator.cpp in Sources */,
4BAE495920328897004BE78E /* ZX8081OptionsPanel.swift in Sources */,
4B89451A201967B4007DE474 /* ConfidenceSummary.cpp in Sources */,

View File

@ -68,7 +68,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"

View File

@ -34,6 +34,7 @@ SOURCES += glob.glob('../../Components/9918/*.cpp')
SOURCES += glob.glob('../../Components/9918/Implementation/*.cpp')
SOURCES += glob.glob('../../Components/AudioToggle/*.cpp')
SOURCES += glob.glob('../../Components/AY38910/*.cpp')
SOURCES += glob.glob('../../Components/DiskII/*.cpp')
SOURCES += glob.glob('../../Components/KonamiSCC/*.cpp')
SOURCES += glob.glob('../../Components/SN76489/*.cpp')

View File

@ -6,3 +6,4 @@ basic10.rom
basic11.rom
colour.rom
microdisc.rom
8dos.rom

View File

@ -0,0 +1,53 @@
//
// AppleGCR.cpp
// Clock Signal
//
// Created by Thomas Harte on 21/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "AppleGCR.hpp"
using namespace Storage::Encodings;
unsigned int AppleGCR::five_and_three_encoding_for_value(int value) {
static const unsigned int values[] = {
0xab, 0xad, 0xae, 0xaf, 0xb5, 0xb6, 0xb7, 0xba,
0xbb, 0xbd, 0xbe, 0xbf, 0xd6, 0xd7, 0xda, 0xdb,
0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xed, 0xee, 0xef,
0xf5, 0xf6, 0xf7, 0xfa, 0xfb, 0xfd, 0xfe, 0xff
};
return values[value & 0x1f];
}
void AppleGCR::encode_five_and_three_block(uint8_t *destination, uint8_t *source) {
destination[0] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[0] >> 3 ));
destination[1] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[0] << 2) | (source[1] >> 6) ));
destination[2] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[1] >> 1 ));
destination[3] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[1] << 4) | (source[2] >> 4) ));
destination[4] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[2] << 1) | (source[3] >> 7) ));
destination[5] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[3] >> 2 ));
destination[6] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[3] << 3) | (source[4] >> 5) ));
destination[7] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[4] ));
}
unsigned int AppleGCR::six_and_two_encoding_for_value(int value) {
static const unsigned int values[] = {
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
return values[value & 0x3f];
}
void AppleGCR::encode_six_and_two_block(uint8_t *destination, uint8_t *source) {
destination[0] = static_cast<uint8_t>(six_and_two_encoding_for_value( source[0] >> 2 ));
destination[1] = static_cast<uint8_t>(six_and_two_encoding_for_value( (source[0] << 4) | (source[1] >> 4) ));
destination[2] = static_cast<uint8_t>(six_and_two_encoding_for_value( (source[1] << 2) | (source[2] >> 6) ));
destination[3] = static_cast<uint8_t>(six_and_two_encoding_for_value( source[2] ));
}

View File

@ -0,0 +1,53 @@
//
// AppleGCR.hpp
// Clock Signal
//
// Created by Thomas Harte on 21/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef AppleGCR_hpp
#define AppleGCR_hpp
#include <cstdint>
namespace Storage {
namespace Encodings {
namespace AppleGCR {
/*!
@returns the eight-bit 13-sector GCR encoding for the low five bits of @c value.
*/
unsigned int five_and_three_encoding_for_value(int value);
/*!
@returns the eight-bit 16-sector GCR encoding for the low six bits of @c value.
*/
unsigned int six_and_two_encoding_for_value(int value);
/*!
A block is defined to be five source bytes, which encodes to eight GCR bytes.
*/
void encode_five_and_three_block(uint8_t *destination, uint8_t *source);
/*!
A block is defined to be three source bytes, which encodes to four GCR bytes.
*/
void encode_six_and_two_block(uint8_t *destination, uint8_t *source);
/*!
@returns the four bit nibble for the five-bit GCR @c quintet if a valid GCR value; INT_MAX otherwise.
*/
// unsigned int decoding_from_quintet(unsigned int quintet);
/*!
@returns the byte composed by splitting the dectet into two qintets, decoding each and composing the resulting nibbles.
*/
// unsigned int decoding_from_dectet(unsigned int dectet);
}
}
}
#endif /* AppleGCR_hpp */

View File

@ -43,7 +43,7 @@ namespace CommodoreGCR {
unsigned int decoding_from_quintet(unsigned int quintet);
/*!
@returns the byte composted of the low five bit five-bit GCR
@returns the byte composed by splitting the dectet into two qintets, decoding each and composing the resulting nibbles.
*/
unsigned int decoding_from_dectet(unsigned int dectet);
}