LCC.js is a JavaScript-based assembler and interpreter for a simple 16-bit virtual machine architecture. Inspired by educational projects like the Low-Cost Computer (LCC), it provides a platform for learning assembly language programming and understanding how high-level code translates to machine operations.
Building on LCC.js, LCC+js introduces an extended assembly instruction set and real-time execution features for more interactive, game-oriented applications. This extension adds new instructions (e.g., for non-blocking input, screen manipulation, and timed delays) and separate .ap
/ .ep
file formats, making it possible to write assembly-based terminal games or simulations.
- Features
- Getting Started
- Usage
- Understanding the Components
- Testing
- Architecture Details
- Contributing
- License
- Contact
- Educational Focus: Ideal for learning the basics of assembly language and virtual machine architectures.
- Cross-Platform: Runs anywhere Node.js is available.
- Modular Design: Separate components for assembling, linking, interpreting, plus extended “plus” modules for advanced use.
- Real-Time Extensions (LCC+js): Non-blocking input, screen clearing, timed delays, and other game-oriented features.
- Extensible: Straightforward to add new instructions or behaviors.
- Node.js: Download and install from nodejs.org.
Clone the repository:
git clone git@github.com:avidrucker/lccjs.git
cd lccjs
Setup aliases on UNIX systems:
chmod u+x alias.sh
./alias.sh
source ~/.bashrc
For a standard .a
assembly file:
node ./src/core/lcc.js path/to/yourfile.a
- lcc.js automatically detects file type, assembles the source, and interprets the resulting
.e
executable.
-
Assemble a
.a
file:node ./src/core/assembler.js path/to/yourfile.a
This generates a
.e
or.o
file (depending on directives) in the same folder. -
Interpret the produced executable:
node ./src/core/interpreter.js path/to/yourfile.e
For LCC+js features (non-blocking input, screen manipulation, real-time instructions, etc.):
- AssemblerPlus processes
.ap
files, generating.ep
executables:node ./src/plus/assemblerplus.js path/to/yourfile.ap
- InterpreterPlus runs the resulting
.ep
:node ./src/plus/interpreterplus.js path/to/yourfile.ep
- LccPlus (combined) for one-step assembly and execution:
node ./src/plus/lccplus.js path/to/yourfile.ap
These tools introduce extended instructions like clear
, sleep
, nbain
, and more. See Instruction Set (LCC.js & LCC+js) for details.
- Purpose: A high-level command-line tool that orchestrates assembly, linking, and execution.
- Functionality:
- Automatically detects file types (
.a
or.o
, etc.). - Assembles
.a
files, interprets.e
files. - Provides a simple CLI for a one-step workflow.
- Automatically detects file types (
- Purpose: Translates
.a
assembly code into machine code (.e or .o). - Key Features:
- Two-Pass Assembly: Builds symbol table (pass 1) and generates code (pass 2).
- Symbol Table and Directives: Handles labels,
.start
,.globl
,.word
, etc. - Error Reporting: Provides errors and warnings if assembly issues occur.
- Purpose: Executes
.e
machine code on a simulated 16-bit virtual machine. - Key Features:
- Registers & Memory: Manages an 8-register set and 65,536 words of memory.
- Instruction Decoding: Implements the standard LCC.js instruction set (arithmetic, logic, control flow, I/O via TRAP).
- Execution Cap: Defaults to 500,000 instructions to prevent infinite loops.
- Purpose: Combines multiple object files (
.o
) into a single executable (.e
). - Key Features:
- Symbol Resolution: Merges global and external symbols.
- Adjusts Addresses: Ensures references and offsets are correct in the final combined output.
- Purpose: Extend LCC.js for real-time, interactive applications (games, demos).
- New Instructions:
clear
,sleep
,nbain
,cursor
,srand
,rand
,millis
,resetc
, etc.- Allows partial screen clearing, non-blocking input, timed delays, etc.
- File Extensions:
.ap
→ AssemblerPlus →.ep
.ep
→ InterpreterPlus → runs advanced instructions in real time.
- Non-Blocking Execution: The interpreter uses an event loop for continuous stepping and immediate keystroke handling.
disassembler.js
: Takes an.e
file and disassembles machine code back to a textual instruction representation—useful for debugging.linkerStepsPrinter.js
: Outputs the step-by-step linking process to help visualize how symbols and references are resolved.
core/
: Contains primary modules for LCC.js (assembler.js, interpreter.js, etc.).utils/
: Utility scripts for generating listings/statistics, name handling, and other shared functionality.plus/
: Modules for LCC+js (assemblerplus.js, interpreterplus.js, lccplus.js) adding extended features.test/
: Houses all test files—both integration tests and end-to-end (e2e).extra/
: Holds additional tools likedisassembler.js
andlinkerStepsPrinter.js
.
Extensive end-to-end (e2e) and integration tests have been implemented for assembler.js, linker.js, interpreter.js, and lcc.js—covering a wide range of functionality. Further edge cases can always be added to improve coverage.
Run all tests:
npm test
Note: If you encounter issues with
jest
not being found, you may need to install it globally:npm install -g jest
.
Run a specific test file:
npx jest test/integration/assembler.integration.test.js
While there are still opportunities for additional test cases (especially unit tests), the current suite provides strong coverage across the main features.
- Registers: 8 (r0–r7), with special roles for
sp
(r6),fp
(r5), andlr
(r7). - Memory: 65,536 words (16-bit each).
LCC.js includes:
- Arithmetic:
ADD
,SUB
,MUL
,DIV
,REM
- Logical:
AND
,OR
,XOR
,NOT
- Data Movement:
MOV
,LD
,ST
,LEA
,LDR
,STR
,PUSH
,POP
- Control Flow:
BR
(brz
,brn
, etc.),JMP
,JSR
,RET
,BL
,BLR
- I/O (TRAP):
AOUT
,DOUT
,HOUT
,SOUT
,AIN
,DIN
,HIN
,SIN
, etc.
LCC+js introduces extended instructions (via assemblerplus.js & interpreterplus.js):
- Non-Blocking Input:
nbain
- Screen Clearing:
clear
, partial reset withresetc
- Timed Delay:
sleep
- Cursor Control:
cursor
(hide/show) - Randomness:
srand
,rand
(seed-based random generation) - Milliseconds:
millis
(retrieve current time mod 1000)
- Debugging Tools: Symbolic debugger or additional introspection features.
- More LCC+js Demos: Additional example programs showing real-time features.
- Edge-Case Test Coverage: Adding more specialized test scenarios to further solidify reliability.
- Performance Optimization: Improving execution speed and memory usage.
- Documentation: Continually refining and expanding docs.
- Fork the repository.
- Create a branch for your feature or fix.
- Submit a Pull Request with a clear explanation of changes.
This project is open-source under the MIT License.
For questions or feedback, please open an issue or submit a pull request.