Struct baby_emulator::core::BabyModel
source · pub struct BabyModel {
pub main_store: [i32; 32],
pub accumulator: i32,
pub instruction_address: u16,
pub instruction: u16,
}
Expand description
The model containing the data in all the registers and memory to be operated upon.
Fields§
§main_store: [i32; 32]
The memory (RAM), this is just 32 words of 32 bits, originally famously stored on a Williams Tube.
accumulator: i32
The register where all mathematical results are stored (negations and subtractions).
instruction_address: u16
The memory address of the instruction currently being executed (program counter).
instruction: u16
The 16 bit instruction being executed (instruction register).
Implementations§
source§impl BabyModel
impl BabyModel
sourcepub fn new_with_program(main_store: [i32; 32]) -> BabyModel
pub fn new_with_program(main_store: [i32; 32]) -> BabyModel
Creates a new model with a specified memory.
Initialised as to start executing at the start of the memory, specified memory can contain program code to be executed.
§Parameters
main_store
- The custom memory to be initialised with.
sourcepub fn new_example_program() -> BabyModel
pub fn new_example_program() -> BabyModel
Creates a new model with an example program loaded into memory.
This program will add 5 to 5, storing the result in the accumulator and end.
§Example
use baby_emulator::core::BabyModel;
let mut model = BabyModel::new_example_program();
loop {
model = match model.execute() {
Ok(m) => m,
Err(_) => break
}
}
println!("{}", model.core_dump());
sourcepub fn execute(&self) -> InstrResult
pub fn execute(&self) -> InstrResult
Executes the instruction in the instruction register.
Decodes the instruction value in the instruction register and performs the relevant operation on the data within the model, will return all the updated data in a new [Ok(BabyModel)] assuming no errors encountered.
§Returns
Ok(BabyModel)
: A new model instance with all data updated as per the instruction, loaded with the next instruction.Err(BabyErrors)
: An enum detailing errors encountered when executing the instruction.
§Example
use baby_emulator::core::BabyModel;
let mut model = BabyModel::new_example_program();
loop {
model = match model.execute() {
Ok(m) => m,
Err(_) => break
}
}
println!("{}", model.core_dump());
sourcepub fn decode_instruction(&self) -> (i32, BabyInstruction)
pub fn decode_instruction(&self) -> (i32, BabyInstruction)
Decodes the instruction in BabyModel.instruction
from the numeric value
to BabyInstruction and the i32 value pointed to by the instruction operand.
sourcepub fn run_loop(&self, max_iter: usize) -> (BabyModel, BabyErrors)
pub fn run_loop(&self, max_iter: usize) -> (BabyModel, BabyErrors)
Executes the instructions in memory until an error is thrown or a limmit is hit.
Kepps calling BabyModel::execute on each sucesssive iteration
until either an error is thrown (such as BabyErrors::Stop) or
the number of iterations hits the max_iter
value.
Returns a tuple of the model in its final state plus the error thrown, error will be BabyErrors::IterationExceeded if iterations exceeded.
§Parameters
max_iter
- The maximum number of iterations of executing successive instructions.
§Example
use baby_emulator::core::BabyModel;
use baby_emulator::core::errors::BabyErrors;
use baby_emulator::core::errors::BabyError;
let model = BabyModel::new_example_program();
match model.run_loop(100) {
(model, BabyErrors::Stop(_)) => println!("{}", model.core_dump()),
(_, err) => println!("{}", err.get_descriptor())
}
sourcepub fn dispatch_instruction(
&self,
instruction: BabyInstruction,
operand_value: i32
) -> InstrResult
pub fn dispatch_instruction( &self, instruction: BabyInstruction, operand_value: i32 ) -> InstrResult
Takes a BabyInstruction and a dereferenced operand value i32 and calls the correct instruction method.
Returns the result of the method call, if BabyInstruction::Stop is will return BabyErrors::Stop.
§Parameters
instruction
- The instruction to execute.operand_value
- The value from memory referenced by the actual operand.
sourcepub fn jump(&self, address: i32) -> BabyModel
pub fn jump(&self, address: i32) -> BabyModel
Carries out a jump to a specified address.
Will update the BabyModel.instruction_address
least significant 5 bits
to the last significant 5 bits of address
, means jumping cannot be indexed outside
of the memory, program execution will then proceed from this address.
§Parameters
address
- The memory address to jump to.
sourcepub fn relative_jump(&self, offset: i32) -> BabyModel
pub fn relative_jump(&self, offset: i32) -> BabyModel
Carries out a jump to the instruction address plus an offset.
This will add the BabyModel.instruction_address
to the offset, then set
the BabyModel.instruction_address
equal to the least significant 5 bits
of the result, this allows the jump to “loop” back to the start
of the memory, program execution will then proceed from this address.
§Parameters
offset
- The value to offset the BabyModel.instruction_address
to.
sourcepub fn negate(&self, value: i32) -> BabyModel
pub fn negate(&self, value: i32) -> BabyModel
Negates a value and stores it into the accumulator.
Negates (adds or removes the “-”) the specified value and stores it in the accumulator, returning the updated model.
Adds 1 to the BabyModel.instruction_address
and keeps only
the least significant 5 bits as to only index within the
allocated memory.
§Parameters
value
- The value to negate.
sourcepub fn store(&self, address: i32) -> BabyModel
pub fn store(&self, address: i32) -> BabyModel
Stores the accumulator at a specified address in memory.
Takes the least significant 5 bits of address
uses this to
index into the memory, as to not index outside of the memory
and stores the value in BabyModel.accumulator
.
Adds 1 to the BabyModel.instruction_address
and keeps only
the least significant 5 bits as to only index within the
allocated memory.
§Parameters
address
- The address to store the accumulator to.
sourcepub fn subtract(&self, value: i32) -> BabyModel
pub fn subtract(&self, value: i32) -> BabyModel
Subtracts the specified value from the accumulator.
Subtracts the specified value from the accumulator, storing the result back to the accumulator.
Adds 1 to the BabyModel.instruction_address
and keeps only
the least significant 5 bits as to only index within the allocated
memory, using this to get the next instruction from the memory and
storing it in BabyModel.instruction
register.
§Parameters
value
- The value to subtract from the accumulator.
sourcepub fn test(&self) -> BabyModel
pub fn test(&self) -> BabyModel
Skips the next instruction address if the accumulator is negative.
Adds 1 to the BabyModel.instruction_address
if the BabyModel.accumulator
is not negative and 2 if it is and keeps only the least significant 5 bits
as to only index within the allocated memory, using this to get the next
instruction from the memory and storing it in BabyModel.instruction
register.
§Parameters
value
- The value to subtract from the accumulator.
sourcepub fn core_dump(&self) -> String
pub fn core_dump(&self) -> String
Generates a string representation of current state of the model.
Generates a formatted string representation of all the registers and memory addresses in the model, able to be printed to the console.
§Example
use baby_emulator::core::BabyModel;
use baby_emulator::core::errors::BabyErrors;
use baby_emulator::core::errors::BabyError;
let model = BabyModel::new_example_program();
match model.run_loop(100) {
(model, BabyErrors::Stop(_)) => println!("{}", model.core_dump()),
(_, err) => println!("{}", err.get_descriptor())
}