Atari ST Protection: Gauntlet II

Another track length protection. Track 78 has to be at least 100 bytes shorter than Track 79. On my disk Track 78 was 5988 bytes, while 79 was 6285 bytes. The content of the track is not important for the protection, just the length. Therefore the track was recorded with ~240kbit/s instead of the normal 250kbit/s.

00B5D2  0000                L0403:DC.W      $0000   ;Restore Command
00B5D4  0010                L0404:DC.W      $0010   ;Seek Command
00B5D6  0030                L0405:DC.W      $0030   ;Step Command
00B5D8  0050                L0406:DC.W      $0050   ;Step-in Command
00B5DA  0070                L0407:DC.W      $0070   ;Step-out Command
00B5DC  0090                L0408:DC.W      $0090   ;Read multiple Sectors
00B5DE  00D0                L0409:DC.W      $00D0   ;Force Interrupt

fdcDoMoveTrack0
00B5E0  303C002C            L040A:MOVE.W    #$2C,D0
00B5E4  323C0002                  MOVE.W    #2,D1
00B5E8  4EBA03EC                  JSR       1004(PC)             fdcDoAction(fdcDoSelectFloppy)
00B5EC  303C0000                  MOVE.W    #0,D0
00B5F0  4EBA03E4                  JSR       996(PC)              fdcDoAction(fdcDoRestore)
00B5F4  303C0028                  MOVE.W    #$28,D0
00B5F8  7200                      MOVEQ     #0,D1
00B5FA  4EBA03DA                  JSR       986(PC)              fdcDoAction(fdcDoWriteTrackNo)
00B5FE  303C002C                  MOVE.W    #$2C,D0
00B602  323C0000                  MOVE.W    #0,D1
00B606  4EBA03CE                  JSR       974(PC)              fdcDoAction(fdcDoSelectFloppy)
00B60A  4E75                      RTS

...

fdcDoAction:
00B9D6  4BFA0304            L0422:LEA       772(PC),A5           L0440
00B9DA  3B400000                  MOVE.W    D0,0(A5)             L0440
00B9DE  426D000E                  CLR.W     14(A5)               L0446
00B9E2  42790000BCF8              CLR.W     $0000BCF8            L0449
00B9E8  0C40002C                  CMPI.W    #$2C,D0
00B9EC  620E                      BHI.S     14(PC)               L0423
00B9EE  49FA030E                  LEA       782(PC),A4           L044E
00B9F2  28740000                  MOVEA.L   0(A4,D0.W),A4
00B9F6  4E94                      JSR       (A4)
00B9F8  302D000A                  MOVE.W    10(A5),D0            L0444
00B9FC  4E75                L0423:RTS

fdcDoRestore:
00B9FE  33FC008000FF8606    L0424:MOVE.W    #$80,$FF8606.L
00BA06  3E3AFBCA                  MOVE.W    -1078(PC),D7         L0403 = Restore Command
00BA0A  4EBA01A8                  JSR       424(PC)              fdcWriteD7
00BA0E  4EBA01C4                  JSR       452(PC)              fdcWaitDone
00BA12  4E75                      RTS

fdcDoSeekD1
00BA14  33FC008600FF8606    L0425:MOVE.W    #$86,$FF8606.L
00BA1C  3E01                      MOVE.W    D1,D7
00BA1E  4EBA0194                  JSR       404(PC)              fdcWriteD7
00BA22  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BA2A  3E3AFBA8                  MOVE.W    -1112(PC),D7         L0404 = Seek Command
00BA2E  4EBA0184                  JSR       388(PC)              fdcWriteD7
00BA32  4EBA01A0                  JSR       416(PC)              fdcWaitDone
00BA36  4E75                      RTS

fdcDoStep
00BA38  33FC008000FF8606    L0426:MOVE.W    #$80,$FF8606.L
00BA40  3E3AFB94                  MOVE.W    -1132(PC),D7         L0405 = Step Command
00BA44  4EBA016E                  JSR       366(PC)              fdcWriteD7
00BA48  4EBA018A                  JSR       394(PC)              fdcWaitDone
00BA4C  4E75                      RTS

fdcDoStepIn
00BA4E  33FC008000FF8606    L0427:MOVE.W    #$80,$FF8606.L
00BA56  3E3AFB80                  MOVE.W    -1152(PC),D7         L0406 = Step-in Command
00BA5A  4EBA0158                  JSR       344(PC)              fdcWriteD7
00BA5E  4EBA0174                  JSR       372(PC)              fdcWaitDone
00BA62  4E75                      RTS

fdcDoStepOut
00BA64  33FC008000FF8606    L0428:MOVE.W    #$80,$FF8606.L
00BA6C  3E3AFB6C                  MOVE.W    -1172(PC),D7         L0407 = Step-out Command
00BA70  4EBA0142                  JSR       322(PC)              fdcWriteD7
00BA74  4EBA015E                  JSR       350(PC)              fdcWaitDone
00BA78  4E75                      RTS

fdcDoForceInterrupt
00BA7A  3E3AFB62            L0429:MOVE.W    -1182(PC),D7         L0409 = Force Interrupt
00BA7E  4EBA0134                  JSR       308(PC)              fdcWriteD7
00BA82  3E3C3E80                  MOVE.W    #$3E80,D7
00BA86  51CFFFFE            L042A:DBF       D7,-2(PC)            L042A
00BA8A  4E75                      RTS

fdcDoReadSectors
00BA8C  2E0B                L042B:MOVE.L    A3,D7
00BA8E  4EBA00C6                  JSR       198(PC)              fdcDoSetAddress
00BA92  33FC00010000BCF8          MOVE.W    #1,$0000BCF8         L0449
00BA9A  33FC009000FF8606          MOVE.W    #$90,$FF8606.L
00BAA2  33FC019000FF8606          MOVE.W    #$190,$FF8606.L
00BAAA  33FC009000FF8606          MOVE.W    #$90,$FF8606.L
00BAB2  3E3C000C                  MOVE.W    #$C,D7
00BAB6  4EBA00FC                  JSR       252(PC)              fdcWriteD7
00BABA  33FC008400FF8606          MOVE.W    #$84,$FF8606.L
00BAC2  3E01                      MOVE.W    D1,D7
00BAC4  4EBA00EE                  JSR       238(PC)              fdcWriteD7
00BAC8  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BAD0  3E390000B5DC              MOVE.W    $0000B5DC,D7         L0408 = Read multiple Sectors
00BAD6  4EBA00DC                  JSR       220(PC)              fdcWriteD7
00BADA  4EBA00F8                  JSR       248(PC)              fdcWaitDone
00BADE  4EBA00A0                  JSR       160(PC)              fdcDoReadAddress
00BAE2  4EBA0040                  JSR       64(PC)               fdcDoReadStatus
00BAE6  4E75                      RTS

fdcDoReadSectorNo
00BAE8  33FC008400FF8606    L042C:MOVE.W    #$84,$FF8606.L
00BAF0  4EBA00D2                  JSR       210(PC)              fdcReadD0
00BAF4  024000FF                  ANDI.W    #$FF,D0
00BAF8  3B400006                  MOVE.W    D0,6(A5)             L0442
00BAFC  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BB04  4E75                      RTS

fdcDoReadTrackNo
00BB06  33FC008200FF8606    L042D:MOVE.W    #$82,$FF8606.L
00BB0E  4EBA00B4                  JSR       180(PC)              fdcReadD0
00BB12  024000FF                  ANDI.W    #$FF,D0
00BB16  3B400004                  MOVE.W    D0,4(A5)             L0441
00BB1A  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BB22  4E75                      RTS

fdcDoReadStatus
00BB24  33FC008000FF8606    L042E:MOVE.W    #$80,$FF8606.L
00BB2C  4EBA0096                  JSR       150(PC)              fdcReadD0
00BB30  024000FF                  ANDI.W    #$FF,D0
00BB34  3B40000A                  MOVE.W    D0,10(A5)            L0444
00BB38  4E75                      RTS

fdcDoWriteTrackNo
00BB3A  33FC008200FF8606    L042F:MOVE.W    #$82,$FF8606.L
00BB42  3E01                      MOVE.W    D1,D7
00BB44  024700FF                  ANDI.W    #$FF,D7
00BB48  4EBA006A                  JSR       106(PC)              fdcWriteD7
00BB4C  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BB54  4E75                      RTS

fdcDoSetAddress
00BB56  2B470010            L0430:MOVE.L    D7,16(A5)            L0447
00BB5A  13C700FF860D              MOVE.B    D7,$FF860D.L
00BB60  E08F                      LSR.L     #8,D7
00BB62  13C700FF860B              MOVE.B    D7,$FF860B.L
00BB68  E08F                      LSR.L     #8,D7
00BB6A  13C700FF8609              MOVE.B    D7,$FF8609.L
00BB70  2E2D0010                  MOVE.L    16(A5),D7            L0447
00BB74  7000                      MOVEQ     #0,D0
00BB76  3002                      MOVE.W    D2,D0
00BB78  DE80                      ADD.L     D0,D7
00BB7A  2B470014                  MOVE.L    D7,20(A5)            L0448
00BB7E  4E75                      RTS

fdcDoReadAddress
00BB80  303900FF8606        L0431:MOVE.W    $FF8606.L,D0
00BB86  02400007                  ANDI.W    #7,D0
00BB8A  3B40000C                  MOVE.W    D0,12(A5)            L0445
00BB8E  7200                      MOVEQ     #0,D1
00BB90  123900FF8609              MOVE.B    $FF8609.L,D1
00BB96  E189                      LSL.L     #8,D1
00BB98  123900FF860B              MOVE.B    $FF860B.L,D1
00BB9E  E189                      LSL.L     #8,D1
00BBA0  123900FF860D              MOVE.B    $FF860D.L,D1
00BBA6  2B410014                  MOVE.L    D1,20(A5)            L0448
00BBAA  92AD0010                  SUB.L     16(A5),D1            L0447
00BBAE  3B410008                  MOVE.W    D1,8(A5)             L0443
00BBB2  4E75                      RTS

fdcWriteD7
00BBB4  4EBA00BE            L0432:JSR       190(PC)              fdcDelay32
00BBB8  33C700FF8604              MOVE.W    D7,$FF8604.L
00BBBE  4EBA00B4                  JSR       180(PC)              fdcDelay32
00BBC2  4E75                      RTS

fdcReadD0
00BBC4  4EBA00AE            L0433:JSR       174(PC)              fdcDelay32
00BBC8  303900FF8604              MOVE.W    $FF8604.L,D0
00BBCE  4EBA00A4                  JSR       164(PC)              fdcDelay32
00BBD2  4E75                      RTS

fdcWaitDone
00BBD4  303C0360            L0434:MOVE.W    #$360,D0
00BBD8  51C8FFFE            L0435:DBF       D0,-2(PC)            L0435
00BBDC  203C00035000              MOVE.L    #$35000,D0
00BBE2  0839000500FFFA01    L0436:BTST      #5,$FFFA01.L
00BBEA  67000064                  BEQ       100(PC)              L0438
00BBEE  5380                      SUBQ.L    #1,D0
00BBF0  67000044                  BEQ       68(PC)               L0437
00BBF4  4A790000BCF8              TST.W     $0000BCF8            L0449
00BBFA  67E6                      BEQ.S     -26(PC)              L0436
00BBFC  13F900FF86090000BCFB      MOVE.B    $FF8609.L,$0000BCFB  L044A+1
00BC06  13F900FF860B0000BCFC      MOVE.B    $FF860B.L,$0000BCFC  L044A+2
00BC10  13F900FF860D0000BCFD      MOVE.B    $FF860D.L,$0000BCFD  L044A+3
00BC1A  2E390000BCFA              MOVE.L    $0000BCFA,D7         L044A
00BC20  BEAD0014                  CMP.L     20(A5),D7            L0448
00BC24  6D00FFBC                  BLT       -68(PC)              L0436
00BC28  4EBAFE50                  JSR       -432(PC)             fdcDoForceInterrupt
00BC2C  42790000BCF8              CLR.W     $0000BCF8            L0449
00BC32  6000001C                  BRA       28(PC)               L0438
00BC36  303900FF8604        L0437:MOVE.W    $FF8604.L,D0
00BC3C  024000FF                  ANDI.W    #$FF,D0
00BC40  3B40000C                  MOVE.W    D0,12(A5)            L0445
00BC44  4EBAFE34                  JSR       -460(PC)             fdcDoForceInterrupt
00BC48  3B7C0001000E              MOVE.W    #1,14(A5)            L0446
00BC4E  4E75                      RTS
00BC50  303900FF8604        L0438:MOVE.W    $FF8604.L,D0
00BC56  024000FF                  ANDI.W    #$FF,D0
00BC5A  3B40000A                  MOVE.W    D0,10(A5)            L0444
00BC5E  4E75                      RTS

fdcWaitForMotorOff
00BC60  33FC008000FF8606    L0439:MOVE.W    #$80,$FF8606.L
00BC68  4EBAFF5A            L043A:JSR       -166(PC)             fdcReadD0
00BC6C  08000007                  BTST      #7,D0
00BC70  66F6                      BNE.S     -10(PC)              L043A
00BC72  4E75                      RTS

fdcDelay32
00BC74  40E7                L043B:MOVE      SR,-(A7)
00BC76  3F00                      MOVE.W    D0,-(A7)
00BC78  303C0020                  MOVE.W    #$20,D0
00BC7C  51C8FFFE            L043C:DBF       D0,-2(PC)            L043C
00BC80  301F                      MOVE.W    (A7)+,D0
00BC82  46DF                      MOVE      (A7)+,SR
00BC84  4E75                      RTS

fdcDoSelectFloppy:
00BC86  4DF900FF8800        L043D:LEA       $FF8800.L,A6
00BC8C  303C07FF                  MOVE.W    #$7FF,D0
00BC90  018E0000                  MOVEP.W   D0,0(A6)
00BC94  7E00                      MOVEQ     #0,D7
00BC96  3E01                      MOVE.W    D1,D7
00BC98  6604                      BNE.S     4(PC)                L043E
00BC9A  4EBAFFC4                  JSR       -60(PC)              fdcWaitForMotorOff
00BC9E  0A070007            L043E:EORI.B    #7,D7
00BCA2  02070007                  ANDI.B    #7,D7
00BCA6  40E7                      MOVE      SR,-(A7)
00BCA8  007C0700                  ORI.W     #$700,SR
00BCAC  1CBC000E                  MOVE.B    #$E,(A6)
00BCB0  1016                      MOVE.B    (A6),D0
00BCB2  020000F8                  ANDI.B    #$F8,D0
00BCB6  8E00                      OR.B      D0,D7
00BCB8  1D470002                  MOVE.B    D7,2(A6)
00BCBC  46DF                      MOVE      (A7)+,SR
00BCBE  4A41                      TST.W     D1
00BCC0  6618                      BNE.S     24(PC)               L043F
00BCC2  303C073F                  MOVE.W    #$73F,D0
00BCC6  018E0000                  MOVEP.W   D0,0(A6)
00BCCA  13FC000300FFFC00          MOVE.B    #3,$FFFC00.L
00BCD2  13FC009600FFFC00          MOVE.B    #$96,$FFFC00.L
00BCDA  4E75                L043F:RTS

