Pages: [1] 2 3 ... 10   Go Down
Author Topic: Arduino 6502 emulator + BASIC interpreter  (Read 33713 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I wrote a 6502 CPU emulator for the Arduino! I originally wrote it a couple years ago for a NES emulator, then modified it a bit for this. One of the changes was to make cycle timing a little less accurate (doesn't check for page boundary crosses on some opcodes) for a speed increase. If anybody wants that fixed for something, let me know.

To demonstrate it, I have the ROM for "Enhanced BASIC 6502" embedded in the code. Given the Uno's tiny 2 KB RAM, I am only able to provide the CPU emulator with 1.5 KB, but it's enough to minimally run EhBASIC! You can connect to the Arduino with any terminal program (like PuTTY) and play around in the BASIC interpreter.  smiley-cool



It makes for a fun little toy, even if not all that useful. With more memory on an Arduino, you could turn this into a simple Apple ][ emulator or something like that. I might look into that actually. If anybody actually uses this for a project let me know if you need help.

* arduino_6502.zip (18.34 KB - downloaded 387 times.)
« Last Edit: October 13, 2013, 10:37:19 pm by miker00lz » Logged

Johannesburg. UTC+2
Online Online
Faraday Member
**
Karma: 108
Posts: 4777
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Brilliant...

6502.... Apple ][.... that takes the clock back a bit!
Logged

The Elders of the Internet know who I am
I'm on LinkedIn: http://www.linkedin.com/in/jimbrownza

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks! smiley

I actually forgot to attach the project to the post, d'oh! Doing that now...
« Last Edit: October 14, 2013, 12:33:27 am by miker00lz » Logged

Valencia, Spain
Online Online
Faraday Member
**
Karma: 150
Posts: 5680
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ideas:

Store the program in EEPROM and get more than 767 bytes. It would also survive a reset.

Set up some virtual addresses to change the state of Arduino pins using poke().



Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ideas:

Store the program in EEPROM and get more than 767 bytes. It would also survive a reset.

Set up some virtual addresses to change the state of Arduino pins using poke().

The program (as in the EhBASIC ROM image) is stored in the flash memory along with the code. The emulator has access to 1536 bytes of RAM, but the first 512 bytes make up the 6502's zero page and stack page, then the next 256 are used by the BASIC interpreter itself. The 767 bytes is just what EhBASIC reports as the remaining storage for BASIC code and variables.

I wouldn't want to use EEPROM because it can only be written to so many times before it goes bad. I'm looking into getting a 32 KB SPI chip for more memory. Should be pretty simple. smiley
« Last Edit: October 14, 2013, 02:07:13 am by miker00lz » Logged

Valencia, Spain
Online Online
Faraday Member
**
Karma: 150
Posts: 5680
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The program (as in the EhBASIC ROM image) is stored in the flash memory along with the code. The emulator has access to 1536 bytes of RAM, but the first 512 bytes make up the 6502's zero page and stack page, then the next 256 are used by the BASIC interpreter itself. The 767 bytes is just what EhBASIC reports as the remaining storage for BASIC code and variables.

I meant store the BASIC program in EEPROM (and variables in RAM).

I wouldn't want to use EEPROM because it can only be written to so many times before it goes bad.

It's a lot of times though. You could probably spend a lifetime writing BASIC and not wear it out (how long would it take you to make 100,000 edits to a program?)

More ideas: Make it so that if you connect a special pin to GND it automatically runs the BASIC program (stored in EEPROM) on boot-up. That way you could program it in BASIC and deploy it in real projects.

Map the analog ports to memory addresses so if you peek() them you read the analog value (only 8 bits, but hey...the bottom 2 bits are usually just noise anyway)
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good ideas, but I think you are misunderstanding how it works a little bit. I wrote no code of this BASIC interpreter. It is a 6502 program that already existed. I only wrote a 6502 CPU emulator that runs this interpreter. I have no way of knowing where in the 6502 memory space the relevant BASIC program information is, otherwise I might do it. This of course means I have no way to auto-load a program and start it either.

I would have to do all 6502 memory space read/write to the EEPROM, and it could be writing to memory constantly depending on the 6502 machine code being run. It may wear out parts of the EEPROM in a matter of seconds actually!  smiley-mr-green

Besides, the BASIC interpreter I'm emulating is really just a simple demonstration for the core concept, the 6502 emulator. I do like your ideas, they just aren't possible to implement with the way this thing works.
Logged

Valencia, Spain
Online Online
Faraday Member
**
Karma: 150
Posts: 5680
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good ideas, but I think you are misunderstanding how it works a little bit. I wrote no code of this BASIC interpreter. It is a 6502 program that already existed. I only wrote a 6502 CPU emulator that runs this interpreter. I have no way of knowing where in the 6502 memory space the relevant BASIC program information is, otherwise I might do it. This of course means I have no way to auto-load a program and start it either.

Oh, I see...

It might work if you put page0/page1 in RAM and the rest in EEPROM but the BASIC variables would probably end up in EEPROM too, not good.

OH, well, they were just ideas. :-)
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 224
Posts: 13921
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try it on a MEGA to have more RAM?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good ideas, but I think you are misunderstanding how it works a little bit. I wrote no code of this BASIC interpreter. It is a 6502 program that already existed. I only wrote a 6502 CPU emulator that runs this interpreter. I have no way of knowing where in the 6502 memory space the relevant BASIC program information is, otherwise I might do it. This of course means I have no way to auto-load a program and start it either.

Oh, I see...

It might work if you put page0/page1 in RAM and the rest in EEPROM but the BASIC variables would probably end up in EEPROM too, not good.

OH, well, they were just ideas. :-)


