I wish to remind you that next week we're going to take all the chips and the logic gates that we've built in previous weeks of this course. And we are going to assemble them together into a unified hardware platform which we call the Hack computer. Now in order to set up to this very engaging and interesting construction work, we decided that this week we have to give you a good overview of what is it exactly that you're going to build. And that's one reason why we decided to explore all these notions of low level programming, the Hack assembly language, and the Hack hardware. Because at this very low level of operation, everything is tightly coupled. When you build the computer, you have to think about its instruction sets. When you design the machine language or the instruction set, you have to think about the computer. There's no way to avoid it. So once again, the purpose of this week was, first of all, to expose you to low level programming. But we also wanted to give you a feeling of the hardware platform that you're actually going to implement in the next week. This is also the purpose of project four. In project four, you will write two programs that will let you put your hands on the hardware and program it in a very low level. In a level which is almost connected to the machine. So we'll do this by writing two relatively simple programs. The first program will effect some algebraic manipulation and the second program will interact with the user operating on both the screen and the keyboard. All right, so without further ado here is the first program which is called Mult. And the purpose of this program is to compute the product or the multiplication of R0 and R1. So here's a screenshot of this program executing in the CPU emulator. In fact it's a screenshot of the end of this program's execution. If you look carefully at the top of the RAM, you will see that RAM0 is 6, RAM 1 is 7, and RAM 2 is 42. And that's exactly what this program is supposed to do to multiply the first two registers in the memory and place the product of these two numbers in RAM 2. So the assumption is that once the user has loaded this program into the data memory, into the instruction memory, the user also places two numbers in RAM 0 and RAM 1. Clicks the go button or the play button, starts playing and if everything works nicely the program will compute the product of these two numbers. On the right-hand side, in the screen area, we see a script that we supply together with this project. And the script is designed to test the program using some pairs of numbers that we made up. And obviously you can explore the script as well in order to see what kind of tests we're going to subject your program to. And this is maybe also the place to point out that in the simulator, in the CPU emulator, we use the screen as sort of a multi-purpose device. Sometimes it works as a real physical screen, sometimes we use it as a window to display our test scripts and so on. All right, so once again in this area you'll see the two inputs and the output of the program. And I guess the question that burns right now is, how do we write such a program? Well recall that the Hack machine language doesn't have a multiplication operation. All we have is addition and subtraction. So we are faced with a challenge of expressing a multiplication operation using addition and subtraction. I don't think that I have to say much more than this. I can give you perhaps only one more hint, you will have to use a loop. Using this loop you will somehow compute the result. By the way, those of you who will choose to take part two of this course, Nand to Tetris part two, will also go through the process of developing an operating system. And one thing that our operating system is going to deliver is a math library that features all sorts of mathematical operations. And one of these mathematical operations is going to be multiply. And the multiplication algorithm that we will use in the operating system is extremely efficient and something that we don't expect you to do in this exercise. In this exercise we simply expect you to somehow multiply the two numbers, and maybe you can try to do it as efficiently as you can. But we don't expect you to get out of your way and come up with some very fancy algorithms to carry out multiplication. All right, so this is the first assignment. And the second assignment is to write a simple interactive program that performs the following operation. This program listens to the keyboard. And as long as the user does nothing with the keyboard, nothing happens. But once the user touches a key on the keyboard, any key, once you touch a key, look what happens, the program blackens the screen completely. And once you lift your finger from the keyboard the screen becomes again, clear. You put your finger again on any key on the keyboard, the screen becomes black. You take your finger away, the screen becomes clear. That's what this program is doing. It is going through some sort of an infinite loop. That listens to the keyboard all the time and acts accordingly. So actually we have here two separate challenges. One of them is to probe the keyboard and understand whether or not any key is pressed. And the other challenge is to be able to blacken the screen or whiten the screen, which is essentially the same operation. In one we write a certain value to the memory map, and in the other operation we write some other value. What makes this exercise somewhat easy is the fact that we operate on the entire memory map. So we don't have to be picky and select certain pixels to turn on and off. We simply, sort of a shotgun approach, we either turn on all the pixels or turn off all the pixels. In that respect, the program is not terribly complicated. And in general, it's not really a terribly complicated program. But it's kind of fun. It allows you to see how you can control peripheral devices using standard Hack machine language code. All right, so here is the general implementation strategy. Listen to the keyboard, to blacken or clear the screen. We write code that fills the entire screen memory map with white or black pixels. And in order to do this, we have to address every register in the memory map. And we do it using some sort of a loop that works with pointers in a very similar way to what we did in the previous unit when we discussed pointers manipulation. So you really have all the firepower that you need in order to implement this particular program. In order to test this program on the CPU emulator, make sure that the no animation selection is selected. And also, we cannot provide a test script that tests this program. Or we can, but we thought that it would be too complicated. So we simply have to test it as I demonstrated, put your finger down, put your finger up, and hope that the screen will be blackened or whitened, and so on. You can also think, if you want, you can think about some fancy ways to blacken or whiten the screen. Instead of going line by line, you may want to go column by column. You may want to create some this'll be quite challenging to create some drawing, swirls, I don't know. You can use your imagination, do whatever you want in order to blacken or whiten the screen. And that's actually what is expected from you in this particular program. All right, I want to describe some general things about the overall program development process or cycle when you want to write programs in the Hack machine language. First of all, your programs are going to reside within regular text files that you can write with any text editor. So, you invoke your favorite text editor, you write the program, you save it using the extension asm. And, by convention, we give our programs names that begin with capital letters. So, we give it a name .asm and then you load this program as is into the CPU emulator. As I explained before, the CPU emulator has this very nice service that when you load the program, it automatically translates the program into binary code. So you can next run the program on the CPU emulator and ask yourself if you are satisfied with the results. If so, you are done. You can submit the program to us. And if you're unsatisfied with the program which will be probably the case in the first few iterations of debugging the you'll fix the program. You'll look for errors and you fix the errors. And you fix them by going back into the text editor, working in the editor or saving the program again, reloading it into the CPU emulator and so on. So it's quite convenient to have two windows opened on your screen at the same time, text editor here, CPU emulator there. And you can easily move between the two, but don't forget to load your updated program after you fix it. The error diagnostics of the CPU emulator is quite primitive. So when you load the program in to CPU emulator, if there is a syntax error in this program, the CPU emulator will simply refuse to load it. It will issue some cryptic error message. It will give you some very important information. It will give you the line number where the error occurred in the first error that was found. And then you can go into this line number and fix the problem. And once you're done with the syntax errors, well, then the real problems begin. These are the runtime errors, which are much harder to detect. And you typically detect them by watching the execution of your program, seeing that something does not work properly. And then once again you have to go through the same cycle and fix your program until it works to your satisfaction. So this is the general mechanics of developing a program using a CPU emulator and a text editor. And as you see it's quite aimple and friendly. All right, finally, I want to say a few words about best practice and advice on dos and don'ts. There's no reason really to think about machine language programs as some sort of a strange animal. It's yet another example of programming artifact. And all the principles that applied to writing programs in a high level language also apply at the low level. We expect your programs to be short or not unnecessarily long, they should be short, they should be efficient, they should be elegant, and they should be self-describing. So we expect you to document the programs, but do it by using some judgement. Don't over document the program. The best, I think, to do is simply to look at our examples and follow something similar. So typically we use some high level operation to describe, we start a comment we write something like here we are going to say if I is greater than n go to. And then we write the six or seven instructions in machine code that actually implement this semantics. Now, here are some very important technical tips that will make your life easier. First of all, you must use symbolic variables and labels. Otherwise your programs will be helplessly, and hopelessly, complex and cryptic. So if you want to go to somewhere in your program, use a label. If you want to store something repetitively, make up a variable name. So when you're done writing the program,look at it and make sure that you don't see any actual addresses there. You have to make sure that everything is symbolic. This is one very important of virtue of well written machine language programs. When you invent your variables and your labels, as usual in programming, use sensible names. Don't make cryptic names like GU53& or something like this. Use instead something like Loop, End, Stop, Positive, Negative. Depending on what is it that you want to do, try to use sensible label names and likewise variable names. Use nice names like i, m, sum, count, and so on. Now, when you declare or when you use these variable names, use lower-case for variables and upper-case for labels. If you go back to our program examples, you will see that all the labels, typically words like END and STOP, were upper-case. And all the variables, i, n, x, y, and so on, were lower case. If you follow this convention, which is not required by the way, it's not something that the assembler cares about. But if you use this convention you will have a very easy time for yourself to distinguish between variables and labels. So when you see an a at command, an a command, when we see something like at some, if the sum is lowercase, it's a variable. If it's in uppercase you know that we mean to go to a label called sum. And finally, use indentation. Once again, follow the examples that we gave in the previous units. And make sure that your program are good-looking and easy to read. And it's always recommended to start with pseudo code. Writing machine level code is always challenging. And your life will be much easier if you first make up the program or write the program using some sort of a high level language that you can make up for yourself or once again, follow our examples. Once the program works nicely in pseudo code, and this is something that you have to check on a piece of paper, you can then translate that into machine language and continue the debugging process. All right, where do you find everything you need? Well, as usual, you go to the Nand to Tetris website, you look at project four. All the files that you need for this exercise are described in this project. Are described in this webpage. And there is no need to download anything because if you downloaded the software suite at the beginning of the course, you now have, on your personal computer, you have a directory called project/04. And this directory already contains all the files that you have to use and manipulate in project 4. So, this has been the unit in which we hopefully gave you some tips on how to write the programs in project 4. And we now go onto the last unit in this week in which we reflect on what we did during the entire week.