more stuff i worked on
This commit is contained in:
@@ -3,13 +3,14 @@ use beneater::parts::cpu_display::CpuDisplay;
|
||||
use macroquad::prelude::*;
|
||||
use macroquad::telemetry::frame;
|
||||
use beneater::parts::ben_eater_pc::BenEaterPC;
|
||||
use beneater::parts::display_matrix::DisplayMatrix;
|
||||
use beneater::parts::backplane::Backplane;
|
||||
#[macroquad::main("Ben Eaters PC")]
|
||||
async fn main() {
|
||||
println!("Taxation is Theft");
|
||||
|
||||
let mut computer = BenEaterPC::new();
|
||||
computer.load_rom("resources/beneater/roms/ror.bin");
|
||||
let mut backplane = Backplane::new();
|
||||
backplane.load_rom("resources/beneater/roms/ror.bin");
|
||||
|
||||
|
||||
let mut dm = DisplayMatrix::new(200.0, 50.0);
|
||||
let message_to_show = "Taxation is theft";
|
||||
@@ -23,7 +24,7 @@ async fn main() {
|
||||
|
||||
draw_text("Ben Eater", 20.0, 20.0, 30.0, BLACK);
|
||||
dm.render(20.0, 40.0);
|
||||
CpuDisplay::render(&computer.cpu, 20.0, 120.0);
|
||||
// CpuDisplay::render(&computer.cpu, 20.0, 120.0);
|
||||
|
||||
frame_number += 1;
|
||||
|
||||
@@ -37,6 +38,5 @@ async fn main() {
|
||||
}
|
||||
|
||||
next_frame().await
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
use core::mos6502cpu::Mos6502Cpu;
|
||||
use crate::parts::mos6522_peripheral::Mos6522Peripheral;
|
||||
use crate::parts::via6522::VIA6522;
|
||||
use core::constants::constants_system::*;
|
||||
use core::periph::at28c256::At28C256;
|
||||
pub struct Backplane {
|
||||
cpu: Mos6502Cpu,
|
||||
via: VIA6522,
|
||||
memory: [u8; SIZE_64KB],
|
||||
rom: At28C256
|
||||
}
|
||||
|
||||
impl Backplane {
|
||||
pub fn new() -> Self {
|
||||
Backplane {
|
||||
cpu: Mos6502Cpu::default(),
|
||||
via: VIA6522::default(),
|
||||
memory: [0x00; SIZE_64KB],
|
||||
rom: At28C256::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_rom(&mut self, to_load: &[u8; SIZE_32KB]) {
|
||||
self.rom.program(to_load);
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
// is the CPU in read or write state
|
||||
let address = self.cpu.address_bus();
|
||||
let data = self.cpu.data_bus();
|
||||
match address {
|
||||
/// VIA
|
||||
0x6000..0x6010 => {
|
||||
if self.cpu.read_signal {
|
||||
self.cpu.set_data_bus(self.via.read((address - 0x6000) as u8));
|
||||
} else {
|
||||
self.via.write((address - 0x6000) as u8, self.cpu.data_bus());
|
||||
}
|
||||
}
|
||||
/// RAM
|
||||
0x0000..=0x3fff => {
|
||||
if self.cpu.read_signal {
|
||||
self.cpu.set_data_bus(self.memory[address as usize]);
|
||||
} else {
|
||||
self.memory[*address as usize] = data;
|
||||
}
|
||||
}
|
||||
/// ROM
|
||||
0x4000..=0x7fff => {
|
||||
|
||||
}
|
||||
/// The ether. Scarrrrrrrryyyy......
|
||||
_ => {
|
||||
println!("Lost READ:?{} to {:04x}", self.cpu.read_signal, address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +1,209 @@
|
||||
use macroquad::prelude::*;
|
||||
use crate::parts::address_bus::AddressBus;
|
||||
use crate::parts::data_bus::DataBus;
|
||||
use crate::parts::display_matrix::MatrixEntryMode::{Delete, DeleteShift, Insert, InsertShift};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub enum MatrixEntryMode {
|
||||
Delete,
|
||||
DeleteShift,
|
||||
Insert,
|
||||
InsertShift,
|
||||
}
|
||||
|
||||
pub struct DisplayMatrix {
|
||||
width: f32,
|
||||
height: f32,
|
||||
text_buffer: [u8; 80],
|
||||
cgram: [u8; 64],
|
||||
data_bus: DataBus,
|
||||
#[derive(Debug)]
|
||||
pub struct HD44780 {
|
||||
// Bus inputs
|
||||
data_bus: u8,
|
||||
rs: bool,
|
||||
rw: bool,
|
||||
enable: bool,
|
||||
prev_enable: bool,
|
||||
|
||||
// Internal memory
|
||||
ddram: [u8; 80],
|
||||
cgram: [u8; 64],
|
||||
|
||||
// Cursor & display state
|
||||
cursor_position: u8,
|
||||
busy: bool,
|
||||
entry_mode: MatrixEntryMode,
|
||||
cursor: bool,
|
||||
display_on: bool,
|
||||
blink: bool,
|
||||
cursor_shift: bool,
|
||||
display_shift: bool,
|
||||
enabled: bool,
|
||||
cursor_on: bool,
|
||||
blink_on: bool,
|
||||
entry_increment: bool,
|
||||
entry_shift: bool,
|
||||
|
||||
// Function set flags
|
||||
data_length_8bit: bool,
|
||||
two_line_mode: bool,
|
||||
font_5x10: bool,
|
||||
|
||||
// Busy flag
|
||||
busy: bool,
|
||||
last_command_time: Instant,
|
||||
}
|
||||
|
||||
impl DisplayMatrix {
|
||||
pub fn set_bus(&mut self, rs: bool, rw: bool, bus: u8, e: bool) {
|
||||
self.rs = rs;
|
||||
self.rw = rw;
|
||||
self.data_bus.data = bus;
|
||||
self.enabled = e;
|
||||
}
|
||||
|
||||
/// Reset the Display to its 'factory boot' state
|
||||
pub fn reset(&mut self) {
|
||||
// 1. Display clear
|
||||
self.set_bus(false, false, 0b0000_0001, true);
|
||||
self.tick(false, false, true, 0b0000_0001);
|
||||
// Function Set
|
||||
// DL = 1; 8-bit interface data
|
||||
// N = 0; 1-line display
|
||||
// F = 0; 5 × 8 dot character font
|
||||
self.tick(false, false, true, 0b0011_0000);;
|
||||
// 3. Display on/off control:
|
||||
// D = 0; Display off
|
||||
// C = 0; Cursor off
|
||||
// B = 0; Blinking off
|
||||
self.tick(false, false, true, 0b0000_1000);
|
||||
// 4. Entry mode set:
|
||||
// I/D = 1; Increment by 1
|
||||
// S = 0; No shift
|
||||
self.tick(false, false,true, 0b0000_0110);
|
||||
self.busy = false;
|
||||
}
|
||||
|
||||
pub fn new(width: f32, height: f32) -> DisplayMatrix {
|
||||
let mut matrix = DisplayMatrix {
|
||||
width,
|
||||
height,
|
||||
text_buffer: String::from(""),
|
||||
data_bus: DataBus::new(),
|
||||
impl HD44780 {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data_bus: 0,
|
||||
rs: false,
|
||||
rw: false,
|
||||
cursor_position: 0x00,
|
||||
busy: false,
|
||||
entry_mode: MatrixEntryMode::InsertShift,
|
||||
display_on: false,
|
||||
cursor: false,
|
||||
blink: false,
|
||||
cursor_shift: false,
|
||||
display_shift: false,
|
||||
enabled: false,
|
||||
};
|
||||
matrix
|
||||
}
|
||||
enable: false,
|
||||
prev_enable: false,
|
||||
|
||||
/// Tick
|
||||
pub fn tick(&mut self, rw: bool, rs: bool, enabled: bool, data: u8) {
|
||||
self.enabled = enabled;
|
||||
self.data_bus.data = data;
|
||||
self.rw = rw;
|
||||
self.rs = rs;
|
||||
// parse whats on the data bus.
|
||||
match (self.rs, self.rw) {
|
||||
(true, true) => {
|
||||
// read from cg or ddram
|
||||
}
|
||||
(true, false) => {
|
||||
// write to cg or ddram
|
||||
println!("WRITE TO CG/DD RAM -> {:08b} / {:02x} / {}", self.data_bus.data, self.data_bus.data, self.data_bus.data);
|
||||
}
|
||||
(false, true) => {
|
||||
// read the busy flag.
|
||||
self.data_bus.data = (self.busy as u8) << 7 | (self.cursor_position & 0x7F);
|
||||
self.enabled = true;
|
||||
}
|
||||
(false, false) => {
|
||||
match self.data_bus.data {
|
||||
0b0000_0001 => {
|
||||
// clear display
|
||||
self.text_buffer = " ".repeat(32);
|
||||
}
|
||||
0b0000_0010..=0b0000_0011 => {
|
||||
// return home
|
||||
self.cursor_position = 0x00;
|
||||
}
|
||||
0b0000_0100..=0b0000_0111 => {
|
||||
self.entry_mode = match self.data_bus.data {
|
||||
0b01 => DeleteShift,
|
||||
0b10 => Insert,
|
||||
0b11 => InsertShift,
|
||||
_ => {
|
||||
// Default mode
|
||||
Delete
|
||||
}
|
||||
};
|
||||
}
|
||||
0b0000_1000..=0b0000_1111 => {
|
||||
// display control
|
||||
self.display_on = self.data_bus.data & 0b100 == 0b100;
|
||||
self.cursor = self.data_bus.data & 0b10 == 0b10;
|
||||
self.blink = self.data_bus.data & 0b1 == 0b1;
|
||||
}
|
||||
0b0001_0000..=0b0001_1111 => {
|
||||
// cursor control
|
||||
self.cursor_shift = self.data_bus.data & 0b1000 == 0b1000;
|
||||
self.display_shift = self.data_bus.data & 0b100 == 0b100;
|
||||
}
|
||||
0b0010_0000..=0b0011_1111 => {
|
||||
// function set
|
||||
println!("Ignoring function set. this is going to play like an 8bit 2 row");
|
||||
}
|
||||
0b0100_0000..=0b0111_1111 => {
|
||||
// set CGRam Address
|
||||
println!("Ignoring set CGRam Address. Not Changing how the characters are displayed.");
|
||||
}
|
||||
0b1000_0000..=0b1111_1111 => {
|
||||
// set DDRam address
|
||||
self.cursor_position = self.data_bus.data & 0b0111_1111;
|
||||
}
|
||||
_ => {
|
||||
// Invalid Command
|
||||
}
|
||||
}
|
||||
}
|
||||
ddram: [b' '; 80],
|
||||
cgram: [0; 64],
|
||||
|
||||
cursor_position: 0,
|
||||
display_on: true,
|
||||
cursor_on: false,
|
||||
blink_on: false,
|
||||
entry_increment: true,
|
||||
entry_shift: false,
|
||||
|
||||
data_length_8bit: true,
|
||||
two_line_mode: true,
|
||||
font_5x10: false,
|
||||
|
||||
busy: false,
|
||||
last_command_time: Instant::now(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_letter(&mut self, letter_to_push: char) {
|
||||
self.cursor_position += 1;
|
||||
self.text_buffer.push(letter_to_push)
|
||||
pub fn write_control_lines(&mut self, rs: bool, rw: bool, enable: bool) {
|
||||
self.rs = rs;
|
||||
self.rw = rw;
|
||||
|
||||
// On rising edge of Enable
|
||||
if enable && !self.prev_enable {
|
||||
self.evaluate();
|
||||
}
|
||||
|
||||
self.prev_enable = enable;
|
||||
}
|
||||
|
||||
pub fn clear_display(&mut self) {
|
||||
self.cursor_position = 0;
|
||||
self.text_buffer.clear()
|
||||
pub fn set_data_bus(&mut self, value: u8) {
|
||||
self.data_bus = value;
|
||||
}
|
||||
|
||||
pub fn render(&self, x_offset: f32, y_offset: f32) {
|
||||
DisplayMatrix::draw_square(x_offset,
|
||||
y_offset,
|
||||
x_offset + self.width,
|
||||
y_offset + self.height,
|
||||
BLACK);
|
||||
|
||||
let mut tmp = self.text_buffer.clone();
|
||||
tmp.push('#');
|
||||
draw_text(&*tmp, x_offset + 5.0, y_offset + 20.0, 20.0, BLACK);
|
||||
pub fn read_data_bus(&self) -> u8 {
|
||||
if !self.rs && self.rw {
|
||||
// Return busy flag + current address
|
||||
let busy_flag = if self.busy { 0x80 } else { 0x00 };
|
||||
busy_flag | (self.cursor_position & 0x7F)
|
||||
} else {
|
||||
// Not implemented: read from DDRAM/CGRAM
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
|
||||
// println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color);
|
||||
draw_line(x1, y1, x2, y1, 1.0, color);
|
||||
draw_line(x1, y1, x1, y2, 1.0, color);
|
||||
draw_line(x1, y2, x2, y2, 1.0, color);
|
||||
draw_line(x2, y1, x2, y2, 1.0, color);
|
||||
pub fn tick(&mut self) {
|
||||
if self.busy && self.last_command_time.elapsed() > Duration::from_micros(50) {
|
||||
self.busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate(&mut self) {
|
||||
if self.rw {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.rs {
|
||||
self.write_data(self.data_bus);
|
||||
} else {
|
||||
self.execute_command(self.data_bus);
|
||||
}
|
||||
|
||||
self.busy = true;
|
||||
self.last_command_time = Instant::now();
|
||||
}
|
||||
|
||||
fn write_data(&mut self, data: u8) {
|
||||
if self.cursor_position < 0x50 {
|
||||
self.ddram[self.cursor_position as usize] = data;
|
||||
self.cursor_position = self.cursor_position.wrapping_add(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_command(&mut self, cmd: u8) {
|
||||
match cmd {
|
||||
0x01 => {
|
||||
self.ddram.fill(b' ');
|
||||
self.cursor_position = 0;
|
||||
}
|
||||
0x02 => {
|
||||
self.cursor_position = 0;
|
||||
}
|
||||
0x04..=0x07 => {
|
||||
self.entry_increment = (cmd & 0b10) != 0;
|
||||
self.entry_shift = (cmd & 0b01) != 0;
|
||||
}
|
||||
0x08..=0x0F => {
|
||||
self.display_on = (cmd & 0b100) != 0;
|
||||
self.cursor_on = (cmd & 0b010) != 0;
|
||||
self.blink_on = (cmd & 0b001) != 0;
|
||||
}
|
||||
0x10..=0x1F => {
|
||||
// Cursor/display shift — not yet implemented
|
||||
}
|
||||
0x20..=0x3F => {
|
||||
self.data_length_8bit = (cmd & 0b10000) != 0;
|
||||
self.two_line_mode = (cmd & 0b1000) != 0;
|
||||
self.font_5x10 = (cmd & 0b100) != 0;
|
||||
}
|
||||
0x40..=0x7F => {
|
||||
// Set CGRAM address — stub
|
||||
}
|
||||
0x80..=0xFF => {
|
||||
self.cursor_position = cmd & 0x7F;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_display_lines(&self) -> (String, String) {
|
||||
let row1: String = self.ddram[0x00..0x10].iter().map(|&b| b as char).collect();
|
||||
let row2: String = self.ddram[0x40..0x50].iter().map(|&b| b as char).collect();
|
||||
(row1, row2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoke() { assert!(true); }
|
||||
fn pulse_enable(lcd: &mut HD44780) {
|
||||
lcd.write_control_lines(lcd.rs, lcd.rw, true);
|
||||
lcd.write_control_lines(lcd.rs, lcd.rw, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn device_init() {
|
||||
let display = DisplayMatrix::new(100.0, 100.0);
|
||||
fn test_clear_display() {
|
||||
let mut lcd = HD44780::new();
|
||||
lcd.set_data_bus(0x01);
|
||||
lcd.write_control_lines(false, false, true);
|
||||
lcd.write_control_lines(false, false, false);
|
||||
lcd.tick();
|
||||
assert!(lcd.ddram.iter().all(|&b| b == b' '));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_data() {
|
||||
let mut lcd = HD44780::new();
|
||||
lcd.set_data_bus(0x41); // 'A'
|
||||
lcd.write_control_lines(true, false, true);
|
||||
lcd.write_control_lines(true, false, false);
|
||||
lcd.tick();
|
||||
assert_eq!(lcd.ddram[0], b'A');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_cursor() {
|
||||
let mut lcd = HD44780::new();
|
||||
lcd.set_data_bus(0x80 | 0x40);
|
||||
lcd.write_control_lines(false, false, true);
|
||||
lcd.write_control_lines(false, false, false);
|
||||
lcd.tick();
|
||||
assert_eq!(lcd.cursor_position, 0x40);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_busy_flag_and_address() {
|
||||
let mut lcd = HD44780::new();
|
||||
lcd.busy = true;
|
||||
lcd.cursor_position = 0x15;
|
||||
lcd.write_control_lines(false, true, true);
|
||||
let data = lcd.read_data_bus();
|
||||
assert_eq!(data, 0x80 | 0x15);
|
||||
}
|
||||
}
|
||||
@@ -6,3 +6,5 @@ pub mod address_bus;
|
||||
pub mod data_bus;
|
||||
pub mod cpu_display;
|
||||
pub mod ram_display;
|
||||
pub mod mos6522_peripheral;
|
||||
pub mod backplane;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
pub trait Mos6522Peripheral {
|
||||
fn write(&mut self, port: u8);
|
||||
fn control(&mut self, control: u8);
|
||||
fn read(&mut self) -> u8;
|
||||
}
|
||||
+119
-37
@@ -1,45 +1,127 @@
|
||||
pub enum Via6522Port {
|
||||
A(u8),
|
||||
B(u8)
|
||||
use crate::parts::display_matrix::HD44780;
|
||||
use crate::parts::mos6522_peripheral::Mos6522Peripheral;
|
||||
|
||||
pub struct VIA6522 {
|
||||
// Data registers
|
||||
ora: u8,
|
||||
orb: u8,
|
||||
|
||||
// Data direction
|
||||
ddra: u8,
|
||||
ddrb: u8,
|
||||
|
||||
// Control lines (external pins)
|
||||
ca1: bool,
|
||||
ca2: bool,
|
||||
cb1: bool,
|
||||
cb2: bool,
|
||||
|
||||
// Timers
|
||||
t1_counter: u16,
|
||||
t1_latch: u16,
|
||||
t1_enabled: bool,
|
||||
|
||||
t2_counter: u16,
|
||||
t2_latch: u16,
|
||||
t2_enabled: bool,
|
||||
|
||||
// Interrupt flags
|
||||
ifr: u8,
|
||||
ier: u8,
|
||||
|
||||
// Peripheral (e.g., LCD)
|
||||
pub lcd: Option<Box<dyn Mos6522Peripheral>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Via6522 {
|
||||
data_bus: u8,
|
||||
address_bus: u16,
|
||||
port_a_state: u8,
|
||||
port_b_data: u8,
|
||||
port_a_direction: u8,
|
||||
port_b_direction: u8,
|
||||
memory_offset: u16,
|
||||
}
|
||||
|
||||
impl Via6522 {
|
||||
pub fn new(offset: u16) -> Self {
|
||||
Via6522 {
|
||||
memory_offset: offset,
|
||||
..Default::default()
|
||||
impl VIA6522 {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ora: 0,
|
||||
orb: 0,
|
||||
ddra: 0,
|
||||
ddrb: 0,
|
||||
ca1: false,
|
||||
ca2: false,
|
||||
cb1: false,
|
||||
cb2: false,
|
||||
t1_counter: 0,
|
||||
t1_latch: 0,
|
||||
t1_enabled: false,
|
||||
t2_counter: 0,
|
||||
t2_latch: 0,
|
||||
t2_enabled: false,
|
||||
ifr: 0,
|
||||
ier: 0,
|
||||
lcd: Some(HD44780::new().into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_port_direction(&mut self, port: Via6522Port) {
|
||||
match port {
|
||||
Via6522Port::A(x) => {
|
||||
self.port_a_direction = x;
|
||||
},
|
||||
Via6522Port::B(x) => {
|
||||
self.port_b_direction = x;
|
||||
pub fn read(&self, addr: u8) -> u8 {
|
||||
match addr & 0x0F {
|
||||
0x0 => self.orb,
|
||||
0x1 => self.ora,
|
||||
0x2 => self.ddrb,
|
||||
0x3 => self.ddra,
|
||||
0x4 => (self.t1_counter & 0xFF) as u8,
|
||||
0x5 => (self.t1_counter >> 8) as u8,
|
||||
0x6 => (self.t1_latch & 0xFF) as u8,
|
||||
0x7 => (self.t1_latch >> 8) as u8,
|
||||
0x8 => (self.t2_counter & 0xFF) as u8,
|
||||
0x9 => (self.t2_latch & 0xFF) as u8,
|
||||
0xD => self.ifr,
|
||||
0xE => self.ier | 0x80,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, addr: u8, value: u8) {
|
||||
match addr & 0x0F {
|
||||
0x0 => self.orb = value,
|
||||
0x1 => self.ora = value,
|
||||
0x2 => self.ddrb = value,
|
||||
0x3 => self.ddra = value,
|
||||
0x4 => {
|
||||
self.t1_latch = (self.t1_latch & 0xFF00) | value as u16;
|
||||
self.t1_counter = self.t1_latch;
|
||||
}
|
||||
0x5 => {
|
||||
self.t1_latch = (value as u16) << 8 | (self.t1_latch & 0x00FF);
|
||||
self.t1_counter = self.t1_latch;
|
||||
self.t1_enabled = true;
|
||||
}
|
||||
0x6 => self.t1_latch = (self.t1_latch & 0xFF00) | value as u16,
|
||||
0x7 => self.t1_latch = (value as u16) << 8 | (self.t1_latch & 0x00FF),
|
||||
0x8 => self.t2_counter = value as u16,
|
||||
0x9 => self.t2_latch = value as u16,
|
||||
0xD => self.ifr &= !value, // Clear interrupt flags
|
||||
0xE => {
|
||||
if value & 0x80 != 0 {
|
||||
self.ier |= value & 0x7F;
|
||||
} else {
|
||||
self.ier &= !(value & 0x7F);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
if self.t1_enabled {
|
||||
if self.t1_counter > 0 {
|
||||
self.t1_counter -= 1;
|
||||
if self.t1_counter == 0 {
|
||||
self.ifr |= 0x40; // Set T1 interrupt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.t2_enabled {
|
||||
if self.t2_counter > 0 {
|
||||
self.t2_counter -= 1;
|
||||
if self.t2_counter == 0 {
|
||||
self.ifr |= 0x20; // Set T2 interrupt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// check for output pins and see what they say
|
||||
pub fn update_pins(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
/// check for input mode pins and see what they say
|
||||
pub fn read_pins(&self) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user