19 changed files with 274 additions and 46 deletions

No files matched your search

+1 -1
View File
@@ -2,4 +2,4 @@
**/*.rs.bk
/Cargo.lock
/rust_dos.com
rust.kex
*.kex
+7 -5
View File
@@ -2,7 +2,7 @@
name = "kos"
version = "0.1.0"
authors = ["Kitsu <mail@kitsu.me>", "Sweetbread"]
edition = "2018"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,11 +14,13 @@ path = "examples/hwa.rs"
name = "con"
path = "examples/con.rs"
[[example]]
name = "dark"
path = "examples/dark.rs"
[profile.release]
opt-level = "z"
lto = "thin"
[dependencies]
cstr_core = { version = "0.2.4", default-features = false, features = ["nightly"] }
[build-dependencies]
[[example]]
name = "fs_demo"
+1 -1
View File
@@ -18,4 +18,4 @@ args = ["build", "@@remove-empty(RELEASE_FLAG)"]
[tasks.example]
command = "cargo"
args = ["objcopy", "@@remove-empty(RELEASE_FLAG)", "--example", "${@}", "--", "-O", "binary", "--strip-all", "${@}.kex"]
#install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = ["--help"] }
# install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = ["--help"] }
+2 -1
View File
@@ -1,7 +1,8 @@
# Rust library for KolibriOS
Project uses [cargo-make](https://github.com/sagiegurari/cargo-make) for building steps.
You need to install cargo-binutils: `cargo install cargo-binutils` and llvm-tools-preview: `rustup component add llvm-tools-preview` to make it work.
Also you need a working [FASM](https://flatassembler.net/download.php).
Once installed building is trivial then: `cargo make --profile production <example name>` produces
Once installed building is trivial then: `cargo make --profile production example <example name>` produces
a ready-to-use binary at root.
+2 -6
View File
@@ -1,19 +1,15 @@
#![no_std]
#![no_main]
use cstr_core::cstr;
use kos::{dll::Console, threads::exit};
extern crate alloc;
#[no_mangle]
pub fn kol_main() {
let header = cstr!("Rust!");
let string = "Hi from Rust!";
let con_lib = Console::import(None).unwrap();
con_lib.init(u32::MAX, u32::MAX, u32::MAX, u32::MAX, header);
con_lib.write_string(string);
con_lib.init(u32::MAX, u32::MAX, u32::MAX, u32::MAX, c"Rust!");
con_lib.write_string("Hi from Rust!");
con_lib.exit(false);
exit();
+116
View File
@@ -0,0 +1,116 @@
#![no_std]
#![no_main]
use kos::{
graphics::{display_message, Color, Dot, Size},
input::fetch_key,
threads::{exit, fetch_event, Event},
windows::{
define_button, define_window, end_window_draw, get_button_id, invert_pixel,
start_window_draw, WindowKind, WindowParams, CLOSE_BUTTON,
},
};
const HEADER: &'static CStr = c"Dark Mode Demo";
const TEXT: [&'static CStr; 6] = [
c"Lorem ipsum dolor sit amet,",
c"semper et rutrum placerat,",
c"Integer sed diam commodo quam varius",
c"Sed finibus urna sit amet felis",
c"vestibulum elementum. Maecenas at feugiat lacus",
c"tristique et sit amet tortor.",
];
const BTN: u32 = 42;
const WINDOW_SIZE: Size = Size {
width: 400,
height: 400,
};
extern crate alloc;
fn draw_window(invert: bool) {
start_window_draw();
define_window(
Dot { x: 50, y: 50 },
WINDOW_SIZE,
WindowParams {
color: Color::rgb(0xff, 0xff, 0xff),
kind: WindowKind::FixedThemed,
title: Some(HEADER),
},
);
display_message(Dot { x: 10, y: 10 }, Color::rgb(0, 0, 0), TEXT[0], None);
display_message(Dot { x: 10, y: 50 }, Color::rgb(0, 0, 0), TEXT[1], None);
display_message(Dot { x: 10, y: 90 }, Color::rgb(0, 0, 0), TEXT[2], None);
display_message(Dot { x: 10, y: 130 }, Color::rgb(0, 0, 0), TEXT[3], None);
display_message(Dot { x: 10, y: 170 }, Color::rgb(0, 0, 0), TEXT[4], None);
display_message(Dot { x: 10, y: 210 }, Color::rgb(0, 0, 0), TEXT[5], None);
define_button(
Dot { x: 10, y: 300 },
Size {
width: 100,
height: 30,
},
BTN,
true,
true,
Some(Color::rgb(147, 112, 219)),
);
display_message(
Dot { x: 20, y: 310 },
Color::rgb(255, 255, 255),
if invert {
c"Light mode"
} else {
c"Dark mode"
},
None,
);
if invert {
for x in 0..WINDOW_SIZE.width {
for y in 0..WINDOW_SIZE.height {
invert_pixel(Dot { x, y })
}
}
}
end_window_draw();
return;
}
fn button_handler(invert: &mut bool) {
let btn_id = get_button_id();
if btn_id.is_some() {
match btn_id.unwrap() {
CLOSE_BUTTON => exit(),
BTN => {
*invert = !*invert;
draw_window(*invert);
}
_ => {}
}
}
}
#[no_mangle]
fn kol_main() {
let mut invert = false;
while let Some(ev) =
fetch_event((Event::Redraw as u32) | (Event::KeyPress as u32) | (Event::BtnPress as u32))
{
match ev {
Event::Redraw => draw_window(invert),
Event::KeyPress => drop(fetch_key()),
Event::BtnPress => button_handler(&mut invert),
_ => break,
}
}
}
+10
View File
@@ -0,0 +1,10 @@
#![no_std]
#![no_main]
use kos::fs::read_file;
#[no_mangle]
pub fn kol_main() {
let mut buf = [0u8; 256];
let _ = read_file(c"/rd/1/readme.txt", &mut buf);
}
+11 -9
View File
@@ -1,8 +1,8 @@
#![no_std]
#![no_main]
use cstr_core::{cstr, CStr};
use alloc::ffi::CString;
use core::ffi::CStr;
use kos::{
graphics::{display_message, Color, Dot, Size},
input::fetch_key,
@@ -14,8 +14,8 @@ use kos::{
},
};
const HEADER: &CStr = cstr!("Hey Kolibri");
const MSG: &CStr = cstr!("Hello from Rust!");
const HEADER: &CStr = c"Hey Kolibri";
const MSG: &CStr = c"Hello from Rust!";
const BTN: u32 = 42;
#[macro_use]
@@ -45,16 +45,18 @@ fn draw_window(c: usize) {
);
let btn_str = match get_lang() {
Lang::German => format!("Taste gedrückt: {} mal\0", c),
Lang::Russian => format!("Кнопка нажата: {} раз\0", c),
Lang::French => format!("Button enfoncé : {} fois\0", c),
_ => format!("Button pressed: {} times\0", c),
Lang::German => format!("Taste gedrückt: {} mal", c),
Lang::Russian => format!("Кнопка нажата: {} раз", c),
Lang::French => format!("Button enfoncé : {} fois", c),
_ => format!("Button pressed: {} times", c),
};
display_message(
Dot { x: 10, y: 30 },
Color::rgb(0, 0, 0),
CStr::from_bytes_with_nul(btn_str.as_bytes()).unwrap_or(cstr!("String error")),
CString::new(btn_str.as_bytes())
.expect("CString error")
.as_c_str(),
None,
);
+1 -1
View File
@@ -1,7 +1,7 @@
{
"arch": "x86",
"cpu": "pentium",
"data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128",
"data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
"dynamic-linking": false,
"executables": true,
"has-rpath": true,
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::sys;
use cstr_core::CStr;
use core::ffi::CStr;
mod console;
pub use console::Console;
+5 -8
View File
@@ -1,7 +1,6 @@
use crate::dll::DLL;
use core::ffi::CStr;
use core::mem::transmute;
use cstr_core::cstr;
use cstr_core::CStr;
pub struct Console {
con_init: extern "stdcall" fn(u32, u32, u32, u32, *const u8),
@@ -11,16 +10,14 @@ pub struct Console {
impl Console {
pub fn import(path: Option<&CStr>) -> Result<Self, &str> {
let lib = DLL::load_dll(path.unwrap_or(cstr!("/sys/lib/console.obj")));
let lib = DLL::load_dll(path.unwrap_or(c"/sys/lib/console.obj"));
match lib {
Err(e) => return Err(e),
Ok(dll) => unsafe {
Ok(Console {
con_init: transmute(dll.get_func(cstr!("con_init")).ok().unwrap()),
con_write_string: transmute(
dll.get_func(cstr!("con_write_string")).ok().unwrap(),
),
con_exit: transmute(dll.get_func(cstr!("con_exit")).ok().unwrap()),
con_init: transmute(dll.get_func(c"con_init").ok().unwrap()),
con_write_string: transmute(dll.get_func(c"con_write_string").ok().unwrap()),
con_exit: transmute(dll.get_func(c"con_exit").ok().unwrap()),
})
},
}
+58
View File
@@ -0,0 +1,58 @@
use core::ffi::CStr;
use crate::sys::{fs_execute, FsBlock};
fn execute(op: u32, offset: u32, offset_hi: u32, count: u32, buf: *mut u8, path: &CStr) -> Result<(), u32> {
let info = FsBlock {
operation: op,
offset,
offset_hi,
byte_count: count,
buffer: buf,
_pad: 0,
path: path.as_ptr() as *const u8,
};
match unsafe { fs_execute(&info) } {
0 => Ok(()),
e => Err(e),
}
}
pub fn read_file(path: &CStr, buf: &mut [u8]) -> Result<(), u32> {
execute(0, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path)
}
pub fn read_folder(path: &CStr, buf: &mut [u8]) -> Result<(), u32> {
execute(1, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path)
}
pub fn create_file(path: &CStr, buf: &[u8]) -> Result<(), u32> {
execute(2, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path)
}
pub fn write_file(path: &CStr, buf: &[u8]) -> Result<(), u32> {
execute(3, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path)
}
pub fn set_size(path: &CStr, size: u64) -> Result<(), u32> {
execute(4, size as u32, (size >> 32) as u32, 0, core::ptr::null_mut(), path)
}
pub fn get_attributes(path: &CStr, buf: &mut [u8]) -> Result<(), u32> {
execute(5, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path)
}
pub fn set_attributes(path: &CStr, buf: &[u8]) -> Result<(), u32> {
execute(6, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path)
}
pub fn run(path: &CStr) -> Result<(), u32> {
execute(7, 0, 0, 0, core::ptr::null_mut(), path)
}
pub fn delete(path: &CStr) -> Result<(), u32> {
execute(8, 0, 0, 0, core::ptr::null_mut(), path)
}
pub fn create_folder(path: &CStr) -> Result<(), u32> {
execute(9, 0, 0, 0, core::ptr::null_mut(), path)
}
+1
View File
@@ -20,3 +20,4 @@ SF_SYS_MISC = 68
SSF_MEM_ALLOC = 12
SSF_MEM_FREE = 13
SSF_LOAD_DLL = 19
SF_FILE = 70
+1
View File
@@ -6,6 +6,7 @@ mod nanolibc;
pub mod allocation;
pub mod dll;
pub mod sys;
pub mod fs;
pub use modules::*;
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::sys;
use cstr_core::CStr;
use core::ffi::CStr;
#[derive(Clone, Copy)]
pub struct Color(u8, u8, u8);
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::sys;
use crate::throw_new;
use alloc::string::String;
use cstr_core::CStr;
use core::ffi::CStr;
trait Debuggable {
fn data_iter(self) -> impl Iterator<Item = u8>;
+19 -11
View File
@@ -2,7 +2,8 @@ use crate::graphics::{Color, Dot, Size};
use crate::sys;
use crate::system::debug_write;
use crate::throw_new;
use cstr_core::{cstr, CStr};
use alloc::ffi::CString;
use core::ffi::CStr;
#[repr(u32)]
pub enum WindowKind {
@@ -16,12 +17,12 @@ pub enum WindowKind {
pub struct WindowParams<'a> {
pub color: Color,
pub kind: WindowKind,
pub title: Option<&'a cstr_core::CStr>,
pub title: Option<&'a CStr>,
}
pub const CLOSE_BUTTON: u32 = 1;
pub fn define_window(start: Dot, size: Size, params: WindowParams<'_>) {
pub fn define_window(start: Dot, size: Size, params: WindowParams) {
const RELATIVE_FLAG: u32 = 0x20;
unsafe {
@@ -39,6 +40,15 @@ pub fn define_window(start: Dot, size: Size, params: WindowParams<'_>) {
}
}
pub fn put_pixel(pos: Dot, color: Option<Color>) {
let color: u32 = color.unwrap_or(Color::rgb(255, 255, 255)).as_rgb_val();
unsafe { sys::put_pixel(pos.x, pos.y, color) }
}
pub fn invert_pixel(pos: Dot) {
unsafe { sys::put_pixel(pos.x, pos.y, 1 << 24) }
}
pub fn define_button(
start: Dot,
size: Size,
@@ -51,14 +61,12 @@ pub fn define_button(
crate::graphics::display_message(
Dot { x: 10, y: 200 },
Color::rgb(255, 0, 0),
CStr::from_bytes_with_nul(
format!(
"x:{:?} y:{:?} w:{:?} h:{:?}\n\0",
start.x, start.y, size.width, size.height
)
.as_bytes(),
)
.unwrap_or(cstr!("String error")),
CString::new(format!(
"x:{:?} y:{:?} w:{:?} h:{:?}\n",
start.x, start.y, size.width, size.height
))
.expect("CString error")
.as_c_str(),
None,
);
throw_new!(format!(
+19
View File
@@ -8,6 +8,10 @@ extern "C" {
#[link_name = "_define_window"]
pub fn define_window(ebx: u32, ecx: u32, edx: u32, esi: u32, edi: u32);
// 1
#[link_name = "_put_pixel"]
pub fn put_pixel(ebx: u32, ecx: u32, edx: u32);
// 2
#[link_name = "_pressed_key"]
pub fn pressed_key() -> u32;
@@ -63,4 +67,19 @@ extern "C" {
// 68.19
#[link_name = "_load_dll"]
pub fn load_dll(name: *const u8) -> *const u32;
// 70
#[link_name = "_fs_execute"]
pub fn fs_execute(info: *const FsBlock) -> u32;
}
#[repr(C)]
pub(crate) struct FsBlock {
pub operation: u32,
pub offset: u32,
pub offset_hi: u32,
pub byte_count: u32,
pub buffer: *mut u8,
pub _pad: u8,
pub path: *const u8,
}
+17
View File
@@ -7,6 +7,7 @@ section '.text'
public _start_window_draw
public _end_window_draw
public _define_window
public _put_pixel
public _display_message
public _wait_event
public _pressed_key
@@ -19,6 +20,7 @@ section '.text'
public _get_lang
public _load_dll
public _set_event_mask
public _fs_execute
_exit:
mov eax, SF_TERMINATE_PROCESS
@@ -50,6 +52,14 @@ _define_window:
pop edi
ret
_put_pixel:
mov eax, SF_PUT_PIXEL
mov ebx, dword [esp + 4 * 1]
mov ecx, dword [esp + 4 * 2]
mov edx, dword [esp + 4 * 3]
int 0x40
ret
_display_message:
push esi edi
mov eax, SF_DRAW_TEXT
@@ -134,3 +144,10 @@ _set_event_mask:
int 0x40
ret
_fs_execute:
push ebx
mov eax, SF_FILE
mov ebx, [esp + 4 * 2]
int 0x40
pop ebx
ret