asmachina

Crates.ioasmachina
lib.rsasmachina
version0.1.0
created_at2025-06-30 18:36:25.872939+00
updated_at2025-06-30 18:36:25.872939+00
descriptionMachine W emulator core - 16-bit architecture with full instruction set support
homepage
repositoryhttps://github.com/szymonwilczek/asmodeus
max_upload_size
id1732195
size74,764
Szymon Wilczek (szymonwilczek)

documentation

README

Asmachina

Core Machine W Emulator for Asmodeus

┌────────────────────────────────────────────────────────────────────────────┐
│                                                                            │
│   █████╗ ███████╗███╗   ███╗ █████╗  ██████╗██╗  ██╗██╗███╗   ██╗ █████╗   │
│  ██╔══██╗██╔════╝████╗ ████║██╔══██╗██╔════╝██║  ██║██║████╗  ██║██╔══██╗  │
│  ███████║███████╗██╔████╔██║███████║██║     ███████║██║██╔██╗ ██║███████║  │
│  ██╔══██║╚════██║██║╚██╔╝██║██╔══██║██║     ██╔══██║██║██║╚██╗██║██╔══██║  │
│  ██║  ██║███████║██║ ╚═╝ ██║██║  ██║╚██████╗██║  ██║██║██║ ╚████║██║  ██║  │
│  ╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝╚═╝  ╚═╝  │
│                                                                            │
│                Machine W Virtual Machine & Execution Engine                │
└────────────────────────────────────────────────────────────────────────────┘

Asmachina is the core virtual machine that emulates the legendary Machine W architecture. It provides a complete 16-bit execution environment with 2048 words of memory, comprehensive instruction set support, and advanced debugging capabilities.

🏗️ Architecture Overview

Machine W Specification

  • Word Size: 16-bit architecture
  • Memory: 2048 words (4096 bytes total)
  • Address Space: 11-bit addressing (0-2047)
  • Instruction Format: 16-bit words with opcode and operand fields
  • Stack: Hardware stack growing downward from address 2047

Register Set

┌─────────────────┬──────────┬─────────────────────────────────┐
│ Register        │ Size     │ Purpose                         │
├─────────────────┼──────────┼─────────────────────────────────┤
│ AK (Accumulator)│ 16-bit   │ Primary arithmetic register     │
│ L (Counter)     │ 11-bit   │ Instruction counter (PC)        │
│ AD (Address)    │ 11-bit   │ Address register for operands   │
│ KOD (Opcode)    │ 5-bit    │ Current instruction opcode      │
│ WS (Stack Ptr)  │ 11-bit   │ Stack pointer (grows downward)  │
│ R0-R7           │ 16-bit   │ General purpose registers       │
└─────────────────┴──────────┴─────────────────────────────────┘

Memory Layout

0x0000 ┌─────────────────────────────────────┐
       │             Program Code            │
       │                                     │
       ├─────────────────────────────────────┤
       │             Data Section            │
       │                                     │
       ├─────────────────────────────────────┤
       │             Free Space              │
       │                                     │
       │                 ⋮                   │
       │                                     │
       ├─────────────────────────────────────┤
       │               Stack                 │
       │          (grows downward)           │
0x07FF └─────────────────────────────────────┘

🎯 Features

Core Execution Engine

  • Complete Instruction Set: All Machine W opcodes implemented
  • Extended Instructions: MNO, DZI, MOD arithmetic operations
  • Multiple Addressing Modes: Direct, immediate, indirect, register-based
  • Hardware Stack: Full stack operations with overflow protection
  • Interrupt System: Hardware interrupt handling and masking

Advanced Features

  • Debugging Support: Step-by-step execution with breakpoints
  • Interactive I/O: Real-time character input/output
  • Error Handling: Comprehensive runtime error detection
  • State Inspection: Complete machine state access
  • Memory Protection: Address bounds checking

I/O System

  • Batch Mode: Pre-loaded input buffers and output collection
  • Interactive Mode: Real-time character-based I/O
  • Buffered Output: Capture all program output for analysis

📚 Instruction Set Reference

Arithmetic Instructions

