// 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::{env, sync::Arc, time::Duration}; use trve::{ consts::{Byte, DWord, HWord, Word}, core::Core, exceptions::ExceptionType, mem::{DeviceEntry, MemConfig, MemDeviceInterface, PageNum, Ram}, }; use anyhow::{Result, bail}; use crate::basic_uart::BasicUart; mod execload; fn main() -> Result<()> { let mut ram = Ram::try_new(16 * 1024 * 1024 / 4096)?; let buf = ram.buf_mut(); let args: Vec = env::args().collect(); if args.len() != 2 { eprintln!("USAGE: trve "); bail!("Wrong number of arguments"); } let entry_point = execload::load(&args[1], buf, 0x8000_0000)?; 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(entry_point); core.run(); Ok(()) } mod basic_uart; struct DbgOut; impl MemDeviceInterface for DbgOut { fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), ExceptionType> { 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<(), ExceptionType> { 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<(), ExceptionType> { 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<(), ExceptionType> { eprintln!("Wrote Byte {value:02x} to Debug-Out page {page}, offset {offset}"); Ok(()) } fn read_dword(&self, _page: PageNum, _offset: u16) -> Result { Err(ExceptionType::LoadAccessFault) } fn read_word(&self, _page: PageNum, _offset: u16) -> Result { Err(ExceptionType::LoadAccessFault) } fn read_hword(&self, _page: PageNum, _offset: u16) -> Result { Err(ExceptionType::LoadAccessFault) } fn read_byte(&self, _page: PageNum, _offset: u16) -> Result { Err(ExceptionType::LoadAccessFault) } fn get_atomic_word( &self, _page: PageNum, _offset: u16, ) -> Result<&std::sync::atomic::AtomicU32, ExceptionType> { Err(ExceptionType::StoreAmoAccessFault) } fn get_atomic_dword( &self, _page: PageNum, _offset: u16, ) -> Result<&std::sync::atomic::AtomicU64, ExceptionType> { Err(ExceptionType::StoreAmoAccessFault) } }