Actually, I did a lot of assembly coding on 6809 and 6502 back in the day, and also played a lot of the Zachtronics games. It's not really the same at all! Zachtronics games are all about challenges that are quite a bit more ridiculous than you have in real life with small machines. In a typical Zachtronics assembly programming game, you spend a lot of time trying to figure out how to do pretty trivial things using a ludicrously small amount of resources, like maybe you've got two reigsters to work with. In a real assembly project, you'll have a few kilobytes to work with, or at a bare minimum 512 bytes. The smallest system I worked with had 512 bytes of RAM and 8kb of ROM. The Zachtronics games were fun and challenging, but they were more like puzzles rather than real programming. Puzzling out how to get the assigned task done with ridiculous artificial limitations.
Contrast that to an example of a real-life non-trivial assembly thing I did on a 6502. I needed to respond to remote control commands from an infrared remote similar to what you have with a TV. For input, I'd get interrupts connected to an IO-pin that would fluctuate up and down when receiving IR input. The task involved "recording" commands from a remote, then later monitoring the input and seeing if it matched any of the pre-recorded patterns. You'd count the amount of time between successive pulses, using a real-time clock that was connected to some other IO pins. It's not rocket science, but it's fun and challenging figuring out how to get all that going with a limited amount of memory. To me that kind of thing is a lot more fun than figuring out how to do the various challenges in Zachtronics games, which mostly center around taking something that'd be trivial do if you had a couple hundred bytes of memory to work with, but they are forcing you to do it with 2 bytes of memory. So you make little side constructs that act as memory, or other side constructs that somehow use message queues as memory, or whatever.
The appeal of retro emulators I think is that it's a system that's small and limited enough that you have more of a chance of understanding it from end to end. There's a feeling of comfort or coolness in knowing that you know exactly what the system is up to on every cycle. With larger computers, the hard drive starts blinking and God only knows what it's doing, or why. There's this feeling on small embedded or emulated systems that you are really in control of what's happening. On larger, more complex systems, the software I write is just one little part of the larger who-knows-what going on inside the machine.
For me another aspect of it is how much I'm getting done with so little code. There's something very satisfying about knowing the entire binary package of assembled code I've generated, and being able to point to any byte of that and understand what it is.
It's the exact opposite of what's going on in my other terminal, where as I type it's creating a new react app and downloading untold megabytes of who-knows-what with countless dependencies and abstractions. In retro systems, if the system is capable of doing something, it's probably because you personally made it able to do that thing.
Back in the late 70s, I did the bring-up of a Z80 system. I coded an EPROM (2708) with 1KB. Wrote a very small bootstrap monitor that did not require RAM to be operational. Drove a serial terminal (autobaud on CR entry). Display/Set memory and Go to address. Just enough to enter a memory test and a disk bootstrap, which was then added to the EPROM. So, there are examples of "zero RAM" programs. With no stack, use a single level of subroutine - LD DE,ret addr, LD HL,subroutine, JMP (HL), and at the end of the subroutine: LD HL,DE and JMP (HL) did it. The EPROM had to work on both 8080 and Z80 CPUs. The code had to be small, because it was manually entered into an EPROM programming device.
Fairly common stuff back then...
I enjoyed this kind of work. No debugger, no safety net. The code had to be simple, understandable, and work. However, these days I still don't use debuggers (much). This may be slowing me down; not sure about that.
Actually, I did a lot of assembly coding on 6809 and 6502 back in the day, and also played a lot of the Zachtronics games. It's not really the same at all! Zachtronics games are all about challenges that are quite a bit more ridiculous than you have in real life with small machines. In a typical Zachtronics assembly programming game, you spend a lot of time trying to figure out how to do pretty trivial things using a ludicrously small amount of resources, like maybe you've got two reigsters to work with. In a real assembly project, you'll have a few kilobytes to work with, or at a bare minimum 512 bytes. The smallest system I worked with had 512 bytes of RAM and 8kb of ROM. The Zachtronics games were fun and challenging, but they were more like puzzles rather than real programming. Puzzling out how to get the assigned task done with ridiculous artificial limitations.
Contrast that to an example of a real-life non-trivial assembly thing I did on a 6502. I needed to respond to remote control commands from an infrared remote similar to what you have with a TV. For input, I'd get interrupts connected to an IO-pin that would fluctuate up and down when receiving IR input. The task involved "recording" commands from a remote, then later monitoring the input and seeing if it matched any of the pre-recorded patterns. You'd count the amount of time between successive pulses, using a real-time clock that was connected to some other IO pins. It's not rocket science, but it's fun and challenging figuring out how to get all that going with a limited amount of memory. To me that kind of thing is a lot more fun than figuring out how to do the various challenges in Zachtronics games, which mostly center around taking something that'd be trivial do if you had a couple hundred bytes of memory to work with, but they are forcing you to do it with 2 bytes of memory. So you make little side constructs that act as memory, or other side constructs that somehow use message queues as memory, or whatever.
The appeal of retro emulators I think is that it's a system that's small and limited enough that you have more of a chance of understanding it from end to end. There's a feeling of comfort or coolness in knowing that you know exactly what the system is up to on every cycle. With larger computers, the hard drive starts blinking and God only knows what it's doing, or why. There's this feeling on small embedded or emulated systems that you are really in control of what's happening. On larger, more complex systems, the software I write is just one little part of the larger who-knows-what going on inside the machine.
For me another aspect of it is how much I'm getting done with so little code. There's something very satisfying about knowing the entire binary package of assembled code I've generated, and being able to point to any byte of that and understand what it is.
It's the exact opposite of what's going on in my other terminal, where as I type it's creating a new react app and downloading untold megabytes of who-knows-what with countless dependencies and abstractions. In retro systems, if the system is capable of doing something, it's probably because you personally made it able to do that thing.