mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Begins keyboard sketches and notes.
This commit is contained in:
parent
3514e537ca
commit
3d9f86c584
92
Machines/Amiga/Keyboard.cpp
Normal file
92
Machines/Amiga/Keyboard.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// Keyboard.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 29/07/2021.
|
||||||
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Keyboard.hpp"
|
||||||
|
|
||||||
|
// Notes to self:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Before
|
||||||
|
// the transmission starts, both KCLK and KDAT are high. The keyboard starts
|
||||||
|
// the transmission by putting out the first data bit (on KDAT), followed by
|
||||||
|
// a pulse on KCLK (low then high); then it puts out the second data bit and
|
||||||
|
// pulses KCLK until all eight data bits have been sent.
|
||||||
|
//
|
||||||
|
// When the computer has received the eighth bit, it must pulse KDAT low for
|
||||||
|
// at least 1 (one) microsecond, as a handshake signal to the keyboard. The
|
||||||
|
// keyboard must be able to detect pulses greater than or equal
|
||||||
|
// to 1 microsecond. Software MUST pulse the line low for 85 microseconds to
|
||||||
|
// ensure compatibility with all keyboard models.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// If the handshake pulse does not arrive within
|
||||||
|
// 143 ms of the last clock of the transmission, the keyboard will assume
|
||||||
|
// that the computer is still waiting for the rest of the transmission and is
|
||||||
|
// therefore out of sync. The keyboard will then attempt to restore sync by
|
||||||
|
// going into "resync mode." In this mode, the keyboard clocks out a 1 and
|
||||||
|
// waits for a handshake pulse. If none arrives within 143 ms, it clocks out
|
||||||
|
// another 1 and waits again.
|
||||||
|
//
|
||||||
|
// The keyboard Hard Resets the Amiga by pulling KCLK low and starting a 500
|
||||||
|
// millisecond timer. When one or more of the keys is released and 500
|
||||||
|
// milliseconds have passed, the keyboard will release KCLK.
|
||||||
|
//
|
||||||
|
// The usual sequence of events will therefore be: power-up; synchronize;
|
||||||
|
// transmit "initiate power-up key stream" ($FD); transmit "terminate key
|
||||||
|
// stream" ($FE).
|
||||||
|
|
||||||
|
using namespace Amiga;
|
||||||
|
|
||||||
|
uint8_t Keyboard::update(uint8_t input) {
|
||||||
|
// If a bit transmission is ongoing, continue that, up to and including
|
||||||
|
// the handshake. If no handshake comes, set a macro state of synchronising.
|
||||||
|
switch(shift_state_) {
|
||||||
|
case ShiftState::Shifting:
|
||||||
|
// The keyboard processor sets the KDAT line about 20 microseconds before it
|
||||||
|
// pulls KCLK low. KCLK stays low for about 20 microseconds, then goes high
|
||||||
|
// again. The processor waits another 20 microseconds before changing KDAT.
|
||||||
|
switch(bit_phase_) {
|
||||||
|
default: break;
|
||||||
|
case 0: lines_ = Lines::Clock | (shift_sequence_ & 1); break;
|
||||||
|
case 20: lines_ = (shift_sequence_ & 1); break;
|
||||||
|
case 40: lines_ = Lines::Clock | (shift_sequence_ & 1); break;
|
||||||
|
}
|
||||||
|
bit_phase_ = (bit_phase_ + 1) % 60;
|
||||||
|
|
||||||
|
if(!bit_phase_) {
|
||||||
|
--bits_remaining_;
|
||||||
|
shift_sequence_ >>= 1;
|
||||||
|
if(!bits_remaining_) {
|
||||||
|
shift_state_ = ShiftState::AwaitingHandshake;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines_;
|
||||||
|
|
||||||
|
case ShiftState::AwaitingHandshake:
|
||||||
|
if(!(input & Lines::Data)) {
|
||||||
|
shift_state_ = ShiftState::Idle;
|
||||||
|
}
|
||||||
|
++bit_phase_;
|
||||||
|
if(bit_phase_ == 143) {
|
||||||
|
// shift_state_ = ShiftState::Synchronising;
|
||||||
|
}
|
||||||
|
return lines_;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(state_) {
|
||||||
|
case State::Startup:
|
||||||
|
bit_phase_ = 0;
|
||||||
|
shift_sequence_ = 0xff;
|
||||||
|
shift_state_ = ShiftState::Shifting;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines_;
|
||||||
|
}
|
45
Machines/Amiga/Keyboard.hpp
Normal file
45
Machines/Amiga/Keyboard.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// Keyboard.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 29/07/2021.
|
||||||
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Keyboard_hpp
|
||||||
|
#define Keyboard_hpp
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Amiga {
|
||||||
|
|
||||||
|
class Keyboard {
|
||||||
|
public:
|
||||||
|
enum Lines: uint8_t {
|
||||||
|
Data = (1 << 0),
|
||||||
|
Clock = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t update(uint8_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class ShiftState {
|
||||||
|
Shifting,
|
||||||
|
AwaitingHandshake,
|
||||||
|
Idle,
|
||||||
|
} shift_state_ = ShiftState::Idle;
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Startup,
|
||||||
|
} state_ = State::Startup;
|
||||||
|
|
||||||
|
int bit_phase_ = 0;
|
||||||
|
uint32_t shift_sequence_ = 0;
|
||||||
|
int bits_remaining_ = 0;
|
||||||
|
|
||||||
|
uint8_t lines_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Keyboard_hpp */
|
@ -584,6 +584,8 @@
|
|||||||
4B9EC0E326AA27BA0060A31F /* Blitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E126AA27BA0060A31F /* Blitter.cpp */; };
|
4B9EC0E326AA27BA0060A31F /* Blitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E126AA27BA0060A31F /* Blitter.cpp */; };
|
||||||
4B9EC0E626AA4A660060A31F /* Chipset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E426AA4A660060A31F /* Chipset.cpp */; };
|
4B9EC0E626AA4A660060A31F /* Chipset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E426AA4A660060A31F /* Chipset.cpp */; };
|
||||||
4B9EC0E726AA4A660060A31F /* Chipset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E426AA4A660060A31F /* Chipset.cpp */; };
|
4B9EC0E726AA4A660060A31F /* Chipset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E426AA4A660060A31F /* Chipset.cpp */; };
|
||||||
|
4B9EC0EA26B384080060A31F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E826B384080060A31F /* Keyboard.cpp */; };
|
||||||
|
4B9EC0EB26B384080060A31F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E826B384080060A31F /* Keyboard.cpp */; };
|
||||||
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11C82272375400701480 /* qltrace.txt.gz */; };
|
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11C82272375400701480 /* qltrace.txt.gz */; };
|
||||||
4B9F11CA2272433900701480 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
|
4B9F11CA2272433900701480 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
|
||||||
4B9F11CC22729B3600701480 /* OPCLOGR2.BIN in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */; };
|
4B9F11CC22729B3600701480 /* OPCLOGR2.BIN in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */; };
|
||||||
@ -1592,6 +1594,8 @@
|
|||||||
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Blitter.cpp; sourceTree = "<group>"; };
|
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Blitter.cpp; sourceTree = "<group>"; };
|
||||||
4B9EC0E426AA4A660060A31F /* Chipset.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Chipset.cpp; sourceTree = "<group>"; };
|
4B9EC0E426AA4A660060A31F /* Chipset.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Chipset.cpp; sourceTree = "<group>"; };
|
||||||
4B9EC0E526AA4A660060A31F /* Chipset.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Chipset.hpp; sourceTree = "<group>"; };
|
4B9EC0E526AA4A660060A31F /* Chipset.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Chipset.hpp; sourceTree = "<group>"; };
|
||||||
|
4B9EC0E826B384080060A31F /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
|
||||||
|
4B9EC0E926B384080060A31F /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
|
||||||
4B9F11C82272375400701480 /* qltrace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = qltrace.txt.gz; sourceTree = "<group>"; };
|
4B9F11C82272375400701480 /* qltrace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = qltrace.txt.gz; sourceTree = "<group>"; };
|
||||||
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = OPCLOGR2.BIN; path = "68000 Coverage/OPCLOGR2.BIN"; sourceTree = "<group>"; };
|
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = OPCLOGR2.BIN; path = "68000 Coverage/OPCLOGR2.BIN"; sourceTree = "<group>"; };
|
||||||
4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZX8081.cpp; sourceTree = "<group>"; };
|
4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZX8081.cpp; sourceTree = "<group>"; };
|
||||||
@ -4275,9 +4279,11 @@
|
|||||||
4BC080D826A25ADA00D03FD8 /* Amiga.cpp */,
|
4BC080D826A25ADA00D03FD8 /* Amiga.cpp */,
|
||||||
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */,
|
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */,
|
||||||
4B9EC0E426AA4A660060A31F /* Chipset.cpp */,
|
4B9EC0E426AA4A660060A31F /* Chipset.cpp */,
|
||||||
|
4B9EC0E826B384080060A31F /* Keyboard.cpp */,
|
||||||
4BC080D726A25ADA00D03FD8 /* Amiga.hpp */,
|
4BC080D726A25ADA00D03FD8 /* Amiga.hpp */,
|
||||||
4B9EC0E026AA260C0060A31F /* Blitter.hpp */,
|
4B9EC0E026AA260C0060A31F /* Blitter.hpp */,
|
||||||
4B9EC0E526AA4A660060A31F /* Chipset.hpp */,
|
4B9EC0E526AA4A660060A31F /* Chipset.hpp */,
|
||||||
|
4B9EC0E926B384080060A31F /* Keyboard.hpp */,
|
||||||
);
|
);
|
||||||
path = Amiga;
|
path = Amiga;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -5286,6 +5292,7 @@
|
|||||||
4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */,
|
4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */,
|
||||||
4B0E04F11FC9EA9500F43484 /* MSX.cpp in Sources */,
|
4B0E04F11FC9EA9500F43484 /* MSX.cpp in Sources */,
|
||||||
4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */,
|
4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */,
|
||||||
|
4B9EC0EB26B384080060A31F /* Keyboard.cpp in Sources */,
|
||||||
4B894521201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
4B894521201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
||||||
4B8318B522D3E548006DB630 /* Macintosh.cpp in Sources */,
|
4B8318B522D3E548006DB630 /* Macintosh.cpp in Sources */,
|
||||||
4B8DF4FA254E36AE00F3433C /* Video.cpp in Sources */,
|
4B8DF4FA254E36AE00F3433C /* Video.cpp in Sources */,
|
||||||
@ -5601,6 +5608,7 @@
|
|||||||
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
|
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
|
||||||
4B1B58FF246E19FD009C171E /* State.cpp in Sources */,
|
4B1B58FF246E19FD009C171E /* State.cpp in Sources */,
|
||||||
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */,
|
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */,
|
||||||
|
4B9EC0EA26B384080060A31F /* Keyboard.cpp in Sources */,
|
||||||
4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */,
|
4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */,
|
||||||
4BC57CD92436A62900FBC404 /* State.cpp in Sources */,
|
4BC57CD92436A62900FBC404 /* State.cpp in Sources */,
|
||||||
4BDA00E622E699B000AC3CD0 /* CSMachine.mm in Sources */,
|
4BDA00E622E699B000AC3CD0 /* CSMachine.mm in Sources */,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user