In my last post, I figured out how to use Apple’s leaked Flasher utility from the 1990s to reflash a ROM SIMM inside of my Performa 630. It’s basically the Mac equivalent of a BIOS update, but only for Apple’s developers. The research involved in that post was quite a journey of reverse engineering from both a software and hardware perspective. I had to disassemble the code to figure out which computers were compatible and what the software was expecting to find. I also had to create a replica of an Apple development ROM SIMM that was wired exactly the way Macs of the era expected it. Although I was very excited about my discoveries, one big question remained:

What was the purpose of the bottom right half of the main window labeled “PDS ROM Info”? And what would it take to enable it?

Read the rest of this entry

After I wrote about the possibility of programmable Mac ROM SIMMs in Quadras a couple of months ago, I suspected that there had been a way for developers at Apple in the 68k Mac era to reflash the ROM in their Macs during development, just like BIOS updates on PCs. The reason I believed this is because the ROM SIMM socket in the Quadras brought out pins for 12V (VPP) and write enable (/WE). I had verified that the write enable pin was going into the memory controller chip in several Mac models, so I was pretty confident that in-system programming was possible.

As luck would have it, multiple people pointed out to me that an Apple internal utility used for ROM flashing had been uploaded to the Macintosh Garden. It was recovered from a prototype PowerBook 520 purchased in 2020. Of course, I had to download this utility and figure out how it works.

I ran it on my LC 475 and this is what it looked like:

Read the rest of this entry

TL;DR: The pinout of modern programmable Mac ROM SIMMs needs to be changed for correct operation in Quadras. If you’re interested in how I reached that conclusion, or at least want to see some cool pictures, read on below.

If you’ve been paying attention to the Classic Mac scene these days, you’re probably familiar with custom Mac ROM SIMMs such as the ROM-inator II. If not, here’s some intro material about them. JDW also made an awesome YouTube video explaining them.

One thing that you usually discover when searching for info about these programmable ROM modules is that they’re compatible with the earliest 68030-based desktop Macs: the SE/30, IIx, IIcx, IIci, IIfx, and IIsi. The most common use of them is to set up a special custom bootable ROM disk using Rob Braun’s driver, Big Mess o’ Wires’ driver based on Rob’s, or Garrett’s Workshop’s driver. In general, the compatible ROM images out there are all using the IIsi ROM which is capable of booting any of the aforementioned Macs.

What you may not know is that most of the later 68k Macs also have provisions for a ROM SIMM socket, but aside from the very first Quadras (700/900/950) which always have the socket installed, it’s not usually populated. Some early production or prototype units have it, but most just have empty through-holes filled with solder where the socket would go.

Don’t worry, I already replaced those leaky capacitors before they had a chance to damage the board.

Read the rest of this entry

Several months ago, Will from CayMac Vintage reached out to me looking to resurrect my old Mac ROM SIMM programmer project. As a quick summary of that project, it provides a convenient way to program custom 64-pin ROM SIMM modules for vintage Macs from the late ’80s to early ’90s. There are several reasons you might want to do this, including: replacing an original ROM module that has gone bad, disabling the startup RAM test to decrease boot time in systems with a lot of RAM, bbraun’s amazing bootable ROM disk hack, or my startup chime hack. JDW recently made a cool YouTube video explaining custom ROM SIMMs if you’re curious about them. He even included some footage from 2003 of me playing basketball!

I used to make programmer boards and programmable ROM SIMMs and sell them to hobbyists, but it burnt me out. In particular, assembling the boards and the logistics of shipping were not fun to deal with. Thankfully, in 2016, Steve from Big Mess o’ Wires stepped in to take over. He made his own customizations to the programmer and made some really neat improvements to the bootable ROM disk driver. He still sells the Mac ROM-inator II SIMM to this day, but he stopped selling the programmer board. In the meantime, many other players have entered the market with custom ROM SIMMs, but nobody has been making the programmer available to the community, likely due to my non-commercial license on the PCB design.

Will was looking to fill that void. I helped him get going, but we discovered that the AT90USB646 microcontroller that I originally used was hard to find due to the chip shortage. At the time, it was easier to find the AT90USB1286 instead, which is essentially just the exact same chip, but with 128 KB of flash instead of 64 KB of flash.

