home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / m / msh_ut11.zip / FORMUNIT.PAS < prev    next >
Pascal/Delphi Source File  |  1992-05-10  |  9KB  |  291 lines

  1. unit Formunit;   {Formatierroutinen für Standardformate}
  2. { This unit is from the german magazine c't #2/90 }
  3.  
  4. interface
  5.  
  6. const     {Laufwerkstabellen für Standardformate}
  7.   tab36 : array[1..11] of byte
  8.           = ($df,$02,$25,$02,$09,$2a,$ff,$50,$f6,$0f,$08);
  9.   tab12 : array[1..11] of byte
  10.           = ($df,$02,$25,$02,$0f,$1b,$ff,$54,$f6,$0f,$08);
  11.   tab14 : array[1..11] of byte
  12.           = ($af,$02,$25,$02,$12,$1b,$ff,$6c,$f6,$0f,$08);
  13.   form36 : array[1..4] of byte
  14.                            {Mediabyte, Sektoren pro Cluster}
  15.           = ($fd,2,$70,2);
  16.                {Einträge Hauptverzeichnis, Sektoren pro FAT}
  17.   form72 : array[1..4] of byte
  18.           = ($f9,2,$70,3);
  19.   form12 : array[1..4] of byte
  20.           = ($f9,1,$e0,7);
  21.   form14 : array[1..4] of byte
  22.           = ($f0,1,$e0,9);
  23.   versuche = 5;       {Zahl der Versuche bei Fehlern}
  24.  
  25. type
  26.   tabelle = array[1..4] of byte;
  27.  
  28. var
  29.   laufwerka, laufwerkb : byte;    {Art der Laufwerke}
  30.   tabalt, tabneu       : pointer; {Zeiger auf Laufwerkstabelle}
  31.   formtab              : ^tabelle; {Zeiger auf Diskformate}
  32.   einzelschritt        : boolean;  {Einzelstep}
  33.  
  34. procedure diskreset;                   {Reset bei Fehlern}
  35. function  config(drive : byte) : byte; {Laufwerkskonfiguration}
  36. procedure einzelstep;          {720 KB in 5.25 MF-Laufwerk}
  37. procedure schreibrate(art, kap, drive : byte);
  38.  {Schreibrate wählen}
  39.  {Procedure Schreibrate immer vor Laufwerkstabneu aufrufen !}
  40. procedure laufwerkstabneu;     {neuer DPB}
  41. procedure laufwerkstabalt;
  42. function  readwriteverify(was, spur, seite, sektor,
  43.                           anzahl, drive : byte;
  44.                           var buffer) : byte;
  45. function  spurformat(spur, seite, sektor,
  46.                      anzahl, drive : byte) : byte;
  47.  
  48. implementation
  49.  
  50. uses dos;
  51.  
  52. {************************************************************}
  53. procedure diskreset;
  54. var
  55.   cpu     : registers;
  56.   zaehler : byte;
  57.  
  58. begin
  59.   zaehler:=versuche;
  60.   repeat
  61.     cpu.ah:=0;  {Diskreset}
  62.     cpu.dl:=0;  {Reset für alle Laufwerke}
  63.     intr($13, cpu);
  64.     dec(zaehler,1);
  65.   until (zaehler=0) or (cpu.flags and fcarry=0) or (cpu.ah=0);
  66.   if einzelschritt then einzelstep;  {Wichtig}
  67.   {Nach jedem Reset umschalten auf Einzelstep !}
  68. end;
  69. {************************************************************}
  70. function config(drive : byte) : byte;
  71. var                                   { 0 : Kein Laufwerk}
  72.   cpu     : registers;                { 1 : 360 KB}
  73.   zaehler : byte;                     { 2 : 1.2 MB}
  74.                                       { 3 : 720 KB}
  75.                                       { 4 : 1.44 MB}
  76. begin
  77.   zaehler:=versuche;
  78.   repeat
  79.     cpu.ah:=8;     {Feststellen des Laufwerkstyps}
  80.     cpu.dl:=drive; {Nummer des Laufwerks}
  81.     intr($13, cpu);
  82.     dec(zaehler,1);
  83.   until (zaehler=0) or (cpu.flags and fcarry=0) or (cpu.ah=0);
  84.   if zaehler=0 then
  85.   begin {Funktion nicht vorhanden, dann XT oder ähnlich}
  86.     case drive of
  87.       0: begin
  88.            intr($11, cpu); {Feststellung der Konfiguration}
  89.            config:=(cpu.al and $01) ;      {1 = Drive A da}
  90.          end;{Equipmentword IPL-Bit, überhaupt Diskette da?}
  91.  
  92.       1: begin
  93.            intr($11, cpu); {Feststellung der Konfiguration}
  94.            zaehler:=(cpu.al and $C0) shr 6;
  95.            if zaehler=0 then {kein Laufwerk B}
  96.               config:=0
  97.            else
  98.               config:=1     {Laufwerk B da}
  99.          end; {Equipmentword Drive-Zähler, 00=1 Drive, 01=2}
  100.     else
  101.          config:=0; {alle anderen Anforderungen abweisen}
  102.     end;
  103.   end
  104.   else
  105.     config:=cpu.bl;  {Art des Laufwerks}
  106. end;
  107. {************************************************************}
  108. procedure einzelstep; {720 KB in 5.25 MF-Laufwerk}
  109. var
  110.   inhalt : byte;
  111. begin
  112.   inhalt:=mem[$0040:$0090]; {Controllerbyte}
  113.   inhalt:=inhalt and $DF;
  114.   mem[$0040:$0090]:=inhalt; {Einzelstep für Laufwerk A}
  115.   inhalt:=mem[$0040:$0091];
  116.   inhalt:=inhalt and $DF;
  117.   mem[$0040:$0091]:=inhalt; {Einzelstep für Laufwerk B}
  118. end;
  119. {************************************************************}
  120. procedure schreibrate(art, kap, drive : byte);
  121. var
  122.   cpu           : registers;
  123.   form, zaehler : byte;
  124.   ax            : word;
  125.  
  126. begin
  127.   if art=1 then
  128.   begin
  129.     form:=1;  {360 KB Laufwerk}
  130.     tabneu:=@tab36;   {360 KB Laufwerkstabelle}
  131.     if kap=2 THEN
  132.       formtab:=@form72 {720 KB Diskettenformat}
  133.      ELSE
  134.       formtab:=@form36; {360 KB Diskettenformat}
  135.     cpu.ax:=$1828; cpu.cx:=$2709;  {Parameter für 18h}
  136.   end
  137.   else
  138.   if art=2 then        {1.2 MB MF-Laufwerk}
  139.     if kap<=2 then
  140.     begin
  141.       form:=2;
  142.       tabneu:=@tab36;  {360 KB oder 720 KB in 5,25 MF-Drive}
  143.       cpu.ax:=$1828; cpu.cx:=$2709;
  144.       if kap=1 then formtab:=@form36 else formtab:=@form72;
  145.     end
  146.     else
  147.     begin
  148.       form:=3;
  149.       tabneu:=@tab12;  {1.2 MB in 1.2 MB-Laufwerk}
  150.       formtab:=@form12;
  151.       cpu.ax:=$1850; cpu.cx:=$4f0f;
  152.     end
  153.   else
  154.   if art>=3 then         {720 KB oder 1.44 MB Laufwerk}
  155.     if kap<=2 then
  156.     begin
  157.       form:=4;
  158.       tabneu:=@tab36;
  159.       formtab:=@form72;  {720 KB}
  160.       cpu.ax:=$1850; cpu.cx:=$4f09;
  161.     end
  162.     else
  163.     begin
  164.       form:=3;
  165.       tabneu:=@tab14;
  166.       formtab:=@form14;  {1.44 MB}
  167.       cpu.ax:=$1850; cpu.cx:=$4f12;
  168.     end;
  169.   zaehler:=versuche;
  170.   ax:=cpu.ax;       {AX-Register wird durch Funktion verändert}
  171.   repeat
  172.     cpu.ax:=ax;
  173.     cpu.dl:=drive;  {Nummer des Laufwerks}
  174.     intr($13, cpu); {Funktion Nr. 18h aufrufen}
  175.     if cpu.flags and fcarry=1 then
  176.     begin
  177.       diskreset;    {Fehler aufgetreten}
  178.       dec(zaehler);
  179.     end;
  180.   until (cpu.flags and fcarry=0) or (zaehler=0) or (cpu.ah=0);
  181.   if (zaehler=0) then  {Funktion 18h nicht vorhanden}
  182.   begin
  183.     zaehler:=versuche; {letzte Rettung}
  184.     repeat     {Funktion Nr. 17h, falls 18h nicht vorhanden}
  185.       cpu.ah:=$17;     {Schreibrate setzen}
  186.       cpu.al:=form;
  187.       cpu.dl:=drive;   {Welches Laufwerk formatieren}
  188.       intr($13, cpu);
  189.       if cpu.flags and fcarry=1 then
  190.       begin
  191.         diskreset;     {Fehler aufgetreten}
  192.         dec(zaehler);
  193.       end;
  194.     until (cpu.flags and fcarry=0) or (zaehler=0) or (cpu.ah=0);
  195.   end;
  196.   if (art=2) and (kap=2) then
  197.   begin    {720 KB in 5,25}
  198.     einzelstep;
  199.     einzelschritt:=true;  {Merker für Einzelstep eingeschaltet}
  200.   end
  201.   else     {anderes Format gewählt}
  202.     einzelschritt:=false; {Kein Einzelschritt eingeschaltet}
  203. end;
  204. {************************************************************}
  205. procedure laufwerkstabneu;
  206.  
  207. begin
  208.   getintvec($1e,tabalt);
  209.   setintvec($1e,tabneu);
  210. end;
  211. {************************************************************}
  212. procedure laufwerkstabalt;
  213.  
  214. begin
  215.   setintvec($1e,tabalt);
  216. end;
  217. {************************************************************}
  218. function readwriteverify(was, spur, seite, sektor,
  219.                          anzahl, drive : byte;
  220.                          var buffer) : byte;
  221. var
  222.   cpu     : registers;
  223.   zaehler : byte;
  224.  
  225. begin                {was=2 : Sektoren von Diskette lesen}
  226.   zaehler:=versuche; {was=3 : Sektoren auf Diskette schreiben}
  227.   repeat             {was=4 : Sektoren verifizieren}
  228.     cpu.ah:=was;
  229.     cpu.dl:=drive;
  230.     cpu.dh:=seite;
  231.     cpu.ch:=spur;
  232.     cpu.cl:=sektor;
  233.     cpu.al:=anzahl;
  234.     cpu.es:=seg(buffer);
  235.     cpu.bx:=ofs(buffer);
  236.     intr($13, cpu);
  237.     readwriteverify:=cpu.ah;    {Rückgabe des Fehlercodes}
  238.     if cpu.flags and fcarry=1 then
  239.     begin
  240.       readwriteverify:=cpu.ah;  {Fehlercode}
  241.       diskreset;
  242.     end;
  243.     dec(zaehler);
  244.   until (zaehler=0) or (cpu.flags and fcarry=0) or (cpu.ah=0);
  245. end;
  246. {************************************************************}
  247. function  spurformat(spur, seite, sektor,
  248.                      anzahl, drive : byte) : byte;
  249. type
  250.   formrec = record
  251.               trackdisk, seitedisk, sektordisk, zahlbyte : byte;
  252.             end;
  253. var
  254.   cpu       : registers;
  255.   formattab : array[1..18] of formrec; {Max. 18 Sektoren}
  256.   zaehler   : byte;
  257.   sekzahl   : byte;
  258.  
  259. begin
  260.   zaehler:=versuche;
  261.   for sekzahl:=1 to anzahl do
  262.   begin
  263.     formattab[sekzahl].trackdisk:=spur;
  264.     formattab[sekzahl].seitedisk:=seite;
  265.     formattab[sekzahl].sektordisk:=sekzahl;
  266.     formattab[sekzahl].zahlbyte:=2;
  267.   end;
  268.   repeat
  269.     cpu.ah:=5;     {Spur formatieren}
  270.     cpu.dl:=drive;
  271.     cpu.dh:=seite;
  272.     cpu.ch:=spur;
  273.     cpu.al:=anzahl;
  274.     cpu.es:=seg(formattab);
  275.     cpu.bx:=ofs(formattab);
  276.     intr($13, cpu);
  277.     spurformat:=cpu.ah;  {Rückgabe des Fehlercodes}
  278.     if cpu.flags and fcarry=1 then
  279.     begin
  280.       spurformat:=cpu.ah;
  281.       diskreset;
  282.     end;
  283.     dec(zaehler);
  284.   until (zaehler=0) or (cpu.flags and fcarry=0) or (cpu.ah=0);
  285. end;
  286. {********************Hauptprogramm der Unit******************}
  287. begin
  288.   laufwerka:=config(0);
  289.   laufwerkb:=config(1);  {Art von Laufwerk A und B}
  290. end.
  291.