taste          = $BFEC01
Cont           = $BFEE01
IntCon         = $BFED01
MaxWart        = $4000
MinWart        = $1000
;
;------- graphics.library ------
;
Textaus              = -30 - 30InitRastPort         = -30 -168
Movee                = -30 -210Draw                 = -30 -216
RectFill             = -30 -276
SetAPen              = -30 -312
InitBitMap           = -30 -360
;
;--------- exec.library --------
;
ExecBase             =        4
;
AllocMem             = -30 -168
AvailMem             = -216
FreeMem              = -30 -180
OldOpenLibrary       = -30 -378
CloseLibrary         = -30 -384
FindName             = -276
;
MEMF_Chip            = $02
MEMF_Fast            = $04
MEMF_Largest         = $20000

DevList              = 350
Port                 = 36                      ;Drive 0
IDNestCnt      = 294

;
;-------------------------------
;
floppy_size = floppyend - floppy

floppy_s       = floppy_size/6-1

ON             = 1
OFF            = 0

;Error-Flag Werte

NoError        = $0000
KeineSync      = $0001
Längeungleich  = $0002
Längeungleich2 = $0003
KeineDisk      = $0004
ReadError      = $0005
VerifyError    = $0006
DiskProtect    = $0007
NotProtect     = $0008
Escape         = $0009

CopyVersuche1  = 3                       ;Versuche, bei illegalen Daten
CopyVersuche2  = 3                       ;Versuche, bei NoSync

;Ladeoptionen

OhneSync       = $0000
MitSync        = $ffff

;Schreiboptionen

NoIndex        = $0000
IndexOk        = $ffff

;Größe des belegten Speichers

SortBlockAnz  = $40      ;Anzahl der Blöcke deren Längen Sortiert werden
Bytelesen      = $3600
BSize          = 2*Bytelesen
req            = 2        ;Chip Memory
CIAA           = $BFE000

Lückenlänge    = $500    ;Länge der Lücke bei FastCopy
AnzLesenF      = 5       ;Anzahl der Leseversuche bei Readerror (Fast)

;Werte für Cruncher

KurzNull       = $80
MittelNull     = $20
LangNull       = $08
KurzNorm       = $40
MittelNorm     = $10
LangNorm       = $04
KurzKein       = $c0
MittelKein     = $30
LangKein       = $02
LeerBlock      = $01


               lea DevName,a1
               move.l $4,a6
               lea DevList(a6),a0
               jsr FindName(a6)
               move.l d0,a0
               beq Ende
               lea Port(a0),a0
               clr.w d0
\An2:          tst.l (a0)+
               beq \An1
               bset d0,Drives
\An1:          addq.w #1,d0
               cmp.w #4,d0
               bne.s \An2
        move.l ExecBase,a6
        lea    gfxname,a1
        jsr    OldOpenLibrary(a6)
        move.l d0,gfxbase
        beq  no_gfxbase

        move.l #$2800,d0
        move.l #$10002,d1
        jsr    AllocMem(a6)
        move.l d0,bit_adress
        beq  no_bitmap

        move.l #copsize+2,d0
        move.l #$10002,d1
        jsr    AllocMem(a6)
        move.l d0,cop_adress
        beq  no_copper
               MOVE.L #BSize,D0
               MOVE.L #req,D1
               JSR AllocMem(A6)
               TST.L D0
               BEQ no_DPuffer
               MOVE.L D0,TrackPuffer1
               addq.l #6,TrackPuffer1
               add.l #Bytelesen-6,d0
               move.l D0,TrackPuffer2
               bsr HolSpeicher           ;Speicher für Cruncher

               bra beg
copy_start:    MOVE.L $4,A6
               MOVE.B #$FF,$BFD300
      move.w #$0020,$dff09a
               JSR Disable

               MOVE.W #$8210,$DF096      ;DMA-Reg setzen

               clr.w FreiFlagCh
               clr.w FreiFlagFa

               bsr KopfAnf               ;Köpfe auf Null/Motorbits stellen
               bsr Start_End             ;Kopierbereich festlegen
               cmp.b #ON,dc1             ;Deepcopy 1
               beq \ME7
               cmp.b #ON,dc2
               bne \ME5
\ME7:          move.b SD,d0              ;ein Laufwerk-Copy?
               cmp.b DD,d0
               beq \ME6                  ;ja
               bsr SchaltS
\ME5:          bsr TestProtect
               tst.l d0
               bmi \ME4
               bsr protect_source
               tst.l d0
               bmi \ME3                  ;Escape
               bra \ME5
\ME4:
               cmp.b #ON,fa              ;Fastcopy on?
               bne \ME1
               bsr FastCopy
               bra \ME3
\ME1:          cmp.b #ON,dc1             ;Deepcopy1 on?
               bne \ME2
               bsr DeepCopy
               bra \ME3
\ME2:          cmp.b #ON,dc2             ;Deepcopy2 on?
               bne \ME3
\ME6:          bsr DeepCopy
\ME3:
               bsr SchaltS
               bsr MotorAus
               bsr SchaltD
               bsr MotorAus

               move.w #$0600,$dff09e
               move.w #$8100,$dff09e     ;Bits wieder zurückstellen
\Fehler:       bsr Enable
        move.w #$8020,$dff09a
Ende:          rts

TextausL:      move.w StartTrack,d0
               lsr.w #1,d0
               move.b d0,Cylinder
               bsr reading_cyl
               rts
TextausS:      move.w StartTrack,d0
               lsr.w #1,d0
               move.b d0,Cylinder
               bsr writing_cyl
               rts
;Read-Error ausgeben
RError:        move.w StartTrack,d0
               move.b #1,side
               btst #0,d0
               bne \RE1
               clr.b side
\RE1:          lsr.w #1,d0
               move.b d0,Cylinder
               bsr read_error
               rts
;Write-Error ausgeben
WError:        move.w StartTrack,d0
               move.b #1,side
               btst #0,d0
               bne \RE1
               clr.b side
\RE1:          lsr.w #1,d0
               move.b d0,Cylinder
               bsr write_error               rts

FastCopy:
               bsr Lückeschaffen
               move.b DD,d0
               cmp.b SD,d0
               beq \FC1
               bra FastCopyML            ;für mehrere Laufwerke
\FC1:          bra FastCopyEL            ;für ein Laufwerk

;FastCopy für mehrere Laufwerke
FastCopyML:
               bsr SchaltD
\FC5:          bsr TestProtect
               tst.l d0
               bpl \FC1
               bsr protect_Destination
               tst.l d0
               bmi \Fehler               ;Escape gedrückt
               bra \FC5
\FC1:          bsr TextausL
               bsr TrackLSF              ;Track von Source laden
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               bsr SchaltD
               move.w StartTrack,d0
               bsr KopfPos
               bsr TextausS
               bsr TrackFSchreiben
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #DiskProtect,ErrorFlag
               bne \FC3
               bsr protect_destination
               bra \Fehler
\FC3:          cmp.b #ON,vd              ;Verify ON ?
               bne \FC2                  ;verzweige, wenn nicht an
               bsr TrackFVerify
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #VerifyError,ErrorFlag
               bne \FC2
               bsr WError
               bsr compare_drives
\FC2:          add.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w EndTrack,d0
               bls \FC1
\Fehler        rts

;FastCopy für ein Laufwerk

FastCopyEL:
               clr.b KurzByte            ;KurzByte für Chruncher = 0
               move.w #$1600,Länge
               bsr NextSpeicher          ;Speicher zuordnen
\FCEL1:        bsr TestProtect
               tst.l d0
               bmi \FCEL3
               bsr protect_Source
               tst.l d0
               bmi \FCEL2                ;Escape gedrückt
               bra \FCEL1
\FCEL3:        bsr FCopy1DL              ;in Speicher lesen
               tst.l d0
               bmi \FCEL2
               move.l SchreibAnf,a5               add.l #LückenLänge,a5
\FCEL7:        move.w TNumPufferA,StartTrack
               bsr insert_destination
               tst.l d0
               bmi \FCEL2                ;Escape
\FCEL5:        bsr TestProtect
               tst.l d0
               bpl \FCEL6
               bsr protect_Destination
               tst.l d0
               bmi \FCEL2                ;Escape gedrückt
               bra \FCEL5
\FCEL6:        bsr FCopy1DS              ;Tracks schreiben
               tst.l d0
               bmi \FCEL2
               cmp.b #ON,ws              ;mehrfach schreiben?
               bne \FCEL8                ;nein
               bsr write_b_again
               cmp.w #Escape,ErrorFlag
               beq \FCEL2
               tst.l d0
               bpl \FCEL7                ; erneut schreiben
\FCEL8:        move.w StartTrack,TNumPufferA
               move.w TNumPufferE,d0
               cmp.w EndTrack,d0
               bcc \FCEL2
               bsr insert_source
               tst.l d0
               bmi \FCEL2                ;Escape
               bra \FCEL1
\FCEL2:        rts

FCopy1DL:
\FCD1:         bsr TrackLSF              ;Track von Source laden
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               move.l TrackPuffer2,a0    ;Zeiger Übergeben
               bsr Packe                 ;Track crunchen
               tst.l d0
               bmi \FCD2                 ;Speicher voll
               bsr TextausL              ;Text ausgeben
               add.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w EndTrack,d0
               bls \FCD1
\FCD2:         subq.w #1,StartTrack
               clr.l d0
               move.w StartTrack,TNumPufferE       ;Letzter Track
               rts
\Fehler:       move.l #-1,d0
               rts

;Copyteil zum schreiben mit einem Laufwerk
FCopy1DS:
               move.w StartTrack,d0      ;erster gelesenser Track
\FDS1:         bsr KopfPos
               bsr TextausS
               move.l TrackPuffer2,a0    ;Puffer für Track (Ziehl)
               bsr EntPacke              ;Track wieder in Normgröße
               move.l a5,a1              ;Ziehl (TrackPuffer1 + Lücke)
               move.l TrackPuffer2,a0    ;Quelle
               move.w StartTrack,d0      ;zu lesener Track
               bsr CodeTrack             ;Track kodieren
               move.w #00,FirstBlockSp   ;erster Block = Null
               bsr TrackFSchreiben
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #DiskProtect,ErrorFlag
               bne \FDS3
               bsr protect_destination
               bra \Fehler
\FDS3:         cmp.b #ON,vd              ;Verify ON ?
               bne \FDS2                 ;verzweige, wenn nicht an
               bsr TrackFVerify
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #VerifyError,ErrorFlag
               bne \FDS2
               bsr WError
\FDS2:         bsr Get_Key               ;Escape gedrückt ?
               cmp.b #$45,d0
               bne \FCS4                 ; nein, weiter
               move.w #Escape,ErrorFlag
               bra \Fehler
\FCS4:         addq.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w TNumPufferE,d0
               bls \FDS1
               clr.l d0
               clr.w FreiFlagCh          ;Chip-Mem ist wieder frei
               clr.w FreiFlagFa          ;Fast-Mem ist wieder frei
               rts
\Fehler:       move.l #-1,d0
               rts

;Track Crunchen und ablegen
;>= A0 Zeiger auf TrackPuffer
Packe:                                   ;Zeiger auf Track
               move.l a2,-(a7)
               move.l a0,a2
\PA2:          lea TrackZeiger,a0        ;Zeiger auf Tracktabelle
               clr.l d0
               move.w StartTrack,d0      ;Tracknummer
               lsl.w #2,d0
               adda.l d0,a0              ;Zeiger auf Speicherzeiger
               move.l SpeicherAnf,(a0)   ;Zeiger auf Track eintragen
               move.l SpeicherAnf,a1
               move.l a2,a0
               bsr Crunch
               tst.l d0
               bpl \PA1                  ;Ok, weiter
               bsr NextSpeicher          ;neuen Speicher holen
               tst.l d0
               bpl \PA2                  ;Ok, Speicher geholt
\PA1:          move.l (a7)+,a2
               rts

;Track aus Speicher holen
;>= A0 = Zeiger auf Ziehl für Track
EntPacke:
               move.l a0,a1
               lea TrackZeiger,a0        ;Zeiger auf Tracktabelle
               clr.l d0
               move.w StartTrack,d0     ;Tracknummer
               lsl.w #2,d0
               adda.l d0,a0              ;Zeiger auf Speicherzeiger
               move.l (a0),a0            ;Zeiger auf Track holen
               bsr DeCrunch
               rts

HolSpeicher:
               move.l a6,-(a7)
               move.l #MEMF_Chip,d1
               or.l #MEMF_Largest,d1
               move.l ExecBase,a6
               jsr AvailMem(a6)
               move.l d0,LängeChip
               bne \HS1
               clr.l SpeicherChip        ;kein Chip verfügbar
               bra \HS2                  ;Fast-Mem holen
\HS1:          jsr AllocMem(a6)
               move.l d0,SpeicherChip
\HS2:          move.l #MEMF_Fast,d1
               or.l #MEMF_Largest,d1
               jsr AvailMem(a6)
               move.l d0,LängeFast
               bne \HS3                  ;ok
               clr.l SpeicherFast
               bra \HS4                  ;kein Fast verfügbar
\HS3:          jsr AllocMem(a6)
               move.l d0,SpeicherFast
\HS4:          move.l (a7)+,a6
               clr.w FreiFlagCh          ;Speicher ist frei
               clr.w FreiFlagFa
               rts

;Nächsten Speicherblock holen
NextSpeicher:
               tst.w FreiFlagCh          ;Chip noch Frei
               bpl \NS1                  ;Ja, ist frei
\NS3:          tst.w FreiFlagFa          ;Fast noch frei
               bpl \NS4                  ;Ja, ist frei
\NS5:          move.l #-1,d0             ;kein Speicher frei
               bra \NS2
\NS4:          move.l SpeicherFast,d0
               beq \NS5                  ;kein Fast frei
               move.l LängeFast,d1
               move.w #$ffff,FreiFlagFa  ;Fast belegen
               bra \NS6
\NS1:          move.l SpeicherChip,d0
               beq \NS3                  ;kein Chip frei
               move.l LängeChip,d1
               move.w #$ffff,FreiFlagCh  ;Chip belegen
\NS6:          move.l d0,SpeicherAnf
               move.l d1,SpeicherLänge
               clr.l d0
\NS2:          rts

;Track laden (Fastcopy)
;>= StartTrack = Track der geladen wird
;=> SBytes = Anzahl der Bytes zu schreiben
;=> SchreibAdr = Adresse, ab der geschrieben wird

TrackLSF:
               movem.l d2/a2,-(a7)
               bsr SchaltS
               move.l TrackPuffer1,a5
               move.l a5,SchreibAnf
               add.l #Lückenlänge,a5
               move.l TrackPuffer2,a4
               move.w #(LückenLänge+$2ec0+2),SLänge
               move.w StartTrack,d0
               bsr KopfPos
               move.w #AnzLesenF-1,d2
\TSF6:         bsr FastLesen
               move.w FirstBlock,FirstBlockSp  ;erster geladener Block
               cmp.w #KeineDisk,ErrorFlag
               beq \TSF7
               cmp.w #ReadError,ErrorFlag
               bne \TSF5
               dbf d2,\TSF6              ;verzweige, wenn erleutes Lesen
               tst.l d0                  ;Keine Sync gefunden
               bpl \TSF1
               move.l a4,a0              ;Puffer Übergeben
               bsr DOSLösch              ;Track als leer speichern
\TSF1:
               bsr RError                ;Fehler ausgeben
               move.l a4,a0
               move.l a5,a1
               move.w StartTrack,d0      ;Tracknummer übergeben
               bsr CodeTrack             ;Track aus den Daten generieren
               clr.w FirstBlockSp        ;erster Block = 0
\TSF5:         clr.l d0
\TSF7:         movem.l (a7)+,d2/a2
               rts

;Lückenbytes in Trackpuffer eintragen
Lückeschaffen:
               move.l TrackPuffer1,a0
               move.w #(Lückenlänge/4)+4,d0
\LS1:          move.l #$aaaaaaaa,(a0)+
               dbf d0,\LS1
               rts

TrackFVerify:
               movem.l d2-d4/a4-a5,-(a7)
               clr.w d3                  ;Destzähler
               clr.w VerErrFlag          ;Verify-Error-Flag löschen
               move.b MotorBits,d4       ;MotorBits speichern
\TF2:          move.l TrackPuffer2,a5
               move.l TrackPuffer1,a4
               add.l #Lückenlänge,a4
\TF1:
               move.b tr,d2              ;Azahl der Schreibversuche
               move.w d3,d1              ;Destnummer nach D1
               bsr SchaltND              ;Desteinschalten
               tst.l d0                  ;Laufwerk vorhanden
               bmi \TF6                  ;Nein
\TF4:          bsr FastVerify
               cmp.w #KeineDisk,ErrorFlag
               beq \TF3                  ;Error, No Disk
               cmp.w #VerifyError,ErrorFlag               bne \TF6                  ;kein Error, weiter
               subq.b #1,d2              ;Errorzähler verringern
               bne \TF5                  ;Weiter, wenn noch ein Versuch
               bset d3,VerErrFlag        ;Bit für Error setzen
