Welcome to this unit in which we're going to talk about the input capabilities of our operating system, and in particular, we're going to talk about a class called keyboard. That manages all the dialogue, if you will, between our computer, and the physical keyboard. And if you recall, this is how we handle input output devices on the hack platform, this was covered in spot one, and mentioned only, also, in module zero of this course. So, by convention, we allocate certain space in the RAM to represent, or stand for the screen, and likewise, we allocate a single 16 bit register in the RAM to represent the keyboard. Now, this is a 16 bit representation is all that is needed in order to represent any possible character in the unique called character set. So, this is a sufficient for handling the keyboard. And this is called the keyboard memory map, which, once again, is a single RAM register. That's how it looks like using this graphical metaphor, so, on the right-hand side, we see a keyboard, which is identical more or less to the keyboard that you are currently using on your computer. And on the left, we see this, a single RAM register that we discussed before, which we also call keyboard by convention. So, here's the contract. When you press a certain key on the keyboard, the keyboard register works in such a way that it immediately and instantaneously displays the binary value of the scan code, or the Unicode or the Ascii code, that you have pressed. All these codes are the same within the subset of characters that are recognizable by the Heka computer. And so that's what happens when you press the keyboard, once you release your finger and no key is pressed, the keyboard register is set to zero. So normally, the keyboard register is zero, because most of the time, no one touches the keyboard. And in the few instances in which we touch the keyboard, we get some non-zero value reflected in this register. This contract is delivered by the hardware. And therefore, we don't have to worry about it. And yet, everything that we will do in the keyboard class of the operating system is going to be built on this very humble foundation. So, let me illustrate to you how this thing works. Suppose I take my finger and press K, now, as long as my finger is down on the K key, I'm going to see in the keyboard register the value of the scan-code that represents K, which happens to be 75 in as key. So once again, as long as the finger is down, I'm going to see 75. Once I lift my finger off, and nothing touches the keyboard, I'm going to see the default value, which is zero in the keyboard register. Now, I take my finger again and touch four, the key that represents the four digit. Now, the ASCII code of four happens to be 52, and that's what I'm going to see in the keyboard register. Once I lift my finger, I'm going to see nothing, or zero. Put my finger again down, this time on space, as long as the finger is down on space, I'm going to see 32, which happens to be the ASCII value representing space. Lift my finger, I see zero, I put my finger down again, this time on the up arrow key. It so happens that the ASCII code of a up arrow is 131, so I'm going to see this number in the keyboard register, once again I lift it up, I see zero and so on, and so forth. You got the idea. Now, with that in mind, here is the complete character set that the Hack computer recognizes. What you see here is a table, which I split into several columns to make it easier to follow. On the left column, you see the name of the character. It's an agreed upon name, and on the right-hand side, you see yet another agreed upon code that represents this character using some integer value. Taken together, all these characters are the Hack, jack, character set. So, now that we understand the notion of characters, let's move on and talk about the keyboard class. We have chosen to base this class on four subroutines, and here they are. There's no need to read the documentation, because we are going to delve into every one of these subroutines, and implement it carefully. But basically, keyPressed is designed to capture one, Event of pressing a key on the keyboard, readChar is designed to capture the event of reading a character from the keyboard, and then we have read line, which reads a string up to an enter or carriage return character. And finally, read ent does the same, but interprets what it read as an integer. And taken together, this is the API of our keyboard adapter, or our keyboard class. And so, let's go on and begin to implement this class, starting with keyPressed. KeyPressed is quite trivial. If a keyboard key is pressed, we return the scan code of that key, else, we return zero. You may be guessing how to implement it, and if not, we'll discuss it later, when we talk about our implementation nodes. So this is the most primitive function, or input function in the operating system. And notice that this is kind of, it's a realtime listener, kind of a function. In other words, when you invoke it, what you get is what is currently being pressed on the keyboard in this very instant of time, in which we invoke this method. And so it operates on a sort of a blink of a second. You call this method, it returns a value, and that's it. So it's the most real time function that you can think of. Now, readchar is quite different. The readchar function has persistence. It returns the key that was last pressed by the user, and notice this is a very different from keypressed, and I'll try to explain why. Once again, keyPressed is a real-time operation, and also, post and write the program that puts a string on the screen saying something like, press a key. I tell the user to press a key. So now, I have to wait and see what the user will do. See, that's what readChar does. First of all, the user may not be willing to cooperate, maybe he saw this prompt, press the key, and he decided to go and get himself a cup of coffee. So, by the time he returns or she returns, ten minutes had passed, and he, they haven't yet pressed the key, and then all of a sudden, they press a key. Now, I'm exaggerating, but even in real key presses, one key press, it might take a few milliseconds here, and a few milliseconds there. Different users react, have different response times. So at some point, the user is going to press a key. And then, we also have no idea how long the user will be willing to leave his or her finger on the keyboard. Maybe they enjoy putting their fingers for a few seconds, maybe they lift the keyboard, their fingers, immediately. So once again, we don't know. So we see that readChar has to overcome, or handle two sources of uncertainty, how long it takes before the user obliges and presses the key, and how long it takes before the user is willing to remove his or her finger. So, how do we handle it? We have to neutralize this uncertainties. So, first of all, we display the cursor. Or if you want to be nice, we want to show the user where actually on the screen, they would see the feedback of what they press. And then we have to wait until the key is pressed. The most natural way to do it is to use this strange looking while loop. And basically, we say that as long as keypress is zero, we do nothing. So, if you think about it, all the action of this loop is actually in the condition. The condition here is very active, because the condition calls the keyPress function for its effect, and it does it in this loop, which may well be infinite if user is not going to press anything. And so this loop is essentially a mounts to sampling the keyboard, with sample the keyboard until something happens. Now, when something happens, key press will not be zero any longer. So, we're going to be ejected outside this wire loop. And then we can finally capture the key that the user has pressed. We put it in some variable that I called c, and I remembered the finger is down. So, the finger is down. And we don't know for how long, so we are going to wait until the key is released. And we'll do it using a very similar loop, so that as long as the finger is down, we do nothing, okay? And once the finger goes up, keypressed will become, again, zero. And then we can finally give the users from feedback, on what he or she pressed, and return c to the caller. So once again, I hope that you appreciate the difference between readChar and keyPress, and understand that we need readChar to overcome these uncertainties that we cannot control. Well, actually, we do control and quite nicely, but in, within the program level. And then, the next method or function that I'd like to discuss is reading a string. And recall that, typically, when we ask the user to enter something, enter your name, or enter your age, we expect the user to enter several keys, not one, several keys, the name, Peter, or 53, or whatever. And normally, we expect the user to signify that input has been completed by entering Enter, or sometime call it Return. So we have to write some logic to handle this kind of user behavior. And that's what readLine is doing in the always keyboard API. So, we begin, we're going to build the string, right? That's the string that the user is entering, and we start with null. And then we're going to enter some repeat loop, in which we're going to grow the string, according to the key strokes that the user is submitting. So, first of all, we read the character. And notice the beauty of this obstruction, we say readChar, but we know that we've completely handled all the drama of putting the finger down, putting the finger up. All this is encapsulated by readChar, we took care of it. So, we read the character, and then we want to look at this character and check what it is. So, if the character is new line, which is the ASCII code of the enter key, or whatever is this key on your keyboard, then we want to display new line and return the string. Now, display new line is not our business, this is something which is done by the output class, so we have to call the output method that displays a new line, you can check the output API how to do it. And this will cause the cursor to go to the next line. And by then, we know that the str, the string has been entered, so we simply return it, so that's the end of the process. Now, another possibility is Backspace. If the user has entered Backspace, then we know that the character that was last entered should be arrays. So, we move the last character of SDR, and then we also want to acknowledge the fact that the user has pressed backspace. And we do it by calling the output Backspace function. In this function, which we discussed in the previous unit knows how to move the cursor one position backward, but that's not our business. Output is going to do it for us. So, these are the two kind of extreme possibilities of entering characters. So, if it's not Enter, and it's not Backspace, then presumably, we have a bonafide character. We have a real character to work with. So, we take this character, and we append it to SDR, and that's the end of the logic here. We keep on doing this. And notice, that the only way to get out of this loop, is, to encounter a new line, which is exactly what we wanted. And when this happens, we return str. So that's the function for reading lines from the keyboard. So, having described the logic of these functions, I'd like to give you some hints on how to implement them on the Hack platform. So, beginning with keyPressed, well, keyPressed can be very easily implemented using memory peak. If you recall, we have the function called peak, that allows you to get into any register in the RAM and return its value. Well, one of these registers happen to keep the kind contents of the keyboard. So, take it from here, and I'm sure you will know how to implement it. Okay, what about readchar, where readchar simply implement the pseudo code that I showed you in the previous slide. And likewise, readLine, you can implement the same. Well, bits of the code of readLine. And finally, we have readInt. And readInt is a function which is quite similar to readLine, except that we expect the user to enter digits only, and as we read these digits we build an integer from them. And once again, this is logic that you should be able to write on your own, using the guidelines that we gave you before. So, these are all the necessary implementation notes for writing the keyboard class, and with that, we have completed all these classes on the operating system, and we are ready to move on and talk about string processing.