Go Down

Topic: Arduino 6502 emulator + BASIC interpreter (Read 48527 times) previous topic - next topic

miker00lz

Oct 14, 2013, 05:27 am Last Edit: Oct 14, 2013, 05:37 am by miker00lz Reason: 1
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.  8)



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.

JimboZA

Brilliant...

6502.... Apple ][.... that takes the clock back a bit!
"Could you do the egg bacon spam and sausage without the spam then? "

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

miker00lz

#2
Oct 14, 2013, 05:36 am Last Edit: Oct 14, 2013, 07:33 am by miker00lz Reason: 1
Thanks! :)

I actually forgot to attach the project to the post, d'oh! Doing that now...

fungus

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().



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

miker00lz

#4
Oct 14, 2013, 09:03 am Last Edit: Oct 14, 2013, 09:07 am by miker00lz Reason: 1

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. :)

fungus


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)
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

miker00lz

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.

fungus


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. :-)
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

robtillaart

Rob Tillaart

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

miker00lz



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! :)

miker00lz


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. :)

Manawyrm

#11
Oct 15, 2013, 12:26 pm Last Edit: Oct 15, 2013, 12:32 pm by Manawyrm Reason: 1
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 :)

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*

miker00lz


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 :)


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 ][. :)


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.

janost

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. :)
[/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.

fungus


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)

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

Go Up