Sunday, June 18, 2017

A 6502 CPU for the RC2014 - Software

Hardware is useless without software. So what software do we have for the 6502 CPU board?

Cross Assembler

The biggest challenge as a Mac user in the ancient computing world is that most cross-development tools for 8-bit microprocessors are for use with Windows (and preferably DOS).

Running VMware Fusion is an option but a relatively expensive one: you need to buy Fusion along with a Windows license.

The other option is running TASM in a DOSbox. But that still requires some work.

Since I am quite lazy, I settled on asmx. This is a multi-CPU cross-assembler (it supports everything from the Z80 to the RCA 1802). The maintainer, Bruce Tomlin, can still be reached by email and has been responsive to my (usually dumb) questions.

The trick to using asmx on a modern OS X computer is the compilation process. Yes, you download the sources and run make on them. By default, make will try to build the old ppc binaries. You'll need to edit the src/Makefile to just compile for i686:

        TARGET_ARCH = -arch i686

Bring up

Once you have designed and built a new CPU board, you need at a minimum some code to make sure that the CPU board is working. You don't want the initial test code to be too complicated because complication = risk of errors.

Fortunately, there is the Real Retro UART Board. This is based on the ancient AY-3-1015 or similar UART devices. Unlike the more modern (that being a relative term) devices like the 6850, Zilog SIO, 16550 and others, the AY-3-1015 is hard configured i.e. you configure the device by wiring up various signal pins. There is no need to write code to initialize the device.

This makes bringing up a new CPU a little easier: there's less new code to write. I generally just write a bunch of 'A' characters to the serial console to show that the new CPU is running correctly. With the 6502, the code will look like:

                   ldx   #'A'
        lda   uart_status     ; serial port status
        and   #$02            ; is tx buffer empty
        beq   uart_out1       ; no
        stx   uart_xmit           ; put character to Port
        jmp   reloop


To make a new CPU system minimally usable, you need a Monitor/Debugger. This will allow you to develop and test other software.

An interesting article about the various 6502 monitors can be found here.

For the RC2014 6502 CPU board, I took Daryl Rictor's "lite" monitor and heavily modified it. The key changes are the following:

  • Provide the same user interface as the Monitor/Debugger for the Z80
  • Implement a BIOS-like approach for console I/O with (a) an externally accessible vector table for console I/O calls and (b) a way to swap in handlers for different types of UARTs
  • Resume from breakpoint
The source code can be found here. The ROM images are here.

There are several versions of the Monitor/Debugger, depending on which UART/serial IO board you want to use. If you are using the 16550 board, you'll want to have a 16C550 version of the UART. The 16C550 has the autoflow control feature to automatically toggle the RTS signal without intervention from the 6502. This allows us to run that UART at 115200 baud without overwhelming the 6502.


No new RC2014 CPU board is complete without a version of BASIC.

The 6502 has several versions of BASIC available. I decided to start with a port of Lee Davison's Enhanced BASIC.

Lee passed away several years ago and the original source host site is no longer available. A copy of the 2.22 version is hosted on GitHub by Klaus2m5 and can be found here. A discussion forum dedicated to EhBASIC (as it is referred to) is here.

My own fork of EhBASIC is on GitHub here. As usual, I've made some changes:

  • Implementation of a SYS function to exit back to the Monitor/Debugger
  • Clear cold start and warm start entry points. This is meant to provide a similar user interface as the MS BASIC that is used for the Z80 on the RC2014.
  • The use of the BIOS API entry points for console I/O
A pre-build ROM image that combines EhBASIC with the Monitor/Debugger is here. The image is 32KB in size but only the top 16KB is actually used.

The EhBASIC cold start entry point is at $c100 (just above the I/O space) and the warm start entry point is at $c103.

Unlike the RC2014 MS BASIC, EhBASIC only recognizes uppercase (caps) commands/functions. Very retro!


The Z80 and the 6502 are very different devices.

The Z80 runs four clock cycles to execute the fastest instruction. The 6502 runs just one. The Z80 has more registers and more complex ("dense") instructions compared to the 6502.

Therefore, you cannot compare the Z80 and the 6502 by just looking at the clock speeds.

My estimate is that at a given clock speed, the 6502 is approximately 4 times faster than the Z80. Putting it another way, a 1MHz 6502 runs as fast as a 4MHz Z80. The 7.3728MHz Z80 on the RC2014 is as fast as a 1.8432MHz 6502.

Since we now have a version of BASIC for the 6502, I decided to run a benchmark test. The algorithm used is Robert Sharp's prime number program:

40 FOR N = 3 TO L
50 FOR D = 2 TO (N-1)
90 GOTO 110
100 PRINT ".";
110 NEXT N
120 END

I ran this on a 14.7456 MHz Z80 (using my Z80 CPU board) and a 4MHz 6502 (using the 6502 board for the RC2014). 

To find all prime numbers to 199, the Z80 gave 10.62 seconds (iPhone stopwatch), whereas the 6502 gave 10.82 seconds.

Which mostly confirms my hypothesis. The Z80 runs slightly denser/more efficient code which makes it a little faster.


I will be doing two things in the near future:
  • Port of Peter Jennings' Microchess to the RC2014
  • Port of MS BASIC along with an update benchmark - see new article here
I have both working today but checking them into GitHub will require some clean up work... :)

And of course, there is Forth with several versions floating around in the 6502 world.

1 comment:

  1. What about a small device like PIC16Fxxxx to simulate the "hardwired" UART, as Mostek AY-Devices are real old things, hard to find and easy to ruin...

    Together with some CPLD for adress-decoding and "house-keeping" intelligent Controllers would take over lots of time intensive jobs, especially in serial communications and in Audio/Video field, helping the main processors to speed up to a real usable speedrange. PC and Unix-workstations did the same in the 90ties to speed up graphics output, and even today the processor on a high-end "gaming" video-card is much stronger than the main cpu...

    Also on SW-Level it is much easier to emulate elder chipsets than in HW, e.g. Network-Cards for ethernet or sound output (a soft 6581 "SID" will run on either a small FPGA or a DSPic device in the 5$ range and with less pins than the original device (if wanted so)).

    And after a while i guess, you will end up in LVDS-signalling and multi-FPGA instead of 8Bit-Busses paralleled... ;o)