init version
This commit is contained in:
1
deps/bios/.gitignore
vendored
Normal file
1
deps/bios/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
10
deps/bios/Cargo.toml
vendored
Normal file
10
deps/bios/Cargo.toml
vendored
Normal 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
1
deps/bios/README.md
vendored
Normal 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
43
deps/bios/src/_dbg.rs
vendored
Normal 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
181
deps/bios/src/lib.rs
vendored
Normal 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
11
deps/bios/src/pte.rs
vendored
Normal 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
2
deps/bios/src/stages.rs
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// disk_num, lba_start
|
||||
pub type SecondStageFn = unsafe extern "fastcall" fn(u16, u32) -> !;
|
||||
Reference in New Issue
Block a user