68k Trying to get old library linking into retro68 project without crashing the system

Relating to a 68k application

bribri

New Tinkerer
Jun 28, 2024
2
0
1
Hello! This is my first post here, so I figure I should introduce myself briefly. I've recently gotten back into classic Mac game development. Back in the 90s when I was young (and I was in my preteens / teens) I made a bunch of HyperCard and C++ games, most of which were never finished much less released. Of my few finished projects, the one I'm probably best well known for is "Unicycle!". And just last year I made a new HyperCard game called "Blah Blob" that's a full platformer with scrolling, and requires a G4 or better to play. (Or Mini vMac with the speed maxed out.)

Just for fun, I've started working on a new game, this time in C with the goal of it being fully playable on original hardware. I'm targeting 68030 macs, and so far I've got an engine that can render full screen scrolling tiles and upwards of twelve animated sprites at ~45 fps on an SE/30. So good progress.

I've just turned my attention towards trying to add in music. While I probably could write my own music driver, what I'd rather do is try and get the old Sound-Trecker driver working since it performs great on 68k macs, and there's already tons of great tools for authoring MOD files. I did some deep software archeology and managed to reconstruct the drivers for version 2 of it (which are not presently on Macintosh Garden or anywhere else I could find) as well as its headers, and I can use it successfully if I compile using the THINK C / Symantec C++ compiler.

However, I've been making my game in retro68, and I'd really like to keep using it. Partly because gcc is just a better compiler compared to Symantec or CodeWarrior in terms of optimizing, and also because it's really convenient to use a modern IDE and toolchain. But so far, I cannot figure out how to use this library in retro68 without it crashing the system!

Here's the technical details, and what I've tried:

The Sound-Trecker v2 driver is not actually distributed as a library for mpw, Symantec, and/or CodeWarrior. The raw code itself is stored in two resources (ISTk and PSTk), and the Symantec-compatible library available for it just contains stub functions that load those resources and make execution jump into the right places in the resources' data.

I managed to turn the stub library into a gcc-compatible static library by finding which bytes the various functions in it are located and manually creating a .s file. When I link against it with retro68 and include the PSTk and ISTk resources in my application, several of the functions work properly. But most of them cause the system to crash hard.

Next I figured out where the actual functions in the ISTk and PSTk resources reside, side-stepping the need for the stub functions. Now I can just load the resources, create a function pointer with the right signature, and point it to the correct place in the resource's data. This method works great when compiling with Symantec's compiler. But with retro68 it still crashes the system.

The last thing I tried was converting the whole ISTk and PSTk resources into gcc static libraries so I could compile them directly into my application using retro68. That too didn't work -- a few functions work, but the rest still just crash the system in exactly the same way.

At this point I'm not sure what's going wrong. I gather there must be some difference in the way code is being linked together with retro68 compared to Symantec, or that retro68's standard library is somehow interfering with the old code in these ISTk and PSTk resources. But I'm more of a high level programmer. C is typically as low level as I get, and I'm not very familiar with the inner workings of compilers and linkers. I've only just started to dabble in 68k assembler for the first time as I puzzled through figuring out what the stub functions were doing.

The only other clue I have is that there's a similar issue using CodeWarrior, and it depends on which version of CodeWarrior it is. The above method of loading the ISTk and PSTk resources and calling its functions directly works when I compile with CodeWarrior 9, but it crashes the system with CodeWarrior 11! So it's not just retro68 that has a problem with this.

This is a pretty esoteric issue, and I'm not sure what I can do at this point to try and fix it. I've started an issue on the retro68 github page but no response there so far. Anyone have an idea of what could be going wrong?
 

bribri

New Tinkerer
Jun 28, 2024
2
0
1
I figured it out! There's nothing like asking for help to suddenly come upon the answer yourself.

It turns out the issue was inconsistent int sizes. In THINK C / Symantec C++, it's two bytes. In retro68, it's four bytes. In CodeWarrior, you have the option of having it compile using either 2 or 4 byte ints, and the default changed in CodeWarrior 11, which is why it blew up when CodeWarrior 9 didn't. In any case, all I had to do was change my function signatures to use explicitly sized int types and everything started working.

I knew from my decades of being a C programmer that one must beware of ints and their inconsistent, compiler-dependent size, but rarely does it bite me like this. But now I'm a little bit wiser than I was before.