\TF6:          addq.w #1,d3              ;Dest Zahl erhöhen
               cmpi.w #4,d3
               bcs \TF1               bra \TF3                  ;keine weitern Laufwerke
\TF5:          bsr TrackFSchreiben
               bra \TF4
\TF3:          move.b d4,MotorBits
               movem.l (a7)+,d2-d4/a4-a5
               rts

TrackFschreiben:
               move.l a5,-(a7)
               move.l SchreibAnf,a5
               move.w SLänge,d0
               move.w #NoIndex,d1
               bsr schreiben
               move.l (a7)+,a5
               rts
DeepCopy:
               move.b DD,d0
               cmp.b SD,d0
               beq \DC1
               bra DeepCopyML            ;für mehrere Laufwerke
\DC1:          bra DeepCopyEL            ;für ein Laufwerk

DeepCopyEL:
               move.b #$aa,KurzByte      ;KurzByte für Chruncher = aa
               bsr NextSpeicher          ;Speicher zuordnen
               bsr insert_destination
               tst.l d0
               bmi \FCEL2
\FCEL9:        bsr TestProtect
               tst.l d0
               bpl \FCEL10
               bsr protect_Destination
               tst.l d0
               bmi \FCEL2                ;Escape gedrückt
               bra \FCEL9
\FCEL10:       bsr LängenTest
               move.w StartTrack,TrackNumS
               move.w LängeDest,d0       ;Länge für Cruncher
               addi.w #$10,d0
               move.w d0,Länge
\FCEL11:       bsr insert_source
               tst.l d0
               bmi \FCEL2
\FCEL1:        bsr TestProtect
               tst.l d0
               bmi \FCEL3
               bsr protect_Source
               tst.l d0
               bmi \FCEL2                ;Escape gedrückt
               bra \FCEL1
\FCEL3:        bsr DeepCopy1DL           ;in Speicher lesen
               tst.l d0
               bmi \FCEL2
\FCEL7:        move.w TNumPufferA,StartTrack
               bsr insert_destination
               tst.l d0
               bmi \FCEL2
\FCEL5:        bsr TestProtect
               tst.l d0
               bpl \FCEL6
               bsr protect_Destination
               tst.l d0
               bmi \FCEL2                ;Escape gedrückt
               bra \FCEL5
\FCEL6:        bsr DeepCopy1DS           ;Tracks schreiben
               tst.l d0
               bmi \FCEL2
               cmp.b #ON,ws              ;mehrfach schreiben?
               bne \FCEL8                ;nein
               bsr write_b_again
               cmp.w #Escape,ErrorFlag
               beq \FCEL2
               tst.l d0
               bpl \FCEL7                ; erneut schreiben
\FCEL8:        move.w StartTrack,TNumPufferA
               move.w TNumPufferE,d0
               cmp.w EndTrack,d0
               bcs \FCEL11
\FCEL2:        rts

DeepCopy1DL:
\FCD1:         clr.w ErrorFlag
               bsr TrackLS               ;Track von Source laden               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               move.l TrackPuffer2,a0    ;Zeiger Übergeben
               move.l SchreibAnf,a1
               lea -6(a0),a0
               move.l a1,(a0)
               move.w SLänge,4(a0)
               bsr Packe                 ;Track crunchen
               tst.l d0
               bmi \FCD2                 ;Speicher voll
               bsr TextausL
\FCD3:         add.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w EndTrack,d0
               bls \FCD1
\FCD2:         subq.w #1,StartTrack
               clr.l d0
               move.w StartTrack,TNumPufferE       ;Letzter Track
               rts
\Fehler:       move.l #-1,d0
               rts

;Copyteil zum schreiben mit einem Laufwerk
DeepCopy1DS:
               move.w StartTrack,d0      ;erster gelesenser Track
\FDS1:         bsr KopfPos
               bsr TextausS
               move.l TrackPuffer2,a0    ;Puffer für Track (Ziehl)
               lea -6(a0),a0
               bsr EntPacke              ;Track wieder in Normgröße
               move.l TrackPuffer2,a0
               move.l -6(a0),Schreibanf
               move.w -2(a0),SLänge
               move.l #$aaaaaaaa,-4(a0)
               bsr TrackSchreiben
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #DiskProtect,ErrorFlag
               bne \FDS3
               bsr protect_destination
               bra \Fehler
\FDS3:         cmp.b #ON,vd              ;Verify ON ?
               bne \FDS2                 ;verzweige, wenn nicht an
;               bsr TrackFVerify
;               cmp.w #KeineDisk,ErrorFlag
;               beq \Fehler
;               cmp.w #VerifyError,ErrorFlag
;               bne \FDS2
;               bsr WError
\FDS2:         addq.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w TNumPufferE,d0
               bls \FDS1
               clr.l d0
               clr.w FreiFlagCh          ;Chip-Mem ist wieder frei
               clr.w FreiFlagFa          ;Fast-Mem ist wieder frei
               rts
\Fehler:       move.l #-1,d0
               rts


DeepCopyML:
               bsr SchaltD
\DC5:          bsr TestProtect
               tst.l d0
               bpl \DC3
               bsr protect_Destination
               tst.l d0
               bmi \Fehler               ;Escape gedrückt
               bra \DC5
\DC3:          bsr LängenTest
               tst.l d0
               bmi \Fehler
\DC1:
               bsr TextausL
               bsr TrackLS               ;Track von Source laden
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               bsr SchaltD
               move.w StartTrack,d0
               bsr KopfPos
               bsr TextausS
               bsr TrackSchreiben
               cmp.w #KeineDisk,ErrorFlag
               beq \Fehler
               cmp.w #DiskProtect,ErrorFlag
               bne \DC2
               bsr protect_destination
               bra \Fehler
\DC2:          add.w #1,StartTrack
               move.w StartTrack,d0
               cmp.w EndTrack,d0
               bls \DC1
\Fehler:       rts


;Track von Source oder Dest. laden
;>= StartTrack = Track der geladen wird

TrackLS:       bsr SchaltS
               move.l TrackPuffer1,a5
               move.w StartTrack,d0
               bsr KopfPos
               bsr TrackLaden   
               rts

;Überprüft die Längen der Source- und Destdiskette;=>LängeSource = Länge der Sourcedisk
;=>LängeDest   = Länge der Destdisk
LängenTest:
               bsr SchaltD
               move.w StartTrack,d0
               bsr KopfPos
               move.l TrackPuffer2,a5
               bsr löschen
               move.w #Bytelesen-$15,d0
               bsr schreiben
               tst.l d0
               bmi \TD1                  ;Disk schreibgeschützt
               bsr Zählen
               tst.l d0
               bmi \TD1                  ;Keine Disk im Laufwerk
               move.w CheckLänge,LängeDest
\TD1:          rts

;Track laden, nachdem die Motorbits eingestellt wurden
;>= A5 = Zeiger auf den Lesepuffer
;=> SchreibAnf = Zeiger auf die zu schreibenden Daten
;=> SLänge = Anzahl der zu schreibenden Bytes

TrackLaden:
               move.w #CopyVersuche1,CopyVersuch1
Versuch1:
               move.w #CopyVersuche2,CopyVersuch2   ;Versuche, bei NoSync
Versuch2:

;Länge von Track messen (Index <=> Index)
;Lesen der Daten ohne DMA in Puffer ab A5

               move.w #NoError,ErrorFlag
               bsr Zählen                ;=> Checklänge = länge von Track
               tst.l d0                  ;Disk im Laufwerk?
               bmi \TrackLadenEnd

;entfernung von Index zu Sync messen
;wenn keine Sync, dann D0 = -1
;=> Syncweit = Entfernung bis Sync

               bsr Syncentfernung
               tst.l d0
               bpl \OK2
               sub.w #1,CopyVersuch2
               bne Versuch2

;Programmteil, wenn keine Sync gefungen wird

\TL7:          move.l TrackPuffer2,a5
               bsr CopyOSync               bra \TL11

\OK2:
               move.w CheckLänge,d0
               add.w #$100,d0
               move.w #MitSync,d1
               bsr laden
               move.w SyncWort,(a5)      ;erste Sync eintragen

;Anzahl der Bytes auf Track ermitteln (Sync zu Sync)
;=> D0 = -1, wenn Anzahl zu stark von Checklänge abweicht
;=> TrackBytes = Länge des Tracks

               bsr SuchTEnd
               tst.l d0
               bpl \TL3
               bsr SuchTEnd2
               tst.l d0
               bpl \TL3
               sub.w #1,Copyversuch1
               bne Versuch1

               move.w CheckLänge,TrackBytes
               sub.w #$10,TrackBytes     ;Wenn kein Ende gefunden
                                         ;Track kürzen

;Lücke suchen, wenn Sync gefunden
;>= A5 Zeiger auf Trackanfang
;=> Größe1 = größe des größten Blocks
;=> Größe2 = größe der zweitgrößten Blocks

;=> GrößePos = Position des größten Blocks
;=> SyncAnz = Anzahl der gefundenen Syncs

\TL3:
               clr.l d0
               move.w TrackBytes,d0
               add.l a5,d0
               move.l d0,EndPos

               bsr Blockerkennung
               cmp.w #SortBlockAnz,SyncAnz
               bls \TL2                  ;Anzahl der Sync Ok

;Zu viele Blöcke zum zwischenspeichern

               move.l GrößePos,AnfPos   ;Lücke beim größten Block               bra \TL1                 ;Zu viele Blöcke zum sortieren
\TL2:
               bsr TrackAmiga            ;Testen, ob Amiga-Track
               tst.l d0
               bpl \TL4                  ;verzweige, wenn Amiga-Track
               cmp.b #ON,sy              ;Sync-Korrektur
               bne \TL5                  ;nein
\TL4:          bsr Synckorrektur
\TL5:          bsr OrdneBlöcke
               bsr SuchLücke
\TL1:          move.l TrackPuffer2,a4    ;Ziehl beim Kopieren
               bsr Umkopieren
\TL11:         clr.l d0                  ;Errorflag löschen
\TrackladenEnd:
               rts

;Track Laden, der keine Sync hat
;>= A5 = Trackpuffer
;=> Lückelang = Lenge der Lücke
;=> Syncweit = 0  (keine Sync)
;=> TrackBytes = Anzahl der Bytes auf dem Track

CopyOSync:
               movem.l d2-d3,-(a7)
               move.w CheckLänge,d0
               cmp.w #Bytelesen-50,d0       ;Source-Track zu lang
               bcc \COS7
               add.w #36,d0
               bra \COS6
\COS7:         move.w #Bytelesen-50,CheckLänge
               move.w #Bytelesen-16,d0
\COS6:         move.w #OhneSync,d1
               bsr laden
               tst.l d0
               bmi \COS1
               move.w CheckLänge,d1
               sub.w #50,d1

               move.l a5,a0              ;Trackpuffer
               move.b (a0)+,d2           ;erste Byte holen
\COS2:         move.b (a0)+,d3
               cmp.b d2,d3               ;Bytes vergleichen
               bne \COS4                 ;ungleich
               sub.w #1,d1               ;Anzahl erhöhen
               bne \COS2
               bra \COSOK                ;Track überall gleich

\COS4:         add.l #2,a0               ;Lücke überspringen
               move.b (a0)+,d2
\COS3:
               move.b (a0)+,d3
               cmp.b d2,d3               ;Bytes vergleichen
               bne \COSNO                ;nicht immer gleich
               sub.w #1,d1               ;Zähler erhöhen
               bne \COS3               move.l a5,a0

\COSOK:        move.w LängeDest,d0
               add.w #$10,d0
\COS5:         move.b d2,(a0)+
               dbf d0,\COS5
\COSNO:        move.w LängeDest,d0
               add.w #$4,d0
               move.w d0,TrackBytes
               move.w d0,SLänge          ;Anzahl der zu Schreibbytes
               move.l a5,SchreibAnf      ;Anfang der Daten
               move.w #KeineSync,ErrorFlag
               clr.l d0
               movem.l (a7)+,d2-d3
               rts
\COS1:         move.l #-1,d0
               rts

Trackschreiben:
               move.l SchreibAnf,a5
               move.w SLänge,d0
               bsr schreiben
               rts
löschen:
               move.l TrackPuffer2,A0
               move.w #(Bytelesen-$10)/4,d0
\Lö2:          move.l #$aaaaaaaa,(a0)+
               dbf d0,\Lö2
               rts

;Kopierbereich festlegen (Start- und End-Cylinder)
;>= StartTrack = Track bei dem angefange wird (Track!!)
;>= EndTrack   = Track der als letztes kopiert wird (Track!!)

Start_End:     clr.l d0
               move.b fc,d0              ;erster Cylinder
               lsl.b #1,d0               ;Cylinder => Track
               move.w d0,StartTrack
               move.w d0,TNumPufferA
               move.b lc,d0              ;letzer Cylinder
               lsl.b #1,d0               ;Cylinder => Track
               add.w #1,d0               ;letzeer Track = Untere Seite
               move.w d0,EndTrack
               rts

;Prüft, ob Disk im Laufwerk
;=> D0 = -1, wenn keine Disk im Laufwerk

DiskInFloppy:
               clr.l d0
               move.b $bfe001,d0
               btst #2,d0
               bne \DIF
               move.l #-1,d0
               move.w #KeineDisk,ErrorFlag
\DIF:          rts

;Track Laden
;A5 = Zeiger auf Datenpuffer

Laden:         MOVEM.L d2-d3,-(A7)
               move.w d0,d3              ;ByteAnz zu lesen
               lsr.w #1,d3
               bsr DiskInFloppy
               tst.l d0
               bmi \L1
               MOVE.W #$8010,$DFF096     ;Disk-DAM ermöglichen
               move.w #$7f00,$DFF09E     ;Disk-Bits löschen
               MOVE.L A5,A1              ;Zeiger auf Datenpuffer
               MOVE.L A1,$DFF020         ;Datenpuffer übergeben
               cmp.w #MitSync,d1
               bne \L3
               MOVE.W SyncWort,$DFF07E   ;SYNC-Wort übergeben
               move.w #$8500,$DFF09E
               lea 2(a5),a1
               move.l a1,$DFF020         ;neue Adresse übergeben
               bra \L4

\L3:           MOVE.W #$8100,$DFF09E     ;Auf MFM Format
\L4:           MOVE.W #$4000,$DFF024     ;Übertragung vorbereiten
               bsr Index                 ;Auf Index warten
               tst.l d0
               bmi \L1
               or.w #$8000,d3
               MOVE.W d3,$DFF024
               MOVE.W d3,$DFF024         ;Daten lesen
               clr.l d0                  ;Ok Meldung
               MOVE.L #$18000,D1         ;Zeitzähler setzen
               move.w #$0002,$dff09c     ;Blockdone Int löschen
\L2:           MOVE.W $DFF01E,D2
               BTST #1,D2
               BNE.S \L1                 ;auf Disk-Block Ready warten
               SUBQ.L #1,D1              ;Zähler verringern
               BNE.S \L2                 ;verzweige, wenn nicht fertig
               move.l #-1,d0
\L1:           MOVE.W #$4000,$DFF024
\L5:           MOVEM.L (A7)+,D2-d3
               RTS

;Auf Intexloch warten

Index:
               move.l d1,-(a7)
               clr.l d0
               move.l #$30000,d1
               MOVE.B $BFDD00,D0
Index1:        MOVE.B $BFDD00,D0         ;Auf Indexloch warten
               BTST #4,D0
               Bne.s Index2
               sub.l #1,d1
               bne Index1
               move.l #-1,d0
Index2:
               move.l (a7)+,d1
               rts


;Motorbits bestimmen Köpfe auf Null
KopfAnf:
               movem.l d2-d4,-(a7)
               clr.w d3
               move.b DD,d2              ;Dest-Drives
               or.b SD,d2                ;Source-Drives
\KA1:          clr.l d0
               btst d3,d2                ;Laufwerk jetzt gebraucht?
               beq \KA2                  ;nicht gebraucht
               bset d3,d0                ;Bit für Laufwerk
               lsl.b #3,d0
               eor.b #$fb,d0
               move.b d0,MotorBits
               bsr MotorAn
               clr.l d0
               bsr KopfPos
\KA2:
               addq.w #1,d3
               cmp.w #4,d3
               bne \KA1

               bsr MotBits
               move.b MotorBitsD,MotorBits
               move.b #-1,Flag
               clr.w TrackNumS
               clr.w TrackNumD
               bsr SchaltS
               movem.l (a7)+,d2-d4
               rts
TestDrive:
               move.l a0,-(a7)
               lea $bfd000,a0
               bclr #1,MotorBits
               bsr Schritt
               bset #1,MotorBits
               bsr Schritt
               move.l (a7)+,a0
               rts

