diff --git a/drafts/church-encoding-in-javascript.markdown b/drafts/church-encoding-in-javascript.markdown
index beadd8c..9ac3e69 100644
--- a/drafts/church-encoding-in-javascript.markdown
+++ b/drafts/church-encoding-in-javascript.markdown
@@ -11,3 +11,389 @@ TODO
TODO
+
+``` {.javascript .code-term .numberLines}
+/**
+ * (C) Copyright Collin J. Doering 2015
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+/**
+ * File: church.js
+ * Author: Collin J. Doering
+ * Date: Feb 2, 2015
+ */
+
+var church = (function () {
+ var spec,
+ t = function (x) {
+ var ret = function (y) {
+ return x;
+ };
+ return ret;
+ },
+ f = function (x) {
+ var ret = function (y) {
+ return y;
+ };
+ return ret;
+ },
+ church_zero = function (f) {
+ var ret = function (x) {
+ return x;
+ };
+ return ret;
+ },
+ nil;
+
+ // ------------------------------
+ // Church Boolean implementation
+ // ------------------------------
+
+ function make_bool (b) {
+ // b ? return t : return f
+ if (b) {
+ return t;
+ } else {
+ return f;
+ }
+ }
+
+ function unchurch_bool (b) {
+ return b(true)(false);
+ }
+
+ function and (x) {
+ var ret = function (y) {
+ return x(y)(x);
+ };
+ return ret;
+ }
+
+ function or (x) {
+ var ret = function (y) {
+ return x(x)(y);
+ };
+ return ret;
+ }
+
+ function not (x) {
+ var ret = function (y) {
+ var aret = function (z) {
+ return x(z)(y);
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function xor (x) {
+ var ret = function (y) {
+ return x(not(y))(y);
+ };
+ return ret;
+ }
+
+ function church_if (p) {
+ var ret = function (a) {
+ var aret = function (b) {
+ return p(a)(b);
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ // -----------------------
+ // Church natural numbers
+ // -----------------------
+
+ function succ (n) {
+ var ret = function (f) {
+ var aret = function (x) {
+ return f(n(f)(x));
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function add (n) {
+ var ret = function (m) {
+ var aret = function (f) {
+ var bret = function (x) {
+ return n(f)(m(f)(x));
+ };
+ return bret;
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function mult (n) {
+ var ret = function (m) {
+ var aret = function (f) {
+ var bret = function (x) {
+ return n(m(f))(x);
+ };
+ return bret;
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function expt (n) {
+ var ret = function (m) {
+ var aret = function (f) {
+ var bret = function (x) {
+ return (m(n))(f)(x);
+ };
+ return bret;
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function isZero (n) {
+ var ret = n(function (x) {
+ return f;
+ })(t);
+ return ret;
+ }
+
+ function make_nat (n) {
+ var i, ret = church_zero.bind({});
+ for (i = 0; i < n; i += 1) {
+ ret = succ(ret);
+ }
+ return ret;
+ }
+
+ function unchurch_nat (n) {
+ var ret = function (i) {
+ var aret = function (m) {
+ i += 1;
+ return i;
+ };
+ return aret;
+ }, i = 0;
+ return n(ret(i))(0);
+ }
+
+ // -------------
+ // Church Pairs
+ // -------------
+
+ function make_pair (a) {
+ var ret = function (b) {
+ var aret = function (f) {
+ return f(a)(b);
+ };
+ return aret;
+ };
+ return ret;
+ }
+
+ function fst (p) {
+ return p(t);
+ }
+
+ function snd (p) {
+ return p(f);
+ }
+
+ function unchurch_pair (p) {
+ return [fst(p), snd(p)];
+ }
+
+ // -------------
+ // Church Lists
+ // -------------
+
+ function make_list () {}
+
+ function unchurch_list (xs) {}
+
+ nil = make_pair(t)(t);
+ isNil = fst;
+
+ function cons (h) {
+ var ret = function (t) {
+ return make_pair(f)(make_pair(h)(t));
+ };
+ return ret;
+ }
+
+ function head (l) {
+ return fst(snd(l));
+ }
+
+ function tail (l) {
+ return snd(snd(l));
+ }
+
+ // -----------------
+ // The Y Combinator
+ // -----------------
+ // * This doesn't work as javascript is strictly evaluated
+ // -----------------
+
+ function fix (g) {
+ var f = function (x) {
+ return g(x(x));
+ };
+ return f(f);
+ }
+
+ // Setup specification object
+ spec = {
+ "if": church_if,
+ fix: fix,
+ bool: {
+ make: make_bool,
+ toNative: unchurch_bool,
+ t: t,
+ f: f,
+ not: not,
+ and: and,
+ or: or,
+ xor: xor
+ },
+ nat: {
+ make: make_nat,
+ toNative: unchurch_nat,
+ zero: church_zero,
+ succ: succ,
+ add: add,
+ mult: mult,
+ expt: expt,
+ isZero: isZero
+ },
+ pair: {
+ make: make_pair,
+ toNative: unchurch_pair,
+ fst: fst,
+ snd: snd
+ },
+ list: {
+ make: make_list,
+ toNative: unchurch_list,
+ nil: nil,
+ isNil: isNil,
+ cons: cons,
+ head: head,
+ tail: tail
+ }
+ };
+ return spec;
+})();
+
+// -------------------------
+
+function unchurch_church_nat_test (lim) {
+ var i,
+ lim = lim || 12;
+ for (i = 0; i <= lim; i += 1) {
+ if (i !== church.nat.toNative(church.nat.make(i))) {
+ console.log('Failed church.nat.toNative(church.nat.make(' + i + '))');
+ return false;
+ }
+ }
+ console.log('Created church nats from 1 to ' + lim + ' successfully.');
+ return true;
+}
+
+function uncurry (f) {
+ var ret = function (x, y) {
+ return f(x)(y);
+ };
+ return ret;
+}
+
+function matrix_test (f, g, n, tp) {
+ var i, j,
+ t = tp || 100,
+ name = n || "unnamed";
+ for (i = 0; i <= t; i += 1) {
+ for (j = 0; j <= t; j += 1) {
+ if (f(i,j) !== g(i,j)) {
+ console.log('Failed matrix test for ' + name + ' with inputs ' + i + ' and ' + j + '.');
+ return false;
+ }
+ }
+ }
+ console.log('Successfully completed test for ' + name + '.');
+ return true;
+}
+
+unchurch_church_nat_test(100);
+
+matrix_test(function (a, b) {
+ return a + b;
+}, function (a, b) {
+ return church.nat.toNative(church.nat.add(church.nat.make(a))(church.nat.make(b)));
+}, "Church addition");
+
+// matrix_test(function (a, b) {
+// return a - b;
+// }, function (a, b) {
+// return church.nat.toNative(minus(church.nat.make(a))(church.nat.make(b)));
+// });
+
+matrix_test(function (a, b) {
+ return a * b;
+}, function (a, b) {
+ return church.nat.toNative(church.nat.mult(church.nat.make(a))(church.nat.make(b)));
+}, "Church multiplication");
+
+// very slow for some reason? (not that this implementation will ever be fast)
+matrix_test(function (a, b) {
+ return Math.pow(a, b);
+}, function (a, b) {
+ return church.nat.toNative(church.nat.expt(church.nat.make(a))(church.nat.make(b)));
+}, "Church exponentiation", 7);
+
+
+// -------------------------------------------------------
+// Factorial function written similar to how the y-combinator works
+function factorial (x) {
+ var g = function (h) {
+ var f = function (n) {
+ if (n < 2) {
+ return 1;
+ } else {
+ return n * h(h)(n - 1);
+ }
+ };
+ return f;
+ };
+ return g(g)(x);
+}
+
+var i;
+for (i = 0; i < 10; i += 1) {
+ console.log(factorial(i));
+}
+```
+
+
diff --git a/drafts/computer-from-scratch.markdown b/drafts/computer-from-scratch.markdown
index e7a2cf3..7145cc6 100644
--- a/drafts/computer-from-scratch.markdown
+++ b/drafts/computer-from-scratch.markdown
@@ -11,23 +11,104 @@ Recently I have had the pleasure of completing the course *Nand to Tetris* on
thought it would be possible for me to understand computers all the way down to the hardware
level (past assembly that is); *Nand to Tetris* has shown me otherwise! It has also inspired me
to pursue learning a real world hardware description language and attempt to implement the
-*Hack* system on an FPGA. In this article I will describe how the process is coming and the
+*Hack* system on an [FPGA](https://en.wikipedia.org/wiki/Field-programmable_gate_array) (Field
+Programmable Gate Array). In this article I will describe how the process is coming and the
what remains to be completed.
+For the impatient, the repository is located [here][hack-git] and is documented
+[here][hack-docs].
+
After implementing the *Hack Computer System* in the hardware description language described by
-the course, I went on to implement everything in [VHDL](https://en.wikipedia.org/wiki/VHDL),
-with the end goal of being able to realize the design on a
-[FPGA](https://en.wikipedia.org/wiki/Field-programmable_gate_array) (Field Programmable Gate
-Array). I also needed a set of test benches to verify correctness of the design through
-simulation. Initially I set out to find a completely open source solution. To my dismay, I
-found that FPGA's are incredibly proprietary. Namely, the process of *synthesis* cannot be done
-using open source tools, though there exists a few projects which are reverse engineering the
-bit file format of various FPGA's in order to develop a open solution to synthesis, they are
-not yet ready for use. So, synthesis needs to be done with proprietary tools.
+the course, I wanted to explorer further. So after doing a little research, I found there were
+two main industry strength hardware description languages,
+[VHDL](https://en.wikipedia.org/wiki/VHDL) and
+[Verilog](https://en.wikipedia.org/wiki/Verilog). I then set out to find open source
+implementations of these languages. Happily I found [GHDL](http://ghdl.free.fr/) and
+[Icarus Verilog](http://iverilog.icarus.com/) respectively. After briefly looking over both
+languages and their open source implementations, I decided I would use VHDL because I'm a fan
+of type systems and it is similar to the hardware description language given by the *Nand to
+Tetris* course.
+
+Now both *Icarus Verilog* and *GHDL* are unable to do *synthesis*. For those of you who are
+unaware of what *synthesis* is, it refers to the process of taking a hardware description and
+converting it into a format a FPGA can use. This is generally a bit file for JTAG programming
+or a bin file for writing to the FPGA board's internal memory. To my dismay, FPGA's are
+incredibly proprietary! Namely, the *synthesis* process can only be done using proprietary
+tools. So initially I decided I would forgo thinking about how exactly I would get my
+implementation on a FPGA but instead get the components of the system designed and verified
+though simulation, which can be completed using all open source tools. Now, there is a
+unsynthesizable subset of both VHDL and Verilog, so care needs to be taken to ensure that the
+design doesn't utilize these parts as the end goal is to implement the *Hack Computer System*
+on a FPGA. An exception to this is when a entity/module will only be used in simulation (Eg.
+Reading a text file and emulating a ROM that contains the machine language instructions
+specified in the file).
+
+Following the materials given by the course, I then went on to implement the *Hack Computer
+System* in VHDL. Currently, the project [resides here][hack-git] and has some
+[accompanying documentation][hack-docs] which explain how things work, how to build the
+project, and how to run a simulation. Please refer to the [documentation][hack-docs] for
+complete instructions on building and using the [hack][hack-git] project and simulator.
+
+Before going into detail on some of the design choices I made, I'd like to give an example of
+setting up the simulator and running the default simulation of the top most unit,
+`computer_tb`, which computes the first 25 Fibonacci numbers and puts them in RAM address' `0x3`
+through `0x28`.
+
+``` {.bash .code-term}
+$ git clone http://git.rekahsoft.ca/hack
+$ cd hack/src
+$ ghdl -i --workdir=work *.vhdl
+$ ghdl -m --workdir=work computer_tb.vhdl
+$ ghdl -r computer_tb --stop-time=750ns --vcd=wave/vcd/computer-fib.vcd
+$ vcd2fst wave/vcd/computer-fib.vcd wave/vcd/computer-fib.fst
+```
+
+First, clone the sources, then import and build them with `ghdl`. Finally run the simulation
+using the default input program and output a vcd file to `src/wave/vcd/computer-fib.vcd` which
+is then converted to a `fst` file using `vcd2fst`. Now once the simulation has complete the
+*vcd* or *fst* file can be opened with a wave form viewer. I recommend and have only tested
+with [GtkWave][]. To open the dump file open [GtkWave][] and go to `File -> Open New Tab` (or
+`C-t`) and select the output file (in our case `src/wave/vcd/computer-fib.fst`). I have
+provided pre-saved "views" for `computer_tb` (as well as the other entities within the project)
+so that the signals of interest for the entity in question don't need to be repopulated into
+the signals panel each time [GtkWave][] is opened. To open the [GtkWave][] save file go to
+`File -> Read Save File` (or `C-o`) and select the appropriate save file. In our case we will
+open `src/wave/gtkw/computer-fib.gtkw`.
+
+Note running this simulation will take some time (likely longer then an hour) and will consume
+lots of RAM and CPU and generate a large vcd dump (> 20 GB). By changing the length of time the
+simulation runs for one can limit the size of the vcd dump, but the usage of the CPU and RAM
+will remain the same. The large vcd dump file is unavoidable (as far as I know) because *GHDL*
+records data for all signals in the design and there's no way to filter its output until after
+the simulation has run (using external tools).
+
+![[GtkWave][] displaying a simulation dump from *computer_tb* running
+ *src/asm/Fib.hack*](files/images/gtkwave.png)
+
+Using a
+[generic property](http://www.doulos.com/knowhow/fpga/Setting_Generics_Parameters_for_Synthesis/)
+`program_file`, a user is able to pass a text file containing *Hack Machine Language* to the
+`computer_tb` unit using the `-g` switch to *GHDL* like so:
+`-gprogram_file=path/to/program.hack`. If none is specified it defaults to
+[src/asm/Fib.hack](http://git.rekahsoft.ca/hack/tree/src/asm/Fib.hack) (the corresponding *Hack
+assembly* form is provided [here](http://git.rekahsoft.ca/hack/tree/src/asm/Fib.asm)). The
+contents of the given `program_file` are used as the ROM data for the duration of the
+simulation.
+
+Unfortunately specifying generic properties when ghdl is invoked is only implemented in very
+recent versions of *GHDL* (later then 2015-03-07; see
+[ticket](http://sourceforge.net/p/ghdl-updates/tickets/37/?limit=25)). If you are running an
+older version of *GHDL* then you must modify `src/computer_tb.vhdl` to specify the program you
+want to run in the simulation. See the [documentation][hack-docs] for details.
+
+![[GtkWave][] zoomed in to view approximately *100 ns* of signal
+ output](files/images/gtkwave-closeup.png)
-which is
-taking the hardware description (either VHDL or Verilog) and convert it to a bit file (a format
-the FPGA can use).
+TODO: talk about current state of project (deficiencies in regards to screen and keyboard memory maps)
+
+[hack-git]: http://git.rekahsoft.ca/hack/
+[hack-docs]: http://git.rekahsoft.ca/hack/about
+[GtkWave]: http://gtkwave.sourceforge.net/
diff --git a/files/images/gtkwave-closeup.png b/files/images/gtkwave-closeup.png
new file mode 100644
index 0000000..38d5c10
Binary files /dev/null and b/files/images/gtkwave-closeup.png differ
diff --git a/files/images/gtkwave.png b/files/images/gtkwave.png
new file mode 100644
index 0000000..a811471
Binary files /dev/null and b/files/images/gtkwave.png differ