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
@ -5,4 +5,9 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
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
|
||||
{
|
||||
#{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
|
||||
|
111
src/main.rs
111
src/main.rs
@ -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("");
|
||||
}
|
||||
|
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>
|
||||
{
|
||||
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) =>
|
||||
|
Loading…
x
Reference in New Issue
Block a user