extern crate term;
extern crate vga_framebuffer;
use vga_framebuffer::{Attr, Col, Colour, AsciiConsole, Position, Row};
mod rust_logo;
struct Dummy {
col: usize,
output: Box<dyn term::Terminal<Output = std::io::Stdout>>,
}
impl<'a> vga_framebuffer::Hardware for &'a mut Dummy {
fn configure(&mut self, width: u32, sync_end: u32, line_start: u32, clock_rate: u32) {
println!(
"width={}, sync_end={}, line_start={}, clock_rate={}",
width, sync_end, line_start, clock_rate
);
}
fn vsync_on(&mut self) {
println!("vsync_on");
}
fn vsync_off(&mut self) {
println!("vsync_off");
}
fn write_pixels(&mut self, red: u32, green: u32, blue: u32) {
let mut old_colour = None;
for bit in (0..8).rev() {
let red_bit = red & (1 << bit) != 0;
let blue_bit = blue & (1 << bit) != 0;
let green_bit = green & (1 << bit) != 0;
let colour: u8 = ((red_bit as u8) << 2) + ((green_bit as u8) << 1) + (blue_bit as u8);
if old_colour != Some(colour) {
match colour {
0b110 => {
self.output.fg(term::color::YELLOW).unwrap();
}
0b101 => {
self.output.fg(term::color::MAGENTA).unwrap();
}
0b100 => {
self.output.fg(term::color::RED).unwrap();
}
0b011 => {
self.output.fg(term::color::CYAN).unwrap();
}
0b010 => {
self.output.fg(term::color::GREEN).unwrap();
}
0b001 => {
self.output.fg(term::color::BLUE).unwrap();
}
0b000 => {
self.output.fg(term::color::BLACK).unwrap();
}
_ => {
self.output.fg(term::color::WHITE).unwrap();
}
}
old_colour = Some(colour);
}
write!(self.output, "@@").unwrap();
}
self.col += 1;
if self.col == vga_framebuffer::HORIZONTAL_OCTETS {
self.col = 0;
println!();
}
}
}
use std::fmt::Write;
fn main() {
let mut d = Dummy {
col: 0,
output: term::stdout().unwrap(),
};
let mut mode2_buffer = vec![
0xAAu8;
vga_framebuffer::USABLE_HORIZONTAL_OCTETS
* vga_framebuffer::USABLE_LINES_MODE2
];
let mut fb = vga_framebuffer::FrameBuffer::new();
let max_col = Col(vga_framebuffer::TEXT_MAX_COL as u8);
let max_row = Row(vga_framebuffer::TEXT_MAX_ROW as u8);
fb.init(&mut d);
fb.clear();
fb.write_char_at(b'$', Position::origin()).unwrap();
fb.write_char_at(b'$', Position::new(max_row, Col::origin()))
.unwrap();
fb.write_char_at(b'$', Position::new(Row::origin(), max_col))
.unwrap();
fb.write_char_at(b'$', Position::new(max_row, max_col))
.unwrap();
writeln!(fb, "\nThis is a test").unwrap();
for _ in 0..628 {
fb.isr_sol();
}
let mut wheel = [Colour::Red, Colour::Green, Colour::Blue].iter().cycle();
for y in 0..=vga_framebuffer::TEXT_MAX_ROW {
for x in 0..=vga_framebuffer::TEXT_MAX_COL {
fb.set_attr_at(
Position::new(Row(y as u8), Col(x as u8)),
Attr::new(Colour::White, *wheel.next().unwrap()),
);
}
wheel.next();
}
for (src, dest) in rust_logo::RUST_LOGO_DATA
.iter()
.zip(mode2_buffer.iter_mut())
{
*dest = flip_byte(*src);
}
fb.mode2(&mut mode2_buffer[..], 0);
for _ in 0..628 {
fb.isr_sol();
}
}
fn flip_byte(mut b: u8) -> u8 {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
(b & 0xAA) >> 1 | (b & 0x55) << 1
}