Saturday, June 24, 2017

MS BASIC for the RC2014 6502 CPU Part 1

The RC2014 ships with Nascom's version of MS BASIC for the Z80.

I have ported Lee Davison's Enhanced BASIC to the 6502 CPU board. As described in my previous article, Enhanced BASIC is really quite fast. A 4MHz 6502 CPU running a prime number benchmark with Enhanced BASIC is almost as fast as a 14.7456MHz Z80 running MS BASIC.

There are several versions of MS BASIC for the 6502 dating from the original Apple 1.

Michael Steil wrote an excellent archeological analysis of MS BASIC in this article. The key point of the article is that you are now able to build an exact replica of MS BASIC for several ancient 6502-based microcomputers.

The complete source code is hosted on GitHub.

The challenge though is that you need to use the cc65 cross-compiler to build the binaries from source.

Apparently, the latest versions of cc65 don't work. Folks have recommended using version 2.13.3. This can be found in several places including this GitHub repository.

If you are a Windows user, Grant Searle has a prebuilt set of binaries here. However, if you are a Mac user, you will have to build cc65-2.13.3 yourself.

Here is how I did it:

  • Decompress the cc65 source package to cc65-2.13.3 (you can use another name and substitute accordingly in the following steps)
  • Build the cc65 cross-compiler
    • cd cc65-2-13.3
    • cp make/gcc.mak makefile
    • make
    • make install

In my next article, I'll talk about how to actually configure and build  MS BASIC.

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:

        reloop
                   ldx   #'A'
    uart_out1                
        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


Monitor/Debugger

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.

BASIC

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!

Benchmarks

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:


20 PRINT "LIMIT";
30 INPUT L
40 FOR N = 3 TO L
50 FOR D = 2 TO (N-1)
60 IF N/D=INT(N/D) THEN GOTO 100
70 NEXT D
80 PRINT N;
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.


Future

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.
















Monday, June 5, 2017

A 6502 CPU for the RC2014 Part 2b

Readers of Part 2 of this series of articles on getting the 6502 CPU to run on the RC2014 will recall that I was having trouble getting the standard RC2014 Serial I/O module to work reliably.

The latter is based on the Motorola 68B50 ACIA which uses the same bus architecture as the 6502. So compatibility should have been a slam dunk.

That it was not was entirely due to human error: mine.

I had correctly re-wired pin 14 (the E clock pin) of the 68B50 to pin 4 (TX_CLK) which is itself derived from the Phi2 signal of the 6502. All good there.





However, by doing that, I had removed the IORQ signal from the address decoding process! This meant that I was randomly reading and (worst) writing to the 68B50 while read/writing memory!

The 6502 should select the 68B50 only when IORQ was valid.

This is solved by removing the M1 signal from the CS0 pin of the 68B50. Remember that the M1 signal is unique to the Z80. In that world, you want it to be high ("1") to validate any I/O cycle. On the 6502 CPU board, we had tied this to VCC.

Now that the CS0 pin of the 68B50 is available, we can use it with IORQ. The latter is active low while the CS0 is active high. Pin 2 of the 74HCT04 is the inverse of IORQ and can be used directly to validate CS0.

So we keep the 74HCT04 and connect its pin 2 to CS0 (pin 8 of the 68B50).

Voici:


And it all works!!

Conclusion
- If you want to explore the world of the 6502 CPU with a RC2014, you can reuse all the standard modules (RAM, ROM, Serial I/O) with a little bit of re-wiring work.
- All you need is the 6502 CPU board, a 6502 CPU and a number of other easy to get components.




Saturday, June 3, 2017

A 6502 CPU for the RC2014 Part 2

Today's article will talk about how to use RC2014 hardware with the 6502 CPU Board aka what is compatible and what is not.

You can go Tor-Eirik's route by using only custom memory and I/O boards to build a Replica 1. Or you can use what you already have (e.g. the boards that come with the RC2014 Full Monty kit).

To start, the following picture shows how we are inverting the Z80 and 6502 memory space as discussed in the last article:




RAM

RAM compatibility is the easiest to deal with.

The original 32KB RAM module works as-is. The entire 32KB is mapped to 0000h-7FFFh in the 6502 address space.

The 64KB RAM module works as long as you either disable or remove the lower 32KB device. This may sound counterintuitive until you consider that we're inverting the A15 signal to flip the upper and lower 32KB memory segments. If you look at this picture, the device to remove is U3 (marked as Start-7FFF). You will want to keep the device marked 8000-FFFF as it will be remapped to 0000h-7FFFh by the inverted A15 signal.

