echo keyboard

This commit is contained in:
sfja 2026-01-14 17:28:59 +01:00
parent da56e9c8cc
commit 99c8c14dc4
6 changed files with 76 additions and 32 deletions

View File

@ -3,6 +3,8 @@
%define KBD_CODE 0x1ffe
%define VCD 0x2000
%define FL_EQ 1 << 1
%define KBD_FLAG_IS_RELEASE 0x1
mov rsp, 0x1000
@ -38,9 +40,13 @@ key_press_int:
mov r0, [0x600]
add r0, r0, VCD
mov r1, [KBC_CODE]
cmp r1, 44 ; spacebar
mov r2, rfl
and r2, r2, FL_EQ
jnz r2, .incr
add r1, r1, 61
mov byte [r0], r1
.incr:
mov r0, [0x600]
add r0, r0, 1
mov [0x600], r0

View File

@ -184,9 +184,6 @@ void Builder::store_byte_reg(Reg dst, uint16_t offset, Reg op2)
i.imm_without_flag(offset);
i.op2_reg(op2);
i.build(*this);
std::println("store_byte_reg = {:08b}{:08b}",
this->m_data[m_ip - 4],
this->m_data[m_ip - 3]);
}
void Builder::store_byte_imm(uint16_t dst, Reg op2)

View File

@ -113,6 +113,8 @@ auto IoDevice::set_char(uint16_t offset, uint8_t value)
{
auto lock = std::lock_guard(mx);
std::println("char = '{}' or '{}'", static_cast<char>(value), value);
SDL_Color* buffer;
int pitch;
int res = SDL_LockTexture(m_texture, NULL, (void**)&buffer, &pitch);

View File

@ -13,10 +13,6 @@ struct SDL_Texture;
namespace vc5 {
namespace events {
}
class IoEvent {
public:
enum class Type {

View File

@ -67,15 +67,15 @@ int main()
l.load_word_imm(r0, 0x600);
l.add_imm(r0, r0, 0x2000);
// l.load_word_imm(r1, 0x1ffe);
// l.add_imm(r1, r1, 61);
l.mov_imm(r1, 'A');
l.nop();
l.nop();
l.load_word_imm(r1, 0x1ffe);
l.cmp_imm(r1, 44);
l.mov_reg(r2, rfl);
l.and_imm(r2, r2, 1 << std::to_underlying(Flag::Eq));
auto to_set_key_press_incr = l.ip();
l.jnz_imm(r2, 0);
l.add_imm(r1, r1, 61);
l.store_byte_reg(r0, 0, r1);
l.nop();
l.nop();
auto key_press_incr = l.ip();
l.load_word_imm(r0, 0x600);
l.add_imm(r0, r0, 1);
l.store_word_imm(0x600, r0);
@ -85,6 +85,8 @@ int main()
l.set_ip(to_set_key_press_int + 2);
l.push(key_press_int);
l.set_ip(to_set_key_press_incr + 2);
l.push(key_press_incr);
l.set_ip(to_set_key_press_int_leave + 2);
l.push(key_press_int_leave);

View File

@ -1,10 +1,15 @@
#include "vm.hpp"
#include <array>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <print>
#include <stdexcept>
#include <string_view>
#include <utility>
using namespace vc5;
using namespace std::literals;
void VM::load(uint16_t offset, const uint8_t* data, size_t data_size)
{
@ -21,6 +26,41 @@ int VM::run()
return result;
}
// if (not m_halted) {
// auto line = std::string();
// do {
// std::print("> ");
// std::cout.flush();
// std::getline(std::cin, line);
//
// if (line == "r") {
// for (uint16_t reg = 0; reg < 10; ++reg) {
// constexpr auto reg_strs = std::array {
// "R0"sv,
// "R1"sv,
// "R2"sv,
// "R3"sv,
// "R4"sv,
// "R5"sv,
// "Rbp"sv,
// "Rsp"sv,
// "Rfl"sv,
// "Rip"sv,
// };
// std::println(" {: <3} | {:04x} {: 5}",
// reg_strs[reg],
// m_regs[reg],
// m_regs[reg]);
// }
// } else if (line.starts_with("p")) {
// uint16_t v
// = std::strtoul(line.c_str() + 2, nullptr, 16) &
// 0xfffe;
// std::println("[{: 4x}] {: 4x}", v, word(v));
// }
// } while (!line.empty());
// }
poll_events();
}
return 0;
@ -109,6 +149,11 @@ struct InsReader {
return static_cast<Reg>(ins >> 7 & 0b111);
}
auto dst() const -> uint16_t
{
return vm->reg(dst_reg());
}
auto op1() const -> uint16_t
{
return vm->reg(op1_reg());
@ -141,14 +186,13 @@ struct InsReader {
}
}
auto mem_addr(uint16_t imm) const -> uint16_t
auto mem_addr(uint16_t base, uint16_t imm) const -> uint16_t
{
bool is_imm = to_u16() >> 6 & 1;
if (is_imm) {
return imm;
}
auto base = op2();
auto offset = static_cast<int16_t>(imm);
if (offset >= 0) {
return base + static_cast<uint16_t>(offset);
@ -168,11 +212,16 @@ int VM::run_instruction()
auto ins = InsReader(*this);
auto op = static_cast<Op>(ins.to_u16() & 0b11'1111);
std::println(" [{: 4x}]: {:04x} {}, r0 = {}",
std::println(
" [{: 2x}]: 0x{:04x} {: <9} {:04b} {:04b} {:04b} {:04b} {:04x}",
ip,
ins.to_u16(),
op_str(op),
m_regs[std::to_underlying(Reg::R0)]);
ins.to_u16() >> 12 & 0xf,
ins.to_u16() >> 8 & 0xf,
ins.to_u16() >> 4 & 0xf,
ins.to_u16() & 0xf,
word(*m_rip));
switch (op) {
case Op::Nop:
@ -201,7 +250,7 @@ int VM::run_instruction()
break;
}
case Op::LoadWord: {
auto addr = ins.mem_addr(eat_word());
auto addr = ins.mem_addr(ins.op2(), eat_word());
if ((addr & 0b1) != 0) {
std::println(stderr,
@ -217,7 +266,7 @@ int VM::run_instruction()
break;
}
case Op::StoreWord: {
auto addr = ins.mem_addr(eat_word());
auto addr = ins.mem_addr(ins.dst(), eat_word());
if ((addr & 0b1) != 0) {
std::println(stderr,
@ -239,14 +288,14 @@ int VM::run_instruction()
break;
}
case Op::LoadByte: {
auto addr = ins.mem_addr(eat_word());
auto addr = ins.mem_addr(ins.op2(), eat_word());
auto reg = ins.dst_reg();
set_reg(reg, byte(addr));
break;
}
case Op::StoreByte: {
auto addr = ins.mem_addr(eat_word());
auto addr = ins.mem_addr(ins.dst(), eat_word());
auto src = ins.op2();
if (m_vcd_loaded) {
@ -412,18 +461,10 @@ void VM::vcd_maybe_send_byte(uint16_t addr, uint8_t value)
return;
constexpr uint16_t screen_size = 40 * 24;
const auto& d = m_vcd_descriptor;
std::println(" addr = {}", addr);
std::println(" printing = {}",
addr >= d.map_base_addr and addr < d.map_base_addr + screen_size);
if (addr >= d.map_base_addr and addr < d.map_base_addr + screen_size) {
std::println(
"printing {} or '{}' at {}", value, static_cast<char>(value), addr);
m_device->set_char(addr - d.map_base_addr, value).value();
}
}