mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 16:30:29 +00:00
Merge pull request #549 from TomHarte/MSXPaste
Simplifies and corrects MSX pasting behaviour.
This commit is contained in:
commit
12e9478a81
@ -298,7 +298,12 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void type_string(const std::string &string) override final {
|
void type_string(const std::string &string) override final {
|
||||||
input_text_ += string;
|
std::transform(
|
||||||
|
string.begin(),
|
||||||
|
string.end(),
|
||||||
|
std::back_inserter(input_text_),
|
||||||
|
[](unsigned char c) -> unsigned char { return (c == '\n') ? '\r' : c; }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: MSX::MemoryMap
|
// MARK: MSX::MemoryMap
|
||||||
@ -500,26 +505,31 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
// Take this as a convenient moment to jump into the keyboard buffer, if desired.
|
// Take this as a convenient moment to jump into the keyboard buffer, if desired.
|
||||||
if(!input_text_.empty()) {
|
if(!input_text_.empty()) {
|
||||||
// TODO: is it safe to assume these addresses?
|
// The following are KEYBUF per the Red Book; its address and its definition as DEFS 40.
|
||||||
const int buffer_start = 0xfbf0;
|
const int buffer_start = 0xfbf0;
|
||||||
const int buffer_end = 0xfb18;
|
const int buffer_size = 40;
|
||||||
|
|
||||||
|
// Also from the Red Book: GETPNT is at F3FAH and PUTPNT is at F3F8H.
|
||||||
int read_address = ram_[0xf3fa] | (ram_[0xf3fb] << 8);
|
int read_address = ram_[0xf3fa] | (ram_[0xf3fb] << 8);
|
||||||
int write_address = ram_[0xf3f8] | (ram_[0xf3f9] << 8);
|
int write_address = ram_[0xf3f8] | (ram_[0xf3f9] << 8);
|
||||||
|
|
||||||
const int buffer_size = buffer_end - buffer_start;
|
// Write until either the string is exhausted or the write_pointer is immediately
|
||||||
int available_space = write_address + buffer_size - read_address - 1;
|
// behind the read pointer; temporarily map write_address and read_address into
|
||||||
|
// buffer-relative values.
|
||||||
const std::size_t characters_to_write = std::min(static_cast<std::size_t>(available_space), input_text_.size());
|
std::size_t characters_written = 0;
|
||||||
write_address -= buffer_start;
|
write_address -= buffer_start;
|
||||||
for(std::size_t c = 0; c < characters_to_write; ++c) {
|
read_address -= buffer_start;
|
||||||
char character = input_text_[c];
|
while(characters_written < input_text_.size()) {
|
||||||
ram_[write_address + buffer_start] = static_cast<uint8_t>(character);
|
const int next_write_address = (write_address + 1) % buffer_size;
|
||||||
write_address = (write_address + 1) % buffer_size;
|
if(next_write_address == read_address) break;
|
||||||
|
ram_[write_address + buffer_start] = static_cast<uint8_t>(input_text_[characters_written]);
|
||||||
|
++characters_written;
|
||||||
|
write_address = next_write_address;
|
||||||
}
|
}
|
||||||
write_address += buffer_start;
|
input_text_.erase(input_text_.begin(), input_text_.begin() + static_cast<std::string::difference_type>(characters_written));
|
||||||
input_text_.erase(input_text_.begin(), input_text_.begin() + static_cast<std::string::difference_type>(characters_to_write));
|
|
||||||
|
|
||||||
|
// Map the write address back into absolute terms and write it out again as PUTPNT.
|
||||||
|
write_address += buffer_start;
|
||||||
ram_[0xf3f8] = static_cast<uint8_t>(write_address);
|
ram_[0xf3f8] = static_cast<uint8_t>(write_address);
|
||||||
ram_[0xf3f9] = static_cast<uint8_t>(write_address >> 8);
|
ram_[0xf3f9] = static_cast<uint8_t>(write_address >> 8);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user