Read the rest of this entry

I was looking at one of my classic Macs a few weeks ago, and noticed that my Ubuntu 18.04 netatalk server wasn’t showing up in the Chooser anymore. If you’re not familiar with netatalk, it’s an implementation of Apple Filing Protocol (AFP) that runs on Unix-like operating systems such as Linux and NetBSD. It allows other operating systems to act as Mac file servers. Version 2.x, which I use, supports the ancient AppleTalk protocol. This allows it to work with really old classic Macs that don’t even have a TCP/IP stack installed. Support for AppleTalk was removed in version 3.x, so that’s why I’m still using 2.x.

I checked out the server, and noticed that atalkd wasn’t running.

doug@miniserver:~$ ps ax | grep atalkd
3351 pts/0 R+ 0:00 grep --color=auto atalkd

Hmmm….why wouldn’t atalkd be running? I went ahead and tried to restart netatalk:

Read the rest of this entry

After upgrading my Ubuntu server from 14.04 to 16.04, I noticed that legacy AppleTalk clients connecting to my netatalk (afpd) server showed an empty volume list; I could no longer access my “Home Directory” share that showed up by default in 14.04.

After some research, I discovered that the 14.04 to 16.04 upgrade brought netatalk from version 2.2.2 up to 2.2.5. It turns out that 2.2.5 has a bug which causes AppleTalk clients to not see anything from /etc/netatalk/AppleVolumes.default; only /etc/netatalk/AppleVolumes.system is read. Here is a link to the bug report I posted.

You could rebuild netatalk 2.2.5 with the latest unreleased patches as I mentioned in my first comment of the bug report above, or you can do what I did: just put your volumes into /etc/netatalk/AppleVolumes.system instead. I’m unsure if the “~” share works properly when it’s in /etc/netatalk/AppleVolumes.system, so I hardcoded it to my home directory path just in case. It works fine!

I recently repaired a Macintosh IIx I bought on eBay. It wouldn’t power on at all–both the rear power button and the keyboard power button did nothing. I was already aware that this system needs fresh batteries in order to boot, and I had removed the old batteries and replaced them with new ones, which didn’t make a difference. The real culprit: all of the surface-mount aluminum electrolytic capacitors had leaked electrolyte all over the logic board. This is a very common problem in older computers. These capacitors have a nasty habit of leaking after about 20 years or so. The electrolyte ate away at traces and several traces near capacitors were broken. Several IC pins were corroded really bad as well and had lost contact to their solder pads.

It was quite a journey figuring out how to fix it. The power button didn’t do anything, so I didn’t have a clue where to look. Luckily, an important figure in the Classic Mac community, Gamba, created a schematic of the power circuit. Sadly, Gamba passed away, but his site is still operational (update 4/5/2019: his site was finally taken down, but I updated the links to point to archive.org). I think there is a small error in his schematic, so I went ahead and fixed it. The fixed schematic is depicted below. The only change is the positioning of J18-15 and TS1 on the right side:

macIIsch_fixed

I began looking at this schematic and realized I didn’t have a clue what was going on in any of it. All of those NAND gates, diodes, and transistors looked intimidating. I buckled down and did my best to read the schematic and figure out what every piece does. After lots of experimentation and research, I feel like I understand this circuit pretty well now. I’ve decided to write this post to help explain the circuit and maybe help people in the future who are trying to figure out why their II/IIx won’t start up. Note: I am not an electronics expert. I’m trying my best, but I could be wrong about some details. Corrections would be appreciated!

Note that the diagram’s component numbering is for the Mac II. The IIx is slightly different. I would provide more detail, except my IIx logic board is a prerelease one that has the same component numbering as the II. So my IIx’s logic board’s component numbering matched this diagram. Other IIx systems do not match.

Let’s get started!

Overview

Here’s a broad overview of the different pieces of the circuit:

Overview

The ADB portion of this circuit is unrelated to this discussion, so I will skip it. Don’t worry–I have included the keyboard power button as part of my description of the power on circuit.

When I first looked at this diagram, for some reason I thought the top half was for the keyboard and the bottom half was for the rear power button. I was totally wrong. The keyboard and rear power button share most of the same power on circuitry. Now, I’m going to cover each section in more detail.