;=> D0 = -1 => Disk protect
TestProtect:   bsr TestDrive
               clr.w ErrorFlag
               move.b $bfe001,d0
               btst #3,d0
               bne \TP2
               move.w #DiskProtect,ErrorFlag
               move.l #-1,d0
               bra \TP1
\TP2:          clr.l d0
\TP1:          rts

;Kopf auf in D0 angegebene Position Fahren 
  
KopfPos:       MOVEM.L D0-D3,-(A7)
               lea $bfd000,a0
               tst.w d0
               beq KopfNull
               move.w TrackNum,d2          ;Jetzige Tracknummer
               CMP.W d2,D0
               BEQ.S Kopfend             ;Ende wenn richtiger Track
               move.w d0,d3              ;Tracknummer nach D3
               move.b MotorBits,d1
               bset #2,d1                ;unterer Kopf
               btst #0,d3
               beq Unten                 ;unterer Kopf gewählt
               bclr #2,d1
Unten:         move.b d1,MotorBits          ;oberer Kopf
               move.b d1,$100(a0)
               move.w d3,TrackNum
               lsr.w #1,d2
               lsr.w #1,d3               ;Schrittweite berechnen
               sub.w d3,d2
               bcs.s Inn
               bhi.s Aus
               bra Kopfend
Inn:           bclr #1,d1
               move.b d1,MotorBits
               neg.w d2
               bra.s rechok
Aus:           bset #1,d1               move.b d1,MotorBits
               bra.s rechok
Kopfs:         bsr Schritt
rechok:        dbf d2,Kopfs
Kopfend:       movem.l (a7)+,d0-d3
               rts

KopfNull:
               move.b Motorbits,d1
               bset #2,d1
               bset #1,d1
               move.b d1,Motorbits
               clr.w TrackNum
KopfNull1:     move.b $bfe001,d0
               btst #4,d0
               beq.s \Ko1
               bsr Schritt
               bra KopfNull1
\Ko1:          bclr #1,MotorBits
               bsr Schritt
               bset #1,MotorBits
               bsr Schritt
               bra Kopfend

Schritt:
               move.b MotorBits,d0
               lea $100(a0),a1
               move.b d0,d1
               bclr #0,d0
               move.b d0,(a1)
               nop
               nop
               move.b d1,(a1)
               jsr Zeit
               move.b MotorBits,(a1)
               rts

;Warteschleife

Zeit:          MOVE.L D7,-(A7)
               MOVE.W #2500,D7
\L1:           DBRA D7,\L1
               MOVE.L (A7)+,D7
               RTS
Zeit2:         MOVE.L D7,-(A7)
               MOVE.L #$6000,D7
\L1:           sub.l #1,D7
               bne \L1
               MOVE.L (A7)+,D7
               RTS

;Motorroutine:   D0=0 => Motor aus

MotorAus:      clr.l d0
               bra Motor
MotorAn:       move.b #$01,d0

Motor:         movem.l d1/d2,-(a7)
               lea $bfd000,a0
               tst d0
               seq d1
               andi.b #$80,d1
               move.b MotorBits,d2
               andi.b #$80,d2
               cmp.b d1,d2
               beq.s Mook
               bclr #7,MotorBits
               or.b d1,MotorBits
               move.b #$ff,d1
               eor.b d2,d1
               move.b d1,$100(a0)
               move.b MotorBits,$100(a0)
               btst #7,MotorBits
               bne Mook
               jsr Zeit2
Mook:          movem.l (a7)+,d1/d2
               rts

Disable:       move.w #$4000,$dff09a
               move.l a6,-(a7)
               move.l $4,a6
               add.b #1,IDNestCnt(a6)
               move.l (a7)+,a6
               rts
Enable:        move.l a6,-(a7)
               move.l $4,a6
               sub.b #1,IDNestCnt(a6)
               bge L005
               move.w #$c000,$dff09a
L005:          move.l (a7)+,a6
               rts

;Wartet auf Byte beim Lesen und speichert Byte ab (a0)+

               rts

;>= a0 Adresse der zu suchnenden Daten
;>= A1 Adresse von der ab gesucht wird
;>= Suchlang = Anzagl der Worte für Fehler
;>= Anzworte = Anzahl der Worte, auf die verglichen wird
;=> D1 Anzahl der Bytes bis Fund
;=> Position = Wo gefunden
;=> D0 = -1 = nicht gefunden
;=> A0 Position wo gefunden

BitSuch:
               movem.l d2-d6/a2-a4,-(a7)
               move.l a0,a2
               move.l a1,a3
               clr.w d5
               move.w Suchlang,d4            ;Suchanzsuch2:         move.w #00,d3             ;Anzahl verschiebebits
such1:         move.l (a2),d1
               move.l (a3),d2
               bsr comp
               tst.w d0
               beq suchok
               move.l a0,a2
               tst.w d5
               beq such4
               clr.w d5
               move.w d6,d3
               move.l a4,a3
  
such4:         add.w #1,d3
               cmp.w #$10,d3
               bne such1
such3:         add.l #2,a3
               clr.w d5                  ;richtige vergleiche
               dbf d4,such2              ;Zähler für Versuche
               move.l #-1,d0             ;nicht gefunden
               bra suchend
suchok:
               tst.w d5
               bne suchok2
               move.l a3,a4
               move.w d3,d6

suchok2:       add.w #1,d5
               cmp.w Anzworte,d5               beq suchend1
               add.l #2,a2
               add.l #2,a3
               bra such1
suchend1:      move.l #0,d0
               sub.w #1,d5
               lsl.w #1,d5
               suba.l d5,a3
               move.l a3,a0
               move.l a3,Position
               move.l a3,a0              ;Position
               move.w d3,Verschieb       ;Bitverschiebung
               sub.l a1,a3
               move.l a3,d1              ;Anzahl der Bytes bis finden
suchend:       movem.l (a7)+,d2-d6/a2-a4
               rts

comp:          movem.l d1-d2,-(a7)
               lsl.l d3,d2
               swap d1
               swap d2
               eor.w d1,d2
               move.w d2,d0
               movem.l (a7)+,d1-d2
               rts



MotBits:
               move.b SD,d0              ;Source Disk
               lsl.b #3,d0
               eor.b #$fb,d0
               move.b d0,MotorBitsS
               move.b DD,d0              ;Dest Disk
               lsl.b #3,d0
               eor.b #$fb,d0
               move.b d0,MotorBitsD
               rts

;Nächstes Dest. Laufwerk einschalten
;!!! Vorsicht !!! alte Motorbits werden gelöscht
;>= D1 = wievieltes Laufwerk ( < 4)
;=> D0 = -1, wenn kein weiteres Laufwerk vorhanden
;=> D0 = Null, wenn ok

SchaltND:
               move.l d2,-(a7)
               clr.l d0
               move.b DD,d2
               btst d1,d2                ;Laufwerk angeschlosen?
               bne \SND1                 ;ja, angeschlosen
               move.l #-1,d0
               bra \SND2
\SND1:         bset d1,d0                ;Bit für Laufwerk
               lsl.b #3,d0
               eor.b #$7b,d0
               move.w StartTrack,d1
               bset #2,d0
               btst #0,d1
               beq \SND3                  ;unterer Kopf gewählt
               bclr #2,d0
\SND3:         move.b d0,MotorBits          ;oberer Kopf
               move.b d0,$bfd100
               clr.l d0
\SND2:         move.l (a7)+,d2
               rts

SchaltS:
               tst.b Flag
               bpl \S1
               move.b MotorBits,MotorbitsD
               move.w TrackNum,TrackNumD
               move.b MotorBitsS,MotorBits
               move.w TrackNumS,TrackNum
               move.b #$7f,$bfd100
               move.b MotorBits,d0
               bclr #7,d0
               move.b d0,$bfd100
               move.b d0,MotorBits
               clr.b Flag
\S1:           rts
SchaltD:
               tst.b Flag
               bmi \S1
               move.b MotorBits,MotorbitsS
               move.w TrackNum,TrackNumS
               move.b MotorBitsD,MotorBits
               move.w TrackNumD,TrackNum
               move.b #$7f,$bfd100
               move.b MotorBits,d0
               bclr #7,d0
               move.b d0,$bfd100
               move.b d0,MotorBits
               move.b #-1,Flag
\S1:           rts


;Track speichern
;>= D0 = Byteanzahl zu schreiben
;>= A5 = Trackpuffer
;>= D1 = Angabe, ob auf Index gewartet wird (IndexOk/NoIndex)

schreiben:     MOVEM.L D2-D3,-(A7)
               move.w d1,d2
               move.w d0,d3              ;Anzahl nach D3
               clr.w ErrorFlag
               bsr DiskInFloppy
               tst.l d0
               bmi \Protect
               move.b $bfe001,d0
               btst #3,d0
               bne \SR5
               move.w #DiskProtect,ErrorFlag
               bra \Protect
\SR5:          lsr.w #1,d3               ;Aus Byte mach Wort
               jsr MotorAn
               MOVE.W #2,$DFF09C         ;Disk-Block Int löschen
               MOVE.L A5,$DFF020         ;Datenpuffer übergeben
               MOVE.W #$8210,$DFF096     ;Disk-DMA ermöglichen
               move.w #$7f00,$dff09e
               MOVE.W #$8100,$DFF09E     ;Auf MFM Format
               cmp.w #80,StartTrack
               bcs \SR1
               move.w #$a000,$dff09e     ;Precompension
\SR1:          MOVE.W #$4000,$DFF024     ;Übertragung vorbereiten
               cmp.w #NoIndex,d2
               beq \SR2
               bsr Index
               tst.l d0
               bmi \Protect
\SR2:          or.w #$c000,d3            ;Auf schreiben schalten
               MOVE.W d3,$DFF024
               MOVE.W d3,$DFF024         ;Daten schreiben
               clr.l d0                  ;Ok-Meldung übergeben
               MOVE.L #$20000,D1         ;Zeitzähler setzen
\SR3:          MOVE.W $DFF01E,D2
               BTST #1,D2
               BNE.S \SR4                ;auf Disk-Block Ready warten
               SUBQ.L #1,D1              ;Zähler verringern
               BNE.S \SR3                ;verzweige, wenn nicht fertig
\Protect:      move.l #-1,d0
\SR4:          move.w #$4000,$dff024
               MOVEM.L (A7)+,D2-D3
               RTS

;Sucht Trackende wenn Sync gefunden
;>= A5 = Zeiger auf Trackpuffer (Syncs gefunden)
;=> TrackBytes = Anzahl der Bytes auf Track (suche nach Sync)
;=> D0 = -1, dann zu große Abweichnung zu CheckLänge

SuchTEnd:
               move.l a5,a0
               clr.l d0
               move.w CheckLänge,d0
               sub.w #$4,d0
               adda.l d0,a0
               move.w #$10,d0
               bsr SuchSync
               tst.l d0
               bmi \STE2
               suba.l a5,a0
               sub.w #2,a0
               move.w a0,TrackBytes
               rts
\STE2:         move.l #-1,d0
               move.w #Längeungleich,ErrorFlag               rts

SuchTEnd2:
               move.l a5,a0
               adda.l #$04,a0
               move.l a0,a1
               clr.l d0
               move.w CheckLänge,d0
               sub.w #$40,d0
               adda.l d0,a1
               move.w #$40,Suchlang
               move.w #$60,Anzworte
               bsr BitSuch               tst.l d0
               bmi \STE2
               suba.l a5,a0
               suba.l #6,a0              ;Position vor Sync
               move.w a0,TrackBytes
               rts
\STE2:         move.l #-1,d0
               move.w #Längeungleich2,ErrorFlag
               rts

;Blöcke suchen und speichern
;>= A5 Zeiger auf Trackanfang
;=> Größe1 = größe des größten Blocks
;=> Größe2 = größe der zweitgrößten Blocks
;=> GrößePos = Position des größten Blocks
;=> SyncAnz = Anzahl der gefundenen Syncs
;=> Blöcke = Puffer in den die Blockgrößen stehen

Blockerkennung: movem.l d2-d4/a3,-(a7)
               move.w TrackBytes,d2      ;Byte auf Track
               move.l a5,a3              ;Anfang des Tracks
               clr.w Größe1
               clr.w Größe2
               clr.w SyncAnz
               clr.w d3

\S2:           move.w d2,d0
               move.l a3,a0              ;Ab wo suchen
               bsr SuchSyncF
               tst.l d0
               bmi \S5                   ;Ende
               tst.w d1
               beq \S6
               move.w d3,d4
               add.w d1,d3               ;Anzahl + Sync
               bsr Blockeintrag
               bsr Größe
               clr.w d3                  ;Synclänge = 0
\S6:
               add.w #2,d3               ;Synclänge +2
               add.w #2,d1
               andi.l #$ffff,d1
               adda.l d1,a3
               sub.w d1,d2
               bcc \S2
               bra \S7
\S5:           move.w d2,d1
               add.w #2,d1               ;Amzahl +2
               move.w d3,d4              ;Syncanz
               add.w d1,d3               ;Anzahl + Syn
               bsr Blockeintrag
               bsr Größe
\S7:           movem.l (a7)+,D2-d4/A3
               rts

;Eintragen der Größe der Blöcke
;>= D1 Blockgröße

Größe:
               cmp.w Größe1,d3
               bcs \S3
               move.w Größe1,Größe2
               move.w d3,Größe1
               move.l a0,a1
               move.l a1,GrößePos
               bra \S4
\S3:           cmp.w Größe2,d3
               bcs \S4
               move.w d1,Größe2
\S4:           rts

Blockeintrag:
               move.w SyncAnz,d0
               cmp.w #$40,d0             ;Zu viele Blöcke ?
               bcc \S1                   ;ja, dann nicht eintragen
               lsl.w #2,d0
               lea Blöcke,a1
               lsr.w #1,d4
               move.w d4,(a1,d0)
               add.w #2,d0
               move.w d3,(a1,d0)         ;Block eintragen
\S1:           add.w #1,SyncAnz
               rts

;Sync-Markierungen suchen (fast)
;>= A0 Suchadresse
;>= D0 Byteanzahl für erlaubte Fehler
;=> A0 Syncadresse
;=> D0 = -1, dann keine Sync gefunden
;=> D1 = nach wieviel Bytes gefunden
SuchSyncF:
               lsr.w #1,d0               ;aus Byte mach Wort
               move.l a0,a1
\SSF2:         cmp.w #$4489,(a0)+
               beq \SSF1
               dbf d0,\SSF2
               move.l #-1,d0
               bra \SSF3
\SSF1:         suba.l #2,a0
               move.l a0,d0
               sub.l a1,a0
               move.w a0,d1
               move.l d0,a0
               clr.l d0
\SSF3:         rts


;Sync-Markierung suchen
;>= A0 Suchadresse
;>= D0 Byteanzahl für erlaubte Fehler
;=> A0 Syncadresse
;=> D0 = -1, dann keine Sync gefunden
;=> D1 = nach wieviel Bytes gefunden
;=> Verschieb = um wieviel Bits verschoben



SuchSync:
               movem.l d2-d4/a2,-(a7)
               move.l a0,a2
               lsr.w #2,d0               ;aus Byte- mach Langwortanzahl
               lea SyncBase,a1
\SS3:          clr.l d1
               move.l #$ffff0000,d3
               move.l (a0)+,d2
\SS2:          move.l d2,d4
               and.l d3,d4
               cmp.l (a1,d1),d4
               beq \SS1
               add.w #4,d1
               lsr.l #1,d3
               cmp.w #$40,d1
               bls \SS2
               dbf d0,\SS3
               move.l #-1,d0
               bra \SS4
\SS1:          clr.l d0
               lsr.w #2,d1
               move.w d1,Verschieb
               cmp.w #$8,d1
               bcc \SS5
               suba.l #2,a0
\SS5:          suba.l #2,a0
               move.l a0,d1
               suba.l a2,a0
               exg.l a0,d1
\SS4:          movem.l (a7)+,d2-d4/a2
               rts

;Entfernung Index <=> Sync
;=> Syncweit = entfernung Index<=>Sync
;=> D0 = -1, dann keine Sync gefunden

Syncentfernung:
               move.l a5,a0
               move.w CheckLänge,d0
               bsr SuchSync
               tst.l d0
               bpl \SE1
               move.w #KeineSync,ErrorFlag
               bra \SE2
\SE1:
               move.w d1,Syncweit
\SE2:          rts

;A5 = TrackPuffer

;Zähler der Daten auf Disk ohne Sync und ohne DMA
;>= A5 = Zeiger auf Verify-Puffer zum Lesen der Daten ohne Sync
;=> CheckLänge = Länge eines Tracks (Von Index bis Index)

Zählen:
               bsr DiskInFloppy
               tst.l d0
               bmi \Z5
               movem.l d2-d4/a2-a3,-(a7)
               move.w #$0600,$dff09e     ;Sync ausschalten
               move.w #$8000,$dff024
               lea $dff01b,a0
               lea $dff01a,a1
               lea $bfdd00,a2
               move.l #15,d2
               move.l #4,d3
               move.w #1,d4
               clr.w d0
               move.b (a2),d1            ;Byteready Flag löschen
