Placeholder Image

Subtitles section Play video

  • I set out to write the classic hello world Program, but not like this.

  • Not building on a whole stack of software, but starting with just a microprocessor.

  • And this is the 65 02 microprocessor that started the home computer revolution in the 19 eighties.

  • But I haven't gotten too far just yet.

  • You know, the last video.

  • We hook this up and it is actually executing code, but it's just not doing anything all that interesting just yet.

  • You've got the data bus pins hooked up here through these resistors.

  • Eso, no matter what the processor does, it always reads 11101010 which is E.

  • A and Hexi decimal.

  • So whenever tries to fetch an instruction, it always gets E A.

  • And that happens to be the op code for the no up or no operation instruction, which does nothing.

  • So we saw in the last video the microprocessor initialize is and fetches and executes instructions, but right now we aren't able to feed it any instructions from anything other than literally hard wiring the snow up instruction.

  • So it just sits here successfully doing nothing forever.

  • So I guess it's running a program, but not a very interesting one.

  • But let's back up a romp chip that we can program with some different instructions that the process will be able to fetch and execute using different addresses.

  • So this is a 28 C 2 50 60 prom, and the 2 56 refers to the fact that it can store 256 K or 256,000 bits.

  • That's bit so if you want to think in terms of bites, it's gonna be 32 kilobytes now.

  • If we look at the pin out for the problem, you know, it's pretty straightforward.

  • They're a bunch of address lines on.

  • Then there's the eight data lines, the Io lines, and basically, the way this works is if we settle these address lines to particular address, then we get out some data on the data lines based on whatever we've programmed in the pram for that address.

  • So we can use this program or two to program it ahead of time with whatever instructions or data we want the microprocessor to read.

  • But I'll get into that in a minute.

  • First, let's walk through exactly how this is gonna work now.

  • Roughly speaking, it's pretty straightforward.

  • We'll hook up 15 address lines from the microprocessor over to the prom here, and then we'll hook up the eight data lines between the processor and the problem.

  • And then whenever the processor wants to fetch an instruction from the prom, it'll set those 15 address lines to some particular address and use the data lines to read whatever data the prom spits out at it.

  • One thing you might notice is that a promise got 15 address lines, right?

  • A zero through a 14 but the microprocessors got 16 address lines.

  • A zero through a 15.

  • So what does that mean?

  • Well, it was 16 address lines on the microprocessor.

  • The address could be anything from all zeros, which is, you know, an address of zero through all ones, which is an address of, you know, 65,000 or FFFF in Hex.

  • So basically the microprocessor can access, you know, up to 65,000 unique addresses.

  • But the rahm only needs 15 address lines because it can only hold 32 K of data.

  • So we kind of have a choice here.

  • If we just took a zero through a 14 directly from the microprocessor to the rahm, just like we have here.

  • Then when the microprocessor Reed's address zero through seven f f f or you know 7 32,067 Then it's gonna read Address zero through seven f f f for 7 32,067 from the prom, which means it's gonna be able to read from anywhere in the room, which is which is great.

  • But then, if the processor tries to read from address 8000 through F f f f this is this a 15 line will be high.

  • This this first bit here that's gonna be high.

  • But the rest of the rest of the address lines are still gonna count for essentially from zero through seven FFF.

  • Essentially, the processor is going to see the contents of the Rahm sort of repeated twice.

  • And, you know, maybe that's okay, but it's kind of a waste because we could use these addresses here for something else.

  • So what we could Dio is we could connect that that a 15 line that we otherwise weren't using, we could connect that up to the chip enable signal on the problem, and that's Ah, that's an active low signal.

  • So what this will do is we'll say, Well, the prom's only gonna output anything so the chip is enabled.

  • It's only gonna help put anything when when a 15 is low, because it's an active low signal that way, the wrong sort of maps to the first half of the address space.

  • But if the processor tries to read from the other half the address based, then you know that top bid that a 15 bit is gonna be high.

  • And so the room's not gonna output anything.

  • And that means we could have other things that these addresses, like RAM or input and output devices and so on.

  • But you might remember from the last video that when the microprocessor starts up, the first thing it does is it reads from address F, f, F, C and F F F D, and does that to figure out where to start fetching instructions.

  • So we'd really like the F, F, C and F FT addresses to be somewhere in our rum so that we can program that start addressing the Rome.

  • But you know, that's easy enough.

  • We can just invert a 15 before we before we connected to the chip enable signal.

  • So this way, when the microprocessor is reading from this upper half of the address space that a 15 line is gonna be high, that first bit is a one.

  • So this will be high, which when we inverted it will be low.

  • And then the low signal here will activate the chip enable, which is an active low pin.

  • And so this inverter will essentially move the E prom from the lower half of the address base to the upper half of the address space.

  • Which means we can get that f f f c n f f f d value out of the prom and then the lower part of the address space from zero all the way to seven FFF.

  • That'll be unused, and we can use that in the future for something else.

  • So let's hook this up.

  • And actually, instead of an inverter, I'm going to use a NAND gate configured like this, and this is just the same as an inverter because both pins are tied together like this.

  • So both inputs air high than the outputs gonna be low And if both inputs are lower than the outputs, gonna be high and it could just as easily use an inverter.

  • But you'll you'll see later why I'm using the damn gate.

  • So at the prom and start by connecting power and ground.

  • Then there are a couple of control signals I can hook up.

  • So we got the right enable signal here, which is active low on Pin 27.

  • So I'll tie that high, since that's just used for programming.

  • E prom.

  • Yes, even though it's a programmable realm, it's it's designed to function as a romp, and you read only memory.

  • So once it's programmed and put into a circuit like this, we really only want to read from it.

  • Next, we'll type in 22 which is output enable I'll tie that low so the outputs always enabled.

  • But of course, that's still only if the chip is enabled.

  • So, really, by tying the output, enable pin to ground like this, were saying that the output of the problem will be enabled anytime the chip is enabled.

  • But the chip enable signal on pin 20.

  • Remember, we're gonna hook that through the inverter back Thio a 15 that the top address line.

  • Let's do that.

  • Remember for the inverter.

  • I'm actually gonna use a nan gates.

  • I'll add a 74 h c 00 which is which has four nan gates on it.

  • And then I'll connect power and ground for this chip.

  • Then I'll collect the A 15 line, which is this pin right here.

  • This is the address 15 object that around Thio pins 12 and 13 which are just two of the two inputs for one of the the Nan gates On here.

  • I'll connect those two pins together, which basically turns this into an inverter and then the outputs on pin 11.

  • So this is just the inverted copy now of of a 15 and I'll connect that around to the chip enable signal over here on the prom.

  • So now if the microprocessors reading from the upper half of its address space, this a 15 line will be high, and then we inverted over here, So now it'll be low.

  • But then the chip enable signal here is active low, so the prom will be active whenever the processors reading from the upper half of the outer space, which is what we want.

  • And now that's just this NAND gate here, connecting from address 15 through to the chip enable line of the the problem.

  • Now the rest of this is pretty straightforward.

  • Is connecting address line zero through 14 and the data lines that the data lines.

  • Let's do that.

  • I'll hook up the other 15 address lines from the processor to the e problem and again, starting with a zero on the processor, connecting to a zero on the prom and going all the way through a 14 on the processor, connecting to a 14 on the problem.

  • And if you doing this, project yourself.

  • You know, maybe you bought the kids for me with all the parts.

  • Definitely check out the data sheets to make sure you're connecting the right address lines to the right address lines.

  • Once you got the address lines hooked up, then we want to do the same thing with the data lines.

  • But first make it these resistors out of here, since we're no longer hard coating that no up instruction.

  • So then I'll hook up the eight data lines from microprocessor to GE prom, and I'll start with D seven on the microprocessor and hook that to D seven on the prom and work my way back to D zero on the microprocessor, hooking to D zero on the problem.

  • So now whenever the processor wants to fetch an instruction from the e problem, it can read from any address in the in the top half of the address space and will be able to use these data lines these blue wires to read whatever data the E problem spits out at it.

  • So now let's program the prom with some instructions, and maybe a good place to start is toe.

  • Fill the prom with no up instructions.

  • So kind of where we started with resistors, hard wiring, that no up instruction.

  • But instead we'll have any problem full of no up instructions.

  • And so I'm gonna python to create any prom image file.

  • But I suppose you could use anything that lets you create a binary file with specific bites in it.

  • I'm using Python because it's quicker and easier for me, but it has more to do with my personal familiarity with it than anything else.

  • But anyway, I'm creating a bite array just full of hex E a bites and there's gonna be 32,768 of them and like the last video using the E a hex, because that's the op code for a no op instruction.

  • So when the processor reads that, A, it'll do nothing and just move on to the next bite.

  • So nothing but he is don't make for a very interesting program, But at least it is a valid program.

  • And then I can open a file to write it to w B.

  • Means right.

  • Binary and then out file will be the file handle.

  • And then I could just use out file Teoh right the rahm image, and that'll create a binary file called rahm dot been with exactly 32,768 hex ee A's in it.

  • And it has to be exactly 32,768 bites long because that's how big the E promise.

  • So 32 k a problem.

  • If we save that and run it, that'll create a rahm dot been file, and if I dump the contents, if you can see it's just full of days and it goes from zero all the way up in the star just means the rest of the files is the same as this line.

  • So it's just a whole bunch of e a cz all the way up to 8000 hex, which is 32,768.

  • And so we put this on the problem.

  • This is gonna be address zero on the problem through Well, actually address seven FFF.

  • But when we put that on the prom, remember that the processors actually gonna fetch those bites from address 8000 through f f f f because the e promise only active when a 15 the top address line is active.

  • Okay, so let's get the pram programmed.

  • So put the pram in the pram programmer here.

  • And this is ah, t l 8662 plus a prom programmer, which seems to work pretty well.

  • It comes with Windows software, which will let you write a file to the prom.

  • But there's also this open source many pro software that works with Mac or Lennox, so I could just do many pro tell you what type of device I'm using.

  • In this case, it's Ah 80 28 c 2 56 e prom and until it to right the wrong dot been file and there goes its programming, the prom with the contents of that file full of ease.

  • And let's try it out.

  • I'll put the prom back in the circuit, and I'm gonna hook up the Arduino mega like I did in the last video.

  • So I'm hooking up all 16 address lines so we can monitor exactly what the processors doing with, um, So there's a 16 address lines and then I'll hook up all eight data lines to the Arduino as well, so we can see the data that the prom is outputting.

  • Then also hook up the reed right signals.

  • We can keep an eye on that and the clock signals.

  • So the Arduino knows when to sample everything.

  • And speaking of the clock, when you hook up the clock module here, this will let us slow down, pause and single step the clock, and then I'll connect that power.

  • So make sure we connect the power here between the clock and the rest of this and connect the ground here common ground from the art.

  • We know like that somewhere, and then we can power it all up Now if I use the same Arduino program for the last video and open up the serial monitor, we could see the processor is reading e a bites from somewhere, and it seems to be executing them now.

  • Hold down, reset and stop the clock, and we can single step through the initialization.

  • First, I'll clear the output here and I'll step through.

  • And then the 1st 7 clocks are initialization, and then we should see it reads from address F f f c and F f f d.

  • And remember from the last video it does that when it first resets to get the address to jump to, to start executing.

  • Now, since it reads E a and e a, then that means it's gonna jump to address ee ay ee ay to start running code.

  • So if we advance the clock again, we see it goes to address ee ay ee ay and it reads a new instruction.

  • And of course, E a is the no up instruction.

  • And so it'll just keep fetching and running Those e a no up instructions, at least until it gets to the end of the prom.

  • It address FFFF, but so far this is basically what we're doing in the last video.

  • It's just that instead of hard wiring, all of those days, as just with those resisters, were reading them from the prom.

  • But let's make a change to the prom and see what happens.

  • So the first thing I'll changes, let's have it start executing at the beginning of the prom instead of address ee ay ee ay!

  • And to do that want to change those addresses at f f f c N f f f d, which right now we're reading e a N d A.

  • Which is giving us the start address of the a d a.

  • So to do that, you're here after we fill up the rahm with e a bites.

  • What I can d'oh is overwrite.

  • It was something else, so I could say the Rahmat address seven f f c should be zero and then Graham at address seven f f d.

  • Should be, Ah, 80 hex.

  • And this is where we have to be careful not to confuse ourselves.

  • We're setting position a seven f f c and seven f f d of the rahm to these values, but because in order to enable the rum, the processor also has to set that a 15 The top address bit toe one.

  • Aah!

  • These values will actually appear to the processor at address F f, c and F F f d.

  • And in the values here, 00 and 80 the process.

  • We're gonna interpret that as address 8000.

  • And so that's where it's gonna jump to start executing instructions.

  • But force address 8000 to the processor is really address zero in the rahm and in this file that we're creating here.

  • So actually, with just this change, let's give it a try.

  • So I'll save this and run the Python program to regenerate the file.

  • And now we look a hex dump of the rahm file.

  • You see, it's still mostly full of the A's, but now we change these two bites here at you know, seven f f c and seven f f d.

  • Rich, of course, world appear is F f F c and F F F T to the processor, and in the process is also gonna read this address.

  • You know, 0080 So I couldn't read that as address 8000 because of 65 02 processor always reads addresses with the low order bite first, followed by the high order bite.

  • So it seems backwards.

  • But this is a relatively common way to store addresses, and it's and it's the way the 65 to processor stores addresses, and it's ah, you'll often see it referred to his little Indian, which just means that the low order by tissue is stored first.

  • So let me fish the A pram out of there, and then we'll re program it, and I'll just run the programmer again to write the new file to the Rome.

  • There it goes, And now let's get the round back into the circuit.

  • I'll reset everything by starting a clock up, holding down reset and stopping the clock so we can walk through the initialization.

  • So clear the output here and then I'll step through the 1st 7 clock cycles to initialize it.

  • And then, on the next clock cycle, we can see when it reads from F F F C.

  • It's getting a 00 and then when it reads from FFT, it's getting an 80 It's now in the next step it should go to address 8000 and there goes, goes to address 8000 And of course it's reading an E a there because that's what the rest of the promise filled with.

  • And, of course, if we just keep going, it's just gonna keep reading those ears like before.

  • Cool.

  • So now let's try writing a program that does something a little more interesting than just a bunch of no ups, because at this point, the processor is gonna try and execute any instructions that it finds starting at that address 8000 which is really address zero of the rum.

  • So let's try feeding it some different instructions.

  • Well, if we look at the data sheet for the microprocessor, it's got this table that shows us all the different up codes.

  • And so, for example, if you wanted to a load a flip over here, we can find this L D.

  • A instruction, which is gonna load some value into the A register.

  • And we look here to see what the hex decimal ah up code is for.

  • For that load a instruction and actually a number of different up codes for low day, depending on you know what we want to load into the A register.

  • For example, if I'm gonna load the A register with the value for memory, the op code is a D in hex.

  • And then we'd give it a memory address to load from or if we wanted a load from some memory address, plus an offset, you know, from the X or Y register their up codes for that and other things.

  • Or if we want to just load the A register with a particular immediate value, there's an op code for that, and that's what a nine is.

  • So if we go back to where we're creating our rahm image file, if we said the first fight in a rahm to a nine, you know, this has load the next bite from Rahm into the register so we could set the next bite at Location one here, too, you know, some other random value, you know?

  • So you know, let's just say 42 hex And then now these 1st 2 bites here make up the first instruction that the processor is gonna execute and it says load the value 42 into the A register, and, you know, maybe that's not very exciting.

  • But now that we have a value in the register weaken, do something with it.

  • Like, you know, try writing it to some other address.

  • So we look back at our instruction up codes.

  • Um, go down here.

  • There's, ah, store a instruction down here at the bottom which will store the value in the register to some location.

  • And again, they're, you know, they're different addressing modes.

  • But this 1st 18 d is going to store the value in the register to an address.

  • So we go back to our program, you know, after loading the a register with this value 42 if we had another instruction a D?

  • Yeah, that's gonna stay.

  • Store that value that 42 somewhere in memory and expects the next two bites here to give it an address.

  • So we can set the next two bites to, you know, say 00 and say 60 Then you know, these three bites together, the eighties ears there, 60 Say to store the contents of the A register at address 6000.

  • So what is this actually gonna do?

  • Well, let's give it a try.

  • So I'll save this and then I'll run the Python script to regenerate the round file.

  • And now, if we look at the hex dump for the round file, we could see our program here in a two beginning.

  • So this is our program.

  • The load A 42 and then the store A 6000.

  • And then everything else is full of IAI instructions up here till the very end where we have the reset vector, which tells it to start executing, you know, right here to start.