# Running MSBASIC on my breadboard 6502 computer

## Метаданные

- **Канал:** Ben Eater
- **YouTube:** https://www.youtube.com/watch?v=XlbPnihCM0E
- **Просмотры:** 295,661
- **Источник:** https://ekstraktznaniy.ru/video/20729

## Описание

More 6502: https://eater.net/6502
Code from this video: https://github.com/beneater/msbasic

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://x.com/beneater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
19day, Adrien Friggeri, Aleksey Smolenchuk, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, criis, Cristi Cobzarenco, Daniel Tang, Daniel Zimmer, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, Demonia

## Транскрипт

### The MSBASIC code []

I want to get basic running on my homemade 6502 based breadboard computer and conveniently there's this GitHub repository with Microsoft basic for the 6502 it says it can generate nine different versions of Microsoft basic for different 6502 based computers unfortunately none of these are the computer I built so we'll need to see what it'll take to adapt this to work on my computer we'll start by cloning the repo there we go and basically the only thing the documentation really says is that we run make. sh to generate all the different versions of basic so I guess that generated everything um and to see what it's doing let's take a look at that Mak script so it says if there's no temp directory then it makes a temp directory and then it iterates through all the different versions basically setting this variable I to each of these strings then for each one it echoes I which I guess is what it was doing here was it's printing each one out and then for each one it runs the assembler and the Linker so ca65 is the assembler and it's assembling msbasic dos it's assembling the same source file for each of these different versions of basic but the- D creates a Define um so it's defining a pre-processor variable equal to you know uh each specific version and then the output goes to uh Temp and then whatever the version is. O then l65 is the Linker it's taking thato file and it's creating an output of a bin file also in Temp and it's using a different configuration file um for each version again with just the version name. CFG and then it looks like it's also creating a symbol file um in temp the version name. Lael so if we look in that uh temp directory we can see for each version there's AO file a bin file and a label file so we want to create

### Creating our own version of MSBASIC [1:42]

our own version of basic so let's uh take a look at how one of these existing ones works so you know in each case the assembler is running or is assembling this Ms basic. s file so let's start there so here we can see basically all this does is includes a bunch of other source files with different parts of basic um but the first one it starts with is defines dos so let's take a look at that and in here it just has a bunch of conditional compilation directives so if CBM basic is defined uh then it sets cbm1 uh to one it includes this defined cbm1 otherwise if OSI is defined then it sets OSI to one and it includes this different defines file otherwise if applesoft is defined it sets Apple to one and includes this different defines file so basically it's doing this for each of the different versions so if we want to add our own we could uh just go down to the bottom here right before this end if and say else if eater is defined now we'll call that our version we can set you know a similar variable to one and then include our own Uh custom defines file so now we need to create that custom defines file so we could just copy one of the other ones and if we look there's a bunch of them in here if we just look at the different defines files there's the main defines s we were just looking at but then there's one for each different version so you know we could take the one for uh commodor Basic 2 and just copy that so if we copy that then we'll be able to edit that new file and configure our version of basic to work for our specific Hardware as you can see this file has a bunch of different configuration options so that seems promising so if we look back at the readme file in the GitHub repo it's got some documentation for different configuration options that we could set you know for example it's got this one um config defined that specifies which version of or Microsoft version of basic we're using so in our case you know we copied the config from commodor Basic 2 so we're going to be using config 2A and that's what's configured here then the rest of this file is a bunch of configuration options as well as you know pointers and other variables and some of these options turn on commodor specific features that we don't have hardware for um so what I did to figure out what in here is absolutely necessary is just to comment out everything and start from there so I'll start with nothing in this configuration file other than saying we want Microsoft uh basic version 2A and go from there now to build it there's the make script that you saw that builds each version um so I'm going to edit that script to have it now build our new version so here's where it goes through this list and just builds each of these versions so we can add our new version to the end here or you know since we really don't need to build all the other versions We could actually just delete them as well so now this will only go through here once and I will just be equal to eer um the one time it goes through so that'll build our version so if we run that we get some errors which is not that surprising at this point you know because my process here is basically try to build it like this and see what errors we get and then you know investigate what's missing to generate that error figure out what makes sense for my particular hardware and you know to fill in that missing thing whatever it is um and so it looks like we've got

### Zero-page configuration [4:53]

