initial commit
This commit is contained in:
		
							
								
								
									
										7
									
								
								.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
[unstable]
 | 
			
		||||
build-std = ["core", "compiler_builtins", "alloc"]
 | 
			
		||||
build-std-features = ["compiler-builtins-mem"]
 | 
			
		||||
 | 
			
		||||
[build]
 | 
			
		||||
target = "dos.json"
 | 
			
		||||
rustflags = ["-C", "opt-level=z"]
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/target
 | 
			
		||||
							
								
								
									
										22
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "rust-le-demo"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
authors = ["lucia"]
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
heapless = { version = "0.7.16", features = ["ufmt-impl"] }
 | 
			
		||||
spin = "0.9.4"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[profile.dev]
 | 
			
		||||
panic = "abort"
 | 
			
		||||
lto = "fat"
 | 
			
		||||
codegen-units = 1
 | 
			
		||||
 | 
			
		||||
[profile.release]
 | 
			
		||||
panic = "abort"
 | 
			
		||||
lto = "fat"
 | 
			
		||||
codegen-units = 1
 | 
			
		||||
							
								
								
									
										30
									
								
								dos.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								dos.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
{
 | 
			
		||||
    "arch": "x86",
 | 
			
		||||
    "cpu": "i386",
 | 
			
		||||
    "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",
 | 
			
		||||
    "dynamic-linking": false,
 | 
			
		||||
    "executables": true,
 | 
			
		||||
    "exe-suffix": ".elf",
 | 
			
		||||
    "linker-flavor": "gcc",
 | 
			
		||||
    "linker-is-gnu": true,
 | 
			
		||||
    "llvm-target": "i586-unknown-none-none",
 | 
			
		||||
    "max-atomic-width": 64,
 | 
			
		||||
    "position-independent-executables": false,
 | 
			
		||||
    "relocation-model": "static",
 | 
			
		||||
    "disable-redzone": true,
 | 
			
		||||
    "pre-link-args": {
 | 
			
		||||
      "gcc": [
 | 
			
		||||
        "-m32",
 | 
			
		||||
        "-nostdlib",
 | 
			
		||||
        "-march=i386",
 | 
			
		||||
        "-Wl,-r"
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    "relro-level": "full",
 | 
			
		||||
    "target-c-int-width": "32",
 | 
			
		||||
    "target-endian": "little",
 | 
			
		||||
    "target-pointer-width": "32",
 | 
			
		||||
    "os": "none",
 | 
			
		||||
    "vendor": "unknown",
 | 
			
		||||
    "panic-strategy": "abort"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								rust-toolchain
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								rust-toolchain
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
nightly
 | 
			
		||||
							
								
								
									
										120
									
								
								src/dpmi.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/dpmi.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
use core::{arch::asm, fmt::{Arguments, Write}};
 | 
			
		||||
 | 
			
		||||
extern crate alloc;
 | 
			
		||||
 | 
			
		||||
#[allow(dead_code)]
 | 
			
		||||
#[repr(packed)]
 | 
			
		||||
pub struct DpmiRegs {
 | 
			
		||||
    pub edi: u32,
 | 
			
		||||
    pub esi: u32,
 | 
			
		||||
    pub ebp: u32,
 | 
			
		||||
    reserved_zero: u32,
 | 
			
		||||
    pub ebx: u32,
 | 
			
		||||
    pub edx: u32,
 | 
			
		||||
    pub ecx: u32,
 | 
			
		||||
    pub eax: u32,
 | 
			
		||||
    pub status_flags: u16,
 | 
			
		||||
    pub es: u16,
 | 
			
		||||
    pub ds: u16,
 | 
			
		||||
    pub fs: u16,
 | 
			
		||||
    pub gs: u16,
 | 
			
		||||
    ip_ignored: u16,
 | 
			
		||||
    cs_ignored: u16,
 | 
			
		||||
    pub sp: u16,
 | 
			
		||||
    pub ss: u16
 | 
			
		||||
}
 | 
			
		||||
impl DpmiRegs {
 | 
			
		||||
    pub const fn zero() -> Self {
 | 
			
		||||
        DpmiRegs { edi: 0, esi: 0, ebp: 0, reserved_zero: 0, ebx: 0, edx: 0, ecx: 0, eax: 0, status_flags: 0, es: 0, ds: 0, fs: 0, gs: 0, ip_ignored: 0, cs_ignored: 0, sp: 0, ss: 0 }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[inline]
 | 
			
		||||
pub fn set_video_mode(mode: u8) {
 | 
			
		||||
    let mut regs = DpmiRegs::zero();
 | 
			
		||||
    regs.eax = mode as u32;
 | 
			
		||||
    real_int(0x10, &mut regs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn getchar() -> u16 {
 | 
			
		||||
    let mut regs = DpmiRegs::zero();
 | 
			
		||||
    real_int(0x16, &mut regs);
 | 
			
		||||
    regs.eax as u16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn kb_status() -> Option<u16> {
 | 
			
		||||
    let mut regs = DpmiRegs::zero();
 | 
			
		||||
    regs.eax = 0x100;
 | 
			
		||||
    real_int(0x16, &mut regs);
 | 
			
		||||
    match regs.status_flags & 0x40 {
 | 
			
		||||
        0 => match regs.eax as u16 {
 | 
			
		||||
            0 => None,
 | 
			
		||||
            v => Some(v),
 | 
			
		||||
        },
 | 
			
		||||
        _ => None
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn get_psp() -> *const u8 {
 | 
			
		||||
    let psp: u32;
 | 
			
		||||
    unsafe { asm!(
 | 
			
		||||
        "int 0x21",
 | 
			
		||||
        in("ax") 0x5100_u16,
 | 
			
		||||
        out("ebx") psp
 | 
			
		||||
    ); }
 | 
			
		||||
    (psp << 4) as *const u8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn real_int(int: u8, regs: &mut DpmiRegs) {
 | 
			
		||||
    unsafe { asm!(
 | 
			
		||||
        "int 0x31",
 | 
			
		||||
        in("bx") 0x0000_u16 | int as u16,
 | 
			
		||||
        in("cx") 0x0000_u16,
 | 
			
		||||
        in("edi") regs,
 | 
			
		||||
        inout("ax") 0x0300_u16 => _
 | 
			
		||||
    );}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn dpmi_print(string: &str) {
 | 
			
		||||
    // DOS DPMI function 21h, AH 9h
 | 
			
		||||
    // Prints string pointed to
 | 
			
		||||
    // by EDX, terminated with $
 | 
			
		||||
    unsafe { asm!(
 | 
			
		||||
        "int 0x21",
 | 
			
		||||
        in("ah") 0x9_u8,
 | 
			
		||||
        in("edx") string.as_ptr()
 | 
			
		||||
    ); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn dpmi_exit() -> ! {
 | 
			
		||||
    // DOS DPMI function Exit: 21h, AH 4Ch
 | 
			
		||||
    unsafe { asm!(
 | 
			
		||||
        "int 0x21",
 | 
			
		||||
        in("ah") 0x4C_u8
 | 
			
		||||
    ); }
 | 
			
		||||
    loop {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
macro_rules! _raw_print {
 | 
			
		||||
    ($($arg:tt)*) => ($crate::dpmi::_print(format_args!($($arg)*)));
 | 
			
		||||
}
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! print {
 | 
			
		||||
    ($($arg:tt)*) => ($crate::_raw_print!("{}$", format_args!($($arg)*)));
 | 
			
		||||
}
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! println {
 | 
			
		||||
    () => (_raw_print!("\r\n$"));
 | 
			
		||||
    ($($arg:tt)*) => ($crate::_raw_print!("{}\r\n$", format_args!($($arg)*)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
pub fn _print(args: Arguments) {
 | 
			
		||||
    let mut s: alloc::string::String = alloc::string::String::new();
 | 
			
		||||
    //let mut s: heapless::String<20> = heapless::String::new();
 | 
			
		||||
    s.write_fmt(args).unwrap();
 | 
			
		||||
    dpmi_print(s.as_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										192
									
								
								src/dpmi_alloc.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								src/dpmi_alloc.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
use core::{ptr::null_mut, arch::asm, alloc::Layout};
 | 
			
		||||
use core::fmt::Write;
 | 
			
		||||
use heapless::String;
 | 
			
		||||
 | 
			
		||||
const PTR_COUNT: usize = 1024;
 | 
			
		||||
 | 
			
		||||
struct Locked<A> {
 | 
			
		||||
    inner: spin::Mutex<A>,
 | 
			
		||||
}
 | 
			
		||||
impl<A> Locked<A> {
 | 
			
		||||
    pub const fn new(inner: A) -> Self {
 | 
			
		||||
        Locked {
 | 
			
		||||
            inner: spin::Mutex::new(inner)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn lock(&self) -> spin::MutexGuard<A> {
 | 
			
		||||
        self.inner.lock()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn init_allocator() { unsafe {
 | 
			
		||||
    ALLOCATOR.inner.force_unlock();
 | 
			
		||||
    let mut t = ALLOCATOR.lock();
 | 
			
		||||
    //  3.53 - DOS function 0FF91h - DOS/32 Advanced Allocate High Memory Block
 | 
			
		||||
    //  In: 	AX = 0FF91h
 | 
			
		||||
    //  EBX = size of memory block in bytes
 | 
			
		||||
    //  Out: 	
 | 
			
		||||
    //  if successful:
 | 
			
		||||
    //  CF clear
 | 
			
		||||
    //  EBX = linear address of allocated memory block
 | 
			
		||||
    //  ESI = handle of allocated memory block
 | 
			
		||||
    //  if failed:
 | 
			
		||||
    //  CF set
 | 
			
		||||
    let ptr: u32;
 | 
			
		||||
    let handle: u32;
 | 
			
		||||
    asm!(
 | 
			
		||||
        "mov edx, esi",
 | 
			
		||||
        "int 0x21",
 | 
			
		||||
        "mov eax, esi",
 | 
			
		||||
        "mov esi, edx",
 | 
			
		||||
        inout("eax") 0x0FF91 => handle,
 | 
			
		||||
        inout("ebx") PTR_COUNT * core::mem::size_of::<DpmiPtr>() => ptr,
 | 
			
		||||
        out("edx") _
 | 
			
		||||
    );
 | 
			
		||||
    t.ptrs = ptr;
 | 
			
		||||
    t.global_handle = handle;
 | 
			
		||||
    let mut ptrs = core::slice::from_raw_parts_mut::<DpmiPtr>(t.ptrs as *mut DpmiPtr, PTR_COUNT);
 | 
			
		||||
    for p in ptrs.iter_mut() {
 | 
			
		||||
        *p = DpmiPtr { ptr: 0, handle: 0 };
 | 
			
		||||
    }
 | 
			
		||||
} }
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
struct DpmiPtr {
 | 
			
		||||
    ptr: u32,
 | 
			
		||||
    handle: u32
 | 
			
		||||
}
 | 
			
		||||
pub struct DpmiAlloc {
 | 
			
		||||
    ptrs: u32,
 | 
			
		||||
    global_handle: u32
 | 
			
		||||
}
 | 
			
		||||
impl DpmiAlloc {
 | 
			
		||||
    const fn new() -> Self { DpmiAlloc { ptrs: 0, global_handle: 0 } }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsafe impl core::alloc::GlobalAlloc for Locked<DpmiAlloc> {
 | 
			
		||||
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
 | 
			
		||||
        let mut dat = self.lock();
 | 
			
		||||
        let mut ptrs = unsafe { core::slice::from_raw_parts_mut::<DpmiPtr>(dat.ptrs as *mut DpmiPtr, PTR_COUNT) };
 | 
			
		||||
        let free_idx: usize = {
 | 
			
		||||
            let mut tmp = None;
 | 
			
		||||
            for (i, p) in ptrs.iter().enumerate() {
 | 
			
		||||
                if p.ptr == 0 { tmp = Some(i); break; }
 | 
			
		||||
            }
 | 
			
		||||
            match tmp {
 | 
			
		||||
                None => { asm!("int 0x1", in("eax") ptrs.as_ptr()); return null_mut(); }
 | 
			
		||||
                Some(i) => i
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        //  3.53 - DOS function 0FF91h - DOS/32 Advanced Allocate High Memory Block
 | 
			
		||||
        //  In: 	AX = 0FF91h
 | 
			
		||||
        //  EBX = size of memory block in bytes
 | 
			
		||||
        //  Out: 	
 | 
			
		||||
        //  if successful:
 | 
			
		||||
        //  CF clear
 | 
			
		||||
        //  EBX = linear address of allocated memory block
 | 
			
		||||
        //  ESI = handle of allocated memory block
 | 
			
		||||
        //  if failed:
 | 
			
		||||
        //  CF set
 | 
			
		||||
        let ptr: u32;
 | 
			
		||||
        let handle: u32;
 | 
			
		||||
        asm!(
 | 
			
		||||
            "mov edx, esi",
 | 
			
		||||
            "int 0x21",
 | 
			
		||||
            "mov eax, esi",
 | 
			
		||||
            "mov esi, edx",
 | 
			
		||||
            inout("eax") 0x0FF91 => handle,
 | 
			
		||||
            inout("ebx") layout.size() as u32 => ptr,
 | 
			
		||||
            out("edx") _
 | 
			
		||||
        );
 | 
			
		||||
        ptrs[free_idx] = DpmiPtr { ptr, handle };
 | 
			
		||||
        ptr as *mut u8
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
 | 
			
		||||
        if ptr as u32 == 0 { return; }
 | 
			
		||||
        let mut dat = self.lock();
 | 
			
		||||
        let mut ptrs = unsafe { core::slice::from_raw_parts_mut::<DpmiPtr>(dat.ptrs as *mut DpmiPtr, PTR_COUNT) };
 | 
			
		||||
        let mut found_idx: Option<usize> = None;
 | 
			
		||||
        for i in 0..ptrs.len() {
 | 
			
		||||
            if ptrs[i].ptr == ptr as u32 { found_idx = Some(i); break; }
 | 
			
		||||
        }
 | 
			
		||||
        let handle = match found_idx {
 | 
			
		||||
            None => return,
 | 
			
		||||
            Some(i) => ptrs[i].handle
 | 
			
		||||
        };
 | 
			
		||||
        //  3.54 - DOS function 0FF92h - DOS/32 Advanced Free High Memory Block
 | 
			
		||||
        //  In: 	AX = 0FF92h
 | 
			
		||||
        //  ESI = handle of previously allocated memory block
 | 
			
		||||
        //  Out: 	
 | 
			
		||||
        //  if successful:
 | 
			
		||||
        //  CF clear
 | 
			
		||||
        //  if failed:
 | 
			
		||||
        //  CF set
 | 
			
		||||
        asm!(
 | 
			
		||||
            "mov edx, esi",
 | 
			
		||||
            "mov esi, ebx",
 | 
			
		||||
            "int 0x21",
 | 
			
		||||
            "mov esi, edx",
 | 
			
		||||
            in("eax") 0x0FF92,
 | 
			
		||||
            in("ebx") handle,
 | 
			
		||||
            out("edx") _
 | 
			
		||||
        );
 | 
			
		||||
        ptrs[found_idx.unwrap()] = DpmiPtr { ptr: 0, handle: 0 };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 {
 | 
			
		||||
        if ptr.is_null() { return null_mut(); }
 | 
			
		||||
        let mut dat = self.lock();
 | 
			
		||||
        let mut ptrs = core::slice::from_raw_parts_mut::<DpmiPtr>(dat.ptrs as *mut DpmiPtr, PTR_COUNT);
 | 
			
		||||
        let mut found_idx: Option<usize> = None;
 | 
			
		||||
        for i in 0..ptrs.len() {
 | 
			
		||||
            if ptrs[i].ptr == ptr as u32 { found_idx = Some(i); break; }
 | 
			
		||||
        }
 | 
			
		||||
        let old_handle = match found_idx {
 | 
			
		||||
            None => return null_mut(),
 | 
			
		||||
            Some(i) => ptrs[i].handle
 | 
			
		||||
        };
 | 
			
		||||
        //  3.55 - DOS function 0FF93h - DOS/32 Advanced Resize High Memory Block
 | 
			
		||||
        //  In: 	AX = 0FF93h
 | 
			
		||||
        //  EBX = new size of memory block in bytes
 | 
			
		||||
        //  ESI = handle of previously allocated memory block
 | 
			
		||||
        //  Out: 	
 | 
			
		||||
 | 
			
		||||
        //  if successful:
 | 
			
		||||
        //  CF clear
 | 
			
		||||
        //  EBX = new linear address of allocated memory block
 | 
			
		||||
        //  ESI = new handle of allocated memory block
 | 
			
		||||
 | 
			
		||||
        //  if failed:
 | 
			
		||||
        //  CF set
 | 
			
		||||
        let ptr: u32;
 | 
			
		||||
        let handle: u32;
 | 
			
		||||
        asm!(
 | 
			
		||||
            "xchg edx, esi",
 | 
			
		||||
            "int 0x21",
 | 
			
		||||
            "xchg esi, edx",
 | 
			
		||||
            inout("eax") 0x0FF93 => _,
 | 
			
		||||
            inout("ebx") new_size as u32 => ptr,
 | 
			
		||||
            inout("edx") old_handle => handle
 | 
			
		||||
        );
 | 
			
		||||
        ptrs[found_idx.unwrap()] = DpmiPtr { ptr, handle };
 | 
			
		||||
        ptr as *mut u8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[global_allocator]
 | 
			
		||||
static ALLOCATOR: Locked<DpmiAlloc> = Locked::new(DpmiAlloc::new());
 | 
			
		||||
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
pub fn _print(args: core::fmt::Arguments) {
 | 
			
		||||
    let mut s: String<256> = String::new();
 | 
			
		||||
    s.write_fmt(args).unwrap();
 | 
			
		||||
    crate::dpmi::dpmi_print(s.as_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[alloc_error_handler]
 | 
			
		||||
fn alloc_error_handler(layout: Layout) -> ! {
 | 
			
		||||
    _print(format_args!("allocation error: {:?}$", layout));
 | 
			
		||||
    crate::dpmi::dpmi_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
#![feature(alloc_error_handler)]
 | 
			
		||||
#![feature(abi_x86_interrupt)]
 | 
			
		||||
#![no_main]
 | 
			
		||||
#![no_std]
 | 
			
		||||
 | 
			
		||||
use core::arch::asm;
 | 
			
		||||
 | 
			
		||||
extern crate alloc;
 | 
			
		||||
 | 
			
		||||
mod dpmi;
 | 
			
		||||
mod dpmi_alloc;
 | 
			
		||||
mod panic;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("Hello, world!");
 | 
			
		||||
    debug_trap!();
 | 
			
		||||
    println!("Done.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(unused_macros)]
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! debug_trap {
 | 
			
		||||
    () => { unsafe { asm!("int 0x1"); } };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
pub extern "C" fn start() {
 | 
			
		||||
    unsafe { asm!(
 | 
			
		||||
        "push ds",
 | 
			
		||||
        "pop es",
 | 
			
		||||
    ); }
 | 
			
		||||
    main();
 | 
			
		||||
    dpmi::dpmi_exit();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								src/panic.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/panic.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
use crate::dpmi::dpmi_exit;
 | 
			
		||||
 | 
			
		||||
#[panic_handler]
 | 
			
		||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
 | 
			
		||||
    //crate::println!("Panic! {}", info);
 | 
			
		||||
    dpmi_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user