Placeholder Image

字幕列表 影片播放

  • building a simple computer based on the 65 02 processor.

  • And in previous videos we got it working and actually displaying some text.

  • But then we tried to simplify the code to use subroutines.

  • It stopped working, and it's not working because when the computer jumps into a subroutine, it pushes the return address on to the stack, which is in memory.

  • And at the end of the subroutine, it pulls that return address off the stack so it can jump back from where it came.

  • Our problem is that our computer didn't actually have any ram in it.

  • So in the last video, I started hooking up this Ram chip here, and I've got the 15 address lines.

  • Is green wires here hooked up to the address bus, The eight data lines, the blue here hooked up to the data bus and the right enable pin, which is this yellow wire underneath here that goes all the way over, hooked up to the reed right pin on the microprocessor, and that's hooked up pretty much like this.

  • We've got the 15 address lines, we've got the eight data lines, and we've got the read write or a right, enable signal hooked up here.

  • But then the Ram chips got a couple of control signals here is well to enable it.

  • And for that we said, Well, we can hook those up to address 14 and 15 so that when both of those air low, the ram is enabled, and that'll ensure that the ram is enabled anytime the addresses between 0000 and three f f f, which is the range we want to use for the ram.

  • But then, in the last video, we took a closer look at the timing diagram for the Ram to take a closer look at the timing requirements for interfacing with it.

  • And then we looked at the timing diagram for the microprocessor as well.

  • It's kind of the interaction between these two.

  • And so that was That was in the last video, and what we found is that this wouldn't actually work quite like this.

  • Instead, we have to add a little bit of logic here, and this is to ensure that the chip select signal doesn't go low until all of the address lines are set and stabilized, and then the chips like signal would go high before any of the address lines change anytime we're doing a read or write, particularly a right to the ram.

  • And so that's what this additional logic here does.

  • And in my last video, I went over exactly why we needed this.

  • So in this video, let's hook this this extra logic up and see if we get the ram working.

  • I'll start with the address 14 and hook that around to the output enable.

  • So address 14.

  • Is this pain here?

  • And we're gonna take that to output enable over here.

  • And so this will ensure that the ram is not gonna output anything unless address 14 is low, which it has to be.

  • If we're addressing anything in that zero through three FFF address range, then we need to hook up the chip select, and the Chip Select is going through these logic gates now conveniently, we already have one of the logic.

  • It's hooked up already because we have this address 15 being inverted through an and gate like this that we already did for the chip Select for the rahm.

  • And so address 15 is coming down here and this is actually I just 15 here and it's connected.

  • And if you can see, it's connected to both inputs of one of these Nan Gates.

  • And in the output here is ah is going back up around a chip select for the rum.

  • But we can reuse that to go to one of the inputs of this other Nan Gates.

  • I'll just hook from the output of that first NAND gate to one of the inputs of the next man gate with just a little tiny jumper there.

  • So that's that connection there.

  • And then this neon gate, the output of that will go to the chips elect of the Ram.

  • That's gonna be the output of this nan gate here has got to go all the way around to the chip Select input of the Ram.

  • And I've got a nicely measured wire that I need to somehow speed through here and there we go.

  • So we've got one of the inputs going into this neon gate and then we've got the output going around to the chip select over here, and then the other input is gonna be our clock signal and already got the clock signal hooked up here.

  • Coming from the clock pin of the processor around to the clock in put down here of the interface adapter.

  • And what I'm gonna do is I'm gonna pull this this longer, wire out and replace it with two shorter wires so we can drop it into this NAND gate and put here as well, we'll pull that clock wire out and we'll come from the processor down to that input on the NAND gate.

  • And then we'll have another shorter wire that goes from that important an and gate around to the interface adapter Luck.

  • So there we go.

  • So that restores that same connection we have before.

  • But now we have also have a clock input going into the NAND gate There.

  • Now I'm using three of these Nan gates, and I'm not planning to use the fourth Man gate.

  • And it's a good practice when you're not using inputs to tie them either high or low.

  • So they're not floating and potentially hovering between high and low and causing the chip to switch on and off, in which get introduced noise and such into into the rest of the circuit.

  • So it's just a good practice to tie those unused inputs high.

  • So go ahead and do that.

  • But with that, you know we've got Let's see, we've got address 14 now hooked output enable We've got address.

  • 15 already was being inverted by this first NAND gate.

  • And now that's going into the second Man gate as well as the clock going to the second and gate.

  • And then the output of that NAND gate is coming all the way around here to chip Select.

  • So with that, we should now have RAM in our computer, which also means we should now have a stack in our computer.

  • So let's ah, let's go ahead and try to power it up and see if our program works.

  • Because if we have a stack our program out of work, plug this in and so your clock is running, will reset.

  • And, yeah, there we go, our partners working.

  • And I haven't changed the program in the room.

  • So it's using the jump to subroutine instruction and obviously the return from subroutine instruction, which is what wasn't working before.

  • And it appears to be working now, which which is great.

  • So, yeah, let's take a closer look at that.

  • Let's ah, let's get this out of the way and I will hook Thea Arduino back up so we can actually monitor step by step and see that stack operation again.

  • But this time actually see it work.

  • So power this off.

  • Get the Arduino back here and I'll hook.

  • They are doing you up again.

  • Toe monitor everything.

  • So like before, I'll start by hooking up all 16 of the address lines to 16 inputs of the artery.

  • No, and then we'll hook up another eight inputs of the Arduino to eight of the data lines.

  • And then we'll hook up the reed right signal from the processor to to another input and, of course, hook up the clock to another input on the Arduino to trigger it.

  • And then finally, we need a common ground.

  • All right, so that's all hooked up.

  • And it's pretty annoying to hook up, I have to say, but in any event, I will hook up the Arduino to the computer and power up the computer.

  • Other computer reset here and her program's running, but I'm going to, ah, hold down, reset and stop the clock.

  • That way, we'll be able to a single step through this and see what's going on.

  • So here's the output of the artery.

  • No serial monitor and all good and clear that in this hard we know program that I'm running well, actually, let us see what's on the data and an address buses for each clock cycle.

  • And you can check out a previous video where I talked more about how it works really well.

  • Step through the 1st 7 clock cycles to let the processor initialize itself and then the next to clock cycles, reading FFC Enough 50 that reads The Reset Vector, which is 8000 and we'll jump to 8000 We'll start reading instructions.

  • So a two is the load X and an F f so that loads ff into the ex register.

  • And this is initializing the stack pointers because the next instruction is gonna be our transfer X two s and that's Ah nine a.

  • Is thea up code for that?

  • And then we get Thio a nine, which is load A.

  • And actually we see this repeated because really, what's happening here is the transfer excess takes to clock cycles.

  • So this first clock cycle, where it looks like it's reading a nine from address 8003 That is what happens to be on the bus.

  • But I think it's still executing the transfer ext.

  • S instruction on that clock cycle.

  • And it's on this next clock cycle where it's actually reading the load, eh?

  • Because then it's gonna follow up with Load A F F, which is actually the next instruction.

  • Then we have a D, which is story, and it's a story six years or two, which is the address for DDR.

  • Be so this is all just part of the initialization.

  • So I'm gonna go this pretty quickly just to get to the point where we're actually calling and returning from the subroutine, since I've already shown a lot of this in previous videos.

  • But anyway, we're next.

  • We'll have Ah, well, this is actually the right.

  • So it's actually writing the FF to address six years or two, you're gonna read Low Day E zero and then store, eh?

  • Six years or three, it's now it's gonna store the easy road address six years or three.

  • Then we have a low day 38 So that's the first instruction that we're actually gonna send to the LCD.

  • So the next instruction now is going to be the jumps.

  • A subroutine up code to zero is jumped a subroutine, and then the address of that is going to be 8060 or no, it's not a 060 that this actually kind of fooled me because the 60 it's reading from, you know, address 8010 That is gonna be part of the address that we're jumping to.

  • But you could see this 80 is actually being read from 101 f f and that is gonna be the bottom of our stack because the FF remember, that is our stack pointer.

  • And so, actually, what we should be doing is now that we're pointing at that stack, we should be writing Yes, 8011 into the bottom two positions of the stack.

  • So 01 ff and 01 Effie.

  • And now we're reading from 8011 And so the 806 there is, in fact, the address that we're jumping to for the subroutine.

  • It's just that by pure coincidence, the headdress 01 f f happened to have 80 in it on so that that kind of will be there for a minute.

  • There's a little bit confusing because of two things going on here.

  • I talked about this in the last video, but you know, we're jumping to subroutines, so this to zero is the instruction to jump to subroutine.

  • And then it needs to read the address there jumping too.

  • So it reads from the next address 010 so that the instruction was a needs a reserve f so that it reads from 80108011 It reads the address that were jumping to, and so that's 8060 I was thrown off here because it's also has to write the address that were jumping from, which is 8011 And it's writing that 201 F F 01 F fees.

  • It's pushing those onto the stack.

  • And then there's this extra clock cycle in here where the bus is not being used.

  • You know something internally going on in the processor because the jump to subroutine takes an extra clock cycle for whatever reason internally, so the process is not really reading this value 80 from the bottom of the stack.

  • It just happens to set the address lines to that value.

  • And this happens happen to be what was in memory, which which confused me there for a minute.

  • But any rate, we've got our return address pushed onto the stack 8011 and we've read the address that we're jumping to 8060 So we should now jump 28060 And there we are.

  • Word, age, address, AIDS or 60 ever reading a D.

  • And that's because we're down in the LCD instruction subroutine.

  • And 80 is the first up code for for story, so I'll just go through this pretty quickly.

  • So we have ah, store a 6000 which is pork.

  • Be so there it is.

  • Storing the 38 into Port B.

  • We have, ah, load a 00 And so this is to clear the register, select, read, write and enable bits and then store a six years or a one, which is poured a and there goes storing zero into port A.

  • We have, ah load a 80 That's the enable bit and store a 6001 again.

  • And there it is, writing that out to 6 to 01 So it's setting the enable bit.

  • And then we load a 002 clearly enable bit and store a six years or one.

  • And there it is, writing that out again.

  • And then we get to our return to subroutine instruction.

  • So 60 is returned from subroutine.

  • And so at this point, it should read back those values that it's stored on the stacks.

  • What store?

  • The return value.

  • 8011 on the stack at 01 f F 01 Effie.

  • So it should pull those back off the stack.

  • So let's see here.

  • So it jumps ahead to 88073 And again, I think this is a ah clock cycle that's being used internally.

  • I don't think it's actually trying to read this next instruction, but now it goes to zero on F D, which is where the stack pointers pointing.

  • And then it reads from 01 Effie and 01 f.

  • F.

  • So again, I think these two clock cycles here the processor is not actually using the bus.

  • It's just Those clock cycles are being used internally, and this just happens to be what's on the bus.

  • But certainly for these two clock cycles.

  • Here we are, reading the return address 8011 And if you watch the last video before we had the ram installed, this is where things fell apart.

  • Because when we tried to read that return address back, well, it wasn't stored in the Ram because there was no ram.

  • And so the next instruction, we jumped off into some garbage address.

  • But now we're reading the correct thing back.

  • 8011 So we should see it jumped to 8011 and continue executing.

  • And so here we are at 8011 and notice that, you know, jumps back to 011 which is not actually the next instruction.

  • This is this is actually the last half of the address that we jumped too.

  • So we're not quite at the next instruction, which is the low day.

  • That's gonna be an 801 too.

  • So if we keep going, here we are 8012 So, again, I think you know this is a little bit confusing the way that that this monitor shows what's going on because it prints out what's on the bus for each clock cycle, even if that clock cycle is not actually transferring data on the bus.

  • But nonetheless, I think we can conclude that this is working correctly because now here we are at 8012 which is in fact, the next load A.

  • And so we should see that load A zero E, which is the next LCD instruction that we wantto execute.

  • And then we should again see another jump to subroutine to the LCD, which is gonna be the 8060 and so that it is reading the 060 and also pushing the return address, which this time is 8016 The bottom line is, if we let this run as we saw before, it's just gonna work because now we've got the ram there, and because we have the ram, we have a stack, and because we have a stack, our jumped us ever thine instruction is gonna work for us.

  • I think there are a few improvements that we can make to our hello World Program before we're completely done with this one of them, you can probably see right off the bat here is that we're not clearing the screen at the beginning.

  • You know, before it was working fine, because when we first plugged, the computer in the screen starts out cleared.

  • But here, you know, I let the program run for a little bit and we stop the clock.

  • And then I used the reset to reset it.

  • And as part of our reset sequence, we don't actually clear the screen.

  • So let's go ahead and add that is, that's a pretty straightforward thing to add.

  • We'll take a look at the data sheet for the LCD module.

  • We can see there's an instruction for clearing the display, and it's just all the bits are zero, except for the last bit, which is the one, and that's fairly straightforward to d'oh!

  • Just go down here with all of the other instructions that were sending to the LCD and add another instruction to clear the display and instructions.

  • Just all zeros, except for one man that clears the display.

  • And once we load that instruction in today register, we just jump to the subroutine, and that's it.

  • That should clear the display before we print our message.

  • So save that, and I'll switch over to the terminal and run our assembler to assemble that program into binary.

  • And this will output file a doubt out with binary that we need to put on the prom.

  • Can we take a look at what's on that binary if we want?

  • There's our program.

  • It's now we need to you program that onto the prom that's buried in here.

  • So what I'm gonna do is disconnect all of this because I don't think I'm gonna be using this monitor again in this video.

  • Get that out of the way.

  • And then I can carefully remove the prom carefully and put it in the pram programmer, being again careful to put it in the right place in the pram burger, and I'll go ahead and write this to the prom.

  • And so it's writing that to the prom and there we go.

  • It's done.

  • Let's pull the pram out carefully.

  • Put it back in our circuit.

  • Here we go.

  • And now let's power this up and we should get Ah, hello.

  • World Message reset.

  • Mm.

  • something's not working quite right here.

  • What's going on?

  • And it looks like my clock fell out about that.

  • Look that back in and there it goes.

  • And we could speed this up if I reset should clear and reprint it.

  • Beautiful.

  • And so there we go.

  • We've got working.

  • Ah, working ram in our computer, which means we've got a working stack, which means that our program that uses subroutines, eyes working and as you can see, it was easier.

  • Easy to add another instruction of the LCD to get it to clear just by adding another subroutine call.

  • So that should make programming this thing a lot easier.

  • And in fact, there are some or improvements I want to make to the program for hello world.

  • So, you know, even six videos in I'm still not done with writing a basic a world program.

  • But, you know, what do you want from me?

  • I assume if you've been watching the last half hour of timing diagrams, you're probably OK with the situation.

  • But anyway, in the next video, I'm gonna add some more improvements to the program and also get rid of our clock module here and replace it with our one megahertz, uh uh, crystal oscillator clock so that our computer will actually running at speeds that we talked about when we looked at the timing diagrams.

  • Is there be a few more interesting things we'll have to think about when we do that?

  • And remember, if you're interested in following along with these videos, you can get all the parts I'm using over at my website eater dot net slash 65 02 I've got the base computer kit as well as everything else you need to follow along with these videos, so you can check that out at eater dot net slash 65 02 And of course, as always, I want to thank all my patrons.

  • Your support is a huge part of what makes these videos possible, So thank you.