;  SPEEDER+: Verdopplung der Schreib- und Lesegeschwindigkeit
;            des ATARI ST
;  (c) Stefan Schreiber, Oktober 1990
;  Programmiersprache: PROFIMAT-Assembler


hdv_rw  = $476
swv_vec = $46E

 data
newbios4:  ds.l    1
oldbios4:  ds.l    1

meldetext: dc.b 13,10,"Speeder+ V4.0 is installing...",13,10
           dc.b "(c) 1990  Stefan Schreiber",13,10
           dc.b "Greetings to ",27,"p"," Klapauzius ",27,"q","!",13,0
 align.w
fehlermeldung:
           dc.b 10,10,"Installation Error!!!",13,10
           dc.b "I can't find an important TOS-function!",13,10
           dc.b "Press ",27,"p"," RETURN ",27,"q"," to continue...",13,0

 align.w
mediach:   dc.l $4E560000, $48E70304, $0C6E0002
flopread:  dc.l $3CBC0090, $3CBC0190, $3CBC0090
rwabs:     dc.l $4E560000, $48E70700, $3E2E0012
go2track:  dc.l $42690000, $3CBC0082, $42476100

 bss
buffer:    ds.b 4000

 text
        move.l  4(a7),a6
        move.l  12(a6),d7       ; L„nge des PRG-Bereichs
        add.l   20(a6),d7       ; + L„nge des DATA-Bereichs
        add.l   28(a6),d7       ; + L„nge des BSS-Bereichs
        addi.l  #$100,d7        ; + L„nge der Basepage

        move.l  #meldetext,-(sp)
        move    #9,-(sp)
        trap    #1
        addq.l  #6,sp           ; Meldetext ausgeben
        clr.l   -(sp)
        move    #$20,-(sp)
        trap    #1
        addq.l  #6,sp           ; Supervisormodus
        move.l  d0,d6           ; sp in d6 zwischenspeichern

        move.l  swv_vec,a0
        lea     mediach(pc),a1
        bsr     search
        move.l  a0,a6           ; Beginn der Mediach-Routine --> a6
        move.l  swv_vec,a0
        lea     flopread(pc),a1
        bsr     search
        sub.l   #30,a0          ; Beginn der floprd-Routine --> a0
        lea     buffer(pc),a1
        cmpa.l  a6,a0     ; Floppy-Routine mit niedrigster Addresse
        blo     rainbow   ; bestimmen. Diese ist je nach TOS-Version
oldtos:                   ; eine von den beiden oben aufgefhrten
        move.l  a6,a0     ; Routinen!
rainbow:
        move.l  a0,d2     ; d2 wird fr die Relocate-Routinen ben”tigt
        move    #249,d1
copy:   move.l  (a0)+,(a1)+     ; Floppy-Routinen ins RAM schaufeln
        move.l  (a0)+,(a1)+     ; 250*16 = 4000 Bytes
        move.l  (a0)+,(a1)+
        move.l  (a0)+,(a1)+
        dbf     d1,copy

        lea     buffer(pc),a0
        lea     rwabs(pc),a1
        bsr     search
        move.l  a0,newbios4  ; newbios 4: Vektor auf neue rwabs-Routine


relocator:
        lea     buffer(pc),a0
        move.l  d2,a5        ; untere und obere Grenze des
        move.l  d2,a6        ; kopierten ROM-Bereichs
        add.l   #4000,a6
        move    #1999,d1
loop:   cmp     #$4eb9,(a0)+    ; jsr ... ?
        beq     relocate
        dbf     d1,loop

cont:   lea     buffer(pc),a0
        lea     go2track(pc),a1
        bsr     search
        cmp.b   #$14,61(a0)          ; FDC-Befehl 'Seek mit Verify'?
        bne     error2
        move.b  #$10,61(a0)          ; um„ndern zu 'Seek ohne Verify'!
        move.l  hdv_rw,oldbios4      ; alte rwabs-Routine retten
        move.l  #switch_rw,hdv_rw    ; Scheduler installieren
        move.l  d6,-(sp)
        move    #$20,-(sp)
        trap    #1
        addq.l  #6,sp                ; User-Modus
       
        clr     -(sp)
        move.l  d7,-(sp)
        move    #$31,-(sp)
        trap    #1                   ; Keep process

; Speeder+ ist jetzt als residentes Programm  installiert.

relocate:
        cmpa.l  (a0),a5        ; Sprung in eine Floppy-Routine?
        bhi     no_floppy_function
        cmpa.l  (a0),a6
        blo     no_floppy_function
        sub.l   d2,(a0)
        add.l   #buffer,(a0)
no_floppy_function:
        addq.l  #4,a0          ; a0 auf n„chsten 68000er-Befehl
        subq.w  #2,d1          ; 2 W”rter berspringen
        cmp     #-1,d1         ; Z„hler noch im korrekten Bereich?
        bgt     loop           ; ja
        bra     cont

search: move    #10000,d4      ; nicht mehr als 10000 Worte lang suchen
check:  move    (a0)+,d0       ; pažt 1. Wort?
        cmp     (a1),d0
        dbeq    d4,check
        cmp     #-1,d4
        beq     error
        move    #-2,d3
check_on:
        add     #2,d3
        cmp     #10,d3
        beq     string_found
        move    (a0,d3.w),d0
        cmp     2(a1,d3.w),d0  ; 5 weitere Worte berprfen!
        beq     check_on
        dbf     d4,check
string_found:
        subq.l  #2,a0          ; a0: Addresse der gesuchten Routine
        rts

error:  addq.l  #4,sp          ; sp reparieren
error2: move.l  #fehlermeldung,-(sp)
        move    #9,-(sp)
        trap    #1
        addq.l  #6,sp
        move    #7,-(sp)
        trap    #1
        addq.l  #2,sp
        move.l  d6,-(sp)       ; auf Tastendruck warten
        move    #$20,-(sp)
        trap    #1
        addq.l  #6,sp
        clr     -(sp)
        trap    #1             ; Term


;************************************************************************

switch_rw:
        cmpi    #2,14(a7)       ; Ramdisk oder Festplatte angesprochen?
        bhs     old             ; dann alte Routine
        move.l  newbios4,a0
        jmp     (a0)            ; a0 darf verwendet werden
old:
        move.l  oldbios4,a0
        jmp     (a0)



 END
 