summaryrefslogtreecommitdiff
path: root/system/net/1.8.7/src/net hardware interface
blob: 4e3466ab006558679ff053e8e86a71f61236c8f6 (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
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
PACKET net hardware

(************************************************************************)
(****  Netzprotokoll Anpassung                                          *)
(****  Komplette Version mit BUS Anpassung           10.06.87           *)
(****  mit I/0 Controls  fuer integrierte Karten                        *)
(****  Verschiedene Nutztelegrammgrössen                                *)
(****  Version: GMD 2.0                              A.Reichpietsch     *)
(************************************************************************)

   DEFINES
        blockin,
        blockout,
        set net mode,
        net address,
        mode text,
        data length,
        data length via node,
        decode packet length,
        next packet start,
        flush buffers,
        transmit header,
        transmit trailer,
        version,
        reset box,
        max mode,
        net mode:




   LET                eak prefix laenge = 6,
               packet length before stx = 14  (*eth header =14 *),
                        maximum mode nr = 12,
                                    stx = ""2"",
                                niltext = "",
                                   null = "0",
                               hex null = ""0"",
                                  blank = " ",
                             eak prefix = ""0""0""0""0"",
                             typefield  = "EU",
                        prefix adresse  = "BOX",
                 second prefix adresse  = ""0"BOX",
             second address type bound  = 90;

   INT CONST data length via node :: 64;
   TEXT CONST version :: "GMD 2.0  (10.6.87)";


   TEXT VAR own address;
   INT VAR paketlaenge, eumel paket laenge, mode, rahmenlaenge, actual data length;

BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge): 
   INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
   REAL VAR time out := clock (1) + 10.0;
   REP 
      blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); 
   UNTIL hilfslaenge = 0 OR clock (1) > time out PER  ;
   IF hilfslaenge <> 0
   THEN report ("blockin abbruch, fehlende Zeichen: "+text(hilfslaenge));
    FI;
   hilfslaenge = 0
END PROC blockin; 
 
PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge): 
   INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512; 
   REP 
      blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); 
   UNTIL hilfslaenge = 0 PER 
END PROC blockout; 

PROC set net mode (INT CONST new mode):
   mode := new mode ;
   own address := net address (station(myself));
   SELECT mode OF
      CASE 1,3   : set data length (64);
      CASE 2     : std framelength; set data length (64)
      CASE 4,6   : set data length (128)
      CASE 5     : std framelength; set data length (128)
      CASE 7,9   : set data length (256)
      CASE 8     : std framelength; set data length (256)
      CASE 10,12 : set data length (512)
      CASE 11    : std framelength; set data length (512);

      OTHERWISE
   END SELECT.

   std framelength:
      rahmenlaenge := eak prefix laenge + packet length before stx.

ENDPROC set net mode;

INT PROC max mode:
   maximum mode nr
ENDPROC max mode;

INT PROC net mode:
   mode
ENDPROC net mode;

TEXT PROC mode text:
   mode text (mode)
ENDPROC mode text;

TEXT PROC mode text (INT CONST act mode):
   SELECT act mode OF
      CASE 1:   "Modus: (1)  EUMEL-Netz           64 Byte"
      CASE 2:   "Modus: (2)  ETHERNET via V.24    64 Byte"
      CASE 3:   "Modus: (3)  ETHERNET integrated  64 Byte"
      CASE 4:   "Modus: (4)  EUMEL-Netz           128 Byte"
      CASE 5:   "Modus: (5)  ETHERNET via V.24    128 Byte"
      CASE 6:   "Modus: (6)  ETHERNET integrated  128 Byte"
      CASE 7:   "MODUS: (7)  EUMEL-Netz           256 Byte"
      CASE 8:   "MODUS: (8)  ETHERNET via V.24    256 Byte"
      CASE 9:   "MODUS: (9)  ETHERNET integrated  256 Byte"
      CASE 10:  "MODUS: (10) EUMEL-Netz           512 Byte"
      CASE 11:  "MODUS: (11) ETHERNET via V.24    512 Byte"
      CASE 12:  "MODUS: (12) ETHERNET integrated  512 Byte"
      OTHERWISE  errorstop ("Modus " + text(mode) + " gibt es nicht");
                 error message
   END SELECT

ENDPROC mode text;

PROC set data length (INT CONST new data length):
    actual data length := new data length
ENDPROC set data length;

INT PROC data length:
    actual data length
ENDPROC data length;

PROC reset box (INT CONST net mode):
   SELECT net mode OF
      CASE 1,4,7,10   :   eumel net box reset
      CASE 2,5,8,11   :   eak reset
      OTHERWISE    controler reset
   END SELECT.

   eumel net box reset:
      out (90*""4""); 
      REP UNTIL incharety (1) = niltext PER. 

   eak reset:
      out ("E0"13"E0"13"").

   controler reset:
      INT VAR dummy;
      control (-35, 0,0,dummy);
      control (22,0,0,dummy).

ENDPROC reset box;

PROC remove frame
   (TEXT VAR erstes zeichen vom eumel telegramm, BOOL VAR kein telegramm da):
   kein telegramm da := FALSE;
   SELECT net mode OF
      CASE 2,5,8,11  : remove ethernet frame
                       (erstes zeichen vom eumel telegramm, kein telegramm da)
   OTHERWISE
   END SELECT;
ENDPROC remove frame;