Opcode Mnemonic Format Description
0001 DOD DOD addr Add memory[addr] to AK
0001 DOD DOD #value Add immediate value to AK
0010 ODE ODE addr Subtract memory[addr] from AK
0010 ODE ODE #value Subtract immediate value from AK

Memory Instructions

Opcode Mnemonic Format Description
0011 ŁAD/LAD LAD addr Store AK to memory[addr]
0100 POB POB addr Load memory[addr] to AK
0100 POB POB #value Load immediate value to AK

Control Flow Instructions

Opcode Mnemonic Format Description
0101 SOB SOB addr Unconditional jump to addr
0110 SOM SOM addr Jump to addr if AK < 0
10000 SOZ SOZ addr Jump to addr if AK = 0
0111 STP STP Stop program execution

Stack Instructions

Opcode Mnemonic Format Description
1001 PZS PZS Pop from stack to AK
1010 SDP SDP Push AK to stack

I/O Instructions

Opcode Mnemonic Format Description
1110 WEJSCIE WEJSCIE Read input to AK
1111 WYJSCIE WYJSCIE Output AK value

Extended Instructions (Require Extended Mode)

Opcode Mnemonic Format Description
10001 MNO MNO addr Multiply AK by memory[addr]
10001 MNO MNO #value Multiply AK by immediate value
10010 DZI DZI addr Divide AK by memory[addr]
10010 DZI DZI #value Divide AK by immediate value
10011 MOD MOD addr AK = AK % memory[addr]
10011 MOD MOD #value AK = AK % immediate value

Interrupt Instructions

Opcode Mnemonic Format Description
1000 DNS DNS Disable interrupts
1011 CZM CZM Clear interrupt mask
1100 MSK MSK Set interrupt mask
1101 PWR PWR Return from interrupt

🧮 Addressing Modes

Direct Addressing

// POB 100 - Load from memory address 100
let instruction = 0x2064; // 0010 000 001100100

Immediate Addressing

// POB #42 - Load immediate value 42
let instruction = 0x212A; // 0010 001 000101010

Indirect Addressing

// POB [100] - Load from memory[memory[100]]
let instruction = 0x2264; // 0010 010 001100100

Register Addressing

// POB R1 - Load from register 1
let instruction = 0x2301; // 0010 011 000000001

🔧 Advanced Features

  • Debugging Support (breakpoints, memory dumps)
  • Memory Managment (bounds checking, size validation)
  • I/O operations (WEJ, WYJ instructions)

🛠️ Error Handling

Asmachina provides comprehensive error detection:

use asmachina::MachineError;

match machine.step() {
    Err(MachineError::AddressOutOfBounds { address }) => {
        println!("Invalid memory access at address {}", address);
    }
    Err(MachineError::DivisionByZero { address }) => {
        println!("Division by zero at instruction {}", address);
    }
    Err(MachineError::StackOverflow) => {
        println!("Stack overflow - too many pushes");
    }
    Err(MachineError::StackUnderflow) => {
        println!("Stack underflow - pop from empty stack");
    }
    Err(MachineError::InvalidOpcode { opcode }) => {
        println!("Unknown instruction opcode: {:05b}", opcode);
    }
    Ok(()) => println!("Instruction executed successfully"),
}

📖 Examples

Simple Calculator

use asmachina::MachineW;

let mut machine = MachineW::new();

// Program: Add 25 + 17 = 42
let program = vec![
    0x2019,  // POB 25 (address 25)
    0x0800 | 26,  // DOD 26 (add value at address 26)
    0x7800,  // WYJSCIE (output result)
    0x3800,  // STP (stop)
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // padding
    25,      // address 25: first number
    17,      // address 26: second number
];

machine.load_program(&program)?;
machine.run()?;

assert_eq!(machine.get_output_buffer(), &[42]);

Stack Operations

let mut machine = MachineW::new();