\Z4:           move.b (a2),d1
               btst #4,d1
               beq.s \Z4
               move.w (a1),d1            ;Byteready Flag löschen
               move.b (a2),d1            ;Indexbit löschen
               move.l a5,a3
\Z1:
               btst d2,(a1)
               beq.s \Z1
               btst d3,(a2)
               bne.s \Z2
               add.w d4,d0
               move.b (a0),(a3)+
               bra \Z1
\Z2:
               andi.w #$fffe,d0
               move.w d0,CheckLänge
               cmp.w #Bytelesen,d0       ;Track zu lang
               bcs \Z6
               move.w #Bytelesen-16,CheckLänge
\Z6:           bclr #31,d0               ;Errorbit löschen
               movem.l (a7)+,d2-d4/a2-a3
\Z5:           move.w #$4000,$dff024
               rts

;Sortiert Blockgrößen

OrdneBlöcke:
               move.l d2,-(a7)
               cmp.w #SortBlockAnz,SyncAnz               bhi \OBEND                ;zu viele Blöcke
               tst.w SyncAnz
               beq \OBEND                ;keine Blöcke
               clr.w AnzSortBlock
               lea Blöcke,a0
               move.w SyncAnz,d0
\OB5:          move.l (a0)+,d1
               sub.w #1,d0
               lea SortBlöcke,a1         ;Anzahl der Blöcke -1
               move.w AnzSortBlock,d2
               tst.w d2
               beq \OB2                  ;erster Block
\OB4:          cmp.w (a1)+,d1
               bne \OB3                  ;gefunden
               add.w #1,(a1)
               bra \OB6
\OB3:          adda.w #2,a1
               sub.w #1,d2
               bne \OB4                  ;weiter suchen
\OB2:          move.w d1,(a1)+
               move.w #1,(a1)+
               add.w #1,AnzSortBlock
\OB6:          tst.w d0
               bne \OB5                  ;neu suchen
\OBEND:        move.l (a7)+,d2
               rts

SuchLücke:
               move.l d2,-(a7)
               clr.l AnfPos
               move.w AnzSortBlock,d0

               cmp.b #1,dc1
               beq \SL10                 ;DeepCopy 1 (lücke nach gr. Block)
;einzelne Blöcke suchen

               sub.w #1,d0               ;Blocknummer -1
\SL3:
               bsr EinBlock              ;Einzelnen Block suchen
               tst.l d0                  ;Lücke gefunden?
               bpl \SL7                  ;verzweige, wenn gefunden
\SL10:         move.l GrößePos,a0        ;Lücke beim größten Block
\SL7:
               move.l A0,AnfPos
               cmp.l EndPos,a0
               bcs \SL8
               move.l a5,a0
               move.l a0,AnfPos
\SL8:
               move.l GrößePos,d0
               cmp.l EndPos,d0
               bcs \SL9
               move.l a5,GrößePos
\SL9:          move.l (a7)+,d2
               rts



;Einzelnen Block suchen
;=> D0 = Blocknummer
;=> D0 = Blocknummer des nächsten Blocks
;=> D0 = -1, wenn keinen gefunden
;=> D1 = Größe des Blocks
;=> a0 = Adresse des Blocks

EinBlock:
               movem.l d2-d4,-(a7)
               and.l #$ffff,d0          ;Fehlermeldung löschen
               tst.w d0
               bmi \EB3
               lea SortBlöcke,a0
\EB2:          move.w d0,d1
               lsl.w #2,d1
               move.l (a0,d1),d2
               cmp.w #1,d2
               beq \EB1                  ;Block gefunden
               sub.w #1,d0
               tst.w d0
               bpl \EB2
\EB3:          move.l #-1,d0
               bra \EBEND                ;Fehler
\EB1:          move.w (a0,d1),d2         ;Blocklänge
               clr.w d3                  ;Blockadr löschen
               lea Blöcke,a0
\EB4:          move.l (a0)+,d1
               add.w d1,d3               ;Adresse ermitteln
               cmp.w d1,d2
               bne \EB4                  ;weiter, wenn nicht fertig
               sub.l a0,a0               ;A0 löschen
\EB5:          move.w d3,a0              ;Offset
               add.l a5,a0               ;Adresse
               move.w d2,d1              ;Blockgröße
               sub.w #1,d0               ;Nummer des nächsten Blocks
\EBEND:        movem.l (a7)+,d2-d4
               rts

;Prüfen, ob Track auf Amigaformat
;=> D0 = Null, wenn Track Amigaformat
;=> D0 = -1, wenn kein Amigaformat
TrackAmiga:
               move.l d2,-(a7)
               lea Blöcke,a0             ;Zeiger auf Blockspeicher
               cmp.w #$0b,SyncAnz        ;SyncAnzahl bei Amigaformat
               bne \PL1                  ;Nein, kein Amigaf.
               clr.w d1
               clr.l d2
               move.w #$0a,d0
\PL3:          move.w d0,d2
               lsl.w #2,d2
               cmp.w #$0440,2(a0,d2)      ;Blocklänge für Amiga
               bne \PL2
               add.w #1,d1
\PL2:          dbf d0,\PL3
               cmp.w #$9,d1              ;mindestens 9 Amiga-Blöcke
               bcs \PL1
               clr.l d0                  ;OK. Amigaformat
               move.b #ON,AmigaTrack
\PL4:          move.l (a7)+,d2
               rts
\PL1:          move.l #-1,d0             ;kein Amigaformat
               move.b #OFF,AmigaTrack
               bra \PL4


;Das Programm geht davon aus, das alle Syncs gleich lang sind, somit
;werden alle Syncs der ersten angepasst
;>= A5 = Zeiger auf Trackpuffer

Synckorrektur:
               movem.l d2-d4,-(a7)
               cmp.w #1,SyncAnz
               beq \SK1                  ;nur eine Sync
               lea Blöcke,a0
               clr.w d0
               clr.l d3
               move.l a5,a1
               move.l (a0)+,d2
               move.w d2,d3              ;Blocklänge
               swap d2                   ;Syncrichtwert
\SK3:          adda.l d3,a1              ;Zeiger auf Block
               add.w #1,d0
               cmp.w SyncAnz,d0
               bcc \SK1
               move.l (a0)+,d1
               move.w d1,d3              ;Blocklänge
               swap d1                   ;SyncAnz von Block
               cmp.w d2,d1
               bcc \SK3                  ; nicht korrigieren
               sub.w d2,d1
               not.w d1
               move.w d1,d4              ;Anzahl der neuen Syncs
               move.l a1,-(a7)
\SK2:
               cmp.l GrößePos,a1         ;muß Pos verändert werden               bne \SK8
               sub.l #2,GrößePos         ;GrößePos verändern
\SK8:          move.w #$4489,-(a1)

               dbf d4,\SK2
               move.l (a7)+,a1
               add.w #1,d1
               add.w d1,-4(a0)
               lsl.w #1,d1
               sub.w d1,-6(a0)
               add.w d1,-2(a0)
               bra \SK3
\SK1:          cmp.w #Längeungleich,ErrorFlag
               beq \SK7                  ;keine endkorrektur nötig
               move.w d2,d0              ;Syncrichtwert
               move.l EndPos,a1
               add.l #2,a1               ;Zeiger auf Sync stellen
               bra \SK4
\SK6:          cmp.w #$4489,(a1)+        ;Übergang zu Anfang testen
               bne \SK5
\SK4:          dbf d0,\SK6
\SK7:          movem.l (a7)+,d2-d4
               rts
\SK5:          sub.w d0,d2
               lsl.w #1,d2
               sub.l #2,EndPos
               sub.w #2,TrackBytes
               sub.w #2,-2(a0)             ;Letzter Block ist kürzer
               bra \SK7

;Nachdem die Lücke feststeht, werden die Daten zurechtkopiert um
;geschrieben zu werden
;>= A5 TrackPuffer (Quelle)
;>= A4 TrackPuffer (Ziehl)

Umkopieren:
               move.l a2,-(a7)
               move.l a4,a1
               move.l AnfPos,a0
               sub.l a5,a0               ;Offset des Anfangs
               clr.l d0
               move.w Syncweit,d0
               sub.w #$0044,d0           ;Enfernungskorrektur
               bcc \UK6                  ;Entfernung zu klein?
               clr.w d0                  ;ja, Enfernung = 0
\UK6:
               add.l d0,a0               ;Entfernung von Index
               move.w a0,Offset          ;Anzahl der Bytes vor Sync
               suba.l a0,a1              ;Schreibanfang
               move.l a1,SchreibAnf
               move.w TrackBytes,d0
               lsr.w #1,d0               ;Byte zu Wort
               move.w LängeDest,d1
               move.l AnfPos,a0          ;Quell-Adrese
               move.l a4,a1              ;Ziehl-Adresse
               cmp.b #ON,AmigaTrack
               bne \UK9
               add.l #4,a1
\UK9:          move.l #$aaaaaaaa,-4(a1)
\UK4:          move.w (a0),(a1)+
               sub.w #1,d1
               cmp.l EndPos,a0
               bcs \UK3
               move.l a5,a0
               bra \UK5
\UK3:          adda.l #2,a0
\UK5:          dbf d0,\UK4
               move.l (a7)+,a2
               and.w #$f000,d1
               bne \UK8                  ;Source länger Dest
\UK7:          move.w #$aaaa,(a1)+       ;wenn Dest länger Source
               dbf d1,\UK7
\UK8:          move.w LängeDest,d0
               sub.w #$0006,d0
               add.w Offset,d0
               move.w d0,SLänge
               rts


;Track lesen und decodieren
;>= A4 = Zeiger auf Puffer für dekodierte Daten
;>= A5 = Zeiger auf Puffer für kodierte Daten

Fastlesen:
               MOVEM.L D2-D4/a3/a6,-(A7)
               lea decode,a3             ;Einsprung bei decode
               move.w #$080,DecodeAnz    ;Anzahl Langworte zu decodieren
               lea $40(a5),a0
               move.l a0,DecodeAdr       ;Datenbereich des 1. Blocks
               adda.l #$400,a0
               move.l a0,FTestAdr        ;Adresse des nächsten Blocks
               move.w #OFF,VerifyFlag
               bra FLes

FastVerify:    movem.l d2-d4/a3/a6,-(a7)
               lea FVerify,a3            ;Einsprung bei Verify
               move.l a5,DecodeAdr
               lea $440(a5),a0
               move.l a0,FTestAdr
               move.w #ON,VerifyFlag

FLes:
               clr.w ErrorFlag
               bsr DiskInFloppy
               tst.l d0
               bmi \FastFehler
               MOVEA.L A5,A6             ;TrackPuffer
               move.l #$aaaaaaaa,(a6)+
               move.w #$4489,(a6)+       ;erste Sync eintragen
               bsr suchen
               tst.l d0
               bmi \FlesenEnd

               bsr FLösch                ;Trackpuffer vorbereiten
               clr.l d2
               move.w BytesVLücke,d2     ;Anz. der Bytes vor Lücke
               tst.l d2
               beq \FL1                  ;Keine Bytes vor der Lücke
               clr.w BlockAdr            ;Offset im Block
               bsr Anzlesen              ;Bytes lesen
               clr.l d0
               move.w BytesVLücke,d0
               move.l a5,a6
               adda.l d0,a6              ;Zeiger auf nächsten Puffer
               move.l #$aaaaaaaa,(a6)+
               move.w #$4489,(a6)+       ;erste Sync eintragen
\FL1:          move.w BytesNLücke,d2
               tst.l d2
               beq \FL2
               clr.w BlockAdr
               bsr Anzlesen
\FL2:          cmp.w #ON,VerifyFlag               beq \FL3
               bsr letzterblock          ;kein letzter Block bei Verify
\FL3:          BTST #2,$BFE001
               BEQ.S \FastFehler         ;Fehler, wenn keine Disk
               MOVEQ #0,d0               ;OK-Meldung
               move.l #$aaaaaaaa,$2ec0(a5) ;Lücke nach Daten schaffen
               bra \FlesenEnd\FastFehler:   move.l #-1,d0
\FlesenEnd:    MOVEM.L (A7)+,D2-D4/a3/A6
               RTS

;Trackpuffer vorbereiten (Blockanfänge löschen)
;>= A5 = Zeiger auf TrackPuffer

FLösch:        move.l a5,a0
               move.w #10,d1
               clr.l d0
\L1:           move.l d0,$440(a0)
               adda.l #$440,a0
               dbf d1,\L1
               lea BlockMeldung,a0
               move.w #10,d1
\L2:           clr.w (a0)+
               dbf d1,\L2
               rts

;Eingestellte Anzahl von Bytes lesen
;>= A6 = Zeiger auf Ziehl
;>= D2 = Anzahl der Bytes zum lesen

Anzlesen:
               jsr install
               MOVE.W D2,D0
               LSR.W #1,D0
               ORI.W #$8000,D0
               add.w #1,d0
               MOVE.W D0,36(A1)
               MOVE.W D0,36(A1)
               jsr (a3)
               LEA $DFF000,A1
               MOVE.W #$4000,$24(A1)
               rts

;Vorbereitung zum Lesen
;>= A6 Zeiger auf Trackpuffer

install:       LEA $DFF000,A1
               move.w #$4000,$24(a1)     ;Disk-Len zurücksetzen
               move.w #$8400,$9e(a1)     ;Disk Sync einschalten
               move.w #$4489,$7e(a1)     ;SYNC-Markierung
               MOVE.L A6,$20(A1)         ;Puffer übergeben
               move.w #$0002,$dff09c
               rts

;Langwort kodieren und in Puffer eintragen
;>= D0 = Langwort
;>= A0 = Zeiger auf Puffer

CodeLWort:     MOVEM.L D2-D3,-(A7)
               MOVE.L D0,D3
               LSR.L #1,D0
               BSR \CH1
               MOVE.L D3,D0
               BSR \CH1
               BSR Randsetzen
               MOVEM.L (A7)+,D2-D3
               RTS
\CH1:          ANDI.L #$55555555,D0
               MOVE.L D0,D2
               EORI.L #$55555555,D2
               MOVE.L D2,D1
               LSL.L #1,D2
               LSR.L #1,D1
               BSET #$1F,D1
               AND.L D2,D1
               OR.L D1,D0
               BTST #0,-1(A0)
               BEQ.S \CH2
               BCLR #$1F,D0
\CH2:          MOVE.L D0,(A0)+
               RTS
;Ränder richtig setzten

Randsetzen:    MOVE.B (A0),D0
               BTST #0,-1(A0)
               BNE.S \CH4
               BTST #6,D0
               BNE.S \CH6
               BSET #7,D0
               BRA.S \CH5
\CH4:          BCLR #7,D0
\CH5:          MOVE.B D0,(A0)
\CH6:          RTS

;Prüfsumme über Datenbereich ermitteln
;>= D1 = Anzahl der Bytes (muß immer durch 4 teilbar sein)
;>= A0 = Zeiger auf Puffer
;=> D0 = Prüfsumme

PrüfSumme:     MOVE.L D2,-(A7)
               LSR.W #2,D1
               SUBQ.W #1,D1
               MOVEQ #0,D0
\PS1:          MOVE.L (A0)+,D2
               EOR.L D2,D0
               DBRA D1,\PS1
               ANDI.L #$55555555,D0
               MOVE.L (A7)+,D2
               RTS

;Blockheader decodieren
;>= A0 ist Zeiger auf Header
;=> D0 = Header

Header:        move.l (a0)+,D0
               move.l (a0)+,D1
               andi.l #$55555555,d0
               andi.l #$55555555,d1
               lsl.l #1,D0
               or.l D1,D0
               rts

;ersten nicht zuerstörten Block suchen
;=> A6 = Zeiger auf TrackPuffer
;=> D0 = Null: Block gefunden
;=> BytesVLücke = Anzahl der Bytes vor der Lücke
;=> BytesNLücke = Anzahl der Bytes nach der Lücke

suchen:                       movem.l d2-d4,-(a7)
               move.w #11,d2             ;Anzahl der erlaubten Fehler
\SU1:          bsr install
               move.w #$8024,d0          ;$24 Worte lesen
               MOVE.W D0,$dff024
               MOVE.W D0,$dff024
               bsr Blockready            ;auf Block ready warten
               tst.l d0                  ;Fehler, dann D0 = -1
               bmi \SUError

               lea 8(a5),a0              ;Zeiger auf Blockheader
               moveq #$28,d1             ;Langwortanzahl
               bsr Prüfsumme             ;Summe über Header
               move.l d0,d3              ;Summe retten
               lea 48(a5),a0             ;*Summe
               bsr Header                ;Summe aus Header holen
               cmp.l d0,d3               ;Summen vergleichen
               bne \SUNeu
               lea 8(a5),a0
               jsr Header                ;Header decodieren
               move.w d0,d3              ;Header nach D3
               lsr.w #8,d3
               andi.w #$00ff,d3          ;Sektornummer inolieren
               addi.w #1,d3              ;Sektornummer erhöhen
               cmp.w #$000a,d3           ;Nummer über 10?
               bls \SU2                  ;Nein, OK
               clr.w d3                  ;Nummer = 0
