The Uzebox design guidelines were simple: keep complexity and parts count low, yet don't cut on quality.
And the ATMega644 greatly helped me to accomplish this. They have so much integrated peripherals and functions
(like SPI, UARTS, counters, analog comparator, pull-ups, etc); it was 'almost' too easy to attain that goal.
Let's a have look at the big picture and then I'll describe the global flow and what each block does.
Here's the Uzebox block diagram:

The CPU

The hearth of the system is a chip called a micro-controller (or MCU for short).
Contrary to the first computers which had separate chips for the CPU, RAM, ROM, peripherals and so on,
MCUs have everything inside the same chip. Not only does that reduce the footprint and cost, it also reduce complexity,
because you don't have to deal with such thing as memory and peripherals timing issues.
There's literally hundreds of MCUs on the market, each with their own particularities.
Some have 32 bits core, can run up to several hundred megahertz and have hundreds of
pins and a very complex set of peripherals. Some have simpler 8 bits cores and runs at 20Mhz.
Some even have parts in DIP format making them much more hobbyist friendly. That's the case of the Atmega644,
a member of the AVR family of MCUs made by Atmel. They are relatively simple to understand, yet they are
very powerful having very efficient RISC cores that yields near one MIPS per megahertz.
The AVRs have embedded RAM, flash memory for programs and static data, EEPROM and a 2 cycle hardware multiplier.
Plus they have one of the most extensive set of peripherals of their class.
Lots of I/O ports, 8 and 16 bits Counters, UARTs, SPI, TWI, watchdog timer, brown-out detector, you name it.
The ATmega644 is naturally the heart of the system. Its job is quite simple: do everything! Well, except the NTSC color generation.
This would have been quite time consuming for such a low-end MCU. So what means almost everything?
- Generate the video synchronization signals. The AD725 doesn't do that, only color conversion, so the MCU has to do it. And
it has to be precise to avoid jitter!
- Render the picture. This include scrolling and determining sprites transparency against the background
- Mix and output the music and sound effects
- Read the joystick buttons states
- Read and handle the MIDI data stream read through the UART
- Handle read/writes to the SD card
- And last but not least...run your games!
The most important thing going out of the MCU is the graphics 'pipeline'. The MCU has a dedicated 8-bit port (PORTC)
onto which pixel data is output. This is a digital port and can only output binary data, 0 or 1s (or if you prefer, 0 volt or 5 volts).
Each pixel needs exactly one byte to represent its color. 3 bits are allocated to the red component,
3 bits to the green component and 2 bits for the blue. In theory, this gives 256 simultaneous colors.
Though in practice there are a number of colors that are very close to each others.
Anyhow, this arrangement will give a color table that looks like this:
The DAC

A DAC, or digital-to-analog converter, is a circuit that converts a binary value to a proportional output voltage or current.
So if your DAC has a maximum output of 1V, and you give it a binary value of 128 (half the maximum value that can hold a byte),
you'll get 0.5 volt at the output. There is several ways to implement a DAC. You can take off-the-shelf chips or build one out of resistors.
With the resistors approach, there are two main types: R-2R and weighted. I used the R-2R approach.
Explaining how that works is a bit out of the scope of this document, so I'll encourage readers to search the net.
There's a lot of good tutorial available on the subject. So let's just say that, according to Wikipedia:
"The R-2R ladder operates as a string of current dividers whose output accuracy is solely
dependent on how well each resistor is matched to the others. The R-2R ladder is inexpensive and
relatively easy to manufacture since only two resistor values are required. It is fast and has fixed output impedance R."
The Uzebox DAC is in reality composed of 3 smaller ones; one for each color component.
If you look at the schematic you'll see them, each boxed with the color they represent.
You can see the red and green each have 3 wires going back to the MCU, while the blue component only has 2.
Also, if you look closely, you will notice that each block's output goes to an input pin of the AD725, which correspond to the appropriate color.
In between, those little capacitors are used to block DC voltage from entering the AD725.
(Note: This represents my R-2R DAC. Since the initial release, it changed to a different 'weighted' version
that takes half the resistors and gives better whites. Since my schematic is not updated with it yet, if you want
to build your own with the new DAC, see the download section for the "AVCore" schematic.)

So in the end, the DACs simply converts binary values that represent color components(0-7 for red and green and 0-3 for blue)
to voltage ranges (0-0.7V) suitable for the AD725.
The AD723 / AD725

As mentioned earlier, NTSC composite color generation is not trivial. And especially not efficient in pure software.
The AD725 (and the more recent AD723) take out that problem from the equation.
It accepts as input discrete voltages for each RGB color components and, internally, converts them to
the appropriate luminance and chrominance information. It also generates the color burst, adds it to the
composite sync generated by the MCU, does some filtering and outputs composite video and S-video simultaneously.
No hassles and guaranteed stable results.
The AD725 requires two more input to perform its job. One is the composite sync signal generated by the MCU.
The other one is a clock signal at 14.31818Mhz. This clock happens to be four times the frequency of the color burst
and is absolutely required in order to generate color. That clock's frequency also happens to be exactly half that of the MCU.
This is no coincidence. The MCU has a timer set to toggle an output pin at half its main clock.
Joystick Interface

The beauty of the NES interface is its simplicity and ease of integration. In each NES joypad there's a
small chip, an 8-bit shift register. The way it works is simple. When the console wants to read the buttons
state, it activate the latch line that tells the shift register to load all the button states.
Then it releases the line and the buttons are memorized by the shift register. The console starts toggling
the clock line and eight bits are serially shifted into the console's data line.
No external parts required, and only 4 I/O lines for 2 joysticks. Can't be simpler.
What's more, the SNES interface is identical, except that you shift 16 bits, to account for the extra buttons.
Note that the whole PORTA could be used to support other joysticks like 2 PSX or 1 Sega or Atari.
For more details, have a look at this very good
NES/SNES interface document from Parallax.
MIDI Interface

MIDI, or Musical Instrument Digital Interface, is a specification developed many years ago to allow the
inter-connection of musical instruments and computers. It's a simple unidirectional serial
interface running at a somewhat slow 31250 bauds. MIDI-In is the communication stream from the
host (PC, keyboard) to the instrument. MIDI-Out is the communication stream from the
instrument to the host. A MIDI communication stream consists of events: tempo, which notes as been pressed, velocity, channel volume, etc.
Currently, only the MIDI-In has been implemented. Hardware wise it's dead simple:
It only requires an octocoupler, 2 resistors and a diode.
SD card Interface

The SD card interface is also very simple. It requires only few external components.
A SD card socket, a few resistors to act as voltage translator and another voltage regulator
since the SD card works at 3.3 Volts. Everything else that could be remotely complex is part of the SD card itself!