6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Mar 29, 2024 12:58 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Mon Feb 21, 2022 9:52 am 
Offline

Joined: Fri Nov 12, 2021 10:24 pm
Posts: 13
Just starting off on the 6502 and thought a fun first project would be to hookup LED's to A0-A15 and D0-D7 and use a 74HCT574 to latch the LED's which will be controlled via code written to a ROM.

What I want to do is write some assembly to turn on D0 through D7, one LED at a time, which is easy enough with the '574 and some address logic, then also want to do the same with the LED's on A0-A15 via the '574's. So each LED which be turned on and off in turn as I read? from memory.

Not sure if this is doable. I can't just hookup '574s to the address lines can I? How would I address them?


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 10:16 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8412
Location: Southern California
For the address lines, you could connect phase 2 to the 574s' clock inputs since they're triggered on the rising edge and the address is always stable by the time you reach the rising edge.

For the data lines though, you'd want an inverted phase 2, so you'd get the data that's available at the end of the clock cycle, ie, when phase 2 falls.

Why the 574's though? Unless you bring the clock speed down to a few Hertz, the 574s' outputs would still be too fast to see anything. You could put the LEDs directly on the address and data lines, with series resistors, say 3.3K each, to control the current.

If you want to control the LEDs to flash one at a time though instead of showing what's on the data bus in each cycle, you'll need some minor address decoding for the 574, and treat it like I/O (actually the "O" part, ie, output), then write a little program to sequence them.

Do go through the 6502 primer. You'll find it fills in a lot of holes and answers a lot of questions. http://wilsonminesco.com/6502primer/ It was written years ago to answer questions that kept coming up on the forum, and hardly a week goes by that it doesn't get updated. It comes in 22 logically arranged chapters.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 10:29 am 
Offline

Joined: Fri Nov 12, 2021 10:24 pm
Posts: 13
Thanks for the info. I'll take a look at the primers and using phase 2 - at least this points me in the right direction.

I want to control all the LED"s individually so will need to use the latch.


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 11:20 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1392
Location: Scotland
For the output latch on the data bus, it's fairly easy to do - I did just that on my early Ruby boards - There is a little video here:

https://www.youtube.com/watch?v=0nrVC7XUgZs

The IC to the right of the board is a 74ALS573 latch.

The tricky bit is decoding - I "cheat" by using a GAL to save me using TTL - for that board any address in $FExx sent a byte to the latch - also any read from that range put the button status into bit7 (again, easy to do in the GAL)

Go for it!

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 1:27 pm 
Offline
User avatar

Joined: Sun Nov 07, 2021 4:11 pm
Posts: 101
Location: Toronto, Canada
gmc wrote:
Thanks for the info. I'll take a look at the primers and using phase 2 - at least this points me in the right direction.

I want to control all the LED"s individually so will need to use the latch.


The hard part (though not really that hard!) is going to be “decoding” the '574's address so that it latches on to the data bus only when you intend for it to. Otherwise, if you simply tied it to ɸ2, you'd end up grabbing data from the bus at every cycle, even though the CPU may be doing other things (such as reading each instruction from the ROM). As Drogon mentioned, you'll need some combinatory logic for this—a GAL really does save a lot of time in these cases, but you can also just use discrete logic chips. For example:

Attachment:
Screen Shot 2022-02-21 at 08.35.49.png
Screen Shot 2022-02-21 at 08.35.49.png [ 124.98 KiB | Viewed 1107 times ]


Here, the outputs of U1 and U2 will both be low when you read or write to $FE00. When /WE is low and ɸ2 is high, the output of U4A will also be low. Feed everything into U5A, and it will output a high when you try to write to $FE00, which will latch your '574 to pick up data from the bus. (Please note: I'm very much a newbie, and this is untested, so it might not be right :-) — also, I'm sure that more experienced folks can come up with a simpler scheme.)

Another option is to use a 6522; this is more expensive than a handful of discrete logic chips, but it'll be much easier to wire up. At some point or other, you will probably want to use a 6522 to handle I/O in your design anyway, so you might as well get a leg up on figuring out how it works.

HTH!


—Marco

Edit: I had U1 and U2 wired backwards to the bus. Fixed!


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 1:56 pm 
Offline

Joined: Fri Nov 12, 2021 10:24 pm
Posts: 13
Good point on 6522 - I didn't even think about this option yet and it might be the way to go.
That can be phase 2 of the project :)


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 2:30 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10760
Location: England
I feel a bit unclear on what you're up to here, gmc, although I welcome any experimentation and I'm sure you'll learn by it.

