Saturday, November 29, 2014

ERIC-1: Homebrew Computer

Everyone seems to be building their 6502-based 80s esque computers nowadays, and it seems to be a lot of fun. Well, I don't want to miss the party, so I've recently started building one of my own. I've now been working on the thing for a few nights and here's what I've got so far....


Behold the mighty ERIC-1 running at whopping 2 Mhz! 


As you can see I'm building this on a breadboard, but the plan is to build the final version on a PCB that I'll be etching myself. But before I can do that I need to settle on a few features.

The general design is quite simple. There's is the 6502 CPU, 64 KB of SRAM (actually I'm using a 128 KB SRAM chip but the 6502 can only address 64 KB) and a coprocessor. The coprocessor is an ATMega1284P microcontroller that has several purposes: first it generates the necessary reset and clock signals for the 6502. It also contains the ROM image and implements the I/O interface for the system. Later I'm planning to use it to generate composite video and maybe sound.

Reset and Clock Signals


The 6502 seems to be very picky about the quality of the reset and clock signals. I found out the hard way that simply connecting a button to the reset line is not enough, like with e.g. AVR microcontrollers. The reset signal must be clean, rise quickly and be properly debounced. Also the clock signal can only be stopped in high state although modern versions of the 6502 do not have this restriction. I wanted to be able to switch between different clock frequencies easily and switch between free run and single step modes on the fly. The ATMega1284P can handle these tasks and more easily.

Shared Memory


The only way to implement I/O with a 6502 is to use memory mapping. This means that the I/O devices usually sit on the address and data bus of the 6502 and the 6502 simply reads and writes certain addresses corresponding to the I/O devices. Usually this is implemented with some sort of address decoding logic which generates chip select signals for devices based on the status of the address lines.

I wanted to try a different approach. In ERIC-1 the 6502 and the coprocessor share the same 64 kilobytes of memory. Naturally both devices cannot access the memory at the same time, so the coprocessor acts as the bus master. Since the coprocessor also generates the clock signal for the 6502, it can simply halt the 6502 when it needs to access the memory. When the 6502 is halted it still drives the address bus so I'm using 74HC541 buffers to detach the CPU from the bus. The buffers are controlled by a single output pin of the coprocessor.

But what about the data bus? In case the CPU is halted during a write cycle, the 6502 is driving the data lines. Trying to update the SRAM at the same time will cause bus contention when both the coprocessor and 6502 are trying to write data to the bus. A simple fix for this is to halt the CPU only during read cycles, e.g. when 6502's R/W is high. This means the coprocessor may have to wait a few clock cycles longer when it wants to access the bus, but overall this seems like a good solution.

Here is the code fragment from the AVR firmware that I'm using to halt the CPU:


ROM


Any computer needs some memory non-volatile memory (memory that keeps its state even when powered off) so that it knows what to do when it boots up. Usually in 6502 systems there is a separate ROM chip that contains the boot up routines of the computer. The ROM chip is mapped to upper part of the 64 KB address space, because when the 6502 wakes up it first reads the starting address from $FFFC - $FFFD (6502 is little endian, so the lo byte of the address is stored first, then the hi byte). This reset vector points to the machine code routine (in ROM) that should be executed first.

Since the coprocessor of ERIC-1 has full access to the SRAM, I decided to use the upper part of SRAM as ROM. The ROM code is stored in microcontroller's flash memory. At startup the coprocessor holds the 6502 in reset while the ROM image is copied to the SRAM chip.

What can it do?


To test the computer that I've built so far, I made a simple ROM routine that… you guessed it, blinks a LED! Here is the ROM routine, hand assembled in the coprocessor firmware:

The coprocessor firmware holds the 6502 in reset, copies this piece of code to SRAM, starts generating the clock signal. Every thousand clock cycles of so it halts the 6502, reads the byte at address $10 and turn the LED on/off based on the value read: if the value is below 128 the LED is on, otherwise it's off. The ROM routine therefore has a delay loop (the X registers counts from 255 to 0), otherwise the blinking would be way too fast to notice with the naked eye.

Now that I have the basic setup working, I'm going to add more I/O. I'll probably start working on the video generation next. Until that time!

Schematic



p.s. ERIC-1?? Some of you may remember an obscure 6502 based computer, the Oric from the 80s. It was not a hugely popular computer, and in fact I've never even seen one, but I thought it would cool to nickname my computer to remind of a real 6502 system. Or it could just be acronym for "Extraordinarily Robust Integrated Computer" :)  

12 comments:

  1. I thought the name was because of the Kim-1 computer. It was the first thing i thought when I saw the display.

    ReplyDelete
  2. Oh, yeah, the Kim-1. Totally forgot it. I'm too young to really know it (I think it was made in the 70s?) but I've certainly heard about its existence.

    ReplyDelete
  3. Hello PETRI, first of all, congratulations, this is a very interesting project. I have some questions about the schematic: (1) Where comes from the signals /WE (IC5) and NS4 (IC1 - Phi0)? (2) The CLK signal is connected on R/W (IC1), how this work? Great job! Cheers.

    ReplyDelete
    Replies
    1. Thank you! Oops, there seems to be slight errors in the schematic. Some signals connecting to IC 1 have been misnamed. I've updated the schematic. Thank you for spotting this!

      Delete
  4. Ops... Now I got it, I saw the project upgrade. Really nice job!

    ReplyDelete
  5. I recognised the name as an Oric-1 reference but then I have one in the loft.

    I've also got a 6502 chip and was considering using an external processor (maybe an Arduino) to generate clock and simulate/emulate I/O and memory for the 6502, so a bit simpler than yours as you're using real RAM.

    ReplyDelete
    Replies
    1. Hi! Thanks for the comment! I also thought about using a microcontroller to emulate an SRAM but unfortunately the AVR chips are too slow to emulate a SRAM. Unless of course the 6502 is clocked very slow.

      Delete
    2. The Arduino Mega 2560 has 8k RAM and 54 I/O pins, easily enough to connect to every 6502 pin, I was thinking of making a crude 'shield' & letting the Mega 2560 generate the clock signal, supply ROM and RAM data as the 6502 needs it.

      I'm not worried about the speed or the RAM size as I'm not intending to do anything more serious than play about - IF I do it at all!

      There may be problems I haven't thought of.

      Delete
    3. Sounds like a good plan then! The ATmega2560 runs at 16 MHz, right? I think it should be possible to run the 6502 close to 1 MHz, the bottleneck being ram accesses. Have fun!

      Delete
  6. What's the tool that you use to draw the schematics?

    ReplyDelete
    Replies
    1. I'm using free version of Eagle. It's pretty good once you get used to its user interface.

      Delete
    2. Ah, the colour scheme mislead me to think it's some old OrCAD - I used to use it many years ago (DOS version, only for schematics, with Tango for PCBs).

      These days I use DipTrace, I just can't stand Eagle's UI. And Altium is way too expensive :-/

      Delete