Summer ’25 Update

This last year has been extremely busy with real-life things, so there’s been very little time to work on the emulator. During the winter and summer breaks we did have bit of time to work on some things, and there’s a couple important changes that might be of interest for you – so here’s a brief breakdown of the most important things that’ve been updated:

File deletion support

This has been one of the long-time tasks that’s been on the backlog, and has been causing issues with at least a number of test applications, which expect file deletion to work and would fail in random ways when this still was not implemented (this includes games such as Might & Magic 3, Dungeon of Doom, and others). This feature was delayed for a long time as it not only involves deleting the pair of AppleDouble header/data file pairs, but also maintaining the in-memory AVL tree presentation of the file system in stable state – which have now been implemented, at least in basic form, and the aforementioned applications now work much better

Dynamic configuration

One of most important changes for this year has been adding finally support for dynamic configuration of runtime, which means that emulated machine type and features can be configured using mace.settings file (located in the Resources folder within the app bundle), and a set of predefined machine profiles. Here’s brief breakdown of all configuration settings that are implemented:

Profile selection:

EnvProfile: Select the machine profile. Current predefined profiles are:
- mace_plus_4mb_sys607.profile: The default Mac Plus-like environment, with 4 megabytes of RAM and reports System version as 6.0.7
- mace_plus_4mb_sys700.profile: Same as previous profile, but reports System version as 7.0.0
- mace_se_4mb_sys700.profile: Same as previous, but instead of Mac Plus identifies as Mac SE. This profile should be used with THINK Pascal 4.x, as MACE trap tables always in the format of SE/II and later models (Long story short, Mac Plus had different trap table layout, which THINK Pascal would expect when it identified that model, and it would lead to conflict) 
- mace_68020_8mb_sys700_24bit.profile: 24-bit 68020 Mac II with 8 megabytes of RAM and reports System version as 7.0.0
- mace_68030_32mb_sys755_32bit.profile: 24-bit 68030 Mac II with 32 megabytes of RAM, 32-bit memory manager eanbled, and reports System version as 7.5.5
- mace_68040_32mb_sys755_32bit.profile: Same as previous, but with 68040 CPU emulation level

Application settings:

EnvStartupWorkingDirectory: Choose startup directory within the emulated file system
EnvStartupFile: Choose which file will be LAUNCHed at emulator startup
EnvAppName: Default application display name (for bundled applications)

(Note that any non-ASCII custom characters in the filenames should be escaped using \xNN format, where NN is the MacRoman code for the character)

Additional configuration settings (for mace.settings):

EnvUseRelativeMouse: Set this to 1 to use relative mouse mode instead of absolute (use for games that alter mouse position, such as Apache strike or Wolfenstein 3D, or for games that hide mouse pointer and use it for input, such as Dark Castle). NOTE: There's a weird glitch from combination of the most recent macOS versions, the version of SDL2 we're using, and the software cursor obscuring code, which cause cursor sometimes jumping to screen center when this mode is enabled
EnvDisableDeskAccessories: Disable desk accessories
EnvClassicSoundPhaseShift: Alter the default .Sound DRVR output phase, set this to -1 (minus one) for Dark Castle for audio to work properly
EnvGetNextEventDelayHack: Set this to 1 for old games that run too fast (such as Stunt Copter)
EnvDefaultColorDepth: Set bit depth of the color video device
EnvVideoScreenWidth: Set width of the color video device
EnvVideoScreenHeight: Set height of the color video device

IMPORTANT NOTE: If you set the combined framebuffer size of color video (that is, width times height times bit depth of screen) to larger than 1 megabyte, it will only work if a 32-bit machine profile is used! This is as currently we only support fixed memory modes set at startup time, and on real macs in 24-bit mode the machine would transparently do MMU switching between 32- and 24-bit modes for screen accesses, something we don’t support yet!

The machine profile settings can be overridden from mace.settings, but changing most of the other default profile settings is not recommended as they will likely lead to non-functional environment.

New experimental CDN for demo application bundle builds

The old versions of demo applications haven’t been updated for a long time, but this year we wanted to get you a bit more recent version of the emulator to try out. However, there’s some challenges as our Apple Developer program ran out, so we don’t have signed binaries available, and we don’t have at moment a working Windows machine so we also don’t have windows versions available. HOWEVER, we did build ARM64 (unsigned) versions of both the existing demo applications, and we also created bundles for a number of new apps to try out, including a number of color games such as KYE, and demo version of Civilization and Eric’s Ultimate Solitaire Sampler, and a few others. Head over to the “Downloads” section using the link at top of the page to try them out! We also moved the files to a dedicated low-cost CDN, so WordPress should no longer mess up and randomly delete the ZIP files like in the past.

Please note that as they’re unsigned, you’ll have to at first launch choose “Done” instead of “Move to Bin” to not delete the application, and then go to System Settings -> Privacy & Security -> Security and choose “Open Anyway” to force macOS to open the demo apps. This is as we didn’t want to spend this year another $100 on Apple’s Developer Program as we have other expenses we need to cover. We’ll make the signed binaries again available someday in future, once we have chance to get back working on the emulator with more time.

Other minor fixes

There’s also some other minor fixes, such as:

  • Fixes to 16-bit (“thousands of colors”) support for color quickdraw, which had still issues in the direct mode blitting, most notable drawing of mouse cursor. This seems to work now well enough so that Marathon is able to run in this mode. However, as gamma tables are not yet implemented, the gamma fades used by games to do fade-to-black effects do not yet work. This should be however a trivial feature to implement in future. There’s also foundation for 32-bit (“millions of colors”) mode, but most of blitters are still unimplemented so it’s not usable yet.
  • cscSetGray control code support for color video DRVR. This allows setting the screen to monochrome mode for indexed display modes, allowing you to relive the fun memories of having a 16-grayscale monochrome displays 🙂
  • Fix PutScrap to not keep incrementing the LMScrapSize value. This caused ResEdit to quickly run out of memory especially in color mode
  • Fix UpdateGWorld to not reference old GWorld (this bug surfaced when we experimented color depth switching within Marathon)
  • Other minor fixes

Some screenshots of the grayscale mode

Hopefully we’ll have again more to show you guys in the winter. We also have had the AppleDoubler tool ready for a long time, which would speed up a lot converting native files to the ADF format used by the emulator, but sadly haven’t had time to polish and publish it properly. But we’ll definitely get over to doing it around December/Christmas break.

Full list of changes since last post

