
     Speed Disk

     Dit programma moet de disk access time verkleinen door de gewenste 
     gegevens in zo'n volgorde in de sectoren weg te schrijven dat ze snel 
     toegankelijk zijn. Mogelijkheden hiervoor zijn:

     - Alle systeem bestanden (veel attributen) vooraan.
     - Alle directory sectoren in de eerste sectoren van de disk schrijven.
     - Bestanden achter elkaar in de sectoren schrijven, zodat de diskdrive 
     head(s) niet veel over de disk hoeven te verplaatsen.
     - Veel gebruikte bestanden vooraan zetten. Bijvoorbeeld eerst .COM 
     files etc. Dit moet door de gebruiker kunnen worden opgegeven.

     Om dit te kunnen bereiken wordt de disk vanuit het oogpunt van de 
     clusters bekeken. Vanuit de directory registraties is aangegeven in 
     welke cluster een bestand of andere sub-directory begint.

     Het programma kijkt in alle gevallen of verplaatsen noodzakelijk is, 
     anders wordt er niet veranderd.

     Bij het verplaatsen van gegevens moet er crash-vrij gewerkt worden. Het 
     programma leest de gegevens die nu op de plaatst staan waar de nieuwe 
     gegevens moeten komen. Deze gegevens worden eerst op een vrije plaats 
     op disk weggeschreven. Daarna wordt de FAT aangepast, zodat 
     geregistreerd is waar de data staat, daarna wordt de directory 
     aangepast zodat ook van daaruit bekend is waar de data nu staat. Daarna 
     wordt weer de FAT aangepast, zodat het oude blok weer vrij is. Daarna 
     wordt er pas nieuwe data opgehaald en op eenzelfde als hierboven 
     beschreven methode op de nieuwe plaats op de disk geschreven.

     Bij het inlezen van de gegevens wordt er van al het beschikbare 
     geheugen gebruik gemaakt. Hiervoor wordt MemMan ondersteund, maar 
     zonder MemMan werkt het programma ook goed. Bij het verplaatsen van 
     gegevens zijn er dus twee limieten voor wat betreft de hoeveelheid data 
     die in een keer wordt verplaatst.

     Ten eerste kan er nooit meer worden verplaatst dan er in het geheugen 
     past. Dit is niet echt een limiet omdat er in meerdere keren gegevens 
     verplaatst kunnen worden.

     Verder is het aantal nog vrije clusters op disk een belangrijk gegeven. 
     Het is tenslotte niet mogelijk meer ruimte vrij te maken om een nieuw 
     stuk data in te schrijven dan er (tijdelijk) in de vrije clusters 
     geschreven kan worden.

     De verwijderde bestanden hebben nog het eerste cluster nummer. Onder 
     MSX-DOS 2 staat in de kopie van de FAT de clusters chain van dat 
     bestand. De kopie van de FAT moet dus overschreven worden met zijn 
     origineel en alle directory entries van deleted files kunnen verwijderd 
     worden.

     De eerste stap van Speed Disk zal zijn het sorteren van de directories. 
     Paul te Bokkel heeft al een programma waaraan een mooi voorbeeld 
     ontleend kan worden. Deze kan sorteren op attributen en gedeelten van 
     bestandsnamen. Op deze manier kunnen met een eerste run alle bestanden 
     met de attributen S en H vooraan worden gezet (systeem bestanden als 
     MSXDOS2.SYS en COMMAND2.COM etc), daarna kan weer met een attribuut 
     filter alle directory sectoren vooraan gezet worden en daarachter met 
     eventueel de .COM files eerst de bestanden.

     Voordat een directory gesorteerd wordt moeten alle deleted entries 
     eruit gewipt worden. Bestanden van 0 bytes moeten blijven bestaan.

     Nadat alle directories zijn gesorteerd op de gewenste volgorde moeten 
     de bestanden verplaatst worden zodat alle clusters achter elkaar op 
     disk staan. Hiervoor zijn meerdere fasen nodig. Ten eerste moeten alle 
     directories doorlopen worden, beginnend bij de root. De root staat al 
     vooraan. In de root staan subdirectory registraties. Deze worden 
     allemaal achter de root geplakt. Daarna wordt de eerste sub-dir in 
     gegaan en weer hetzelfde geintje uitgehaald. Dit gaat door tot alle 
     sub-directories geweest zijn.

     Daarna moeten de bestanden erachter. Nu moeten de sub-directories bij 
     een eerste run door de directory overgeslagen worden totdat alle 
     bestanden geweest zijn. Daarna worden de sub-directories een voor een 
     op dezelfde manier afgelopen totdat ook deze allemaal weer geweest 
     zijn.

     Daarna staat alles in de gewenste volgorde. De kopie van de FAT moet 
     overschreven zijn met de inhoud van de originele FAT, dit om het 
     UNDELeten van MSX-DOS2 te voorkomen.

     Van alle directory entries die op disk aanwezig zijn moet een tabel 
     bijgehouden worden waarin het eerste clusternummer van de bestanden uit 
     die directory staan. Op die manier kan snel worden teruggezocht bij 
     welke directory een eerste cluster hoort en kan deze directory entry 
     snel worden aangepast. Struktuur van de tabel:

     - (2) aantal opgeslagen directory clusters = m
     - m keer:
       - (2) cluster nummer van de volgende groep directory entries
       - (1) aantal directory entries dat volgt (maximaal 256) = n
       - n keer:
         - (2) eerste clusternummer van een entry

     Bij het verplaatsen van gegevens op de disk moeten een aantal stappen 
     doorlopen worden om ervoor te zorgen dat tijdens een computer-crash te 
     alle tijden geen gegevens verloren kunnen gaan.

     1 - Bereken uit de hoeveelheid vrij geheugen het aantal clusters dat in 
     een keer opgeslagen kan worden. Als het maximum aantal clusters meer is 
     dan er vrij zijn op disk moet dit laatste aantal genomen worden.

     2 - Een pointer naar een van de directory entries in een van de 
     sectoren geeft aan wat er nu verplaatst moet worden. Het te 
     verplaatsen cluster nummer moet bepaald worden. Als het nummer al op de 
     juiste plaats staat, dan moet er niets aan veranderd worden. Anders 
     moet er ruimte gemaakt worden.

     3 - Lees vanaf de eerste te verplaatsen cluster een blok clusters in 
     dat in het geheugen past. Alleen de clusters die niet in gebruik zijn 
     moeten worden ingelezen. In het beste geval zijn alle clusters vrij. 
     Merk op dat er niet meer clusters ingelezen kunnen worden als daar 
     geheugen voor is, omdat er niet meer vrije clusters zijn om ze weer in 
     op te slaan.

     4 - Ga achter het vrij te maken blok clusters op zoek naar vrije 
     clusters en schrijf daar de zojuist ingelezen clusters weer in weg. In 
     de FAT moeten de overschreven clusters nog vrijblijven. In een tabel 
     moet bijgehouden worden welke clusters waar naartoe verplaatst zijn, 
     dat scheelt straks bij het verleggen van strukturen.

     5 - Nu moeten de FAT en directory entries aangepast worden. De inhoud 
     van het oude cluster moet worden overgenomen en het oude cluster 
     leeggemaakt.
     Als een omgelegd cluster een voorganger heeft, dan is er niets aan de 
     hand. De verwijzing van de voorganger naar de nieuwe moet worden 
     aangepast.
     Als een cluster echter geen voorganger heeft, dan is het het begin van 
     een cluster-chain en moet er een directory entry worden aangepast. In 
     de tabel met de directory entry registraties kan het oude cluster 
     nummer worden opgezocht, deze moet er altijd zijn als het goed is. De 
     bijbehorende directory cluster waar deze entry in staat moeten worden 
     ingelezen, de entry opgezocht in het cluster en aangepast en alleen de 
     gewijzigde sector hoeft weer naar disk geschreven te worden.
     Merk op dat er ook directory sectoren zijn die al in het geheugen 
     aanwezig zijn. Eventueel moeten deze ook aangepast worden, ze hoeven 
     niet naar disk geschreven te worden. Een doorloop op zoek naar het oude 
     cluster nummer is dus voldoende.

     6 - Schrijf de aangepaste FAT naar disk als originele en backup FAT. 
     Punt 5 en 6 zijn cruciaal. Als in die periode iets gebeurt, dan gaan er 
     een aantal bestanden verloren.

     8 - Nu kunnen de vrijgekomen clusters gevuld worden. De pointer naar de 
     directory entry van punt 2 kan weer worden opgehaald. De clusters 
     waarin het bestand staat kunnen worden ingelezen en op de nieuwe 
     positie weggeschreven. Daarna kan in een keer de FAT aangepast worden 
     en de directory sector naar disk worden geschreven. Als niet het eerste 
     deel maar een ander deel van een bestand verplaatst wordt, dan hoeft de 
     directory sector niet naar disk te worden geschreven.


     Bij het verleggen van een cluster kan heel eenvoudig te werk worden 
     gegaan. Ten eerste kan in de FAT zelf worden gezocht naar een entry die 
     naar het om te leggen cluster wijst. Als deze er is dan hoeft alleen de 
     voorganger maar aangepast te worden en kan de nieuwe cluster op een 
     andere plaats worden weggezet. Als er geen verwijzing naar de te 
     verplaatsen cluster in de FAT gevonden kan worden, dan moet in de 
     directory sectoren gezocht worden naar deze entry. Misschien dat op een 
     eenvoudig manier de set van eerste-clusters bijgehouden kan worden en 
     de directory entry waar deze uit komt, eventueel met cluster nummer. Op 
     die manier kan de bijbehorende directory sector snel teruggevonden 
     worden en de eerst-cluster pointer aangepast worden.
     Deze tabel moet alle entries bevatten, want ook een cluster dat niet 
     bij de bestanden hoort in de directory die bijgewerkt wordt kan worden 
     verplaatst. Dit kan nog wel eens heel wat opslag capaciteit gaan 
     vereissen.

     Het te gebruiken geheugen is natuurlijk al het TPA geheugen, alle 
     segmenten die MemMan vrij geeft (geen overlay geheugen!), al het vram 
     en expanded vram.

     Bij een partitie van 32Mb staan er 32*1024*2 = 65536 sectoren op. In 1 
     directory sector kunnen 16 entries. Iedere file beslaat minimaal 1 
     sector (0 byte files uitgesloten). Voor 16 files zijn dus 17 sectoren 
     nodig. Er kunnen dan dus 65536/17*16 = 61680 files op een disk. Maar: 
     Bij een disk van 32Mb en 12 FAT sectoren zijn er 16 sectoren per 
     cluster nodig. Er gaan dan dus maar 65536/(17*16)*16 = 3855 bestanden 
     op. Bij minder FAT sectoren moeten er meer sectoren per cluster.

     Die pointer tabel voor de directory entries en eerste cluster nummers 
     zal dus nog wel het grootste probleem worden. Hierin moeten minimaal 2 
     bytes voor het cluster nummer en 2 bytes voor het cluster nummer van de 
     sector. 4*61640 is meer dan er in een gemiddelde MSX past... Daar moet 
     dus een of andere vorm van flexibilitiet gestop worden. Als deze tabel 
     achterwege wordt gelaten moeten alle directory sectoren doorlopen 
     worden om het de eerste-cluster te vinden. Dit kan nog wel eens 
     aanzienlijk meer tijd gaan kosten.

     --------- Tweede (dit keer revolutionaire) methode -----------

     Een andere methode dan hierboven beschreven is eerst volledig bepalen 
     hoe de nieuwe FAT eruit moet komen te zien en daarna clusters op disk 
     gaan verplaatsen tot deze nieuwe FAT tot stand is gekomen. Het voordeel 
     hierbij is dat sneller te zien is welke clusters wel of niet verplaatst 
     hoeven te worden.

     Er moeten drie tabellen worden bijgehouden in de vorm van een FAT 
     waarin wordt bijgehouden hoe de oude chains eruit zien, de nieuwe 
     chains eruit zien en welke oude cluster in welke nieuwe cluster 
     verplaatst moet worden. Verder kan van te voren al opgeslagen worden 
     welke directory entries aangepast moeten worden.

     Voor de eerste drie tabellen wordt dus gewoon een FAT gedefinieerd. 
     Deze kan maximaal 4087 clusters bevatten en 12 sectoren groot zijn. 
     12*512 = 6144 bytes. Voor drie FATs zijn er dus 18432 bytes nodig.

     Dan de tabel met aan te passen directory entries. Deze tabel moet voor 
     iedere directory entry het eerste cluster nummer bevatten waarin de 
     bijbehorende file begint. Ook sub-directories moeten hier in staan. Als 
     een cluster omgelegd is moet ook de directory entry aangepast worden. 
     Er moet dus worden bijgehouden in welke cluster de directory entry 
     staat en welke offset in het cluster de entry heeft zodat de entry snel 
     terug gevonden kan worden. Twee extra byte zijn dan voldoende. In de 
     eerste wordt de sector offset in het cluster opgeslagen (0..255), in de 
     tweede de entry offset in de sector *8. Om de offset *16 te krijgen 
     hoeft deze waarde nog maar met 2 vermenigvuldigd te worden. *16 kan 
     niet, want dan past de offset niet in een byte. De tabel zal dus 
     4-bytes groot zijn per entry.
     Iedere entry moet echter ook nog in een cluster zitten. Per cluster 
     wordt er een entry om de tabel heen gemaakt. Dit gaat er dan als volgt 
     uit zien:

     (2) Cluster nummer
     (n) Aantal entries dat volgt
     n keer: (2) Eerste cluster van de file
             (1) Sector offset in het cluster
             (1) Entry offset *8

     Het vullen van de tabellen gaat als volgt: Er zijn twee run's nodig om 
     te bepalen wat directory clusters zijn omdat deze moeten vooraan komen 
     en wat de de clusters van de bestanden zijn, deze moeten daar achter 
     komen.

     De tweede en derde FAT tabel worden leeg gemaakt en de tabel met 
     directory entries wordt leeggemaakt. Daarna wordt vanuit de root alle 
     directory entries doorlopen. Deze worden op de gewenste volgorde 
     gesorteerd en weer naar disk geschreven. Als na het sorteren een 
     cluster overblijft aan het einde van de sub-directory, waarin alleen 
     maar lege of deleted entries staan, dan moet dit cluster worden 
     vrijgegeven.

     Als we in de root zitten, dan worden alle directory entries een voor 
     een afgelopen. Bestanden worden vanaf de eerste vrije positie 
     weggeschreven in de clusters. Als het om een sub-directory ging dan 
     wordt deze in gegaan.

     In de eerste run worden de sub-directories ook gesorteerd en weer naar 
     disk geschreven. Dan worden alleen de clusters van diepere 
     sub-directories naar de vrije clusters geschreven. Daarna wordt de 
     eerste diepere directory in gegaan tot alle diepere sub-directories 
     geweest zijn.

     In de tweede run worden de diepere directory registraties uit de 
     sub-directories overgeslagen en de bestanden in de vrije clusters 
     geschreven. Daarna worden de diepere sub-directories een voor een 
     afgewerkt.

     Alleen in de root kunnen dus bestanden voorkomen die voor de 
     allereerste sub-directory clusters komen te staan. In alle verdere 
     sub-directories worden altijd eerst de sub-directory clusters 
     weggeschreven. Als alles klaar is kunnen er dus eerste een paar 
     clusters zijn met systeem bestanden, daarachter komen alle 
     sub-directory clusters en daarachter komen pas alle bestanden zelf.

     Bij het logisch verplaatsen van clusters gaat het altijd om een heel 
     bestand tegelijk, of het nu een sub-directory of een file is. Er wordt 
     in de vierde tabel een directory entry registratie gemaakt met het oude 
     eerste cluster nummer. Daarna wordt per cluster in de derde tabel het 
     eerstvolgende vrije cluster genomen, gelinkt aan zijn voorganger als 
     die er is en eventueel als laatste cluster betiteld. In de tweede tabel 
     wordt de verwijzing van de derde naar de eerste tabel bijgehouden zodat 
     straks zo kan worden uitgelezen welk cluster er opgehaald moet worden 
     om in de derde tabel te plaatsten.