My own Real Retro 3KB RAM board will work as long as you short the JP1 jumpers. The latter will map the RAM from 0000h-0C00h in the 6502 memory space.

My Simple RAM/ROM board will also work. You will want to configure it, if you are inverting A15 on the 6502 CPU board, for ROMLO and RAMHI.

ROM

ROM is a little bit more complicated.

There are currently 2 "standard" ROM modules for the RC2014. I'll ignore the 8K module as I think it's no longer available.

The first module is that one that you'll get with the Full Monty kit. This module/board uses a 27512 ROM and splits the 64KB capacity of the ROM into 8 pages of 8KB each.

The address lines A15, A14 and A13 are used to decode the ROM in memory and 3 jumpers are used to select the page.

If we were to use the module without any modifications, we will map the ROM correctly to the top 32KB memory segment of the 6502 address space. However, the A14 and A13 will only select the ROM when they are low (0) which ends up mapping the ROM page to the lowest 8KB of that 32KB memory segment. Instead, we need the ROM page to be mapped to the highest 8KB in memory.

My solution has been to lift off Pins 1 through 3 of U1 (the 74HCT32), then solder a link from Pin 3 (U1) to ground. See this picture:



The next step is to select the right page in the ROM.

Assuming that you are using one of my ROM images and a 27512 ROM, you will probably only be writing the ROM image to the bottom 32KB of the 27512 ROM.

The 6502 boot code and Monitor/Debugger are located at the top part of the ROM image i.e. in page 3 of the 27512. So you will want to configure the jumpers to select Page 3.

The above applies only if you are using a 27512 device. If you are like me and use a 28C256 32KB EEPROM, you will want to tie the jumpers high (to '1').

The Pageable ROM module/board is a little easier although you will still want to make a wiring change.

The latter is to disable the paging circuitry. I have not tested that circuitry with the 6502. However, I have verified that it will crash an Intel 8085 (my 8085 CPU board for the RC2014). The reason for this is that the paging circuitry does not fully qualify I/O requests (e.g. via the WR or RD signals). So the ROM may be paged out in error.

To disable the paging circuitry, remove U6 (74HC393) and U2 (74HCT138). Then solder a link from pin 3 of the 74HC393 to ground.

If you are using a 27512, you will want to configure for a 32KB page size, then select the lower 32KB page (A15 of the 27512 to ground or '0').

If you are using a 28C256, things get more complicated. You will select a 32KB page size, but leave off the left-most jumper. Then jumper the A14 and A15 lines (in the page selector) to high or '1'. See the following illustration:

Page size:
x x x x x
  | | | |
x x x x x
x x x x x  

Page selection:
x x x x x x
        | |
x x x x x x
x x x x x x

My Simple RAM/ROM board will also work. You will want to configure it, if you are inverting A15 on the 6502 CPU board, for ROMLO and RAMHI.

Serial I/O

Serial I/O on the RC2014 is done by a Motorola 68B50 ACIA. This device is bus compatible with the 6502. However, because of the way it is wired for use with the Z80, compatibility with the 6502 is not straightforward.

At the minimum, the E signal (Pin 14) must be disconnected from IORQ. To do this, you just need to pull the 74HCT04! Then you need to connect E to the CLK line of the RC2014 bus. The easiest way is to Pin 3 or 4 of the 68B50.

Finally, you will want to run the 6502 at a baudrate-friendly frequency. This is because the 6502's Phi2 output is connected to CLK and therefore used to generate the baudrate on the 68B50. I use a 1.8432MHz oscillator.

Now, this setup works. However, it has not worked reliably for me. It is possible that the 68B50 needs the actual R/W signal from the 6502 instead of the RD signal. I'll have to investigate further.

My own UART boards (both 16550 versions and the Real Retro UART) work. The key again, with I/O is to add C000h to the original Z80 port addresses.

Dr Baker's SIO board will likely not work as it uses a Z80-specific device. In any case, I have not tested it.

Other hardware

There are a number of other interesting RC2014 boards but I have not tested them for compatibility with the 6502. I would encourage other folks to check them out and let the community know what works vs doesn't work and/or workarounds/patches.

The RC2014 community itself has gone in many directions as far as add-on boards are concerned. Spencer Owen has graciously compiled a list of RC2014-compatible projects here.

Hopefully, the availability of a 6502 CPU board will spur development in even more directions...!

Next

In my next article, I'll cover software for the 6502.