main.rs 3.4 KB
Newer Older
1 2 3
#![feature(alloc)]
#![feature(asm)]
#![feature(heap_api)]
Jeremy Soller's avatar
Jeremy Soller committed
4
#![feature(question_mark)]
5 6 7 8 9

extern crate alloc;
extern crate syscall;

use std::fs::File;
Jeremy Soller's avatar
Jeremy Soller committed
10
use std::io::{Read, Write};
Jeremy Soller's avatar
Jeremy Soller committed
11 12
use std::thread;
use syscall::{physmap, physunmap, Packet, Scheme, MAP_WRITE, MAP_WRITE_COMBINE};
13 14

use mode_info::VBEModeInfo;
15
use primitive::fast_set64;
Jeremy Soller's avatar
Jeremy Soller committed
16
use scheme::DisplayScheme;
17 18 19 20

pub mod display;
pub mod mode_info;
pub mod primitive;
Jeremy Soller's avatar
Jeremy Soller committed
21 22
pub mod scheme;
pub mod screen;
Jeremy Soller's avatar
Jeremy Soller committed
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
fn main() {
    let width;
    let height;
    let physbaseptr;

    {
        let mode_info = unsafe { &*(physmap(0x5200, 4096, 0).expect("vesad: failed to map VBE info") as *const VBEModeInfo) };

        width = mode_info.xresolution as usize;
        height = mode_info.yresolution as usize;
        physbaseptr = mode_info.physbaseptr as usize;

        unsafe { let _ = physunmap(mode_info as *const _ as usize); }
    }

    if physbaseptr > 0 {
        thread::spawn(move || {
Jeremy Soller's avatar
Jeremy Soller committed
41
            let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
Jeremy Soller's avatar
Jeremy Soller committed
42

43 44
            let size = width * height;

Jeremy Soller's avatar
Jeremy Soller committed
45
            let onscreen = unsafe { physmap(physbaseptr, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
46 47
            unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };

Jeremy Soller's avatar
Jeremy Soller committed
48
            let scheme = DisplayScheme::new(width, height, onscreen);
49

Jeremy Soller's avatar
Jeremy Soller committed
50
            let mut blocked = Vec::new();
Jeremy Soller's avatar
Jeremy Soller committed
51 52
            loop {
                let mut packet = Packet::default();
53
                socket.read(&mut packet).expect("vesad: failed to read display scheme");
Jeremy Soller's avatar
Jeremy Soller committed
54
                //println!("vesad: {:?}", packet);
55 56

                // If it is a read packet, and there is no data, block it. Otherwise, handle packet
Jeremy Soller's avatar
Jeremy Soller committed
57 58
                if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.will_block(packet.b) {
                    blocked.push(packet);
59 60 61 62
                } else {
                    scheme.handle(&mut packet);
                    socket.write(&packet).expect("vesad: failed to write display scheme");
                }
63 64

                // If there are blocked readers, and data is available, handle them
Jeremy Soller's avatar
Jeremy Soller committed
65 66 67 68 69 70 71 72 73 74
                {
                    let mut i = 0;
                    while i < blocked.len() {
                        if ! scheme.will_block(blocked[i].b) {
                            let mut packet = blocked.remove(i);
                            scheme.handle(&mut packet);
                            socket.write(&packet).expect("vesad: failed to write display scheme");
                        } else {
                            i += 1;
                        }
75 76
                    }
                }
77 78

                // If there are requested events, and data is available, send a notification
Jeremy Soller's avatar
Jeremy Soller committed
79 80
                /* TODO
                if (! scheme.screen.borrow().input.is_empty() || scheme.screen.borrow().end_of_input) && scheme.screen.borrow().requested & EVENT_READ == EVENT_READ {
81 82
                    let event_packet = Packet {
                        id: 0,
83 84 85
                        pid: 0,
                        uid: 0,
                        gid: 0,
86 87 88
                        a: syscall::number::SYS_FEVENT,
                        b: 0,
                        c: EVENT_READ,
Jeremy Soller's avatar
Jeremy Soller committed
89
                        d: scheme.screen.borrow().input.len()
90 91 92
                    };
                    socket.write(&event_packet).expect("vesad: failed to write display scheme");
                }
Jeremy Soller's avatar
Jeremy Soller committed
93
                */
Jeremy Soller's avatar
Jeremy Soller committed
94
            }
95 96 97
        });
    }
}