DeviceList     EQU 350
TrackTask      EQU 302
TrackPort      EQU 36
SPReg          EQU 54
RückAdresse    EQU 70
IDNestCnt      EQU 294
PortStatus     EQU 34
CMD_READ       EQU 2
FindName       EQU -276
Wait           EQU -318
AllocMem       EQU -198
FreeMem        EQU -210

Req1           EQU $01                   ;MEMF_PUBLIC
Req2           EQU $03
TrackSize      EQU $1604                 ;Anzahl der Bytes eines Tracks

ReadError      EQU 21
NoDisk         EQU 29
NoSync         EQU 21

               lea $fc0000,a0
               cmp.l #$2033332E,$1c(a0)
               bne \Fehler4
               cmp.l #$31393220,$20(a0)               bne \Fehler4
               move.l $4,a6
               bsr Disable
               move.l #Ende-Anfang,d0
               move.l #Req1,d1
               jsr AllocMem(a6)
               move.l d0,a1
               move.l a1,a4              ;Speicheradresse retten
               move.l d0,d4
               beq \Fehler1
               lea TrackName(pc),a1
               lea DeviceList(a6),a0
               jsr FindName(a6)
               tst.l d0
               beq \Fehler3
               move.l d0,a5

               lea MyTask(pc),a0               lea Anfang(pc),a1
               suba.l a1,a0
               adda.l a0,a4              ;Adresse von MeinTask
               clr.l d3
\l3:           move.l TrackPort(a5,d3),d0
               beq \l5
               move.l d0,a3
               move.l #TrackSize,d0
               move.l #Req2,d1
               jsr AllocMem(a6)
               lea TrackSpeicher1(pc),a0               lea (a0,d3),a0            ;TrackSpeicher für Laufwerk
               move.l d0,(a0)
               beq \Fehler2
\l1:           btst #0,PortStatus(a3)    ;Warten, bis Task in Wait
               bne \l1
               move.l #1800,$2c(a3)      ;Stepmotor beschleunigen
               move.l #1,$30(a3)         ;keine Wartezeit nach Posi.
               lea TrackTask+SPReg(a3),a2
               move.l (a2),a1
               move.l a4,RückAdresse(a1)
\l5:           addq.l #4,d3
               cmpi.w #16,d3
               bcs \l3

               move.l #Ende-Anfang,d0
               lea Anfang(pc),a0
               move.l d4,a1
\l4:           move.b (a0)+,(a1)+        ;Daten kopieren
               subq.l #1,d0
               bne \l4
               bsr blink
\Fehler1:
               bsr Enable
\Fehler4:      clr.l d0
               rts
\Fehler2:      subq.l #4,d3
               bcs \Fehler3
               lea TrackSpeicher1(pc),a0
               lea (a0,d3),a0
               move.l (a0),a1
               move.l #TrackSize,d0
               jsr FreeMem(a6)
               bra \Fehler2
\Fehler3:      move.l #Ende-Anfang,d0
               move.l a4,a1
               jsr FreeMem(a6)
               bra \Fehler1

Blink:         move.l D0,-(a7)
               move.l #$20000,d0
\l1:           move.w d0,$dff180
               sub.l #1,d0
               bne \l1
               move.l (a7)+,D0
               rts

Anfang:
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 \l1
               move.w #$c000,$dff09a
\l1:           move.l (a7)+,a6
               rts

DerTask:       MOVEA.L 8(A7),A6
               MOVEA.L 4(A7),A3
               LEA $12E(A3),A0
               MOVE.L A0,$10(A3)
               JSR $FE9960
LFEAE64:       BSR.S LFEAE7A
               MOVE.L #$300,D0
               MOVE.L A6,-(A7)
               MOVEA.L $34(A6),A6
               JSR Wait(A6)
MyTask:        MOVEA.L (A7)+,A6
               BRA.S LFEAE64
LFEAE7A:       BSET #0,$22(A3)
               BNE NoMessage
LFEAE84:       MOVEA.L A3,A0
               MOVE.L A6,-(A7)
               MOVEA.L $34(A6),A6
               JSR -$174(A6)
               MOVEA.L (A7)+,A6
               TST.L D0
               BEQ LFEAF3E
               MOVEA.L D0,A2
               BCLR #3,$40(A3)
               BEQ LFEAF1E
               MOVEA.L $52(A3),A0
               BCLR #0,2(A0)
               BEQ LFEAEBA
               MOVE.L A0,$4E(A3)
               JSR $FEA958
