Arduino 6502 emulator + BASIC interpreter

This is really something all CBM lovers (fanatics) should play with.

It is by no way a real C64 but it is a real CBM PET/Vic20/C64 machine.

And its fun.

To come, The SCI-64 :slight_smile:

I broke a leg on the 1284 while moving it to a perfboard.

Damn me! I shouldn't be doing these mistakes after so many years?

Well, it will still run but the program will be a bit awkward?

It's going to have a real calculator mode.
That is a tribute to CBM and Jack Tramiel.

And to my dear friend Ray who is writing that part.

janost:
I broke a leg on the 1284 while moving it to a perfboard.

Damn me! I shouldn't be doing these mistakes after so many years?

Well, it will still run but the program will be a bit awkward?

I have used an Xacto knife before to cut (scrape) the encasement enough to solder a wire to a broken leg. After ensuring a connection, coat with a drop of fast set epoxy.

Ray

mrburnette:
I have used an Xacto knife before to cut (scrape) the encasement enough to solder a wire to a broken leg. After ensuring a connection, coat with a drop of fast set epoxy.

Ray

I know Ray, been there before. :slight_smile:

That's why I said I shouldn't be doing things like that?

I'm not the only one! Back when any IC was quite expensive, especially when my only income was mowing lawns, I had to repair IC legs a few times.

Hi. Can somone please post the complete code (if without the roms is will still be ok) of the serial version (from pito)?

thx, Peter

Enclosed pls find the serial version.

It works with a terminal, ie. Teraterm, 40x25 char. It is an extremely simple emulation of a video output and keyboard input, with no graphics, etc.

Worked here with Fubarino SD (pic32MX) and the newest Majenko's SDZL board (pic32MZ).

It runs the trigonometric demo in 12secs with pic32MZ @200MHz (or 5secs at 921k6 serial).

It may work with atmega1284p (yes it worked) or DUE (etc.), but you have to adjust the ram sizes in both files.

Caps Lock must be ON on your keyboard when writing Basic programs in the emulator.

arduino_6502_pic_C64_OK.zip (25.8 KB)

@pito: thx. I can confirm, it works also with arduino due.

