forked from AbleOS/ableos
Arguments are actually passed into programs
This commit is contained in:
parent
f2e561e242
commit
f074527e42
|
@ -1,19 +1,28 @@
|
||||||
mod memory;
|
mod memory;
|
||||||
|
|
||||||
use core::{arch::{asm, global_asm}, fmt::Write};
|
use {
|
||||||
use alloc::boxed::Box;
|
alloc::boxed::Box,
|
||||||
use sbi::system_reset::{ResetType, ResetReason, system_reset};
|
core::{
|
||||||
use spin::{Mutex, Once};
|
arch::{asm, global_asm},
|
||||||
use uart_16550::MmioSerialPort;
|
fmt::Write,
|
||||||
|
},
|
||||||
|
sbi::system_reset::{system_reset, ResetReason, ResetType},
|
||||||
|
spin::{Mutex, Once},
|
||||||
|
uart_16550::MmioSerialPort,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{allocator, memory::PhysicalAddress, arch::riscv64::memory::{PAGE_TABLE, PageEntryFlags, PageSize, PageTable}};
|
use crate::{
|
||||||
|
allocator,
|
||||||
|
arch::riscv64::memory::{PageEntryFlags, PageSize, PageTable, PAGE_TABLE},
|
||||||
|
memory::PhysicalAddress,
|
||||||
|
};
|
||||||
|
|
||||||
global_asm!(include_str!("entry.s"));
|
global_asm!(include_str!("entry.s"));
|
||||||
global_asm!(include_str!("memory_regions.s"));
|
global_asm!(include_str!("memory_regions.s"));
|
||||||
|
|
||||||
pub const PAGE_SIZE: usize = 4096;
|
pub const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
static TEXT_START: PhysicalAddress;
|
static TEXT_START: PhysicalAddress;
|
||||||
static TEXT_END: PhysicalAddress;
|
static TEXT_END: PhysicalAddress;
|
||||||
|
|
||||||
|
@ -39,12 +48,15 @@ extern {
|
||||||
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern fn _kernel_start() -> ! {
|
unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) }));
|
SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) }));
|
||||||
crate::logger::init().expect("failed to set logger");
|
crate::logger::init().expect("failed to set logger");
|
||||||
log::info!("Initialising AKern {}", crate::VERSION);
|
log::info!("Initialising AKern {}", crate::VERSION);
|
||||||
|
|
||||||
allocator::init(INITIAL_KERNEL_HEAP_START.as_mut_ptr::<u8>(), INITIAL_KERNEL_HEAP_SIZE);
|
allocator::init(
|
||||||
|
INITIAL_KERNEL_HEAP_START.as_mut_ptr::<u8>(),
|
||||||
|
INITIAL_KERNEL_HEAP_SIZE,
|
||||||
|
);
|
||||||
memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE);
|
memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE);
|
||||||
|
|
||||||
let mut page_table_addr = PAGE_TABLE.get().unwrap().lock();
|
let mut page_table_addr = PAGE_TABLE.get().unwrap().lock();
|
||||||
|
@ -61,9 +73,17 @@ unsafe extern fn _kernel_start() -> ! {
|
||||||
// Map bss section (includes stack and initial kernel heap)
|
// Map bss section (includes stack and initial kernel heap)
|
||||||
page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite);
|
page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite);
|
||||||
// Map usable memory range (as rw so not executable)
|
// Map usable memory range (as rw so not executable)
|
||||||
page_table.identity_map_range(USABLE_MEMORY_START, USABLE_MEMORY_START + USABLE_MEMORY_SIZE.into(), PageEntryFlags::ReadWrite);
|
page_table.identity_map_range(
|
||||||
|
USABLE_MEMORY_START,
|
||||||
|
USABLE_MEMORY_START + USABLE_MEMORY_SIZE.into(),
|
||||||
|
PageEntryFlags::ReadWrite,
|
||||||
|
);
|
||||||
// Map Uart so we can continue using serial
|
// Map Uart so we can continue using serial
|
||||||
page_table.identity_map(0x1000_0000_usize.into(), PageEntryFlags::ReadWrite, PageSize::Size4KiB);
|
page_table.identity_map(
|
||||||
|
0x1000_0000_usize.into(),
|
||||||
|
PageEntryFlags::ReadWrite,
|
||||||
|
PageSize::Size4KiB,
|
||||||
|
);
|
||||||
|
|
||||||
let table_ppn = page_table_addr.as_addr() as usize >> 12;
|
let table_ppn = page_table_addr.as_addr() as usize >> 12;
|
||||||
let satp_value = 8 << 60 | table_ppn;
|
let satp_value = 8 << 60 | table_ppn;
|
||||||
|
|
|
@ -1,72 +1 @@
|
||||||
use {
|
|
||||||
crate::kmain::DEVICE_TREE,
|
|
||||||
able_graphics_library::raw_pixel::Display,
|
|
||||||
embedded_graphics::{pixelcolor::Rgb888, prelude::*},
|
|
||||||
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
|
|
||||||
spin::{Lazy, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub static DISPLAY: Lazy<Mutex<Display>> = Lazy::new(|| {
|
|
||||||
static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
|
||||||
let fb1: &NonNullPtr<Framebuffer> = &FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
|
||||||
|
|
||||||
{
|
|
||||||
use crate::alloc::string::ToString;
|
|
||||||
let mut dt = DEVICE_TREE.lock();
|
|
||||||
let mut disp = xml::XMLElement::new("display_0");
|
|
||||||
|
|
||||||
disp.set_attribute("width", fb1.width);
|
|
||||||
disp.set_attribute("height", fb1.height);
|
|
||||||
disp.set_attribute("bits per pixel", fb1.bpp);
|
|
||||||
disp.set_attribute("pitch", fb1.pitch);
|
|
||||||
// disp.set_attribute("fb ptr", fb1.address.as_ptr().unwrap());
|
|
||||||
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
|
||||||
}
|
|
||||||
let _size: usize = (fb1.width * fb1.height).try_into().unwrap();
|
|
||||||
let back_buffer: alloc::vec::Vec<u32> = alloc::vec![0; 800*600];
|
|
||||||
|
|
||||||
let m = Mutex::new(Display {
|
|
||||||
fb: fb1.address.as_ptr().unwrap().cast(),
|
|
||||||
bb: back_buffer.as_slice().as_ptr() as *mut u32,
|
|
||||||
size: Size::new(fb1.width as u32, fb1.height as u32),
|
|
||||||
color: Rgb888::WHITE,
|
|
||||||
});
|
|
||||||
log::info!("Graphics initialised");
|
|
||||||
log::info!(
|
|
||||||
"Graphics front ptr {:?}",
|
|
||||||
fb1.address.as_ptr().unwrap() as *const u8
|
|
||||||
);
|
|
||||||
m
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
Lazy::force(&DISPLAY);
|
|
||||||
}
|
|
||||||
// pub fn virtio_gpu<T: Transport>(transport: T) {
|
|
||||||
// let mut gpu = VirtIOGpu::<AbleosHal, T>::new(transport).expect("failed to create gpu driver");
|
|
||||||
// let (width, height) = gpu.resolution().expect("failed to get resolution");
|
|
||||||
// let width = width as usize;
|
|
||||||
// let height = height as usize;
|
|
||||||
// log::info!("GPU resolution is {}x{}", width, height);
|
|
||||||
// let fb = gpu.setup_framebuffer().expect("failed to get fb");
|
|
||||||
// for y in 0..height {
|
|
||||||
// for x in 0..width {
|
|
||||||
// let idx = (y * width + x) * 4;
|
|
||||||
// fb[idx] = x as u8;
|
|
||||||
// fb[idx + 1] = y as u8;
|
|
||||||
// fb[idx + 2] = (x + y) as u8;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// gpu.flush().expect("failed to flush");
|
|
||||||
// //delay some time
|
|
||||||
// log::info!("virtio-gpu show graphics....");
|
|
||||||
// for _ in 0..100000 {
|
|
||||||
// for _ in 0..100000 {
|
|
||||||
// unsafe {
|
|
||||||
// core::arch::asm!("nop");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// log::info!("virtio-gpu test finished");
|
|
||||||
// }
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule},
|
crate::bootmodules::BootModule, core::arch::asm, embedded_graphics::pixelcolor::Rgb888,
|
||||||
core::arch::asm,
|
log::warn, rdrand::RdSeed,
|
||||||
embedded_graphics::pixelcolor::Rgb888,
|
|
||||||
log::warn,
|
|
||||||
rdrand::RdSeed,
|
|
||||||
};
|
};
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
|
@ -83,51 +80,51 @@ unsafe extern "C" fn start() -> ! {
|
||||||
device_info_collector::collect_device_info();
|
device_info_collector::collect_device_info();
|
||||||
|
|
||||||
// Graphics test
|
// Graphics test
|
||||||
{
|
// {
|
||||||
graphics::init();
|
// graphics::init();
|
||||||
let mut dis = DISPLAY.lock();
|
// let mut dis = DISPLAY.lock();
|
||||||
use embedded_graphics::prelude::RgbColor;
|
// use embedded_graphics::prelude::RgbColor;
|
||||||
|
|
||||||
let _ = dis.set_color(Rgb888::YELLOW);
|
// let _ = dis.set_color(Rgb888::YELLOW);
|
||||||
let thick = 6;
|
// let thick = 6;
|
||||||
let p1 = (400, 30);
|
// let p1 = (400, 30);
|
||||||
let p2 = (200, 150);
|
// let p2 = (200, 150);
|
||||||
let p3 = (600, 150);
|
// let p3 = (600, 150);
|
||||||
let p4 = (200, 350);
|
// let p4 = (200, 350);
|
||||||
let p5 = (600, 350);
|
// let p5 = (600, 350);
|
||||||
let p6 = (400, 470);
|
// let p6 = (400, 470);
|
||||||
|
|
||||||
{
|
// {
|
||||||
//HEXAGON
|
// //HEXAGON
|
||||||
|
|
||||||
let _ = dis.line(p1.0, p1.1, p2.0, p2.1, thick);
|
// let _ = dis.line(p1.0, p1.1, p2.0, p2.1, thick);
|
||||||
let _ = dis.line(p1.0, p1.1, p3.0, p3.1, thick);
|
// let _ = dis.line(p1.0, p1.1, p3.0, p3.1, thick);
|
||||||
let _ = dis.line(p2.0, p2.1, p4.0, p4.1, thick);
|
// let _ = dis.line(p2.0, p2.1, p4.0, p4.1, thick);
|
||||||
let _ = dis.line(p3.0, p3.1, p5.0, p5.1, thick);
|
// let _ = dis.line(p3.0, p3.1, p5.0, p5.1, thick);
|
||||||
let _ = dis.line(p6.0, p6.1, p4.0, p4.1, thick);
|
// let _ = dis.line(p6.0, p6.1, p4.0, p4.1, thick);
|
||||||
let _ = dis.line(p6.0, p6.1, p5.0, p5.1, thick);
|
// let _ = dis.line(p6.0, p6.1, p5.0, p5.1, thick);
|
||||||
}
|
// }
|
||||||
{
|
// {
|
||||||
let _ = dis.line(600, 150, 200, 350, thick);
|
// let _ = dis.line(600, 150, 200, 350, thick);
|
||||||
let _ = dis.line(600, 350, 400, 250, thick);
|
// let _ = dis.line(600, 350, 400, 250, thick);
|
||||||
}
|
// }
|
||||||
|
|
||||||
{
|
// {
|
||||||
let _ = dis.set_color(Rgb888::WHITE);
|
// let _ = dis.set_color(Rgb888::WHITE);
|
||||||
let hp1 = (350, 150);
|
// let hp1 = (350, 150);
|
||||||
let hp2 = (350, 350);
|
// let hp2 = (350, 350);
|
||||||
let hp3 = (450, 250);
|
// let hp3 = (450, 250);
|
||||||
let hp4 = (350, 250);
|
// let hp4 = (350, 250);
|
||||||
let hp5 = (450, 150);
|
// let hp5 = (450, 150);
|
||||||
let hp6 = (450, 350);
|
// let hp6 = (450, 350);
|
||||||
|
|
||||||
let _ = dis.line(hp1.0, hp1.1, hp2.0, hp2.1, thick);
|
// let _ = dis.line(hp1.0, hp1.1, hp2.0, hp2.1, thick);
|
||||||
let _ = dis.line(hp3.0, hp3.1, hp4.0, hp4.1, thick);
|
// let _ = dis.line(hp3.0, hp3.1, hp4.0, hp4.1, thick);
|
||||||
let _ = dis.line(hp5.0, hp5.1, hp6.0, hp6.1, thick);
|
// let _ = dis.line(hp5.0, hp5.1, hp6.0, hp6.1, thick);
|
||||||
}
|
// }
|
||||||
|
|
||||||
dis.swap_buffers();
|
// dis.swap_buffers();
|
||||||
};
|
// };
|
||||||
|
|
||||||
// TODO: Add in rdseed and rdrand as sources for randomness
|
// TODO: Add in rdseed and rdrand as sources for randomness
|
||||||
let _rand = xml::XMLElement::new("Random");
|
let _rand = xml::XMLElement::new("Random");
|
||||||
|
|
|
@ -25,6 +25,11 @@ pub struct ExecThread<'p> {
|
||||||
|
|
||||||
unsafe impl<'p> Send for ExecThread<'p> {}
|
unsafe impl<'p> Send for ExecThread<'p> {}
|
||||||
impl<'p> ExecThread<'p> {
|
impl<'p> ExecThread<'p> {
|
||||||
|
pub fn set_arguments(&mut self, ptr: u64, length: u64) {
|
||||||
|
self.vm.registers[1] = hbvm::value::Value(ptr);
|
||||||
|
self.vm.registers[2] = hbvm::value::Value(length);
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
|
pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
|
||||||
ExecThread {
|
ExecThread {
|
||||||
vm: unsafe {
|
vm: unsafe {
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
//! AbleOS Kernel Entrypoint
|
//! AbleOS Kernel Entrypoint
|
||||||
|
|
||||||
use {hashbrown::HashMap, hbvm::mem::Address};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
capabilities,
|
|
||||||
holeybytes::ExecThread,
|
|
||||||
ipc::buffer::{self, IpcBuffer},
|
|
||||||
};
|
|
||||||
// use crate::arch::sloop;
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
bootmodules::{build_cmd, BootModules},
|
bootmodules::{build_cmd, BootModules},
|
||||||
|
capabilities,
|
||||||
device_tree::DeviceTree,
|
device_tree::DeviceTree,
|
||||||
|
holeybytes::ExecThread,
|
||||||
|
ipc::buffer::{self, IpcBuffer},
|
||||||
},
|
},
|
||||||
alloc::format,
|
alloc::format,
|
||||||
|
hashbrown::HashMap,
|
||||||
|
hbvm::mem::Address,
|
||||||
|
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
|
||||||
log::{debug, info, trace},
|
log::{debug, info, trace},
|
||||||
spin::{Lazy, Mutex},
|
spin::{Lazy, Mutex},
|
||||||
xml::XMLElement,
|
xml::XMLElement,
|
||||||
|
@ -32,6 +30,7 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
// TODO: pass into the program
|
// TODO: pass into the program
|
||||||
// Pass CMDLine into an IPCBuffer and put the ptr to the IPCBuffer in r200
|
// Pass CMDLine into an IPCBuffer and put the ptr to the IPCBuffer in r200
|
||||||
_bmcmd = build_cmd(name, bm.cmd.clone());
|
_bmcmd = build_cmd(name, bm.cmd.clone());
|
||||||
|
log::info!("{:?}", _bmcmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,12 +46,47 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
// TODO: Schedule the VFS from initramfs
|
// TODO: Schedule the VFS from initramfs
|
||||||
// TODO: schedule the init system from the initramfs
|
// TODO: schedule the init system from the initramfs
|
||||||
|
|
||||||
|
drop(dt);
|
||||||
|
|
||||||
|
let fb1: &NonNullPtr<Framebuffer> = &FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
||||||
|
|
||||||
|
{
|
||||||
|
use crate::alloc::string::ToString;
|
||||||
|
let mut dt = DEVICE_TREE.lock();
|
||||||
|
let mut disp = xml::XMLElement::new("display_0");
|
||||||
|
|
||||||
|
disp.set_attribute("width", fb1.width);
|
||||||
|
disp.set_attribute("height", fb1.height);
|
||||||
|
disp.set_attribute("bits per pixel", fb1.bpp);
|
||||||
|
disp.set_attribute("pitch", fb1.pitch);
|
||||||
|
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
||||||
|
}
|
||||||
|
log::info!("Graphics initialised");
|
||||||
|
log::info!(
|
||||||
|
"Graphics front ptr {:?}",
|
||||||
|
fb1.address.as_ptr().unwrap() as *const u8
|
||||||
|
);
|
||||||
|
|
||||||
let mut executor = crate::task::Executor::default();
|
let mut executor = crate::task::Executor::default();
|
||||||
let bm_take = boot_modules.len();
|
let bm_take = boot_modules.len();
|
||||||
unsafe {
|
unsafe {
|
||||||
for module in boot_modules.into_iter().take(bm_take) {
|
for module in boot_modules.into_iter().take(bm_take) {
|
||||||
|
let mut cmd = module.cmd;
|
||||||
|
{
|
||||||
|
// Remove the quotes
|
||||||
|
cmd.remove(0);
|
||||||
|
cmd.pop();
|
||||||
|
}
|
||||||
|
let cmd_len = cmd.as_bytes().len() as u64;
|
||||||
|
|
||||||
|
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
||||||
|
|
||||||
executor.spawn(async move {
|
executor.spawn(async move {
|
||||||
if let Err(e) = ExecThread::new(&module.bytes, Address::new(0)).await {
|
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
||||||
|
if cmd_len > 0 {
|
||||||
|
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
||||||
|
}
|
||||||
|
if let Err(e) = thr.await {
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -68,6 +102,7 @@ pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
||||||
let dt = DeviceTree::new();
|
let dt = DeviceTree::new();
|
||||||
Mutex::new(dt)
|
Mutex::new(dt)
|
||||||
});
|
});
|
||||||
|
pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
pub type IpcBuffers = HashMap<u64, IpcBuffer>;
|
pub type IpcBuffers = HashMap<u64, IpcBuffer>;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
extern crate kernel;
|
extern crate kernel;
|
||||||
|
|
|
@ -139,9 +139,7 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
|
||||||
io::copy(
|
io::copy(
|
||||||
&mut File::open("limine/BOOTAA64.EFI")
|
&mut File::open("limine/BOOTAA64.EFI")
|
||||||
.map_err(Report::from)
|
.map_err(Report::from)
|
||||||
.attach_printable(
|
.attach_printable("Copying Limine (ARM): have you pulled the submodule?")?,
|
||||||
"Copying Limine (ARM): have you pulled the submodule?",
|
|
||||||
)?,
|
|
||||||
&mut bootdir.create_file("bootaa64.efi")?,
|
&mut bootdir.create_file("bootaa64.efi")?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -233,6 +231,7 @@ fn run(release: bool, target: Target) -> Result<(), Error> {
|
||||||
"-drive", "file=target/disk.img,format=raw",
|
"-drive", "file=target/disk.img,format=raw",
|
||||||
"-m", "4G",
|
"-m", "4G",
|
||||||
"-smp", "cores=4",
|
"-smp", "cores=4",
|
||||||
|
// "-enable-kvm",
|
||||||
"-cpu", "Broadwell-v4"
|
"-cpu", "Broadwell-v4"
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,4 @@ TERM_BACKDROP=008080
|
||||||
MODULE_CMDLINE=""
|
MODULE_CMDLINE=""
|
||||||
|
|
||||||
MODULE_PATH=boot:///limine_framebuffer_driver.hbf
|
MODULE_PATH=boot:///limine_framebuffer_driver.hbf
|
||||||
MODULE_CMDLINE=""
|
MODULE_CMDLINE="height=10 width=10 arch=${ARCH}"
|
|
@ -4,23 +4,131 @@
|
||||||
// Use std abstractions if they exist like logging functionality
|
// Use std abstractions if they exist like logging functionality
|
||||||
import "sysdata/test-programs/hblib/std" as std;
|
import "sysdata/test-programs/hblib/std" as std;
|
||||||
|
|
||||||
|
|
||||||
|
fn rect(reg_x, reg_y, w, h, color) {
|
||||||
|
li64(r3, 0);
|
||||||
|
li64(r4, 0);
|
||||||
|
li64(r5, w);
|
||||||
|
li64(r6, h);
|
||||||
|
|
||||||
|
let start_y = label();
|
||||||
|
|
||||||
|
let start_x = label();
|
||||||
|
|
||||||
|
add64(r9, r3, reg_x);
|
||||||
|
add64(r10, r4, reg_y);
|
||||||
|
pixel(r9, r10, color);
|
||||||
|
|
||||||
|
li64(r1, 1);
|
||||||
|
add64(r3, r3, r1);
|
||||||
|
|
||||||
|
jltu(r3, r5, start_x);
|
||||||
|
|
||||||
|
li64(r1, 1);
|
||||||
|
add64(r4, r4, r1);
|
||||||
|
|
||||||
|
li64(r3, 0);
|
||||||
|
|
||||||
|
jltu(r4, r6, start_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pixel(reg_x, reg_y, color) {
|
||||||
|
let BUFFER = 0xFFFF8000C0000000;
|
||||||
|
let WIDTH = 1024;
|
||||||
|
|
||||||
|
// r1 = y * WIDTH
|
||||||
|
li64(r1, WIDTH);
|
||||||
|
mul64(r1, reg_y, r1);
|
||||||
|
|
||||||
|
// r2 = x + r2
|
||||||
|
add64(r2, reg_x, r1);
|
||||||
|
|
||||||
|
// r2 = r2 * 4
|
||||||
|
li64(r1, 4);
|
||||||
|
mul64(r2, r2, r1);
|
||||||
|
|
||||||
|
// store pixel value
|
||||||
|
li64(r1, color);
|
||||||
|
st(r1, r2, BUFFER, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear() {
|
||||||
|
// rect(r0, r0, 1024, 768, 0xff222222);
|
||||||
|
|
||||||
|
let BUFFER = 0xFFFF8000C0000000;
|
||||||
|
// on arm the FB is at 0xFFFF8000BC430000
|
||||||
|
// FIXME: get the framebuffer pointer from the starting arguments
|
||||||
|
|
||||||
|
li64(r1, 0xff222222);
|
||||||
|
li64(r2, 0);
|
||||||
|
li64(r3, 1);
|
||||||
|
li64(r4, 1024 * 768);
|
||||||
|
li64(r5, 4);
|
||||||
|
let start = label();
|
||||||
|
mul64(r6, r2, r5);
|
||||||
|
st(r1, r6, BUFFER, 4);
|
||||||
|
add64(r2, r2, r3);
|
||||||
|
jltu(r2, r4, start);
|
||||||
|
}
|
||||||
|
|
||||||
// Define main
|
// Define main
|
||||||
fn main(){
|
fn main(){
|
||||||
std::Info("Starting the limine framebuffer driver.");
|
std::Info("Starting the limine framebuffer driver.");
|
||||||
// Color
|
|
||||||
li64(r1, 0xffffffff);
|
li64(r100, 300);
|
||||||
// iterator
|
li64(r101, 300);
|
||||||
li32(r2, 0);
|
li64(r102, 1);
|
||||||
// count
|
li64(r103, 1);
|
||||||
li64(r3, 12);
|
li64(r104, 1024 - 20);
|
||||||
// Label here
|
li64(r105, 768 - 20);
|
||||||
|
li64(r106, 0);
|
||||||
|
li64(r107, 0);
|
||||||
|
|
||||||
|
clear();
|
||||||
|
|
||||||
let start = label();
|
let start = label();
|
||||||
// Write to the memory
|
|
||||||
st(r1, r2, 0xFFFF8000C0000000, 1);
|
rect(r100, r101, 20, 20, 0xff222222);
|
||||||
// Increment
|
//clear();
|
||||||
addi64(r2, r2, 1);
|
|
||||||
// std::Info("abc");
|
add64(r100, r100, r102);
|
||||||
jltu(r2, r3, start);
|
add64(r101, r101, r103);
|
||||||
|
|
||||||
|
let after_x_right = declabel();
|
||||||
|
jltu(r100, r104, after_x_right);
|
||||||
|
li64(r102, -1);
|
||||||
|
here(after_x_right);
|
||||||
|
|
||||||
|
let after_x_left = declabel();
|
||||||
|
jgtu(r100, r106, after_x_left);
|
||||||
|
li64(r102, 1);
|
||||||
|
li64(r100, 0);
|
||||||
|
here(after_x_left);
|
||||||
|
|
||||||
|
let after_y_right = declabel();
|
||||||
|
jltu(r101, r105, after_y_right);
|
||||||
|
li64(r103, -1);
|
||||||
|
here(after_y_right);
|
||||||
|
|
||||||
|
let after_y_left = declabel();
|
||||||
|
jgtu(r101, r107, after_y_left);
|
||||||
|
li64(r103, 1);
|
||||||
|
li64(r101, 0);
|
||||||
|
here(after_y_left);
|
||||||
|
|
||||||
|
rect(r100, r101, 20, 20, 0xffffffff);
|
||||||
|
|
||||||
|
li64(r200, 0);
|
||||||
|
li64(r201, 1);
|
||||||
|
li64(r202, 10000);
|
||||||
|
let wait = label();
|
||||||
|
add64(r200, r200, r201);
|
||||||
|
jltu(r200, r202, wait);
|
||||||
|
|
||||||
|
jeq(r0, r0, start);
|
||||||
|
//jmp(start);
|
||||||
|
|
||||||
|
std::Info("done");
|
||||||
|
|
||||||
// Terminate execution.
|
// Terminate execution.
|
||||||
tx();
|
tx();
|
||||||
|
|
Loading…
Reference in a new issue