Batteries

Batteries

The two batteries B1 and B2 (3.6V 1/2 AA lithium) are in series with each other. This means they combine together to create a 7.2V voltage across ground and the positive terminal of B1. [Edit: Lee Carter pointed out in the comments below that the original batteries are actually 3V 1/2 AA, so they would actually total together to be 6V. You can correct the voltage numbers in the pictures and description below based on this new information] The three diodes seem to serve two purposes:

  1. Drop the voltage a little bit
  2. Protect against reverse polarity (putting the batteries in backwards)

In particular, D5 and D6 take the 7.2V voltage from the batteries and drop it down to about 7V or so. Normally these diodes would have a higher voltage drop, but you will see that while sitting idle, there isn’t much current being drawn from them, so the diode voltage drop is pretty low. D4 drops the 3.6V voltage a little bit, but I think its main purpose is to protect against reverse polarity. If you put B1 and B2 in backwards, D4 and D5 will prevent negative voltages from making their way to any other part of the logic board.

The 1000 μF capacitor is (I believe) the capacitor on the battery replacement board, and it can be found on both the II and the IIx, despite what Gamba’s diagram says. These computers originally came with the two batteries soldered directly to the logic board. When they needed to be replaced, there was a little circuit board that a service provider would solder on to replace the original batteries. It had two battery holders and a 1000 μF capacitor. I don’t fully understand the purpose of the capacitor, but it might be to make life easier on the batteries when the power button is pressed.

So this portion of the circuit takes two batteries as input, and as output provides a 3.3V-ish voltage rail and a 7V-ish voltage rail. I say “-ish” because I measured anywhere from 6.8V to 7V when I was debugging this circuit. But it’s somewhere in that ballpark. The 3.3V voltage is for powering the PRAM and clock while the computer is turned off. The 7V voltage is for turning the power supply on when you press either of the computer’s power buttons.

If you’re troubleshooting this portion of the circuit, make sure the cathode of D6 has 7V or so, and the cathode of D4 has 3.3V or so. If not, there’s something wrong with some of the traces and/or components pictured above. Check continuity between everything in the diagram above, and if needed, test D4, D5, and D6.

Clock/PRAM

ClockPRAM

This portion of the circuit is responsible for powering the clock and PRAM. On most (all?) of the Macs that came after the II/IIx, this is the *only* thing the single 3.6V battery is used for, at least as far as I know.

Recall that I already explained that there is about 3.3V on the cathode of D4 coming from battery B2. The 4.7KΩ resistor R17 is limiting the amount of current that will be supplied to UB6, the clock/PRAM chip. So…when the computer is turned off, the battery B2 is powering UB6. D3 is preventing the battery voltage from going into the +5V rail (which will be 0V when the power supply is turned off).

When the power supply turns on, the +5V rail actually has 5V on it. D3 will allow the 5V to go through into UB6, so the +5V rail will power UB6. I believe the 4.7KΩ resistor (R17) makes it so that the 5V rail does most of the work powering UB6 instead of the battery when the power is on. D4 is also (I believe) preventing the circuit from sending +5V into the battery circuit when the computer is powered on.

This part of the circuit is pretty simple! I don’t think a problem in here would necessarily prevent the computer from turning on, but it might prevent settings from being remembered while the power is off.

Power On

PowerOn

OK, here is where things really get interesting and more complicated. This is also where it will become obvious that both batteries must be installed in order for the II/IIx to boot. Recall that the cathode of D6 has about 7V on it or so. It powers UB2 (which is a 74HC132 containing four NAND gates–three are used, one is unused). UB2 doesn’t draw much current, so that’s why the diodes mentioned in the battery portion of the circuit don’t have much of a voltage drop. Without the batteries, these NAND gates will not be powered at all, and therefore the power circuit won’t work. It’s a good thing UB2 doesn’t draw much current, because otherwise the batteries would run out of juice too quickly.

Supplying 7V to the 74HC132 is a bit risky — it’s within the allowed range, but the datasheet I have recommends a maximum of 6V. Whatever–it seems to work. [Edit: The discussion about 3V vs. 3.6V above probably explains this discrepancy]

