Simple mandelbrot in rust
This commit is contained in:
@@ -34,6 +34,4 @@ SECTIONS
|
|||||||
PROVIDE(_stack_size = 1024); /* 1 KiB */
|
PROVIDE(_stack_size = 1024); /* 1 KiB */
|
||||||
PROVIDE(_stack_start = _memory_end);
|
PROVIDE(_stack_start = _memory_end);
|
||||||
PROVIDE(_stack_end = _stack_start - _stack_size);
|
PROVIDE(_stack_end = _stack_start - _stack_size);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ rustflags = [
|
|||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core", "compiler_builtins"]
|
build-std = ["core", "compiler_builtins"]
|
||||||
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fpga-lib = { path = "../fpga-lib" }
|
fpga-lib = { path = "../fpga-lib" }
|
||||||
|
libm = "0.2.11"
|
||||||
|
|||||||
@@ -1,51 +1,120 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::{
|
||||||
|
arch::asm,
|
||||||
|
ops::{Add, Mul},
|
||||||
|
};
|
||||||
|
|
||||||
use fpga_lib::{
|
use fpga_lib::{
|
||||||
interface::{Buttons, Leds},
|
interface::{Buttons, Leds},
|
||||||
panic_handler,
|
panic_handler,
|
||||||
register::X31,
|
register::X31,
|
||||||
vga::{BLACK, BLUE, FONT_WIDTH, GREEN, RED, VGA, WHITE},
|
vga::{BLACK, BLUE, Color, FONT_WIDTH, GREEN, HEIGHT, RED, VGA, WHITE, WIDTH},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Float = f32;
|
||||||
|
pub const ITERATIONS: usize = 100;
|
||||||
|
pub const ASPECT_RATIO: f32 = WIDTH as f32 / HEIGHT as f32;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Complex(Float, Float);
|
||||||
|
|
||||||
|
impl Complex
|
||||||
|
{
|
||||||
|
pub fn sq_mag(&self) -> Float
|
||||||
|
{
|
||||||
|
self.0 * self.0 + self.1 * self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map(x: Float, xmin: Float, xmax: Float, ymin: Float, ymax: Float) -> Float
|
||||||
|
{
|
||||||
|
((x - xmin) / (xmax - xmin)) * (ymax - ymin) + ymin
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Complex
|
||||||
|
{
|
||||||
|
type Output = Complex;
|
||||||
|
|
||||||
|
fn add(self, Self(a, b): Self) -> Self::Output
|
||||||
|
{
|
||||||
|
Complex(self.0 + a, self.1 + b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul for Complex
|
||||||
|
{
|
||||||
|
type Output = Complex;
|
||||||
|
|
||||||
|
fn mul(self, Self(a, b): Self) -> Self::Output
|
||||||
|
{
|
||||||
|
Complex(self.0 * a - self.1 * b, self.0 * b + self.1 * a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
panic_handler! {}
|
panic_handler! {}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn main() -> !
|
pub extern "C" fn main() -> !
|
||||||
{
|
{
|
||||||
loop
|
let color_lut: [Color; ITERATIONS] = {
|
||||||
|
let mut tab = [BLACK; _];
|
||||||
|
for i in 0..(ITERATIONS - 1)
|
||||||
|
{
|
||||||
|
let val = ((i as Float / ITERATIONS as Float) * 255.) as u8;
|
||||||
|
tab[i] = Color::from_rgb(val, val, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
tab
|
||||||
|
};
|
||||||
|
|
||||||
|
let width = 2.;
|
||||||
|
for x in 0..WIDTH
|
||||||
{
|
{
|
||||||
unsafe {
|
for y in 0..HEIGHT
|
||||||
VGA::draw_string(10, 10, "Running RUST !", GREEN);
|
{
|
||||||
VGA::draw_string(10, 23, "LedIp state :", RED);
|
let pos = Complex(
|
||||||
|
map(
|
||||||
|
x as Float,
|
||||||
|
0.,
|
||||||
|
WIDTH as Float,
|
||||||
|
-width * ASPECT_RATIO * 0.5,
|
||||||
|
width * ASPECT_RATIO * 0.5,
|
||||||
|
) - 0.5,
|
||||||
|
map(y as Float, 0., HEIGHT as Float, -width * 0.5, width * 0.5),
|
||||||
|
);
|
||||||
|
let mut acc = pos;
|
||||||
|
let mut iter = 0;
|
||||||
|
|
||||||
let clint_time: *mut u64 = 0x0200bff8 as *mut u64;
|
// Optimisations
|
||||||
|
let p = ((pos.0 - 0.25) * (pos.0 - 0.25)) + pos.1 * pos.1;
|
||||||
let clocks = *clint_time;
|
if (pos.0 < libm::sqrtf(p) - 2. * p + 0.25)
|
||||||
let seconds = clocks / 80_000_000;
|
|| (pos.0 + 1.) * (pos.0 + 1.) + pos.1 * pos.1 < 1. / 16.
|
||||||
VGA::draw_string(100, 10, "CLint:", BLUE);
|
|
||||||
VGA::draw_u64(150, 10, clocks, BLUE, BLACK);
|
|
||||||
VGA::draw_string(100, 23, "(s)", BLUE);
|
|
||||||
VGA::draw_u64(150, 23, seconds, BLUE, BLACK);
|
|
||||||
|
|
||||||
for i in 0..4
|
|
||||||
{
|
{
|
||||||
VGA::draw_char(10 + i * 16, 46, 'B', RED);
|
iter = ITERATIONS - 1;
|
||||||
VGA::draw_char(16 + i * 16, 46, (b'0' + i as u8) as char, RED);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for i in 0..ITERATIONS
|
||||||
|
{
|
||||||
|
acc = acc * acc + pos;
|
||||||
|
if acc.sq_mag() > 1.
|
||||||
|
{
|
||||||
|
iter = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if Buttons::get_button(i as u8)
|
unsafe {
|
||||||
{
|
VGA::write_pixel_unsafe(x as u16, y as u16, color_lut[iter]);
|
||||||
Leds::set_led(i as u8, true);
|
|
||||||
VGA::draw_char_bg(10 + i * 16, 59, '1', GREEN, BLACK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Leds::set_led(i as u8, false);
|
|
||||||
VGA::draw_char_bg(10 + i * 16, 59, '0', RED, BLACK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
core::hint::spin_loop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user