diff options
author | Yuchen Pei <me@ypei.me> | 2018-01-17 10:04:48 +0100 |
---|---|---|
committer | Yuchen Pei <me@ypei.me> | 2018-01-17 10:04:48 +0100 |
commit | 3a9265774c48865547702fe58d127c9fe10338a1 (patch) | |
tree | 8a1fd693efe8863a101ae0a6dceee621400c24dd | |
parent | 17c169707a1efc2d576e1b03d2956b0b4be4135d (diff) |
finished Memory.jack
-rw-r--r-- | projects/12/Memory.jack | 46 | ||||
-rw-r--r-- | projects/12/MemoryTest/Main.vm | 126 | ||||
-rw-r--r-- | projects/12/MemoryTest/Memory.jack | 84 | ||||
-rw-r--r-- | projects/12/MemoryTest/Memory.vm | 362 | ||||
-rw-r--r-- | projects/12/MemoryTest/MemoryTest.out | 2 |
5 files changed, 620 insertions, 0 deletions
diff --git a/projects/12/Memory.jack b/projects/12/Memory.jack index 941eec1..b1e67ef 100644 --- a/projects/12/Memory.jack +++ b/projects/12/Memory.jack @@ -9,26 +9,72 @@ * consists of 32,768 words, each holding a 16-bit binary number.
*/
class Memory {
+ static Array memory;
+ static Array heap;
+ static int first;
/** Initializes the class. */
function void init() {
+ let memory = 0;
+ let heap = 2048;
+ let heap[0] = -1;
+ let heap[1] = 14334;
}
/** Returns the RAM value at the given address. */
function int peek(int address) {
+ return memory[address];
}
/** Sets the RAM value at the given address to the given value. */
function void poke(int address, int value) {
+ let memory[address] = value;
}
/** Finds an available RAM block of the given size and returns
* a reference to its base address. */
function int alloc(int size) {
+ var int current;
+ var int size2;
+ var int newLast;
+ let current = 0;
+ let size2 = size + 2;
+ while ((current > -1) & (heap[current + 1] < size2)) {
+ let current = heap[current];
+ }
+ if (current = -1) {
+ String.println("Insufficient space for allocation!");
+ Sys.error(1);
+ } else {
+ let heap[current + 1] = heap[current + 1] - size2;
+ let newLast = current + heap[current + 1] + 2;
+ let heap[newLast] = heap[current];
+ let heap[current] = newLast;
+ let heap[newLast + 1] = size;
+ return heap + newLast + 2;
+ }
}
/** De-allocates the given object (cast as an array) by making
* it available for future allocations. */
function void deAlloc(Array o) {
+ var int base;
+ var int current;
+ var int prev;
+ let prev = 0;
+ let current = heap[prev];
+ let oBase = o - heap - 2;
+ while ((current > -1) & (~(current = oBase))){
+ let prev = current;
+ let current = heap[current];
+ }
+ if (current = -1) {
+ String.println("The impossible happened");
+ Sys.error(1);
+ } else {
+ let heap[prev] = heap[current]
+ let heap[prev + 1] = heap[prev] - prev - 2;
+ return;
+ }
}
}
diff --git a/projects/12/MemoryTest/Main.vm b/projects/12/MemoryTest/Main.vm new file mode 100644 index 0000000..a3a9e81 --- /dev/null +++ b/projects/12/MemoryTest/Main.vm @@ -0,0 +1,126 @@ +function Main.main 4 +push constant 8000 +push constant 333 +call Memory.poke 2 +pop temp 0 +push constant 8000 +call Memory.peek 1 +pop local 0 +push constant 8001 +push local 0 +push constant 1 +add +call Memory.poke 2 +pop temp 0 +push constant 3 +call Array.new 1 +pop local 1 +push constant 2 +push local 1 +add +push constant 222 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 8002 +push constant 2 +push local 1 +add +pop pointer 1 +push that 0 +call Memory.poke 2 +pop temp 0 +push constant 3 +call Array.new 1 +pop local 2 +push constant 1 +push local 2 +add +push constant 2 +push local 1 +add +pop pointer 1 +push that 0 +push constant 100 +sub +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 8003 +push constant 1 +push local 2 +add +pop pointer 1 +push that 0 +call Memory.poke 2 +pop temp 0 +push constant 500 +call Array.new 1 +pop local 3 +push constant 499 +push local 3 +add +push constant 2 +push local 1 +add +pop pointer 1 +push that 0 +push constant 1 +push local 2 +add +pop pointer 1 +push that 0 +sub +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 8004 +push constant 499 +push local 3 +add +pop pointer 1 +push that 0 +call Memory.poke 2 +pop temp 0 +push local 1 +call Array.dispose 1 +pop temp 0 +push local 2 +call Array.dispose 1 +pop temp 0 +push constant 3 +call Array.new 1 +pop local 2 +push constant 0 +push local 2 +add +push constant 499 +push local 3 +add +pop pointer 1 +push that 0 +push constant 90 +sub +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 8005 +push constant 0 +push local 2 +add +pop pointer 1 +push that 0 +call Memory.poke 2 +pop temp 0 +push local 3 +call Array.dispose 1 +pop temp 0 +push local 2 +call Array.dispose 1 +pop temp 0 +push constant 0 +return diff --git a/projects/12/MemoryTest/Memory.jack b/projects/12/MemoryTest/Memory.jack new file mode 100644 index 0000000..8583b62 --- /dev/null +++ b/projects/12/MemoryTest/Memory.jack @@ -0,0 +1,84 @@ +// This file is part of www.nand2tetris.org
+// and the book "The Elements of Computing Systems"
+// by Nisan and Schocken, MIT Press.
+// File name: projects/12/Memory.jack
+
+/**
+ * This library provides two services: direct access to the computer's main
+ * memory (RAM), and allocation and recycling of memory blocks. The Hack RAM
+ * consists of 32,768 words, each holding a 16-bit binary number.
+ */
+class Memory {
+ static Array memory;
+ static Array heap;
+ static int first;
+
+ /** Initializes the class. */
+ function void init() {
+ let memory = 0;
+ let heap = 2048;
+ let heap[0] = -1;
+ let heap[1] = 14334;
+ return;
+ }
+
+ /** Returns the RAM value at the given address. */
+ function int peek(int address) {
+ return memory[address];
+ }
+
+ /** Sets the RAM value at the given address to the given value. */
+ function void poke(int address, int value) {
+ let memory[address] = value;
+ return;
+ }
+
+ /** Finds an available RAM block of the given size and returns
+ * a reference to its base address. */
+ function int alloc(int size) {
+ var int current;
+ var int size2;
+ var int newLast;
+ let current = 0;
+ let size2 = size + 2;
+ while ((current > -1) & (heap[current + 1] < size2)) {
+ let current = heap[current];
+ }
+ if (current = -1) {
+ do String.println("Insufficient space for allocation!");
+ do Sys.error(1);
+ return -1;
+ } else {
+ let heap[current + 1] = heap[current + 1] - size2;
+ let newLast = current + heap[current + 1] + 2;
+ let heap[newLast] = heap[current];
+ let heap[current] = newLast;
+ let heap[newLast + 1] = size;
+ return heap + newLast + 2;
+ }
+ }
+
+ /** De-allocates the given object (cast as an array) by making
+ * it available for future allocations. */
+ function void deAlloc(Array o) {
+ var int oBase;
+ var int current;
+ var int prev;
+ let prev = 0;
+ let current = heap[prev];
+ let oBase = o - heap - 2;
+ while ((current > -1) & (~(current = oBase))){
+ let prev = current;
+ let current = heap[current];
+ }
+ if (current = -1) {
+ do String.println("The impossible happened");
+ do Sys.error(1);
+ return;
+ } else {
+ let heap[prev] = heap[current];
+ let heap[prev + 1] = heap[prev] - prev - 2;
+ return;
+ }
+ }
+}
diff --git a/projects/12/MemoryTest/Memory.vm b/projects/12/MemoryTest/Memory.vm new file mode 100644 index 0000000..c7410fc --- /dev/null +++ b/projects/12/MemoryTest/Memory.vm @@ -0,0 +1,362 @@ +function Memory.init 0 +push constant 0 +pop static 0 +push constant 2048 +pop static 1 +push constant 0 +push static 1 +add +push constant 1 +neg +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 1 +push static 1 +add +push constant 14334 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 0 +return +function Memory.peek 0 +push argument 0 +push static 0 +add +pop pointer 1 +push that 0 +return +function Memory.poke 0 +push argument 0 +push static 0 +add +push argument 1 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 0 +return +function Memory.alloc 3 +push constant 0 +pop local 0 +push argument 0 +push constant 2 +add +pop local 1 +label WHILE_EXP0 +push local 0 +push constant 1 +neg +gt +push local 0 +push constant 1 +add +push static 1 +add +pop pointer 1 +push that 0 +push local 1 +lt +and +not +if-goto WHILE_END0 +push local 0 +push static 1 +add +pop pointer 1 +push that 0 +pop local 0 +goto WHILE_EXP0 +label WHILE_END0 +push local 0 +push constant 1 +neg +eq +if-goto IF_TRUE0 +goto IF_FALSE0 +label IF_TRUE0 +push constant 34 +call String.new 1 +push constant 73 +call String.appendChar 2 +push constant 110 +call String.appendChar 2 +push constant 115 +call String.appendChar 2 +push constant 117 +call String.appendChar 2 +push constant 102 +call String.appendChar 2 +push constant 102 +call String.appendChar 2 +push constant 105 +call String.appendChar 2 +push constant 99 +call String.appendChar 2 +push constant 105 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 110 +call String.appendChar 2 +push constant 116 +call String.appendChar 2 +push constant 32 +call String.appendChar 2 +push constant 115 +call String.appendChar 2 +push constant 112 +call String.appendChar 2 +push constant 97 +call String.appendChar 2 +push constant 99 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 32 +call String.appendChar 2 +push constant 102 +call String.appendChar 2 +push constant 111 +call String.appendChar 2 +push constant 114 +call String.appendChar 2 +push constant 32 +call String.appendChar 2 +push constant 97 +call String.appendChar 2 +push constant 108 +call String.appendChar 2 +push constant 108 +call String.appendChar 2 +push constant 111 +call String.appendChar 2 +push constant 99 +call String.appendChar 2 +push constant 97 +call String.appendChar 2 +push constant 116 +call String.appendChar 2 +push constant 105 +call String.appendChar 2 +push constant 111 +call String.appendChar 2 +push constant 110 +call String.appendChar 2 +push constant 33 +call String.appendChar 2 +call String.println 1 +pop temp 0 +push constant 1 +call Sys.error 1 +pop temp 0 +push constant 1 +neg +return +goto IF_END0 +label IF_FALSE0 +push local 0 +push constant 1 +add +push static 1 +add +push local 0 +push constant 1 +add +push static 1 +add +pop pointer 1 +push that 0 +push local 1 +sub +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push local 0 +push local 0 +push constant 1 +add +push static 1 +add +pop pointer 1 +push that 0 +add +push constant 2 +add +pop local 2 +push local 2 +push static 1 +add +push local 0 +push static 1 +add +pop pointer 1 +push that 0 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push local 0 +push static 1 +add +push local 2 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push local 2 +push constant 1 +add +push static 1 +add +push argument 0 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push static 1 +push local 2 +add +push constant 2 +add +return +label IF_END0 +function Memory.deAlloc 3 +push constant 0 +pop local 2 +push local 2 +push static 1 +add +pop pointer 1 +push that 0 +pop local 1 +push argument 0 +push static 1 +sub +push constant 2 +sub +pop local 0 +label WHILE_EXP0 +push local 1 +push constant 1 +neg +gt +push local 1 +push local 0 +eq +not +and +not +if-goto WHILE_END0 +push local 1 +pop local 2 +push local 1 +push static 1 +add +pop pointer 1 +push that 0 +pop local 1 +goto WHILE_EXP0 +label WHILE_END0 +push local 1 +push constant 1 +neg +eq +if-goto IF_TRUE0 +goto IF_FALSE0 +label IF_TRUE0 +push constant 23 +call String.new 1 +push constant 84 +call String.appendChar 2 +push constant 104 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 32 +call String.appendChar 2 +push constant 105 +call String.appendChar 2 +push constant 109 +call String.appendChar 2 +push constant 112 +call String.appendChar 2 +push constant 111 +call String.appendChar 2 +push constant 115 +call String.appendChar 2 +push constant 115 +call String.appendChar 2 +push constant 105 +call String.appendChar 2 +push constant 98 +call String.appendChar 2 +push constant 108 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 32 +call String.appendChar 2 +push constant 104 +call String.appendChar 2 +push constant 97 +call String.appendChar 2 +push constant 112 +call String.appendChar 2 +push constant 112 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 110 +call String.appendChar 2 +push constant 101 +call String.appendChar 2 +push constant 100 +call String.appendChar 2 +call String.println 1 +pop temp 0 +push constant 1 +call Sys.error 1 +pop temp 0 +push constant 0 +return +goto IF_END0 +label IF_FALSE0 +push local 2 +push static 1 +add +push local 1 +push static 1 +add +pop pointer 1 +push that 0 +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push local 2 +push constant 1 +add +push static 1 +add +push local 2 +push static 1 +add +pop pointer 1 +push that 0 +push local 2 +sub +push constant 2 +sub +pop temp 0 +pop pointer 1 +push temp 0 +pop that 0 +push constant 0 +return +label IF_END0 diff --git a/projects/12/MemoryTest/MemoryTest.out b/projects/12/MemoryTest/MemoryTest.out new file mode 100644 index 0000000..8259ed2 --- /dev/null +++ b/projects/12/MemoryTest/MemoryTest.out @@ -0,0 +1,2 @@ +|RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]| +| 333 | 334 | 222 | 122 | 100 | 10 | |