aboutsummaryrefslogtreecommitdiff
path: root/projects/12
diff options
context:
space:
mode:
authorYuchen Pei <me@ypei.me>2018-01-17 10:04:48 +0100
committerYuchen Pei <me@ypei.me>2018-01-17 10:04:48 +0100
commit3a9265774c48865547702fe58d127c9fe10338a1 (patch)
tree8a1fd693efe8863a101ae0a6dceee621400c24dd /projects/12
parent17c169707a1efc2d576e1b03d2956b0b4be4135d (diff)
finished Memory.jack
Diffstat (limited to 'projects/12')
-rw-r--r--projects/12/Memory.jack46
-rw-r--r--projects/12/MemoryTest/Main.vm126
-rw-r--r--projects/12/MemoryTest/Memory.jack84
-rw-r--r--projects/12/MemoryTest/Memory.vm362
-rw-r--r--projects/12/MemoryTest/MemoryTest.out2
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 |