echo keyboard
This commit is contained in:
parent
da56e9c8cc
commit
99c8c14dc4
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -13,10 +13,6 @@ struct SDL_Texture;
|
||||
|
||||
namespace vc5 {
|
||||
|
||||
namespace events {
|
||||
|
||||
}
|
||||
|
||||
class IoEvent {
|
||||
public:
|
||||
enum class Type {
|
||||
|
||||
18
src/main.cpp
18
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);
|
||||
|
||||
|
||||
73
src/vm.cpp
73
src/vm.cpp
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user