arduino_6502_pic_C64_OK.cpp.o: warning: definition of `RAM' overriding common
cpu1.c.o: warning: common is here

Der Sketch verwendet 33.628 Bytes (6%) des Programmspeicherplatzes. Das Maximum sind 524.288 Bytes.
Erase flash
Write 34764 bytes to flash

runs just fine.
On Mega, even with just 4096 bytes ram, 21k on variable space is missing.

Peter

Tested on a Stellaris Launchpad using Energia, works great. Just changed the memory size to 16kb for testing, Because the Stellaris has only 32KB of RAM. This blew my mind (now I will no sleep tonight thinking in this hehehe). Anyways, Does anybody think about an Atari 2600 emu based on an Arduino? May be using another chip for audio/video

I have Leonardo set up to write to the keyboard of my laptop, but it will stop working when i have nes emulator running.

Any idea of an easy way to make those keypresses work on nes emulator?

Did anyone try this on an esp8266? (26-80Mhz, 32kB, $4)

Specs: Official specifications - Everything ESP8266

Nard

Ok, i tried this myself. I had to remove all progmen references because esp8266 doesn't seem to handle this. It still runs on my pro mini, but on an esp8266-01, I get the following error on upload: '.text' will not fit in region íram_0_seq'. I suspect this means that there is not enough memory, but can't understand why, the esp8266-01 should have 512kb. If I reduce the rom table to 2 bytes the error persists. If I reduce the program code the error vanishes.

I have posted an question on the esp8266.com forum for help and am hoping I have to use some specific esp command to load the sketch in the correct memory-part.

The original code (message 1 of this thread) works on esp8266! :slight_smile:

All credits go to martinayotte! esp8266 forum - explanation and sourcecode

Ø
Starting 6502 CPU...

6502 EhBASIC [C]old/[W]arm ?

Memory size ? 

34047 Bytes free

Enhanced BASIC 2.22

Ready
FOR I=1 TO 10000:NEXT I

Ready

I did a speed test using "FOR I=1 TO 10000:NEXT I".The esp8266 finished in 15 seconds on 80 Mhz, and in 8 seconds on 160 Mhz! So this makes the esp8266 emulate an 1,13Mhz 6502. Haven't looked into the code optimization performed after message 1 of this thread, so could become even faster!

Furthermore the internal memory of the esp8266 makes it possible to allocate 32kB in code. (change "#define RAM_SIZE 1536" in cpu.cpp to "#define RAM_SIZE 34816")

This could be the base for a very cheap C64. I found some internet posts which claim that with an esp-12 it should be possible to get some sort of ISP interface. So using this to interface to 2x 32k256 chips (3.3V same as esp8266) we have 64kB. Another pin to input a ps/2 keyboard and a pin to output video commands (to another 8266 to off-load the 6502 emulator ) and we have a <$10 C64!

And I got Pito's code for the Pic32 working on an esp2866-01. Since the rom is bigger, a little bit less memory remains. The speed is still about 112% that of an real C64. See attachement for code.

    **** COMMODORE 64 BASIC V2 ****

 64K RAM SYSTEM  28767 BASIC BYTES FREE

READY.
FOR I=1 TO 10000:NEXT I

READY.

esp8266C64.zip (43.3 KB)

Here's a version for the STM32F103 series of microcontrollers. See HardwareTimer : How to handle HardwareTimer instance caller in the timer callback - Arduino for STM32 for more details.

The zipped version will work on pretty much any STM32F103, if the your variant has more than the 20K RAM in the sketch, simply adjust where appropriate.

STM32C64.zip (44.9 KB)

Looking at the 6502 code...I'm having trouble understanding the "exec6502(100)" line. What does the 100 do? Does the 100 slow down the code execution speed? Is exec6502(1) faster? Can someone please explain

Here's a real c64 emulation on a Teensy:
Youtube: Teensy 3.6 - C64 Emulator - YouTube
(please excuse the quality)

This is a great project. Very easy to implement and use. Thanks to miker00lz for sharing this. I took the program version from the first post and added some changes that might be from iterest to others.

  • Mods and Patches to EhBASIC
  • AVR register accessible via PEEK/POKE (Ports, ADC, ...)
  • 1 msecTimer with prescaler
  • EDO RAM expansion board driver
  • OLED IIC textmode driver
  • Sourcecode included

EDO RAM Expansion board

I have build a RAM Expansion for my Arduino Nano from an old PC SIMM Module. Now I have about 2MByte with just two RAM chips and a '573 for the Address Latch. It uses just 12 Port Bits from the Arduino for interfacing. Access is not very fast on the Nano, cause I do not have a complete 8 Bit Port (when leaving Serial Interface, SPI and IIC free for expansion). Speed is about 100 KBytes Read or Write per second.
I directly read/wite the AVR ports for better performance, avoiding digitalWrite() and digitalRead() functions.
However, it can't expand the internal RAM of the microcontroller - the necessary signals are not available outside of the microcontroller chip. The RAM is just available with special load and store functions via port pins.

Arduino 6502 emulator with RAM Expansion board

After some benchmarking I use the Nano with 512Bytes of fast internal RAM for Zeropage and Stack. The external EDO Ram is used in the range from $0200 to $BFFF, so I have 48383 Bytes free for EhBasic.

The complete 2 MByte are available as Hi-Memory for the 6502. There are two 1KByte addressblocks in the Memory Map and the EDO RAM can be accessed within these two addressblocks. Each Himem has its own base address register an can be adjusted in Steps of 256 Bytes.

Timer Tick

I also added some virtual Hardware.
The EDO RAM refresh uses a 1 msec timer interrupt (Timer1 Lib), which can also be used as some kind of stopwatch. From the refresh interrupt I generate a timer/counter with adjustable prescaler that can be used for benchmarking for example.

The address for the timer tick is $f0a0/$f0a1 (16 bit).
Write access sets the prescaler and also resets the counter.
Read access reads the current value.

Example:

doke $f0a0,1000

Reset the timer and set the prescaler to 1000 (increase tick counter after 1000 msec)

print deek($f0a0)

Print the current timer tick value

Example:

doke $f0a0,1:for i=0 to 1000:next:print deek($f0a0)

Reset the timer and set the prescaler to 1 (increase tick counter every millisecond)
Print the timer tick after benchmarking the FOR-Loop in milliseconds.

With high prescaler values the timer runs slow. A value of 30000 will generate just two ticks per minute (after 30000 mseconds).

The two bytes of the 16 bit timer are buffered, so read and write access using DEEK/ DOKE will give correct results.

AVR IO-Register / Hardware

The IO-Registers of the AVR are available for Peek and Poke within the address range $F100 - $F1FF.

Example:
poke $F1C6,65 send the letter "A" (ASCII 65) to the Serial Terminal

$F1C6 is $C6 of the AVR (UDR0, USART I/O Data Register)

edo_6502.ino (1.9 KB)

cpu.c (150 KB)

edo.c (4.18 KB)

edo.h (1.43 KB)

ramfix.h (2.5 KB)

t1306.cpp (5.54 KB)

t1306.h (14.4 KB)