As we all know, computers are equipped with all sorts of input/output devices, and likewise, the head computer can also be connected to some input/output devices. And in this unit, we're going to talk about how we use machine language to control and manipulate these IO devices. So we start with the basic architecture that we've seen all along, but now, we're going to extend this architecture with two fancy IO devices. We're going to have a display unit similar to your screen, and we're going to have a keyboard, which is actually identical to the keyboard that you're currently using. These devices are sometimes called peripheral because as you see in the picture, they exist outside the computer, they exist somewhere in the periphery of the computer. And here is how we actually use them. Well, obviously, we use the IO devices in order to communicate with the user. We show some pictures or animations or anything that we want to show to the user using the display unit. And we acquire input from the user using the keyboard. Now obviously, we have some more devices like mouse and microphones and so on, but for now, let us talk only about the two sort of most important device units, which are the display unit and the keyboard. How do you control these devices? Well, if you're lucky to work in a high level environment, if you use languages like Java or Python, well, in that case, you have numerous libraries that provide all sorts of fancy way to manipulate these devices. You can create graphics, animation, audio, video, and so on. However, if you work at the low level that we are operating on, the only thing that you have is bits. So, you have to be very clever about it, and you have to figure out a way to use these very spartan 0s and 1s in order to do something useful and display and acquire information from users and to users. Now, you may be wondering, how do we use the high level in order to manipulate IO devices? Because this is also something that we have to learn and understand, how these libraries work. How do you draw a line? How do you draw a circle? And so on. Well, this is something that we deal with in the second part of this course. So, if you want to learn about the software hierarchy, if you want to learn about the design of high level languages and the IO libraries that extend them and how they operate also, how they communicate with the operating system, this is something that we do in the second part of this course. In this part of the course, we deal with the hardware only, so once again, in this course, we are going to talk about the very clever ways in which we use bits to manipulate these devices. So the first thing that we'll talk about is how to manipulate the output or how to manipulate the display unit, also called screen sometimes. Well, how do you do it? Well, the most important player in this game is something called a screen memory map. And a screen memory map is a designated area, which is part of the data memory of what we sometimes call RAM. So the theme is such that the physical display unit is continuously refreshed from the contents of the memory map. And this happens many times each second. So if I'm a programmer and I'm restricted to working with 0s and 1s only, if I want to write something on the display unit, what I can do is simply manipulate some bits in the memory map. And I can count on the fact that in the next refresh cycle, what I change in the memory is going to be reflected on the screen. Now obviously, I have to be very careful about it, then if I want to write a text like Hello world, well, it's going to take a lot of work. I have to turn on and off pixels in very specific locations in order to effect this particular output. So we do some of this today, and we'll do some more fancy, input/output operations, some much more fancy operations in the second part of this course as I explained earlier. All right, so let's delve into the screen memory map. This is how we used to think about display units, but as far as the hack computer is concerned, the display unit is the following obstruction. It's a table or a matrix consisting of 256 rows and 512 columns, and in each intersection of a row and a column, we have what is known as a pixel. This is a black and white screen, so we can either turn the pixel on, or we can turn it off. This is the physical display unit that the hack computer assumes. Now, how do we control it? Well, as I just explained, we have something called a memory map. And the memory map is a sequence of 16-bit values. Every one of these values is sometimes called a word. So we have, altogether, 8k 16-bit words. Why do we have 8k 16-bit words? Because it turns out that 8k times 16 gives something like 13,000 and something, and this is the number of pixels that we have on the physical display unit. So for every pixel on the physical display unit, we have a bit that represents this pixel in the screen memory map. And if I want to turn on this pixel, I put 1 in this bit, if you want to turn it off, I put 0 in this bit. So in order to understand and control these bits judiciously, I have to come up with some mapping that describes exactly which bit corresponds to which pixel. Now, this is a little bit involved, because on the right hand side, I have a two dimensional abstraction, and on the left hand side, I have a one dimensional abstraction, and I somehow have to connect the two. So, how do we do it? Well, first of all, you should notice, and I'd like to reemphasize the fact that when we access memory, we can only retrieve 16-bits in one chunk. We cannot access individual bits, if I want to access an individual bit, I have to figure out, first of all, in which word this bit resides, so to speak. And then I have to retrieve the entire word, do something to this value and manipulate this particular bit, and then I have to take this value and put it back, write it back into memory. So the read/write operations are always 16-bit operations. So I take the 16-bit out, manipulate something, and put it back. All right, so what is the mapping? Well, here it is. The first 32 words in the memory map correspond to the first row in the display unit, okay? So the first pixel that we see here and actually you can see it in the picture. We see that the picture begins with four black pixels and indeed we see four 1s at the top of the memory. Then we have 0, 1, 0, 1, white, black, white, black and so on and so forth, okay? So that's the row 0, then we have row 1 all the way down to row 255. So this is the first mapping that we have to bear in mind. Now suppose that I want to manipulate a certain pixel on the screen, and pixels on the screen are characterized by a row and a column. How do I map this row column pair on the right register in the memory map? Well, here's how I do it. Well, first of all, I multiply row by 32 and then I compute column divided by 16. And this by the way is integer division, namely I flow away the remainder of the divisions. So for example, if column equals 18 then 18 divided by 16 is 1. So I take the result of this integer division I added up to 32 times row, and this gives me the address of the register that I have to manipulate in the respective memory map. Now, notice the word screen, what does screen means here? Well, in the Hack architecture and in this course, we are going to implement the screen memory map using a chip called Screen. So, we're going to have an 8k chip called Screen, which behaves exactly as a memory unit, we can retrieve data from it, we can right data into it, and this chip will serve as our memory map. However, when we build the overall computer, this chip is going to be part of the data memory. So the data memory, or the RAM, will consist of several chips and the screen will be one of them. You know that's exactly how we described it before, we said that the memory map is part of the data memory. But notice that once you take this screen chip and put it in a larger memory context, the base address of the memory map changes. So if I access the Screen chip, I use the address that you see here. But if I access the overall RAM, I have to take this relative address and add to it the base address of the memory map ,in the overall memory which happens to be 16384. So this is just the technical detail, you know if you want to write to the screen using the screen chip directly, you use the first map algebraic expression. And if you are told that the Screen is part of a larger memory, you have to add up the base address. All right, so we have this 16 bit word, and then we want to manipulate a particular bit inside it. Which bit is it? Well it turns out that this bit is the column modulo 16, it's the remainder which remains after we divide the column by 16. So, we get the number, which is between 0 and 15, we manipulate this bit, we turn it to 0 or to 1. We take the resulting value and we write it back into the RAM. Okay, that's, if we won't do it, we won't change it, right. We have to somehow write it back into the memory map. And in the next refresh cycle, what we just did is going to change the pixel in the outside display. I guess that some of you are kind of shocked at how much work it takes to turn on or off one pixel but that's it that's the reality. If you work in a very low level in the level of bits, that's what we have to do in order to control the screen. Now, I didn't work out all the algebra, this is something you can do on your own. It will take a few minutes if you want but you can just take an example. Let's say that you want to change the bit in the fourth row and in column number 55. Work out the numbers and convince yourself if you are going to access the right bit in the memory. Once again, I want to emphasize that 1 and 3, the fetching value and writing the value back are regular RAM operations. Read, write and we discuss it before when we talk about memory units in general. Okay, now I also want to give you an example of how this thing actually works inside our Simulators. So I'd like to load the Screen chip into the Memory manipulate it and we can see in our own eyes how it's actually going to change the screen and manipulate the pixels. So let us load the built-in Screen chip. So we look for Screen and here it is. Loaded it, I can inspect the HDL code and see that indeed the screen shape is built in chip, and it's a memory chip. And if I look at the input panes and the output panes I see that it has the typical memory chip interface. It has an in input and out output and load bit, that must be asserted before right operations. And it has an address, that enables me to select a register on which I want to operate. Another thing that we can observe is that the Screen built-in chip has a GUI side effect, which is this panel here. Which represent or simulates physical screen consisting of 512 columns and 256 rows. And every one of these rows is represented in the Screen memory chip by 32 registers as we explained in the lecture. So let's say that we want to turn the first 16 pixels of row number 3 to black. So in order to do this, we have to get to the register that represents the first 16 bits in row number 3. So we do 32 times 3, which gives us 96, this is the address that we have to manipulate. So we write 96 in the address input, we assert the load of it because we are going to write something into the memory. And we have to write 1, 1, 1, 1, 16 times and it turns out that 1, 1, 1, 16 times in decimal and 2's complement is minus 1. If you're not convinced we can turn The representation to binary and we see that indeed we go up 16 1s. Let's turn it back into decimal, which is easy to read. And we see that it's very nice that we enter all these values into the memory but we haven't ran the clock. So nothing really happened, this is a memory device. So let's run the clock, and we see that once we run it, we get two things happen. First of all, the memory now contains this value in address number 96. But also we have the side effect of seeing 16 black pixels at the beginning of row number 3 in the physical screen. Now, let us write some other arbitrary value in some other arbitrary address in the screen. So, we go to the address input. We pick up some arbitrary address like 3035. And let's pick up some arbitrary value like 17 that we want to write into this address. And I'm not sure how many 1s we have in 17, let's turn the binary on and we see that we have only 2 1s. So this is not going to be extremely visible. But in any rate, let's run the clock and indeed we see that these two babies popped up right in the middle of some obscure screen location, which happens to correspond to the register that we manipulated in the screen memory map. So, these two pixels obviously correspond to the 2 1s that happened to be the only two 1 bits in the binary representation of 17. So, this has been a demo of manipulating the physical screen using the respective memory map via screen chip that controls it. So, the next thing that I want to talk about is the input unit. How do we control and manipulate the keyboard? Well, the physical keyboard is connected to the computer using a cable. If you will trace this cable, you will see that it goes into an area in the RAM, which is called keyboard memory map. Just like we had the screen memory map, we also have keyboard memory map, and this is the representative of the keyboard inside the computer architecture. Now, it turns out that in order to represent the keyboard, you don't need more than 16 bits. So, the keyboard memory map is a single register, 16 bit register, which is called keyboard, and this is how the connection works. We have a special chip called keyboard, which once again is simply a 16 bit register. And in the next few minutes, I'm going to describe how this thing actually works, so we'll do it using examples. When a key is pressed on the keyboard, the key's scan code, which is an agreed upon value, travels through the cable and appears in the keyboard memory map. For example, if I press k, there is an agreed upon value, which is happens to be 75, a completely, well not exactly, but almost an arbitrary value. And this value of 75 is going to appear in its binary manifestation in the keyboard chip. All right, I take my finger off and I click something else like 4. Well 4, it's true that it's a number but on the keyboard, it's yet another symbol so, the scan code of 4 happens to be 52. So if I click 4, I see the number 52 appearing in the keyboard memory map. If I click Space, well Space is yet another symbol. I see the number 32 appearing there. If I click up arrow it’s yet another symbol, I see number 131, and so on and so forth. Every key on the keyboard has a scan key, which represents this selection inside the computer using a binary code. All right, so what we have here is the complete character set of the Hack computer. These are the keys that the Hack computer recognizes. It's a subset of the keys that you have on your regular keyboard, but it's a sufficiently rich subset for our own purposes. Obviously, we could have represented all the other keys, but we decided to represent a subset of keys only. And by the way, if you have 16 bit, you can represent numerous keys and letters in many different languages and it's more than enough. Those of you who are familiar with an ocean of Unicode or ASCII can make the connection between these notions and in what we do here. It's essentially the very same idea. And by the way, when you don't touch the keyboard, when the keyboard is idle, the number that we see in the memory map is 0. So, that's how we can tell if the keyboard is actually being used. The memory map, once again, this a 16 bit register. And if you want to check which key is currently pressed, all we have to do is probe the contents of the keyboard chip. In the Hack computer, we probe the contents of RAM in address 24576 because this is where the keyboard memory map happens to reside. That is, when we are going to build the overall computer, we'll do it next week, we're going to connect several chips together. We're going to begin with some regular memory units. And then we're going to add to it the screen memory chip. And finally, we're going to add the keyboard. And the keyboard in this overall address space is going to be located in address 24576. So if I want to know if someone is pressing the keyboard, I have to look up the value of this particular memory register. If the register contains 0, no key is pressed. If the register contains some other number, well, I can tell which key was pressed according to the scan code, according to this number. So, to make this thing more vivid, I'd like to give you a demonstration of how your physical keyboard is connected to the Hack computer through this keyboard memory map. So that's what we'll do next. Let us load the built in keyboard chip and here it is. Let's take a look at the HDL code and we see that indeed, keyboard is a built-in chip. And, if we look at the chip interface, we see that it's a read-only chip. It has no input pins at all. It has only one output, which omits the value that is currently stored in the keyboard chip. Now, this keyboard Chip also has a side effect which is that the keyboard chip is connected to the actual keyboard that I'm using on my computer, on my real computer. And so will be the setting at your end. If you use a hardware simulator, the hardware simulator is connected to your physical regular keyboard and if you touch the keyboard, if you press any key on the keyboard, the scan code of this key is going to be emitted by the built in keyboard chip. So let us test this and I'm taking my finger now and I'm pressing the key G and nothing happens, well nothing happens because I have to enable the keyboard. So I do it by clicking this button here. So now let us start click G and I'm holding my finger down and as long as I hold my finger down, I will see the scan code of G, which happens to be 71, emitted by the built in keyboard chip which acts as the keyboard memory map. So I'm lifting my finger now and as you see, the keyboard chip now emits the value 0, which means that none of the keys of the keyboard are presently pressed. Let's try another key, I'm going to press Space. So pressing Space and I see that the scan code of space which happens to be 32, appears. Let me press down arrow and down arrow happens to be 133. Let's press a digit, say 8 and 8 happens to associated with a scan code of 56 and so on and so forth. So this has been a demonstration of how we can figure out which key the user is currently pressing on the keyboard. And once again, recall that if the user is not pressing anything, we're going to see 0. So this has been the unit in which we broadened our prospectives so to speak and added Input, Output units to the computer. And the most important part of this unit was to give you an idea of how you as a programmer can actually control these input/output units.