It would be cool to save the programs, for sure! smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try it on a MEGA to have more RAM?

I was kind of thinking about that, but the again it still only has 8 KB. I think the best solution would be a cheap 23A256 for an instant 32 KB.

https://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en539040

Maybe even the 23A512 for 64 KB, then an Apple ][ could be emulated. smiley
Logged

Alfeld (Leine) / Germany
Offline Offline
Full Member
***
Karma: 9
Posts: 211
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A very cool piece of code, nice work.
I have to look into it tonight.

If I'm reading your code correctly, to enable the use of external -- say SPI memory you would only need to write read6502() and write6502() for your SPI flash, right? Very cool smiley

Also: Have you thought about mapping a whole arduino I/O Port to the memory? That would enable for a HELL OF A LOT of mega cool features. Just think about printer integration, maybe even floppy.
Or maybe even go one step further: Reading programs from a cassette tape *scnr*
« Last Edit: October 15, 2013, 05:32:52 am by Manawyrm » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A very cool piece of code, nice work.
I have to look into it tonight.

If I'm reading your code correctly, to enable the use of external -- say SPI memory you would only need to write read6502() and write6502() for your SPI flash, right? Very cool smiley

Thanks! Yep, that's right. Those are the only two functions you need to worry about. If you were to get at least 48 KB of SPI memory you could emulate the Apple ][. smiley


Quote
Also: Have you thought about mapping a whole arduino I/O Port to the memory? That would enable for a HELL OF A LOT of mega cool features. Just think about printer integration, maybe even floppy.
Or maybe even go one step further: Reading programs from a cassette tape *scnr*

The thought crossed my mind. It would be cool to experiment with. You could also use a microSD shield to store Apple disk images on. You would need something like the Mega 2560 for that, though. There isn't enough program storage on an Uno to link in the SD card functions and still have the BIOS embedded with it, I tried.

Cassette should also be reasonably easy to add. I wrote an Apple emu for Windows a while back with cassette support (via WAV files), and the interface is unbelievably simple.
Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 524
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The program (as in the EhBASIC ROM image) is stored in the flash memory along with the code. The emulator has access to 1536 bytes of RAM, but the first 512 bytes make up the 6502's zero page and stack page, then the next 256 are used by the BASIC interpreter itself. The 767 bytes is just what EhBASIC reports as the remaining storage for BASIC code and variables.

I wouldn't want to use EEPROM because it can only be written to so many times before it goes bad. I'm looking into getting a 32 KB SPI chip for more memory. Should be pretty simple. smiley
[/quote]

Hi
I hacked around abit with your emulator and patched Read/Write6502.

I used a 24LC256 32Kb EEPROM for memorystorage.
It can take 1000000 writes before going bad.

To be safe I mapped the first 768bytes to Arduino RAM and the rest is EEPROM space.
That should keep it relative safe even though the basic variables gets written in EEPROM when the basicprogram runs.

It's just a first test any as I plan to run CBM-basic on it for Vic-20/C64 emulation.
Logged

Valencia, Spain
Online Online
Faraday Member
**
Karma: 150
Posts: 5680
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
I hacked around abit with your emulator and patched Read/Write6502.

I used a 24LC256 32Kb EEPROM for memorystorage.
It can take 1000000 writes before going bad.

To be safe I mapped the first 768bytes to Arduino RAM and the rest is EEPROM space.
That should keep it relative safe even though the basic variables gets written in EEPROM when the basicprogram runs.

It's just a first test any as I plan to run CBM-basic on it for Vic-20/C64 emulation.

I assume you can't put everything in EEPROM or it will be hellishly slow.

Zero page and stack can be in Arduino RAM, the program could be in EEPROM, but where are the BASIC variables stored? On most interpreted BASICs they start at the top of RAM and work down towards where the program is. That makes it hard to detect what goes in RAM and what goes in EEPROM. If the variables are in EEPROM it could slow things down a lot.

There might be a system variable you can look at to see where the end of the program is. Everything above that (ie. vars) goes in RAM, everything below (ie. program) goes in EEPROM.

(maybe)

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Pages: [1] 2 3 ... 10   Go Up
Jump to:  

Powered by SMF 1.1.19 | SMF © 2013, Simple Machines