Getting to the free-run stage is easy. Where it gets complicated is when you add hardware to make your fancy program counter into a real computer. When you’re doing a project like this, its assumed you are willing to put in the time to learn some electronics in order to move forward. Both the journey and the destination are the rewards.
Every computer as a system needs these basic things:
- Input/ Output
On its own, the 6502 holds up to 65,535 (64k) address “slots”, each holding 8 bits of data. This is what we call “memory (or address) space”. But not all of the address is dedicated to memory as most people think of it (RAM). Rather, its divided up among various parts of our system: RAM, I/O devices, ROM, etc. Therefore, we need a map of the memory in order to understand the hardware.
For my basic learning system, I’ve scaled things down quite a bit. For now, I’m only using 32k of RAM, 4k of ROM and a tiny portion for one I/O device – the 6551 ACIA (serial) chip.
$0000 – 7FFF: 32k SRAM
$8000 – $BFFF: Open
$C000 – $EFFF: I/O (ACIA uses $C000 – $C003)
$F000 – $FFFF: ROM
The Apple /// introduced a concept called, “bank-switched memory”. This allowed the /// to extend beyond the 64k capability of the 6502 by swapping in/out banks of RAM in 32k sections. With the right daughter-card, the /// could use 96, 128, 256 or 512k of RAM.
The /// was also a software-centric machine. On first boot, the memory space from $F000 – $FFFF is hardwired to ROM. Once it ran through its diagnostics, it would look for the SOS operating system in the built-in drive. SOS would then take over that ROM space and use it for RAM as well. (I’m over-simplifying things here. But the important take-away is that SOS took full command of the hardware and did extraordinary things with it.)
RAM is important in that the 6502 utilizes zero-page memory for a lot of its data handling and processing. A “page” is 256 bits of data. Zero-page is the first 256 bits of address. So we need some RAM wired to the first byte of the address bus.
I’m using a 62256 SRAM chip, capable of 32k of RAM. For simplicity, I’ll wire the 6502’s address pins A0 – A14 to the RAM chip’s address pins. Likewise, I’ll connect the 6502’s 8 data pins to it as well.
Next, in order for my simple computer to talk with me, I’ll wire in a 6551 ACIA. The 8-bit data bus will connect to its 8 data pins, but I only need to connect address pins A0 and A1 to the 6551. More on that later.
Finally, we need a program in order for anything useful to happen. That program will need to be stored in ROM, or in my case, a 28C64 EEPROM. This EEPROM is capable of storing up to 8,191 bytes of data. But the ///’s ROM program was only 4,096 bytes (half that amount). So I will connect the 6502’s address lines A0 – A11 to the same pins on the EEPROM, and tie it’s A12 pin to ground.
The last piece of the puzzle is a question of logic. These 4 chips are all connected to the address and data busses. However, they all can’t be enabled at the same time. We need a traffic cop of sorts to tell which chip, according to our program in ROM, will be active at a time. This is called, “memory address decoding.”
The RAM, ROM and ACIA chips have chip-enable pins which activate the chip when they are tied LOW. The typical way to tell which chip needs to be active is determined by which address is on the data bus. This is where the memory map comes in.
When the numbers $0000 – $7FFF are on the address bus, our address decoder will enable the SRAM chip. When our address is in the range of $C000 – $CFFF, the ACIA is enabled. Finally, addresses $F000 – $FFFF will enable the ROM chip. The 6502 doesn’t have a chip-enable pin because it’s the brain of the system. It always needs to be enabled.
So, to perform this address decoding, I’m using a 74LS138 (3 to 8) decoder (multiple ones soon). The input pins are connected to A12 – A15 of the 6502. Based on the address fed to it, one of the 8 output pins will be made LOW. By looking at the 138’s truth table, we can see which of it’s output pins can connect to which device.
One final note – I’ve moved everything over to a wire wrap board. Breadboards are known to cause problems with high-frequency circuits, including capacitance issues and flaky connections. I knew I’d want to move my project to a permanent board anyway, so I made the leap of faith over to just mounting on a wire wrap board. Trust me: you WILL want to go this route.
Working with wire wrap allows much more flexibility with layout and connections. You can solder in your smaller components, such as resistors and capacitors – as I’ve done with the reset circuit. But larger components like ICs are connected together reliably via wire wrap. When using breadboards, I consistently ran into problems with routing jumper wires among the various chips. The connections were not secure and it quickly turned into a spaghetti mess.
Wire wrap is suited for connecting address and data busses together among the chips. You can still make corrections easily. Overall, you will save an immense amount of time and frustration by going to wire wrap.