00BCDC  002C                L0440:DC.W      $002C
00BCDE  0000                      DC.W      $0000
00BCE0  0000                L0441:DC.W      $0000
00BCE2  0000                L0442:DC.W      $0000
00BCE4  0A00                L0443:DC.W      $0A00
00BCE6  00A4                L0444:DC.W      $00A4
00BCE8  0003                L0445:DC.W      $0003
00BCEA  0000                L0446:DC.W      $0000
00BCEC  00050CFC            L0447:DC.L      $00050CFC
00BCF0  000516FC            L0448:DC.L      $000516FC
00BCF4  00000000                  DC.L      $00000000
00BCF8  0000                L0449:DC.W      $0000
00BCFA  000516FC            L044A:DC.L      $000516FC
00BCFE  0000B9FE            L044E:DC.L      $0000B9FE            00 fdcDoRestore
00BD02  0000BA14                  DC.L      $0000BA14            04 fdcDoSeekD1
00BD06  0000BA38                  DC.L      $0000BA38            08 fdcDoStep
00BD0A  0000BA4E                  DC.L      $0000BA4E            0C fdcDoStepIn
00BD0E  0000BA64                  DC.L      $0000BA64            10 fdcDoStepOut
00BD12  0000BA8C                  DC.L      $0000BA8C            14 fdcDoReadSectors
00BD16  0000BA7A                  DC.L      $0000BA7A            18 fdcDoForceInterrupt
00BD1A  0000BB06                  DC.L      $0000BB06            1C fdcDoReadTrackNo
00BD1E  0000BAE8                  DC.L      $0000BAE8            20 fdcDoReadSectorNo
00BD22  0000BB24                  DC.L      $0000BB24            24 fdcDoReadStatus
00BD26  0000BB3A                  DC.L      $0000BB3A            28 fdcDoWriteTrackNo
00BD2A  0000BC86                  DC.L      $0000BC86            2C fdcDoSelectFloppy
00BD2E  1234                      DC.W      $1234

copyProtectionCheck
00BD30  4EB90000B5E0        L044F:JSR       $0000B5E0            fdcDoMoveTrack0
00BD36  303C002C                  MOVE.W    #$2C,D0
00BD3A  323C0002                  MOVE.W    #2,D1
00BD3E  4EB90000B9D6              JSR       $0000B9D6            fdcDoAction(fdcDoSelectFloppy)
00BD44  303C1F40                  MOVE.W    #$1F40,D0
00BD48  51C8FFFE            L0450:DBF       D0,-2(PC)            L0450
00BD4C  303C0004                  MOVE.W    #4,D0
00BD50  323C004E                  MOVE.W    #$4E,D1
00BD54  4EB90000B9D6              JSR       $0000B9D6            fdcDoAction(fdcDoSeekD1)
00BD5A  4EB90000BDAE              JSR       $0000BDAE            fdcReadTrack
00BD60  4EB90000BE28              JSR       $0000BE28            dmaReadAddress
00BD66  23C00000BE5E              MOVE.L    D0,$0000BE5E         L045A
00BD6C  303C1F40                  MOVE.W    #$1F40,D0
00BD70  51C8FFFE            L0451:DBF       D0,-2(PC)            L0451
00BD74  303C000C                  MOVE.W    #$C,D0
00BD78  4EB90000B9D6              JSR       $0000B9D6            fdcDoAction(fdcDoStepIn)
00BD7E  4EB90000BDAE              JSR       $0000BDAE            fdcReadTrack
00BD84  4EB90000BE28              JSR       $0000BE28            dmaReadAddress
00BD8A  91B90000BE5E              SUB.L     D0,$0000BE5E         L045A
00BD90  303C1F40                  MOVE.W    #$1F40,D0
00BD94  51C8FFFE            L0452:DBF       D0,-2(PC)            L0452
00BD98  4EB90000B5E0              JSR       $0000B5E0            fdcDoMoveTrack0
00BD9E  0CB9000000640000BE5E      CMPI.L    #100,$0000BE5E       L045A
00BDA8  6D00FF86                  BLT       -122(PC)             L044F
00BDAC  4E75                      RTS

fdcReadTrack
00BDAE  303C2710            L0453:MOVE.W    #$2710,D0
00BDB2  51C8FFFE            L0454:DBF       D0,-2(PC)            L0454
00BDB6  41F90001457C              LEA       $1457C,A0
00BDBC  4EB90000BE42              JSR       $0000BE42            dmaWriteAddress
00BDC2  33FC009000FF8606          MOVE.W    #$90,$FF8606.L
00BDCA  33FC019000FF8606          MOVE.W    #$190,$FF8606.L
00BDD2  33FC009000FF8606          MOVE.W    #$90,$FF8606.L
00BDDA  4EB90000BE16              JSR       $0000BE16            fdcDelay
00BDE0  33FC001F00FF8604          MOVE.W    #$1F,$FF8604.L
00BDE8  4EB90000BE16              JSR       $0000BE16            fdcDelay
00BDEE  33FC008000FF8606          MOVE.W    #$80,$FF8606.L
00BDF6  4EB90000BE16              JSR       $0000BE16            fdcDelay
00BDFC  33FC00E400FF8604          MOVE.W    #$E4,$FF8604.L
00BE04  4EB90000BE16              JSR       $0000BE16            fdcDelay
00BE0A  0839000500FFFA01    L0455:BTST      #5,$FFFA01.L
00BE12  66F6                      BNE.S     -10(PC)              L0455
00BE14  4E75                      RTS

fdcDelay
00BE16  40E7                L0456:MOVE      SR,-(A7)
00BE18  3F07                      MOVE.W    D7,-(A7)
00BE1A  3E3C0020                  MOVE.W    #$20,D7
00BE1E  51CFFFFE            L0457:DBF       D7,-2(PC)            L0457
00BE22  3E1F                      MOVE.W    (A7)+,D7
00BE24  46DF                      MOVE      (A7)+,SR
00BE26  4E75                      RTS

dmaReadAddress
00BE28  4280                L0458:CLR.L     D0
00BE2A  103900FF8609              MOVE.B    $FF8609.L,D0
00BE30  E188                      LSL.L     #8,D0
00BE32  103900FF860B              MOVE.B    $FF860B.L,D0
00BE38  E188                      LSL.L     #8,D0
00BE3A  103900FF860D              MOVE.B    $FF860D.L,D0
00BE40  4E75                      RTS

dmaWriteAddress
00BE42  2008                L0459:MOVE.L    A0,D0
00BE44  13C000FF860D              MOVE.B    D0,$FF860D.L
00BE4A  E088                      LSR.L     #8,D0
00BE4C  13C000FF860B              MOVE.B    D0,$FF860B.L
00BE52  E088                      LSR.L     #8,D0
00BE54  13C000FF8609              MOVE.B    D0,$FF8609.L
00BE5A  4E75                      RTS

00BE5C  5678                      DC.W      $5678
00BE5E  00000120            L045A:DC.L      $00000120

Atari ST Protection: Garfield

Track 79: shorter than 6100 bytes (and longer than 4996 bytes), that is not possible to be written with a standard drive. Pretty standard.

; allocate screen buffer
0x0d452: 0x2f3c 0x0000 0x9000                       MOVE.L   #0x9000,-(A7)
0x0d458: 0x3f3c 0x0048                              MOVE.W   #0x48,-(A7)
0x0d45c: 0x4e41                                     TRAP     #0x1
0x0d45e: 0x6700 0xfa8e                              BEQ      *-0x570 [0xCEEE]
0x0d462: 0x5c8f                                     ADDQ.L   #6,A7
0x0d464: 0x2d40 0x0142                              MOVE.L   D0,(0x142,A6)

...

; check copy protection with allocated screen buffer as track buffer.
; This buffer is reused right after this call.
0x0d4d2: 0x206e 0x0142                              MOVEA.L  (0x142,A6),A0
0x0d4d6: 0x6100 0x4430                              BSR      *+0x4432 [0x11908]
0x0d4da: 0x4a00                                     TST.B    D0
0x0d4dc: 0x6704                                     BEQ.S    *+0x6 [0xD4E2]

; protection failed, jump to beginning of init routine, but because of supervisor
; mode it will crash with a bus error initializing the IKBD...
0x0d4de: 0x6000 0xfa0e                              BRA      *-0x5F0 [0xCEEE]

...


----------------------------------------------------------------------------------------------------

0x11908: 0x48e7 0x7f7e                              MOVEM.L  D1-D7/A1-A6,-(A7)
0x1190c: 0x23c8 0x0001 0x1d1a                       MOVE.L   A0,0x11D1A         ;track buffer
0x11912: 0x13fc 0x0000 0x0001 0x1d1e                MOVE.B   #0,0x11D1E         ;supervisor mode flag
0x1191a: 0x263c 0x0000 0x0001                       MOVE.L   #1,D3
0x11920: 0x23c3 0x0001 0x1d20                       MOVE.L   D3,0x11D20         ;retry counter
0x11926: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x1192c: 0x4eb9 0x0001 0x1ce8                       JSR      InitProtBuffer
0x11932: 0x50f9 0x0000 0x043e                       ST .B    0x43E
0x11938: 0x4eb9 0x0001 0x19ea                       JSR      YMPortDeselect
0x1193e: 0x4eb9 0x0001 0x1a28                       JSR      FDCForceInterrupt
0x11944: 0x4eb9 0x0001 0x1a4c                       JSR      FDCSeekTrack79
0x1194a: 0x4eb9 0x0001 0x1aa2                       JSR      FDCReadTrack
0x11950: 0x4eb9 0x0001 0x1aa2                       JSR      FDCReadTrack
0x11956: 0x4eb9 0x0001 0x1a28                       JSR      FDCForceInterrupt
0x1195c: 0x4eb9 0x0001 0x1baa                       JSR      YMDeselectFloppy
0x11962: 0x51f9 0x0000 0x043e                       SF .B    0x43E
0x11968: 0x4eb9 0x0001 0x1bc4                       JSR      ExitSuper
0x1196e: 0x4eb9 0x0001 0x1ca0                       JSR      CheckProtBuffer
0x11974: 0x1039 0x0001 0x1d08                       MOVE.B   0x11D08,D0         ;failed flag
0x1197a: 0xb03c 0x0000                              CMP.B    #0,D0
0x1197e: 0x6700 0x000c                              BEQ      *+0xE [0x1198C]
0x11982: 0x2639 0x0001 0x1d20                       MOVE.L   0x11D20,D3         ;retry counter
0x11988: 0x51cb 0xff96                              DBF      D3,*-0x68 [0x11920]
0x1198c: 0x4cdf 0x7efe                              MOVEM.L  (A7)+,D1-D7/A1-A6
0x11990: 0x4e75                                     RTS

EnterSuper
0x11992: 0x2f3c 0x0000 0x0001                       MOVE.L   #1,-(A7)
0x11998: 0x3f3c 0x0020                              MOVE.W   #0x20,-(A7)
0x1199c: 0x4e41                                     TRAP     #1
0x1199e: 0xdffc 0x0000 0x0006                       ADDA.L   #6,A7
0x119a4: 0x4a40                                     TST.W    D0
0x119a6: 0x6600 0x002c                              BNE      *+0x2E [0x119D4]
0x119aa: 0x42a7                                     CLR.L    -(A7)
0x119ac: 0x3f3c 0x0020                              MOVE.W   #0x20,-(A7)
0x119b0: 0x4e41                                     TRAP     #1
0x119b2: 0xdffc 0x0000 0x0006                       ADDA.L   #6,A7
0x119b8: 0x23c0 0x0001 0x1d0a                       MOVE.L   D0,0x11D0A         ;USP stack pointer
0x119be: 0x1239 0x0001 0x1d1e                       MOVE.B   0x11D1E,D1         ;supervisor mode flag
0x119c4: 0x4a01                                     TST.B    D1
0x119c6: 0x6600 0x0020                              BNE      *+0x22 [0x119E8]
0x119ca: 0x13fc 0x0002 0x0001 0x1d1e                MOVE.B   #2,0x11D1E         ;supervisor mode flag
0x119d2: 0x4e75                                     RTS
0x119d4: 0x1239 0x0001 0x1d1e                       MOVE.B   0x11D1E,D1         ;supervisor mode flag
0x119da: 0x4a01                                     TST.B    D1
0x119dc: 0x6600 0x000a                              BNE      *+0xC [0x119E8]
0x119e0: 0x13fc 0x0001 0x0001 0x1d1e                MOVE.B   #1,0x11D1E         ;supervisor mode flag
0x119e8: 0x4e75                                     RTS

YMPortDeselect:
0x119ea: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x119f0: 0x303c 0x0000                              MOVE.W   #0,D0
0x119f4: 0x5200                                     ADDQ.B   #1,D0
0x119f6: 0xe308                                     LSL.B    #1,D0
0x119f8: 0x0040 0x0000                              ORI.W    #0,D0
0x119fc: 0x0a00 0x0007                              EORI.B   #7,D0
0x11a00: 0x0200 0x0007                              ANDI.B   #7,D0

YMPortSelect:
0x11a04: 0x40e7                                     MOVE     SR,-(A7)
0x11a06: 0x007c 0x0700                              ORI      #0x700,SR
0x11a0a: 0x13fc 0x000e 0x00ff 0x8800                MOVE.B   #0xE,0xFF8800
0x11a12: 0x1239 0x00ff 0x8800                       MOVE.B   0xFF8800,D1
0x11a18: 0x0201 0x00f8                              ANDI.B   #0xF8,D1
0x11a1c: 0x8200                                     OR.B     D0,D1
0x11a1e: 0x13c1 0x00ff 0x8802                       MOVE.B   D1,0xFF8802
0x11a24: 0x46df                                     MOVE     (A7)+,SR
0x11a26: 0x4e75                                     RTS

FDCForceInterrupt:
0x11a28: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11a2e: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606
0x11a36: 0x3c3c 0x00d0                              MOVE.W   #0xD0,D6
0x11a3a: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg
0x11a40: 0x3e3c 0x0028                              MOVE.W   #40,D7
0x11a44: 0x4eb9 0x0001 0x1bfe                       JSR      DelayD7
0x11a4a: 0x4e75                                     RTS

FDCSeekTrack79:
0x11a4c: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11a52: 0x4eb9 0x0001 0x1c42                       JSR      0x11C42
0x11a58: 0x33fc 0x0086 0x00ff 0x8606                MOVE.W   #0x86,0xFF8606
0x11a60: 0x3c3c 0x004f                              MOVE.W   #0x4F,D6
0x11a64: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg
0x11a6a: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606
0x11a72: 0x3c3c 0x001b                              MOVE.W   #0x1B,D6
0x11a76: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg
0x11a7c: 0x2e3c 0x0006 0x0000                       MOVE.L   #0x60000,D7
0x11a82: 0x5387                                     SUBQ.L   #1,D7
0x11a84: 0x6700 0x0010                              BEQ      *+0x12 [0x11A96]
0x11a88: 0x0839 0x0005 0x00ff 0xfa01                BTST     #5,0xFFFA01
0x11a90: 0x6600 0xfff0                              BNE      *-0xE [0x11A82]
0x11a94: 0x4e75                                     RTS
0x11a96: 0x3f3c 0xfff9                              MOVE.W   #0xFFF9,-(A7)
0x11a9a: 0x4eb9 0x0001 0x1c9e                       JSR      0x11C9E
0x11aa0: 0x4e75                                     RTS