// Program: Use stack to reverse two numbers
let program = vec![
    0x210A,  // POB #10 (load 10)
    0x5000,  // SDP (push to stack)
    0x2114,  // POB #20 (load 20)  
    0x5000,  // SDP (push to stack)
    0x4800,  // PZS (pop 20)
    0x7800,  // WYJSCIE (output 20)
    0x4800,  // PZS (pop 10)
    0x7800,  // WYJSCIE (output 10)
    0x3800,  // STP
];

machine.load_program(&program)?;
machine.run()?;

assert_eq!(machine.get_output_buffer(), &[20, 10]);

Extended Arithmetic

// Note: Extended instructions require special handling in real usage
let mut machine = MachineW::new();

// Program: 6 * 7 = 42 (using extended MNO instruction)
let program = vec![
    0x2106,  // POB #6
    // MNO #7 would be: 0x8907 (extended instruction)
    0x7800,  // WYJSCIE
    0x3800,  // STP
];

// Extended instructions are typically handled by the assembler
// This is just for demonstration of the concept

🧪 Testing

Unit Tests

cargo test -p asmachina

Integration Tests

cargo test -p asmachina --test integration

Specific Test Categories

cargo test -p asmachina instruction_tests
cargo test -p asmachina stack_tests  
cargo test -p asmachina extended_set_tests
cargo test -p asmachina error_tests

🔍 Performance Characteristics

  • Execution Speed: ~1M instructions per second (typical)
  • Memory Usage: ~8KB base + program size
  • Startup Time: <1ms for new machine creation
  • Step Execution: ~1μs per instruction (with debugging)

🤝 Integration with Asmodeus Pipeline

Asmachina integrates seamlessly with other Asmodeus components:

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Hephasm   │───▶│  Asmachina  │───▶│   Output    │
│ (Assembler) │    │    (VM)     │    │   Results   │
└─────────────┘    └─────────────┘    └─────────────┘
     ▲                      ▲                ▲
     │                      │                │
 AST from              Machine Code      Execution
  Parseid                                 Results

📝 API Reference

Core Types

pub struct MachineW {
    pub memory: Vec<u16>,           // 2048 words of memory
    pub ak: u16,                    // Accumulator
    pub l: u16,                     // Instruction counter  
    pub ad: u16,                    // Address register
    pub kod: u8,                    // Opcode register
    pub ws: u16,                    // Stack pointer
    pub is_running: bool,           // Execution state
    pub registers: [u16; 8],        // General purpose registers
    // ... other fields
}

pub enum MachineError {
    AddressOutOfBounds { address: u16 },
    DivisionByZero { address: u16 },
    StackOverflow,
    StackUnderflow,
    InvalidOpcode { opcode: u8 },
    InvalidRegister { register: u8 },
    BreakpointHit { address: u16 },
    IoError { message: String },
}

Key Methods

impl MachineW {
    pub fn new() -> Self;
    pub fn reset(&mut self);
    pub fn load_program(&mut self, program: &[u16]) -> Result<(), MachineError>;
    pub fn run(&mut self) -> Result<(), MachineError>;
    pub fn step(&mut self) -> Result<(), MachineError>;
    pub fn step_instruction(&mut self) -> Result<(), MachineError>;
    
    // Memory operations
    pub fn read_memory(&self, address: u16) -> Result<u16, MachineError>;
    pub fn write_memory(&mut self, address: u16, value: u16) -> Result<(), MachineError>;
    
    // I/O operations  
    pub fn set_input_buffer(&mut self, inputs: Vec<u16>);
    pub fn get_output_buffer(&self) -> &[u16];
    pub fn set_interactive_mode(&mut self, enabled: bool);
    
    // Debugging
    pub fn add_breakpoint(&mut self, address: u16) -> Result<(), MachineError>;
    pub fn remove_breakpoint(&mut self, address: u16) -> bool;
    pub fn get_current_state(&self) -> MachineWState;
}

🔗 Related Components

  • Hephasm - Assembler that generates machine code for Asmachina
  • Dismael - Disassembler that converts machine code back to assembly
  • Shared - Common types and utilities used by Asmachina

📜 License

This crate is part of the Asmodeus project and is licensed under the MIT License.


Asmachina - Where Machine W Lives Again 🚀

Commit count: 0

cargo fmt