// 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/Keyboard.jack /** * A library for handling user input from the keyboard. */ class Keyboard { /** Initializes the keyboard. */ function void init() { return; } /** * Returns the character of the currently pressed key on the keyboard; * if no key is currently pressed, returns 0. * * Recognizes all ASCII characters, as well as the following keys: * new line = 128 = String.newline() * backspace = 129 = String.backspace() * left arrow = 130 * up arrow = 131 * right arrow = 132 * down arrow = 133 * home = 134 * End = 135 * page up = 136 * page down = 137 * insert = 138 * delete = 139 * ESC = 140 * F1 - F12 = 141 - 152 */ function char keyPressed() { return Memory.peek(24576); } /** Waits until a key is pressed on the keyboard and released, * then echoes the key to the screen, and returns the character * of the pressed key. */ function char readChar() { var char key; // Wait for key press while (Keyboard.keyPressed() = 0) {} let key = Keyboard.keyPressed(); // Wait for release while (~(Keyboard.keyPressed() = 0)) {} // Echo (except backspace) if (key < 129) { // Handle newline specially for cleaner output? if (key = 128) { do Output.println(); } else { do Output.printChar(key); } } // If key > 129 (arrows etc), printChar might print garbage or square. return key; } /** Displays the message on the screen, reads from the keyboard the entered * text until a newline character is detected, echoes the text to the screen, * and returns its value. Also handles user backspaces. */ function String readLine(String message) { var String s; var char c; do Output.printString(message); let s = String.new(64); // Assume max line 64 while (true) { let c = Keyboard.readChar(); if (c = 128) { // Newline do Output.println(); return s; } if (c = 129) { // Backspace if (s.length() > 0) { do s.eraseLastChar(); do Output.backSpace(); // Erase not supported by Output, so we print space and back up again? // But printChar sends cursor forward. // To visually erase: Backspace (move left), Print Space (overwrite, move right), Backspace (move left). // My output implementation doesn't support 'erasing' naturally. // But this trick works. do Output.printChar(32); // Space do Output.backSpace(); } } else { do s.appendChar(c); } } return s; } /** Displays the message on the screen, reads from the keyboard the entered * text until a newline character is detected, echoes the text to the screen, * and returns its integer value (until the first non-digit character in the * entered text is detected). Also handles user backspaces. */ function int readInt(String message) { var String s; var int val; let s = Keyboard.readLine(message); let val = s.intValue(); do s.dispose(); return val; } }