2025-07-19 02:01:43 +0300 • Add EnvClassicSoundPhaseShift to dynamic settings 
2025-07-19 00:40:38 +0300 • Update version number                             
2025-07-19 00:39:42 +0300 • Fix setup of csMode from gdFlags in InitGDevice   
2025-07-18 16:26:20 +0300 • Implement cscSetGray for the color video DRVR     
2025-06-30 03:37:05 +0300 • Fix reference to old GWorld in UpdateGWorld exit  
2025-06-30 03:23:59 +0300 • Add 32-bit graphics output blitter to SDL module  
2025-06-30 03:02:56 +0300 • Better divsul overflow fix (takes size into cons..
2025-06-30 02:30:25 +0300 • Fix compilation errors in mdb and mpr             
2025-06-30 02:26:00 +0300 • Update trap list source                           
2025-06-30 02:25:25 +0300 • Fix negative integer overflow in divsul           
2025-06-30 02:24:24 +0300 • Fix nested sourceDevice declaration               
2025-06-29 23:13:34 +0300 • Hack CMakeLists.txt to work with new CMake version
2025-06-29 23:12:57 +0300 • Fix 32-bit ROM resource zone corruption bug       
2025-06-29 23:12:19 +0300 • Make screen size configurable in mace.settings    
2025-06-29 23:11:31 +0300 • Fix incorrect color depth in a number of test apps
2025-03-14 23:06:39 +0200 • Fix inverted cursor drawing glitch in direct mode 
2025-03-14 11:18:47 +0200 • CRT filter for 16-bit mode                        
2025-03-09 02:17:32 +0200 • Fix PutScrap setting invalid LMScrapSize value    
2025-01-15 23:05:10 +0200 • Support GetNextEventDelayHack in dynamic settings 
2025-01-15 14:03:01 +0200 • Minor fixes to Fool's Errand app configuration    
2025-01-13 01:27:56 +0200 • Fix F/A-18 Hornet test app filename in settings   
2025-01-13 00:04:43 +0200 • Fix setup of 32-bit mode memory pages             
2025-01-12 22:32:59 +0200 • Handle escaped hex values in configuration strings
2025-01-12 01:53:17 +0200 • Fix NewAlias stub to return a dummy Alias Handle  
2025-01-12 00:43:20 +0200 • Relocate trap generator to its own sub folder     
2025-01-12 00:42:50 +0200 • First implementation of dynamic settings system   
2025-01-05 03:21:29 +0200 • Remove old backup of trap list source file        
2025-01-04 02:28:52 +0200 • Work on refactoring configs to dynamic settings   
2025-01-02 19:38:26 +0200 • Implement basic file deletion (logical & physical)
2024-11-03 21:30:22 +0200 • Partial RestoreEntries implementation             
2024-10-23 13:32:06 +0300 • Add missing std file dialog 'dctb' color tables   
2024-10-23 13:31:29 +0300 • Add Ares Demo test app config                     
2024-08-14 11:20:20 +0300 • Save regs on CallComponentFunction & debug cleanup

Summer ’24 Update – Component & MIDI Manager news

It’s been a while since previous update, as life has been really busy during the past year. Sadly progress has been slow because of lack of time, but we do have some exciting news to share though for this year. Let’s dig in…

Enchanted Scepters

On Emaculation forums, one member asked us whether Enchanted Scepters was compatible with MACE. As we do have both 24-bit (and recently also 32-bit) addressing support, the original version of the game not being 32-bit clean was not an issue, but we ran into other interesting feature in the World Builder engine…when calling HandToHand to duplicate handle, we did return error code in D0, and resulting handle in A0 as specified by Apple documentation…HOWEVER, the original apple routine also does TST.W D0 before returning, so the zero flag is set to indicate the error state already at that state…Enhanced scepters expected this flag to be set by the time HandToHand returned, and of course we did not do this explicit testing of D0 register, and thus it crashed and burned with SysError 10. After adding a manual TSTW_D0 glue call at end of the trap (and a bunch of other traps returning value in Dn register), Enhanced Scepters seems to be mostly co-operating:

Enchanted Scepters

There’s still a bit weirdness with the custom WDEF it’s using, but we haven’t looked more into that yet.

Larger than 1mb slot space in 32-bit mode

As we did last year add the 32-bit addressing mode support to memory manager, we were finally able to experiment with taking advantage of this increased space, and added support for slot video devices to go beyond the 1MB slot device memory window limitation, which allows us to now use (almost) arbitrarily large display resolutions, that were previously limited to roughly 640×480 at thousands of colors, or 1024×768 at 256 colors. So…what better way to test this, than running SimCity 2000 in Full HD resolution:

SimCity 2000 running in Full HD resolution in full-screen mode

16-bit QuickDraw direct mode improvements

As some people might know, the original Marathon was recently released by Aleph One team for free on Steam, and partially inspired by this, we decided to work a bit on the direct color mode support of MACE, to allow running original Marathon in those higher depth modes. We previously already did have Marathon running in the usual, indexed 256-color mode, but there was a bunch of stuff missing or broken that needed to be implemented:

  • SetDepth needed to also accept color depth in addition to device modes
  • Cursor blitters and color table expansion did not yet work properly in direct modes
  • Device type of GDevices was set up incorrectly
  • Some blitters were unimplemented (i.e. colorizing BitBlt)
  • A bunch of blitters had byteswap bugs, that did not surface earlier, as indexed modes were never using more than 8 bits per pixel
  • 16-bit bitmap to pixmap expansion was missing
  • hilite draw modes were not rendering correctly as they did not expect data to be 16 or more bits per pixel
  • Some pattern drawing modes were not applying background/foreground color properly, as in direct modes black&white are reversed when compared to indexed modes, and this was not taken into account (in indexed modes, black is always last, white first, while in direct modes black is first, as its RGB value is zero, and white is last, as it’s either 7FFF or 00FFFFFF)

Here’s some before & after shots of Marathon main menu taken during this development process:

And here’s pic of the ingame dithering being inverted and font rendering still being broken:

Marathon “quit game” confirm dialog before the 16-bit color support fixes

Here’s also pics of the settings screen, before and after fixing the byteswap bug of 16-bit BitBlt:

Also, some pics of “Get File” dialog before & after fixes (also includes PICT 2 fixes, which will follow up):

PICT 2 recording improvements

As part of Marathon fixes, we also ended up digging into improving the previously broken PICT version 2 recording implementation. As the original PICT recording was specifically implemented with “classic”, non-color QuickDraw in mind that uses 1-byte opcodes, a lot of QD routines did not support saving the opcodes in the 2-byte format used by PICT version 2. Marathon uses this specifically for drawing a preview of the current map location, saving that in the savegame file, and using it to display preview in the Open/Get File dialog. Fixing this involved going through all the recording routines, and modifying it to use PICT version-independent code. This also has nice benefit that it made ResEdit DLOG/WIND previews also work now in color mode:

ResEdit DLOG preview works now in color modes too

AND also, this seems to have fixed the previously crashing Civilization 2 city screen, which uses PICT 2 recording somewhere in it:

Civilization 2 city screen no longer crashes

Sadly all recording are not yet fully supported, as StdBits is still missing some cases, and that causes at least ResEdit trying to display preview of windows that have goaway/zoom boxes, which are PixMaps, to fail to record/play back properly.

MAJOR FEATURE: Component Manager first steps

One other important milestone feature has also been support for Component Manager, which has now been partially implemented enough to allow Internet Config component extension to register, and the Internet Config application to load up and use the registered component mostly okay:

In case there’s somebody reading this, who does not remember what Internet Config was used for, it was the tool used to configure practically any internet-related settings in the old MacOS, offering through Component Manager a unified API for any applications to share & use these settings, co-exist and co-operate together. It consists of two main parts:

  • Internet Config Extension – This is actually not a traditional extension, which would contain ‘INIT’ code, but a component of type ‘thng’. Component Manager loads all these components during system startup, and registers them to be used by any applications which might rely on them
  • Internet Config Application – This is the UI for configuring the Internet Config settings, and it uses Component Manager to discover and connect to the Internet Config ‘ICAp’ component

Internet Config was a great test case for this, as it has very precise set of Component Manager features it uses, and does not depend on too many other features of the system, which we might not yet have implemented. There’s still dependency on file deletion which causes the saving of settings to fail, but we’ll eventually get that implemented and it should not be a major issue.

Originally Component Manager was developed for QuickTime, to support loading various video/audio codecs, but another major use case for it is Sound Manager 3.x – which is actually the major motivation for us to work on supporting components, as we hope to make our Sound Manager 3.x implementation follow the Sound Components design as closely as possible, which in turn relies on having Component Manager available to abstract all the mixers, hardware devices, compressors/decompressors etc in an universal pipeline.

Resource Manager fixes & ResEdit CODE editor

Just as a filler, we also wanted to get the famous ResEdit ‘CODE’ editor to work in MACE, as it allows disassembling any 68k code using the ResEdit itself. Interestingly almost everything needed to do this was implemented fine, but we had to implement SetResPurge trap (and default purge procedure), and also found a bug in reallocation or purged compressed resources by happy accident. Here’s pic of the CODE editor in action:

ResEdit ‘CODE’ Editor

AppleDoubler UTF-8 denormalization

Also on the side, we noticed that at some point the UTF-8 to MacRoman encoding in AppleDoubler tool had broken because of way UTF-8 can be present same file names both in normalized and denormalized formats, and we only supported denormalized UTF-8. As our current macOS host system gave us normalized file names, we added denormalization for all characters that are part of the MacRoman character set, and after that we were happily able to convert exotic names such as Déjà Vu II’s folder name into AppleDouble:

Déjà Vu II folder name denormalized & converted to MacRoman properly

Font/DA Mover

We already have had support for Desk Accessories for quite a while now, but until now we did all testing & adding those to the System file by manually copying the resources of those DAs. When we were working on the MIDI Manager support (news of which will follow up after this), we wanted to also add PatchBay DA to the System file, but decided to try for fun, how well would Apple’s Font/DA Mover work in MACE? Well…

Font/DA Mover

…the answer is: It worked just perfectly out of the box! We were able to manipulate both existing and new DAs from DA suitcases just fine, and the tool was happy to install PatchBay into our completely custom System file without any issues!

MIDI Manager implementation

And now to one of the coolest features we did do for this update: We had already been planning about experimenting with adding support for Apple MIDI Manager interface (which actually works using SoundDispatch with tool number 4), but we didn’t really get into this until this summer. One major breakthrough was finding finally the very elusive set of MIDI Manager documentation, which nowdays appears to be only found in Apple DocViewer format:

Apple DocViewer showing MIDI Manager SDK documentation

(The Palatino font above is a bit weird, as by design bitmap fonts default to half- or double-size versions if exact fit is not found, which in this case was the double-size one. Normally when viewing this font in this size in System 7 you’d get a way smoother look thanks to TrueType rendering, which we don’t support…yet!)

It took a couple weeks of work during the summer, but we finally got enough of MIDI Manager API implemented to allow both PatchBay to happily show our custom MIDI driver, load up MIDI Jukebox, and make connections between the driver and the application:

MIDI Jukebox and PatchBay in MACE

BUT what was even cooler, was the fact that thanks to MIDI packet format being universal, we eventually had very little to do to allow passing all the MIDI packets from MIDI Jukebox, through our custom driver, to the host system using CoreMIDI. And as we were able to hook actual MIDI Hardware, which in our case was M-Audio USB MIDI Adapter, and an original Roland SoundCanvas SC-55MkII, we got this nice recording of playing MIDI files in MIDI Jukebox in MACE through the real, physical hardware synthesizer:

The mouse cursor is a bit laggy in this capture, as we ran this whole non-stop one hour session in debug mode in Xcode, which is really slow even on a Mac Studio. We still need to work on the Time port timers, as randomly they don’t start up properly, instead stalling up the whole port. But once you get the timer running, it seems to work stable for a long time!

The very original motivation was to support native MIDI playback in Space Quest 1 remake, which does take advantage of Apple MIDI Manager:

Space Quest 1 using MIDI Manager, as seen in PatchBay

Sadly Space Quest 1 expects the sound module to be a MT-32, and we couldn’t figure out how to get SC-55mkII into MT-32 emulation mode, so the music in that game does not sound very great, and we didn’t take capture of it. Plus there’s also something missing from other part of emulation, as the game never proceeds from the intro screen, but stays there playing happily the music without allowing player to skip forward.

Also, thanks to PatchBay DA, which also uses the rarely used Desk Accessory feature of having its own menu in applications menu bar, we finally had a test case for SystemMenu trap, which was implemented!

Bonus: Some Havoc screenshots

Here’s also some screenshots of Havoc running on MACE…we wanted to just check if the game would try to use any QuickDraw 3D routines (as it’s supposedly one of the few QD3D compatible games), but apparently it’s happy to do everything in software 3D and actually runs pretty well, so…here’s how it looks like:

That’s all for now…we don’t know when the next update will be, as life’s going to get just more busy…but rest assured, work on MACE will continue. We’ll…be…back!

Full list of changes since last post

2024-08-12 02:03:18 +0300 • Fix MIDI timer drift (hook to time manager global)
2024-08-11 03:49:44 +0300 • Fix disabled MIDI debug message compile warnings
2024-08-11 03:49:04 +0300 • Quick hack to connect host CoreMIDI to MIDI Driver
2024-08-11 03:27:59 +0300 • Readhook implementation and packet dequeueing
2024-08-10 19:51:39 +0300 • Update MIDI time ports from the MIDI timer handler
2024-08-10 19:49:52 +0300 • Start MIDI driver clock
2024-08-10 01:25:43 +0300 • First proto of MIDIWritePacket implementation
2024-08-06 00:25:08 +0300 • Work on MIDIWritePacket (packet alloc & dealloc)
2024-07-29 19:38:05 +0300 • Implement MIDI time conversion for formats 0 to 5
2024-07-29 17:55:46 +0300 • Implement MIDIGetCurTime for MIDI Manager
2024-07-29 16:13:56 +0300 • Fix MIDI driver signature & data port directions
2024-07-29 16:13:22 +0300 • Partial implementation of MIDIConnectData
2024-07-29 14:50:11 +0300 • Implement MIDIGetPortName and MIDISetSync
2024-07-29 14:36:33 +0300 • Add temporary (quick hack) ports to MIDI driver
2024-07-29 14:35:27 +0300 • Implement MIDIGetPortInfo for MIDI Manager
2024-07-29 14:34:41 +0300 • Fix invalid port ID bug in MIDIGetPorts
2024-07-29 14:00:23 +0300 • Fixes to global MIDI port indexing
2024-07-29 13:28:38 +0300 • Partial stub of MIDIConnectTime implementation
2024-07-29 00:25:24 +0300 • Partial stub of MIDISetCurTime implementation
2024-07-28 10:40:26 +0300 • Tweak type of Get/SetSR in M68kHelper
2024-07-28 02:22:48 +0300 • Link CoreMIDI on macOS targets
2024-07-28 02:22:39 +0300 • Implement MIDIStartTimer for MIDI Manager
2024-07-28 02:15:41 +0300 • Part of MIDIAddPort implementation
2024-07-26 15:53:05 +0300 • Test code to dump list of host CoreMIDI devices
2024-07-26 01:43:54 +0300 • Fix MIDI Manager version number
2024-07-25 00:59:39 +0300 • Implement SystemMenu trap (for PatchBay DA)
2024-07-25 00:45:18 +0300 • Implement MIDISignOut (partially) for MIDI Manager
2024-07-24 16:45:48 +0300 • Add dummy DILoad stub for Font/DA Mover to work
2024-07-24 04:35:59 +0300 • Implement MIDIGetClientName for MIDI Manager
2024-07-24 04:26:11 +0300 • Implement MIDIGetPorts for MIDI Manager
2024-07-24 04:07:04 +0300 • Implement MIDIGetClientIcon for MIDI Manager
2024-07-24 04:01:47 +0300 • Implement MIDIGetClients for MIDI Manager
2024-07-24 04:01:32 +0300 • Implement MIDIWorldChanged for MIDI Manager
2024-07-24 03:53:18 +0300 • First MIDISignIn implementation test pass
2024-07-23 18:13:04 +0300 • A bit of work on MIDISignIn (checks for duplicate)
2024-07-23 18:12:09 +0300 • Call MIDI sign-in from the MIDI driver
2024-07-23 18:11:46 +0300 • Add MIDIDriverSignIn alternate MIDISignIn selector
2024-07-20 04:48:30 +0300 • Fix stack mismatch icon transformed SICN rendering
2024-07-17 21:48:21 +0300 • Add Deja Vu 2 test application configuration
2024-07-17 20:59:06 +0300 • Implement utf8 denormalization in AppleDoubler
2024-07-17 07:00:12 +0300 • Fix reallocation of purged compressed resources
2024-07-17 05:40:17 +0300 • Implement SetResPurge
2024-06-08 17:56:50 +0300 • Fix 32-bit memory manager free space debug checker
2024-06-08 17:56:23 +0300 • Add missing AppleEvent header additions
2024-06-08 02:30:42 +0300 • Merge branch 'master' of
2024-06-08 02:30:24 +0300 • Fake sound manager gestalt
2024-06-08 02:22:10 +0300 • Add dummy stub for AEPutKeyPtr AppleEvent selector
2024-06-08 02:18:11 +0300 • Add dummy stub Pack8 AECreateAppleEvent selector
2024-06-07 22:31:04 +0300 • Fix color graying out crashes in popupmenu CDEF 63
2024-06-07 22:13:23 +0300 • Dummy stub for IconSuiteToRgn icon utils selector
2024-06-07 21:52:27 +0300 • Fix calculation of offsets in thing ID validation
2024-06-07 21:51:03 +0300 • Fix incorrect size of component open file table
2024-06-07 13:35:25 +0300 • Implement OpenDefaultComponent
2024-06-07 13:35:03 +0300 • Implement FindNextComponent
2024-06-07 13:34:48 +0300 • Fixes to & cleanup in RegisterComponent
2024-06-07 13:26:14 +0300 • Fix comp head byteswap bug in RegisterComponent
2024-06-07 02:40:10 +0300 • Fix CallComponent Delegate fallback case stack bug
2024-06-07 02:11:51 +0300 • Add dummy stub for FlushCacheRange in HWPriv
2024-06-07 02:04:45 +0300 • Fix stack mismatch in component parameters cleanup
2024-06-07 02:04:14 +0300 • Implement DelegateComponentCall (simple case)
2024-06-07 00:33:58 +0300 • Fix component & instance index/pointer conversion
2024-06-05 23:25:27 +0300 • Minor component bug fixes
2024-06-05 23:20:40 +0300 • Implement Set/GetComponentInstanceStorage
2024-06-05 23:19:28 +0300 • Implement CallComponentFunction
2024-06-05 23:18:59 +0300 • First proto of OpenComponent & open component call
2024-06-05 14:30:23 +0300 • LoadComponent partial implementation (in sys zone)
2024-06-05 14:08:51 +0300 • Implement CloseComponentResFile
2024-06-05 13:55:45 +0300 • Implement OpenComponentResFile
2024-06-05 13:54:56 +0300 • Fix resolving file of registered components
2024-06-05 11:52:17 +0300 • Component validation added, start work on loading
2024-06-05 00:22:56 +0300 • Work on open/close/register/unregister comp calls
2024-06-04 01:08:59 +0300 • Use UPPs in CallComponent instead of a 68k callsub
2024-06-03 16:15:53 +0300 • ComponentDispatch refactor & proto CallComponent
2024-06-03 16:13:44 +0300 • Use opcode enum in ClosePicture, not hard-coded FF
2024-05-27 18:39:38 +0300 • Implement GrafDevice trap
2024-05-18 15:18:11 +0300 • Fix screen dirty area tracker overflow
2024-05-18 14:10:08 +0300 • Fix StdFile dialog visibility failsafe not working
2024-05-18 02:57:42 +0300 • Fix byteswap size in PICT v2 padding
2024-05-18 02:37:27 +0300 • Merge branch 'master' of
2024-05-18 02:37:16 +0300 • Fix padding of PICT v2 data when recording opcodes
2024-05-18 02:30:22 +0300 • Fix srcOr mode for 16-bit region blitters
2024-05-18 02:30:06 +0300 • Fix or & bic modes for 16-bit rectangle blitters
2024-05-17 16:33:49 +0300 • Fix colorization of srcOr & srcBic in direct modes
2024-05-17 02:26:57 +0300 • Merge branch 'master' of
2024-05-17 02:26:54 +0300 • Disable debug zone dump for MoveHHi
2024-05-17 02:05:25 +0300 • Fix zcbFree after MoveHHi to below min size target
2024-05-15 03:25:46 +0300 • Fix cast warnings for reading shifted pattern data
2024-05-15 01:41:36 +0300 • Fix hilite drawing mode to work in 16-bit colors
2024-05-15 00:59:58 +0300 • 1-to-16bit monochrome pixel expansion routine
2024-05-15 00:59:11 +0300 • Major work on version 2 PICT recording support
2024-05-13 16:02:35 +0300 • Fix byteswap bug causing 16bit color mode glitches
2024-05-13 14:51:33 +0300 • Add colorizing block blitter srcCopy mode
2024-05-13 12:26:06 +0300 • Fix wrong gdType in InitGDevice after SetDepth
2024-05-13 11:45:10 +0300 • Support blitting cursor in direct modes properly
2024-05-13 03:02:13 +0300 • Make QDScaleMask16 work with 16-bit cursor data
2024-05-13 01:32:11 +0300 • Tweak GetCTable to pass through 16-bit case
2024-05-13 01:18:21 +0300 • Fix SetDepth to also accept mode as depth argument
2023-12-25 04:31:05 +0200 • Add SimCity Classic and Duke 3D 68k Demo test apps
2023-12-10 23:19:19 +0200 • Enable >1mb slot space for slot devices in 32-bi..
2023-12-10 23:13:30 +0200 • Fix 32-bit heap compaction
2023-11-27 19:31:59 +0200 • Fix MIDIWorldChanged signature
2023-11-24 15:08:05 +0200 • Add dummy MIDIWorldChanged stub for SoundDispatch
2023-11-24 14:57:28 +0200 • Merge branch 'master' of
2023-11-24 14:57:21 +0200 • Work on Component Manager call dispatcher
2023-11-24 04:06:23 +0200 • Add Enchanted Scepters test app JSON config
2023-11-24 04:05:54 +0200 • Reinforce unsigned selStart/selEnd in TextEdit
2023-11-24 04:03:47 +0200 • Do explicit TSTW_D0 to update flags in HandToHand
2023-11-24 04:02:49 +0200 • Do a explicit TSTW_Dn on traps that return Dn
2023-11-13 00:47:13 +0200 • Implement FSpOpenRF for HighLevelFSDispatch
2023-11-13 00:44:25 +0200 • Start work on CopyDeepMask
2023-10-21 14:04:37 +0300 • Fix far-right edge ShieldCursor bug in classic QD
2023-10-21 14:03:05 +0300 • Update OSX icns files
2023-10-21 14:02:29 +0300 • Add Shadowgate to test apps list

Summer ’23 update

Happy summer of 2023! This post is a bit late, as it’s the last day of summer today, but they do say better later than never! Most of progress in this half of year has been done in the spring, as summer has been more quiet, but there’s still a lot of both under-the-hood and actually visible improvements. Here’s a breakdown what’s new, in somewhat chronological order but also a bit grouped by the topic:

Eat my Photons! (and runtime color depth switching)

While trying to get “Eat my Photons!” game to start up, one major feature that was added was the ability to switch color depth using Palette Manager’s SetDepth & color video DRVR’s cscSetMode Control code. That particular SetDepth was actually a non-functional dummy TODO from long time ago, but now it has proper implementation.

The fact that early Macs of this era had fixed resolutions, but adjustable color depths, does show in the fact that for changing modes happens through this single API call. Interestingly, display modes also (at least by default) started from 128, so 128 was 1-bit monochrome mode, 129 was 2-bit 4-color mode, etc. up to 133 for 32-bit color mode.

SetDepth does not only call the driver to select the new color depth, but also handles some quite important tasks while doing so:

  • Sets the GDevice flags to reflect whether color or grayscale mode was requested
  • Saves highlighted menu & restores it
  • Calls InitGDevice to do the actual device reinitialization
  • Active palette of front window again (to apply any possible changes to default colors needed for the GDevice’s color table through Color Manager)
  • Redraws desktop, all windows, menu bar – and the rounded corners

The InitGDevice, which was already implemented during the early work on color QD, was fixed to get the video parameters from the given mode parameter instead of hard-coded depth. Other duties of this call include graying the screen using cscGrayScreen DRVR call, reinitialization of GDevice pixmap for new depth, reset drawing colors, reinitialize mouse cursor etc.

With these changes (and implementing the Fix2X trap handler) we did get the Eat my Photons! title screen to show up (after it switched from 256 to 16 color mode on the fly):

“Eat my Photons” launch screen after color depth switching works

Sadly we haven’t yet been able to get further in that game, presumedly because of missing Apple Event support.

Improved INIT handling

One thing that was experimented already earlier was support for INIT (extension/control panel) loading, but it was still quite experimental and had bunch of issues with it. Some things we improved were:

  • Previously, the INITs would be loaded on system heap, but that was the wrong way to do it. Instead, we now do more like the real Mac system does:
  • Use a temporary application heap zone where INIT operates by default. This is thrown away after each INIT load, while persistent data is expected to be allocated explicitly in the system zone.
  • Use ‘sysz’ resource to increase system zone size by requested amount (plus minimum 16K slop) IF the system zone does not have enough requested space. Also compact the zone, and re-open active INIT file if needed while doing so.
  • Support loading INITs from not just boot folder (System Folder) but also from arbitrary folders, such as Control Panels and Extensions folders.

These improvements allow us to now run more fun toys, such as ColorDesk, which can be used to set the desktop background picture:

ColorDesk control panel in action, with desktop background image

Also, Aaron was also experimented with (in this pic the icon family plotting was not yet implemented), with MacEnvy giving interesting information about the MACE environment:

First attempt of running Aaron – with MacEnvy machine profile

And for fun, we tried loading lots of INITs at once too 😀 This includes Aaron, After Dark, ColorDesk, ColorSwitch Pro (which does not yet work very well), MenuBarPattern and SoftwareFPU:

Lot of INITs

Icon Utilities – and more Aaron

As mentioned before, the window title bar icons, and scroll bar arrows/indicator were missing because Icon Utilities was missing the icon family drawing routines, so this gave us a good excuse to finally implement them. Brief summary of what this included:

  • Added icon family drawing routines, such as PlotIconID, PlotIconSuite, PlotCIconHandle, and such, which share quite lot of code
  • Handling the requested transformations (selected, disabled, and lowcolor variants)
  • Choosing the appropriate icon data for given transformation and destination depth
  • Adding proper label colors to the System (eventually modifiable by the Colors control panel), and applying those to the icons using a very specific tinting method which attempts to imitate Apple’s original tinting as closely as possible
  • Handle alignment of icons (vertical and horizontal placement) plus choosing correct icon size for destination bounds

With this ton of work done, a lot of debugging, cursing and bug-fixing, we now have the new Icon Utilities routines working good enough to make Aaron WDEF to appear correctly (as mentioned, in this case the close & zoom boxes, plus the scroll bar contents):

Aaron works now!

Kaleidoscope Installer – a bunch of file manager fixes

Inspired by how nicely Aaron worked, we wanted to give Kaleidoscope also a try, given it’s the gold standard of classic Mac OS theming. To do this, we actually wanted to try to see how well Kaleidoscope Installer (made with Aladdin InstallerMaker) would work. This led to discovery of a bunch of bugs which we fixed, and a couple missing features which were implemented:

  • NativeFS driver’s Prime call was missing IODone call
  • DirCreate did not return ioDirID for newly created directory, thus causing the caller to receive parent ID instead
  • Return this proper directory ID from FindFolder, when a new folder was created
  • Implemented SetCatInfo, and fixed SetFileInfo to not ignore file name. These allow the installer to set correct metadata for files, such as file creator and type…which are quite important!

Sadly this did not yet allow us to try out Kaleidoscope, as that control panel seems to be incompatible with System 6-style control panel (that is, it ignores the “numItems” parameter in the CDEV function). But on positive side, the File Manager fixes also fix the issues we previously had in Compact Pro SEA archive extraction!

Monochrome color QD fixes

While experimenting with color QD in monochrome mode, we noticed a couple glitches which were fixed:

  • The optimization case for text drawing was accidentally using background color for text, which was fixed to use the foreground
  • Mask buffer was not applied to regions in colorQD mode for 1-bit targets, which caused artifacts at least in Glider 4.x

Default color mode stack – and Colonization

When trying out Colonization, we got hit by mysterious crashes, which turned out to be an stack overflow issue. With some research, we noticed that on color QD macs, the default stack (DefltStack) is three times larger than the default one for “classic” macs (24K vs 8K). So after we increased it, Colonization seems to (mostly) work now…with some minor glitching in a bunch of places (like game setup screens):

RTE exception frame handling fix – and THINK Pascal color mode debugger

One interesting thing that we noticed was that even though the debugger breakpoints in THINK Pascal was working fine in “classic” (68000) mode, they would crash and burn in color (68020+) mode. This was eventually traced down to the fact that in 68020 mode, the 68K uses varying exception frame size depending on the exception type (in this case being a TRAP exception). After we added a (still somewhat hacky) handling of the variation in frame size, we got the debugger to work in color mode too:

THINK Pascal debugger breakpoints & stepping work now in color mode too!

BBEdit

Inspired by the fact that ObjectDraw demo app was written by the same guy who wrote BBEdit, we wanted to give it also a try. There was suprisingly a hidden bug in vCheckLoad call mechanism, where we had forgotten to assign 68K registers on exit from native CheckLoad, which caused the resource decompression in BBEdit to fail badly. But with that fixed, BBEdit at least starts up now:

BBEdit Preferences

One bonus feature of BBEdit is that its preferences’ file types setup uses the new icon family drawing routines, giving us another test case for them!

Proper MoveHHi implementation – THINK Pascal compilation fix

Another long-time task has been the proper implementation of MoveHHi for Memory Manager, which not only has caused THINK Pascal to fail compilation of large projects due to memory fragmentation, but also has been a blocker for starting implementation of the 32-bit memory manager. With a couple days of research and work, we finally got it working, and THINK Pascal can FINALLY compile even the huge TCL demo apps from scratch without failing due to fragmentation:

THINK Pascal compilation is reliable now!

Here’s also a pic of Art Class demo app running in THINK Pascal after being compiled:

About dialog of Art Class demo app

and the big news…

32-bit Memory Manager!

Not visually very interesting yet, but under the hood quite significant, we have now 32-bit mode support! After the aforementioned MoveHHi was implemented, we finally had all basic 24-bit Memory Manager calls implemented, so we could start implementing the 32-bit mode! As most of code was shared between 24- and 32-bit mode calls, it was pretty straightforward to branch out the 32-bit version, although there we some special cases that needed to be handled. To sum up this:

  • Separated the 24- and 32-bit implementations, but both of them still available at same time as memory manager mode could switch dynamically (not tried that yet though)
  • Use the extended memory block header for 32-bit memory blocks (12 bytes vs 8 bytes)
  • In 32-bit mode, Control Manager needs to use Auxiliary Control Records for storing control variant code. The same applies to Window Manager which stores the window variant code in AuxWinRecs.
  • Dispose control’s AuxCtlRec, AND acCTable (if not default one) in DisposeControl
  • Do the same for AuxWinRec for windows in CloseWindow

So far the only visible change of 32-bit mode is that instead of complaining about missing 32-bit mode, Ultimate Doom now loads up a bit further, but wants Sound Manager 3.x next :

Ultimate Doom 32-bit mode, but still missing Sound Manager 3.x

In future, the availability for 32-bit mode will allow further features, such as memory access optimizations by bypassing the virtual memory system as pure 32-bit pointers (using mmap to map RAM, ROM and VRAM to be contiguous, and avoid having to mask the pointers). We will talk more about this when we have time to experiment more with this and get some results for it.

Started work on Component Manager

As we eventually want to get Sound Manager 3.x working, and we want to support Sound Components from the Day 1, the next major step is implement the Component Manager – which was originally designed for the QuickTime, but was adopted by Sound Manager 3. There also exist some other use cases besides SM3, one quite approachable one to use as a test case being Internet Config. Which makes it even nicer use case is the fact that BBEdit also supports IC, which will allow us to not just experiment hosting IC with Component Manager, but also trying out BBEdit as client for it!

It will still take a bit of work to get visual results, but implementing it is advancing steadily (we’re been working on load-time component file searching and component loading).

Other notable changes

  • Added support for version 2 ‘snd ‘ resources in Sound Manager 2.x SndPlay – these were used by Capitalist Pig game
  • Fixed broken ioCompletion call mechanism in IODone, was surprisingly long unnoticed, but Hidden Agenda game was interestingly the first one to use asynchronous I/O calls
  • Had to update SDL2 to 2.28.1 for XCode 14.3 compatibility and tweak target requirements (which still need refinement)

Stay tuned for the next update around Christmas/new year time! 🙂 Hopefully we will have new builds of MACE available by then, sadly we did not have time to work on that for this update 😦

Full list of changes since last post

2023-07-26 04:11:10 +0300 • Fix 32-bit allocation of default window aux record
2023-07-24 17:58:55 +0300 • Tweak minimum deployment target
2023-07-24 17:57:57 +0300 • Add new frameworks required by SDL2 to make.cmake
2023-07-24 17:56:49 +0300 • Disable dirty rectangle optimization for now
2023-07-24 17:56:25 +0300 • Disable SDL minimize shortcut
2023-07-24 17:56:16 +0300 • Update SDL2 to 2.28.1 for XCode 14.3 compatibility
2023-07-24 17:54:42 +0300 • Fix thread spawning race condition
2023-07-24 14:32:28 +0300 • Add dummy 68040/7.5.5 profile
2023-07-24 14:31:17 +0300 • Mask handle in 24-bit MMWhichZone
2023-07-24 14:29:55 +0300 • Work on RegisterComponentResource
2023-05-07 01:40:58 +0300 • Add CreateFileIDRef selector for FSDispatch
2023-05-05 18:14:38 +0300 • Implement RegisterComponent for Component Manager
2023-05-05 15:57:22 +0300 • Partial RegisterComponentResource implementation
2023-05-05 12:18:07 +0300 • Add gestaltSysArchitecture 'sysa' Gestalt function
2023-05-05 01:48:06 +0300 • Add missing export of Count1Resources in Rsrc Mgr
2023-05-05 01:46:55 +0300 • Partial RegisterComponentResourceFile handling
2023-05-05 01:34:20 +0300 • Allocate component instance table
2023-05-05 01:21:22 +0300 • Allocate & setup component table in InitComponents
2023-05-03 02:26:49 +0300 • Partial InitComponents and GetComponentMgrVersion
2023-04-29 01:11:55 +0300 • Do groundwork for loading System Folder components
2023-04-29 01:09:43 +0300 • Add Component Manager types
2023-04-28 05:41:04 +0300 • Add Component Manager module
2023-04-28 05:11:12 +0300 • Add dummy AEDisposeDesc
2023-04-28 05:05:23 +0300 • Add dummy AEPutDesc, AEPutKeyDesc, AEGetEventHan..
2023-04-28 01:31:30 +0300 • Fix 32-bit MoveHHi handle masking
2023-04-27 00:14:17 +0300 • Handle 32-bit AuxWinRec stuff in CloseWindow
2023-04-27 00:09:00 +0300 • Handle 32-bit AuxCtlRec stuff in DisposeControl
2023-04-26 23:40:21 +0300 • Handle 32-bit mode case in GetControlVariant
2023-04-26 23:39:58 +0300 • Handle 32-bit mode cases in NewControl
2023-04-26 23:07:48 +0300 • Implement 32-bit GetWVariant
2023-04-26 22:57:35 +0300 • Add MenuList validation function
2023-04-26 22:57:03 +0300 • Fix sysmenu check in MBDF 0 (MenuList dereference)
2023-04-26 22:55:31 +0300 • Set MMU32Bit based on machine 24/32 bit mode state
2023-04-26 05:50:49 +0300 • Fix block relocation, update size of claimed space
2023-04-26 05:49:51 +0300 • Fix master pointer offsets in 32-bit CompactMem
2023-04-26 05:48:40 +0300 • Fix offsets for 32-bit mode fake rom resources
2023-04-26 03:34:39 +0300 • Add 32-bit fake ROM rsrcs to 32bit machine profile
2023-04-26 03:33:21 +0300 • Add 32-bit mode support for mem manager prologue
2023-04-26 03:31:42 +0300 • Support 32-bit zones in the zone dump function
2023-04-26 03:30:58 +0300 • Fix missing deref in 32-bit MP flag manipulation
2023-04-26 03:30:19 +0300 • Fix 32-bit MaxLimit stack address masking
2023-04-26 03:29:48 +0300 • Set zone bkLim properly on 32-bit zone growth
2023-04-26 03:29:12 +0300 • Add 32-bit InitApplZone
2023-04-26 03:28:51 +0300 • Fix CompactMem return value for 32-bit zones
2023-04-26 03:27:23 +0300 • Add MemMgrToggle32BitMode
2023-04-26 03:26:05 +0300 • Conditionally enable 32-bit VM at initialization
2023-04-26 03:24:36 +0300 • Fix VM page handler size for 32-bit video driver
2023-04-26 03:23:26 +0300 • Add 32-bit fake ROM resources
2023-04-26 03:21:39 +0300 • Update MakeROMResources tool
2023-04-25 23:17:31 +0300 • Separate 24- & 32-bit mem mgr code to own modules
2023-04-24 13:56:59 +0300 • Add 32-bit machine profile
2023-04-23 03:17:08 +0300 • Finalize MoveHHi second iteration implementation
2023-04-22 00:35:43 +0300 • Partial work on the REAL MoveHHi implementation
2023-04-20 00:21:30 +0300 • Fix 'itlb' 0 rez source and add some default icons
2023-04-19 16:42:05 +0300 • Implement PlotIconSuite in IconUtils (not tested!)
2023-04-19 16:00:03 +0300 • Set up 68k registers on exit from vCheckLoad
2023-04-19 01:11:06 +0300 • Fix RTE instruction exception frame decoding
2023-04-15 20:28:36 +0300 • Fix typo in fakeplus4mb_sys7 profile
2023-04-15 01:00:31 +0300 • Tweak command handling in SMHandleCommand
2023-04-15 00:58:32 +0300 • Support version 2 'snd ' resource playback in SM2
2023-04-15 00:57:05 +0300 • Add missing EnvBootStackSize to classic profiles
2023-04-14 14:45:11 +0300 • Fix invocation of ioCompletion for async FM calls
2023-04-13 22:16:23 +0300 • Allow DefltStack override & use 0x6000 in color QD
2023-04-13 01:09:56 +0300 • Fix byteswap bug in AECreateDesc
2023-04-13 01:07:31 +0300 • Make SetApplLimit behave like on MacOS 7.5.3
2023-04-10 10:46:14 +0300 • Implement AECreateList selector for AppleEvents
2023-04-10 02:22:11 +0300 • Dummy AEManagerInfo AppleEventDispatch selector
2023-04-10 02:05:51 +0300 • Add dummy IUTextOrder selector, for Galactica Demo
2023-04-10 01:36:44 +0300 • Fix subPin stretching blitter color overflow
2023-04-09 04:28:58 +0300 • Handle OpenWD invalid dirID error & remove assert
2023-04-05 19:42:36 +0300 • Fix minor InitZone & SetApplLimit comparison bugs
2023-04-05 02:01:19 +0300 • Fix passing local variables to IconUtils devloop
2023-04-05 00:41:02 +0300 • Implement hidden CacheFlush trap for ResEdit 2.1.1
2023-04-04 23:34:50 +0300 • Fix memory moved after deref bug in 'dcmp' invoke
2023-04-04 22:20:43 +0300 • Fix applying mask bitmap to region mask in colorQD
2023-04-03 00:26:12 +0300 • Fix color QD text optimization case for b&w ports
2023-04-03 00:24:20 +0300 • Add missing part of new SetCatInfo implementation
2023-04-02 21:44:44 +0300 • Add monochrome version of generic icon blitter
2023-04-02 17:40:40 +0300 • Fix the 1-bit to color port icon blit in IconUtils
2023-04-01 22:08:59 +0300 • Fix FindFolder, return right dirID from DirCreate
2023-04-01 22:05:38 +0300 • Implement _SetCatInfo & improve _SetFileInfo
2023-03-30 00:31:52 +0300 • Return the newly created ioDirID from DirCreate
2023-03-30 00:30:11 +0300 • Fix return from NativeFS driver Prime routine
2023-03-28 00:22:16 +0300 • Implement FCMPD selector for SANE
2023-03-26 01:00:39 +0200 • Commit the new improved INIT loading mechanism
2023-03-26 00:58:36 +0200 • Simulate the InitApplZone wrap patch in SetAppBase
2023-03-23 23:29:31 +0200 • Fix leaking mask region handles in icon blitter
2023-03-23 23:20:08 +0200 • Implement low-color icon blitter
2023-03-23 00:28:07 +0200 • Fix alignment code in Icon Utilities
2023-03-23 00:07:12 +0200 • Fix rgnBBox width calculation in BitmapToRgn
2023-03-22 23:49:42 +0200 • First parts of icon family drawing in IconUtils
2023-03-22 14:29:49 +0200 • Refactor IconUtils colorization code to own module
2023-03-19 11:07:09 +0200 • Implement CheckColorTolerance for PaletteDispatch
2023-03-07 00:38:33 +0200 • Add proto Rez scripts for building the System file
2023-03-04 22:03:00 +0200 • Initialize Icon Utilities global data
2023-03-02 00:17:08 +0200 • Add missing export of Get1IndResource to headers
2023-03-02 00:16:41 +0200 • Add dummy stub for TempMaxMem OSDispatch selector
2023-03-01 23:06:44 +0200 • Fix INIT resource load bug (use Get1IndResource)
2023-02-27 21:11:47 +0200 • Lock boot thread to prevent unexpected interrupts
2023-02-27 21:07:32 +0200 • Add dummy SReadPRAMRec selector to Slot Manager
2023-02-26 13:46:32 +0200 • Implement dummy SReadWord for Slot Manager
2023-02-26 13:41:28 +0200 • Implement PMgrVersion selector for PaletteDispatch
2023-02-26 13:35:33 +0200 • Add dummy SNextTypeSRsrc selector for slot manager
2023-02-26 12:59:31 +0200 • Don't crash on failed OpenResFile ini INIT loading
2023-02-26 12:35:48 +0200 • Implement DisposeIconSuite for IconUtils
2023-02-26 12:15:36 +0200 • Fix byteswap bug in InitRsrcZone sysmap overrides
2023-02-26 00:34:44 +0200 • Add color video DRVR cscGetDefaultMode status call
2023-02-25 01:46:58 +0200 • Proper SetDepth functionality + required DRVR code
2023-02-24 23:04:47 +0200 • Fix fRelAtEnd handling bug in block allocator
2023-02-24 14:58:27 +0200 • Fix Fix2X/Frac2X stack issue, and add X2Fix/X2Frac
2023-02-24 02:38:47 +0200 • Implement Fix2X and Frac2X traps

5 year anniversary! And happy new year 2023

It feels crazy to think that today it’s been a whopping 5 years since the project got rebooted to its current iteration! Sorry again for slow progress between late summer and the Christmas holidays, a lot of things going on so we have had to juggle between different things and try to prioritise them. But past couple months have been again quite productive, and we have some nice updates to share:

File system improvements

One important feature that was added to NativeFS has been ability to create directories using DirCreate, something that not only installer applications, but also some apps generally depend on. It’s still not perfect (for example extracting the THINK Pascal installer archives made with SmallerInstaller causes the directories to get a bit haywire), but basic use cases such as creating Desktop & Trash folders seems to work.

Also, some groundwork has been laid to support deletion of files, as the AVL tree routines for node deletion were added – but actual deletion of file system items is still a work-in-progress task, which needs to be done carefully and is not to be rushed considering errors and bugs in this code might cause a bit headache to the end-users.

And also, when doing test runs on some Installer VISE installers, we found out that the NativeFS DRVR’s Control handler had used incorrect csCodes for the logical/physical drive icons (we were using 0x16 and 0x17, while correct ones were 0x15 and 0x16), this tiny mistake caused the whole installer to crash…oops! Another quite important bug fix was adding missing IODone call to the NativeFS DRVR’s Status handler, as that caused basically the entire Device Manager to hang…

List Manager multi-select

Not really a tough feature to implement, but one that has been a TODO for long time, list manager multi-selection has been finally implemented. A very good test case for this has been ResEdit, as it supports multi-selection both in the 2-dimensional icon grid, and in the 1-dimensional list view

List multi-select in action in ResEdit

SeedCFill & CalcCMask

Also as part of filling some missing traps, SeedCFill and CalcCMask were implemented. Like the aforementioned list multi-selection, ResEdit again was a wonderful test case for this, as the color editor PACK 1 in it uses these for the color flood-fill tool:

SeedCFill & CalcCMask in ResEdit’s PACK 1 color pixmap editor

Technically, the SeedCFill and CalcCMask actually call SeedFill and CalcMask, and to do that, they first map the color pixmap passed to the routine to a 1-bit image by using a custom color search proc to a temporary bitmap, which replaces matching colors with 0 and non-matching with 1 (i.e. doing floodfill on certain color gets flooded only to exactly matching pixels, while being bound by any other colors)

Application zone teardown updates & fixes

A bunch of fixes and missing features were added to the InitApplZone & SetApplBase, which makes doing transfer/shell launch to other apps way more reliable:

  • Font caches are flushed in SetApplBase and InitApplZone. Sometimes recently used font might be left cached in the application zone, and doing Launch/Chain to new app might accidentally use the cached (but not obliterated from memory) font, causing random crashes.
  • All color grafports, palettes, and VBL tasks located in application zone are disposed/closed

These are quite important fixes, as the aim is to provide soon the much-promised “generic” MACE runtime, which would contain an application shell (i.e. Finder replacement) to reliably run applications from

Communications Toolbox foundation

Weirdly, the Comm Toolbox has a bunch of very non-related routines included, which some applications seem to depend on. The first one we encountered was some Installer VISE installers using the CountDITL selector to get number of items in dialog item list, which the designers of the toolbox interestingly put as part of the Communications Toolbox. Also, the dispatcher mechanism they use is a very non-standard one (they basically pass parameter block pointer in A0 register, which contains the actual arguments of the routine – which might vary in size and number depending on the API call – and expecting result in D0 register). Although there’s just this one call implemented, the foundation for Comm Toolbox was done so that other routines can be added as needed later.

SoftFPU support

Even though Pekka is working hard on the 6888x FPU support, we did interesting experiment to see how well the SoftFPU control panel would work on MACE. Basically, that utility hooks as the F-line exception handler, using SANE calls to the actual math, and passing those results as emulated FPU instruction results. So, emulation inside emulation, kind of. Getting this done was actually quite easy, as the SANE emulation already covers so many calls, so we just had to hook up the F-line exceptions, and implement two missing SANE FP68K selectors (FNEXTX and alternate FX2X), and we were able to run a test app written in THINK Pascal with native 68881/68882 code generation with correct results:

SoftFPU running on MACE

In the above test application, the Compile Options dialog shows that 68881/68882 codegen is active, the code contains math for 9 / 2, and the Text window shows the result of 4.5 (in scientific formatting, as the Dec2Str routine still has some unfinished features)

Some updates to get Civilization 2 to work…almost

One cool game we also have been wanting to play for a long time is legendary Civilization 2, and we took a small steps in getting closer to being able to play that game someday soon:

  • Time Manager’s “hidden” microseconds trap (A093). This one was a bit hard to find documentation for, but we were able to produce close-enough results to keep Civilization 2 happy, which uses it for some reason. Basically the call returns 64-bit microseconds counter, with low 32 bits in D0, and high 32 bits in A0 register.
  • Added DriverGestalt (43) status call to NativeFS, and dgDeviceType (‘devt’) to it, which Civilization 2 seems to use to detect the media type of volume it was launched from (to see if it was started from the CD-ROM or Hard Disk)
  • CopyPalette trap handler (only partial implementation, but seems to be enough for Civ2 startup)
  • Added some more fake process manager data to GetProcessInformation results, in this case basically faked the processAppSpec by using HGetVol to get active directory, and CurApName from low mem…really dirty, but luckily enough again for Civ2. When process manager is someday added, this hack will be replaced by a proper implementation

With these done, we did get the game to progress quite far already:

There are still some big issues in the game, such as missing for some reason the entire backdrop images from the start-up menus, fonts looking ugly because truetype is not implemented (bitmap fonts have the pixelation on non-exact sizes), and color picture recording has still missing features causing city screens to crash.

Newer Technology GURU: “GUide to Ram Upgrades”

One other nice application that we were also experimenting is NewerTech’s GURU, which not only at the time was nice tool for checking out what RAM/VRAM upgrade options you had for Macs, but also doubles as nice mini-encyclopdia of various Macs, clones – and even printers – with their specs and nice color icons included.

GURU running on MACE

To get GURU running, there were a couple things needed:

  • We had again to temporarily tweak the GetProcessInformation’s processSignature (which sadly also WarCraft 2 uses, so both this app and that game need a proper implementation for this
  • Interestingly, the tiny and very harmless-looking popup menu triangles (seen in the screenshot on right-hand side) were actually 16-bit RLE-compressed pixmap images, so we had to implement both the 16-bit pixel translator, and the RLE decompressor in the Color QD Picture bits opcode handler
  • Also, the About Box in GURU used TESetText for styled textfield, which was previously a TODO, so that had to be implemented (it basically just replaces existing styles with a single style run)

MacWrite (finally) works now!

We also took some time to dig into other long-time known issues, one of which the MacWrite crashing on newline issue. Interestingly, two separate bugs did surface:

  • The biggest issue was that doing post/pre-increment of registers in middle of execution was not handled properly, in MacWrite’s case the offending instruction was ADDA.W (A0)+,A0, where value from memory pointed was read, A0 was supposed to be incremented by the word size (2 bytes), and the result added to A0 register. The bug caused the increment to get missed before adding the value to A0, causing it to be 2 bytes too low. This caused a bunch of havok in MacWrite, as the app used its own data structures to keep style data for rows, and this made – among memory corruption – the font size to go to a whopping 255 pixels when adding a new line on keyboard
  • The “justify” text alignment was one of rare cases where spExtra of GrafPorts was used to do sub-pixel (fixed-point) spacing of text, so we didn’t notice before Font Manager was missing a byteswap in handling of spExtra, which caused the cached spExtra to get totally crazy values
  • A rare case of resource map not being initialized properly surfaced on document saving, which was fixed
  • And also, document saving in MacWrite seems to depend on IUSetIntl trap (to apparently write localization data to the document), that trap had to be implemented

With these fixes, MacWrite finally works:

MacWrite works now!

Strategic Conquest

Although most of the features we had tested in Strategic Conquest were working, the map drawing had glitches: polygon lines were missing. We did some investigation about this, and found out that MapPoly trap only mapped the polygon points, but totally forgot to do the mapping for polyBBox. This in turn caused the polygon drawing to assume points were out of range, and fail to render anything in most of cases. With this fixed, the map seems to work fine now (at least in the B&W version):

Strategic Conquest MapPoly works now!

Arkanoid has sound!!!

One issue that was also mysterious for long time was why Arkanoid had no audio, while (almost) every single other black & white game/application had sound. After some researching, we found out that being super smart (and bizarre), instead of the standard VLB queue item (like 99.9% of games), or the not-so-common Lvl1DTVIACA1 interrupt handler (which Fokker Triplane does), Arkanoid actually hooks directly to the AutoInt1 vector on the 68K exception vector list, which normally would be handled by the Mac OS to invoke the VBL interrupts. After adding a level of indirection to the AutoInt1 vector (and adding possibility to later add other interrupt handlers to this level), Arkanoid sounds works perfectly! Sadly we did not have time to get a nice video capture of this for this update 😦

THINK Pascal zone check fixed

Another long-time issue that had been bothering us was that THINK Pascal kept saying in debug mode all the time that all zones were damaged, so we finally took time to dig into the THINK Pascal code and look for their zone check code and see what it was doing. Luckily, the only part that was failing was the trailer check, which checked that the bkLim block was supposed to be always 12 bytes in 24-bit mode, was getting triggered because when GrowZone was adjusting the zone trailer, it accidentally wrote 0 (zero) as trailer size, instead of the expected 12 (ironically InitZone did set it up properly). Although this bug had no functional effects to anything else but the zone check, the THINK Pascal was way more happier now, and looks like the LightsBug debugger is working perfectly, zone browser now included!

LightsBug working nicely after zone checks pass

Other bug fixes

There were a couple bugs/missing features that were fixed, with varying effects:

  • Fixed mask overflow in 32-bit pixel data stretching blitter, and implemented TODOs for some 32-bit pixel data colorization variables – These caused black buttons in some F/A Hornet 2.0 dialogs
  • ScrollRect passed wrong offsetPt to ShieldCursor – this caused some cursor artifacts (this bug did not manifest itself until after the actual software cursor code was added recently)
  • The WDEF 0 (standard window defproc) did not offset the grow box drawing correctly when a window grafport was offset to a non-zero origin (like in PhotoShop) – this caused the bottom-right growbox to get drawn in wrong position on the desktop)
  • 1-bit cursor data saving was missing from SetCCursor – This caused the cursor update to not get triggered if doing InitCursor or SetCursor after doing SetCCursor
  • Fixed issue in RestoreBits, where the menu bar was invalidated in RestoreBits even though it was restored, which in turn caused recursive call to DrawMenuBar when had a menu highlighted (the kMBDFMessageHilite message in MBDF code called RestoreBits which in turn did InvalMenuBar call, which caused the DrawMenuBar to get triggered from the second HiliteMenu call inside the DrawMenuBar) – Fixes the issue of MenuBarPattern code getting stuck in infinite recursion in Civilization, as it tried to double-patch itself from the recursed DrawMenuBar call
  • Added missing call to SystemEvent in GetNextEvent, which caused some events, such as key press events, to not get passed properly to Desk Accessories – Fixes the issue of Key Caps DA not receiving text input
  • Allow BlockMove to receive negative lengths. After researching how the List Manager in some 68k Mac OS versions handle the case of having zero rows but non-zero columns, it seems that they do pass negative lengths (maybe on purpose) to BlockMove with no side effects, and BlockMove ignores those – Fixes the unncessary negative length assertion in ResEdit with empty resource files
  • vRefNum case was missing for GetWDInfo calls in NativeFS, which caused ResEdit to not be able to open files from root directory of a volume
  • Do proper setup of stack pointer on application launch to BufPtr, because this was missing (and SP was left in boot-time default), it cut amount of available memory to apps down to 75% of total RAM! This also surfaced another bug that the startup-time boot grafport (used to draw any stuff during INIT loading etc) was not closed, so any code assuming that all PortList entries were valid were randomly crashing
  • Added style support for TEDelete, so using backspace key in SimpleText works now

What next?

It’s always hard to estimate what will be done and when, but there are still some key goals we’re aiming in the near future:

  • To get the public binaries finally updated after we have time to figure out not only a nice, cheap and practical CDN or other way update the files
  • When electricity prices go down (which got crazy during winter, so had to turn off most of extra computer equipment), work on automating the builds for different platforms, instead of manually building everything (even though CMake does a lot of the hard lifting)
  • Get Sound Manager 3.x to work, so we can start putting out the color version too
  • Try to make sure ReserveMem & NewHandle combos work as expected, right now this is causing THINK Pascal to run out of memory – this is something we want to make sure works, before we move to:
  • 32-bit memory manager. Something that’s needed not just to get more than 8 megabytes of accessible memory, but also to get some picky games (such as Doom) to run, AND to allow:
  • Direct memory access support, for avoiding the overhead of virtual memory interface, potentially speeding up emulation quite a lot. This requires 32-bit memory model to work efficiently.
  • Update build system to include creation of the System file from resource scripts – it’s still being handled as binary file that’s edited using native resource tools, which is not only cumbersome, but also makes it difficult to have variants of the System file for different system types – when we at some point do add process manager support, the way for example desk accessories and fonts are handled needs adjustment, as in process manager-aware (System 7 and later) those are external files instead of ones in System like in System 6 and earlier
  • Work on the so-many missing features (which do also cause known bad behaviour or crashes)
  • Debug and research the problems and crashes which we know about, but haven’t yet figured out what is causing them (such as F/A Hornet and F117A drawing issues, ball missing bug in Loony Labyrinth, timing issues in Monkey Island and Prince of Persia 2…)
  • Prepare a Discord server for public access
  • Many, many, ….many other things

We will as always update our progress on this blog, hopefully a bit more frequently. Your support and encouragement has been very inspiring, and we’re trying as soon as possible to share more and more of the stuff we’ve been making with you.

Full list of changes since last post

2023-02-15 14:56:38 +0200 • Fix 24-bit zone trailer & add bkLim validation
2023-02-15 03:45:35 +0200 • Add dummy ADBOp trap (for SoftWindows)
2023-02-14 21:47:21 +0200 • Expose & use low-level AutoInt1 vector for VBLs
2023-02-13 23:34:21 +0200 • Add LMKbdType and use it for Gestalt & SysEnvirons
2023-02-13 00:27:16 +0200 • Also adjust polyBBox in MapPoly
2023-02-12 17:40:45 +0200 • Style support for TEDelete
2023-02-12 17:39:11 +0200 • Disable font width table logging in debug mode
2023-02-08 23:48:12 +0200 • Merge branch 'master' of
2023-02-08 23:47:43 +0200 • Remember to close the startup-time GrafPort
2023-02-08 06:12:54 +0200 • Merge branch 'master' of
2023-02-08 06:12:50 +0200 • Handle TEMeasure start in middle of style run
2023-02-08 06:12:02 +0200 • Don't return random value if FindFolder fails
2023-02-08 06:11:09 +0200 • Some cleanup in HighLevelFSDispatch
2023-02-08 06:10:30 +0200 • Don't ignore opIFore and opIBack
2023-02-06 02:47:11 +0200 • Reset stack pointer A7 in non-multitasking Launch
2023-02-06 00:48:02 +0200 • Handle vRefNum case in GetWDInfo
2023-02-05 23:15:40 +0200 • Implement IUSetIntl selector for IntlUtils Pack6
2023-02-05 22:29:59 +0200 • Fix rare case of res map handle not initialized
2023-02-05 22:26:45 +0200 • Fix ADDA.W/L postincrement same as destination bug
2023-01-30 12:28:55 +0200 • Fix byteswap bug on spExtra handling in FMSwapFont
2023-01-29 01:26:40 +0200 • Add dummy stub for HMRemoveBalloon (for Excel 3.0)
2023-01-28 08:35:17 +0200 • Implement TESetText styled textfield case
2023-01-28 00:35:35 +0200 • Some process manager placeholder hacks for GURU2.6
2023-01-28 00:34:03 +0200 • Use 16-bit RLE decoder for PICT packtype 3
2023-01-28 00:33:37 +0200 • Add 16-bit RLE decompressor for QD Pictures
2023-01-28 00:32:33 +0200 • Add 16bit direct to indexed color pixel translator
2023-01-26 21:06:19 +0200 • Merge branch 'master' of
2023-01-26 21:06:17 +0200 • Fix 68k Bxx opcode with 32-bit extension
2023-01-26 01:07:16 +0200 • Fix return value of Microseconds trap
2023-01-25 14:45:34 +0200 • Hack face processAppSpec in GetProcessInformation
2023-01-25 13:52:55 +0200 • Partial CopyPalette (0xAAA1) trap implementation
2023-01-25 03:32:02 +0200 • Add dummy Lower/Strip/Upper/StripUpperText handler
2023-01-25 03:01:56 +0200 • Handle 'devt' driver gestalt in NativeFS
2023-01-25 03:00:19 +0200 • Return controlErr on non-support NFS Control codes
2023-01-25 02:41:18 +0200 • Add DriverGestaltParam & dummy handler in NativeFS
2023-01-25 02:39:21 +0200 • Fix broken return from NativeFS Status handler
2023-01-25 02:38:02 +0200 • Implement Microseconds trap (A093) for Time Mgr
2023-01-23 03:10:20 +0200 • Expose some rsc manager stuff for SetResourceSize
2023-01-23 03:09:21 +0200 • Merge branch 'master' of
2023-01-23 03:08:20 +0200 • Log also 68k program counter in trap debug msgs
2023-01-23 03:07:21 +0200 • Update TimeManager.c
2023-01-23 03:06:42 +0200 • Work on SetResourceSize
2023-01-17 22:25:49 +0200 • F-line handler for M68kHelper glue module
2023-01-17 22:04:05 +0200 • Implement FNEXTX and alternative FX2X selector $10
2023-01-17 22:01:38 +0200 • Fix f-line dispatcher installation in 68k cpu code
2023-01-17 00:27:06 +0200 • Add CountDITL, and a VERY bizarre A08B dispatcher
2023-01-16 14:06:31 +0200 • Fix invalid icon csCode in NFS + add assert checks
2023-01-16 13:54:23 +0200 • Fix byteswap bug
2023-01-16 13:41:18 +0200 • Remove VBL tasks in app zone in InitApplZone
2023-01-16 13:34:27 +0200 • Dispose palettes in app zone in InitApplZone
2023-01-16 13:22:09 +0200 • Close all open grafports in InitApplZone
2023-01-16 13:21:38 +0200 • Flush font caches in InitApplZone
2023-01-16 13:02:15 +0200 • Flush font caches in SetApplBase
2023-01-16 13:01:45 +0200 • Add SLCheckApplZoneAddress, for app zone cleanup
2023-01-16 13:01:04 +0200 • Detect use of ResErrProc in resource manager
2023-01-16 13:00:29 +0200 • Add (partial) font cache flushing in Font Dispatch
2023-01-16 12:59:34 +0200 • Implement FCMPL selector in SANE FP68K trap
2023-01-09 23:32:54 +0200 • Implement QDExtensions's GDeviceChanged selector
2023-01-09 23:22:39 +0200 • Implement QDExtensions's OffscreenVersion selector
2023-01-08 23:17:28 +0200 • Added AVL Tree node deletion routines
2023-01-08 13:49:24 +0200 • Implement SeedCFill + CalcCMask QD traps
2023-01-06 16:57:46 +0200 • Fix handling of zero & negative BlockMove lengths
2023-01-06 11:24:27 +0200 • Check VCB flags in SetFileInfo/SetCatInfo
2023-01-01 17:46:21 +0200 • List Mgr's LClick multiselect (shift+cmd) support
2022-12-29 11:06:57 +0200 • Implement RsrcMapEntry trap handler
2022-12-20 00:02:35 +0200 • Don't return mouseMovedMessage unless app4 bit set
2022-12-18 14:05:14 +0200 • Implement SysEdit trap handler
2022-12-18 14:04:49 +0200 • Fix issue of GetNextEvent not calling SystemEvent
2022-12-17 00:25:55 +0200 • Fix unneeded invalidate of menu bar in restorebits
2022-12-14 21:29:16 +0200 • Save 1-bit cursor data in SetCCursor
2022-12-14 16:21:12 +0200 • Fix wDrawGIcon incorrect offset in nonzero origin
2022-12-13 21:49:42 +0200 • Proper fix for horizontal stretch pixel masking
2022-08-24 02:02:08 +0300 • Fix ShieldCursor offset in ScrollRect
2022-08-22 23:21:44 +0300 • Improve relative mouse mode host cursor behaviour
2022-08-22 22:11:12 +0300 • Merge branch 'master' of
2022-08-22 22:11:02 +0300 • Add dummy MIDI driver module (for MIDI Manager)
2022-08-22 22:09:16 +0300 • Fixes to 32-bit direct-to-8bit color QD blitter
2022-08-22 22:08:03 +0300 • Fix mask overflow in 32-bit horizontal CQD stretch
2022-08-21 13:30:13 +0300 • Fix sound manager header
2022-08-05 03:58:52 +0300 • Add empty dummy MIDIGetClients selector
2022-08-05 02:58:50 +0300 • Refactor filesystem AVL tree code & add validation
2022-08-05 02:57:45 +0300 • Cleanup SoundDispatch & add SndDispVersion handler
2022-08-01 17:28:51 +0300 • Merge branch 'master' of
2022-08-01 17:28:46 +0300 • Implement DirCreate file manager trap
2022-07-31 23:09:20 +0300 • Re-export traps & selectors for status update

Summer ’22 update

In attempt to increase frequency of status updates on the project after slow progress during the past year, here’s some information about what we’ve been working hard during the summer vacation.

Styled TextEdit updates

One of the most overlooked – but still very important – features has been the Styled TextEdit support. We already had started working on the foundations almost two years ago, and had last year got the drawing to work pretty well (mostly focusing on Marathon’s “computer terminal” screens) – but actual editing features of the styled text have been largely missing. Luckily SimpleText, with its fully-featured styled text editing features, provides a bunch of test cases for a number of them. Below is screenshot of some text styling at work:

Basic styled text editing in SimpleText

Right now, styled text can be finally entered (using various style parameters such as face, font, size), and SimpleText can also open various text documents with styling information. Below is one example, the READ ME file of Prince of Destruction:

Opening a styled text document in SimpleText

But a lot of work needs to be still done, as major features are still unfinished (such as hit-testing of styled text records, which is needed for both mouse click, arrow key and selection support).

“AppleDoubler” tool

Motivation to work on the “AppleDoubler” tool got boost by a question asked in the June on emaculation about our file system choices. We had planned for a long time to make tool for converting native Mac files to the ADF format, but hadn’t taken time to work on that until now. It didn’t actually take more than a couple hours to write (plus some random time to do some tweaks later), but as nice effect we are able now to convert applications for testing blazingly quickly (compared to the manual conversion process earlier). This has led to discovery of a number of bugs which were fixed, and missing special cases of existing features that have been tweaked.

The AppleDoubler tool will be available as soon as we sort out our binary distributions to work a bit better (until now, files have been hosted here on the WP blog, but due to a bunch of issues with executables, and the time-consuming progress of updating downloads page, we will look into more automated alternate solutions, to allow more frequent updates, and also more downloads to be available.)

Software cursor

One longtime “to-do” task has been proper software cursor implementation, which has been delayed mostly because SDL’s cursor API has handled the monochrome cursors quite well for most of the use cases. However, there have been three downsides of this approach:

  1. The “inverted” cursors (such as the I-beam, and Lemming’s cursors) don’t show up properly, as most modern host systems don’t support inversions in cursor graphics. Especially in lemmings this has been tricky in the monochrome mode, as the cursor would appear black on black background, making the game really hard to play
  2. The native cursors don’t show up when doing screenshots of windows, or when capturing in OBS using window capture. This has been mostly prominent on Twitch streams where mouse has been invisible
  3. Color cursor support has been unimplemented, as for proper ‘crsr’ display the mapping of cursor color table needs to be done

The final push for software cursor implementation came when we tried running Super Studio Session editor, which replaces a number of default cursor vectors with its own implementation (which it uses to align the “note” cursor on music sheet at certain spots). We saw that the cursor that application implemented all by itself worked mostly really well, but because of some ShieldCursor bugs, it was leaving trails at certain places. Below are screenshots of Super Studio Session (ignore the “THINK Pascal” window title, we don’t yet have proper general-purpose shell/desktop application yet, so we used the very practical “Transfer” feature of THINK Pascal to launch any application from the file system through Standard File dialog, without needing to do any extra work 😀 )

It took a couple days of work to get the software cursor to work (the work was sped up a lot by a number abstractions we had done earlier, related to VBL task execution etc), and adding color cursor support was not that tough as ‘crsr’ and ‘ppat’ resources share a common heritage, and thus their color table and depth expansion code could be shared. Below are some screenshots of Civilization, showing the color mouse cursor in action:

SoftWindows

As a curiosity, in progress of trying out various applications, we noticed that SoftWindows 1.x (the last 68k-compatible version of that application) seems to work pretty well. As it does have quite high memory requirements (considering the currently implemented 24-bit memory manager by default has only 8 megabytes of RAM), we did have to make a temporary hack to boost the RAM limit in the test configuration to 12 megabytes (leaving space for only 3 slots in the emulated slot address space – while the default configuration allows up to 7). This allowed us to actually boot into Windows 3.1 and run a number of games/apps on it (biggest limiting factor for what worked was that this version SoftWindows only emulates a 286, thus allowing only Standard mode in Windows 3, instead of the Enhanced mode required by a lot of applications). Below are some screenshots of what we tried out:

MIDI Manager research

As we knew that certain Sierra games do advertise MT-32 compatibility, we did some quick snooping around, and learned that at least Space Quest 1 does use Apple’s little-known MIDI Manager to handle the hardware MIDI playback (unlike Thexder, which appears to have its own serial driver for MIDI, choosing to use the serial port directly). This led to some curiosity about the MIDI Manager implementation, for which there is sadly very little documentation – an article about programming it on the always valuable MacTech archive and the universal headers. A couple articles from mid 90’s point to ARPA as source to buy the MIDI documentation and SDK from, which sadly is no longer available.

The work on MIDI Manager support is still ongoing, but we feel it might be relatively easy to write a layer that emulates MIDI Manager’s patching features, and wrap the MIDI driver as a abstract device that could pass the MIDI packets to host OS’ native MIDI interface (in Mac OS X case, the CoreMIDI). All MIDI Manager calls go anyway through the same SoundDispatch trap like a number of Sound Manager calls, so tapping to that interface is really easy. (Another question, though, is how well timing will work, and whether default MIDI synthesizer (or the SC-55 midi hardware) will handle Space Quest’s MIDI output that expects an MT-32…)

Various other updates

As mentioned before, there have been a ton of fixes and updates, but here is mention of a couple ones that might be of interest:

Popup Control CDEF (and TextEdit) fixes: There were a number of bugs in both the Popup Control drawing (and TextEdit setup) code, which manifested quite visually in the HyperCard script editor. Below are screenshots of “before” and “after” to show what kind of effects the fixes had:

Menu Bar Pattern Control Panel: As another curiosity, we tried this one old Control Panel from early 90s, to see what would happen – and seems that whatever magic it uses to draw patterns behind menu bar, it seems to be 100% compatible:

Menu Bar Pattern Control Panel

FracSin/FracCos: The After Dark module called “Spotlight” (not to be confused with the OS X search tool) was the first case that needed FracSin/FracCos implementation to work, so we used it as a test case for those traps and got it working pretty well:

After Dark “Spotlight”

Palette fixes: There were a number of bugs & missing features in Palette Manager code (for example, SetEntries had bug that made it fail incorrectly with cProtectErr, which caused a number of issues around the place). Here is Lode Runner: The Legend Returns editor, which had weird color issues before the fix (ignore the palette debugger in bottom right):

Lode Runner: The Legend Returns level editor

BitmapToRegion: This trap was already before used by Escape Velocity, but as that game needs a couple other improvements to reach playable state, Snood worked out pretty well as a use case for this (as it uses it for practically all of its sprites to convert their masks to regions for drawing). After a couple hours, the game seems to be quite happy with the routine (Snood 1.x pictured):

Snood using sprites with masks defined by BitmapToRegion

Default MDEF ‘cicn’ support: While trying out Snood, we noticed that Snood 2 was the first use case of color icons (‘cicn’s) in menu items. As the MDEF already had almost-working handling for this case, we added some temporary code to the Icon Utilities module and got nice color icons in menus now:

Color icons in Snood 2.x Players menu

More blitter fixes/improvements: There were numerous fixes to basic blitters too, which affected test cases such as 3 in Three, “Spotlight” (when brightness was other than 0%), Shanghai II mahjong, etc). Here’s some screenshots of what we got working with the improvements:

