Files
eceg431/12/Memory.jack
2025-12-07 23:31:41 -05:00

78 lines
2.6 KiB
Plaintext

// 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 ram;
static Array heap;
static int freeList;
static int heapBottom;
/** Initializes the class. */
function void init() {
let ram = 0;
let heap = 2048; // heapBase
let heapBottom = 16384;
let freeList = heap;
let heap[0] = heapBottom - heap; // length of first block
let heap[1] = 0; // next pointer
return;
}
/** Returns the RAM value at the given address. */
function int peek(int address) {
return ram[address];
}
/** Sets the RAM value at the given address to the given value. */
function void poke(int address, int value) {
let ram[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 curr, next, len;
var int block;
let curr = freeList;
// Search for a block with enough space (size + 1 for header)
while (~(curr = 0)) {
let len = ram[curr];
// Check if block is large enough (size + 1 for header)
// Ideally we also want to leave at least 2 words for the free block itself to remain valid
if (len > (size + 2)) {
// Carve from the end of the block
let ram[curr] = len - (size + 1); // Reduce free block size
let block = curr + ram[curr]; // Base of new block (including header)
let ram[block] = size + 1; // Set allocated block size (including header)
return block + 1; // Return user pointer
}
let curr = ram[curr + 1]; // Next block
}
return 0; // Out of memory
}
/** De-allocates the given object (cast as an array) by making
* it available for future allocations. */
function void deAlloc(Array o) {
var int block;
let block = o - 1; // Get header
// Append to head of freeList
let ram[block + 1] = freeList;
let freeList = block;
return;
}
}