DataMuseum.dk

Presents historical artifacts from the history of:

RC3500

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC3500

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦472a8e846⟧ TextFileVerbose

    Length: 14592 (0x3900)
    Types: TextFileVerbose
    Names: »alcjob«

Derivation

└─⟦a41ae585a⟧ Bits:30001842 SW-save af projekt 1000, Alarm-system
    └─⟦72244f0ef⟧ 
        └─⟦this⟧ »alcjob« 

TextFileVerbose

job hj 2 200 time 11 0 area 10 size 100000
source = edit hdlctxt
m e
g b/reclev/port/
l t, p
l./hdlc/, d, i/
process alc (                (*  asynchr link control     *)
  var sem : !ts_pointer;     (*  main semaphore           *)
  var lamsem: !sempointer;   (*  lam driver sem           *)
  port : byte    );          (*  lam port used            *)
/,
l./testmax/,   r/127/31/,
l./field/,   d,   i/
commandfield = byte;
/,
l./,ffo,/,  d2,  i/
 lambits, res : byte;
/,
l./field/,  r/commandfield/byte/,
l./flag/,   i/

array6 = array (1..6) of integer;
array8 = array (0..7) of integer;

statistics = record                       (*  for statistics     *)
 na1, na2, na3 : integer;          (*  not used         *)
 recnu,    recs,                   (*     -    , received blocks   *)
 tranu,    trans,                  (*     -    , transmitted blocks *)
 skipnu,   skips,                  (*     -    , give ups           *)
 retrnu,  retrans : integer;       (*      -   , retransmissions    *)
 rec_rnr,                          (*  last received rec error      *)
 xmt_rnr,                          (*  last received xmt error status  *)
 rec_rej,                          (*  timeouts after enq          *)
 xmt_rej,                          (*  waits for xmt               *)
 ack_times,                        (*  timeouts after data          *)
 dsr, dcd, sqd,                    (*  lambit  12  11  10  off   *)
 ci :               integer;       (*  lam u4   lam u2        *)
 last_rec,                         (*  last opcode received       *)
 last_xmt : byte;                  (*  last opcode transmitted    *)
 xmterr, recerr :   integer;       (*  times when u2 <> 0 and 5  *)
 fut : array6;                     (*  counter(lam u2 div 8)      *)
 bits : array8;                    (*  lambit 13..15              *)
end;

statetype = ( discon, connec, idle, wack, wrep );     (*  xstate   *)
inputtype = ( data, ackn, enqu, rese, nons );
arow = array (inputtype) of byte;
actiontabletype = array ( connec..wrep) of arow;
/,
l./const/,
l1,   d./z=8/,
i/
  maxinputs = 2;
  alc_control = 0+4+24+96;       (*  8 data, odd par, 2 stop, 1200 bps  *)
  alc_time = 4;

  zeroes = statistics (
   0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
   0,0,0,0,0, 0,0,0,0, array6(6***0), array8(8***0) );

  timeru3 = 250;         (*  250,2 = 1000 = 1 sec   *)
  timeru4 = 2;

  send_ok = 0;
  down   = 1;
  trouble = 1+8;
  waiting = 10;
  nonsens = 26;
  discp = 99;

  enq    = 5;              (*  operation codes     *)
  reset  = 21;
  ack_0  = 19;
  ack_1  = ack_0+1;
  data_0 = 28;
  data_1 = data_0+1;
  codediff = data_0 - ack_0;

 actiontable =
 actiontabletype (
                    (*              data   ack   enq  reset  nons    *)
                    (*connec*) arow(  3,    2,    7,    1,    0 ),
                    (* idle *) arow(  3,    0,    7,    0,    0 ),
                    (* wack *) arow(  3,    4,    7,    0,    0 ),
                    (* wrep *) arow(  3,    5,    7,    6,    0 ));
/,
l./timer/,   r/1/6/,
l./recansw/,   r/2/read_it/,
l1,   r/3/write_it/,
l1,   r/4/create_it_ch/,
l./modemc/
d15,  l./var/,
i/

\f



var
/,
l1, d2,  i/
retrans, auto : boolean:= false;
/,
l./dok/,   r/sendok,//,
l./xstate/,  r/xstate,//,   l1, d3,
l./xmtle/,   r/xmtlev,//,   r/;/:= 0;/,
l./st: stat/,   d,   i/
 st: status;
