Initial commit

merge-requests/1/head
kirbylife 2021-04-27 11:03:16 -05:00
parent b20ac3eeee
commit e19764d7b2
6 changed files with 262 additions and 1 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
Cargo.lock
target/

23
Cargo.toml 100644
View File

@ -0,0 +1,23 @@
[package]
name = "rvgax"
version = "0.0.1"
authors = [
"Kirbylife <kirbylife@protonmail.com>",
]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://gitlab.com/kirbylife/rvgax"
description = """
VGA library for Arduino UNO to use with rust-avr.
"""
build = "core_generator/build.rs"
keywords = ["avr", "arduino", "uno", "vga", "vgax"]
[dependencies]
arduino = "0.1"
[build-dependencies]
avr-mcu = "0.2"

View File

@ -1,3 +1,3 @@
# rVGAx # rVGAx
VGA library for Arduino UNO to use with rust-avr. ## WIP, DOES NOT WORK :c

2
src/.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
# Generated automatically.
config.rs

View File

@ -0,0 +1,96 @@
#![feature(llvm_asm, asm, lang_items, abi_avr_interrupt)]
#![no_std]
extern crate arduino;
use core::ptr::write_volatile;
use arduino::TCNT0;
const HSYNCPIN: u8 = 3;
const COLORPIN0: u8 = 6;
const COLORPIN1: u8 = 7;
const VSYNCPIN: u8 = 9;
const SKIPLINES: u8 = 90;
const VGAX_HEIGHT: usize = 60;
const VGAX_BWIDTH: usize = 30;
const VGAX_WIDTH: usize = VGAX_BWIDTH * 4;
const VGAX_BSIZE: usize = VGAX_BWIDTH * VGAX_HEIGHT;
const VGAX_SIZE: usize = VGAX_WIDTH * VGAX_HEIGHT;
static mut afreq: u8 = 0;
static mut afreq0: u8 = 0;
static mut vtimer: u16 = 0;
static mut aline: u8 = 0;
static mut rlinecnt: u8 = 0;
static mut vskip: u8 = 0;
static vgaxfb: [u8; VGAX_HEIGHT * VGAX_BWIDTH] = [0; VGAX_HEIGHT * VGAX_BWIDTH];
pub unsafe fn begin() {}
#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer0_compare_a() {
aline -= 1;
vskip = SKIPLINES;
vtimer += 1;
rlinecnt = 0;
}
#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {
if vskip != 0 {
vskip -= 1;
return;
}
if rlinecnt < VGAX_HEIGHT as u8 {
const DEJITTER_OFFSET: u8 = 1;
const DEJITTER_SYNC: i8 = -2;
llvm_asm!(
r" lds r16, ${timer0}
subi r16, ${tsync}
andi r16, 7
call TL
TL:
pop r31
pop r30
adiw r30, (LW-TL-5)
add r30, r16
ijmp
LW:
nop
nop
nop
nop
nop
nop
nop
LBEND:
"
:
: "{timer0}"(&TCNT0),
"{offset}"(DEJITTER_OFFSET),
"{tsync}"(DEJITTER_SYNC)
: "r30", "r31", "r16"
: "volatile");
}
}
pub mod std {
#[lang = "eh_personality"]
pub unsafe extern "C" fn rust_eh_personality(
_state: (),
_exception_object: *mut (),
_context: *mut (),
) -> () {
}
#[panic_handler]
fn panic(_info: &::core::panic::PanicInfo) -> ! {
loop {}
}
}

138
src/lib.rs 100644
View File

@ -0,0 +1,138 @@
#![feature(asm, lang_items, abi_avr_interrupt)]
#![no_std]
extern crate arduino;
use arduino::{PORTD, TCNT0, TXEN0, UCSR0B, UDR0};
use core::ptr::write_volatile;
const HSYNCPIN: u8 = 3;
const COLORPIN0: u8 = 6;
const COLORPIN1: u8 = 7;
const VSYNCPIN: u8 = 9;
const SKIPLINES: u8 = 35;
const EXTRACOLORPORT: *mut u8 = PORTD;
// const SKIPLINES: u8 = 90;
const VGAX_HEIGHT: usize = 80;
const VGAX_BWIDTH: usize = 24;
const VGAX_WIDTH: usize = VGAX_BWIDTH * 8;
const VGAX_BSIZE: usize = VGAX_BWIDTH * VGAX_HEIGHT;
const VGAX_SIZE: usize = VGAX_WIDTH * VGAX_HEIGHT;
const VGAX_ECSWIDTH: usize = 3;
static mut vtimer: u16 = 0;
static mut aline: u8 = 0;
static mut rlinecnt: u8 = 0;
static mut vskip: u8 = 0;
static vgaxfb: [u8; VGAX_HEIGHT * VGAX_BWIDTH] = [0; VGAX_HEIGHT * VGAX_BWIDTH];
static mut videoline: *mut u8 = 0 as *const u8 as *mut u8;
static vmask: u8 = 0;
// const VGAXFBPTR: *mut u8 = vgaxfb as *mut u8;
// Port pointers
// const PORTD: *mut u8 = 43 as *mut u8;
pub unsafe fn begin() {}
// VSYNC
#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer0_compare_a() {
aline -= 1;
vskip = SKIPLINES;
vtimer += 1;
rlinecnt = 0;
videoline = vgaxfb.as_ptr() as *const u8 as *mut u8;
}
// HSYNC
#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {
if vskip != 0 {
vskip -= 1;
return;
}
if rlinecnt < VGAX_HEIGHT as u8 {
const DEJITTER_SYNC: i8 = -0;
asm!(
" lds r16, $0
\t subi r16, $1
\t andi r16, 7
\t call TL
\tTL:
\t pop r31
\t pop r30
\t adiw r30, (LW-TL-5)
\t add r30, r16
\t ijmp
\tLW:
\t nop
\t nop
\t nop
\t nop
\t nop
\tLBEND:
\t"
:
: "i"(&TCNT0),
"i"(DEJITTER_SYNC)
: "r30", "r31", "r16", "r17"
: "volatile");
}
fn bit(n: u8) -> u8 {
1 << n
}
unsafe fn nop() {
asm!("nop");
}
static mut p: *mut u8 = videoline;
static mut c: *mut u8 = p.add(1) as *const u8 as *mut u8;
fn drawF() {
unsafe {
write_volatile(UDR0, c as u8);
write_volatile(UCSR0B, bit(TXEN0));
c = p.add(1) as *const u8 as *mut u8;
nop();
}
}
fn drawS() {
unsafe {
write_volatile(UDR0, c as u8);
write_volatile(EXTRACOLORPORT, vmask);
for _ in 0..7 {
nop();
}
c = p.add(1) as *const u8 as *mut u8;
}
}
fn draw8() {
unsafe {
write_volatile(UDR0, c as u8);
for _ in 0..12 {
nop();
}
c = p.add(1);
}
}
}
pub mod std {
#[lang = "eh_personality"]
pub unsafe extern "C" fn rust_eh_personality(
_state: (),
_exception_object: *mut (),
_context: *mut (),
) -> () {
}
#[panic_handler]
fn panic(_info: &::core::panic::PanicInfo) -> ! {
loop {}
}
}