Skip to content

Latest commit

 

History

History
299 lines (252 loc) · 17 KB

diskette_elende.md

File metadata and controls

299 lines (252 loc) · 17 KB
                    D I S K E T T E   E L L E N D E 
                                                     
      
      Iedere MSX'er heeft dit waarschijnlijk al  eens  meegemaakt;
      een disk die na het saven van een file  'kapot'  is  doordat
      tijdens  de  save  aktie  van  diskette  gewisseld  is.  Dit
      probleem  is  al  heel  lang  bekend  (de  oplossingen   ook
      overigens) en ik vertel dan ook weinig nieuws, maar  ik  heb
      nog nooit ergens na kunnen lezen  wat  er  allemaal  precies
      fout gaat.
      
      Ik wil me hier vooral op MSXDOS-1  richten  omdat  dit  voor
      diskettes  de  grote  boosdoener  is.  Diskettes  kunnen  in
      tegenstelling tot hun grotere broers, de harddisks  uit  hun
      gleuf geknikkerd worden. Dat is op zich  heel  handig,  maar
      het probleem is dat de BDOS hier praktisch niet  achter  kan
      komen.  De  BDOS  is  namelijk  blind  voor  onaangekondigde
      diskwisselingen. Snapt u nu waarom een Apple Macintosh  geen
      eject knop heeft?  Het enige wat de BDOS kan zien is dat  er
      tijdens een diskaktie geen disk in de drive zit, waarna deze
      kan vragen om het ding weer terug te plaatsen.  Het  woordje
      'deze' in de vorige zin  is  in  dit  verhaal  van  cruciaal
      belang. De BDOS gaat er  nl.  vanuit  dat  tijdens  kritieke
      akties altijd de fysiek gelijke diskette in de drive zit.
      
      Theoretisch is het mogelijk dat de  BDOS  ook  daadwerkelijk
      controleert of dit het geval is, maar dat zou een  diskaktie
      zo traag maken dat iedereen nog  vrolijk  met  cassettetapes
      zou werken omdat die sneller zouden zijn. De BDOS  eist  dus
      een bepaalde discipline van de gebruiker om tijdens kritieke
      diskakties NOOIT van diskette te wisselen. Ik ben echter van
      nature een onderzoeker (lees: eigenwijs) en heb eens gekeken
      naar wat er nu precies mis kan gaan.
      
      
              H E T   L E Z E N   V A N   E E N   F I L E 
      
      Het inlezen van een file begint met het  openen  ervan.  Bij
      DOS1 worden nu de 3  FAT sektoren en de directorysektor waar
      de te laden file in genoemd is in het  geheugen  geladen  en
      die blijven daar ook. Vervolgens kan de file gelezen  worden
      waarbij in het geheugen  1  sektor  met  laadgegevens  wordt
      bijgehouden. Dit wordt gedaan om bv. 4 bytes uit de file  te
      kunnen lezen. Eerst wordt de sektor ingeladen en  vervolgens
      worden de 4 bytes naar het DMA gekopieerd.
      
      Tijdens het inladen kan de gebruiker tot de ontdekking komen
      dat dit een oude versie van de file is waarna hij de disk in
      een reflex uit de drive neemt. Indien hij deze na  protesten
      van de BDOS terug stopt, dan is er niets aan de hand.  Stopt
      hij echter een andere disk terug in de drive met de nieuwere
      versie van de file, dan gaat het fout. Alle informatie  over
      waar de file precies op de disk te vinden is staat nl. al in
      het geheugen (FAT + dir.sektor) en op deze nieuwe  disk  kan
      deze file wel op een heel andere positie staan. In dit geval
      gaat het lezen dus  wel  door,  maar  wordt  alleen  rotzooi
      gelezen.
      
      Geconcludeerd mag worden  dat  het  wisselen  van  diskettes
      tijdens een laadaktie resulteert in een fout ingelezen file,
      maar dat de diskettes zelf heel blijven. Hoe anders  is  dit
      bij een schrijfaktie.
      
      
          H E T   S C H R I J V E N   V A N   E E N   F I L E 
      
      Tijdens het cre�ren van een file zoekt de BDOS de  directory
      sektoren af naar een lege positie voor de nieuwe file. Zodra
      een  plaats  gevonden  is  wordt  o.a.  de  filenaam  alvast
      ingevuld. De sektor waar de directory entry in terecht  komt
      blijft in het geheugen staan. Nu wordt in de  FAT  naar  een
      geschikte startpositie voor de file gezocht.  De  FAT  wordt
      overigens ook in het geheugen gelezen.
      
      Laten we zeggen dat de file 1kB lang is en dat de eerste 128
      bytes nu weggeschreven worden waarbij niets  fout  gaat.  Nu
      haalt een onverlaat echter de disk uit de  drive  waarna  de
      volgende 128 bytes geschreven worden. Wat zal er volgens jou
      gebeuren tijdens deze tweede schrijfaktie?  Een disk-offline
      melding misschien?
      
      FOUT!!  De schrijfaktie gaat wonder boven wonder  goed.  Dat
      komt  omdat  ook  tijdens  een  schrijfaktie ��n sektor  met
      informatie in het geheugen wordt bijgehouden  en  omdat  een
      sektor 512 bytes groot is, wordt deze buffer nog  niet  naar
      disk geflushed.
      
      Nu wordt het resterende deel van  de  1kB  file  in  1  keer
      weggeschreven en komt  de  diskdrive  dus  wel  degelijk  in
      aktie. Hier doen zich drie potenti�le foutsituaties voor, te
      weten:
      - Disk offline
      - Disk full
      - Physical I/O error (kras op de magnetische laag etc.)
      
      In een eerder artikel op Sunrise Magazine Special #4 heb  ik
      al eens geprobeerd uit te leggen hoe de error  handling  van
      de BDOS werkt (met die dubbele pointer constructie etc.) Bij
      een disk offline wordt nu naar een eventueel  ge�nstalleerde
      error handler gesprongen. Zo ook bij een fysieke I/O  error.
      Bij een disk  full  wordt  echter  alleen  register  A  =  1
      (MSXDOS-1 call) gemaakt en wordt naar de aanroepende routine
      terug gesprongen.
      
      De vraag op dit punt is, wat moet je nu doen?  Indien er een
      disk offline is geweest die nu is opgelost, maar de  persoon
      een andere disk in de drive heeft gestopt, dan  is  de  kans
      99.99% dat deze nieuwe  disk  bij  de  minste  of  geringste
      volgende diskaktie onherstelbaar  beschadigd  raakt  doordat
      zowel de FAT als de directory sektor van de andere  disk  op
      de huidige geschreven worden.
      
      Even terug naar de vraag: "wat nu te doen ?". Indien de file
      wordt gesloten, dan wordt  de  in  het  geheugen  opgeslagen
      directorysektor teruggeschreven naar de disk. Dit wordt  ook
      met de FAT sektoren gedaan. De nieuwe  disk  wordt  dus  met
      voor  hem  onzinnige  informatie  gevuld,  maar  indien   de
      originele disk is  teruggestopt  dan  gaat  het  (uiteraard)
      goed.
      
      Indien de hele schrijfaktie domweg afgebroken wordt, dan zal
      de nieuwe disk niet vernield worden, of wel ?? Het  antwoord
      daarop is dat deze disk in eerste instantie  inderdaad  heel
      blijft. Tijdens mijn testjes heb ik in die situatie eens  de
      directory opgevraagd en zag tot  mijn  stomme  verbazing  de
      directory van de schijf die ik net  gewisseld  had  op  mijn
      beeldscherm verschijnen. (Opm: De totale directory  van  die
      schijf pastte in 1 sektor) De BDOS had kennelijk  niet  door
      dat er een andere disk in de  drive  was  gestoken.  Of  dit
      onder DOS-2 ook het geval is weet ik overigens niet, maar ik
      kan me voorstellen dat het hier wel goed gaat omdat hier met
      Volume-IDs gewerkt wordt.
      
      Waarom kijkt de BDOS in deze situatie niet naar de  disk  om
      te kijken of deze misschien gewisseld is?  Anders  doet  hij
      het immers altijd (het zou  niet  best  zijn  als  dat  niet
      gebeurde). Het enige wat de oorzaak  van  dit  probleem  kan
      zijn is het feit dat de file waarop de schijfaktie fout ging
      nooit gesloten is. De BDOS neemt immers aan dat een diskette
      alleen tussen het lezen  en  schrijven  van  komplete  files
      gewisseld wordt. Het domweg  afbreken  van  de  schrijfaktie
      omdat er iets fout ging is dus NOOIT goed.
      
      Iets anders is BDOS call 13; de  drive  reset.  Indien  deze
      call wordt uitgevoerd voordat een gecre�erd bestand gesloten
      is, dan gaat het toch fout doordat o.a. de FAT sektoren weer
      worden teruggeschreven. In deze situatie dus niet gebruiken.
      
      
                           D E   M O R A A L 
      
      De moraal van dit verhaal is dat indien je een file cre�ert,
      je deze ook moet sluiten. Doe je het niet, dan verschuif  je
      de ramp alleen maar in tijd naar voren, maar hij zal komen !
      Dat  hierdoor  diskjes  vernield  kunnen  raken  doodat   ze
      tussentijds gewisseld worden is jammer, maar doe je het niet
      dan biedt alleen het uitzetten van de computer een  garantie
      dat de disk bij de volgende diskaktie in  orde  blijft.  Het
      zal hem wel aan mij liggen, maar de  melding  "Please  reset
      your MSX before continuing"  lijkt me alleen in  Metal  Gear
      grappig, maar niet in een tekstverwerker.
      
      Wat dient er nu te gebeuren  indien  een  disk  schrijfaktie
      afgebroken  wordt  door  de  gebruiker  (disk  offline   met
      (A)bort) of de BDOS (disk vol)?  Welnu, als eerste  moet  de
      file gesloten worden. Daarna moet de  gemaakte  rotzooi  nog
      opgeruimd worden, door de aangemaakte file te  deleten.  Als
      dat gebeurt is, is er niets aan de hand en kan  de  komplete
      aktie later nog eens herhaald worden op een  disk  die  meer
      kans van slagen biedt.
      
      
           P R O G R A M M E U R S   E N   D I S K E T T E S 
      
      Gebruikers moeten weten dat ze tussen het  cre�ren  van  een
      file en het sluiten ervan met hun tengels van  de  diskdrive
      af moeten blijven. Programmeurs moeten er met wat praktische
      programmeer psychologie voor zorgen dat mensen  niet  in  de
      verleiding komen om het  toch  te  doen.  Tevens  moeten  ze
      aangeven wanneer het laad/save proces begint en eindigd.
      
      Neem  als  voorbeeld  MoonBlaster.  Het  filemenu  van   dit
      meesterwerk laat weinig te wensen over. Het  is  voor  zowel
      eencellige  wezens,  Stefan  Boer  en  mensen  overduidelijk
      wanneer de computer bezig is met laden of saven. Het  lampje
      van de diskdrive knippert nl. uiterst vrolijk  tijdens  zo'n
      aktie waarbij  (samples  buiten  beschouwing  gelaten)  geen
      verwarrende   pauzes   voorkomen.   Dat   laatste   voorkomt
      vroegtijdige eject neigingen.
      
      Een puntje van kritiek is  wel  dat  MoonBlaster  'mislukte'
      files niet delete bij bv. een disk full error.
      
      Abort en Retry opties tijdens een schrijfaktie mogen dus ook
      wel. Het schrijfproces mag immers zonder het sluiten van  de
      file toch niet afgebroken worden en dus mag je de  gebruiker
      best de kans geven om  de  fout  te  herstellen.  Dergelijke
      opties zijn echter geen must. Een retry omdat iemand de disk
      uit de drive haalt en  deze  daarna  weer  terug  stopt  zou
      eigenlijk met een hatelijke "Blijf daar van af met je fikke"
      sample beantwoord moeten worden en  niet  met  het  redelijk
      beschaafde "Eh sorry, zal ik het nog eens proberen?".
      
      
                  T E C H N I S C H E   D E T A I L S 
      
      Even resumerend:
      - Bij het laden van een file mag je van de gebruiker
        verwachten dat hij van de eject knop af blijft. Doet hij
        het toch, dan kan het geheugen corrupt raken, maar de disk
        blijft tenminste heel.
      - Bij het saven waarbij fouten optreden moet je niet gewoon
        doen alsof je neus bloed, maar moet je netjes de rotzooi
        opruimen. Zorg er m.b.v. je programma voor dat de
        gebruiker niet in de verleiding komt om van diskette te
        wisselen, zodat dit zo goed als altijd goed zal gaan.
      
      Het  valt op  dat het  eigenlijk ontzetend  vaak goed  gaat. 
      Blijkbaar komt  men niet  zo snel op het idee om tijdens een 
      schijfaktie  van disk te wisselen. Dit is dus blijkbaar niet 
      zo'n probleem. Er is echter een situatie denkbaar waarbij in 
      verhouding veel  meer diskettes  vernield raken. Stefan Boer 
      heeft deze situatie op Sunrise Special #1 ook al beschreven. 
      De  situatie  treedt  op wanneer  het cre�ren  van een  file 
      mislukt  door een  'write protected'  diskette. De gebruiker 
      stopt nu  een nieuwe  disk in  de drive en drukt op (r)etry. 
      Deze  nieuwe disk  wordt nu vernield indien de error handler 
      verkeerd  geschreven  is.  Hier  is  een  (r)etry  dus  niet 
      ongevaarlijk!
      
      
                  ! ! !   B E L A N G R I J K   ! ! ! 
                                                       
      
      Een vroeger (ook door mij) sterk  gepropageerde  methode  om
      een retry uit te voeren in de BDOS error  handler  was  door
      register C=1 te maken, gevolgd door een RET instruktie.  Dit
      systeem werkt vaak goed, maar  in  de  hierboven  beschreven
      situatie gaat het hopeloos fout. Het geval wil  nl.  dat  de
      FAT en directory sektor van de  originele  disk  al  in  het
      geheugen staan op het moment dat een "write protected" error
      optreed. Na een (R)etry wordt echter niet meer gekeken of de
      diskette gewisseld is. Tijdens het  schrijven  van  de  file
      worden  dus  met  hoge   waarschijnlijkheid   andere   files
      overschreven  en  na  het  sluiten  van  de  file  staat  er
      plotseling een verkeerde  FAT  en  directory  sektor  op  de
      nieuwe disk.
      
      Samengevat: DOE NIET LD C,1 gevolgd door RET  om  een  retry
      optie te implementeren, maar doe het zoals  de  abort  optie
      werkt!!!!  Herstel de stack en belangrijke  registers  zoals
      ze voor de aanroep naar de BDOS waren en JP  terug  naar  de
      BDOS. Nu worden nl. eerst weer de FAT en  directory  van  de
      potentieel onbekende disk ingelezen. Ik heb  dit  geprobeerd
      en het klopt als een bus.
      
      
                          C O N C L U S I E S 
      
      Deze hele discussie over wat er nu precies moet gebeuren  om
      disk crashes  te  voorkomen  loopt  al  een  tijdje.  Binnen
      Sunrise leeft bij monde van Stefan Boer al geruime  tijd  de
      overtuiging om diskakties bij foutsituaties zo snel mogelijk
      af te breken (waarbij ik niet weet of hij adviseert ze eerst
      te sluiten, maar dat zal wel), maar dat lijkt me dus  alleen
      maar gevaarlijker dan een keurige afhandeling.
      
      Kortom, neem aan dat de gebruiker niet gek is en handel  een
      schrijffout beschaafd af (sluiten en deleten).  Zorg  echter
      wel  voor  een  beetje  transparantie   van   akties   zodat
      gebruikers niet in het ongewisse zijn over het feit  wanneer
      de diskaktie echt klaar is (lees: wanneer de  file  gesloten
      is). Een tekstje "saving file..." op een statusbalk  is  bv.
      een hele goeie. Verder MOET je er dus  voor  zorgen  dat  de
      retry optie in de error handler goed ge�mplementeerd is.
      
      Op Sunrise  Special #4  staat ook  een listing van mijn hand 
      over  diskerror  afvanging  onder  DOS1  (en  dus  ook  DOS2 
      alhoewel  deze eigen en betere routines heeft). Deze listing 
      werkt wel  aardig en  is leuk voor demo's en zo, maar het is 
      wat  beperkt en  de LD C,1 ; RET bug in de error handler zit 
      er  ook  in.  Ik  heb (met  behulp van  dit onderzoekje)  de 
      routines nog  eens dunnetjes  over gedaan, waarbij vooral de 
      veiligheid  van disk  I/O prioriteit heeft gekregen. Affijn, 
      ik ben  van mening  dat deze nieuwe routines heel veel beter 
      en  veiliger zijn  dan de  vorige en raad het gebruik van de 
      oude af.  Lees echter  ook de  tekst op  de volgende submenu 
      optie  die  wat  uitgebreidere  uitleg  over  de  listing en 
      routines geeft.
      
      Ik  vind het  redelijk om van gebruikers het besef te vragen 
      dat ze  zolang het  disklampje brandt  niet aan de ejectknop 
      moeten  komen. Je  kunt immers  ook aan mensen vragen om bij 
      een rood  verkeerslicht te  wachten. Diegenen  die dat  niet 
      doen  lopen dan het risiko om 5 liter rood lichaamsvocht aan 
      het  ZOAB   asfalt  kwijt  te  raken,  maar  dat  wisten  ze 
      vantevoren.
      
                                                 Alex van der Wal