Placeholder Image

字幕列表 影片播放

  • 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.

  • Okay, so now let me just power this off and I'll fish the pram out of here so we can re program it, get that back into the programmer, and then I'll go ahead and reprogram it of writing that new rahm file.

  • There it goes.

  • Okay, it's programmed.

  • Put the prom back in our circuit and all powered up.

  • And then just to get this reset and everything, we'll let the clock run a little bit and then hold down, reset to reset it while the clock is running.

  • And then stop the clock and then I'll go ahead and clear the output overhears we can see what's going on and I'll start stepping the clock so again it's gonna be seven clock cycles to initialize.

  • And then the next two is going to read the Reset Vector.

  • And so we see it's reading 00 than 80 So it's gonna jump to 8000.

  • And there it goes, and I can see it's reading a nine from Address 8000 because that's the op code for the load A instruction.

  • And so next we'll see that it reads the 42 hex.

  • So at this point, it should have loaded that 42 now into the register.

  • The next we're going to see the Instruction eight D, which is the instruction to store the contents of the A register.

  • So then it'll it's gonna keep going to get the address to store, too.

  • So we see a 00 and then 60 And so at this point, it's read this instruction to say, you know, store a address.

  • You know, 6000 because right, it's gonna read that sort of backwards or in little Indian format if you will.

  • But now watch the next clock cycle.

  • Now the processors set the address to 6000 and now it's writing to that address instead of reading.

  • And it's writing the value 42.

  • And then if we keep going, you see it jumps back to address 8005.

  • And now it's just gonna read, you know, the e a no up instructions, since that's what the rest of the realm is filled with.

  • But this is pretty interesting here.

  • You know, we got the processor to actually write this value, which means it's settled the address lines to 6000 and then the processor put the value 42 on the data lines and set the reed right line low t indicate that it was writing.

  • So in all these other cases, when we look at the data here, the state is coming from the E prom, right?

  • This is our program we put in the pram.

  • But this 42 here, this is actually being put out on the bus by the processor itself.

  • Now, this case, there's nothing, actually, at address 6000 you know, the only thing connected to the processor other than you know, the art.

  • We know that we're just using for monitoring, you know, the only other thing connected is the problem, and it's only enabled for addresses 8000 through F f f f.

  • So in some sense, when the processor outputs to address 6000 here, it's just kind of yelling into the void.

  • There's nothing actually paying attention to address 6000.

  • But, you know, we could add some other hardware that responds to different addresses.

  • You know, either RAM.

  • So, you know, data like this 42 could you know, we could be stored in memory somewhere or other hardware.

  • In fact, this is actually how we're gonna do input and output, you know?

  • So we want to output data.

  • We have some hardware that responds when the processor sets the address lines to to a particular address like this and then from the processors perspective, you know, it'll just store different values to a particular address to tell the output hardware.

  • What to d'oh.

  • So think about what that output hardware might look like.

  • You know, so far, program and the processor is gonna output data by writing to a particular dress like this.

  • This writing to address 6000 for example, then the output hardware.

  • You know, whether you know it's It's a display, or whatever it is, it needs to be able to look at the address lines of the processor to see when they match.

  • You know, this particular address, and then when they dio, you know, grab the data from the data lines here and do something with it.

  • And, you know, the important insight here is that when the processor outputs data, you know, it's using the same address bus in the same data bus that it uses for everything else.

  • You know, some processors might have separate interfaces or something to do.

  • I Oh, but the 65 02 uses the same address bus and the same data bus that it uses to to fetch and execute instructions or access memory or whatever else you know.

  • So if we're thinking about how out port hardware might work, then we've got to realize that, you know, these address lines are gonna be flipping all over the place, and the data lines are flipping all over the place.

  • And so the only thing that's relevant to the output hardware in all of this is this one moment here where the processors actually using the address and data lines to output something.

  • So if we wanted some sort of output display to display this 42 or whatever, then we need some hardware that's looking at the address lines and then only when they match 6000.

  • You grab the data, this 42 latch it into an external register or something.

  • You know, somehow store this 42 because it's only there for this one clock cycle.

  • So this means any kind of output device we need has to have at least two components.

  • Some address decode logic to detect when the processor is writing to this 6000 address and then a latch to store the data that its output so that it can be displayed even after the processor here has moved on to other things.

  • Now, when it comes to latching data, I've got a whole series of videos where I build a CPU from scratch and is part of that Siri's I've got videos where I talk about s R latches de latches d flip flops on, and then how to build a register and even an output display all from scratch.

  • So if you want to go down that rabbit hole.

  • Well, you're in luck.

  • But for this video, I mean, he was a chip that does a lot of that work for us.

  • And that's the 65 c 22 versatile interface adapter.

  • And as the name would imply, the 65 c 22 virtual interface adapter is designed to work alongside the 65 c zero to microprocessor that we've already been using.

  • And it does a whole you know, a bunch of interesting and useful things that would you take multiple videos to fully explore.

  • One of the most basic things that does is latch data for input and output.

  • So if we start by just looking at the pin out, you get some sense of what it will do for us.

  • It's got these D zero through D seven pins, which interface right to our data bus.

  • And there's also got the fee to which is the clock pin, which is designed to connect right up to the same system clock used for the microprocessor.

  • And, you know, the nice thing about this chip is because it's designed to work with the 65 02 processor.

  • You know, all the timing's gonna just work, you know?

  • So we just have to connect the same clock and it's just designed to be able to send data back and forth on the data bus here.

  • And, you know, we could still go through all the timing diagrams and double check that it that it's actually gonna work.

  • But the point is, the chips, they're designed to work together.

  • So I'm not gonna go through all that in this video, but it's got the clock.

  • It's got the data.

  • It's gotta read, right pin that, you know, will connect right up to the reed right pin on the processor.

  • And then a couple of chips select pins the CS one and CS to hear that we can use to tell the chip when the processors actually talking to it.

  • And so we'll have to have some, you know, address decode logic that, you know, when we're writing to just the right address, it enables those chips elect pins.

  • And so, you know, basically, once we hook this up the process, we're gonna be able to easily talk back and forth to this chip and then on the other side, there's just a whole bunch of io lines that are latched.

  • Yes, we've got port A zero through seven and important be zero through seven.

  • And these air, these air latched outputs, or we can actually also use them for inputs.

  • And so one of the things that this chip lets us do is we can send some data from the processor over here, and then it'll latch that data onto, you know, one of these i o ports over here, the port airport B and then hold that data there while the processor goes on to do other things.

  • And it's got these four register select pins are a zero through Rs three that are used to select which port we're talking to our or, you know, some of the other functions the chip supports.

  • We're going up the clock, we're gonna hook up the data bus, and we're gonna hook up the reed right signal.

  • But before we get any of that, we need some logic to figure out when we're actually talking to this chip.

  • So, for example, with we want data that we're writing Thio address 6000 to be latched by the 65 22 we need some logic to enable the 65 22 when the processor is writing to or, you know or reading from address 6000.

  • So for address 6000 hex, this is what that looks like in binary.

  • So this is what the address lines will look like when the processor is writing to address 6000.

  • So we need some logic that will tell us if the address bits are set to these values.

  • And then if they are enable the chip select signals.

  • And by enabling the chips like signals.

  • That tells the 65 22 that it's time to pay attention to the data bus.

  • And the 6 22 has actually two chips like signals, and they both have to be active.

  • Chip Select one is active high and chips like to is active low, which is indicated with the bar over it.

  • Actually, if you look at the data sheet, they don't have the bar.

  • They just have chips like one and chips like to be.

  • But the be at the end just means that tips like to bar.

  • So should be a bar over it.

  • But I guess instead of drawing the bar, they just put to be at the end, but anyway, that's what that means.

  • Like R.

  • W.

  • B is read and then right with a bar over it like that.

  • But in any event, I'll just draw it with the with the bar like that, indicate that it's inactive low.

  • So if we want to build some logic that will recognize when the address ah, bits are set this way and then enable both of these chips like signals Um, let's just actually just start with the first the first bits here.

  • So if you just look at the first to bits, the first bit is zero the in the second bits of one.

  • So if we invert the zero and then just take the one and then and those together, well, that'll tell us that the 1st 2 bits are set correctly.

  • And of course, we could actually build something similar with with only nand gates that would look like this.

  • We're here.

  • This this top man gate is essentially inverting that zero.

  • So just like the inverter we just saw and then we're ending it with the with one, and then we get a zero over here and actually can feed that directly into the active low chips Look, too.

  • So chips like to hear will be active when the 1st 2 bits of our address.

  • All right, then what we can do is we can we can feed this third bit address 13 in directly into the chip.

  • Select one.

  • Because that's supposed to be a one.

  • When when Our address is at 6000 and so that will be active And check if the third bit of our address is a one.

  • And so just like this, this will activate the 65 22 when the 1st 3 bits are correct for an address of 6000.

  • But you might be wondering, you know, what about the rest of the bits?

  • How do we check if they're all zeros?

  • Because Because the rest of these bits are all supposed to be zeros.

  • If the processors writing address 6000 Well, you know, it might seem strange, but I'm actually not going to check those other bits at all.

  • I'm just gonna ignore them.

  • So that means that that this chip is actually gonna be enabled for any address from 6000 all the way through seven FFF Because those are the addresses from 6000 through seven FFF Those air the addresses where those 1st 3 bits are 011 And I know what you're thinking.

  • You know, that seems horribly inefficient, right?

  • We really taking up, you know, over 8000 addresses just for this one ship.

  • It seems like such a waste, right?

  • But, you know, with engineering, everything is a trade off.

  • So there's never, like, a perfect design, because one factor that's always in play is cost.

  • And, you know, a big advantage of this design is that it just uses these to Nan Gates.

  • And in fact, you might have already spotted that that this NAND gate here is already in our circuit because we're using it for the chip enable for the prom.

  • So we can we actually kind of use double duty on that?

  • So, really, you know, this design is only adding a single damn gate, so, yes, we're kind of wasting, you know, 8000 addresses or whatever it is to activate this one chip.

  • But we're actually saving, you know, a whole bunch of logic, gates, because if we had to put logic gates in here to check that all of these bits were zeros and feed that into some logic that activated the 65 22.

  • That would require a whole bunch of logic gates.

  • And so, you know, it's a tradeoff that ultimately depends on exactly what we're building this for.

  • You know, we're trying to build something that requires, you know, a certain number of addresses where we need a certain amount of memory or a certain amount of Io or something like that.

  • You know, we might have to add that complexity to use our address based most efficiently.

  • But if we don't actually need all of that address space, then maybe it makes more sense to accept something that kind of at first sight might seem like.

  • We're wasting some resource like addresses, but really, we're saving on the resource that really matters in our case, which would be logic Gates, you know, And that's hardware, which you know, if you're designing a product that directly translates to cost and you know, I suppose yes, we're building This is a hobby or something.

  • So you might not care about that which, you know, fair enough.

  • But if you're interested in real world engineering.

  • You're not always gonna have the luxury of prioritizing your personal aesthetic of some ideal, you know, quote unquote design.

  • You're eventually gonna have to make trade offs like this.

  • And one interesting factor of this design is if you wanted to add multiple 65 20 twos, which you know, if you wanna expand this, you might want to do you could just use address 12 11 10 and so on.

  • And hook those up to the chip.

  • Select one pin of the of the second or third or fourth 65 22.

  • So if you want to add Maur more, I owe this design.

  • Makes it kind of easy to expand.

  • Still not efficient use of the address space, but very efficient use of the hardware because you don't actually need to add any additional address decode logic.

  • But anyway, let's start hooking this up.

  • I'll start by disconnecting the Arduino so you can see what's going on in here.

  • It will add the 65 c 22 chip here.

  • If we look back at the pin out here, you can see that power and ground R V D D and V.

  • S s a pins 20 and one.

  • So start by connecting those up.

  • In 20 is power five volts and then pin one is ground.

  • If we start with that address decode logic, you can see that we've got the chip.

  • Select one and chips.

  • Look to that.

  • We're gonna hook up to this logic here.

  • And of course, we already have this neon gate hooked up.

  • Here's we've got address.

  • 15 coming down that says green wire going into the two inputs of one of these nan gates and then the yellow wire is the output here.

  • That right now is going to chip select for the rahm.

  • We could also take that and bring it into another input for another NAND gate because this chip here has foreign and gates on it.

  • And that's actually why I used in Nam Gate instead of an inverter here.

  • Since we can use one chip that has four nan gates on it to do to do both things.

  • So connect the output of this NAND gate around to the input of another one of the inputs of another nan, get on the same chip.

  • So that's this connection here and then we'll connect address 14 to the other input of this NAND gate down here.

  • Address 14 is one of these.

  • Ah, this address pin up here.

  • So there we go.

  • That's address 14 And that's gonna come around and connect to the second input on this nan gate.

  • And the output of this neon gate is gonna go to the chips, like to input of the 65 22 to the output of this NAND gate.

  • Is this pain right here?

  • And then that's gonna come around to the chips elect to pin you look back at the pin out here.

  • Chip Select, too, is pin 23.

  • That's this pin right here.

  • It's now the 65 22 is only gonna be enabled when address 15 0 and address 14 is one.

  • Because that's what this logic does.

  • Next, we're gonna connect Address 13 from the microprocessor over to the chip.

  • Select one input of the 65 22.

  • So address 13 is also up here, starting to get a little bit tight.

  • But let's see if I can get this in there.

  • Address 13 isn't gonna come down and connect to the chip Select one pin and chimp select one is pin 24.

  • So right to the left of chips elect to that's that one right?

  • There we go.

  • And so that's the address.

  • Decode logic for the 65 22.

  • But then we got some other stuff down here.

  • We need to connect as well.

  • So if you look at what we got down here, you've obviously got all of the data lines.

  • But we also have the reed right signal and the clock single this fee too.

  • And the rewrite signal is just this signal that comes out of the microprocessor that says if the microprocessor is reading or writing data to the bus because the 65 22 doesn't just do output, it does input as well and has a bunch of other functions that the microprocessor gonna need to be able to either read or write from.

  • So we need this signal and the reed, right?

  • Pain on the microprocessor is pin 34 here.

  • That's right here.

  • And then the rewrite pin on the ah 65 22 is over here.

  • Pin 22.

  • So that's down here.

  • Let me try and sneak through here again.

  • Here we go.

  • we're connecting to read, Write pain here.

  • That pin down to read right pin here, which is pin 22.

  • Should be that pin there.

  • And then we also got a clock pin to the clock signal on 65 02 Comes in here, remember, that's where we've been connecting the clock module here, and that goes to the fee to clock pin here.

  • Pin 25 on the 65 22.

  • And that's right there.

  • And then one other signal that we actually do need to connect that I didn't draw on here is the reset pin.

  • So the 65 22 also has a reset pin.

  • And you know, we would need to reset the 65 22 before we start running any programs.

  • So what we do is we can connect that reset pin up to our reset circuit here.

  • So that was pin 34 which is right here.

  • And I'll just connect that up, actually to this side of the reset button.

  • And that's the same is up here, which is, you know, this reset pin is normally tide high through this resistor, but then when we push the button, it connects it to ground over here.

  • So that's active low when we reset it.

  • And by connecting it down here, both sides of this switch or just electrically connected inside the switch.

  • So this is this.

  • Here is the same signal that the microprocessors getting.

  • And then, of course, we need to connect all of our data pins.

  • We've got D zero through d seven.

  • We just need to collect this data bus over to the data pins on 65 22.

  • We'll start with D zero and connect that from the processor to the 65 22 and then D one D, two d three d, four t five, t six and d seven.

  • And I'll just kind of clean all this up.

  • Try to make it as tight as I can.

  • It's a whole bunch of wires going everywhere, so it's gonna be a little bit challenging, but hopefully get this a little bit neater so you can kind of see what's going on here.

  • And there we go.

  • So that takes care of everything that we kind of drew out here.

  • There are four more pins that we need to worry about, and that's thes register Select pin so there's register.

  • Select 012 and three.

  • And what those do is those air used to well, as the name would imply, select a different register because the 65 22 has 16 different registers that you can address by using those four different register select pins.

  • And it's those different registers that allow the 65 22 to do all the different functions that it has.

  • And for this video, really, the only thing we care about is the output Register A and B because, remember, if we go back to the pin out here, we've got eight minutes here for port a port a zero through through seven and then Port B zero through seven in a way that we output data to either port Airport B is by using these register select pins here.

  • So if they're all zeros, then we're out putting to register.

  • Be if it's 0001 then we're out putting to register A.

  • But actually, with the 65 22 that port a in port be can be used for input as well, so their input or output and the way you tell it.

  • Whether it's importer output is with this data direction register.

  • So there's a data direction register for being a data direction, register for a and you could write a value to those registers to tell it which bits of port, eh?

  • Our inputs and which bits of port air outputs in ST Report B.

  • So it's all 16 of these pins weaken, you know, select individually to be either input or output.

  • And you do that with these data direction registers.

  • So we want some way from the microprocessor to be able to set values into each of these different registers.

  • And the way I'm gonna do that is by connecting these register select pins to the address pins coming from the microprocessor.

  • That way, you know, we've got our address decode logic here that says, enable the 65 22 when we're an address 6000.

  • And I said, we're gonna ignore the rest of these address pins.

  • So really, it's not just address 6000 is a whole bunch of addresses where the 65 22 is gonna be active, and that could include address 6000 where ah, you address zero through three year old zeros.

  • But also 6001 where address zero is the one or address 6002 where address one is a 1 6003 and so on.

  • So, actually, the way we're gonna talk to the 65 22 is not only just address 6000 but 12345678 6009 A, B, C, D, e and F.

  • So we'll actually have 16 different addresses that the microprocessor will be able to address by using both the decode logic here to enable the 65 22 when we're kind of, you know, in the right range.

  • But then also used these low order address bits to select the specific register that we want.

  • So, for example, if we want to set the date a direction for the port be then we would write to address 6002 and then, you know, once we've configured port be for output.

  • If we want to actually out put something there.

  • Well, then we can write the address.

  • 6000 in total output to Port B or 6001 down port to port.

  • Eh?

  • So I took that up address zero go to register.

  • Select zero.

  • Andrews wanted a register.

  • Select one, Andrews to to register, select to an address.

  • Three to register.

  • Select three.

  • And there we go.

  • So we've got our register.

  • Select pins all hooked up.

  • We've gotta reset.

  • Pan hooked up with Obviously got all over data pins hooked up.

  • We've got a clock pin and our two chips like pins, and I read right pin, and that should be everything.

  • We need to get the 65 22 to work in terms of being able to output data on the poor.

  • Day and port be here, but a course.

  • We actually want to see what's being output on port a import be.

  • Let's hook up some ladies, so I'm just gonna temporarily stick eight.

  • Led is over here, so we just monitor, you know, eight of the output bits and then I'll connect the negative side of each led to ground through a 220 ohm resistor and you could tell the negative side of the L A.

  • Because it's usually the one with a shorter leg.

  • It's also the one with the flat side in the plastic.

  • Is that in the positive side of the led.

  • I'll just hook up to the eight pins of Port B, which depends 10 through 17.

  • There we go.

  • Now, if we write anything to port be we should see it latched on the output here and we should see that show up on the ladies.

  • Now, let's try to write a program that will output something to those ladies.

  • And before I get too much farther with this, what we do is is gonna reform at this.

  • So instead of assigning each bite like this, what will those defining array up here, Then we just list out the op codes and everything for each instruction.

  • And so this is the same thing appear that I had down here.

  • So just get rid of all this.

  • And now the rahm is going to be the code.

  • Plus, whatever padding is needed to get it up to 32,768 bites and total length and size actually gonna be 7 32,068 minus the length of the code.

  • And so far, I haven't actually changed anything about how this code works.

  • It's still doing exactly what it was before, so this first part up here, these 1st 2 bites, this is essentially, ah, load A of 42 hex.

  • And then this next line is a story at Address 6000.

  • And so this is exactly what we had before.

  • Haven't changed anything.

  • It's just a little bit more of a compact way to write it so easy, Right?

  • More code, hopefully will be a little bit easier to follow, but we wouldn't want to start out by writing a 42 to address 6000 because the first thing we actually need to do is set the date a direction for the register.

  • So if report be, which is what we're using, the data direction register is registered number two.

  • So we want to write to register to which will be able to get to at address 6002.

  • And the way this works is if we look at how the data direction registers work, you can see that if we set a bit to one in the data direction register that sets that pin for output and if we said it to zero that sets that pin for input, right, because port be itself has actually got eight pins here, and we can set each of these pins each each of these eight pins for input or output individually.

  • Now, in our case, we want to set him all his output.

  • So what we want to do for our direction is set each bit of the direction registered to a one for output.

  • And basically, what that would look like is the data direction register be so it address 6002.

  • We want to write something that's all ones, which is gonna be FF in Hexi Decimal.

  • And really, we've kind of almost got the code here that we need.

  • What we just need to changes is load FF into the register and I'll update the comment as well.

  • And then instead of writing that to address $6 when we want to write that to address 6002 and then course the addresses Little Indian So it's gonna be 02 followed by 60 So we're loading FF into the register and then we're storing that it address 6002.

  • And what that's gonna do is it's gonna put an F f in the data direction register.

  • Be to say that all of the pins for the B register Our output.

  • Now we can actually output something to the B port, which is registered number zero.

  • So that's actually gonna be address 6000.

  • And we could basically copy this same code.

  • So I'm gonna copy both of these lines and then change it so that we load some different value.

  • So perhaps I'll load 55 and then store that address 6000 and I'll update the comments over here as well.

  • So by five and 6000 it's now what this code will do is after it sets the data direction to output for register be it'll write a 55 hex to register be and 55 hex in binary is just gonna be 01010101 So it's just gonna alternate the ladies on and off.

  • And if we want, we can write different patterns.

  • So I could just copy this again.

  • And once it's written that 55 we can load in some different values.

  • Soul Just say a, which is also 10101010 But it's the other 10 So it'll sort of flip flip all the bits and on the update that comment here as well.

  • And so then that'll change.

  • What's going out?

  • That port and change change with the ladies are set to.

  • And so the next thing I'm gonna do is create a loop so that once we're done, you know, loading 55 writing that out to the port and then loading a in writing that out to the port.

  • What I want to do is is just have the program loop back up and right out the 55 again.

  • And to do that, we need another up code.

  • We need the op code for the jump instruction, and there is a jump instruction here jumped to new location.

  • And if we're going to give it a full memory address, the op code for that jump is four c.

  • So add another op code here four c and then have to give it the address to jump to.

  • Um And what I could do is I could do Ah 00 80 and remember, 0080 That's gonna be interpreted as 8000 which is the start location of our program.

  • So this would

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

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

CPU如何讀取機器代碼?- 6502第二部分 (How do CPUs read machine code? — 6502 part 2)

  • 6 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字