Garth speaks about the clock rate. That's because the 16 address lines and 8 data lines are changing, every single clock cycle, whatever program you are running. If you wanted to have some insight into what a program is doing, by monitoring those 24 lines with LEDs, you would indeed have to run very slowly, or to single-step.

But I wonder if perhaps it's something else that you're trying to do. If, for example, you wanted to have 8 LEDs which you can control from your program, you would indeed indirectly attach them to the databus. You'd need to latch the data bus values at the point your program writes the 8 bit value in question, and so the latch would normally be controlled by some logic which decodes an address. You find that you've built a simple 8 bit output port.

And that's a valid and interesting experiment.

I'm rather less sure about the idea of having 16 LEDs controlled by the address bus. If they are to sample the address bus, at some time that's dictated by a program you're running, then the address they capture will (I think) be the address of the program, or an address the program chooses to access.

Could you perhaps sketch a bit more, either about what you hope to see, or what you hope to build?


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 3:30 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3328
Location: Ontario, Canada
gmc wrote:
Just starting off on the 6502
Welcome, gmc!

BigEd wrote:
I feel a bit unclear on what you're up to here
I too was wondering about this, gmc. Allow me to review some fundamentals, just in case.

You mentioned code stored in ROM, so let's look at what code is and does. And let's just say the code is stored in memory (because it could be in ROM or in RAM).

An instruction such as LDA $1234 occupies just one line in your assembly language source, but it requires four cycles to execute. Here's what happens in the latter half of each cycle when Phi2 is high. (The first half of each cycle is merely the time during which the address bus changes in preparation for the second half.) We'll assume the LDA $1234 instruction is stored at address $0200. It is a 3-byte instruction.

Cycle 1: the CPU puts $0200 on the address bus, and the data bus returns the opcode byte of the instruction, in this case $AD.

Cycle 2: the CPU puts $0201 on the address bus, and the data bus returns the first operand byte of the instruction, in this case $34.

Cycle 3: the CPU puts $0202 on the address bus, and the data bus returns the second operand byte of the instruction, in this case $12. (Yes, the most-significant byte of the $1234 comes last!)

Cycle 4: the CPU puts $1234 on the address bus. The data bus returns whatever happens to be stored there and the CPU copies that value to the accumulator.

It should be obvious that address and data buses carry a lot of activity, even for one simple instruction! Your post makes me wonder whether you have a good grasp of this. We'll be happy to steer you toward further information! Or perhaps I'm mistaken, in which case I apologize.

Cheers,
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 3:53 pm 
Offline

Joined: Fri Nov 12, 2021 10:24 pm
Posts: 13
A bit more details on what I'm trying to do

The plan is build a 6502 tester where the program stored in ROM will loop and turn on the LED (connected via some latch/logic) connected to D0 on, then D1 on, D2 off, D3 on D2 off etc

And then repeat the same for A0 to A15. This way I can get some visible feedback that all the address and data lines are working as expected.

Or am I overthinking this as is there a better way to test the address lines to check if one if stuck high or low. I thought having a visual display of LED's connected to each address line would be the simplest, but then maybe not.


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 4:03 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1392
Location: Scotland
gmc wrote:
A bit more details on what I'm trying to do

The plan is build a 6502 tester where the program stored in ROM will loop and turn on the LED (connected via some latch/logic) connected to D0 on, then D1 on, D2 off, D3 on D2 off etc

And then repeat the same for A0 to A15. This way I can get some visible feedback that all the address and data lines are working as expected.

Or am I overthinking this as is there a better way to test the address lines to check if one if stuck high or low. I thought having a visual display of LED's connected to each address line would be the simplest, but then maybe not.


If there is a stuck address line then the chances of it booting to a ROM are slim...

Howeber, you might want to look-up a NOP Test...

You jam the NOP opcode ($EA) on the data bus and let it run. No ROM required. The address-lines will cycle-binary counter like continually as long as there is clock (and the other CPU signals set appropriately). If you were driving the clock and reset externally and can monitor all 16 address lines from e.g. an ATmega or PIC then you could test all 65536 combinations...

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 4:24 pm 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 288
gmc wrote:
The plan is build a 6502 tester where the program stored in ROM will loop and turn on the LED (connected via some latch/logic) connected to D0 on, then D1 on, D2 off, D3 on D2 off etc

