vi and busybox

This commit is contained in:
wcjbr
2026-07-29 10:56:30 +08:00
commit 86dbf7482f
47 changed files with 9647 additions and 0 deletions
+328
View File
@@ -0,0 +1,328 @@
use crate::drivers::platform::pic;
use crate::io::{disable_interrupts, enable_interrupts, inb};
const DATA_PORT: u16 = 0x60;
const STATUS_PORT: u16 = 0x64;
const OUTPUT_FULL: u8 = 1 << 0;
const BUFFER_SIZE: usize = 256;
static mut KEYBOARD: Ps2Keyboard = Ps2Keyboard::new();
pub struct Ps2Keyboard {
buffer: [u8; BUFFER_SIZE],
read_index: usize,
write_index: usize,
shift: bool,
extended: bool,
}
impl Ps2Keyboard {
const fn new() -> Self {
Self {
buffer: [0; BUFFER_SIZE],
read_index: 0,
write_index: 0,
shift: false,
extended: false,
}
}
fn push(&mut self, byte: u8) {
let next = (self.write_index + 1) % BUFFER_SIZE;
if next != self.read_index {
self.buffer[self.write_index] = byte;
self.write_index = next;
}
}
fn pop(&mut self) -> Option<u8> {
if self.read_index == self.write_index {
return None;
}
let byte = self.buffer[self.read_index];
self.read_index = (self.read_index + 1) % BUFFER_SIZE;
Some(byte)
}
fn handle_scancode(&mut self, scancode: u8) {
if scancode == 0xe0 {
self.extended = true;
return;
}
if self.extended {
self.extended = false;
if scancode & 0x80 != 0 {
return;
}
match scancode {
0x48 => self.push_escape_sequence(b"\x1b[A"),
0x50 => self.push_escape_sequence(b"\x1b[B"),
0x4b => self.push_escape_sequence(b"\x1b[D"),
0x4d => self.push_escape_sequence(b"\x1b[C"),
0x47 => self.push_escape_sequence(b"\x1b[H"),
0x4f => self.push_escape_sequence(b"\x1b[F"),
0x53 => self.push_escape_sequence(b"\x1b[3~"),
_ => {}
}
return;
}
let released = scancode & 0x80 != 0;
let code = scancode & 0x7f;
match code {
0x2a | 0x36 => {
self.shift = !released;
return;
}
_ if released => return,
_ => {}
}
if let Some(ascii) = scancode_set1_to_ascii(code, self.shift) {
self.push(ascii);
}
}
fn push_escape_sequence(&mut self, bytes: &[u8]) {
for byte in bytes {
self.push(*byte);
}
}
}
pub unsafe fn init() {
unsafe {
drain_output_buffer();
pic::unmask_irq(pic::KEYBOARD_IRQ);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn zeroos_ps2_keyboard_interrupt() {
unsafe {
if inb(STATUS_PORT) & OUTPUT_FULL != 0 {
let scancode = inb(DATA_PORT);
(*(&raw mut KEYBOARD)).handle_scancode(scancode);
}
pic::end_of_interrupt(pic::KEYBOARD_IRQ);
}
}
pub fn read_char() -> Option<u8> {
disable_interrupts();
let ch = unsafe { (*(&raw mut KEYBOARD)).pop() };
enable_interrupts();
ch
}
pub fn has_char() -> bool {
disable_interrupts();
let ready = unsafe {
let keyboard = &*(&raw const KEYBOARD);
keyboard.read_index != keyboard.write_index
};
enable_interrupts();
ready
}
unsafe fn drain_output_buffer() {
unsafe {
while inb(STATUS_PORT) & OUTPUT_FULL != 0 {
let _ = inb(DATA_PORT);
}
}
}
fn scancode_set1_to_ascii(code: u8, shift: bool) -> Option<u8> {
let byte = match code {
0x01 => 0x1b,
0x02 => {
if shift {
b'!'
} else {
b'1'
}
}
0x03 => {
if shift {
b'@'
} else {
b'2'
}
}
0x04 => {
if shift {
b'#'
} else {
b'3'
}
}
0x05 => {
if shift {
b'$'
} else {
b'4'
}
}
0x06 => {
if shift {
b'%'
} else {
b'5'
}
}
0x07 => {
if shift {
b'^'
} else {
b'6'
}
}
0x08 => {
if shift {
b'&'
} else {
b'7'
}
}
0x09 => {
if shift {
b'*'
} else {
b'8'
}
}
0x0a => {
if shift {
b'('
} else {
b'9'
}
}
0x0b => {
if shift {
b')'
} else {
b'0'
}
}
0x0c => {
if shift {
b'_'
} else {
b'-'
}
}
0x0d => {
if shift {
b'+'
} else {
b'='
}
}
0x0e => 0x08,
0x0f => b'\t',
0x10 => letter(b'q', shift),
0x11 => letter(b'w', shift),
0x12 => letter(b'e', shift),
0x13 => letter(b'r', shift),
0x14 => letter(b't', shift),
0x15 => letter(b'y', shift),
0x16 => letter(b'u', shift),
0x17 => letter(b'i', shift),
0x18 => letter(b'o', shift),
0x19 => letter(b'p', shift),
0x1a => {
if shift {
b'{'
} else {
b'['
}
}
0x1b => {
if shift {
b'}'
} else {
b']'
}
}
0x1c => b'\r',
0x1e => letter(b'a', shift),
0x1f => letter(b's', shift),
0x20 => letter(b'd', shift),
0x21 => letter(b'f', shift),
0x22 => letter(b'g', shift),
0x23 => letter(b'h', shift),
0x24 => letter(b'j', shift),
0x25 => letter(b'k', shift),
0x26 => letter(b'l', shift),
0x27 => {
if shift {
b':'
} else {
b';'
}
}
0x28 => {
if shift {
b'"'
} else {
b'\''
}
}
0x29 => {
if shift {
b'~'
} else {
b'`'
}
}
0x2b => {
if shift {
b'|'
} else {
b'\\'
}
}
0x2c => letter(b'z', shift),
0x2d => letter(b'x', shift),
0x2e => letter(b'c', shift),
0x2f => letter(b'v', shift),
0x30 => letter(b'b', shift),
0x31 => letter(b'n', shift),
0x32 => letter(b'm', shift),
0x33 => {
if shift {
b'<'
} else {
b','
}
}
0x34 => {
if shift {
b'>'
} else {
b'.'
}
}
0x35 => {
if shift {
b'?'
} else {
b'/'
}
}
0x39 => b' ',
_ => return None,
};
Some(byte)
}
const fn letter(lower: u8, shift: bool) -> u8 {
if shift { lower - 32 } else { lower }
}