Next step

We will continue working on the missing features as always, trying to reach the goal of a generic runtime release as soon as possible. We also will try to find solution for the binary file distribution in near future, so anybody interested trying the new features out could do that as soon as possible (especially considering the last released binaries are already getting quite old). We will keep you updated on this blog on our progress as always.

Full list of changes since last post

2022-07-31 00:45:08 +0300 • Implement colorizing srcOr rectangle blitter
2022-07-30 23:49:00 +0300 • Implement colorizing srcBic rectangle blitter
2022-07-30 13:34:42 +0300 • Fix missing handle derefence bug
2022-07-30 13:47:58 +0300 • Implement SaveEntries trap for Palette Manager
2022-07-30 04:09:17 +0300 • Disable potentially invalid check in Entry2Index
2022-07-30 03:08:06 +0300 • Stretching subPin blitter + improve call interface
2022-07-30 03:07:01 +0300 • Reinforce zone checks for handle operations
2022-07-30 01:27:53 +0300 • Fix AppendMenu/InsertMenuitem legnth > 127 cases
2022-07-30 01:14:39 +0300 • Implement a rudimentary PlotCIconHandle (for MDEF)
2022-07-30 00:39:04 +0300 • Merge branch 'master' of
2022-07-30 00:38:58 +0300 • Proper implementation for BitmapToRegion QD trap
2022-07-26 23:16:20 +0300 • Add dummy MIDIManager (+ MIDISignIn & MIDIAddPort)
2022-07-26 20:35:26 +0300 • Merge branch 'master' of
2022-07-26 20:35:16 +0300 • Implement PaletteDispatch ResizePalette selector
2022-07-26 18:28:13 +0300 • Fix timer thread race condition issue
2022-07-26 15:53:28 +0300 • Implement color QD opDefHilite PICT opcode
2022-07-26 15:52:42 +0300 • Implement opPnLocHFrac PICT opcode
2022-07-26 15:52:06 +0300 • Fix edge case of shielding cursor in classic mode
2022-07-26 14:51:53 +0300 • Fix GetNew(C)Window autopositioning code
2022-07-26 14:07:53 +0300 • Fix TESetStyleScrap (StyleDataPtr -> TextStylePtr)
2022-07-26 05:35:47 +0300 • Version 9 compressed resource support (+fixes)
2022-07-26 03:05:37 +0300 • Add dummy ReplaceText selector stub for ScriptUtil
2022-07-26 00:46:57 +0300 • Add TESetStyleScrap (needs still some work)
2022-07-25 03:33:36 +0300 • Update line start for redraw when setting heights
2022-07-24 14:12:29 +0300 • Implement styled TESetSelect
2022-07-24 14:11:48 +0300 • Partial implementation of styled TEInsert
2022-07-24 06:08:06 +0300 • Merge branch 'master' of
2022-07-24 06:05:17 +0300 • Work on styled text (TEContinuousStyle selector)
2022-07-24 06:03:22 +0300 • Implement AdMin blend mode in color region blitter
2022-07-23 22:33:53 +0300 • Call vector #4 for unimplemented instructions
2022-07-23 02:07:22 +0300 • AppleDoubler: cleanup tool console output logging
2022-07-23 01:40:40 +0300 • AppleDoubler: add timestamps,buildscript & cleanup
2022-07-21 16:26:26 +0300 • Fix incorrect cProtectErr check in SetEntries
2022-07-21 15:32:55 +0300 • Implement FracSin and FracCos traps
2022-07-19 15:40:00 +0300 • Only mark arc dirty, if drawn on the screen port
2022-07-19 15:02:32 +0300 • Fix some compiler warnings (missing QD includes)
2022-07-19 15:00:12 +0300 • Use bullet (0xA5) as mark in popupUseWFont CDEF 63
2022-07-19 14:58:54 +0300 • Fix one-off error in MBDF hittest (crashed popups)
2022-07-19 06:45:32 +0300 • Fix saving of port state in TextEdit calls
2022-07-19 06:44:33 +0300 • Fix warnings in cursor module
2022-07-19 06:13:22 +0300 • Merge branch 'master' of
2022-07-19 06:12:48 +0300 • Add color QD hilite & fix font state in CDEF 63
2022-07-18 21:14:00 +0300 • Merge branch 'master' of
2022-07-18 21:13:52 +0300 • Cleanup: Refactor cursor code out of Mouse module
2022-07-18 04:12:22 +0300 • Support also function key (F1-F15) key codes
2022-07-17 07:38:02 +0300 • Fix incorrect ShieldCursor offsetPt in CopyBits
2022-07-17 07:27:27 +0300 • Implement DefaultSetCCursor (for 'crsr' support)
2022-07-17 07:26:49 +0300 • Fix MCallSetCCursor (called wrong vector)
2022-07-17 07:26:03 +0300 • Fix handle resizing bug in GetCCursor
2022-07-17 06:15:09 +0300 • Fix cursor left-side clipping
2022-07-17 02:36:52 +0300 • Color QD monochrome software cursor implemented
2022-07-11 23:12:03 +0300 • Use DoVBLTask do update cursor in color QD mode
2022-07-11 23:09:54 +0300 • Implement AddIconToSuite selector in IconDispatch
2022-07-11 21:56:20 +0300 • Implement NewIconSuite selector for IconDispatch
2022-07-11 19:40:19 +0300 • Implement AttackVBL trap
2022-07-11 14:27:11 +0300 • More color vs b&w QD cursor code specialization
2022-07-11 02:43:18 +0300 • Cleanup Cursor module code
2022-07-11 02:42:49 +0300 • Specialize Color QD case in ShieldCursor
2022-07-11 02:35:42 +0300 • Init cursor at startup
2022-07-10 14:29:23 +0300 • Redraw software cursor in SetCursor, if changed
2022-07-10 13:13:16 +0300 • Fix clamping of mouse in DefaultCrsrTask
2022-07-10 04:07:45 +0300 • Merge branch 'master' of
2022-07-10 04:07:02 +0300 • Implement software cursor for "classic" QD mode
2022-07-10 04:05:22 +0300 • Fix DefaultShieldCursor (it did not erase cursor)
2022-07-10 03:58:34 +0300 • Fix CrsrObscure handling in the DefaultCrsrTask
2022-07-10 03:57:44 +0300 • Only setup AllocCursor and SetCCursor in color QD
2022-07-10 03:56:18 +0300 • Increase screen buffer refresh rate temporarily
2022-07-10 03:55:34 +0300 • Fix mouse native window clamping (-1 from bounds)
2022-07-08 02:35:07 +0300 • Merge branch 'master' of
2022-07-08 02:35:00 +0300 • Vectorize SetCCursor (& fix some setup bugs)
2022-07-08 02:17:30 +0300 • Merge branch 'master' of
2022-07-07 20:25:22 +0300 • Fix ShieldCursor bugs
2022-07-05 23:44:59 +0300 • Fix Serial.h
2022-07-05 02:56:01 +0300 • Merge branch 'master' of
2022-07-05 02:55:56 +0300 • AppleDoubler: Fix OSX's weird swap of ':' and '/'
2022-07-04 16:50:27 +0300 • Fix LoadSeg 32K+ offset wraparound (use unsigned)
2022-07-04 16:29:48 +0300 • Merge branch 'master' of
2022-07-04 16:29:41 +0300 • Add dummy serial driver stub (AIn/AOut/Bin/BOut)
2022-07-04 15:04:51 +0300 • Fix UPP call signature of JShieldCursor
2022-07-04 04:28:09 +0300 • Merge branch 'master' of
2022-07-04 04:27:59 +0300 • AppleDoubler: Also encode folder names
2022-07-04 02:16:46 +0300 • Fix byteswap bug in font size check
2022-07-04 02:00:14 +0300 • Fix FOND style lookup: start at 1st match,not last
2022-07-04 01:56:59 +0300 • Add Oregon Trail (1.x) to test app configs
2022-07-03 14:05:54 +0300 • Implement QDDone selector for QDExtensions
2022-07-03 13:56:22 +0300 • Merge branch 'master' of
2022-07-03 13:56:16 +0300 • Add (no-op) LockRange & UnlockRange in FSDispatch
2022-07-03 04:29:30 +0300 • Add first version of AppleDoubler converter tool
2022-07-02 06:13:32 +0300 • Handle NFSGetDirInfo errors in NFSCreateFileHook
2022-07-02 06:12:36 +0300 • Implement DateToSeconds
2022-07-02 04:06:13 +0300 • Add SoftWindows test app to JSON configs
2022-07-02 04:05:42 +0300 • Implement GetGWorldDevice selector in QDExtensions
2022-06-18 02:05:16 +0300 • Add ZPC to test app config JSONs
2022-04-28 04:01:02 +0300 • Fix crash in TECallCharByte utility routine
2022-04-28 04:00:57 +0300 • Add missing header file from previous commit
2022-04-28 03:57:54 +0300 • Tweak naming of some private TE data structures
2022-04-28 01:18:54 +0300 • Fix GetCTable crash of locked 'clut' in 24bit mode
2022-04-23 22:04:03 +0300 • Implement styled TESetStyle
2022-04-23 21:42:07 +0300 • Work a bit on InitScripts (load smRoman 'itlb' 0)
2022-04-23 13:55:03 +0300 • Add Font2Script & implement FontScript+IntlScript
2022-04-18 11:28:33 +0300 • Temporary fail-safe in _Enqueue
2022-04-18 02:06:31 +0300 • Finish faster non-MeasureText path in NPixel2Char
2022-04-17 22:52:23 +0300 • Use NPixel2Char in TextEdit (FindLine etc)
2022-04-17 22:50:50 +0300 • First version of working NPixel2Char in Script Mgr
2022-04-16 21:08:10 +0300 • Implement SndControl (classic SM2)
2022-04-15 05:03:02 +0300 • Prep TEHitTestHook calls to work with NPixel2Char
2022-04-15 04:59:57 +0300 • Handle 0x2C (font) and 0x2E (glyph state) in PICTs
2022-04-13 16:20:10 +0300 • Fix Munger ptr2=nil & len2=0 case (search)
2022-04-13 02:41:36 +0300 • Allow bypass of ampCmd and timbreCmd in snth 4101