And then repeat the same for A0 to A15. This way I can get some visible feedback that all the address and data lines are working as expected.


If that is all your tester needs to do, then it's relatively easy. All you need (apart from clock and reset and so on) is a ROM, '574s for the LEDs, and a tiny bit of logic. Reads always come from the ROM. Writes always load the '574s.

The code is simple too. With no RAM there's no stack, so you can't use JSR. But that's OK. Store $01, $02, ... $80 to address 0, with a delay between writes. Then store $00 to addresses $0001, $0002, ..., $8000, again with a delay between each. That will do exactly what you've described, but won't be capable of very much more.


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 4:28 pm 
Offline

Joined: Fri Nov 12, 2021 10:24 pm
Posts: 13
John West wrote:
Store $01, $02, ... $80 to address 0, with a delay between writes. Then store $00 to addresses $0001, $0002, ..., $8000, again with a delay between each. That will do exactly what you've described, but won't be capable of very much more.


This is exactly what I'm looking to do for the first project. Nothing more, nothing less.

Time to get out the breadboard and start messing around.


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 4:37 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10760
Location: England
(Thanks John, very clear thinking there to use RnW as the distinguishing signal!)


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 21, 2022 7:45 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1918
Location: Sacramento, CA, USA
For a very tidy medium length delay, I recommend Bruce's little gem here:

viewtopic.php?f=12&t=5271&p=62581#p62581

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 06, 2022 4:44 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
It is possible to make an "all singing, all dancing" 6502 tester. However, it will definitely require another processor which is in a known good state. This may or may not be another 6502.

If you want boot-strap and you only have one processor then the best solution is to keep one breadboard configured as a 6502 NOP tester. This requires a dedicated oscillator and reset circuit to be kept on the breadboard. The upside is that you'll have a known good oscillator and known good reset circuit even if your 6502 remains dubious but passes NOP test.

A new CMOS 6502 can be officially clocked at 0-14MHz. However, NMOS 6502 may be restricted to 0.15-1MHz. To obtain the common range, I use 16MHz ceramic resonator and one or more 4 bit counter chips to divide the clock by 16 or more. The standard NOP test using opcode $EA may lead you astray because 6502/65C02/65816 will by default fetch the next byte during an idle cycle - and then fetch it again when executing the next instruction. Therefore, dividing the input clock by 65536 and comparing with A15 may be off by a factor of two. It is instructive to supply opcode $A9 (LDA imm) or similar.

To test each address line, place one current limited LED from ground to signal and another current limited LED from from signal to power. I have a lazy technique where I wire two red, orange or yellow LEDs in series to make them five volt tolerant and then wire two pairs back-to-back so that the indicator works in either orientation. It takes hours to solder enough of these indicators but you'll save more time when you can place them with abandon.

NMOS 6502 will not be able to light two red, orange or yellow LEDs connected to ground. However, NMOS 6502 is able to light two LEDs connected to power. CMOS will light either permutation. Within this arrangement, it is quite easy to determine if LEDs are at full brightness or not. If one LED is at full brightness or constantly off then one address line is not functional.

After you have taken 6502 from your NOP test breadboard, it is possible to make a very flexible memory map using one 74HC139. One half of the 74HC139 may provide read/write signals suitable for Output Enable/Write Enable signals of RAM or ROM. The other half of the 74HC139 may provide 4*16KB address decode. For your experimentation, this may be 16KB RAM, 16KB for one or more output latches, 16KB for one or more 6522 chips and 16KB ROM. (This arrangement may be expanded or quickened with minor substitutions.)

If you don't mind bus contention, it is possible to place multiple 65xx peripheral chips within one I/O segment. To achieve this, connect all 6522 active low chip selects to output 2 of the 74HC139. Then connect A4, A5 and suchlike to individual 6522 active high chip selects. Within 16KB I/O segment, it is possible to connect up to 10 6522 chips with no further hardware. (Yes, this is 200 GPIO.)

When your experimentation has progressed, you may substitute your output latch with more RAM. In this case, your memory map would be 16KB RAM, 16KB more RAM, 16KB for one or more 6522 and 16KB ROM.


Attachments:
example-memory-decode0-0-0.odg [6.41 KiB]
Downloaded 35 times
example-memory-decode0-0-1.png
example-memory-decode0-0-1.png [ 9.51 KiB | Viewed 960 times ]

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: