Monthly Archives: December 2019

Happy Holidays!

It’s again the Christmas season, and time again for the annual holiday update, now for the second time! As our greeting to you, here’s the (apparently now traditional) Christmas tree easter egg screenshots from Dark Castle running the latest M.A.C.E. version (it appears only when the game notices that the system time is set to 25th of December in UTC time):

Dark Castle was one of the first games we actually tried M.A.C.E. on over one year ago, and it was already working quite well on the previous Christmas. At that time, the CPU bugs were preventing FireBall levels from being played, but luckily those issues were fixed during this summer, and now all the levels are in playable state.

There are however still minor hiccups, such as weirdly behaving robots, dungeon key being always on the right-most side in the Trouble 3 level, Mutants spawning too quickly, Burning Eye not shooting fireballs, etc. Pukka thinks a common denominator for these issues might be some random number generation code in Dark Castle, but it still needs to be analyzed further.

To celebrate the progress, we recorded a short video of Dark Castle gameplay (with Christmas tree in The Great Hall) on this Christmas Day for your entertainment – all rooms were visited, but sadly I was not lucky enough to topple the Black Knight off his throne this time, even after two tries:

Dark Castle running on M.A.C.E. (Christmas Day easter egg)

Teasers for 2020

Sadly the holiday season has been very busy, which has also slowed down the project progress a little bit. There’s still some teasers for upcoming features which are almost complete, but not yet ready for release:

MacTCP driver

After we tested Bolo in M.A.C.E., we got inspired by the network support it has and had a idea about trying to implement a simple MacTCP driver in M.A.C.E., which would allow us to try out Bolo’s network gameplay we used to play with long time ago. However, the non-standard IODone mechanism, and Bolo’s tricky network performance measurement code, there is still a bit of work to be done to get that into playable state. However, MacTCP Ping seems to be working already quite well, including the DNS resolver:

There is though a “record route” option in “Options” menu, which we could not test because for some reason even using the same option on the real ping (ping -R) on Mac OS X causes the echo packets to get lost.

A more proper introduction about how this all works will be added later when we get the entire driver to work. For now, at least UDP calls to the .IPP driver seem to be working on an “okay” level, although they have so far been really tested only with Bolo, and only for the very first couple UDP packets exchanged by it.

Windows support

As many people have requested, we are already experimenting with adding a third platform into the build system, Windows (from Microsoft, the notorious arch-enemy of Apple Computer 🙂

We already fixed a couple thousand build errors, but there is still a lot of work to be done. For example, the MSVC compiler has a lot of source-code level differences in the C compiler, which need to be abstracted to allow the code to compile both with LLVM/GCC and MSVC targets. Additionally, the networking, file system APIs – and a bunch of other things we have – are POSIX/Unix-only at the moment, which need Win32/64 equivalents to be implemented.

Beyond those two work-in-progress features, we are also still working on increasing stability through bug fixing and debugging. You can always follow the progress on this blog, and check the list of compatible applications in the “Status” page. Thank you for you interest in our efforts, have a merry Christmas!

Full list of changes since last post

2019-12-21 14:09:25 +0200 • Fix VerticalRetraceMgr byteswap bug in inVBL flag 
2019-12-21 14:08:18 +0200 • Add UDPWrite implementation to MacTCP emulation   
2019-12-20 03:14:50 +0200 • First successful UDPRead in MacTCP call (w/ Bolo) 
2019-12-20 01:00:52 +0200 • Implemented UDPCreate for MacTCP driver           
2019-12-20 00:01:36 +0200 • Add MacWWW test app (not working, needs color QD!)
2019-12-20 00:00:21 +0200 • Make MacTCP ipctlEchoICMP support async operations
2019-12-19 23:57:26 +0200 • Improve DA/DeviceMgr enums (accXXX, ioInProgress…)
2019-12-19 23:55:07 +0200 • Fix byteswap bug of dCtlDelay in SystemTask       
2019-12-18 19:22:56 +0200 • Disable unused 128-bit float test code            
2019-12-17 04:29:47 +0200 • Reinforce interrupt safety of device manager calls
2019-12-17 04:02:39 +0200 • Don't close the MacTCP driver                     
2019-12-15 05:23:27 +0200 • Add very primitive foundation for MacTCP driver   
2019-12-15 03:42:24 +0200 • Add a couple more kCStackBased mixedmode handlers 
2019-12-15 03:40:51 +0200 • Add missing prWrErr from earlier PRAM modification
2019-12-15 03:39:53 +0200 • Make RSReturnValue argument safe for function call
2019-12-15 03:37:15 +0200 • Add the DRVR 22 MacTCP (.IPP) driver to fake ROM  
2019-12-15 03:35:32 +0200 • Add MacTCP Ping test app to CMake JSON config     
2019-12-15 02:48:56 +0200 • Fix indexing for GetFileInfo/SetFileInfo          
2019-12-15 02:45:45 +0200 • Start work on kCStackBased MixedMode routine type 
2019-12-15 02:44:19 +0200 • Fix off-by-one-byte bug in FindFolder fld# handler
2019-12-13 03:25:39 +0200 • Add dummy ReadXPRam and WriteXPram for Bolo     

Finding the Finder

Recently, somebody was asking on Emaculation forums, what would happen if Apple’s Finder would be attempted to run in M.A.C.E.? That was an interesting question, which motivated us to try it out.

Mac System Software architecture

To think about what would make Finder work, let’s consider the classic Mac system software as an architecture consisting of roughly three layers (in real Macs):

  • ROM: Most of Toolbox APIs, ROM resources and stage 0 boot loader.
  • System: Patches to ROM, extensions, system zone, the so-called “kernel” of old MacOS.
  • Finder: The “desktop metaphor” front-end running as a regular Mac application.

This categorization is very naïve, does not consider details such as role of hard drive drivers in boot process, etc. Additionally, M.A.C.E. combines roles of ROM and System as a single entity implemented in native code.

The interesting part to highlight is how Finder is basically “just another” application running on the System, and was even replaced by alternate startup applications on the old Macs (such as MiniFinder, MultiFinder, or other applications using the “Set Startup” option). As such, especially on System 6.x and older, the undocumented dependencies between System and Finder might be few in number, if any.

The first run

So, the question was, what would happen if we would try to run it? Well, we got this far on the first attempt, and with a couple minor fixes to progress further:

So, almost there. What we needed was a couple new (missing) routines and some fixes:

  • Fixed the 0x16 and 0x17 csCodes for .NativeFS driver, which return the logical/physical ICN# data for the volume icon (as seen on the desktop). We actually had that icon already one year ago, but this was the first time anything wanted to access it. 🙂
  • Added working directory indexing to GetWDInfo, which Finder uses to close all open working directories, presumably left open by misbehaving applications under System 6.x.
  • Fixed a buffer overflow bug in GetVolInfo (in volume name).
  • Implemented File locking APIs, which Finder wants to use to maintain the Desktop file.

Getting to the desktop

After a long and tedious session of debugging, it was discovered that due to a stupid bug in GetWDInfo Finder was crashing upon attempting to enumerate volumes. After that fix, we got nice Finder desktop, and a lot of functionality already working:

Operating on the Finder windows added need to implement a couple other missing traps, although as dummy versions for now (SetCatInfo and SetVolInfo, which Finder attempts to use to write metadata about modifications done in the spatial finder windows, icons, etc). Some points:

  • Finder and system icons appear as documents, but that might be because those don’t yet exist in the System file. Not sure about that yet.
  • It’s nice to see how a Finder 6.1.8 from Apple’s real System 6.0.7 behaves nicely even though M.A.C.E. System declares being version 7.0. 🙂
  • For some reason, doing “Get Info” on our Hard Drive turns our custom icon returned by the .NativeFS DRVR to a generic floppy icon.
  • It’s interesting how Finder considers at the moment our custom Hard Drive as “AppleTalk” device, but that might be because we’re hooking into the ExtFS file manager hooks which *I think* were used by AppleTalk in the real System 6.x. Just another thing which needs more investigation.
  • The modification and creation dates shown in “Get Info” (and list-style finder windows) use International Utilities date & time formatting functions, which are still placeholders. And as such, they only display mostly the numeric value of date-time instead of the proper, human-readable format.

Making the Desktop file work

At this point, we didn’t yet get the proper application and document icons to appear, so we did a bit more debugging on what was happening with the Desktop file – which Finder uses to keep track of known application creator & types, file comments, etc. It turned out, that we accidentally had all the “hasBundle” (0x2000) bits turned off in applications, which is why they were not detected by Finder.

As this issue was fixed, Finder started to process the applications properly, and quickly needed a some improvements to Resource Manager APIs. Mostly, it wanted to use UniqueID to allocate unique IDs for resources inside the Desktop file’s resource fork (to avoid conflicts). After that, updating Desktop file seems to work quite nicely, resulting in some fancy icons now appearing in the Finder under M.A.C.E.:

For now, running the real Finder remains as a curiosity, but nevertheless works as a great test case for a various number of Toolbox File Manager APIs which still need work (among some other minor bugs). The summary of the major known issues is:

  • The launching of programs “almost” works. Everything else appears to be fine, but it suffers from the same issue as previously found out using the “Transfer” command in THINK Pascal: The Font Manager data caches do not clear completely, leaving some dangling handles/pointers to the old application zone, which cause crash on attempting to reference them after the zone has been reinitialized for the new application.
  • Getting back to Finder (or any shell) is not yet possible, as ExitToShell is still hard-coded to terminate the entire emulator, instead of launching LMGetFinderName() application. Getting this to work would also encourage researching the Emscripten and Process Manager compatibility, as all of those features share a common need for a better in-emulator process management.
  • SetCatInfo/SetVolInfo are still dummy placeholders, so Finder is trying to use them to update metadata, though it is not yet saved.
  • Folder creation (_DirCreate), File/Folder deletion (_Delete), renaming (_Rename) are not yet implemented, so attempting those operations on Finder will still fail.
  • The _Eject trap is not yet implemented (and in any case you will not be able to eject the NativeFS drives).
  • As previously pointed out, Date & Time formatting does not yet work
  • The “Rebuild Desktop” operation (though using option + cmd keys at startup) does not yet seem to do the actual rebuild on a “fresh” start (i.e. if Desktop file has been wiped). Additionally, attempting that operation while old Desktop file exist will error out because _Delete is unimplemented, and old file cannot be removed out of the way.
  • Maybe other issues too, those are just the ones found out in the quick testing.

The “generic” M.A.C.E. environment might benefit of this though, as a replacement shell and/or program launcher, that could be optionally used by the end-user.

Full list of changes since last post

2019-12-12 18:19:41 +0200 • Add UniqueID/…1ID, to allow Desktop file updates
2019-12-12 17:49:18 +0200 • Add Disk Initialization Pack2 to keep Finder happy
2019-12-12 17:46:55 +0200 • Fix byteswap bug in NativeFS _Allocate handler
2019-12-12 15:00:12 +0200 • Add missing NativeFS.c changes for previous commit
2019-12-12 04:34:28 +0200 • Add dummy SetCatInfo and SetVolInfo selectors
2019-12-12 04:02:48 +0200 • Fix GetWDInfo bug (ioVRefNum & ioWDVRefNum mixed)
2019-12-09 02:58:47 +0200 • Fix memFullErr check in SetApplLimit
2019-12-08 06:31:06 +0200 • Fix filename overflow in GetVolInfo NativeFS call
2019-12-08 06:30:06 +0200 • Implemented CloseWD
2019-12-08 06:29:03 +0200 • Add WD indexing to GetWDInfo
2019-12-08 06:27:20 +0200 • Add Finder test app to cmake configs
2019-12-08 06:27:01 +0200 • Implement icon csCodes in NativeFS Control call
2019-12-08 06:25:52 +0200 • Make more macros in memory manager MSVC friendly
2019-12-08 06:25:18 +0200 • Add dummy SetFilLock and RstFilLock
2019-12-08 06:23:36 +0200 • Fix FinderName lowmem global
2019-12-06 23:44:06 +0200 • Add Bash Big Blue to cmake config for testing
2019-12-04 21:21:36 +0200 • Fix QD_LOG to respect debug settings
2019-12-04 20:48:17 +0200 • Add Cairo ShootOut! to cmake config for testing
2019-11-30 02:02:05 +0200 • Fix empty VA_ARGS problem in MaceLog macro
2019-11-29 23:55:30 +0000 • Make SWAP and MIN/MAX macros MSVC compatible
2019-11-29 23:54:08 +0000 • Made vararg ellipsis parameters MSVC compatible
2019-11-29 23:52:21 +0000 • Make Memory Manager return macros MSVC compatible
2019-11-29 23:51:27 +0000 • Make ROMScratch macros MSVC compatible
2019-11-29 23:50:08 +0000 • Move SwapPoint to MacQuickDraw.h to make it inline
2019-11-29 23:48:05 +0000 • Change void* to UInt8* in fake ROM (for MSVC)
2019-11-29 23:46:50 +0000 • Make SANE conversion macros MSVC compatible
2019-11-29 23:33:03 +0000 • Merge branch 'master' of
2019-11-29 23:32:43 +0000 • WinAPI EndianXX_Swap macros
2019-11-30 01:30:54 +0200 • Add UInt128 type to EmuMacTypes.h