#include "block_device.hpp" #include "builder.hpp" #include "io_device.hpp" #include "vm.hpp" #include #include #include #include using namespace std::chrono_literals; using namespace vc5; using namespace vc5::regs; static void make_program(uint8_t* data); int main(int argc, char** argv) { auto device = IoDevice::create().value(); device->set_title("vc5"); if (argc < 2) { auto disk = MemoryDisk(128); make_program(disk.data()); auto vm = VM(*device, disk); vm.run(); } else { auto disk = FileDisk(argv[1]); auto memory_disk = MemoryDisk(128); make_program(memory_disk.data()); auto file_block = std::vector(BlockDevice::block_size); disk.read(file_block.data(), 0); auto memory_block = std::vector(BlockDevice::block_size); memory_disk.read(memory_block.data(), 0); std::println("file memory"); for (size_t i = 0; i < 64; i += 4) { std::println( "{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", file_block[i], file_block[i + 1], file_block[i + 2], file_block[i + 3], memory_block[i], memory_block[i + 1], memory_block[i + 2], memory_block[i + 3]); } auto vm = VM(*device, disk); vm.run(); } } void make_program(uint8_t* data) { auto l = tools::Builder(data); l.mov_imm(rsp, 0x1000); l.mov_reg(rbp, rsp); l.mov_imm(r0, 512); l.mov_imm(r1, 1); l.dskr(r0, r1); l.mov_imm(r0, 0x2000); l.store_word_imm(0x700, r0); l.lvcd_imm(0x700); l.mov_imm(r0, 0x1ffc); l.store_word_imm(0x702, r0); l.mov_imm(r0, 0x1ffe); l.store_word_imm(0x704, r0); auto to_set_key_press_int = l.ip(); l.mov_imm(r0, 0); l.store_word_imm(0x706, r0); l.lkbd_imm(0x702); l.mov_imm(r0, 0); l.store_word_imm(0x600, r0); auto main_loop = l.ip(); l.hlt(); l.jmp_imm(main_loop); auto key_press_int = l.ip(); l.load_word_imm(r0, 0x1ffc); l.and_imm(r0, r0, 1); auto to_set_key_press_int_leave = l.ip(); l.jnz_imm(r0, 0); l.load_word_imm(r0, 0x600); l.add_imm(r0, r0, 0x2000); l.load_word_imm(r1, 0x1ffe); l.cmp_imm(r1, 44); l.mov_reg(r2, rfl); l.and_imm(r2, r2, 2); 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); auto key_press_incr = l.ip(); l.load_word_imm(r0, 0x600); l.add_imm(r0, r0, 1); l.store_word_imm(0x600, r0); auto key_press_int_leave = l.ip(); l.reti(); 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); } extern "C" const char* __asan_default_options(void) { return "detect_leaks=0"; }