some errors here in zero page. s lines 56 40 and 67 so let's take a look at those so we'll edit zero page. s and so line five is this org zp start one and the other errors if we look at those is you know org zp start 2 somewhere there zp start 3 and zp start 4 down here and what's going on here is this file is defining a bunch of variables in the zero page and the zero page is just the first 256 bytes of ram um you know but the 6502 treats it differently a lot of instructions run faster you know they take fewer clock Cycles when working with data in the zero page rather than elsewhere in memory so if you have a bunch of commonly used variables it's a good idea to put them in the zero page like this and then so that's what's going on here it's just a list of variable uh variable names and then reserving a certain number of bytes for each one but I guess you know different implementations of basic put these in different locations within the zero page and I think that's what these zp start uh org directives are are saying exactly where in the first 256 bytes uh do these variables go so if we go to our defines file here that we copied we don't really care you know in our case how the zero page is arranged as long as everything's there so you know we can look here this is how it was configured for the Commodore and it actually seems a little jumbled up right so zp start one is at address zero that makes sense but if we jump over to that file zp start one we see we've got three uh six8 10 bytes of variables after zp start one before we get to zp start 2 but you know here it puts zp start 3 at address 3 so it seems like that overlaps and you know maybe that's fine and maybe the commodor implementation doesn't actually use all those variables I don't really know uh but I do know that after zp start one there's 10 bytes of stuff so I could put zp start 2 on my computer at 0a and it would just follow those 10 bytes and then same thing after zp start to I can count up you know there's one two 3 four looks like six bytes before zp start 3 so let's see if I add six to a that's 16 and then after zp start three we've got one two see one two three four at least six 7 8 9 10 11 another 11 bytes and then after zp start 4 well it doesn't really matter there's nothing after that so if we start at z a 1 Zer and 1 B that puts all those zero page variables in the zero page without overlapping except actually if we switch back and look closely there is one variable here input buffer which doesn't Reserve any space and so we haven't left any room for it but we need to and the input buffer is where you know whatever instruction we're typing is going to get stored so we need to leave enough room for a line of text and so we could do that by bumping zp start 3 and four to you know 60 and 6B just to leave plenty of room after zp start 2 for that input buffer and going back to the readme file this is actually something that kind of differs from one version to the next so you can see in commodor Basic 2 it actually doesn't put it in the zero page it puts it somewhere else in memory for input buffer but we can put it in the zero page that seems simpler um so we'll go with this so let's save that and try building it again now we' got a couple errors in anits lines 395 418 and 434 so let's take a look at what's going on there so we'll go to line 395 and it's saying that this config scr TCH whatever that is order um is not defined and that's what the other errors are as well if we just search for that we can see it's checking if it's one at the top here two and then the next one is checking if it's three and those are the three errors that we're getting so it's just that one variable that's not defined and I'm not really sure what scr TCH is uh but it looks like there's a sub routine um that it's calling with that same name and then depending on whether this config variable is set to you know one two or three it's just calling that sub routine in a different place and again I'm not really sure what this sub routine is or what it does exactly or what difference it makes when it gets called um but you know I tried setting this variable to um different values and as far as I could tell it didn't seem to make any difference but we do need to set it here in the commodor basic 2 config it was set to two and like I said I couldn't tell the difference but you know maybe someone in the comments will know what it does and can tell us if it matters but anyhow with that set now let's try building again

### Configuring our version [9:32]

