working visualization of the vm
This commit is contained in:
parent
6ab27289a8
commit
d58425bf75
2087
Cargo.lock
generated
2087
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -6,3 +6,8 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
customasm = "0.13.9"
|
customasm = "0.13.9"
|
||||||
|
pixels = "0.15"
|
||||||
|
|
||||||
|
[dependencies.winit]
|
||||||
|
version = "0.30"
|
||||||
|
features = ["rwh_05"]
|
11
examples/first.asm
Normal file
11
examples/first.asm
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
;#include "../src/foot.asm"
|
||||||
|
|
||||||
|
CNST. r0, 0xFBFF
|
||||||
|
CNST. r29, 0x400
|
||||||
|
|
||||||
|
label:
|
||||||
|
CNST.r [r0++], 0b1100110011001100
|
||||||
|
|
||||||
|
CNST. r31, label
|
||||||
|
|
||||||
|
data:
|
@ -1,3 +1,5 @@
|
|||||||
|
#once
|
||||||
|
|
||||||
#subruledef operand
|
#subruledef operand
|
||||||
{
|
{
|
||||||
#{immediate: s5} => 0b000 @ immediate
|
#{immediate: s5} => 0b000 @ immediate
|
||||||
@ -28,7 +30,7 @@
|
|||||||
|
|
||||||
#ruledef
|
#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
|
#bankdef mem
|
||||||
|
111
src/main.rs
111
src/main.rs
@ -1,18 +1,111 @@
|
|||||||
|
#![windows_subsystem = "windows"]
|
||||||
|
|
||||||
mod vm;
|
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()
|
fn main()
|
||||||
{
|
{
|
||||||
let mut vm = FootVM::new();
|
let mut vm = FootVM::new();
|
||||||
vm[0] = 0xFEED;
|
vm.load(ASM_SRC, Some(&mut std::io::stderr())).expect("");
|
||||||
vm[1] = 0b0000_0000_001_00000;
|
|
||||||
|
|
||||||
let result = vm.load("CNST. r0, 0xBEEF", Some(&mut std::io::stderr()));
|
let event_loop = EventLoop::new().unwrap();
|
||||||
if result.is_ok()
|
event_loop.set_control_flow(ControlFlow::Poll);
|
||||||
{
|
|
||||||
vm.cycle();
|
|
||||||
|
|
||||||
println!("{}", vm.registers[0]);
|
let mut app = App::new(vm);
|
||||||
}
|
event_loop.run_app(&mut app).expect("");
|
||||||
}
|
}
|
||||||
|
15
src/vm.rs
15
src/vm.rs
@ -80,7 +80,7 @@ impl TryFrom<u32> for Operand
|
|||||||
|
|
||||||
fn try_from(value: u32) -> Result<Self, Self::Error>
|
fn try_from(value: u32) -> Result<Self, Self::Error>
|
||||||
{
|
{
|
||||||
match (value >> 5).try_into()
|
match ((value >> 5) & 0b111).try_into()
|
||||||
{
|
{
|
||||||
Ok(addressing_mode) => Ok(
|
Ok(addressing_mode) => Ok(
|
||||||
Operand
|
Operand
|
||||||
@ -124,7 +124,8 @@ impl TryFrom<u32> for Instruction
|
|||||||
let ceflag: ConditionalExecutionFlag = (value >> 29).try_into()?;
|
let ceflag: ConditionalExecutionFlag = (value >> 29).try_into()?;
|
||||||
let rflag: bool = (value >> 28 & 1) == 1;
|
let rflag: bool = (value >> 28 & 1) == 1;
|
||||||
let dst: Operand = (value >> 16).try_into()?;
|
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)),
|
0 => Ok(CNST(ceflag, rflag, dst, (value & 0xFFFF) as u16)),
|
||||||
1 =>
|
1 =>
|
||||||
@ -178,10 +179,18 @@ const MEMORY_SIZE: usize = 1 << 16;
|
|||||||
pub struct FootVM
|
pub struct FootVM
|
||||||
{
|
{
|
||||||
memory: [u16; MEMORY_SIZE],
|
memory: [u16; MEMORY_SIZE],
|
||||||
pub registers: [u16; 32],
|
registers: [u16; 32],
|
||||||
status: Status
|
status: Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for FootVM
|
||||||
|
{
|
||||||
|
fn default() -> Self
|
||||||
|
{
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! run_instruction
|
macro_rules! run_instruction
|
||||||
{
|
{
|
||||||
($self:ident, $cef:ident, $rep:ident, $name:ident, $d:ident, $a:ident) =>
|
($self:ident, $cef:ident, $rep:ident, $name:ident, $d:ident, $a:ident) =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user