PROC remove ethernet frame (TEXT VAR string, BOOL VAR schrott):
   TEXT VAR  speicher, t;
   INT VAR lg;

   t := string;
   speicher := niltext;
   WHILE kein stx da REP
      lies zeichen ein;
      teste auf timeout;
   UNTIL textoverflow PER;
   melde eingelesene zeichen.

   lies zeichen ein:
      speicher CAT t;
      t := incharety (1).

   teste auf timeout:
      IF t = niltext THEN schrott := (speicher <> niltext)
                                         CAND not only fill characters;
                          string := niltext;
                          LEAVE remove ethernet frame
      FI.

   not only fill characters:
      pos (speicher, ""1"", ""254"",1) <> 0.

   kein stx da :
      t <> stx.

   textoverflow:
      length (speicher) > 1000.

   melde eingelesene zeichen:
      IF kein stx da
         THEN kein eumeltelegrammanfang
         ELSE untersuche ethernet header
      FI.

   kein eumeltelegrammanfang:
      report ("skipped ,fehlendes <STX> ,letztes Zeichen:", t);
      string := t;
      schrott := TRUE.

   untersuche ethernet header:
      string := t;
      IF ethernet header inkorrekt
         THEN melde fehler
      FI.

   ethernet header inkorrekt:
      lg := length (speicher);
      packet zu kurz COR adresse falsch.

   packet zu kurz:
      lg < packet length before stx.

   adresse falsch:
      INT VAR adrpos := pos (speicher, own address);
      zieladresse falsch COR adresse nicht an der richtigen pos .

   zieladresse falsch:
      adrpos < 1.

   adresse nicht an der richtigen pos:
      adrpos <> lg - packet length before stx + 1.

   melde fehler:
      report ("Header inkorrekt eingelesen: ", speicher + t);
      string := t;
      schrott := TRUE.

ENDPROC remove ethernet frame;

TEXT PROC next packet start:

  TEXT VAR t := niltext;
  BOOL VAR schrott := FALSE;

   t:= incharety (1);
   IF t = niltext THEN LEAVE next packet start WITH niltext
                  ELSE remove frame (t, schrott)
   FI;
   IF schrott THEN no stx or niltext
              ELSE t
   FI.

   no stx or niltext:
      IF t = stx THEN "2"
        ELIF t = niltext THEN "0"
          ELSE t
      FI.

ENDPROC next packet start;

PROC flush buffers:
  REP UNTIL incharety (5) = niltext PER;
  report ("buffers flushed");
ENDPROC flush buffers;

PROC transmit header (DATASPACE CONST w):
   BOUND INT VAR laengeninformation := w;
   eumel paket laenge := laengeninformation ;
   decode packet length (eumel paket laenge);
   SELECT net mode OF
      CASE 1,4,7,10     :
      CASE 2,5,8,11     : eak und eth header senden (w)
      OTHERWISE         : telegrammanfang melden;
                          std ethernet header senden (w)
   END SELECT;

ENDPROC transmit header;

PROC decode packet length (INT VAR decoded length):

  decoded length DECR 2;
  rotate (decoded length, 8);

  IF decoded length < 96 THEN
    ELIF decoded length < 128 THEN decoded length INCR 32
      ELIF decoded length < 160 THEN decoded length INCR 128
        ELIF decoded length < 192 THEN decoded length INCR 352
          ELIF decoded length < 224 THEN decoded length INCR 832
            ELIF decoded length < 256 THEN decoded length INCR 1824
  FI;

ENDPROC decode packet length;

PROC transmit trailer:
   INT VAR dummy;
   SELECT net mode OF
      CASE 3,6,9,12 : control (21,0,0,dummy)
       OTHERWISE
   END SELECT.

ENDPROC transmit trailer;

PROC std ethernet header senden (DATASPACE CONST x):
   TEXT VAR  eth adresse, ethernet kopf := niltext;
   INT VAR adresse;
   BOUND STRUCT (INT head, zwischennummern) VAR header := x;
   zieladresse holen;
   zieladresse senden;
   quelladresse senden;
   typfeld senden;
   ausgeben.
   
   zieladresse holen:
      adresse := header.zwischennummern AND 255;
      eth adresse := net address (adresse).

   zieladresse senden:
      ethernetkopf CAT eth adresse.

   quelladresse senden:
      ethernetkopf CAT own address.

   typfeld senden:
      ethernetkopf CAT typefield.

   ausgeben:
      out (ethernetkopf).

ENDPROC std ethernet header senden;

PROC telegrammanfang melden:
   INT VAR dummy;
      control (20,eumel paket laenge + packet length before stx,0, dummy).

ENDPROC telegrammanfang melden;

PROC eak und eth header senden (DATASPACE CONST x):
   TEXT VAR res:= niltext;

   neue laenge berechnen;
   eak kopf senden;
   std ethernet header senden (x).

   neue laenge berechnen:
      paket laenge := rahmenlaenge + eumel paket laenge.
    
   eak kopf senden:
      res := code (paket laenge DIV 256);
      res CAT (code (paket laenge AND 255));
      res CAT eak prefix;
      out(res).

ENDPROC eak und eth header senden;

TEXT PROC net address (INT CONST eumel address):
   TEXT VAR res ;
   INT VAR low byte;

SELECT mode OF
   CASE 1,4,7,10 : eumel net address
   OTHERWISE ethernet address
END SELECT.

eumel net address:
    text(eumel address).

ethernet address:
   IF second adress kind THEN second eth header
                         ELSE first eth header
   FI;
   res.

   second adress kind:
      eumel address = 34 COR
       eumel address > second address type bound.

   second eth header:
      low byte := eumel address AND 255;
      res := second prefix adresse + code (low byte);
      res CAT hex null.

   first eth header:
      res := prefix adresse + text (eumel address, 3);
      changeall (res, blank, null).

ENDPROC net address;

ENDPACKET net hardware;