echo keyboard
This commit is contained in:
parent
da56e9c8cc
commit
99c8c14dc4
@ -3,6 +3,8 @@
|
|||||||
%define KBD_CODE 0x1ffe
|
%define KBD_CODE 0x1ffe
|
||||||
%define VCD 0x2000
|
%define VCD 0x2000
|
||||||
|
|
||||||
|
%define FL_EQ 1 << 1
|
||||||
|
|
||||||
%define KBD_FLAG_IS_RELEASE 0x1
|
%define KBD_FLAG_IS_RELEASE 0x1
|
||||||
|
|
||||||
mov rsp, 0x1000
|
mov rsp, 0x1000
|
||||||
@ -38,9 +40,13 @@ key_press_int:
|
|||||||
mov r0, [0x600]
|
mov r0, [0x600]
|
||||||
add r0, r0, VCD
|
add r0, r0, VCD
|
||||||
mov r1, [KBC_CODE]
|
mov r1, [KBC_CODE]
|
||||||
|
cmp r1, 44 ; spacebar
|
||||||
|
mov r2, rfl
|
||||||
|
and r2, r2, FL_EQ
|
||||||
|
jnz r2, .incr
|
||||||
add r1, r1, 61
|
add r1, r1, 61
|
||||||
mov byte [r0], r1
|
mov byte [r0], r1
|
||||||
|
.incr:
|
||||||
mov r0, [0x600]
|
mov r0, [0x600]
|
||||||
add r0, r0, 1
|
add r0, r0, 1
|
||||||
mov [0x600], r0
|
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.imm_without_flag(offset);
|
||||||
i.op2_reg(op2);
|
i.op2_reg(op2);
|
||||||
i.build(*this);
|
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)
|
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);
|
auto lock = std::lock_guard(mx);
|
||||||
|
|
||||||
|
std::println("char = '{}' or '{}'", static_cast<char>(value), value);
|
||||||
|
|
||||||
SDL_Color* buffer;
|
SDL_Color* buffer;
|
||||||
int pitch;
|
int pitch;
|
||||||
int res = SDL_LockTexture(m_texture, NULL, (void**)&buffer, &pitch);
|
int res = SDL_LockTexture(m_texture, NULL, (void**)&buffer, &pitch);
|
||||||
|
|||||||
@ -13,10 +13,6 @@ struct SDL_Texture;
|
|||||||
|
|
||||||
namespace vc5 {
|
namespace vc5 {
|
||||||
|
|
||||||
namespace events {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class IoEvent {
|
class IoEvent {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
|||||||
18
src/main.cpp
18
src/main.cpp
@ -67,15 +67,15 @@ int main()
|
|||||||
|
|
||||||
l.load_word_imm(r0, 0x600);
|
l.load_word_imm(r0, 0x600);
|
||||||
l.add_imm(r0, r0, 0x2000);
|
l.add_imm(r0, r0, 0x2000);
|
||||||
// l.load_word_imm(r1, 0x1ffe);
|
l.load_word_imm(r1, 0x1ffe);
|
||||||
// l.add_imm(r1, r1, 61);
|
l.cmp_imm(r1, 44);
|
||||||
l.mov_imm(r1, 'A');
|
l.mov_reg(r2, rfl);
|
||||||
l.nop();
|
l.and_imm(r2, r2, 1 << std::to_underlying(Flag::Eq));
|
||||||
l.nop();
|
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.store_byte_reg(r0, 0, r1);
|
||||||
l.nop();
|
auto key_press_incr = l.ip();
|
||||||
l.nop();
|
|
||||||
|
|
||||||
l.load_word_imm(r0, 0x600);
|
l.load_word_imm(r0, 0x600);
|
||||||
l.add_imm(r0, r0, 1);
|
l.add_imm(r0, r0, 1);
|
||||||
l.store_word_imm(0x600, r0);
|
l.store_word_imm(0x600, r0);
|
||||||
@ -85,6 +85,8 @@ int main()
|
|||||||
|
|
||||||
l.set_ip(to_set_key_press_int + 2);
|
l.set_ip(to_set_key_press_int + 2);
|
||||||
l.push(key_press_int);
|
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.set_ip(to_set_key_press_int_leave + 2);
|
||||||
l.push(key_press_int_leave);
|
l.push(key_press_int_leave);
|
||||||
|
|
||||||
|
|||||||
73
src/vm.cpp
73
src/vm.cpp
@ -1,10 +1,15 @@
|
|||||||
#include "vm.hpp"
|
#include "vm.hpp"
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
#include <print>
|
#include <print>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace vc5;
|
using namespace vc5;
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
void VM::load(uint16_t offset, const uint8_t* data, size_t data_size)
|
void VM::load(uint16_t offset, const uint8_t* data, size_t data_size)
|
||||||
{
|
{
|
||||||
@ -21,6 +26,41 @@ int VM::run()
|
|||||||
return result;
|
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();
|
poll_events();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -109,6 +149,11 @@ struct InsReader {
|
|||||||
return static_cast<Reg>(ins >> 7 & 0b111);
|
return static_cast<Reg>(ins >> 7 & 0b111);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto dst() const -> uint16_t
|
||||||
|
{
|
||||||
|
return vm->reg(dst_reg());
|
||||||
|
}
|
||||||
|
|
||||||
auto op1() const -> uint16_t
|
auto op1() const -> uint16_t
|
||||||
{
|
{
|
||||||
return vm->reg(op1_reg());
|
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;
|
bool is_imm = to_u16() >> 6 & 1;
|
||||||
if (is_imm) {
|
if (is_imm) {
|
||||||
return imm;
|
return imm;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto base = op2();
|
|
||||||
auto offset = static_cast<int16_t>(imm);
|
auto offset = static_cast<int16_t>(imm);
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
return base + static_cast<uint16_t>(offset);
|
return base + static_cast<uint16_t>(offset);
|
||||||
@ -168,11 +212,16 @@ int VM::run_instruction()
|
|||||||
|
|
||||||
auto ins = InsReader(*this);
|
auto ins = InsReader(*this);
|
||||||
auto op = static_cast<Op>(ins.to_u16() & 0b11'1111);
|
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,
|
ip,
|
||||||
ins.to_u16(),
|
ins.to_u16(),
|
||||||
op_str(op),
|
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) {
|
switch (op) {
|
||||||
case Op::Nop:
|
case Op::Nop:
|
||||||
@ -201,7 +250,7 @@ int VM::run_instruction()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op::LoadWord: {
|
case Op::LoadWord: {
|
||||||
auto addr = ins.mem_addr(eat_word());
|
auto addr = ins.mem_addr(ins.op2(), eat_word());
|
||||||
|
|
||||||
if ((addr & 0b1) != 0) {
|
if ((addr & 0b1) != 0) {
|
||||||
std::println(stderr,
|
std::println(stderr,
|
||||||
@ -217,7 +266,7 @@ int VM::run_instruction()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op::StoreWord: {
|
case Op::StoreWord: {
|
||||||
auto addr = ins.mem_addr(eat_word());
|
auto addr = ins.mem_addr(ins.dst(), eat_word());
|
||||||
|
|
||||||
if ((addr & 0b1) != 0) {
|
if ((addr & 0b1) != 0) {
|
||||||
std::println(stderr,
|
std::println(stderr,
|
||||||
@ -239,14 +288,14 @@ int VM::run_instruction()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op::LoadByte: {
|
case Op::LoadByte: {
|
||||||
auto addr = ins.mem_addr(eat_word());
|
auto addr = ins.mem_addr(ins.op2(), eat_word());
|
||||||
auto reg = ins.dst_reg();
|
auto reg = ins.dst_reg();
|
||||||
|
|
||||||
set_reg(reg, byte(addr));
|
set_reg(reg, byte(addr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op::StoreByte: {
|
case Op::StoreByte: {
|
||||||
auto addr = ins.mem_addr(eat_word());
|
auto addr = ins.mem_addr(ins.dst(), eat_word());
|
||||||
auto src = ins.op2();
|
auto src = ins.op2();
|
||||||
|
|
||||||
if (m_vcd_loaded) {
|
if (m_vcd_loaded) {
|
||||||
@ -412,18 +461,10 @@ void VM::vcd_maybe_send_byte(uint16_t addr, uint8_t value)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
constexpr uint16_t screen_size = 40 * 24;
|
constexpr uint16_t screen_size = 40 * 24;
|
||||||
|
|
||||||
const auto& d = m_vcd_descriptor;
|
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) {
|
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();
|
m_device->set_char(addr - d.map_base_addr, value).value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user