LFEAEBA:       MOVEA.L $52(A3),A0
               MOVEQ #-1,D0
               MOVE.W D0,0(A0)
               MOVE.W D0,$4C(A3)
               MOVEQ #0,D0
               JSR $FEA462
               MOVEA.L A6,A0
               MOVEA.L $34(A0),A6
               ADDQ.B #1,$127(A6)
               MOVEA.L A0,A6
               TST.W $24(A3)
               BNE LFEAF12
               MOVEQ #0,D0
               MOVE.B $43(A3),D0
               MOVE.L A6,-(A7)
               MOVEA.L $3C(A6),A6
               JSR -$C(A6)
               MOVEA.L (A7)+,A6
               LEA $24(A6),A0
               MOVEQ #0,D0
               MOVE.B $43(A3),D0
               LSL.L #2,D0
               ADDA.L D0,A0
               CLR.L (A0)
               SUBA.L A1,A1
               MOVE.L A6,-(A7)
               MOVEA.L $34(A6),A6
               JSR -$120(A6)
               MOVEA.L (A7)+,A6
LFEAF12:       MOVE.L A6,-(A7)
               MOVEA.L $34(A6),A6
               JSR -$8A(A6)
               MOVEA.L (A7)+,A6
LFEAF1E:       MOVEA.L A2,A1
               LEA $86(A3),A0
               CMPA.L A0,A2
               BNE.S LFEAF30
               JSR $FE9960
               BRA LFEAE84
LFEAF30:       BSET #1,$22(A3)
               bsr Schritt1
               BRA LFEAE84
LFEAF3E:       BCLR #1,$22(A3)
               BCLR #0,$22(A3)
NoMessage:     RTS

Schritt1:      MOVE.L A2,-(A7)
               MOVEA.L A1,A2
               ANDI.B #-6,$40(A3)
               jsr $FE998C
               MOVEA.L A2,A1
               MOVE.W $1C(A2),D0
               cmp.b #CMD_READ,d0
               beq Schritt2
               BTST #$F,D0
               BEQ.S LFEA052
               BSET #2,$40(A3)
               MOVE.L $126(A3),D1
               CMP.L $30(A2),D1
               BLS.S LFEA052
               MOVE.B #$1D,$1F(A2)
               JSR $FEA1B0
               BRA.S LFEA066
LFEA052:       MOVEQ #0,D1
               MOVE.B D0,D1
               LSL.W #2,D1
               LEA $FEA300,A0
               MOVEA.L 0(A0,D1.W),A0
               JSR (A0)
LadenEnde:
               JSR $FE998C
LFEA066:       MOVEA.L (A7)+,A2
               RTS

Schritt2: ;     bsr Blink
               bsr Schritt3
               bra LadenEnde

Schritt3:
 MOVEM.L A2-A4,-(A7)
 MOVEA.L $18(A1),A3
 MOVEA.L A1,A2
 MOVE.L A2,$44(A3)
 MOVE.L #0,$20(A2)
 MOVE.L $28(A2),$56(A3)
 MOVE.L $2C(A2),D0
 JSR $FEA182
 TST.L D0
 BMI LFEA92A
 MOVE.W D0,$4A(A3)
 MOVE.B D1,$49(A3)
 MOVE.L $2C(A2),D0
 ADD.L $24(A2),D0
 JSR $FEA182
 TST.L D0
 BMI LFEA92A
 BTST #2,$40(A3)
 BEQ.S LFEA78E
 MOVE.L $34(A2),$5A(A3)
 BEQ.S LFEA78E
 BSET #0,$40(A3)
LFEA78E:BTST #1,$40(A3)
 BEQ.S LFEA7A0
 MOVE.B #$1D,$1F(A2)
 BRA LFEA920
LFEA7A0:MOVE.W $4A(A3),D0
 JSR $FEA93C
 MOVE.L A0,$4E(A3)
 BNE.S LFEA804
 jsr $FEA952 MOVEA.L A0,A2
 MOVE.L A2,$4E(A3)
