summaryrefslogtreecommitdiff
path: root/system/dos/1986/src/disk descriptor.dos.hd
blob: 312b2731967a87487c727e8c5ef9a1eae0fb6d1d (plain)
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
PACKET dos disk DEFINES                       (* Copyright (C) 1985, 86 *)
                                              (* Frank Klapper          *)
  first fat byte,                             (* 30.05.86               *)
  begin of fat,
  number of fat sectors, 
  number of fat entrys, 
  number of fat copies,
  begin of dir,
  number of dir sectors,
  begin of data area,
  sectors per cluster,
  cluster size,
  sector size,

  eublock,
  first block no of cluster,

  reset disk attributes,
  set disk attributes:
 
LET dir entrys per block    = 16,
    first non dummy ds page = 2;

LET DOSDISK = STRUCT (INT sectors per cluster,
                          number of reserved sectors,
                          number of fats,
                          number of dir sectors,
                          first fat byte,
                          number of fat sectors,
                          heads,
                          sectors per track,
                          tracks,
                          number of fat entrys,
                     REAL size);

LET BLOCK = BOUND STRUCT (ALIGN dummy, ROW 64 REAL block row);

INT CONST sector size :: 512;

TEXT VAR bpb := 32 * " ";

INITFLAG VAR bpb ds used := FALSE;

DATASPACE VAR bpb ds;

BLOCK VAR bpb block;

DOSDISK VAR disk format;
BOUND DOSDISK VAR format table;

INT VAR eu sectors,
        xbegin of data area;

INT PROC eublock (INT CONST nr):
(*COND FLOPPY
  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:
  nr MOD disk format.sectors per track.

trac: 
  (nr DIV disk format.sectors per track) DIV disk format.heads.

head:
  (nr DIV disk format.sectors per track) MOD disk format.heads.

eu sectors per head:
  eu sectors * eu tracks.

ENDCOND*)
(*COND HDU*)
  nr

(*ENDCOND*)

END PROC eublock;

INT PROC first block no of cluster (INT CONST cluster no):
  IF cluster no < 2
    THEN error stop ("interner Fehler")
  FI;
  begin of data area + (cluster no - 2) * sectors per cluster.

END PROC first block no of cluster;

INT PROC first fat byte:
  disk format.first fat byte

END PROC first fat byte;
 
INT PROC number of fat copies:
  disk format.number of fats

END PROC number of fat copies;

INT PROC number of fat sectors:
  disk format.number of fat sectors 

END PROC number of fat sectors;

INT PROC number of fat entrys:
  disk format.number of fat entrys

END PROC number of fat entrys;

INT PROC number of dir sectors:
  disk format.number of dir sectors 

END PROC number of dir sectors;

INT PROC begin of fat (INT CONST no):
  disk format.number of reserved sectors + no * disk format.number of fat sectors

END PROC begin of fat;

INT PROC begin of dir:
  disk format.number of reserved sectors + 
  disk format.number of fats * disk format.number of fat sectors
 
END PROC begin of dir;

INT PROC begin of data area:
  xbegin of data area

END PROC begin of data area;

INT PROC sectors per cluster:
  disk format.sectors per cluster 

END PROC sectors per cluster;

INT PROC cluster size:
  disk format.sectors per cluster * 512

END PROC cluster size;

PROC set disk attributes (INT CONST first fat byte):
  enable stop;
(*COND FLOPPY
  get bios parameter block; 
  IF is valid bpb
    THEN load disk data from bpb
    ELSE load disk disk data from ds
  FI;
  eu sectors := eu last sector - eu first sector +1;
ENDCOND*)
  xbegin of data area := disk format.number of reserved sectors +
        disk format.number of fats * disk format.number of fat sectors +
        disk format.number of dir sectors; 