/,
l./mx/,   r/b1,b2,//,   r/mw1,//,
r/cmdrbuf,recdev,xmtdev/pending/,
l./dow/,  d,
r/rec,xmt,//,  r/asem,qs1,//,
r/,s:/:/,
l1, r/4/3+maxinputs/,
l1,  r/4/1/,
l./cmdr/, d,
l./qs,/,   d7,   
i@

 xstate : statetype;    (*  process state          *)
 input  : inputtype;    (*  received from lam      *)
 lastack,               (*  save for enq   *)
 func,                  (*  returned u1           *)
 opk,                   (*  u3 to/from lam         *)
 action,                (*   selected action       *)
 modem_state,           (*   lambits div 8         *)
 result,                (*  for answer to router   *)
 block_no : byte;       (*  last send data code    *)
 mr : array (0..maxinputs-1) of reference;
 vcodes : array (1..6) of byte;         (*  saved opcodes  *)
 stc : statistics := zeroes;   (*  stat counters         *)

\f



@,
l./asgn/,
l1,  d10,
d./ure resetact/,   d2
i@


procedure exception ( cause: integer);
forward;


procedure event ( cause: integer);
forward;


procedure readlam;
(*                 send input request to lam driver    *)
  var um: reference;

begin
 if (bstate < maxinputs) and (xstate > discon) then
 begin
  if open ( ique) then
  begin
   wait ( um, ique);
   push ( mr(bstate), um);
   bstate:= bstate+1;
   um^.u2:= port;
   um^.u3:= data_0;      (*  gives check of first, last in lam  *)
  signal ( um, lamsem^);
 (*q  trace ( bstate);   q*)
end
 end
end;



procedure create_channel;
begin
 if not nil ( mc) then
 begin
  mc^.u2:= port;
   (*q  trace ( port*256+alc_control);   q*)
  signal ( mc, lamsem^)
 end
end;


\f



procedure getresult;
begin
 st.res:= m^.u2;
 st.lambits:= m^.u4;
 modem_state:= m^.u4 div 8;
 i:= m^.u4 mod 8;
 count ( stc.bits(i));
 stc.ci:= m^.u4*256+m^.u2;
 i:= m^.u2 div 8;
 if i> 0 then count ( stc.fut(i));
 if modem_state < 7 then
 begin
 if modem_state < 4 then count ( stc.sqd);
 if modem_state mod 2 = 0 then count ( stc.dsr);
 if modem_state mod 4 < 2 then count ( stc.dcd);
 if xstate >= idle then event ( 9);
 end
end;



\f


procedure release_buf;
begin
 pending^.u2:= result;
 pending^.u3:= port;
 return ( pending);
 result:= waiting;
 time:= -1;
end;




procedure trans ( transcode : byte);
begin
 if nil ( mx) then
 begin
  count ( stc.xmt_rej);
  vi:= vi+1;
  if vi > 6 then         (*  lam in exception or stopped    *)
  begin
   event ( 10);
   vi:= 2;
  end;
  vcodes(vi):= transcode;
 end  else
 begin
  mx^.u2:= port;
  mx^.u3:= transcode;
  signal ( mx, lamsem^);
  (*q  trace ( transcode);   q*)
  stc.last_xmt:= transcode;
  time:= t2;
 end
end;   (*  of trans  *)
\f





procedure transdata;
begin
       (*  pending and mx is not nil    *)
 mx^.u2:= port;
 mx^.u3:= block_no;
 push ( mx, pending);
 signal ( pending, lamsem^);
 (*q  trace ( block_no);   q*)
 stc.last_xmt:= block_no;
 time:= t2;
 result:= waiting;
 xstate:= wack;
end;





procedure block_ok;
begin
 result:= send_ok;
 if nil ( pending) then
 begin
  (*   ack received before lam xmt finished    *)
  event ( 4);
 end  else
 begin
  (* count ( xmt_cnt );    *)
  xstate:= idle;
  release_buf; (* pending *)
 end
end;

\f



procedure give_up ( cause : byte);
begin
 result:= cause;
 (*q  trace ( cause);   q*)
 count ( stc.skips);
 if nil ( pending) then
 begin
 (*    lam xmt is dead, when i give up    *)
  event ( 3);
 end  else
  release_buf;
 time:= t2;

 if xstate > connec then
 if auto then                      (*  try to connect again   *)
 begin
  event ( 11);
  xstate:= connec;
 end  else
 begin
  event ( 12);
  xstate:= discon;
 end
end;