LFEA7B8:BTST #0,2(A2)                    ;Spur im Puffer
 BEQ.S LFEA7D4                           ;Nein, einlesen
 JSR $FEA958
 TST.L D0
 BEQ.S LFEA7D4
 MOVEA.L $44(A3),A1
 MOVE.B D0,$1F(A1)
 BRA LFEA920
LFEA7D4:MOVE.W $4A(A3),0(A2)
 BCLR #0,2(A2)
 CLR.B $42(A3)
 bsr lesen                               ;Spur in Puffer lesen
 MOVE.B 3(A2),D0
 CMPI.B #$B,D0
 BCS.S LFEA804
 MOVE.W #-1,0(A2)
 MOVEA.L $44(A3),A1
 MOVE.B D0,$1F(A1)
 BRA LFEA920
LFEA804:MOVEA.L $44(A3),A2
 MOVE.W $1C(A2),D0
 MOVEA.L $4E(A3),A0
 CMPI.B #3,D0
 BNE LFEA890
 BSET #0,2(A0)
 MOVEQ #0,D0
 MOVE.B $49(A3),D0
 SUB.B 3(A0),D0
 BPL.S LFEA82E
 ADDI.B #$B,D0
LFEA82E:MULU #$440,D0
 LEA $680(A0),A4
 ADDA.L D0,A4
 BTST #0,$40(A3)
 BEQ.S LFEA866
 MOVEA.L $5A(A3),A0
 MOVE.L #$10,D0
 LEA $10(A4),A1
 JSR $FEAB4A
 LEA 8(A4),A0
 MOVE.W #$28,D1
 JSR $FEADA4
 LEA $30(A4),A0
 JSR $FEAD46
LFEA866:MOVEA.L $56(A3),A0
 MOVE.L #$200,D0
 LEA $40(A4),A1
 JSR $FEAB4A
 LEA $40(A4),A0
 MOVE.W #$400,D1
 JSR $FEADA4
 LEA $38(A4),A0
 JSR $FEAD46
 BRA LFEA8D6
LFEA890:MOVEQ #0,D0
 BTST #0,$40(A3)                         ;SecLabel gesetz?
 BEQ.S LFEA8C4                           ;nein
 MOVE.B $49(A3),D0                       ;Sektornummer nach D0
 SUB.B 3(A0),D0
 BPL.S LFEA8A0
 ADDI.B #$B,D0
LFEA8A0:MULU #$440,D0
 LEA $680(A0),A4
 ADDA.L D0,A4
 LEA $10(A4),A1
 MOVEA.L $5A(A3),A0
 MOVE.L #$10,D0
 JSR $FEACB2
LFEA8C4:
 clr.l d0
 MOVE.B $49(A3),D0                       ;Sektornummer nach D0
 MOVEA.L $56(A3),A1                      ;Ziehladresse
 lea TrackSpeicher1(pc),a0
 clr.l d1
 move.b $43(a3),d1
 lsl.w #2,d1
 adda.l d1,a0
 movea.l (a0),a0
 mulu #$200,d0
 adda.l d0,a0
 move.w #$200,d0
 bsr CopyBlock
LFEA8D6:MOVE.L #$200,D1
 ADD.L D1,$56(A3)
 MOVE.L $20(A2),D0
 ADD.L D1,D0
 MOVE.L D0,$20(A2)
 BTST #0,$40(A3)
 BEQ.S LFEA8FA
 ADDI.L #$10,$5A(A3)
LFEA8FA:CMP.L $24(A2),D0
 BCC.S LFEA920
 MOVEA.L $4E(A3),A2
 ADDQ.B #1,$49(A3)
 CMPI.B #$B,$49(A3)
 BLT LFEA804
 MOVE.B #0,$49(A3)
 ADDQ.W #1,$4A(A3)
 BRA LFEA7B8
LFEA920:MOVEA.L $44(A3),A1
 JSR $FEA1B0
 BRA.S LFEA936
LFEA92A:MOVEA.L $44(A3),A1
 MOVE.B #-4,$1F(A1)
 BRA.S LFEA920
LFEA936:MOVEM.L (A7)+,A2-A4
 RTS
lesen:         MOVEM.L A2,-(A7)
               MOVEA.L $4E(A3),A2
               MOVEQ #1,D0
               jsr $FEA462               ;Motor An
