diff --git a/exercises/110_quiz9.zig b/exercises/110_quiz9.zig
index 4ac2032..171a509 100644
--- a/exercises/110_quiz9.zig
+++ b/exercises/110_quiz9.zig
@@ -68,40 +68,31 @@ const testing = std.testing;
 
 pub fn main() !void {
     var PORTB: u4 = 0b0000; // only 4 bits wide for simplicity
+
+    // The LCD display on our robot is not behaving as expected. In order to
+    // get it functioning properly, we must initialize it by sending the
+    // correct sequence of half-bytes to PORTB's lower four pins.
     //
-    // Let's first take a look at toggling bits.
+    // See if you can solve the following problems to get the lcd working and
+    // reveal the message our robot has stored in his EEPROM.
     //
-    // ------------------------------------------------------------------------
-    // Toggling bits with XOR:
-    // ------------------------------------------------------------------------
-    // XOR stands for "exclusive or". We can toggle bits with the ^ (XOR)
-    // bitwise operator, like so:
+    //                           .--.      .--.
+    //                           |  |      |  |
+    //                    +--------------------------+
+    //                    | +----------------------+ |
+    //                    | |                      | |
+    //                    | |  XXXXXXXX  XXXXXXXX  | | <-- LCD
+    //                    | |                      | |
+    //                    | +----------------------+ |
+    //                    |        _________         |
+    //                    |       |_|_|_|_|_|        |
+    //                    |                          |
+    //                    +--------------------------+
+    //                              |     |
     //
-    //
-    // In order to output a 1, the logic of an XOR operation requires that the
-    // two input bits are of different values. Therefore, 0 ^ 1 and 1 ^ 0 will
-    // both yield a 1 but 0 ^ 0 and 1 ^ 1 will output 0. XOR's unique behavior
-    // of outputing a 0 when both inputs are 1s is what makes it different from
-    // the OR operator; it also gives us the ability to toggle bits by putting
-    // 1s into our bitmask.
-    //
-    // - 1s in our bitmask operand, can be thought of as causing the
-    //   corresponding bits in the other operand to flip to the opposite value.
-    // - 0s cause no change.
-    //
-    //                            The 0s in our bitmask preserve these values
-    // -XOR op- ---expanded---    in the output.
-    //            _______________/
-    //           /       /
-    //   0110   1   1   0   0
-    // ^ 1111   0   1   0   1 (bitmask)
-    // ------   -   -   -   -
-    // = 1001   1   0   0   1 <- This bit was already cleared.
-    //              \_______\
-    //                       \
-    //                         We can think of these bits having flipped
-    //                         because of the presence of 1s in those columns
-    //                         of our bitmask.
+    // The last two problems throw you a bit of a curve ball. Try solving them
+    // on your own. If you need help, scroll to the bottom to see some in depth
+    // explanations on toggling, setting, and clearing bits in Zig.
 
     print("Toggle pins with XOR on PORTB\n", .{});
     print("-----------------------------\n", .{});
@@ -121,49 +112,6 @@ pub fn main() !void {
 
     newline();
 
-    // Now let's take a look at setting bits with the | operator.
-    //
-    // ------------------------------------------------------------------------
-    // Setting bits with OR:
-    // ------------------------------------------------------------------------
-    // We can set bits on PORTB with the | (OR) operator, like so:
-    //
-    // var PORTB: u4 = 0b1001;
-    // PORTB = PORTB | 0b0010;
-    // print("PORTB: {b:0>4}\n", .{PORTB}); // output: 1011
-    //
-    // -OR op-  ---expanded---
-    //                    _ Set only this bit.
-    //                   /
-    //   1001   1   0   0   1
-    // | 0010   0   0   1   0 (bit mask)
-    // ------   -   -   -   -
-    // = 1011   1   0   1   1
-    //           \___\_______\
-    //                        \
-    //                          These bits remain untouched because OR-ing with
-    //                          a 0 effects no change.
-    //
-    // ------------------------------------------------------------------------
-    // To create a bit mask like 0b0010 used above:
-    //
-    // 1. First, shift the value 1 over one place with the bitwise << (shift
-    // left) operator as indicated below:
-    //           1 << 0 -> 0001
-    //           1 << 1 -> 0010  <-- Shift 1 one place to the left
-    //           1 << 2 -> 0100
-    //           1 << 3 -> 1000
-    //
-    // This allows us to rewrite the above code like this:
-    //
-    // var PORTB: u4 = 0b1001;
-    // PORTB = PORTB | (1 << 1);
-    // print("PORTB: {b:0>4}\n", .{PORTB}); // output: 1011
-    //
-    // Finally, as in the C language, Zig allows us to use the |= operator, so
-    // we can rewrite our code again in an even more compact and idiomatic
-    // form: PORTB |= (1 << 1)
-
     print("Set pins with OR on PORTB\n", .{});
     print("-------------------------\n", .{});
 
@@ -183,86 +131,6 @@ pub fn main() !void {
 
     newline();
 
-    // So now we've covered how to toggle and set bits. What about clearing
-    // them? Well, this is where Zig throws us a curve ball. Don't worry we'll
-    // go through it step by step.
-
-    // ------------------------------------------------------------------------
-    // Clearing bits with AND and NOT:
-    // ------------------------------------------------------------------------
-    // We can clear bits with the & (AND) bitwise operator, like so:
-
-    // PORTB = 0b1110; // reset PORTB
-    // PORTB = PORTB & 0b1011;
-    // print("PORTB: {b:0>4}\n", .{PORTB}); // output -> 1010
-    //
-    // - 0s clear bits when used in conjuction with a bitwise AND.
-    // - 1s do nothing, thus preserving the original bits.
-    //
-    // -AND op- ---expanded---
-    //                __________ Clear only this bit.
-    //               /
-    //   1110   1   1   1   0
-    // & 1011   1   0   1   1 (bit mask)
-    // ------   -   -   -   -
-    // = 1010   1   0   1   0 <- This bit was already cleared.
-    //           \_______\
-    //                    \
-    //                      These bits remain untouched because AND-ing with a
-    //                      1 preserves the original bit value whether 0 or 1.
-    //
-    // ------------------------------------------------------------------------
-    // We can use the ~ (NOT) operator to easily create a bit mask like 1011:
-    //
-    //  1. First, shift the value 1 over two places with the bit-wise << (shift
-    //     left) operator as indicated below:
-    //          1 << 0 -> 0001
-    //          1 << 1 -> 0010
-    //          1 << 2 -> 0100 <- The 1 has been shifted two places to the left
-    //          1 << 3 -> 1000
-    //
-    //  2. The second step in creating our bit mask is to invert the bits
-    //          ~0100 -> 1011
-    //     in C we would write this as:
-    //          ~(1 << 2) -> 1011
-    //
-    //     But if we try to compile ~(1 << 2) in Zig, we'll get an error:
-    //          unable to perform binary not operation on type 'comptime_int'
-    //
-    //     Before Zig can invert our bits, it needs to know the number of
-    //     bits it's being asked to invert.
-    //
-    //     We do this with the @as (cast as) built-in like this:
-    //          @as(u4, 1 << 2) -> 0100
-    //
-    //     Finally, we can invert our new mask by placing the NOT ~ operator
-    //     before our expression, like this:
-    //          ~@as(u4, 1 << 2) -> 1011
-    //
-    //     If you are offput by the fact that you can't simply invert bits like
-    //     you can in languages such as C without casting to a particular size
-    //     of integer, you're not alone. However, this is actually another
-    //     instance where Zig is really helpful because it protects you from
-    //     difficult to debug integer overflow bugs that can have you tearing
-    //     your hair out. In the interest of keeping things sane, Zig requires
-    //     you simply to tell it the size of number you are inverting. In the
-    //     words of Andrew Kelley, "If you want to invert the bits of an
-    //     integer, zig has to know how many bits there are."
-    //
-    //     For more insight into the Zig team's position on why the language
-    //     takes the approach it does with the ~ operator, take a look at
-    //     Andrew's comments on the following github issue:
-    //     https://github.com/ziglang/zig/issues/1382#issuecomment-414459529
-    //
-    // Whew, so after all that what we end up with is:
-    //          PORTB = PORTB & ~@as(u4, 1 << 2);
-    //
-    // We can shorten this with the &= combined AND and assignment operator,
-    // which applies the AND operator on PORTB and then reassigns PORTB. Here's
-    // what that looks like:
-    //          PORTB &= ~@as(u4, 1 << 2);
-    //
-
     print("Clear pins with AND and NOT on PORTB\n", .{});
     print("------------------------------------\n", .{});
 
@@ -283,37 +151,222 @@ pub fn main() !void {
     newline();
     newline();
 
-    // ------------------------------------------------------------------------
-    // Conclusion
-    // ------------------------------------------------------------------------
-    //
-    // While the examples in this exercise have used only 4-bit wide variables,
-    // working with 8 bits is no different. Here's a an example where we set
-    // every other bit beginning with the two's place:
-
-    // var PORTD: u8 = 0b0000_0000;
-    // print("PORTD: {b:0>8}\n", .{PORTD});
-    // PORTD |= (1 << 1);
-    // PORTD = setBit(u8, PORTD, 3);
-    // PORTD |= (1 << 5) | (1 << 7);
-    // print("PORTD: {b:0>8} // set every other bit\n", .{PORTD});
-    // PORTD = ~PORTD;
-    // print("PORTD: {b:0>8} // bits flipped with NOT (~)\n", .{PORTD});
-    // newline();
-    //
-    // // Here we clear every other bit beginning with the two's place.
-    //
-    // PORTD = 0b1111_1111;
-    // print("PORTD: {b:0>8}\n", .{PORTD});
-    // PORTD &= ~@as(u8, 1 << 1);
-    // PORTD = clearBit(u8, PORTD, 3);
-    // PORTD &= ~@as(u8, (1 << 5) | (1 << 7));
-    // print("PORTD: {b:0>8} // clear every other bit\n", .{PORTD});
-    // PORTD = ~PORTD;
-    // print("PORTD: {b:0>8} // bits flipped with NOT (~)\n", .{PORTD});
-    // newline();
 }
 
+
+// ************************************************************************
+//                    IN-DEPTH EXPLANATIONS BELOW
+// ************************************************************************
+
+
+
+
+
+
+
+
+
+
+
+
+// ------------------------------------------------------------------------
+// Toggling bits with XOR:
+// ------------------------------------------------------------------------
+// XOR stands for "exclusive or". We can toggle bits with the ^ (XOR)
+// bitwise operator, like so:
+//
+//
+// In order to output a 1, the logic of an XOR operation requires that the
+// two input bits are of different values. Therefore, 0 ^ 1 and 1 ^ 0 will
+// both yield a 1 but 0 ^ 0 and 1 ^ 1 will output 0. XOR's unique behavior
+// of outputing a 0 when both inputs are 1s is what makes it different from
+// the OR operator; it also gives us the ability to toggle bits by putting
+// 1s into our bitmask.
+//
+// - 1s in our bitmask operand, can be thought of as causing the
+//   corresponding bits in the other operand to flip to the opposite value.
+// - 0s cause no change.
+//
+//                            The 0s in our bitmask preserve these values
+// -XOR op- ---expanded---    in the output.
+//            _______________/
+//           /       /
+//   0110   1   1   0   0
+// ^ 1111   0   1   0   1 (bitmask)
+// ------   -   -   -   -
+// = 1001   1   0   0   1 <- This bit was already cleared.
+//              \_______\
+//                       \
+//                         We can think of these bits having flipped
+//                         because of the presence of 1s in those columns
+//                         of our bitmask.
+//
+// Now let's take a look at setting bits with the | operator.
+//
+
+
+
+
+
+
+// ------------------------------------------------------------------------
+// Setting bits with OR:
+// ------------------------------------------------------------------------
+// We can set bits on PORTB with the | (OR) operator, like so:
+//
+// var PORTB: u4 = 0b1001;
+// PORTB = PORTB | 0b0010;
+// print("PORTB: {b:0>4}\n", .{PORTB}); // output: 1011
+//
+// -OR op-  ---expanded---
+//                    _ Set only this bit.
+//                   /
+//   1001   1   0   0   1
+// | 0010   0   0   1   0 (bit mask)
+// ------   -   -   -   -
+// = 1011   1   0   1   1
+//           \___\_______\
+//                        \
+//                          These bits remain untouched because OR-ing with
+//                          a 0 effects no change.
+//
+// ------------------------------------------------------------------------
+// To create a bit mask like 0b0010 used above:
+//
+// 1. First, shift the value 1 over one place with the bitwise << (shift
+// left) operator as indicated below:
+//           1 << 0 -> 0001
+//           1 << 1 -> 0010  <-- Shift 1 one place to the left
+//           1 << 2 -> 0100
+//           1 << 3 -> 1000
+//
+// This allows us to rewrite the above code like this:
+//
+// var PORTB: u4 = 0b1001;
+// PORTB = PORTB | (1 << 1);
+// print("PORTB: {b:0>4}\n", .{PORTB}); // output: 1011
+//
+// Finally, as in the C language, Zig allows us to use the |= operator, so
+// we can rewrite our code again in an even more compact and idiomatic
+// form: PORTB |= (1 << 1)
+
+// So now we've covered how to toggle and set bits. What about clearing
+// them? Well, this is where Zig throws us a curve ball. Don't worry we'll
+// go through it step by step.
+
+
+
+
+
+
+// ------------------------------------------------------------------------
+// Clearing bits with AND and NOT:
+// ------------------------------------------------------------------------
+// We can clear bits with the & (AND) bitwise operator, like so:
+
+// PORTB = 0b1110; // reset PORTB
+// PORTB = PORTB & 0b1011;
+// print("PORTB: {b:0>4}\n", .{PORTB}); // output -> 1010
+//
+// - 0s clear bits when used in conjuction with a bitwise AND.
+// - 1s do nothing, thus preserving the original bits.
+//
+// -AND op- ---expanded---
+//                __________ Clear only this bit.
+//               /
+//   1110   1   1   1   0
+// & 1011   1   0   1   1 (bit mask)
+// ------   -   -   -   -
+// = 1010   1   0   1   0 <- This bit was already cleared.
+//           \_______\
+//                    \
+//                      These bits remain untouched because AND-ing with a
+//                      1 preserves the original bit value whether 0 or 1.
+//
+// ------------------------------------------------------------------------
+// We can use the ~ (NOT) operator to easily create a bit mask like 1011:
+//
+//  1. First, shift the value 1 over two places with the bit-wise << (shift
+//     left) operator as indicated below:
+//          1 << 0 -> 0001
+//          1 << 1 -> 0010
+//          1 << 2 -> 0100 <- The 1 has been shifted two places to the left
+//          1 << 3 -> 1000
+//
+//  2. The second step in creating our bit mask is to invert the bits
+//          ~0100 -> 1011
+//     in C we would write this as:
+//          ~(1 << 2) -> 1011
+//
+//     But if we try to compile ~(1 << 2) in Zig, we'll get an error:
+//          unable to perform binary not operation on type 'comptime_int'
+//
+//     Before Zig can invert our bits, it needs to know the number of
+//     bits it's being asked to invert.
+//
+//     We do this with the @as (cast as) built-in like this:
+//          @as(u4, 1 << 2) -> 0100
+//
+//     Finally, we can invert our new mask by placing the NOT ~ operator
+//     before our expression, like this:
+//          ~@as(u4, 1 << 2) -> 1011
+//
+//     If you are offput by the fact that you can't simply invert bits like
+//     you can in languages such as C without casting to a particular size
+//     of integer, you're not alone. However, this is actually another
+//     instance where Zig is really helpful because it protects you from
+//     difficult to debug integer overflow bugs that can have you tearing
+//     your hair out. In the interest of keeping things sane, Zig requires
+//     you simply to tell it the size of number you are inverting. In the
+//     words of Andrew Kelley, "If you want to invert the bits of an
+//     integer, zig has to know how many bits there are."
+//
+//     For more insight into the Zig team's position on why the language
+//     takes the approach it does with the ~ operator, take a look at
+//     Andrew's comments on the following github issue:
+//     https://github.com/ziglang/zig/issues/1382#issuecomment-414459529
+//
+// Whew, so after all that what we end up with is:
+//          PORTB = PORTB & ~@as(u4, 1 << 2);
+//
+// We can shorten this with the &= combined AND and assignment operator,
+// which applies the AND operator on PORTB and then reassigns PORTB. Here's
+// what that looks like:
+//          PORTB &= ~@as(u4, 1 << 2);
+//
+
+// ------------------------------------------------------------------------
+// Conclusion
+// ------------------------------------------------------------------------
+//
+// While the examples in this quiz have used only 4-bit wide variables,
+// working with 8 bits is no different. Here's a an example where we set
+// every other bit beginning with the two's place:
+
+// var PORTD: u8 = 0b0000_0000;
+// print("PORTD: {b:0>8}\n", .{PORTD});
+// PORTD |= (1 << 1);
+// PORTD = setBit(u8, PORTD, 3);
+// PORTD |= (1 << 5) | (1 << 7);
+// print("PORTD: {b:0>8} // set every other bit\n", .{PORTD});
+// PORTD = ~PORTD;
+// print("PORTD: {b:0>8} // bits flipped with NOT (~)\n", .{PORTD});
+// newline();
+//
+// // Here we clear every other bit beginning with the two's place.
+//
+// PORTD = 0b1111_1111;
+// print("PORTD: {b:0>8}\n", .{PORTD});
+// PORTD &= ~@as(u8, 1 << 1);
+// PORTD = clearBit(u8, PORTD, 3);
+// PORTD &= ~@as(u8, (1 << 5) | (1 << 7));
+// print("PORTD: {b:0>8} // clear every other bit\n", .{PORTD});
+// PORTD = ~PORTD;
+// print("PORTD: {b:0>8} // bits flipped with NOT (~)\n", .{PORTD});
+// newline();
+
+
+
 // ----------------------------------------------------------------------------
 // Here are some helper functions for manipulating bits
 // ----------------------------------------------------------------------------