okay so now we've got lots more errors and it's all a bunch of undefined stuff so these are probably things we're going to have to Define and come up with uh reasonable values for so let's get back to our defines file and uh I'm actually going to run make again inside the editor here so it just be kind of easier to switch back and forth okay there's the output with all the errors and we'll start with ram start 2 here so we can uncomment that and this refers to where Ram starts um not counting the zero page or stack or anything and you know 0400 seems reasonable that's in RAM on our computer so we'll go with that go back to our errors here next we've got width and width two and those are defined here as well as 40 and 30 and I'm not actually entirely sure what widths these are referring to you know my first guess would be terminal width but I don't think that's right since these values seem to work for me with an 80 column terminal and longer instructions um so as long as these work I'm going to leave them as is then we've got C out that's down here and it's set to um character out which is defined up here as ffd 2 so we can simplify this by just setting mon C out to ffd 2 and so what this is defining is the address in the commodor of the function to Output a character now on my computer this will almost certainly need to be a different address like I talked about in my last video you know we're going to have what I was calling a bios routine to Output a character somewhere in memory and we'll have to put that address here but for now I'm just going to leave this wrong address um and you know we'll have just have to come back to it so then next we've got uh this is control C and same deal here it's defined to be equal to that address so again we'll have to come back and fill in the right addresses when we get these functions um in memory uh next we've got stack top and for now we'll just leave that as it is here fa next is mon read key and same deal as mon C out I'll replace this with ff4 for now but know that we need to change these then we've got space for go sub I'm also going to stick with this like it is as uh 3E and like I said I'm not the expert here both of these appear to do with the stack which is normally in memory at uh 0100 through 01 FF uh go sub is a basic instruction for calling a sub routine um which requires pushing some info onto a stack somewhere and I think this is saying how much space is needed on the stack for that um and you know maybe in our particular case it could be smaller I'm not really sure why this would be different from one version to the next uh but my thought process here is I'm just trying to get this working at the moment um but if we do run into trouble depending on where the problems we have crop up these are some things we might want to come back to and try to understand better but for now I'm just going to go with this so the next undefined thing is user and that's just pointing to go restart and now user is an instruction in basic uh that it's a way of calling into a user to find assembly instruction routine um from within basic and I'm not sure what this particular variable does in relation to that but again I'm just going to leave it like this um but you know if we get everything working and the user instruction doesn't seem to work quite right this could be a good place to start and then finally we've got save and load and those just point to bios functions for loading or saving a file uh which we don't have yet okay so now that we fixed the undefined things that it was complaining about now they're at least defined even if they're not right let's try building again okay so now the only error we're getting is that there's no config file um and that's coming from the Linker so that means that the assembler was actually able to assemble everything and now we're just missing this config file for the Linker

### Adding our BIOS code and Wozmon [13:08]

but before we get into the Linker config I want to um bring in the code from the last video the BIOS code and the won code and that's because you know those missing um read character write character instructions those are going to be coming from this bios code that has the code that's specific for the hardware for my computer and you know in poking around a bit I found that this Microsoft basic repo has a pretty convenient way of including extra code like this into the image that It ultimately builds so if we go back and look at that main file um msbasic dos you we saw before this includes all the different parts of basic uh but at the very end it has this include extra. s to include extra stuff apparently and if we look at extra. s you can see that for some of the different versions it's including um an extra file and so we can do the same thing so at the bottom we can say that if eater is defined then we want to do some stuff and we'll close that with an end if then we'll include uh bios. s and so that should do it let's see if that builds it's now it's saying in Wason uh symbol run is already defined and you know so I guess For

### Linker configuration [14:15]

Better or For Worse there's a single Global name space and I guess basic is using the label run for something and so if we look in wmon we can find that run variable or run label and we just need to change it to something else so we can call it run program something like that and then where we call it up here we also want that to be run program and I think that's the only place that shows up and hopefully that's not already used as well so let's try building that again okay so that assembled and now it's just back to the Linker again looking for its config file so to create that config file you know just like the different defines files each different version of basic has its own Linker configuration file so we could start with one of the existing ones that are here you know like the one for the Commodore basic version two we can just copy that over and if we look at what we've got there this should look at least a little bit familiar if you watched my last video we've got a memory layout with the zero page starting at address zero and the size is 256 bytes and it's read write so that describes the zero page that makes sense then we've got base ROM which you'll see is where in ROM basic is going to be loaded and you know I guess in the Commodore it's address c0000 and in this case it's set to not be padded with zeros so Phill no and it's being written to the default file name percent o means whatever output file was passed on the command line so in our case that'll be eater. bin then there's this dummy memory area which It also says it starts at address zero uh but it's not actually written to the file so the file name is blank so it doesn't uh that explicitly tells it to throw away anything that would normally go into this memory area and there's also a dummy segment down here that's loaded into that dummy area and all of this seems to be part of I guess some sort of hack that um uses macros and some other tricks to kind of help with uh this single code based thing being able to build basic for all the different Hardware platforms um as far as I can tell for our purposes we can just leave this alone it's not written to the output file um and doesn't have any other effect that we really care about but now that we've added our bios file um it's got some new segments defined in it so we've got this bios segment for example which has the code for character in and character out get character in character out we've got well we're including Wasson which has a Wason segment and we're now including this reset Vector uh segment as well again this is all from my last video on what I'm calling our bios so those new segments are bios wmon and reset VC and you know the BIOS segment can be anywhere you know we could just load that into the ROM with the rest of the basic code if we want and it's code going into ROM so it's going to be readon and then Wasson I think we want to put that at address ff0000 so we'll have to make that explicit so let's load that as a special Wason location and of course it'll still be in ROM so it's still going to be readon and then finally the reset vectors also need to go in a special location FFA so we'll load them at the reset VC location which is also going to be readon now for the memory map ROM on our computer starts at address 800 and you know excluding wmon and the reset vectors the size of ROM is going to be um 7 f00 which is about 32k and we do want to fill it since we're trying to create an image file to program to our ROM so we want a 32k file so we'll say Phill equals yes then we'll add Wason and that's going to start at address ff0000 which is where we want that the size of Wason is fa 250 bytes and we want to fill that space as well and write it to the same default file then finally the reset Vector started address FFA the sizes is just six bytes we'll set fil to yes and also write that to the same file so with that configuration let's save that and try building it again and we didn't get any errors so let's see it puts the output in temp we've got eater. o we've got eater. Lael and then eater. bin is the binary file that we're going to write to the ROM it's 32k that's a good sign so if we take a look at it we'll do a hex dump of the output file that bin file we can see a bunch of stuff that looks promising so you know there's a bunch of stuff you know you can see you know 1977 Microsoft company that looks promising um that goes up to you know about 20 about 8,000 bytes I guess a little over 8,000 bytes then it's all zeros up to 7 f0000 which is going to be address ff0000 in the computer and then this looks like wmon and then the last six bytes look uh plausible for the reset Vector so that's great but of