LFEA9AC:       MOVEQ #0,D0
               MOVE.W $4A(A3),D0
               jsr $FEA3DA               ;Kopf Posi.
LFEA9B6:       LEA 1664(A2),A0
               lea TrackSpeicher1(pc),a1
               clr.l d0
               move.b $43(a3),d0
               lsl.w #2,d0
               adda.l d0,a1
               move.l (a1),a1
               bsr tracklesen
               move.w FirstBlock(pc),D0
               MOVE.B d0,3(A2)
               lea ErrorFlag(pc),a0
               tst.w (a0)
               beq \Ende                 ;Kein Fehler
\Error:        MOVE.B 1(a0),3(A2)        ;Fehler eintragen
               ADDQ.B #1,$42(A3)
               MOVE.B $42(A3),D0
               CMP.B $34(A3),D0
               BGT.S \Ende               ;Ende zu viele Fehler
               ANDI.B #3,D0
               BNE.S LFEA9B6
               MOVE.W #-1,$4C(A3)
               BRA.S LFEA9AC
\Ende:         MOVEM.L (A7)+,A2
               RTS

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

Tracklesen:
               MOVEM.L D2-D4/a4-a5,-(A7)
               move.l a0,a5
               move.l a1,a4
               lea ErrorFlag(pc),a1
               clr.w (a1)
               lea DecodeAnz(pc),a1               move.w #$080,(a1)         ;Anzahl Langworte zu decodieren
               lea $40(a5),a0
               lea DecodeAdr(pc),a1
               move.l a0,(a1)            ;Datenbereich des 1. Blocks
               adda.l #$400,a0
               lea FTestAdr(pc),a1
               move.l a0,(a1)            ;Adresse des nächsten Blocks
               jsr $FEADDC               ;Laufwerk anmelden
               MOVE.B $41(A3),$BFD100
               BTST #2,$BFE001           ;Disk in Laufwerk
               BNE.S \FL3                ;Ok
               lea ErrorFlag(pc),a1
               move.w #NoDisk,(a1)       ;Keine Disk im Laufwerk
               BRA   \FL5                ;Ende

\FL3:          bsr Disable
               move.l a6,-(a7)
               MOVEA.L A5,A6             ;TrackPuffer
               move.l #$aaaaaaaa,(a6)+
               move.w #$4489,(a6)+       ;erste Sync eintragen
               bsr suchen
               tst.l d0
               bpl \FL8
               lea ErrorFlag(pc),a1
               move.w #NoSync,(a1)       ;No Sync
               bra \FL9                  ;Ende
\FL8:          bsr FLösch                ;Trackpuffer vorbereiten
               clr.l d2
               move.w BytesVLücke(pc),d2 ;Anz. der Bytes vor Lücke
               tst.l d2
               beq \FL1                  ;Keine Bytes vor der Lücke
               lea BlockAdr(pc),a1
               clr.w (a1)                ;Offset im Block
               bsr Anzlesen              ;Bytes lesen
               clr.l d0
               move.w BytesVLücke(pc),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(pc),d2
               tst.l d2
               beq \FL2
               lea BlockAdr(pc),a1
               clr.w (a1)
               bsr Anzlesen
               bsr letzterblock
\FL2:          move.l #$aaaaaaaa,$2ec0(a5) ;Lücke nach Daten schaffen
               BTST #2,$BFE001           ;Disk Im Laufwerk?
               bne   \FL9                ;Ok, Disk in Drive
               lea ErrorFlag(pc),a1
               move.w #NoDisk,(a1)
