Support non-nightly no_std builds

This commit is contained in:
Jan Bujak 2023-10-20 06:10:55 +00:00
parent 71fcdf7b39
commit e02a4b8b37
5 changed files with 40 additions and 23 deletions

View file

@ -1,5 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(error_in_core))]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
@ -16,4 +15,4 @@ extern crate bitflags;
mod virtual_mos6502_decoder; mod virtual_mos6502_decoder;
mod virtual_mos6502; mod virtual_mos6502;
pub use virtual_mos6502::{Interface, State, Context, Address, EmulationStatus, decode_instruction}; pub use virtual_mos6502::{Interface, State, Context, Address, EmulationError, EmulationStatus, decode_instruction};

View file

@ -224,7 +224,8 @@ impl fmt::Display for EmulationError {
} }
} }
impl core::error::Error for EmulationError { #[cfg(feature = "std")]
impl std::error::Error for EmulationError {
fn description( &self ) -> &str { fn description( &self ) -> &str {
use self::EmulationError::*; use self::EmulationError::*;
match *self { match *self {

View file

@ -1,5 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(error_in_core))]
#![allow(dead_code)] #![allow(dead_code)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
@ -54,6 +53,6 @@ mod filter;
#[cfg(test)] #[cfg(test)]
mod testsuite; mod testsuite;
pub use virtual_nes::{Interface, State, Context, Button, ControllerPort}; pub use virtual_nes::{Interface, State, Context, Button, ControllerPort, Error};
pub use rp2c02::{Framebuffer, Palette}; pub use rp2c02::{Framebuffer, Palette};
pub use rom::LoadError; pub use rom::LoadError;

View file

@ -1,6 +1,5 @@
use core::cmp::max; use core::cmp::max;
use core::fmt; use core::fmt;
use core::error;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::format; use alloc::format;
@ -36,13 +35,8 @@ impl fmt::Display for LoadError {
} }
} }
impl error::Error for LoadError { #[cfg(feature = "std")]
fn description( &self ) -> &str { impl std::error::Error for LoadError {}
match *self {
LoadError::Custom( ref message ) => &message[..],
}
}
}
pub const ROM_BANK_SIZE: usize = 16 * 1024; pub const ROM_BANK_SIZE: usize = 16 * 1024;
pub const VROM_BANK_SIZE: usize = 8 * 1024; pub const VROM_BANK_SIZE: usize = 8 * 1024;

View file

@ -1,4 +1,3 @@
use core::error::Error;
use core::mem; use core::mem;
use alloc::boxed::Box; use alloc::boxed::Box;
@ -11,6 +10,31 @@ use rom::{NesRom, LoadError};
use emumisc::{WrappingExtra, PeekPoke, copy_memory}; use emumisc::{WrappingExtra, PeekPoke, copy_memory};
use memory_map::{translate_address_ram, translate_address_ioreg_ppu, translate_address_ioreg_other}; use memory_map::{translate_address_ram, translate_address_ioreg_ppu, translate_address_ioreg_other};
#[derive(Debug)]
pub struct Error( ErrorKind );
impl core::fmt::Display for Error {
fn fmt( &self, fmt: &mut core::fmt::Formatter ) -> core::fmt::Result {
match self.0 {
ErrorKind::EmulationError( error ) => error.fmt( fmt )
}
}
}
#[derive(Debug)]
enum ErrorKind {
EmulationError( mos6502::EmulationError )
}
impl From< mos6502::EmulationError > for Error {
fn from( error: mos6502::EmulationError ) -> Self {
Error( ErrorKind::EmulationError( error ) )
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
pub trait Context: Sized { pub trait Context: Sized {
fn state_mut( &mut self ) -> &mut State; fn state_mut( &mut self ) -> &mut State;
fn state( &self ) -> &State; fn state( &self ) -> &State;
@ -38,15 +62,15 @@ pub trait Interface: Sized + Context {
Private::copy_into_memory( self, offset, data ) Private::copy_into_memory( self, offset, data )
} }
fn execute_until_vblank( &mut self ) -> Result< (), Box< dyn Error > > { fn execute_until_vblank( &mut self ) -> Result< (), Error > {
Private::execute_until_vblank( self ) Private::execute_until_vblank( self )
} }
fn execute_for_a_frame( &mut self ) -> Result< (), Box< dyn Error > > { fn execute_for_a_frame( &mut self ) -> Result< (), Error > {
Private::execute_for_a_frame( self ) Private::execute_for_a_frame( self )
} }
fn execute_cycle( &mut self ) -> Result< bool, Box< dyn Error > > { fn execute_cycle( &mut self ) -> Result< bool, Error > {
Private::execute_cycle( self ) Private::execute_cycle( self )
} }
@ -94,7 +118,7 @@ pub struct State {
apu_state: virtual_apu::State, apu_state: virtual_apu::State,
dma_state: dma::State, dma_state: dma::State,
mapper: Option< Box< dyn Mapper > >, mapper: Option< Box< dyn Mapper > >,
error: Option< Box< dyn Error > >, error: Option< Error >,
ready: bool, ready: bool,
cpu_cycle: u32, cpu_cycle: u32,
frame_counter: u32, frame_counter: u32,
@ -366,7 +390,7 @@ trait Private: Sized + Context {
copy_memory( data, &mut self.state_mut().ram[ offset as usize.. ] ); copy_memory( data, &mut self.state_mut().ram[ offset as usize.. ] );
} }
fn execute_until_vblank( &mut self ) -> Result< (), Box< dyn Error > > { fn execute_until_vblank( &mut self ) -> Result< (), Error > {
if !self.state().ready { if !self.state().ready {
return Ok(()); return Ok(());
} }
@ -375,7 +399,7 @@ trait Private: Sized + Context {
while self.state().frame_counter == last_counter_value { while self.state().frame_counter == last_counter_value {
let result = mos6502::Interface::execute( self.newtype_mut() ); let result = mos6502::Interface::execute( self.newtype_mut() );
if let Err( error ) = result { if let Err( error ) = result {
self.state_mut().error = Some( Box::new( error ) ); self.state_mut().error = Some( error.into() );
break; break;
} }
} }
@ -388,7 +412,7 @@ trait Private: Sized + Context {
} }
} }
fn execute_for_a_frame( &mut self ) -> Result< (), Box< dyn Error > > { fn execute_for_a_frame( &mut self ) -> Result< (), Error > {
if !self.state().ready { if !self.state().ready {
return Ok(()); return Ok(());
} }
@ -397,7 +421,7 @@ trait Private: Sized + Context {
while self.state().full_frame_counter == last_counter_value { while self.state().full_frame_counter == last_counter_value {
let result = mos6502::Interface::execute( self.newtype_mut() ); let result = mos6502::Interface::execute( self.newtype_mut() );
if let Err( error ) = result { if let Err( error ) = result {
self.state_mut().error = Some( Box::new( error ) ); self.state_mut().error = Some( error.into() );
break; break;
} }
} }
@ -410,7 +434,7 @@ trait Private: Sized + Context {
} }
} }
fn execute_cycle( &mut self ) -> Result< bool, Box< dyn Error > > { fn execute_cycle( &mut self ) -> Result< bool, Error > {
let last_counter_value = self.state().full_frame_counter; let last_counter_value = self.state().full_frame_counter;
mos6502::Interface::execute( self.newtype_mut() )?; mos6502::Interface::execute( self.newtype_mut() )?;