### Pointing BASIC to our BIOS [18:50]

course it's not going to work yet right let's go back to our definitions here and clean this up because of course these addresses for these iOS functions aren't going to be correct so we've got our configuration uh version 2A and we don't need any of this for now so let me clean that up we've got our zero page definitions and then we're not using any of these other zero page variables we just are using our zero page definitions none of this and we got these different constants here and uh I'll clean this up a little bit but as far as the values I'm going to kind of just leave those alone for now unless we run into any um issues you know if something's not working right we can revisit the particular values here and then for the monitor functions there's only a couple we need so we've got load save is control C uh mon C out and mon read key and of course all these addresses are wrong since my computer is not a Commodore um but that's really I think the only part of this that we need to address now is just get these addresses right and we probably will have something that works hopefully so we could go figure out where the exactly the appropriate bios functions are in memory and put the correct address here but an easier way to do this is to just put these labels directly in the Bios code so if we go and uh load up our bios code so there's our bios code we've got two functions in here um so far we've got uh there's character out and up here is character in so those read and write a character from input output we could go over here and say monc out equals uh character out and mon read key equals character in and so now those point to the right place um alternatively though we could go over here and for character in we could add another label of mon read key and then go down to character out and add another label of mon C out so now those labels directly point to the code here so they'll always refer to the right address and then in our config we can just delete these definitions Al together since now they're defined in the Bios file now for these other functions load save and is control C we don't actually have code for those anywhere but we could add some to our bios code so if we go we go up to the top here we can add a function for load and just say return from sub routine so anything that calls this load sub routine it's just going to return from the sub routine without doing anything we can do the same thing for Save and we can also is control C so now those three functions are defined they don't really do anything but at least they're defined and so we don't need these definitions over here anymore so we can actually delete all of that and this is now our config so let's save all that save that and see if it still builds so it looks like it built everything so let's give it a try and write this to an eom and see if it works so I've got the eom here and in my previous videos I've been using this uh tl866 eprom programmer and the company that makes this stopped making these and replaced it with this which is the t48 programmer um it basically works just the same but until very recently the open source mini proo software that I've been using uh didn't work with the t48 uh but fortunately the community has recently added experimental support for it and so if you download the latest code you actually clone the git repo from gitlab here and build it yourself then it then it works you know alternatively of course you could use a software for the manufacturer that also works but that software is only available on Windows whereas mini pro you could run on Mac or Linux or Windows wherever you want so I'll use the t48 here and with the latest build of mini proo I can do mini- p to tell that we're using a 28c 256 eom and then you have to say - U to unprotect it before writing and then capital P to protect it again after writing those flags didn't used to be required but now they are then- W to write uh temp eater. bin and there it goes it's writing our code to the eom and it says you know warning t48 support is experimental um but I found that it it's actually working pretty well now and it looks like it worked so let's put that chip

### Running BASIC! [23:09]

