[][src]Trait melon::System

pub trait System {
    const ID: &'static str;
    const MEM_PAGES: u8;
    fn pre_cycle(&mut self, vm: &mut VM) -> Result<()> { ... }
fn post_cycle(&mut self, vm: &mut VM) -> Result<()> { ... }
fn prepare(&mut self, vm: &mut VM) -> Result<()> { ... }
fn finish(&mut self, vm: &mut VM) -> Result<()> { ... }
fn system_call(&mut self, vm: &mut VM, signal: u16) -> Result<()> { ... } }

An interface to communicate with the VM

Example

If you wanted to implement a text based system you could write something like this:

extern crate melon;

use melon::typedef::*;
use melon::{System, VM};
use std::sync::mpsc::Receiver;


pub const MAX_CHARACTERS_PER_LINE: usize = 100;

pub struct TextSystem {
    current_output_line: String,
    current_input_line: String,
    recv: Receiver<u8>,
}


impl TextSystem {
    /// The receiver allows you to safely inject characters from another thread
    pub fn new(recv: Receiver<u8>) -> TextSystem {
        TextSystem {
            current_output_line: Default::default(),
            current_input_line: Default::default(),
            recv: recv,
        }
    }
}

impl System for TextSystem {
    const ID: &'static str = "com.example.text-system";

    const MEM_PAGES: u8 = 1;

    fn system_call(&mut self, vm: &mut VM, signal: u16) -> Result<()> {
        match signal {
            // This is pretty much like `write_line`
            1 => {
                // Read the memory of the vm until you reach the terminal `0x00` but only to a
                // maximum of 100 characters
                let line = vm.mem
                    .iter()
                    .take(MAX_CHARACTERS_PER_LINE)
                    .map(|x| *x)
                    .take_while(|x| x != &0_u8)
                    .collect::<Vec<u8>>();

                self.current_output_line = String::from_utf8(line)?;

                println!("{}", self.current_output_line);
            }
            // This is pretty much like `read_line`
            2 => {
                // Receive single characters until you reach the terminal `0x00` but only to a
                // maximum of 100 characters
                let mut line = self.recv
                    .iter()
                    .take(MAX_CHARACTERS_PER_LINE)
                    .take_while(|x| x != &0_u8)
                    .collect::<Vec<u8>>();

                line.push(0); // Push terminal `0x00`

                self.current_input_line = String::from_utf8(line.clone())?;

                // Copy characters to vm memory
                for i in 0..line.len() {
                    let vm_index = (MAX_CHARACTERS_PER_LINE + 1) + i;
                    vm.mem[vm_index] = line[i];
                }
            }
            _ => unreachable!(),
        }

        Ok(())
    }
}

Following the basic principles in this example, you are able to build any retro style computing system you want.

Associated Constants

const ID: &'static str

A unique ID to identify the System

const MEM_PAGES: u8

The minimum number of memory pages required for this system

Loading content...

Provided methods

fn pre_cycle(&mut self, vm: &mut VM) -> Result<()>

Hook into the state before each cycle

fn post_cycle(&mut self, vm: &mut VM) -> Result<()>

Hook into the state after each cycle

fn prepare(&mut self, vm: &mut VM) -> Result<()>

Prepare the state of the VM

fn finish(&mut self, vm: &mut VM) -> Result<()>

Make finalizing manipulations to the state before the VM's shutdown

fn system_call(&mut self, vm: &mut VM, signal: u16) -> Result<()>

React to the SysCall instruction and process the given signal

Loading content...

Implementors

Loading content...