\SU2:          move.w d3,SektNum         ;Nummer speichern
               move.w d3,FirstBlock      ;Nummer erster Block

               move.w d0,d3              ;Header
               andi.w #$ff,d3            ;Sektoren bis Lücke
               cmp.b #$0c,d3             ;Header OK?
               bcs.s \SUok
\SUNeu:        dbf d2,\SU1
               bra \SUError
\SUok:

               sub.w #1,d3               ;Anzahl der Blöcke bis Lücke
               move.w d3,d2
               move.w #$000b,d4
               sub.b d2,d4               ;Anzahl der Blöcke nach Lücke
               mulu #$440,d3             ;Anzahl der Bytes bis Lücke
               mulu #$440,d4             ;Anzahl der Bytes nach Lücke
               clr.l d0
               move.w d3,BytesVLücke
               move.w d4,BytesNLücke
               move.w #$0b,SektBL        ;Sektoren vor Lücke nach dem Laden
               bra \SUEnd
\SUError:      move.l #-1,d0
               move.w #ReadError,ErrorFlag
\SUEnd:        movem.l (a7)+,d2-d4
               rts

Blockready:    clr.l d0                  ;Error-Flag löschen
               move.l #$20000,d1
               move.w #$0002,$dff09c     ;DiskInt löschen
\B1:           MOVE.W $DFF01E,D0
               BTST #1,D0
               bne.s \B2
               sub.l #1,d1
               bne \B1
               move.l #-1,d0             ;Fehler aufgetreten
\B2:           RTS


;Bytes dekodieren, bis Block gelesen

decode:
               movem.l d2-d3/a2,-(a7)
               clr.l d3
               move.w BlockAdr,d3        ;Offset im Block
               move.l FTestAdr,a0        ;Adresse zu testen ob
                                         ;Block schon geladen
               move.l DecodeAdr,a2       ;Adresse, bei der dekodiert wird
               move.w DecodeAnz,d2       ;Abzahl für dekodierung

\DC1:          MOVE.W $DFF01E,D0
               BTST #1,D0                ;Bereich schon gelesen
               bne  \DCEnd              ;Ja, ende               tst.l (a0)                ;TestAdr
               beq \DC1                  ;Warten, bis Block gelesen

               movem.l a0-a1,-(a7)       ;Register retten
               lea -$40(a2),a1           ;* Blockanfang
               bsr BlockCheck            ;Block checken
               movem.l (a7)+,a0-a1       ;Register zurückholen
               move.w SektNum,d0
               mulu #$200,d0
               move.l a4,a1              ;Basiadresse für Ziehldaten
               add.l d0,a1               ;Adresse des Blocks
\DC2:
               MOVE.W $DFF01E,D0
               BTST #1,D0
               bne.s \DCEnd              ;Breich schon gelesen

               move.l (a2),D0
               move.l $200(a2),D1
               adda.l #4,a2
               andi.l #$55555555,d0
               andi.l #$55555555,d1
               lsl.l #1,D0
               or.l D1,D0
               move.l d0,(a1,d3)         ;Langword eintragen
               addq.w #4,d3
               subq.w #1,D2              ;Decode Anzahl
               bne \DC2
               adda.l #$240,a2           ;erhöhe Adresse
               adda.l #$440,a0           ;TestAdr
               move.l #$080,D2           ;Decode Anzahl
               clr.w d3                  ;Offset auf Null
               add.w #1,SektNum          ;Sektornummer erhöhen
               cmp.w #$0b,SektNum        ;Nummer über 10?
               bcs \DC3                  ;Nein, OK
               clr.w SektNum             ;Nummer = 0
\DC3:          bra \DC1

\DCEnd:
               move.w d3,BlockAdr
               move.l a2,DecodeAdr
               move.l a0,FTestAdr
               move.w D2,DecodeAnz

               movem.l (a7)+,d2-d3/a2
               RTS

;Letzten Block entkodieren

LetzterBlock:                 movem.l d2-d3/a2,-(a7)

               move.w SektNum,d0
               mulu #$200,d0
               move.l a4,a1              ;Basiadresse für Ziehldaten
               add.l d0,a1               ;Adresse des Blocks
               clr.l d3
               move.l DecodeAdr,a2
               move.w DecodeAnz,d2
\LB1:          move.l (a2),D0
               move.l $200(a2),D1
               adda.l #4,a2
               andi.l #$55555555,d0
               andi.l #$55555555,d1
               lsl.l #1,D0
               or.l D1,D0
               move.l d0,(a1,d3)
               addq.w #$4,d3
               subq.w #1,D2               ;Decode Anzahl
               bne \LB1
               movem.l (a7)+,d2-d3/a2
                              RTS

;Block auf Fehler prüfen
;A1 = Zeiger auf Blockanfang

BlockCheck:
               movem.l d2-d3,-(a7)
               clr.l d3
               move.w SektNum,d3
               lsl.w #1,d3               ;Sektornummer => Offset
               lea BlockMeldung,a0
               move.w (a0,d3),d0         ;Eintrag holen
               tst.w d0                  ;schon geprüft?
               bne \CBEnd2               ;Ja, ende

               lea 64(a1),a0
               move.w #$400,d1
               jsr Prüfsumme             ;Summe über Datenblock
               move.l d0,d2              ;Summe retten
               lea 56(a1),a0             ;Zeiger auf Datensumme
               jsr Header                ;Summe decodieren
               cmp.l d0,d2
               bne \DatenFalsch

               lea 8(a1),a0
               bsr Header                ;Header decodieren
               move.w d0,d2              ;Unterres Wort speichern
               lsr.w #8,d2               ;Sektornummer nach d2
               cmp.b SektNum+1,d2        ;richtiger Sektor
               bne \FalscherSektor
               swap d0                   ;Tracknummer nach D0
               cmp.b StartTrack+1,d0     ;richtiger Track?
               bne \FalscherTrack
               andi.l #$ff00,d0
               cmp.w #$ff00,d0
               bne \KeinDosTrack
               lea 8(a1),a0
               moveq #$28,d1             ;Langwortanzahl
               bsr Prüfsumme             ;Summe über Header
               move.l d0,d2              ;Summe retten
               lea 48(a1),a0             ;*Summe
               bsr Header                ;Summe aus Header holen
               cmp.l d0,d2               ;Summen vergleichen
               bne \HeaderFalsch
               move.w #$ffff,d0
\CBEnd1:       lea BlockMeldung,a0
               move.w d0,(a0,d3)
               btst #0,-1(a1)
               beq \CB1
               move.l #$2aaaaaaa,(a1)
               bra \CB2
\CB1:          move.l #$aaaaaaaa,(a1)
\CB2:          move.l #$44894489,4(a1)
               move.w #$ff00,d0          ;Header neu erstellen
               move.b StartTrack+1,d0               swap d0
               move.b SektNum+1,d0
               lsl.w #8,d0
               move.b SektBL+1,d0
               lea 8(a1),a0
               bsr CodeLWort             ;Header eintragen
               lea 8(a1),a0
               moveq #$28,d1             ;Langwortanzahl
               bsr Prüfsumme             ;Summe über Header
               lea 48(a1),a0             ;*Summe
               bsr CodeLWort             ;Prüfsumme eintagen
               subq.w #1,SektBL
\CBEnd2:       movem.l (a7)+,d2-d3
               rts

\FalscherSektor: move.w #$0001,d0
                 bra \Flagsetzen
\FalscherTrack: move.w #$0002,d0
                 bra \Flagsetzen
\KeinDosTrack:  move.w #$0017,d0
                 bra \Flagsetzen
\HeaderFalsch:  move.w #$001b,d0
                 bra \Flagsetzen
\DatenFalsch:   move.w #$0019,d0
\Flagsetzen:    move.w #ReadError,ErrorFlag
                bra \CBEnd1

;gelesene Bytes mit alten vergleichen
;>= A4 = Zeiger auf Basisadresse des alten Blocks

FVerify:
               cmp #VerifyError,ErrorFlag
               beq \FVEnd2
               movem.l d2-d3/a2,-(a7)
               clr.l d3
               move.w BlockAdr,d3        ;Offset im Block
               move.l FTestAdr,a0        ;Adresse zum testen ob
                                         ;Block schon geladen
               move.l DecodeAdr,a2       ;Adresse, bei der verglichen wird
\FV1:          MOVE.W $DFF01E,D0
               BTST #1,D0                ;Bereich schon gelesen
               bne  \FVEnd               ;Ja, ende
               tst.l (a0)                ;TestAdr
               beq \FV1                  ;Warten, bis Block gelesen
               move.w #$110,d2           ;Vergleichanzahl
               move.w SektNum,d0
               sub.w FirstBlockSp,d0               bcc \FV2
               addi.w #11,d0
\FV2:
               mulu #$440,d0
               move.l a4,a1              ;Basiadresse für Ziehldaten
               add.l d0,a1               ;Adresse des Blocks
\FV3:
               move.l (a2)+,d0
               cmp.l (a1,d3),d0               beq \FV6                  ;Verify ok
;Auf Sonderfall testen  ($aaaaaaaa und $2aaaaaaa)
               move.l (a1,d3),d1
               eor.l d1,d0
               cmp.l #$80000000,d0
               bne \FV5
\FV6:          addq.w #4,d3
               subq.w #1,d2
               bne \FV3
               adda.l #$440,a0           ;TestAdr
               clr.l d3                  ;Offset auf Null
               add.w #1,SektNum          ;Sektornummer erhöhen
               cmp.w #$0b,SektNum        ;Nummer über 10?
               bcs \FV1                  ;Nein, OK
               clr.w SektNum             ;Nummer = 0
               bra \FV1
\FV5:          move.w #VerifyError,ErrorFlag
               bra \FVEnd3
\FVEnd:
               clr.w ErrorFlag
               move.w d3,BlockAdr
               move.l a2,DecodeAdr
               move.l a0,FTestAdr
\FVEnd3:       movem.l (a7)+,d2-d3/a2
\FVEnd2:       RTS

;Track codieren
;>= A0 = Zeiger auf Quelle
;>= A1 = Zeiger auf Ziehl
;>= D0 = Tracknummer
CodeTrack:
               movem.l d2-d4/a2-a3,-(a7)
               move.l d0,d4
               move.l a0,a2
               move.l a1,a3
               moveq #$0b,d2
               clr.w d3
\CT1:          move.w #$ff00,d0
               move.b d4,d0
               swap d0
               move.w d3,d0
               lsl.w #8,d0
               move.b d2,d0
               move.l a2,a0              ;Quelle
               move.l a3,a1              ;Ziehl
               bsr ErstellBlock
               add.l #$440,a3
               add.l #$200,a2
               addq.w #1,d3
               subq.w #1,d2
               bne \CT1
               movem.l (a7)+,d2-d4/a2-a3
               rts

;Block kodieren und Header erstellen
;>= A0 = Unkodierte Daten (Quelle)
;>= A1 = Datenpuffer für kodierte Daten (Ziehl)
;>= D0 = unkodierter Header

ErstellBlock:  MOVEM.L D2/A2/A4,-(A7)
               MOVEA.L A1,A4
               MOVEA.L A0,A2
               MOVE.L D0,D2
               MOVEQ #0,D0
               LEA 0(A4),A0
               BSR CodeLWort
               MOVE.L #$44894489,4(A4)
               MOVE.L D2,D0
               LEA 8(A4),A0
               BSR CodeLWort
               MOVEQ #3,D2
\EB1:          MOVEQ #0,D0
               BSR CodeLWort
               DBRA D2,\EB1
               LEA 8(A4),A0
               MOVEQ #$28,D1
               BSR Prüfsumme
               LEA $30(A4),A0
               BSR CodeLWort
               MOVE.L #$200,D0
               MOVEA.L A2,A0
               LEA $40(A4),A1
               BSR CodeBlock
               LEA $40(A4),A0
               MOVE.W #$400,D1
               BSR Prüfsumme
               LEA $38(A4),A0
               BSR CodeLWort
               MOVEM.L (A7)+,D2/A2/A4
               RTS

;Datenblock kodieren
;>= D0 = Länge der Quelle
;>= A0 = Zeiger auf Quelle
;>= A1 = Zeiger auf Ziehl

CodeBlock:

               movem.l  d2/a5,-(a7)
               MOVE.W D0,D1
               LSL.W #2,D1
               ORI.W #8,D1
               MOVE.W D1,D2
               movem.l d0-d1/a0-a1/a5,-(a7)
               move.l a0,d1
               move.l a1,a5
               lea $dff000,a0
               bsr BlitWart
               bsr BlitterCode
               movem.l (a7)+,d0-d1/a0-a1/a5
               MOVE.L D0,D1
               MOVEA.L A1,A0
               BSR Randsetzen
               ADDA.L D1,A0
               BSR Randsetzen
               ADDA.L D1,A0
               BSR Randsetzen
               movem.l (a7)+,d2/a5
               RTS

;A0 = $dff000
;D0 = Länge der Quelle
;D1 = Quelle
;A5 = Ziehl

BlitterCode:
               bsr Modulu                ;Modulu setzen
               MOVE.L D1,$4C(A0)
               MOVE.L D1,$50(A0)
               MOVE.L A5,$54(A0)
               MOVE.W #$1DB1,$40(A0)
               MOVE.W #0,$42(A0)
               bsr StartBlit
               MOVE.L A5,$4C(A0)         ;Source B
               MOVE.L D1,$50(A0)         ;Source A
               MOVE.L A5,$54(A0)         ;Dest
               MOVE.W #$2d8c,$40(A0)
               bsr StartBlit
               movem.l d0-d1/a5,-(a7)
               ADD.L D0,D1
               SUBQ.L #2,D1
               ADDA.L D0,A5
               ADDA.L D0,A5
               SUBQ.L #2,A5
               MOVE.L D1,$4C(A0)
               MOVE.L D1,$50(A0)
               MOVE.L A5,$54(A0)
               MOVE.W #$DB1,$40(A0)
               MOVE.W #$1002,$42(A0)
               bsr StartBlit
               movem.l (a7)+,d0-d1/a5
               movem.l d0-d1/a5,-(a7)
               ADDA.L D0,A5
               MOVE.L A5,$4C(A0)
               MOVE.L D1,$50(A0)
               MOVE.L A5,$54(A0)
               MOVE.W #$1D8C,$40(A0)
               MOVE.W #0,$42(A0)
               bsr StartBlit
               movem.l (a7)+,d0-d1/a5
               rts

;Blit start und auf Ende von Blitter warten

StartBlit:
               MOVE.W d2,$dff058
BlitWart:      btst #14,$dff002
               bne.s BlitWart
               rts

;Modulu für codierug setzen
;>= A0 = $dff000
Modulu:
               movem.l d0/a1,-(a7)
               MOVEQ #0,D0
               LEA $44(A0),A1
               MOVE.L #-1,(A1)
               LEA $62(A0),A1
               MOVE.L D0,(A1)+
               MOVE.W D0,(A1)+
               ADDQ.L #8,A1
               MOVE.W #$5555,(A1)
               movem.l (a7)+,d0/a1
               rts

;Track mit DOS löschen
;>= A0 = Zeiger auf Trackpuffer
DOSLösch:
               move.l #$444F5300,d0      ;DOS + 0
               move.w #$57f,d1
\DO1:          move.l d0,(a0)+           ;Track löschen
               addq.b #1,d0
               dbf d1,\DO1
               rts

;Track verkützen und im Speicher ablegen
;>= A0 = Zeiger auf den Anfang des Tracks
;>= A1 = Zeiger auf Ziehladresse
;>= Länge = Anzahl der zu kürzenden Bytes
;>= KutzByte = Byte, das kürzer abgelegt werden soll
;=> A1 = Zeiger auf Speicher nach gekürztem Block

Crunch:
               movem.l d2-d7/a2/a4,-(a7)
               clr.w d7
               clr.w d2
               move.w Länge,d3      ;Anzahl der Bytes
               move.l SpeicherLänge,d6
\CHAnf:
               tst.w d7
               bne \CHEnd
               movea.l a0,a2             ;Adrsse zwischenspeichern
\CH4:          bsr \LeererBlock
               tst.w d0
               beq \CHAnf
               move.b (a0),d4
               cmp.b KurzByte,d4
               beq \KF1                  ;Nullbyte
               cmp.b 1(a0),d4
               bne \CH10                 ;Keine folge
               cmp.b 2(a0),d4
               beq \AF1                  ;Andere Folge
\CH10:         addq.l #1,a0
               subq.w #1,d3
               bne \CH4                  ;weiter suchen
               bsr \KeineFolge
