6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 8:04 am

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Mon May 31, 2021 9:01 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
While working on a real 6502 I got sidetracked by a lonely Adafruit Trinket M0 sitting on my desk doing nothing. I wondered if I could get a working Apple I emulator onto it. If you're not familiar with the SAMD21 chip it is based on, it has a reasonably high clock rate and a fair amount of flash and ram space. I decided to throw in some extra goodies while I was at it to make it worthwhile (see video). It worked reasonably well. It seems to be running at around the equivalent of a 0.5Mhz 6502. Not great, but usable and you can still have fun with it. Encouraged by that minor success I wanted to see how small I could go. Adafruit also has even smaller boards that plug directly into a USB port. I found that Digikey still had the Neo Trinket in stock (it's apparently out of stock at Adafruit). The chip specs are the same as the Trinket M0, but the LED's are different. BTW, I use the LED's to change color when you switch "ROM" banks (not shown in video). See the link below for a video showing the system in action. I'm going to put the code out on GitHub soon if anyone is interested. I need to clean up a few loose ends first. I thought I'd give an early preview to see what feedback I get.

There is no audio in the video, but some text in the upper right corner will let you know what's happening. BTW, the video is captured from "cool-retro-term" which has a very fun simulation of analog monitors.

Link: https://flic.kr/p/2m2RXse

You can have an Apple I (sort of) on your keychain! :D

--Robert


Top
 Profile  
Reply with quote  
PostPosted: Mon May 31, 2021 9:06 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Always interested to see code appear!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 31, 2021 11:08 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
I should add before anyone gets their expectations raised... I didn't write the underlying emulator. I modified the one floating around for arduinos by Mike Chamber (miker00lz). My project is more systems integration and packaging. Although I did figure out some potentially useful tricks for loading Apple Basic programs programatically. Code should be online in a few days. Stay tuned.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 01, 2021 2:38 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
If that emulator was written to run on a classic Arduino based on an AVR microcontroller, many tradeoffs were probably made for smaller code size rather than faster speed. If you incorporate one written for the Cortex or ARM, you can likely make it several times faster.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 01, 2021 4:52 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
BillG wrote:
If that emulator was written to run on a classic Arduino based on an AVR microcontroller, many tradeoffs were probably made for smaller code size rather than faster speed. If you incorporate one written for the Cortex or ARM, you can likely make it several times faster.


Well the main compromise is that the current implementation is written in C/C++. It does have the advantage of portability to other platforms supported by the Arduino IDE which is why I could use it on the SAMD21. A native assembly code version would certainly see some performance improvements. But for the intended "parlor trick" of a tiny but usable Apple I, I think I'll stick with the current implementation as it is quite usable, even for Microchess. For anything serious I'd prefer building some real hardware for a proper "replica". Also, my experience so far is that except for maybe the AVR platforms, the Arduino universe is in such a constant state of "upgrades" it's hard to know what boards will be available for how long. So portability over performance has some advantages.

Even so, the slightly slow but still quite usable implementation on the SAMD21 provides a VERY affordable entry into the Apple 1 universe to play around with some classic programs, fiddle with WozMon, etc. If I were to add anything at this point it would be an assembler (maybe Krusader) so if someone really wanted to they could do some 6502 assembly on the board. The Neo Trinket (which may not be available anymore) is particularly nice because it's just a single dongle you can pop in your laptop and go. I plan to work out a 3d printed case for it so it looks like a USB pen drive.

BTW, the best implementation I've seen so far is apple1js (https://www.scullinsteel.com/apple1/). I took some inspiration for loading programs from that implementation, although my method is different.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jun 02, 2021 3:08 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
I was not saying write it in assembly language, but that an emulator developed for the most common Arduino likely had too many tradeoffs made in favor of small size instead of speed to shoehorn it into 32K of code and 2K of static RAM. Decisions such as excessive factoring into too many subroutines and foregoing the use of lookup tables.

You might look for a compiler option to inline as much code as possible.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jun 02, 2021 8:55 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
BillG wrote:
I was not saying write it in assembly language, but that an emulator developed for the most common Arduino likely had too many tradeoffs made in favor of small size instead of speed to shoehorn it into 32K of code and 2K of static RAM. Decisions such as excessive factoring into too many subroutines and foregoing the use of lookup tables.

You might look for a compiler option to inline as much code as possible.


