Sunday 10 February 2019

Resurrecting Apple /// SOS copy protected disks

There are a few Apple /// disk images around that won't work due the SOS copy protection failing. I described this in an earlier post, and its due to the volume numbers for specific sectors not matching with the ones that SOS is expecting. The dsk/po disk format does not include this information, just the sector data itself. So they are never going to be able to work for SOS protected disk images.

As an example, the Apple3SystemDemo.dsk disk image on apple3.org, will not boot and gives 'SYSTEM FAILURE = $06'




I did find a reference to this error code in the Apple /// technotes, see:
 TA32241 Apple III: System Failure Errors

  "Copying certain protected diskettes will cause an error $06 when the copy is booted. This
  is a normal effect of the protection scheme."


This is an interesting way of way of saying if you copy it, it's not going to work.



To resurrect these disks, there are two possible ways we could achieve this:
  1. Convert the disk image to a format that includes the necessary information to look like the original disk.
  2. Read in the SOS.INTERP file and then decrypt it with the known SOS key, and then write it back out to disk.
I decided to have a look at the first option. I'll try and come back to the second option at a later date.

There are two things we need to achieve to satisfy the SOS copy protection, the specific volumes numbers, and synchronisation of the tracks. The synchronisation is needed as SOS reads the first specific track/sector to get the first key/volume number and then just steps to the next track and reads the first sector it finds. At the last track, the sector number that is found and read first is compared with the expected one and if it does not match, then the protection check fails.

We now have available the woz disk image format that will work perfectly for this. If we image the original disks directly to woz format, then they work correctly. (thanks Jorma for imaging Apple /// software to woz format)

But what about our disk images that we do not have the original disk for. If we had a way to convert the dsk image to a woz format and add back the required volume numbers and track synchronisation, then we should be able to get a working disk image. I remembered reading that someone had written a dsk2woz program to do this exact thing (thanks Tom). All we need to do is modify it to meet the requirements needed for the SOS protection check.

Step 1 - add the volume numbers

The first thing to add are the volume numbers we need. I looked back at the previous blog post and this is the list, the first value is the required volume number.

VISIKEY:    .byte $7C      ;track 16, Sector 6
            .byte $BD      ;track 15, Sector 10
            .byte $BD      ;track 14, Sector 14
            .byte $9B      ;track 13, Sector 2
            .byte $F3      ;track 12, Sector 6
            .byte $E4      ;track 11, Sector 10
            .byte $C1      ;track 10, Sector 14
            .byte $B4      ;track  9, Sector 2


There is a part of the code in dsk2woz that builds the bitstream for each track. It just adds 254 as the default volume number for each track/sector. I then updated the code in this part to check if its one of the track and sectors in the list, and then add the expected volume number for these. Other wise, we just put in the default value for the volume number.

I converted the dsk image and then tried this in MAME to see if it would load. It still gave the same System failure $06 error. The synchronisation part needed sorting out now.

Step 2 - add the correct positioning of the tracks with respect to each other

dsk2woz builds each track with the sector data in the same order and position, as usually we don't need to worry about any special track alignment for non protected disks, so we end up with all tracks the same.

To check what SOS is getting when we boot this disk up, I referred back to the listing of BFM_INIT2 module. Looks like the check is done at the end of the key reading and its looking for sector number 06

00B8F3  1  A5 98            LDA       SECTOR
00B8F5  1  C9 06            CMP       #ENDSECT      ;TRACKS SYNC'ED?
00B8F7  1  D0 08            BNE       NOTPROT


Next was to startup MAME with the debugger active and set a break point at $B8F5 and see which sector is actually getting read. Turns out it was reading sector number 3.

Then I needed to add into dsk2woz some different alignment of the track data. The trackdata in a woz is the complete bitstream, and the length of the actual data is 6288 bytes long in the dsk2woz generated woz file tracks. All we really need to do is rotate the data for each track after its been prepared, before writing it out to the woz file. We will also need to keep track of this offset, so the next track is offset from the last tracks starting position and then 'rotated' by the same amount.

I added this to the code, and then just picked an arbitrary value of 600 bytes to shift the tracks by. Sure enough, SOS found a different sector, but not the correct one. I ended up just using trial and error to work out the offset needed to get SOS to end up reading the correct sector number at the end. There was around 400 bytes of range that resulted in the correct one being read, so i settled on a value in the middle of the range that worked.

The end result was the disk I started with now successfully boots now in MAME using the created woz file!



The converted file is available here Apple3SystemDemo.woz

The updated dsk2woz program is available here a3dsk2woz

Summary

This method will give the ability to run some disks in the emulator now, that have not been able to be run from the dsk images due to the copy protection info missing. I don't think we are missing any of this software, but its been an interesting project to see if this was possible. It also shows the beauty and power of the woz file format and how it caters for so much more than we have had before. Thanks John! and thanks to the MAME team for adding woz support in.