FDCReadTrack:
0x11aa2: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11aa8: 0x42b9 0x0001 0x1d12                       CLR.L    0x11D12        ;current DMA address pointer
0x11aae: 0x40f9 0x0001 0x1d02                       MOVE     SR,0x11D02     ;saved status register
0x11ab4: 0x46fc 0x2700                              MOVE     #0x2700,SR
0x11ab8: 0x33fc 0x0090 0x00ff 0x8606                MOVE.W   #0x90,0xFF8606
0x11ac0: 0x33fc 0x0190 0x00ff 0x8606                MOVE.W   #0x190,0xFF8606
0x11ac8: 0x33fc 0x0090 0x00ff 0x8606                MOVE.W   #0x90,0xFF8606
0x11ad0: 0x3c3c 0x0016                              MOVE.W   #22,D6         ;22 Sectors
0x11ad4: 0x343c 0x0200                              MOVE.W   #0x200,D2
0x11ad8: 0xc4c6                                     MULU.W   D6,D2
0x11ada: 0x33c2 0x0001 0x1d04                       MOVE.W   D2,0x11D04     ;number of bytes to read
0x11ae0: 0x2639 0x0001 0x1d1a                       MOVE.L   0x11D1A,D3     ;track buffer
0x11ae6: 0xd483                                     ADD.L    D3,D2
0x11ae8: 0x23c2 0x0001 0x1d0e                       MOVE.L   D2,0x11D0E     ;calculated DMA end address
0x11aee: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg    ;write sector count

0x11af4: 0x2039 0x0001 0x1d1a                       MOVE.L   0x11D1A,D0     ;track buffer
0x11afa: 0x13c0 0x00ff 0x860d                       MOVE.B   D0,0xFF860D
0x11b00: 0xe088                                     LSR.L    #8,D0
0x11b02: 0x13c0 0x00ff 0x860b                       MOVE.B   D0,0xFF860B    ;DMA base address to buffer start
0x11b08: 0xe088                                     LSR.L    #8,D0
0x11b0a: 0x13c0 0x00ff 0x8609                       MOVE.B   D0,0xFF8609

0x11b10: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606 ;FDC Command Register
0x11b18: 0x3c3c 0x00e8                              MOVE.W   #0xE8,D6
0x11b1c: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg    ;Read Track

0x11b22: 0x2e3c 0x0005 0x0000                       MOVE.L   #0x50000,D7
0x11b28: 0x2a79 0x0001 0x1d0e                       MOVEA.L  0x11D0E,A5     ;calculated DMA end address
0x11b2e: 0x303c 0x0200                              MOVE.W   #0x200,D0
0x11b32: 0x51c8 0xfffe                              DBF      D0,*-0x0 [0x11B32] ;little delay
0x11b36: 0x0839 0x0005 0x00ff 0xfa01                BTST     #5,0xFFFA01    ;FDC done?
0x11b3e: 0x6700 0x0030                              BEQ      *+0x32 [0x11B70]
0x11b42: 0x5387                                     SUBQ.L   #1,D7          ;timeout?
0x11b44: 0x6700 0x0060                              BEQ      *+0x62 [0x11BA6]
0x11b48: 0x13f9 0x00ff 0x8609 0x0001 0x1d13         MOVE.B   0xFF8609,0x11D12+1
0x11b52: 0x13f9 0x00ff 0x860b 0x0001 0x1d14         MOVE.B   0xFF860B,0x11D12+2
0x11b5c: 0x13f9 0x00ff 0x860d 0x0001 0x1d15         MOVE.B   0xFF860D,0x11D12+3
0x11b66: 0xbbf9 0x0001 0x1d12                       CMPA.L   0x11D12,A5     ;check current DMA address
0x11b6c: 0x6e00 0xffc8                              BGT      *-0x36 [0x11B36]

0x11b70: 0x33fc 0x0090 0x00ff 0x8606                MOVE.W   #0x90,0xFF8606
0x11b78: 0x3a39 0x00ff 0x8606                       MOVE.W   0xFF8606,D5    ;FDC status
0x11b7e: 0x33c5 0x0001 0x1d06                       MOVE.W   D5,0x11D06     ;FDC status
0x11b84: 0x0805 0x0000                              BTST     #0,D5          ;Still Busy?
0x11b88: 0x6700 0x0018                              BEQ      *+0x1A [0x11BA2]
0x11b8c: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606
0x11b94: 0x4eb9 0x0001 0x1c80                       JSR      FDCReadRegB
0x11b9a: 0x46f9 0x0001 0x1d02                       MOVE     0x11D02,SR     ;saved status register
0x11ba0: 0x4e75                                     RTS
0x11ba2: 0x6000 0xfff6                              BRA      *-0x8 [0x11B9A]
0x11ba6: 0x6000 0xfff2                              BRA      *-0xC [0x11B9A]

YMDeselectFloppy:
0x11baa: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11bb0: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606
0x11bb8: 0x103c 0x0007                              MOVE.B   #7,D0
0x11bbc: 0x4eb9 0x0001 0x1a04                       JSR      YMPortSelect
0x11bc2: 0x4e75                                     RTS

ExitSuper:
0x11bc4: 0x1039 0x0001 0x1d1e                       MOVE.B   0x11D1E,D0             ;supervisor mode flag
0x11bca: 0x5300                                     SUBQ.B   #1,D0
0x11bcc: 0x4a00                                     TST.B    D0
0x11bce: 0x6700 0x002c                              BEQ      *+0x2E [0x11BFC]
0x11bd2: 0x2f3c 0x0000 0x0001                       MOVE.L   #1,-(A7)
0x11bd8: 0x3f3c 0x0020                              MOVE.W   #0x20,-(A7)
0x11bdc: 0x4e41                                     TRAP     #1
0x11bde: 0xdffc 0x0000 0x0006                       ADDA.L   #6,A7
0x11be4: 0x4a40                                     TST.W    D0
0x11be6: 0x6700 0x0014                              BEQ      *+0x16 [0x11BFC]
0x11bea: 0x2f39 0x0001 0x1d0a                       MOVE.L   0x11D0A,-(A7)         ;USP stack pointer
0x11bf0: 0x3f3c 0x0020                              MOVE.W   #0x20,-(A7)
0x11bf4: 0x4e41                                     TRAP     #1
0x11bf6: 0xdffc 0x0000 0x0006                       ADDA.L   #6,A7
0x11bfc: 0x4e75                                     RTS

DelayD7:
0x11bfe: 0x51cf 0xfffe                              DBF      D7,*-0x0 [0x11BFE]
0x11c02: 0x4e75                                     RTS

FDCWriteReg:
0x11c04: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11c0a: 0x4eb9 0x0001 0x1c30                       JSR      fdcDelay
0x11c10: 0x33c6 0x00ff 0x8604                       MOVE.W   D6,0xFF8604
0x11c16: 0x4eb9 0x0001 0x1c30                       JSR      fdcDelay
0x11c1c: 0x4e75                                     RTS

FDCReadReg:
0x11c1e: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11c24: 0x3639 0x00ff 0x8604                       MOVE.W   0xFF8604,D3
0x11c2a: 0x4eb9 0x0001 0x1c30                       JSR      fdcDelay

fdcDelay
0x11c30: 0x40e7                                     MOVE     SR,-(A7)
0x11c32: 0x3f07                                     MOVE.W   D7,-(A7)
0x11c34: 0x3e3c 0x0028                              MOVE.W   #40,D7
0x11c38: 0x51cf 0xfffe                              DBF      D7,*-0x0 [0x11C38]
0x11c3c: 0x3e1f                                     MOVE.W   (A7)+,D7
0x11c3e: 0x46df                                     MOVE     (A7)+,SR
0x11c40: 0x4e75                                     RTS

0x11c42: 0x3c39 0x0001 0x1d16                       MOVE.W   0x11D16,D6
0x11c48: 0x0246 0x0003                              ANDI.W   #3,D6
0x11c4c: 0x2e3c 0x0005 0x0000                       MOVE.L   #0x50000,D7
0x11c52: 0x33fc 0x0080 0x00ff 0x8606                MOVE.W   #0x80,0xFF8606
0x11c5a: 0x4eb9 0x0001 0x1c04                       JSR      FDCWriteReg
0x11c60: 0x5387                                     SUBQ.L   #1,D7
0x11c62: 0x6700 0x0010                              BEQ      *+0x12 [0x11C74]
0x11c66: 0x0839 0x0005 0x00ff 0xfa01                BTST     #0x5,0xFFFA01
0x11c6e: 0x6600 0xfff0                              BNE      *-0xE [0x11C60]
0x11c72: 0x4e75                                     RTS
0x11c74: 0x3f3c 0xfff9                              MOVE.W   #0xFFF9,-(A7)
0x11c78: 0x4eb9 0x0001 0x1c9e                       JSR      0x11C9E
0x11c7e: 0x4e75                                     RTS                         ;crash because of 0xFFF9 on the stack

FDCReadRegB:
0x11c80: 0x4eb9 0x0001 0x1992                       JSR      EnterSuper
0x11c86: 0x4eb9 0x0001 0x1c30                       JSR      fdcDelay
0x11c8c: 0x33f9 0x00ff 0x8604 0x0001 0x1d18         MOVE.W   0xFF8604,0x11D18   ;FDC register
0x11c96: 0x4eb9 0x0001 0x1c30                       JSR      fdcDelay
0x11c9c: 0x4e75                                     RTS

0x11c9e: 0x4e75                                     RTS


CheckProtBuffer:
0x11ca0: 0x2239 0x0001 0x1d1a                       MOVE.L   0x11D1A,D1     ;track buffer
0x11ca6: 0x0681 0x0000 0x2ee0                       ADDI.L   #6000*2,D1     ;6000 word buffer
0x11cac: 0x2041                                     MOVEA.L  D1,A0
0x11cae: 0x263c 0x0000 0x0dac                       MOVE.L   #3500,D3       ;compare up to 3501 words
0x11cb4: 0x243c 0x0000 0x0000                       MOVE.L   #0,D2          ;byte counter of unused bytes in the track buffer
0x11cba: 0x3a20                                     MOVE.W   -(A0),D5
0x11cbc: 0x3020                                     MOVE.W   -(A0),D0
0x11cbe: 0xba40                                     CMP.W    D0,D5
0x11cc0: 0x660a                                     BNE.S    *+0xC [0x11CCC]
0x11cc2: 0x5482                                     ADDQ.L   #2,D2
0x11cc4: 0x51cb 0xfff6                              DBF      D3,*-0x8 [0x11CBC]
0x11cc8: 0x6000 0x0014                              BRA      *+0x16 [0x11CDE]   ;track too short (shorter than 4996 bytes) => failed
0x11ccc: 0x0482 0x0000 0x170c                       SUBI.L   #5900,D2       ;track length larger than (12000-5900) = 6100 bytes? => fail!
0x11cd2: 0x6b0a                                     BMI.S    *+0xC [0x11CDE]
0x11cd4: 0x13fc 0x0000 0x0001 0x1d08                MOVE.B   #0,0x11D08     ;failed flag = not failed
0x11cdc: 0x4e75                                     RTS
0x11cde: 0x13fc 0x0001 0x0001 0x1d08                MOVE.B   #1,0x11D08     ;failed flag = failed protection
0x11ce6: 0x4e75                                     RTS

InitProtBuffer:
0x11ce8: 0x243c 0x0000 0x176f                       MOVE.L   #5999,D2
0x11cee: 0x2079 0x0001 0x1d1a                       MOVEA.L  0x11D1A,A0     ;track buffer
0x11cf4: 0x2639 0x0000 0x04ba                       MOVE.L   0x4BA.w,D3     ; _hz_200
0x11cfa: 0x30c3                                     MOVE.W   D3,(A0)+       ;fill track buffer with "random" filler
0x11cfc: 0x51ca 0xfffc                              DBF      D2,*-0x2 [0x11CFA]
0x11d00: 0x4e75                                     RTS

0x11D02: 0000           ;saved status register
0x11D04: 0000           ;number of track bytes to read
0x11D06: 0000           ;FDC status
0x11D08: 0000           ;failed flag (0 = protection OK, 1 = protection failed)
0x11D0A: 00000000       ;USP stack pointer
0x11D0E: 00000000       ;DMA end address
0x11D12: 00000000       ;current DMA address pointer
0x11D16: 0003           ;floppy port selection bits
0x11D18: 0000           ;FDC register
0x11D1A: 00000000       ;track buffer
0x11D1E: 0000           ;supervisor mode flag
0x11D20: 00000000       ;retry counter

Atari ST Protection: Brataccas

The protection is also simple: track 81, sector 20 has to contain at least 71 times ‘JAKE’ at the beginning. It then reads sector 1 in track 5, which has to have a CRC error in the data block (the FDC status has bit 3 set, but not bit 4).

Interesting, but not as interesting as the code in the boot sector. Michael K. Glover had some fun with it:

This is the executed code:

$FFFF8800 = $0E, $FFFF8802 = $05    ;Select Disk A, Side 0
$FFFF8606 = $80, $FFFF8604 = $03    ;CMD Restore
WAIT BTST #0,$FA01                  ;wait for completion
$FFFF8606 = $86, $FFFF8604 = $0A    ;DATA = 10
$FFFF8606 = $80, $FFFF8604 = $10    ;CMD Seek to track 10
WAIT BTST #0,$FA01                  ;wait for completion
$FFFF8606 = $84, $FFFF8604 = $0A    ;SECTOR = 10
$FFFF8606 = $82, $FFFF8604 = $45    ;TRACK = $45
$FFFF8609 = $00, $FFFF860B = $04, $FFFF860D = $80,  ;DMA ADDRESS = $000480
$FFFF8606 = $90, $FFFF8606 = $190, $FFFF8606 = $90  ;DMA read
$FFFF8604 = $01                     ;1 sector (512 bytes)
$FFFF8606 = $80, $FFFF8604 = $80    ;CMD Read Sector
WAIT BTST #0,$FA01                  ;wait for completion
JMP (A6) => $480


    TEXT
$0000 BRA.S     L0000
$0002 DC.B      'M.Glover',$00
$000B DC.B      $00,$02, $02, $01,$00, $02, $70,$00, $D0,$02, $F8, $05,$00, $09,$00, $01,$00, $00,$00
$001E DC.B      $00,$00, $00,$00, $00,$00, $00,$00, $00,$00, $00,$00
    DC.B      $00,$04, $00,$00, $00,$00,$80,$00
    DC.B      'TOS     IMG',$00

L0000:MOVE      #$2700,SR
    BRA       L000E

    DC.B      'This beauty by Michael K. Glover.(JAKE)'
    DC.B      'I dont know about "NEUTER BOOTER",but you need real balls to check this out!!!',0

    //        D0    D4    D5    D6    D7    A1    A2    A3    A4    A5
L0001:DC.W      $0000,$0001,$0001,$0000,$001A,$8800,$8608,$FA01,$8609,$000F

L0002:
$00CC EXT.W     D0
$00CE MOVEM.W   L0001(PC,D0.W),A1-A5/D4-D7/D0
$00D4 MOVEM.L   L0005(PC,D7.W),A6-A7            ; L0007
$00DA LEA       L0007+3(PC,A5.L),A5

L0003:
$00DE MOVE.B    (A5)+,D6
$00E0 MOVE.B    D6,(A1)+            ;select floppy and side
$00E2 ADDQ.L    #1,A1
$00E4 DBF       D5,L0003

L0004:
$00E8 JSR       L000C(PC,D7.W)  ;L000D
$00EC JSR       L0004(PC,D7.W)  ;L0008
$00F0 JSR       L000B(PC,D7.W)  ;L000D
$00F4 JSR       L0006(PC,D7.W)  ;L0008
$00F8 JSR       L0009(PC,D7.W)  ;L000D

;set DMA address
$00FC MOVE.W    (A5)+,D2
$00FE MOVE.B    D2,(A4)+
$0100 ADDQ.L    #1,A4
L0005:
$0102 DBF       D7,$00FC

;$90,$190,$90 => FFFF8606
$0106 ADDQ.L    #2,A0
$0108 MOVE.W    (A5)+,(A0)
$010A DBF       D4,$0108
$010E MOVEQ     #1,D0
$0110 JSR       L0010(PC,D7.W)  ;$0167 + D7 (-1) => $0166 = L000D
L0006 EQU $0112
$0114 JSR       L0003(PC,D7.W)  ;$00DE + $46 => $0124 = L0008
$0118 BRA       L000F

    //        A6    A7
