What are common mistakes for beginners?

For discussing the 65xx hardware itself or electronics projects.
Lost
Posts: 20
Joined: 07 Oct 2007
Location: Toronto, Canada
Contact:

What are common mistakes for beginners?

Post by Lost »

In a different thread Garthwilson commented how there are common mistakes made by beginners when designing their own systems. I'm wondering what I should be looking for myself.

Garthwilson said to Put capacitors as close to the IC that needs them as possible.

what else would be obvious to the experience people that us rookies wouldn't see right away?

Also, as I think about some of the design decisions made and I'm not sure I understand why so here are a few questions of my own:

Why are the memory mapped devices typically in the high-end RAM areas (just below ROM)? I would think having as much contiguous memory for the programs as possible would be more beneficial so sticking the device mappings in 0200 - 02FF strikes me as the better location (just above the stack area).

How fast should I be able to get a W65C02 chip to go in a breadboard? Related to that, how fast would a motherboard go before timing issues arise (assuming a less than ideal design)? I'm asking because it seams most hobby systems don't go much beyond 4MHz on chips that can go at around 14MHz. I would think in this case faster is better. I am myself hoping for over 10MHz after I get off the breadboard.

When just starting out (and not sure how far I will go) what are the essential tools?
- soldering iron (for everything after the breadboard)
- EEPROM writer
- ?

I ran across an old analog oscilloscope (that I now have access to) but I'm not sure how fast it is (or if it even works). How fast would it need to be to be of use initially (assuming a 2MHz system initially)?
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

Quote:
Why are the memory mapped devices typically in the high-end RAM areas (just below ROM)? I would think having as much contiguous memory for the programs as possible would be more beneficial so sticking the device mappings in 0200 - 02FF strikes me as the better location (just above the stack area).
I chose the boundary between RAM and ROM on my SBC-2 boards because it simplified address decoding. Low A15, High A14-A8. When running these into an 8 input NAND, I only needed to invert A15.

My next SBC's will use programmable logic for address decoding and I plan to use the $02xx page for my IO; for the same reason, to keep memory as contiguous as possible.
Quote:
How fast should I be able to get a W65C02 chip to go in a breadboard? Related to that, how fast would a motherboard go before timing issues arise (assuming a less than ideal design)? I'm asking because it seams most hobby systems don't go much beyond 4MHz on chips that can go at around 14MHz. I would think in this case faster is better. I am myself hoping for over 10MHz after I get off the breadboard.
My SBC-2 ran at 5MHz, but 6MHz was too fast for the 65C51 (2MHz part). Once WDC gets their 14MHz 65C51's in production, I should be able to go faster. The next slowest part is the EEPROM - mine are 120ns (8MHz). You can get 55ns EPROMs that will help increase your clock speed.
Quote:
Garthwilson said to Put capacitors as close to the IC that needs them as possible.
If you plan to wire wrap on a breadboard, then you can solder bypass caps under the socket between the power and ground pins. Some distributors even sell socket with caps already installed that way.
Quote:
I ran across an old analog oscilloscope (that I now have access to) but I'm not sure how fast it is (or if it even works). How fast would it need to be to be of use initially (assuming a 2MHz system initially)?
I am working on a 14.3MHz project and my 50MHz scope does not perform well. Once I get down to about 5 MHz, the waves seem to display better.

Smilingphoenix gave me this advice in another thread:
Quote:
For a square wave to look even reasonable on a scope, the scope needs a bandwidth of at least 10 times the square waves frequency. On my 30MHz scope, a 14.318MHz signal looks vaugely sinusoidial! You need a 150MHz scope for a 14MHz square wave to look square.
Hope this helps.

Daryl
Wally Daniels
Posts: 53
Joined: 30 Aug 2002
Location: Windsor Forks, N.S. Canada

Re: What are common mistakes for beginners?

Post by Wally Daniels »

Lost wrote:
Garthwilson said to Put capacitors as close to the IC that needs them as possible.
Yes, this is always good advice.
Quote:
Why are the memory mapped devices typically in the high-end RAM areas (just below ROM)? I would think having as much contiguous memory for the programs as possible would be more beneficial so sticking the device mappings in 0200 - 02FF strikes me as the better location (just above the stack area).
This decision is influenced alot by functionality. If you have a handy
way of (re) loading High ROM such as a ROM emulator it can be handy
to use RAM in the ROM area when building your basic OS. For example
the 27C256 is an 8X32K ROM and is almost a drop in for it's RAM equiv
the 62256 ( or equiv ) just A14, R/W and.......Vpp I think need to be
manipulated. As well two '256' devices can conveniently give you lots
of Room for RAM & ROM space. I/O can be added with alittle glue logic.