Ok. Got it. For some reason, I completely forgot about changing the compiler options (cue up Homer Simpson's "DOH!"). That does seem to help a bit. I haven't done any timings, but it seems closer to a 1Mhz chip now.

Looking at the original emulator code (largely untouched), the only potential major inefficiency I see is that the opcodes are parsed as a long switch statement (shades of old Windows programming *grin*). A lookup table might be faster and I have plenty of room for one. But in reading a bit about switch vs lookup tables it's not clear that one has an advantage over the other depending on the compiler implementation and what optimizations they make. Also, the lookup table would likely just be a mapping to function pointers, adding another level of indirection and M0 compute cycles. Any thoughts? Either way, I'll probably defer rewriting things to a later version so I can get what I have published sooner than later.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 03, 2021 10:39 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
zeefour wrote:
Looking at the original emulator code (largely untouched), the only potential major inefficiency I see is that the opcodes are parsed as a long switch statement (shades of old Windows programming *grin*). A lookup table might be faster and I have plenty of room for one. But in reading a bit about switch vs lookup tables it's not clear that one has an advantage over the other depending on the compiler implementation and what optimizations they make. Also, the lookup table would likely just be a mapping to function pointers, adding another level of indirection and M0 compute cycles. Any thoughts? Either way, I'll probably defer rewriting things to a later version so I can get what I have published sooner than later.

A decent compiler should be able to pick the best way to implement a switch, whether by a series of compare and branch tests or a jump table.

The calculation of the states of the flags can sometimes be streamlined by the use of tables.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 04, 2021 8:22 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
BillG wrote:
zeefour wrote:
Looking at the original emulator code (largely untouched), the only potential major inefficiency I see is that the opcodes are parsed as a long switch statement (shades of old Windows programming *grin*). A lookup table might be faster and I have plenty of room for one. But in reading a bit about switch vs lookup tables it's not clear that one has an advantage over the other depending on the compiler implementation and what optimizations they make. Also, the lookup table would likely just be a mapping to function pointers, adding another level of indirection and M0 compute cycles. Any thoughts? Either way, I'll probably defer rewriting things to a later version so I can get what I have published sooner than later.

A decent compiler should be able to pick the best way to implement a switch, whether by a series of compare and branch tests or a jump table.

The calculation of the states of the flags can sometimes be streamlined by the use of tables.


A couple of updates for you.
1. Just published the GitHub repo, see new thread...
2. I noticed that Mike Chambers published his Fake6502 code here on 6502.org. It appears to use a lookup table, or jump table but at least it ISN'T using a switch statement. I tried it and it seem to actually run a bit slower than the switch version he put out for the Arduino (not available on 6502.org). So I just reverted back to my old switch-statement code and I'll run with that. With heavy compiler optimizations it runs about 0.8Mhz and as Adam Osborne once said "adequate is sufficient" :)
3. I took a bit longer to get this out because I realized I had the infamous BCD bug. But I plugged Mike B's BCD patch in and it worked a treat and EhBasic gives the proper results to HEX$(). Yay! It might be good if someone updated Fake6502 to include that as well.

Barring any bugs that raise their ugly heads, I'll get back to my other project and see where this one goes over the next few days.

It's been a fun rabbit hole and I've learned a lot about the Apple I and 6502 emulations in general.

Robert


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 04, 2021 8:56 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
That new thread:


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 07, 2021 7:09 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
Just a quick update that I was glad to see Adafruit has a new run of Neo Trinkey's back in stock. So it isn't discontinued. I'm waiting to get a rp2040 Trinkey that they have coming soon, which should keep the same small Trinkey format, but have a substantially improved CPU with more ram and faster clock.

I'm not sure who really cares, but just in case you were put off by the Trinkey's being out of stock -- it's no longer a problem.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 15, 2021 7:35 pm 
Offline
User avatar

Joined: Mon May 03, 2021 4:48 am
Posts: 12
An update to my update :D

I made a successful port of the SAMD21 emulator to a couple of Adafruit RP2040 boards. These platforms run approximately equivalent to a 2.5Mhz system, so it's now comparable to a good system from back in the day (or my 6502 Badge). Also, it has more RAM so I can get the Apple I "RAM" up to 48K with this version. Interestingly, the serial I/O is extremely fast and in a terminal emulator, screen updates are almost instantaneous. Running my port of Microchess, it almost feels like it's in graphics mode versus serial ASCII text.

I need to get back to some other projects I've neglected, and reconcile the code changes with the Arduino version. But eventually I'll post the rp2040 code on GitHub. The downside to the rp2040 is that it currently does not have Arduino support and you have to use the C/C++ sdk. The build process is different and there are even some subtle differences in behavior between the RP2040 sdk and the standard Arduino libraries. But it's doable.

FWIW, there's even a Trinkey version of the RP2040:
https://www.adafruit.com/product/5056

I have this and the "feather" version. They both work the same for the Apple I emulator.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 15, 2021 7:51 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
> I made a successful port of the SAMD21 emulator to a couple of Adafruit RP2040 boards
Bravo!

> But eventually I'll post the rp2040 code on GitHub
Hurrah!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 31 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: