Posted: February 16, 2015 Filed under: Art, Coding, Creations, DIY, Explorations, That Totally Worked, Uncategorized | Tags: APA102, Apple, Apple //e, Apple II, AppleII, arduino, art, blinky, CALL -151, DIY, DotStar, fastled, glow, glowy, LED, LEDs, light, LPD8806, retrocomputing, WS2801
These days, I hack LEDs. I’m the co-author (with Daniel Garcia) of the FastLED library for driving tons of high speed LED pixels and strips using microcontrollers like Arduino and Teensy.
But back in the day, I hacked a lot of Apple II. I published a couple of shoot-em-up games (with Geoffrey Engelstein), all written in lovingly hand-crafted 6502 assembly language.
Finally I decided it was time to link the present to the past: to connect a hundred high-speed RGB LEDs to an Apple II, somehow, and ‘port’ our FastLED library to 6502 assembly language.
Well, I did it, and it works. My new creation, “FastLED6502”, can drive a hundred 24-bit RGB pixels at more than 30 frames per second from an Apple //e :
Here are the details of “FastLED6502”:
- “FastLED6502” is a lightweight port of FastLED’s core functions to 6502 assembly language for the Apple ][, Apple ][+, Apple //e, and Apple //gs.
- Supports APA102 / Adafruit DotStar LED strips, as well as LPD8806 and WS2801 (though those two are not fully tested yet).
- The LED strip is connected to the Apple II using the 16-pin DIP game port on the computer’s motherboard. The 9-pin DB joystick/mouse port on the back of the //c, //c+, and //gs cannot be used, as it lacks the TTL digital output signals needed to drive the LED strip.
- 24-bit FastLED Rainbow colors are included, along with FillRainbow, Random8 and a number of other useful functions from FastLED’s main library.
- Everything had to be re-written from scratch in 6502 assembly language. Luckily(?), I still remember how to do that.
- The assembly code knows the binary serial protocols for the APA102 (Adafruit DotStar), LPD8806, and WS2801 LED driver chips. Depending on which one you select, FastLED6502 transmits the LED colors in the correct protocol over the game port TTL digital output lines.
Considering that the Apple II sports a 1MHz 6502 so slow that even a “NOP” takestwo cycles, overall performance is pretty good: more than 30 frames per second for a 100-pixel strip.
Speaking of speed, or lack thereof, “three-wire” clockless LED strips such as the WS2811 NeoPixel are not supported now, nor will they ever be. The CPU is would need to be at least 20X faster to support them, and it isn’t. For that you want an Arduino or Teensy, and FastLED proper: http://fastled.io/
I gave the code its public debut at Veracode Hackathon 7. (The theme was “Cozy Cabin” — I don’t usually wear plaid.)
FastLED6502 at Veracode Hackathon 7
How’s it work?
So how does this all work? Well, you connect the CLOCK and DATA_IN pins from the LED strip to a couple of pins on your Apple II’s DIP game connector port, add power, and you’re ready to go. The Apple II’s game connector not only has inputs for joysticks, paddles, buttons, and so on, but it also has a few digital outputs — and that’s what FastLED6502 uses to deliver signals to the LED strip. On all the 16-pin DIP Apple II game ports (except for the //gs!), there’s even one pin that delivers a super-fast digital pulse; pin 5 is the C040STROBE line, which can pulse twice as fast as the other digital outputs. If you choose that for your CLOCK pin, the FastLED6502 code automatically shifts into high gear, and you get faster performance. FastLED proper does this, too, in a much fancier way; it’s amusing that ‘little’ FastLED6502 does some of this, too.
The code is in the “extras” directory here (and eventually on FastLED’s main branch, but not yet)
This is Crazy
Overall, this bit of code is completely nuts, and we don’t expect anyone to use it. At all. Ever. Accordingly, we’re not going to really support it, either. At all. Ever. It was a labor of love and a creation of pure modern retrocomputing insanity. But here it is, in all it’s insane glory, “FastLED6502”.
And now, if you cut me, I’ll bleed 16,777,216 colors at thirty frames a second.