back in our computer and reset it and it looks like we've got Wasson so now how do we run basic you know we've got to figure out what address it's at and so this took a little trial and error and poking around to figure out but if we look back at the code if we look at a knit. s near the top here there is this cold start label and it turns out that I think that's where execution is supposed to start so we need to figure out where that cold start label is actually in memory but fortunately when we built it created that label file right we've got the object file as well as the bin file that we're writing to the eom but it also creates this label file so if we look at that um it's going to list the final address for every label so we can just search for cold start and see that it's address 9 f06 so now if we go to won and we type 9 f06 it tells us there's an A2 at that location okay uh but now that's the current address so if we Type R and hit enter it'll jump to that address and start running code from that address and hey it asks memory size and that's actually the first thing that basic does when it starts up is ask you how much memory it's allowed to use so we're running basic now and we can actually just hit enter to have it auto detect the memory size and then same thing for terminal width we can just hit enter and then it says we have 15 359 bytes free of memory and we've got our okay prompt we're running basic so we could try print hello world and it prints hello world we could write a program so we could say line 10 forx = 0 to5 line 20 print hello and line 30 next X if we type list it prints out our program that we just typed in and if we do run it'll print out hello F or let's see oh I did uh did x equals 0 to five so yeah prints out hello six times now you might be wondering why we've got all these blank lines everywhere and I think that's because my terminal is set up to interpret a standalone carriage return as a carage return and a Line Feed and I've got that setting there because Wasson only outputs Standalone Carriage returns but I think basic is outputting both so we get a carage return and then this turns that into a carage return and a line feed which probably also turns into another carage return and so that might be something we want to look into seeing if we can fix somehow um and then the other thing we probably want to do is try to get control C working so if I write a new program so new will erase the program that's in there and I say 10 print hello 20 go to 10 and I run that now it's just going to endlessly print hello and I have no way of stopping that if I hit contrl C it should break the program but it's not implemented yet so the only way to get out of this is to reset the entire computer with the reset with the hardware reset button here that drops us back into Wasson and then to get back into basic it's let's see what address 9 f06 run and now we're back in basic but our program is gone so that's not ideal um so let's uh let's fix and

### Bugfixes and making control-C work [26:32]

clean up some of these issues now for all these extra blank lines there's this config no carriage return that you might think would help you know it says terminal doesn't need explicit Carriage Returns on line ends but it doesn't actually do what we need because we want to suppress the line feeds not the carriage returns you know but really ideally what I'd want to do is actually leave basic alone because it's actually working the way I kind of like and I'd rather have wson print both Carriage returns and line feeds so if we go and edit Wason basically everywhere that we send a carriage return uh we want to also send a line feed so here we're sending a carriage return I'll just copy that and also send a line feed here we're testing of carage return here we're also testing um and here we're outputting copy that so make this a Line Feed and yeah that should do it I think it's just those two places so now wsman will send carage return and Line Feed at the end of each line um but unfortunately this now makes wson bigger than 250 bytes um but at this point I'm okay with that you know more interested in improving Wasson than trying to confine it to its original size uh but that does mean we need to tweak our memory map to make room so that's our Linker config file and so Wason we will uh I'll back that up and put it at Fe 0000 instead of ff0000 so it still be kind of a the end of memory and then the size will now be 1 fa so I'm just giving it an extra 256 bytes so plenty of room need to shrink our ROM to 7 e0000 and I think that should do it and then you know as for getting control C working properly this took a bit of effort to understand what I had to do basically I found this spot in one of the many files flow. s flow 1. s actually that just in the middle here includes this is control C. S and this is you know 200 lines into this file just in the middle it just includ it's included in line at a particular point in this file where it wants to check if control C has been pressed and you know what it's expecting is that if control C has not been pressed at this particular Point um then whatever code is included here should do a return from sube whereas if contrl C was pressed then this code here shouldn't do anything and execution will just drop down to this stop statement so anyway let's take a look at this file this is control C. S file and so here's is control C. S and so what it does is it just checks what platform we're on and includes a different file for each platform and so for us we can just add another include here uh for us so we'll say if def eer then we'll include eer control C do s and then end if then we can save that and create a separate file for our control- C routine and so here's where we can put our custom code that checks if control C was pressed and either returns from sub 14 or falls through uh to the rest of that code where that stop statement was so we'll start with the is control C label and then we're going to do some stuff here and then either end up at not contrl C or is contrl C and so if contrl C wasn't pressed then we're just going to do a return from sub routine and if contrl C was pressed then we're not going to do anything we'll just do a no operation and that'll just fall through to that stop statement that comes after the include uh back where this is ultimately included and in fact we don't even really need this noop because it's just going to fall through then to determine if contr C was pressed we can call Mon read key and that's going to attempt to read a key from the user and if that returns with a carry flag cleared then that means that no key was pressed at all and so we can uh Branch if carry is clear so no key was pressed so if no key was pressed then it's not contrl C otherwise at this point a key was pressed um and so now we need to check if the key that was pressed was contrl C and so when you press contrl C the asky code you get is three so we can just compare what's in the a register to three and if it's not equal then it's a key other than contrl c so we can Branch not equal to not control C otherwise it was a control C that was pressed and we can just jump to is control C and that should be all that we need uh for that to work and so finally one other thing I want to improve is you know instead of having to know the address of cold start uh to jump to in order to get basic running from Wason I'd rather have an easy to remember address if we look at the Linker config um the ROM starts at address 800 which is easier to remember and the first thing loaded into the ROM here is this header segment now if we look at header. s which is where that header segment is defined whatever code comes after this is going to be the first code in ROM and so it's got some different machine specific stuff and so none of this is going to apply to our computer but I could add something here and it'll be at the of ROM so if I say if def eater so this will be on our computer jump cold start and then end if this says on our computer um the first thing in ROM is going to be this jump to cold start wherever that is so in wson we can just jump to address 800 and then from there it'll jump to cold start and get us into basic so let's try all that out run make again and it says in BIOS symbol is controls already defined yep because we just wrote that other file so go to bios. S we can get rid of our is control C function there we still have our do nothing load and save but that's of course because our computer doesn't have a file system so wouldn't expect those to do anything but let's build that no errors and let's write the output to an eom just rerun that same minipro command and it's writing our eater. bin file to the eom so now we'll put that eom back in