The 7V rail also goes to the emitter of transistor Q3, which is a PNP transistor. We’ll see in a minute, but when the power button is not being pressed, the transistor is turned off, so it shouldn’t be drawing any current.

Additionally, the 7V rail is directly connected to one of the inputs on each of the three NAND gates. In effect, it means each one of these NAND gates is really acting as an inverter (e.g. a logic 0 at the other input becomes a logic 1 at the output, and a logic 1 becomes a logic 0). This is because:

  • 1 NAND 1 = 0
  • 0 NAND 1 = 1

I’ll go into this in a bit more detail when I describe what happens when you press the power button.

Finally, the 7V rail goes through the 100KΩ resistor R18 to the second input of the leftmost NAND gate. This is a pull-up resistor that keeps the second input of the NAND gate pulled up to a logic 1 by default. The 100Ω resistor R3 is also connected to this part of the circuit, but the other end of it is floating when both power buttons are not being pressed, so it doesn’t really affect the circuit until a power button gets pressed.

So in the default state when the system is plugged in but no power button has been pressed:

  • The leftmost HC132 NAND gate has both inputs at 7V. This means its output will be 0V.
  • The output of that first NAND gate is fed into the other two NAND gates.
  • Each of those NAND gates has one input at 0V, and one input directly wired to 7V, so they are both outputting 7V.
  • Since 7V is going into the left side of R14, there is no current between the emitter and base of the transistor. The transistor is turned off.
  • Because the transistor is turned off, the power supply control pin (J18, pin 15) is left floating (remember, the +5V output is not supplying 5V yet, since the power supply is off).
  • Thus, the power supply stays off.

When the keyboard power button is pressed, the left side of R3 is grounded. This pulls pin 2 of the HC132 NAND gate to ground through the 100Ω resistor R3. So:

  • The leftmost HC132 NAND gate has one input at 0V, and one input directly wired to 7V.
  • The output of that NAND gate is thus 7V, which is fed into the other two NAND gates.
  • Each of these NAND gates has 7V going into both input pins, so they are both outputting 0V.
  • Since 0V is going into the left side of R14, current is flowing from the emitter of the transistor to the base of the transistor. The transistor is turned on and allowing current to flow from the emitter to the collector.
  • Because the transistor is turned on, the power supply control pin is driven to 7V or so (just assume that TS1 is a short circuit for now–it will be described in more detail in the power off circuit description)
  • Thus, the power supply turns itself on.

As soon as the power supply turns itself on, it begins outputting 5V. 5V goes through D2 and R10, pulling the power supply control pin up to +5V (minus the diode drop) through the 220Ω resistor. As soon as you release the power button, this mechanism keeps the power supply control pin high. Otherwise, the power supply would immediately turn itself back off.

The rear power switch does essentially the same thing as the keyboard power switch. When you press it:

  • It completes a circuit to allow the battery to begin charging up capacitor C3, which is discharged when this process begins.
  • The left side of R3 starts at 0V and slowly starts raising up as C3 charges.
  • Since C3 starts at 0V, the same steps are followed as when the keyboard power button was pressed, and the power supply turns on.
  • After the power supply turns on, 5V is available through R9, so C3 will charge up to 5V.
  • C3 charging up to 5V is an important detail. If the button is later used for turning the computer off, the rear power switch won’t try to turn on Q3 at the same time it tries to turn the power supply off. It also gives you some time to release the power button before the system tries to turn itself back on again.

Wow! I may try to add some more diagrams in the future to depict it a bit more clearly. It’s a lot to digest.

You may be wondering: what is the point of the three NAND gates? At first glance, all they are effectively doing is repeating the input value that came out of R3. The purpose seems to be to allow better current drive capability for controlling the transistor, and a clean output that ensures that the signal controlling Q3 is either on or off, and not somewhere in between as capacitors charge up.

The three NAND gates essentially combine to create a buffer with double the current drive capability of a single NAND gate’s output. As long as all of the NAND gate pins are connected together and the NAND gates are working, you can assume that a low value at pin 2 of UB2 will turn the transistor on, and a high value at pin 2 will turn the transistor off.

Power Off

PowerOff