\CHEnd:
               move.b #$00,d0
               move.b d0,(a1)+
               subq.l #1,d6
               bcs CrunEnd
               move.l d6,SpeicherLänge
               move.l a1,SpeicherAnf
               clr.l d0
               movem.l (a7)+,d2-d7/a2/a4               rts
;Kurzfolge

\KF1:          cmp.b 1(a0),d4
               bne \CH10                 ;Keine Nullfolge
               bsr \KeineFolge
               bsr ZähleBytes
               cmp.w #$40,d1
               bcc \KF2                  ;zu groß für ein Byte
               ori.b #KurzNull,d1               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
               bra \KF4
\KF2:          cmp.w #$1000,d1
               bcc \KF3                  ;zu groß, muß Wort sein
               move.w d1,d0
               lsr.w #8,d0
               ori.b #MittelNull,d0      ;Nullfolge mit Folge-Byte
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
               bra \KF4
\KF3:          move.b #LangNull,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.w d1,d0
               lsr.w #8,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
\KF4:          bra \CHAnf

;Andere Folge

\AF1:          bsr \KeineFolge
               bsr ZähleBytes
               cmp.w #$40,d1
               bcc \AF2                  ;zu groß für ein Byte
               ori.b #KurzNorm,d1
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
               bra \AF4
\AF2:          cmp.w #$1000,d1
               bcc \AF3                  ;zu groß, muß Wort sein
               move.w d1,d0
               lsr.w #8,d0
               ori.b #MittelNorm,d0      ;beliebige Folge mit Folge-Byte               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
               bra \AF4
\AF3:          move.b #LangNorm,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.w d1,d0
               lsr.w #8,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd
\AF4:          move.b d4,d0              ;anderes Byte eintragen
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd
               bra \CHAnf

;Keine Folge gefunden
\KeineFolge2:  move.w #1,Abzug           ;Siehe CrunEnd2
               bra \KF20
\KeineFolge:   clr.w Abzug
\KF20:         move.l a0,a4
               sub.l a2,a4
               move.w a4,d1
               beq \KFEnd
               swap d1
               move.w a4,d1
               cmp.w #$40,d1
               bcc \CH5                  ;zu groß für ein Byte
               ori.b #KurzKein,d1
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               bra \CH6
\CH5:          cmp.w #$1000,d1
               bcc \CH7                  ;zu groß, muß Wort sein
               move.w d1,d0
               lsr.w #8,d0
               ori.b #MittelKein,d0               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               bra \CH6
\CH7:          move.b #LangKein,D0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               move.w d1,d0
               lsr.w #8,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               move.b d1,(a1)+
               subq.l #1,d6
               beq CrunEnd2
\CH6:          swap d1
               andi.l #$ffff,d1
               sub.l d1,d6               beq CrunEnd2
               bcs CrunEnd2
               bra \CH8\CH9:          move.b (a2)+,(a1)+
\CH8:          dbf d1,\CH9
\KFEnd:        clr.w Abzug               ;Siehe CrunEnd2
               rts

\LeererBlock:
               move.w d3,d0
               andi.w #$fe00,d0
               cmp.w d0,d3
               bne \LBEnd2
               move.l a0,a3
               move.w #$7e,d5
               move.l (a0)+,d4
               move.l d4,d0
               andi.l #$ff000000,d0
               cmp.l #$44000000,d0
               bne \LBNein
\LB1:          addq.b #1,d4
               cmp.l (a0)+,d4               bne \LBNein
               dbf d5,\LB1
               bsr \KeineFolge2
               move.b #LeerBlock,d0
               move.b d0,(a1)+
               subq.l #1,d6
               beq CrunEnd2
               clr.w d0                  ;Ok Meldung
               subi.w #$200,d3
               bne \LBEnd
               move.w #-1,d7             ;Endmarkierung
               bra \LBEnd
\LBNein:       move.l a3,a0
\LBEnd2:       move.w #-1,d0
\LBEnd:        rts

ZähleBytes:    clr.w d1
\ZB2:          cmp.b (a0)+,d4
               bne \ZB1
               addq.w #1,d1
               subq.w #1,d3
               bne \ZB2
               move.w #-1,d7             ;Endmarkierung
\ZB1:
               subq.l #1,a0
               rts



CrunEnd2:      move.w Abzug,d2
\CE1:          adda.l #$4,a7
               dbf d2,\CE1
CrunEnd:
               movem.l (a7)+,d2-d7/a2/a4               move.l #-1,d0
               rts

;Track wieder in Normgröße bringen
;>= A0 = Zeiger auf der gecrunchten Track
;>= A1 = Zeiger auf Ziehladresse

DeCrunch:
               move.b (a0)+,d0
               tst.b d0
               beq \DCEnd                ;Endmarkierung
               move.b d0,d1
               andi.b #$c0,d1
               bne Kurz
               move.b d0,d1
               andi.b #$30,d1
               bne Mittel
               move.b d0,d1
               cmpi.b #LeerBlock,d1
               beq \BlockLeer
               move.b (a0)+,d0
               lsl.w #8,d0
               move.b (a0)+,d0
               cmpi.b #LangNull,d1
               beq \NullLang
               cmpi.b #LangNorm,d1
               beq \NormLang
               cmpi.b #LangKein,d1
               beq \UndefLang
;Fehler
               move.l $4,a6
               sub.l a5,a5
               move.l #$12345678,d7
               jsr -108(a6)
\DCEnd:        rts


;Leerer Block
\BlockLeer:    move.w #$7f,d1
               move.l #$444F5300,d0
\LB1:          move.l d0,(a1)+
               addq.b #1,d0
               dbf d1,\LB1
               bra DeCrunch
;Lang

\LA1:          move.b (a0)+,(a1)+
\UndefLang:    dbf d0,\LA1
               bra DeCrunch\NullLang:     move.b Kurzbyte,d1
               bra \LA2
\NormLang:     move.b (a0)+,d1
               bra \LA2
\LA3:          move.b d1,(a1)+
\LA2:          dbf d0,\LA3
               bra DeCrunch
Kurz:
               cmpi.b #KurzNull,d1
               beq \KU1
               cmpi.b #KurzNorm,d1
               beq \KU2
;KurzUndeff
               andi.w #$3f,d0
               bra \KU3
\KU4:          move.b (a0)+,(a1)+
\KU3:          dbf d0,\KU4               bra DeCrunch\KU1:          move.b Kurzbyte,d1
               bra \KU5
\KU2:          move.b (a0)+,d1
\KU5:          andi.w #$003f,d0
               bra \KU6
\KU7:          move.b d1,(a1)+
\KU6:          dbf d0,\Ku7
               bra DeCrunchMittel:
               andi.w #$0f,d0
               lsl.w #8,d0
               move.b (a0)+,d0
               cmpi.b #MittelNull,d1
               beq \KU1
               cmpi.b #MittelNorm,d1
               beq \KU2
;MittelUndeff
               bra \KU3
\KU4:          move.b (a0)+,(a1)+
\KU3:          dbf d0,\KU4               bra DeCrunch\KU1:          move.b Kurzbyte,d1
               bra \KU6
\KU2:          move.b (a0)+,d1
               bra \KU6
\KU7:          move.b d1,(a1)+
\KU6:          dbf d0,\Ku7
               bra DeCrunch

beg:
        move.w #$0008,$dff09a

        move.l gfxbase,a6
        lea    bitmap,a0
        move.b #1,d0
        move.w #320,d1
        move.w #256,d2
        jsr    InitBitMap(a6)
        move.l bit_adress,plane1
        move.l bit_adress,d1
        move.w d1,plane_lo
        swap   d1
        move.w d1,plane_hi

        lea    rastport,a1
        jsr    InitRastPort(a6)
        move.l #bitmap,r_bitmap

        move.l #ncopper,a0
        move.l cop_adress,a1
        move.l #copsize,d0
copy_loop:
        move.b (a0)+,(a1)+
        dbf    d0,copy_loop

        bsr  adresses
        move.l c1_adress,flash_adress

        move.l bit_adress,a0
        move.w #$27ff,d0
clear_loop:
        clr.b  (a0)+
        dbf    d0,clear_loop

        move.l gfxbase,a0
        move.w #$0080,$dff096
        move.l $6c,oldirq
        move.l #newirq,$6c
        move.l 50(a0),oldcopper
        move.l cop_adress,50(a0)
        move.w #$82b0,$dff096

new_start:
        move.w #7,x1
        move.w #54,y1
        move.b #$4f,lc
        move.b #$00,fc
        move.b #$03,tr
        move.b #$00,ws
        move.b #$01,vd
        move.b #$01,fa
        move.b #$00,dc1
        move.b #$00,dc2
        move.b #$01,sd
        move.b #$00,dd
        move.b #$01,sy
        move.b #$00,new
        move.b #$00,zeiger1
        move.b #$00,color_ptr
        move.b drives,dd
        bsr  end_drive
        bsr  show_lc
        move.l #text1,text_ptr
        bsr  set_title
        bra  menu_control
exit:
        move.w #$8008,$dff09a
        move.l gfxbase,a0
        move.w #$0080,$dff096
        move.l oldirq,$6c
        move.l oldcopper,50(a0)
        move.w #$82b0,$dff096

no_DPuffer:
        move.l ExecBase,a6
        move.l cop_adress,a1
        move.l #copsize+2,d0
        jsr    FreeMem(a6)
no_copper:
        move.l ExecBase,a6
        move.l bit_adress,a1
        move.l #$2800,d0
        jsr    FreeMem(a6)
no_bitmap:
        move.l ExecBase,a6
        move.l gfxbase,a1
        jsr    CloseLibrary(a6)
no_gfxbase:
        clr.l  d0
        rts

newirq:
        move   SR,-(a7)
        movem.l a0-a6/d0-d7,-(a7)
        addq.b #1,waiting
        cmp.b  #2,waiting
        ble    endirq
        clr.b  waiting
        move.l flash_adress,a2
        cmpi.b #$00,color_ptr
        bne.s  irq_flash
        move.w #$00ee,(a2)
        bra.s  endirq
irq_flash:
        cmpi.b #$00,back
        beq.s  upward
downward:
        subi.w #$0011,(a2)
        cmpi.w #$0044,(a2)
        bcc.s  endirq
        move.b #$00,back
        bra.s  endirq
upward: addi.w #$0011,(a2)
        cmpi.w #$00ff,(a2)
        bcs.s  endirq
        move.b #$01,back
endirq: movem.l (a7)+,a0-a6/d0-d7
        move   (a7)+,SR
        dc.w $4ef9
oldirq: dc.l 0

menu_control:
        bsr  wait_key
        cmpi.b #$46,d0
        beq  destination_drive
        cmpi.b #$50,d0
        beq  start_copy
        cmpi.b #$51,d0
        beq  first_cylinder
        cmpi.b #$52,d0
        beq  last_cylinder
        cmpi.b #$53,d0
        beq  how_many_tries
        cmpi.b #$54,d0
        beq  write_serveral_times
        cmpi.b #$55,d0
        beq  verify_destination
        cmpi.b #$56,d0
        beq  fast_copy
        cmpi.b #$57,d0
        beq  deepcopy_1
        cmpi.b #$58,d0
        beq  deepcopy_2
        cmpi.b #$59,d0
        beq  source_drive
        cmpi.b #$21,d0
        beq  synccorrection
        bra.s  menu_control

start_copy:
        move.l c2_adress,flash_adress
        move.b #$01,color_ptr
        bsr  show_start
start_copy2:
        bsr  wait_key
        cmpi.b #$45,d0
        beq  new_start
        cmpi.b #$44,d0                   ;Resturn
        beq.s  end_start
        cmpi.b #$43,d0
        bne.s  start_copy2
end_start:
        move.b #$00,color_ptr
        move.w #28,y1
        bsr    cl2
        move.w #10,d0
estlop: bsr    zeit
        dbf    d0,estlop
        bsr clear_eol
        bsr copy_start                   ;copy-Routine
        cmp.w #Escape,ErrorFlag
        beq new_start
        cmp.w #diskprotect,errorflag
        beq start_copy
        cmp.w #keinedisk,errorflag
        beq start_copy
        cmp.w #NotProtect,ErrorFlag        beq.s start_copy
        bsr  cl1
esd1:   bsr  wait_key
        cmpi.b #$40,d0
        bne.s  esd1
esd2:   bra new_start

destination_drive:
        move.l c13_adress,flash_adress
        move.b #$01,color_ptr
destination1:
        bsr  wait_key
        cmpi.b #$0a,d0
        beq.s  d_drive0
        cmpi.b #$01,d0
        beq.s  d_drive1
        cmpi.b #$02,d0
        beq  d_drive2
        cmpi.b #$03,d0
        beq  d_drive3
        cmpi.b #$43,d0
        beq.s  end_destination
        cmpi.b #$44,d0
        bne.s  destination1
end_destination:
        cmpi.b #$00,dd
        beq.s  destination1
        move.b #$00,color_ptr
        bra  menu_control
d_drive0:
        btst   #0,drives
        beq  end_drive
        btst   #0,dd
        beq.s  dd0_0
        bclr   #0,dd
        bra.s  dd0_1
dd0_0:  bset   #0,dd
        move.b #1,drv
dd0_1:  bra  end_drive

d_drive1:
        btst   #1,drives
        beq  end_drive
        btst   #1,dd
        beq.s  dd1_0
        bclr   #1,dd
        bra.s  dd1_1
dd1_0:  bset   #1,dd
        move.b #2,drv
dd1_1:  bra.s  end_drive

d_drive2:
        btst   #2,drives
        beq.s  end_drive
        btst   #2,dd
        beq.s  dd2_0
        bclr   #2,dd
        bra.s  dd2_1
dd2_0:  bset   #2,dd
        move.b #4,drv
dd2_1:  bra.s  end_drive

d_drive3:
        btst   #3,drives
        beq.s  end_drive
        btst   #3,dd
        beq.s  dd3_0
        bclr   #3,dd
        bra.s  end_drive
dd3_0:  bset   #3,dd
        move.b #8,drv
end_drive:
        cmpi.b #$01,dc1
        bne.s  st1
        bra.s  st2
st1:    cmpi.b #$01,dc2
        bne  steve1
st2:    move.b drv,dd
        bra  steve
steve1: btst   #0,sd
        beq.s  ste1
        andi.b #$0e,dd
        cmpi.b #$00,dd
        bne.s  steve
        bset   #0,dd
        bra.s  steve
ste1:   btst   #1,sd
        beq.s  ste2
        andi.b #$0d,dd
        cmpi.b #$00,dd
        bne.s  steve
        bset   #1,dd
        bra.s  steve
ste2:   btst   #2,sd
        beq.s  ste3
        andi.b #$0b,dd
        cmpi.b #$00,dd
        bne.s  steve
        bset   #2,dd
        bra.s  steve
ste3:   btst   #3,sd
        beq.s  steve
        andi.b #$07,dd
        cmpi.b #$00,dd
        bne.s  steve
        bset   #3,dd
steve:  btst   #0,dd
        bne.s  end_dd1
        lea    off_text,a0
        bra.s  end_dd2
end_dd1:lea    on_text2,a0
end_dd2:bsr  set_drive0
        btst   #1,dd
        bne.s  end_dd3
        lea    off_text,a0
        bra.s  end_dd4
end_dd3:lea    on_text2,a0
end_dd4:bsr  set_drive1
        btst   #2,dd
        bne.s  end_dd5
        lea    off_text,a0
        bra.s  end_dd6
end_dd5:lea    on_text2,a0
end_dd6:bsr  set_drive2
        btst   #3,dd
        bne.s  end_dd7
        lea    off_text,a0
        bra.s  end_dd8
end_dd7:lea    on_text2,a0
end_dd8:bsr  set_drive3
        cmpi.b #$00,zeiger1
        bne.s  end_dd9
        move.b #$01,zeiger1
        rts
end_dd9:bra  destination1

set_drive0:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #61,d0
        move.w #213,d1
        jsr    Movee(a6)        bra.s  set_text
set_drive1:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #126,d0
        move.w #213,d1
        jsr    Movee(a6)        bra.s  set_text
set_drive2:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #190,d0
        move.w #213,d1
        jsr    Movee(a6)        bra.s  set_text
set_drive3:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #254,d0
        move.w #213,d1
        jsr    Movee(a6)set_text:
        lea    rastport,a1
        move.w #$0003,d0
        jsr    Textaus(a6)        rts

first_cylinder:
        move.l c3_adress,flash_adress
        move.b #$01,color_ptr
        bsr  wait_key
        cmpi.b #$4f,d0
        beq.s  fc_down
        cmpi.b #$4e,d0
        beq.s  fc_up
        cmpi.b #$43,d0
        beq  compare_fc
        cmpi.b #$44,d0
        bne.s  first_cylinder
compare_fc:
        move.b lc,d0
        cmp.b fc,d0        beq  compare_fc2
        blt.s  first_cylinder
compare_fc2:
        move.b #$00,color_ptr
        bra  menu_control
