Expand description

Contains types and functionality for assembling Baby asm.

Baby Assembly

This module contains the types and functionality for assembling Baby asm.

The main part of this module is the assemble function, that takes a string of asm and attempts to assemble to a vector of BabyInstruction representing individual Baby machine code instructions.

This can be fed straight into BabyInstruction::to_numbers that can then be used to with BabyModel::new_with_program to make a runnable instance of the Baby emulator loaded with the assembled program.

Example

This is a simple example that assembles an assembly string, converts the result to a memory array using BabyInstruction::to_numbers, instantiates a baby model and then runs it as per the example in core module.

use baby_emulator::assembler::assemble; 
use baby_emulator::core::{BabyModel, instructions::BabyInstruction};
 
 
const ASM: &str = 
"
ldn $start_value  ; Loads 10 into the accumulator 
   
:loop_start_value ; The memory address the loop should return to 
sub $subtract_val ; Subtract 1 from the accumulator 
cmp               ; Skip the next jump instruction if the accumulator is negative 
jmp $loop_start   ; Jump to the start of the loop 
stp               ; Program stops when the accumulator is negative 
 
:loop_start       ; Pointer to the memory address the loop should return to 
abs $loop_start_value
 
:subtract_val     ; Value to be subtracted
abs 0d1
   
:start_value      ; Value to start in the accumulator 
abs 0d-10
";

fn main() {
    let instructions = match assemble(&String::from(ASM), false) {
        Ok(v) => v,
        Err(e) => { println!("{}", e.describe(true)); return; }
    };
    let main_store = BabyInstruction::to_numbers(instructions);
 
    let mut model = BabyModel::new_with_program(main_store);
    loop {
        model = match model.execute() {
            Ok(m) => m,
            Err(_) => break
        };
    }
    println!("{}", model.core_dump());
}

Syntax

The original Manchester Baby did not have an assembly language, this is just a simple language put together to make programming a little bit easier.

Instructions

Baby assembly contains the following instructions:

Modern NotationOriginal NotationDescription
JMP ##, ClJump to the instruction at the address obtained from the specified memory address # (absolute unconditional jump)
JRP #Add #, ClJump to the instruction at the program counter plus (+) the relative value obtained from the specified memory address # (relative unconditional jump)
LDN #-#, CTake the number from the specified memory address #, negate it, and load it into the accumulator
STO #c, #Store the number in the accumulator to the specified memory address #
SUB #SUB #Subtract the number at the specified memory address # from the value in accumulator, and store the result in the accumulator
CMPTestSkip next instruction if the accumulator contains a negative value
STPStopStop
  • All modern instruction are case insensitive.
  • # represents a value which can be in any format in the Values table above.
  • All instructions with a value operand # the value operand is always a memory address.

Values

The following value formats are accepted:

FormatExample
Hex0xA
Decimal0d10
Octal0o12
Binary0b1010
Tag Reference$start

Tags

You can tag a position in the program stack and reference it’s memory address as a value using a named tag, for instance the following code jumps to a stop command by referencing prog_end as the value parameter to a jump instruction.

jmp $prog_end
 
:prog_end
stp

Absolute values

Often you will need to include values in your program code in, you will have to add these to your program stack in memory, to do this you can use the abs # directive, this looks looks like an instruction but in reality just tells the assembler to just put whatever value you wrote into the program stack.

These the value can be of any kind from the values table above, including a tag reference, you can also write negative values here like 0x-A, 0d-10, 0o-12, 0b-1010 (tag references cannot be written as negative however).

The below program loads a “10” into the accumulator from memory by negatively loading a “-10” from a location denoted by the tag foo:

ldn $foo
 
:foo
abs 0d-10

Comments

Comments can be used with a ; as with other assembly languages.

; This is a comment
JMP 0d1 ; And so is this 

Full example

This shows a simple program in both modern and original notation that loads negative a -10 into the accumulator (or, loads 10 into the accumulator), then enters a loop where it subtracts 1 from the accumulator and jumps back to the start of the loop if the accumulator is not negative, when the accumulator is negative, a stop instruction is hit and the machine stops.

Modern notation:

ldn $start_value  ; Loads 10 into the accumulator 
   
:loop_start_value ; The memory address the loop should return to 
sub $subtract_val ; Subtract 1 from the accumulator 
cmp               ; Skip the next jump instruction if the accumulator is negative 
jmp $loop_start   ; Jump to the start of the loop 
stp               ; Program stops when the accumulator is negative 
 
:loop_start       ; Pointer to the memory address the loop should return to 
abs $loop_start_value
 
:subtract_val     ; Value to be subtracted
abs 0d1
   
:start_value      ; Value to start in the accumulator 
abs 0d-10

Original notation:

-$start_value, C  ; Loads 10 into the accumulator 
 
:loop_start_value ; The memory address the loop should return to 
SUB $subtract_val ; Subtract 1 from the accumulator 
Test              ; Skip the next jump instruction if the accumulator is negative 
$loop_start, CL   ; Jump to the start of the loop 
Stop              ; Program stops when the accumulator is negative 
 
:loop_start       ; Pointer to the memory address the loop should return to 
abs $loop_start_value
 
:subtract_val     ; Value to be subtracted
abs 0d1
 
:start_value      ; Value to start in the accumulator 
abs 0d-10

Modules

  • Contains types for handling errors found during the overall assembling process.
  • Contains types and functionality for linking asm post parsing.
  • Contains types and functionality for parsing Baby asm.

Functions