Just like the power on part of the circuit, the power off part of the circuit uses NAND gates that make it look way more complicated than it really is. These NAND gates are powered by the power supply’s +5V line. The two leftmost NAND gates form an SR latch. The SR latch’s top “set” input is connected to UB11, pin 13 (and the power button’s second pole). I believe this line is pulled up to +5V by a pull-up resistor inside the 6522 VIA (UB11), keeping it high (deasserted) while the computer is running. UB11 pin 13 is the /POWEROFF signal. At startup, C5 is fully discharged to 0 volts, so the SR latch’s “reset” input is low (asserted), which sets the SR latch’s stored “Q” value to 0. Then, C5 charges up, so the “reset” input goes high (deasserts itself) and stays deasserted while the computer is powered on. So the entire time the computer is running, the SR latch’s “Q” value is 0.

The !Q output of the SR latch is connected to the next two NAND gates, which act as an inverter just like in the power on circuit as I described earlier. So the output of the dual-NAND-gate inverter connected to R15 is really just the noninverted Q output of the SR latch, but with twice the maximum current. Thus, the voltage on the left side of R15 is 0V while the computer is on, keeping the NPN transistor Q2 turned off. Remember that the power supply control pin (J18, pin 15) is being pulled up to +5V in the power on circuit, keeping the power supply turned on.

Let me explain TS1 now. TS1 is a temperature switch. During normal operation, it acts like a short circuit. If the temperature gets too hot, it becomes an open circuit. If it becomes an open circuit, the power supply control pin is no longer pulled up to +5V, so the power supply shuts off (I’m pretty sure the power supply has a weak internal pulldown on that pin). During normal operation, TS1 will act like a wire.

When you tell the computer to shut down, the computer drives UB11 pin 13 (/POWEROFF) low. This causes the SR latch’s “set” input to go low, so it’s now asserted. This makes the !Q output low, which makes the inverter output high, so Q2 turns on, connecting R11 to ground. Now there is a 27Ω pulldown pulling the power supply control pin low, and a 220Ω pullup pulling the power supply control pin high (in the “power on” portion of the circuit). This is a voltage divider, so the voltage at the power supply control pin will be approximately 0.5V. This is low enough to tell the power supply to turn off.

If you press the power button on the back of the computer, the same thing happens — it connects the SR latch’s top “set” input to ground, and the exact same thing happens.

Troubleshooting

OK, so I have tried my best to explain what’s going on in each portion of the circuit. If you have a broken power circuit, how do you fix it?

The system will not power on

First of all, there are a few traces that have a tendency to go bad because they run nearby leaky capacitors:

Of course, make sure you have removed, cleaned around, and replaced all of the electrolytic capacitors on the logic board.

Make sure that all of the connections between R3, UB2, R14, and Q3 are OK. If you can, use a voltmeter to verify that the NAND gates are operating as expected when you press either of the power buttons. You can do this with the logic board out of the computer as long as the batteries are installed.

Check the power supply control pin (J18, pin 15) to see if it’s correctly getting a voltage when you press either of the power buttons. If it is, there’s a chance that the power supply is at fault.

UB2 is somewhat near a capacitor. There’s a good chance that some of its pins have lost connectivity due to corrosion. Check every pin on UB2 and make sure it has connectivity as shown in the schematic.

The keyboard power button works, but the rear power button doesn’t

There are only a few parts of the circuit that could cause this. Make sure R9, C3, the rear power button, R3, and the keyboard power button pin of L2 are all connected as shown in the schematic diagram. For the rear power button to not work when the keyboard does, one of the connections between those components has to be broken.

The system powers on, but it won’t power off

UB1 is extremely close to a capacitor. There’s an extremely good chance that it has lost some connectivity due to corrosion. Verify all connections.

See if the output of UB1 pin 8/11 is correctly going high when you press the rear power button while the system is on. If not, follow the circuit and see where the broken trace is.

Final thoughts

I thought this would be a good idea to explain the circuit in more detail. This has turned into quite a long-winded explanation, and it doesn’t have quite as many pictures as I would have hoped. Maybe this would be better as a video or an animation that shows what the circuit is doing. For now, I hope this is enough to help someone out there troubleshoot their Macintosh II/IIx power circuit.

