ECE 476 – Spring 2003
Christopher Foster and Jeff Puchalski
When Chris and I first started tossing around project ideas, I sputtered out: ‘Hey! Wouldn’t it be cool if we could emulate a Nintendo using some Atmel chips?’ Chris replied ‘Ooh, that’d be awesome, then I could play Ice Hockey and Final Fantasy 1 again!’
After looking over some documentation on the NES, we realized how impossible it was going to be to emulate not only its 6502 processing core, but also the separate Picture Processing Unit (PPU). The systems integration would have probably taken us a year to build ourselves, so we decided to scale down the project a little..
The result? ‘We’re going to build an Atari 2600 emulator! Yeah!!’ This seemed more manageable, and we began work on it in zest, hoping to be able to relive our childhoods of playing Asteroids and Pitfall!. Once again though, we were about to realize that we bit off more than we could chew. Due to some insane synchronization constraints between the Atari’s 6502 processing core and the proprietary Stella Television Interface Adapter (TIA) chip, we were pushing the limits of our poor little Atmel chips. The emulation process usually degrades one’s processing capability considerably, and there just wasn’t going to be enough cycles in the Stella emulator chip to render video and process input from the 6502.
Once again, we needed to adjust the bounds of our project, or else risk certain failure. Finally, we settled on the unifying element of all these systems: the MOS 6502 processor. This was the backbone of all the systems we examined, and so we figure it would be the right place to start. We’ve set a series of goals that increase in complexity, and plan to conquer as many of them as we can. In the short term, we want working emulation; father off on the horizon, we’d like to add in some video generation and input capabilities to be able to play Apple II games.
And so, we begin our quest to emulate one of the greatest processors ever to walk the earth.
As he stated above, when Jeff approached me with the concept of building a Nintendo out of the Atmel, I instantly thought back to the winter afternoons when I used to come home from middle school and spend hours glued to the gaming system. We quickly jumped at this opportunity, and began to research the technical specifications of the system. Yet, despite our over-ambitious nature, we soon realized that our original goals were simply unattainable due to the constraints of both time and processing power.
Looking back at this past month, this project was not only a test of our ability to program a microcontroller to emulate a different processing core, but also a test of both our patience (with the equipment, the code, and especially each other), as well as a test of our ability to balance our ambition with our sense of reality. Since hindsight is usually 20/20, I feel the need to briefly impart my advice to future 476 students. As an addendum to the Top Ten Things You Can Do to Survive ECE476’s Final Project Month, I’d like to add this advice:
Know your limits. As much as we’d all love to have a final project whose bells and whistles rival Las Vegas slot machines, realize that a month is a very short time, and that dealing with the disappointment of having to scale back your project as you progress along is much better than coming to the same realization on the day of your demonstration.
An Introduction to the MOS 6502
The MOS Technologies 6502 processor was one of the most popular CPUs of the late 1970’s and early 1980’s. It was introduced in 1975 as an inexpensive alternative to designs from several other companies, notably Motorola and Intel, not to mention that it outperformed most of them.
MOS Technologies was started by a group of engineers from Motorola who had designed the 6800 processor. Their original, completely new design was the 6501, which prompted Motorola to sue because its pin layout was compatible with the 6800. As a result, they rearranged the pin layout, and thus the 6502 was born.
The 6502 was first sold in September 1975, for $25, which was over $100 less than their main competitor’s chips, the Motorola 6800 and Intel 8008. Its popularity soared, and it worked its way into many mainstream systems, including the Atari 2600, Apple II, Commodore PC, Nintendo Entertainment System, and even Furbys (aww).
The MOS 6502 is an 8-bit processor with a 16-bit address bus. Despite its slow clock speed (approx. 1MHz), the internal processing logic runs four times as fast, thus making the chip competitive with other, higher-clocked CPUs. The 6502 has only 5 registers, all 8 bits wide: an accumulator, two index registers (X and Y), a processor status register, and a stack pointer.
The stack address space ranges from 0x100 to 0x1FF. There are four implied stack instructions used to access the stack. They are pha/pla, to push and pull the accumulator, and php/plp, to push and pull the processor status register, respectively. There are numerous addressing modes available for each instruction. These include implied, absolute, relative, accumulator, indexed indirect, indirect indexed, and immediate. There is also a zero-page mode that accesses memory locations in the first page of memory (addresses 0 to 255), consuming one less byte for the address. Relative addressing was used mostly by branches, which could move to a location +/- 128 bytes from itself.
There are a number of undocumented instructions too, which resulted from about 32 opcodes being left undefined in the original specification. Also, in the original 6502, the indirect jump instruction, JMP (xxxx), was broken. This problem was not fixed until the 65C02.
A more detailed specification sheet on the 6500 series family of processors can be found here.
Since the goal of this project was to emulate the 6502 chip, most of the work consisted of programming, and the amount of hardware needed was minimal. Besides using the Atmel Mega32 microcontroller chip, we needed to use a 32K external SRAM chip as the data memory for the 6502. Additionally, we needed a way to load 6502 code into the Atmel’s memory. We decided that the best way to do this was through the USART’s RS-232 connection on the Atmel. A block diagram of the complete emulator is shown below:
Once the Atmel has been turned on and the user has opened a connection to the Atmel via Hyperterm, the first thing they must do is load a 6502 program onto the chip. In Hyperterm the user gives the Atmel a command telling the microcontroller that a program will be loaded. The user will then send the program binary via Hyperterm to the microcontroller using the Xmodem protocol. Once the microcontroller has received the binary, it will send a reply via Hyperterm, confirming that the program has been loaded. Upon completion, the user can then run the program, and while it is running the microcontroller will send the results of each instruction back to Hyperterm. The user can then choose to either run the program again or load a new program to run.
In order to implement these features, we designed various state machines to control the different aspects of the system, which are described in the software section of this site. The hardware section of this site gives an in-depth look at the integration of the three main components of our project.
For more detail: MOS 6502 Emulation on an Atmel Mega32