← ST-Computer 03 / 1990

Fast-Dfree (Assembler)

Programmierpraxis

Jeder kennt bei Harddisks das Problem, den freien Speicherplatz zv ermitteln. Das GEMDOS stellt zwar eine Funktion dafĂŒr zur VerfĂŒgung, aber bei einer SH205 mit 4 Partitionen dauert das fĂŒr alle zusammen schon mal 20 Sekunden. Mit diesem kleinen Programm im AUTO-Ordner, das im Speicher nicht mal 500 Bytes belegt, ist die Dfree-Funktion des GEMDOS 14 (!!!)mal schneller als vorher, D.H. die gesamten freien Cluster der Harddisk hat man in ca. 1,4 Sekunden!

Diese kleine Routine ersetzt die Dfree-Funktion des GEMDOS vollstÀndig. Nur bei Disketten (12-Bit-FAT) wird die (dort hinreichend schnelle) Originalroutine genutzt. Man kann die Routine auch sehr schön in eine Command-Shell implementieren, welche (wenn an IBM angelehnt) bei jedem DIR die freie KapazitÀt der DatentrÀgers ausgibt. Auch selbstprogrammierte File-Selektoren mit Laufwerksinfo profitieren von dieser Routine.

Besonderer Dank gilt an dieser Stelle Thomas Quester, der mich erst auf die Idee gebracht hat, eine solche Routine zu schreiben.

Das Programm ist zwar dokumentiert, aber hier noch einmal eine grobe Beschreibung der Vorgehensweise von Fast-Dfree():

  1. Bios-Parameter-Block des entsprechenden Laufwerks anfordern
  2. bei 12-Bit-FAT in die Originalroutine ->
  3. sonst die Gesamt-Cluster-Anzahl merken sowie den Startsektor der 2.FAT
  4. 2 Sektoren der FAT einlesen (der Buffer ist gerade 1k groß).
  5. Beim ersten Aufruf werden die ersten 3 Cluster nicht mitgezÀhlt, da Sie vom GEMDOS aus nur intern verwandt werden.
  6. Alle Words, welche gleich 0 sind, werden gezÀhlt (16-Bit-FAT!).
  7. Dabei wird die Gesamt-Cluster-Anzahl heruntergezÀhlt,
  8. wenn 512 Cluster gezÀhlt wurden und die Gesamt-Cluster-Anzahl>0 ist, nach 4
  9. Das war’s.

Da das Programm mit dem OMIKRON.Assembler (Version 1.52) erstellt wurde, ist es gut möglich, daß andere Assembler z.B. den Pseudo-Opcode OUTPUT nicht kennen. Diesen kann man einfach weglassen. Ebenso ist mit der Adressierungsart Absolut-Short zu verfahren, welche beim OMIKRON.Assembler durch ein .w hinter dem Operator erzwungen werden kann.

