// 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 int freeList; /** Initializes the class. */ function void init() { let freeList = 2048; //freeList番地にfreeListLengthを入れる do Memory.poke(freeList, 16383 - freeList + 1); //(freeList + 1)番地にfreeListNext(-1=行き先ナシ)を入れる do Memory.poke(freeList + 1, -1); return; } /** Returns the RAM value at the given address. */ function int peek(int j) { var Array memory; var int x; let memory = 0; let x = memory[j]; return x; } /** Sets the RAM value at the given address to the given value. */ function void poke(int j, int y) { var Array memory; let memory = 0; let memory[j] = y; 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 pointer, segmentLength, segment, segmentRest; if(size < 1) { do Sys.error(44); } let segment = freeList; let segmentLength = Memory.peek(segment); let segmentRest = segmentLength - size; while(segmentRest < 2) { let segment = Memory.peek(segment + 1); if(segment = -1) { //割り当てできる領域がない(メモリ不足) do Sys.error(41); } let segmentLength = Memory.peek(segment); } //確保したメモリの頭 let pointer = segment + segmentLength - size; //確保したメモリの前のアドレスにサイズを入れる do Memory.poke(pointer - 1, size + 1); //現在のsegmentのサイズを更新する do Memory.poke(segment, segmentLength - (size + 1)); return pointer; } /** De-allocates the given object (cast as an array) by making * it available for future allocations. */ function void deAlloc(Array o) { var int segment; //freeListにsegmentを追加する //次のアドレスがない(=-1)まで移動 let segment = freeList; while(~(Memory.peek(segment + 1) = -1)) { let segment = Memory.peek(segment + 1); } //freeListの最後にsegmentを追加する do Memory.poke(segment + 1, o - 1); //次のアドレスに-1を入れておく(-1: 次はなし) do Memory.poke(o, -1); return; } }