Tetris Max and System 6, Fixing 31-Year-Old Bugs
31 years ago Tetris Max for the Macintosh was born, an improved clone of tetris, and it became an insanely popular Mac game during the 1990s. I may or may not have had some involvement in its development. (See lots more Tetris Max history.) Macintosh System 6 was the current OS version at the time of the game’s release, but System 7 was introduced shortly afterwards. It’s recently come to my attention that the final version of Tetris Max (v2.9.1) may not work when running System 6 on certain Mac hardware, even though the game was advertised as System 6 compatible. I haven’t yet been able to fully verify this myself, but there’s a Macintosh Garden bug report from ironboy36 in 2022, and more recently a detailed bug report complete with video (thank you James!) Obviously I need to fix this stuff ASAP – 31-year-old bug be damned. And I need your help! Consider this a group debugging effort.
Both bug reports mention an “Unimplemented Trap” error message, which probably means Tetris Max tried to call a Toolbox function that’s only available in System 7 or later, and isn’t available from System 6. I suspect this bug only applies to color-capable 68K Macintosh models running System 6, because Tetris Max 2.9 works OK under System 6.0.8 on my B&W-only Macintosh SE. That limits the range of Mac models where this problem might appear to the Macintosh II family (including the Mac SE/30), because later Mac models can’t run System 6 anyway, and earlier models (like the Mac Plus and original SE) aren’t color-capable.
James’ test was performed on a Mac SE/30 with the built-in black-and-white screen, running System 6.0.8 loaded from a BMOW Floppy Emu disk emulator. I think he was also using a Mac ROM-inator II replacement ROM during this test. Ironboy36 didn’t mention what hardware was used, so we can only guess.
Reproduction
Challenge #1 is simply reproducing the bug. Unfortunately I think this needs to be done on real hardware, and not under emulation, because I’m not aware of any software that can emulate a color-capable 68K Macintosh running System 6. Mini vMac only emulates non-color Macs like the Plus and SE. Basilisk II can’t handle 24-bit addressing or System 6, and Sheepshaver is PowerPC-only emulation. There’s MESS, but I’m not sure about its capabilities, and setting it up is daunting. [Note: I learned there’s a Macintosh II version of Mini vMac that can handle System 6, but I found it to be slightly unstable and not a reliable testing platform.]
Working on real hardware is OK, even if it’ll be more difficult, but I don’t have easy access to any appropriate machines. My SE/30 needs to be recapped and currently doesn’t boot. I also have a Mac IIci and a Mac IIsi, but one is missing the power supply and the other has an unknown motherboard problem. I can probably get one of those machines working again, but at least for now I need to rely on other people to run Tetris Max with System 6 on systems like these, and send me reports.
Other Complications and Possible Causes
I don’t remember intentionally dropping System 6 support in later versions of Tetris Max, but it’s possible. After 31 years, with no source control and no release notes, I couldn’t tell you exactly what changed between the last few versions of Tetris Max. Version 2.9.1 was the last public release from the 1990s, but the game was later patched to create a 2.9.2x version which supported running directly from a locked disk like the ROM disk provided by the Mac ROM-inator II. And before 2.9.1, there was straight version 2.9, which is the most common version found in archives today. For the purposes of troubleshooting this bug, I think all three versions behave identically.
It’s possible this is actually a Mac ROM-inator II problem, since that’s what James used and possibly ironboy36 too. It would help to try running Tetris Max on the same computer, with the same System version, with the Mac ROM-inator and then again with the stock Apple ROM. Maybe the game is confused into thinking the SE/30 is a IIsi, and then tries to call some System routines that aren’t available in the SE/30? Just a guess.
Another possibility is that the version of 6.0.8 that’s on the Floppy Emu’s SD card is missing some data that’s supposed to be in the System file, and which is actually the source of the problem. For example, I know it’s missing some of the standard bitmap font sizes, though this shouldn’t cause an Unimplemented Trap error. I suspect this particular 6.0.8 System file was borrowed from a Disk Tools floppy rather than being the result of running the full 6.0.8 installer. It would help to try Tetris Max on a Macintosh II series machine with either System 6.0.7, or a fresh install of 6.0.8 from the installer floppies.
Debugging
I was able to dig through many layers of dusty old backups, and get Tetris Max rebuilt and running in the debugger with Codewarrior Pro, on an emulated System 9.0 PowerPC Macintosh with Sheepshaver. I stepped through all the code that runs between application launch and when the game window appears, and didn’t see anything that’s obviously System 7-only, but there’s a lot of code and I don’t have a good sense of which OS calls might be to blame. If you’re a developer, you can find the source code at Macintosh Garden.
Ideally I would run Tetris Max in the debugger on a color-capable 68K Mac with System 6.0.8, and go step-by-step until the game crashes, but there are a couple of problems with that approach. The version of Codewarrior Pro that Tetris Max is built with probably doesn’t work under System 6, or on Mac systems as old as the Macintosh II series. Even if it does, I don’t currently have working hardware to do it.
Macintosh Garden also has older versions of Tetris Max, including 2.8, 2.3.1, and older. If I can get the game running on real hardware, or somebody else can try it and report their results, I could find out what version broke the System 6 compatibility. That could provide more clues.
If my ancient memories are correct, someone could also install MacsBug on their Mac, and then they’d get more debugging info when the error occurs, instead of a mostly-useless “unimplemented trap” message. I think MacsBug would report which Toolbox trap the game tried to call, which would be very useful to know.
For the moment, the only viable debugging approach I can think of is to create a series of instrumented builds of Tetris Max, which beep or log their progress to a file during startup, and share these builds with people who can help test. That could eventually narrow down the point of the crash until the offending Toolbox call is identified. From there I could hopefully implement a work-around. But this approach is barely better than inserting PRINT statements into a 1979 BASIC program to aid with debugging, and I don’t like it very much. 30 years later, shouldn’t there be an easier method of debugging?
Read 20 comments and join the conversation20 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
Macintosh IIci has entered the chat. Confirmed the Unimplemented Trap crash with Tetris Max 2.9 under System 6.0.8. It happens with a stock Apple ROM, regardless of whether the monitor is set for black-and-white or 256 colors. Same result with a fresh copy of 6.0.8 from the Apple installer floppies. Same result with a 6.0.7 Tools boot floppy.
The plot thickens. Using MacsBug I narrowed down the crash to somewhere in a Tetris Max function named OpenResFileInDataFolder(), which is called while loading the music. I think the offending Toolbox trap call may be FSMakeFSSpec or ResolveAliasFile. But that’s not really the root issue.
Tetris Max checks if the CPU is a 68000, and if it is, the game won’t ever call LoadMusic(). The music is permanently disabled. That explains why the game doesn’t crash on a Mac Plus or SE, but *why* isn’t the music loaded? Was it always like this? Is there some inherent problem with the music on a 68000 CPU or with System 6? Was this some misguided attempt of mine to fit into 1 MB memory on a Mac Plus? Having no music on 68000-based machines isn’t very friendly.
Looking through the code, I think I probably confused “has 68020 or better CPU” with “has System 7 or later” when conditionally enabling some features, so 68030 Macs with System 6 will be a problem. To make sense of this code, I need to figure out what the heck I was trying to do in the first place, 31 years ago. I also need some kind of reference that tells me whether FSMakeFSSpec and ResolveAliasFile are available in System 6, along with other Toolbox calls of interest.
Ah looks like you’ve already been able to reproduce it, but I wanted to let you know that there is a version of MinivMac that emulates the Mac II. You can download the binary from https://www.gryphel.com/c/minivmac/dnld_mii.html . I was able to reproduce the crash with MinivMac emulating a Mac II with system 6.
Thanks, that Mac II version of Mini vMac will be very handy!
I think I’m close to a solution for the crash: The code that loads music from external resource files tries to follow aliases (like modern shortcuts). I dimly remember adding this capability at some point. But aliases are a System 7 feature and this code crashes under System 6. I’m working on some alternate code to skip alias resolution if the OS version is less than 7, though it’s not working yet.
I’m still very puzzled by the larger mystery of how the code reached this state. The 2.9.x versions of Tetris Max are badly broken under System 6, and there’s also no music on 68000 machines, and I don’t know why. Even without music, the 68000 machines are still broken under System 6, as James discovered the same Unimplemented Trap error if you open the game’s Preferences dialog in that setup.
Attempting to piece together some shards of memories from 30 years ago:
– The original version of Tetris Max definitely supported System 6, with music. It did not support 68000 machines at all, nor the 512 x 384 black-and-white screens in the toaster Mac models.
– Tetris Max (renamed as Bricklayer) appeared in the Mac Arcade Pak, a commercially-published game collection. I could have sworn the publisher asked me to add support for 68000 B&W machines like the Mac Plus and Mac SE, but I just tried it and Bricklayer gracefully declines to run on Macs without Color Quickdraw. So when did I add the support for the Mac Plus and SE? I can’t remember. Were those versions always without music? Why?
– By the time version 2.9 was released, the Macintosh world had been using System 7 for years and hardly anybody was still running System 6. So my testing of version 2.9 with System 6 was probably very cursory, if there was any at all.
I thought the Mac SE and Classic had color quickdraw, and only the Plus lacked it.
Only the SE/30 had Color Quickdraw – the other compact Macs like the Plus, SE, and Classic do not. Well maybe the Classic II had it also, but I stopped paying attention by then.
I’m running into more difficulty than I expected here. Basically I need to create System 6 workarounds for the functions FSMakeFSSpec and FSpOpenResFile. Maybe also GetProcessInformation – I’m not sure if that’s available in System 6.
HOpenResFile is supposedly a substitute for FSpOpenResFile, but I’m still getting an Unimplemented Trap error when I call HOpenResFile on the IIci with System 6.0.8. I don’t know why. I need to open a resource file in a subdirectory, so I don’t think plain OpenResFile will do.
GetProcessInformation is used to get the volumeId and directoryId in which the game app resides, so I can search for files with a given resource type in a subdirectory within that directory. As I vaguely recall, the current directory has changed at this point in the program, so I can’t just call GetCurrentVref() and GetCurrentDir().
There’s one more challenge: Sheepshaver has started crashing whenever I try to run the Codewarrior Debugger on the emulated Mac, so I can no longer debug anything.
I haven’t thought about any of this Mac programming stuff in decades.
I need some sample code that enumerates all the files in a particular directory. I had been using some code from Apple DTS with a function named CreatorTypeFileSearch, which internally uses PBCatSearchSync. This doesn’t seem to be working under System 6, although I’m not getting any errors – it just doesn’t find anything. The inability to actively debug under System 6 makes it hard to guess why.
Enumerating all the files wasn’t actually the problem after all – that’s working fine. The problem is now with the preference dialog, because it uses a popup menu for the choices for changing the music, backgrounds, and pieces. Popup menus are usually called drop-down menus today, and they weren’t introduced until Macintosh System 7.
No popup menus… how did UI designers in the System 6 era make a dialog box that needed a bunch of choices that weren’t known until run time? There’s really no way to embed a menu inside a dialog box with System 6?
I’m thinking about showing the current music selection as a static text item, with a button next to it that advances to the next available choice each time it’s pressed. It should work, but it’s not as nice as a UI that shows all the available choices at once.
As a young kid in the 90s, I played Tetris Max obsessively. This soon evolved into ResEdit tinkering: breaking it and other shareware apart to try and understand how they worked. Followed by sleepless nights struggling to reproduce them: first in HyperCard, and then with sloppy, self-taught CodeWarrior spaghetti code (lacking any reference books, mentors, or community of any kind).
As someone from a generally lower socioeconomic background in Australia (public education that struggled to maintain textbooks, from a single-parent household, etc) who now somehow lives in San Francisco working in the tech industry, I find these posts both wonderfully nostalgic, and a heartening reminder that I’m standing on the shoulders of giants.
Thanks for the memories.
Mark, thanks for sharing your story, and yes that feeling of complete ignorance was a central part of my early coding experience too. No Google, no Stack Overflow, just endless programming struggles over the simplest things.
Returning to this 1990s coding in 2023, it should be easier now, but it doesn’t feel like it. I think I have a working solution for a popup menu alternative that works under System 6, but somewhere along the way I may have introduced a new memory trashing bug, or changed the behavior of an existing one.
Good news, I may finally have it working. What does GetDialogItem() do if the specified item number doesn’t exist? The Inside Macintosh reference doesn’t say, and the function doesn’t have a return value, but I think it was the cause of my memory trashing. Fingers crossed…
There were a LOT of bugs! Basically anything that wasn’t a color Macintosh running System 7+ was going to have problems. It should hopefully work now in System 6 or 7+, black and white or color, 68000 or 68020/30/40 or PPC. Programming and debugging with mid-90s tools and several layers of emulators was a fun experience. For several hours I was grinding through Macsbug sessions with full-screen displays of hexadecimal numbers and 68000 assembly mnemonics. What a nostalgia trip.
What an awesome read.
Fixing and updating a >30 years old game, this must be the game with the longest support by it’s original Author.
I really loved this game, it’s artstyle and the music back in the days. And I still feel the same. This was and always will be my favourite Tetris game.
I guess it’s time to fire up a 68k/PPC Mac emulator and play some more Tetris Max. 🙂
Let me know your high score! For posterity, here are the fixes that were ultimately needed, and answers to some questions I raised earlier.
The main problem was using FileSpec functions like FSMakeFSSpec and FSpOpenResFile, which weren’t introduced until System 7. Under System 6, this caused an Unimplemented Trap error when launching the game application. If you could somehow launch the application and reach the title screen, it would also crash due to FileSpec functions when opening the preferences dialog box. I had to implement an alternate code path for System 6, which simply builds the path to the resource files as strings and then calls OpenResFile for each one.
A second problem was in the preferences dialog box, where I used popup menus for selecting among the options for music, pieces, and backgrounds. Popup menus weren’t introduced until 7, and while they didn’t crash in System 6, they didn’t work either. For System 6, I replaced the popups with static text that shows the currently selected music/backgrounds name, and a button that opens a file picker where you can choose a different option. Not quite as elegant, but it works.
There were a few other inconsistencies involving how some features are disabled for 68000 CPUs, for black-and-white displays, and for System versions lower than System 7.
I was correct that the original version of Tetris Max didn’t support black-and-white displays, but not about the rest of the history. Support was added in 1993 (version 2.0) for black-and-white displays and the Mac Plus / Mac SE. The release notes for this version say “music is automatically disabled on 68000-based systems”. This might have been because the 68000 wasn’t powerful enough to play background music without slowing down the falling pieces animations.
The Mac Arcade Pak publisher actually had me split the game into two separate applications – one for B&W computers and one for color – which seems strange. Now that I think about, there may have been a B&W version of the Arcade Pak that was published a year or two after the original.
Version 2.9 was the first to support online shareware registration, using a fancy new platform called “The Web”. Prior to this, registrations needed to be mailed: an actual paper letter sent via the post office. How times have changed…
Today, someone added v2.9.3b to the MacGarden page.
I wrote an app (technically, an ‘appx’ and ‘INIT’) for System 7 and right before we were going to ship was told that I had to support System 6 as well. I didn’t want to have to re-do a bunch of testing for what I knew was going to be short lived changes, so I wrote a patcher that my INIT would use to run the app. It patched _LoadSeg and replaced unimplemented traps in the newly loaded segments with a jmp to a thunk (which had to include the instructions right before the trap) to my own implementation of the code that was missing from System 6. I think it was mostly file manager routines.
Hi Steve,
I’m the Apple guy for MAME (MESS hasn’t existed since 2015 when we merged the projects). The next release of MAME at the end of August will run every desktop 680×0 Mac with each model’s correct ROM and specific quirks from the first 128K through the final LC 580 except the IIfx, Quadra 900/950, and Quadra AVs. Unlike vMac and Basilisk and SheepShaver, we don’t cheat any hardware devices. Floppies are emulated down to the flux level (we had the first .MOOF support), hard disks emulate the 5380 or 5394/5396 controller driving a bit-accurate and timing-accurate parallel SCSI bus model, and the ADB microcontrollers (including Egret and Cuda) run the original Apple ROM code and speak real bit-serial ADB to the keyboard and mouse. You can freely configure NuBus cards and have a Mac II with 6 video cards from Apple, Radius, SuperMac, and RasterOps, or 5 plus an Ethernet card, or whatever. The Mac II can have either the Ron Hochsprung fake MMU or a real 68851. All machines that support it can run either 24 or 32 bit mode. And you can boot from real CD-ROM ISO or BIN/CUE images.
There is an extensive debugger where you can break on a location if D5 equals some value and the disassembly shows Mac traps by name. You can step backwards in code as well, and save and load states while stepping. And open multiple windows for memory and disassembly views.
Yes, all of this power can be challenging to get used to. If you are on a modern Intel or Apple Silicon Mac, there is an excellent “training wheels” GUI available at https://github.com/ksherlock/ample/releases . For everyone else we have a Mac-specific usage manual at https://wiki.mamedev.org/index.php/Driver:Mac_68K and for techies we have extensive technical info linked off of that page that breaks down the internal secrets of classic Macs.
Arbee that sounds great! Thanks for all your work on the classic Apple computer support. It’s been several years since I last tried, but I remember that MESS installation and usage were quite complicated compared to other emulators. If I’m not mistaken, there wasn’t any pre-built executable and everything had to be compiled from source, after installing cygwin and gcc and other dependencies first. Would it be possible to make a Windows installer with a pre-packaged MAME executable ready to go? These days I prefer a Mac for personal stuff, but all BMOW development and business work is still on Windows.
We do distribute binaries for 64-bit Windows: https://www.mamedev.org/release.html
Internet Archive has all of the ROMs, and you can find some canned installed System HDD images on the wiki page I linked above, as well as instructions on how to create your own HDD image, boot the Apple Legacy Recovery CD, and install the System of your choice.
That’s great news, thanks! It’s been a few years, but now that I think about it, I was probably building MESS/MAME from source because I had changed the code to support some experiments. I needed to test custom ROMs with non-standard sizes and checksums for the ROM-inator II.
Pop-up menus were around long before System 7. The PopUpMenuSelect function is documented in Inside Macintosh V. The pop-up menu CDEF 63 was introduced in the Communications Toolbox for System 6 before becoming more generally available in System 7, so if you want to use the CDEF on System 6 you could just require the user to have installed the Comm Toolbox. I think it might also have been possible to license the CDEF so that you could copy it into your application. Before the pop-up menu CDEF existed, you would create a “user item” in your DITL and use it to draw the pop-up menu manually, and call PopUpMenuSelect yourself when it was clicked. The System 6 version of Tex-Edit, one of the first real Macintosh applications whose source code I got to study in the 90s, does pop-up menus this way, as do ResEdit, standard file dialogs, and Tetris Max’s own Help dialog.
And thank you for Tetris Max and for fixing these bugs. I spent countless happy hours playing it on my Quadra in the 90s.