From 04e68443040c7abad84d66477e98f93bed701760 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 4 Feb 2019 13:09:03 +0100 Subject: Initial import --- .../3.1/src/setup eumel 3: modulkonfiguration | 854 +++++++++++++++++++++ 1 file changed, 854 insertions(+) create mode 100644 system/setup/3.1/src/setup eumel 3: modulkonfiguration (limited to 'system/setup/3.1/src/setup eumel 3: modulkonfiguration') diff --git a/system/setup/3.1/src/setup eumel 3: modulkonfiguration b/system/setup/3.1/src/setup eumel 3: modulkonfiguration new file mode 100644 index 0000000..529d0de --- /dev/null +++ b/system/setup/3.1/src/setup eumel 3: modulkonfiguration @@ -0,0 +1,854 @@ + +(**************************************************************************) +(***** Ergänzung des SHards um ein Modul (mit Dialog) *****************) +(***** Copyright (c) 1987, 1988 by *****************) +(***** Lutz Prechelt, Karlsruhe *****************) +(**************************************************************************) + +PACKET setup eumel modulkonfiguration (* Copyright (c) by *) +DEFINES configurate module, (* Lutz Prechelt, Karlsruhe *) + print configuration, (* Eumel 1.8.1 *) + give me, take you, (* Stand : 12.07.88 3.2 *) + new index, + perform dtcb dialogue, + perform ccb dialogue, + (* für Modulprogrammierer : *) + write info, + channel free, + reserve channel, + channels of this module, + buffer address : + +(* Dieses Modul führt den kompletten Dialog mit dem Benutzer durch, der + nötig ist, um alle Kanäle, die mit demselben Modul laufen sollen, zu + konfigurieren. + Verfahren : + im alten SHard den dtcb suchen + dtcb und Modul im neuen SHard eintragen + dtcb mit oder ohne Vorbild konfigurieren + alle ccbs zu dem Modul im alten SHard suchen und Kanalnummern merken + Auswahl einer Kanalmenge durch Benutzer mit alten als Vorschlag + ccbs in neuen SHard kopieren + ccbs mit oder ohne Vorbild konfigurieren + Kanaltabelle auf den neuen Stand bringen + neuen Shard und seine geänderte Länge zurückgeben + + Dabei kann der "Dialog" bei geeigneten Rahmenbedingungen durch bloßes + Übertragen der Werte aus einem Vorlage-SHard ersetzt werden, wenn der + Benutzer dies wünscht (want automatic mode). Dann geht alles von selbst. + (....kaufen Sie Setup-Eumel und es geht alles wie von selbst !) + +Format des SHard-Hauptmoduls : + 1. (Byte 0-2) jmp boot (3 Byte) + 2. (Byte 3) reserviert + 3. (Byte 4) SHard-Version + 4. (Byte 5) SHard-Release + 5. (Byte 6/7) SHardlänge (2 Byte) + 6. (Byte 8/9) Verweis auf Bad-Block Tabelle (2 Byte) + 7. (Byte 10/11) Verweis auf Kanaltabelle + 8. (Byte 16-175) Eumelleiste + 9. (Byte 176-299) SHardleiste + 10. (ab Byte 300) Shardhauptmodulroutinen und -daten + 11. (danach) Rumpf des Hauptmoduls mit Bad-Block-Tabelle, + Kanaltabelle, Routinen und Daten + 12. (danach) Folge der Module (bis Byte SHardlänge - 1) + +Kanaltabelle: + feste Länge 40 Einträge "nr of channels total" (Kanal 0 bis Kanal 39) + jeder Eintrag besteht aus : (alles 2 Byte) + offset dtcb, offset ccb + +Achtung : Dieses Programm schmiert bei SHards über 32767 Byte Länge + eventuell ab (es hat noch niemand probiert) ! + +Abkürzungen: cb steht für control block und meint entweder ccb oder dtcb + +Implementationsanmerkung : +Bei der Verwendung von THESAURUS wird von dem Wissen über die Art der +Implementation derselben Gebrauch gemacht, indem folgende Annahmen in den +Code eingehen: +1. Bei einem THESAURUS, in dem nicht gelöscht wurde, ist highest entry gleich + der Kardinalität +2. außerdem entspricht dann die Nummer (link) eines Eintrags seinem + Eintragszeitpunkt, d.h. der Position in der Eintragsfolge +3. + und - liefert THESAURi, in denen nicht gelöscht wurde und die Eintrags- + reihenfolge ist wie von den Parametern vorgegeben (bei + links zuerst) +4. certain und ONE liefern THESAURi, in denen nicht gelöscht wurde. +*) + +(************************* Daten ********************************) + +LET nr of channels total = 40, (* SHard Tabellenlänge *) + mdts = 40, (* max dialogtable size in INTs *) + mchm = 20, (* max channels for module *) + offset sh version = 4, + offset sh structureversion = 5, + offset shardlength = 6, + + do name = "PrOgRaM tO Do"; + +LET UNSIGNED = INT, + VARIABLES = ROW mdts ROW mchm INT; +TEXT CONST variables var xxv :: "ROW " + text (mdts) + " ROW "+ + text (mchm) + " INT VARxxv;"; + +VARIABLES VAR v; (* siehe give me / take you *) + +INT VAR max index; (* Information für new index *) + +INT VAR channels of module; (* Information für channels of this module *) + +TEXT VAR actual info; (* fuer write info *) + +ROW 256 INT VAR channel table of new shard; (* für channel free *) + +DATASPACE VAR dummy ds; (* für print configuration *) + +REAL VAR new shard length; + +(***************************************************************************) +(************* Hier geht's los...... ***************************************) +(***************************************************************************) + +(******************** configurate module **********************************) + +PROC configurate module (MODUL VAR new shard, MODUL CONST old shard, + BOOL CONST old shard valid, want automatic mode, + TEXT CONST modulname) : + do configurate module (new shard, old shard, old shard valid, + want automatic mode, modulname, FALSE) +END PROC configurate module; + +(********************** print configuration *******************************) + +PROC print configuration (MODUL CONST old shard, TEXT CONST modulname) : + (* Es ist hier schon sichergestellt, daß old shard valid ist und das Modul + auch im SHard enthalten + *) + forget (dummy ds); dummy ds := nilspace; + BOUND MODUL VAR dummy :: dummy ds; + do configurate module (dummy, old shard, TRUE, FALSE, modulname, TRUE); + forget (dummy ds). +END PROC print configuration; + + +(******************* do configurate module *********************************) + +PROC do configurate module (MODUL VAR new shard, MODUL CONST old shard, + BOOL CONST old shard valid, want automatic mode, + TEXT CONST modulname, + BOOL CONST print configuration only): + (* In dieser Prozedur ist die Beschränkung auf Module mit unter 32kB + Länge ausgenutzt. + Ist kein alter SHard vorhanden, so muss ein leerer SHard übergeben + werden (d.h. alle Einträge in der Kanaltabelle sind 0). + Ein alter SHard darf keinesfalls unterschiedliche releases desselben + Modultyps enthalten. + Resultierende SHardgesamtlängen von über 32k sind noch nicht getestet. + *) + BOUND MODUL VAR m; + INT VAR (***** Daten über das neue Modul *****) + sh version, sh structure version, release, + max ccb, nr of ccbs, + dtcb table entries, offset dtcb table, (* Variablentabellen *) + ccb table entries, offset ccb table, + muster ccb length, offset muster ccb, (* Muster-ccb im Modul *) + module body length, (* Länge des zu kopierenden Modulrumpfs *) + offset module body, offset dtcb; + TEXT VAR modultyp; (* 4 Byte *) + INT VAR (***** Daten über den alten SHard *****) + old release :: -2; (* garantiert inkompatibel *) + REAL VAR offset old dtcb :: 0.0; + ROW nr of channels total REAL VAR offset old ccb; + BOOL VAR old cbs valid :: FALSE; + THESAURUS VAR old channels :: empty thesaurus; + (***** Daten über den neuen SHard *****) + REAL VAR dtcb location; + ROW nr of channels total REAL VAR ccb location; + (***** Sonstige Daten *****) + INT VAR i, k, kanal, ccb count; + BOOL VAR automatic mode, configurate :: NOT print configuration only; + reset direction (FALSE); (* zur Sicherheit *) + IF configurate + THEN new shard length := unsigned (int (new shard, offset shard length)) FI; + connect module; + get module data; + test sh version compatibility; (* ggf. LEAVE *) + (* Bisher wurde nur gelesen, ab jetzt darf nicht mehr abgebrochen werden *) + search old shard for module and find all old ccbs; + test release compatibility; (* ggf. LEAVE *) + IF configurate + THEN write module with dtcb to shard; + perhaps set automatic mode; + FI; + configurate dtcb; + IF configurate + THEN kopf; + select channels; + write ccbs to shard; + ELSE nr of ccbs := highest entry (old channels) + FI; + configurate ccbs; + IF configurate + THEN make entries in channeltable of new shard; + int (new shard, offset shardlength, unsigned (new shard length)) + FI. + +connect module : + m := old (modulname); + actual info := info (m); + IF configurate + THEN kopf + ELSE put ("-----"); put (modulname); putline ("-----") + FI. + +get module data : + (* Format des Moduls in den ersten Bytes: + Byte Entry + 0/1 offset dtcb variablen tabelle + 2/3 offset ccb variablen tabelle + 4/5 offset muster-ccb + 6/7 offset modulrumpf + 8/9 offset dtcb + 10/11 max anzahl ccbs + die tabellen enthalten im ersten Wort die Anzahl ihrer Einträge + der modulrumpf und der ccb ihre Länge in Byte + die Länge der Tabellen ergibt sich aus den offset-Differenzen. + dtcb-Format : Modultyp (4 Byte) + SHardversion (1 Byte) + SHardstrukturversion (1 Byte) + Modulrelease (2 Byte) .... + *) + max ccb := int (m, 10); + offset dtcb table := int (m, 0); + dtcb table entries := int (m, offset dtcb table); + offset ccb table := int (m, 2); + ccb table entries := int (m, offset ccb table); + offset muster ccb := int (m, 4); + muster ccb length := int (m, offset muster ccb); + offset module body := int (m, 6); + module body length := int (m, offset module body); + offset dtcb := int (m, 8); +(***** +put (" offset dtcb table:"); put( offset dtcb table); line; +put (" dtcb table entrie:"); put( dtcb table entries); line; +put (" offset ccb table :"); put( offset ccb table); line; +put (" ccb table entrie:"); put( ccb table entries); line; +put (" offset muster ccb:"); put( offset muster ccb); line; +put (" muster ccb length:"); put( muster ccb length); line; +put (" offset module bod:"); put( offset module body); line; +put (" module body lengt:"); put( module body length); line; +put (" offset dtcb :"); put( offset dtcb); line;*****) + modultyp := text (m, offset dtcb, 4); + sh version := byte (m, offset dtcb + 4); + sh structureversion := byte (m, offset dtcb + 5); + release := int (m, offset dtcb + 6). + +test sh version compatibility : + IF configurate AND NOT version is compatible + THEN putline ("Das Modul ist mit dieser SHard-Version nicht mehr verträglich."); + putline (""10""10""15" Installation des Moduls wird abgebrochen. "14""7""13""10""); + go on; + LEAVE do configurate module + FI. + +version is compatible: + (* Kompatibel, wenn das Modul eine ältere oder gleiche sh version verlangt + und die gleiche sh structureversion + *) + sh version <= byte (new shard, offset sh version) CAND + sh structure version = byte (new shard, offset sh structureversion). + +search old shard for module and find all old ccbs : + (* Es werden alle Kanäle des alten SHard untersucht, ob der dortige Treiber + den gleichen Modultyp hat und in diesem Fall die Kanalnummer in + "old channels" gesammelt, sowie offset old ccb gemerkt, im Nichterfolgs- + falle wird offset old ccb auf diesem Kanal 0 gesetzt. + Es werden auch alle verketteten Treiber untersucht. + Auch old cbs valid und offset old dtcb werden ggf. gesetzt. + *) + IF NOT old shard valid + THEN LEAVE search old shard for module and find all old ccbs FI; + IF configurate THEN put ("Ich untersuche den alten SHard :") FI; + FOR kanal FROM 0 UPTO nr of channels total - 1 REP + IF configurate THEN cout (kanal) FI; + collect ccbs on this channel + PER; + IF configurate THEN put (""13""5"") FI. (* Zeile löschen *) + +collect ccbs on this channel : + REAL VAR p dtcb :: sh dtcb offset (old shard, kanal), + p ccb :: sh ccb offset (old shard, kanal); + WHILE p dtcb <> 0.0 AND p ccb <> 0.0 REP + BOOL CONST success :: text (old shard, p dtcb, 4) = modultyp; + IF success + THEN offset old dtcb := p dtcb; + old release := int (old shard, p dtcb + 6.0); + insert (old channels, text (kanal)); + offset old ccb [kanal+1] := p ccb + ELSE p dtcb := unsigned (int (old shard, p ccb + 2.0)); (* verkettet *) + p ccb := unsigned (int (old shard, p ccb + 4.0)) + FI + UNTIL success PER; + old cbs valid := old shard valid AND offset old dtcb <> 0.0 AND + (release = old release + 1 OR release = old release). + +test release compatibility: + IF print configuration only AND NOT old cbs valid + THEN putline ("Kein Zugriff auf die Konfigurationsdaten möglich"); + LEAVE do configurate module + FI. + +write module with dtcb to shard : + put ("Modul """ + modulname + """ wird in den SHard eingetragen :"); + IF int (new shard length MOD 2.0) <> offset module body MOD 2 + THEN new shard length INCR 1.0 FI; (* kopiert so schneller *) + dtcb location := new shard length + + real (offset dtcb - offset module body); + copy (m, real (offset module body), new shard, new shard length, + module body length); + new shard length INCR real (module body length). + +perhaps set automatic mode : + IF old cbs valid AND old release = release + THEN automatic mode := want automatic mode + ELSE automatic mode := FALSE FI. + +configurate dtcb : + IF configurate + THEN kopf; + putline ("Konfiguration des Treibers :"); + get new channel table (new shard, channel table of new shard); + FI; + perform dtcb dialogue (m, real (offset dtcb table+2), dtcb table entries, + new shard, dtcb location, + old shard, offset old dtcb, + old cbs valid, release = old release, + dtcb refinements (m), dtcb abfragen (m), + automatic mode, print configuration only). + +select channels : + ccb count := highest entry (old channels); + k := min (ccb count, max ccb); (* .... Mutter der Porzellankiste *) + nr of ccbs := max (k, 1); + IF automatic mode THEN LEAVE select channels FI; + IF max ccb > 1 + THEN REP + editget ("Wieviele Kanäle mit diesem Treiber (1 bis " + + text (max ccb) + ") : ", nr of ccbs); + out (""13"") + UNTIL nr of ccbs IN range (1, max ccb) PER; + out (""10""10"") + ELSE nr of ccbs := 1 FI; + IF nr of ccbs < ccb count (* weniger als früher *) + THEN put ("Wählen Sie mindestens"); putline (x kanäle aus deren); + putline ("Werte nicht als Vorbesetzung angeboten werden sollen"10""); + REP + THESAURUS CONST help :: certain (old channels, empty thesaurus); + IF NOT enough refused THEN out (""7"") FI + UNTIL enough refused PER; + old channels := old channels - help; + out (""3""3""3""4"") (* clear screen from incl. "Wählen..." on *) + FI. + +x kanäle aus deren : + IF ccb count - nr of ccbs > 1 + THEN text (ccb count - nr of ccbs) + " Kanäle aus, deren" + ELSE "einen Kanal aus, dessen" FI. + +enough refused : + highest entry (help) >= ccb count - nr of ccbs. + +write ccbs to shard : + (* Ausserdem wird hier ccb location vorbereitet *) + out ("Die Kanäle werden in den neuen SHard eingetragen : "); + FOR i FROM 1 UPTO nr of ccbs REP + ccb location [i] := new shard length; + copy (m, real (offset muster ccb + 2), new shard, new shard length, + muster ccb length); + new shard length INCR real (muster ccb length) + PER. + +configurate ccbs : + (*put (old shard valid); put ("Release:"); put (release); put (" old release:"); put (old release); + put (old cbs valid); pause;*) + IF configurate + THEN out (""13""10"Konfiguration der Kanäle:"13""10""); + get new channel table (new shard, channel table of new shard) + FI; + ccb count := 0; + FOR kanal FROM 0 UPTO nr of channels total REP + IF old channels CONTAINS text (kanal) + THEN ccb count INCR 1; + offset old ccb [ccb count] := offset old ccb [kanal+1] + FI + PER; + FOR i FROM ccb count + 1 UPTO nr of ccbs REP + offset old ccb [i] := 0.0 + PER; + perform ccb dialogue (m, real (offset ccb table+2), ccb table entries, + new shard, ccb location, + old shard, offset old ccb, + nr of ccbs, + offset old dtcb <> 0.0, release = old release, + ccb refinements (m), ccb abfragen (m), + automatic mode, print configuration only). + +make entries in channeltable of new shard : + kopf; + out ("Konfigurationsdaten werden in den neuen SHard eingetragen : "); + FOR i FROM 1 UPTO nr of ccbs REP + cout (i); + kanal := (*v[1][i]falsch???!!!*) byte (new shard, ccb location [i]); + make entry in channeltable of new shard + PER. + +make entry in channeltable of new shard : + IF NOT channel free (kanal) + THEN (* dtcb/ccb Adresse aus channel table nach neuem ccb umtragen. *) + int (new shard, ccb location [i] + 2.0, + unsigned (sh dtcb offset (new shard, kanal))); + int (new shard, ccb location [i] + 4.0, + unsigned (sh ccb offset (new shard, kanal))); + ELSE (* Folge-dtcb/ccb Adresse auf 0 setzen *) + int (new shard, ccb location [i] + 2.0, 0); + int (new shard, ccb location [i] + 4.0, 0); + FI; + (* Jetzt neue Adresse in channel table eintragen *) + sh dtcb offset (new shard, kanal, dtcb location); + sh ccb offset (new shard, kanal, ccb location [i]); + k := byte (new shard, ccb location [i] + 1.0); (* Zusatzkanalnummer *) + IF k <> 255 (* 255 = kein Zusatzkanal vorhanden *) + THEN (* IF NOT channel free (k) THEN alter eintrag futsch !!! *) + sh dtcb offset (new shard, k, dtcb location); + sh ccb offset (new shard, k, ccb location [i]) + FI. + +kopf : + write head ("""" + modulname + """ in den SHard aufnehmen"); + out (actual info); + out (""13""10""). +END PROC do configurate module; + + +(********************* perform dialogue ************************************) + +PROC perform dtcb dialogue + (MODUL VAR m, REAL CONST offset dialogue table, + INT CONST dialogue table entries, + MODUL VAR dtcb, REAL CONST offset dtcb, + MODUL CONST old dtcb, REAL CONST offset old dtcb, + BOOL CONST old dtcb valid, same release, + TEXT CONST refinements, INT CONST count, + BOOL CONST automatic mode, print configuration only): + ROW nr of channels total REAL VAR offset cb, offset old cb; + offset cb [1] := offset dtcb; + offset old cb [1] := offset old dtcb; + perform dialogue (TRUE, m, offset dialogue table, dialogue table entries, + dtcb, offset cb, old dtcb, offset old cb, 1, + old dtcb valid, same release, refinements, count, + automatic mode, print configuration only). +END PROC perform dtcb dialogue; + +PROC perform ccb dialogue + (MODUL VAR m, REAL CONST offset dialogue table, + INT CONST dialogue table entries, + MODUL VAR ccb, ROW nr of channels total REAL CONST offset ccb, + MODUL CONST old ccb, ROW nr of channels total REAL CONST offset old ccb, + INT CONST nr of ccbs, BOOL CONST old ccbs valid, same release, + TEXT CONST refinements, INT CONST count, + BOOL CONST automatic mode, print configuration only) : + perform dialogue (FALSE, m, offset dialogue table, dialogue table entries, + ccb, offset ccb, old ccb, offset old ccb, nr of ccbs, + old ccbs valid, same release, refinements, count, + automatic mode, print configuration only). +END PROC perform ccb dialogue; + + +PROC perform dialogue + (BOOL CONST is dtcb, + MODUL VAR m, REAL CONST offset dialogue table, + INT CONST dialogue table entries, + MODUL VAR cb, ROW nr of channels total REAL CONST offset cb, + MODUL CONST old cb, ROW nr of channels total REAL CONST offset old cb, + INT CONST nr of cbs, BOOL CONST old cb valid, same release, + TEXT CONST refinements, INT CONST refinement count, + BOOL CONST automatic mode, print configuration only) : + (* Konfigurationsdialog für einen (Satz von) Kontrollblock(s) oder bloßes + Anzeigen der Konfigurationsdaten derselben. + + 1. bei NOT print configuration only: + Führt den Dialog für eine Tabelle (also ccb oder dtcb Variablentabelle) + durch und bestückt den controlblock entsprechend. + Es wird gleich eine ganze Tabelle von controlblocks (max. mchm Stück) + abgearbeitet und zwar nr of cbs Stück; im Falle is dtcb wird natürlich + nur der Eintrag 1 der Tabellen benutzt (vom Aufrufer). + Das Eingabemodul ist m mit der zu bearbeitenden Tabelle an der Stelle + offset dialogue table. Die Tabelle enthält dialogue table entries + Einträge (max. mdts Stück !) + Die Ausgabe des Prozesses landet im Modul cb ab den Stellen offset cb. + cb ist dabei jeweils der neue SHard, damit man nicht das Modul ändert. + Die Vorlagen zum Abgucken liefert, falls old cb valid ist, das + Modul old cb (der alte SHard) ab offset old cb, dabei ist die Struktur + gleich der neuen, wenn same release gilt, andernfalls sind die + Vorversionsoffsets zu benutzen (Versionsnummer um genau 1 erhöht). + Bei automatic mode werden nur still diese Vorgabewerte übernommen. + Die Elan-Teile für den Dialog liefert schliesslich der Text refinements, + er enthält refinement count Abfragen der Namen r1, r2, ..... + Wenn refinent count = 0 ist, passiert hier eigentlich nichts, + deshalb sollte dann + für eine korrekte Initialisierung auch die Variablentabelle leer sein; + ist sie es allerdings doch nicht, werden hier noch die Standardwerte in + die ccbs eingetragen und nur der leere Dialog unterdrückt. + Vor Beginn/Nach Ende des gesamten Dialogs wird das refinement + dialoguestart/dialogueend aufgerufen; bei NOT is dtcb vor/nach dem Dialog + jedes Kanals auch noch channelstart/channelend. + + 2. bei print configuration only: + Die Daten zum new shard werden überhaupt nicht benutzt, von den + refinements wird nur für jeden Kanal einmal "print configuration" + aufgerufen. + *) + REAL VAR table byte :: offset dialogue table; + ROW mdts INT VAR offset, old offset, length; + INT VAR i, k; + BOOL VAR configurate :: NOT print configuration only; + TEXT VAR program, t; + IF print configuration only (* Hier wird evtl. schon verlassen *) + THEN startup for print + ELSE startup for dialogue FI; + IF refinement count > 0 THEN build program FI; + build data in v; + IF refinement count > 0 THEN do program FI; + IF configurate THEN put values in cb FI. + +startup for print : + IF refinement count = 0 OR dialogue table entries = 0 + THEN LEAVE perform dialogue FI. + +startup for dialogue: + IF refinement count = 0 + THEN putline ("Keine Konfiguration notwendig."); + IF dialogue table entries = 0 + THEN pause (20); LEAVE perform dialogue FI + ELSE putline ("Die Konfiguration wird vorbereitet.") FI. + +build program: + max index := refinement count; (* damit new index bescheid weiss *) + program := variables var xxv; + program cat main part; + perhaps program cat data refinements; + program CAT refinements. + +program cat main part : + program CAT "LET UNSIGNED=INT;giveme(xxv);INT VARxxi::1,actchannel;"; + IF print configuration only OR automatic mode + THEN program cat main part for print or automatic mode + ELSE program cat main part for dialogue FI. + +program cat main part for print or automatic mode: + (* Leider muss man, wenn man den Modulprogrammierer bei den .ccb und .dtcb + Teilen nicht zu stark reglementieren will, einiges mitübersetzen, was + dann gar nicht benutzt wird (z.B. alle Refinements). + Und der Gedanke macht ihn blaß, + wenn er fragt: was kostet das ? + Wilhelm Busch + *) + program CAT "FORactchannelFROM 1 UPTOchannelsofthismoduleREP"; + IF print configuration only + THEN program CAT "printconfigurationPER." + ELSE (* automatic mode: *) program CAT "automaticPER;takeyou(xxv)." + FI; + program CAT " xxa:actchannel. thischannel:"; + IF NOT is dtcb THEN program CAT "channelstart;" FI; + FOR i FROM 1 UPTO refinement count REP + program CAT "r"; (* Alle in this channel aufrufen, damit *) + program CAT text (i); (* "LEAVE this channel" kein Fehler ist. *) + program CAT ";" + PER; + IF NOT is dtcb + THEN program CAT "channelend" FI; + program CAT ". ". + +program cat main part for dialogue: + program CAT "dialoguestart;FORactchannelFROM 1 UPTOchannelsofthismoduleREP"; + program CAT "thischannelPER;dialogueend;takeyou(xxv). "; + program CAT "xxa:actchannel. thischannel:"; + IF NOT is dtcb THEN program CAT "channelstart;" FI; + program CAT "REP SELECTxxiOF "; + FOR i FROM 1 UPTO refinement count REP + program CAT "CASE "; + program CAT text (i); + program CAT ":r"; + program CAT text (i); + program CAT " " + PER; + program CAT "ENDSELECT UNTIL NOTnewindex(xxi)PER"; + IF NOT is dtcb + THEN program CAT ";channelend;reservechannel(xxv[1][xxa])" FI; + program CAT ". ". + +perhaps program cat data refinements : + FOR i FROM 1 UPTO dialogue table entries REP + IF configurate THEN cout (i) FI; + read start of next table entry; (* must be done in autom. mode, too, *) + t := next variable name; (* to get offset/oldoffset/length [i] *) + program CAT t; + program CAT ":xxv["; + program CAT text (i); + program CAT "][xxa]. "; (* Das war der normale Eintrag "varname" *) + program CAT t; (* Jetzt der für alle Kanäle "varname k" *) + program CAT "k:xxv["; + program CAT text (i); + program CAT "]. " + PER. + +read start of next table entry : + (* Format der Einträge in den Variablentabellen: + dw offset in cb + dw offset in old cb (oder ffffh falls neu) + db Typ (d.h. Länge und ist 1 oder 2) + db Namenslänge + db ...(Name)... + *) + INT CONST length of variable :: byte (m, table byte + 4.0), + length of name :: byte (m, table byte + 5.0); + old offset [i] := int (m, table byte + 2.0); (* Diese Sammlung *) + offset [i] := int (m, table byte); (* bereitet das Datenholen vor *) + length [i] := length of variable; + IF length of variable < 1 OR length of variable > 2 + THEN errorstop ("invalid variablelength : " + text (length of variable)) + FI; + table byte INCR 6.0. + +next variable name: + table byte INCR real (length of name); + text (m, table byte - real (length of name), length of name). + +build data in v : + FOR k FROM 1 UPTO nr of cbs REP (* Kanäle *) + IF configurate THEN cout (k) FI; + FOR i FROM 1 UPTO dialogue table entries REP (* Variablen *) + v[i][k] := next init value + PER + PER. + +next init value : + IF old cb valid CAND old cb present CAND value accessible + THEN value from old cb + ELSE value from new cb FI. + +old cb present : + offset old cb [k] > 0.0. + +value accessible : + same release OR + (* Ein release zuvor und Variable gibts schon: *) old offset [i] <> -1. + +value from old cb : + IF length [i] = 1 + THEN byte (old cb, offset old cb [k] + real (offset of old value)) + ELSE int (old cb, offset old cb [k] + real (offset of old value)) + FI. + +value from new cb : + IF length [i] = 1 + THEN byte (cb, offset cb [k] + real (offset [i])) + ELSE int (cb, offset cb [k] + real (offset [i])) FI. + +offset of old value : + IF same release + THEN offset [i] + ELSE old offset [i] FI. + +do program : + reset direction (TRUE); + channels of module := nr of cbs; + IF setup testing + THEN (* für diesen THEN-Teil beim abgespeckten Eumel + setup eummel mini eumel dummies insertieren *) + forget (do name, quiet); + FILE VAR f := sequentialfile (output, do name); + putline (f, program); + (*edit (do name);*) + run (do name); + forget(do name, quiet); + ELSE do (program); + FI; + program := ""; (* Platz sparen *) + reset direction (FALSE). + +put values in cb : + FOR k FROM 1 UPTO nr of cbs REP + cout (k); + FOR i FROM 1 UPTO dialogue table entries REP + IF length [i] = 1 THEN put byte ELSE put int FI + PER; + PER. + +put byte : + byte (cb, offset cb [k] + real (offset [i]), v[i][k]). + +put int : + int (cb, offset cb [k] + real (offset [i]), v[i][k]). +END PROC perform dialogue; + +(****************** give me, take you, new index ***************************) + +(* Diese Prozeduren werden aus dem do beim perform dialogue heraus aufgerufen + Sie dienen zur Kommunikation mit den Paketdaten dieses Pakets (give me, + take you) oder zur Verkleinerung des do-Programms (new index) +*) + +PROC give me (VARIABLES VAR variables) : + (* Der Sinn dieser Prozedur besteht in Folgendem : + bei perform dialogue wird in dem do, das die refinements des + SHard-Moduls ausführt, eine Datenstruktur vom Typ VARIABLES aufgebaut, + die alle in den Variablentabellen des Moduls aufgeführten Variablen + enthält und einzeln über passend benannte refinements zugänglich macht. + Diese Datenstruktur wird zuvor in diesem Paket hier initialisiert mit + Initwerten aus der Variablentabelle oder wenn möglich mit den + entsprechenden Werten aus dem alten SHard. Mit give me fordert das + do-Programm die initialisierte Datenstruktur aus diesem Paket hier an. + Im do wird am Schluss mit take you diese Datenstruktur an dieses Paket + (und damit an perform dialogue) zurückgegeben, damit die durch den + Dialog gesetzten Werte in den neuen SHard eingetragen werden können. + Eine alternative Methode, diese Kommunikation zu realisieren, wäre die + Benutzung von BOUND VARIABLES VARs mit demselben Datenraum. + *) + variables := v +END PROC give me; + +PROC take you (VARIABLES CONST variables) : + (* Gegenstück zu give me, siehe dort *) + v := variables +END PROC take you; + +BOOL PROC new index (INT VAR index) : + (* Verändert den Index je nach der direction und fragt bei down am Ende, + ob fertig. Liefert, ob es noch weitergehen soll (falls nein: index = 1) + *) + LET up = ""3"", + down = ""10"", + error = ""0""; + TEXT CONST old direction :: direction; + reset direction (TRUE); + IF old direction = error (* Bei Fehlern immer stehenbleiben *) + THEN TRUE + ELIF index = max index (* am Schluss aufhören oder nach 1 springen *) + THEN perhaps end + ELIF index = 1 AND old direction = up (* bei 1 und up an den Schluss *) + THEN index := max index; TRUE + ELSE normal new index (* sonst je nach direction up oder down *) + FI. + +perhaps end : (* index = max index *) + IF old direction = up AND max index > 1 (* hoch vom Ende *) + THEN index DECR 1; + TRUE + ELIF old direction = up + THEN TRUE + ELIF old direction = down (* runter am Ende *) + THEN index := 1; + TRUE + ELSE reset direction (FALSE); (* normal oder runter ans Ende *) + index := 1; + BOOL CONST ready :: yes (1, 23, "Fertig", FALSE); + reset direction (TRUE); + NOT ready + FI. + +normal new index : + IF old direction = up + THEN index DECR 1; TRUE + ELSE index INCR 1; TRUE FI. +END PROC new index; + +(******************** channel (table) handling *****************************) + +BOOL PROC channel free (INT CONST nr, + ROW 256 INT CONST channel table of shard) : + IF nr < 0 OR nr > nr of channels total + THEN FALSE + ELSE channel table of shard [index ccb offset] = 0 FI. + +index ccb offset : + 2 * nr + 1 + 1. +END PROC channel free; + +BOOL PROC channel free (INT CONST nr) : + channel free (nr, channel table of new shard). +END PROC channel free; + +PROC reserve channel (INT CONST nr, + ROW 256 INT VAR channel table of shard) : + IF nr >= 0 AND nr < nr of channels total + THEN channel table of shard [index ccb offset] := 1 (* nichtnull *) FI. + +index ccb offset : + 2 * nr + 1 + 1. (* Start nicht bei 0 und ccb hinter dtcb *) +END PROC reserve channel; + +PROC reserve channel (INT CONST nr) : + reserve channel (nr, channel table of new shard). +END PROC reserve channel; + +(*THESAURUS PROC free channels (ROW 256 INT VAR channel table of shard): + (* Liefert einen THESAURUS, der die Klartextform genau aller in + channel table of shard als frei angegebenen Kanäle enthält. + *) + INT VAR i; + THESAURUS VAR result :: empty thesaurus; + FOR i FROM 1 UPTO nr of channels total REP + IF channel free (i, channel table of shard) + THEN insert (result, text (i)) FI + PER; + result. +END PROC free channels;*) + +INT PROC channels of this module : + channels of module. +END PROC channels of this module; + +(********************* write info, buffer adress **************************) + +PROC write info : + putline (actual info) +END PROC write info; + +INT PROC buffer address (INT CONST buffer size): + IF new shard length MOD 2.0 <> 0.0 THEN new shard length INCR 1.0 FI; + INT CONST buf adr := unsigned (new shard length); + new shard length INCR real (buffer size); + IF new shard length >= 65536.0 OR buffer size > 1024 + THEN errorstop ("zu großer Puffer verlangt") + FI; + buf adr +END PROC buffer address; + +(************************* Hilfsprozeduren *******************************) + +PROC elan (INT CONST mode, DATASPACE CONST source, TEXT CONST line, + INT VAR start module nr, BOOL CONST new init, ins, dump, lst, + sys, coder, rt check, sermon) : + EXTERNAL 256 +END PROC elan; + +PROC do (TEXT CONST long line) : + DATASPACE VAR ds; + INT VAR module nr :: 0; + elan (2, ds, long line, module nr, FALSE, FALSE, FALSE, FALSE, + FALSE, FALSE, FALSE, FALSE); + forget (ds); + no do again +END PROC do; + +PROC go on : + put (" >>>>> Taste drücken zum Weitermachen "); + REPEAT UNTIL incharety (2) = "" PER; + pause; + line. +END PROC go on; + +END PACKET setup eumel modulkonfiguration; + -- cgit v1.2.3