fc_down:subi.b #$01,fc
        cmpi.b #$ff,fc
        bne.s  fc_down2
        move.b #$00,fc
fc_down2:
        bra  show_fc
fc_up:  addi.b #$01,fc
        cmpi.b #$52,fc
        bne.s  fc_down2
        move.b #$51,fc
show_fc:lea    fc_text,a0
        move.b fc,d0
        bsr  byte_umrechnung
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #295,d0
        move.w #64,d1
        jsr    Movee(a6)        lea    rastport,a1
        lea    fc_text,a0
        move.w #$0002,d0
        jsr    Textaus(a6)        bra  first_cylinder

last_cylinder:
        move.l c4_adress,flash_adress
        move.b #$01,color_ptr
        bsr  wait_key
        cmpi.b #$4f,d0
        beq.s  lc_down
        cmpi.b #$4e,d0
        beq.s  lc_up
        cmpi.b #$43,d0
        beq  compare_lc
        cmpi.b #$44,d0
        bne.s  last_cylinder
compare_lc:
        move.b fc,d0
        cmp.b lc,d0        beq  compare_lc2
        bge.s  last_cylinder
compare_lc2:
        move.b #$00,color_ptr
        bra  menu_control
lc_down:subi.b #$01,lc
        cmpi.b #$ff,lc
        bne.s  lc_down2
        move.b #$00,lc
lc_down2:
        bra  lcc
lc_up:  addi.b #$01,lc
        cmpi.b #$52,lc
        bne.s  lc_down2
        move.b #$51,lc
lcc:    bsr.s  show_lc
        bra  last_cylinder    
show_lc:lea    lc_text,a0
        move.b lc,d0
        bsr  byte_umrechnung
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #295,d0
        move.w #74,d1
        jsr    Movee(a6)        lea    rastport,a1
        lea    lc_text,a0
        move.w #$0002,d0
        jsr    Textaus(a6)        rts

how_many_tries:
        move.l c5_adress,flash_adress
        move.b #$01,color_ptr
tries1: lea    tr_text,a0
        bsr  wait_key
        cmpi.b #$4e,d0
        beq.s  tries_up
        cmpi.b #$4f,d0
        beq.s  tries_down
        cmpi.b #$43,d0
        beq.s  end_tries
        cmpi.b #$44,d0
        bne.s  tries1
end_tries:
        move.b #$00,color_ptr
        bra  menu_control
tries_up:
        addi.b #$01,tr
        cmpi.b #$0a,tr
        bne.s  tries_up2
        move.b #$09,tr
tries_up2:
        move.b tr,d0
        addi.w #$30,d0
        move.b d0,(a0)
        bra.s  tries2
tries_down:
        subi.b #$01,tr
        cmpi.b #$00,tr
        bne.s  tries_down2
        move.b #$01,tr
tries_down2:
        move.b tr,d0
        addi.w #$30,d0
        move.b d0,(a0)
tries2: move.l gfxbase,a6
        lea    rastport,a1
        move.w #303,d0
        move.w #84,d1
        jsr    Movee(a6)        lea    rastport,a1
        lea    tr_text,a0
        move.w #$0001,d0
        jsr    Textaus(a6)        bra  tries1

synccorrection:
        move.l c12_adress,flash_adress
        move.b #$01,color_ptr
        cmpi.b #$01,sy
        bne.s  sync2
        clr.b  sy
        lea    off_text,a0
        bra.s  sync3
sync2:  move.b #$01,sy
        lea    on_text,a0
sync3:  lea    rastport,a1
        move.w #287,d0
        move.w #157,d1
        jsr    Movee(a6)        lea    rastport,a1
        move.w #3,d0
        jsr    Textaus(a6)
        move.b #$00,color_ptr
        bra  menu_control

write_serveral_times:
        move.l c6_adress,flash_adress
        move.b #$01,color_ptr
        move.b sd,d0
        cmp.b dd,d0        bne  wait_return
        cmpi.b #$00,ws
        bne.s  write_s2
write_s1:
        move.b #$01,ws
        lea    on_text,a0
        bra.s  end_write_serveral
write_s2:
        move.b #$00,ws
        lea    off_text,a0
end_write_serveral:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #287,d0
        move.w #94,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.w #$0003,d0
        jsr    Textaus(a6)
esw:    move.b #$00,color_ptr
        bra  menu_control

verify_destination:
        move.b dc1,d0
        or.b dc2,d0
        tst.b d0
        bne menu_control
        move.l c7_adress,flash_adress
        move.b #$01,color_ptr
        cmpi.b #$00,vd
        bne.s  verify_d2
verify_d1:
        move.b #$01,vd
        lea    on_text,a0
        bra.s  end_verify
verify_d2:
        move.b #$00,vd
        lea    off_text,a0
end_verify:
        bsr verify_d3
        bra  menu_control
verify_off:
        move.b #$00,vd
        lea    off_text,a0
verify_d3:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #287,d0
        move.w #104,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.w #$0003,d0
        jsr    Textaus(a6)
        move.b #$00,color_ptr
        rts

fast_copy:
        move.l c8_adress,flash_adress
        move.b #$01,color_ptr
        cmpi.b #$01,dd
        beq.s  fcop1
        cmpi.b #$02,dd
        beq.s  fcop1
        cmpi.b #$04,dd
        beq.s  fcop1
        cmpi.b #$08,dd
        beq.s  fcop1
        bra  wait_return
fcop1:  cmpi.b #$01,fa
        bne.s  fastcopy1
        move.b #$00,fa
        move.b #$01,dc1
        move.b #$00,dc2
        bra.s  end_fast
fastcopy1:
        move.b #$01,fa
        move.b #$00,dc1
        move.b #$00,dc2
end_fast:
        cmp.b #ON,DC1
        bne fcop2
        bsr verify_off
fcop2:  bsr  show_copies
        move.b #$00,color_ptr
        bra  menu_control

deepcopy_1:
        bsr verify_off
        move.l c9_adress,flash_adress
        move.b #$01,color_ptr
        cmpi.b #$01,dd
        beq.s  deep4
        cmpi.b #$02,dd
        beq.s  deep4
        cmpi.b #$04,dd
        beq.s  deep4
        cmpi.b #$08,dd
        beq.s  deep4
        bra.s  wait_return
deep4:  cmpi.b #$00,dc1
        beq.s  deep1
        move.b #$00,fa
        move.b #$00,dc1
        move.b #$01,dc2
        bra.s  end_deep1
deep1:  move.b #$00,fa
        move.b #$01,dc1
        move.b #$00,dc2
end_deep1:
        bra  end_fast

wait_return:
        move.l #text12,text_ptr
        move.w #16,x1
        move.w #28,y1
        bsr  set_text3
wait_r3:bsr  wait_key
        cmpi.b #$44,d0
        beq.s  wait_r2
        cmpi.b #$43,d0
        bne.s  wait_return
wait_r2:
        bsr AnfText
        bra  end_fast
wait_r4:bsr    wait_key
        cmpi.b #$45,d0
        beq.s  wait_r5
        cmpi.b #$44,d0
        beq \W1
        cmpi.b #$43,d0
        beq \W1
        cmpi.b #$40,d0
        bne.s  wait_r4
\W1:    move.l d0,-(a7)
        bsr    clear_eol
        move.l (a7)+,d0
        clr.l  d0
        rts
wait_r5:move.l #-1,d0
        move.w #Escape,ErrorFlag
        rts

deepcopy_2:
        bsr verify_off
        move.l c10_adress,flash_adress
        move.b #$01,color_ptr
        cmpi.b #$01,dd
        beq.s  deep3
        cmpi.b #$02,dd
        beq.s  deep3
        cmpi.b #$04,dd
        beq.s  deep3
        cmpi.b #$08,dd
        beq.s  deep3
        bra  wait_returndeep3:  cmpi.b #$01,dc2
        beq.s  deep2
        move.b #$00,fa
        move.b #$00,dc1
        move.b #$01,dc2
        bra.s  end_deep2
deep2:  move.b #$01,fa
        move.b #$00,dc1
        move.b #$00,dc2
end_deep2:
        bra  end_fast
show_copies:
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #287,d0
        move.w #114,d1
        jsr    Movee(a6)
        lea    rastport,a1
        cmpi.b #$00,fa
        beq.s  show1
        lea    on_text,a0
        bra.s  show2
show1:  lea    off_text,a0
show2:  move.w #$0003,d0
        jsr    Textaus(a6)
        lea    rastport,a1
        move.w #287,d0
        move.w #124,d1
        jsr    Movee(a6)
        lea    rastport,a1
        cmpi.b #$00,dc1
        beq.s  show3
        lea    on_text,a0
        bra.s  show4
show3:  lea    off_text,a0
show4:  move.w #$0003,d0
        jsr    Textaus(a6)
        lea    rastport,a1
        move.w #287,d0
        move.w #134,d1
        jsr    Movee(a6)
        lea    rastport,a1
        cmpi.b #$00,dc2
        beq.s  show5
        lea    on_text,a0
        bra.s  show6
show5:  lea    off_text,a0
show6:  move.w #$0003,d0
        jsr    Textaus(a6)
        rts

source_drive:
        move.l c11_adress,flash_adress
        move.b #$01,color_ptr
source1:
        bsr  wait_key
        cmpi.b #$0a,d0
        beq.s  s_drive0
        cmpi.b #$01,d0
        beq.s  s_drive1
        cmpi.b #$02,d0
        beq  s_drive2
        cmpi.b #$03,d0
        beq  s_drive3
        cmpi.b #$43,d0
        beq.s  source2
        cmpi.b #$44,d0
        bne.s  source1
source2:move.b zeiger1,d7
        clr.b  zeiger1
        bsr  end_drive
        move.b d7,zeiger1
        move.b #$00,color_ptr
        bra  menu_control
s_drive0:
        btst   #$00,drives
        beq   source1
s_dd0:  move.b #$01,sd
        move.b #$00,d0
        bra  set_s_drive
s_drive1:
        btst   #$01,drives
        beq  source1
s_dd1:  move.b #$02,sd
        move.b #$01,d0
        bra  set_s_drive
s_drive2:
        btst   #$02,drives
        beq  source1
s_dd2:  move.b #$04,sd
        move.b #$02,d0
        bra.s  set_s_drive
s_drive3:
        btst   #$03,drives
        beq source1
        move.b #$08,sd
s_dd3:  move.b #$03,d0
set_s_drive:
        lea    sd_text,a0
        addi.b #$30,d0
        move.b d0,(a0)
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #303,d0
        move.w #144,d1
        jsr    movee(a6)
        lea    rastport,a1
        move.w #$0001,d0
        jsr    Textaus(a6)
        bra  source1

byte_umrechnung:
        cmpi.w #$0a,d0
        bmi.s  byte2
        divu   #$0a,d0
        move.w d0,d1
        addi.w #$30,d1
        swap   d0
        bra.s  byte3
byte2:  move.w #$0030,d1
byte3:  move.b d1,(a0)+
        addi.w #$0030,d0
        move.b d0,(a0)+
        rts

adresses:
        move.l cop_adress,d0
        move.l #color1,d1
        move.l #ncopper,d2
        sub.l d2,d1        add.l d1,d0        move.l d0,c1_adress
        addi.l #$000010,d0
        move.l d0,c2_adress
        addi.l #$000008,d0
        move.l d0,c3_adress
        addi.l #$000008,d0
        move.l d0,c4_adress
        addi.l #$000008,d0
        move.l d0,c5_adress
        addi.l #$000008,d0
        move.l d0,c6_adress
        addi.l #$000008,d0
        move.l d0,c7_adress
        addi.l #$000008,d0
        move.l d0,c8_adress
        addi.l #$000008,d0
        move.l d0,c9_adress
        addi.l #$000008,d0
        move.l d0,c10_adress
        addi.l #$000008,d0
        move.l d0,c11_adress
        addi.l #$000008,d0
        move.l d0,c12_adress
        addi.l #$000010,d0
        move.l d0,c13_adress
        rts

set_title:
        clr.l  d6
        move.w #$0009,d6
set_text1:
        move.l gfxbase,a6
        bsr  set_text2
        addi.l #$000026,text_ptr
        addi.w #$000a,y1
        dbf    d6,set_text1
        lea    floppy,a0
        move.l bit_adress,a1
        add.l #$001c26,a1        move.l a1,a2
        bsr.s  box
        lea    floppy,a0
        move.l a1,a2
        add.l  #$000008,a2
        bsr.s  box
        lea    floppy,a0
        move.l a1,a2
        add.l  #$000010,a2
        bsr.s  box
        lea    floppy,a0
        move.l a1,a2
        add.l  #$000018,a2
        bsr.s  box
        bra.s  set_weiter
box:
        move.w #floppy_s,d0
bit_copy_loop:
        move.b (a0)+,(a2)+
        move.b (a0)+,(a2)+
        move.b (a0)+,(a2)+
        move.b (a0)+,(a2)+
        move.b (a0)+,(a2)+
        move.b (a0)+,(a2)+
        add.l #$22,a2        dbf    d0,bit_copy_loop
        rts
set_weiter:
        move.w #44,y2
        bsr  draw_line
        move.w #148,y2
        bsr  draw_line
        move.w #218,y2
        bsr  draw_line
        move.w #250,y2
        bsr  draw_line
        move.w #160,y2
        bsr  draw_line
        move.w #157,y1
        move.l #text11,text_ptr
        bsr  set_text2
        move.w #170,y1
        move.w #$0001,d2
        move.l #text2,text_ptr
set_loop2:
        bsr  set_text2
        addi.l #$000026,text_ptr
        addi.w #$000a,y1
        dbf    d2,set_loop2
        move.w #$0001,d2
        move.l #text3,text_ptr
        move.w #230,y1
set_loop3:
        bsr  set_text2
        addi.w #$000f,y1
        addi.l #$000026,text_ptr
        dbf    d2,set_loop3
        lea    rastport,a1
        move.b #1,d0
        jsr    SetAPen(a6)
        lea    rastport,a1
        move.w #10,d0
        move.w #10,d1
        move.w #309,d2
        move.w #40,d3
        jsr    RectFill(a6)
        lea    rastport,a1
        move.b #0,d0
        jsr    SetAPen(a6)
        lea    rastport,a1
        move.w #11,d0
        move.w #11,d1
        move.w #308,d2
        move.w #39,d3
        jsr    RectFill(a6)
        lea    rastport,a1
        move.b #1,d0
        jsr    SetAPen(a6)
AnfText: move.l #text4,text_ptr
        move.w #16,x1
        move.w #18,y1
        bsr  set_text3
        move.l #text20,text_ptr        move.w #28,y1
        bsr  set_text3
        move.l #text21,text_ptr        move.w #38,y1
        bsr set_text3
        rts

draw_line:
        lea    rastport,a1
        move.w #$0000,d0
        move.w y2,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.w #$013f,d0
        move.w y2,d1
        jsr    Draw(a6)
        rts

set_text2:
        move.l a6,-(a7)
        move.l gfxbase,a6
        lea    rastport,a1
        move.w x1,d0
        move.w y1,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.l text_ptr,a0
        move.w #$0026,d0
        jsr    Textaus(a6)
        move.l (a7)+,a6
        rts

set_text3:
        move.l a6,-(a7)
        move.l gfxbase,a6
        lea    rastport,a1
        move.w x1,d0
        move.w y1,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.l text_ptr,a0
        move.w #$0024,d0
        jsr    Textaus(a6)
        move.l (a7)+,a6
        rts

show_start:
        lea    text6,a0
        btst   #0,dd
        bne  show_s1
        btst   #0,sd
        beq.s  show_start1
show_s1:lea    df0,a1
        bsr  copy_drives
show_start1:
        btst   #1,dd
        bne.s  show_s2
        btst   #1,sd
        beq.s  show_start2
show_s2:lea    df1,a1
        bsr  copy_drives
show_start2:
        btst   #2,dd
        bne.s  show_s3
        btst   #2,sd
        beq.s  show_start3
show_s3:lea    df2,a1
        bsr.s  copy_drives
show_start3:
        btst   #3,dd
        bne.s  show_s4
        btst   #3,sd
        beq.s  show_start4
show_s4:lea    df3,a1
        bsr.s  copy_drives
show_start4:
        move.w #16,x1
        move.w #18,y1
        move.w #$002,d2
        move.l #text5,text_ptr
show_loop:
        bsr  set_text3
        addi.w #$000a,y1
        addi.l #$000024,text_ptr
        dbf    d2,show_loop
        move.w #16,d0
        lea    text6,a0
lop:    move.b #$20,(a0)+
        dbf    d0,lop
        rts

copy_drives:
        move.w #$0003,d0
copy_d_loop:
        move.b (a1)+,(a0)+
        dbf    d0,copy_d_loop
        rts

read_error:
        clr.l  d0
        move.b cylinder,d0
        lea    text7,a0
        add.l #$00001a,a0        bsr  byte_umrechnung
        move.b side,d0
        add.l #$000006,a0        bsr  byte_umrechnung
        move.w #7,x1
        move.w #230,y1
        move.l #text7,text_ptr
        bra  set_text2

