<< LINES .001/.009 ARE RESERVED FOR SYSTEMS INTEGRATION>>               00005000
$control map,code,uslinit                                               00010000
<< inin -- module 10 >>                                        <<1040>> 00015000
<<hp32033c mpe source c.00.00>>                                         00020000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00025000
<<     this program may be used with one computer system at a       >>  00030000
<<     time and shall not otherwise be recorded, transmitted or     >>  00035000
<<     stored in a retrieval system.  copying or other reproduction >>  00040000
<<     of this program except for archival purposes is prohibited   >>  00045000
<<     without the prior written consent of hewlett-packard company.>>  00050000
<< **** note - dollar copyright cannot be used with this module *** >>  00055000
$control main=inin                                                      00060000
$tp                                                                     00065000
begin                                                                   00070000
<<                                                                      00075000
                                                                        00080000
      internal interrupt segment                                        00085000
                                                                        00090000
>>                                                                      00095000
                                                                        00100000
integer s0 = s-0;                                              <<06095>>00105000
integer s1 = s-1;                                              <<06095>>00110000
equate usermsgport = 1,                                        <<06095>>00115000
       savemsg = %100000;                                      <<*8778>>00120000
define  asmb = assemble#,                                               00125000
        cc   = (6:2)#,                                                  00130000
        f = absolute#,                                                  00135000
        abs=absolute#,                                         <<01809>>00140000
        pdisable=asmb(psdb)#,                                  <<mpeiv>>00145000
        penable=asmb(pseb)#,                                   <<mpeiv>>00150000
        init = con %20302;con 6#,                                       00155000
        disable = asmb( sed 0 )#,                                       00160000
        enable = asmb( sed 1 )#,                                        00165000
        lmem = asmb( lsea )#,                                  <<1040>> 00170000
        rccr = con %20104;con 0#,                                       00175000
        sclr = con %20104;con 1#,                                       00180000
        ton  = con %20104;con 3#,                                       00185000
        sinc = con %20104;con %10#,                                     00190000
        cbkp = con %36160#;                                             00195000
define  trapsoff = push(status);                               <<01858>>00200000
                   tos.(2:1) := 0;                             <<01858>>00205000
                   set(status)#;                               <<01858>>00210000
define  mappingfirmware = logical(abs(%1220))#,                <<06095>>00215000
        sysnrpgmsegs    = abs(%1223)#;                         <<06095>>00220000
$include inclmeas                                              <<mpeiv>>00225000
                                                                        00230000
$include inclmift                                              <<04106>>00235000
equate                                                         <<06210>>00240000
        cce  = 2,                                                       00245000
        ccg  = 0,                                                       00250000
        ccl  = 1,                                                       00255000
        iflagmaskword = %100177, <<word used to clear>>        <<03008>>00260000
                                 <<desired flags>>             <<03008>>00265000
                                 << of iflag of ilt on power up >>      00270000
        dstb = 2,                                              <<1040>> 00275000
        sysdb  = %1000,                                                 00280000
        tracelabel = %1257,                                             00285000
        qi = 5,                                                         00290000
        zi = 6;                                                         00295000
$include inclics                                               <<mpeiv>>00300000
                                                               <<mpeiv>>00305000
                                                                        00310000
integer  x = x,                                                         00315000
         p = q-2,     << stack marker p value >>                        00320000
         deltaq = q+0,                                                  00325000
         status = q-1,<< stack marker status >>                         00330000
         param = q+1; << interrupt parameter >>                         00335000
                                                               <<1040>> 00340000
integer pointer dsti' = dstb;                                  <<1040>> 00345000
                                                                        00350000
equate ics'qi=5;                                               <<mpeiv>>00355000
equate sysbase=%1000,                                          <<mpeiv>>00360000
       slix=1,                                                 <<mpeiv>>00365000
       sysxl=sysbase+slix,                                     <<mpeiv>>00370000
       dstix=2,                                                <<mpeiv>>00375000
       sysdst=sysbase+dstix,                                   <<mpeiv>>00380000
       pcbix=3,                                                <<mpeiv>>00385000
       syspcb=sysbase+pcbix,                                   <<mpeiv>>00390000
       dfcix=%32,                                              <<mpeiv>>00395000
       sysdfc=sysbase+dfcix,                                   <<mpeiv>>00400000
       icsix=7,                                                <<mpeiv>>00405000
       sysics=sysbase+icsix,                                   <<mpeiv>>00410000
       cstxblkix=%51,                                          <<mpeiv>>00415000
       syscstxblk=sysbase+cstxblkix,                           <<mpeiv>>00420000
       syswaittodispmsg=%1053;                                 <<mpeiv>>00425000
                                                               <<mpeiv>>00430000
define memtrapflag=(4:1)#;                                     <<mpeiv>>00435000
equate pagepower=7;                                            <<06210>>00440000
                                                               <<06210>>00445000
                                                               <<mpeiv>>00450000
<<system table ptrs for lst access>>                           <<mpeiv>>00455000
                                                               <<mpeiv>>00460000
integer pointer dst=dstix,                                     <<mpeiv>>00465000
                pcb=pcbix,                                     <<mpeiv>>00470000
                cstxblk=cstxblkix,                             <<mpeiv>>00475000
               ics=icsix;                                      <<mpeiv>>00480000
                                                               <<mpeiv>>00485000
integer dstsysbaseinx=db+dstix,                                <<mpeiv>>00490000
        slsysbaseinx=db+slix,                                  <<mpeiv>>00495000
                dfc=db+dfcix;                                  <<mpeiv>>00500000
$include inclst                                                <<mpeiv>>00505000
$include inclpcb5                                              <<06642>>00510000
                                                               <<mpeiv>>00515000
<<wait/awake parameter definitions>>                           <<mpeiv>>00520000
equate noinfo=0,                                               <<mpeiv>>00525000
       memorywaitcode=%10000,                                  <<mpeiv>>00530000
       junkwaitcode=%20,                                       <<mpeiv>>00535000
       memorytrap=%4000,                                       <<mpeiv>>00540000
       nowait=0;                                               <<mpeiv>>00545000
                                                               <<mpeiv>>00550000
$include inclmsg                                               <<mpeiv>>00555000
$include incltrl                                               <<06827>>00560000
$include inclobj                                               <<06210>>00565000
$include inclpcbx                                              <<06210>>00570000
$include inclreg                                               <<06210>>00575000
$page ""                                                       <<06210>>00580000
define setallocflag=(8:1)#;                                    <<mpeiv>>00585000
equate uncallablebit=1;                                        <<mpeiv>>00590000
$include incllpdt                                              <<06829>>00595000
$include inclmmst                                              <<06830>>00600000
$include inclkcim                                              <<06210>>00605000
$include inclkdim                                                       00610000
procedure  abort(mode,code,param);                                      00615000
   value mode,code,param;                                               00620000
   logical mode,code,param;                                             00625000
   option external;                                                     00630000
                                                                        00635000
procedure abortproc(procinx,abortcode);                        <<mpeiv>>00640000
value procinx,abortcode;                                       <<mpeiv>>00645000
integer procinx,abortcode;                                     <<mpeiv>>00650000
option external;                                               <<mpeiv>>00655000
                                                               <<mpeiv>>00660000
logical procedure iomessage(setno,msgno,mask,p1,p2,p3,p4,      <<03094>>00665000
     p5,dest,reply,offset,ditp,iotype);                        <<03094>>00670000
value setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,              <<03094>>00675000
     offset,ditp,iotype;                                       <<03094>>00680000
integer setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,            <<03094>>00685000
     offset,iotype;                                            <<03094>>00690000
integer pointer ditp;                                          <<03094>>00695000
option variable,external;                                      <<03094>>00700000
                                                               <<03094>>00705000
                                                               <<04184>>00710000
procedure dcu'request(msgstate);                               <<04184>>00715000
value msgstate;                                                <<04184>>00720000
logical msgstate;                                              <<04184>>00725000
option external;                                               <<04184>>00730000
                                                               <<04184>>00735000
                                                               <<03650>>00740000
procedure lynx'pf'check;    option external;                   <<03650>>00745000
                                                               <<03650>>00750000
procedure delayedint; option external;                         <<03040>>00755000
                                                                        00760000
procedure  eadd; option external;                                       00765000
                                                                        00770000
procedure  esub; option external;                                       00775000
                                                                        00780000
procedure  empy; option external;                                       00785000
                                                                        00790000
procedure  ediv; option external;                                       00795000
                                                                        00800000
procedure  eneg; option external;                                       00805000
                                                                        00810000
procedure  ecmp; option external;                                       00815000
                                                                        00820000
procedure  qadd;  option external;                                      00825000
                                                                        00830000
procedure  qsub;  option external;                                      00835000
                                                                        00840000
procedure  qmpy;  option external;                                      00845000
                                                                        00850000
procedure  qdiv;  option external;                                      00855000
                                                                        00860000
procedure  qneg;  option external;                                      00865000
                                                                        00870000
procedure  qcmp;  option external;                                      00875000
                                                                        00880000
procedure  qasl;  option external;                                      00885000
                                                                        00890000
procedure  qasr;  option external;                                      00895000
                                                                        00900000
procedure  dimpy; option external;                                      00905000
                                                                        00910000
procedure  didiv; option external;                                      00915000
                                                                        00920000
procedure  help; option external;                                       00925000
                                                                        00930000
procedure  dmul; option external;                                       00935000
                                                                        00940000
procedure  cvad; option external;                                       00945000
                                                                        00950000
procedure  cvda; option external;                                       00955000
                                                                        00960000
procedure  cvbd; option external;                                       00965000
                                                                        00970000
procedure  cvdb; option external;                                       00975000
                                                                        00980000
procedure  sld; option external;                                        00985000
                                                                        00990000
procedure  nsld; option external;                                       00995000
                                                                        01000000
procedure  srd; option external;                                        01005000
                                                                        01010000
procedure  cmpd; option external;                                       01015000
                                                                        01020000
procedure  addd; option external;                                       01025000
                                                                        01030000
procedure  subd; option external;                                       01035000
                                                                        01040000
procedure mpydsim; option external;                                     01045000
                                                                        01050000
procedure stunsim; option external;                            <<01744>>01055000
                                                               <<01744>>01060000
                                                                        01065000
procedure tick; option external;                                        01070000
                                                                        01075000
double procedure  teststop(s,p,pinx);                          <<07302>>01080000
   value s,p,pinx;                                                      01085000
   double s;                                                   <<06655>>01090000
   integer p,pinx;                                             <<06655>>01095000
   option external;                                                     01100000
                                                                        01105000
procedure  debug; option external;                                      01110000
                                                                        01115000
procedure  suddendeath(a);                                              01120000
   value  a;                                                            01125000
   integer  a;                                                          01130000
   option  external;                                                    01135000
                                                               <<k7614>>01140000
procedure soft'death(a);                                       <<k7614>>01145000
   value a;                                                    <<k7614>>01150000
   integer a;                                                  <<k7614>>01155000
   option external;                                            <<k7614>>01160000
                                                                        01165000
procedure masterclearhpib(ditp);                               <<01301>>01170000
value ditp;                                                             01175000
pointer ditp;                                                           01180000
option external;                                                        01185000
                                                                        01190000
procedure bconvert(word);                                               01195000
value word;                                                             01200000
integer word;                                                           01205000
option external;                                                        01210000
                                                                        01215000
procedure dconvert(word);                                               01220000
value word;                                                             01225000
integer word;                                                           01230000
option external;                                                        01235000
                                                                        01240000
procedure mpxcontrol(op,ditp);                                          01245000
value op,ditp;                                                          01250000
integer op;                                                             01255000
pointer ditp;                                                           01260000
option external;                                                        01265000
                                                                        01270000
procedure write2(word);                                                 01275000
value word;                                                             01280000
integer word;                                                           01285000
option external;                                                        01290000
                                                                        01295000
procedure awakeio(ditp,flags);                                          01300000
value ditp,flags;                                                       01305000
pointer ditp;                                                           01310000
integer flags;                                                          01315000
option external;                                                        01320000
                                                                        01325000
procedure checkldev(dev);                                               01330000
value dev;                                                              01335000
integer dev;                                                            01340000
option external;                                                        01345000
                                                                        01350000
integer procedure dequeue(linkindex,qn);                                01355000
value linkindex,qn;                                                     01360000
integer linkindex,qn;                                                   01365000
option external;                                                        01370000
                                                                        01375000
procedure iofailure(drtn,ditp);                                         01380000
value drtn,ditp;                                                        01385000
integer drtn;                                                           01390000
integer pointer ditp;                                                   01395000
option external;                                                        01400000
                                                                        01405000
                                                                        01410000
integer procedure get'dsdevice (ldev);                         <<01775>>01415000
value ldev;                                                    <<01775>>01420000
integer ldev;                                                  <<01775>>01425000
option external;                                               <<01775>>01430000
                                                                        01435000