In my particular case, a trace was broken in the R3-R18-C6-UB2 group of pins that should be connected together, and UB1 was completely covered in capacitor leakage, which had very badly corroded its pins and solder pads. I ended up replacing both UB1 and UB2 to be safe. A trace between a via and C5’s positive end was also broken and needed a patch wire. I had to run several patch wires to repair broken traces:

UB1_UB2_before_after

UB1_UB2_after

By the way, this wasn’t the only problem with my IIx. This was actually the last part of the logic board that I fixed. The whole power on circuit can be bypassed by tapping a 3.6V battery between ground and the power supply control pin, so I did that for testing until I repaired this circuit. The power supply would turn on, but nothing would happen. It turns out that there were a ton of other traces that were corroded. The 53C80 SCSI chip (again, near a capacitor) was very badly corroded, so I removed it, cleaned the solder pads, and replaced it with a new one. One of the solder pads had a break from its trace, so I had to run a patch wire. I also found several other broken traces on solder pads near two chips on the board.

Corrosion2

UB8_before_after

It’s been a wild ride, but I now have a working IIx!

In the early- to mid-1990s, Apple produced their Macintosh Performa line of computers. These computers were meant for home users and typically came bundled with software such as ClarisWorks and Mario Teaches Typing, along with interactive tutorials teaching the basics of how to use the Mac OS. They were sold in places such as Wal-Mart and Sears.

One interesting thing about these computers is that at least initially, they did not come with any software restore disks. If something bad happened and you wiped out your system software (which was easy enough to do — somehow I did it as a kid), you didn’t have a supplied set of disks (or a CD) for restoring the software. Instead, these computers came with software called Apple Backup, and you were supposed to back up your system onto 1.44 MB floppies when you first got it. When you ran Apple Backup, it would let you choose to back up either the full hard drive or just your system folder:

Picture 3

The number of disks needed here is small because I ran it on a simple barebones system to make this screenshot. With all of the bundled software on a stock Performa machine, it would have taken somewhere in the ballpark of 50 floppy disks to complete the backup of the full hard drive. Seriously, how many people would have bothered to buy all of the floppies that would have been necessary, and then actually taken the time to do it? Some people definitely did, and I’m impressed by the dedication. I know my family didn’t bother when I was growing up. It would have been more realistic to only back up user-created files, and then provide a system restore disk (or set of disks) to restore any original software, but the backup software didn’t work that way. Apple obviously learned from their mistake because they began bundling Performa computers with restore CDs at some point later on. (Note: To be completely fair to Apple, it was possible to obtain restore disks from them if you needed to restore your system and your Performa didn’t come with any.)

I ran the backup process on an old Mac for fun, and it guided me through the process of backing up the system. Click the thumbnails to see the full size, if you care:

Picture 1 Picture 2 Picture 3 Picture 4
Picture 5 Picture 8 Picture 9 Picture 10

The resulting disks were normal Mac floppy disks, named “Backup Disk 1”, “Backup Disk 2”, and so on, each containing a single 1,414 KB file named Apple Backup Data.

To restore your data after a failure, you would boot up your Performa using the Utilities disk that came with the computer. The Utilities disk contained a barebones system folder along with disk formatting/repair utilities and a program called Apple Restore. You guessed it: Apple Restore was used to restore the system. You would run it and then insert your backup floppies one at a time to restore everything you backed up.

I looked at some of Apple’s later Performa restore CDs, and interestingly enough, they came with programs called “Restore All Software” and “Restore System Software”, each with a folder full of 1,414 KB files named “Data File 1”, “Data File 2”, and so on. So presumably Apple simply used Apple Backup to back up a stock system and stuck the resulting data files onto a CD to create the restore CD.

I decided that it might be useful to have Apple Backup’s file format documented in case someone out there ends up needing to restore files from their old backups (or wants to extract files from a factory restore CD). Although backup floppies from the 90s are probably going bad by now, I think it’s still cool to have the information out there. Anyway, I decided to reverse engineer Apple Backup and one of the factory CD restore programs (which does essentially the same thing as Apple Restore). I believe I have successfully reverse engineered the Apple Backup file format.

The rest of this blog posting contains the technical details about the format of the files that Apple Backup creates.