write_error:
        clr.l  d0
        move.b cylinder,d0
        lea    text8,a0
        add.l #$00001b,a0        bsr  byte_umrechnung
        move.b side,d0
        add.l #$000006,a0        bsr  byte_umrechnung
        move.w #7,x1
        move.w #230,y1
        move.l #text8,text_ptr
        bra  set_text2

clear_error:
        move.l #text3,text_ptr
        move.w #7,x1
        move.w #230,y1
        bra  set_text2

reading_cyl:
        clr.l d0
        move.b cylinder,d0
        lea    rcyl_text,a0
        bsr  byte_umrechnung
        lea    rcyl_text,a0
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #127,d0
        move.w #245,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.w #$0002,d0
        jsr    Textaus(a6)
        rts

writing_cyl:
        clr.l  d0
        move.b cylinder,d0
        lea    wcyl_text,a0
        bsr  byte_umrechnung
        lea    wcyl_text,a0
        move.l gfxbase,a6
        lea    rastport,a1
        move.w #271,d0
        move.w #245,d1
        jsr    Movee(a6)
        lea    rastport,a1
        move.w #$0002,d0
        jsr    Textaus(a6)
        rts

insert_source:
        move.l #text9,text_ptr
        bra.s  melvin
insert_destination:
        move.l #text10,text_ptr
        bra.s  melvin
protect_source:
        bsr  cl
        move.l #text13,text_ptr
        bra.s  melvin
protect_destination:
        bsr  cl
        move.l #text14,text_ptr
melvin:
        move.w #16,x1
        move.w #28,y1
        bsr  set_text3
        move.l #text5,text_ptr
        move.w #18,y1
        bsr    set_text3
        bra  wait_r4
clear_eol:
        move.l #text15,text_ptr
        move.w #16,x1
        move.w #28,y1
        bsr set_text3        move.w #18,y1
        bra    set_text3

write_b_again:
        bsr  cl
        move.l #text17,text_ptr
        move.w #16,x1
        move.w #28,y1
        bsr    set_text3
wba1:   bsr    wait_key
        cmpi.b #$45,d0
        beq.s  wba4
        cmpi.b #$31,d0
        beq.s  wba2
        cmpi.b #$36,d0
        bne.s  wba1
        move.l #-1,d0
        bra.s  wba3
wba2:   clr.l  d0
wba3:   move.l d0,-(a7)
        bsr    clear_eol
        move.l (a7)+,d0
        rts
wba4:   move.w #escape,errorflag
        rts

compare_drives:
        move.w #18,y1
        bsr    cl2
        lea    text19,a0
        clr.w  d2
cdl1:   lea    df0,a1
        btst   d2,vererrflag
        beq.s  cdl4
        move.w d2,d0
        lsl    #2,d0
        add.l  d0,a1
        bsr.s  cdl2
cdl4:   addq.w #1,d2
        cmpi.w #4,d2
        bne.s  cdl1
        move.l #text18,text_ptr
        move.w #28,y1
        bra    set_text3
cdl2:   move.w #3,d1
cdl3:   move.b (a1)+,(a0)+
        dbf    d1,cdl3
        rts

wait_key:
        movem.l d1-d7,-(a7)
        move.w Tastenabl,d1
l8:     move.b IntCon,d0
        btst #7,d1
        bne l1
        sub.l #1,TastenCnt
        beq Tastrepeat
l1:     btst #3,d0
        beq l8
        move.b Taste,d0
        ori.b #$40,Cont
        not.b d0
        ror.b #1,d0
        move.w #$600,d1
l5:     dbf d1,l5
        andi.b #$bf,Cont
        move.l #MaxWart,CntWart
        move.l #MaxWart,TastenCnt
        move.w d0,Tastenabl
tastenend:
        movem.l (a7)+,d1-d7
        rts
tastrepeat:
        move.l CntWart,d1
        cmp.l  #MinWart,d1
        bcs.s  repeat1
        sub.l  #$800,d1
        move.l d1,CntWart
repeat1:move.l d1,TastenCnt
        move.w Tastenabl,d0
        bra.s  tastenend

get_key:
        move.w $dff01e,d1
        btst #3,d1
        beq \l1
        move.b Taste,d0
        ori.b #$40,Cont
        not.b d0
        ror.b #1,d0
        move.w #$600,d1
\l2:    dbf d1,\l2
        andi.b #$bf,Cont
\l1:    rts

cl:     move.w #28,y1
cl2:    move.w #16,x1
        move.l #text15,text_ptr
        bsr  set_text3
        addi.w #10,y1
        bsr  set_text3
        rts

cl1:    bsr.s  cl
        move.w #18,y1
        bsr  set_text3
        move.w #28,y1
        move.l #text16,text_ptr
        bsr  set_text3
        rts


gfxname:        dc.b "graphics.library",0
         align.w
gfxbase:        dc.l 0
oldcopper:      dc.l 0
bit_adress:     dc.l 0
cop_adress:     dc.l 0
c1_adress:      dc.l 0
c2_adress:      dc.l 0
c3_adress:      dc.l 0
c4_adress:      dc.l 0
c5_adress:      dc.l 0
c6_adress:      dc.l 0
c7_adress:      dc.l 0
c8_adress:      dc.l 0
c9_adress:      dc.l 0
c10_adress:     dc.l 0
c11_adress:     dc.l 0
c12_adress:     dc.l 0
c13_adress:     dc.l 0

rastport:       blk.l  1,0
r_bitmap:       blk.l 24,0

bitmap:         blk.l  2,0
plane1:         blk.l  8,0

ncopper:
                dc.w $008e,$2681,$0090,$24c1
                dc.w $0092,$0038,$0094,$00d0
                dc.w $00e0
plane_hi:       dc.w $0000,$00e2
plane_lo:       dc.w $0000
                dc.w $0100,$1200,$0102,$0000,$0104,$0000
                dc.w $0108,$0000,$010a,$0000
                dc.w $0120,$0000,$0122,$0000
                dc.w $0180,$0000,$0182
color1:         dc.w $00ee,$0d01,$fffe,$0182
                dc.w $00ee,$5401,$fffe,$0182
color2:         dc.w $00ee,$6001,$fffe,$0182
color3:         dc.w $00ee,$6a01,$fffe,$0182
color4:         dc.w $00ee,$7201,$fffe,$0182
color5:         dc.w $00ee,$7d01,$fffe,$0182
color6:         dc.w $00ee,$8601,$fffe,$0182
color7:         dc.w $00ee,$9001,$fffe,$0182
color8:         dc.w $00ee,$9a01,$fffe,$0182
color9:         dc.w $00ee,$a401,$fffe,$0182
color10:        dc.w $00ee,$af01,$fffe,$0182
color11:        dc.w $00ee,$b701,$fffe,$0182
color12:        dc.w $00ee,$c501,$fffe,$0182
                dc.w $00ee,$c701,$fffe,$0182
color13:        dc.w $00ee,$ff01,$fffe,$0182
                dc.w $00ee,$ffff,$fffe
                dc.w $0000,$0000
copend:
copsize = copend - ncopper

drives:         dc.b 0
d_drives:       dc.b 0
s_drives:       dc.b 0
color_ptr:      dc.b 0
back:           dc.b 0
zeiger1:        dc.b 0
cylinder:       dc.b 0
side:           dc.b 0
new:            dc.b 0
drv:            dc.b 0
       align.w
flash_adress:   dc.l 0
text_ptr:       dc.l 0

x1:             dc.w 7
y1:             dc.w 54
y2:             dc.w 0

tastenabl:      dc.w $ffff
cntwart:        dc.l MaxWart
tastencnt:      dc.l MaxWart

fc_text:        dc.b "00"
ralf:           dc.b 0
lc_text:        dc.b "79"
tr_text:        dc.b "0"
sd_text:        dc.b "0"
rcyl_text:      dc.b "00"
wcyl_text:      dc.b "00"
on_text:        dc.b ".ON"
on_text2:       dc.b " ON"
off_text:       dc.b "OFF"
df0:            dc.b "DF0 "
df1:            dc.b "DF1 "
df2:            dc.b "DF2 "
df3:            dc.b "DF3 "

text1:  dc.b "F1  = START COPY......................"
        dc.b "F2  = FIRST CYLINDER (CRSR).........00"
        dc.b "F3  = LAST  CYLINDER (CRSR).........79"
        dc.b "F4  = HOW MANY TRIES (CRSR)..........3"
        dc.b "F5  = WRITE SEVERAL TIMES..........OFF"
        dc.b "F6  = VERIFY DESTINATION............ON"
        dc.b "F7  = FASTCOPY......................ON"
        dc.b "F8  = DEEPCOPY 1...................OFF"
        dc.b "F9  = DEEPCOPY 2...................OFF"
        dc.b "F10 = SOURCE DRIVE (0/1/2/3).......DF0"
text2:  dc.b "DEL = DESTINATION DRIVE (0/1/2/3)....."
        dc.b "      DF0:    DF1:    DF2:    DF3:    "
text3:  dc.b "         STATUS: 00, OK,00,00         "
        dc.b "  READING CYL. 00 / WRITING CYL. 00   "
text4:  dc.b "       A M I G A - COPY  V1.2       "
text5:  dc.b "        (ESC) TERMINATES COPY       "
        dc.b "INSERT DISK(S) IN  "
text6:  dc.b "                 "
        dc.b "PRESS RETURN OR ENTER WHEN READY !¡!"
text7:  dc.b "STATUS: READ-ERROR ON CYL.00 SIDE 00  "
text8:  dc.b "STATUS: WRITE-ERROR ON CYL.00 SIDE 00 "
text9:  dc.b "    PLEASE INSERT SOURCE DISK !!    "
text10: dc.b "  PLEASE INSERT DESTINATION DISK !  "
text11: dc.b " S  = SYNCCORRECTION................ON"
text12: dc.b "       ONLY ONE DESTINATION !!      "
text13: dc.b " SOURCE DISK INSN'T WRITEPROTECTED. "
text14: dc.b "DESTINATION DISK IS WRITEPROTECTED. "
text15: dc.b "                                    "
text16: dc.b "          COPY COMPLETE !!          "
text17: dc.b "    WRITE BUFFER AGAIN ??? (Y/N)    "
text18: dc.b " ERROR ON DRIVE(S) "
text19: dc.b "                 "
text20: dc.b "            WRITTEN BY :            "
text21: dc.b "   R. GELFAND AND S. THUBEAUVILLE   "
       align.w
floppy:
 dc.l $00000000,$00000000,$00000000,$00000000,$000007ff,$ffffffe0  dc.l $04000000,$002005ff,$ffffffa0,$05ffffff,$ffa00400,$00000020
 dc.l $04ffffff,$ff200880,$00000110,$08800000,$01100880,$1ff80110
 dc.l $08801008,$011008bf,$f00ffd10,$07a00000,$05e008bf,$f00ffd10
 dc.l $08800ff0,$01100a90,$00000110,$08800000,$01100480,$00000120
 dc.l $04ffffff,$ff200400,$00000020,$07ffffff,$ffe00000,$00000000
floppyend:


;Fast Copy

DecodeAnz:     dc.w 0      ;Zähler für zu dekodierende Langworte
DecodeAdr:     dc.l 0      ;Adresse bei der dekodiert wird
BlockAdr:      dc.w 0      ;Offset im Block für dekodieren
FTestAdr:      dc.l 0      ;Testadresse, ob Block schon geladen
SektNum:       dc.w 0      ;Zähler für Sektornummer
BytesVLücke:   dc.w 0      ;Bytes vor der Lücke
BytesNLücke:   dc.w 0      ;Bytes nach der Lücke
FirstBlock:    dc.w 0      ;Blocknummer des ersten Blocks
FirstBlockSp:  dc.w 0      ;Dauerspeicher für ersten Block
SektBL:        dc.w 0      ;Sektorzähler für Sektoren vor der Lücke
VerifyFlag:    dc.w 0      ;gibt an, ob Lesen oder Verify
VerErrFlag:    dc.w 0      ;Flag für Errors bei Verify Bit = 1 => Error
TNumPufferA:   dc.w 0      ;Tracknummerspeicher bei 1D-Copy (Start-Track)
TNumPufferE    dc.w 0      ;Puffer für Endnummer der geladenen Track
BlockMeldung:  ds.w 11

;Cruncher

Länge:         dc.w $1600
KurzByte:      dc.b 0
               align.w
TrackZeiger:   ds.l 164    ;Speicher, für Zeiger auf gepackte Tracks
SpeicherAnf:   dc.l 0      ;Speicheranfang für Chrunchen
SpeicherLänge: dc.l 0      ;Speichelänge für Crunchen
SpeicherChip:  dc.l 0
LängeChip:     dc.l 0
FreiFlagCh:    dc.w 0
SpeicherFast:  dc.l 0
LängeFast:     dc.l 0
FreiFlagFa:    dc.w 0
Abzug:         dc.w 0      ;Siehe CrunEnd2

;Verwaltung

TrackPuffer1:  dc.l 0
TrackPuffer2:  dc.l 0
TrackNumS:     dc.w 0
TrackNumD:     dc.w 0
TrackNum:      dc.w 0
StartTrack:    dc.w 0           ;erster zu lesender Track
EndTrack       dc.w 0           ;letzter zu lesender Track
MotorBits:     dc.b $F3
MotorBitsS:    dc.b $F3
MotorBitsD:    dc.b $F3
Flag:          dc.b $00                  ;gigt an ob Source or Dest
               align.w

;Deep Copy

Position:      dc.l 0           ;Für Suchroutine
Verschieb:     dc.w 0           ;Anzahl der Bits bei verschiebung
Größe1:        dc.w 0           ;größe der größten Blocks
Größe2:        dc.w 0           ;größe der zweitgrößten Blocks
GrößePos:      dc.l 0           ;Position des größten Blocks
Suchlang:      dc.w 0           ;Wieviele Fehlerhaft Worte dürfen sein
AnzWorte:      dc.w 0           ;auf wieviele Worte wird verglichen
ErrorFlag:     dc.w 0
EndPos:        dc.l 0           ;Endposition des Tracks
AnfPos:        dc.l 0           ;Anfang der Tracks (nach Lücke)
SLänge:        dc.w 0           ;Anzahl der zu schreibenden Bytes
SchreibAnf:    dc.l 0           ;Adresse, ab der geschrieben wird
Offset:        dc.w 0           ;Anzahl der Bytes vor Sync beim schreiben
TrackBytes:    dc.w 0           ;Bytes auf dem Track
CheckLänge:    dc.w 0           ;Bytes auf Track (Kontrolle)
LängeDest:     dc.w 0           ;Tracklänge der Dest.-Disk
Syncweit:      dc.w 0           ;Endfernung von Indx zu Sync
SyncAnz:       dc.w 0           ;Anzahl der gefundenen Syncs
CopyVersuch1:  dc.w 0           ;Illegale Daten wie oft lesen
CopyVersuch2:  dc.w 0           ;wie oft lesen bei NoSync

Blöcke:        ds.l SortBlockAnz    ;Speicher für Blocklängen+SyncAnz
SortBlöcke:    ds.l SortBlockAnz    ;Speicher für Blocksortierung
AnzSortBlock:  dc.w 0      ;Anzahl der verschieden sortierten Blöcke

SyncWort:      dc.w $4489       ;Wert für Lesen

;Tabelle für Syncsuche
;Sync = $4489

SyncBase:      dc.l %01000100100010010000000000000000
               dc.l %00100010010001001000000000000000
               dc.l %00010001001000100100000000000000
               dc.l %00001000100100010010000000000000
               dc.l %00000100010010001001000000000000
               dc.l %00000010001001000100100000000000
               dc.l %00000001000100100010010000000000
               dc.l %00000000100010010001001000000000
               dc.l %00000000010001001000100100000000
               dc.l %00000000001000100100010010000000
               dc.l %00000000000100010010001001000000
               dc.l %00000000000010001001000100100000
               dc.l %00000000000001000100100010010000
               dc.l %00000000000000100010010001001000
               dc.l %00000000000000010001001000100100
               dc.l %00000000000000001000100100010010
               dc.l %00000000000000000100010010001001

AmigaTrack:    dc.b 0  ;gibt an, ob Amiga-Format bei DeepCopy

fc:  dc.b 00    ;First Cylinden
lc:  dc.b 79    ;Last    "
tr:  dc.b 3     ;Ties
ws:  dc.b 0     ;write mehrfach
vd:  dc.b 1     ;Verify
fa:  dc.b 1     ;Fast Copy
dc1: dc.b 0     ;D1 Copy
dc2: dc.b 0     ;D2 Copy
sd:  dc.b 1     ;SourceBits
dd:  dc.b 2     ;DestDits
sy:  dc.b 0     ;Sync-Korrektur

waiting: dc.b 0 ;irq wait_conter

DevName:       dc.b "trackdisk.device",0

               END