### Everything is working [32:30]

our computer and reset so now we're back in wmon and now we should be able to run basic from address 800 and actually now you know it looks like Wasson sted to give us those um extra blank lines if we say like 8. 80 FF and now we're getting all these blank lines in Wasson because we're getting the carriage return and Line Feed so if I change this to no longer insert the extra line feeds there now we're not getting those extra blanks so let's try something like that again go 800 to 82f let's say yeah that looks a lot better so won is giving us Carriage returns and line feeds which is kind of the quote unquote correct thing to do I think and so now we should just be able to say 800 R and that'll run basic that'll just jump right to the beginning of ROM which will jump to cold start we don't need to know that address anymore and there we go memory size and by the way you know there's a little Easter egg in the original basic code that um when it asks for memory size instead of typing a number if you type a and hit enter it gives you this little thing that says written by Wyland and Gates uh referring to Rick wiland who I think was the first employee at Microsoft and of course Bill Gates but you know we can just hit enter and terminal width we can hit enter and now we're into basic and now if I do something like 10 and actually if you mistype something here there's some very crude editing if you do underscore that'll be interpreted as a backspace so now I can type print hello 20 go to 10 and if I do a list you can see those underscores were interpreted as Backspaces that's the extremely rudimentary line editing you get here but anyway now I've got this infinite Loop if we do run we've got the

### Not everything is working [34:16]

infinite Loop if I hit control c h it doesn't work so let's see what did I do wrong here I'm going to use the reset to go back to wmon let's look at our control C code I obviously did something wrong that's our custom one here so we're saying jump subar monitor read key Branch carry clear so that would be if a key was not pressed then it's not contrl C right if no key was pressed then control- C certainly wasn't pressed then we're going to compare the key pressed to three oh this is going to be Memory address three not the number three we want to compare the value in the a register to the number three we don't whatever happens to be in memory location three that would not be what we want so that's probably what happened there okay so if it's not equal to three then it's not contrl C otherwise it is control C okay I think that was probably the bug so let's make that let's write that back to an eom we'll put that eom back in the computer reset there we are in

### Everything is actually working now [35:29]

wmon and so now if we go to address 800 run here we're in basic 10 print hello 20 go to 10 run that and if I hit contrl C yep there we go it works and our program is still there excellent so it looks like we've got basic running on this breadboard computer so if you're interested in taking a closer look at this code I made a fork of this project and pushed the changes from this video to it uh so I'll leave that over on GitHub I'll put a link in the description you can check that out you can download the code and try it yourself or if you look at this latest commit it shows all of the changes to everything in this video so this is the new bios file that we added um and then the changes to the various different files as well as uh at the end here is wmon so check that out if you want to see more and of course build the computer and try it out yourself you can get all the kits with all the parts and everything over on my website as well so check that out if you're interested and uh as always of course thanks to all the patrons who help make these videos possible