Overall layout of an Apple Backup data file

  • Type code: ‘OBDa’ (CD restore files have type ‘OBDc’ instead, but are otherwise identical in format)
  • Creator code: ‘OBBa’
  • There is no resource fork, and the data fork content is summarized in the table below:
Backup disk header
Boot blocks
File #1 header
File #1 full path
File #1 data fork data (if any)
File #1 resource fork data (if any)
Zero padding to next multiple of 0x200 bytes
File #2 header
File #2 full path
File #2 data fork data (if any)
File #2 resource fork data (if any)
Zero padding to next multiple of 0x200 bytes
File #3, 4, 5, … until data file is full

Next, allow me to describe the content of the data fork in more detail:

Backup disk header format

All offsets and lengths are in bytes. All multi-byte quantities are in big-endian format as would be expected from a Mac file format.

Offset Length Name Notes
0x00 2 Version This spec is valid up to and including version 0x0104
0x02 4 Magic number ‘CMWL’ – identifies this file as an Apple Backup file
0x06 2 This disk number Value is between 1 and the number of disks.
0x08 2 Total number of disks The total number of disks used for the backup.
0x0A 4 Backup start time In a Mac time format (seconds since January 1, 1904 00:00:00 local time)
0x0E 4 Backup start time Appears to always be a duplicate of the value above
0x12 32 Hard drive name The name of the hard drive that was backed up. Stored as a Pascal-style Str31 (1 byte length, 31 bytes of string data)
0x32 4 Total size of this file The total size of this restore file; value typically (always?) seen is 0x161800
0x36 4 Total size used in this file The number of bytes actually used in this restore file; value is typically 0x161800 except on last disk where it is probably going to be smaller.
0x3A 0x1C6 Unused Filled with zeros

Total length: 0x200 bytes

Boot blocks

These appear to be standard Mac OS boot blocks, 0x400 bytes in size. Easily seen in a hex editor because it begins with LK, and soon thereafter has names: System, Finder, MacsBug, Disassembler, StartUpScreen, Finder, Clipboard. They are written to the hard drive by the restore program when the System Folder is blessed as it’s restored. For just extracting files, they are not really relevant. They begin at an offset of 0x200 from the start of the backup file, and end at an offset of 0x600 (where the first file header begins)

File/folder header format

Each file or folder starts out with a header. Again, all offsets and lengths are in bytes, and everything is big-endian. This header will always begin on a 0x200-byte boundary; padding bytes of zero are added to the end of the previous file’s data fork/resource fork data if needed. The first file header in a backup data file is always at 0x600, immediately after the boot blocks.

Offset Length Name Notes
0x00 2 Version This spec is valid up to and including version 0x0104
0x02 4 Magic number ‘RLDW’ – identifies this as a file/folder header
0x06 2 Disk number that contains first part of this file/folder This will match the current disk number, unless this file is split across multiple disks and this is the second, third, etc. part of the file.
0x08 4 Backup start time Will be the same as the time in the backup disk header
0x0C 4 Offset of header The offset where this header begins in the disk (example: 0x00000600 in the first file header in every disk)
0x10 32 File/folder name The name of this file or folder. Stored as a Pascal-style Str31
0x30 2 Which file part this is 1, unless this is part of a file that has been split across multiple disks, in which case it will be 2, 3, etc.
0x32 1 Folder flags Bit 7 = 1 if this is a folder, 0 if this is a file.
Bit 0 = 1 if this is the system folder and it needs to be blessed [selected as the current system folder]
0x33 1 Validity flag Bit 0 = 1 if the following file info/attributes/dates are valid.
Bit 0 = 0 if this was a folder that is known to exist but its properties could not be read during the backup.
If a file’s properties cannot be read, the file is skipped during the backup process. So bit 0 = 0 could only happen with folders.
0x34 16 FInfo/DInfo about this file/folder A standard Mac FInfo or DInfo struct containing info about this file or folder (from HFileInfo or DirInfo)
0x44 16 FXInfo/DXInfo about this file/folder A standard Mac FXInfo or DXInfo struct containing info about this file or folder (from HFileInfo or DirInfo)
0x54 1 File/folder attributes Standard ioFlAttrib byte from Mac Toolbox HFileInfo/DirInfo struct
0x55 1 Unused
0x56 4 Creation date Standard Mac time
0x5A 4 Modification date Standard Mac time
0x5E 4 Length of file’s data fork Total length of data fork of the full restored file including all split parts (zero for folders)
0x62 4 Length of file’s resource fork Total length of resource fork of the full restored file including all split parts (zero for folders)
0x66 4 Length of data fork provided by this disk The length of data fork data this disk is providing for this file
0x6A 4 Length of resource fork provided by this disk The length of resource fork data this disk is providing for this file
0x6E 2 Length of full file path Maximum length of 33*50 (enough space for 50 colon-delimited path elements, with many extra bytes left over).
This is the length of the string that immediately follows this header.

