The "Little Man Computer" (LMC) is a very basic model of a van Neumann computer, made for education purpose. The LMC as a concept was originally created by Dr. Stuart Madnick at MIT in 1965.
My goal when working on my LMC simulator was to practice creating a little grammar based parser (using lark), to make a model of the fetch/decode/execute cycle of a CPU and to implement some fundamental CPU operations.
My LMC simulator follows the LMC definition of the Marquette University, Milwaukee, Wisconsin, USA, but with the Mnemonics as reported by Wikipedia, and not the Marquette LMC mnemonics. I also did not implement Marquette's "store address". Therefore, opcode 4 remains as "reserved".
My implementation of the LMC simulator stays decimal, but does only allow positive numbers for addresses, RAM cells and register values. My ALU simulation uses ten's complement addition. It folds back overflows into the including number ranges (0, 99) for addresses and (0, 999) for memory and register values.
LMC simulator's registers
| Name | Meaning | Remark |
|---|---|---|
| ACC | Accumulator | Changed by operations INP, LDA, ADD, SUB, and changes do affect the CPU flags |
| PC | Program Counter | Incremented by a fetch, always points to the next instruction to be executed. Set to a new value by BRA, BRP or BRZ |
| CIR | Current Instruction Register | Always holds the instruction to be executed after a fetch and decode |
| MAR | Memory Address Register | The RAM address involved in the next memory read or write |
| MDR | Memory Data Register | The value to be written to the memory cell referenced by MAR, or the value most recently read from memory |
| Z-Flag | Zero Flag | Set if the ACC is zero, else reset |
| P-Flag | Positive Flag | Set if the ACC has a value greater or equal 500, reset if 0 <= ACC < 500 |
The LMC instructions support direct addressing (ADD, SUB, LDA, STA, BRA, BRP, BRZ) and implicit addressing (INP, OUT, HLT). Indirect addressing is not supported on CPU level.
- ADD works like ACC = (ACC + MDR) mod 1000.
- SUB works like ACC = (ACC + 1000 - MDR) mod 1000
The Z and P flags are adjusted after any opration affecting ACC.
- The simulator core functions are in the source file vm.py.
- There is an assembler that translates LMC source files (.a) into LMC machine code that can directly be loaded into the simulator core.
- The assembler is based on Lark. It provides support for symbolic memory locations and for the DAT directive. It does support an ORG directive to allow easy location of the code and data inside the LMC's RAM.
- An LMC launcher allows to assemble and run programs.
- The launcher is based on Typer. It has a run mode and an interactive mode.
Try
python lmc.py --helpto see a usage information. The interactive mode ("trace mode") uses Textual to create the Terminal User Interface (TUI). The "run mode" uses Rich.
Example programs for the LMC are given in the examples directory.
- Python 14.x
- Rich
- Textual
- Lark
- Typer