Really I think most designers simply add RAM in the Low are because
of the Stack & lets not forget Zero Page :-) not to mention tradition !
Quote:
How fast should I be able to get a W65C02 chip to go in a breadboard?
Hard to say...it depends on how many long wires you have...Try to pick
a clock source that can be scaled up easily. That way you can start low
say with 1Mhz and move up. You might be suprised. It would be a neat
experiment.
I can tell you that you can easily reach 8Mhz with wire wrap. I have not
gone much beyond this because of the chips I am using.

- W
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

I fail utterly to see how placing I/O in page 2 will give you more contiguous amounts of RAM. Indeed, it has precisely the opposite effect.

You'll end up with a system with RAM from $0000-$01FF, then a 256 byte gap, then $0300-$xxxx.

The reason I/O is usually placed just beneath the ROM is because that produces the most contiguous amount of RAM possible. It takes extra logic (read, extra gates, extra transistors, extra money) to do memory decoding that is not on a power of two boundary, or to remap some RAM pages elsewhere.

For example, placing ROM at $C000-$FFFF, and I/O from $8000-$BFFF, with RAM at $0000-$7FFF takes only a handful of gates. This costs pennies. "OK," you might say, "but now you have lost 16KiB to I/O space!" Very true. There are four major ways to handle this problem, and to do it right, every one requires some form of programmable logic, just to keep propegation delays under control.

1) Deal with it as it is. Use software to swap memory in and out of the address space as you need it. Machine language compiled with a "virtual memory aware" language compiler would enable this to occur without you ever having to think about it. It would probably be fast enough for most tasks as well.

2) Introduce additional RAM banks that overlap each other in $0000-$7FFF. This is how most Apple IIs and Atari systems worked. Here, you'd use a control register in I/O space to select which chunk of 32KiB you'd like to see at any given time. More advanced forms of this will break the 32KiB into (say) 4 8KiB "pages", with each page containing its own upper address bits.

3) Add address decoding logic that switches I/O space out of the address space. Since the 6502 lacks dedicated I/O instructions, this takes some creativity. Here are some ideas I've come up with off the top of my head just now:

3A - Set a bit in a control register in I/O space that, when set, remains set for something like 1024 (or so) clock cycles. While this bit is set, you have access to underlying RAM. Once the bit resets, I/O space will return. Not suitable for storing or executing code, unless you reset that bit periodically via an interrupt of some kind. It'd still be useful for storing non-executable data though.

3B - Detect when a BRK instruction is executed (if (sync==0) && (d0-d7 == 0) && (phi2 == 1)), and upon doing so, force I/O (and, if applicable, ROM) to come back into the memory space.

3C - Code running in $0000-$3FFF sees I/O at $8000-$9FFF, while code running at $4000-$7FFF sees I/O at $A000-$BFFF. Code running in $8000-$BFFF never sees I/O at all. This takes some trickery to implement though. Not recommended.

3D - Create a single-port mirror for an I/O register dedicated to controlling memory configuration. For example, the Commodore 128 had a set of registers at $FF00-$FF05 IIRC, which were decoded expressly for the purposes of allowing the CPU to recover its I/O registers once they were switched out. Commodore 64 and Plus/4 had a somewhat similar solution.

3E -- Always keep I/O space in memory, but let it float about the address space. This can be done by allocating one byte of I/O space to holding the "current I/O page", which is used to compare against A8-A15. This way, you can place the I/O at $0200-$02FF, but if you need to access RAM in that area, you can just move it out of the way by rewriting that register temporarily.

4. And finally, use a different CPU -- the 65816 comes to mind -- which offers a larger address space and the instructions needed to access it, wihch makes cheaper address decoding techniques viable again, and supports a 16MB address space.

Note, however, that the 65816 has a quirk -- when it boots up, it tries to fetch vectors from $00FFFx, not $FFFFFx. Because of this, you must use, at a minimum, an address decoder that properly handles at least 9 bits of address lines. Ouch!! Not cheap, not fast, and not pretty. It is possible to apply option 3E to the decoding of ROM addresses, of course, but again, I'd rather the CPU just not force me to have to segment my memory space into non-contiguous chunks in the first place.

These are some of the options you have available, and I hope I've answered your question.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

kc5tja wrote:
I fail utterly to see how placing I/O in page 2 will give you more contiguous amounts of RAM. Indeed, it has precisely the opposite effect.

