Maniac Mansion, the 1987 version, is protected against copies using what is often referred to as a “fat track”: data perfectly identical and aligned across multiple tracks and half tracks.
As Pete Rittwage’s website suggests, Maniac Mansion uses a fat track at tracks 35.0, 35.5, and 36.0. Having a look in my Flux Studio, indeed data in these tracks is identical and perfectly aligned:
Let’s have a look at the drive code that scans through tracks 35.0, 35.5, and 36.0 and protects against copies:
; Loaded from t/s 18/8 *=$0400 V0400 SEI LDY #$FF B0403 INY LDA $0412,Y EOR T04AE ; Decode the following code segment STA $0412,Y CPY T04B0 BNE B0403 ; Decoded segment follows JSR S046F LDX #$00 ; Zero FDC return value storage STX $0009 LDX #$02 ; Set count for stepping 2 times STX $0008 LDA #$23 ; Start at track 35 STA $0006 B0424 LDY #$10 ; Sector 16 STY $0007 B0429 LDA #$80 ; Job: Read sector in buffer 0 STA $0000 JSR S047F ; Wait for job to finish CMP #$01 BEQ *+5 ; Branch if successful STA $0009 ; Store FDC error DEC $0007 ; Sector-- BPL B0429 ; Repeat for other sectors, down to sector 0 (included) JSR S048E ; Step head to the next half track DEC $0008 ; Decrement count of steps to do (35.0:0x01, 35.5:0x00, 36.0:0xFF) BPL B0424 ; Loop until we finished with track 36 LDY #$02 JSR S0487 ; Step head to the previous half track DEY BPL *-4 ; Now we are back on track 35, which is a valid DOS one LDA $0009 ; Was there an error reading any sector? None in the original BNE *+7 ; Branch if not LDA #$FF ; Flag this as a copy (and fail the protection check) STA $01FF LDA #$12 ; Track 18 STA $0006 LDA #$00 ; Sector 0 STA $0007 LDA #$B0 ; Job: seek track STA $0000 JSR S047F ; Wait for job to finish JSR S046F JMP J04B2 S046F LDA $1C0C ORA #$0E ; %00001110 BNE *+7 LDA $1C0C AND #$FD ; %11111101 STA $1C0C RTS ; Wait for job to finish S047F CLI LDA $0000 BMI *-3 SEI RTS ; Step head to the previous half track S0487 LDX $1C00 DEX JMP J0492 ; Step head to the next half track S048E LDX $1C00 INX J0492 TXA AND #$03 STA $0044 LDA $1C00 AND #$FC ORA $0044 STA $1C00 LDA #$D0 ; $80 | $50 STA $1805 BIT $1805 BMI *-3 RTS T04AE .byte $BA ; Byte used to decrypt the code T04AF .byte $00 T04B0 .byte $9B,$00 J04B2 LDA $0001 ; Remove the above code from the drive's RAM LDY #$00 STA $0400,Y INY CPY #$B2 BCC *-6 CLI RTS
There is nothing in this code that checks for tracks 35.0, 35.5, and 36.0 being perfectly aligned. The only timing code (using $1805) is the one that delays after the read head steps on a different track, which is commonly done to allow the head itself to stabilize (in fact, the stepping produces mechanical oscillations).
So what does this code do and protect against? Very simply, it starts at track 35 and reads in all sectors, from 16 down to 0, using the job queue of the 1541 corresponding to buffer 0. It then repeats the same on tracks 35.5 and 36.0. If any sector read error occurs during this test, the protection check fails (and $9 in the drive’s RAM is set to the last FDC status code, while $01FF is set to $FF).
You might contend: “There’s no need to have a fat track on disk since the reciprocal alignment of all three tracks is not checked!”.
Well, yes and no. You see, it’s hardware from the 80s we are talking about. It’s perfectly reasonable to expect that emulators will be able to read data off those half tracks that are “squeezed” in the middle of adjacent tracks without errors. But can a real Commodore drive do the same? Well, that depends on the drive’s electronic characteristics.
The truth is that when reading half track 35.5 in Maniac Mansion a real Commodore drive will probably be influenced by the data on at least one adjacent track, i.e. either 35.0 or 36.0. The result is that the read head will pick up a signal that’s the combination of the flux reversals on track 35.5 and of one adjacent track: that’s inter-track interference.
Now the question is: what happens if the data on track 35.5 and one of the adjacent tracks from where signal is also picked up is not aligned? Well, a mish-mash of signals from both tracks that is likely to result in errors while attempting to read at least one sector (out of the 51 sectors Maniac Mansion tries to read in total).
So the perfect alignment in a fat track is required due to the inability of the read head to read half tracks without being influenced by the signal in neighboring tracks, which is also consistent with the fact half tracks are not used by the Commodore DOS: such choice ensures good separation between tracks to avoid inter-track interference.
There is still more work and testing to do, but so far the above is what the testing suggests. Also, emulators should really try to emulate inter-track interference when loading data from half tracks in a G64, otherwise there will always be a difference in behavior when compared to real Commodore drives: even by skewing data in the tracks and half tracks that make up a fat track, emulators will read half tracks cleanly, where real hardware will likely not.
I have been discussing the above with Flavioweb and SLC, who also went the extra mile by testing on the field, so a big “thank you” goes to them for this article.
Nothing has so far been said about writing fat tracks. I’ve been focusing exclusively on how the real hardware reads them. In my next article on the fat track subject I will also comment on the task of writing fat tracks and whether or not it’s possible to do so on a Commodore 1541 or compatible drive.
Stay tuned for more on the fat track subject!