L0007:
$011C DC.W      $0000,$0480
$0120 DC.W      $0007,$0000

L0008:
$0124 BTST      D6,(A3)
$0126 BNE.S     L0008
$0128 MOVE.W    (A5)+,D7
L0009:
$012A MOVE.W    (A5)+,D0
L000A:
$012C RTS

L000X:
$012E DC.B      $0E,$05
$0130 DC.W      $0080,$0003,$003C   ;=> L0008
$0136 DC.W      $0028,$0001         ;=> L000D, D0=1

$013A DC.W      $0086,$000A
L000B:
$013E DC.W      $0080,$0010,$0012   ;L0008

    DC.W      $003C,$0001         ;L000D
    DC.W      $0084,$000A
L000C:DC.W      $0082,$0045,$0002
    DC.W      $0000,$0004,$0080
    DC.W      $0090,$0190,$0090
    DC.W      $0001,$0080,$0080,$0046

L000D:
$0166 MOVEA.L   A2,A0
L0010 EQU       *-1
    MOVE.W    (A5)+,-(A0)
    BSR.S     L000A
    MOVE.W    (A5)+,-(A0)
    DBF       D0,L000D
    MOVE.W    (A5)+,D7
    RTS

    DC.B      'So there it is. What a little beauty Eh?'

L000E:MOVE      SR,D0
    ORI.W     #0,D0
    ORI.W     #6,D1
    ORI.W     #8,D1
    ORI.W     #0,D1
    BRA       L0002

    DC.B      'The code in this game is by Dave,Jake and Phil!!'

L000F:JMP       (A6)

    ; checksum
    DC.B      $90,$EE,$00,$00,$00,$00,$00,$00
    DCB.W     9,0

Atari ST Protection: Turrican

The boot sector starts quite interesting: copying code to address 8 and executing it there. The format of the disk is different, but not special: sector 1 in the track is 512 bytes long, sector 2–6 are each 1024 bytes long. 5632 bytes per track out of possible 6250 bytes, pretty good capacity on a double sided disk. The trick is that the last 1024 byte sector starts at the end of the track and extends for more than 500 bytes over the index marker. The first sector is packed right after the sector at the beginning. The tracks 75..79 are not used. Strangely on the back side Track 79 contains an empty 512 sector, which does not seem to be part of the protection.

Track 7 to 10 contain the actual protection. The test starts in track 7 and tests the protection, if it fails it continous till track 10 to find a valid protection. If it fails on all 4 tracks, it erases the memory till it crashes…

The usual 6 sectors exist in these tracks, but they also contain sector 0 and 16 in different positions (the position is not tested). They are supposed to be each 1024 bytes long, but they only have an address mark plus the sector header and can not be read without a CRC error. The reason for this is interesting and István Fábián figured out what is going on the the actual disk medium! http://www.atari-forum.com/viewtopic.php?f=47&t=19948&start=25

Track  7: sector order: 5,3,6, 0,16, 1,4,2
Track  8: sector order:  0,16, 1,4,2,5,3,6
Track  9: sector order:  5,3,6, 0,16, 1,4,2
Track 10: sector order:  0,16, 1,4,2,5,3,6

Sector 0 starts with the following data, as you can see it clearly contains the sector header of sector 16! You can also see four weird bytes: 0x14, 0x14, 0x14, 0x00. These bytes are actually 3 sync markers 0xa1 and another sector header 0xfe, but shifted by one bit and the FDC will re-sync to them when trying to read sector 16. And because data bits and clock bits are interleaved, the re-sync will now actually read the clock bits instead of the data bits! The protection therefore reads the data bits via sector 0 (re-sync is disabled after a 0xFE is found for 1024 bytes plus CRC) and then the clock bits via sector 16.

0000   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
0010   A1 A1 A1 FE 07 00 10 03 BB 21 4E 4E 4E 4E 4E 4E    .........!NNNNNN
0020   4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E    NNNNNNNNNNNNNNNN
0030   FF FF FF FF FF FF FF FF FF FF FF FE 14 14 14 00    ................
0040   FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF    ................
0050   80 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00    ................
0060   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

The DMA read code ignores the first 64 bytes, which is a gap and the re-sync for the sector 16. The following 16 bytes have to contain 0xFF bytes and other 32 bytes have to have more than 204 cleared bits (out of 256 possible bits).

Sector 16 (the clock bits) starts with the following data:

0000   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
0010   40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    @...............
0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

The first 16 bytes have to contain 0x00 bytes and other 32 bytes have to have more than 204 cleared bits (out of 256 possible bits), because of clock drift the FDC probably can randomly read a 1 instead of a 0.

copyProtection:
    MOVEM.L   A0-A6/D0-D7,-(A7)
    MOVE.L    #$100000,D0
L056B:SUBQ.L    #1,D0           ;delay
    BNE.S     L056B
    MOVE      SR,-(A7)
    BTST      #5,(A7)
    BNE.S     L056C
    CLR.L     -(A7)
    MOVE.W    #$20,-(A7)    ;SUPER
    TRAP      #1
    MOVE.L    D0,2(A7)
L056C:MOVE      #$2700,SR

    BSR       clearKeyboard

    LEA       $FFFF8000.W,A4  ;ffff8000
    LEA       1549(A4),A3     ;ffff860d
    LEA       1542(A4),A2     ;ffff8606
    LEA       1540(A4),A1     ;ffff8604
    LEA       31233(A4),A0    ;fffffa01

    MOVEQ     #5,D0
    BSR       selectFloppy

    MOVE.W    #$82,(A2)       ;track register
    BSR       fdcDelay
    MOVE.W    (A1),D0
    ANDI.W    #$FF,D0
    MOVE.W    D0,-(A7)        ;current track

    MOVE.W    #$80,(A2)
    MOVEQ     #$01,D2
    BSR       fdcCommand      ;Restore

    MOVEQ     #7,D7           ;start with track 7
L056D:MOVE.W    D7,D2
    BSR       fdcSeek
    BSR       checkSectors
    TST.W     D6
    BPL.S     L056F
    ADDQ.W    #1,D7
    CMPI.W    #10,D7          ;up to track 10
    BLE.S     L056D

    LEA       $80000,A7
L056E:CLR.L     -(A7)           ;erase everything and crash...
    BRA.S     L056E

L056F:MOVE.W    (A7)+,D2        ;current track
    BSR       fdcSeek
L0570:MOVE.W    (A1),D0         ;wait for motor off
    TST.B     D0
    BMI.S     L0570
    MOVEQ     #7,D0
    BSR       selectFloppy    ;deselect drive
    BSR.S     clearKeyboard
    MOVE.W    (A7)+,D0
    CMPI.W    #$20,D0         ;supervisor mode active?
    BNE.S     L0571
    MOVEA.L   (A7)+,A0
    MOVE.W    (A7)+,D0
    MOVE      A7,USP          ;back to user mode
    MOVEA.L   A0,A7
L0571:MOVE      D0,SR
    MOVEM.L   (A7)+,A0-A6/D0-D7
    BRA       copyProtectionReturn

clearKeyboard
    MOVEQ     #$FF,D0
L0573:BTST      #0,$FFFFFC00.W
    BEQ.S     L0574
    MOVE.B    $FFFFFC02.W,D0
    BRA.S     clearKeyboard
L0574:DBF       D0,L0573
    RTS

checkSectors:
    MOVEQ     #4,D6           ;5 tries
checkSectorsTries:
    MOVEQ     #0,D1           ;sector 0
    MOVEQ     #4,D5           ;skip 5 DMA buffer (one empty at the beginning)
    LEA       -128(A7),A5     ;base address
    BSR       readSector
    MOVEQ     #15,D0
L0577:CMPI.B    #$FF,(A5)+      ;16 0xFF bytes have to be at the beginning of the buffer
    BNE.S     checkSectorsFailed
    DBF       D0,L0577
    BSR       countClearedBits
    CMPI.W    #$CC,D0         ;at least 204 cleared bits have to be in the buffer
    BLT.S     checkSectorsFailed

    MOVEQ     #16,D1          ;sector 16
    MOVEQ     #0,D5           ;skip 1 DMA buffer (which is empty anyway)
    LEA       -64(A7),A5      ;base address
    BSR       readSector
    MOVEQ     #15,D0
L0578:TST.B     (A5)+           ;16 0x00 bytes have to be at the beginning of the buffer
    BNE.S     checkSectorsFailed
    DBF       D0,L0578
    BSR.S     countClearedBits
    CMPI.W    #$CC,D0         ;at least 204 cleared bits have to be in the buffer
    BGE.S     checkSectorsSuccess
checkSectorsFailed:
    DBF       D6,checkSectorsTries
checkSectorsSuccess:
    RTS

;count the number of cleared bits in 32 bytes
countClearedBits:
    MOVEQ     #0,D0
    MOVEQ     #31,D1
L057C:MOVEQ     #7,D2
L057D:BTST      D2,(A5)
    BNE.S     L057E
    ADDQ.L    #1,D0
L057E:DBF       D2,L057D
    ADDQ.L    #1,A5
    DBF       D1,L057C
    RTS

readSector:
    MOVE.L    A5,D0
    MOVE.B    D0,(A3)
    LSR.W     #8,D0
    MOVE.B    D0,1547(A4)     ;set the DMA address
    SWAP      D0
    MOVE.B    D0,1545(A4)
    MOVE.W    #$90,(A2)
    MOVE.W    #$190,(A2)      ;read
    MOVE.W    #$90,(A2)
    MOVEQ     #$10,D2
    BSR       fdcWriteD2      ;16*512 byte
    MOVE.W    #$84,(A2)
    MOVE.W    D1,D2           ;sector number
    BSR       fdcWriteD2
    MOVE.W    #$80,(A2)
    BSR       fdcDelay
    MOVE.W    #$80,(A1)       ;read sector

;5+3 DMA buffer = 128 bytes

L0580:MOVEM.L   (A5),D0-D3      ;read original bytes from the buffer
    SUBQ.W    #1,D5           ;5 DMA buffers
    BMI.S     L0582
    MOVE.W    A5,D4
L0581:CMP.B     (A3),D4         ;DMA low unchanged?
    BEQ.S     L0581           ;wait!
    MOVEM.L   D0-D3,(A5)
    LEA       16(A5),A5
    BRA.S     L0580

L0582:MOVEQ     #2,D1
L0583:MOVE.B    (A3),D0
L0584:CMP.B     (A3),D0         ;wait for DMA low to change 3 times
    BEQ.S     L0584
    DBF       D1,L0583

    MOVE.W    #$50,(A2)
    MOVE.W    #$150,(A2)      ;just weird...
    MOVE.W    #$50,(A2)
    BRA       fdcWait

    RTS

selectFloppy:
    MOVE.B    #$E,2048(A4)
    MOVEQ     #$F8,D1
    AND.B     2048(A4),D1
    OR.B      D0,D1
    MOVE.B    D1,2050(A4)
    RTS

fdcSeek:
    MOVE.W    #$86,(A2)
    BSR.S     fdcWriteD2
    MOVE.W    #$80,(A2)
    MOVEQ     #$11,D2
fdcCommand:
    BSR.S     fdcWriteD2
fdcWait:
    BTST      #5,(A0)
    BNE.S     fdcWait
    RTS

fdcWriteD2:
    BSR.S     fdcDelay
    MOVE.W    D2,(A1)

fdcDelay:
    MOVEQ     #$7F,D3
L058B:DBF       D3,L058B
    RTS

copyProtectionReturn:
    RTS

Atari ST Protection: The Sentry or The Sentinel

This protection is in track 20, it searches for $13,$07,$F7,$19,$87,$F7 right AFTER the CRC of sector 9, especially the $F7 is nasty, because the FDC normally writes a two byte CRC when receiving a $F7 with the write track command. Because of a bad implementation these bytes could be written inside sector 9 and it would still work…

001644  605C                      BRA.S     92(PC)               L0000

001646  4E4E4E4E4E4E6969          DC.B      $4E,$4E,$4E,$4E,$4E,$4E,$69,$69
00164E  6900020201000270          DC.B      $69,$00,$02,$02,$01,$00,$02,$70
001656  00D002F805000900          DC.B      $00,$D0,$02,$F8,$05,$00,$09,$00
00165E  01000000                  DC.B      $01,$00,$00,$00

001662                            DC.B 'Copyright (c) 1987 Michael K. Glover/Icom Simulations (U.K.) Ltd'

0016A2  780A                L0000:MOVEQ     #$A,D4
0016A4  2444                      MOVEA.L   D4,A2
0016A6  D4C4                      ADDA.W    D4,A2
0016A8  42AA0010                  CLR.L     16(A2)            ;$24
0016AC  42AA0030                  CLR.L     48(A2)            ;$44
0016B0  4EBA0136                  JSR       310(PC)              loadRegisters

0016B4  1145FFFE                  MOVE.B    D5,-2(A0)           ;$FF8800 = $0E
0016B8  E05D                      ROR.W     #8,D5
0016BA  1085                      MOVE.B    D5,(A0)             ;$FF8802 = $25

0016BC  32BC0080                  MOVE.W    #$80,(A1)           ;$FF8606 = $80
0016C0  4EBA0148                  JSR       328(PC)              clrTrace
0016C4  337C0003FFFE              MOVE.W    #3,-2(A1)           ;$FF8604 = $03   Restore
0016CA  4EBA012C                  JSR       300(PC)              waitFDC

0016CE  2C0E                      MOVE.L    A6,D6               ;buffer address = $30000
0016D0  17460002                  MOVE.B    D6,2(A3)            ;$FF860D = low
0016D4  E05E                      ROR.W     #8,D6
0016D6  1686                      MOVE.B    D6,(A3)             ;$FF860B = mid
0016D8  4846                      SWAP      D6
0016DA  1746FFFE                  MOVE.B    D6,-2(A3)           ;$FF8609 = high
0016DE  3282                      MOVE.W    D2,(A1)             ;$FF8606 = $90
0016E0  8441                      OR.W      D1,D2
0016E2  3282                      MOVE.W    D2,(A1)             ;$FF8606 = $190 DMA Read
0016E4  9441                      SUB.W     D1,D2
0016E6  3282                      MOVE.W    D2,(A1)             ;$FF8606 = $90
0016E8  4EBA0120                  JSR       288(PC)              clrTrace
0016EC  3343FFFE                  MOVE.W    D3,-2(A1)           ;$FF8604 = $1F 31 DMA Sectors
0016F0  4EBA0118                  JSR       280(PC)              clrTrace
0016F4  3284                      MOVE.W    D4,(A1)             ;$FF8606 = $80
0016F6  4EBA0112                  JSR       274(PC)              clrTrace
0016FA  3347FFFE                  MOVE.W    D7,-2(A1)           ;$FF8604 = $E0 Read Track
0016FE  4EBA00F8                  JSR       248(PC)              waitFDC

001702  32BC0086                  MOVE.W    #$86,(A1)           ;$FF8606 = $86
001706  4EBA0102                  JSR       258(PC)              clrTrace
00170A  337C0014FFFE              MOVE.W    #$14,-2(A1)         ;$FF8604 = $14
001710  4EBA00F8                  JSR       248(PC)              clrTrace
001714  3284                      MOVE.W    D4,(A1)             ;$FF8606 = $80
001716  4EBA00F2                  JSR       242(PC)              clrTrace
00171A  337C0013FFFE              MOVE.W    #$13,-2(A1)         ;$FF8606 = $13 Seek Track 20
001720  4EBA00D6                  JSR       214(PC)              waitFDC