You'll end up with a system with RAM from $0000-$01FF, then a 256 byte gap, then $0300-$xxxx.
Yes, you are right. However, $0000-$01FF is what I consider special purpose RAM (Zero page and Stack space). By putting IO at $02xx, I can start general purpose RAM at $0300 and go as high as I want in one contiguous block. I could place a small boot code in ROM at the top of the address space to align with the reset vector. The rest would be G.P. RAM. Also, placing shadow RAM under the upper ROM and copying ROM to RAM and switching out ROM also would yield a large block of contiguous RAM.

I also agree that bank switching is also a common practice that can effectively increase useable RAM.

My SBC-3 (65816 based) will have IO at $02xx and 512k of RAM. From $000300 to $07FFFF will be contiguous G.P. RAM. Yes, I know the 65816 can place the stack anywhere, and that zero page can effectively be moved as well, I am choosing to keep the traditional locations reserved for their purposes.

That is my current line of thinking. I hope that clears up my original comments.

Daryl
Lost
Posts: 20
Joined: 07 Oct 2007
Location: Toronto, Canada
Contact:

So many options.

Post by Lost »

kc5tja wrote:
I fail utterly to see how placing I/O in page 2 will give you more contiguous amounts of RAM. Indeed, it has precisely the opposite effect.

You'll end up with a system with RAM from $0000-$01FF, then a 256 byte gap, then $0300-$xxxx.
I really should have explained my assumptions better. In general I see your point and you are quite right. I was thinking along the line of what 8BIT was talking about:

0000-00FF is the zero page and acts as special purpose registers
0100-01FF is the processor stack (on 6502) and can't be moved

If I stick all the device I/O at 0200-02FF AND I use all remaining addressing for RAM and ROM, then I think I get more flexibility for RAM/ROM tradeoffs. I can:

1) use a very small boot ROM (say 4K)
2) use a large ROM (say 32K)
3) or something in-between (like 16K)

and all the memory in between is contiguous and can be used for loading and running programs without having to worry about making sure holes are left for the I/O area.

Of course these assumptions may result in significantly more cost and/or complexity than I am not ready to deal with. Which is why I asked.

So, thank you for your answer.
kc5tja wrote:
...

These are some of the options you have available, and I hope I've answered your question.
Wow I've got a lot to learn. It's going to take me a few days to fully understand all that you have offered.
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

8BIT wrote:
That is my current line of thinking. I hope that clears up my original comments.
We're just going to have to agree to disagree on this. I see this as a distinct step backwards, personally. If I were to "overlap" the I/O with anything, I'd do it with ROM, not RAM.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

kc5tja wrote:
We're just going to have to agree to disagree on this.
Agree!!! Believe me, I do understand your reasons.

As I recall, there were some designs that put IO on part of zero page to increase access. I guess we all have our own way of thinking and looking at design choices.

thanks!

Daryl
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

Yes, the Atari 2600 placed is I/O registers in zero-page to allow for faster register accesses. Seeing as how the 2600 rendered its display almost exclusively on CPU timing artifacts, this was a wise choice. :)
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

When I was at university, some of my clever fellows realised that it was possible to add write-only I/O devices to a system without losing any of the memory map. Simply enable the ROM for read accesses only and then re-use the same addresses for your write registers. Since the ROM was a 16k device, their address decoding could be equally simple and sloppy with no loss of memory map.

If you are looking at possible spaces for I/O, you could always do what Acorn did with the BBC micro and use the address range FC00 - FEFF. This gave them a 15k ROM, 3/4K of I/O space and then a 256 byte ROM block which was only used for interrupt and MOS vectors. Incidently, if you put the Beeb's MOS rom in another system, the "missing" 3/4k holds all the credits for the system designers.
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
Gapter
Posts: 3
Joined: 22 May 2007
Location: Moscow, Russia

Post by Gapter »

smilingphoenix wrote:
When I was at university, some of my clever fellows realised that it was possible to add write-only I/O devices to a system without losing any of the memory map. Simply enable the ROM for read accesses only and then re-use the same addresses for your write registers. Since the ROM was a 16k device, their address decoding could be equally simple and sloppy with no loss of memory map.
...
It seems to be too complicated ;). But why write-only? If SYNC goes high - read ROM, otherwise - read i/o :D
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

