working visualization of the vm

This commit is contained in:
shylie 2025-03-07 02:58:45 -05:00
parent 6ab27289a8
commit d58425bf75
6 changed files with 2210 additions and 25 deletions

2087
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,3 +6,8 @@ edition = "2021"
[dependencies]
byteorder = "1"
customasm = "0.13.9"
pixels = "0.15"
[dependencies.winit]
version = "0.30"
features = ["rwh_05"]

11
examples/first.asm Normal file
View File

@ -0,0 +1,11 @@
;#include "../src/foot.asm"
CNST. r0, 0xFBFF
CNST. r29, 0x400
label:
CNST.r [r0++], 0b1100110011001100
CNST. r31, label
data:

View File

@ -1,3 +1,5 @@
#once
#subruledef operand
{
#{immediate: s5} => 0b000 @ immediate
@ -28,7 +30,7 @@
#ruledef
{
CNST{flags: crflags} {dst: operand}, {imm: i16} => imm @ 0b0000 @ flags @ dst
CNST{flags: crflags} {dst: operand}, {imm: i16} => imm @ flags @ 0b0000 @ dst
}
#bankdef mem

View File

@ -1,18 +1,111 @@
#![windows_subsystem = "windows"]
mod vm;
use vm::{FootVM};
use std::sync::Arc;
use vm::FootVM;
use pixels::{Pixels, SurfaceTexture};
use winit::application::ApplicationHandler;
use winit::dpi::LogicalSize;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};
pub struct App
{
vm: FootVM,
window: Option<Arc<Window>>,
pixels: Option<Pixels<'static>>
}
impl App
{
fn new(vm: FootVM) -> Self
{
App
{
vm,
window: None,
pixels: None
}
}
fn draw(&mut self)
{
let pixels = &mut self.pixels.as_mut().unwrap();
let frame = pixels.frame_mut();
for i in 0u16..32u16
{
for j in 0u16..32u16
{
let index = i + j * 32;
let mut value = self.vm[index + 0xFBFF];
for k in 0..16
{
let pixel_value = ((value & 1) * 255) as u8;
let pixel_index = (index as usize * 64) + k * 4;
frame[pixel_index + 0] = pixel_value;
frame[pixel_index + 1] = pixel_value;
frame[pixel_index + 2] = pixel_value;
frame[pixel_index + 3] = 0xFF;
value >>= 1;
}
}
}
pixels.render().expect("");
}
}
impl ApplicationHandler for App
{
fn resumed(&mut self, event_loop: &ActiveEventLoop)
{
const WIDTH: u32 = 128;
const HEIGHT: u32 = 128;
let window = event_loop.create_window(
WindowAttributes::default()
.with_resizable(false)
.with_inner_size(LogicalSize::new(WIDTH * 4, HEIGHT * 4))
.with_title("foot vm")
).unwrap();
let window = Arc::new(window);
self.window = Some(window);
let surface_texture = SurfaceTexture::new(WIDTH * 4, HEIGHT * 4, self.window.as_ref().unwrap().clone());
self.pixels = Some(Pixels::new(WIDTH, HEIGHT, surface_texture).unwrap());
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent)
{
self.vm.cycle();
match event
{
WindowEvent::RedrawRequested => self.draw(),
WindowEvent::CloseRequested => event_loop.exit(),
_ => {}
}
}
}
const ASM_SRC: &'static str = include_str!("../examples/first.asm");
fn main()
{
let mut vm = FootVM::new();
vm[0] = 0xFEED;
vm[1] = 0b0000_0000_001_00000;
vm.load(ASM_SRC, Some(&mut std::io::stderr())).expect("");
let result = vm.load("CNST. r0, 0xBEEF", Some(&mut std::io::stderr()));
if result.is_ok()
{
vm.cycle();
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);
println!("{}", vm.registers[0]);
}
let mut app = App::new(vm);
event_loop.run_app(&mut app).expect("");
}

View File

@ -80,7 +80,7 @@ impl TryFrom<u32> for Operand
fn try_from(value: u32) -> Result<Self, Self::Error>
{
match (value >> 5).try_into()
match ((value >> 5) & 0b111).try_into()
{
Ok(addressing_mode) => Ok(
Operand
@ -124,7 +124,8 @@ impl TryFrom<u32> for Instruction
let ceflag: ConditionalExecutionFlag = (value >> 29).try_into()?;
let rflag: bool = (value >> 28 & 1) == 1;
let dst: Operand = (value >> 16).try_into()?;
match value >> 24
let opcode = (value >> 24) & 0xF;
match opcode
{
0 => Ok(CNST(ceflag, rflag, dst, (value & 0xFFFF) as u16)),
1 =>
@ -178,10 +179,18 @@ const MEMORY_SIZE: usize = 1 << 16;
pub struct FootVM
{
memory: [u16; MEMORY_SIZE],
pub registers: [u16; 32],
registers: [u16; 32],
status: Status
}
impl Default for FootVM
{
fn default() -> Self
{
Self::new()
}
}
macro_rules! run_instruction
{
($self:ident, $cef:ident, $rep:ident, $name:ident, $d:ident, $a:ident) =>