001724  224E                      MOVEA.L   A6,A1
001726  D2FC125A                  ADDA.W    #$125A,A1           ;offset before header of sector 9 in track 0
00172A  3C3C0500                  MOVE.W    #$500,D6            ;search to the end of the track
00172E  7E05                L0001:MOVEQ     #5,D7
001730  41FA00F8                  LEA       248(PC),A0           L000F
                                        $13,$07,$F7,$19,$87,$F7 ;these bytes are directly after the CRC of sector 9.
                                                                ;funny thing: you could copy them INTO sector 9 and
                                                                ;the protection would still work.

001734  B308                L0002:CMPM.B    (A0)+,(A1)+
001736  6606                      BNE.S     6(PC)                L0003
001738  51CFFFFA                  DBF       D7,-6(PC)            L0002
00173C  600A                      BRA.S     10(PC)               L0004
00173E  51CEFFEE            L0003:DBF       D6,-18(PC)           L0001
001742  DECB                      ADDA.W    A3,A7               ;kill stackpointer (it will become negative => double bus fault)
001744  4EBA00C4                  JSR       196(PC)              clrTrace

001748  41FA0058            L0004:LEA       88(PC),A0            L0005
00174C  227C00054C00              MOVEA.L   #$54C00,A1
001752  2E3C0000A400              MOVE.L    #$A400,D7
001758  4EBA0062                  JSR       98(PC)               loadFile

00175C  41FA0047                  LEA       71(PC),A0            L0006
001760  227C00048000              MOVEA.L   #$48000,A1
001766  2E3C00007D00              MOVE.L    #$7D00,D7
00176C  4EBA004E                  JSR       78(PC)               loadFile

001770  41FA003E                  LEA       62(PC),A0            L0007
001774  227C00070000              MOVEA.L   #$70000,A1
00177A  2E3C00007D00              MOVE.L    #$7D00,D7
001780  4EBA003A                  JSR       58(PC)               loadFile

001784  42A7                      CLR.L     -(A7)
001786  3F3C0020                  MOVE.W    #$20,-(A7)
00178A  4E41                      TRAP      #1
00178C  5C8F                      ADDQ.L    #6,A7

00178E  13FC007B0005C452          MOVE.B    #$7B,$5C452
001796  11FC00801876              MOVE.B    #$80,$1876.W
00179C  4EF900058000              JMP       $58000

0017A2  534D00              L0005:DC.B      'SM',0
0017A5  5446494E414C2E4249  L0006:DC.B      'TFINAL.BIN',0
0017B0  534B59424F582E42    L0007:DC.B      'SKYBOX.BIN',0

0017BC  3F3C0000            loadFile:MOVE.W    #0,-(A7)
0017C0  2F08                      MOVE.L    A0,-(A7)
0017C2  3F3C003D                  MOVE.W    #$3D,-(A7)
0017C6                      L0009 EQU       *-2
0017C6  4E41                      TRAP      #1
0017C8  508F                      ADDQ.L    #8,A7
0017CA  3C00                      MOVE.W    D0,D6
0017CC  2F09                      MOVE.L    A1,-(A7)
0017CE  2F07                      MOVE.L    D7,-(A7)
0017D0  3F06                      MOVE.W    D6,-(A7)
0017D2  3F3C003F                  MOVE.W    #$3F,-(A7)
0017D6  4E41                      TRAP      #1
0017D8  DEFC000C                  ADDA.W    #$C,A7
0017DC  3F06                      MOVE.W    D6,-(A7)
0017DE  3F3C003E                  MOVE.W    #$3E,-(A7)
0017E2  4E41                      TRAP      #1
0017E4  588F                      ADDQ.L    #4,A7
0017E6  4E75                      RTS

0017E8  E744                loadRegisters:ASL.W     #3,D4
0017EA  4CBB3FFE40D6              MOVEM.W   -42(PC,D4.W),A0-A5/D1-D7 L0009      ;001814
0017F0  4DF900030000              LEA       $30000,A6
0017F6  4E75                      RTS

0017F8  2C3C0007A120        waitFDC:MOVE.L    #500000,D6
0017FE  08120005            L000C:BTST      #5,(A2)
001802  6704                      BEQ.S     4(PC)                L000D
001804  5386                      SUBQ.L    #1,D6
001806  66F6                      BNE.S     -10(PC)              L000C
001808  4E75                L000D:RTS

00180A  42B80024            clrTrace:CLR.L     $24.W
00180E  42B8002C                  CLR.L     $2C.W
001812  4E75                      RTS

001814  01000090001F0080          DC.W      $0100,$0090,$001F,$0080     ; D1,D2,D3,D4
00181C  250E230E00E08802          DC.W      $250E,$230E,$00E0,$8802     ; D5,D7,D7,A0
001824  8606FA01860B              DC.W      $8606,$FA01,$860B           ; A1,A2,A3

00182A  1307F71987F7FFA0    L000F:DC.B      $13,$07,$F7,$19,$87,$F7,$FF,$A0 ;A4,A5
001832  00000000CA4B0000          DC.B      $00,$00,$00,$00,$CA,$4B,$00,$00
00183A  0000000000000000          DC.B      $00,$00,$00,$00,$00,$00,$00,$00
001842  0000000000000000          DC.B      $00,$00,$00,$00,$00,$00,$00,$00
00184A  0000000000000000          DC.B      $00,$00,$00,$00,$00,$00,$00,$00
001852  0000000000000000          DC.B      $00,$00,$00,$00,$00,$00,$00,$00

Atari ST Protection: Arkanoid/CopylockST

This is an earlier version of CopylockST from Rob Northen from 29/09/88, it doesn’t use timing variations but three tests:

  • Track 79: has to be shorter than 6027 bytes, that is not possible to be written with a standard drive.
  • Track 0: The GAP 3a of Sector 1 (after the address mark) has to be exactly 32 bytes long and followed by 0x56,0x1E. Easily to miss this one.
  • Track 0: Byte 8 and 9 of Sector 1 has to contain 0xF5 and 0xF7 (not really a “protection”)
copyProtectionBaseAddress:
000188e4: 243c 0000 0200                 MOVE.L   #$200,D2
000188ea: 206f 0004                      MOVEA.L  (4,A7),A0
000188ee: 2628 000c                      MOVE.L   (12,A0),D3
000188f2: 0483 0000 0044                 SUBI.L   #$44,D3
000188f8: 41fa ffea                      LEA      copyProtectionBaseAddress(PC),A0
000188fc: 43fa 002a                      LEA      startOfDecodedBlock(PC),A1
00018900: 4280                           CLR.L    D0
00018902: 4281                           CLR.L    D1
00018904: 3a30 0000                      MOVE.W   (0,A0,D0.W),D5
00018908: bb71 1000                      EOR.W    D5,(0,A1,D1.W)
0001890c: 3a31 1000                      MOVE.W   (0,A1,D1.W),D5
00018910: 5481                           ADDQ.L   #2,D1
00018912: b243                           CMP.W    D3,D1
00018914: 6600 fff2                      BNE      *-$C [$18908]
00018918: 5480                           ADDQ.L   #2,D0
0001891a: b07c 0044                      CMP.W    #$44,D0
0001891e: 6700 fff8                      BEQ      *-$6 [$18918]
00018922: b042                           CMP.W    D2,D0
00018924: 6600 ffdc                      BNE      *-$22 [$18902]

startOfDecodedBlock:
00018928: 2a6f 0004                      MOVEA.L  (4,A7),A5
0001892c: 206d 0010                      MOVEA.L  ($10,A5),A0
00018930: 43fa 0948                      LEA      ($948,PC) [$1927A],A1
00018934: 2288                           MOVE.L   A0,(A1)

00018936: 6100 0454                      BSR      disableMFPInterrupts
0001893a: 6100 02ea                      BSR      checkFloppyProtection
0001893e: 6100 0036                      BSR      readArkanoidProFile
00018942: 6100 0084                      BSR      decompressArkanoidProFile
00018946: 6100 0158                      BSR      checksumCompare
0001894a: 6100 0180                      BSR      relocateApplication
0001894e: 6100 01d8                      BSR      getApplicationSizes
00018952: 6100 0206                      BSR      runApplication
; the following code is unused, because runApplication never returns anyway

00018956: 6100 0174                      BSR      relocateApplication
0001895a: 6100 01cc                      BSR      getApplicationSizes
0001895e: 6100 042c                      BSR      disableMFPInterrupts
00018962: 6100 0012                      BSR      readArkanoidProFile
00018966: 6100 0060                      BSR      decompressArkanoidProFile
0001896a: 6100 0134                      BSR      checksumCompare
0001896e: 6100 02b6                      BSR      checkFloppyProtection
00018972: 6000 01e6                      BRA      runApplication


readArkanoidProFile:
00018976: 4267                           CLR.W    -(A7)
00018978: 487a 090a                      PEA      ($90A,PC) [$19284]
0001897c: 3f3c 003d                      MOVE.W   #$3D,-(A7)
00018980: 4e41                           TRAP     #1                        ;Fopen ("arkanoid.PRO", 0)
00018982: 508f                           ADDQ.L   #8,A7
00018984: 4a80                           TST.L    D0
00018986: 6b00 0038                      BMI      *+$3A [$189C0]
0001898a: 3f00                           MOVE.W   D0,-(A7)
0001898c: 2f3a 08ec                      MOVE.L   ($8EC,PC) [$1927A],-(A7)  ;buffer address
00018990: 2f3a 08e0                      MOVE.L   ($8E0,PC) [$19272],-(A7)  ;number of bytes
00018994: 3f00                           MOVE.W   D0,-(A7)
00018996: 3f3c 003f                      MOVE.W   #$3F,-(A7)
0001899a: 4e41                           TRAP     #1                        ;Fread ( int16_t handle, int32_t count, void *buf )
0001899c: dffc 0000 000c                 ADDA.L   #$C,A7
000189a2: 4a80                           TST.L    D0
000189a4: 6b00 001a                      BMI      *+$1C [$189C0]
000189a8: b0ba 08c8                      CMP.L    ($8C8,PC) [$19272],D0     ;all bytes read?
000189ac: 6600 0012                      BNE      *+$14 [$189C0]
000189b0: 3f3c 003e                      MOVE.W   #$3E,-(A7)
000189b4: 4e41                           TRAP     #1                        ;Fclose ( int16_t handle )
000189b6: 588f                           ADDQ.L   #4,A7
000189b8: 4a80                           TST.L    D0
000189ba: 6b00 0004                      BMI      *+$6 [$189C0]
000189be: 4e75                           RTS
000189c0: 41fa 08ea                      LEA      ($8EA,PC) [$192AC],A0     ;"[ESC]lDisc error loading file"
000189c4: 6000 01f4                      BRA      fatalError

decompressArkanoidProFile:
000189c8: 41fa ff1a                      LEA      copyProtectionBaseAddress,A0
000189cc: 203c 0000 0972                 MOVE.L   #$972,D0
000189d2: 6100 00ea                      BSR      longChecksumD6
000189d6: 41fa 092e                      LEA      ($92E,PC) [$19306],A0
000189da: 227a 089e                      MOVEA.L  ($89E,PC) [$1927A],A1     ;arkanoid pro file buffer
000189de: 323c 0001                      MOVE.W   #1,D1
000189e2: 4240                           CLR.W    D0
000189e4: 4a70 0000                      TST.W    (0,A0,D0.W)
000189e8: 6700 0032                      BEQ      *+$34 [$18A1C]
000189ec: b270 0000                      CMP.W    (0,A0,D0.W),D1
000189f0: 6700 0008                      BEQ      *+$A [$189FA]
000189f4: 5840                           ADDQ.W   #4,D0
000189f6: 6000 ffec                      BRA      *-$12 [$189E4]
000189fa: 3f30 0002                      MOVE.W   (2,A0,D0.W),-(A7)
000189fe: e448                           LSR.W    #2,D0
00018a00: 0640 0001                      ADDI.W   #1,D0
00018a04: 6100 0018                      BSR      *+$1A [$18A1E]
00018a08: 301f                           MOVE.W   (A7)+,D0
00018a0a: 343a 0876                      MOVE.W   ($876,PC) [$19282],D2     ;copy protection checksum
00018a0e: bd42                           EOR.W    D6,D2
00018a10: b540                           EOR.W    D2,D0
00018a12: 6100 005c                      BSR      *+$5E [$18A70]
00018a16: 5281                           ADDQ.L   #1,D1
00018a18: 6000 ffc8                      BRA      *-$36 [$189E2]
00018a1c: 4e75                           RTS

00018a1e: 48e7 c000                      MOVEM.L  D0-D1,-(A7)
00018a22: b240                           CMP.W    D0,D1
00018a24: 6700 0044                      BEQ      *+$46 [$18A6A]
00018a28: 0440 0001                      SUBI.W   #1,D0
00018a2c: 0441 0001                      SUBI.W   #1,D1
00018a30: e548                           LSL.W    #2,D0
00018a32: e549                           LSL.W    #2,D1
00018a34: 2430 0000                      MOVE.L   (0,A0,D0.W),D2
00018a38: 21b0 1000 0000                 MOVE.L   (0,A0,D1.W),(0,A0,D0.W)
00018a3e: 2182 1000                      MOVE.L   D2,(0,A0,D1.W)
00018a42: 0280 0000 ffff                 ANDI.L   #$FFFF,D0
00018a48: 0281 0000 ffff                 ANDI.L   #$FFFF,D1
00018a4e: ef88                           LSL.L    #7,D0
00018a50: ef89                           LSL.L    #7,D1
00018a52: 2449                           MOVEA.L  A1,A2
00018a54: 2649                           MOVEA.L  A1,A3
00018a56: d5c0                           ADDA.L   D0,A2
00018a58: d7c1                           ADDA.L   D1,A3
00018a5a: 203c 0000 007f                 MOVE.L   #$7F,D0
00018a60: 2212                           MOVE.L   (A2),D1
00018a62: 24d3                           MOVE.L   (A3),(A2)+
00018a64: 26c1                           MOVE.L   D1,(A3)+
00018a66: 51c8 fff8                      DBF      D0,*-$6 [$18A60]
00018a6a: 4cdf 0003                      MOVEM.L  (A7)+,D0-D1
00018a6e: 4e75                           RTS

00018a70: 48e7 4080                      MOVEM.L  D1/A0,-(A7)
00018a74: 0281 0000 ffff                 ANDI.L   #$FFFF,D1
00018a7a: 5381                           SUBQ.L   #1,D1
00018a7c: e189                           LSL.L    #8,D1
00018a7e: e389                           LSL.L    #1,D1
00018a80: 207a 07f8                      MOVEA.L  ($7F8,PC) [$1927A],A0
00018a84: d1c1                           ADDA.L   D1,A0
00018a86: 223c 0000 00ff                 MOVE.L   #$FF,D1
00018a8c: 4a58                           TST.W    (A0)+
00018a8e: 6700 0006                      BEQ      *+$8 [$18A96]
00018a92: b168 fffe                      EOR.W    D0,(-2,A0)
00018a96: 51c9 fff4                      DBF      D1,*-$A [$18A8C]
00018a9a: 4cdf 0102                      MOVEM.L  (A7)+,D1/A0
00018a9e: 4e75                           RTS

