forked from christoh/fdformat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WIMAGE.PAS
217 lines (209 loc) · 6.31 KB
/
WIMAGE.PAS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
{$A+,B-,D+,E-,F-,I-,L+,N-,O-,R-,S-,V-}
{$M 4096,0,655360}
PROGRAM WIMAGE;
{WIMAGE - Write Diskette to file / Read Diskette from file - Ver 1.21}
{Compiled with Turbo-Pascal Ver 6.0}
USES auxdos,dos,diskio;
VAR para : String[50];
fn : String[50];
f : FILE;
lw : Byte;
ok : Boolean;
trk : Word;
rest : Word;
t,rt : Word;
j : Word;
written : Word;
xsec : LongInt;
readdisk : Boolean;
FileBoot : ^bpbtyp;
ysec : LongInt;
ftrk : Word;
CylMem : CmTyp;
PROCEDURE SyntaxError;
BEGIN
InOutRes:=0;
WriteLn(stderr,'Syntax Error.');
WriteLn(stderr);
WriteLn(stderr,'Syntax is: WIMAGE <drive>: <file> (write Diskette to file)');
WriteLn(stderr,' WIMAGE <file> <drive>: (read Diskette from file)');
WriteLn(stderr);
WriteLn(stderr,'Exapmles: WIMAGE A: C:\DISKS\MYDISK.360');
WriteLn(stderr,' WIMAGE C:\DISKS\DOS330.144 A:');
WriteLn(stderr);
Halt(1);
END;
PROCEDURE BootError;
BEGIN
InOutRes:=0;
WriteLn(stderr,'File ',fn,' is no diskette image.');
Halt(9);
END;
PROCEDURE DosError;
BEGIN
InOutRes:=0;
WriteLn(stderr,'This program requires DOS 3.20 or higher.');
Halt(10);
END;
PROCEDURE CloseExitProc;
BEGIN
Close(f);
IF readdisk THEN Erase(f);
DefExitProc;
END;
BEGIN
SetIntVec($1B,@CtrlBreak);
WriteLn;
WriteLn('WIMAGE-Write Disk to File/Read Disk from File-V1.21');
WriteLn('Copyright (c) 1988 - 1991, Christoph H. Hochst„tter');
WriteLn;
IF Swap(DosVersion)<$314 THEN DosError;
IF (Length(ParamStr(1))=2) AND (Length(ParamStr(2))=2) THEN SyntaxError;
IF Length(ParamStr(1))=2 THEN BEGIN
para:=ParamStr(1);
fn:=ParamStr(2);
readdisk:=True;
END ELSE IF Length(ParamStr(2))=2 THEN BEGIN
para:=ParamStr(2);
fn:=ParamStr(1);
readdisk:=False;
END ELSE
SyntaxError;
IF fn='' THEN SyntaxError;
FOR lw:=1 TO Length(fn) DO fn[lw]:=Upcase(fn[lw]);
IF para[2]<>':' THEN SyntaxError;
lw:=Ord(Upcase(para[1]))-$40;
BootSec.init(ok);
IF NOT(ok) THEN BEGIN
WriteLn(stderr,'Not enough Memory.');
Halt(4);
END;
BootSec.Readx(lw);
IF BootSec.UnknownDrive THEN BEGIN
WriteLn(stderr,'Drive does not exist.');
Halt(3);
END;
IF (BootSec.Status AND $9200) <> 0 THEN BEGIN
WriteLn(stderr,'WIMAGE does not work with a SUBST/ASSIGN/NETWORK Drive.');
Halt(2);
END;
IF BootSec.Media=5 THEN BEGIN
WriteLn(stderr,'WIMAGE does not handle fixed disks.');
Halt(8);
END;
WITH BootSec.bpb^ DO BEGIN
IF sec<>0 THEN
xsec:=sec
ELSE
xsec:=lsc;
rest:=xsec MOD (hds*spt);
IF rest<>0 THEN BEGIN
WriteLn(stderr,'This disk has hidden sectors.');
Halt(5);
END;
trk:=xsec DIV (hds*spt);
WriteLn('Information from the floppy:');
WriteLn('Tracks : ',trk);
WriteLn('Sectors/Track: ',spt);
WriteLn('Sides : ',hds);
IF readdisk THEN BEGIN
WriteLn('Bytes total : ',DiskSize(lw));
WriteLn('Bytes free : ',DiskFree(lw));
END ELSE ysec:=DiskSize(lw);
WriteLn;
Assign(f,fn);
IF readdisk THEN BEGIN
FileMode:=OWriteOnly OR ODenyWrite;
Rewrite(f,1);
Reset(f,1);
END ELSE BEGIN
FileMode:=OReadOnly OR ODenyWrite;
Reset(f,1);
END;
IF IoResult<>0 THEN BEGIN
WriteLn(stderr,'File ',fn,' cannot be openend.');
Halt(6);
END;
ExitProc:=@CloseExitProc;
IF NOT(readdisk) THEN BEGIN
GetMem(FileBoot,512);
BlockRead(f,FileBoot^,512,written);
IF (written<>512) OR
(FileBoot^.boot_code[511]<>$AA) OR
(FileBoot^.boot_code[510]<>$55) THEN BEGIN
BootError;
END;
IF FileBoot^.sec=0 THEN
ysec:=FileBoot^.lsc
ELSE
ysec:=FileBoot^.sec;
ftrk:=ysec DIV (FileBoot^.spt*FileBoot^.hds);
WriteLn('Information from the Image-File');
WriteLn('Tracks : ',ftrk);
WriteLn('Sectors/Track: ',FileBoot^.spt);
WriteLn('Sides : ',FileBoot^.hds);
WriteLn;
IF (ftrk<>trk) OR (FileBoot^.spt<>spt) OR (FileBoot^.hds<>hds) THEN BEGIN
InOutRes:=0;
WriteLn(stderr,'Source File and Destination Disk have different formats.');
Halt(11);
END;
Seek(f,0);
FreeMem(FileBoot,512);
END;
maxcyl:=AllocCyl(CylMem,trk-1);
WriteLn(Succ(maxcyl)*LongInt(CylMem^[0]^.Datalen),' Bytes available for ',maxcyl+1,' Cylinders.');
WriteLn;
t:=0;
IF readdisk THEN BEGIN
WHILE t<trk DO BEGIN
InOutRes:=0;
EndProgram(128,'User abort.');
IF t+maxcyl>trk-1 THEN rt:=trk-t ELSE rt:=maxcyl+1;
Write('Reading',rt:3,' Cylinders from',t:3,' to',t+rt-1:3,' ');
FOR j:=0 TO rt-1 DO BEGIN
InOutRes:=0;
EndProgram(128,'User abort. Partial file '+fn+' erased.');
CylMem^[j]^.Readx(lw,t+j);
END;
WriteLn('- Writing to File ',fn);
FOR j:=0 TO rt-1 DO BEGIN
BlockWrite(f,CylMem^[j]^.data^,CylMem^[j]^.Datalen,written);
IF IoResult<>0 THEN BEGIN
WriteLn(stderr,'Error writing to file ',fn);
Halt(13);
END;
IF written<>CylMem^[j]^.Datalen THEN BEGIN
InOutRes:=0;
WriteLn(stderr,'Disk Full - File: ',fn);
Halt(7);
END;
END;
t:=t+rt;
END;
END ELSE BEGIN
WHILE t<trk DO BEGIN
EndProgram(128,'User abort.');
IF t+maxcyl>trk-1 THEN rt:=trk-t ELSE rt:=maxcyl+1;
Write('Reading from file ',fn,' ');
FOR j:=0 TO rt-1 DO BEGIN
BlockRead(f,CylMem^[j]^.data^,CylMem^[j]^.Datalen,written);
IF (written<>CylMem^[j]^.Datalen) OR (IoResult<>0) THEN BEGIN
WriteLn(stderr,'Error reading from File ',fn);
Halt(12);
END;
END;
WriteLn('- Writing',rt:3,' Cylinders from',t:3,' to',t+rt-1:3);
FOR j:=0 TO rt-1 DO BEGIN
InOutRes:=0;
EndProgram(128,'User abort.');
CylMem^[j]^.Writex(lw,t+j);
END;
t:=t+rt;
END;
BootSec.Remount(lw);
END;
Close(f);
ExitProc:=@DefExitProc;
END;
END.