Skip to content

Commit

Permalink
Merge pull request #5 from craigthomas/add-unit-tests
Browse files Browse the repository at this point in the history
Refactor assembler for Python 3.6
  • Loading branch information
craigthomas authored Oct 10, 2019
2 parents ec75cb9 + 9c4183f commit 67c38cd
Show file tree
Hide file tree
Showing 14 changed files with 1,084 additions and 548 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pyc
.idea
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: python
sudo: false
python:
- 3.6
addons:
apt:
packages:
- python-dev
virtalenv:
system_site_packages: true
script:
- coverage run -m nose
after_success:
- bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
115 changes: 66 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# (Super) Chip 8 Assembler

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://img.shields.io/travis/craigthomas/Chip8Assembler?style=flat-square)](https://travis-ci.org/craigthomas/Chip8Assembler)
[![Codecov](https://img.shields.io/codecov/c/gh/craigthomas/Chip8Assembler?style=flat-square)](https://codecov.io/gh/craigthomas/Chip8Assembler)
[![Codacy Badge](https://img.shields.io/codacy/grade/f100b6deb9bf4729a2c55ef12fb695c9?style=flat-square)](https://www.codacy.com/app/craig-thomas/Chip8Assembler?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=craigthomas/Chip8Python&amp;utm_campaign=Badge_Grade)
[![Dependencies](https://img.shields.io/librariesio/github/craigthomas/Chip8Assembler?style=flat-square)](https://libraries.io/github/craigthomas/Chip8Assembler)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://opensource.org/licenses/MIT)

## Table of Contents

1. [What is it?](#what-is-it)
2. [Requirements](#requirements)
3. [Installation](#installation)
4. [Usage](#usage)
1. [Print Symbol Table](#print-symbol-table)
2. [Print Assembled Statements](#print-assembled-statements)
3. [Input Format](#input-format)
1. [Input Format](#input-format)
2. [Print Symbol Table](#print-symbol-table)
3. [Print Assembled Statements](#print-assembled-statements)
5. [Mnemonic Table](#mnemonic-table)
1. [Chip 8 Mnemonics](#chip-8-mnemonics)
2. [Super Chip 8 Mnemonics](#super-chip-8-mnemonics)
Expand All @@ -21,70 +25,40 @@

## What is it?

This project is a (Super) Chip 8 assembler written in Python 2.7. The assembler will
This project is a (Super) Chip 8 assembler written in Python 3.6. The assembler will
take valid Super Chip 8 assembly statements and generate a binary file containing
the correct machine instructions.


## Requirements

The only requirements for this project is:

* [Python 2.7](http://www.python.org)
In order to run the assembler, you will need to use Python 3.6 or greater. If you wish
to clone the repository for development, you will need Git.


## Installation

To install the source files, simply clone the repository in the directory
of your choice:
To install the source files, download the latest release from the
[releases](https://github.com/craigthomas/Chip8Assembler/releases) section of
the repository and unzip the contents in a directory of your choice. Or,
clone the repository in the directory of your choice with:

git clone https://github.com/craigthomas/Chip8Assembler.git

Next, you will need to install the required packages for the file:

pip install -r requirements.txt


## Usage

To run the assembler:

python chip8asm/chip8asm.py input_file -o output_file
python assembler.py input_file --output output_file

This will assemble the instructions found in file `input_file` and will generate
the associated Chip 8 machine instructions in binary format in `output_file`.

### Print Symbol Table

To print the symbol table that is generated during assembly, use the `-s` switch:

python chip8asm/chip8asm.py test.asm -s

Which will have the following output:

-- Symbol Table --
start 0x200
data1 0x209
data 0x208

### Print Assembled Statements

To print out the assembled version of the program, use the `-p` switch:

python chip8asm/chip8asm.py test.asm -p

Which will have the following output:

-- Assembled Statements --
0x0200 6100 start LOAD r1,$0 # Clear contents of register 1
0x0202 7101 ADD r1,$1 # Add 1 to the register
0x0204 310A SKE r1,$A # Check to see if we are at 10
0x0206 1200 JUMP start # Jump back to the start
0x0208 1208 end JUMP end # Loop forever

With this output, the first column is the offset in hex where the statement starts,
the second column contains the full machine-code operand, the third column is the
user-supplied label for the statement, the forth column is the mnemonic, the fifth
column is the register values of other numeric or label data the operation will
work on, and the fifth column is the comment string.


### Input Format

The input file needs to follow the format below:
Expand All @@ -94,9 +68,9 @@ The input file needs to follow the format below:
Where:

* `LABEL` is a 15 character label for the statement
* `MNEMONIC` is a Chip 8 operation mnemonic from the table below
* `OPERANDS` are registers, values or labels, as described in detail below
* `COMMENT` is a 30 character comment describing the statement
* `MNEMONIC` is a Chip 8 operation mnemonic from the [Mnemonic Table](#mnemonic-table) below
* `OPERANDS` are registers, values or labels, as described in the [Operands](#operands) section
* `COMMENT` is a 30 character comment describing the statement (may have a `#` preceding it)

An example file:

Expand All @@ -111,6 +85,49 @@ An example file:
data1 FDB $FBEE Two byte piece of data


### Print Symbol Table

To print the symbol table that is generated during assembly, use the `--symbols`
switch:

python assembler.py test.asm --symbols

Which will have the following output:

-- Symbol Table --
0x0200 clear
0x0202 start
0x020A end
0x020C data
0x020E data1


### Print Assembled Statements

To print out the assembled version of the program, use the `--print` switch:

python assembler.py test.asm --print

Which will have the following output:

-- Assembled Statements --
0x0200 0000 # A comment line that contains nothing
0x0200 00E0 clear CLR #
0x0202 6100 start LOAD r1,$0 # Clear contents of register 1
0x0204 7101 ADD r1,$1 # Add 1 to the register
0x0206 310A SKE r1,$A # Check to see if we are at 10
0x0208 1202 JUMP start # Jump back to the start
0x020A 120A end JUMP end # Loop forever
0x020C 001A data FCB $1A # One byte piece of data
0x020E FBEE data1 FDB $FBEE # Two byte piece of data

With this output, the first column is the offset in hex where the statement starts,
the second column contains the full machine-code operand, the third column is the
user-supplied label for the statement, the forth column is the mnemonic, the fifth
column is the register values of other numeric or label data the operation will
work on, and the fifth column is the comment string.


## Mnemonic Table

The assembler supports mnemonics for both the Chip 8 and Super Chip 8 language
Expand Down
67 changes: 67 additions & 0 deletions assembler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
Copyright (C) 2014-2018 Craig Thomas
This project uses an MIT style license - see LICENSE for details.
A Chip 8 assembler - see the README.md file for details.
"""
# I M P O R T S ###############################################################

import argparse

from chip8asm.program import Program

# F U N C T I O N S ###########################################################


def parse_arguments():
"""
Parses the command-line arguments passed to the assembler.
"""
parser = argparse.ArgumentParser(
description="Assemble or disassemble "
"machine language code for the Chip8. See README.md for more "
"information, and LICENSE for terms of use."
)
parser.add_argument("filename", help="the name of the file to examine")
parser.add_argument(
"--symbols", action="store_true", help="print out the symbol table"
)
parser.add_argument(
"--print", action="store_true",
help="print out the assembled statements when finished"
)
parser.add_argument(
"--output", metavar="FILE", help="stores the assembled program in FILE")
return parser.parse_args()


def main(args):
"""
Runs the assembler with the specified arguments.
@param args: the arguments to the main function
@type: namedtuple
"""
program = Program()
program.parse_file(args.filename)
program.translate_statements()
program.set_addresses()
program.fix_opcodes()

if args.symbols:
print("-- Symbol Table --")
for symbol, value in program.get_symbol_table().items():
print("0x{} {}".format(value[2:].rjust(4, '0').upper(), symbol))

if args.print:
print("-- Assembled Statements --")
for statement in program.get_statements():
print(statement)

if args.output:
program.save_binary_file(args.output)


main(parse_arguments())

# E N D O F F I L E #######################################################
Loading

0 comments on commit 67c38cd

Please sign in to comment.