< hieronder nog aanpassen >
     Als alle tabellen zijn aangemaakt begint het fysieke verplaatsen van de 
     clusters. In de tweede tabel wordt van de eerste tot en met de laatste 
     cluster alles doorlopen. Als het cluster vrij is moet het worden 
     overgeslagen.

     Er moet in de eerste FAT worden gecontroleerd of dit cluster vrij is. 
     Als dat niet zo is, dan moet het cluster dat er nu staat worden 
     verplaatst naar een vrij cluster. Het cluster wordt hiervoor ingelezen 
     en op de nieuwe positie weggeschreven. Daarna wordt de verwijzing van 
     zijn voorganger in de eerste FAT aangepast en eventueel wordt een 
     directory entry aangepast.

     Als het eventueel in de weg staand cluster verplaatst is kan te 
     verplaatsen cluster worden ingelezen en op de nieuwe positie 
     weggeschreven. In de eerste tabel wordt de wijziging genoteerd. Daarna 
     wordt de verwijzing van zijn voorganger in de eerste FAT aangepast en 
     eventueel wordt een directory entry aangepast.

     Nadat een cluster verplaatst is moet de FAT en de eventueel gewijzigde 
     directory entry ook naar disk worden geschreven. Voor de directory 
     entry hoeft niet de hele cluster maar alleen de sector waar de entry in 
     zit naar disk worden geschreven.

     Bij het fysieke verplaatsen van clusters moet er altijd een vrij 
     cluster aanwezig zijn. Als directories gesorteerd worden is het 
     mogelijk dat er een cluster vrij komt. De controle op de aanwezigheid 
     van een vrij cluster moet dus pas daarna gedaan worden.
< tot hier nog aanpassen >
    
     Eerst werden de directory sectoren allemaal in het geheugen bewaard als 
     een sub-directory betreden werd. Een pointer hield bij waar het vrije 
     geheugen gebied zat. Nu is er maar 1 sector buffer waarin een directory 
     sector kan staan. Er wordt bij gehouden in welk cluster er gewerkt 
     wordt, hoeveel sectoren er nog in dit cluster afgewerkt moeten worden 
     en hoeveel entries nog in deze sector. Als er een sub-directory 
     betreden wordt, dan wordt het nummer van de laatste ingelezen sector 
     opgeslagen en de nieuwe sub-directory betreden. Bij terugkeer wordt het 
     laatste gebruikte sectornummer van de onderliggende directory weer 
     opgehaald en de sector weer ingeladen.

     Als een directory gesorteerd moet worden, dan moeten de bestanden en 
     directories in een bepaalde volgorde komen te staan. Als eerst komt het 
     volume label. Daarna volgen de systeem bestanden MSXDOS?.SYS en 
     COMMAND?.COM. Daarachter komen de sub-directory registratie en als 
     laatste komen de gewone bestanden. Eventueel kunnen daarbij ook eerst 
     weer de .BAT of .COM files worden gezet en daarna pas de rest.

