Update multiply instructions

This commit is contained in:
shylie 2025-03-16 10:22:45 -04:00
parent 8bdd8a47f6
commit 96a8152170
5 changed files with 96 additions and 63 deletions

View File

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

18
examples/mandelbrot.asm Normal file
View File

@ -0,0 +1,18 @@
;#include "../src/foot.asm"
value_count = 1024
; generate starting values
CNST. r30, #value_count
CNST. r0, #xvals
ADDI.r [r0++], r30, #0
end:
CNST
xvals:
#res value_count
yvals:
#res value_count

View File

@ -2,7 +2,7 @@
#subruledef operand
{
#{immediate: u5} => 0b000 @ immediate
#{immediate: i5} => 0b000 @ immediate
r{register: u5} => 0b001 @ register
[r{register: u5}++] => 0b010 @ register
[r{register: u5}--] => 0b011 @ register
@ -30,7 +30,7 @@
#ruledef
{
CNST{flags: crflags} {dst: operand}, {imm: i16} => imm @ flags @ 0b0000 @ dst
CNST{flags: crflags} {dst: operand}, #{imm: i16} => imm @ flags @ 0b0000 @ dst
CMPR{flags: crflags} {dst: operand}, {a: operand} => 0x00 @ a @ flags @ 0b0001 @ dst
BWNG{flags: crflags} {dst: operand}, {a: operand} => 0x01 @ a @ flags @ 0b0001 @ dst
ARNG{flags: crflags} {dst: operand}, {a: operand} => 0x02 @ a @ flags @ 0b0001 @ dst
@ -44,9 +44,11 @@
CLSH{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1000 @ dst
ADDI{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1001 @ dst
SUBT{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1010 @ dst
MULT{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1011 @ dst
DIVI{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1100 @ dst
MODU{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1101 @ dst
MULL{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1011 @ dst
MULS{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1100 @ dst
MULU{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1101 @ dst
DIVI{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1110 @ dst
MODU{flags: crflags} {dst: operand}, {a: operand}, {b: operand} => b @ a @ flags @ 0b1111 @ dst
}
#bankdef mem

View File

@ -13,6 +13,14 @@ use winit::event::{StartCause, WindowEvent};
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
use winit::window::{Window, WindowAttributes, WindowButtons, WindowId};
const WIDTH: u32 = 64;
const HEIGHT: u32 = 64;
const BITS_PER_PIXEL: u32 = 4;
const PIXELS_PER_ADDRESS: u32 = 16 / BITS_PER_PIXEL;
const MEMORY_SLOTS: u32 = WIDTH * HEIGHT / PIXELS_PER_ADDRESS;
const BASE_ADDRESS: u32 = 0xFFFF - MEMORY_SLOTS;
const PIXEL_SCALE: u32 = 8;
pub struct App
{
vm: FootVM,
@ -42,24 +50,20 @@ impl App
let pixels = &mut self.pixels.as_mut().unwrap();
let frame = pixels.frame_mut();
for i in 0u16..32u16
for ptr in 0..MEMORY_SLOTS
{
for j in 0u16..32u16
{
let index = i + j * 32;
let mut value = self.vm[index + 0xFBFF];
let mut value = self.vm[(ptr + BASE_ADDRESS) as u16];
for k in 0..16
for k in 0..PIXELS_PER_ADDRESS
{
let pixel_value = ((value & 1) * 255) as u8;
let pixel_index = (index as usize * 64) + k * 4;
let pixel_value = ((value & 0xF) * 17) as u8;
let pixel_index = ((ptr * PIXELS_PER_ADDRESS + k) * 4) as usize;
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;
}
value >>= BITS_PER_PIXEL;
}
}
@ -84,21 +88,18 @@ 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_enabled_buttons(WindowButtons::CLOSE | WindowButtons::MINIMIZE)
.with_inner_size(LogicalSize::new(WIDTH * 4, HEIGHT * 4))
.with_inner_size(LogicalSize::new(WIDTH * PIXEL_SCALE, HEIGHT * PIXEL_SCALE))
.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());
let surface_texture = SurfaceTexture::new(WIDTH * PIXEL_SCALE, HEIGHT * PIXEL_SCALE, self.window.as_ref().unwrap().clone());
self.pixels = Some(Pixels::new(WIDTH, HEIGHT, surface_texture).unwrap());
}

View File

@ -110,7 +110,9 @@ enum Instruction
CLSH(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
ADDI(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
SUBT(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
MULT(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
MULL(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
MULS(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
MULU(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
DIVI(ConditionalExecutionFlag, bool, Operand, Operand, Operand),
MODU(ConditionalExecutionFlag, bool, Operand, Operand, Operand)
}
@ -144,7 +146,7 @@ impl TryFrom<u32> for Instruction
{
let a: Operand = (value & 0xFF).try_into()?;
let b: Operand = ((value >> 8) & 0xFF).try_into()?;
match (value >> 24) & 0xF
match opcode
{
2 => Ok(BWOR(ceflag, rflag, dst, b, a)),
3 => Ok(BAND(ceflag, rflag, dst, b, a)),
@ -155,9 +157,11 @@ impl TryFrom<u32> for Instruction
8 => Ok(CLSH(ceflag, rflag, dst, b, a)),
9 => Ok(ADDI(ceflag, rflag, dst, b, a)),
10 => Ok(SUBT(ceflag, rflag, dst, b, a)),
11 => Ok(MULT(ceflag, rflag, dst, b, a)),
12 => Ok(DIVI(ceflag, rflag, dst, b, a)),
13 => Ok(MODU(ceflag, rflag, dst, b, a)),
11 => Ok(MULL(ceflag, rflag, dst, b, a)),
12 => Ok(MULS(ceflag, rflag, dst, b, a)),
13 => Ok(MULU(ceflag, rflag, dst, b, a)),
14 => Ok(DIVI(ceflag, rflag, dst, b, a)),
15 => Ok(MODU(ceflag, rflag, dst, b, a)),
_ => Err(())
}
},
@ -197,13 +201,17 @@ macro_rules! run_instruction
{
if $rep
{
while $self.should_repeat()
let loop_count = $self.loop_count();
for i in 0..loop_count
{
*$self.mut_loop_count() = i;
if $self.check($cef)
{
$self.$name($d, $a)
}
}
*$self.mut_loop_count() = loop_count;
}
else if $self.check($cef)
{
@ -214,13 +222,17 @@ macro_rules! run_instruction
{
if $rep
{
while $self.should_repeat()
let loop_count = $self.loop_count();
for i in 0..loop_count
{
*$self.mut_loop_count() = i;
if $self.check($cef)
{
$self.$name($d, $a, $b)
}
}
*$self.mut_loop_count() = loop_count;
}
else if $self.check($cef)
{
@ -294,7 +306,7 @@ impl FootVM
{
let first_word = self[self.program_counter()];
let second_word = self[self.program_counter() + 1];
let full_instruction_bits = (second_word as u32) << 16 | first_word as u32;
let full_instruction_bits = u32::from(second_word) << 16 | u32::from(first_word);
*self.mut_program_counter() = self.program_counter().wrapping_add(2);
match full_instruction_bits.try_into()
{
@ -326,8 +338,12 @@ impl FootVM
run_instruction!(self, cef, rep, addi, dst, a, b),
Ok(SUBT(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, subt, dst, a, b),
Ok(MULT(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, mult, dst, a, b),
Ok(MULL(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, mull, dst, a, b),
Ok(MULS(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, muls, dst, a, b),
Ok(MULU(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, mulu, dst, a, b),
Ok(DIVI(cef, rep, dst, b, a)) =>
run_instruction!(self, cef, rep, divi, dst, a, b),
Ok(MODU(cef, rep, dst, b, a)) =>
@ -422,7 +438,7 @@ impl FootVM
{
let a = self.load_operand(src_a);
let b = self.load_operand(src_b);
self.store_operand(dst, a.rotate_left(b as u32));
self.store_operand(dst, a.rotate_left(u32::from(b)));
}
fn addi(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
@ -439,11 +455,25 @@ impl FootVM
self.store_operand(dst, a.wrapping_sub(b));
}
fn mult(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
fn mull(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
{
let a = self.load_operand(src_a);
let b = self.load_operand(src_b);
self.store_operand(dst, a.wrapping_mul(b));
let a = u32::from(self.load_operand(src_a));
let b = u32::from(self.load_operand(src_b));
self.store_operand(dst, (a * b) as u16);
}
fn muls(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
{
let a = i32::from(self.load_operand(src_a));
let b = i32::from(self.load_operand(src_b));
self.store_operand(dst, ((a * b) >> 16) as u16);
}
fn mulu(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
{
let a = u32::from(self.load_operand(src_a));
let b = u32::from(self.load_operand(src_b));
self.store_operand(dst,((a * b) >> 16) as u16);
}
fn divi(&mut self, dst: Operand, src_a: Operand, src_b: Operand)
@ -522,26 +552,12 @@ impl FootVM
fn loop_count(&self) -> u16
{
self.registers[29]
self.registers[30]
}
fn mut_loop_count(&mut self) -> &mut u16
{
&mut self.registers[29]
}
fn should_repeat(&mut self) -> bool
{
if self.loop_count() > 0
{
*self.mut_loop_count() -= 1;
true
}
else
{
false
}
&mut self.registers[30]
}
fn check(&self, cef: ConditionalExecutionFlag) -> bool