McMartin

Professional software developer, vintage computing nerd. Some modern graphics/game-y stuff too.

@rygorous I have, sadly, actually seen people do themselves harm by understanding that idiom in the hot-take way.

You still do end up with ambiguity between "yeah, I burned the candle at both ends for this one and will need to recover from it now" on one end and "we set expectations low enough that modestly exceeding them is a sustainable state of affairs"

This week on the blog: a more detailed look at my optimization work for my first SEGA Genesis project, seven years (!) ago. This goes a bit further than my thread last week, and also discusses the tradeoffs of some other classic optimizations that I'm *not* doing.

bumbershootsoft.wordpress.com/

#retrocomputing #segagenesis #megadrive

I tend to work a bit ahead on the blog so that the update schedule stays constant even as my free time does not, but part of that also means that there's still a marked rhythm between writing code and writing *up* that code.

We see some of that here--next week's post will be a more thorough treatment of last week's Sega-vs-SNES thread, for instance--but it's usually kept neatly under wraps.

That said: I've now gotten the *entirety* of that Sega Genesis project where I wanted it to go. Hooray!

@cobbpg I think I'd need an angle beyond "can I make it fit" because generally these projects aren't to play the game but to show off some kind of technique or to explore a new-to-me sort of architecture.

The exciting parts of the TED to me are the way that the current vertical and horizontal raster counts are *writable* but I have not yet found a good resource on taking advantage of the hardware.

More likely I'd rely on one of my other templates to show how to get away with no sprites. :)

@cobbpg That's pretty close to how the Atari version manages the lights themselves. I do also want to animate the button presses, but that will likely end up being a secondary (well, quaternary) revisit at some future point.

The past three posts were a nerdsnipe on the way to the project I was actually aiming to do, so this is mostly just a nice place to pause again.

(There's a whole set of things one could imagine *also* doing with FLI shenanigans, but I'll do *those* on the TMS9918A, thanks)

Spectacular choice for the thumbnail, there; good work, everyone.

This week on the blog: thanks to a misclick I post the week's article 12 hours early. I finish last week's revisit of an early C64 project and push the system just that little bit harder to get some nice high-resolution drop shadows and get about as close to the NES version of this project as I expect to get.

bumbershootsoft.wordpress.com/

#retrocomputing #c64

McMartin boosted:
Noel Berrynoelfb
2025-06-21

I've been making video games in some form for 20 years, so I wrote an article about my process - and why I don't use an engine.

noelberry.ca/posts/making_game

McMartin boosted:
Ariadne Conill 🐰:therian:ariadne@treehouse.systems
2025-06-21

i find the regulatory capture of the commons (so-called "supply chain security") to be frustrating

@joew Definitely feels like it's on the right track, yeah. I have been toying with some ideas adjacent to this for some time, but they haven't gelled into something yet that wouldn't end up picking fights with the entire world at once.

I find myself wanting to weave corporate-consortium stuff like OpenGL and Apache into the narrative more cleanly.

@SJohnRoss Ah, I see; I was thinking more in the "miniatures" direction and, like, yeah, as I understand your delineation, if you're thinking about the mechanics, that's LTT, and military wargames with minis and stuff are *primarily* about that...

@SJohnRoss That's an interesting circle to be squared; normally I would think of large-scale military things a place where characterized tactical infinity gets _dramatically reduced._

@zarfeblong Somehow I had missed the entirety of Bithell's post-Thomas non-Ground-Shatter work. Hot dang, as they say.

There's apparently an old joke about how the Genesis design is cleaner but more primitive but with a vastly overpowered CPU compared to the SNES and its wild array of three-quarters-baked bespoke hardware. The SNES was "a Lamborghini with a lawnmower engine", and the Sega was "a lawnmower with a Lamborghini engine."

It's a good line, but I think there may be less justice to it than my first impressions of the platforms suggested.

/end. Thanks for reading to the end, if you made it this far!

That code ported very neatly over to the Sega; I'd already managed to jam the code into 3 registers and now I had 15. A few decisions go the other way; recomputing some values is cheaper than spilling to memory, but "spilling" to OTHER REGISTERS is cheaper still. Once it was in place? A 20-25% speedup over the original, meeting and sometimes exceeding the SNES capabilities, but nevertheless broadly at par.

That code was VERY MUCH written to just be Definitely Correct instead of fast. It had quite a few procedure calls in it. In my revisit I calculated that the call/return instructions ALONE were enough to account for an entire frame of lag, and some other individual expensive instructions added up to sizable fractions of one. As part of avoiding register spilling on the SNES, all of that code was entirely gone, thanks to, essentially, extremely aggressive induction variable optimizations.

That wasn't enough to catch up to the SNES, though, which had a full 20% advantage over the Sega... and even though it turns out that one clever little trick I did (which didn't port over to the m68k) that let me remove a loop variable turned out to save enough time to produce the whole disparity on its own. No, the major gain was in porting over the changes I made to the NON-central loop.

The one with 500 iterations instead of 16,000.

The one I could be sloppy about because it doesn't matter.

The big win for me at the instruction level was realizing that post-incrementing pointers is free: reading or writing "(a0)+" is the same cost as "(a0)" since the add happens under the hood. Incrementing with its own instruction costs *8* cycles, and that's nearly a whole frame wasted in my most expensive loop.

Better yet, while switching to post-increment broke subsequent indexes, it removed one index entirely, saving 4 bytes, 4 cycles, and an additional half a frame.

At a high level, the m68k's advantage turns out to be that while the memory is slower (2MHz, as opposed to the 3.6MHz FastROM speed on the SNES), each cycle brings in *a word* of instructions because *the word* and not the byte is the unit of instructions. That gives us rough parity on transfer speed and the larger instruction words means the code *density* in "instruction bytes per second" can take an edge. Smaller instructions do more, even as the instructions are maybe larger.

Here in 2025, I've decided to return to my original m68k code and see if I could bring back some of what I'd learned since. It was, after all, my first "real" m68k program, and I then went on to pick up a few years of hobby experience on the Amiga, Classic Mac, and Atari ST.

In returning to my old code, I find a third possible explanation: I was *real* bad at this back then.

After tightening up my code and porting back in the portable improvements that I'd made SNES-side, now the m68k wins.

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst