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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
|
PACKET dos disk DEFINES (* Copyright (C) 1986, 87 *)
(* Frank Klapper *)
(* Referenz: 3-22 *) (* 11.09.87 *)
open dos disk,
sectors per cluster,
fat copies,
dir sectors,
media descriptor,
fat sectors,
begin of fat,
fat entrys,
begin of dir,
begin of cluster,
cluster size,
bpb exists,
write bpb,
eu block,
bpb dump modus:
INITFLAG VAR bpb ds initialisiert := FALSE;
DATASPACE VAR bpb ds;
BOUND STRUCT (ALIGN dummy, ROW 512 INT daten) VAR bpb;
BOOL VAR bpb dump flag := FALSE;
REAL VAR begin of data area;
INT VAR sectors per track,
heads;
IF exists ("shard interface")
THEN load shard interface table
FI;
TEXT CONST bpb type 254 :: ""00""00""00"" +
""69""85""77""69""76""66""80""66"" +
""00""02"" +
""01"" +
""01""00"" +
""02"" +
""64""00"" +
""64""01"" +
""254"" +
""01""00"" +
""08""00"" +
""01""00"" +
""00""00"",
bpb type 255 :: ""00""00""00"" +
""69""85""77""69""76""66""80""66"" +
""00""02"" +
""02"" +
""01""00"" +
""02"" +
""112""00"" +
""128""02"" +
""255"" +
""01""00"" +
""08""00"" +
""02""00"" +
""00""00"";
PROC open dos disk:
enable stop;
bpb ds an bound koppeln;
bpb lesen;
IF bpb ungueltig
THEN versuche pseudo bpb zu verwenden
FI;
ueberpruefe bpb auf gueltigkeit;
globale variablen initialisieren;
IF bpb dump flag
THEN dump schreiben
FI.
bpb ds an bound koppeln:
IF NOT initialized (bpb ds initialisiert)
THEN bpb ds := nilspace;
bpb := bpb ds
FI.
bpb lesen:
INT VAR return;
check rerun;
read block (bpb ds, 2, 0, return);
IF return <> 0
THEN lesefehler (return)
FI.
bpb ungueltig:
(* Byte 12 = Byte 13 = ... = Byte 23 <==> Word 6 = ... = Word 11 *)
INT VAR word no;
FOR word no FROM 6 UPTO 10 REP
IF bpb.daten [word no + 1] <> bpb.daten [word no + 2]
THEN LEAVE bpb ungueltig WITH FALSE
FI
PER;
TRUE.
versuche pseudo bpb zu verwenden:
lies ersten fat sektor;
IF fat sektor gueltig und pseudo bpb vorhanden
THEN pseudo bpb laden
ELSE error stop ("Format unbekannt")
FI.
lies ersten fat sektor:
(* da der bpb in diesem Fall ungültig, lese ich den fat sektor in den bpb
Datenraum *)
check rerun;
read block (bpb ds, 2, 1, return);
IF return <> 0
THEN lesefehler (return)
FI.
fat sektor gueltig und pseudo bpb vorhanden:
TEXT VAR fat start := "1234";
replace (fat start, 1, bpb.daten [1]);
replace (fat start, 2, bpb.daten [2]);
(fat start SUB 2) = ""255"" CAND (fat start SUB 3) = ""255"" CAND
pseudo bpb vorhanden.
pseudo bpb vorhanden:
pos (""254""255"", fat start SUB 1) > 0.
pseudo bpb laden:
INT VAR i;
FOR i FROM 1 UPTO 15 REP
bpb.daten [i] := bpb puffer ISUB i
PER.
bpb puffer:
IF pseudo bpb name = ""255""
THEN bpb type 255
ELSE bpb type 254
FI.
pseudo bpb name:
fat start SUB 1.
ueberpruefe bpb auf gueltigkeit:
IF bytes per sector <> 512
THEN error stop ("DOS Format nicht implementiert (unzulässige Sektorgröße)")
FI;
IF (fat sectors > 64)
THEN error stop ("ungültige DOS Disk (BPB)")
FI.
globale variablen initialisieren:
sectors per track := bpb byte (25) * 256 + bpb byte (24);
heads := bpb byte (27) * 256 + bpb byte (26);
begin of data area := real (reserved sectors + fat copies * fat sectors + dir sectors).
dump schreiben:
dump ("Sektoren pro Cluster", sectors per cluster);
dump ("Fat Kopien ", fat copies);
dump ("Dir Sektoren ", dir sectors);
dump ("Media Descriptor ", media descriptor);
dump ("Sektoren pro Fat ", fat sectors);
dump ("Fat Anfang (0) ", begin of fat (0));
dump ("Fat Einträge ", fat entrys);
dump ("Dir Anfang ", begin of dir).
END PROC open dos disk;
PROC lesefehler (INT CONST fehler code):
error stop (fehlertext).
fehlertext:
SELECT fehler code OF
CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
CASE 2: "Lesefehler"
OTHERWISE "Lesefehler " + text (fehler code)
END SELECT.
END PROC lesefehler;
TEXT VAR konvertier puffer := "12";
INT PROC bpb byte (INT CONST byte no):
replace (konvertier puffer, 1, bpb.daten [byte no DIV 2 + 1]);
code (konvertier puffer SUB puffer pos).
puffer pos:
IF even byte no
THEN 1
ELSE 2
FI.
even byte no:
(byte no MOD 2) = 0.
END PROC bpb byte;
INT PROC bytes per sector:
bpb byte (12) * 256 + bpb byte (11)
END PROC bytes per sector;
INT PROC sectors per cluster:
bpb byte (13)
END PROC sectors per cluster;
INT PROC reserved sectors:
bpb byte (15) * 256 + bpb byte (14)
END PROC reserved sectors;
INT PROC fat copies:
bpb byte (16)
END PROC fat copies;
INT PROC dir sectors:
dir entrys DIV dir entrys per sector.
dir entrys:
bpb byte (18) * 256 + bpb byte (17).
dir entrys per sector:
16.
END PROC dir sectors;
REAL PROC dos sectors:
real (bpb byte (20)) * 256.0 + real (bpb byte (19))
END PROC dos sectors;
INT PROC media descriptor:
bpb byte (21)
END PROC media descriptor;
INT PROC fat sectors:
bpb byte (23) * 256 + bpb byte (22)
END PROC fat sectors;
INT PROC begin of fat (INT CONST fat copy no):
(* 0 <= fat copy no <= fat copies - 1 *)
reserved sectors + fat copy no * fat sectors
END PROC begin of fat;
INT PROC fat entrys:
anzahl daten cluster + 2.
anzahl daten cluster:
int ((dos sectors - tabellen sektoren) / real (sectors per cluster)).
tabellen sektoren:
real (reserved sectors + fat copies * fat sectors + dir sectors).
END PROC fat entrys;
INT PROC begin of dir:
reserved sectors + fat copies * fat sectors.
END PROC begin of dir;
REAL PROC begin of cluster (REAL CONST cluster no):
begin of data area + (cluster no - 2.0) * real (sectors per cluster)
END PROC begin of cluster;
INT PROC cluster size:
512 * sectors per cluster
END PROC cluster size;
BOOL PROC bpb exists (INT CONST no):
exists ("bpb ds") AND no > 0 AND no < 4.
END PROC bpb exists;
PROC write bpb (INT CONST no):
INT VAR return;
write block (old ("bpb ds"), no + 1, 0, 0, return);
IF return <> 0
THEN error stop ("Schreibfehler")
FI.
END PROC write bpb;
(* Da DOS-Partitionen maximal 32 MByte groß sein können, können die Blocknummern
durch 16 BIT unsigned Integer dargestellt werden. Die Werte die die 'eublock'-
Prozeduren liefern sind als solche zu verstehen *)
INT PROC eu block (INT CONST dos block no):
IF hd version
THEN dos block no
ELSE dos block no floppy format
FI.
dos block no floppy format:
IF page format
THEN head * eu sectors per head + trac * eu sectors + sector
ELSE head * eu sectors + trac * abs (eu heads) * eu sectors + sector
FI.
page format:
eu heads < 0.
sector:
dos block no MOD sectors per track.
trac:
(dos block no DIV sectors per track) DIV heads.
head:
(dos block no DIV sectors per track) MOD heads.
eu sectors per head:
eu sectors * eu tracks.
eu sectors:
eu last sector - eu first sector + 1.
END PROC eu block;
INT PROC eu block (REAL CONST dos block no):
eublock (low word (dos block no)).
END PROC eublock;
PROC bpb dump modus (BOOL CONST status):
bpb dump flag := status
END PROC bpb dump modus;
END PACKET dos disk;
|