Sound Manager 2.x Support

It’s again been quite a bit of time since last update, as we’ve been busy on doing other stuff for the latter half of 2021, and the winter – but now in spring, we again had time to work on the emulator. During the past couple weeks, Toni spent time finishing the first round of Sound Manager 2 research, so we were able to move to implementation phase last week. And after first week of coding, we already have a handful of test applications with (mostly) working Sound Manager 2 support – although, as planned, it is at moment limited only to applications running in the “classic” emulation mode. Here’s a short video demonstration of the new audio capabilities:

Sound Manager 2.x tests on M.A.C.E.

In the video, the following test applications are shown:

  • Civilization, with fully working sound output (exclusively with bufferCmds through ‘snd ‘ resources).
  • Prince of Persia 1, also fully working (interestingly, even without Sound Manager, PoP1 was able to *mostly* output audio with Sound Driver, but looping sounds (door opening) caused hang in that mode because of the way it used the Device Manager routines. With Sound Manager, none of those issues are present and all seems work fine (again, using bufferCmd commands).
  • Bard’s Tale was a bit different test case for us, as it uses soundCmd combined with noteCmd/restCmd etc commands to play the music. But it also works now, apparently fully.
  • Railroad Tycoon has also fully working sound support, again using bufferCmd with ‘snd ‘ resources like Civilization 1. This game has interestingly its own sound queuing system, separate from Sound Manager command queues – which allows funny way of queueing multiple sounds if invoked rapidly after each other, which eventually get played in turn after each other. Also this behaviour seems to match fully how audio in the game works on real Macs.
  • Pararena 1.3 also has now working sounds
  • And Pipe Dream finally also got sound and music
  • Finally, Loom also has working sound & music, although the Mac Plus/Classic style behaviour of music does sound a bit “fishy”. We checked that the music does sound same way at least on minivmac, although it appears to have been meant to be played using 4-channel output, while the “classic” hardware is limited to only one channel at once. This game also uses soundCmd/noteCmd to adjust playback frequency of samples, like Bard’s Tale. Also, there is still at least one known race condition issue in playback, which appears to actually be identical to a deadlock that happens also in minivmac, if the game is run under that emulator on faster than 1x speed.

Also, there’s working button click sounds in Speedometer system info window, and we’re working on getting sound to work also in Bolo soon (it uses apparently older style selectors for SoundDispatch at least in one case, which we don’t handle yet, so we need to improve that next).

All of the features of Sound Manager 2 haven’t been implemented yet, as we’ve been adding them “on demand” as we’ve been trying out various test applications. Some of features not yet implemented include:

  • Compressed sound decompression/compression
  • At moment, only ‘snth’ 5 (sampledSynth) synthesizer is supported (the squareWaveSynth and waveTableSynth still need to be added)
  • Sound Manager command timing is supposed to the drift-free Extended Time Manager tasks, but they for now default to regular TMTask behaviour. This will cause songs played using noteCmd/restCmd/etc, that depend on command duration for timing, to drift off a bit (at least in Bard’s Tale and Loom)
  • And as mentioned before, only Sound Manager 2.x for “classic” mode was implemented, so the color mode does not yet have audio. But that will follow up later as Sound Manager 3.x compatibility after we finish research on it (we plan to implement Component Manager emulation as first step on way to SM3 compatibility, which both allows us to provide Sound Component capabilities, and also allows in future other APIs that depend on Components to be implemented – such as QuickTime and Internet Config)

Other fixes

There are also a number of other improvements, of which some are listed here:

  • MDEF 0 now supports scrolling in popup menus, which allows the Machine Record selection popup to be opened in Speedometer, when screen size is smaller than the menu
  • Fixed issue in “classic” QuickDraw PICT color translation mapping, which was causing black credits screen in Railroad Tycoon
  • GhostWindow low-memory global handling was added – this fixes most of the issues in SuperPaint 1
  • ScalePt/FixDiv had a couple bugs, which caused at least two separate issues in MacDraw (related to calculation of object coordinates on the document)
  • Color search proc support and a couple color picker package traps were added (for HSV conversion) were added to allow Solarian 2 to work
  • Rounded windows (WDEF 1) finally have the close box (and color support) – this allows for example the about screen in Glider 2 & 3 to be closed 🙂
  • Allocation of WDCBs through OpenWD now check for existing working directories, to not flood the WDCB table and run out of memory. This happened at least with certain applications using the “Mercutio” MDEF, which on each message did SysEnvirons call, which in turn opened a WD in the system folder
  • A bunch of other important fixes
  • And finally, as first step of getting FPU support, Pukka has started implementation of the 68881/2 emulation, so we will eventually be able to run applications requiring the math co-processor instructions (such as Specular Logomotion and Pixar Typestry)

Full list of changes since last post

2022-04-12 23:42:44 +0300 • Fix typo in Bolo JSON config                      
2022-04-12 23:29:35 +0300 • Fix signed/unsigned comparison in FMSeek          
2022-04-12 23:28:33 +0300 • Tweak test apps for sound tests + add BoloSounds  
2022-04-12 22:06:17 +0300 • Fix classic QD color-to-mono translation mapping  
2022-04-12 21:31:19 +0300 • Implement rateCmd in snth 4101 (classic SM2)      
2022-04-12 21:24:47 +0300 • Fix uninitialized SndChannelPtr in SndPlay        
2022-04-12 00:48:08 +0300 • Add scrolling support to popup menu case of MDEF 0
2022-04-11 17:00:05 +0300 • Fix disposal of channel if SndNewChannel fails    
2022-04-11 16:45:48 +0300 • Some PrimeTime prep for extended timer mgr support
2022-04-11 16:43:27 +0300 • Fix timer task deactivation in RmvTime            
2022-04-11 16:42:37 +0300 • Fix setting of channel idle state from quietCmd   
2022-04-11 16:41:42 +0300 • Swap new buffer in note/freqCmd if already playing
2022-04-11 14:55:02 +0300 • Fix duration passed to timer in waitCmd           
2022-04-11 14:53:59 +0300 • Setup synthesizer state correct in noteCmd/freqCmd
2022-04-11 14:52:36 +0300 • Fix bug in checking whether timer was active      
2022-04-11 00:34:59 +0300 • Implement emptyCmd in snth 4101 (classic SM2)     
2022-04-11 00:33:56 +0300 • Fix sample rate conversion bug in soundCmd        
2022-04-09 19:10:16 +0300 • Handle noteCmd/freqCmd in snth 4101 (classic SM2) 
2022-04-09 00:02:14 +0300 • Implement waitCmd (classic SM2)                   
2022-04-09 00:02:01 +0300 • Implement restCmd in snth 4101 (classic SM2)      
2022-04-08 23:37:15 +0300 • Handle soundCmd in snth 4101 (classic SM2)        
2022-04-08 20:23:59 +0300 • Fix SM2 locking (dispose channel during playback) 
2022-04-08 20:21:14 +0300 • Fix  end-of-buffer handling in snth 4101 VBL Task 
2022-04-08 20:19:38 +0300 • Set correct state in quietCmd handler in snth 4101
2022-04-08 20:18:56 +0300 • Clear busy flag correctly at end of snth VBL Task 
2022-04-08 13:01:33 +0300 • Fix size mismatch when setting channelIdle flag   
2022-04-08 12:47:08 +0300 • Implement flushCmd handling (classic SM2)         
2022-04-08 12:46:50 +0300 • Implement SndDoImmediate (classic SM2)            
2022-04-08 12:25:55 +0300 • Implement freeCmd in snth 4101 (classic SM2)      
2022-04-08 12:25:41 +0300 • Fix a couple byteswap bugs in channel flags       
2022-04-08 12:23:09 +0300 • Implement SndDisposeChannel (classic SM2)         
2022-04-08 04:18:00 +0300 • Implement callbackCmd (classic SM2)               
2022-04-08 04:12:18 +0300 • Handle quietCmd in snth 4101                      
2022-04-08 03:56:40 +0300 • Implement resumeCmd handling                      
2022-04-08 03:47:29 +0300 • Handle tickleCmd in snth 4101 (classic SM2)       
2022-04-08 03:36:14 +0300 • Implement basic snth 4101 buffering (classic SM2) 
2022-04-08 03:34:44 +0300 • Implement Timer1 & tickleCmd sending (classic SM2)
2022-04-07 03:49:16 +0300 • Handle bufferCmd in 'snth' 4101 (classic SM2)     
2022-04-07 03:47:59 +0300 • Handle high-level pauseCmd (SM2 classic variant)  
2022-04-07 02:08:33 +0300 • Implement command timer & dequeueing (classic SM2)
2022-04-06 20:25:16 +0300 • Implement queueing in SndDoCommand (SM2 variant)  
2022-04-06 19:21:39 +0300 • Handle initCmd in 'snth' 5 (SM2 "classic" variant)
2022-04-06 18:21:17 +0300 • Implement availableCmd and versionCmd in 'snth' 5 
2022-04-06 18:08:38 +0300 • Implement quietCmd handler                        
2022-04-06 17:58:52 +0300 • SndAddModifier mostly implemented (SM2.x variant) 
2022-04-06 02:17:47 +0300 • Implement SndPlay 'snd ' format 1 resource parsing
2022-04-06 01:33:48 +0300 • Fix typo in previous commit                       
2022-04-06 01:33:08 +0300 • Initialize Sound Manager (and fix byteswap bug)   
2022-04-06 01:17:33 +0300 • Use SndAddModifier in SndNewChannel               
2022-04-06 01:14:29 +0300 • Add SndAddModifier trap (dummy stub at moment)    
2022-04-06 01:13:07 +0300 • SndNewChannel proto implementation (SM2.x variant)
2022-04-06 01:11:00 +0300 • Add snth 0x1005 (mac plus variant of sampledSynth)
2022-04-06 01:10:33 +0300 • Update sound manager headers with new information 
2022-04-03 22:31:59 +0300 • fix constants                                     
2022-04-03 21:32:09 +0300 • base for fpu                                      
2022-03-23 00:27:09 +0200 • Reinforce IODone to handle weirdness of SimCity1.3
2022-03-20 05:02:17 +0200 • Add missing GhostWindow check to FrontWindow trap 
2022-03-19 03:47:11 +0200 • Fix ScalePt special case byteswap bug             
2022-03-19 00:31:53 +0200 • Better fix for FixDiv overflow case               
2022-03-19 00:29:30 +0200 • Set MemErr to noErr when MoreMasters succeeds     
2022-03-18 04:39:24 +0200 • Avoid weird C bug causing FixDiv fail in release  
2022-03-08 03:14:17 +0200 • Add missing music file to PipeDream test app      
2022-02-17 22:40:14 +0200 • Re-use existing WDCB when possible (not MF-aware) 
2022-02-17 15:24:34 +0200 • Allow skip of selector high byte in some selectors
2022-02-17 15:20:12 +0200 • Fix overflow in iteration of WDCB list            
2022-01-12 02:43:01 +0200 • Implement _DelSearch (0xAA4C) Color Manager Trap  
2022-01-11 04:02:15 +0200 • Implement FADDL selector for FP68K in SANE        
2022-01-11 04:01:28 +0200 • Implement HSV2RGB in Pack12 (color picker package)
2022-01-10 00:25:46 +0200 • Implement RGB2HSV in Pack12 (color picker package)
2022-01-09 21:08:25 +0200 • Add dummy SndChannelStatus to SoundDispatch       
2022-01-09 08:56:43 +0200 • Call searchProc in _Color2Index trap when needed  
2022-01-09 08:56:05 +0200 • Implement _AddSearch (0xAA3A) Color Manager Trap  
2021-12-01 15:15:21 +0200 • Add dummy GNEFilter for modal dialogs             
2021-12-01 15:14:06 +0200 • Support kSpecialCaseGNEFilterProc mixedmode calls 
2021-11-03 05:54:14 +0200 • Fix handling of MP lock flag in MMSetSize24       
2021-11-03 05:52:18 +0200 • Fix measuring memory purge range in memory manager
2021-10-29 13:09:10 +0300 • Add Uninvited to test app JSON configs            
2021-10-27 14:52:29 +0300 • Fix calculation of offset to font name in 'ictb'  
2021-10-27 14:33:29 +0300 • Fix opOrigin PICT opcode (disposed wrong region)  
2021-10-27 13:54:33 +0300 • Fix typo in the Hornet JSON test app config file  
2021-10-27 13:31:04 +0300 • Add F/A-18 Hornet 2.0.1 to test app configs       
2021-10-27 13:30:38 +0300 • Fix SysEnvirons, use 'proc' instead of 'cput'     
2021-10-27 13:29:04 +0300 • Handle special palettes with bit 14 set in flags  
2021-10-27 05:13:14 +0300 • Fix minor Palette Manager bugs                    
2021-10-27 04:18:39 +0300 • Add ADB Manager & dummy CountADBs/GetADBInfo traps
2021-10-27 03:57:20 +0300 • Video DRVR: Handle status codes & add linear gamma
2021-09-26 20:45:07 +0300 • Disable SDL minimize/close keys (3rd party lib!!!)
2021-09-26 20:40:59 +0300 • Temp fix for return address of TRAP # instructions
2021-09-26 20:38:25 +0300 • Fix 32-bit overflow in ASR.W instruction          
2021-09-26 20:37:53 +0300 • Fix RTE instruction                               
2021-08-22 13:10:43 +0300 • Fix pattern masking bug in arithmetic rect blitter
2021-08-17 23:32:14 +0300 • Add dummy SRsrcInfo selector for Slot Manager     
2021-08-17 03:47:44 +0300 • Fix artifacting of outline/shadow color QD text   
2021-08-16 17:42:58 +0300 • Fix some Memory Manager type conversion warnings  
2021-08-16 17:42:03 +0300 • Add srcOr/srcXor/srcBic colorQD region blit modes 
2021-08-16 14:35:33 +0300 • Add missing WDEF 1 changes from previous commit   
2021-08-16 14:35:06 +0300 • WDEF 1 (rounded window) color support & GoAway box
2021-08-16 14:34:13 +0300 • Fix array overflow in the minilauncher hack proto 
2021-08-12 22:06:06 +0300 • Fix memory leak in DialogManager (Get)New(C)Dialog
2021-08-12 22:03:05 +0300 • Fix memory leak in CloseWindow (call CloseCPort)  
2021-07-29 19:48:49 +0300 • Add 1-to-2 bit non-colorizing pixel translator    
2021-07-13 23:42:11 +0300 • Sanity check ioNamePtr in _GetVol trap            
2021-07-13 23:41:02 +0300 • Add Bards Tale test app JSON configs              
2021-07-13 18:21:41 +0300 • Add Macintalk test app JSON configs               
2021-07-07 00:12:25 +0300 • Bump up version number                            
2021-07-07 00:12:14 +0300 • Fix VBL interrupt crash from start race condition 
2021-07-06 21:42:48 +0300 • Fix changes that broke .Sound DRVR #3             
2021-07-06 00:05:22 +0300 • Install dummy DRVR 4 at startup                   
2021-07-05 23:06:35 +0300 • Tweak Space Quest 1 config JSON (pass copy checks)
2021-07-05 23:06:02 +0300 • Add missing DskErr lowmem from previous commit    
2021-07-05 23:05:48 +0300 • Add dummy .Sony driver, allows DRVR 4 Status calls

First status update of 2021

For the past half year progress has been a bit more slower than usually, mostly due to Toni being busy with the daily work, playing around on Twitch, and experimenting with his retro raycaster 3D engine prototype, while Pekka has been busy with work and private stuff. There has however been some bits of progress, which are summarized in this post:

“Classic” audio upsampling

Even though Sound Manager support is still under development (with relatively good progress), the audio support for “Classic” type audio (that is, the emulation of audio hardware of Mac 128K through Plus/SE/Classic series machines) has been improved a bit. Originally the audio buffer with 22255 Hz sample rate was passed directly to SDL2, which caused some problems as some systems were not able to handle that format very well. Even though it worked on Mac Pro, for example on M1 Macs it caused the audio in other applications to start cracking and breaking up. By allocating the SDL2 audio buffer in default native format (usually 44100hz), and upsampling the audio data in emulator, most of this problem was eliminated. However, in some cases, clicks are still present in the audio, mostly due to the way how original hardware handles square-wave and sampled sound as a mix of both unsigned and signed 8-bit samples (that is, square wave sound amplitude ranges from 0 to 255, while in same buffer, sampled sounds are in range -128 to 127, with different “silent” baseline level.

TextEdit fixes

There were two critical fixes in the TextEdit, one of which caused at least one of Marathon terminals to crash:

  • In styled text line height table handling code, the code that was used to zero newly added line heights (when adding new lines) was not working properly in the case number of lines was reduced (causing it to try to clear a negative number of lines, wrapping around to a crazy number)
  • TESetStyle was calling TESelView with an invalid pointer

With these fixes, this particular Marathon terminal is now working without crashes – and looks identical to the one on real Macs:

The previously crashed Marathon terminal that works now

Minor fixes to allow streaming of The Fool’s Errand

Most of code needed to support running The Fool’s Errand was already implemented long time ago, but one of the most important things, a way to display the prologue and finale was missing. The original game used a separate application for prologue, and also a dynamically generated file for viewing the finale after completing the game.

On real Macs they were opened using Finder, but we needed to have an easy-to-use way to open them when running the emulator from the single-click app bundle. For this purpose, we hacked very quickly a “MiniLauncher” tool, which allows not only selecting the launch application, but also passing a document in launch parameters – which is required to show the finale (as clicking “Show finale” on Macs actually launches “prologue – finale” application passing the “Show finale” as opened document to it).

Right now the Minilauncher is very primitive and a quick hack to support this one single game, but we plan to improve it later to a more reusable launch tool, probably similar to Apple’s old MiniFinder, to use as a stopgap tool for the first general-purpose version of M.A.C.E.

While implementing this, we found a minor byteswap bug in Launch trap’s handling of AppParmHandle. (Also, Toni was able to complete the full Fool’s Errand playthrough on Twitch using this improved version).

Star Wars day

This year we also celebrated the official Star Wars day (May the 4th) by trying out how the Brøderbund’s Star Wars arcade game’s Mac port works on M.A.C.E. and streaming a bit of it on Twitch:

Star Wars for Mac

Both the sound and visuals seemed to work without any problems. The “main menu” of the game did seem to run a bit faster than on real Macs, but luckily the actual ingame play was not affected by machine speed, and ran just fine.

Monkey Island

Inspired by the number of people recently streaming Monkey Island on Twitch, we were interested to see how the Mac version of that game would run on M.A.C.E. There were a couple tweaks needed to get it to run:

  • The Start Manager traps GetVideoDefault and SetVideoDefault traps were needed, and it seems the the dummy implementations were good enough to make Monkey Island happy
  • ReserveEntry palette manager trap had a bug where the GDevice’s color table was not reseeded when clearing the “reserve” (only when setting it). This caused the inverse color lookup table to not update properly, turning at least the pile of monkeys in Monkey Island about box from grayscale to black & white 🙂

It seems that Monkey Island runs quite well now on the emulator, although doesn’t yet have any sounds until the Sound Manager implementation gets finished. Also, it has some timing glitches at least in cutscenes, which may be related to the timer issues with Prince of Persia 2 and Loony Labyrinth (which need more investigation).

Hilite transfer mode

Another task from long time ago was implementing the hilite transfer mode for Color QuickDraw. It is basically a special transfer mode used to improve the highlighting of selections, done with simple color inversion in monochrome Macs, with a more colorful visualization.

In this mode, the color ports have special rgbHiliteColor field used to determine highlighting color (which by default is populated from HiliteRGB low-memory global). If using the hilite transfer mode of 50 or 58 (or when the special hilitebit in HiliteMode low-memory global is cleared in combination of using xor transfer mode), QuickDraw will swap background and hiliteColor with each other, producing toggleable highlight coloring:

Additionally, the hilite mode was also one missing piece of the scrollbar CDEF thumbnail drag drawing code, so that is now also visualized correctly.

The mysterious stuff in Sierra games #1: Sound in Mixed-Up Mother Goose

Although King’s Quest 1 was already working nicely since last year, Mixed-Up Mother Goose was interestingly having trouble playing audio, so we did a bit of investigation about it. It turns out that game is very strangely using some of the unused 68K user exception vectors to save handle to data being used to track music/audio playback in their VBL handler.

The reason this didn’t work, is that all those vectors were originally uninitialized (set to zero), and this particular version Sierra’s AGI engine checked if the exception vector pointer was set to a value above ROMBase, and it being lower assumed some handler was already present, and skipped using it for its own data. On real Macs, every unused 68K exception vector is initialized during startup by the Error Manager to DS exception handler, which by default is in ROM, and thus makes the game work on those systems. By adding a dummy exception handler and populating all the exception vectors, Mixed-Up Mother Goose was able to play music & sounds without any problems (Toni also did a one-hour playthrough of this game on Twitch to celebrate this fix).

Mixed-Up Mother Goose (with audio working)

The mysterious stuff in Sierra games #2: Color support

One of Toni’s friends on Twitch mentioned that some Sierra AGI games had problems running the 16-color versions in Mac emulators (specifically Space Quest 1), so we were curious and investigated this issue. On the first try, the same problem manifested also in M.A.C.E., so we started to dig a little bit deeper to find the cause of this, and found something interesting.

When I dissected the AGI code in Space Quest 1, I noticed that really weirdly, as the very first thing, the game checks if the the baseAddr of screenBits is above $F000 0000 – and if this check failed, even if the screen would be set to higher bit depth, it would go on and assume it was displaying the game on a monochrome screen.

As the problem on other Mac emulators may be partially related to inability of switching to 24-bit mode (at least when I tried it with Basilisk II), I believe that what is happening is that Slot Manager addresses the cards in different way in 24- vs 32-bit modes (for example, card $9 is accessed through “minor slot space” range of $009x xxxx, which translates to 32-bit address range in “standard slot space” of $F90x xxxx – problem is, that in 32-bit mode, the address would be in “super slot space” of $9xxx xxxx). It should be noted that even in 24-bit mode, at least QuickDraw handles the actual video memory access in 32-bit mode by using SwapMMUMode to temporarily switch the mode – same thing that some 24-bit compatible early color games also do, such as Maelstrom.

In our emulator, as we ran everything in pure 24-bit mode, including the video memory access, we didn’t care about the high byte of the address, which being zero originally displayed the same behaviour. However, after populating the high byte with “faked” standard slot space-type address of 0xF9900000 for video memory as a hack, both Space Quest 1 and Mixed-Up Mother Goose started to work in color mode:

Space Quest 1 in color mode

A more proper memory addressing and slot manager implementation will however be definitely needed, and that will most likely be done when we will be adding the 32-bit memory addressing support in the later part of this year.

Minor Warcraft 2 demo progress

We also did a little bit of work on trying to get Warcraft 2 (and its demo) to work. As it’s so far the only game that requires Thread Manager, it was previously put on a hold due to uncertainty about how much threading features it would be using. Turns out that adding dummy implementations for MacGetCurrentThread, SetThreadSwitcher and YieldToThread were enough to get Warcraft 2 progress a bit. Naturally proper Thread Manager implementation will be added at a later point, most likely in combination of Process Manager and EPPC/AppleTalk support which all are related to each other. But for now, we are able to get at least to the startup options screen – but sadly not further yet:

Warcraft 2 demo startup options dialog

What’s next?

For now, we will try to focus on continuing the research of Sound Manager during the summer. So far the progress on that has been pretty good, as we have already good idea about some of the sound manager data structures and behaviour – but more work is still needed to get it to the point where it can be used in the test applications, and to actually produce the sounds. It should be noted that we will be adding two variants of Sound Manager, the 2.x compatible version that will be used in the “classic” mode (which was the highest Sound Manager version supported by the old monochrome Macs), and 3.x compatible version for the color-capable (i.e. slot manager) emulation mode. We also may need to implement ASC-compatible version of the “.Sound” driver to support stuff like fourtone synthesizer in early color games (but instead of hardware emulation like in “classic” mode, that will be all done directly in software).

Full list of changes since last post

2021-06-21 03:42:10 +0300 • Add dummy IconIDTorgn & PlotIconID to IconDispatch
2021-06-21 03:41:08 +0300 • Fix NewGWorld fail crash (duplicate DisposeHandle)
2021-06-21 03:39:03 +0300 • Add dummy SPBOpenDevice to SoundInputManager      
2021-06-21 03:38:17 +0300 • Add dummy YieldToThread selector to ThreadDispatch
2021-06-19 13:27:53 +0300 • Fix some incorrect PaletteDispatch selector sizes 
2021-06-19 13:04:30 +0300 • Add dummy SetThreadSwitcher to ThreadDispatch     
2021-06-19 13:01:37 +0300 • Don't crash MDEF 0 on unsupported messages        
2021-06-18 21:00:20 +0300 • Add ThreadDispatch & dummy MacGetCurrentThread    
2021-06-18 17:30:21 +0300 • Add dummy Thread Manager module                   
2021-06-14 16:30:06 +0300 • Add Space Quest 1 test application JSON configs   
2021-06-14 16:29:41 +0300 • Add 16-color Sierra AGI compatibility HACK        
2021-06-14 16:27:15 +0300 • Add dummy _Eject trap handler                     
2021-06-05 04:09:17 +0300 • Fix drawing of scroll thumb outline in color mode 
2021-06-05 03:18:30 +0300 • Add Civilization DEMO test application JSON config
2021-06-04 22:18:11 +0300 • Fix GetResource (DON'T set resNotFound to ResErr) 
2021-06-04 00:03:10 +0300 • Implement PixMap32Bit                             
2021-06-04 00:02:12 +0300 • Fix initialization of screen GDevice pmVersion    
2021-06-03 23:39:35 +0300 • Fix byteswap bug in GetPixelsState in QDExtensions
2021-06-03 23:00:04 +0300 • TextEdit fixes for the hilite mode support        
2021-06-03 22:58:40 +0300 • Implement GetIconSuite for IconDispatch           
2021-06-03 21:11:28 +0300 • Fix inet_ntop buffer size in AddrToStr in MacTCP  
2021-06-03 17:43:28 +0300 • Also add hilite transfer mode to region blitter   
2021-06-03 17:21:44 +0300 • Support hilite transfer mode in rectangle blitter 
2021-06-03 17:18:33 +0300 • Fix mask of source pixels in transparent blit mode
2021-06-03 01:39:31 +0300 • Merge branch 'master' of <redacted> 
2021-06-03 01:39:26 +0300 • Fix ReserveEntry (reseed CT also w/ reserve=false)
2021-06-03 01:35:55 +0300 • Add StartManager + dummy Get/SetVideoDefault traps
2021-06-03 01:35:02 +0300 • Add Monkey Island test app JSON configs           
2021-05-31 11:50:14 +0300 • Merge branch 'master' of <redacted> 
2021-05-31 11:50:10 +0300 • Add dummy minilauncher code, to be improved later 
2021-05-30 22:01:00 +0300 • Fix nested VBL interrupt support (to not hang)    
2021-05-30 20:25:37 +0300 • Add a generic DS exception handler to all vectors 
2021-05-30 20:21:55 +0300 • Add Mother Goose test app JSON configs            
2021-05-04 04:55:48 +0300 • Add Star Wars test app, for May 4th celebration 🙂
2021-04-13 16:47:10 +0300 • Merge branch 'master' of <redacted> 
2021-04-13 16:47:05 +0300 • Fix 1-bit pixmap expansion with custom colortable 
2021-03-30 02:09:37 +0300 • Fix byteswap bug of AppParmHandle in A5 world     
2021-03-03 13:15:25 +0200 • Ignore thirdparty lib xcode user workspace folder 
2021-03-02 22:45:30 +0200 • Merge branch 'master' of <redacted> 
2021-03-02 22:45:12 +0200 • Fix invalid pointer bug in TESetStyle             
2021-03-02 22:44:15 +0200 • Fix negative bytecount bug in TESetLineHeights    
2021-03-02 19:42:19 +0200 • Fix debug mode in posix file copy utlity (errno)  
2021-03-02 19:41:43 +0200 • Fix __APPLE_ preprocessor typo to __APPLE__       
2021-03-02 19:11:43 +0200 • Make raspberry pi version compile again           
2021-03-02 02:45:14 +0200 • Make CMP0114 policy compatible with old CMake too 
2021-03-01 22:22:12 +0200 • Remove printf                                     
2021-03-01 04:09:50 +0200 • Setup QoS class for main thread on Apple M1       
2021-03-01 04:09:09 +0200 • Upsample audio from 22255 to 44100 manually       
2021-02-24 22:56:53 +0200 • Universal compilation cmake config for M1 macs    
2021-02-21 01:20:48 +0200 • Minor fixes(?) to 16/32-bit bitmap upscaling      
2021-02-21 01:18:25 +0200 • Fix planeBytes comparison in PixMap equality check

Happy new year! First M1 benchmarks, and other fixes

First tests on Apple Silicon

Toni finally got a M1 MacBook Air in mid-January, so we have now been able to try out compiling the emulator on macOS arm64 target. As all arm-specific issues were already fixed in the Raspberry port, the code compiled directly without any modifications needed, and is also running without any issues. However, the CMake build system needs to be tweaked a little bit to allow universal builds, as by default it generates only arm64-only builds. Soon when this is sorted out, we will update the available downloads to include the M1-native versions. Below however are some Speedometer test that we got from quick testing:

Here’s breakdown of the scores:

  • The first score, 35.8 total (0.774 cpu) is from x64 native code running on 2015 MacBook Pro (2.7 Ghz i5)
  • The second score, 90.6 total (1.700 cpu) is from x64 code running on M1 MacBook Air in Rosetta emulation
  • The third score, 146.2 total (2.770 cpu) is from arm64 code running on M1 MacBook Air natively

So it seems that the Apple Silicon builds seem to be working quite well (even though according to Pukka, there is a lot of possibility for optimization; more about this later)

Color support for scrollbar controls

Another TODO-task from long time ago was adding finally color support for the scroll bar control (CDEF 1). The windows, standard buttons and menus had already color support, but this was the last piece missing from a full reproduction of System 7-style appearance. Technically the control code is complete, but the scrollbar thumb dragging is still missing hilite mode rendering, so it is only 99% complete. Below is screenshot of one of the games where this visual change is visible (scrollbars on the SimCity 2000 map window):

Color scrollbar (CDEF 1) contols, here in SimCity 2000

Boolean bitmap color blending fixed

Another fix we did was analyzing and fixing the problem with text rendering in Master of orion, which we wrote about in the last month’s update. What we found out, was that according to IM:Imaging With QuickDraw book, sourcing any bitmap transfers from monochrome sources to color destinations need to be colorized in a bit different way compared to color transfers. What this means, is that when doing pixel scaling, the source color table lookups are skipped, and the foreground/background colors are applied directly on the source bitmap data. With this fixed, all the texts appear now correctly in Master of Orion:

Master of Orion with text blending issue fixed

Trying out a couple more new games

We also added some new games to the suite of test cases, in this case Might & Magic II and Loom:

  • Might & Magic III needed a couple Script Manager routines, which we added as placeholders, so the game starts up, but text rendering is still a bit off
  • Loom seems to work nicely as-is, although like all other color applications, needs Sound Manager support to get any sound.

68k TRAP instructions and THINK Pascal LightsBug

Another thing that we got to work was the 68K TRAP instruction handler, which enabled the debugging in THINK Pascal to work quite nicely. Breakpoints, execution control, LightsBug features (variable views, 68K registers, heap) seem to work mostly okay. The IDE does however complain about memory zone corruption, although all zones are fine (something is also causing the LightsBug zone explorer to fail, so there may be still some minor incompatiblity there).

Pukka is currently in progress of improving the exception support in the 68k emulator, so we will have the support for TRAPs fully implemented soon.

Other stuff

Here’s a couple other things that were fixed:

  • Added support for drawing labels for the popup menu control (CDEF 63). This is used by Master of Orion in the new game setup dialogs
  • Don’t assume FMExist low-memory global exists on “classic” type Macs. This came up as THINK Pascal does a lot low-level patching on a number of Toolbox routines (to allow running applications inside THINK Pascal itself), InitFonts is expected to run on the older machine profiles even if FMExist would be marked to tell that Font Manager is initialized
  • Fixed CopyBits device port pre-draw intersection to take port origin into account; ignoring this cased scrolling up ResEdit editors to make contents of window disappear as the origin moved far enough up off the screen
  • Graying of standard button control (CDEF 0) checkbox and radio button variants; this fixes the issue that disabled controls did not render as grayed out in color ports
  • Added a number of color menu table access routines (GetMCInfo, SetMCInfo, DisposeMCInfo + other tweaks), which allow ResEdit to now display MENU resource previews also in Color QD mode – and also, the MENU resource editor seems to also work, with full color editing features

Regarding optimization, after discussion with Pukka, we decided that we should try in very near future an alternate way of mapping the emulated machine memory using host system/machine paging instead of the currently VM lookup table. Theoretically, using mmap (with possible combination of libsegv or similar) to map memory to a certain fixed “window” in memory, we could almost completely eliminate the penalty of emulated machine memory accesses. According to profiling results, should theoretically double the emulation speed, but we need to experiment with this to see how the results are. We will write more about this when we soon have chance to try it out.

Also, Toni has been doing a couple small experiments on using M.A.C.E. for trying out Twitch.TV streaming at https://www.twitch.tv/truetonizz.

Full list of changes since last post

2021-01-12 13:55:56 +0200 • Add missing path to toolbox cmake build script
2021-01-12 11:03:38 +0200 • Inline VM access calls & add dummy page handler
2021-01-12 02:57:09 +0200 • Add Loom test app JSON config settings for CMake
2021-01-12 02:55:57 +0200 • QDScaleColorize1ToIndexed4 (colorizing 1-to-4 bit)
2021-01-08 13:58:28 +0200 • Add QDScale1ToIndexed4 (1-to-4-bit depth scaling)
2021-01-06 05:12:58 +0200 • Apply bgColor in patBic mode in color rect blitter
2021-01-05 22:22:34 +0200 • Force also ROM clut copies to NoPurge in GetCTable
2021-01-05 22:19:49 +0200 • Set MemErr in HPurge/HNoPurge/HClrRBit/HSetRBit
2021-01-05 16:37:01 +0200 • Handle empty (zero-size) 'ictb' resources properly
2021-01-05 02:10:20 +0200 • Fix also graying of CDEF 0 radio/checkbox buttons
2021-01-05 01:50:08 +0200 • Color QD button graying (text & default frame)
2021-01-04 22:41:52 +0200 • Fix color QD CopyBits when scrolling w/ SetOrigin
2021-01-04 06:00:32 +0200 • Implement GetMCInfo/SetMCInfo/DisposeMCInfo traps
2021-01-03 03:10:35 +0200 • Don't use FMExist on "classic" b&w configuration
2021-01-03 03:09:32 +0200 • Use non-MacPlus trap table profile in THINK Pascal
2021-01-02 20:32:55 +0200 • Minor code cleanup in standard windowproc (WDEF 0)
2021-01-02 20:31:57 +0200 • Add color support to scrollbar controls (CDEF #1)
2021-01-02 20:30:52 +0200 • Merge branch 'master' of
2021-01-01 10:49:54 +0200 • Clean up Dialog Manager drawing save state locals
2021-01-01 02:28:56 +0200 • Implement VisibleLength selector for ScriptUtil
2021-01-01 01:34:20 +0200 • Add dummy StyledLineBreak selector to ScriptUtil
2021-01-01 01:12:18 +0200 • Partial implementation of TEGetStyleScrap selector
2020-12-30 23:20:43 +0200 • Merge branch 'master' of
2020-12-30 23:08:14 +0200 • Add CMake JSON test config for Might & Magic III
2020-12-30 20:47:49 +0200 • Add colorizing 1-to-8bit pixel translation
2020-12-30 20:45:07 +0200 • Fix ctSeed byteswap in stretch dither mode check
2020-12-30 18:45:02 +0200 • Uncheck item after popup menu selection
2020-12-30 18:41:35 +0200 • Draw labels in popup menu control + colorQD stuff
2020-12-30 10:14:41 +0200 • Fix some byteswap bugs in the popup menu control
2020-12-30 00:42:07 +0200 • Fix popup menu control MENU reloading
2020-12-29 23:28:18 +0200 • Fix mouseMoved message signature
2020-12-29 22:16:18 +0200 • Pixpat expander a bit safer in case of memory move
2020-12-29 22:12:37 +0200 • Add correct 1-bit boolean stretching depth scaling
2020-12-24 00:11:46 +0200 • use memory macros for all 68k emulator memory i/o
2020-12-24 00:10:27 +0200 • use memory macro in cpu look, remove unused proc..
2020-12-24 00:09:10 +0200 • make index offset branchless
2020-12-22 00:09:37 +0200 • Add Solarian II to test application CMake configs

Merry X-Mas! (with Glider 4 and Scarab of RA)

Even though it’s been a rough year around the world, soon will again be the time of the year, when the friendly, white-bearded dude in red outfit from Lapland will fly around the world, giving presents to everyone.

This year we are able to contribute to your holiday celebration, as we got permissions for distributing not only one, but two new classic Mac games, which you can enjoy during the holiday break:

New application bundles available for download: Scarab of RA and Glider 4

Thanks to the generous permissions by John Calhoun (author of Glider 4), and Rick Holzgrafe (author of Scarab of RA), those two defining samples of the classic Mac gaming history are now again available for everybody to play with during the holidays!

To download and try out these classics, go to the https://mace.software/files page on this site, and you will find links to both Mac and Windows 10 versions of these application bundles, including details about these games.

Although Glider already runs quite well in color mode, it is only available as the “classic” version for the time being, as sound is not yet working in the color mode. I will update the application bundle later in the spring, when the color version is ready for public testing.

NOTE: The current version of M.A.C.E. may cause random “pops” on macOS platforms, and possibly low-volume high-pitch background noise on Windows 10 platform. This is most likely is caused by the old classic sound emulation code we are still using, as it passes the 22255 Hz frequency used by old Macs directly to SDL2. It may apparently, depending on platform, give the job of upsampling it to the host operating system, which in some cases may give varying results depending on the audio hardware and drivers being used. This is a known issue, and it will be fixed when Sound Manager implementation is added in the spring, possibly even before that.

Most recent new tests cases: Holiday Lemmings, Master of Orion, Pararena 2.0

Fitting for the holiday season, we tried running X-Mas Lemmings demo, and for most parts it seems to work pretty well. However, in this game, the most important features missing are still Sound Manager and color cursor support.

Another test case, which we recently added, was inspired by watching a Twitch streamer playing the DOS version of this particular game: Master of Orion. The Mac version seems to work okay’ish in M.A.C.E., but there are some minor glitches:

  • Dialog items are missing from various new game setup dialogs
  • A lot of the color texts are drawn reversed, i.e. the text is transparent but rectangle around is text color. This is probably just a minor glitch in text blitter, which we will investigate and fix soon.
  • Sounds are missing because of the aforementioned missing work on Sound Manager

And as part of getting John Calhoun’s great games to work in our emulator, we also made some fixes which allow Pararena 2.0 to (almost) work in M.A.C.E. The only missing feature, which we know of, is again Sound Manager support. I guess that will be a main goal to aim for during the spring…

More Styled Textedit updates

In other news, there is progress in various parts of the emulator, one of them being the ongoing work on improving Styled Textedit support. Two of the test cases most recently made functional are Speedometer and the aforementioned Pararena 2.0 (which both ironically use it for help screens, by pure coincidence):

There is still some work to do, as for example editing a Styled Textedit field does not yet work, because caret and highlight features are still not updated for multi-style support.

Full list of changes since last post

2020-12-21 03:14:09 +0200 • Fix updating FSSpec name from TE field in StdFile 
2020-12-21 03:12:17 +0200 • Implement StandardPutFile selector (#5) in Pack3  
2020-12-21 02:56:24 +0200 • Add Master of Orion test app to CMake JSON configs
2020-12-21 02:04:46 +0200 • Implement DisposeCCursor trap for Color QD
2020-12-20 01:21:33 +0200 • Merge branch 'master' of
2020-12-20 01:21:23 +0200 • Add Holiday Lemmings Demo CMake JSON configs
2020-12-20 01:19:57 +0200 • Fix handle MP flag check in ResrvMem
2020-12-19 17:36:06 +0200 • Remove colon from CMake JSON config app names
2020-12-18 17:01:07 +0200 • Merge branch 'master' of
2020-12-18 17:00:41 +0200 • Color PICT recording updates
2020-12-17 01:10:47 +0200 • Rename native EqualRect to not collide Win64 API
2020-12-17 01:09:52 +0200 • Make GestaltKeyboardType windows compatible
2020-12-17 01:09:16 +0200 • Update windows icon caches
2020-12-17 01:08:26 +0200 • Update appname in cmake configs to support windows
2020-12-17 00:40:50 +0200 • Fix invalid character in wolf 3d cmake json config
2020-12-10 23:38:31 +0200 • Implement TEGetOffset trap
2020-12-10 23:32:23 +0200 • Add Pararena 2 CMake JSON test application config
2020-12-10 23:31:31 +0200 • Implement TEGetStyle selector for TEDispatch
2020-12-10 23:01:36 +0200 • Add patOr color QD rectangle blitter mode support
2020-12-10 02:44:49 +0200 • Mark rect dirty in b&w CopyMask (+fix warnings)
2020-12-10 01:44:02 +0200 • Add some john calhoun's games to CMake JSON conf..
2020-12-10 01:35:42 +0200 • Use ShieldCursor instead of HideCursor in CopyMask
2020-12-10 01:34:02 +0200 • Some cursor code cleanup (init state, AllocCursor)
2020-12-09 16:07:08 +0200 • Add patOr, patXor & patBic color QD StdLine modes
2020-12-09 13:57:13 +0200 • Fix missing icon check in Dialog Manager item draw
2020-12-08 03:14:20 +0200 • Handle launch failure more gracefully
2020-12-06 05:26:53 +0200 • Add SimpleText test app JSON config to CMake
2020-12-06 05:25:59 +0200 • Tweak Glider 4 CMake config, update 4.06 to 4.10
2020-12-05 16:21:48 +0200 • Fix Pixel2Char output width on TRUE result case
2020-12-05 14:30:26 +0200 • Work on TEStyleInsert; Speedometer help works now
2020-12-04 05:50:01 +0200 • Fix start pt to bottom right clamp in GrowWindow
2020-12-02 22:47:00 +0200 • More CMake tweak + update build number
2020-12-02 20:30:30 +0200 • Update some CMake test app JSON configs
2020-12-02 02:37:25 +0200 • Fix compilation on Xcode 12

TextEdit update: first styled text features added

The progress has been a bit slow in the last month because of us being extra busy at our regular daytime jobs, but we did manage to squeeze some long-awaited changes in. We finally started the work on multistyled textedit support, which is extension added to TextEdit API around System 6.0.4, allowing more than a single style to be applied within text edit records.

As we did not have much time to work on this yet during November, we only have so far roughly these features implemented for style support:

  • Multistyled TE record creation using TEStyleNew
  • Partial setting of appending multistyled text using TEStyleInsert
  • Adjusting existing styles using TESetStyle
  • Drawing multistyled text within the TEDoText’s teDraw selector
  • Measuring multistyled text

And the following style properties can be used within the styles:

  • Style font family
  • Text face (bold, italic, underline, etc…)
  • Font size
  • Text color

From the test applications we have been running, the most important ones requiring styled textedit support have been HyperCard 2.x and Marathon. Below is screenshot of HyperCard 2.0 Home stack, with multistyled text showing right on the welcome screen:

HyperCard 2.0 Home stack with multistyled text

And even more importantly, Marathon terminals can now be opened and operated, which means that we can finally proceed forward in Marathon gameplay to the other levels beyond the first one:

Marathon’s terminal view, with multistyled textedit field used for the text rendering

However, there are still some missing features, of which we need add these most important ones next:

  • Finalize TEStyleInsert to handle given StScrpHandle data properly
  • Implement other multistyle TEDoText selectors, such as teFind and teCaret, to allow actual styled text editing
  • Merge identical adjacent styles after style adjust operations, to avoid excessive style run array growth
  • Add other missing selectors to TEDispatch where needed
  • Also implement any other missing toolbox calls used by textedit where needed

With current speed of progress, the most important ones of the remaining parts textedit API should be usable within a couple of weeks. Unless we get too distracted by playing Marathon 🙂

Full list of changes since last post

2020-11-29 23:52:29 +0200 • Added PortChanged (no-op) selector in QDExtensions
2020-11-29 23:27:24 +0200 • Add JSON cmake config for HyperCard 2.2 test app
2020-11-29 23:26:55 +0200 • Add no-op dummy InitDateCache ScriptUtil selector
2020-11-29 23:22:50 +0200 • Implement partially ScriptUtil's SetEnvirons
2020-11-28 04:47:13 +0200 • Fix clamping of negative offset in TEPinScroll
2020-11-28 04:46:09 +0200 • Fix clamping of below bottom in pt-to-line routine
2020-11-28 03:48:03 +0200 • Implement TEGetPoint selector for TEDispatch
2020-11-27 01:30:49 +0200 • Handle styled text in TEDispose
2020-11-27 00:52:53 +0200 • Refactor TE locals, don't cache dereferenced hTE
2020-11-26 05:38:32 +0200 • Other fixes to make TESetStyle to work & add debug
2020-11-26 05:33:34 +0200 • Get correct style run idx for singlebyte edge case
2020-11-26 05:31:53 +0200 • Fix lineheight calc (wrong index & zero new slots)
2020-11-26 05:28:27 +0200 • Add missing TEApplyStyle byteswap (run->startChar)
2020-11-26 05:27:33 +0200 • Return correct style index @ existing style lookup
2020-11-26 05:26:30 +0200 • Set stCount, stHeight and stAscent for new styles
2020-11-26 05:25:31 +0200 • Add viewRect validation to TEDoText (debug mode)
2020-11-26 05:24:38 +0200 • Set stCount to 1 when inserting a new style
2020-11-26 05:23:52 +0200 • Re-deref TEHandle in TEStyleNew after hText alloc
2020-11-26 05:22:51 +0200 • Increment text pointer in TEFindLine for new style
2020-11-26 05:19:32 +0200 • Fix byteswap in numerator check in StdText
2020-11-25 04:28:32 +0200 • Work on TESetStyle (not yet working, but almost)
2020-11-23 03:24:16 +0200 • Start work on TESetStyle (and TEContinuousStyle)
2020-11-22 05:15:36 +0200 • Add style support to TEGetLineForV
2020-11-22 04:47:30 +0200 • TESetSelect styled text support
2020-11-22 04:45:35 +0200 • More TEStyleInsert work (line heights calculated)
2020-11-22 00:57:54 +0200 • TEStyleInsert progress (TEFindLine style support)
2020-11-21 04:53:05 +0200 • TextEdit BIG refactor & start adding TEStyleInsert
2020-11-21 02:46:25 +0200 • Implement GetCPixel and SetCPixel (ResEdit PACK 1)
2020-11-20 15:59:17 +0200 • Fix colorQD colormap bug, 1&2-bit modes flipped fg
2020-11-20 15:37:02 +0200 • Implement GetEntryUsage trap for palette manager
2020-11-20 15:23:33 +0200 • Implement old-style FONT lookup in RealFont
2020-11-20 14:47:15 +0200 • Fix bugs in styled text rendering, it works now
2020-11-20 13:56:34 +0200 • Don't set/read flags for purged/unallocated handle
2020-11-20 12:44:49 +0200 • Implement TEGetHeight (non-styled) for SimCity 2K
2020-11-20 12:28:04 +0200 • Make SWAP macro single-line safe
2020-11-20 05:48:11 +0200 • Fix for what looks like VERY strange bug in Excel…
2020-11-20 05:45:10 +0200 • Add dummy GetPortNameFromPSN selector @ OSDispatch
2020-11-20 05:44:27 +0200 • Add PPC trap dispatcher w/ dummy PPCInit & PPCOpen
2020-11-20 05:20:57 +0200 • Temporarily increase system heap size
2020-11-20 05:20:15 +0200 • Dummy switcher info data for testing Excel 3.0
2020-11-20 04:36:18 +0200 • Prototype styled TextEdit draw & linewidth measure
2020-11-10 22:48:13 +0200 • Implement TEGetStyleHandle for TEDispatch
2020-11-10 22:28:22 +0200 • Implement dummy IsLayer selector for LayerDispatch
2020-11-10 22:09:35 +0200 • Add TEDispatch, and TECustomHook and TEFeatureFlag
2020-11-10 03:22:20 +0200 • Implement TEStyleNew trap handler for TextEdit
2020-11-10 03:20:44 +0200 • Update Scarab of RA test app config to new version
2020-11-08 13:47:35 +0200 • Optional release version logging/assertions toggle
2020-11-08 13:46:56 +0200 • Minor code cleanups (logging, prep dirtyrects etc)
2020-11-08 13:27:22 +0200 • Fix src/mask address calculation in B&W CopyMask
2020-11-08 00:54:19 +0200 • Reinforce save of auxiliary regs in C->68k calls
2020-11-08 00:42:58 +0200 • Fix clamping of teLength in TextEdit's DoDraw proc
2020-11-04 16:17:43 +0200 • Add GWorld rowbytes calculation method selection
2020-10-31 03:26:53 +0200 • Handle wInGoAway also in SystemClick (Close DA)
2020-10-31 03:25:08 +0200 • Add missing change from the slot manager commit