checksumCompare:
00018aa0: 207a 07d8                      MOVEA.L  ($7D8,PC) [$1927A],A0
00018aa4: 203a 07cc                      MOVE.L   ($7CC,PC) [$19272],D0
00018aa8: 6100 0014                      BSR      longChecksumD6
00018aac: bcba 07d0                      CMP.L    ($7D0,PC) [$1927E],D6
00018ab0: 6700 000a                      BEQ      *+$C [$18ABC]
00018ab4: 41fa 0826                      LEA      ($826,PC) [$192DC],A0     ;"[ESC]lData has been corrupted"
00018ab8: 6000 0100                      BRA      fatalError
00018abc: 4e75                           RTS

longChecksumD6:
00018abe: e488                           LSR.L    #2,D0
00018ac0: 4286                           CLR.L    D6
00018ac2: dc98                           ADD.L    (A0)+,D6
00018ac4: 5380                           SUBQ.L   #1,D0
00018ac6: 6600 fffa                      BNE      *-$4 [$18AC2]
00018aca: 4e75                           RTS

relocateApplication:
00018acc: 207a 07ac                      MOVEA.L  ($7AC,PC) [$1927A],A0
00018ad0: 2028 0002                      MOVE.L   (2,A0),D0             ;text size
00018ad4: d0a8 0006                      ADD.L    (6,A0),D0             ;data size
00018ad8: 43fa 079c                      LEA      ($79C,PC) [$19276],A1 ;application text+data size
00018adc: 2280                           MOVE.L   D0,(A1)
00018ade: 4a68 001a                      TST.W    ($1A,A0)              ;reloc info
00018ae2: 6600 0042                      BNE      *+$44 [$18B26]
00018ae6: 2248                           MOVEA.L  A0,A1
00018ae8: d3fc 0000 001c                 ADDA.L   #28,A1
00018aee: 2449                           MOVEA.L  A1,A2
00018af0: d5e8 0002                      ADDA.L   (2,A0),A2             ;text size
00018af4: d5e8 0006                      ADDA.L   (6,A0),A2             ;data size
00018af8: d5e8 000e                      ADDA.L   ($E,A0),A2            ;symbol table size
00018afc: 4281                           CLR.L    D1
00018afe: 41fa fde4                      LEA      copyProtectionBaseAddress,A0
00018b02: 2408                           MOVE.L   A0,D2
00018b04: 201a                           MOVE.L   (A2)+,D0
00018b06: d5b1 0800                      ADD.L    D2,(0,A1,D0.L)
00018b0a: 121a                           MOVE.B   (A2)+,D1
00018b0c: 4a01                           TST.B    D1
00018b0e: 6700 0016                      BEQ      *+$18 [$18B26]
00018b12: d081                           ADD.L    D1,D0
00018b14: b23c 0001                      CMP.B    #1,D1
00018b18: 6600 ffec                      BNE      *-$12 [$18B06]
00018b1c: 0680 0000 00fd                 ADDI.L   #254-1,D0
00018b22: 6000 ffe6                      BRA      *-$18 [$18B0A]
00018b26: 4e75                           RTS

getApplicationSizes:
00018b28: 206f 0008                      MOVEA.L  (8,A7),A0
00018b2c: 43fa fdb6                      LEA      copyProtectionBaseAddress,A1
00018b30: 2009                           MOVE.L   A1,D0
00018b32: 227a 0746                      MOVEA.L  ($746,PC) [$1927A],A1
00018b36: 2169 0002 000c                 MOVE.L   (2,A1),(12,A0)        ;text size
00018b3c: d0a8 000c                      ADD.L    (12,A0),D0
00018b40: 2140 0010                      MOVE.L   D0,(16,A0)
00018b44: 2169 0006 0014                 MOVE.L   (6,A1),(20,A0)        ;data size
00018b4a: d0a8 0014                      ADD.L    (20,A0),D0
00018b4e: 2140 0018                      MOVE.L   D0,(24,A0)
00018b52: 2169 000a 001c                 MOVE.L   (10,A1),(28,A0)       ;bss size
00018b58: 4e75                           RTS

runApplication:
00018b5a: 588f                           ADDQ.L   #4,A7
00018b5c: 206f 0004                      MOVEA.L  (4,A7),A0
00018b60: 2468 0018                      MOVEA.L  (24,A0),A2            ;bss address
00018b64: 2228 001c                      MOVE.L   (28,A0),D1            ;bss size
00018b68: 264a                           MOVEA.L  A2,A3
00018b6a: d7c1                           ADDA.L   D1,A3                 ;bss end address
00018b6c: 207a 070c                      MOVEA.L  ($70C,PC) [$1927A],A0
00018b70: d1fa 0700                      ADDA.L   ($700,PC) [$19272],A0
00018b74: b1cb                           CMPA.L   A3,A0
00018b76: 6d00 0004                      BLT      *+$6 [$18B7C]
00018b7a: 2648                           MOVEA.L  A0,A3
00018b7c: 203c 0000 000b                 MOVE.L   #$B,D0
00018b82: 41fa 0036                      LEA      fatalError,A0
00018b86: 43fa fd5c                      LEA      copyProtectionBaseAddress,A1
00018b8a: 2f09                           MOVE.L   A1,-(A7)
00018b8c: 3f20                           MOVE.W   -(A0),-(A7)
00018b8e: 51c8 fffc                      DBF      D0,*-$2 [$18B8C]
00018b92: 207a 06e6                      MOVEA.L  ($6E6,PC) [$1927A],A0
00018b96: d1fc 0000 001c                 ADDA.L   #28,A0                ;text + data code
00018b9c: 203a 06d8                      MOVE.L   ($6D8,PC) [$19276],D0 ;application text+data size
00018ba0: 4ed7                           JMP      (A7)
00018ba2: 22d8                           MOVE.L   (A0)+,(A1)+
00018ba4: 5980                           SUBQ.L   #4,D0
00018ba6: 6a00 fffa                      BPL      *-$4 [$18BA2]
00018baa: 429a                           CLR.L    (A2)+
00018bac: b7ca                           CMPA.L   A2,A3
00018bae: 6e00 fffa                      BGT      *-$4 [$18BAA]
00018bb2: dffc 0000 0018                 ADDA.L   #$18,A7
00018bb8: 4e75                           RTS

fatalError:
00018bba: 227a 06be                      MOVEA.L  ($6BE,PC) [$1927A],A1
00018bbe: 12d8                           MOVE.B   (A0)+,(A1)+
00018bc0: 6600 fffc                      BNE      *-$2 [$18BBE]
00018bc4: 5389                           SUBQ.L   #1,A1
00018bc6: 41fa 072e                      LEA      ($72E,PC) [$192F6],A0 ;" - Press a key"
00018bca: 12d8                           MOVE.B   (A0)+,(A1)+
00018bcc: 6600 fffc                      BNE      *-$2 [$18BCA]
00018bd0: 2009                           MOVE.L   A1,D0
00018bd2: 0800 0000                      BTST     #0,D0
00018bd6: 6700 0004                      BEQ      *+$6 [$18BDC]
00018bda: 5289                           ADDQ.L   #1,A1
00018bdc: 3f21                           MOVE.W   -(A1),-(A7)
00018bde: b3fa 069a                      CMPA.L   ($69A,PC) [$1927A],A1
00018be2: 6600 fff8                      BNE      *-$6 [$18BDC]

; copy fail text onto the stack and jump into this routine, it erases the copy protection routine
; and prints a fail text.
00018be6: 2c4f                           MOVEA.L  A7,A6
00018be8: 203c 0000 000d                 MOVE.L   #13,D0
00018bee: 41fa 0036                      LEA      ($36,PC) [$18C26],A0
00018bf2: 3f20                           MOVE.W   -(A0),-(A7)
00018bf4: 51c8 fffc                      DBF      D0,*-$2 [$18BF2]
00018bf8: 41fa fcea                      LEA      copyProtectionBaseAddress,A0
00018bfc: 227a 067c                      MOVEA.L  ($67C,PC) [$1927A],A1
00018c00: 93c8                           SUBA.L   A0,A1
00018c02: 203a 066e                      MOVE.L   ($66E,PC) [$19272],D0
00018c06: d089                           ADD.L    A1,D0
00018c08: 4ed7                           JMP      (A7)

00018c0a: 4218                           CLR.B    (A0)+
00018c0c: 51c8 fffc                      DBF      D0,*-$2 [$18C0A]
00018c10: 2f0e                           MOVE.L   A6,-(A7)
00018c12: 3f3c 0009                      MOVE.W   #9,-(A7)
00018c16: 4e41                           TRAP     #1
00018c18: 5c8f                           ADDQ.L   #6,A7
00018c1a: 3f3c 0001                      MOVE.W   #1,-(A7)
00018c1e: 4e41                           TRAP     #1
00018c20: 548f                           ADDQ.L   #2,A7
00018c22: 4267                           CLR.W    -(A7)
00018c24: 4e41                           TRAP     #1


checkFloppyProtection:
00018c26: 6100 05b4                      BSR      GEMDOS_Dgetdrv
00018c2a: 41fa 062a                      LEA      ($62A,PC) [$19256],A0
00018c2e: 3140 0000                      MOVE.W   D0,(0,A0)                 ;floppy drive
00018c32: b07c 0002                      CMP.W    #2,D0
00018c36: 6d00 001a                      BLT      *+$1C [$18C52]
00018c3a: 317c 0000 0000                 MOVE.W   #0,(0,A0)                 ;floppy drive = A
00018c40: 6100 0022                      BSR      checkProtectionDrive
00018c44: 6700 001c                      BEQ      *+$1E [$18C62]
00018c48: 41fa 060c                      LEA      ($60C,PC) [$19256],A0
00018c4c: 317c 0001 0000                 MOVE.W   #1,(0,A0)                 ;floppy drive = B
00018c52: 6100 0010                      BSR      checkProtectionDrive
00018c56: 6700 000a                      BEQ      *+$C [$18C62]
00018c5a: 41fa 066a                      LEA      ($66A,PC) [$192C6],A0     ;"[ESC]lThis disc is a copy"
00018c5e: 6000 ff5a                      BRA      fatalError
00018c62: 4e75                           RTS

checkProtectionDrive:
00018c64: 41fa 05f0                      LEA      ($5F0,PC) [$19256],A0
00018c68: 217a 0610 0002                 MOVE.L   ($610,PC) [$1927A],(2,A0) [$19258] ;FDC Buffer
00018c6e: 317c 00e0 0008                 MOVE.W   #$E0,(8,A0) [$1925E]      ;Read Track
00018c74: 41fa 05e0                      LEA      ($5E0,PC) [$19256],A0
00018c78: 317c 004f 000a                 MOVE.W   #$4F,(10,A0) [$19260]     ;Track 79
00018c7e: 6100 0144                      BSR      scheduleFDCCommand
00018c82: 243a 05e6                      MOVE.L   ($5E6,PC) [$1926A],D2     ;end address of the DMA
00018c86: 94ba 05d0                      SUB.L    ($5D0,PC) [$19258],D2     ;- start address of the DMA = length of the track
00018c8a: 6100 00d4                      BSR      testTrack79
00018c8e: 43fa 05f2                      LEA      ($5F2,PC) [$19282],A1     ;copy protection checksum
00018c92: 3282                           MOVE.W   D2,(A1)                   ;track length (filtered by valid values, should be $1746)
00018c94: 383c 0002                      MOVE.W   #2,D4                     ;try 3 times!
00018c98: 41fa 05bc                      LEA      ($5BC,PC) [$19256],A0
00018c9c: 317c 0000 000a                 MOVE.W   #0,(10,A0) [$19260]       ;Track 0
00018ca2: 6100 0120                      BSR      scheduleFDCCommand
00018ca6: 6100 0084                      BSR      testTrack0
00018caa: 57cc ffec                      DBEQ     D4,*-$12 [$18C98]

00018cae: 40e7                           MOVE     SR,-(A7)
00018cb0: 3f3c 0001                      MOVE.W   #1,-(A7)                  ;count
00018cb4: 4267                           CLR.W    -(A7)                     ;side
00018cb6: 4267                           CLR.W    -(A7)                     ;track
00018cb8: 3f3c 0001                      MOVE.W   #1,-(A7)                  ;sector
00018cbc: 3f3a 0598                      MOVE.W   ($598,PC) [$19256],-(A7)  ;devno = floppy drive
00018cc0: 42a7                           CLR.L    -(A7)                     ;filler
00018cc2: 2f3a 05b6                      MOVE.L   ($5B6,PC) [$1927A],-(A7)  ;FDC Buffer
00018cc6: 3f3c 0008                      MOVE.W   #8,-(A7)
00018cca: 4e4e                           TRAP     #$E
00018ccc: dffc 0000 0014                 ADDA.L   #$14,A7
00018cd2: 44df                           MOVE     (A7)+,CCR
00018cd4: 6600 000c                      BNE      *+$E [$18CE2]
00018cd8: 207a 05a0                      MOVEA.L  ($5A0,PC) [$1927A],A0
00018cdc: 0c68 f5f7 0008                 CMPI.W   #$F5F7,(8,A0)             ;Byte 8 and 9 in the boot sector should contain these bytes
00018ce2: 4e75                           RTS

track0SearchSector1:
00018ce4: 323a 057a                      MOVE.W   ($57A,PC) [$19260],D1     ;track number
00018ce8: 207a 0590                      MOVEA.L  ($590,PC) [$1927A],A0     ;buffer
00018cec: 4280                           CLR.L    D0
00018cee: 0c30 00fe 0000                 CMPI.B   #$FE,(0,A0,D0.W)          ;ID Address Mark
00018cf4: 6600 0028                      BNE      *+$2A [$18D1E]
00018cf8: b230 0001                      CMP.B    (1,A0,D0.W),D1            ;Track Number
00018cfc: 6600 0020                      BNE      *+$22 [$18D1E]
00018d00: 0c30 0000 0002                 CMPI.B   #0,(2,A0,D0.W)            ;Side = 0
00018d06: 6600 0016                      BNE      *+$18 [$18D1E]
00018d0a: 0c30 0001 0003                 CMPI.B   #1,(3,A0,D0.W)            ;Sector = 1
00018d10: 6600 000c                      BNE      *+$E [$18D1E]
00018d14: 0c30 0002 0004                 CMPI.B   #2,(4,A0,D0.W)            ;Sector Length = 2 (512 bytes)
00018d1a: 6700 000e                      BEQ      *+$10 [$18D2A]
00018d1e: 5280                           ADDQ.L   #1,D0
00018d20: b07c 1900                      CMP.W    #$1900,D0
00018d24: 6600 ffc8                      BNE      *-$36 [$18CEE]
00018d28: 7001                           MOVEQ    #1,D0
00018d2a: 4e75                           RTS

testTrack0:
00018d2c: 6100 ffb6                      BSR      track0SearchSector1       ;D0 should point the the Address Mark of the first sector
00018d30: 662c                           BNE.S    *+$2E [$18D5E]
00018d32: 323c ffff                      MOVE.W   #-1,D1
00018d36: 5280                           ADDQ.L   #1,D0
00018d38: 5281                           ADDQ.L   #1,D1
00018d3a: 0c30 004e 0006                 CMPI.B   #$4E,(6,A0,D0.W)          ;skip GAP 3a
00018d40: 6700 fff4                      BEQ      *-$A [$18D36]
00018d44: b27c 0020                      CMP.W    #32,D1                    ;should be exactly 32 bytes long! (normal is 22)
00018d48: 6600 0014                      BNE      *+$16 [$18D5E]
00018d4c: 1230 0006                      MOVE.B   (6,A0,D0.W),D1
00018d50: e149                           LSL.W    #8,D1                     ;$561E follow right after that
00018d52: 1230 0007                      MOVE.B   (7,A0,D0.W),D1
00018d56: 43fa 052a                      LEA      ($52A,PC) [$19282],A1     ;copy protection checksum
00018d5a: d351                           ADD.W    D1,(A1)                   ;$561e + $1746 == $6d64 ('md')
00018d5c: 7000                           MOVEQ    #0,D0
00018d5e: 4e75                           RTS

