127 lines
3.0 KiB
C++
127 lines
3.0 KiB
C++
#include "block_device.hpp"
|
|
#include "builder.hpp"
|
|
#include "io_device.hpp"
|
|
#include "vm.hpp"
|
|
#include <SDL2/SDL_main.h>
|
|
#include <cstdint>
|
|
#include <print>
|
|
#include <string>
|
|
|
|
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<uint8_t>(BlockDevice::block_size);
|
|
disk.read(file_block.data(), 0);
|
|
|
|
auto memory_block = std::vector<uint8_t>(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";
|
|
}
|