Total length: 0x70 bytes. See Inside Macintosh: Files and the Mac Toolbox C headers named “Files.h” and “Finder.h” for more info on FInfo, DInfo, FXInfo, DXInfo, and ioFlAttrib. These items are where the type and creator code, invisible flag, and icon position in folder are stored, for example.

Full path format

The full path is just that: the full path to the folder or file, with the hard drive already being assumed. The components of the path are colon-delimited. The file being restored is the last component of the path. Example:

System Folder:Control Panels:Memory

(if the file being restored is the Memory control panel). It’s just printed as raw bytes, no null terminator or anything — it’s basically a Pascal string with a two-byte length, and the length is at the end of the file/folder header.

The actual file data

Immediately after the full path, the data fork bytes begin (number of bytes = “Length of data fork provided by this disk”), followed by resource fork bytes (number of bytes = “Length of resource fork provided by this disk”). It’s perfectly OK for the length of either (or both) of these to be zero. After that, there is padding (filled with “0” bytes) to the nearest 0x200 byte boundary, and then the next file/folder header begins.

When a file overflows the disk

If there is not enough space remaining on a disk for a complete file (this almost always happens at the end of each data file), the amount of file data that will fit on the disk is stored so that the full disk file size matches the size given in the disk header. Then the first file header on the next disk will be the same file’s header with the exception of the “Which file part this is” field, which will be incremented by one. It is possible for a file’s data to span several disks in this manner; the intermediate disks will only have one file header, followed by a repeat of the file path and data using up all available space on the disk.

For example: Let’s pretend you have 0x1000 bytes remaining on the current data file before its size reaches 1,414 KB. You’re ready to back up a file “Applications:TestApp” that that has a 512 KB data fork and a 128 KB resource fork. The file header will take up 0x70 of those bytes and the full path will take up 20 (0x14) of those bytes, for a total of 0x84 bytes — so there are 0xF7C (3,964) bytes left. So the file header is going to specify a data fork length in this disk of 3,964 bytes, and a resource fork length of 0 on this disk (the total lengths will be filled in as 512 KB and 128 KB though). Then the first 3,964 bytes of the data fork will be written to the file, giving it a total length of 1,414 KB. Then this disk will end. The first file header on the next disk will finish the remaining 520,324 data fork bytes and all of the 131,072 resource fork bytes, and then the next file’s header will begin on the nearest 0x200 byte boundary after that.

Conclusion

As you can see, the format is pretty simple. It’s just basically a disk header followed by a flat list of files until the end of the disk is reached. It should be possible to extract full and partial files from these backup archives even if the data files from some disks are missing. The partial files probably wouldn’t be very useful though.

The original Apple Restore utility didn’t let you pick and choose which files you wanted to restore — it just tried to restore them all, and it would ask you what to do if the file already existed and was newer than the backed up version. I see no reason why a utility couldn’t go through all of these files, give you a list of everything available, and let you selectively extract the files you want. It’s easy to detect what disk a particular backup data file came from because the disk header contains a field for what disk it belongs to.

If anyone’s interested in adding the ability to decode this format in an archive expander program, I would be happy to provide some sample data files. I may or may not decide to write a program to extract files from these backups, depending on how bored I get 🙂

Update 8/23/2022: GitHub user siddhartha77 created a new classic Mac utility called Apple Backup Extractor that can decode this file format. It can even decode what it can from an incomplete set of backup disks. If you’re looking for a way to recover data from these files, this is certainly the way to go!