testTrack79:    // D2 should be 0x1738, should return $1746 in D2
00018d60: 41fa 0018                      LEA      ($18,PC) [$18D7A],A0
00018d64: b458                           CMP.W    (A0)+,D2
00018d66: 6cfc                           BGE.S    *-$2 [$18D64]
00018d68: 3220                           MOVE.W   -(A0),D1          ;max
00018d6a: 9260                           SUB.W    -(A0),D1          ;min
00018d6c: e249                           LSR.W    #1,D1
00018d6e: d250                           ADD.W    (A0),D1           ;val = (max - min) / 2 + min
00018d70: b441                           CMP.W    D1,D2             ;closer to previous value?
00018d72: 6d02                           BLT.S    *+$4 [$18D76]     ;then return min
00018d74: 4a58                           TST.W    (A0)+
00018d76: 3410                           MOVE.W   (A0),D2           ;else return max
00018d78: 4e75                           RTS
00018D7A: DC.W $0000,$1746,$17d1,$186a,$190a,$19b2,$1a64,$1b20,$7fff


disableMFPInterrupts:
00018d8c: 7800                           MOVEQ    #0,D4
00018d8e: 41fa 0016                      LEA      ($16,PC) [$18DA6],A0
00018d92: 3030 4000                      MOVE.W   (0,A0,D4.W),D0
00018d96: 6700 000c                      BEQ      *+$E [$18DA4]
00018d9a: 6100 001c                      BSR      *+$1E [$18DB8]
00018d9e: 5484                           ADDQ.L   #2,D4
00018da0: 6000 ffec                      BRA      *-$12 [$18D8E]
00018da4: 4e75                           RTS
00018DA6: DC.W 1,2,4,9,10,11,12,14,0
00018db8: 3f00                           MOVE.W   D0,-(A7)
00018dba: 3f3c 001a                      MOVE.W   #$1A,-(A7)
00018dbe: 4e4e                           TRAP     #$E                   ;Jdisint(number)
00018dc0: 588f                           ADDQ.L   #4,A7
00018dc2: 4e75                           RTS



scheduleFDCCommand:
00018dc4: 48e7 ff7e                      MOVEM.L  D0-D7/A1-A6,-(A7)
00018dc8: 43fa 049a                      LEA      ($49A,PC) [$19264],A1
00018dcc: 6100 0420                      BSR      GEMDOS_SuperOn
00018dd0: 50f9 0000 043e                 ST.B     $43E
00018dd6: 6100 037e                      BSR      select
00018dda: 6100 005a                      BSR      *+$5C [$18E36]
00018dde: 6700 0036                      BEQ      *+$38 [$18E16]
00018de2: 4a71 5000                      TST.W    (0,A1,D5.W)       ;track position for drive valid?
00018de6: 6a00 001c                      BPL      *+$1E [$18E04]    ;=> yes
00018dea: 6100 028e                      BSR      fdcRestore
00018dee: 6700 0014                      BEQ      *+$16 [$18E04]
00018df2: 7c0a                           MOVEQ    #$0A,D6           ;Restore with no spin-up, but with verify
00018df4: 6100 025a                      BSR      executeFDCCommandD6
00018df8: 6600 001c                      BNE      *+$1E [$18E16]
00018dfc: 6100 027c                      BSR      fdcRestore
00018e00: 6600 0014                      BNE      *+$16 [$18E16]

00018e04: 6100 0246                      BSR      executeFDCcommand
00018e08: 0c68 0069 0008                 CMPI.W   #$69,(8,A0) [$1925E]
00018e0e: 6700 0006                      BEQ      *+$8 [$18E16]
00018e12: 6100 007a                      BSR      *+$7C [$18E8E]
00018e16: 6100 032e                      BSR      deselect
00018e1a: 4279 0000 043e                 CLR.W    $43E
00018e20: 6100 0402                      BSR      GEMDOS_SuperOff
00018e24: 3028 0006                      MOVE.W   (6,A0) [$1925C],D0
00018e28: e348                           LSL.W    #1,D0
00018e2a: 31a9 0004 000a                 MOVE.W   (4,A1),(10,A0,D0.W) [$19260]
00018e30: 4cdf 7eff                      MOVEM.L  (A7)+,D0-D7/A1-A6
00018e34: 4e75                           RTS

00018e36: 0c68 007a 0008                 CMPI.W   #$7A,(8,A0) [$1925E]
00018e3c: 6700 000e                      BEQ      *+$10 [$18E4C]
00018e40: 0c68 007d 0008                 CMPI.W   #$7D,(8,A0) [$1925E]
00018e46: 6700 0018                      BEQ      *+$1A [$18E60]
00018e4a: 4e75                           RTS

00018e4c: 6100 0026                      BSR      *+$28 [$18E74]
00018e50: 6600 0008                      BNE      *+$A [$18E5A]
00018e54: 33a8 000c 0000                 MOVE.W   (12,A0),(0,A1,D0.W)
00018e5a: 003c 0004                      ORI      #$4,CCR
00018e5e: 4e75                           RTS

00018e60: 6100 0012                      BSR      *+$14 [$18E74]
00018e64: 6600 0008                      BNE      *+$A [$18E6E]
00018e68: 3171 0000 000c                 MOVE.W   (0,A1,D0.W),(12,A0)
00018e6e: 003c 0004                      ORI      #$4,CCR
00018e72: 4e75                           RTS

00018e74: 303c 0000                      MOVE.W   #0,D0
00018e78: 0c68 0012 000a                 CMPI.W   #$12,(10,A0) [$19260]      ; Drive A
00018e7e: 6700 000c                      BEQ      *+$E [$18E8C]
00018e82: 303c 0002                      MOVE.W   #2,D0
00018e86: 0c68 001a 000a                 CMPI.W   #$1A,(10,A0) [$19260]      ; Drive B
00018e8c: 4e75                           RTS

00018e8e: 0c68 00e0 0008                 CMPI.W   #$E0,(8,A0) [$1925E]       ;read track
00018e94: 6700 008e                      BEQ      *+$90 [$18F24]
00018e98: 0c68 00f0 0008                 CMPI.W   #$F0,(8,A0) [$1925E]       ;write track
00018e9e: 6700 0018                      BEQ      *+$1A [$18EB8]
00018ea2: 0c68 0053 0008                 CMPI.W   #$53,(8,A0) [$1925E]       ;write sector
00018ea8: 6700 0088                      BEQ      *+$8A [$18F32]
00018eac: 0c68 005d 0008                 CMPI.W   #$5D,(8,A0) [$1925E]       ;???
00018eb2: 6700 00f4                      BEQ      *+$F6 [$18FA8]
00018eb6: 4e75                           RTS

00018eb8: 3c3c 00f0                      MOVE.W   #$F0,D6
00018ebc: 6100 0174                      BSR      dmaWriteMode
00018ec0: 33fc 001f 00ff 8604            MOVE.W   #$1F,$FF8604
00018ec8: 33fc 0180 00ff 8606            MOVE.W   #$180,$FF8606
00018ed0: 6100 0228                      BSR      wrfdc
00018ed4: 2e3c 0004 0000                 MOVE.L   #$40000,D7
00018eda: 0839 0005 00ff fa01            BTST     #5,$FFFA01
00018ee2: 6700 0014                      BEQ      *+$16 [$18EF8]
00018ee6: 5387                           SUBQ.L   #1,D7
00018ee8: 6600 fff0                      BNE      *-$E [$18EDA]
00018eec: 6100 0220                      BSR      forceInterrupt
00018ef0: 7e01                           MOVEQ    #1,D7
00018ef2: 3347 0004                      MOVE.W   D7,(4,A1)
00018ef6: 4e75                           RTS
00018ef8: 33fc 0190 00ff 8606            MOVE.W   #$190,$FF8606
00018f00: 3039 00ff 8606                 MOVE.W   $FF8606,D0
00018f06: 0800 0000                      BTST     #0,D0
00018f0a: 6700 ffe4                      BEQ      *-$1A [$18EF0]
00018f0e: 33fc 0180 00ff 8606            MOVE.W   #$180,$FF8606
00018f16: 6100 020e                      BSR      readfdc
00018f1a: 0247 0044                      ANDI.W   #$44,D7
00018f1e: 3347 0004                      MOVE.W   D7,(4,A1)
00018f22: 4e75                           RTS


00018f24: 3c3c 00e0                      MOVE.W   #$E0,D6           ;read track
00018f28: 247c 0000 2c00                 MOVEA.L  #$2C00,A2         ;maximum number of bytes
00018f2e: 6000 001a                      BRA      *+$1C [$18F4A]

00018f32: 33fc 0084 00ff 8606            MOVE.W   #$84,$FF8606      ;FDC Sector Register
00018f3a: 3c28 000c                      MOVE.W   (12,A0) [$19262],D6 ;sector number
00018f3e: 6100 01ba                      BSR      wrfdc
00018f42: 3c3c 0090                      MOVE.W   #$90,D6           ;write sector
00018f46: 3468 000e                      MOVEA.W  (14,A0) [$19264],A2 ;number of bytes


00018f4a: 6100 00cc                      BSR      dmaReadMode
00018f4e: 33fc 0016 00ff 8604            MOVE.W   #$16,$FF8604
00018f56: d5e8 0002                      ADDA.L   (2,A0) [$19258],A2 ;end address of the buffer
00018f5a: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
00018f62: 6100 0196                      BSR      wrfdc
00018f66: 2e3c 0004 0000                 MOVE.L   #$40000,D7
00018f6c: 137c 0000 0006                 MOVE.B   #0,(6,A1)

00018f72: 0839 0005 00ff fa01            BTST     #5,$FFFA01        ;wait for the FDC to complete
00018f7a: 6700 008a                      BEQ      fdcDone
00018f7e: 1379 00ff 8609 0007            MOVE.B   $FF8609,(7,A1) [$1926A+1]
00018f86: 1379 00ff 860b 0008            MOVE.B   $FF860B,(8,A1) [$1926A+2]    ;or the end address being reached
00018f8e: 1379 00ff 860d 0009            MOVE.B   $FF860D,(9,A1) [$1926A+3]
00018f96: b5e9 0006                      CMPA.L   (6,A1) [$1926A],A2
00018f9a: 6f00 0066                      BLE      *+$68 [$19002]
00018f9e: 5387                           SUBQ.L   #1,D7             ;or a timeout
00018fa0: 6600 ffd0                      BNE      *-$2E [$18F72]
00018fa4: 6700 005c                      BEQ      fdcTimeout

00018fa8: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
00018fb0: 6100 0182                      BSR      waitl
00018fb4: 3e39 00ff 8604                 MOVE.W   $FF8604,D7
00018fba: 0247 0002                      ANDI.W   #2,D7
00018fbe: 6700 fff4                      BEQ      *-$A [$18FB4]
00018fc2: 6100 0054                      BSR      dmaReadMode
00018fc6: 33fc 0001 00ff 8604            MOVE.W   #1,$FF8604
00018fce: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
00018fd6: 3828 000c                      MOVE.W   (12,A0) [$19262],D4
00018fda: 3c3c 00c0                      MOVE.W   #$C0,D6           ;Read Address
00018fde: 2e3c 0004 0000                 MOVE.L   #$40000,D7
00018fe4: 6100 0114                      BSR      wrfdc
00018fe8: 0839 0005 00ff fa01            BTST     #5,$FFFA01
00018ff0: 6700 000c                      BEQ      *+$E [$18FFE]
00018ff4: 5387                           SUBQ.L   #1,D7
00018ff6: 6700 000a                      BEQ      *+$C [$19002]
00018ffa: 6000 ffec                      BRA      *-$12 [$18FE8]
00018ffe: 51cc ffda                      DBF      D4,*-$24 [$18FDA]

fdcTimeout:
00019002: 6100 010a                      BSR      forceInterrupt

fdcDone:
00019006: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
0001900e: 6100 0116                      BSR      readfdc
00019012: 3347 0004                      MOVE.W   D7,(4,A1)
00019016: 4e75                           RTS

dmaReadMode:
00019018: 33fc 0090 00ff 8606            MOVE.W   #$90,$FF8606
00019020: 33fc 0190 00ff 8606            MOVE.W   #$190,$FF8606
00019028: 33fc 0090 00ff 8606            MOVE.W   #$90,$FF8606
00019030: 4e75                           RTS

dmaWriteMode:
00019032: 33fc 0190 00ff 8606            MOVE.W   #$190,$FF8606
0001903a: 33fc 0090 00ff 8606            MOVE.W   #$90,$FF8606
00019042: 33fc 0190 00ff 8606            MOVE.W   #$190,$FF8606
0001904a: 4e75                           RTS

executeFDCcommand:
0001904c: 3c28 000a                      MOVE.W   (10,A0) [$19260],D6
executeFDCCommandD6:
00019050: 4a46                           TST.W    D6
00019052: 6700 0026                      BEQ      fdcRestore
00019056: 33fc 0086 00ff 8606            MOVE.W   #$86,$FF8606
0001905e: 6100 009a                      BSR      wrfdc
00019062: 3c3c 0010                      MOVE.W   #$10,D6
00019066: 6100 0038                      BSR      doFDCCommand
0001906a: 6600 000c                      BNE      *+$E [$19078]
0001906e: 3c28 000a                      MOVE.W   (10,A0) [$19260],D6
00019072: 3386 5000                      MOVE.W   D6,(0,A1,D5.W)    ;store track position for drive
00019076: 4246                           CLR.W    D6
00019078: 4e75                           RTS

fdcRestore:
0001907a: 4246                           CLR.W    D6
0001907c: 6100 0022                      BSR      doFDCCommand
00019080: 0807 0002                      BTST     #2,D7             ;Track 0 indicator
00019084: 0a3c 0004                      EORI     #$4,CCR
00019088: 6600 0014                      BNE      *+$16 [$1909E]
0001908c: 33fc 0082 00ff 8606            MOVE.W   #$82,$FF8606
00019094: 7c00                           MOVEQ    #0,D6
00019096: 6100 0062                      BSR      wrfdc             ;Set Track Register to 0
0001909a: 4271 5000                      CLR.W    (0,A1,D5.W)       ;reset track position for drive
0001909e: 4e75                           RTS

doFDCCommand:
000190a0: 3039 0000 0440                 MOVE.W   $440,D0           ;seekrate (0 - 6ms, 1 - 12ms, 2 - 2ms, 3 - 3ms (default))
000190a6: 0200 0003                      ANDI.B   #3,D0
000190aa: 8c00                           OR.B     D0,D6
000190ac: 2e3c 0004 0000                 MOVE.L   #$40000,D7
000190b2: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606      ;FDC Status
000190ba: 6100 006a                      BSR      readfdc
000190be: 0800 0007                      BTST     #7,D0             ;Motor already on?
000190c2: 6600 0008                      BNE      *+$A [$190CC]
000190c6: 2e3c 0006 0000                 MOVE.L   #$60000,D7        ;no => longer timeout
000190cc: 6100 002c                      BSR      wrfdc
000190d0: 5387                           SUBQ.L   #1,D7
000190d2: 6700 001e                      BEQ      *+$20 [$190F2]
000190d6: 0839 0005 00ff fa01            BTST     #5,$FFFA01
000190de: 6600 fff0                      BNE      *-$E [$190D0]
000190e2: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
000190ea: 6100 003a                      BSR      readfdc
000190ee: 4246                           CLR.W    D6
000190f0: 4e75                           RTS
000190f2: 6100 001a                      BSR      forceInterrupt
000190f6: 7c01                           MOVEQ    #1,D6
000190f8: 4e75                           RTS

