diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5b2d0a2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,159 @@
+### rivet - Register / Instruction Visualizer and Explainer Tool
+
+---
+
+## Introduction
+
+This tool lets you generate visual explanations of binary instructions, or describe the contents of a register.
+
+The layout and style can be customized to fit your needs.
+
+For a full description of the schema format, please check out [format.md](format.md)
+
+## Requirements
+
+- [Python 3+](https://www.python.org/)
+- [Pygame](https://pypi.org/project/pygame/) - used to render the images
+- [Beautiful Soup 4](https://pypi.org/project/beautifulsoup4/) - used to parse XML files
+- [PyYAML](https://pypi.org/project/PyYAML/) - used to parse YAML files
+
+## Usage
+
+Basic usage:
+```bash
+python3 main.py schema.xml
+```
+
+Directory mode + config:
+```bash
+python3 main.py -o out/ -c config.json -d schemas/
+```
+
+## Options
+
+Several command line options are available:
+- `-o PATH` sets the output path. If not given, the output file will be located in the same directory as the input file, and given the same name (different extension)
+- `-d` enables directory mode. If set, the input and output paths are directories and all files inside the input directory are processed
+- `-c PATH` sets the config path. For more details on available config parameters, please read the [Config section](#config).
+
+## Examples
+
+The following images were generated from this schema ([example1.yaml](example1.yaml)):
+
+
+Show / hide
+
+```yaml
+structures:
+ main:
+ bits: 32
+ ranges:
+ 31-28:
+ name: cond
+ 27:
+ name: 0
+ 26:
+ name: 1
+ 25:
+ name: I
+ 24:
+ name: P
+ description: pre / post indexing bit
+ values:
+ 0: post, add offset after transfer
+ 1: pre, add offset before transfer
+ 23:
+ name: U
+ description: up / down bit
+ values:
+ 0: down, subtract offset from base
+ 1: up, addition offset to base
+ 22:
+ name: B
+ description: byte / word bit
+ values:
+ 0: transfer word quantity
+ 1: transfer byte quantity
+ 21:
+ name: W
+ description: write-back bit
+ values:
+ 0: no write-back
+ 1: write address into base
+ 20:
+ name: L
+ description: load / store bit
+ values:
+ 0: store to memory
+ 1: load from memory
+ 19-16:
+ name: Rn
+ description: base register
+ 15-12:
+ name: Rd
+ description: source / destination register
+ 11-0:
+ name: offset
+ depends-on: 25
+ values:
+ 0:
+ description: offset is an immediate value
+ structure: immediateOffset
+ 1:
+ description: offset is a register
+ structure: registerOffset
+ immediateOffset:
+ bits: 12
+ ranges:
+ 11-0:
+ name: 12-bit immediate offset
+ description: unsigned number
+ registerOffset:
+ bits: 12
+ ranges:
+ 11-4:
+ name: shift
+ description: shift applied to Rm
+ 3-0:
+ name: Rm
+ description: offset register
+```
+
+
+#### config.json
+![default black on white](example_normal.png)
+
+#### dark.json
+![white on black](example_dark.png)
+
+#### blueprint.json
+![white on blue](example_blueprint.png)
+
+#### transparent.json
+![grey on transparent](example_transparent.png)
+
+## Config
+
+The config file may change the following values to customize the layout and style:
+- `defaultFontFamily`: the default font family
+- `defaultFontSize`: the default font size
+- `italicFontFamily`: the italic font family (for value description)
+- `italicFontSize`: the italic font size
+- `backgroundColor`: the image background color (ex: [222, 250, 206])
+- `textColor`: the default text color
+- `linkColor`: the color of linking lines and arrows
+- `borderColor`: the color of register borders
+- `bitWidth`: the width of 1 bit (in pixels)
+- `bitHeight`: the height of 1 bit (in pixels)
+- `descriptionMargin`: the space between descriptions (in pixels)
+- `dashLength`: the length of one dash (for dashed lines)
+- `dashSpace`: the space between dashes (for dashed lines)
+- `arrowSize`: the arrow size (height in pixels, width for horizontal arrow)
+- `margins`: the margins from the borders of the image (in pixels, [top, right, bottom, left])
+- `arrowMargin`: the margin between arrows and registers (in pixels)
+- `valuesGap`: the gap between values (in pixels)
+- `arrowLabelDistance`: the distance between arrows and their label (in pixels)
+- `forceDescsOnSide`: if true, descriptions are placed on the side of the register, otherwise, they are placed as close as possible to the bit
+- `leftLabels`: if true, descriptions are put on the left, otherwise, they default to the right hand side
+- `width`: the image width (in pixels)
+- `height`: the image height (in pixels)
\ No newline at end of file
diff --git a/example_blueprint.png b/example_blueprint.png
new file mode 100644
index 0000000..f891d40
Binary files /dev/null and b/example_blueprint.png differ
diff --git a/example_dark.png b/example_dark.png
new file mode 100644
index 0000000..5723dd4
Binary files /dev/null and b/example_dark.png differ
diff --git a/example_normal.png b/example_normal.png
new file mode 100644
index 0000000..f098a12
Binary files /dev/null and b/example_normal.png differ
diff --git a/example_transparent.png b/example_transparent.png
new file mode 100644
index 0000000..cd6e405
Binary files /dev/null and b/example_transparent.png differ
diff --git a/format.md b/format.md
new file mode 100644
index 0000000..06f0d66
--- /dev/null
+++ b/format.md
@@ -0,0 +1,125 @@
+# Schema Format
+
+_**Supported syntaxes: JSON, XML, YAML**_
+
+The following description uses the JSON syntax
+
+For examples in different formats, see [example1.yaml](example1.yaml), [example2.yaml](example2.yaml), [example3.json](example3.json) and [example4.xml](example4.xml).
+
+## Main layout
+
+A schema contains a dictionary of structures. There must be at least one defined structure named "main"
+```json
+{
+ "structures": {
+ "main": {
+ ...
+ },
+ "struct1": {
+ ...
+ },
+ "struct2": {
+ ...
+ },
+ ...
+ }
+}
+```
+
+## Structure
+
+A structure has a given number of bits and one or multiple ranges. Each range of bits can have a name, a description and / or values with special meaning (see [Range](#range)). A range's structure can also depend on another range's value (see [Dependencies](#dependencies))
+
+The range name (or key) defines the left- and rightmost bits (e.g. 7-4 goes from bit 7 to bit 4). Bits are displayed in big-endian, i.e. the leftmost bit has the highest value.
+```json
+"main": {
+ "bits": 8,
+ "ranges": {
+ "7-4": {
+ ...
+ },
+ "3-2": {
+ ...
+ },
+ "1": {
+ ...
+ },
+ "0": {
+ ...
+ }
+ }
+}
+```
+
+## Range
+
+A range represents a group of consecutive bits. It can have a name (display in the bit cells), a description (displayed under the structure) and / or values.
+
+For values depending on other ranges, see [Dependencies](#dependencies).
+
+> **Note**
+> In YAML, make sure to wrap values in quotes because some values can be interpreted as octal notation (e.g. 010)
+
+```json
+"3-2": {
+ "name": "op",
+ "description": "Logical operation",
+ "values": {
+ "00": "AND",
+ "01": "OR",
+ "10": "XOR",
+ "11": "NAND"
+ }
+}
+```
+
+## Dependencies
+
+The structure of one range may depend on the value of another. To represent this situation, first indicate on the child range the range on which it depends:
+
+```json
+"7-4": {
+ ...
+ "depends-on": "0"
+}
+```
+
+Then, in its values, indicate which structure to use. A description can also be added (displayed above the horizontal dependency arrow)
+
+```json
+"7-4": {
+ ...
+ "depends-on": "0",
+ "values": {
+ "0": {
+ "description": "immediate value",
+ "structure": "immediateValue"
+ },
+ "1": {
+ "description": "value in register",
+ "structure": "registerValue"
+ }
+ }
+}
+```
+
+Finally, add the sub-structures to the structure dictionary:
+
+```json
+{
+ "structures": {
+ "main": {
+ ...
+ },
+ "immediateValue": {
+ "bits": 4,
+ ...
+ },
+ "registerValue": {
+ "bits": 4,
+ ...
+ },
+ ...
+ }
+}
+```
\ No newline at end of file