mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Use BACK state; accept other ACKs at any time.
This commit is contained in:
parent
55f92e2411
commit
0e07f802ac
@ -17,9 +17,13 @@ struct Keyboard {
|
|||||||
Keyboard(HalfDuplexSerial &serial) : serial_(serial) {}
|
Keyboard(HalfDuplexSerial &serial) : serial_(serial) {}
|
||||||
|
|
||||||
void set_key_state(int row, int column, bool is_pressed) {
|
void set_key_state(int row, int column, bool is_pressed) {
|
||||||
// if(!scan_keyboard_) return;
|
if(!scan_keyboard_) return;
|
||||||
// TODO: scan_keyboard_ seems to end up in the wrong state. Investigate.
|
|
||||||
|
|
||||||
|
// Don't waste bandwidth on repeating facts.
|
||||||
|
if(states_[row][column] == is_pressed) return;
|
||||||
|
states_[row][column] = is_pressed;
|
||||||
|
|
||||||
|
// Post new key event.
|
||||||
const uint8_t prefix = is_pressed ? 0b1100'0000 : 0b1101'0000;
|
const uint8_t prefix = is_pressed ? 0b1100'0000 : 0b1101'0000;
|
||||||
enqueue(static_cast<uint8_t>(prefix | row), static_cast<uint8_t>(prefix | column));
|
enqueue(static_cast<uint8_t>(prefix | row), static_cast<uint8_t>(prefix | column));
|
||||||
consider_dequeue();
|
consider_dequeue();
|
||||||
@ -43,6 +47,14 @@ struct Keyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch(phase_) {
|
switch(phase_) {
|
||||||
|
case Phase::ExpectingACK:
|
||||||
|
if(input != NACK && input != SMAK && input != MACK && input != SACK) {
|
||||||
|
reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
phase_ = Phase::Idle;
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
case Phase::Idle:
|
case Phase::Idle:
|
||||||
switch(input) {
|
switch(input) {
|
||||||
case RQID: // Post keyboard ID.
|
case RQID: // Post keyboard ID.
|
||||||
@ -58,14 +70,29 @@ struct Keyboard {
|
|||||||
enqueue(0, 0);
|
enqueue(0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NACK:
|
||||||
|
scan_keyboard_ = scan_mouse_ = false;
|
||||||
|
break;
|
||||||
|
case SMAK:
|
||||||
|
scan_keyboard_ = scan_mouse_ = true;
|
||||||
|
break;
|
||||||
|
case MACK:
|
||||||
|
scan_keyboard_ = false;
|
||||||
|
scan_mouse_ = true;
|
||||||
|
break;
|
||||||
|
case SACK:
|
||||||
|
scan_keyboard_ = true;
|
||||||
|
scan_mouse_ = false;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if((input & 0b1111'0000) == 0b0100'0000) {
|
if((input & 0b1111'0000) == 0b0100'0000) {
|
||||||
// RQPD; request to echo the low nibble.
|
// RQPD; request to echo the low nibble.
|
||||||
serial_.output(KeyboardParty, 0b1110'0000 | (input & 0b1111));
|
serial_.output(KeyboardParty, 0b1110'0000 | (input & 0b1111));
|
||||||
}
|
} else if(!(input & 0b1111'1000)) {
|
||||||
|
|
||||||
if(!(input & 0b1111'1000)) {
|
|
||||||
// LEDS: should set LEd outputs.
|
// LEDS: should set LEd outputs.
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -94,32 +121,9 @@ struct Keyboard {
|
|||||||
reset();
|
reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
dequeue_next();
|
||||||
phase_ = Phase::ExpectingACK;
|
phase_ = Phase::ExpectingACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Phase::ExpectingACK:
|
|
||||||
switch(input) {
|
|
||||||
default:
|
|
||||||
reset();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NACK:
|
|
||||||
scan_keyboard_ = scan_mouse_ = false;
|
|
||||||
break;
|
|
||||||
case SMAK:
|
|
||||||
scan_keyboard_ = scan_mouse_ = true;
|
|
||||||
break;
|
|
||||||
case MACK:
|
|
||||||
scan_keyboard_ = false;
|
|
||||||
scan_mouse_ = true;
|
|
||||||
break;
|
|
||||||
case SACK:
|
|
||||||
scan_keyboard_ = true;
|
|
||||||
scan_mouse_ = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
phase_ = Phase::Idle;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consider_dequeue();
|
consider_dequeue();
|
||||||
@ -127,14 +131,16 @@ struct Keyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void consider_dequeue() {
|
void consider_dequeue() {
|
||||||
if(phase_ == Phase::Idle) {
|
if(phase_ == Phase::Idle && dequeue_next()) {
|
||||||
dequeue_next();
|
phase_ = Phase::ExpectingBACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HalfDuplexSerial &serial_;
|
HalfDuplexSerial &serial_;
|
||||||
|
|
||||||
|
bool states_[16][16]{};
|
||||||
|
|
||||||
bool scan_keyboard_ = false;
|
bool scan_keyboard_ = false;
|
||||||
bool scan_mouse_ = false;
|
bool scan_mouse_ = false;
|
||||||
enum class Phase {
|
enum class Phase {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user