wrfdc:
000190fa: 6100 0038                      BSR      waitl
000190fe: 33c6 00ff 8604                 MOVE.W   D6,$FF8604
00019104: 6000 002e                      BRA      waitl

delayD7:
00019108: 51cf fffe                      DBF      D7,delayD7
0001910c: 4e75                           RTS

forceInterrupt:
0001910e: 33fc 0080 00ff 8606            MOVE.W   #$80,$FF8606
00019116: 3c3c 00d0                      MOVE.W   #$D0,D6
0001911a: 6100 ffde                      BSR      wrfdc
0001911e: 3e3c 000f                      MOVE.W   #15,D7
00019122: 6100 ffe4                      BSR      delayD7

readfdc:
00019126: 6100 000c                      BSR      waitl
0001912a: 3e39 00ff 8604                 MOVE.W   $FF8604,D7
00019130: 0247 007f                      ANDI.W   #$7F,D7

waitl:
00019134: 40e7                           MOVE     SR,-(A7)
00019136: 3f07                           MOVE.W   D7,-(A7)
00019138: 3e3c 0020                      MOVE.W   #$20,D7
0001913c: 51cf fffe                      DBF      D7,*-$0 [$1913C]
00019140: 3e1f                           MOVE.W   (A7)+,D7
00019142: 46df                           MOVE     (A7)+,SR
00019144: 4e75                           RTS

deselect:
00019146: 3e3c 3a98                      MOVE.W   #15000,D7
0001914a: 6100 ffbc                      BSR      delayD7
0001914e: 103c 0007                      MOVE.B   #7,D0
00019152: 6000 0064                      BRA      *+$66 [$191B8]

select:
00019156: 3028 0000                      MOVE.W   (0,A0),D0
0001915a: 6a00 0006                      BPL      *+$8 [$19162]
0001915e: 6100 007c                      BSR      GEMDOS_Dgetdrv
00019162: 0240 0003                      ANDI.W   #3,D0
00019166: 1a00                           MOVE.B   D0,D5
00019168: 0200 0001                      ANDI.B   #1,D0
0001916c: 5200                           ADDQ.B   #1,D0
0001916e: e308                           LSL.B    #1,D0
00019170: 0805 0001                      BTST     #1,D5
00019174: 6700 0006                      BEQ      *+$8 [$1917C]
00019178: 0000 0001                      ORI.B    #1,D0
0001917c: 0a00 0007                      EORI.B   #7,D0
00019180: 0200 0007                      ANDI.B   #7,D0
00019184: 6100 0032                      BSR      *+$34 [$191B8]
00019188: 13e8 0005 00ff 860d            MOVE.B   (5,A0),$FF860D
00019190: 13e8 0004 00ff 860b            MOVE.B   (4,A0),$FF860B
00019198: 13e8 0003 00ff 8609            MOVE.B   (3,A0),$FF8609
000191a0: 0245 0001                      ANDI.W   #1,D5
000191a4: e34d                           LSL.W    #1,D5
000191a6: 3c31 5000                      MOVE.W   (0,A1,D5.W),D6    ;track position for drive
000191aa: 33fc 0082 00ff 8606            MOVE.W   #$82,$FF8606      ;set track register
000191b2: 6100 ff46                      BSR      wrfdc
000191b6: 4e75                           RTS

000191b8: 40e7                           MOVE     SR,-(A7)
000191ba: 007c 0700                      ORI      #$700,SR
000191be: 13fc 000e 00ff 8800            MOVE.B   #$E,$FF8800
000191c6: 1239 00ff 8800                 MOVE.B   $FF8800,D1
000191cc: 0201 00f8                      ANDI.B   #$F8,D1
000191d0: 8200                           OR.B     D0,D1
000191d2: 13c1 00ff 8802                 MOVE.B   D1,$FF8802
000191d8: 46df                           MOVE     (A7)+,SR
000191da: 4e75                           RTS

GEMDOS_Dgetdrv:
000191dc: 48e7 7ffe                      MOVEM.L  D1-D7/A0-A6,-(A7)
000191e0: 3f3c 0019                      MOVE.W   #$19,-(A7)
000191e4: 4e41                           TRAP     #1
000191e6: 548f                           ADDQ.L   #2,A7
000191e8: 4cdf 7ffe                      MOVEM.L  (A7)+,D1-D7/A0-A6
000191ec: 4e75                           RTS

GEMDOS_SuperOn:
000191ee: 48e7 00c0                      MOVEM.L  A0-A1,-(A7)
000191f2: 2f3c 0000 0001                 MOVE.L   #1,-(A7)
000191f8: 3f3c 0020                      MOVE.W   #$20,-(A7)
000191fc: 4e41                           TRAP     #1
000191fe: dffc 0000 0006                 ADDA.L   #6,A7
00019204: 4a40                           TST.W    D0
00019206: 6600 0016                      BNE      *+$18 [$1921E]
0001920a: 42a7                           CLR.L    -(A7)
0001920c: 3f3c 0020                      MOVE.W   #$20,-(A7)
00019210: 4e41                           TRAP     #1
00019212: dffc 0000 0006                 ADDA.L   #6,A7
00019218: 41fa 0054                      LEA      ($54,PC) [$1926E],A0
0001921c: 2080                           MOVE.L   D0,(A0)
0001921e: 4cdf 0300                      MOVEM.L  (A7)+,A0-A1
00019222: 4e75                           RTS

GEMDOS_SuperOff:
00019224: 48e7 00c0                      MOVEM.L  A0-A1,-(A7)
00019228: 2f3c 0000 0001                 MOVE.L   #1,-(A7)
0001922e: 3f3c 0020                      MOVE.W   #$20,-(A7)
00019232: 4e41                           TRAP     #1
00019234: dffc 0000 0006                 ADDA.L   #6,A7
0001923a: 4a40                           TST.W    D0
0001923c: 6700 0012                      BEQ      *+$14 [$19250]
00019240: 2f3a 002c                      MOVE.L   ($2C,PC) [$1926E],-(A7)
00019244: 3f3c 0020                      MOVE.W   #$20,-(A7)
00019248: 4e41                           TRAP     #1
0001924a: dffc 0000 0006                 ADDA.L   #6,A7
00019250: 4cdf 0300                      MOVEM.L  (A7)+,A0-A1
00019254: 4e75                           RTS

BEFORE:
A0:
0 $19256: DC.W $ffff
2 $19258: DC.L $ffffffff
6 $1925C: DC.W $0001
8 $1925E: DC.W $00e0
10 $19260: DC.W $0000
12 $19262: DC.W $0000

A1:
$19264: DC.W $ffff,$ffff
$19268: DC.W $ffff
$1926A: DC.L $00000000
$1926E: DC.L $00000000
$19272: DC.L $00000200
$19276: DC.L $0
$1927A: DC.L $0001fd88
$1927E: DC.L $695cb2a0
$19282: DC.W $0000


$19284: DC.B "arkanoid.PRO",0
$192AC: DC.B "\x1blDisc error loading file",0
$192C6: DC.B "\x1blThis disc is a copy",0
$192DC: DC.B "\x1blData has been corrupted",0
$192F6: DC.B " - Press a key",0,0

$19306: DC.W $0001,$e1f0,$0000
$1930C: DS.B ...            ;buffer

Atari ST Protection: PASTI file format

Files in this format have the extension “.stx”, probably for “ST – eXtended”. This description is valid for files created with PASTI 0.4b BETA.

  • 0x.. is a hex offset to the beginning of the structure
  • .b = a single byte
  • .w = a 16-bit word (little endian!)
  • .l = a 32-bit word (little endian!)

A typical protected file looks like this:

  • File Header
  • Track Header
  • Sector Header
  • Sector Header
  • Sector Header
  • Fuzzy sector mask
  • Track data (either the sectors or the whole track)
  • Track Header
  • Sector Header
  • Sector Header
  • Sector Header
  • Fuzzy sector mask
  • Track data (either the sectors or the whole track)

File header (16 bytes)

  • 0x00 : ‘R’,‘S’,‘Y’,0 – File ID
  • 0x04 : 0x03,0x00 – Probably the version number of the format
  • 0x06 : 1.w
  • 0x08 : 0.w
  • 0x0a : tracks.b (e.g. 80 or 160 for double sided)
  • 0x0b : 1
  • 0x0c : 0.l

After the file header one block for each track is following. Each block also starts with a 16 byte header:

Track Header (16 bytes)

  • 0x00.l : length of the track in bytes. This value plus the current position in the file points to the following track header.
  • 0x04.l : bytes of fuzzy sector mask in this track
  • 0x08.w : number of sectors in the track
  • 0x0A.w : bitmask with flags
  • 0x0C.w : length of the track in bytes (around 6kb is normal)
  • 0x0E.b : track number
  • 0x0F.b : unused in the file

The bitmask for the flags

  • 7 – The track image also contains a sync-offset to the beginning of the first sync marker
  • 6 – If set the track is saved as an image with all gaps via the read track command with the sector content filled in via read sector.
  • 5 – with PASTI 0.4b always set, if Bit 0 is set (= track protected)
  • 4 – unused
  • 3 – unused
  • 2 – unused
  • 1 – unused
  • 0 – If set the track is protected or with a non-standard sectorsize (!= 512 bytes)

If Bit 0 is clear, the track is unprotected and the number of sectors as stored in the track block header are simply saved as 512 byte blocks directly after the header. The track is therefore 16 + 512 * sectors bytes long.

If Bit is set, the header is first followed the sector headers. One for each sector in the track, again 16 bytes per header.

Sector Header (16 bytes)

  • 0x00.l : sector offset inside the track data
  • 0x04.w : position of the sector header relative to the beginning of the track as a time stamp. The position timing is depended on the RPM speed of the drive, but for a ~6250 byte track the value for a full rotation is around 50000 (for 300 rpm). This allows software to simulate the time it takes to find the sector and read it, something certain copy protection schemes test.
  • 0x06.w : read timing of the sector data, certain copy protections write sectors so, that it takes longer to read them. The protection measures the time to read the sector. 16384 is the default value, larger values mean that it takes longer to read the sector than normal. However if the measured value by PASTI is within 2% of this value (16384 +/- 320), the value written to the stx file is 0 as a sign for a stable read speed.
  • 0x08.b : Track number from the address block identifying the sector (typically 0..79)
  • 0x09.b : Side from the address block identifying the sector (typically 0 or 1)
  • 0x0a.b : Sector from the address block identifying the sector (typically 1..9)
  • 0x0b.b : Size of the sector from the address block identifying the sector (typically: 0=128, 1=256, 2=512 or 3=1024 bytes)
  • 0x0c.b : First byte of the CRC over the address block
  • 0x0d.b : Second byte of the CRC over the address block
  • 0x0e.b : FDC status register after reading the sector
  • 0x0f.b : Sector flags, always 0x00

The CRC is a CCITT CRC16 calculated by the FDC. It is initialized with 0xFFFF and includes the sync marks, therefore typically 0xA1,0xA1,0xA1,0xFE plus the 4 bytes from the address block.

The FDC status is typically 0x00. Also common is 0x10 for a sector not found and 0x08 for a CRC error when reading. Bit 7 has a special meaning: it hints that the sector has fuzzy bits and the fuzzy sector mask should be used. If Bit 7 is set, Bit 3 is usually also set, because fuzzy bits will trigger a CRC error inside the sector.

After the sector headers the fuzzy sector mask is following, if the value is != 0 in the track header. The mask identifies the bits that are random in a given sector. The size of the fuzzy sector mask depends on the sector size (from the header) and the number of fuzzy sectors in the track itself. The fuzzy sector mask has bits set for every bit in in the sector, that is not random. Therefore a byte generated with the mask could be calculated like this:

fdcSectorByte[byteOffset] = (sectorData[byteOffset] & fuzzyMask[byteOffset])
                            | (rand() & ~fuzzyMask[byteOffset])`

After the fuzzy sector mask, the sectors are written to the file. If neither Bit 6 or 7 in the track flags is set, only the content of the sectors is written. Again with the sector size in the header taking into consideration. These tracks can be also easily recognized by sector offsets that are always a power of 2 (typically in 512 byte increments), starting at 0.

Following the fuzzy sector mask is the track data area. This area can contain either the sectors by itself, or the complete track image with the sectors embedded, or the complete track with the sectors separate (following the track image). How they are stored is stored in Bit 6 and 7 in the track flags.

If Bit 6 and 7 are clear, there is no track image and the sectors are stored just by order end length – just like the fuzzy sector mask, except this time for all sectors. Warning: sectors can be missing, if only a header was read, but the data was missing. The FDC status has Bit 4 (Record not found) set in this case.

If Bit 6 is set and 7 is clear, the track image is written with a track image header and the sectors follow the track image in the usually order and length. The track image header is just a word (little endian, as usual) that contains the length of the track image.

Bit Bit 6 and 7 is set, the track image is written with a track image header that has two words: the first one is a byte offset to the first 0xA1 address mark sync, the second word is the length of the track image in bytes.

If Bit 7 is set, the sector data is usually merged inside the track image, the sector offsets then point inside the actual track image. However, it is possible for single sectors to have an offset behind the track image, if PASTI couldn’t map them correctly into the track image. A software should always read the sectors based on the sector offset in the sector header.

Atari ST Protection: Spy Vs Spy from Databyte

Another simple, yet efficient protection. Sector 9 in Track 79 is read twice, the EOR checksum has to change, done via “weak” or “fuzzy” bits in the sector. Again: easily defeated with a Floprd() patch.

move.w #$9,d0                                    ; 00CEC0: 303C 0009
bsr .l +$28 {$00CEEE}                            ; 00CEC4: 6100 0028
move.b d0,$cf2c                                  ; 00CEC8: 13C0 0000 CF2C
move.w #$9,d0                                    ; 00CECE: 303C 0009
bsr .l +$1a {$00CEEE}                            ; 00CED2: 6100 001A
move.b $cf2c,d1                                  ; 00CED6: 1239 0000 CF2C
cmp.b d0,d1                                      ; 00CEDC: B200
beq .l +$8 {$00CEE8}                             ; 00CEDE: 6700 0008
move.b #$0,d0                                    ; 00CEE2: 103C 0000
rts                                              ; 00CEE6: 4E75
move.b #$1,d0                                    ; 00CEE8: 103C 0001
rts                                              ; 00CEEC: 4E75
move.w #$1,-(a7)                                 ; 00CEEE: 3F3C 0001
move.w #$0,-(a7)                                 ; 00CEF2: 3F3C 0000
move.w #$4f,-(a7)                                ; 00CEF6: 3F3C 004F
move.w d0,-(a7)                                  ; 00CEFA: 3F00
move.w #$0,-(a7)                                 ; 00CEFC: 3F3C 0000
clr.l -(a7)                                      ; 00CF00: 42A7
move.l #$cf2e,-(a7)                              ; 00CF02: 2F3C 0000 CF2E
move.w #$8,-(a7)                                 ; 00CF08: 3F3C 0008
trap #14                                         ; 00CF0C: 4E4E
adda.l #$14,a7                                   ; 00CF0E: DFFC 0000 0014
lea $cf2e,a0                                     ; 00CF14: 41F9 0000 CF2E
move.w #$10,d1                                   ; 00CF1A: 323C 0010
move.b #$0,d0                                    ; 00CF1E: 103C 0000
move.b (a0)+,d2                                  ; 00CF22: 1418
eor.b d2,d0                                      ; 00CF24: B500
dbra d1,-6 {$00CF22}                             ; 00CF26: 51C9 FFFA
rts                                              ; 00CF2A: 4E75