home *** CD-ROM | disk | FTP | other *** search
- UNIT jobs; {$project vt }
- { Job-Verwaltung zum Programm VideoText }
-
- INTERFACE; FROM vt USES datei;
-
- VAR editor,configpath: str80;
- toplevel: Integer;
- active: Byte; { aktive Jobs in der Seitensuche }
- maxwait, burst,shuffle: Integer;
- i2c_snooze: Boolean;
-
- PROCEDURE sleep;
- PROCEDURE wakeup;
- PROCEDURE kill_queue;
- PROCEDURE handle_queue;
- PROCEDURE handle_jobs;
- PROCEDURE attempt_input(job: Integer);
- PROCEDURE add_job(entry: str80; blind: Boolean);
- PROCEDURE kill_job(nr: Integer);
- PROCEDURE cancel_job(entry: str80);
- PROCEDURE hurricane;
- PROCEDURE page_grabber(filter: Boolean);
- PROCEDURE topgrab(pg0: p_onepage);
- PROCEDURE getconfig(nr: Integer);
- FUNCTION edconfig(nr: Integer): Boolean;
- PROCEDURE dump_numbers;
-
- { ---------------------------------------------------------------------- }
-
- IMPLEMENTATION;
-
- {$ opt q,s+,i+} { keine Laufzeitprüfungen außer Stack und Feldindizes }
-
- CONST SERMAG = $0800; { C11 }
- RENEW = $0100; { C8 }
- STITLE = $0040; { C6 }
- HEADLN = $0020; { C5 }
-
- VAR bedtime: zeiteintrag;
-
- PROCEDURE uhrzeit(VAR zeit: zeiteintrag);
- BEGIN
- telltime(zeit.tage,zeit.min,zeit.tics);
- END;
-
- PROCEDURE add_time(delta: zeiteintrag; VAR zeit: zeiteintrag);
- BEGIN
- IF zeit.tics + delta.tics>=3000 THEN Inc(zeit.min);
- zeit.tics := (zeit.tics + delta.tics) MOD 3000;
- IF zeit.min + delta.min>=1440 THEN Inc(zeit.tage);
- zeit.min := (zeit.min + delta.min) MOD 1440;
- zeit.tage := zeit.tage + delta.tage;
- END;
-
- PROCEDURE sub_time(delta: zeiteintrag; VAR zeit: zeiteintrag);
- BEGIN
- IF zeit.tics - delta.tics<0 THEN Dec(zeit.min);
- zeit.tics := (zeit.tics - delta.tics + 3000) MOD 3000;
- IF zeit.min - delta.min<0 THEN Dec(zeit.tage);
- zeit.min := (zeit.min - delta.min + 1440) MOD 1440;
- zeit.tage := zeit.tage - delta.tage;
- END;
-
- FUNCTION diff_time(alt, neu: zeiteintrag): Long;
- { liefert die Differenz zwischen zwei Zeitpunkten in Ticks (1/50-Sekunden) }
- BEGIN
- diff_time := neu.tics - alt.tics + 3000 * ( (neu.min - alt.min)
- + 1440 * (neu.tage - alt.tage) );
- END;
-
- PROCEDURE sleep;
- { wird vor Unterbrechung der Hauptschleife (z. B. durch FileRequester) }
- { aufgerufen }
- BEGIN
- uhrzeit(bedtime);
- END;
-
- PROCEDURE wakeup;
- { Verhindert in Zusammenarbeit mit sleep, daß Zeiten, während derer der }
- { VT-Decoder gar nicht abgefragt wird, zum Löschen von Jobs wegen }
- { Zeitüberschreitung führen. }
- VAR delta: zeiteintrag;
- j: Integer;
- BEGIN
- uhrzeit(delta);
- sub_time(bedtime,delta);
- FOR j := 0 TO maxactive-1 DO
- add_time(delta,activejobs[j].lastaction);
- END;
-
- PROCEDURE kill_queue;
- VAR i: Integer;
- BEGIN
- queued := 0;
- IF thisjob<0 THEN thisjob := 0;
- FOR i := 0 TO maxactive-1 DO BEGIN
- activejobs[i].pg := 0; sperren(i);
- END;
- END;
-
- PROCEDURE count_them;
- { durchzählen, wer in der Seitensuche alles bedient werden will: }
- VAR j: Integer;
- BEGIN
- active := 0;
- FOR j := 0 TO maxactive-1 DO
- IF (activejobs[j].pg>0) THEN Inc(active);
- END;
-
- PROCEDURE handle_queue;
- { Verwaltet das Aufrücken wartender Jobs. }
- { Jobs mit unbestimmter Unterseitennummer, also mit /0, /*, /., /! können }
- { aktive Jobs mit gleicher Seitennummer aus der Seitensuche verdrängen }
- VAR i,j,killer,moved: Integer;
- BEGIN
- moved := 0;
- REPEAT
- j := -1;
- IF queued>0 THEN BEGIN
- { Soll ein aktiver Job verdrängt werden? }
- IF queue[firstinq].sp<1 THEN
- FOR i := 0 TO maxactive-1 DO
- IF activejobs[i].pg=queue[firstinq].pg THEN j := i;
- { Oder ist ein Platz in der Seitensuche frei? }
- IF j<0 THEN
- FOR i := maxactive-1 DOWNTO 0 DO
- IF activejobs[i].pg=0 THEN j := i;
- END;
- IF j>=0 THEN BEGIN
- { Empfangseinheit <j> mit wartendem Job belegen }
- { Ein wartender Job besteht nur aus Seiten- und Unterseitennummer, }
- { jetzt kommen eine Menge Informationen dazu. }
- WITH activejobs[j] DO BEGIN
- pg := queue[firstinq].pg; sp := queue[firstinq].sp;
- sp_count := 0; sp_max := 0;
- holen := False; erledigt := False;
- FOR i := 0 TO maxsubpage DO sp_check[i] := False;
- uhrzeit(lastaction);
- anfordern(j,pg,sp,%111);
- END;
- IF i2c_status<>0 THEN BEGIN { Oh Mann! Dummer I²C-Bus! }
- activejobs[j].pg := 0; { Kommando zurück }
- j := -1; { hier ist nichts mehr zu holen }
- END ELSE BEGIN
- { Warteschlange aufrücken: }
- Dec(queued); Inc(firstinq); IF firstinq>qlen THEN firstinq := 1;
- { Auswahlzeiger des Benutzers dem Aufrücken entsprechend nachführen: }
- IF thisjob=-1 THEN thisjob := j
- ELSE IF thisjob<0 THEN Inc(thisjob);
- IF thisjob>=0 THEN BEGIN
- aktspeicher := thisjob; display_select(aktspeicher); END;
- Inc(moved);
- END;
- END;
- UNTIL j=-1;
- IF moved>0 THEN redraw_queue(-1);
- count_them;
- END;
-
- PROCEDURE requeue(i: Integer; fifo: Boolean);
- { einen aktiven Job in die Warteschlange zurückstellen }
- VAR j: Integer;
- BEGIN
- IF (queued<qlen) AND (activejobs[i].pg>0) THEN BEGIN
- IF fifo THEN BEGIN
- j := firstinq+queued; IF j>qlen THEN j := 1;
- END ELSE BEGIN
- Dec(firstinq); IF firstinq=0 THEN firstinq := qlen; j := firstinq;
- END;
- Inc(queued);
- queue[j].pg := activejobs[i].pg; queue[j].sp := activejobs[i].sp;
- END;
- activejobs[i].pg := 0; sperren(i);
- END;
-
- PROCEDURE rausschmeisser;
- { Prüfen, ob ein Job wegen Zeitüberschreitung gestrichen werden kann. }
- { Wenn der Job allerdings so lange wartet, weil er sich auf eine einzelne }
- { Unterseite bezieht, ist ihm verziehen und er wird lediglich ans Ende der }
- { Warteschlange gesetzt. Und für festgehaltene Seitennummern findet eine }
- { Prüfung auf Zeitüberschreitung gar nicht erst statt. }
- VAR i, j: Integer;
- jetzt: zeiteintrag;
- BEGIN
- uhrzeit(jetzt);
- FOR j := 0 TO maxactive-1 DO WITH activejobs[j] DO
- IF (pg<>0) AND (diff_time(lastaction,jetzt) > 50*maxwait)
- AND (sp>-2) THEN { keine "festgehaltenen" Seiten! }
- IF sp IN [0,-1] THEN BEGIN
- { einfache Seitennummer streichen }
- pg := 0; sperren(j); redraw_queue(j);
- END ELSE IF queued>0 THEN BEGIN
- { Unterseitenanforderung nur hintenanstellen }
- requeue(j,True); redraw_queue(-1);
- END;
- count_them;
- END;
-
- PROCEDURE handle_jobs;
- { Überprüft, ob in einem der Empfangskreise eine Seite eingetroffen ist, und }
- { wenn ja, ob sie aufgrund ihrer Unterseitennummer überhaupt eingelesen }
- { werden muß. Es wird auch entschieden, ob der Job durch die eingetroffene }
- { Seite erledigt ist. Kriterium für 'erledigt': }
- { Ein Job mit sp>0 ist erledigt, sobald die eine angeforderte Unterseite }
- { da ist. Ein Job mit sp=0 ist erst dann erledigt, wenn alle seine }
- { Unterseiten eingelesen wurden. Wann das ist, läßt sich nur raten, aber }
- { ganz gut raten. Und es gibt noch einige Sonderfälle mit sp<0 ... }
- VAR j: Integer;
- dummy: p_onepage;
- sp_decval: Integer;
- BEGIN
- rausschmeisser;
- { Schauen, ob irgendwo das Eintreffen einer Kopfzeile gemeldet wurde: }
- FOR j := 0 TO maxactive-1 DO WITH activejobs[j] DO
- IF (pg>0) AND NOT holen THEN IF seite_da(j) THEN BEGIN
- New(dummy);
- uhrzeit(lastaction);
- getpage(j,dummy,False); { *nur* Status und Seitennummer holen }
- akt_sp := dummy^.sp;
- sp_decval := get_bcd(akt_sp);
- { *** Schauen, ob die Seite eingelesen werden muß. Gründe, weswegen }
- { man eine Seite evtl. nicht haben will: }
- { 1.: Unterseite wurde bereits eingelesen. }
- { (Bei zu großen Unterseitennummern kann das nur über ein etwas }
- { armseliges Hilfskriterium festgestellt werden.) }
- IF (sp_decval<=maxsubpage) THEN holen := NOT sp_check[sp_decval]
- ELSE holen := (akt_sp>sp_max);
- { 2.: Nur eine Unterseite war angefordert, und zwar nicht diese. }
- { Das dürfte allerdings kaum vorkommen, da der CCT ausdrücklich auf }
- { die eine Unterseite programmiert wurde. }
- IF sp>0 THEN holen := (akt_sp=sp);
- { Selbstnumerierende Unterseiten werden blind alle eingelesen, bis }
- { der Job erledigt ist: }
- IF sp<-10 THEN BEGIN
- holen := True; akt_sp := make_bcd(sp_count+1);
- IF sp=-11 THEN akt_sp := 0;
- sp_decval := get_bcd(akt_sp);
- END;
- IF holen THEN BEGIN
- { *** Unterseitenverwaltung aktualisieren: }
- Inc(sp_count);
- IF (sp_decval<=maxsubpage) THEN sp_check[sp_decval] := True;
- IF akt_sp>sp_max THEN sp_max := akt_sp;
- redraw_queue(j);
- { *** Schauen, ob magazinserielle oder -gemischte Übertragung }
- { vorliegt und danach die Wartezeit festlegen: }
- IF (dummy^.cbits AND SERMAG)=0 THEN
- wartezeit := shuffle ELSE wartezeit := burst;
- END ELSE
- anfordern(j,pg,sp,%111); { blöde Unterseite, Suche fortsetzen }
- { *** Prüfen, ob der Job durch die eingetroffene Seite erledigt ist. }
- { Das geht z. B. durch Unterseite 0 (= einzige Unterseite). }
- { auf keinen Fall aber durch eine Unterseite mit der bislang }
- { höchsten Nummer. }
- IF sp_check[0] THEN
- erledigt := sp_count>get_bcd(sp_max)
- ELSE IF akt_sp<sp_max THEN
- erledigt := sp_count=get_bcd(sp_max);
- { Auch möglich: die einzig geforderte Unterseite ist da. }
- IF ((sp>0) OR (sp=-1)) AND holen THEN
- erledigt := True;
- { Oder es sind genauso viele selbstnumerierende Unterseiten }
- { eingetroffen, wie angefordert waren. }
- IF (sp<-10) THEN
- erledigt := (sp_count=-sp-10);
- { überwachte Seiten sind aus kosmetischen Gründen immer "erledigt": }
- IF (sp=-2) OR (sp=-3) THEN
- erledigt := True;
- Dispose(dummy);
- END;
- END;
-
- PROCEDURE attempt_input{(job: Integer)};
- { Das Einlesen geschieht in einem zweiten Schritt, da nach Eintreffen der }
- { Kopfzeile erst eine Weile gewartet werden muß. }
- { Evtl. wird die Seite auch gleich ausgegeben: auf dem Bildschirm, falls }
- { <thisjob> auf den zugehörigen Job zeigt oder wenn eine festgehaltene }
- { Seite aktualisiert wurde; in die Ausgabedatei, falls es eine zu }
- { protokollierende Seite war. }
- { Jobs, die nach diesem Einlesen erledigt sind, wurden bereits entsprechend }
- { gekennzeichnet und werden aus der Liste gestrichen. }
- VAR dummy,seite: p_onepage;
- jetzt: zeiteintrag;
- exciting: Boolean;
- i: Integer;
- BEGIN
- { Prüfen, ob die Wartezeit für eine einzulesende Seite um ist: }
- WITH activejobs[job] DO
- IF (pg>0) AND holen THEN BEGIN
- uhrzeit(jetzt);
- IF diff_time(lastaction,jetzt) >= wartezeit THEN BEGIN
- { Seite einlesen: }
- IF i2c_snooze THEN busy_pointer;
- { Ist bereits eine alte Version dieser Seite in der Liste, die dann }
- { lediglich überschrieben werden müßte? }
- seite := hunt_in_list(pg,akt_sp,True);
- IF seite=Nil THEN BEGIN
- New(seite);
- getpage(job,seite,True);
- IF i2c_snooze THEN normal_pointer;
- IF sp<-10 THEN seite^.sp := akt_sp; { selbstnumerierende Seite! }
- add_sp_number(seite);
- IF i2c_status<>0 THEN BEGIN Dispose(seite); Exit; END;
- ins_to_list(seite);
- update_list(seite,1);
- END ELSE BEGIN
- getpage(job,seite,True);
- IF i2c_snooze THEN normal_pointer;
- IF sp<-10 THEN seite^.sp := akt_sp; { selbstnumerierende Seite! }
- add_sp_number(seite);
- IF i2c_status<>0 THEN Exit;
- IF seite<>thispage THEN update_list(seite,0);
- END;
- { bildschirmüberwachte Seiten sind interessant, wenn sie das erste }
- { Mal eintreffen oder wenn sich der Inhalt geändert hat: }
- exciting := (sp=-2) AND ((sp_count=1) OR (seite^.cbits AND RENEW<>0))
- AND (seite^.cbits AND STITLE=0) AND (seite^.sp=0);
- { Untertitel und Mehrfachseiten aber ausgenommen! }
- { bildschirmüberwachte Seite anzeigen: }
- IF (seite=thispage) OR exciting THEN BEGIN
- mainline;
- IF exciting THEN showscreen(True);
- IF seite<>thispage THEN BEGIN
- Write('neuer Inhalt S. ',hexstr(pg,3),'!');
- writepage(seite,True);
- mainline; Write('bitte Leertaste dr}cken');
- END ELSE
- writepage(seite,True);
- END;
- { dateiüberwachte Seite abspeichern: }
- IF sp=-3 THEN
- IF (sp_count=1) OR (seite^.cbits AND RENEW<>0) THEN BEGIN
- sleep; IF save_action(seite,1)=0 THEN BEGIN
- { nach einmal genehmigtem Überschreiben auf Anhängen umschalten: }
- overwrite := False; fileinfo;
- END ELSE
- sp_count := 0; { nach fehlgeschlagenem Speichern }
- { sofort beim nächsten Mal wieder versuchen lassen }
- wakeup;
- END ELSE
- mainline;
- holen := False; { beendet auch "Schonfrist" für erledigte Jobs }
- anfordern(job,pg,sp,%111); { um PBLF wieder zu setzen }
- END;
- END;
- { Erledigten (und eingelesenen) Job löschen: }
- WITH activejobs[job] DO
- IF (pg>0) AND erledigt AND NOT holen THEN BEGIN
- IF (sp IN [-2,-3]) THEN BEGIN { Sonderfälle: niemals erledigt }
- { nur die Zähler zurücksetzen, außer sp_count }
- sp_max := 0; erledigt := False;
- FOR i := 0 TO maxsubpage DO sp_check[i] := False;
- END ELSE BEGIN
- pg := 0; sperren(job); { löschen }
- END;
- redraw_queue(job);
- END;
- count_them;
- END;
-
- PROCEDURE add_job{(entry: Str80; blind: Boolean)};
- { Eine Eingabe, die eine Seitennummer darstellt (oder auch nicht), in die }
- { Warteschlange einzureihen versuchen. }
- { Bei blind=False wird noch überprüft, ob sich vielleicht bereits ein }
- { identischer Job in der Seitensuche befindet. }
- { Anschließend zeigt <thisjob> auf die neu besetzte Stelle. }
- VAR i,j,page,subpage: Integer;
- s: str80;
- ok: Boolean;
- BEGIN
- i := Pos('-',entry);
- j := Pos('/',entry);
- IF i > 0 THEN BEGIN
- page := hexval(Copy(entry,1,i-1));
- Val(Copy(entry,i+1,Length(entry)-i),subpage,i); { Anzahl nicht als BCD! }
- subpage := -10-subpage;
- END ELSE IF j > 0 THEN BEGIN
- page := hexval(Copy(entry,1,j-1));
- subpage := hexval(Copy(entry,j+1,Length(entry)-j));
- IF entry[j+1]='*' THEN subpage := -1;
- IF entry[j+1]='.' THEN subpage := -2;
- IF entry[j+1]='!' THEN subpage := -3;
- END ELSE BEGIN
- page := hexval(entry);
- subpage := 0;
- END;
- ok := (page>=$100) AND (page<$900);
- { evtl. weitere Einschränkung: mit bereits vorhandenen Jobs vergleichen }
- { und keinen Job zulassen, der ein Verdrängen bewirken würde }
- IF NOT blind THEN BEGIN
- FOR j := 0 TO maxactive-1 DO
- IF (activejobs[j].pg=page) AND (subpage<1) THEN ok := False;
- FOR j := 1 TO queued DO BEGIN
- i := (firstinq + j - 2) MOD qlen + 1;
- IF (queue[i].pg=page) AND (subpage<1) THEN ok := False;
- END;
- END;
- IF ok AND (queued<qlen) THEN BEGIN
- Inc(queued);
- IF fifo THEN BEGIN
- j := firstinq+queued-1; IF j>qlen THEN j := 1;
- thisjob := -queued;
- END ELSE BEGIN
- Dec(firstinq); IF firstinq=0 THEN firstinq := qlen; j := firstinq;
- thisjob := -1;
- END;
- queue[j].pg := page; queue[j].sp := subpage;
- END;
- END;
-
- PROCEDURE kill_job{(nr: Integer)};
- { einen Job löschen, <thisjob> nachführen, Bildschirm aber *nicht* }
- { aktualisieren }
- VAR j: Integer;
- BEGIN
- IF nr>=0 THEN BEGIN { aktiver Job }
- activejobs[nr].pg := 0;
- sperren(nr);
- END ELSE IF (-nr<=queued) THEN BEGIN { wartender Job }
- FOR j := -nr TO queued-1 DO
- queue[(firstinq+j-2) MOD qlen + 1] :=
- queue[(firstinq+j-1) MOD qlen + 1];
- Dec(queued);
- IF fifo AND (thisjob<=nr) THEN Inc(thisjob); { normal: thisjob=nr }
- IF -thisjob>queued THEN Inc(thisjob);
- END;
- END;
-
- PROCEDURE cancel_job{(entry: str80)};
- { Als Erleichterung gegenüber kill_job() wird nicht die Position in der }
- { Warteschlange sondern der 'Name' des Jobs angegeben. }
- VAR page,j: Integer;
- BEGIN
- page := hexval(Copy(entry,1,3));
- FOR j := 0 TO maxactive-1 DO
- IF activejobs[j].pg=page THEN kill_job(j);
- FOR j := -queued TO -1 DO
- IF queue[(-j+firstinq-2) MOD qlen + 1].pg=page THEN kill_job(j);
- END;
-
- PROCEDURE hurricane;
- { Die Seiten aus der Seitensuche zurück in die Warteschlange fegen. }
- VAR j: Integer;
- BEGIN
- FOR j := 0 TO maxactive-1 DO
- requeue(j,False);
- END;
-
- PROCEDURE page_grabber{(filter: Boolean)};
- { Rechenzeitintensive Variante der Seitensuche: alle Seiten einlesen, wie }
- { sie kommen. Für <filter>=True werden nur Seiten mit rein dezimaler }
- { Seitennummer gelesen, Pseudoseiten also herausgefiltert. }
- { Prinzip des Algorithmus: }
- { Kreis 3 Kreis 2 Kreis 1 Kreis 0 (nach aufsteigender Priorität) }
- { * x x x | }
- { ===== * | === Kopfzeile * anfordern }
- { ----- | --- Folgezeile x sperren }
- { ----- | ^^^ Seite komplett }
- { ^^^^^ ===== * | }
- { ----- | Gesucht wird i. a. nach Seite }
- { ----- | "???", bei magazinparalleler }
- { ^^^^^ ===== * | Übertragung dagegen nach "X??", }
- { ----- | wobei X=1..8 für alle 4 Kreise }
- { ----- | gleich sein muß. }
- { ^^^^^ ===== | }
- { Jetzt sind die Seiten in 3, 2 und 1 stabil und komplett und können }
- { ausgelesen werden. }
- { Eine ganz naheliegende Idee wäre es, 3 und 2 bereits auszulesen, noch }
- { während man in 1 bzw. 0 auf Kopfzeilen wartet. }
- { Andererseits ist es wichtig, bereits die erste Seite, die nach der }
- { Anforderung eintrifft, im jeweiligen Kreis einzufrieren. Für alle }
- { danach eintreffenden Seiteninhalte wird der Speicher nämlich nicht mehr }
- { extra gelöscht, so daß unvollständig definierte Seiten (Schlagzeilen }
- { z. B.) mit ihren Vorgängern verschmelzen, was nicht so toll aussieht. }
- { Diese zeitoptimale Methode ist darum nur bei magazinparalleler }
- { Übertragung bedenkenlos möglich. Dort treffen aufeinanderfolgende }
- { Seiten eines Magazins nur ca. alle 0.8 sec ein, und so schnell geht das }
- { Einlesen über den I²C-Bus noch allemal (ca. 0.4 sec/Seite). }
- VAR i,mag,anz,neu: Integer;
- seite,dummy: p_onepage;
- timeout,parmode: Boolean;
- PROCEDURE waitforpg(unit: Integer);
- { max. 2 Sekunde auf das Eintreffen einer Seite warten }
- VAR t0,t: zeiteintrag;
- BEGIN
- uhrzeit(t0);
- REPEAT
- uhrzeit(t); timeout := diff_time(t0,t)>100;
- UNTIL seite_da(unit) OR timeout;
- END;
- PROCEDURE einlesen(unit: Integer);
- { neue Seite einlesen und einreihen }
- BEGIN
- getpage(unit,dummy,False);
- IF (make_bcd(get_bcd(dummy^.pg))=dummy^.pg) OR NOT filter THEN BEGIN
- Inc(anz); seite := hunt_in_list(dummy^.pg,dummy^.sp,True);
- IF seite=Nil THEN BEGIN
- New(seite); Inc(neu);
- getpage(unit,seite,True); add_sp_number(seite); ins_to_list(seite);
- END;
- END;
- END;
- BEGIN
- New(dummy);
- anz := 0; neu := 0;
- hurricane; redraw_queue(-1); { Seitensuche freimachen }
- REPEAT
- FOR i := 0 TO 2 DO sperren(i);
- anfordern(3,$100,0,%000);
- waitforpg(3); getpage(3,dummy,False);
- parmode := (dummy^.cbits AND SERMAG)=0;
- IF parmode THEN BEGIN { magazinparallele Sendefolge ;-\ }
- FOR i := 3 DOWNTO -1 DO IF NOT timeout THEN BEGIN
- { indirektes Sperren von (i+1): }
- IF i>-1 THEN anfordern(i,dummy^.pg,0,%100)
- { Die Seite in (i+2) ist bereits komplett und stabil: }
- IF i<2 THEN einlesen(i+2);
- { jetzt auf die zuletzt angeforderte Seite warten: }
- IF i>-1 THEN waitforpg(i);
- END
- END ELSE BEGIN { normale, magazinserielle Sendefolge }
- FOR i := 2 DOWNTO 0 DO IF NOT timeout THEN BEGIN
- { (i+1) sperren und auf die nächste Seite warten: }
- anfordern(i,$100,0,%000); waitforpg(i);
- END;
- { alle kompletten Seiten einlesen: }
- IF NOT timeout THEN
- FOR i := 3 DOWNTO 1 DO einlesen(i);
- END;
- mainline; Write(anz,' Seiten gefunden, ',neu,' gelesen');
- event_scan;
- UNTIL newevent OR timeout;
- IF timeout THEN BEGIN
- mainline; Write('keine neuen Seiten - Abbruch');
- END;
- Dispose(dummy);
- END;
-
- PROCEDURE topgrab{(pg0: p_onepage)};
- { alle laut TOP-Text verfügbaren Seiten anfordern, allerdings nur bis zu }
- { der durch <toplevel> vorgegebenen Priorität }
- CONST interleave=10;
- VAR i,j,n,level: Integer;
- pri: ARRAY[0..17] OF Char;
- BEGIN
- pri := '-KABCDEFHGJI-----';
- FOR level := 1 TO toplevel DO
- FOR i := 0 TO interleave-1 DO
- FOR j := 0 TO 799 DIV interleave DO BEGIN
- n := 100 + j*interleave + i;
- IF (n<900) THEN BEGIN
- IF Ord(pri[topcode[pg0^.chars[n-60]]])-64=level THEN
- add_job(IntStr(n),True); { nach absteigender Priorität }
- END;
- END;
- redraw_queue(-1);
- END;
-
- PROCEDURE getconfig{(nr: Integer)};
- VAR datei: Text;
- sender, zeile, name: str80;
- is_header, found, anything, save_fifo: Boolean;
- t: Integer;
- BEGIN
- IF activejobs[0].pg=0 THEN BEGIN
- anfordern(0,$100,0,%000);
- t := 50; { max. 1 sec warten! }
- REPEAT Delay(1); Dec(t) UNTIL seite_da(0) or (t=0);
- END;
- gethead(0,sender);
- IF activejobs[0].pg=0 THEN sperren(0);
- IF nr=2 THEN name := configpath+'VT2.config'
- ELSE name := configpath+'VT.config';
- Reset(datei,name);
- IF IOResult<>0 THEN BEGIN
- mainline; Write(#155'2m"',name,'" nicht gefunden!');
- add_job('100',False);
- redraw_queue(-1);
- Exit;
- END;
- Buffer(datei,500);
- found := False; anything := False;
- is_header := True;
- save_fifo := fifo; fifo := True;
- WHILE NOT EoF(datei) DO BEGIN
- ReadLn(datei,zeile);
- t := Length(zeile); WHILE t>0 DO BEGIN
- IF zeile[t]=' ' THEN zeile[t] := #0 ELSE t := 1;
- Dec(t);
- END;
- IF zeile='' THEN
- is_header := True { auf eine Leerzeile folgt ein Titel }
- ELSE BEGIN
- IF is_header THEN BEGIN
- found := (Pos(zeile,sender)>0);
- IF found THEN BEGIN
- mainline; Write('hole '); IF nr>1 THEN Write(nr,'. ');
- Write('Seitenauswahl f}r "',zeile,'"');
- anything := True;
- END;
- END ELSE
- IF found THEN add_job(zeile,True);
- is_header := False;
- END;
- END;
- IF NOT anything THEN BEGIN
- Write('unbekannter Sender: "',Copy(sender,5,10),'"');
- add_job('100',False);
- END;
- Close(datei);
- fifo := save_fifo;
- redraw_queue(-1);
- END;
-
- FUNCTION edconfig{(nr: Integer): Boolean};
- VAR fenster: Text;
- s: Str80;
- LIBRARY DosBase: { Include-Files nein danke }
- -222 : FUNCTION Execute(D1: Str; D2,D3: Long): Boolean;
- END;
- BEGIN
- showscreen(False);
- Reset(fenster,'CON:100/100/440/80/VT-Ausgabefenster');
- IF nr=2 THEN s := editor + configpath + 'VT2.config'
- ELSE s := editor + configpath + 'VT.config';
- edconfig := Execute(s,0,FileHandle(fenster));
- Close(fenster);
- showscreen(True);
- END;
-
- PROCEDURE dump_numbers;
- { Sendername und Seitennummern ins Clipboard schreiben, Hilfe beim Erstellen }
- { der config-Dateien }
- VAR anz,nextnr,i: Integer;
- hilf: p_onepage;
- ok: Boolean;
- s: str80;
- BEGIN
- IF root=Nil THEN Exit;
- anz := 0; hilf := root;
- WHILE hilf<>Nil DO BEGIN
- IF hilf^.next=Nil THEN nextnr := -1 ELSE nextnr := hilf^.next^.pg;
- IF (hilf^.pg<$900) AND (hilf^.pg<>nextnr) THEN Inc(anz);
- hilf := hilf^.next;
- END;
- start_clip(26+4*anz);
- FOR i := 2 TO 25 DO BEGIN
- s[i] := Chr(root^.chars[i+6]);
- IF s[i]<' ' THEN s[i] := ' ';
- END;
- s[1] := #10; s[26] := #10; s[27] := #0;
- clip_it(s,26);
- hilf := root;
- WHILE hilf<>Nil DO BEGIN
- IF hilf^.next=Nil THEN nextnr := -1 ELSE nextnr := hilf^.next^.pg;
- IF (hilf^.pg<$900) AND (hilf^.pg<>nextnr) THEN BEGIN
- s := hexstr(hilf^.pg,3)+#10; clip_it(s,4);
- END;
- hilf := hilf^.next;
- END;
- end_clip;
- END;
-
- BEGIN { Initialisierungen }
- editor := 'c:Ed '; { Editor für configs }
- configpath := '';
- toplevel := 4; { nur Programm- und Blockseiten }
- maxwait := 80;
- burst := 0;
- shuffle := 20;
- i2c_snooze := False; { kein Busy-Pointer beim Lesen von Seiten! }
- END.
-