Surprisingly sophisticated. I didn't remember them being much more than annoying when my kids "had to have one."

Hey, I recognize those opcodes. 6502 (Commodore, Apple 2, etc) Cool! I had no idea what was running these things.

Time Slice Task Master (aka "cooperative multitasking without preemption")

Interesting they set the PWM (pulse width modulation) based on battery voltage as not to stress out the motors. Cheaper than some caps & resistors for a voltage divider from a high V source, or a boost/buck controller. Still necessary for the CPU though. If I remember correctly, this thing ran off 4 1.5V cells (+6V). Yay, software!

Clever use of tilt sensor to seed the pseudo-random num generator. (page A22)

Too bad the diagnostic file isn't included (diag7.asm) per page A21.

(A33) That cycle-counting timer loop brings back memories, too -- throwing in a few NOP (no-operation) calls just to eat a cycle and get the timing right on a horizontal/vertical retrace -- while here they're doing it so the service intervals on sound & motor control come out right.

(A36) LOL @ "Rap mode"

A39 - the various sensor sequences needed to trigger the modes

I gave up at about 45 pages, but there is obviously some neat stuff here.

Hmmm, I'm alway really surprised when people comment on threads like this.

How much time did you take to do this, I can read code, but I simply can't casually take a look at code like this and say, hey that's cool, hey that's interesting, I have to concentrate and go line by line, a more debugging state of mind.

There are programmers that can sort of skim read code which just amazes me.

Maybe a few seconds per page? Truly, it's really not that much of an accomplishment -- the comments are superb. I spent 10 years writing games in 6502 assembly, so it feels pretty natural to me.

Keep in mind that a lot of this kind of code follows a pattern : lots of EQU ("equates") statements that link a variable to an address like a port or a signal line. Then you'll have the setup code that gets everything into a basic state where it's ready to run the next part

The big loop Here's where the action's act. Just spin in a big loop, waking up every few hundred cycles or so to check and see if a button is pressed, or the IR chip is sending a byte, or the battery is dead, etc. If you're already doing something, keep doing it until you're done. If you're done, wait around for a while or go do something else.

At least, that's what I come expecting. So when I see code like this that basically fits that model, parsing it is simple.

And, like I said, there are great comments. Even a couple about the round-robin service routine that made me laugh.

Perhaps this is a naive question, but why would something like this be written in assembler, and not C or similar?

It seems assembler makes it a bit more complicated without much benefit, and surely there's a compiler for a chip as common as the 6502.

No higher level languages were ever competitive with assembler for the 6502. The stack model of C is not a good fit, as the 6502 machine stack doesn't give any support for reading or writing stack-based variables. Good performance depends on effective use of the zero-page -- the first 256 bytes of memory which have special addressing modes and allow more efficient access. Registers are few and quirky -- accumulator, two index registers which are not quite interchangeable, a byte stack pointer. All operations are 8 bit; 16 bit calcs like for pointers are costly both in code size and speed.

Back in the 80's and 90's the best compiled languages were probably COBAL and Forth. As far as I know nobody seriously used these for games or applications.

There are more recent C compilers, but the code generation is multiples of size and speed (5* maybe?) away from assembler.

For those into modern (!) medium-level 6502 programming, PLASMA [0] may be better (syntax-wise) than Forth and better (size and performance-wise) than C.

[0] https://github.com/dschmenk/PLASMA