\FL9:          move.l (a7)+,a6
\FL5:          bsr Enable
               jsr $FEAE42               ;Laufwerk abmelden
               MOVEM.L (A7)+,D2-D4/a4-a5
               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(pc),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:
               bsr 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)
               bsr decode
               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/a2,-(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
               bsr 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:          lea SektNum(pc),a2
               move.w d3,(a2)            ;Nummer speichern
               lea FirstBlock(pc),a2
               move.w d3,(a2)            ;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
               lea BytesVLücke(pc),a2
               move.w d3,(a2)
               lea BytesNLücke(pc),a2
               move.w d4,(a2)
               lea SektBL(pc),a2
               move.w #$0b,(a2)          ;Sektoren vor Lücke nach dem Laden
               bra \SUEnd
\SUError:      move.l #-1,d0
               lea ErrorFlag(pc),a2
               move.w #ReadError,(a2)
\SUEnd:        movem.l (a7)+,d2-d4/a2
               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-d4/a2-a3,-(a7)
               clr.l d3
               move.l a3,d4              ;Laufwerks-Port retten
               move.w BlockAdr(pc),d3        ;Offset im Block
               move.l FTestAdr(pc),a0        ;Adresse zum testen ob
                                         ;Block schon geladen
               move.l DecodeAdr(pc),a2       ;Adresse, bei der dekodiert wird
               move.w DecodeAnz(pc),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
               move.l d4,a3              ;* Laufwerks-Port
               bsr BlockCheck            ;Block checken
               movem.l (a7)+,a0-a1       ;Register zurückholen
               move.w SektNum(pc),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
               lea SektNum(pc),a3
               add.w #1,(a3)             ;Sektornummer erhöhen
               cmp.w #$0b,(a3)           ;Nummer über 10?
               bcs \DC3                  ;Nein, OK
               clr.w (a3)                ;Nummer = 0
\DC3:          bra \DC1

\DCEnd:
               lea BlockAdr(pc),a3
               move.w d3,(a3)
               lea DecodeAdr(pc),a3
               move.l a2,(a3)
               lea FTestAdr(pc),a3
               move.l a0,(a3)
               lea DecodeAnz(pc),a3
               move.w D2,(a3)

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

;Letzten Block entkodieren

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

               move.w SektNum(pc),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(pc),a2
               move.w DecodeAnz(pc),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/a2,-(a7)
               clr.l d3
               move.w SektNum(pc),d3
               lsl.w #1,d3               ;Sektornummer => Offset
               lea BlockMeldung(pc),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
               bsr Prüfsumme             ;Summe über Datenblock
               move.l d0,d2              ;Summe retten
               lea 56(a1),a0             ;Zeiger auf Datensumme
               bsr 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(pc),d2        ;richtiger Sektor
               bne \FalscherSektor
               swap d0                   ;Tracknummer nach D0
               cmp.b 77(a3),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(pc),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 77(a3),d0
               swap d0
               move.b SektNum+1(pc),d0
               lsl.w #8,d0
               move.b SektBL+1(pc),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
               lea SektBL(pc),a2
               subq.w #1,(a2)
\CBEnd2:       movem.l (a7)+,d2-d3/a2
               rts

\FalscherSektor: move.w #$0017,d0
                 bra \Flagsetzen
\FalscherTrack: move.w #$0017,d0
                 bra \Flagsetzen
\KeinDosTrack:  move.w #$0017,d0
                 bra \Flagsetzen
\HeaderFalsch:  move.w #$001b,d0
                 bra \Flagsetzen
\DatenFalsch:   move.w #$0019,d0
\Flagsetzen:    lea ErrorFlag(pc),a2
                move.w d0,(a2)
                bra \CBEnd1

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

CopyBlock:
               move.l a2,-(a7)
               move.l a0,a2
               LSL.W #2,D0
               ORI.W #8,D0
               lea $dff000,a0
               bsr BlitWart
               bsr BlitterCode
               move.l (a7)+,a2
               RTS

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

BlitterCode:
               bsr Modulu                ;Modulu setzen
               MOVE.L a2,$50(A0)         ;Source
               MOVE.L a1,$54(A0)         ;Dest
               MOVE.W #$09F0,$40(A0)
               MOVE.W #0,$42(A0)
               bsr StartBlit
               rts

;Blit start und auf Ende von Blitter warten

StartBlit:
               MOVE.W d0,$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)+
               movem.l (a7)+,d0/a1
               rts



BytesVLücke:   dc.w 0
BytesNLücke:   dc.w 0
ErrorFlag:     dc.w 0
DecodeAnz:     dc.w 0
DecodeAdr:     dc.l 0
FTestAdr:      dc.l 0
BlockAdr:      dc.w 0
SektNum:       dc.w 0
FirstBlock:    dc.w 0
SektBL:        dc.w 0
TrackSpeicher1:dc.l 0
TrackSpeicher2:dc.l 0
TrackSpeicher3:dc.l 0
TrackSpeicher4:dc.l 0

BlockMeldung:  ds.w 11

TrackName:     dc.b 'trackdisk.device',0,0
Ende:
               END

