A suite of tools for the Simplified Instructional Computer (SIC/XE), written in modern C++. This project currently features a functional disassembler and a linker.
- SIC/XE Disassembler: Translates SIC/XE object code from an object file back into human-readable assembly source code.
- SIC/XE Linker: Links multiple object files into a single loadable memory image.
- Opcode-based Parsing: Utilizes an external opcode definition file (
res/opcodes.txt) for easy modification and extension. - Cross-Platform Core: Written in standard C++ with platform-specific code isolated.
- Built-in Logger: A powerful and configurable logger for debugging and tracing program execution.
Follow these instructions to get a copy of the project up and running on your local machine.
- A C++ compiler that supports at least C++17. The project is built and tested with Clang++.
- Windows: The provided
build.batscript is designed for a Windows environment. - Linux/macOS: You can compile the project manually using the
clang++command found in the build script.
-
Clone the repository:
git clone <your-repository-url> cd <repository-folder>
-
Run the build script:
- On Windows:
.\build.bat
- On Linux/macOS:
You can adapt the command from the build script.
clang++ src/**/*.cpp -std=c++17 -I./src/ -o ./bin/ysicxe
The executable
ysicxe.exe(orysicxeon non-Windows systems) will be created in thebindirectory. - On Windows:
The program is run from the command line. The first argument is the command you want to execute (dasm or link), followed by the command's arguments.
./bin/ysicxe <command> [args...]Disassembles a SIC/XE object file into assembly source code.
Usage:
./bin/ysicxe dasm <file> [args...]Arguments:
| Flag(s) | Description | Required | Default |
|---|---|---|---|
-i, --input |
Path to the input object file (.obj). |
Yes | |
-o, --output |
Path to the output source file (.asm). |
No | out.asm |
-s, --symtab |
Path to an external symbol table for label resolution. | No |
Example:
./bin/ysicxe dasm -i test/testxy.obj -o test/testxy.asm -s test/testxy_symtab.txtLinks multiple SIC/XE object files into a single executable memory image.
Usage:
./bin/ysicxe link [args...]Arguments:
| Flag(s) | Description | Required | Default |
|---|---|---|---|
-i, --inputs |
Comma-separated list of input object files. | Yes | |
-o, --output |
Path to the output executable/memory-dump file. | No | a.out |
-a, --addr |
Starting load address in hexadecimal. | No | 0 |
-e, --export-estab |
Export the global symbol table (ESTAB) to a file. | No |
Example:
./bin/ysicxe link -i test/prog1.obj,test/prog2.obj -o test/linked.exe -a 4000├── bin/ # Compiled binaries
├── res/ # Data files (e.g., opcodes.txt)
├── obj/ # Intermediate object files (.o)
├── src/ # C++ source code
│ ├── cmd/ # Command line parsing and handlers
│ ├── core/ # Core modules (logger, defines, error handling)
│ ├── dasm/ # Disassembler implementation
│ ├── linker/ # Linker implementation
│ ├── util/ # Utility helpers
│ └── main.cpp # Main application entry point
├── test/ # Test files
├── .gitignore
├── build.bat # Windows build script
└── README.md
The disassembler operates by reading a SIC/XE object file, which consists of Header (H), Text (T), and End (E) records.
- Load Opcodes: The program first loads the instruction mnemonics, opcodes, and formats from
res/opcodes.txtinto an in-memory table for quick lookups. - Parse Header Record: It reads the
Hrecord to determine the program name and its starting address. - Process Text Records: For each
Trecord, it iterates through the object code byte by byte. - Instruction Lookup: It identifies the opcode for an instruction. The two least significant bits are masked off to handle format 4 instructions correctly.
- Decode and Reconstruct: Based on the instruction's format (1, 2, 3, or 4), it decodes the operands and addressing modes. It then reconstructs the corresponding assembly language instruction.
- Symbol Resolution: If a symbol table is provided, the disassembler will use it to resolve addresses into labels, making the output more readable.
- Generate Assembly: The reconstructed assembly lines, along with labels, directives (
START,END,RESW,RESB,BYTE,WORD), are written to the specified output file.
The linker performs a two-pass process to resolve external references between different object files and create a single, loadable program.
-
Pass 1:
- Process Control Sections: The linker processes each control section from the input object files.
- Build ESTAB: It builds an External Symbol Table (ESTAB), which stores the names and addresses of all external symbols (defined in
Drecords). - Assign Addresses: It assigns a starting address to each control section and calculates the length of the linked program.
-
Pass 2:
- Generate Object Code: The linker generates the final object code by processing the
Trecords of each control section. - Resolve External References: It uses the ESTAB built in Pass 1 to resolve external references (found in
Mrecords). It modifies the object code at the specified locations to insert the correct addresses. - Write Executable: The final, linked object code is written to the output file, which can then be loaded into memory for execution.
- Generate Object Code: The linker generates the final object code by processing the
Contributions are welcome! If you'd like to contribute, please follow these steps:
- Fork the repository.
- Create a new branch (
git checkout -b feature/YourFeature). - Commit your changes (
git commit -m 'Add some feature'). - Push to the branch (
git push origin feature/YourFeature). - Open a Pull Request.
This project is open-source and under the MIT License, learn more by reading the LICENSE file.