// 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; } } }