// Copyright (c) 2025 taitep // SPDX-License-Identifier: MIT // // This file is part of TRVE (https://gitea.taitep.se/taitep/trve) // See LICENSE file in the project root for full license text. use std::{ error::Error, fs::File, io::{self, Read}, sync::Arc, time::Duration, }; use trve::{ consts::{Byte, DWord, HWord, Word}, core::Core, mem::{DeviceEntry, MemAccessFault, MemConfig, MemDeviceInterface, PageNum, Ram}, }; use crate::basic_uart::BasicUart; fn read_file_to_buffer(path: &str, buffer: &mut [u8]) -> io::Result { let mut file = File::open(path)?; let mut total_read = 0; while total_read < buffer.len() { let n = file.read(&mut buffer[total_read..])?; if n == 0 { return Ok(total_read); } total_read += n; } let mut tmp = [0u8; 1]; if file.read(&mut tmp)? != 0 { return Err(io::Error::other("RAM too small for file")); } Ok(total_read) } fn main() -> Result<(), Box> { let mut ram = Ram::try_new(1024 * 1024 / 4096)?; let buf = ram.buf_mut(); read_file_to_buffer("./img", buf)?; let uart = BasicUart::new(); let uart = uart.spawn_poller(Duration::from_millis(10)); let mem_cfg = MemConfig { ram: Arc::new(ram), ram_start: 0x8000_0000 / 4096, devices: Box::new([ DeviceEntry { base: 0, size: 1, interface: Arc::new(DbgOut), }, DeviceEntry { base: 1, size: 1, interface: uart, }, ]), }; let mut core = Core::new(mem_cfg); core.reset(0x8000_0000); core.run(); Ok(()) } mod basic_uart; struct DbgOut; impl MemDeviceInterface for DbgOut { fn write_dword( &self, page: PageNum, offset: u16, value: DWord, ) -> Result<(), trve::mem::MemAccessFault> { eprintln!( "Wrote DWord {value:016x} to Debug-Out page {page}, offset {offset} (byte {})", offset * 8 ); Ok(()) } fn write_word( &self, page: PageNum, offset: u16, value: Word, ) -> Result<(), trve::mem::MemAccessFault> { eprintln!( "Wrote Word {value:08x} to Debug-Out page {page}, offset {offset} (byte {})", offset * 4 ); Ok(()) } fn write_hword( &self, page: PageNum, offset: u16, value: HWord, ) -> Result<(), trve::mem::MemAccessFault> { eprintln!( "Wrote HWord {value:04x} to Debug-Out page {page}, offset {offset} (byte {})", offset * 2 ); Ok(()) } fn write_byte( &self, page: PageNum, offset: u16, value: Byte, ) -> Result<(), trve::mem::MemAccessFault> { eprintln!("Wrote Byte {value:02x} to Debug-Out page {page}, offset {offset}"); Ok(()) } fn read_dword(&self, _page: PageNum, _offset: u16) -> Result { Err(MemAccessFault) } fn read_word(&self, _page: PageNum, _offset: u16) -> Result { Err(MemAccessFault) } fn read_hword(&self, _page: PageNum, _offset: u16) -> Result { Err(MemAccessFault) } fn read_byte(&self, _page: PageNum, _offset: u16) -> Result { Err(MemAccessFault) } fn get_atomic_word( &self, _page: PageNum, _offset: u16, ) -> Result<&std::sync::atomic::AtomicU32, trve::mem::MemAccessFault> { Err(MemAccessFault) } fn get_atomic_dword( &self, _page: PageNum, _offset: u16, ) -> Result<&std::sync::atomic::AtomicU64, trve::mem::MemAccessFault> { Err(MemAccessFault) } }