mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Adds basic, incomplete dispatcher for the intelligent keyboard.
This commit is contained in:
parent
cf07982a9b
commit
75c3e2dacd
@ -40,13 +40,14 @@ class IntelligentKeyboard:
|
||||
public:
|
||||
IntelligentKeyboard(Serial::Line &input, Serial::Line &output) : output_line_(output) {
|
||||
input.set_read_delegate(this, Storage::Time(2, 15625));
|
||||
output_line_.set_writer_clock_rate(15625);
|
||||
}
|
||||
|
||||
bool serial_line_did_produce_bit(Serial::Line *, int bit) final {
|
||||
command_ = (command_ >> 1) | (bit << 9);
|
||||
bit_count_ = (bit_count_ + 1) % 10;
|
||||
if(!bit_count_) {
|
||||
LOG("[IKBD] Should perform " << PADHEX(2) << ((command_ >> 1) & 0xff));
|
||||
dispatch_command(uint8_t(command_ >> 1));
|
||||
command_ = 0;
|
||||
return false;
|
||||
}
|
||||
@ -54,10 +55,148 @@ class IntelligentKeyboard:
|
||||
}
|
||||
|
||||
private:
|
||||
// MARK: - Serial line state.
|
||||
int bit_count_ = 0;
|
||||
int command_ = 0;
|
||||
Serial::Line &output_line_;
|
||||
float bit_offset_ = 0.0f;
|
||||
|
||||
void output_byte(uint8_t value) {
|
||||
// Wrap the value in a start and stop bit, and send it on its way.
|
||||
output_line_.write(2, 10, 0x200 | (value << 1));
|
||||
}
|
||||
|
||||
// MARK: - Command dispatch.
|
||||
std::vector<uint8_t> command_sequence_;
|
||||
void dispatch_command(uint8_t command) {
|
||||
// Enqueue for parsing.
|
||||
command_sequence_.push_back(command);
|
||||
|
||||
// For each possible command, check that the proper number of bytes are present.
|
||||
// If not, exit. If so, perform and drop out of the switch.
|
||||
switch(command_sequence_.front()) {
|
||||
default:
|
||||
printf("Unrecognised IKBD command %02x\n", command);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
/*
|
||||
Reset: 0x80 0x01.
|
||||
"Any byte following an 0x80 command byte other than 0x01 is ignored (and causes the 0x80 to be ignored)."
|
||||
*/
|
||||
if(command_sequence_.size() != 2) return;
|
||||
if(command_sequence_[1] == 0x01) {
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if(command_sequence_.size() != 2) return;
|
||||
set_mouse_button_actions(command_sequence_[1]);
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
set_relative_mouse_position_reporting();
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
if(command_sequence_.size() != 5) return;
|
||||
set_absolute_mouse_position_reporting(
|
||||
uint16_t((command_sequence_[1] << 8) | command_sequence_[2]),
|
||||
uint16_t((command_sequence_[3] << 8) | command_sequence_[4])
|
||||
);
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
if(command_sequence_.size() != 3) return;
|
||||
set_mouse_keycode_reporting(command_sequence_[1], command_sequence_[2]);
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
if(command_sequence_.size() != 3) return;
|
||||
set_mouse_threshold(command_sequence_[1], command_sequence_[2]);
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
if(command_sequence_.size() != 3) return;
|
||||
set_mouse_scale(command_sequence_[1], command_sequence_[2]);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
interrogate_mouse_position();
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
if(command_sequence_.size() != 6) return;
|
||||
/* command_sequence_[1] has no defined meaning. */
|
||||
set_mouse_position(
|
||||
uint16_t((command_sequence_[2] << 8) | command_sequence_[3]),
|
||||
uint16_t((command_sequence_[4] << 8) | command_sequence_[5])
|
||||
);
|
||||
break;
|
||||
|
||||
case 0x0f: set_mouse_y_upward(); break;
|
||||
case 0x10: set_mouse_y_downward(); break;
|
||||
case 0x11: resume(); break;
|
||||
case 0x12: disable_mouse(); break;
|
||||
case 0x13: pause(); break;
|
||||
case 0x1a: disable_joysticks(); break;
|
||||
}
|
||||
|
||||
// There was no premature exit, so a complete command sequence must have been satisfied.
|
||||
command_sequence_.clear();
|
||||
}
|
||||
|
||||
// MARK: - Flow control.
|
||||
void reset() {
|
||||
// Reset should perform a self test, lasting at most 200ms, then post 0xf0.
|
||||
// Following that it should look for any keys that currently seem to be pressed.
|
||||
// Those are considered stuck and a break code is generated for them.
|
||||
output_byte(0xf0);
|
||||
}
|
||||
|
||||
void resume() {
|
||||
}
|
||||
|
||||
void pause() {
|
||||
}
|
||||
|
||||
// MARK: - Mouse commands.
|
||||
void disable_mouse() {
|
||||
}
|
||||
|
||||
void set_relative_mouse_position_reporting() {
|
||||
}
|
||||
|
||||
void set_absolute_mouse_position_reporting(uint16_t max_x, uint16_t max_y) {
|
||||
}
|
||||
|
||||
void set_mouse_position(uint16_t x, uint16_t y) {
|
||||
}
|
||||
|
||||
void set_mouse_keycode_reporting(uint8_t delta_x, uint8_t delta_y) {
|
||||
}
|
||||
|
||||
void set_mouse_threshold(uint8_t x, uint8_t y) {
|
||||
}
|
||||
|
||||
void set_mouse_scale(uint8_t x, uint8_t y) {
|
||||
}
|
||||
|
||||
void set_mouse_y_downward() {
|
||||
}
|
||||
|
||||
void set_mouse_y_upward() {
|
||||
}
|
||||
|
||||
void set_mouse_button_actions(uint8_t actions) {
|
||||
}
|
||||
|
||||
void interrogate_mouse_position() {
|
||||
}
|
||||
|
||||
// MARK: - Joystick commands.
|
||||
void disable_joysticks() {
|
||||
}
|
||||
};
|
||||
|
||||
using Target = Analyser::Static::Target;
|
||||
@ -396,7 +535,6 @@ class ConcreteMachine:
|
||||
|
||||
// TODO: push v/hsync/display_enable elsewhere.
|
||||
mfp_->set_timer_event_input(1, video_->display_enabled());
|
||||
// printf("%c%c%c\n", video_->display_enabled() ? 'e' : '-', video_->hsync() ? 'h' : '-', video_->vsync() ? 'v' : '-');
|
||||
}
|
||||
cycles_until_video_event_ -= length;
|
||||
video_ += length;
|
||||
|
Loading…
Reference in New Issue
Block a user