 Hi and welcome to another Commodore 64 programming video I just wanted to put out a short video That I hope you'd be interesting to those of you haven't seen something like this before or for a while I mean if you're interested in Commodore 64 programming then you've probably seen dozens of these types of types of video So it's going to be a comparison between a simple basic program and then the equivalent written in assembly language You probably don't need any convincing of the speed virtues the speed difference of Programming in assembly compared to basic, but Assembly is a lot more difficult, especially if you come from basic I think if you started out with assembly you wouldn't know any better and You'd be stunned by how simple basic is you know the other way around it could be quite a step up So you might you know Hopefully find it useful to see how you do the basic program in assembly and fun to see the speed difference And anyway, whatever I'm gonna try and record this live and have minimal editing You know just so you can see a program being coded live and you know Try keep the video as short as I can so you know I don't roll on too long you lose interest I am working on if you've seen my one-pong video, which is a basic Commodore 64 basic version of Yeah, variant of the game Pong for one player You'll see how slow basic is. Yeah, it looks quite nice, but it's Yeah, it was Simple to write because it was in basic, but very slow and I'm working on an assembly version of that which will be too quick Such as the speed difference, but in the meantime And without further ado, let's let's get on with it So what this program is going to do is ask the user to press a Character on the keyboard and then it'll fill the screen with that character So the first thing I like to do is clear the screen And instead of writing shortcuts like I could instead of writing print I could put a question mark and the computer would turn that into the statement print But for readability so you can follow along and if you're new to programming Completely I'll just type the statements out and leave nice spaces everywhere so that yeah, it's just easier to read so on the Commodore 64 if you print The character that's represented by the number 147 it'll clear all it'll clear the screen of all text Okay, so if I just run that now you can see that happens and then the program ends so you get them ready prompt again, but all the I just Right again. Yeah, you see just clears the the screen will take so let's get the listing back up Okay, um Next thing we're going to do is ask the user For input so we can say press any key or run stop to quit I'm using the vice emulator And so runs up is mapped to the escape key You know just to keep the parlance um In common or 64 terms. I'll use the word runs that run an escape So let's just check that works. Yes. Now. We actually need to ask the user for the input so 30 We are going to get now If you wonder why I'm not using input As opposed to get input puts a question mark on the screen and a cursor. Well, we'll do both so I'm just going to store it in a a string variable called a um We'll leave statement if a so you get a little input loop while we're waiting for the user to input something So if a is nothing I'm going to go to 30. We're going to keep waiting. Let's run So you see you get the question mark and the flashing flashing cursor block when we use the input And we have to press enter afterwards to submit our Entry If you change input to get We don't get that and as soon as you press a key it instantly Enters that and you know returns it to the That key press back to the program. It would store it in a So So you see I'd press the letter k Because that doesn't get cleared out just because the program ends Okay, so let's uh Carry on so we're going to ask the user for that Once we've got that We need to Because you can't poke string Variables to the screen or poke them into memory So I'm going to need to convert the character that's been pressed on the keyboard To the the number so you can see a print chr147 in there in the brackets there I need to get the number for whatever key has been pressed. Okay, so we're going to store that in b b with those no dollar symbol afterwards means it's going to be an integer the whole number So b is going to be equivalent to the ascii representation or the ascii number of the a string Yeah, that's wrong So I'm going to press e if I print a dollar If I print b I get 69 So That has worked So we're going to get that I get along 50 For loop now the screen is made up of A couple of 64 text mode screens made up of 1000 squares. So there's 40 columns along by 25 rows high And so you multiply 25 by 40 and you get a thousand now computers start counting from zero It's just the way it is So this for loop is going to be We use n as the variable Zero to 999 so that's 1000 inclusive. We are now going to poke 1024 which is the first space The first memory location for screen memory So that'll be the very upper left here that so where you can see press any key the p for press It'll be in the space directly above that We're going to poke into that Wherever is held in b and then Because that will just poke that into that space a thousand times what we need to do is 1000 variable plus n So the first time through the loop it would be zero so it'd be 1024 it'll be 1025,000 and 26 onwards We're going to poke b into that Next I think that's us done I'm going to press j Ah, so what's happening here then what is happening is on the common of 64 Uh each key has you can represent different a couple of different characters usually Now on the keyboard that i'm using on this computer because i'm using an emulator. I don't know Uh, I can't work that out quickly to know You know what it thinks I've pressed But I do happen to know that to get the alphabet is offset by 64 Um, so I need to whatever b is I need to deduct 64 from it To get the actual the letter of the key that that was pressed Can I just do this? I'm going to press j when it asks me Yes No, I'm not timing that But It's pretty slow That's got to have been the better part of 10 seconds to fill the screen there Try again Yeah, about 10 seconds So that's great Um, we've got we've achieved the goal of of making the uh, you know a program that asks the user for input Then fills the screen with that input Um, you could just do a couple of things to Enhance the program maybe I like Black and white contrast so What i'm going to do here is at the very start Before we even clear the text off the screen I'm going to poke into the memory location for the I think that's the border I'm going to poke in the value zero which is black and I'm going to poke in Backgrounds The memory location for the background color will poke a zero in there I'm going to poke a zero into the memory location for the text Sorry, poke a one in the memory location for the text color So that she gives white text on black background and black border Indeed Now once it's completed Filling the screen We could go back and ask you get it to wait for another key press So it doesn't just have to end after it's gone through once So let's do that 60 go to 30 don't need the instruction again. We know what's uh, what's expected of us Yep, that works fine now As exciting as it is watching the screen flow of characters this way That we we can't you know Can't really go any further you know I don't think we need to so Let's uh write the equivalent program in assembly So this is visual visual studio code with kick assembler c64 extension installed Which just makes um syntax highlighting in the error spotting You know a bit easier It will assemble to the code on 64 debugger I've got installed which might look a bit scary when you see that running, but Just ignore it. Just look at the screen representation um I like to use that because I could see then in real time how a program is running and I'll I'll briefly show that but Without too much rambling. Let's uh carry on so with that Assembly we have to we have to worry about where we're going to put a program into memory whereas with basic We just let the the basic interpret. I'll let the code as it will handle all of that for us But here we have to put it somewhere in memory. So we specify that by using an asterisk equals um, I'm going to put a hex number for memory and I use a thousand I'm going to use a thousand in this case which Translates to a thousand four thousand and ninety six in hexadecimal Sorry a thousand hexadecimal which translates into four thousand ninety six decimal So when we're on the color 64 in the programs in memory would type sys Four zero nine six and that would start executing code starting at that memory location. So we've done that Now what was the first thing we've got the program to do is to set the border in the background color to black And the text to white So you can't have multiple commands on the same line In assembly each one has its own Has its own line don't have line numbers either. So although you can see line numbers on the side of it That's really just for our reference the program has reference Um computer the compiler the assembler doesn't use those they use labels So we're going to start with start a label called start So we're going to do the setup if you like of the program in this in this section Then when we reference start it the computer will just jump to wherever a start begins in memory We don't have to worry about adding line numbers and running out of line numbers. So that's one kind of advantage I think assembly well including the speed as well um Okay, so we're going to clear the screen. I'm going to do that using a kernel routine Which just means a built-in function of the common of 64 So jsi means jump to sub routine and I just so happen to know that that's a memory location hex e544 So that will clear the the screen for us um yeah It'll clear the screen of all text. I should say There's a difference. We won't need to cover that in this in this video. So we're going to do that. They're going to start we're going to Change the border of background colors. So in the load a the accumulator That which is a register You maths with but you can just store store numbers in it as well Same as the x and y register, but we use accumulator load accumulator with the number zero for black I'm going to store that in the memory location That handles the border color and the background color So you remember for the basic program. It was five three two eight zero five three two eight one Well, this is the hexadecimal equivalent and we're all so now we're going to load a with The code for white, which is one store that in zero two eight six Don't know if I need the zero or not Actually, but it should set Clear the screen and set set the colors Okay Well more to go to do here because I know that I'm going to need to use a loop And I'm going to need to count through the loop like with the for loop in basic And I load x with Zero x is another register. I'm going to use that for for counting in this case. You know, I'm pretty sure I don't need to double zero For the leading zero It's just assumed um, yeah So we're going to do that And that should be us set now. So the screen to be clear the colors will be set now. I need to ask the user for input so Let's have uh, we need to put a Have a message an intro text user text specifier here And that the assembler then will convert everything in the Speech marks afterwards Into the actual numerical code You know the hex code for the for the characters that are That are typed in here. So it saves us a lot of time So please this is a feature of kick assembler please Please press any key or run stop to quit Now we want it to nice reach the end when it reaches a zero and intro loop Okay So what we're going to do is load cumulative with The intro text And that'll be the first character will be stored in x at position zero I'm going to store that in the screen memory location first screen memory location Which in hex it's not 1,024 like on basic it's 400 hex We've enough set of x again set zero because we're going to loop up incrementing each time um Once we've reached the end of the of the of the text It's a branch if equals so and a branch if equal to zero If the zero flag where x is zero Um, let's quit which returns us to basic However, we haven't finished displaying the message We're going to increment x just by one I'm going to do this intro loop again. I do this time around x will have incremented And it'll keep incrementing all the way through this So it's done And it hits the zero Then this will be true. So a branch If x is zero and uh It'll just quit. I think we should probably see if this works So I have to type sys 496 It does work Although Didn't change color until after That's interesting the screen wasn't refreshed So if we do the color change first which to be fair and basic That's what we did. We did all the color changing then we cleared the screen of text Uh That should solve that problem. Let's see sys 496 Did I not save it? Was that the problem? That was the problem and now I'm missing the p Seriously, I don't think that has any influence on the x register It's like x has got one in there or something Okay Um, so this sub routine must use x within it And therefore the you know It was interfering so There we go, so that works we are getting um We are getting a A funny character aren't we at the end we're getting that symbol at the end. Let me run that again. I think you're gonna stop to quit Yeah, that's fine. Why are we getting that at the end because this check should be done before we out Put anything to the screen To really hit it. We'll be storing a bit of extra garbage data To the screen Right before we branch away Yep, it really is this complicated folks Just for the most simple programs I'm not really seeing any of that lightning speed that's promised Yeah, are we um, okay So, uh That's all well and good And we don't want to be quitting just as soon as that message is printed. We want to be doing something else so Good thing about labels in that in assembly is it doesn't matter where I you know, I could start right back up the top here if I want to for For the sake of flow And good practice. You kind of keep them in order Um, but I tend to have things like quit and any texts label, you know text sections um At sprite data or whatever Kept separately down the bottom. Um, so I'm going to put this next one in In here which is going to be We need to wait for the user it was the if statement was with a get statement. Sorry get a dollar symbol And then keep asking for it if nothing if nothing is pressed. Yeah, keep waiting So let's just see how that works. Um An assembler so get input we're going to use is another built-in kernel function Which is at memory location ffe4 So that is the equivalent of get Um, you can't specify where or variable it's going to be stored in it'll be just to be stored in the accumulator In the a register So we're going to compare that To zero Okay, so if nothing is pressed zero is that at symbol, you know I've represented by that at symbol that you We saw previously what I was having that that we had at the end of the intro text Because it's pretty nonexistent character. It's just whatever happened to be in memory. So anyway, if it's zero branch if equal Back to get input so if nothing This is that whole get a dollar If a dollar is zero go to the same line number. So it's uh It's about the same kind of length. It's just not as intuitive to get used to it Um, that's what we're doing here. Okay, so let's say something was pressed How are we gonna know if it's the run stop key? We can either compare and Have them to know that 103 is one stop or escape if it is so branch if equal so Same go to if equal Quit okay Anything else It must be a character that we want to use to fill the screen with So what we're going to do is Uh, I'm not going to have time to explain all this if I want the video to be short But we've got to set the carry because we're using um So we're going to be subtracting because they're the processor in the c64 can't actually do straightforward additional subtraction um Yeah, I'm not going to go just know that if you're subtracting a number You need to set the carry flag And then we're going to subtract with carry 40 which is that 64. So, you know, I had the ASCII Um, I got whatever the character was and took 64 off of it when hex that'd be 40 So we're taking that off of it here So we get the correct letter straight away um I'm gonna be Using the next loop again To fill it to the screen. So we've got our input now If there's no jump Your branch away away from this Execution will Just continue at the next uh From the next label the next commands, you know, it'll ignore this They just start executing the commands under it. Okay. So we'll it will flow kind of linearly um, if we're not redirecting execution Um ourselves, so we're going to we've got to fill the screen up now We so we're going to store the store the accumulator Which which would be filled with whatever letters, you know key has been pressed into screen memory The offset of x which would be zero. So it would just be 1,024 or 0400 There's probably clever ways of doing this Well, yeah, okay Don't want to be too too clever. Um I'm going to show you the results as we go. So Restored uh the accumulator into Screen memory we're going to increment x so the next time around it will fill the adjacent square Yeah, the adjacent yeah Square on the screen Um branch if not equal back to screen fill So it's a carry on until we get back to zero Um, which would be when x overflows from 255, which is the maximum number back to zero We'll see the results of that in a moment and then we will Let's jump back to get input Because then that should have the effect of just kind of freezing Until the user presses another key And obviously if they Yeah, quit or press the escape they can do so Unscripted videos are poor Press any key or runs on the grid press o Okay So we've got half Yeah, or one third maybe of a program Now works fine You know, I think under here. I'm also going to clear the screen on exit This Six Now look on the left here. You can see the loop. So we've raced past start. This is the currently current command being executed you can see we're in a loop It's Lightning quick isn't it? It's constantly looped around get input. We're waiting for the the user to input something So when we do that, you do not see it it jump on the left here to screen fill because it's just so fast But that is what is happening Okay And there we go where we break the program break out of it We're also clearing the screenable text How do you feel? Why isn't it filling the whole screen for incrementing x? Well, I kind of mentioned what the problem is on 8 bit computers the maximum number you can store in a single register is uh 255 Yeah, if all the bits are set to one that equals 255 you add another one it overflows back to zero, but then a carry flag is set often um So that you know You know the overflow has happened don't worry about that We know the screen's a thousand characters 255 is the maximum that we can put in one register What do we do? You know because we need to count up beyond that what we do is is to manually add on 255 to 0400 So that we start there and it's as simple as doing that We haven't actually got to open a calculator and work out this new starting memory location. We can just use this Plus whatever that number is plus 255 decimal an offset of x so let's Make sure we're on the right path here. You can see we are So I'm not going to count each square, but wherever 255 was What's actually happening far too fast for us to see is it's it printing the character there And there or wherever it is And then it'll incur one print there and there. So it's actually filling the screen up from two places At once if you like but far too fast for us to have to worry about okay, but that's that is what's happening Um because in this Loop you see restored the q-layer the letter there 0400 and then we're storing at 0400 plus 255 With an offset of x then increment x and do it doing it again. Whatever doesn't really matter. What we now need to do is Add 255 again which We will do in this case by 0400 plus what was 255 times 2 5 10 okay So let's do that Really there now, aren't we? so we're now to the final one Now x is going up to 255 each time So what we don't want to do is add another 255 and then another 255 Or we'll end up overflowing um the screen area So what we need to do is a thousand less 255 to give us what the Location should be which is 744 and that I think is our Program and I'm sure it's been obvious all the way through my prattling on that the speed difference is Insane isn't it whereas it would take you know 7 10 seconds to fill the screen That is instant isn't it like yeah much less than a single second So there you go. I hope you've learned something and uh See you next time