(*COND FLOPPY
  test compatibility 
 
.is valid bpb:
  first fat byte < 252 OR code (bpb SUB 22) = first fat byte.

load disk disk data from ds:
  IF exists (text (first fat byte))
    THEN format table := old (text (first fat byte));
         copy values
    ELSE error stop ("DOS-Diskettenformat nicht implementiert")
  FI.

copy values:
  disk format.sectors per cluster        := format table.sectors per cluster; 
  disk format.number of reserved sectors := format table.number of reserved sectors; 
  disk format.number of fats             := format table.number of fats;
  disk format.size                       := format table.size;
  disk format.number of dir sectors      := format table.number of dir sectors;
  disk format.first fat byte             := format table.first fat byte;
  disk format.number of fat sectors      := format table.number of fat sectors;
  disk format.heads                      := format table.heads;
  disk format.sectors per track          := format table.sectors per track;
  disk format.tracks                     := format table.tracks;
  disk format.number of fat entrys       := format table.number of fat entrys.

test compatibility:
  IF disk format.sectors per track > eu sectors
    OR eu tracks <> disk format.tracks
    OR abs (eu heads) < disk format.heads
    OR disk format.number of reserved sectors <> 1
    THEN error stop ("DOS-Format auf diesem Diskettenlaufwerk nicht lesbar")
  FI; 
ENDCOND*)
 
END PROC set disk attributes;

PROC reset disk attributes:
(*COND FLOPPY
  disk format.sectors per cluster        := 1;
  disk format.number of reserved sectors := 1;
  disk format.number of fats             := 1;
  disk format.size                       := real (eu size);
  disk format.number of dir sectors      := 4;
  disk format.first fat byte             := 255;
  disk format.number of fat sectors      := 1;
  disk format.heads                      := eu heads;
  disk format.sectors per track          := eu tracks;
  disk format.tracks                     := eu sectors;
  disk format.number of fat entrys       := 100.

ENDCOND*)
(*COND HDU*)
  get bios parameter block; 
  load disk data from bpb.

(*ENDCOND*)

END PROC reset disk attributes;

PROC get bios parameter block:
  init bpb ds;
  read bpb;
  copy bpb block to bpb text.

init bpb ds:
  IF NOT initialized (bpb ds used)
    THEN bpb ds := nilspace;
         bpb block := bpb ds
  FI.

read bpb:
  INT VAR error;
  read block (bpb ds, first non dummy ds page, 0, error);
  IF error <> 0
    THEN SELECT error OF 
           CASE 1: errorstop ("Floppylaufwerk nicht betriebsbereit") 
           CASE 2: errorstop ("Schreib-/Lesefehler") 
           CASE 3: errorstop ("Interner Fehler (Blocknummer zu hoch)") 
           OTHERWISE errorstop ("Schreib-/Lesefehler " + text (error)) 
         END SELECT
  FI.

copy bpb block to bpb text:
  replace (bpb, 1, bpb block. block row [1]);
  replace (bpb, 2, bpb block. block row [2]);
  replace (bpb, 3, bpb block. block row [3]); 
  replace (bpb, 4, bpb block. block row [4]).

END PROC get bios parameter block;

PROC load disk data from bpb:
  disable stop;
  enable load disk data from bpb;
  IF is error
    THEN clear error;
         enable stop;
         error stop ("Bios-Parameterblock ungltig")
  FI.

END PROC load disk data from bpb;

PROC enable load disk data from bpb:
  disk format.sectors per cluster        := code (bpb SUB 14);
  disk format.number of reserved sectors := code (bpb SUB 16) * 256 + code (bpb SUB 15);
  disk format.number of fats             := code (bpb SUB 17);
  disk format.number of dir sectors      := dir entrys DIV dir entrys per block; 
  disk format.size                       := real (code (bpb SUB 21)) * 256.0 + real (code (bpb SUB 20));
  disk format.first fat byte             := code (bpb SUB 22);
  disk format.number of fat sectors      := code (bpb SUB 24) * 256 + code (bpb SUB 23); 
  disk format.heads                      := dos heads;
  disk format.sectors per track          := code (bpb SUB 26) * 256 + code (bpb SUB 25);
  disk format.tracks                     :=
        int(disk format.size / real(disk format.sectors per track * disk format.heads));
  disk format.number of fat entrys       := fat entrys.
 
dir entrys:
  code (bpb SUB 19) * 256 + code (bpb SUB 18).

dos heads:
  code (bpb SUB 28) * 256 + code (bpb SUB 27).

fat entrys:
  data clusters + 2.

data clusters:
  int ((disk format.size - real (no of table sectors)) / real (sectors per cluster)).

no of table sectors:
  disk format.number of reserved sectors + disk format.number of fats * disk format.number of fat sectors +
  disk format.number of dir sectors. 

END PROC enable load disk data from bpb;

END PACKET dos disk;