integer procedure cstconv (label',pinx);                       <<06095>>01440000
   value label',pinx;                                          <<06095>>01445000
   integer label',pinx;                                        <<06095>>01450000
   option external;                                            <<06095>>01455000
                                                               <<06095>>01460000
procedure receivemsg (port,len,flag);                          <<06095>>01465000
   value port,len,flag;                                        <<06095>>01470000
   integer port,len;                                           <<06095>>01475000
   logical flag;                                               <<06095>>01480000
   option external;                                            <<06095>>01485000
                                                               <<06095>>01490000
double procedure mappedcsttophycst(mpcst,pinx);                <<06655>>01495000
   value mpcst,pinx;                                           <<06095>>01500000
   integer mpcst,pinx;                                         <<06095>>01505000
   option external;                                            <<06095>>01510000
$page " "                                                      <<06655>>01515000
logical procedure testcrunch(caller);                                   01520000
   value caller;                                                        01525000
   integer caller;                                                      01530000
   option privileged,uncallable;                                        01535000
   begin                                                                01540000
   logical pointer  cst = 1;                                            01545000
   logical ls0=s-0;                                                     01550000
   equate trplbl=%100001,clearstt=%100377,getstt=%77400;                01555000
   equate series33 = 8;                                        <<02021>>01560000
   integer  s0 = s-0;                                                   01565000
   integer array  arrq(*) = q+0;                                        01570000
   equate badref = 8;                                                   01575000
   tos := x;  <<save instruction on which trap occurred>>               01580000
                                                                        01585000
   tos := arrq(-arrq-1); <<get status of trapped procedure>>            01590000
   if < then begin <<privileged mode when trapped>>                     01595000
                                                                        01600000
comment the following code is included to avert sd#10 in                01605000
        the case that two internal interrupts are generated             01610000
        by a single violation, e.g., bnds viol is followed              01615000
        by ill adr in partial memory system.  the following             01620000
        code will set testcrunch true and return, ignoring              01625000
        the ill adr;                                                    01630000
   if s0=trplbl then                                                    01635000
     begin                                                              01640000
     tos := arrq(x:=x-3);<<is this ext trap lbl? check:>>               01645000
     if (ls0 land clearstt)=trplbl then                                 01650000
       begin <<check if delta p is entry for stt in lbl>>               01655000
       tos := tos.(1:7); <<stt>>                                        01660000
       tos := cst(7);  <<absolute loc of inin>>                         01665000
       asmb(xch,sub);                                                   01670000
       tos := cst(4).(4:12)&lsl(2); <<len of inin>>                     01675000
       tos := tos+tos-1;   <<tos:=@ of stt entry from blklbl>> <<02087>>01680000
       tos := cst(6);      <<tos:=bank of inin>>               <<02087>>01685000
       asmb(xch;lsea);     <<tos:=stt entry of blklbl>>        <<02087>>01690000
       asmb(delb,delb);    <<pitch doble addr of stt entry>>   <<02087>>01695000
       tos := tos.(2:14);  <<tos:=deltap of trapped proc>>     <<02087>>01700000
       tos := arrq(-arrq-2); <<delta p at trap time>>                   01705000
       if tos=tos then                                                  01710000
         begin <<double internal interrupt! ignore!>>                   01715000
         testcrunch := true;                                            01720000
         return;                                                        01725000
         end;                                                           01730000
       end                                                     <<01923>>01735000
       else del;                                               <<01923>>01740000
     end;                                                               01745000
   tos := tos land %377;                                                01750000
   if mappingfirmware then                                     <<06095>>01755000
      begin                                                    <<06095>>01760000
         tos:=arrq(-arrq-2);                                   <<06095>>01765000
         if tos.(1:1) = 0 then                                 <<06095>>01770000
            tos := 0                                           <<06095>>01775000
         else tos := 1;                                        <<06095>>01780000
      end                                                      <<06095>>01785000
   else                                                        <<06095>>01790000
   if s0<%300 and cst(s0&lsl(2)+1).systemflag                  <<mpeiv>>01795000
      then tos:=1                                              <<06095>>01800000
   else                                                        <<06095>>01805000
      tos:=0;                                                  <<06095>>01810000
                                                               <<06829>>01815000
if tos = 1 then                                                <<06829>>01820000
     begin << in privileged system code >>                              01825000
   << the code added here in the series 3 version is not  >>   <<01923>>01830000
   << necessary for the series 33 version (due to micro-  >>   <<01923>>01835000
   << code). this already checks to see if the bounds vio >>   <<01923>>01840000
   << that occurred was caused by an exit to a destroyed  >>   <<01923>>01845000
   << user stack marker.  if so, abort process else sf10  >>   <<01923>>01850000
   << the code must be added for the series 44 and 55>>        <<02021>>01855000
       assemble(pcn);     <<cpu number>>                       <<02021>>01860000
       if tos = series33 then                                  <<02021>>01865000
         begin                                                 <<02021>>01870000
            x := arrq(-2) + %111; <<pmap rel loc of caller>>   <<02021>>01875000
            suddendeath(caller+badref);                        <<02021>>01880000
         end                                                   <<02021>>01885000
        else            <<icf'44 and icf'55>>                  <<02021>>01890000
         begin                                                 <<02021>>01895000
            del;                                               <<02021>>01900000
            if (tos land %177400)<> %31400 <<not exit inst>>   <<02021>>01905000
             or caller<>2 then      <<not bounds vio>>         <<02021>>01910000
              begin                                            <<02021>>01915000
die:           x:=arrq(-2)+%111;  <<pmap rel loc of caller>>   <<02021>>01920000
               suddendeath(caller+badref);        <<die>>      <<02021>>01925000
              end else                                         <<02021>>01930000
               begin                                           <<02021>>01935000
                tos:=arrq((-arrq(-arrq)-arrq)-1);              <<02021>>01940000
                <<status marker before trap procedure>>        <<02021>>01945000
                if (tos land %377)<%300 then go die;           <<02021>>01950000
              <<not a trap on exit to a bad user segment>>     <<02021>>01955000
               end                                             <<02021>>01960000
         end                                                   <<02021>>01965000
      end;                                                     <<02021>>01970000
   end <<privileged mode when trapped>>;                                01975000
   status.(1:1) := 1;   << interrupts on on exit >>                     01980000
   end;                                                                 01985000
                                                                        01990000
$page                                                          <<*7755>>01995000
procedure boundsviolation;                                     <<*7755>>02000000
begin                                                          <<*7755>>02005000
                                                               <<*7755>>02010000
define                                                         <<*7755>>02015000
   exit'instruction = (logical(instr) land %177400) = %31400#, <<*7755>>02020000
   p'loc            = stack(-deltaq - 2)#,                     <<*7755>>02025000
   status'loc       = stack(-deltaq - 1)#;                     <<*7755>>02030000
                                                               <<*7755>>02035000
array stack(*) = q+0;                                          <<*7755>>02040000
                                                               <<*7755>>02045000
integer                                                        <<*7755>>02050000
   instr,           << instruction causing trap             >> <<*7755>>02055000
   plabel,          <<                                      >> <<*7755>>02060000
   descstinx;       << dst-relative offset to plabel        >> <<*7755>>02065000
                                                               <<*7755>>02070000
logical                                                        <<*7755>>02075000
   mcy;             << mode of control-y trap procedure     >> <<*7755>>02080000
                                                               <<*7755>>02085000
logical                                                        <<*7755>>02090000
   exit'number = q+1;                                          <<*7755>>02095000
                                                               <<*7755>>02100000
logical subroutine modeok;                                     <<*7755>>02105000
begin                                                          <<*7755>>02110000
                                                               <<*7755>>02115000
<< checks mode of trap procedure and trapped segment. priv  >> <<*7755>>02120000
<< trapped segment can't trap into user mode trap procedure.>> <<*7755>>02125000
                                                               <<*7755>>02130000
modeok := false;                                               <<*7755>>02135000
if pcb(curprc + piinfowordnum).psimfield = 5 then              <<*7755>>02140000
   begin                                                       <<*7755>>02145000
   push(q,dl);                                                 <<*7755>>02150000
   asmb(xch,sub);                                              <<*7755>>02155000
   tos := tos - stack(s0 - 2);     << ptr to pxfixed        >> <<*7755>>02160000
   mcy := stack(tos+6).(3:1);      << control-y trap mode   >> <<*7755>>02165000
   if not (mcy land logical(status'loc.(0:1))) then            <<*7755>>02170000
      begin                                                    <<*7755>>02175000
      modeok := true;                                          <<*7755>>02180000
      end;                                                     <<*7755>>02185000
   end;                                                        <<*7755>>02190000
                                                               <<*7755>>02195000
if pcb(curprc + resabortinfowordnum).delaysoftflag = 1 then    <<*7755>>02200000
   begin                                                       <<*7755>>02205000
   asmb(adds 4);                                               <<*7755>>02210000
   receivemsg(usermsgport,4,savemsg);                          <<*7755>>02215000
   if not logical(s0.(0:1)) land logical(status'loc.(0:1)) then<<*7755>>02220000
      begin                                                    <<*7755>>02225000
      asmb(subs 4);                                            <<*8778>>02230000
      modeok := true;                                          <<*7755>>02235000
      end                                                      <<*8778>>02240000
   else                                                        <<*8778>>02245000
      begin                                                    <<*8778>>02250000
      asmb(subs 4);                                            <<*8778>>02255000
      modeok := false;                                         <<*8778>>02260000
      end;                                                     <<*8778>>02265000
   end;                                                        <<*7755>>02270000
end;       << subroutine modeok >>                             <<*7755>>02275000
                                                               <<*7755>>02280000
                                                               <<*7755>>02285000
instr := x;                                                    <<*7755>>02290000
if not testcrunch(2) then                                      <<*7755>>02295000
   begin                                                       <<*7755>>02300000
   if exit'instruction and p'loc.(0:1) then                    <<*7755>>02305000
      begin                                                    <<*7755>>02310000
                                                               <<*7755>>02315000
      << bounds violation as a result of the trace bit set  >> <<*7755>>02320000
      << for a delayed control-y or soft interrupt on an    >> <<*7755>>02325000
      << internal exit. note that for external exits we go  >> <<*7755>>02330000
      << directly to trace.                                 >> <<*7755>>02335000
                                                               <<*7755>>02340000
      p'loc.(0:1) := 0;                << clear trace bit   >> <<*7755>>02345000
      plabel := 0;                                             <<*7755>>02350000
      plabel.(0:1) := p'loc.(1:1);     << set map flag      >> <<*7755>>02355000
      plabel.(8:8) := status'loc.(8:8);                        <<*7755>>02360000
      descstinx := cstconv(plabel,0);                          <<*7755>>02365000
                                                               <<*7755>>02370000
      if (pcb(curprc + piinfowordnum).psimfield = 5 or         <<*7755>>02375000
          pcb(curprc + resabortinfowordnum).delaysoftflag = 1) <<*7755>>02380000
         and modeok then                                       <<*7854>>02385000
         begin                                                 <<*7755>>02390000
                                                               <<*7755>>02395000
          x := instr.(8:8);                                    <<*7755>>02400000
                                                               <<*7755>>02405000
         << cut back marker layed down by micro code when    >><<*7755>>02410000
         << the bounds violation occurred.                   >><<*7755>>02415000
                                                               <<*7755>>02420000
         push(q);                                              <<*7755>>02425000
         tos := tos - deltaq;                                  <<*7755>>02430000
         set(q);                                               <<*7755>>02435000
         exit'number := x;                                     <<*7755>>02440000
         delayedint;                                           <<*7755>>02445000
                                                               <<*7755>>02450000
         << now need to do the exit that was originally tried>><<*7755>>02455000
         << when the bounds violation was detected. exit     >><<*7755>>02460000
         << number was left at q+1, which is now tos to this >><<*7755>>02465000
         << marker.                                          >><<*7755>>02470000
                                                               <<*7755>>02475000
         tos := exit'number lor %031400;                       <<*7755>>02480000
         asmb(xeq 0);                                          <<*7755>>02485000
         end;                                                  <<*7755>>02490000
      end;                                                     <<*7755>>02495000
   end;                                                        <<*7755>>02500000
                                                               <<*7755>>02505000
x := instr;                                                    <<*7755>>02510000
abort( [8/1,8/0],24,0 );                                       <<*7755>>02515000
end;        << procedure boundsviolation >>                    <<*7755>>02520000
                                                                        02525000
procedure  illegaladdress;                                              02530000
   option privileged,uncallable;                                        02535000
   begin                                                                02540000
   if not testcrunch(1) then                                            02545000
   abort([8/1,8/0],23,0); << with instr in xreg >>             <<03040>>02550000
   end;                                                                 02555000
                                                               <<04793>>02560000
procedure  nonrespondingmodule;                                <<04793>>02565000
   option privileged,uncallable;                               <<04793>>02570000
    << this procedure produces the correct system failure >>   <<04793>>02575000
    << for a non-responding module interrupt.  previously >>   <<04793>>02580000
    << this interrupt was handled as a ghost interrupt    >>   <<04793>>02585000
                                                               <<04793>>02590000
   begin                                                       <<04793>>02595000
   if x=%20302 then     <<io operation>>                       <<04793>>02600000
     begin                                                     <<04793>>02605000
     status.cc := ccl;                                         <<04793>>02610000
     return;                                                   <<04793>>02615000
     end;                                                      <<04793>>02620000
   if not testcrunch(0) then                                   <<04793>>02625000
   abort([8/1,8/0],25,0);                                      <<04793>>02630000
   end;                                                        <<04793>>02635000
                                                                        02640000
procedure dataparity;                                          <<02302>>02645000
   option privileged,uncallable;                               <<02302>>02650000
                                                               <<02302>>02655000
   comment: dataparity will attempt to locate which memory     <<02302>>02660000
   location caused the data parity interrupt.  it does this    <<02302>>02665000
   by referencing all locations in memory until another data   <<02302>>02670000
   parity interrupt is detected.  the location which was last  <<02302>>02675000
   referenced is displayed and the system is halted, sf 13.    <<02302>>02680000
   if the bad location is not located, the machine is halted   <<02302>>02685000
   without a location displayed;                               <<02302>>02690000
                                                               <<02302>>02695000
   begin                                                       <<02302>>02700000
   equate  sysdb = %1000,                                      <<02302>>02705000
           crlf = %6412;   <<carriage return, linefeed>>       <<02302>>02710000
   define  parityerrflag = absolute (sysdb + %61)#,            <<02302>>02715000
           syslastbank   = absolute (sysdb + %361)#,           <<02302>>02720000
           syslastaddr   = absolute (sysdb + %362)#;           <<02302>>02725000
   array   parmsg (0:6) = pb := crlf, "PARITY ERROR";          <<02302>>02730000
   array   bmsg (0:2)   = pb := crlf, "B = ";                  <<02302>>02735000
   array   amsg (0:2)   = pb := crlf, "A = ";                  <<02302>>02740000
   logical b       = s-1,  <<b stack cell: bank # for lsea>>   <<02302>>02745000
           a       = s,    <<a stack cell: offset for lsea>>   <<02302>>02750000
           errbank = q-6,  <<b stack cell after second dp>>    <<02302>>02755000
           erraddr = q-5,  <<a stack cell after second dp>>    <<02302>>02760000
           lastbank,       <<largest bank # configured>>       <<02302>>02765000
           lastaddr;       <<largest addr for current bank>>   <<02302>>02770000
                                                               <<02302>>02775000
   if not parityerrflag then                                   <<02302>>02780000
         <<first dp interrupt: initialize and make another>>   <<02302>>02785000
         begin                                                 <<02302>>02790000
         tos := sysdb d;          <<set sysdb, pitch old db>>  <<02302>>02795000
         assemble (xchd;ddel);                                 <<02302>>02800000
         for x := 0 until 6 do write2(parmsg(x));              <<02302>>02805000
         parityerrflag := true;                                <<02302>>02810000
         lastbank := syslastbank;                              <<02302>>02815000
         lastaddr := %177777;     <<assume all but l.b. full>> <<02302>>02820000
                                                               <<02302>>02825000
         <<reference all of memory to recreate the error>>     <<02302>>02830000
         tos := 0d;               <<a:=b:=0>>                  <<02302>>02835000
         while b <= lastbank do                                <<02302>>02840000
            begin                                              <<02302>>02845000
            while a < lastaddr do                              <<02302>>02850000
               begin                                           <<02302>>02855000
               assemble (lsea;del);                            <<02302>>02860000
               assemble (inca);                                <<02302>>02865000
               end;                                            <<02302>>02870000
            assemble (lsea;del);  <<for last word in bank>>    <<02302>>02875000
            assemble (inca,incb);                              <<02302>>02880000
            if b = lastbank then lastaddr := syslastaddr;      <<02302>>02885000
            end;                                               <<02302>>02890000
         end  <<first parity error>>                           <<02302>>02895000
      else                                                     <<02302>>02900000
         <<second dataparity: print where we found it>>        <<02302>>02905000
         begin                                                 <<02302>>02910000
         for x := 0 until 2 do write2(bmsg(x));                <<02302>>02915000
         dconvert (errbank);                                   <<02302>>02920000
         for x := 0 until 2 do write2(amsg(x));                <<02302>>02925000
         bconvert (erraddr);                                   <<02302>>02930000
         end;  <<second parity error>>                         <<02302>>02935000
   suddendeath(13);                                            <<02302>>02940000
   end;  <<dataparity>>                                        <<02302>>02945000
                                                                        02950000
procedure ghost4;                                              <<04793>>02955000
   option privileged,uncallable;                                        02960000
  begin                                                                 02965000
    entry ghost5,ghost7,                                       <<*8289>>02970000
          ghost22,ghost23,ghost26,ghost27,ghost28,ghost29,              02975000
          ghost30,ghost36;                                              02980000
   if x=%20302 then                                                     02985000
     begin << i/o operation >>                                          02990000
     status.cc := ccl;                                                  02995000
     return;                                                            03000000
     end;                                                               03005000
    tos := 4;                                                  <<04793>>03010000
  mainghost:                                                            03015000
   suddendeath(15);                                                     03020000
  ghost5:                                                               03025000
    tos := 5;                                                           03030000
    goto mainghost;                                                     03035000
  ghost7:                                                               03040000
    tos := 7;                                                           03045000
    goto mainghost;                                                     03050000
  ghost22:                                                              03055000
    tos := 22;                                                          03060000
    goto mainghost;                                                     03065000
  ghost23:                                                              03070000
    tos := 23;                                                          03075000
    goto mainghost;                                                     03080000
  ghost26:                                                              03085000
    tos := 26;                                                          03090000
    goto mainghost;                                                     03095000
  ghost27:                                                              03100000
    tos := 27;                                                          03105000
    goto mainghost;                                                     03110000
  ghost28:                                                              03115000
    tos := 28;                                                          03120000
    goto mainghost;                                                     03125000
  ghost29:                                                              03130000
    tos := 29;                                                          03135000
    goto mainghost;                                                     03140000
  ghost30:                                                              03145000
    tos := 30;                                                          03150000
    goto mainghost;                                                     03155000
  ghost36:                                                              03160000
    tos := 36;                                                          03165000
    goto mainghost;                                                     03170000
  end;                                                                  03175000
                                                                        03180000
procedure extghost;                                                     03185000
option privileged,uncallable,interrupt;                        <<03664>>03190000
begin                                                                   03195000
integer drtn = q+3;         << location of drt number >>       <<03664>>03200000
                                                               <<03664>>03205000
equate unknown'int'msg = 410,   << msg catalog msg # >>        <<03664>>03210000
       opconsole       = 0;     << system cons code for genmsg <<03664>>03215000
                                                               <<03664>>03220000
   disable; << issue a clear interface >>                               03225000
   iomessage(1,unknown'int'msg,%10000,drtn,,,,,opconsole);     <<03664>>03230000
end;                                                                    03235000
                                                                        03240000
                                                               <<03094>>03245000
                                                               <<03094>>03250000
                                                               <<03094>>03255000
                                                               <<03094>>03260000
procedure tempwarnings;                                        <<03094>>03265000
option privileged,uncallable;                                  <<03094>>03270000
                                                               <<03094>>03275000
comment                                                        <<03094>>03280000
         this procedure is for the icf'64 temperature          <<03094>>03285000
         conditions.  the following parameters are dropped     <<03094>>03290000
         by microcode to indicate which type of condition to   <<03094>>03295000
         print out on the console:                             <<03094>>03300000
                                                               <<03094>>03305000
             q+1 =    0      "LOW OVERTEMP CONDITION"          <<03094>>03310000
                      1      "HIGH OVERTEMP CONDITION"         <<03094>>03315000
                      2      "OVERTEMP CONDITION-POWER DOWN    <<03094>>03320000
                                IN PROGRESS"                   <<03094>>03325000
                      3      "TEMPERATURE NORMAL CONDITION".   <<03094>>03330000
                      4      "PDM NOT RESPONDING"              <<04954>>03335000
                      5      "POWER SYSTEM WARNING"            <<04954>>03340000
                      6      "BANNER CLEARED"                  <<04954>>03345000
                                                               <<03094>>03350000
         after the message is sent to the console, we will     <<03094>>03355000
         just return.  even though this is an internal int.,   <<03094>>03360000
         if a 2nd overtemp interrupts while doing this one,    <<04184>>03365000
         it will be held off if we have interrupts disabled.   <<03094>>03370000
         all other interrupts will be held off, too.           <<03094>>03375000
         if it is a fatal overtemp, microcode will trap to     <<04184>>03380000
         powerfail after this message is sent out.             <<03094>>03385000
;                                                              <<03094>>03390000
                                                               <<03094>>03395000
                                                               <<03094>>03400000
                                                               <<03094>>03405000
begin                                                          <<03094>>03410000
                                                               <<03094>>03415000
    <<don't add a variable at q+1-condition must be here>>     <<03094>>03420000
logical condition   = q+1;   <<type of temp. cond. >>          <<03094>>03425000
                           <<dropped by microcode- q+1>>       <<03094>>03430000
                                                               <<03094>>03435000
integer message     = q+2;                                     <<03094>>03440000
                                                               <<03094>>03445000
equate lowovertemp  = 140,   <<nos. for messages printed out>> <<03094>>03450000
       highovertemp = 141,                                     <<03094>>03455000
       fatalovertemp= 142,                                     <<03094>>03460000
       normaltemp   = 143,                                     <<03094>>03465000
       nopdmresp    = 411,                                     <<04954>>03470000
       powrwarng    = 412,                                     <<04954>>03475000
       bannerclr    = 413,                                     <<04954>>03480000
       console      = 0,       <<console num for iomessage>>   <<03094>>03485000
       sysdb        = %1000,                                   <<03094>>03490000
       icf'37       = 5,       <<cpu number for icf'37>>       <<*8289>>03495000
       icf'55       = 4;       <<cpu number for icf'55>>       <<03094>>03500000
                                                               <<03094>>03505000
disable;                                                       <<03094>>03510000
trapsoff;                                                      <<03094>>03515000
asmb(toff);                                                    <<03094>>03520000
                                                               <<03094>>03525000
asmb (adds 1);   <<make room for local variables>>             <<03094>>03530000
asmb (pcn);       <<decide which cpu we have>>                 <<03094>>03535000
if s0 <> icf'55 and tos <> icf'37 then                         <<*8289>>03540000
  begin                                                        <<*8289>>03545000
  suddendeath(15);     <<we should not be here if this>>       <<*8289>>03550000
  del;                 <<is not a icf'55 or icf'37. it>>       <<*8289>>03555000
  end                  <<is therefore a ghost interrupt>>      <<*8289>>03560000
   else begin                                                  <<03094>>03565000
        << find out which message to print out - (q+1) >>      <<03094>>03570000
        message := if condition=0 then lowovertemp             <<03094>>03575000
              else if condition=1 then highovertemp            <<03094>>03580000
              else if condition=2 then fatalovertemp           <<03094>>03585000
              else if condition=3 then normaltemp              <<03094>>03590000
              else if condition=4 then nopdmresp               <<04954>>03595000
              else if condition=5 then powrwarng               <<04954>>03600000
              else if condition=6 then bannerclr               <<04954>>03605000
              else 0;                                          <<03094>>03610000
                                                               <<03094>>03615000
        if message = 0 then suddendeath(15);                   <<03094>>03620000
          <<we should not be here if condition is not set.>>   <<03094>>03625000
          <<so this must be a ghost interrupt.  >>             <<03094>>03630000
                                                               <<03094>>03635000
        tos := sysdb d;                                        <<03094>>03640000
        asmb (xchd);                                           <<03094>>03645000
        iomessage(1,message,,,,,,,console);                    <<03094>>03650000
        asmb (xchd; ddel; ton)                                 <<03094>>03655000
        end                                                    <<03094>>03660000
                                                               <<03094>>03665000
end;                                                           <<03094>>03670000
                                                               <<03094>>03675000
procedure  powerfail;                                                   03680000
   option privileged,uncallable;                                        03685000
begin                                                                   03690000
                                                                        03695000
equate                                                                  03700000
   diltp       = 5,        << dit index to ilt pointer >>               03705000
   cstb        = 0,        <<cst base>>                        <<01372>>03710000
   series'33   = 8,        << series'33 pcn number >>          <<01415>>03715000
   icf'44      = 3,                                            <<03008>>03720000
   devreset    = %100000,  << device masterclear control >>             03725000
   templr      = %22,      << temp storage for limit reg >>    <<01183>>03730000
   powerfail   = %72,      << sysdb index >>                            03735000
   sysdb       = %1000;                                                 03740000
                                                                        03745000
integer                                                                 03750000
   absqi       = q+7,                                                   03755000
   i           = q+6,                                                   03760000
   lr          = q+5,                                                   03765000
   maxdrt      = db+%71,                                                03770000
   param       = q+3,   <<difference between cr and lr>>                03775000
   pf          = db+powerfail,                                          03780000
   s           = s-2,                                                   03785000
   sysup       = db+%73;                                                03790000
                                                                        03795000
integer s0     = s-0;                                          <<03008>>03800000
                                                               <<03008>>03805000
integer pointer                                                         03810000
   ps0         = s-0;                                                   03815000
                                                                        03820000
                                                                        03825000
   tos := 0d;                                                           03830000
   tos := sysdb;                                                        03835000
   asmb(xchd);                                                          03840000
   pf := 1; << set sysdb and pf count >>                                03845000
   sysup := 0;                                                          03850000
   tos := abs(qi);                                                      03855000
                                                               <<01372>>03860000
   <<save cst(2) on tos -- this cst will be rebuilt    >>      <<01372>>03865000
   <<to look like a segment present in non-existent    >>      <<01372>>03870000
   <<physical memory.  powerfail will pcal this seg    >>      <<01372>>03875000
   <<as its last action.  this prevents access to      >>      <<01372>>03880000
   <<memory when the memory controller is mastercleared>>      <<01372>>03885000
   <<by microcode, thus avoiding a hardware problem    >>      <<01372>>03890000
   <<which causes memory to be destroyed.              >>      <<01372>>03895000
                                                               <<01372>>03900000
   x:=abs(cstb)+8;          <<addr of cst(2)>>                 <<01372>>03905000
   tos:=abs(x);             <<word 0>>                         <<01372>>03910000
   tos:=abs(x:=x+1);        <<word 1>>                         <<01372>>03915000
   tos:=abs(x:=x+1);        <<word 2>>                         <<01372>>03920000
   tos:=abs(x:=x+1);        <<word 3>>                         <<01372>>03925000
                                                               <<01372>>03930000
   <<build new cst(2)>>                                        <<01372>>03935000
                                                               <<01372>>03940000
   abs(x):=0;               <<addr>>                           <<01372>>03945000
   abs(x:=x-1):=15;         <<bank>>                           <<01372>>03950000
   abs(x:=x-1):=1;          <<refcount>>                       <<01372>>03955000
   abs(x:=x-1):=%40040;     <<length>>                         <<01372>>03960000
                                                               <<01372>>03965000
   tos := abs(absqi-6); << save qi-6 >>                                 03970000
   tos := abs(x:=x+9);  << qi + 3 >>                                    03975000
   tos := abs(x:=x+1);  << and qi + 4 >>                                03980000
   push(s,q,dl);                                                        03985000
   tos := s - absqi + sysdb; << compute adds value for restart >>       03990000
   abs(x) := tos;                                                       03995000
   asmb(rccr);         << get current time >>                  <<01183>>04000000
   tos := abs(templr);                                         <<01183>>04005000
   asmb(lsub);         << time since last interrupt >>         <<01183>>04010000
   lr := tos;                                                  <<01183>>04015000
                                                                        04020000
   << power fail firmware does io clear (iocl) >>                       04025000
   << 30/33 must be executing in non-existent memory at >>     <<01415>>04030000
   << time of actual power loss - all other machines    >>     <<01415>>04035000
   << may just halt.  if 30/33, pcal cst(2) which was   >>     <<01415>>04040000
   << built above and execute in non-existent memory    >>     <<01415>>04045000
                                                               <<01415>>04050000
   assemble (pcn);           <<get cpu number>>                <<01415>>04055000
   if s0 = series'33 then                                      <<03008>>04060000
      begin    <<this is a 33 - pcal hyperspace>>              <<01415>>04065000
      del;                                                     <<03008>>04070000
      tos := %100002;  <<seg #2, stt#0 - address of hyprspce>> <<01415>>04075000
      assemble (pcal 0);  << "ENERGIZE, SCOTTY" >>             <<01415>>04080000
      end                                                      <<01415>>04085000
   else if tos = icf'44                                        <<03008>>04090000
           then assemble(halt 7)                               <<03008>>04095000
           else asmb(con %20104; con %5);    <<flush for '55>> <<03008>>04100000
end;                                                                    04105000
                                                               <<04184>>04110000
                                                               <<04184>>04115000
procedure dculogging;                                          <<04184>>04120000
option privileged,uncallable;                                  <<04184>>04125000
                                                               <<04184>>04130000
comment                                                        <<04184>>04135000
       this procedure is for the series'64 dcu logging.        <<04184>>04140000
       dcu logging is interrupt driven, written to a           <<04184>>04145000
       temporary memory buffer and later on to disc.           <<04184>>04150000
       dcu'request will handle the writing of the              <<04184>>04155000
       information.  microcode will trap to here first         <<04184>>04160000
       and we will print a message to the console saying       <<04184>>04165000
       that dcu logging is taking place or is done. then       <<04184>>04170000
       we will call the procedure dcu'request.                 <<04184>>04175000
       the parms given to us at q+1:(bit 15)  are:             <<04184>>04180000
                                                               <<04184>>04185000
           0 : dcu logging in progress                         <<04184>>04190000
           1 : dcu logging complete                            <<04184>>04195000
                                                               <<04184>>04200000
       all interrupts will be held off if we have disabled     <<04184>>04205000
       interrupts.                                             <<04184>>04210000
;                                                              <<04184>>04215000
                                                               <<04184>>04220000
                                                               <<04184>>04225000
begin                                                          <<04184>>04230000
                                                               <<04184>>04235000
    <<don't add a variable at q+1-dcumsgstate must be here>>   <<04184>>04240000
logical dcumsgstate  = q+1;  <<dropped by microcode>>          <<04184>>04245000
                                                               <<04184>>04250000
integer dcumessage   = q+2;   <<type of message for console>>  <<04184>>04255000
                                                               <<04184>>04260000
equate msgstart      = 144,                                    <<04184>>04265000
       msgdone       = 145,                                    <<04184>>04270000
       console       = 0,   <<console num for iomessage>>      <<04184>>04275000
       sysdb         = %1000,                                  <<04184>>04280000
       icf'55        = 4;    <<cpu number for series'64>>      <<04184>>04285000
                                                               <<04184>>04290000
disable;                                                       <<04184>>04295000
trapsoff;                                                      <<04184>>04300000
                                                               <<04184>>04305000
asmb(adds 1);   <<make room for local variable>>               <<04184>>04310000
asmb(pcn);                                                     <<04184>>04315000
if tos <> icf'55                                               <<04184>>04320000
   then suddendeath(15)  <<we should not be here if this>>     <<04184>>04325000
                         <<is not a series'64. so this must>>  <<04184>>04330000
                         <<be a ghost interrupt.        >>     <<04184>>04335000
   else begin                                                  <<04184>>04340000
        <<find which type of interrupt it is and msg num.>>    <<04184>>04345000
        if dcumsgstate then dcumessage := msgdone              <<04184>>04350000
                       else dcumessage := msgstart;            <<04184>>04355000
                                                               <<04184>>04360000
        tos := sysdb d;                                        <<04184>>04365000
        asmb(xchd);                                            <<04184>>04370000
        iomessage(1,dcumessage,,,,,,,console);                 <<04184>>04375000
        dcu'request(dcumsgstate);                              <<04184>>04380000
        asmb(xchd; ddel)                                       <<04184>>04385000
        end                                                    <<04184>>04390000
                                                               <<04184>>04395000
end;                                                           <<04184>>04400000
                                                               <<04184>>04405000
                                                               <<04184>>04410000
                                                                        04415000
  procedure systemclock;                                                04420000
    option privileged,uncallable;                                       04425000
    begin                                                               04430000
    array space(0:2)=q; <<protect db and parameter>>                    04435000
    integer tslint=q+3; << time since last interrupt interval >>        04440000
  equate trldstindex=trldst*4+2;                               <<06827>>04445000
    disable;                                                            04450000
  tos := dst(trldstindex);                                     <<06827>>04455000
  tos := dst(x:=x+1);                                          <<06827>>04460000
    asmb(xchd);  <<set db to timer request list>>                       04465000
    tos := tslint; << tick expects this at q-4 >>                       04470000
    tick;                                                               04475000
    asmb(del;xchd;ixit);                                                04480000
    end;                                                                04485000
                                                                        04490000
  procedure breakpoint;                                                 04495000
    option privileged,uncallable;                                       04500000
    begin                                                               04505000
    asmb(cbkp);                                                         04510000
    end;                                                                04515000
                                                                        04520000
procedure  unimplementedinstruction;                                    04525000
   option privileged,uncallable;                                        04530000
   begin                                                                04535000
   integer userx = q-3,                                        <<1040>> 04540000
           s2    = s-2;                                        <<1040>> 04545000
   integer array nextq(*) = q+2;                               <<1040>> 04550000
   integer instr     = nextq,                                  <<1040>> 04555000
           trap'loc  = instr+1;                                <<1040>> 04560000
                                                               <<02011>>04565000
   define  ploc      = p.(2:14) #;                             <<02011>>04570000
                                                               <<02011>>04575000
   logical subroutine dblword'instr;                           <<1040>> 04580000
   begin                                                       <<1040>> 04585000
      comment *** warning: this sub. must not change           <<1040>> 04590000
              *** the x register;                              <<1040>> 04595000
      tos := x;                                                <<1040>> 04600000
      << assign return value to dblword'inst >>                <<1040>> 04605000
      s2 := if instr = %20477 then true else false;            <<1040>> 04610000
      x := tos; << restore x >>                                <<1040>> 04615000
   end;                                                        <<1040>> 04620000
                                                               <<1040>> 04625000
   tos := x; << save instr >>                                  <<1040>> 04630000
                                                               <<04750>>04635000
   if dblword'instr then                                       <<1040>> 04640000
      begin                                                    <<1040>> 04645000
      comment:                                                 <<1040>> 04650000
         instr contains word 1 of the instruction.             <<1040>> 04655000
         for a two word instruction with an invalid            <<1040>> 04660000
         2nd word the 'p' register contains p+2.               <<1040>> 04665000
         however, if there is no microcode to support          <<1040>> 04670000
         the instruction, the trap occured on the              <<1040>> 04675000
         1st word and the 'p' reg. contains p+1.;              <<1040>> 04680000
      << load instruction at p-1 >>                            <<1040>> 04685000
      tos:=0;  <<space for trap'loc>>                          <<04750>>04690000
      tos := 0; << return value for convsegid >>               <<01659>>04695000
      tos := status.(8:8);                                     <<06095>>04700000
      tos.(0:1) := p.(1:1);                                    <<06095>>04705000
      tos := cstconv (*,0);                                    <<06095>>04710000
      tos:=dst(x:=tos+2);                                      <<mpeiv>>04715000
      tos:=dst(x:=x+1)+(p-1);                                  <<mpeiv>>04720000
      lmem;                                                    <<1040>> 04725000
      enable;                                                  <<1040>> 04730000
      instr := tos; << word that caused trap >>                <<1040>> 04735000
      ddel;  << delete extended address >>                     <<1040>> 04740000
      trap'loc := ploc-1; <<save loc of word that trapped>>    <<02011>>04745000
      comment:                                                 <<1040>> 04750000
         if word at p-1 is a double word instruction           <<1040>> 04755000
         then assume no microcode for 2 word instr             <<1040>> 04760000
         else actual 2 word instr with trap on 2nd             <<1040>> 04765000
         word. p gets beginning of 2 word instr.;              <<1040>> 04770000
      if dblword'instr then ploc := ploc-1                     <<02011>>04775000
      else ploc := ploc-2;                                     <<02011>>04780000
      goto l;                                                  <<1040>> 04785000
      end;                                                     <<1040>> 04790000
   enable;                                                     <<1040>> 04795000
   if %20400 <= x <= %20415 then                                        04800000
      begin                                                             04805000
      x := x.(12:4);                                                    04810000
      asmb( br p+1,x );                                                 04815000
      eadd;                                                             04820000
      esub;                                                             04825000
      empy;                                                             04830000
      ediv;                                                             04835000
      eneg;                                                             04840000
      ecmp;                                                             04845000
      assemble(br p+8);                                                 04850000
      assemble(br p+7);                                                 04855000
      qadd;                                                             04860000
      qsub;                                                             04865000
      qmpy;                                                             04870000
      qdiv;                                                             04875000
      qneg;                                                             04880000
      qcmp;                                                             04885000
      end;                                                              04890000
   if x.(0:10) = %157 or x.(0:10) = %117 then                           04895000
      begin <<quad shift>>                                              04900000
      tos := tos.(10:6) + userx;                                        04905000
      if logical(x.(4:1)) then qasr                                     04910000
      else qasl;                                                        04915000
      end;                                                              04920000
   if %20570 <= x <= %20571                                             04925000
   or %20560 <= x <= %20561                                             04930000
   then                                                                 04935000
      if tos then didiv                                                 04940000
      else dimpy;                                                       04945000
   tos := %177617;                                                      04950000
   asmb( and,xax );                                                     04955000
   if  %20601 <= x <= %20614  then                                      04960000
      begin                                                             04965000
      delb;   << cut off parameter >>                                   04970000
      x := x.(12:4);                                                    04975000
      asmb( br p+0,x );                                                 04980000
      dmul;                                                             04985000
      cvad;                                                             04990000
      cvda;                                                             04995000
      cvbd;                                                             05000000
      cvdb;                                                             05005000
      sld;                                                              05010000
      nsld;                                                             05015000
      srd;                                                              05020000
      addd;                                                             05025000
      cmpd;                                                             05030000
      subd;                                                             05035000
      mpydsim;                                                          05040000
      end;                                                              05045000
   ploc := ploc-1;                                             <<02011>>05050000
    tos:=ploc;  <<trap'loc>>                                   <<04750>>05055000
   << at this point p points to 1st word of instr >>           <<03040>>05060000
   << that caused trap, trap'loc points to the    >>           <<03040>>05065000
   << word of the instruction that was bad        >>           <<03040>>05070000
l: if instr = %36000  then                                     <<1040>> 05075000
      begin  << possiblely a breakpoint >>                              05080000
      tos := 0d;  << return value for teststop >>              <<07302>>05085000
      tos := 0d;  << return value for mappedcsttophycst >>     <<06655>>05090000
      tos := status.(8:8);                                     <<06095>>05095000
      tos.(0:1) := p.(1:1);                                    <<06095>>05100000
      tos := mappedcsttophycst(*,0);                           <<06095>>05105000
      teststop(*,trap'loc,curprc);                             <<06642>>05110000
      if  >  then  return;                                              05115000
      if  =  then                                              <<1040>> 05120000
          begin                                                <<1040>> 05125000
          << flag break on 2nd of 2 word instr >>              <<1040>> 05130000
          if trap'loc <> ploc then x := true                   <<02011>>05135000
          else x := false;                                     <<1040>> 05140000
          debug;                                               <<1040>> 05145000
          end;                                                 <<1040>> 05150000
      end;                                                              05155000
   << set up call to abort >>                                  <<03040>>05160000
   x := instr;                                                 <<03040>>05165000
   ploc := trap'loc+1;      << one past illegal word >>        <<03040>>05170000
   abort([8/1,8/0],7,0); << with instr in xreg >>              <<03040>>05175000
   end;                                                                 05180000
$page                                                          <<06655>>05185000
procedure  sttviolation;                                                05190000
   option privileged,uncallable;                                        05195000
   begin                                                                05200000
   enable;                                                              05205000
   abort([8/1,8/0],31,0); << with instr in xreg >>             <<03040>>05210000
   end;                                                                 05215000
                                                                        05220000
procedure  cstviolation;                                                05225000
   option privileged,uncallable;                                        05230000
   begin                                                                05235000
   enable;                                                              05240000
   abort([8/1,8/0],30,0); << with instr in xreg >>             <<03040>>05245000
   end;                                                                 05250000
                                                                        05255000
procedure  dstviolation;                                                05260000
   option privileged,uncallable;                                        05265000
   << db-bank may be invalid >>                                         05270000
   suddendeath(16);                                                     05275000
$page                                                          <<06655>>05280000
procedure stackoverflow;                                       <<mpeiv>>05285000
option privileged,uncallable;                                  <<mpeiv>>05290000
                                                               <<mpeiv>>05295000
comment                                                        <<mpeiv>>05300000
                                                               <<mpeiv>>05305000
stackoverflow is the interrupt handler for internal traps      <<mpeiv>>05310000
caused by an instruction attempting to push s beyond z.when    <<mpeiv>>05315000
such a condition is detected by microcode, control brances     <<mpeiv>>05320000
to this procedure on the ics with interrupts disabled.         <<mpeiv>>05325000
                                                               <<mpeiv>>05330000
the system must crash if the overflowing stack is frozen,      <<mpeiv>>05335000
locked or core resident, since there's no way to extend        <<mpeiv>>05340000
these.  otherwise, a message is sent to the dispatcher to      <<mpeiv>>05345000
write the stack, release its space, and flag the process       <<mpeiv>>05350000
as requiring scheduling attention. (the sll memory request     <<06655>>05355000
pointer of the overflowing process is set to -1, indicating    <<06655>>05360000
to the scheduler that the process' stack must be made present  <<06655>>05365000
before the process can be launched). the stack's new size      <<06655>>05370000
(oldsize + stovrinc) is placed in the stack's xst entry, and   <<mpeiv>>05375000
the stack's st entry is flagged as requiring a modification.   <<mpeiv>>05380000
                                                               <<mpeiv>>05385000
if the code causing the stackoverflow had disabled external    <<mpeiv>>05390000
interrupts or pdisabled switching, it must be allowed to con-  <<mpeiv>>05395000
tinue until it completes the action for which it had set       <<mpeiv>>05400000
the internal lock.  that's the reason stacks are allocated     <<mpeiv>>05405000
an overflow area beyond z.  if the code had disabled interrupts<<mpeiv>>05410000
the interrupt request flip flop of the clock is set,           <<mpeiv>>05415000
and when the code enables interrupts the clock interrupt       <<mpeiv>>05420000
handler will be entered and will do a disp.  if the code       <<mpeiv>>05425000
was pdisabled when it caused the stackoverflow, the disp at    <<mpeiv>>05430000
the end of this procedure will cause control to switch         <<mpeiv>>05435000
to the dispatcher as soon as the process untangles itself.     <<mpeiv>>05440000
                                                               <<mpeiv>>05445000
;                                                              <<mpeiv>>05450000
   begin                                                                05455000
                                                               <<06655>>05460000
   define                                                      <<06655>>05465000
     objident = double(stackdst)#;  << for sendmsg,genspecreq>><<06655>>05470000
                                                               <<06655>>05475000
equate                                                         <<*8591>>05480000
   ics'stackbank   =  5,                                       <<*8591>>05485000
   ics'deltas      =  6,                                       <<*8591>>05490000
   ics'deltaz      =  8,                                       <<*8591>>05495000
   ics'stackbase   =  9,                                       <<*8591>>05500000
   ics'stackdst    = 16,                                       <<*8591>>05505000
   ics'pdisabledcnt= 18;                                       <<*8591>>05510000
                                                               <<*8591>>05515000
   integer array  pcbx(*) = q+0;                                        05520000
   integer  s0 = s-0,                                                   05525000
            users0 = q-4,    <<top of stack at overflow time>> <<00693>>05530000
            deltas = q - ics'deltas,                           <<*8591>>05535000
            deltaz = q - ics'deltaz,                           <<*8591>>05540000
            stackbank = q-ics'stackbank,                       <<*8591>>05545000
            stackbase = q-ics'stackbase;                       <<*8591>>05550000
   double  stdb = q-5;                                                  05555000
   equate  ixit = %20360,                                               05560000
           adds = %35000,                                               05565000
           subs = %35400,                                      <<01415>>05570000
           setr = %027400,                                     <<01967>>05575000
           exit = %31400,                                               05580000
           pshr = %024400,                                     <<01967>>05585000
                                                               <<01415>>05590000
           series'33 = 8,   <<pcn numbers for the various>>    <<01415>>05595000
           icf'44    = 3,   <<cpu that use this code     >>    <<01415>>05600000
          icf'37    = 5,                                       <<*8289>>05605000
           icf'55    = 4;                                      <<01415>>05610000
                                                               <<01415>>05615000
   define  deltaz' = f(f(qi)-ics'deltaz)#;                     <<*8591>>05620000
equate stackovrinc=512,                                        <<01706>>05625000
       extrainc=1152;                                          <<mpeiv>>05630000
equate locvarcnt=14;                                           <<01966>>05635000
logical ls0=s-0;                                               <<mpeiv>>05640000
integer instruction=q+1,                                       <<mpeiv>>05645000
        oldsize=q+2,                                           <<mpeiv>>05650000
        newsize=q+3,                                           <<mpeiv>>05655000
        pagesrequired=q+4,                                     <<mpeiv>>05660000
        wordsrequired=q+5,                                     <<mpeiv>>05665000
        olddeltaz=q+6,                                         <<mpeiv>>05670000
        stackdst=q+7,                                          <<mpeiv>>05675000
        sbreldb=q+8,                                           <<mpeiv>>05680000
        maxstacksize=q+9,                                      <<mpeiv>>05685000
        increment=q+10,                                        <<mpeiv>>05690000
        dbreltostkbase=q+11;                                   <<mpeiv>>05695000
                                                               <<06210>>05700000
                                                               <<06210>>05705000
integer pagesalloc=q+12;                                       <<01706>>05710000
integer pcbpt=q+13;                                            <<01966>>05715000
                                                                        05720000
                                                               <<*8591>>05725000
<< the following variables are only used for the portion of >> <<*8591>>05730000
<< stackoverflow that runs on the ics.                      >> <<*8591>>05735000
<< local variable is at q+3 since q+1 has the double word   >> <<*8591>>05740000
<< value of db pushed. this is needed for the ixit.         >> <<*8591>>05745000
                                                               <<*8591>>05750000
double                                                         <<*8591>>05755000
   last'stack'addr = q+3,                                      <<*8591>>05760000
   dsm1            = s-1;                                      <<*8591>>05765000
                                                               <<*8591>>05770000
   << this portion runs on the ics >>                                   05775000
                                                               <<*8591>>05780000
   asmb(adds 4);     << room for last'stack'addr >>            <<*8591>>05785000
   tos := x;         << save instruction >>                    <<*8591>>05790000
   tos := stackbank;                                           <<*8591>>05795000
   tos := stackbase;                                           <<*8591>>05800000
   tos := tos + rbtorsdisp;                                    <<*8591>>05805000
   asmb(lsea);       << region size for the stack >>           <<*8591>>05810000
   tos := (tos & lsl(pagepower)) - trailerlength;              <<*8591>>05815000
   asmb(xch);        << tos is now offset to rs in header >>   <<*8591>>05820000
   tos := tos + rstorasdisp;  << point to top of reg. header >><<*8591>>05825000
   asmb(add);                                                  <<*8591>>05830000
   last'stack'addr := tos;       << last valid stack address >><<*8591>>05835000
                                                               <<*8591>>05840000
   if lpcb(curprc + stkinfowordnum).stovrallflag then          <<*8591>>05845000
      suddendeath(640);                                        <<*8591>>05850000
                                                               <<*8591>>05855000
   x := tos;      << instruction >>                            <<*8591>>05860000
                                                               <<*8591>>05865000
   if  x = ixit  then  deltas := deltas-4;                              05870000
   tos := stdb;                                                         05875000
   tos := tos+deltas-1;          << user q+1 >>                         05880000
   tos := x;                     << build a marker to get off ics >>    05885000
   tos := @stov'user;                                                   05890000
   if mappingfirmware then asmb( tsbc 1 ); << set physical >>  <<06095>>05895000
   asmb( sdea );                                                        05900000
   tos := tos+2;                                                        05905000
                                                               <<*8620>>05910000
   << check for bank wrap around or falling out of region >>   <<*8620>>05915000
                                                               <<*8620>>05920000
   if carry or dsm1 >= last'stack'addr then                    <<*8620>>05925000
      suddendeath(646);                                        <<*8591>>05930000
                                                               <<*8591>>05935000
   push( status );                                                      05940000
   tos := 4;                                                            05945000
   asmb( sdea );                                                        05950000
   tos := tos+2;                                                        05955000
                                                               <<*8620>>05960000
   << check for bank wrap around or falling out of region >>   <<*8620>>05965000
                                                               <<*8620>>05970000
   if carry or dsm1 >= last'stack'addr then                    <<*8620>>05975000
      suddendeath(646);                                        <<*8591>>05980000
                                                               <<*8591>>05985000
   push( db );                                                          05990000
   asmb( sdea );                                                        05995000
   deltas := deltas+4;                                                  06000000
   deltaz := deltaz + 120;                                              06005000
                                                               <<*8591>>06010000
   asmb(subs 4);     << put s back where it was on entry >>    <<*8591>>06015000
   asmb( psdb; ixit );                                                  06020000
                                                                        06025000
stov'user:  << the marker above exits to here >>                        06030000
   tos:=x;  <<save cir for call to stackoverflow>>             <<00693>>06035000
                                                               <<01415>>06040000
   <<adjust delta p to point to instruction with sk ovrflw>>   <<01415>>06045000
                                                               <<01415>>06050000
   assemble (pcn);              <<get cpu number>>             <<01415>>06055000
   assemble (dup,dup);      <<cpu number again>>               <<*8289>>06060000
   if tos = icf'37 then ddel else                              <<*8289>>06065000
   if tos <> icf'44 then                                       <<01967>>06070000
      begin          <<for series 33 and series 55>>           <<01967>>06075000
        x := logical (x) land %177400;  <<get the opcode only>><<01967>>06080000
                                                               <<01967>>06085000
        if tos = icf'55 then                                   <<01967>>06090000
           begin             <<series 55>>                     <<01967>>06095000
             if x = adds or x = subs or     <<adjust p to >>   <<01967>>06100000
                x = setr or x=exit or       <<retry>>          <<01967>>06105000
                x = pshr then               <<instruction>>    <<01967>>06110000
                      p := p - 1;                              <<01967>>06115000
             if instruction = %020477     <<double word>>      <<01967>>06120000
                then p := p - 2;        <<cobol instruction>>  <<01967>>06125000
           end                                                 <<01967>>06130000
          else                                                 <<01967>>06135000
                                                               <<01967>>06140000
           begin            <<series 33>>                      <<01967>>06145000
             <<code for the series 33 adjustment>>             <<01967>>06150000
 << most instructions do not have to be retried because the >> <<01967>>06155000
 << check for the interrupt flag for stckoverflow is made   >> <<01967>>06160000
 << after the instruction is executed.  the exceptions are  >> <<01967>>06165000
 << checked for below. (microcode is doing the checking)    >> <<01967>>06170000
             if x = adds or x = subs or                        <<01967>>06175000
                 x = setr or x = exit                          <<01967>>06180000
                  then p := p - 1;                             <<01967>>06185000
           end                                                 <<01967>>06190000
      end                                                      <<01967>>06195000
                                                               <<01967>>06200000
   else                                                        <<01415>>06205000
      begin                     <<jaguar icf/44 adjustment>>   <<01415>>06210000
      <<series ii/iii tests for apl too>>                      <<01415>>06215000
      del;              <<delete extra cpu number>>            <<01967>>06220000
      if x <> ixit then                                        <<01415>>06225000
         begin                                                 <<01415>>06230000
         p := p - 1;                                           <<01415>>06235000
         x := logical(x) land %170077;    <<clear left sk op>> <<01415>>06240000
         if 1 <= x <= 63 then                                  <<01415>>06245000
            begin  <<it is a stack inst. with right sk op>>    <<01415>>06250000
            tos := status;  <<is left sk op active?>>          <<01415>>06255000
            assemble (tcbc 3);                                 <<01415>>06260000
            if <> then p := p + 1;                             <<01415>>06265000
            status := tos;                                     <<01415>>06270000
            end;                                               <<01415>>06275000
         end;                                                  <<01415>>06280000
      if instruction = %020477     <<double word>>             <<01967>>06285000
          then p := p - 1;      <<cobol instructions>>         <<01967>>06290000
      end;       <<of delta p adjustment>>                     <<01415>>06295000
                                                               <<01415>>06300000
asmb(adds locvarcnt);                                          <<01564>>06305000
<<instruction already at q+1>>                                 <<01564>>06310000
trapsoff;                                                      <<01858>>06315000
if gclassenabledmask.class0 then                               <<01564>>06320000
   begin  <<measure stk ovrflow event>>                        <<01564>>06325000
   tos:=measstatxdsbank;                                       <<01564>>06330000
   tos:=measstatxdsbase;                                       <<01564>>06335000
   tos:=tos+c0sub0'segreloff+c'stopstkoverflow;                <<01564>>06340000
   asmb(lsea);                                                 <<01564>>06345000
   tos:=tos+1;                                                 <<01564>>06350000
   asmb(ssea;ddel);                                            <<01564>>06355000
   end;                                                        <<01564>>06360000
if gclassenabledmask.class15 then                              <<01809>>06365000
   begin <<process level stackoverflow>>                       <<01809>>06370000
   tos:=measprocxdsbank;                                       <<01809>>06375000
   tos:=measprocxdsbase;                                       <<01809>>06380000
   tos := tos + (curprc)/pcbsize*                              <<06642>>06385000
        class15'sub0size+cp'stopsegexpand;                     <<01809>>06390000
   asmb(lsea);                                                 <<01809>>06395000
   tos:=tos+1;                                                 <<01809>>06400000
   asmb(ssea;ddel);                                            <<01809>>06405000
   end;                                                        <<01809>>06410000
disable;                                                       <<01564>>06415000
pcbpt := curprc;                                               <<06642>>06420000
absolute(syswaittodispmsg).memtrapflag:=1;                     <<01564>>06425000
x:=stackdst:=absolute(absolute(ics'qi)-ics'stackdst);          <<01564>>06430000
tos := mmstatspecreq;                                          <<*7949>>06435000
tos := objident;                                               <<*7949>>06440000
mmstat'(*,*,*,stack'overflow,ics(-ics'deltaz),0,0);            <<*7949>>06445000
oldsize:=dst(x:=stackdst&lsl(2)).datasizefield&lsl(2);         <<01564>>06450000
tos:=absolute(absolute(ics'qi)-ics'stackbank);                 <<01564>>06455000
tos:=absolute(absolute(ics'qi)-ics'stackbase);                 <<01564>>06460000
tos:=tos+rbtorsdisp;                                           <<01706>>06465000
asmb(lsea);                                                    <<01706>>06470000
pagesalloc:=tos;                                               <<01706>>06475000
tos:=tos+rstorbdisp;                                           <<01706>>06480000
tos:=tos+sbtoreldb;                                            <<01564>>06485000
asmb(lsea);                                                    <<01564>>06490000
dbreltostkbase:=tos;                                           <<01564>>06495000
tos:=tos-sbtoreldb;                                            <<01564>>06500000
tos:=tos+stbtomaxdata; <<21 decimal>>                          <<01564>>06505000
asmb(lsea);<<max for pcbxtoz>>                                 <<01564>>06510000
maxstacksize:=tos;                                             <<01564>>06515000
tos:=tos+maxdatatorelz; <<9>>                                  <<01564>>06520000
asmb(lsea);                                                    <<01564>>06525000
olddeltaz:=s0;                                                 <<01564>>06530000
tos:=tos+120;                                                  <<01564>>06535000
asmb(ssea); <<in case block in getdatasegchangestate>>         <<01564>>06540000
if olddeltaz >= maxstacksize-dbreltostkbase then               <<01706>>06545000
   begin <<stack has grown beyond allowable size>>             <<01564>>06550000
   procstate.stovflag := 1;                                    <<06642>>06555000
   if <> then suddendeath(641);                                <<01687>>06560000
   increment:=extrainc;                                        <<01564>>06565000
   tos:=tos-maxdatatorelz;                                     <<01564>>06570000
   tos:=maxstacksize+extrainc;                                 <<01564>>06575000
   asmb(ssea);                                                 <<01564>>06580000
   tos:=tos+maxdatatorelz;                                     <<01564>>06585000
   end                                                         <<01564>>06590000
else                                                           <<01564>>06595000
   begin  <<stack ok, check for adds 0 instr >>                <<01564>>06600000
      if instruction <> %35000 then increment := stackovrinc   <<01564>>06605000
      else increment := stackovrinc + users0;                  <<01564>>06610000
   if logical(olddeltaz+increment) >                           <<01564>>06615000
      logical(maxstacksize-dbreltostkbase)  then               <<01564>>06620000
      increment := (maxstacksize-dbreltostkbase) - olddeltaz;  <<01564>>06625000
   increment:=logical(increment+3) land -4;                    <<01706>>06630000
   end;                                                        <<01564>>06635000
pagesrequired:=(oldsize+increment+overhead-1)                  <<01564>>06640000
                   &lsr(pagepower)+1;                          <<01564>>06645000
wordsrequired:=pagesrequired&lsl(pagepower);                   <<01564>>06650000
<<newsize:=wordsrequired-(overhead+128) causes vds ovrflow>>   <<01564>>06655000
newsize:=oldsize+increment;                                    <<01564>>06660000
tos:=tos+relztorbdisp+rbtorasdisp;                             <<01564>>06665000
asmb(lsea);                                                    <<01564>>06670000
if tos.regiofzflag=1 then                                      <<01564>>06675000
   begin                                                       <<01564>>06680000
   if status.(1:1) = 0 then suddendeath(642);                  <<01687>>06685000
if absolute(absolute(ics'qi)-ics'pdiscntcell) > 1 then         <<02090>>06690000
   comment:  the purpose of the following code is to cover up  <<k7614>>06695000
             a pdisable problem in which an interrupt handler  <<k7614>>06700000
             appears to execute a pdisable without a           <<k7614>>06705000
             corresponding penable.  this strange problem      <<k7614>>06710000
             always appears to leave the pdisable count at 1.  <<k7614>>06715000
             if this condition is met, we shall execute a      <<k7614>>06720000
             penable on behalf of the defective software       <<k7614>>06725000
             [a small prayer is in order here] and continue    <<k7614>>06730000
             execution (soft'death will log this event). ;     <<k7614>>06735000
                                                               <<k7614>>06740000
   if absolute(absolute(ics'qi)-ics'pdiscntcell) = 2 then      <<k7614>>06745000
      begin                                                    <<k7614>>06750000
      penable;  <<it's a miracle>>                             <<k7614>>06755000
      soft'death(642);                                         <<k7614>>06760000
      end                                                      <<k7614>>06765000
   else                                                        <<k7614>>06770000
      suddendeath(642);     <<leave the sf hook in>>           <<k7614>>06775000
                                                               <<02090>>06780000
   end;                                                        <<01564>>06785000
penable;                                                       <<01564>>06790000
tryagain:                                                      <<01949>>06795000
getdatasegchangestate(stackdst);                               <<01564>>06800000
if < then suddendeath(643) else if > then go tryagain;         <<01949>>06805000
<<pdisable in effect now, and stack marked absent!>>           <<01564>>06810000
stkinfo.stovrallflag := 1;                                     <<06642>>06815000
tos:=dst(x:=stackdst&lsl(2)+2);                                <<01564>>06820000
tos:=dst(x:=x+1);                                              <<01564>>06825000
tos:=tos+maxdatatoreldb+stbtomaxdata;                          <<01564>>06830000
asmb(lsea); <<stack base to db>>                               <<01564>>06835000
sbreldb:=tos;                                                  <<01564>>06840000
tos:=tos+reldbtorelz; <<9>>                                    <<01564>>06845000
tos:=olddeltaz+increment;                                      <<01564>>06850000
asmb(ssea);                                                    <<01564>>06855000
if pagesalloc >= pagesrequired then                            <<01706>>06860000
   begin <<current region is ok>>                              <<01564>>06865000
                                                               <<s8583>>06870000
   << no need to cause a swapin for this guy, can fix the    >><<s8583>>06875000
   << stack overflow without making stack absent.            >><<s8583>>06880000
                                                               <<s8583>>06885000
   absolute(syswaittodispmsg).memtrapflag := 0;                <<s8583>>06890000
                                                               <<s8583>>06895000
   pcb(curprc + stkinfowordnum).                               <<06642>>06900000
   stovrallflag:=0;                                            <<01564>>06905000
   dst(x:=stackdst&lsl(2)).datasizefield:=newsize&lsr(2);      <<01564>>06910000
   dst(x).absentflag:=0;                                       <<01564>>06915000
   absolute(absolute(ics'qi)-ics'deltaz):=olddeltaz +          <<01564>>06920000
   increment;                                                  <<01564>>06925000
   <<flip db to stack db for the set z instruction>>           <<01800>>06930000
   tos:=ics(-ics'stkbankcell);                                 <<01800>>06935000
   tos:=ics(-ics'absstkdbcell);                                <<01800>>06940000
   asmb(xchd);                                                 <<01800>>06945000
   tos:=olddeltaz+increment;                                   <<01784>>06950000
   set(z); <<store new delta z into register>>                 <<01784>>06955000
   asmb(xchd;ddel); <<db back to where it belongs>>            <<01800>>06960000
   penable;                                                    <<01564>>06965000
   end                                                         <<01564>>06970000
else                                                           <<01564>>06975000
   begin <<current region isn't big enough>>                   <<01564>>06980000
   genspecreq(objident,newsize&lsr(2),0,0);                    <<06655>>06985000
   tos := objident;                                            <<06655>>06990000
   tos := curprc;                                              <<06642>>06995000
   sendmsg(schedpin,makeabsentport,3,0);                       <<06655>>07000000
   if status.(1:1) = 0 then                                    <<01564>>07005000
      begin <<process had disabled interrupts>>                <<01564>>07010000
      tos:=3; <<clock drt>>                                    <<01564>>07015000
      asmb(sinc);  <<tick will do a disp>>                     <<01564>>07020000
      penable;                                                 <<01564>>07025000
      dst(stackdst&lsl(2)).absentflag:=0; <<mark present>>     <<01939>>07030000
      return;                                                  <<01564>>07035000
      end                                                      <<01564>>07040000
   else asmb(disp;pseb); <<get control to dispatcher>>         <<01564>>07045000
   if ics(-ics'pdiscntcell) > 0 then                           <<01939>>07050000
      begin  <<process has switching disabled>>                <<01939>>07055000
      dst(stackdst&lsl(2)).absentflag:=0; <<mark present>>     <<01939>>07060000
      return; <<disp above will get control to dispatcher>>    <<01939>>07065000
      end;                                                     <<01939>>07070000
   end;                                                        <<01564>>07075000
if pcb(pcbpt+procstatewordnum).stovflag=1                      <<01966>>07080000
and pcb(pcbpt+resabortinfowordnum).critflag=0                  <<01966>>07085000
and pcb(pcbpt+resabortinfowordnum).hassirflag=0                <<01966>>07090000
then                                                           <<04527>>07095000
   begin                                                       <<04527>>07100000
   p := p+1; << update p for abort routine >>                  <<04527>>07105000
   << let kernel routines know we're processing abort >>       <<04527>>07110000
   pcb(pcbpt+resabortinfowordnum).stovabortflag := 1;          <<04527>>07115000
   abort ([8/1,8/4],0,0);                                      <<04527>>07120000
   end;                                                        <<04527>>07125000
end  <<stackoverflow>>;                                        <<01564>>07130000
                                                                        07135000
procedure stackunderflow;                                      <<01744>>07140000
option privileged,uncallable;                                  <<01744>>07145000
begin <<stackunderflow>>                                       <<01744>>07150000
equate      icf44                   = 3,                       <<01744>>07155000
                                                               <<01744>>07160000
            icf37                   = 5,                       <<*8289>>07165000
                                                               <<*8289>>07170000
            icf55                   = 4,                       <<01744>>07175000
                                                               <<01744>>07180000
            qi                      = 5,                       <<01744>>07185000
                                                               <<01744>>07190000
            cpcb                    = 4;                       <<01744>>07195000
                                                               <<01744>>07200000
                                                               <<01744>>07205000
integer     x                       = x,                       <<01744>>07210000
                                                               <<01744>>07215000
            processor'type          = q+4,                     <<01744>>07220000
                                                               <<01744>>07225000
            next1                   = q+3;                     <<01744>>07230000
                                                               <<01744>>07235000
                                                               <<01744>>07240000
logical     deltap                  = q-2,                     <<01744>>07245000
                                                               <<01744>>07250000
            status                  = q-1,                     <<01744>>07255000
                                                               <<01744>>07260000
            instruction             = q+1,                     <<01744>>07265000
                                                               <<01744>>07270000
            cst'entry               = q+4;                     <<01744>>07275000
                                                               <<01744>>07280000
                                                               <<01744>>07285000
double      next'instructions       = q+2;                     <<01744>>07290000
                                                               <<01744>>07295000
                                                               <<01744>>07300000
define      stun'sim'enabled        = stun'sim'bit=0#,         <<01744>>07305000
                                                               <<01744>>07310000
            stun'sim'bit            = f(f(qi)-31).(1:1)#,      <<01744>>07315000
                                                               <<01744>>07320000
            simbit                  = (8:1)#,                  <<01744>>07325000
                                                               <<01744>>07330000
            mode                    = (0:1)#,                  <<01744>>07335000
                                                               <<01744>>07340000
            user'mode               = status.mode=0#,          <<01744>>07345000
                                                               <<01744>>07350000
            cst'base                = f(0)#,                   <<01744>>07355000
                                                               <<01744>>07360000
            cstx'base               = f(1)#,                   <<01744>>07365000
                                                               <<01744>>07370000
            cst                     = status.(8:8)#,           <<01744>>07375000
                                                               <<01744>>07380000
            find'processor'type     = asmb(pcn);               <<01744>>07385000
                                      processor'type:=tos#,    <<01744>>07390000
                                                               <<01744>>07395000
            fetch'next'instructions = x:=cst'entry+2;          <<01744>>07400000
                                      asmb(plda);              <<01744>>07405000
                                      x:=x+1;                  <<01744>>07410000
                                      asmb(plda);              <<01744>>07415000
                                      tos:=tos+deltap+1;       <<01744>>07420000
                                      asmb(ldea);              <<01744>>07425000
                                      next'instructions:=tos#, <<01744>>07430000
                                                               <<01744>>07435000
                                                               <<01744>>07440000
            reset's                 = tos:=@next1;             <<01744>>07445000
                                      set(s)#;                 <<01744>>07450000
                                                               <<01744>>07455000
                                                               <<01744>>07460000
                                                               <<01744>>07465000
                                                               <<01744>>07470000
                                                               <<01744>>07475000
                                                               <<01744>>07480000
asmb(adds 3);                                                  <<01744>>07485000
instruction:=x;                                                <<01744>>07490000
find'processor'type;                                           <<01744>>07495000
if user'mode and stun'sim'enabled and                          <<01744>>07500000
  (processor'type=icf44 or processor'type=icf55 or             <<*8289>>07505000
   processor'type=icf37)                                       <<*8289>>07510000
 then                                                          <<01744>>07515000
  begin                                                        <<01744>>07520000
  cst'entry := cst;                                            <<06095>>07525000
  cst'entry.(0:1) := deltap.(1:1);                             <<06095>>07530000
  cst'entry := cstconv(cst'entry,0) + f(2);                    <<06095>>07535000
  fetch'next'instructions;                                     <<01744>>07540000
  enable;                                                      <<01744>>07545000
  reset's;           <<set s for stunsim call>>                <<01744>>07550000
  stunsim;                                                     <<01744>>07555000
  end;                                                         <<01744>>07560000
enable;                                                        <<01744>>07565000
x := instruction;                                              <<03040>>07570000
abort([8/1,8/0],29,0);                                         <<01744>>07575000
end;     <<stackunderflow>>                                    <<01744>>07580000
                                                                        07585000
procedure  privilegedmodeviolation;                                     07590000
   option privileged,uncallable;                                        07595000
   begin                                                                07600000
   enable;                                                              07605000
   abort([8/1,8/0],6,0);  << with instr in xreg >>             <<03040>>07610000
   end;                                                                 07615000
                                                                        07620000
procedure usertrap;                                                     07625000
   option privileged,uncallable;                                        07630000
   begin                                                                07635000
                                                               <<02010>>07640000
define  cstx'base = f(1)#,                                     <<02010>>07645000
        cst'base = f(0)#,                                      <<02010>>07650000
        cst = status.(8:8)#;                                   <<02010>>07655000
                                                               <<02010>>07660000
integer  x = x,                                                <<02010>>07665000
         instruction = q + 2,                                  <<02010>>07670000
         cst'entry = q + 3,                                    <<02010>>07675000
         deltap = q - 2,                                       <<02010>>07680000
         status = q - 1;                                       <<02010>>07685000
                                                               <<02010>>07690000
                                                               <<02010>>07695000
    comment   this code is being added for the series 44.      <<02010>>07700000
              when a user trap occurs on a double word cobol   <<02010>>07705000
              instruction, the x reg contains the first word   <<02010>>07710000
              of the instruction (%020477).  however, for the  <<02010>>07715000
              double word instruction "CVND", cobol expects to <<02010>>07720000
              see the second word in the x register.  this one <<02010>>07725000
              exception is being done here to insure that the  <<02010>>07730000
              code segment is not swapped out and the delta p  <<02010>>07735000
              can be adjusted correctly.                       <<02010>>07740000
              note : coming into this procedure, delta p points<<02010>>07745000
              to the next true inst. after the double word     <<02010>>07750000
              cobol instruction. therefore, to get the second  <<02010>>07755000
              word, we will decrement p by 1                   <<02010>>07760000
;                                                              <<02010>>07765000
                                                               <<02010>>07770000
   asmb(adds 2);                                               <<02010>>07775000
   instruction := x;       <<save current inst>>               <<02010>>07780000
   if instruction = %020477   <<series 44 and 55>>             <<02010>>07785000
      then begin                                               <<02010>>07790000
             cst'entry := cst;                                 <<06095>>07795000
             cst'entry.(0:1) := deltap.(1:1);                  <<06095>>07800000
             cst'entry := cstconv(cst'entry,0) + f(2);         <<06095>>07805000
             x := cst'entry + 2;                               <<02010>>07810000
             asmb(plda);                                       <<02010>>07815000
             x := x + 1;                                       <<02010>>07820000
             asmb(plda);              <<get cst address>>      <<02010>>07825000
             tos := tos + deltap - 1;   <<adr of 2nd word>>    <<02010>>07830000
             asmb(lsea);                                       <<02010>>07835000
             x := tos;                                         <<02010>>07840000
           end;                                                <<02010>>07845000
                                                               <<02010>>07850000
   enable;                                                              07855000
   abort([8/1,8/0],param,0);                                            07860000
   end;                                                                 07865000
$page                                                          <<06655>>07870000
procedure codeabsence;                                         <<mpeiv>>07875000
option privileged,uncallable,internal;                         <<mpeiv>>07880000
                                                               <<mpeiv>>07885000
comment                                                        <<mpeiv>>07890000
                                                               <<mpeiv>>07895000
codeabsence is the internal interrupt handler for pcal and     <<mpeiv>>07900000
exit references to absent segments.  codeabsence runs on the   <<mpeiv>>07905000
trapping process' stack with the following environment set     <<mpeiv>>07910000
up by firmware :                                               <<mpeiv>>07915000
                                                               <<mpeiv>>07920000
x register-                                                    <<mpeiv>>07925000
   the instruction causing the absence trap is placed by       <<mpeiv>>07930000
   firmware into the index register.                           <<mpeiv>>07935000
                                                               <<mpeiv>>07940000
q+1 firmware parameter -                                       <<mpeiv>>07945000
   if absent on an exit then n = # of procedure parameters     <<mpeiv>>07950000
   to be peeled off the stack.                                 <<mpeiv>>07955000
   if absent on a pcal, then =plabel where (3:7)=cstxeix and   <<mpeiv>>07960000
   (10:6) =entry number.                                       <<mpeiv>>07965000
                                                               <<mpeiv>>07970000
stack markers-                                                 <<mpeiv>>07975000
if pcal, two stack markers. the first marker is the normal     <<mpeiv>>07980000
marker set up by firmware for a pcal so that control and       <<mpeiv>>07985000
return on exit. the second marker contains garbage delta       <<mpeiv>>07990000
p, delta q = 4, and status with the cst number of the segment  <<mpeiv>>07995000
the pcal was going to in it.  codeabsence will fix up this     <<mpeiv>>08000000
marker after the required seg comes in by looking up the       <<mpeiv>>08005000
delta p in the new segmment via the stt, placing this into     <<mpeiv>>08010000
the stack marker.  this marker will then be exited into.       <<mpeiv>>08015000
                                                               <<mpeiv>>08020000
for exits, there's only one stack marker, the regular old      <<mpeiv>>08025000
one.  when the segment comes in, codeabsence will retry the    <<mpeiv>>08030000
exit with the n value obtained from firmware's parameter.      <<mpeiv>>08035000
                                                               <<mpeiv>>08040000
to get the segment into memory, codeabsence has an sll entry   <<06655>>08045000
built for the object in the process' sll and points the sll    <<06655>>08050000
memory pointer at it.  wait is called, waiting on memory       <<06655>>08055000
attention.  (this is accomplished via queueonobject).          <<06655>>08060000
                                                               <<mpeiv>>08065000
;                                                              <<mpeiv>>08070000
                                                               <<mpeiv>>08075000
begin                                                          <<mpeiv>>08080000
                                                               <<mpeiv>>08085000
integer s0=s-0,                                                <<mpeiv>>08090000
        s1=s-1,                                                <<mpeiv>>08095000
        pcalstatus=q-5,                                        <<01949>>08100000
        status=q-1;                                            <<mpeiv>>08105000
integer firmwareparm=q+1,                                      <<03040>>08110000
        procinx=q+6,                                           <<03040>>08115000
        cstxeix=q+7,                                           <<03040>>08120000
        descstinx=q+8;                                         <<06655>>08125000
                                                               <<06655>>08130000
double  objid = q + 9;                                         <<06655>>08135000
logical array objectident(*) = objid;                          <<06655>>08140000
                                                               <<06655>>08145000
logical                                                        <<06655>>08150000
        instr=q+2,                                             <<03040>>08155000
        pcalflag=q+3,                                          <<03040>>08160000
        trace=q+11;                                            <<03040>>08165000
double savedb=q+4;                                             <<03040>>08170000
                                                               <<03040>>08175000
subroutine abort'proc (mode,code,abort'parm);                  <<03040>>08180000
   value mode,code,abort'parm;                                 <<03040>>08185000
   integer mode,code,abort'parm;                               <<03040>>08190000
begin                                                          <<03040>>08195000
   comment:  this code places the instruction in x and         <<03040>>08200000
      calls abort. mode.(8:8), code and abort'parm are as      <<03040>>08205000
      defined for abort;                                       <<03040>>08210000
   x := instr;                                                 <<03040>>08215000
   << pop garbage marker laid down for pcals >>                <<03040>>08220000
   mode.(0:8) := if pcalflag then 2 else 1;                    <<03040>>08225000
   abort (mode,code,abort'parm);                               <<03040>>08230000
end;                                                           <<03040>>08235000
                                                               <<03040>>08240000
tos := x; << set up instr >>                                   <<03040>>08245000
if absolute(absolute(ics'qi)-ics'pdiscntcell) > 0 then         <<02090>>08250000
   comment:  the purpose of the following code is to cover up  <<k7614>>08255000
             a pdisable problem in which an interrupt handler  <<k7614>>08260000
             appears to execute a pdisable without a           <<k7614>>08265000
             corresponding penable.  this strange problem      <<k7614>>08270000
             always appears to leave the pdisable count at 1.  <<k7614>>08275000
             if this condition is met, we shall execute a      <<k7614>>08280000
             penable on behalf of the defective software       <<k7614>>08285000
             [a small prayer is in order here] and continue    <<k7614>>08290000
             execution (soft'death will log this event). ;     <<k7614>>08295000
                                                               <<k7614>>08300000
   if absolute(absolute(ics'qi)-ics'pdiscntcell) = 1 then      <<k7614>>08305000
      begin                                                    <<k7614>>08310000
      penable;  <<it's a miracle>>                             <<k7614>>08315000
      soft'death(644);                                         <<k7614>>08320000
      end                                                      <<k7614>>08325000
   else                                                        <<k7614>>08330000
      suddendeath(644);     <<leave the sf hook in>>           <<k7614>>08335000
                                                               <<02090>>08340000
                                                               <<mpeiv>>08345000
trapsoff;                                                      <<01858>>08350000
pdisable;                                                      <<mpeiv>>08355000
enable;                                                        <<mpeiv>>08360000
                                                               <<mpeiv>>08365000
<<fill in the local variables>>                                <<mpeiv>>08370000
comment  if we have a code absence for a pcal instruction,     <<04269>>08375000
         and we get a control y pseudo interrupt while waiting <<04269>>08380000
         for the segment to come in , the delayed control y    <<04269>>08385000
         flag is set in the delta p by pseudoint inside of     <<04269>>08390000
         bit (0:1). however, when the code segment is brought  <<04269>>08395000
         in, the top two bits of the delta p word will be set  <<04269>>08400000
         to zero (in the old code), and the delayed control y  <<04269>>08405000
         will be forever lost. now the garbage delta p is set  <<04269>>08410000
         to zero before queueing on the segment, and the delta <<04269>>08415000
         p which is restored does not mask off bit 0.          <<04269>>08420000
;                                                              <<04269>>08425000
                                                               <<mpeiv>>08430000
if instr.(0:8) = %(2)00110010 then    << it's a pcal >>        <<06095>>08435000
   begin                                                       <<04269>>08440000
   <<zero any garbage in p, so we do not see it as ctly/trace>><<06095>>08445000
   p := if mappingfirmware then                                <<06095>>08450000
           logical(p) land %40000 << save the map flag >>      <<06095>>08455000
        else                                                   <<06095>>08460000
           0;                                                  <<06095>>08465000
   tos := true;                                                <<04269>>08470000
   end                                                         <<04269>>08475000
else                                                           <<04269>>08480000
   tos := false;                                               <<04269>>08485000
tos:=%1000d;                                                   <<mpeiv>>08490000
x := curprc;                                                   <<06642>>08495000
asmb(xchd); <<fills in savedb>>                                <<mpeiv>>08500000
tos:=x;<<procinx>>                                             <<mpeiv>>08505000
tos := pcb(curprc+pbxwordnum);                                 <<06642>>08510000
tos := savedb;                                                 <<06095>>08515000
set( db );                                                     <<06095>>08520000
tos:=0; << reserved for descstinx, it'll be init later >>      <<06095>>08525000
tos := 0d;    << for objid >>                                  <<06655>>08530000
tos :=status.(8:8);                                            <<06095>>08535000
tos.(0:1):=p.(1:1);                                            <<06095>>08540000
tos:=mappedcsttophycst(*,0);                                   <<06095>>08545000
if <> then suddendeath(999); <<** fix ** fix ** fix ** fix**>> <<06095>>08550000
tos := sysdb d;                                                <<06095>>08555000
set( db );                                                     <<06095>>08560000
descstinx := if objectident(objidtypefield) = slobject         <<06655>>08565000
                then objectident(objidnumfield)&lsl(2) +       <<06655>>08570000
                     logical(dfc)                                       08575000
             else objectident(objidnumfield)&lsl(2) +          <<06655>>08580000
                  logical(cstxblk(cstxeix));                   <<06655>>08585000
tos:=false; <<fill in trace flag later>>                       <<mpeiv>>08590000
if dst(descstinx).codesizefield = 0 then                       <<mpeiv>>08595000
   begin <<bad entry>>                                         <<mpeiv>>08600000
   dst(x).referencedflag:=0;penable;                           <<mpeiv>>08605000
   abort'proc (0,30,0);return;                                 <<03040>>08610000
   end;                                                        <<mpeiv>>08615000
if logical(dst(x:=descstinx+1)).rocflag then                   <<mpeiv>>08620000
   begin <<recoverable>>                                       <<mpeiv>>08625000
   recoveroc(objid,descstinx,0d);                              <<06655>>08630000
   if gclassenabledmask.class0 then                            <<mpeiv>>08635000
      begin  <<measure recovery of code overlay candidate>>    <<mpeiv>>08640000
      tos:=measstatxdsbank;                                    <<mpeiv>>08645000
      tos:=measstatxdsbase;                                    <<mpeiv>>08650000
      tos:=tos+c0sub0'segreloff;                               <<mpeiv>>08655000
      if objectident(objidpbxfield) = pbxobject then           <<06655>>08660000
         tos:=tos+c'pbxrecovery                                <<mpeiv>>08665000
         else tos:=tos+c'slrecovery;                           <<mpeiv>>08670000
      asmb(lsea;inca;ssea;ddel);                               <<mpeiv>>08675000
      end;                                                     <<mpeiv>>08680000
   end                                                         <<mpeiv>>08685000
else                                                           <<mpeiv>>08690000
   begin<<enter request for seg and wait>>                     <<02014>>08695000
   tos:=savedb;                                                <<02014>>08700000
   asmb(xchd);                                                 <<02014>>08705000
   do                                                          <<02014>>08710000
      begin                                                    <<02014>>08715000
      queueonobject(objid);                                    <<06655>>08720000
      pdisable;                                                <<02014>>08725000
                                                               <<06655>>08730000
      << it may have moved >>                                  <<06655>>08735000
                                                               <<06655>>08740000
      if objectident(objidtypefield) = objidpgmtype then       <<06655>>08745000
          descstinx := convsegidtostinx(objid);                <<06655>>08750000
      end                                                      <<02014>>08755000
   until dst(descstinx) > 0;                                   <<02014>>08760000
   asmb(xchd);                                                 <<02014>>08765000
   savedb:=tos;                                                <<02014>>08770000
   <<the required segment is around now>>                      <<02014>>08775000
   end;                                                        <<mpeiv>>08780000
if not pcalflag then                                           <<mpeiv>>08785000
   begin <<retry exit>>                                        <<mpeiv>>08790000
                                                               <<04528>>08795000
   comment :                                                   <<04528>>08800000
                                                               <<04528>>08805000
      the code below will avert a sf10 with a process          <<04528>>08810000
    which has a corrupted stack marker.                        <<04528>>08815000
                                                               <<04528>>08820000
   ;                                                           <<04528>>08825000
                                                               <<04528>>08830000
   if integer(logical(p) land %37777) >                        <<04528>>08835000
      dst(descstinx).codesizefield&lsl(2) and                  <<04528>>08840000
      (pcb(curprc+piinfowordnum).psimfield <> 5 land           <<06642>>08845000
      pcb(curprc+resabortinfowordnum).delaysoftflag<>1) then   <<06642>>08850000
      begin                                                    <<04528>>08855000
      penable;                                                 <<*8085>>08860000
      abort'proc ( 0, 24, 0 );   << bounds violation >>        <<04528>>08865000
      return                                                   <<04528>>08870000
      end;                                                     <<04528>>08875000
   tos:=savedb;                                                <<mpeiv>>08880000
   asmb(xchd);                                                 <<mpeiv>>08885000
   tos:=logical(firmwareparm) lor %31400;                      <<mpeiv>>08890000
   penable;                                                    <<mpeiv>>08895000
   asmb(xeq 0);                                                <<mpeiv>>08900000
   end                                                         <<mpeiv>>08905000
else                                                           <<mpeiv>>08910000
   begin <<make pcal tests for firmware>>                      <<mpeiv>>08915000
   x := dstsysbaseinx + convsegidtostinx(objid);               <<06655>>08920000
   if segdescfirminfo.traceflag=1 then trace:=true;            <<mpeiv>>08925000
   tos:=segdescbank;                                           <<mpeiv>>08930000
   tos:=segdescaddr;                                           <<mpeiv>>08935000
   tos:=segdescfirminfo.codesizefield&lsl(2)-1; <<pl(0)>>      <<mpeiv>>08940000
   asmb(ladd;lsea);                                            <<mpeiv>>08945000
   <<  if no mapping firmware                             >>   <<06095>>08950000
   <<     load total number of stt entries, the check     >>   <<06095>>08955000
   <<     to see if it is internal/external will be       >>   <<06095>>08960000
   <<     done later.                                     >>   <<06095>>08965000
   <<  if mapping firmware                                >>   <<06095>>08970000
   <<     load number of internal stt entries, we will    >>   <<06095>>08975000
   <<     check bounds and internal/external at the       >>   <<06095>>08980000
   <<     same time.                                      >>   <<06095>>08985000
   tos := if mappingfirmware then tos.(0:8) else tos.(8:8);    <<06095>>08990000
   tos:=firmwareparm.(1:7); <<target stt #>>                   <<mpeiv>>08995000
   if s0 > s1 then                                             <<mpeiv>>09000000
      begin <<stt is too large>>                               <<mpeiv>>09005000
      tos:=savedb;                                             <<mpeiv>>09010000
      asmb(xchd);                                              <<mpeiv>>09015000
      penable;                                                 <<mpeiv>>09020000
      abort'proc (0,31,0);  <<badstt>>                         <<03040>>09025000
      return;                                                  <<mpeiv>>09030000
      end;                                                     <<mpeiv>>09035000
   asmb(delb,lsub;lsea);                                       <<mpeiv>>09040000
   if < then                                                   <<mpeiv>>09045000
      begin <<stt being referenced is external>>               <<mpeiv>>09050000
      tos:=savedb;asmb(xchd);penable;                          <<mpeiv>>09055000
      abort'proc (0,31,0);  <<extsttref>>                      <<03040>>09060000
      return;                                                  <<mpeiv>>09065000
      end;                                                     <<mpeiv>>09070000
   asmb(tbc uncallablebit);                                    <<mpeiv>>09075000
   if <> then                                                  <<mpeiv>>09080000
      begin <<entry is uncallable>>                            <<mpeiv>>09085000
      if (pcalflag land pcalstatus>=0)                         <<01949>>09090000
      lor (not pcalflag land status>=0) then                   <<01949>>09095000
         begin <<not privileged>>                              <<mpeiv>>09100000
         tos:=savedb;                                          <<mpeiv>>09105000
         asmb(xchd);                                           <<mpeiv>>09110000
         penable;                                              <<mpeiv>>09115000
         abort'proc (0,17,0);  <<uncallableref>>               <<03040>>09120000
         return;                                               <<mpeiv>>09125000
         end;                                                  <<mpeiv>>09130000
      end;                                                     <<mpeiv>>09135000
                                                               <<mpeiv>>09140000
   <<put the delta p into the second stack marker>>            <<mpeiv>>09145000
                                                               <<mpeiv>>09150000
   << mask off delta p, or in mapflag >>                       <<06095>>09155000
   p := tos land %37777 lor logical(p);                        <<06095>>09160000
   if p.(2:14) > dst(descstinx).codesizefield&lsl(2)           <<04269>>09165000
   then suddendeath(645);                                      <<01687>>09170000
                                                               <<mpeiv>>09175000
   <<check if segment is being traced>>                        <<mpeiv>>09180000
                                                               <<mpeiv>>09185000
   if trace then                                               <<mpeiv>>09190000
      begin                                                    <<mpeiv>>09195000
      tos:=absolute(tracelabel);                               <<mpeiv>>09200000
      if < then                                                <<mpeiv>>09205000
         begin                                                 <<mpeiv>>09210000
         disable;                                              <<mpeiv>>09215000
         asmb(pcal 0);                                         <<mpeiv>>09220000
         end                                                   <<mpeiv>>09225000
      else                                                     <<mpeiv>>09230000
         begin <<trace routine isn't around>>                  <<mpeiv>>09235000
         tos:=savedb;asmb(xchd);penable;                       <<03040>>09240000
         abort'proc (0,22,0);  <<traceabs>>                    <<03040>>09245000
         end;                                                  <<mpeiv>>09250000
      end;                                                     <<mpeiv>>09255000
   tos:=savedb;                                                <<mpeiv>>09260000
   asmb(xchd);                                                 <<mpeiv>>09265000
   penable;                                                    <<mpeiv>>09270000
   end;                                                        <<mpeiv>>09275000
end  <<codeabsence>>;                                          <<mpeiv>>09280000
procedure trace;                                               <<06095>>09285000
                                                               <<06095>>09290000
option privileged,uncallable;                                  <<06095>>09295000
                                                               <<06095>>09300000
<<*********************************************************>>  <<06095>>09305000
<< this procedure handles trace trap.                      >>  <<06095>>09310000
<<                                                         >>  <<06095>>09315000
<<   trapped when pcal :                                   >>  <<06095>>09320000
<<     it is "TRACE".                                      >>  <<06095>>09325000
<<     two markers were put down by microcode. first one   >>  <<06095>>09330000
<<     is "FROM" marker, and the second one is "TO" marker.>>  <<06095>>09335000
<<     the delta p in the second marker needs to be        >>  <<06095>>09340000
<<     repired.                                            >>  <<06095>>09345000
<<     x register contains the trapped instruction.        >>  <<06095>>09350000
<<     q+1 location contains external label of pcal.       >>  <<06095>>09355000
<<                                                         >>  <<06095>>09360000
<<   trapped when exit :                                   >>  <<06095>>09365000
<<     it is trace or delayed soft interrupt.              >>  <<06095>>09370000
<<     check soft interrupt mode and delayed soft int. bit >>  <<06095>>09375000
<<     in pcb and mode of the segment to be exit to to     >>  <<06095>>09380000
<<     determine if it's a right marker to process the     >>  <<06095>>09385000
<<     delayed control-y. if not, then trace.              >>  <<06095>>09390000
<<     x register contains the trapped instruction.        >>  <<06095>>09395000
<<     q+1 location contains number of word to be poped    >>  <<06095>>09400000
<<     (number of procedure parameters).                   >>  <<06095>>09405000
<<*********************************************************>>  <<06095>>09410000
comment this procedure will not check to see of the            <<*7854>>09415000
        interrupted code is system code or not. this           <<*7854>>09420000
        change has been implemented as a result of             <<*7854>>09425000
        the possibility of pause and iowait being              <<*7854>>09430000
        called from within system code. when such is           <<*7854>>09435000
        the case, and a soft interrupt like control y          <<*7854>>09440000
        is intercepted, the process is awoken from a           <<*7854>>09445000
        timer or iowait wait and modifies the immediate        <<*7854>>09450000
        stack marker to trap to inin upon exit. the            <<*7854>>09455000
        delta p is also modified so that the pcal to           <<*7854>>09460000
        pause or iowait be retried upon exit from the          <<*7854>>09465000
        soft interrupt handler. under normal conditions        <<*7854>>09470000
        where the user or system do not call pause or          <<*7854>>09475000
        iowait , pseudoint makes shure that the handler        <<*7854>>09480000
        will not run during system code. but since by          <<*7854>>09485000
        design and specifications iowait and pause can         <<*7854>>09490000
        be interrupted, and system code can call it, the       <<*7854>>09495000
        procedure will not check for interrupted system        <<*7854>>09500000
        code.                                                  <<*7854>>09505000
;                                                              <<*7854>>09510000
begin                                                          <<06095>>09515000
                                                               <<06095>>09520000
   array      q0array (*) = q+0;                               <<06095>>09525000
   integer    inst        = q+2;    << instr from x reg  >>    <<06095>>09530000
   integer    dstoffset   = q+3;    << cst or cstx entry >>    <<06095>>09535000
                                    << offset from dstb  >>    <<06095>>09540000
   integer    plabel       = q + 4;                            <<*7854>>09545000
   logical    mcy          = q + 5;<< mode of usr when cy on >><<*7854>>09550000
                                                               <<06095>>09555000
   subroutine abort'proc(mode, code, abort'parm);              <<06095>>09560000
                                                               <<06095>>09565000
      value mode, code, abort'parm;                            <<06095>>09570000
      integer mode, code, abort'parm;                          <<06095>>09575000
                                                               <<06095>>09580000
      <<***************************************************>>  <<06095>>09585000
      << this routine places the instruction in x and      >>  <<06095>>09590000
      << calls abort. mode, code and abort'parm are as     >>  <<06095>>09595000
      << defined for abort.                                >>  <<06095>>09600000
      <<***************************************************>>  <<06095>>09605000
                                                               <<06095>>09610000
      begin                                                    <<06095>>09615000
         x:=inst;                                              <<06095>>09620000
         abort(mode, code, abort'parm);                        <<06095>>09625000
      end;                                                     <<06095>>09630000
                                                               <<06095>>09635000
   logical subroutine modeok;                                  <<06095>>09640000
                                                               <<06095>>09645000
      <<***************************************************>>  <<06095>>09650000
      << this routine checks modes of the trap procedure   >>  <<06095>>09655000
      << and the trapped segment. the privileged trapped   >>  <<06095>>09660000
      << segment can't trap into user mode trap procedure. >>  <<06095>>09665000
      <<***************************************************>>  <<06095>>09670000
                                                               <<06095>>09675000
      begin                                                    <<06095>>09680000
         if pcb(curprc + piinfowordnum).psimfield = 5 then     <<06642>>09685000
            begin                                              <<06095>>09690000
               push (q, dl);                                   <<06095>>09695000
               asmb (xch, sub);                                <<06095>>09700000
               tos := tos - q0array(s0-2);                     <<06095>>09705000
               mcy := q0array(tos + 6).(3:1);                  <<07363>>09710000
               if not (mcy land                                <<06095>>09715000
                       logical(status.(0:1)) ) then            <<06095>>09720000
                          modeok:=true;                        <<06095>>09725000
            end;                                               <<06095>>09730000
         if pcb(curprc + resabortinfowordnum).                 <<06642>>09735000
                 delaysoftflag = 1 then                        <<06642>>09740000
            begin                                              <<06095>>09745000
               asmb(adds 4);                                   <<06095>>09750000
               receivemsg(usermsgport,4,savemsg);              <<06095>>09755000
               if not (logical(s0.(0:1)) land                  <<06095>>09760000
                       logical(status.(0:1)) ) then            <<06095>>09765000
                  begin                                        <<*8528>>09770000
                  asmb(subs 4);                                <<*8528>>09775000
                  modeok := true;                              <<*8528>>09780000
                  end                                          <<*8528>>09785000
               else                                            <<*8528>>09790000
                  begin                                        <<*8528>>09795000
                  asmb(subs 4);                                <<*8528>>09800000
                  modeok := false;                             <<*8528>>09805000
                  end;                                         <<*8528>>09810000
                                                               <<*8528>>09815000
            end;                                               <<06095>>09820000
      end;                                                     <<06095>>09825000
                                                               <<06095>>09830000
   << ***** beginning of trace *****>>                         <<06095>>09835000
                                                               <<06095>>09840000
   asmb(adds 4);                                               <<*7854>>09845000
   inst:=x;                                                    <<06095>>09850000
   if inst.(0:8) = %(2)00110010 then  << pcal >>               <<06095>>09855000
      begin                                                    <<06095>>09860000
         dstoffset := cstconv(param, 0);                       <<06095>>09865000
         tos := dst(dstoffset+2);    << bank # >>              <<06095>>09870000
         tos := dst(dstoffset+3);    << bank offset >>         <<06095>>09875000
         tos := tos + dst(dstoffset).(4:12)&lsl(2) - 1         <<06095>>09880000
                - param.(1:7);  << bankoffset + seglength >>   <<06095>>09885000
                                << - stthead - sttnumber  >>   <<06095>>09890000
         asmb(lsea); << get stt for called segment >>          <<06095>>09895000
         if < then suddendeath(289);                           <<06095>>09900000
         p.(2:14) := tos.(2:14);                               <<06095>>09905000
         ddel;  << delete bank# and bank offset >>             <<06095>>09910000
         tos := param;                                         <<06095>>09915000
         tos := inst;                                          <<06095>>09920000
         tos := 0;                                             <<06095>>09925000
         tos := f(tracelabel);                                 <<06095>>09930000
         if < then  << trace program existed >>                <<06095>>09935000
            begin                                              <<06095>>09940000
               asmb(pcal 0);                                   <<06095>>09945000
               return;                                         <<06095>>09950000
            end;                                               <<06095>>09955000
         enable;                                               <<06095>>09960000
         abort'proc([8/2,8/0],22,0); << pop dest marker >>     <<06095>>09965000
      end                                                      <<06095>>09970000
   else   << exit >>                                           <<06095>>09975000
      begin                                                    <<06095>>09980000
         p.(0:1) := 0;<< clear trace/control-y bit in marker>> <<06095>>09985000
         plabel.(0:1) := p.(1:1);  << set map flag >>          <<06095>>09990000
         plabel.(8:8) := status.(8:8); << set seg number >>    <<06095>>09995000
         dstoffset := cstconv(plabel,0);                       <<06095>>10000000
         if (pcb(curprc + piinfowordnum).psimfield = 5 or      <<06642>>10005000
            lpcb(curprc + resabortinfowordnum).                <<06642>>10010000
                delaysoftflag) and                             <<06642>>10015000
            modeok then                                        <<*7854>>10020000
            begin                                              <<06095>>10025000
               delayedint;                                     <<06095>>10030000
            end                                                <<06095>>10035000
         else                                                  <<06095>>10040000
            begin                                              <<06095>>10045000
               if deltaq < 0 then deltaq.(0:1) := 1;           <<06095>>10050000
               tos := param;                                   <<06095>>10055000
               tos := inst;                                    <<06095>>10060000
               tos := 0;                                       <<06095>>10065000
               tos := f(tracelabel);                           <<06095>>10070000
               if <> then                                      <<06095>>10075000
                  asmb(pcal 0)                                 <<06095>>10080000
               else                                            <<06095>>10085000
                  begin                                        <<06095>>10090000
                     enable;                                   <<06095>>10095000
                     abort'proc([8/1,8/0],22,0);               <<06095>>10100000
                  end;                                         <<06095>>10105000
            end;                                               <<06095>>10110000
         tos := logical(param) lor %31400;                     <<06095>>10115000
         asmb(xeq 0);                                          <<06095>>10120000
         help;                                                 <<06095>>10125000
      end;                                                     <<06095>>10130000
end;                                                           <<06095>>10135000
                                                                        10140000
procedure  sttuncallable;                                               10145000
   option privileged,uncallable;                                        10150000
   begin                                                                10155000
   enable;                                                              10160000
   << abort with instr. in xreg >>                             <<03040>>10165000
   abort([8/1,8/0],17,0);                                               10170000
   end;                                                                 10175000
                                                                        10180000
$page                                                          <<06655>>10185000
procedure dataabsence;                                         <<mpeiv>>10190000
option privileged,uncallable,internal;                         <<mpeiv>>10195000
                                                               <<mpeiv>>10200000
comment                                                        <<mpeiv>>10205000
                                                               <<mpeiv>>10210000
dataabsence is the internal interrupt handler for moves        <<mpeiv>>10215000
attempted to an absent data segment. dataabsence runs on       <<mpeiv>>10220000
the trapping process' stack, and firmware has pushed the       <<mpeiv>>10225000
target data segment number into q+1. the process attempting    <<06655>>10230000
the move will have an entry for the required data segment      <<06655>>10235000
placed in its sll with the sll memory pointer aimed at it.     <<06655>>10240000
(this is accomplished via queueonobject).                      <<06655>>10245000
the process will then be waited until the seg is made          <<mpeiv>>10250000
present, then the move will be retried by decrementing         <<mpeiv>>10255000
the p register value in the stack marker and exiting.          <<mpeiv>>10260000
                                                               <<mpeiv>>10265000
;                                                              <<mpeiv>>10270000
                                                               <<mpeiv>>10275000
begin                                                          <<mpeiv>>10280000
                                                               <<mpeiv>>10285000
define objident = double(firmwareparm)#;<< for queueonobjdect>><<06655>>10290000
                                                               <<06655>>10295000
integer firmwareparm=q+1,                                      <<03040>>10300000
        instr=q+2,                                             <<03040>>10305000
        s0=s-0;                                                <<03040>>10310000
                                                               <<03040>>10315000
tos := x; << set up instr >>                                   <<03040>>10320000
if absolute(absolute(ics'qi)-ics'pdiscntcell) > 0 then         <<02090>>10325000
   comment:  the purpose of the following code is to cover up  <<k7614>>10330000
             a pdisable problem in which an interrupt handler  <<k7614>>10335000
             appears to execute a pdisable without a           <<k7614>>10340000
             corresponding penable.  this strange problem      <<k7614>>10345000
             always appears to leave the pdisable count at 1.  <<k7614>>10350000
             if this condition is met, we shall execute a      <<k7614>>10355000
             penable on behalf of the defective software       <<k7614>>10360000
             [a small prayer is in order here] and continue    <<k7614>>10365000
             execution (soft'death will log this event). ;     <<k7614>>10370000
                                                               <<k7614>>10375000
   if absolute(absolute(ics'qi)-ics'pdiscntcell) = 1 then      <<k7614>>10380000
      begin                                                    <<k7614>>10385000
      penable;  <<it's a miracle>>                             <<k7614>>10390000
      soft'death(644);                                         <<k7614>>10395000
      end                                                      <<k7614>>10400000
   else                                                        <<k7614>>10405000
      suddendeath(644);     <<leave the sf hook in>>           <<k7614>>10410000
                                                               <<02090>>10415000
                                                               <<mpeiv>>10420000
trapsoff;                                                      <<01858>>10425000
pdisable;                                                      <<mpeiv>>10430000
disable;                                                       <<mpeiv>>10435000
if dst(x:=firmwareparm&lsl(2)).datasizefield = 0 then          <<mpeiv>>10440000
   begin <<dad dst entry>>                                     <<mpeiv>>10445000
   dst(x).referencedflag:=0;                                   <<mpeiv>>10450000
   penable;x:=instr;abort([8/1,8/0],17,0);return;              <<03040>>10455000
   end;                                                        <<mpeiv>>10460000
if logical(dst(x:=firmwareparm&lsl(2)+1)).rocflag then         <<mpeiv>>10465000
   begin  <<recoverable>>                                      <<mpeiv>>10470000
   if gclassenabledmask.class0 then                            <<mpeiv>>10475000
      begin  <<measure data seg recovery>>                     <<mpeiv>>10480000
      tos:=measstatxdsbank;                                    <<mpeiv>>10485000
      tos:=measstatxdsbase;                                    <<mpeiv>>10490000
      tos:=tos+c0sub0'segreloff+c'datarecovery;                <<mpeiv>>10495000
      asmb(lsea);                                              <<mpeiv>>10500000
      tos:=tos+1;                                              <<mpeiv>>10505000
      asmb(ssea;ddel);                                         <<mpeiv>>10510000
      end;                                                     <<mpeiv>>10515000
   tos:=%1000d;                                                <<mpeiv>>10520000
   x := curprc;                                                <<06642>>10525000
   asmb(xchd);                                                 <<mpeiv>>10530000
   recoveroc(objident,firmwareparm&lsl(2),0d);                 <<06655>>10535000
   asmb(xchd);                                                 <<mpeiv>>10540000
   penable;                                                    <<mpeiv>>10545000
   end                                                         <<mpeiv>>10550000
else                                                           <<mpeiv>>10555000
   queueonobject(objident);                                    <<06655>>10560000
p:=p-1; <<exit will cause move instruction to be retried>>     <<mpeiv>>10565000
end  <<dataabsence>>;                                          <<mpeiv>>10570000
                                                                        10575000
procedure  poweron;                                                     10580000
   option privileged,uncallable;                                        10585000
begin                                                                   10590000
                                                                        10595000
entry                                                          <<*8289>>10600000
   mmpowerfail;                                                <<*8289>>10605000
                                                               <<*8289>>10610000
equate                                                                  10615000
   icf'44       = 3,      << cpu number>>                      <<02009>>10620000
   cstb        = 0,     <<cst base>>                           <<01372>>10625000
   compwait    = %13,   << siodm completor wait state >>                10630000
   consldev    = %74,   << sysdb index >>                               10635000
   ddltp       = 4,     << dlt pointer index in dit >>                  10640000
   diltp       = 5,     << ilt pointer index in dit >>                  10645000
   dlink       = 1,     << link offset in dit >>                        10650000
   drt3        = 3,                                                     10655000
   drtsize     = 4,                                                     10660000
   dstat       = 6,     << status index in dit >>                       10665000
   dstop       = 7,     << stop word of trem. dit >>                    10670000
   dtype       = 5,     << dev type index in dlt >>                     10675000
   enableint   = %70351,<< enable clock interrupts >>                   10680000
   enableterm  = %015510,<< escape h to start terminet >>               10685000
   fhdisc      = 1,     << fhd type >>                                  10690000
   icntrl      = 7,    << controller info of ilt >>                     10695000
   iflag       = 13,   << flags word of ilt >>                          10700000
   imask       = 7,    << interrupt mask word >>                        10705000
   lowestdrt   = 8,                                                     10710000
   pfproc      = %144,  << powerfail proc sysdb index >>                10715000
   powerfail   = %72,   << powerfail flag sysdb index >>                10720000
   scsr        = %26,   << status register of sys clock >>     <<01183>>10725000
   templr      = %22,   << temp storage for limit reg >>       <<01183>>10730000
   series'33   = 8,     << cpu # of series 33 >>               <<01183>>10735000
   series'37   = 5,     << cpu # of mm >>                      <<*8289>>10740000
   icf'55      = 4;      <<cpu # of icf55>>                    <<06827>>10745000
                                                                        10750000
define                                                                  10755000
   multi'imb   = cpunum = icf'55 or cpunum = series'37#,       <<*8289>>10760000
   chanq       = (1:6)#, << channel queue num. in ilt >>                10765000
   drtnumber   = (7:9)#,  <<drt number field in ilt>>          <<03008>>10770000
   chan'num    = (9:4)#,  <<4-bit-channel number>>             <<03008>>10775000
   imb'num     = (7:2)#,  <<2-bit-imb number>>                 <<03008>>10780000
   rioa        = con %20302; con %13#, <<for icf55>>           <<03008>>10785000
   drvrdy      = (3:1)#, << drive ready bit in disc status >>           10790000
   iak         = (8:1)#, << int ack bit of dit >>                       10795000
   request     = (3:1)#, << service request bit of dflags >>            10800000
   statef      = (12:4)#,<< siodm state field of dit >>                 10805000
   trm         = (0:1)#, <<a terminal dit>>                    <<04424>>10810000
   type        = (8:8)#; << type field of dlt >>                        10815000
                                                                        10820000
integer                                                                 10825000
   absqi       = q+7,                                                   10830000
   i           = q+6,                                                   10835000
   lr          = q+5,                                                   10840000
   maxdrt      = db+%71,                                                10845000
   param       = q+3,                                                   10850000
   pf          = db+powerfail,                                          10855000
   pfailpin    = db+pfproc,                                             10860000
   sm2         = s-2,                                                   10865000
   s0            = s-0,                                       <<01.02>> 10870000
   sysconsole  = db+consldev,                                           10875000
   sysup       = db+%73; << system up flag >>                           10880000
                                                                        10885000
integer pointer                                                         10890000
  measinfotabptr = %261,  << for clock interface >>            <<mpeiv>>10895000
   busy        = db+%55,                                                10900000
   head        = db+%56,                                                10905000
   ps0         = s-0,                                                   10910000
   ps1         = s-1,                                                   10915000
   ps2          = s-2;                                         <<06827>>10920000
                                                                        10925000
                                                               <<04147>>10930000
<< these defines are for clearing the memory ram after >>      <<04147>>10935000
<< a powerfail.  this needs to be done since the ram is>>      <<04147>>10940000
<< garbage after a powerfail.  it also must be done    >>      <<04147>>10945000
<< before the memlog process is launched.              >>      <<04147>>10950000
                                                               <<04147>>10955000
integer                                                        <<04147>>10960000
   s1 = s - 1;                                                 <<04147>>10965000
                                                               <<04147>>10970000
                                                               <<04147>>10975000
define                                                         <<04147>>10980000
   duplicate = assemble( dup )#,                               <<04147>>10985000
   mcmd      = assemble( con %20104; con 4)#,                  <<*8289>>10990000
   pfl       = con %20104; con %21#;                           <<*8289>>10995000
                                                               <<04147>>11000000
                                                                        11005000
integer                                                        <<03008>>11010000
  ldev     = q+8,                                              <<03008>>11015000
  imb      = q+9,                                              <<03008>>11020000
  channl   = q+10,                                             <<03008>>11025000
  cpunum   = q+11,                                             <<03008>>11030000
  nrimb    = q+12,                                             <<06829>>11035000
  lpdt'index = q+13;                                           <<06829>>11040000
array                                                          <<03008>>11045000
  tempmask (*) = q+14;                                         <<06829>>11050000
                                                               <<03008>>11055000
                                                               <<03008>>11060000
comment                                                        <<03008>>11065000
============================================================== <<03008>>11070000
  power-fail set up the stack like this:                       <<03008>>11075000
                                                               <<03008>>11080000
q+1  db bank                                                   <<03008>>11085000
q+2  db                                                        <<03008>>11090000
q+3  param      <-- s at entry                                 <<03008>>11095000
q+4  adds value <-- s after adds 1                             <<03008>>11100000
q+5  lr                                                        <<03008>>11105000
q+6                                                            <<03008>>11110000
q+7  absqi=abs(qi)   <-- s after values have been restored     <<03008>>11115000
q+8  cst(2)-0        (additional locals safely declared here)  <<03008>>11120000
q+9  cst(2)-1                                                  <<03008>>11125000
q+10 cst(2)-2                                                  <<03008>>11130000
q+11 cst(2)-3                                                  <<03008>>11135000
q+12 save qi-6                                                 <<03008>>11140000
q+13 save qi+3                                                 <<03008>>11145000
q+14 save qi+4                                                 <<03008>>11150000
q+15 push(s)                                                   <<03008>>11155000
q+16 push(q)                                                   <<03008>>11160000
q+17 push(dl)   <-- s after adds 0, ready to pop values        <<03008>>11165000
                    set up by power-fail                       <<03008>>11170000
                                                               <<03008>>11175000
============================================================== <<03008>>11180000
end comment;                                                   <<03008>>11185000
                                                               <<03008>>11190000
                                                               <<03008>>11195000
                                                                        11200000
   asmb(adds 1;adds 0); << restore s >>                                 11205000
   tos := 0;                                                            11210000
   tos := sysdb;                                                        11215000
   set(db,dl,q,s); << restore other registers >>                        11220000
   abs(absqi+4) := tos; << restore qi + 4 >>                            11225000
   abs(x:=x-1) := tos;                                                  11230000
   abs(x:=x-9) := tos; << qi+3, and qi-6 >>                             11235000
                                                               <<01372>>11240000
   <<restore cst(2) which was rebuilt by powerfail>>           <<01372>>11245000
                                                               <<01372>>11250000
   x:=abs(cstb)+11;    <<cst(2) word 3>>                       <<01372>>11255000
   abs(x):=tos;        <<word 3>>                              <<01372>>11260000
   abs(x:=x-1):=tos;   <<word 2>>                              <<01372>>11265000
   abs(x:=x-1):=tos;   <<word 1>>                              <<01372>>11270000
   abs(x:=x-1):=tos;   <<word 0>>                              <<01372>>11275000
                                                               <<01372>>11280000
   asmb( adds 10);  <<protect locals q+8 thru q+17>>           <<03008>>11285000
                                                               <<03008>>11290000
                                                               <<03008>>11295000
   comment     correct the mask for getting the bank number    <<02009>>11300000
               for the icf'44;                                 <<02009>>11305000
   assemble(pcn);     <<get cpu number>>                       <<02009>>11310000
   if tos = icf'44 then                                        <<02009>>11315000
      begin                                                    <<02009>>11320000
        tos := %377;    <<bank mask>>                          <<02009>>11325000
        assemble(con %20104; con %4);                          <<02009>>11330000
      end;                                                     <<02009>>11335000
   goto recover'io;                                            <<*8289>>11340000
                                                               <<*8289>>11345000
                                                               <<*8289>>11350000
                                                               <<*8289>>11355000
                                                               <<*8289>>11360000
                                                               <<*8289>>11365000
                                                               <<*8289>>11370000
                                                               <<*8289>>11375000
                                                               <<*8289>>11380000
                                                               <<*8289>>11385000
                                                               <<*8289>>11390000
                                                               <<*8289>>11395000
                                                               <<*8289>>11400000
                                                               <<*8289>>11405000
                                                               <<*8289>>11410000
                                                               <<*8289>>11415000
                                                               <<*8289>>11420000
                                                               <<*8289>>11425000
                                                               <<*8289>>11430000
                                                               <<*8289>>11435000
                                                               <<*8289>>11440000
                                                               <<*8289>>11445000
                                                               <<*8289>>11450000
                                                               <<*8289>>11455000
                                                               <<*8289>>11460000
                                                               <<*8289>>11465000
mmpowerfail:                                                   <<*8289>>11470000
   asmb( adds 14 ); << protect locals q+4 thru q+17 >>         <<*8289>>11475000
   absqi := abs(5);                                            <<*8289>>11480000
                                                               <<*8289>>11485000
   tos := sysdb d;                                             <<*8289>>11490000
   set( db );                                                  <<*8289>>11495000
   sysup := 0;                                                 <<*8289>>11500000
                                                               <<*8289>>11505000
   if 1 <= pf <= 3 then                                        <<*8289>>11510000
      tos := 0  << don't save registers, and don't >>          <<*8289>>11515000
                << restart previous power fail trap>>          <<*8289>>11520000
   else                                                        <<*8289>>11525000
      begin                                                    <<*8289>>11530000
      pf := 1;                                                 <<*8289>>11535000
      tos := 1; << no previous executing power fail >>         <<*8289>>11540000
                << on the ics, save the registers   >>         <<*8289>>11545000
      end;                                                     <<*8289>>11550000
   asmb( pfl );  << signal microcode power fail >>             <<*8289>>11555000
                 << processing complete         >>             <<*8289>>11560000
                 << execution will resume at the>>             <<*8289>>11565000
                 << next instruction when power >>             <<*8289>>11570000
                 << is restored                 >>             <<*8289>>11575000
                                                               <<02009>>11580000
recover'io:                                                    <<*8289>>11585000
                                                               <<*8289>>11590000
   pf := 2;                                                             11595000
   mmstat'(240,0,0,pf,sysup,0,0);                              <<*7753>>11600000
                                                               <<03008>>11605000
                                                               <<03008>>11610000
    <<======================================================>> <<03008>>11615000
    <<the normal operations of read/set mask are complicated>> <<03008>>11620000
    <<by the introduction of a 4-word interrupt mask for the>> <<03008>>11625000
    <<icf/55.    for non icf/55 cpus:                       >> <<03008>>11630000
    <<    interrupt mask stored at %7                       >> <<03008>>11635000
    <<    read mask returns the (1 word) mask on tos        >> <<03008>>11640000
    <<    set mask expects  the (1 word) mask on tos        >> <<03008>>11645000
    <<           for the icf/55 cpu:                        >> <<03008>>11650000
    <<    interrupt mask stored at %32  (mask for imb 0)    >> <<03008>>11655000
    <<                             %33  (mask for imb 1)    >> <<03008>>11660000
    <<                             %34  (mask for imb 2)    >> <<03008>>11665000
    <<                             %35  (mask for imb 3)    >> <<03008>>11670000
    <<    set mask / read mask expect or return top of stack>> <<03008>>11675000
    <<                             s-3  (mask for imb 3)    >> <<03008>>11680000
    <<                             s-2  (mask for imb 2)    >> <<03008>>11685000
    <<                             s-1  (mask for imb 1)    >> <<03008>>11690000
    <<                  tos ==>    s-0  (mask for imb 0)    >> <<03008>>11695000
    <<======================================================>> <<03008>>11700000
                                                               <<03008>>11705000
                                                               <<03008>>11710000
   asmb(pcn);           <<get the cpu number>>                 <<03008>>11715000
   cpunum := tos;       <<and save it>>                        <<03008>>11720000
                                                               <<03008>>11725000
   if multi'imb then                                           <<*8289>>11730000
      begin                                                    <<*8289>>11735000
      nrimb := 3;                                              <<*8289>>11740000
      tos := -1d;                                              <<*8289>>11745000
      tos := -1d;                                              <<*8289>>11750000
      end                                                      <<*8289>>11755000
   else                                                        <<*8289>>11760000
      begin                                                    <<*8289>>11765000
      nrimb := 0;                                              <<*8289>>11770000
      tos := -1;                                               <<*8289>>11775000
      end;                                                     <<*8289>>11780000
   <<  find out what imb's exist               >>              <<03008>>11785000
   <<  rmsk returns zero if imb doesn't exist  >>              <<03008>>11790000
   assemble( smsk;                                             <<03008>>11795000
             rmsk );  << imb 0 = s-0, imb 3 = s-3 >>           <<03008>>11800000
   x := 0;                                                     <<03008>>11805000
   do begin                                                    <<03008>>11810000
      tempmask(x) := tos;                                      <<03008>>11815000
      x := x+1;                                                <<03008>>11820000
      end until x > nrimb;                                     <<03008>>11825000
                                                               <<03008>>11830000
   <<  do a roll call on all imb's that exist  >>              <<03008>>11835000
   << returns a set bit for each gic that exists on the imb>>  <<03008>>11840000
   << otherwise a zeroed bit. use this info later for init>>   <<03008>>11845000
                                                               <<03008>>11850000
   x := 0;                                                     <<03008>>11855000
   do begin                                                    <<03008>>11860000
      if tempmask(x) <> 0 then  << imb exists? >>              <<03008>>11865000
         begin                                                 <<03008>>11870000
         if multi'imb then                                     <<*8289>>11875000
            begin                                              <<03008>>11880000
            tos := x&lsl(7);  << form imb nr. >>               <<03008>>11885000
            tos := %120000;   << roll call    >>               <<03008>>11890000
            assemble( rioa );                                  <<03008>>11895000
            end                                                <<03008>>11900000
         else                                                  <<03008>>11905000
            begin                                              <<03008>>11910000
            tos := %120000;   << roll call    >>               <<03008>>11915000
            assemble( rioc );                                  <<03008>>11920000
            end;                                               <<03008>>11925000
         tempmask(x) := tos; <<replace mask with roll call>>   <<03008>>11930000
         end;                                                  <<03008>>11935000
      x := x+1;                                                <<03008>>11940000
      end until x > nrimb;                                     <<03008>>11945000
                                                               <<03008>>11950000
   <<  initialize all configured gics  >>                      <<03008>>11955000
   <<  loop from highest imb-channel down to zero         >>   <<03008>>11960000
   <<     based on the imb get the temp int-mask word     >>   <<03008>>11965000
   <<     if the bit is set for the channel (exists?)     >>   <<03008>>11970000
   <<     then init that channel                          >>   <<03008>>11975000
                                                               <<03008>>11980000
                                                               <<03008>>11985000
   i := maxdrt.(7:6); << delete dev# >>                        <<03008>>11990000
   do begin                                                    <<03008>>11995000
      tos := tempmask(i.(10:2));  << imb nr. >>                <<03008>>12000000
      x := i.(12:4);         << chan nr. >>                    <<03008>>12005000
      assemble( tbc 0,x );                                     <<03008>>12010000
      if <> then                                               <<03008>>12015000
         begin                                                 <<03008>>12020000
         tos := i&lsl(3);    << add dev nr. >>                 <<03008>>12025000
         assemble( init );                                     <<03008>>12030000
         end;                                                  <<03008>>12035000
      del;                                                     <<03008>>12040000
      i := i-1;                                                <<03008>>12045000
      end until =;                                             <<03008>>12050000
                                                               <<03008>>12055000
   i := 1;                                                              12060000
   do                                                                   12065000
   begin << step through lpdt and clean up resources >>                 12070000
      lpdt'index := i * size'of'lpdt'entry;                    <<06829>>12075000
      tos := lpdt'dit'ptr;                                     <<06829>>12080000
    if not lpdt'virtual'device  and (ps0(diltp) <> 0)          <<*8271>>12085000
       and ( lpdt'dit'ptr <> 0 )                               <<*8271>>12090000
                                                               <<*8271>>12095000
      then                                                     <<*8271>>12100000
      begin << valid dit pointer >>                                     12105000
         tos := ps0(diltp);                                             12110000
         if get'dsdevice(i) < 2 then                           <<01775>>12115000
           begin                <<not a ds device>>           <<01.02>> 12120000
             x := ps0(icntrl).chanq; << i/o channel resource >>         12125000
             if <> then                                       <<01.02>> 12130000
             begin << free channel resource >>                <<01.02>> 12135000
                busy(x) := 0;                                 <<01.02>> 12140000
                while dequeue(dlink,x) <> -1 do;              <<01.02>> 12145000
             end;                                             <<01.02>> 12150000
             tos := ps0(iflag);                                         12155000
             tos := tos land iflagmaskword; << clear wait bit >>        12160000
             ps1(x) := tos;  << update flags of ilt >>                  12165000
             del;  << delete ilt pointer >>                             12170000
             if ps0.trm<>1 and ps0.statef = compwait then      <<04424>>12175000
             begin << restart the request >>                            12180000
                tos := ps0; << get dflags from dit >>                   12185000
                tos.request := 1;                                       12190000
                tos.iak := 1;                                           12195000
                ps1 := tos;                                             12200000
                ps0(dstat):=-1;  <<set status to disc error>>           12205000
                masterclearhpib(ps0); << clear i/o condition >><<01301>>12210000
             end;                                                       12215000
           end                                                          12220000
         else del; << delete ilt pointer >>                             12225000
      end;                                                              12230000
      del;        << delete ditp from tos >>                   <<06829>>12235000
   end until (i := i + 1) > integer(lpdt'max'entries);         <<06829>>12240000
                                                               <<03008>>12245000
imb := 0;       <<clear temporary mask words>>                 <<03008>>12250000
do tempmask(imb) := 0                                          <<03008>>12255000
until (imb:=imb+1) > nrimb;                                    <<03008>>12260000
                                                               <<03008>>12265000
ldev := 1;     <<loop counter>>                                <<03683>>12270000
do begin    <<restart all disc requests>>                      <<03008>>12275000
   checkldev(ldev);                                            <<03008>>12280000
   if = and carry    <<disc>>                                  <<03008>>12285000
   then begin                                                  <<03008>>12290000
      lpdt'index := ldev * size'of'lpdt'entry;                 <<06829>>12295000
      tos := lpdt'dit'ptr;                                     <<06829>>12300000
      << if state of siodm is waiting for completion, then >>  <<p7754>>12305000
      << reset the state so it will redo the request.      >>  <<p7754>>12310000
                                                               <<p7754>>12315000
      if ps0.(12:4) = %13 then ps0.(12:4) := 0;                <<p7754>>12320000
      tos := ps0(diltp);    <<ilt ptr>>                        <<03008>>12325000
      tos := ps0(icntrl).drtnumber;   <<drt no.>>              <<03008>>12330000
      delb;                 <<delete ilt ptr>>                 <<03008>>12335000
                                                               <<03008>>12340000
      channl:= s0.chan'num;      <<channel number>>            <<03008>>12345000
      imb := tos.imb'num;   <<imb number>>                     <<03008>>12350000
                                                               <<03008>>12355000
      tos := tempmask(imb);  <<get mask word for imb>>         <<03008>>12360000
      x:=channl;                                               <<03008>>12365000
      asmb( tsbc 0,x);        <<set bit for channel>>          <<03008>>12370000
      tempmask(imb) := tos;  <<save back into tempmask>>       <<03008>>12375000
                                                               <<03008>>12380000
      imb := nrimb;  <<load tempmask onto stack>>              <<03008>>12385000
      do tos := tempmask(imb)                                  <<03008>>12390000
      until (imb:=imb-1) < 0;                                  <<03008>>12395000
                                                               <<03008>>12400000
      asmb(smsk);   <<set the mask>>                           <<03008>>12405000
                                                               <<03008>>12410000
      tos := 0;                                                <<03008>>12415000
                 << tos = 0; s-1 = dit ptr>>                   <<03008>>12420000
      if ps1.(12:4) <> %14                                     <<p7754>>12425000
         then awakeio(*,*)                                     <<p7754>>12430000
      else ddel;                                               <<p7754>>12435000
   end;  <<its a disc>>                                        <<03008>>12440000
end until (ldev := ldev+1 ) > integer(lpdt'max'entries);       <<06829>>12445000
    <<end of restart all disc requests>>                       <<03008>>12450000
                                                               <<03008>>12455000
   lynx'pf'check;     <<for icf'55 lynx code>>                 <<03650>>12460000
    << clear memory after a power fail ...>>                   <<04147>>12465000
    << ... for the memlog process         >>                   <<04147>>12470000
    assemble (pcn);                                            <<04147>>12475000
    if tos = icf'55 then begin                                 <<04147>>12480000
     comment : the variable nrimb is used as a loop index      <<04147>>12485000
       in the following code even though this is not its       <<04147>>12490000
       reason for exsistance. this avoids the dynamic          <<04147>>12495000
       allocation of still another variable;                   <<04147>>12500000
     for *nrimb   := 0 until 1023 do begin                     <<04147>>12505000
      tos := logical (nrimb) & lsl(4);                         <<04147>>12510000
      duplicate;                                               <<04147>>12515000
      s1 := [11/0,1/1,4/0];    << write logging ram >>         <<04147>>12520000
      tos := [6/0,4/%12,       << csb bus op; send word >>     <<04147>>12525000
              3/7,           << csb address of memory mod >>   <<04147>>12530000
              3/0];            << no reply expected >>         <<04147>>12535000
      mcmd;                                                    <<04147>>12540000
     end     << clear'logging'ram >>                           <<04147>>12545000
    end;                                                       <<04147>>12550000
   abs(absqi-12) := pfailpin; << tell disp to awakw pf process >>       12555000
   awake(pfailpin,junkwaitcode,nowait);                        <<02833>>12560000
   trlqtime := 1; <<set timer flag to get dispatched>>         <<06827>>12565000
   pf := 3; << this will clear writechar if there from previous pf >>   12570000
   tos := -1;                                                  <<01183>>12575000
      tos := dlabel;                                           <<mpeiv>>12580000
   if <  then  asmb(pcal 0);                                   <<01183>>12585000
   abs(scsr) := 0;   << clear status register >>               <<01183>>12590000
   if cpunum = series'33 then                                  <<*8289>>12595000
   begin    <<cpu is a 33>>                                    <<01415>>12600000
      tos := 1100;   <<default value>>                         <<01415>>12605000
      tos := abs(17).(1:15);  <<specified value>>              <<01415>>12610000
      if = then asmb (del);   <<if 0, use default>>            <<01415>>12615000
      asmb (rccr; dup);                                        <<01415>>12620000
      abs(templr) := tos;                                      <<01415>>12625000
      asmb (ladd;sclr);                                        <<01415>>12630000
   end                                                         <<01415>>12635000
   else                                                        <<01415>>12640000
   if cpunum = icf'44 or cpunum = icf'55 then                  <<*8289>>12645000
   begin    <<icf/44 or icf/55 cpu>>                           <<01415>>12650000
      tos := 100;   <<same as above>>                          <<01415>>12655000
      tos := abs(17).(1:15);                                   <<01415>>12660000
      if = then asmb (del);                                    <<01415>>12665000
      asmb (sclr);                                             <<01415>>12670000
      abs(templr) := 0;                                        <<01415>>12675000
   end;                                                        <<01415>>12680000
   asmb( ton; sinc );                                          <<*8289>>12685000
   pf := 4;                                                    <<*8289>>12690000
   asmb( ixit );                                               <<*8289>>12695000
end;                                                                    12700000
                                                                        12705000
procedure  callhelp;                                                    12710000
   option  privileged,uncallable;                                       12715000
   begin                                                                12720000
   << build a marker to help, exit through it >>                        12725000
   tos := 0;  << x register >>                                          12730000
   tos := f(f(f(0)+@help.(8:8)*4).(4:12)*4+f(x:=x+3)-1-@help.(1:7));    12735000
   tos := tos.(2:14);   << get rid of uncallable bit >>                 12740000
   if mappingfirmware then tos.(1:1):=1; << mapping flag >>    <<06095>>12745000
   push(status);                                                        12750000
   tos.(8:8) := @help;                                                  12755000
   tos := 4;                                                            12760000
   push(s);                                                             12765000
   set(q);                                                              12770000
   end;                                                                 12775000
                                                                        12780000
<< outer block, stt # followed by a call to the procedure >>            12785000
asmb(                                                                   12790000
     con 1;   pcal boundsviolation;                                     12795000
     con 2;   pcal illegaladdress;                                      12800000
     con 3;    pcal nonrespondingmodule;                       <<04793>>12805000
     con 4;   pcal ghost4;                                              12810000
     con 5;   pcal ghost5;                                              12815000
     con 6;   pcal dataparity;                                          12820000
     con 7;   pcal ghost7;                                              12825000
     con 8;   pcal callhelp;                                            12830000
     con 9;   pcal powerfail;                                           12835000
     con 10;  pcal tempwarnings;   <<for icf'64>>              <<03094>>12840000
     con 11;  pcal extghost;                                            12845000
     con 12;  pcal systemclock;                                         12850000
     con 13;  pcal breakpoint;                                          12855000
     con 14;  pcal mmpowerfail;                                <<*8289>>12860000
     con 15;  pcal dculogging;   <<for series'64>>             <<04184>>12865000
     con 16;  pcal unimplementedinstruction;                            12870000
     con 17;  pcal sttviolation;                                        12875000
     con 18;  pcal cstviolation;                                        12880000
     con 19;  pcal dstviolation;                                        12885000
     con 20;  pcal stackunderflow;                                      12890000
     con 21;  pcal privilegedmodeviolation;                             12895000
     con 22;  pcal ghost22;                                             12900000
     con 23;  pcal ghost23;                                             12905000
     con 24;  pcal stackoverflow;                              <<mpeiv>>12910000
     con 25;  pcal usertrap;                                            12915000
     con 26;  pcal ghost26;                                             12920000
     con 27;  pcal ghost27;                                             12925000
     con 28;  pcal ghost28;                                             12930000
     con 29;  pcal ghost29;                                             12935000
     con 30;  pcal ghost30;                                             12940000
     con 31;  pcal codeabsence;                                         12945000
     con 32;  pcal trace;                                               12950000
     con 33;  pcal sttuncallable;                                       12955000
     con 34;  pcal dataabsence;                                         12960000
     con 35;  pcal poweron;                                             12965000
     con 36;  pcal ghost36                                              12970000
);                                                                      12975000
end.                                                                    12980000