Gapter wrote:
smilingphoenix wrote:
When I was at university, some of my clever fellows realised that it was possible to add write-only I/O devices to a system without losing any of the memory map. Simply enable the ROM for read accesses only and then re-use the same addresses for your write registers. Since the ROM was a 16k device, their address decoding could be equally simple and sloppy with no loss of memory map.
...
It seems to be too complicated ;). But why write-only? If SYNC goes high - read ROM, otherwise - read i/o :D
SYNC (which is active-low, BTW) is asserted ONLY for the opcode byte; it is deasserted for the operand bytes that may follow. Therefore, it is possible to use this, but the logic involved will need to be aware of which opcode is being fetched, so that it can "remember" the SYNC state for the appropriate number of operand bytes. This will require a ROM of its own, and a suitable shift register implementation. Although I doubt that the total cost will exceed that of any other solution discussed so far, it is a solution that will (because of the look-up ROM) limit clock speeds due to propegation delays.

I'd say that this is suitable, at best, for devices running 3MHz or slower.

A CPLD version of this will go faster, but I predict that you'll end up dedicating a large amount of CPLD logic to this task.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

I wouldn't even use it for that, because it rules out strings like you might use for error messages, or any other kind of data.
Gapter
Posts: 3
Joined: 22 May 2007
Location: Moscow, Russia

Post by Gapter »

kc5tja wrote:
SYNC (which is active-low, BTW) is asserted ONLY for the opcode byte; it is deasserted for the operand bytes that may follow. Therefore, it is possible to use this, but the logic involved will need to be aware of which opcode is being fetched, so that it can "remember" the SYNC state for the appropriate number of operand bytes.
Can we demarcate single instruction execution without counting operand bytes?
65c02 datasheet wrote:
...The SYNC output is provided to identify those cycles whitch the microprocessor is fetching an OpCode. The SYNC line goes _high_ during the clock cycle of an OpCode fetch... ...In this manner, the SYNC signal can be used to control RDY to cause single_instruction_execution_.
By other words, single instruction demarcates from one SYNC rising edge to another.
OK, let's devide ROM into 2 sections. SHARED ROM share address space with I/O.

Code: Select all

+----------------+
| NONSHARED ROM  |
|                |
+----------------+
|   SHARED ROM   |
|                |
+----------------+
|                |
- Instructions from shared ROM
can't access I/O for read
- Instructions from nonshared ROM:
can access I/O
can call soubrotines from shared ROM
can't access data from shared ROM

How to implement 'memory bank' switching?

Additional signals:

1. SYNC _rising_edge_ (with some delay) gives us signal that indicates opcode fetch - SYNC_S
2. Decoder gives us signal that indicates wich area (SHARED-1, NONSHARED-0) selected - SRA_S

may be like this:

Code: Select all

                   JK flip-flop
SRA_S               +--------+
--------------------| J    Q |------ ROM bank --
                    |        |
SYNC_S              |        |
--------------------| clock  |
                    |        |
SRA_S  |\NOT        |      _ |
-------| >o---------| K    Q |------ I/O bank --
       |/           +--------+
Complicated... Anyway, my suggestion was demorcated with smile. Because I have a stupid question. Why shall we fight for every one KB? Is it reasonable?
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

If you want to use SYNC to determine whether to select ROM or I/O, you don't need to decode the instruction and work out how long the operand is. Simply assume that all instructions are three fetch cycles long. Any shorter instructions are either 1-byte long, in which case they only perform internal or stack operations, or 2 bytes long, in which case they are performing internal or page zero operations on the third cycle. After the third cycle, an instruction will be performing stack, page zero or data read/write cycles. The first two cases don't concern us, because they are not in ROM, and the third case is what we are interested in.

Deciding if a cycle is a code cycle or a data cycle only requires one IC, a basic 4 bit shift register with reset. Use the SYNC signal to reset the shift register. Hold the shift register serial input high. Use the falling edge of phase 2 or the rising edge of phase 1 to clock the shift register. When a 1 appears on the appropriate output, it indicates that code fetches are finished and subsequent cycles are data cycles and should access I/O instead of ROM.

This method does, of course, not allow for any data to be stored in the ROM. However, there is no reason why part of the I/O space should not be a second ROM, which of course could only contain data and not code.

I originally concieved this idea for switching two RAM areas, one that would only contain code and another that would contain data, allowing a full-featured assembler to be written for my acorn atom while still leaving a reasonable ammount of RAM free for the source code and assembler output. It never got implemented because I got one of those dreaded PCs and suddenly had lots of RAM available.

At one time, squeasing as much as possible into the limited address space of a 6502 was required, which is why ideas such as this one, paged RAM and the like were created. Nowadays, anything that requires this ammount of address space should really use a processor with a larger address range, such as the 65C816, so I guess this idea is somewhat academic.
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
Post Reply