Compare commits

..

2 commits

Author SHA1 Message Date
able 02455e2cd8 deprecate the old assembler 2024-05-31 13:35:46 -05:00
able e08eab8627 patching together some broken stuff 2024-05-31 13:31:06 -05:00
15 changed files with 35 additions and 547 deletions

View file

@ -1,4 +1,5 @@
use std::{
fmt::format,
fs::{read_to_string, File},
io::{BufWriter, Write},
process::exit,
@ -67,21 +68,24 @@ impl Package {
let mut files = vec![];
for (count, file) in file_order.enumerate() {
if count != 0 {
println!("{}", file);
files.push(file);
}
}
let mut bundle = vec![];
for file in files {
let contents = read_to_string(file).unwrap();
let file_path = if file.starts_with("libraries") {
format!("sysdata/{}", file)
} else {
format!("sysdata/programs/{}/{}", self.name, file)
};
let contents = read_to_string(file_path).unwrap();
bundle.push((file, contents));
}
use hblang::{codegen, parser};
let mut codegen = codegen::Codegen::default();
for (path, content) in bundle.iter() {
println!("A");
codegen.files = vec![parser::Ast::new(&path, &content, &parser::no_loader)];
codegen.files = vec![parser::Ast::new(path, content, &parser::no_loader)];
codegen.generate();
}
let mut buf = BufWriter::new(Vec::new());
@ -92,7 +96,7 @@ impl Package {
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (),
Err(e) => panic!(),
}
let path = format!("target/test-programs/{}.hbf", self.name);
let path = format!("target/programs/{}.hbf", self.name);
let mut file = File::create(path).unwrap();
file.write_all(&bytes).unwrap();
}

View file

@ -19,14 +19,6 @@ fn main() -> Result<(), Error> {
let mut args = std::env::args();
args.next();
// let disk_meta = fs::metadata("target/disk.img").unwrap();
// let config_meta = fs::metadata("system.toml").unwrap();
// if disk_meta.modified().unwrap() < config_meta.modified().unwrap() {
// // TODO: work on adding in system.toml support
// // TODO: rebuild the disk
// }
match args.next().as_deref() {
Some("build" | "b") => {
let mut release = false;
@ -43,7 +35,6 @@ fn main() -> Result<(), Error> {
}
}
assemble()?;
build(release, target).change_context(Error::Build)
}
Some("run" | "r") => {
@ -61,7 +52,6 @@ fn main() -> Result<(), Error> {
}
}
assemble()?;
build(release, target)?;
run(release, target)
}
@ -82,49 +72,6 @@ fn main() -> Result<(), Error> {
}
}
fn assemble() -> Result<(), Error> {
match std::fs::create_dir("target/test-programs") {
Ok(_) => (),
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (),
Err(e) => return Err(Report::new(e).change_context(Error::Io)),
}
for entry in std::fs::read_dir("sysdata/test-programs")
.map_err(Report::from)
.change_context(Error::Io)?
{
let entry = entry.map_err(Report::from).change_context(Error::Io)?;
if !entry
.file_type()
.map_err(Report::from)
.change_context(Error::Io)?
.is_file()
{
continue;
}
let name = entry.file_name();
let name = name.to_string_lossy();
let name = name.trim_end_matches(".rhai");
let mut out = File::options()
.write(true)
.create(true)
.open(Path::new("target/test-programs").join(format!("{name}.hbf")))
.map_err(Report::from)
.change_context(Error::Io)?;
out.set_len(0)
.map_err(Report::from)
.change_context(Error::Io)?;
// hbasm::assembler(&mut out, |engine| engine.run_file(entry.path()))
// .map_err(|e| report!(Error::Assembler).attach_printable(e.to_string()))?;
}
Ok(())
}
fn get_path_without_boot_prefix(val: &Value) -> Option<&str> {
val.as_str()?.split("boot:///").last()
}
@ -241,7 +188,7 @@ TERM_BACKDROP={}
// let mut real_modules = modules.clone();
modules.into_iter().for_each(|(key, value)| {
if value.is_table() && key == "tests" {
if value.is_table() {
let path = get_path_without_boot_prefix(
value.get("path").expect("You must have `path` as a value"),
)
@ -280,7 +227,7 @@ TERM_BACKDROP={}
.expect("You must have a `path` as a value"),
)
.unwrap();
let fpath = format!("target/test-programs/{}", path);
let fpath = format!("target/programs/{}", path);
copy_file_to_img(&fpath, &fs);
}
});
@ -312,6 +259,7 @@ TERM_BACKDROP={}
fn copy_file_to_img(fpath: &str, fs: &FileSystem<File>) {
let path = Path::new(fpath);
// println!("{path:?}");
io::copy(
&mut File::open(path).expect(&format!("Could not open file {fpath}")),
&mut fs

View file

@ -2,7 +2,7 @@ char := struct {}
log := fn(log_level: int, message: ^char, message_length: int): int {
@eca(i32,1, 1, 1)
return 0;
}
@ -28,4 +28,8 @@ trace := fn(message: ^char, message_length: int): int {
main := fn(): int {
return 0;
}
}
test := fn(): int {
@eca(i32, 1, 1, 1);
}

View file

@ -0,0 +1,11 @@
[package]
name = "diskio_driver"
authors = ["able"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang libraries/stn/src/lib.hb src/main.hb"

View file

@ -1,4 +1,3 @@
main := fn(): int {
return 0;
}

View file

@ -1,5 +1,5 @@
[package]
name = "dev"
name = "fb_driver"
authors = ["able"]
[dependants.libraries]
@ -7,5 +7,5 @@ authors = ["able"]
[dependants.binaries]
hblang.version = "1.0.0"
[build.debug]
command = "hblang libraries/stn/src/lib.hb src/main.hbl"
[build]
command = "hblang libraries/stn/src/lib.hb src/main.hb"

View file

@ -8,4 +8,4 @@ authors = ["able"]
hblang.version = "1.0.0"
[build]
command = "hblang sysdata/libraries/stn/src/lib.hb sysdata/programs/tests/src/main.hb"
command = "hblang libraries/stn/src/lib.hb src/main.hb"

View file

@ -18,5 +18,6 @@ resolution = "1024x768x24"
[boot.limine.ableos.modules]
[boot.limine.ableos.modules.tests]
# TODO: Pull from the programs included here
path = "boot:///tests.hbf"
[boot.limine.ableos.modules.diskio_driver]
path = "boot:///diskio_driver.hbf"

View file

@ -1 +0,0 @@
A kind of standard library.

View file

@ -1,54 +0,0 @@
fn ipc_send(buffer_id, mem_addr, length){
// set the ecall
li64(r1, 3);
// Set the buffer ID to be the BufferID
li64(r2, buffer_id);
lra(r3, r0, mem_addr);
// set the length
li64(r4, length);
// ecall
eca();
}
fn ipc_recv(buffer_id){
li64(r1, 4);
eca();
}
fn ipc_make_bound_buffer(length) {
li64(r1, 1);
li64(r2, 1);
li64(r3, length);
eca();
// The ipc buffer id is in r1
}
private fn log(log_level, string){
// This is NOT the final format
let str = data::str(string + log_level);
// 1 byte for the log level
// 8 bytes for the length to the message
// 8 bytes for the pointer to the string
ipc_send(1, str, str.len);
}
fn Error(string) {log(0, string);}
fn Warn(string) {log(1, string);}
fn Info(string) {log(2, string);}
// Due to rhai limitations this cannot be debug
// because of this all of the log levels are upper case
fn Debug(string) {log(3, string);}
fn Trace(string) {log(4, string);}
fn open(string_path){
let file_path = data::str(string_path);
ipc_send(2, file_path, file_path.len);
}
fn write(){}
fn read(){}
fn close(){}

View file

@ -1,199 +0,0 @@
import "sysdata/test-programs/hblib/std" as std;
fn print_register(reg){
std::Debug("-----------------");
let c0 = declabel();
let c1 = declabel();
let c2 = declabel();
let c3 = declabel();
let c4 = declabel();
let c5 = declabel();
let c6 = declabel();
let c7 = declabel();
let c8 = declabel();
let c9 = declabel();
let ca = declabel();
let cb = declabel();
let cc = declabel();
let cd = declabel();
let ce = declabel();
let cf = declabel();
let end = declabel();
cp(r32, reg);
li64(r35, 16);
let next_loop = label();
addi64(r35, r35, -1);
li64(r37, 4);
mul64(r36, r35, r37);
sru64(r34, r32, r36);
andi(r34, r34, 0xf);
li64(r33, 0);
jeq(r34, r33, c0);
addi64(r33, r33, 1);
jeq(r34, r33, c1);
addi64(r33, r33, 1);
jeq(r34, r33, c2);
addi64(r33, r33, 1);
jeq(r34, r33, c3);
addi64(r33, r33, 1);
jeq(r34, r33, c4);
addi64(r33, r33, 1);
jeq(r34, r33, c5);
addi64(r33, r33, 1);
jeq(r34, r33, c6);
addi64(r33, r33, 1);
jeq(r34, r33, c7);
addi64(r33, r33, 1);
jeq(r34, r33, c8);
addi64(r33, r33, 1);
jeq(r34, r33, c9);
addi64(r33, r33, 1);
jeq(r34, r33, ca);
addi64(r33, r33, 1);
jeq(r34, r33, cb);
addi64(r33, r33, 1);
jeq(r34, r33, cc);
addi64(r33, r33, 1);
jeq(r34, r33, cd);
addi64(r33, r33, 1);
jeq(r34, r33, ce);
addi64(r33, r33, 1);
jeq(r34, r33, cf);
std::Error("This should be an invalid state");
let next = label();
jne(r0, r35, next_loop);
jeq(r0, r0, end);
here(c0);
std::Debug("0");
jeq(r0, r0, next);
here(c1);
std::Debug("1");
jeq(r0, r0, next);
here(c2);
std::Debug("2");
jeq(r0, r0, next);
here(c3);
std::Debug("3");
jeq(r0, r0, next);
here(c4);
std::Debug("4");
jeq(r0, r0, next);
here(c5);
std::Debug("5");
jeq(r0, r0, next);
here(c6);
std::Debug("6");
jeq(r0, r0, next);
here(c7);
std::Debug("7");
jeq(r0, r0, next);
here(c8);
std::Debug("8");
jeq(r0, r0, next);
here(c9);
std::Debug("9");
jeq(r0, r0, next);
here(ca);
std::Debug("A");
jeq(r0, r0, next);
here(cb);
std::Debug("B");
jeq(r0, r0, next);
here(cc);
std::Debug("C");
jeq(r0, r0, next);
here(cd);
std::Debug("D");
jeq(r0, r0, next);
here(ce);
std::Debug("E");
jeq(r0, r0, next);
here(cf);
std::Debug("F");
jeq(r0, r0, next);
here(end);
std::Debug("-----------------");
}
fn get_keyboard_status(){
li64(r1, 5);
li64(r2, 0x64);
eca();
}
fn get_keyboard_input(){
li64(r1, 5);
li64(r2, 0x60);
eca();
}
fn is_keyup(rb, ra){
li64(rb, 15);
sru64(rb, ra, rb);
andi(rb, rb, 1);
}
fn dump_registers(){
li64(r1, 0xff);
eca();
}
fn to_ascii(rb, ra){
let str = data::str(
" 1234567890-= " +
"qwertyuiop[] " +
"asdfghjkl;'` \\" +
"zxcvbnm,./ " +
"* " +
"789-456+1230. "
);
andi(r33, ra, 0x00ff);
lra(rb, r0, str);
add64(rb, rb, r33);
ld(rb, rb, 0, 1);
}
fn display_key(ra){
andi(r33, ra, 0x00ff);
ori(r33, r33, 0x0200);
let location = 0x20000;
li64(r32, location);
st(r33, r32, 0, 2);
li64(r1, 3);
li64(r2, 1);
li64(r3, location);
li64(r4, 2);
eca();
}
fn main(){
let key_up = declabel();
let main_loop = label();
get_keyboard_status();
andi(r12, r3, 1);
li64(r13, 0x1);
jne(r13, r12, main_loop);
get_keyboard_input();
cp(r12, r3);
is_keyup(r14, r12);
jne(r0, r14, key_up);
to_ascii(r15, r12);
display_key(r15);
jeq(r0, r0, main_loop);
here(key_up);
jeq(r0, r0, main_loop);
tx();
}
main();

View file

@ -1,164 +0,0 @@
// Change and add to this as you see fit.
// The STD and even syscalls are still in flux.
// Do your best to avoid adding bad design.
// Use std abstractions if they exist like logging functionality
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;
// let BUFFER = 0xFFFF8000BC430000;
// 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
fn main() {
// Log the arguments
{
cp(r3, r1);
cp(r4, r2);
// log level
li8(r6, 2);
add64(r5, r3, r4);
li64(r7, 1);
st(r6, r5, 0, 1);
add64(r4, r4, r7);
li64(r1, 3);
li64(r2, 1);
eca();
// Zero out all used registers
li64(r1, 0);
li64(r2, 0);
li64(r3, 0);
li64(r4, 0);
li64(r5, 0);
li64(r6, 0);
li64(r7, 0);
}
std::Info("Starting the limine framebuffer driver.");
// un();
li64(r100, 300);
li64(r101, 300);
li64(r102, 1);
li64(r103, 1);
li64(r104, 1024 - 20);
li64(r105, 768 - 20);
li64(r106, 0);
li64(r107, 0);
clear();
let start = label();
rect(r100, r101, 20, 20, 0xff222222);
//clear();
add64(r100, r100, r102);
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.
tx();
}
main();

View file

@ -1,19 +0,0 @@
fn create_buffer_protocol(string) {
let str = data::str("0" + string);
li8(r10, 0);
str(r10, r0, str, 1);
li64(r1, 3);
li64(r2, 0);
lra(r3, r0, str);
li64(r4, str.len);
eca();
}
create_buffer_protocol("protocol Math {\n\r"+
"\tfn add(i64, i64) -> i64;\n\r"+
"\tfn div(i64, i64) -> i64;\n\r"+
"}");
tx();

View file

@ -1,27 +0,0 @@
import "sysdata/test-programs/hblib/std" as std;
fn main(){
let ADDR = 0;
// FIXME: Actually check the arch argument
let architecture = "ARM";
if architecture == "ARM" {
std::Info("Arm Serial Driver");
ADDR = 0x09000000;
}
lra(r3, r0, ADDR);
li64(r1, 0);
li8(r1, 65);
st(r1, r0, ADDR, 1);
// New Line
li8(r1, 12);st(r1, r0, ADDR, 1);
tx();
}
main();

View file

@ -1,15 +0,0 @@
import "sysdata/test-programs/hblib/std" as std;
fn main(){
std::Info("Trying to open a file.");
std::open("/file.hbf");
std::write();
std::read();
std::close();
std::Info("VFS Test done!");
// un();
tx();
}
main();