procedure answer_stat;
begin
 lock m as buf: statistics do buf:= stc;
 m^.u2:= 0;
 m^.u3:= port;
 return ( m)
end;


\f


@,
l./ure otest/,   r/commandfield/byte/,
l./b:=bsta/,   r/xstate/ord(xstate)/,
l1,   r/send/nil(mx)/,
r/sendingiframe/nil(pending)/,
r/aborting/retrans/,
p
l./sensept/,  d7,
l./ure getres/,   d25,
l./ure event/,   l./if/,   i/
 (*q  trace ( cause);   q*)
/,
l./otest(8/,   l./sem/,   r/sem/sem.w^/,
l./u2:=3/,   r/3;/15*8+3;  u3:= port;/,
l./ure cmdrac/,  d9,
l./recp/,   d./until/,  d,
d./end;/
i/

\f



(*--------------------------- main program ----------------------------*)

/,
l./trace/,   r/0);/20);                  (*--------- version ---------*)/
l./xmt/,   
p
d15,
i@
 lastack:= reset;
 block_no:= data_1;
 xstate:= discon;
 result:= waiting;
@,
l./setmodem/,   d5,
l./sem/,   r/sem/sem.s^/,
l./u2/,   d
i/
mc^.u1:= conansw;
h.first:= alc_control*256 + alc_time;
/,
l./,s)/,   r/s/ priq1(-1)/,
l./-1))/,   r/;/;          (*  see 'xmt next block'  line 572    *)/,
l./frame/,   r/frame/head/,   r/sem/sem.s^/, 
l1, d2, i/
 mx^.u1:= xmtansw;
/,
p
l./alloc/,   d12,   i/
 for l:= 0 to maxinputs-1 do
 begin
  alloc ( mr(l), headpool, sem.s^);
  mr(l)^.u1:= recansw;
 end;
/,
l./sem/,   r/sem/sem.s^/,
l./u2/,   r/2/1/,   r/;/;  m^.u2:= m^.u1;/,
r/100/timeru3/,   r/4:=0/4:= timeru4/,
l2,  i/

\f



(*----------------------- main loop -----------------------------------*)
/,
l./sem/,   r/sem/sem.w^/,
l./case/,   d1,
i/
func:= m^.u1;
aux:= m^.u4;
 if m^.u2 = message then
/,
l./rr/,   r/rr/opk/,
l./input/,   i@

sensemess:
 begin
  i:= ord(xstate);
  if i>2 then i:= 2;
  m^.u2:= modem_state*32 +i*8;
  m^.u3:= port;
  return ( m);
end;

@,
l./case bstate/,  d./3,4:/,   d3,
p
i/
begin
 signal ( m, ique);
 (*q  trace ( 1);    q*)
readlam;
end;
/,
l./h.t1/,   r/t2:=h.t1; //,
l1,   i/
 t2:= (h.t1+9) div 10;
/,
l./rstate>2/,  d./rstate>2 *>/,
i/
if xstate < idle then
begin
 xstate:= connec;
 create_channel;
 time:= t2;
end;
/,
l./case rstate/,   d8,   i/
 xstate:= discon;
 event ( 1);
/,
l./testmess:/,   i/

statmess:   answer_stat;

statclrmess:
 begin   answer_stat;   stc:= zeroes;   end;


/,
l./other/,  r/:=4;/:=4;  m^.u3:= port;/,
l./end; <* message/,   r/;//,
l1,
p
i@
 else

  case func of
@,
l2,   d./until false/,

i@
begin
 getresult;
opk:= nonsens;
if m^.u2 = 0 then  begin  opk:= m^.u3;  recerr:= 0  end  else
if m^.u2 <> 5 then
begin
 count ( stc.recerr);
 stc.rec_rnr:= stc.ci;
 (*q  trace ( m^.u2);   q*)
 recerr:= recerr+1;
 if recerr >= n2 then
 begin
  recerr:= 0;
  event ( 13);
 end
end;
 bstate:= bstate-1;
 pop ( mr(bstate), m);
 readlam;
 stc.last_rec:= opk;

case opk of
enq:    input:= enqu;
ack_0,
ack_1:   input:= ackn;
reset:   input:= rese;
data_0,
data_1:  input:= data;
nonsens: input:= nons;
otherwise
 begin
  event ( 7);
  input:= nons;
 end
end;

 if xstate < connec then action:= 0  else
 action:= actiontable(xstate,input);
 if test then
 if testbit(12) then otest ( bstate, action, opk);
