cpclib_asm/assembler/
page_info.rs

1use super::delayed_command::*;
2use super::report::SavedFile;
3use super::save_command::SaveCommand;
4use super::{Env, EnvEventObserver};
5use crate::error::AssemblerError;
6pub type ProtectedArea = std::ops::RangeInclusive<u16>;
7
8/// Store all the compilation information for the currently selected 64kb page
9/// A stock CPC 6128 is composed of two pages
10#[derive(Debug, Clone)]
11pub struct PageInformation {
12    /// Start adr to use to write binary files. Not use when working with snapshots.
13    pub(crate) startadr: Option<u16>,
14    /// maximum address reached when working with 64k data
15    pub(crate) maxadr: u16,
16    /// Current address to write to
17    pub(crate) logical_outputadr: u16,
18    /// Current address used by the code
19    pub(crate) logical_codeadr: u16,
20    /// Maximum possible address to write to
21    pub(crate) output_limit: u16,
22    pub(crate) code_limit: u16,
23    /// List of pretected zones
24    pub(crate) protected_areas: Vec<ProtectedArea>,
25    pub(crate) fail_next_write_if_zero: bool,
26
27    /// List of save commands  that will be executed ONLY after full assembling (they are emptied at the beginning of each pass)
28    delayed_commands: DelayedCommands
29}
30
31impl Default for PageInformation {
32    fn default() -> Self {
33        Self {
34            startadr: None,
35            maxadr: 0,
36            logical_outputadr: 0,
37            logical_codeadr: 0,
38            output_limit: 0xFFFF,
39            code_limit: 0xFFFF,
40            protected_areas: Vec::new(),
41            fail_next_write_if_zero: false,
42            delayed_commands: DelayedCommands::default()
43        }
44    }
45}
46
47impl PageInformation {
48    delegate::delegate! {
49        to self.delayed_commands {
50            pub fn add_breakpoint_command(&mut self, command: BreakpointCommand);
51
52            pub fn add_save_command(&mut self, command: SaveCommand);
53            pub fn add_failed_assert_command(&mut self, command: FailedAssertCommand);
54            pub fn add_print_command(&mut self, command: PrintCommand);
55            pub fn add_pause_command(&mut self, command: PauseCommand);
56            pub fn add_print_or_pause_command(&mut self, command: PrintOrPauseCommand);
57
58            pub fn print_commands(&self) -> &[PrintOrPauseCommand];
59            pub fn print_commands_mut(&mut self) -> &mut [PrintOrPauseCommand];
60
61            pub fn failed_assert_commands(&self) -> &[FailedAssertCommand] ;
62            pub fn failed_assert_commands_mut(&mut self) -> &mut[FailedAssertCommand] ;
63
64            pub fn can_save_in_parallel(&self) -> bool;
65            pub fn get_save_mmrs(&self) -> Vec<u8>;
66            pub fn execute_save(&self, env: &Env, mmr: u8) -> Result<Vec<SavedFile>, AssemblerError>;
67            pub fn nb_files_to_save(&self) -> usize;
68            pub fn collect_assert_failure(&self) -> Result<(), AssemblerError>;
69            pub fn execute_print_or_pause(&self, o: &dyn EnvEventObserver)-> Result<(), AssemblerError>;
70            pub fn collect_breakpoints(&self)-> &[BreakpointCommand];
71        }
72
73    }
74
75    /// Properly set the information for a new pass
76    pub fn new_pass(&mut self) {
77        self.startadr = None;
78        self.maxadr = 0;
79        self.logical_outputadr = 0;
80        self.logical_codeadr = 0;
81        self.output_limit = 0xFFFF;
82        self.fail_next_write_if_zero = false;
83        self.delayed_commands.clear();
84    }
85
86    pub fn set_limit(&mut self, l: u16) -> Result<(), AssemblerError> {
87        if l > self.output_limit {
88            return Err(AssemblerError::AssemblingError {
89                msg: format!(
90                    "Cannot set a limit of &{:X} as a former limit of &{:X} is already set up",
91                    l, self.output_limit
92                )
93            });
94        }
95
96        if l < self.maxadr {
97            return Err(AssemblerError::AssemblingError {
98                msg: format!(
99                    "Cannot set a limit of &{:X} as some bytes has been written at &{:X}p",
100                    l, self.maxadr
101                )
102            });
103        }
104
105        self.output_limit = l;
106        Ok(())
107    }
108}