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():
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