(*q   trace ( opk);        q*)

\f



 case action of

0:   ;  (*  do nothing   *)

1:      (*  reset received   *)
  begin
   xstate:= idle;
   event ( 0);
  end;


2:   (*  ack received when connecting   *)
 begin
  block_no:= opk+codediff;
  xstate:= idle;
  event ( 0);
 end;


3:   (*  data  received    *)
 begin
  m^.u2:= 0;
  m^.u3:= port;
  return ( m);
  lastack:= opk-codediff;
  trans ( lastack);
  count ( stc.recs);
end;


4:      (*  ack received    *)
   if opk+codediff = block_no then block_ok;


5:      (*  ack received after enq   *)
   if opk+codediff = block_no then block_ok
   else retrans:= true;


6:      (*  reset received after data    *)
 begin
   retrans:= true;
  event ( 0);
 end;

7:      (*  enq received   *)
 begin
  trans ( lastack);
  count ( stc.rec_rej);
  if xstate < idle then 
  begin
   xstate:= idle;
   event ( 0);
  end;
 end
end;  (*  case  *)

if input <> data then signal ( m, ique);
readlam;
end;  (*  receiver answer   *)

\f



xmtansw:
begin
 getresult;
 if test then
 if testbit(12) then otest ( 16, action, m^.u3 );
 if m^.u2 = 0 then
 begin
  xmterr:= 0;
  (*q  trace ( m^.u3);     q*)
 end  else
 begin
  count ( stc.xmterr);
  stc.xmt_rnr:= stc.ci;
  xmterr:= xmterr+1;
  if xmterr >= n2 then
  begin
   xmterr:= 0;
   event ( 14);
  end
 end;
 pop ( mx, m);
 if mx^.u3 >= data_0 then 
begin
 pending :=: m;
 if result <> waiting then release_buf;
end;
 readlam;
end;



conansw:
 begin
  mc:=: m;
  if mc^.u2 <> 0 then event ( 14);
 end;


\f


timeransw:
begin
 if time > 0 then time:= time-1;
 if time = 0 then
                    (*  timeout   *)
  case xstate of

connec:
 begin
  event ( 11);
  trans ( enq);
 end;

wack:
 begin
  tn:= 1;
  trans ( enq);
  count ( stc.ack_times);
  xstate:= wrep;
 end;

wrep:
 begin
  tn:= tn+1;
  count ( stc.rec_rej);
  if tn >= n2 then give_up ( trouble)
  else trans ( enq);
 end

otherwise
 time:= -1;

end;  (*  timeout  *)

 m^.u3:= timeru3;   m^.u4:= timeru4;
 sendtimer ( m);
end;  (*  timer  *)

otherwise              (*  unknown answer    *)
 if st.lambits = func then  release ( m)
  else return ( m);
  st.lambits:= func;
  event ( 5);
end;   (*  handling of arriving message    *)
\f




(*   xmt  if requested     *)

if not nil ( mx) then
begin
 if vi > 0 then
 begin
  mx^.u2:= port;
  mx^.u3:= vcodes(1);
  signal ( mx, lamsem^);
  for i:= 2 to vi do vcodes(i-1):= vcodes(i);
  vi:= vi-1;
 end  else
 
if (retrans) and (not nil ( pending)) then
 begin
  transdata;
  count ( stc.retrans);
  retrans:= false;
 end  else

 if (nil ( pending)) and ( xstate < wack ) then    (*  xmt next block   *)
 begin
  i:= 8;
  while passive ( priq(i)^) do i:= i-1;
  if i> -1 then
  begin
   wait ( pending, priq(i)^);
   if xstate = idle then        (*  xmit   *)
   begin
    block_no:= data_0 + data_1 - block_no;
    transdata;
    count ( stc.trans);
   end  else
    give_up ( down);               (*  if line down   *)
  end
 end
end   (*  mx unused    *)

until false

end .   (*  of alc  program   *)

@,
l1, d2,
f
if ok.no
finis
lst = set 1 disc1
lst = indent source mark lc
listc = cross lst
o errors
message  pascal
pascal80 spacing.20 codesize.1200 alarmenv source
o c
lst = copy listc errors
scope user lst
clear user pxalclst
rename lst.pxalclst
lookup pass6code
if ok.yes
 (
  pxalcbin = move pass6code
  finis output.no
)
convert errors
finis
«eof»