;================================================ ;= Fast-Dfree() - beschleunigt die Dfree- = ;= Funktion des Gemdos bei 16-Bit-FATS = ;= bei einer SH205 um Faktor 14 !!! = ;= Auf dem Desktop wird das Info 3mal schneller = ;= Die neue Dfree-Funktion wird ins GEMDOS = ;= eingesetzt und ersetzt bei = ;= 16-Bit-FATS (Harddisk, Ramdisk, etc.) die = ;= originale Dfree-Routine vollstĂ€ndig! = ;= = ;= Nach einer Idee von Thomas Quester (Danke) = ;= = ;= Enwtwickelt von Markus Fritze = ;= (c) MAXON Computer GmbH 1990 = ;================================================ OUTPUT 'DFREE' ;bei andernen Assemblern evtl.weglassen anfang: bra init ;================================================ ;= Der neue Gemdos-Vektor = ;================================================ DC.B 'XBRA' ;XBRA-Standard f.vektorverbgnde Programme DC.B 'XDFR' ;Kennung von X-soft, Unterkennung: DFREE old_vektor: DS.L 1 new_gemdos: move USP,A0 btst #5,(SP) ;Aufruf aus dem User-Mode? beq.s new_gemdos1 ;Ja! movea.l SP,A0 addq.l #6, A0 new_gemdos1: cmpi.w #$36,(A0) ;Dfree() beq.s dfree ;eigene Routine testen new_gemdos_exit:movea.l old_vektor(PC),A0 jmp (A0) ;Originale GEMDOS-Routine ;================================================ ;= Bei einer 12-Bit-FAT (Disketten) ist die = ;= interne Routine schnell genug. = ;= Deswegen haben ich mir die Arbeit gespart. = ;================================================ dfree_12bit_fat:movem.l (SP)+,D1-A6 bra.s new_gemdos_exit ;Originalroutine aufrufen ;================================================ ;= Die neue Dfree()-Funktion fĂŒr 16-Bit-FATs = ;= Es werden einfach alle Null-Words in der = ;= 2.FAT gezĂ€hlt, das ist alles. = ;= Zu beachten ist lediglich, daP die ersten 3 = ;= Words nicht mitgezĂ€hlt werden! = ;================================================ dfree: movem.l D1-A6,-(SP) movea.l 2(A0),A4 ;Bufferadr lea 12(A4),A4 ;fĂŒr Predecrement (s.u.) move.w 6(A0),D7 ;Drive subq.w #1,D7 bpi.s dfree3 ;aktuelles LW? move.w #$19,-(SP) trap #1 ;Dgetdrv() addq.l #2, SP move.w D0,D7 ;aktuelles LW dfree3: cmp.w #1,D7 ;Disk? ble.s dfree_12bit_fat ;dann GEMDOS-Dfree() ;Wenn obige Abfrage fehlt, wird nach dem Formatieren einer einseitigen Disk ;von eine 16-Bit-FAT ausgegangen (fehlendes Media-Change) move.w D7,-(SP) ;drive move.w #7,-(SP) trap #13 ;Getbpb (drive) addq.l #4,SP tst.l D0 bmi.s dfree_error ;GerĂ€t nicht da, Fehler movea.l D0,A6 ;Adresse merken btst #0,17(A6) ;Flagsb testen nach 16 oder 12-Bit-FAT beq.s dfree_12bit_fat ;12-Bit-FAT =>Original ist schnell genug move.w 10(A6),D6 ;fatrec - Startsektor der 2.FAT moveq #0,D5 move.w 2(A6),D5 move.l D5,(A4) ;Sektoren pro Cluster einsetzen move.w (A6),D5 move.l D5,-(A4) ;Bytes pro Sektor einsetzen move.w 14(A6),D5 ;numcl - Gesamtanzahl der Cluster merken move.l D5,-(A4) ;und einsetzen moveq #0,D4 ;Anzahl der freien Cluster=0 moveq #0,D3 ;Flag fĂŒr den Startsektor der FAT löschen dfree0: movea.l $04C6.w,A5 ;Bufferadresse holen (__dskbuf) move.w D7,-(SP) ;Drive move.w D6,-(SP) ;fatrec move.w #2,-(SP) ;2 Sektoren einlesen move.l A5,-(SP) ;Buffer fĂŒr die Sektoren clr.w -(SP) ;normales Lesen move.w #4,-(SP) trap #13 ;Rwabs() lea 14(SP),SP tst.l D0 bmi.s dfree_error ;Lesefehler, Fehlermeldung zurĂŒckgeben addq.w #2,D6 ;fatrec+2 move.w #$01FF,D0 ;512 Cluster pro 2 Sektoren der FAT tas.b D3 ;1.Sektor mit den ersten drei Clustern? bne.s dfree1 ;Nein! => addq.l #6,A5 ;die ersten der Cluster werden subq.w #3,D0 ;nicht mitgezĂ€hlt! subq.w #3,D5 ;3 Cluster bereits abziehen dfree1: tst.w (A5)+ ;freien CLuster gefunden? bne.s dfree2 ;Nein! => addq.w #1,D4 ;einen freien Cluster gefunden dfree2: subq.w #1,D5 ;numcl-1 dbeq D0,dfree1 bne.s dfree0 ;Ende noch nicht erreicht, weiter geht's move.l D4,-(A4) ;Anzahl der freien Cluster einsetzen moveq #0,D0 ;alles ok, kein Fehler dfree_error: movem.l (SP)+,D1-A6 rte ;Das war’s schon init: pea new_gemdos(PC) move.l #$050021,-(SP) trap #13 ;Setexc (33,new_gemdos) addq.l #8, SP move.l D0,old_vektor ;Original-Vektor merken pea init_text(PC) move.w #9,-(SP) trap #1 ;eine Meldung am Anfang addq.l #6,SP clr.w -(SP) ;Kein Fehler aufgetreten pea init-anfang+$0100.w ;residentes Programm <500 Byte move.w #$31,-(SP) trap #1 ;Ptermres() DATA init_text: DC.B 'Fast-Dfree', 13,10 DC.B '(c) 1990 MAXON Computer GmbH, von Markus Fritze',13,10,0 END
Markus Fritze