home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* MEGACOPY.PAS *)
- (* (c) 1989 Michael Holin & TOOLBOX *)
- (* ------------------------------------------------------ *)
- PROGRAM MegaCopy;
-
- {$I-,D-,S-,R-,V-}
-
- USES Dos, Crt;
-
- TYPE
- FormatTyp = RECORD
- spur, seite, sektor, laenge : BYTE;
- END;
- CONST
- ver = 'MegaCopy (c) 1989 Michael Holin & TOOLBOX';
- msgln = 22; barln = 12; txtln = 4;
- Lesen = 2; Schreiben = 3; Verify = 4;
- FName = 'c:\mcopy.$$$';
- Cat = ' einlegen / A oder B für Directory';
-
- VAR
- Regs : Registers;
- FormBuff: ARRAY [1..18] OF FormatTyp;
- t : ARRAY [0..160] OF POINTER;
- Buffer : ARRAY [0..3999] OF BYTE;
- GDT : ARRAY [0..47] OF BYTE;
- { Global Descriptor Table }
-
- ErrCode, ei, ej, elast,
- i, j, last, quell, ziel,
- sp, sek, tries, DriveTyp : BYTE;
- EMtracks, EM, cursor,
- bytes, ii, segm, offs,
- garp, ScrBase, coo : WORD;
- useEM, AT, amDOSlesen,
- Verify_an, Format,
- DochFormat, HD, useHD,
- Again, NoPara, amEMlesen : BOOLEAN;
- c, beep : CHAR;
- f : FILE;
- Master : POINTER;
- EMadr : LONGINT;
- ID : BYTE ABSOLUTE $F000:$FFFE; { AT oder XT }
- VideoMode : BYTE ABSOLUTE 0:$449; { Mono oder Color }
- crsr : WORD ABSOLUTE 0:$460; { Cursorform }
- tabseg : WORD ABSOLUTE 0:122;
- { Zeiger auf Laufwerkstabelle }
- tabofs : WORD ABSOLUTE 0:120;
-
- LABEL LOOP, NOCHMAL;
-
- PROCEDURE ClearLine(x, y : BYTE);
- { löscht Bildschirmzeilen }
- VAR
- i, j : BYTE;
- BEGIN
- FOR i := x TO y DO BEGIN
- GotoXY(1,i);
- FOR j := 1 TO 40 DO Write(#32#32);
- END;
- GotoXY(1,x);
- END;
-
- PROCEDURE Bye;
- BEGIN
- ClearLine(msgln, msgln);
- { eventuelles Blinken abstellen }
- TextColor(LightGray);
- Regs.ah := 1;
- Regs.cx := cursor;
- Intr(16, Regs); { Cursor wieder an! }
- Halt; { Programm beenden }
- END;
-
- PROCEDURE ErrorMsg(TEXT : STRING);
- BEGIN
- GotoXY(1,24);
- TextColor(LightRed);
- WriteLn('Fatal: ', TEXT, beep);
- Bye;
- END;
-
- PROCEDURE Wait;
- BEGIN
- REPEAT UNTIL KeyPressed;
- c := UpCase(ReadKey);
- IF c = #0 THEN c := UpCase(ReadKey);
- IF (c = #27) OR (c = #3) THEN Bye; { ESC & CTRL C }
- IF c = #13 THEN c := #7;
- TextColor(LightGray);
- CASE c OF
- 'Q': BEGIN { Ton an und ausschalten }
- IF beep = #7 THEN beep := #32 ELSE beep := #7;
- IF beep = #7 THEN Mem[ScrBase:158] := $20
- ELSE MemW[ScrBase:158] := $0751;
- Wait;
- END;
- 'F': IF sp > 0 THEN BEGIN { Format an und abschalten }
- IF Format THEN Format := FALSE
- ELSE Format := TRUE;
- GotoXY(65, txtln);
- IF Format THEN Write('J') ELSE Write('N');
- Wait;
- END;
- 'V': IF sp > 0 THEN BEGIN { Verify an und abschalten }
- IF Verify_an THEN Verify_an := FALSE
- ELSE Verify_an := TRUE;
- GotoXY(65, txtln+1);
- IF Verify_an THEN Write('J') ELSE Write('N');
- Wait;
- END;
- END;
- END;
-
- PROCEDURE Input(a, b : CHAR);
- { Wartet bis einer der übergebenen Buchstaben }
- VAR
- x, y : BYTE; { gedrückt wurde }
- BEGIN
- x := WhereX; y := WhereY;
- REPEAT
- Wait;
- GotoXY(x,y); Write(c);
- UNTIL (c = a) OR (c = b);
- END;
-
- PROCEDURE CheckParameter;
- VAR
- a, b : STRING[1];
- i : BYTE;
- BEGIN
- Format := FALSE; { Grundeinstellungen }
- Verify_an := FALSE;
- Again := TRUE;
- NoPara := TRUE;
- beep := #7;
- IF ParamCount = 0 THEN Exit;
- NoPara := FALSE;
- a := ParamStr(1);
- b := ParamStr(2);
- quell := Ord(UpCase(a[1]))-65;
- ziel := quell;
- IF ParamCount = 1 THEN Exit;
- ziel := Ord(UpCase(b[1]))-65;
- IF ParamCount = 2 THEN Exit;
- FOR i := 3 TO ParamCount DO BEGIN
- a := ParamStr(i);
- IF UpCase(a[1]) = 'V' THEN Verify_an := TRUE;
- IF UpCase(a[1]) = 'F' THEN Format := TRUE;
- IF UpCase(a[1]) = 'Q' THEN beep := #32;
- END;
- END;
-
- PROCEDURE Catalog(laufw : CHAR);
- { der aktuelle Bildschirminhalt wird gerettet und das }
- { Directory des angegebenen Laufwerks angezeigt. Danach }
- { wird der alte Bildschirm wiederhergestellt. }
- VAR
- dir : SearchRec;
- x : BYTE;
- BEGIN
- TextColor(LightMagenta);
- Move(Mem[ScrBase:0], Buffer, 4000);
- ClrScr;
- WriteLn('Directory von Laufwerk ', laufw, ':');
- TextColor(LightGray);
- Regs.ah := 28;
- Regs.dl := Ord(laufw)-64;
- Intr(33, Regs); { Laufwerk initialisieren }
- IF Regs.al = 255 THEN
- WriteLn(#13#10'Diskette ist nicht formatiert!')
- ELSE BEGIN
- FindFirst(laufw + ':\*.*', AnyFile - VolumeID, dir);
- x := 1;
- WHILE DosError = 0 DO BEGIN
- GotoXY(x, WhereY);
- Write(dir.name);
- GotoXY(x+14, WhereY);
- IF dir.attr AND 16 = 16 THEN WriteLn('(DIR)')
- ELSE WriteLn(dir.size);
- FindNext(dir);
- IF WhereY = 25 THEN BEGIN
- IF x < 50 THEN Inc(x, 25);
- GotoXY(1,2);
- END;
- END;
- END;
- GotoXY(65,25);
- Write('Press Any Key');
- Wait;
- ClrScr;
- Move(Buffer, Mem[ScrBase:0], 4000);
- END;
-
- PROCEDURE CenterAndWait(zeile : BYTE; TEXT : STRING);
- { gibt übergebenen Text aus und wartet auf Tastendruck. }
- { Sollte A oder B gedrückt worden sein, so wird das }
- { entsprechende Directory angezeigt. }
- VAR
- spalte : BYTE;
- BEGIN
- spalte := 40 - (Length(TEXT) DIV 2);
- GotoXY(spalte, zeile);
- TextColor(Blink + LightRed);
- Write(TEXT, beep);
- REPEAT
- Wait;
- IF (c = 'A') OR (c = 'B') THEN BEGIN
- Catalog(c);
- CenterAndWait(zeile, TEXT);
- END;
- UNTIL (c <> 'A') AND (c <> 'B');
- NormVideo;
- ClearLine(zeile, zeile);
- END;
-
- PROCEDURE LFehler;
- BEGIN
- GotoXY(1, msgln+1);
- IF Regs.ah = 3 THEN
- WriteLn('Disk ist schreibgeschützt!!')
- ELSE
- WriteLn('Ein Schreib-, Lese-Fehler: ', Regs.ah,
- ' ist aufgetreten!', beep);
- Write('R)etry, I)gnore, A)bort ?');
- IF (Regs.ah <> 3) AND (NOT (amDOSlesen OR amEMlesen))
- AND (NOT Format) THEN
- Write(#8'oder F)ormatieren einschalten ?');
- Wait;
- CASE c OF
- 'R': ErrCode := 1;
- 'A': ErrCode := 2;
- 'F': BEGIN
- Format := TRUE;
- DochFormat := TRUE;
- ErrCode := 1;
- END;
- 'I': BEGIN
- Mem[ScrBase:coo] := $45; { ein E schreiben }
- ErrCode:=3;
- END;
- ELSE ErrCode := 1;
- END;
- ClearLine(msgln+1, msgln+2);
- END;
-
- PROCEDURE ClearBuffer; { gibt Speicher wieder frei }
- VAR
- i : BYTE;
- BEGIN
- IF Master <> NIL THEN FreeMem(Master, bytes);
- Master := NIL;
- FOR i := 0 TO sp DO BEGIN
- IF t[i] <> NIL THEN BEGIN
- FreeMem(t[i], bytes);
- t[i] := NIL;
- END;
- END;
- END;
-
- FUNCTION Wohin(spur : BYTE) : WORD;
- BEGIN { berechnet Screen-Koordinate }
- Wohin := barln * 160 + 160 + (spur SHR 1) SHL 1 +
- 160 * (spur AND 1);
- END;
-
- PROCEDURE DiskIO(funktion, laufw, sp : BYTE; p : POINTER);
- { liest, schreibt oder verifiziert eine Spur }
- BEGIN
- CASE funktion OF
- 2: MemW[ScrBase:coo] := $074c;
- { ein L schreiben & Farbe setzen }
- 3: Mem [ScrBase:coo] := $53; { S }
- 4: Mem [ScrBase:coo] := $56; { V }
- END;
- tries := 0;
- ErrCode := 0;
- Regs.ah := 6;
- Regs.dl := 255;
- Intr(33, Regs); { eine Taste abfragen, ohne zu warten }
- IF (Regs.al = 27) OR (Regs.al = 3) THEN Exit;
- REPEAT
- Inc(tries);
- IF tries > 1 THEN BEGIN
- Regs.ah := 0;
- Intr(19, Regs); { LaufwerksReset }
- END;
- Regs.ah := funktion;
- Regs.dl := laufw;
- Regs.dh := (sp AND 1); { seite }
- Regs.ch := (sp SHR 1); { spur }
- Regs.cl := 1; { sektor }
- Regs.al := sek; { anzahl }
- Regs.es := Seg(p^);
- Regs.bx := Ofs(p^);
- Intr(19, Regs);
- UNTIL (Regs.ah = 0) OR (tries = 4);
- IF tries = 4 THEN LFehler;
- IF ErrCode = 2 THEN Regs.al := 27
- ELSE Regs.al := 0; { Abort nach Fehler }
- END;
-
- FUNCTION CheckTyp : BYTE;
- { liefert Laufwerkstyp für Formatierung auf ATs }
- BEGIN
- Regs.ah := 21;
- Regs.dl := ziel; { erkennt Laufwerk Diskwechsel? }
- Intr(19, Regs);
- IF (Regs.flags AND 1) = 1 THEN
- ErrorMsg('Kann Laufwerke nicht initialisieren.');
- CASE Regs.ah OF
- 1: BEGIN { 360KB Drive (erkennt Wechsel nicht) }
- IF sek > 9 THEN
- ErrorMsg('Ziellaufwerk kann keine ' +
- 'HD-Disketten schreiben.');
- CheckTyp := 1;
- END;
- 2: BEGIN { HD-Drive (erkennt Wechsel) }
- IF sek < 15 THEN
- IF sp = 40 THEN
- CheckTyp := 2 { 360K im 1.2 MB }
- ELSE
- CheckTyp := 4; { 720K im 1.4 MB }
- IF sek = 15 THEN
- CheckTyp := 3; { 1.2 MB im 1.2 MB }
- IF sek = 18 THEN
- CheckTyp := 5; { 1.4 MB im 1.4 MB }
- END;
- ELSE ErrorMsg('Laufwerk nicht vorhanden?!');
- END;
- END;
-
- PROCEDURE AnzSektoren;
- { liest 1.Sektor der Quelldisk und stellt am 24.Byte die }
- { Anzahl der Sektoren fest }
- VAR
- MD, i : BYTE;
- BEGIN
- tries := 0;
- TextColor(LightGray);
- REPEAT
- Inc(tries);
- Regs.ah := 0;
- IF tries > 1 THEN Intr(19, Regs); { LaufwerksReset }
- Regs.ah := Lesen;
- Regs.dl := quell;
- Regs.dh := 0; { seite }
- Regs.ch := 0; { spur }
- Regs.cl := 1; { sektor }
- Regs.al := 1; { anzahl }
- Regs.es := Seg(Buffer);
- Regs.bx := Ofs(Buffer);
- Intr(19, Regs);
- UNTIL (Regs.ah = 0) OR (tries = 6);
- IF tries = 6 THEN ErrorMsg('Spur 0 ist nicht lesbar!');
- MD := Buffer[21];
- sek := Buffer[24];
- IF (sek < 8) OR (sek > 18) THEN
- ErrorMsg('Kann Anzahl der Sektoren nicht bestimmen!');
- CASE MD OF { Media Descriptor }
- $F9, $F0: sp := 80;
- { $F0 für 1.44 MB Disks ab DOS 3.3 }
- $FF, $FD: sp := 40;
- ELSE
- ErrorMsg('Kann nur zweiseitige Disketten kopieren!');
- END;
- ClearLine(txtln+4, txtln+6);
- GotoXY(24, txtln+5);
- Write('Kopiere ', sp,' Spuren mit ', sek,' Sektoren. ');
- GotoXY(32, txtln+3);
- IF AT THEN DriveTyp := CheckTyp;
- Write('Format: ');
- IF Buffer[0] < 200 THEN
- Write('Atari ST')
- ELSE
- FOR i := 3 TO 10 DO Write(Chr(Buffer[i]));
- sp := sp * 2 - 1;
- bytes := sek * 512;
- FOR i := 1 TO sek DO BEGIN
- { Parameterblock für Format. erstellen }
- FormBuff[i].sektor := i;
- FormBuff[i].laenge := 2; { nur 512-Byte Sektoren }
- END;
- Mem[tabseg:tabofs+4] := sek;
- { Anz. Sektoren in Laufwerkstabelle eintragen. }
- { Dies ist für's Handhaben von HD-Disks }
- { unbedingt nötig! Hey Michael Tischer, warum }
- { steht das nicht im PC-INTERN 2.0 ? }
- END;
-
- PROCEDURE EMInt;
- { Speicher-Verschiebe-Routine wird aufgerufen }
- BEGIN
- Regs.ah := 135;
- Regs.cx := bytes SHR 1; { BYTES/2 Words verschieben }
- Regs.es := Seg(GDT);
- Regs.si := Ofs(GDT);
- Intr(21, Regs);
- IF Regs.flags AND 1 = 1 THEN
- ErrorMsg('Probleme mit Extended Memory!');
- END;
-
- PROCEDURE EMup(p : POINTER; Adr : LONGINT);
- { Hier werden die nötigen Eintragungen in die GDT für's }
- { Verschieben des Speichers gemacht. p ist der Zeiger }
- { auf den Quellbereich, Adr gibt die Zieladresse im }
- { Extended Memory an. Aus diesen Werten werden zwei 24 }
- { Bit-Einträge für die GDT erzeugt. }
- VAR
- l : LONGINT;
- BEGIN
- l := 16;
- l := l * Seg(p^) + Ofs(p^);
- GDT[20] := l DIV 65536;
- l := l MOD 65536;
- GDT[19] := l DIV 256;
- GDT[18] := l MOD 256;
- GDT[28] := Adr DIV 65536;
- Adr := Adr MOD 65536;
- GDT[27] := Adr DIV 256;
- GDT[26] := Adr MOD 256;
- EMInt; { Speicher verschieben }
- END;
-
- PROCEDURE EMdown(Adr : LONGINT; p : POINTER);
- { Hier genau das Gegenteil: vom Extended Memory in den }
- { Hauptspeicher }
- VAR
- l : LONGINT;
- BEGIN
- l := 16;
- l := l * Seg(p^) + Ofs(p^);
- GDT[28] := l DIV 65536;
- l := l MOD 65536;
- GDT[27] := l DIV 256;
- GDT[26] := l MOD 256;
- GDT[20] := Adr DIV 65536;
- Adr := Adr MOD 65536;
- GDT[19] := Adr DIV 256;
- GDT[18] := Adr MOD 256;
- EMInt;
- END;
-
- PROCEDURE FormatTrack(spur : BYTE);
- VAR
- n, s1, s2 : BYTE;
- BEGIN
- ErrCode := 0;
- Regs.ah := 6;
- Regs.dl := 255;
- Intr(33, Regs); { eine Taste abfragen, ohne zu warten }
- IF (Regs.al = 27) OR (Regs.al = 3) THEN Exit;
- IF AT THEN BEGIN { Modus des HD-Laufwerks festlegen }
- Regs.ah := 23;
- Regs.al := DriveTyp;
- Regs.dl := ziel;
- Intr(19, Regs);
- END;
- s1 := spur SHR 1;
- s2 := spur AND 1;
- FOR n := 1 TO sek DO BEGIN { Parameterblock erstellen }
- FormBuff[n].spur := s1;
- FormBuff[n].seite := s2;
- END;
- tries := 0;
- REPEAT
- Inc(tries);
- Regs.ah := 5;
- Regs.dl := ziel;
- Regs.dh := s2;
- Regs.ch := s1;
- Regs.al := sek;
- Regs.es := Seg(FormBuff);
- { Adresse des Parameterblocks }
- Regs.bx := Ofs(FormBuff);
- Intr(19, Regs); { Spur formatieren }
- UNTIL (Regs.ah = 0) OR (tries = 4);
- IF tries = 4 THEN LFehler;
- END;
-
- BEGIN
- FOR i := 0 TO 160 DO t[i] := NIL;
- IF (ID = 252) OR (ID = 248) THEN AT := TRUE
- ELSE AT := FALSE;
- IF VideoMode = 7 THEN ScrBase := $B000
- ELSE ScrBase := $B800;
- GDT[16] := $FF; GDT[17] := $FF;
- GDT[21] := $92; GDT[22] := 0;
- GDT[23] := 0; GDT[24] := $FF;
- GDT[25] := $FF; GDT[29] := $92;
- GDT[30] := 0; GDT[31] := 0;
- Regs.ah := 8;
- Regs.dl := $80; { Festplatte vorhanden? }
- Intr(19, Regs);
- IF Regs.flags AND 1 = 1 THEN HD := FALSE ELSE HD := TRUE;
- EM := 0; { kein Extended Memory vorhanden }
- Master := NIL;
- sp := 0;
- cursor := crsr;
- Regs.ah := 1;
- Regs.cx := $2020;
- Intr(16, Regs); { Cursor abschalten }
- CheckParameter;
- IF NoPara THEN BEGIN
- ClrScr; TextColor(LightBlue); WriteLn(ver);
- TextColor(LightGray);
- WriteLn(' Bei Ein-Laufwerks-Copy kann Extended Memory ',
- 'oder Festplatte zum Puffern');
- WriteLn(' der Daten genutzt werden'#10);
- WriteLn(' Kopiert nur Tracks mit Inhalt; leere Tracks ',
- 'werden nicht geschrieben');
- WriteLn('Nach einmaligem Lesen kann auf mehrere ',
- 'Disketten geschrieben werden'#10);
- WriteLn('Sollten beim Schreiben Fehler auftreten, so ',
- 'kann nachträglich noch das');
- WriteLn(' Formatieren angeschaltet werden'#10);
- WriteLn('Die Directories der Disketten lassen sich ',
- 'anzeigen');
- WriteLn('Kopiert auch Atari ST Disketten ',
- '(nur Standard-Format)'#10);
- TextColor(Cyan);
- WriteLn('Aufruf: MCOPY [source] [dest] [format] ',
- '[verify] [quiet]');
- WriteLn(' Alle Parameter sind optional! ');
- WriteLn(' MCOPY a : von A: nach A: ',
- 'Ohne Format & Verify');
- WriteLn(' MCOPY b: a: f : von B: nach A: ',
- 'Mit Format, Ohne Verify');
- WriteLn(' MCOPY a b f v q : von A: nach B: ',
- 'Mit Format & Verify & ohne Ton'#10);
- TextColor(LightGray);
- WriteLn('Format, Verify und Ton lassen sich mit F V Q ',
- 'nachträgl. an- und ausschalten');
- WriteLn('Es werden nur zweiseitige Disketten mit 8 ',
- 'bis 18 Sektoren kopiert');
- CenterAndWait(25,'Press Any Key');
- END;
- REPEAT { Noch eine Kopie? }
- ClrScr;
- GotoXY(80,1);
- TextColor(LightGray);
- IF beep = #7 THEN Write(' ') ELSE Write('Q');
- TextColor(LightGreen);
- IF AT THEN BEGIN
- Regs.ah := 136;
- Intr(21, Regs);
- EM := Regs.ax; { wieviel Extended Memory? }
- END;
- useEM := FALSE;
- useHD := FALSE;
- Regs.ah := 1;
- Regs.cx := cursor;
- Intr(16, Regs); { Cursor anschalten }
- DochFormat := FALSE;
- GotoXY(23,1);
- WriteLn(ver);
- TextColor(Cyan);
- GotoXY(1, barln);
- Write(' 1 2 3 4 ',
- ' 5 6 7 7');
- Write('01234567890123456789012345678901234567890123456',
- '789012345678901234567890123456789');
- GotoXY(14, txtln);
- TextColor(LightGray);
- Write('Quellaufwerk : ');
- IF NoPara THEN BEGIN
- Input('A', 'B');
- quell := Ord(c)-65;
- END;
- Write(Chr(65 + quell));
- GotoXY(14, txtln+1);
- Write('Ziellaufwerk : ');
- IF NoPara THEN BEGIN
- INPUT('A', 'B');
- ziel := Ord(c)-65;
- END ELSE Write(Chr(65 + ziel));
- GotoXY(36, txtln);
- Write('Zieldisk formatieren..(J/N): ');
- IF NoPara THEN BEGIN
- Input('J', 'N');
- IF c = 'J' THEN Format := TRUE ELSE Format := FALSE;
- END ELSE
- IF Format THEN Write('J') ELSE Write('N');
- GotoXY(36, txtln+1);
- Write('Zieldisk verifizieren.(J/N): ');
- IF NoPara THEN BEGIN
- Input('J', 'N');
- IF c = 'J' THEN Verify_an := TRUE
- ELSE Verify_an := FALSE;
- END ELSE
- IF Verify_an THEN Write('J') ELSE Write('N');
- GotoXY(24, txtln+4);
- IF (quell = ziel) AND NoPara THEN BEGIN
- Write('Puffer mehrmals schreiben (J/N): ');
- Input('J', 'N');
- IF c = 'N' THEN Again := FALSE ELSE Again := TRUE;
- END ELSE Again := FALSE;
- NoPara := TRUE;
- IF (EM > 0) AND (quell = ziel) THEN BEGIN
- GotoXY(24, txtln+5);
- Write('Extended Memory benutzen (J/N): ');
- INPUT('J', 'N');
- IF c = 'N' THEN BEGIN
- useEM := FALSE;
- EM := 0;
- END ELSE useEM := TRUE;
- END;
- IF HD AND (NOT useEM) AND (quell = ziel) THEN BEGIN
- GotoXY(24, WhereY+1);
- Write('Daten auf Platte puffern (J/N): ');
- Input('J', 'N');
- IF c = 'N' THEN useHD := FALSE ELSE useHD := TRUE;
- END;
-
- REPEAT { Noch eine Kopie mit diesen Einstellungen? }
- sp := 160;
- ClearBuffer;
- IF DochFormat THEN BEGIN
- { Formatieren ggf wieder abschalten }
- Format := FALSE;
- DochFormat := FALSE;
- END;
- bytes := 0;
- ClearLine(barln+2, barln+3);
- Regs.ah := 1;
- Regs.cx := $2020;
- Intr(16, Regs); { Cursor abschalten }
- IF quell <> ziel THEN BEGIN
- CenterAndWait(msgln, 'Bitte Disketten' + Cat);
- AnzSektoren;
- END;
- last := 0; elast := 0;
- i := 0; j := 0; ei := 0; ej := 0;
- REPEAT { Falls Disk nicht ganz in den Speicher paßt }
- IF quell = ziel THEN BEGIN
- CenterAndWait(msgln, 'Bitte Quelldiskette' + Cat);
- IF bytes = 0 THEN AnzSektoren;
- END;
- ClearBuffer;
- IF useEM THEN BEGIN
- GetMem(Master, bytes);
- EMtracks := EM * 10 DIV (bytes DIV 102) - 1;
- IF EM > 1500 THEN EMtracks := 160;
- { soviel Spuren passen ins EM }
- END;
- IF useHD THEN BEGIN
- GetMem(Master, bytes);
- EMtracks := 160;
- { die ganze Disk paßt auf die HD }
- EM := DiskFree(3) DIV 1024;
- IF ((EM + (MaxAvail DIV 1024))*2) < (sp*sek) THEN
- ErrorMsg('Nicht genügend freier Speicher auf '+
- 'Laufwerk C:');
- Assign(f, FName);
- Rewrite(f, bytes);
- coo := IOResult;
- IF coo = 150 THEN
- ErrorMsg('Festplatte ist schreibgeschützt!');
- IF coo > 0 THEN
- ErrorMsg('Schreibfehler auf Festplatte!');
- END;
-
- GotoXY(33, msgln);
- Write('FreeMem:');
- amDOSlesen := TRUE;
- amEMlesen := FALSE;
- REPEAT
- GetMem(t[i], bytes);
- coo := Wohin(i);
- REPEAT
- DiskIO(Lesen, quell, i, t[i]);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL; { ESC gedrückt? }
- segm := Seg(t[i]^);
- offs := Ofs(t[i]^);
- ii := 8;
- garp := MemW[segm:offs]; { erstes Word der Spur }
- REPEAT
- IF MemW[segm:offs+ii] <> garp THEN ii := 10000;
- Inc(ii, 8); { ist Spur leer? }
- UNTIL ii >= bytes;
- IF ii < 10000 THEN BEGIN
- { dann Speicher wieder freigeben }
- FreeMem(t[i], bytes);
- t[i] := NIL;
- Mem[ScrBase:coo] := $FA; { einen . schreiben }
- END;
- Inc(i);
- GotoXY(42, msgln);
- Write(EM + MaxAvail DIV 1024, ' KB ');
- UNTIL (MaxAvail < bytes) OR (i > sp);
- { Lesen bis Speicher voll, }
- last := j; { oder Diskende erreicht ist }
- ei := i;
- amDOSlesen := FALSE;
- IF (useEM OR useHD) AND (i <= sp) THEN BEGIN
- { EM oder HD füllen }
- EMadr := 1048576; { bei 1 MB beginnen }
- amEMlesen := TRUE;
- REPEAT
- coo := Wohin(ei);
- REPEAT
- DiskIO(Lesen, quell, ei, Master);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL; { ESC gedrückt? }
- IF useEM THEN EMup(Master, EMadr)
- ELSE BlockWrite(f, master^, 1);
- Inc(ei);
- Inc(EMadr, bytes);
- GotoXY(42, msgln);
- Write(EM - (EMadr - 1048576) DIV 1024, ' KB ');
- UNTIL (EMtracks < ei-i) OR (ei > sp);
- { Lesen bis EM voll }
- elast := ej; { oder Diskeende erreicht ist }
- IF useHD THEN Close(f);
- amEMlesen := FALSE;
- END;
-
- LOOP:
- IF quell = ziel THEN
- CenterAndWait(msgln, 'Bitte Zieldiskette' + Cat);
- amDOSlesen := FALSE;
- IF Format THEN FormatTrack(j);
- REPEAT
- coo := Wohin(j);
- REPEAT
- REPEAT
- IF Format THEN BEGIN
- Mem[ScrBase:coo] := $46; { ein F ... }
- REPEAT
- FormatTrack(j);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL;
- END;
- IF t[j] <> NIL THEN
- DiskIO(Schreiben, ziel, j, t[j]);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL; { ESC gedrückt? }
- IF Verify_an THEN DiskIO(Verify, ziel, j, t[j]);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL;
- IF ErrCode = 3 THEN Mem[ScrBase:coo] := $45
- ELSE Mem[ScrBase:coo] := $FA;
- Inc(j);
- UNTIL j = i;
- ej := j;
- IF (useEM OR useHD) AND (j <= sp) THEN BEGIN
- IF useHD THEN Reset(f, bytes);
- elast := ei;
- EMadr := 1048576;
- REPEAT
- coo := Wohin(ej);
- IF useEM THEN EMdown(EMadr, Master)
- ELSE BlockRead(f, master^, 1);
- REPEAT
- REPEAT
- IF Format THEN BEGIN
- Mem[ScrBase:coo] := $46; { ein F ... }
- REPEAT
- FormatTrack(ej);
- UNTIL ErrCode <> 1;
- END;
- DiskIO(Schreiben, ziel, ej, Master);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL;
- IF Verify_an THEN
- DiskIO(Verify, ziel, ej, Master);
- UNTIL ErrCode <> 1;
- IF (Regs.al = 27) OR (Regs.al = 3) THEN
- GOTO NOCHMAL;
- IF ErrCode = 3 THEN Mem[ScrBase:coo] := $45
- ELSE Mem[ScrBase:coo] := $FA;
- Inc(ej);
- Inc(EMadr, bytes);
- UNTIL ej = ei;
- IF useHD THEN Close(f);
- END;
- IF Again THEN BEGIN
- CenterAndWait(msgln, 'Nochmal schreiben (J/N)?');
- IF c = 'J' THEN BEGIN
- j := last;
- ej := elast;
- ClearLine(barln+2, barln+3);
- GOTO LOOP;
- END;
- END;
- i := ei;
- j := ej;
- UNTIL ei > sp;
-
- NOCHMAL:
- IF useHD THEN BEGIN
- EM := 0;
- Assign(f, FName);
- IF Regs.ah = 27 THEN Close(f);
- Erase(f); { Pufferfile auf HD löschen }
- END;
- CenterAndWait(msgln,
- 'Noch eine Kopie mit diesen Einstellungen (J/N)?');
- UNTIL c <> 'J';
- CenterAndWait(msgln, 'Noch weitere Kopien (J/N)?');
- UNTIL c <> 'J';
- ClrScr;
- WriteLn('So long...');
- Bye;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von MEGACOPY.PAS *)