6809 (Sixty-Eight-Oh-Nine)
6809 has a special place in my heart because once you read the specs, you start drooling immediately. I think 6809 is a 16bit transition squeezed into 8bit bus package.
- Two 8-bit Accumulators (A,B) that can be combined to form one 16-bit Accumulator (D)
- Two 16-bit Indexable Stack Pointers (S, U)
- Program Counter Relative
- Auto-increment/Decrement by 1 or 2
- 8x8 unsigned multiply
- 16-bit arithmetic
- Transfer/Exchange all registers
- Push/Pull any register or any combination of registers
- Two clock variants: 6809 (internal clocks) and 6809E (requires external clock source).
- Hitachi variant: 6309 and 6309E, emulation mode (6809-compatible) and native mode (faster, 32bit ops)
RetroShield project started because I started building myself a more powerful version of Simon6809 (Simon6809 Turbo) but then realized it would be a lot of hassle to deal with discrete logic gates and I/O to add the functionality I wanted to add (i.e. fast storage, sdio, displays, audio, etc.). So the idea of RetroShield was born for the first time for 6809. After that, I built 6502, then Z80 versions. I’m actually going to build a RetroShield for as many 8bit microprocessors as possible so people can experience them :)
Theory of Operation
Lets go over the following to understand how RetroShield works.
- cycle-by-cycle operation of 6809E
- arduino to uP connections.
- memory maps
- io device(s)
Note: I used 6809E (external clock) variant in RetroShield because it is usually cheaper and more available compared to the internal clock oscillator version (6809 without an E
). 6809 variant basically works the same way, but it generates clocks E and Q internally using a crystal oscillator and outputs them on two pins, whereas on 6809E we need to generate E and Q ourselves for 6809E.
Arduino to 6809E connections
Arduino Mega is connected to the 6809E as follows. Arduino will drive the E, Q clock signals high <-> low, and during each cycle will look at the R/W signal and the address bus to figure out what to do, and then will either drive data bus or capture data bus to finalize the action. Arduino can also drive the IRQ, FIRQ and NMI signals to cause interrupt handling.
Arduino ports are mapped to the 6809E signals as follows. GPIO directions must be set accordingly of course.
/* Digital Pin Assignments */
#define DATA_OUT PORTL
#define DATA_IN PINL
#define ADDR_H PINC
#define ADDR_L PINA
#define ADDR ((unsigned int) (ADDR_H << 8 | ADDR_L))
#define uP_RESET_N 38
#define uP_E 52
#define uP_Q 53
#define uP_RW_N 40
#define uP_FIRQ_N 41
#define uP_IRQ_N 50
#define uP_NMI_N 51
#define uP_GPIO 39
Cycle-by-cycle operation of 6809
6809E uses two clock inputs: E and Q.
- E clock drives the bus cycle (similar to how 6502 clock).
- Q clock is a leading version of E, which I believe is used in internal timing/signaling.
Remember, all interesting things happen on clock edges, specifically E clock:
- E goes down. Processor drives new address bus and R/W to indicate the type of bu activity (Read or Write).
- E goes high, getting ready for data transaction.
- Latching of the data by the destination device (uP or memory or IO) happens when the E goes down.
- if this was a READ cycle, the IO device needs to drive the data before E goes down (min delay circled 17).
- if this was a WRITE cycle, the IO device needs to latch the data when E goes down. Note that data will be ready circled 20 delay after rising edge of Q (a lot of time).
- After E goes down, the processor starts the next cycle by outputting the next adddress and R/W signals.
We didn’t talk about Q much, because if you look at the timing diagram, it doesn’t matter much, other than we have to drive it as specified. So we will toggle accordingly to make 6809E happy.
If you plan to modify the Arduino code to add your own device support, it’s good to know the following two concepts:
- setup time: minimum time data must be stable before the clock edge.
- hold time: minimum time data must stay stable after the clock edge.
if these timings are not met, the data latched may be corrupted, which means you will be scratching your head why your code is acting randomly. Having said that, at ~100kHz operating clock frequency, we usually don’t have to worry about such min delaysbut good to know.
Driving clocks E & Q
to run the processor as fast as possible, the code that does low level signal handling is done thru the timer interrupt with no function calls. In summary, the timer interrupt will go thru one bus cycle, driving the clks high and low, as exactly shown in the timing diagram above, Then the interrupt handle will either input or output data bus according to the control/address signals.
Memory Map
The code currently emulates an Simon6809, which for details you should read the Simon6809 project page.
// MEMORY
#define RAM_START 0x0000
#define RAM_END 0x0FFF
#define ROM_START 0xE000
#define ROM_END 0xFFFF
byte RAM[RAM_END-RAM_START+1];
////////////////////////////////////////////////////////////////////
// Monitor Code
////////////////////////////////////////////////////////////////////
// static const unsigned char
PROGMEM const unsigned char simon09_bin[] = {
0x1a, 0xff, 0x4f, 0x1f, 0x8b, 0x0f, 0x36, 0x7f, 0x01, 0xa5, 0x10, 0xce,
...
0x00, 0x09, 0x00, 0x0c, 0x00, 0x0f, 0xe0, 0x00
};
RAM is created by byte RAM[RAM_END-RAM_START+1]
. The PROGMEM… makes sure the ROM code is saved in the Arduino’s Flash Memory.
IO device(s)
6809 IO devices are memory mapped, meaning all io devices are mapped in memory and access thru memory read/writes.
Simon6809 used an FTDI USB-UART device to communicate. Arduino code links the emulated FTDI chip to the Arduino UART port. For details of FTDI wiring, you should read the Simon6809 project page.
To emulate any IO device, you need to read thru the datasheet and and figure out the registers and what they do/how. And then add the functionality to the interrupt code. The beauty of software is you can do anything you want :)
Last, since you can use existing arduino shields like display, sdcard, audio, etc. you can memory map them to make them available to 6809.
Links for more information:
- Lots of 6809 info at Arto’s site
- Wikipedia 6809 Entry
- SWTPc 6809 systems
- Flex Operating System