From 99c8c14dc4bf9cf911c7a4d47e1db8709c7f880c Mon Sep 17 00:00:00 2001 From: sfja Date: Wed, 14 Jan 2026 17:28:59 +0100 Subject: [PATCH] echo keyboard --- programs/echo_keyboard.txt | 8 ++++- src/builder.cpp | 3 -- src/io_device.cpp | 2 ++ src/io_device.hpp | 4 --- src/main.cpp | 18 +++++----- src/vm.cpp | 73 +++++++++++++++++++++++++++++--------- 6 files changed, 76 insertions(+), 32 deletions(-) diff --git a/programs/echo_keyboard.txt b/programs/echo_keyboard.txt index 334888f..05dab56 100644 --- a/programs/echo_keyboard.txt +++ b/programs/echo_keyboard.txt @@ -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 diff --git a/src/builder.cpp b/src/builder.cpp index 78cac52..3bfbf08 100644 --- a/src/builder.cpp +++ b/src/builder.cpp @@ -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) diff --git a/src/io_device.cpp b/src/io_device.cpp index e5f7e17..cebfa8c 100644 --- a/src/io_device.cpp +++ b/src/io_device.cpp @@ -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(value), value); + SDL_Color* buffer; int pitch; int res = SDL_LockTexture(m_texture, NULL, (void**)&buffer, &pitch); diff --git a/src/io_device.hpp b/src/io_device.hpp index aa5be75..bb1825c 100644 --- a/src/io_device.hpp +++ b/src/io_device.hpp @@ -13,10 +13,6 @@ struct SDL_Texture; namespace vc5 { -namespace events { - -} - class IoEvent { public: enum class Type { diff --git a/src/main.cpp b/src/main.cpp index 05758f0..9e2da60 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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); diff --git a/src/vm.cpp b/src/vm.cpp index bb548e7..80c494e 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1,10 +1,15 @@ #include "vm.hpp" +#include #include +#include +#include #include #include +#include #include 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(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(imm); if (offset >= 0) { return base + static_cast(offset); @@ -168,11 +212,16 @@ int VM::run_instruction() auto ins = InsReader(*this); auto op = static_cast(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(value), addr); - m_device->set_char(addr - d.map_base_addr, value).value(); } }