init version

This commit is contained in:
2026-02-20 22:17:31 +01:00
commit c4c1a4350c
28 changed files with 755 additions and 0 deletions

1
deps/bios/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

10
deps/bios/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "bios"
version = "0.1.0"
edition = "2024"
[lib]
test = false
bench = false
[dependencies]

1
deps/bios/README.md vendored Normal file
View File

@@ -0,0 +1 @@
Figured that the ABI would bug on 16-bit mode so I have to force inline everything in here to prevent issues.

43
deps/bios/src/_dbg.rs vendored Normal file
View File

@@ -0,0 +1,43 @@
use crate::video::{self, BiosColor, print_char};
// commented out for noew bcs i gotta debug and this + all strings
// uses half the the MBR space ffs WHTFD IS CARGO DOING TO NBLOAT IS SIO MUCH AIUDS
// this uses like... 50% of the size fsr... and not THAT many strings
#[inline(always)]
pub fn write_str(string: &[u8], color: BiosColor) {
for &ch in string {
print_char(ch, 0, color);
}
}
#[inline(always)]
pub fn print_u8_hex(n: u8, c: BiosColor) {
for ch in [(n & 0xf0) >> 4, n & 0x0f] {
let ch = if ch < 10 { b'0' + ch } else { b'A' + ch - 10 };
video::print_char(ch, 0, c);
}
}
#[allow(clippy::missing_safety_doc)]
#[inline(always)]
pub unsafe fn memdump_color(from: *const u8, length: usize, ln_break: usize) {
for i in 0..length {
let byte = unsafe { *from.add(i) };
let color = unsafe { core::mem::transmute::<u8, BiosColor>(!byte >> 4) };
self::print_u8_hex(byte, color);
print_char(b' ', 0, color);
if (i + 1) % ln_break == 0 {
print_char(b'\r', 0, color);
print_char(b'\n', 0, color);
}
}
}
#[inline(always)]
pub fn print_u16(n: u16, c: BiosColor) {
let mut i = 10000;
while i > 0 {
video::print_char(b'0' + ((n / i) % 10) as u8, 0, c);
i /= 10;
}
}

181
deps/bios/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,181 @@
#![no_std]
pub mod _dbg;
pub mod pte;
pub mod stages;
pub mod video {
// https://en.wikipedia.org/wiki/INT_10H
use core::arch::asm;
/// https://mendelson.org/wpdos/videomodes.txt
/// 0x0F = (640x480, 16 colors, High-Resolution Text)
/// 0x12 = (640x480, 16 colors)
/// 0x13 = (320x200, 256 colors)
#[inline(always)]
pub fn set_video_mode(mode: u8) {
unsafe {
asm!(
"int 10h",
in("ah") 0x00_u8,
in("al") mode,
);
}
}
#[inline(always)]
pub fn set_cursor_pos(page_num: u8, row: u8, col: u8) {
unsafe {
asm!(
"int 10h",
in("ah") 0x02_u8,
in("bh") page_num,
in("dh") row,
in("dl") col,
);
}
}
#[inline(always)]
pub fn print_char(ch: u8, page_num: u8, color: BiosColor) {
unsafe {
asm!(
"int 10h",
in("ah") 0x0e_u8,
in("al") ch,
in("bh") page_num,
in("bl") color as u8,
options(nomem, nostack),
);
}
}
// https://en.wikipedia.org/wiki/BIOS_color_attributes
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum BiosColor {
Black = 0x0,
Blue = 0x1,
Green = 0x2,
Cyan = 0x3,
Red = 0x4,
Magenta = 0x5,
Brown = 0x6,
LightGray = 0x7,
DarkGray = 0x8,
LightBlue = 0x9,
LightGreen = 0xA,
LightCyan = 0xB,
LightRed = 0xC,
LightMagenta = 0xD,
Yellow = 0xE,
White = 0xF,
}
}
pub mod disk {
// https://en.wikipedia.org/wiki/INT_13H
use core::arch::asm;
#[inline(always)]
pub fn read_sectors(
read_sectors: u8,
cylinder: u16,
sector: u8,
head: u8,
drive: u8,
ptr: *const (),
) -> (u8, u8) {
unsafe {
let mut ah: u8 = 0x02;
let mut al: u8 = read_sectors;
// ptr is es:bx, but all ptrs here are 16bit,
// so we dont care about es and half of bx
//
// cf can be smth on error, but idk how to deal
// properly with it on rust so... ¯\_(ツ)_/¯
asm!(
"push es",
"xor es, es",
"int 13h",
"pop es",
inout("ah") ah,
inout("al") al,
in("cx") (cylinder << 6) | (sector as u16 & 0b0011_1111),
in("dh") head,
in("dl") drive,
in("bx") ptr as u16,
// out("cf") _,
options(nomem, nostack),
);
let ret_code = ah;
let read_sectors = al;
(ret_code, read_sectors)
}
}
#[inline(always)]
pub fn extended_read_from_drive(dap_packet: &dap::DiskAccessPacket, drive: u16) {
let dap_ptr = dap::DiskAccessPacket::to_offset_segment(dap_packet as *const _ as *const _);
unsafe {
asm!(
"push si",
"push ds",
"mov si, {ptr_seg:x}",
"mov ds, {ptr_off:x}",
"int 13h",
"pop ds",
"pop si",
in("ah") 0x42_u8,
in("dx") drive,
ptr_seg = in(reg) dap_ptr.0,
ptr_off = in(reg) dap_ptr.1,
options(nostack)
);
}
}
pub mod dap {
// https://en.m.wikipedia.org/wiki/INT_13H#INT_13h_AH=42h:_Extended_Read_Sectors_From_Drive
#[repr(C, packed)]
pub struct DiskAccessPacket {
size: u8,
__zero: u8,
read_sectors: u16,
offset: u16,
segment: u16,
lba_start: u64,
}
impl DiskAccessPacket {
#[inline(always)]
pub fn new(read_sectors: u16, ptr: *const (), lba_start: u64) -> Self {
let (offset, segment) = Self::to_offset_segment(ptr);
Self {
size: core::mem::size_of::<DiskAccessPacket>() as u8,
__zero: 0,
read_sectors,
offset,
segment,
lba_start,
}
}
#[inline(always)]
pub fn interrupt(&self, drive: u16) {
super::extended_read_from_drive(self, drive);
}
#[inline(always)]
pub fn to_offset_segment(ptr: *const ()) -> (u16, u16) {
let ptr = ptr as u32;
((ptr & 0xF) as u16, (ptr >> 4) as u16)
}
}
}
}

11
deps/bios/src/pte.rs vendored Normal file
View File

@@ -0,0 +1,11 @@
type ChsAddr = [u8; 3]; // my beloved u24
// https://en.wikipedia.org/wiki/Master_boot_record#PTE
#[repr(C, packed)]
pub struct PartitionTableEntry {
pub status: u8,
pub chs_start: ChsAddr,
pub part_type: u8,
pub chs_end: ChsAddr,
pub lba_start: u32, // could make it a ptr?
pub size: u32,
}

2
deps/bios/src/stages.rs vendored Normal file
View File

@@ -0,0 +1,2 @@
/// disk_num, lba_start
pub type SecondStageFn = unsafe extern "fastcall" fn(u16, u32) -> !;