<< ININ -- MODULE 10 >>                                        <<01040>>00012000
<< hp32002c mpe source c.00.00 >>                                       00014000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00016000
<<     this program may be used with one computer system at a       >>  00018000
<<     time and shall not otherwise be recorded, transmitted or     >>  00020000
<<     stored in a retrieval system.  copying or other reproduction >>  00022000
<<     of this program except for archival purposes is prohibited   >>  00024000
<<     without the prior written consent of hewlett-packard company.>>  00026000
<< **** note - dollar copyright cannot be used with this module *** >>  00028000
$control main=inin                                                      00030000
$thirty                                                                 00032000
$control map,code                                              <<04794>>00034000
begin                                                                   00036000
<<                                                                      00038000
                                                                        00040000
      internal interrupt segment                                        00042000
                                                                        00044000
>>                                                                      00046000
                                                                        00048000
define  asmb = assemble#,                                               00050000
        f = absolute#,                                                  00052000
        abs=absolute#,                                         <<01808>>00054000
        pdisable=asmb(psdb)#,                                  <<01549>>00056000
        penable=asmb(pseb)#,                                   <<01549>>00058000
        disable = asmb( sed 0 )#,                                       00060000
        enable = asmb( sed 1 )#,                               <<01040>>00062000
        lmem = asmb( lsea )#,                                  <<01040>>00064000
       lrv = abs(%17).(1:15)#;                                 <<01549>>00066000
define  trapsoff = push(status);                               <<01857>>00068000
                   tos.(2:1) := 0;                             <<01857>>00070000
                   set(status)#;                               <<01857>>00072000
$include inclmeas                                              <<01549>>00074000
$include inclmift                                              <<04107>>00076000
equate  pcbsize = 16,                                                   00078000
       pxglobsize = 8,                                         <<01808>>00080000
        cpcb = 4,                                                       00082000
        pcbb = 3,                                                       00084000
        dstb = 2,                                              <<01040>>00086000
         tracelabel = %1257,                                            00088000
        qi = 5,                                                         00090000
        zi = 6;                                                         00092000
equate icspdisablecntcell=18;                                  <<01549>>00094000
                                                               <<01549>>00096000
                                                                        00098000
integer  x = x,                                                         00100000
         p = q-2,     << stack marker p value >>                        00102000
         deltaq = q+0,                                                  00104000
         status = q-1,<< stack marker status >>                         00106000
         param = q+1; << interrupt parameter >>                         00108000
equate ics'qi=5;                                               <<01549>>00110000
equate sysbase=%1000,                                          <<01549>>00112000
       slix=1,                                                 <<01549>>00114000
       sysxl=sysbase+slix,                                     <<01549>>00116000
       dstix=2,                                                <<01549>>00118000
       sysdst=sysbase+dstix,                                   <<01549>>00120000
       pcbix=3,                                                <<01549>>00122000
       syspcb=sysbase+pcbix,                                   <<01549>>00124000
       dfcix=%32,                                              <<01549>>00126000
       sysdfc=sysbase+dfcix,                                   <<01549>>00128000
       icsix=7,                                                <<01801>>00130000
       cstxblkix=%51,                                          <<01549>>00132000
       syscstxblk=sysbase+cstxblkix,                           <<01549>>00134000
       syswaittodispmsg=%1053;                                 <<01549>>00136000
                                                               <<01549>>00138000
define memtrapflag=(4:1)#;                                     <<01549>>00140000
                                                               <<01549>>00142000
<<system table ptrs for lst access>>                           <<01549>>00144000
                                                               <<01549>>00146000
integer pointer dst=dstix,                                     <<01549>>00148000
               ics=icsix,                                      <<01801>>00150000
                pcb=pcbix,                                     <<01549>>00152000
                cstxblk=cstxblkix;                             <<01549>>00154000
                                                               <<01549>>00156000
integer dstsysbaseinx=db+dstix,                                <<01549>>00158000
        slsysbaseinx=db+slix,                                  <<01549>>00160000
                dfc=db+dfcix;                                  <<01549>>00162000
integer pointer dsti' = dstb;                                  <<01040>>00164000
                                                               <<01549>>00166000
                                                               <<01549>>00168000
<<wait/awake parameter definitions>>                           <<01549>>00170000
equate noinfo=0,                                               <<01549>>00172000
       memorywaitcode=%10000,                                  <<01549>>00174000
       junkwaitcode=%20,                                       <<01549>>00176000
       memorytrap=%4000,                                       <<01549>>00178000
       nowait=0;                                               <<01549>>00180000
$include inclmsg                                               <<01549>>00182000
                                                               <<01549>>00184000
equate uncallablebit=1;                                        <<01549>>00186000
$include inclics                                               <<01549>>00188000
<<segment identifier format>>                                  <<01549>>00190000
                                                               <<01549>>00192000
equate segiddatatype=0,                                        <<01549>>00194000
       segidsltype=1;  <<program type =2 or 3>>                <<01549>>00196000
define segidtypefield=(0:2)#,                                  <<01549>>00198000
       segidpbxflag=(0:1)#,                                    <<01549>>00200000
       segidpbxfield=(1:7)#,                                   <<01549>>00202000
       segidlogsegfield=(8:8)#;                                <<01549>>00204000
                                                               <<01549>>00206000
                                                                        00208000
$include inclst                                                <<01549>>00210000
$include inclpcb                                               <<01549>>00212000
Procedure  abort(mode,code,param);                                      00214000
   value mode,code,param;                                               00216000
   logical mode,code,param;                                             00218000
   option external;                                                     00220000
                                                                        00222000
Procedure abortproc(procinx,abortcode);                        <<01549>>00224000
value procinx,abortcode;                                       <<01549>>00226000
integer procinx,abortcode;                                     <<01549>>00228000
option external;                                               <<01549>>00230000
                                                               <<01549>>00232000
Procedure wait(eventtype,specialinfo);                         <<01549>>00234000
value eventtype,specialinfo;                                   <<01549>>00236000
integer eventtype,specialinfo;                                 <<01549>>00238000
option external;                                               <<01549>>00240000
                                                               <<01549>>00242000
Procedure queueonsegment(segidentifier);                       <<01549>>00244000
value segidentifier;                                           <<01549>>00246000
integer segidentifier;                                         <<01549>>00248000
option external;                                               <<01549>>00250000
                                                               <<01549>>00252000
Procedure set'psif(pcbpt,flags);                               <<01549>>00254000
value pcbpt,flags;                                             <<01549>>00256000
integer pcbpt,flags;                                           <<01549>>00258000
option external;                                               <<01549>>00260000
                                                               <<01549>>00262000
Procedure recoveroc(segidentifier,descstinx);                  <<01549>>00264000
value segidentifier,descstinx;                                 <<01549>>00266000
integer segidentifier,descstinx;                               <<01549>>00268000
option external;                                               <<01549>>00270000
                                                               <<01549>>00272000
                                                               <<01549>>00274000
                                                               <<01549>>00276000
Procedure getdatasegchangestate(segnum);                       <<01549>>00278000
value segnum;                                                  <<01549>>00280000
integer segnum;                                                <<01549>>00282000
option external;                                               <<01549>>00284000
                                                               <<01549>>00286000
Procedure genspecreq(dstnum,newsize,readdisp,movelength);      <<01549>>00288000
value dstnum,newsize,readdisp,movelength;                      <<01549>>00290000
integer dstnum,newsize,readdisp,movelength;                    <<01549>>00292000
option external;                                               <<01549>>00294000
                                                               <<01549>>00296000
Procedure sendmsg(destpin,destportnum,msglength,flags);        <<01549>>00298000
value destpin,destportnum,msglength,flags;                     <<01549>>00300000
integer destpin,destportnum,msglength;                         <<01549>>00302000
logical flags;                                                 <<01549>>00304000
option external;                                               <<01549>>00306000
integer Procedure buildsegid(segtype,segnumber,pin);           <<01549>>00308000
value segtype,segnumber,pin;                                   <<01549>>00310000
integer segtype,segnumber,pin;                                 <<01549>>00312000
option external;                                               <<01549>>00314000
                                                               <<01549>>00316000
integer Procedure convsegidtostinx(segidentifier);             <<01549>>00318000
value segidentifier;                                           <<01549>>00320000
logical segidentifier;                                         <<01549>>00322000
option external;                                               <<01549>>00324000
                                                                        00326000
Procedure  awake(pcbpt,n,waitf);                                        00328000
   value pcbpt,n,waitf;                                                 00330000
   integer pcbpt,n,waitf;                                               00332000
   option external;                                                     00334000
                                                               <<03665>>00336000
logical Procedure iomessage(setno,msgno,mask,p1,p2,p3,p4,      <<03665>>00338000
     p5,dest,reply,offset,ditp,iotype);                        <<03665>>00340000
value setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,              <<03665>>00342000
     offset,ditp,iotype;                                       <<03665>>00344000
integer setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,            <<03665>>00346000
     offset,iotype;                                            <<03665>>00348000
integer pointer ditp;                                          <<03665>>00350000
option variable,external;                                      <<03665>>00352000
                                                               <<03665>>00354000
                                                                        00356000
Procedure delayedint; option external;                         <<03042>>00358000
                                                                        00360000
Procedure  eadd; option external;                                       00362000
                                                                        00364000
Procedure  esub; option external;                                       00366000
                                                                        00368000
Procedure  empy; option external;                                       00370000
                                                                        00372000
Procedure  ediv; option external;                                       00374000
                                                                        00376000
Procedure  eneg; option external;                                       00378000
                                                                        00380000
Procedure  ecmp; option external;                                       00382000
                                                                        00384000
Procedure  qadd;  option external;                                      00386000
                                                                        00388000
Procedure  qsub;  option external;                                      00390000
                                                                        00392000
Procedure  qmpy;  option external;                                      00394000
                                                                        00396000
Procedure  qdiv;  option external;                                      00398000
                                                                        00400000
Procedure  qneg;  option external;                                      00402000
                                                                        00404000
Procedure  qcmp;  option external;                                      00406000
                                                                        00408000
Procedure  qasl;  option external;                                      00410000
                                                                        00412000
Procedure  qasr;  option external;                                      00414000
                                                                        00416000
Procedure  dimpy; option external;                                      00418000
                                                                        00420000
Procedure  didiv; option external;                                      00422000
                                                                        00424000
Procedure  help; option external;                                       00426000
                                                                        00428000
Procedure  dmul; option external;                                       00430000
                                                                        00432000
Procedure  cvad; option external;                                       00434000
                                                                        00436000
Procedure  cvda; option external;                                       00438000
                                                                        00440000
Procedure  cvbd; option external;                                       00442000
                                                                        00444000
Procedure  cvdb; option external;                                       00446000
                                                                        00448000
Procedure  sld; option external;                                        00450000
                                                                        00452000
Procedure  nsld; option external;                                       00454000
                                                                        00456000
Procedure  srd; option external;                                        00458000
                                                                        00460000
Procedure  cmpd; option external;                                       00462000
                                                                        00464000
Procedure  addd; option external;                                       00466000
                                                                        00468000
Procedure  subd; option external;                                       00470000
                                                                        00472000
Procedure mpydsim; option external;                                     00474000
                                                                        00476000
integer Procedure  teststop(s,p,pinx);                                  00478000
   value s,p,pinx;                                                      00480000
   integer s,p,pinx;                                                    00482000
   option external;                                                     00484000
                                                                        00486000
Procedure  debug; option external;                                      00488000
                                                                        00490000
logical Procedure setsysdb;                                             00492000
   option external;                                                     00494000
                                                                        00496000
Procedure resetdb(ix);                                                  00498000
   value ix;                                                            00500000
   integer ix;                                                          00502000
   option external;                                                     00504000
                                                                        00506000
Procedure  suddendeath(a);                                              00508000
   value  a;                                                            00510000
   integer  a;                                                          00512000
   option  external;                                                    00514000
                                                                        00516000
Procedure iounfreeze(en,type,pin);                                      00518000
value en,type,pin;                                                      00520000
integer en,type,pin;                                                    00522000
option external;                                                        00524000
                                                                        00526000
Procedure masterclear(ditp);                                            00528000
value ditp;                                                             00530000
pointer ditp;                                                           00532000
option external;                                                        00534000
                                                                        00536000
Procedure bconvert(word);                                               00538000
value word;                                                             00540000
integer word;                                                           00542000
option external;                                                        00544000
                                                                        00546000
Procedure dconvert(word);                                               00548000
value word;                                                             00550000
integer word;                                                           00552000
option external;                                                        00554000
                                                                        00556000
Procedure mpxcontrol(op,ditp);                                          00558000
value op,ditp;                                                          00560000
integer op;                                                             00562000
pointer ditp;                                                           00564000
option external;                                                        00566000
                                                                        00568000
Procedure write2(word);                                                 00570000
value word;                                                             00572000
integer word;                                                           00574000
option external;                                                        00576000
                                                                        00578000
Procedure awakeio(ditp,flags);                                          00580000
value ditp,flags;                                                       00582000
pointer ditp;                                                           00584000
integer flags;                                                          00586000
option external;                                                        00588000
                                                                        00590000
Procedure checkldev(dev);                                               00592000
value dev;                                                              00594000
integer dev;                                                            00596000
option external;                                                        00598000
                                                                        00600000
integer Procedure dequeue(linkindex,qn);                                00602000
value linkindex,qn;                                                     00604000
integer linkindex,qn;                                                   00606000
option external;                                                        00608000
                                                                        00610000
Procedure iofailure(drtn,ditp);                                         00612000
value drtn,ditp;                                                        00614000
integer drtn;                                                           00616000
integer pointer ditp;                                                   00618000
option external;                                                        00620000
                                                                        00622000
integer Procedure seg'id'type (seg);                           <<01660>>00624000
   value seg;                                                  <<01660>>00626000
   integer seg;                                                <<01660>>00628000
   option external;                                            <<01660>>00630000
Procedure mmstat(p1,p2,p3,p4);                                 <<01563>>00632000
value p1,p2,p3,p4;                                             <<01563>>00634000
integer p1,p2,p3,p4;                                           <<01563>>00636000
option external;                                               <<01563>>00638000
                                                                        00640000
integer Procedure get'dsdevice(ldev);                          <<01623>>00642000
value ldev;                                                    <<01623>>00644000
integer ldev;                                                  <<01623>>00646000
option external;                                               <<01623>>00648000
                                                               <<01623>>00650000
                                                                        00652000
logical procedure testcrunch(caller);                                   00654000
   value caller;                                                        00656000
   integer caller;                                                      00658000
   option privileged,uncallable;                                        00660000
   begin                                                                00662000
   logical pointer  cst = 1;                                            00664000
   logical ls0=s-0;                                                     00666000
   equate trplbl=%100001,clearstt=%100377,getstt=%77400;                00668000
   integer  s0 = s-0;                                                   00670000
   integer array  arrq(*) = q+0;                                        00672000
   equate badref = 8;                                                   00674000
   tos := x;  <<save instruction on which trap occurred>>               00676000
                                                                        00678000
   tos := arrq(-arrq-1); <<get status of trapped Procedure>>            00680000
   if < then begin <<privileged mode when trapped>>                     00682000
                                                                        00684000
comment the following code is included to avert sd#10 in                00686000
        the case that two internal interrupts are generated             00688000
        by a single violation, e.g., bnds viol is followed              00690000
        by ill adr in partial memory system.  the following             00692000
        code will set testcrunch true and return, ignoring              00694000
        the ill adr;                                                    00696000
   if s0=trplbl then                                                    00698000
     begin                                                              00700000
     tos := arrq(x:=x-3);<<is this ext trap lbl? check:>>               00702000
     if (ls0 land clearstt)=trplbl then                                 00704000
       begin <<check if delta p is entry for stt in lbl>>               00706000
       tos := tos.(1:7); <<stt>>                                        00708000
       tos := cst(7);  <<absolute loc of inin>>                         00710000
       asmb(xch,sub);                                                   00712000
       tos := cst(4).(4:12)&lsl(2); <<len of inin>>                     00714000
       tos := tos+tos-1;   <<tos:=@ of stt entry from blklbl>> <<02086>>00716000
       tos := cst(6);      <<tos:=bank of inin>>               <<02086>>00718000
       asmb(xch;lsea);     <<tos:=stt entry of blklbl>>        <<02086>>00720000
       asmb(delb,delb);    <<pitch doble addr of stt entry>>   <<02086>>00722000
       tos := tos.(2:14);  <<tos:=deltap of trapped proc>>     <<02086>>00724000
       tos := arrq(-arrq-2); <<delta p at trap time>>                   00726000
       if tos=tos then                                                  00728000
         begin <<double internal interrupt! ignore!>>                   00730000
         testcrunch := true;                                            00732000
         return;                                                        00734000
         end;                                                           00736000
        end                                                    <<01922>>00738000
        else del;                                              <<01922>>00740000
     end;                                                               00742000
   tos := tos land %377;                                                00744000
   if s0<%300 and cst(s0&lsl(2)+1).systemflag                  <<01549>>00746000
   then                                                                 00748000
     begin << in privileged system code >>                              00750000
        del;                                                   <<00245>>00752000
        if (tos land %177400) <> %31400 or  <<not exit inst>>  <<01922>>00754000
          caller <> 2 then   <<not bounds violation>>          <<01922>>00756000
          begin                                                <<00245>>00758000
die:        x:=arrq(-2)+%111;  <<pmap relative loc of caller>> <<00245>>00760000
            suddendeath(caller+badref); <<die>>                <<00245>>00762000
          end else                                             <<00245>>00764000
          begin                <<bounds violation on exit>>    <<00245>>00766000
            tos:=arrq((-arrq(-arrq)-arrq)-1);   <<status mkr>> <<01922>>00768000
                           <<preceeding trapped Procedure  >>  <<00245>>00770000
            if (tos land %377) < %300 then go die;             <<01922>>00772000
            <<not a trap on exit to a destroyed user segment>> <<00245>>00774000
          end;                                                 <<00245>>00776000
     end;                                                               00778000
   end <<privileged mode when trapped>>;                                00780000
   status.(1:1) := 1;   << interrupts on on exit >>                     00782000
   end;                                                                 00784000
                                                                        00786000
procedure  boundsviolation;                                             00788000
   option privileged,uncallable;                                        00790000
   begin                                                                00792000
   logical                                                     <<03042>>00794000
      instr      = q+2,                                        <<03042>>00796000
      abort'parm = q+3; << [markers to pop/type of abort] >>   <<03042>>00798000
   integer array stack(*) = q+0;                               <<00422>>00800000
   define ploc = stack(-deltaq-2) #;                           <<00422>>00802000
   define exit'n = stack(-deltaq+1) #;                         <<00422>>00804000
   define  psim = (0:3)#;  << pseudo interrupt mode >>         <<00422>>00806000
   define exit'instr = (instr land %177400) =%31400 #;         <<04753>>00808000
   tos:=x; << set up inst >>                                   <<00422>>00810000
   tos:=0; << save space for abort'parm >>                     <<03042>>00812000
   if not testcrunch(2) then                                            00814000
   begin                                                       <<00422>>00816000
      comment:                                                 <<03042>>00818000
         determine number of markers for abort to pop.         <<03042>>00820000
         for exit instruction we want to pop the marker        <<03042>>00822000
         which points to location of exit (since it may        <<03042>>00824000
         point to codeabsence of inin if the segment           <<03042>>00826000
         was absent at the time of exit);                      <<03042>>00828000
      abort'parm := if exit'instr then [8/2,8/0]               <<03042>>00830000
                    else [8/1,8/0];                            <<03042>>00832000
      if exit'instr and ploc.(0:2) = 2 then                    <<03042>>00834000
      begin                                                    <<00422>>00836000
         comment:                                              <<00422>>00838000
            bounds violations result of trace bit set by a     <<03042>>00840000
            delayed cntrl y or soft int on internal exit.  note<<03042>>00842000
            that for external exits we go directly to trace.;  <<00422>>00844000
         if (cpcbpsim <> 5) and (cpcbdelaysoft <> 1) then      <<03042>>00846000
         begin                                                 <<03042>>00848000
            x := instr;                                        <<03042>>00850000
            abort(abort'parm,22,0);                            <<03042>>00852000
         end;                                                  <<03042>>00854000
         ploc.(0:1):=0;                                        <<00422>>00856000
         <<pop bnds viol. marker -- set up for delayedint>>    <<03042>>00858000
         exit'n:=instr.(8:8); <<exit n for delayedint>>        <<03042>>00860000
         push(q); tos:=tos-deltaq; set(q);                     <<00422>>00862000
         delayedint;                                           <<03042>>00864000
      end                                                      <<00422>>00866000
      else                                                     <<03042>>00868000
      begin                                                    <<03042>>00870000
         x:=instr;                                             <<03042>>00872000
         abort(abort'parm,24,0);                               <<03042>>00874000
      end;                                                     <<03042>>00876000
   end;                                                        <<00422>>00878000
   end;                                                                 00880000
                                                                        00882000
procedure  illegaladdress;                                              00884000
   option privileged,uncallable;                                        00886000
   begin                                                                00888000
   if not testcrunch(1) then                                            00890000
   abort([8/1,8/0],23,0); << with instr in xreg >>             <<03042>>00892000
   end;                                                                 00894000
                                                                        00896000
procedure  nonrespondingmodule;                                         00898000
   option privileged,uncallable;                                        00900000
   begin                                                                00902000
   if not testcrunch(0) then                                            00904000
   abort([8/1,8/0],25,0); << with instr in xreg >>             <<03042>>00906000
   end;                                                                 00908000
                                                                        00910000
procedure  systemparity;                                                00912000
   option privileged,uncallable;                                        00914000
   suddendeath(11);                                                     00916000
                                                                        00918000
procedure  addressparity;                                               00920000
   option privileged,uncallable;                                        00922000
   suddendeath(12);                                                     00924000
                                                                        00926000
procedure dataparity;                                          <<02301>>00928000
   option privileged,uncallable;                               <<02301>>00930000
                                                               <<02301>>00932000
   comment: dataparity will attempt to locate which memory     <<02301>>00934000
   location caused the data parity interrupt.  it does this    <<02301>>00936000
   by referencing all locations in memory until another data   <<02301>>00938000
   parity interrupt is detected.  the location which was last  <<02301>>00940000
   referenced is displayed and the system is halted, sf 13.    <<02301>>00942000
   if the bad location is not located, the machine is halted   <<02301>>00944000
   without a location displayed;                               <<02301>>00946000
                                                               <<02301>>00948000
   begin                                                       <<02301>>00950000
   equate  sysdb = %1000,                                      <<02301>>00952000
           crlf = %6412;   <<carriage return, linefeed>>       <<02301>>00954000
   define  parityerrflag = absolute (sysdb + %61)#,            <<02301>>00956000
           syslastbank   = absolute (sysdb + %361)#,           <<02301>>00958000
           syslastaddr   = absolute (sysdb + %362)#;           <<02301>>00960000
   array   parmsg (0:6) = pb := crlf, "PARITY ERROR";          <<02301>>00962000
   array   bmsg (0:2)   = pb := crlf, "B = ";                  <<02301>>00964000
   array   amsg (0:2)   = pb := crlf, "A = ";                  <<02301>>00966000
   logical b       = s-1,  <<b stack cell: bank # for lsea>>   <<02301>>00968000
           a       = s,    <<a stack cell: offset for lsea>>   <<02301>>00970000
           errbank = q-6,  <<b stack cell after second dp>>    <<02301>>00972000
           erraddr = q-5,  <<a stack cell after second dp>>    <<02301>>00974000
           lastbank,       <<largest bank # configured>>       <<02301>>00976000
           lastaddr;       <<largest addr for current bank>>   <<02301>>00978000
                                                               <<02301>>00980000
   if not parityerrflag then                                   <<02301>>00982000
         <<first dp interrupt: initialize and make another>>   <<02301>>00984000
         begin                                                 <<02301>>00986000
         tos := sysdb d;          <<set sysdb, pitch old db>>  <<02301>>00988000
         assemble (xchd;ddel);                                 <<02301>>00990000
         for x := 0 until 6 do write2(parmsg(x));              <<02301>>00992000
         parityerrflag := true;                                <<02301>>00994000
         lastbank := syslastbank;                              <<02301>>00996000
         lastaddr := %177777;     <<assume all but l.b. full>> <<02301>>00998000
                                                               <<02301>>01000000
         <<reference all of memory to recreate the error>>     <<02301>>01002000
         tos := 0d;               <<a:=b:=0>>                  <<02301>>01004000
         while b <= lastbank do                                <<02301>>01006000
            begin                                              <<02301>>01008000
            while a < lastaddr do                              <<02301>>01010000
               begin                                           <<02301>>01012000
               assemble (lsea;del);                            <<02301>>01014000
               assemble (inca);                                <<02301>>01016000
               end;                                            <<02301>>01018000
            assemble (lsea;del);  <<for last word in bank>>    <<02301>>01020000
            assemble (inca,incb);                              <<02301>>01022000
            if b = lastbank then lastaddr := syslastaddr;      <<02301>>01024000
            end;                                               <<02301>>01026000
         end  <<first parity error>>                           <<02301>>01028000
      else                                                     <<02301>>01030000
         <<second dataparity: print where we found it>>        <<02301>>01032000
         begin                                                 <<02301>>01034000
         for x := 0 until 2 do write2(bmsg(x));                <<02301>>01036000
         dconvert (errbank);                                   <<02301>>01038000
         for x := 0 until 2 do write2(amsg(x));                <<02301>>01040000
         bconvert (erraddr);                                   <<02301>>01042000
         end;  <<second parity error>>                         <<02301>>01044000
   suddendeath(13);                                            <<02301>>01046000
   end;  <<dataparity>>                                        <<02301>>01048000
                                                                        01050000
procedure  moduleinterrupt;                                             01052000
   option privileged,uncallable;                                        01054000
   suddendeath(14);                                                     01056000
                                                                        01058000
procedure  ghost;                                                       01060000
   option privileged,uncallable;                                        01062000
   suddendeath(15);                                                     01064000
                                                                        01066000
procedure extghost;                                                     01068000
option privileged,uncallable,interrupt;                        <<03665>>01070000
begin                                                                   01072000
integer drtn = q+3;    << loc of drt number on interrupt >>    <<03665>>01074000
                                                               <<03665>>01076000
equate unknown'int'msg = 410, << msg catalog msg # >>          <<03665>>01078000
       opconsole       = 0;   << system cons code for genmsg >><<03665>>01080000
                                                               <<03665>>01082000
   disable; << issue a clear interface >>                               01084000
   iomessage(1,unknown'int'msg,%10000,drtn,,,,,opconsole);     <<03665>>01086000
   tos := %100000;                                                      01088000
   asmb(cio 1);                                                         01090000
   if >= then                                                  <<03665>>01092000
      begin     << master reset worked - reset interrupts >>   <<03665>>01094000
      tos := %040000;                                          <<03665>>01096000
      asmb(cio 1);                                             <<03665>>01098000
      end;                                                     <<03665>>01100000
                                                               <<03665>>01102000
end;                                                                    01104000
                                                                        01106000
procedure  powerfail;                                                   01108000
   option privileged,uncallable;                                        01110000
begin                                                                   01112000
                                                                        01114000
equate                                                                  01116000
   clockdrt    = 3,        << sys clk drt number >>                     01118000
   crmask      = %70310,   << read clk cr reg >>                        01120000
   diltp       = 5,        << dit index to ilt pointer >>               01122000
   devreset    = %100000,  << device masterclear control >>             01124000
   lrmask      = %70210,   << read clk lr reg >>                        01126000
   powerfail   = %72,      << sysdb index >>                            01128000
   sysdb       = %1000;                                                 01130000
                                                                        01132000
define                                                                  01134000
   maxentry    = (0:8)#;   << # of entries in lpdt >>                   01136000
                                                                        01138000
integer                                                                 01140000
   absqi       = q+7,                                                   01142000
   cr          = q+6,                                                   01144000
   i           = q+3,                                                   01146000
   lr          = q+5,                                                   01148000
   maxdrt      = db+%71,                                                01150000
   pf          = db+powerfail,                                          01152000
   s           = s-2,                                                   01154000
   sysup       = db+%73;                                                01156000
                                                                        01158000
integer pointer                                                         01160000
   lpdt        = db+%10,                                                01162000
   ps0         = s-0;                                                   01164000
                                                                        01166000
double pointer                                                          01168000
   lpdtd       = lpdt;                                                  01170000
                                                                        01172000
                                                                        01174000
   tos := 0d;                                                           01176000
   tos := sysdb;                                                        01178000
   asmb(xchd);                                                          01180000
   pf := 1; << set sysdb and pf count >>                                01182000
   sysup := 0;                                                          01184000
   tos := abs(qi);                                                      01186000
   tos := abs(absqi-6); << save qi-6 >>                                 01188000
   tos := abs(x:=x+9);  << qi + 3 >>                                    01190000
   tos := abs(x:=x+1);  << and qi + 4 >>                                01192000
   push(s,q,dl);                                                        01194000
   tos := s - absqi + sysdb; << compute adds value for restart >>       01196000
   abs(x) := tos;                                                       01198000
   tos := clockdrt;                                                     01200000
   tos := crmask; << get clock cr and lr reg values >>                  01202000
   asmb(cio 1;rio 0);                                                   01204000
   cr := tos;                                                           01206000
   i := 4; << first sio drt >>                                          01208000
   do                                                                   01210000
   if abs(i&lsl(2)) > 0 then                                            01212000
   begin << reset any controller doing sio >>                           01214000
      tos := i;                                                         01216000
      tos := devreset;                                                  01218000
      asmb(cio 1); << issue master clear >>                             01220000
      del;                                                              01222000
   end                                                                  01224000
   until (i:=i+1) > maxdrt;                                             01226000
   asmb(halt 7); << all done >>                                         01228000
end;                                                                    01230000
                                                                        01232000
procedure  unimplementedinstruction;                                    01234000
   option privileged,uncallable;                                        01236000
   begin                                                                01238000
   integer userx = q-3,                                        <<01040>>01240000
           s2    = s-2;                                        <<01040>>01242000
   integer array nextq(*) = q+2;                               <<01040>>01244000
   integer instr     = nextq,                                  <<01040>>01246000
           trap'loc  = instr+1;                                <<01040>>01248000
                                                               <<02000>>01250000
   define  ploc      = p.(2:14) #;                             <<02000>>01252000
                                                               <<02000>>01254000
   logical subroutine dblword'instr;                           <<01040>>01256000
   begin                                                       <<01040>>01258000
      comment *** warning: this sub. must not change           <<01040>>01260000
              *** the x register;                              <<01040>>01262000
      tos := x;                                                <<01040>>01264000
      << assign return value to dblword'inst >>                <<01040>>01266000
      s2 := if instr = %20477 then true else false;            <<01040>>01268000
      x := tos; << restore x >>                                <<01040>>01270000
   end;                                                        <<01040>>01272000
                                                               <<01040>>01274000
   tos := x; << save instr >>                                  <<01040>>01276000
                                                               <<04749>>01278000
   if dblword'instr then                                       <<01040>>01280000
      begin                                                    <<01040>>01282000
      comment:                                                 <<01040>>01284000
         instr contains word 1 of the instruction.             <<01040>>01286000
         for a two word instruction with an invalid            <<01040>>01288000
         2nd word the 'p' register contains p+2.               <<01040>>01290000
         however, if there is no microcode to support          <<01040>>01292000
         the instruction, the trap occured on the              <<01040>>01294000
         1st word and the 'p' reg. contains p+1.;              <<01040>>01296000
      << load instruction at p-1 >>                            <<01040>>01298000
      tos:=0;  <<space for trap'loc>>                          <<04749>>01300000
      tos := 0; << return value for convsegid >>               <<01660>>01302000
      tos := buildsegid(seg'id'type(status.(8:8)),status.(8:8),<<01660>>01304000
                        (x:=f(cpcb)-f(pcbb))/pcbsize);         <<01660>>01306000
      tos := convsegidtostinx (*);                             <<01660>>01308000
      tos:=dst(x:=tos+2);                                      <<01549>>01310000
      tos:=dst(x:=x+1)+(p-1);                                  <<01549>>01312000
      lmem;                                                    <<01040>>01314000
      enable;                                                  <<01040>>01316000
      instr := tos; << word that caused trap >>                <<01040>>01318000
      ddel;  << delete extended address >>                     <<01040>>01320000
      trap'loc := ploc-1; <<save loc of word that trapped>>    <<02000>>01322000
      comment:                                                 <<01040>>01324000
         if word at p-1 is a double word instruction           <<01040>>01326000
         then assume no microcode for 2 word instr             <<01040>>01328000
         else actual 2 word instr with trap on 2nd             <<01040>>01330000
         word. p gets beginning of 2 word instr.;              <<01040>>01332000
      if dblword'instr then ploc := ploc-1                     <<02000>>01334000
      else ploc := ploc-2;                                     <<02000>>01336000
      goto l;                                                  <<01040>>01338000
      end;                                                     <<01040>>01340000
   enable;                                                     <<01040>>01342000
   if %20400 <= x <= %20415 then                                        01344000
      begin                                                             01346000
      x := x.(12:4);                                                    01348000
      asmb( br p+1,x );                                                 01350000
      eadd;                                                             01352000
      esub;                                                             01354000
      empy;                                                             01356000
      ediv;                                                             01358000
      eneg;                                                             01360000
      ecmp;                                                             01362000
      assemble(br p+8);                                                 01364000
      assemble(br p+7);                                                 01366000
      qadd;                                                             01368000
      qsub;                                                             01370000
      qmpy;                                                             01372000
      qdiv;                                                             01374000
      qneg;                                                             01376000
      qcmp;                                                             01378000
      end;                                                              01380000
   if x.(0:10) = %157 or x.(0:10) = %117 then                  <<00217>>01382000
      begin <<quad shift>>                                     <<00217>>01384000
      tos := tos.(10:6) + userx;                               <<00217>>01386000
      if logical(x.(4:1)) then qasr                            <<00217>>01388000
                          else qasl;                           <<00217>>01390000
      end;                                                     <<00217>>01392000
   if %20570 <= x <= %20571                                    <<00217>>01394000
   then                                                        <<00217>>01396000
      if tos then didiv                                        <<00217>>01398000
             else dimpy;                                       <<00217>>01400000
   tos := %177617;                                             <<00217>>01402000
   asmb(and,xax);                                              <<00217>>01404000
   if %20601 <= x <= %20614 then                               <<00217>>01406000
      begin                                                    <<00217>>01408000
      delb;   << cut off parameter >>                          <<00217>>01410000
      x := x.(12:4);                                           <<00217>>01412000
      asmb(br p+0,x);                                          <<00217>>01414000
      dmul;                                                    <<00217>>01416000
      cvad;                                                    <<00217>>01418000
      cvda;                                                    <<00217>>01420000
      cvbd;                                                    <<00217>>01422000
      cvdb;                                                    <<00217>>01424000
      sld;                                                     <<00217>>01426000
      nsld;                                                    <<00217>>01428000
      srd;                                                     <<00217>>01430000
      addd;                                                    <<00217>>01432000
      cmpd;                                                    <<00217>>01434000
      subd;                                                    <<00217>>01436000
      mpydsim;                                                 <<00217>>01438000
      end;                                                     <<00217>>01440000
   ploc := ploc-1;                                             <<02000>>01442000
    tos:=ploc;  <<trap'loc>>                                   <<04749>>01444000
   << at this point p points to 1st word of instr >>           <<03042>>01446000
   << that caused trap, trap'loc points to the    >>           <<03042>>01448000
   << word of the instruction that was bad        >>           <<03042>>01450000
l: if instr = %36000  then                                     <<01040>>01452000
      begin  << possiblely a breakpoint >>                              01454000
      tos := 0; << return value for teststop >>                <<01611>>01456000
      tos := buildsegid(seg'id'type(status.(8:8)),status.(8:8),<<01611>>01458000
                        (x:=f(cpcb)-f(pcbb))/pcbsize);         <<01611>>01460000
      teststop(*,trap'loc,x);                                  <<01040>>01462000
      if  >  then  return;                                              01464000
      if  =  then                                              <<01040>>01466000
          begin                                                <<01040>>01468000
          << flag break on 2nd of 2 word instr >>              <<01040>>01470000
          if trap'loc <> ploc then x := true                   <<02000>>01472000
          else x := false;                                     <<01040>>01474000
          debug;                                               <<01040>>01476000
          end;                                                 <<01040>>01478000
      end;                                                              01480000
   << set up call to abort >>                                  <<03042>>01482000
   x := instr;                                                 <<03042>>01484000
   ploc := trap'loc+1;      << one past illegal word >>        <<03042>>01486000
   abort([8/1,8/0],7,0); << with instr in xreg >>              <<03042>>01488000
   end;                                                                 01490000
                                                                        01492000
procedure  sttviolation;                                                01494000
   option privileged,uncallable;                                        01496000
   begin                                                                01498000
   enable;                                                              01500000
   abort([8/1,8/0],31,0); << with instr in xreg >>             <<03042>>01502000
   end;                                                                 01504000
                                                                        01506000
procedure  cstviolation;                                                01508000
   option privileged,uncallable;                                        01510000
   begin                                                                01512000
   enable;                                                              01514000
   abort([8/1,8/0],30,0); << with instr in xreg >>             <<03042>>01516000
   end;                                                                 01518000
                                                                        01520000
procedure  dstviolation;                                                01522000
   option privileged,uncallable;                                        01524000
   << db-bank may be invalid >>                                         01526000
   suddendeath(16);                                                     01528000
                                                                        01530000
procedure stackoverflow;                                       <<01549>>01532000
option privileged,uncallable;                                  <<01549>>01534000
                                                               <<01549>>01536000
comment                                                        <<01549>>01538000
                                                               <<01549>>01540000
stackoverflow is the interrupt handler for internal traps      <<01549>>01542000
caused by an instruction attempting to push s beyond z.when    <<01549>>01544000
such a condition is detected by microcode, control brances     <<01549>>01546000
to this routine on the ics with interrupts disabled.         <<01549>>  01548000
                                                               <<01549>>01550000
the system must crash if the overflowing stack is frozen,      <<01549>>01552000
locked or core resident, since there's no way to extend        <<01549>>01554000
these.  otherwise, a message is sent to the dispatcher to      <<01549>>01556000
write the stack, release its space, and flag the process       <<01549>>01558000
as requiring scheduling attention.  the sll memory prequest    <<01549>>01560000
pointer of the overflowing process is set to -1, indicating    <<01549>>01562000
to the scheduler that the process' stack must be made present  <<01549>>01564000
before the process can be launched.  the stack's new size      <<01549>>01566000
(oldsize + stovrinc) is placed in the stack's xst entry, and   <<01549>>01568000
the stack's st entry is flagged as requiring a modification.   <<01549>>01570000
                                                               <<01549>>01572000
if the code causing the stackoverflow had disabled external    <<01549>>01574000
interrupts or pdisabled switching, it must be allowed to con-  <<01549>>01576000
tinue until it completes the action for which it had set       <<01549>>01578000
the internal lock.  that's the reason stacks are allocated     <<01549>>01580000
an overflow area beyond z.  if the code had disabled interrupts<<01549>>01582000
the interrupt request flip flop of the clock is set,           <<01549>>01584000
and when the code enables interrupts the clock interrupt       <<01549>>01586000
handler will be entered and will do a disp.  if the code       <<01549>>01588000
was pdisabled when it caused the stackoverflow, the disp at    <<01549>>01590000
the end of this routine will cause control to switch         <<01549>>  01592000
to the dispatcher as soon as the process untangles itself.     <<01549>>01594000
                                                               <<01549>>01596000
;                                                              <<01549>>01598000
   begin                                                                01600000
   integer array  pcbx(*) = q+0;                                        01602000
   integer  s0 = s-0,                                                   01604000
            users0 = q-4,    <<top of stack at overflow time>> <<00556>>01606000
            deltas = q-6,                                               01608000
            deltaz = q-8;                                               01610000
   double  stdb = q-5;                                                  01612000
   equate  ixit = %20360;                                               01614000
   define  deltaz' = f(f(qi)-8)#;                                       01616000
                                                               <<01549>>01618000
equate stackovrinc=512,                                        <<01713>>01620000
       overhead=%27,                                           <<01549>>01622000
       pagepower=7,                                            <<01549>>01624000
       rbtorasdisp=-19,                                        <<01549>>01626000
       rastorbdisp=19,                                         <<01549>>01628000
       extrainc=1152;                                          <<01549>>01630000
equate rbtorsdisp=-18,                                         <<01713>>01632000
       rstorbdisp=18;                                          <<01713>>01634000
define regiofzflag=(7:1)#,                                     <<01549>>01636000
       regfzflag=(6:1)#,                                       <<01549>>01638000
       reglkdflag=(5:1)#;                                      <<01549>>01640000
equate stbtomaxdata=21,                                        <<01549>>01642000
       maxdatatorelz=-11,                                      <<01549>>01644000
       sbtoreldb=1,                                            <<01549>>01646000
       maxdatatoreldb=-20,                                     <<01549>>01648000
       relztorbdisp=-10,                                       <<01549>>01650000
       reldbtorelz=9;                                          <<01549>>01652000
equate  ics'deltaz=8,                                          <<01549>>01654000
        ics'deltas=6,                                          <<01549>>01656000
        ics'stackbank=5,                                       <<01549>>01658000
        ics'stackbase=9,                                       <<01549>>01660000
        ics'pdisabledcnt=18,                                   <<01549>>01662000
        ics'stackdst=16;                                       <<01549>>01664000
equate locvarcnt=14;                                           <<01965>>01666000
logical ls0=s-0;                                               <<01549>>01668000
integer instruction=q+1,                                       <<01549>>01670000
        oldsize=q+2,                                           <<01549>>01672000
        newsize=q+3,                                           <<01549>>01674000
        pagesrequired=q+4,                                     <<01549>>01676000
        wordsrequired=q+5,                                     <<01549>>01678000
        olddeltaz=q+6,                                         <<01549>>01680000
        stackdst=q+7,                                          <<01549>>01682000
        sbreldb=q+8,                                           <<01549>>01684000
        maxstacksize=q+9,                                      <<01549>>01686000
        increment=q+10,                                        <<01549>>01688000
        dbreltostkbase=q+11;                                   <<01549>>01690000
integer pagesalloc=q+12;                                       <<01713>>01692000
integer pcbpt=q+13;                                            <<01965>>01694000
                                                                        01696000
   << this portion runs on the ics >>                                   01698000
   if  x = ixit  then  deltas := deltas-4;                              01700000
   tos := stdb;                                                         01702000
   tos := tos+deltas-1;          << user q+1 >>                         01704000
   tos := x;                     << build a marker to get off ics >>    01706000
   tos := @stov'user;                                                   01708000
   asmb( sdea );                                                        01710000
   tos := tos+2;                                                        01712000
   push( status );                                                      01714000
   tos := 4;                                                            01716000
   asmb( sdea );                                                        01718000
   tos := tos+2;                                                        01720000
   push( db );                                                          01722000
   asmb( sdea );                                                        01724000
   deltas := deltas+4;                                                  01726000
   deltaz := deltaz + 120;                                              01728000
   asmb( psdb; ixit );                                                  01730000
                                                                        01732000
stov'user:  << the marker above exits to here >>                        01734000
   tos:=x; <<save instr causing overflow at q+1>>              <<01549>>01736000
   if x <> ixit and not(%020420 <= x <= %020430) then          <<rn.06>>01738000
      << not an ixit or apl instruction >>                     <<rn.06>>01740000
      begin <<adjust p to retry instruction>>                           01742000
      p := p-1;                                                         01744000
      x := logical(x) land %170077;<<isolate right stackop>>            01746000
      if  1 <= x <= 63  then                                            01748000
         begin <<paired stack operators in instruction>>                01750000
         tos := status;                                                 01752000
         asmb(tcbc 3);                                                  01754000
         if  <>  then  p := p+1;                               <<01.00>>01756000
         status := tos;                                                 01758000
         end;                                                           01760000
      end;                                                              01762000
asmb(adds locvarcnt);                                          <<01563>>01764000
                                                               <<01857>>01766000
trapsoff;                                                      <<01857>>01768000
                                                               <<01857>>01770000
if gclassenabledmask.class0 then                               <<01563>>01772000
   begin  <<measure stk ovrflow event>>                        <<01563>>01774000
   tos:=measstatxdsbank;                                       <<01563>>01776000
   tos:=measstatxdsbase;                                       <<01563>>01778000
   tos:=tos+c0sub0'segreloff+c'stopstkoverflow;                <<01563>>01780000
   asmb(lsea);                                                 <<01563>>01782000
   tos:=tos+1;                                                 <<01563>>01784000
   asmb(ssea;ddel);                                            <<01808>>01786000
   end;                                                        <<01808>>01788000
if gclassenabledmask.class15 then                              <<01808>>01790000
   begin <<process level stackoverflow>>                       <<01808>>01792000
   tos:=measprocxdsbank;                                       <<01808>>01794000
   tos:=measprocxdsbase;                                       <<01808>>01796000
   tos:=tos+((abs(cpcb)-abs(pcbb))/pcbsize)*                   <<01808>>01798000
        class15'sub0size+cp'stopsegexpand;                     <<01808>>01800000
   asmb(lsea);                                                 <<01808>>01802000
   tos:=tos+1;                                                 <<01808>>01804000
   asmb(ssea;ddel);                                            <<01808>>01806000
   end;                                                        <<01808>>01808000
mmstat(2,absolute(absolute(ics'qi)-ics'stackdst),15,           <<01563>>01810000
         absolute(absolute(ics'qi)-ics'deltaz));               <<01563>>01812000
disable;                                                       <<01563>>01814000
absolute(syswaittodispmsg).memtrapflag:=1;                     <<01563>>01816000
pcbpt:=absolute(cpcb)-absolute(pcbb);                          <<01965>>01818000
if absolute(absolute(cpcb)+stkinfowordnum).stovrallflag=1      <<01950>>01820000
then suddendeath(640);                                         <<01950>>01822000
x:=stackdst:=absolute(absolute(ics'qi)-ics'stackdst);          <<01563>>01824000
if logical(dst(x:=x&lsl(2)+1)).segresidentflag                 <<01656>>01826000
then suddendeath(643);                                         <<01680>>01828000
oldsize:=dst(x:=stackdst&lsl(2)).datasizefield&lsl(2);         <<01563>>01830000
tos:=absolute(absolute(ics'qi)-ics'stackbank);                 <<01563>>01832000
tos:=absolute(absolute(ics'qi)-ics'stackbase);                 <<01563>>01834000
tos:=tos+sbtoreldb;                                            <<01563>>01836000
asmb(lsea);                                                    <<01563>>01838000
dbreltostkbase:=tos;                                           <<01563>>01840000
tos:=tos-sbtoreldb;                                            <<01563>>01842000
tos:=tos+stbtomaxdata; <<21 decimal>>                          <<01563>>01844000
asmb(lsea);<<max for pcbxtoz>>                                 <<01563>>01846000
maxstacksize:=tos;                                             <<01563>>01848000
tos:=tos+maxdatatorelz; <<9>>                                  <<01563>>01850000
asmb(lsea);                                                    <<01563>>01852000
olddeltaz:=s0;                                                 <<01563>>01854000
tos:=tos+120;                                                  <<01563>>01856000
asmb(ssea); <<in case block in getdatasegchangestate>>         <<01563>>01858000
if olddeltaz >= maxstacksize-dbreltostkbase then               <<01713>>01860000
   begin <<stack has grown beyond allowable size>>             <<01563>>01862000
   absolute(x:=absolute(4)+procstatewordnum).stovflag:=1;      <<01563>>01864000
   if <> then suddendeath(641);                                <<01680>>01866000
   increment:=extrainc;                                        <<01563>>01868000
   tos:=tos-maxdatatorelz;                                     <<01563>>01870000
   tos:=maxstacksize+extrainc;                                 <<01563>>01872000
   asmb(ssea);                                                 <<01563>>01874000
   tos:=tos+maxdatatorelz;                                     <<01563>>01876000
   end                                                         <<01563>>01878000
else                                                           <<01563>>01880000
   begin  <<stack ok, check for adds 0 instr >>                <<01563>>01882000
      if instruction <> %35000 then increment := stackovrinc   <<01563>>01884000
      else increment := stackovrinc + users0;                  <<01563>>01886000
   if logical(olddeltaz+increment) >                           <<01563>>01888000
      logical(maxstacksize-dbreltostkbase)  then               <<01563>>01890000
      increment := (maxstacksize-dbreltostkbase) - olddeltaz;  <<01563>>01892000
   increment:=logical(increment+3) land -4;                    <<01713>>01894000
   end;                                                        <<01563>>01896000
pagesrequired := (oldsize+increment+overhead-1)                <<01563>>01898000
                   &lsr(pagepower)+1;                          <<01563>>01900000
wordsrequired:=pagesrequired&lsl(pagepower);                   <<01563>>01902000
<<newsize:=wordsrequired-(overhead+128) causes vds ovrflow>>   <<01563>>01904000
newsize:=oldsize+increment;                                    <<01713>>01906000
tos:=tos+relztorbdisp+rbtorasdisp;                             <<01563>>01908000
asmb(lsea);                                                    <<01563>>01910000
if tos.regiofzflag=1 then                                      <<01563>>01912000
   begin                                                       <<01563>>01914000
   if status.(1:1) = 0 then suddendeath(642);                  <<01680>>01916000
if absolute(absolute(ics'qi)-icspdisablecntcell) > 1 then      <<02093>>01918000
                                                               <<02093>>01920000
   comment:  the purpose of the following code is to cover up  <<02093>>01922000
             a pdisable problem in which an interrupt handler  <<02093>>01924000
             appears to execute a pdisable without a           <<02093>>01926000
             corresponding penable.  this strange problem      <<02093>>01928000
             always appears to leave the pdisable count at 1.  <<02093>>01930000
             if this condition is met, we shall execute a      <<02093>>01932000
             penable on behalf of the defective software       <<02093>>01934000
             [a small prayer is in order here] and continue    <<02093>>01936000
             execution.  otherwise we shall halt the machine.  <<02093>>01938000
             previously, the software crashed the machine      <<02093>>01940000
             with a suddendeath(642).  when this problem is    <<02093>>01942000
             corrected the suddendeath should be implemented;  <<02093>>01944000
                                                               <<02093>>01946000
   if absolute(absolute(ics'qi)-icspdisablecntcell) = 2 then   <<02093>>01948000
      penable   <<it's a miracle>>                             <<02093>>01950000
   else                                                        <<02093>>01952000
      if true then                                             <<02093>>01954000
         assemble (halt 7)  <<the lord giveth and . . . >>     <<02093>>01956000
      else                                                     <<02093>>01958000
         suddendeath(642);  <<leave the sf hook in>>           <<02093>>01960000
                                                               <<02093>>01962000
   end;                                                        <<01563>>01964000
penable;                                                       <<01563>>01966000
tryagain:                                                      <<01950>>01968000
getdatasegchangestate(stackdst);                               <<01563>>01970000
if < then suddendeath(643) else if > then go tryagain;         <<01950>>01972000
<<pdisable in effect now, and stack marked absent!>>           <<01563>>01974000
absolute(absolute(cpcb)+stkinfowordnum).stovrallflag:=1;       <<01950>>01976000
tos:=dst(x:=stackdst&lsl(2)+2);                                <<01563>>01978000
tos:=dst(x:=x+1);                                              <<01563>>01980000
tos:=tos+rbtorsdisp;                                           <<01713>>01982000
asmb(lsea);                                                    <<01713>>01984000
pagesalloc:=tos;                                               <<01713>>01986000
tos:=tos+rstorbdisp;                                           <<01713>>01988000
tos:=tos+maxdatatoreldb+stbtomaxdata;                          <<01563>>01990000
asmb(lsea); <<stack base to db>>                               <<01563>>01992000
sbreldb:=tos;                                                  <<01563>>01994000
tos:=tos+reldbtorelz; <<9>>                                    <<01563>>01996000
tos:=olddeltaz+increment;                                      <<01563>>01998000
asmb(ssea);                                                    <<01563>>02000000
if pagesalloc >= pagesrequired then                            <<01713>>02002000
   begin <<current region is ok>>                              <<01563>>02004000
   absolute(absolute(cpcb)+stkinfowordnum).                    <<01563>>02006000
   stovrallflag:=0;                                            <<01563>>02008000
   dst(x:=stackdst&lsl(2)).datasizefield:=newsize&lsr(2);      <<01563>>02010000
   dst(x).absentflag:=0;                                       <<01563>>02012000
   absolute(absolute(ics'qi)-ics'deltaz):=olddeltaz +          <<01563>>02014000
   increment;                                                  <<01563>>02016000
   <<flip db to stack db for the set z instruction>>           <<01801>>02018000
   tos:=ics(-ics'stkbankcell);                                 <<01801>>02020000
   tos:=ics(-ics'absstkdbcell);                                <<01801>>02022000
   asmb(xchd);                                                 <<01801>>02024000
   tos:=olddeltaz+increment;                                   <<01783>>02026000
   set(z); <<store new delta z into register>>                 <<01783>>02028000
   asmb(xchd;ddel); <<db back to where it belongs>>            <<01801>>02030000
   penable;                                                    <<01563>>02032000
   end                                                         <<01563>>02034000
else                                                           <<01563>>02036000
   begin <<current region isn't big enough>>                   <<01563>>02038000
   absolute(syswaittodispmsg).memtrapflag:=1;                  <<01563>>02040000
   x:=stackdst&lsl(2);                                         <<01563>>02042000
   genspecreq(stackdst,newsize&lsr(2),0,0);                    <<01563>>02044000
   tos:=stackdst;                                              <<01563>>02046000
   tos:=absolute(cpcb)-sysbase;                                <<01563>>02048000
   sendmsg(schedpin,makeabsentport,2,0);                       <<01563>>02050000
   if status.(1:1) = 0 then                                    <<01563>>02052000
      begin <<process had disabled interrupts>>                <<01563>>02054000
      tos:=3; <<clock drt>>                                    <<01563>>02056000
      asmb(sin 0); <<tick will do a disp>>                     <<01563>>02058000
      if <> then suddendeath(23);                              <<01563>>02060000
      dst(stackdst&lsl(2)).absentflag:=0; <<mark present>>     <<01940>>02062000
      penable;                                                 <<01563>>02064000
      return;                                                  <<01563>>02066000
      end                                                      <<01563>>02068000
   else asmb(disp;pseb); <<get control to dispatcher>>         <<01563>>02070000
   if ics(-ics'pdiscntcell) > 0 then                           <<01940>>02072000
      begin  <<process has switching disabled>>                <<01940>>02074000
      dst(stackdst&lsl(2)).absentflag:=0; <<mark present>>     <<01940>>02076000
      return; <<disp above will get control to dispatcher>>    <<01940>>02078000
      end;                                                     <<01940>>02080000
   end;                                                        <<01563>>02082000
if pcb(pcbpt+procstatewordnum).stovflag=1                      <<01965>>02084000
and pcb(pcbpt+resabortinfowordnum).critflag=0                  <<01965>>02086000
and pcb(pcbpt+resabortinfowordnum).hassirflag=0                <<01965>>02088000
then                                                           <<04529>>02090000
   begin                                                       <<04529>>02092000
   p := p+1; << update p for abort routine >>                  <<04529>>02094000
   << let kernel routines know we're processing abort >>       <<04529>>02096000
   pcb(pcbpt+resabortinfowordnum).stovabortflag := 1;          <<04529>>02098000
   abort ([8/1,8/4],0,0);                                      <<04529>>02100000
   end;                                                        <<04529>>02102000
end  <<stackoverflow>>;                                        <<01563>>02104000
                                                                        02106000
procedure  stackunderflow;                                              02108000
   option privileged,uncallable;                                        02110000
   begin                                                                02112000
   enable;                                                              02114000
   abort([8/1,8/0],29,0);  << with instr in xreg >>            <<03042>>02116000
   end;                                                                 02118000
                                                                        02120000
procedure  privilegedmodeviolation;                                     02122000
   option privileged,uncallable;                                        02124000
   begin                                                                02126000
   enable;                                                              02128000
   abort([8/1,8/0],6,0); << with instr in xreg >>              <<03042>>02130000
   end;                                                                 02132000
                                                                        02134000
procedure usertrap;                                                     02136000
   option privileged,uncallable;                                        02138000
   begin                                                                02140000
   enable;                                                              02142000
   assemble (adds 200);  <<prevent critical stack overflow>>   <<00260>>02144000
   assemble (subs 200);                                        <<00260>>02146000
   abort([8/1,8/0],param,0);                                            02148000
   end;                                                                 02150000
                                                                        02152000
procedure codeabsence;                                         <<01549>>02156000
option privileged,uncallable,internal;                         <<01549>>02158000
                                                               <<01549>>02160000
comment                                                        <<01549>>02162000
                                                               <<01549>>02164000
codeabsence is the internal interrupt handler for pcal and     <<01549>>02166000
exit references to absent segments.  codeabsence runs on the   <<01549>>02168000
trapping process' stack with the following environment set     <<01549>>02170000
up by firmware :                                               <<01549>>02172000
                                                               <<01549>>02174000
x register-                                                    <<01549>>02176000
   the instruction causing the absence trap is placed by       <<01549>>02178000
   firmware into the index register.                           <<01549>>02180000
                                                               <<01549>>02182000
q+1 firmware parameter -                                       <<01549>>02184000
   if absent on an exit then n = # of Procedure parameters     <<01549>>02186000
   to be peeled off the stack.                                 <<01549>>02188000
   if absent on a pcal, then =plabel where (3:7)=cstxeix and   <<01549>>02190000
   (10:6) =entry number.                                       <<01549>>02192000
                                                               <<01549>>02194000
stack markers-                                                 <<01549>>02196000
if pcal, two stack markers. the first marker is the normal     <<01549>>02198000
marker set up by firmware for a pcal so that control and       <<01549>>02200000
return on exit. the second marker contains garbage delta       <<01549>>02202000
p, delta q = 4, and status with the cst number of the segment  <<01549>>02204000
the pcal was going to in it.  codeabsence will fix up this     <<01549>>02206000
marker after the required seg comes in by looking up the       <<01549>>02208000
delta p in the new segmment via the stt, placing this into     <<01549>>02210000
the stack marker.  this marker will then be exited into.       <<01549>>02212000
                                                               <<01549>>02214000
for exits, there's only one stack marker, the regular old      <<01549>>02216000
one.  when the segment comes in, codeabsence will retry the    <<01549>>02218000
exit with the n value obtained from firmware's parameter.      <<01549>>02220000
                                                               <<01549>>02222000
to get the segment into memory, codeabsence has an sll entry   <<01549>>02224000
built for the segment in the process' sll and points the sll   <<01549>>02226000
memory pointer at it.  wait is called, waiting on memory       <<01549>>02228000
attention                                                      <<01549>>02230000
                                                               <<01549>>02232000
;                                                              <<01549>>02234000
                                                               <<01549>>02236000
begin                                                          <<01549>>02238000
                                                               <<01549>>02240000
integer s0=s-0,                                                <<01549>>02242000
        s1=s-1,                                                <<01549>>02244000
        status=q-1;                                            <<01549>>02246000
integer pcalstatus=q-5;                                        <<01950>>02248000
integer firmwareparm=q+1,                                      <<03042>>02250000
        procinx=q+6,                                           <<03042>>02252000
        cstxeix=q+7,                                           <<03042>>02254000
        sllinx=q+8,                                            <<03042>>02256000
        descstinx=q+9;                                         <<03042>>02258000
logical segidentifier=q+10,                                    <<03042>>02260000
        instr=q+2,                                             <<03042>>02262000
        pcalflag=q+3,                                          <<03042>>02264000
        trace=q+11;                                            <<03042>>02266000
double savedb=q+4;                                             <<03042>>02268000
                                                               <<03042>>02270000
subroutine abort'proc (mode,code,abort'parm);                  <<03042>>02272000
   value mode,code,abort'parm;                                 <<03042>>02274000
   integer mode,code,abort'parm;                               <<03042>>02276000
begin                                                          <<03042>>02278000
   comment:  this code places the instruction in x and         <<03042>>02280000
      calls abort. mode.(8:8), code and abort'parm are as      <<03042>>02282000
      defined for abort;                                       <<03042>>02284000
   x := instr;                                                 <<03042>>02286000
   << pop garbage marker laid down for pcals >>                <<03042>>02288000
   mode.(0:8) := if pcalflag then 2 else 1;                    <<03042>>02290000
   abort (mode,code,abort'parm);                               <<03042>>02292000
end;                                                           <<03042>>02294000
tos := x; << set up instr >>                                   <<03042>>02296000
if absolute(absolute(ics'qi)-icspdisablecntcell) > 0 then      <<02093>>02300000
                                                               <<02093>>02302000
   comment:  the purpose of the following code is to cover up  <<02093>>02304000
             a pdisable problem in which an interrupt handler  <<02093>>02306000
             appears to execute a pdisable without a           <<02093>>02308000
             corresponding penable.  this strange problem      <<02093>>02310000
             always appears to leave the pdisable count at 1.  <<02093>>02312000
             if this condition is met, we shall execute a      <<02093>>02314000
             penable on behalf of the defective software       <<02093>>02316000
             [a small prayer is in order here] and continue    <<02093>>02318000
             execution.  otherwise we shall halt the machine.  <<02093>>02320000
             previously, the software crashed the machine      <<02093>>02322000
             with a suddendeath(644).  when this problem is    <<02093>>02324000
             corrected the suddendeath should be implemented;  <<02093>>02326000
                                                               <<02093>>02328000
   if absolute(absolute(ics'qi)-icspdisablecntcell) = 1 then   <<02093>>02330000
      penable   <<it's a miracle>>                             <<02093>>02332000
   else                                                        <<02093>>02334000
      if true then                                             <<02093>>02336000
         assemble (halt 7)  <<the lord giveth and . . . >>     <<02093>>02338000
      else                                                     <<02093>>02340000
         suddendeath(644);  <<leave the sf hook in>>           <<02093>>02342000
                                                               <<02093>>02344000
                                                               <<01549>>02346000
trapsoff;                                                      <<01857>>02348000
pdisable;                                                      <<01549>>02350000
enable;                                                        <<01549>>02352000
                                                               <<01549>>02354000
<<fill in the local variables>>                                <<01549>>02356000
                                                               <<01549>>02358000
comment  if we have a code absence for a pcal instruction,     <<04268>>02360000
         and we get a control y pseudo interrupt while waiting <<04268>>02362000
         for the segment to come in , the delayed control y    <<04268>>02364000
         flag is set in the delta p by pseudoint inside of     <<04268>>02366000
         bit (0:1). however, when the code segment is brought  <<04268>>02368000
         in, the top two bits of the delta p word will be set  <<04268>>02370000
         to zero (in the old code), and the delayed control y  <<04268>>02372000
         will be forever lost. now the garbage delta p is set  <<04268>>02374000
         to zero before queueing on the segment, and the delta <<04268>>02376000
         p which is restored does not mask off bit 0.          <<04268>>02378000
;                                                              <<04268>>02380000
if firmwareparm < 0 then  << it's a pcal >>                    <<04268>>02382000
   begin                                                       <<04268>>02384000
   p := 0; << delta p in the marker for the absent segment >>  <<04268>>02386000
   tos := true;                                                <<04268>>02388000
   end                                                         <<04268>>02390000
else                                                           <<04268>>02392000
   tos := false;                                               <<04268>>02394000
tos:=%1000d;                                                   <<01549>>02396000
x:=absolute(cpcb)-s0;                                          <<01549>>02398000
asmb(xchd); <<fills in savedb>>                                <<01549>>02400000
tos:=x;<<procinx>>                                             <<01549>>02402000
tos:=pbx;<<cstxeix>>                                           <<01549>>02404000
tos:=sllptr; <<sllinx>>                                        <<01549>>02406000
<<form segidentifier>>                                         <<01549>>02408000
tos:=status.(8:8); <<mask off entry number>>                   <<01549>>02410000
tos:=s0-%300;                                                  <<01549>>02412000
if < then                                                      <<01549>>02414000
   begin <<sl seg>>                                            <<01549>>02416000
   asmb(del);                                                  <<01549>>02418000
   tos:=tos&lsl(2)+dfc;  <<descstinx>>                         <<01549>>02420000
   tos:=buildsegid(1,status.(8:8),0);                          <<01549>>02422000
   end                                                         <<01549>>02424000
else                                                           <<01549>>02426000
   begin <<cstx block seg>>                                    <<01549>>02428000
   asmb(delb);                                                 <<01549>>02430000
   tos:=tos&lsl(2)+cstxblk(cstxeix);  <<descstinx parm>>       <<01549>>02432000
   tos:=buildsegid(2,status.(8:8),                             <<01549>>02434000
   (absolute(cpcb)-absolute(pcbb))/pcbsize);                   <<01549>>02436000
   end;                                                        <<01549>>02438000
tos:=false; <<fill in trace flag later>>                       <<01549>>02440000
if dst(descstinx).codesizefield = 0 then                       <<01549>>02442000
   begin <<bad entry>>                                         <<01549>>02444000
   dst(x).referencedflag:=0;penable;                           <<01549>>02446000
   abort'proc (0,30,0); return;                                <<03042>>02448000
   end;                                                        <<01549>>02450000
if logical(dst(x:=descstinx+1)).rocflag then                   <<01549>>02452000
   begin <<recoverable>>                                       <<01549>>02454000
   recoveroc(segidentifier,descstinx);                         <<01549>>02456000
   if gclassenabledmask.class0 then                            <<01549>>02458000
      begin  <<measure recovery of code overlay candidate>>    <<01549>>02460000
      tos:=measstatxdsbank;                                    <<01549>>02462000
      tos:=measstatxdsbase;                                    <<01549>>02464000
      tos:=tos+c0sub0'segreloff;                               <<01549>>02466000
      if segidentifier.segidpbxflag then                       <<01549>>02468000
         tos:=tos+c'pbxrecovery                                <<01549>>02470000
         else tos:=tos+c'slrecovery;                           <<01549>>02472000
      asmb(lsea;inca;ssea;ddel);                               <<01549>>02474000
      end;                                                     <<01549>>02476000
   end                                                         <<01549>>02478000
else                                                           <<01549>>02480000
   begin<<enter request for seg and wait>>                     <<02013>>02482000
   if gclassenabledmask.class0 then                            <<02013>>02484000
      begin  <<measure code trap event>>                       <<02013>>02486000
      tos:=measstatxdsbank;                                    <<02013>>02488000
      tos:=measstatxdsbase;                                    <<02013>>02490000
      tos:=tos+c0sub0'segreloff;                               <<02013>>02492000
      if segidentifier.segidpbxflag then                       <<02013>>02494000
         tos:=tos+c'stoppbxfault                               <<02013>>02496000
         else tos:=tos+c'stopslfault;                          <<02013>>02498000
      asmb(lsea;inca;ssea;ddel);                               <<02013>>02500000
      end;                                                     <<02013>>02502000
   if gclassenabledmask.class15 then                           <<02013>>02504000
      begin <<process level pbx or sl seg fault>>              <<02013>>02506000
      tos:=measprocxdsbank;                                    <<02013>>02508000
      tos:=measprocxdsbase;                                    <<02013>>02510000
      tos:=tos+((abs(cpcb)-abs(pcbb))/pcbsize)*                <<02013>>02512000
           class15'sub0size;                                   <<02013>>02514000
      if segidentifier.segidpbxflag then                       <<02013>>02516000
         tos:=tos+cp'stoppbxfault                              <<02013>>02518000
         else tos:=tos+cp'stopslfault;                         <<02013>>02520000
      asmb(lsea);                                              <<02013>>02522000
      tos:=tos+1;                                              <<02013>>02524000
      asmb(ssea;ddel);                                         <<02013>>02526000
      end;                                                     <<02013>>02528000
   <<stuff away reason stopped in pcbx of this process>>       <<02013>>02530000
   <<done unconditionally for history for meas interface>>     <<02013>>02532000
   tos:=abs(abs(ics'qi)-ics'stkbankcell);                      <<02013>>02534000
   tos:=abs(abs(ics'qi)-ics'stkbasecell);                      <<02013>>02536000
   tos:=tos+pxglobsize+measstopreason'idx;                     <<02013>>02538000
   tos:=stopsegfault;                                          <<02013>>02540000
   asmb(ssea;ddel);                                            <<02013>>02542000
   tos:=savedb;                                                <<02013>>02544000
   asmb(xchd);                                                 <<02013>>02546000
   do                                                          <<02013>>02548000
      begin                                                    <<02013>>02550000
      queueonsegment(segidentifier);                           <<02013>>02552000
      pdisable;                                                <<02013>>02554000
      if segidentifier.segidpbxflag then descstinx:=           <<02013>>02556000
       convsegidtostinx(segidentifier); <<may have moved>>     <<02013>>02558000
      end                                                      <<02013>>02560000
   until dst(descstinx) > 0;                                   <<02013>>02562000
   asmb(xchd);                                                 <<02013>>02564000
   savedb:=tos;                                                <<02013>>02566000
   <<the required segment is around now>>                      <<02013>>02568000
   end;                                                        <<02013>>02570000
if not pcalflag then                                           <<01549>>02572000
   begin <<retry exit>>                                        <<01549>>02574000
   tos:=savedb;                                                <<01549>>02576000
   asmb(xchd);                                                 <<01549>>02578000
                                                               <<04530>>02580000
   comment :                                                   <<04530>>02582000
                                                               <<04530>>02584000
      the code below will avert a sf10 with a process          <<04530>>02586000
    which has a corrupted stack marker.                        <<04530>>02588000
                                                               <<04530>>02590000
   ;                                                           <<04530>>02592000
                                                               <<04530>>02594000
   if integer(logical(p) land %37777) >                        <<04530>>02596000
      dst(descstinx).codesizefield&lsl(2) and                  <<04530>>02598000
      (cpcbpsim <> 5) and (cpcbdelaysoft <> 1) then            <<04530>>02600000
      begin                                                    <<04530>>02602000
      abort'proc ( 0, 24, 0 );   << bounds violation >>        <<04530>>02604000
      return                                                   <<04530>>02606000
      end;                                                     <<04530>>02608000
   tos:=logical(firmwareparm) lor %31400;                      <<01549>>02610000
   penable;                                                    <<01549>>02612000
   asmb(xeq 0);                                                <<01549>>02614000
   end                                                         <<01549>>02616000
else                                                           <<01549>>02618000
   begin <<make pcal tests for firmware>>                      <<01549>>02620000
   x:=dstsysbaseinx+convsegidtostinx(segidentifier);           <<01549>>02622000
   if segdescfirminfo.traceflag=1 then trace:=true;            <<01549>>02624000
   tos:=segdescbank;                                           <<01549>>02626000
   tos:=segdescaddr;                                           <<01549>>02628000
   tos:=segdescfirminfo.codesizefield&lsl(2)-1; <<pl(0)>>      <<01549>>02630000
   asmb(ladd;lsea);                                            <<01549>>02632000
   tos:=tos.(8:8);  <<number of stt entries for segment>>      <<01549>>02634000
   tos:=firmwareparm.(1:7); <<target stt #>>                   <<01549>>02636000
   if s0 > s1 then                                             <<01549>>02638000
      begin <<stt is too large>>                               <<01549>>02640000
      tos:=savedb;                                             <<01549>>02642000
      asmb(xchd);                                              <<01549>>02644000
      penable;                                                 <<01549>>02646000
      abort'proc (0,31,0);  <<badstt>>                         <<03042>>02648000
      return;                                                  <<01549>>02650000
      end;                                                     <<01549>>02652000
   asmb(delb,lsub;lsea);                                       <<01549>>02654000
   if < then                                                   <<01549>>02656000
      begin <<stt being referenced is external>>               <<01549>>02658000
      tos:=savedb;asmb(xchd);penable;                          <<01549>>02660000
      abort'proc (0,31,0);  <<extsttref>>                      <<03042>>02662000
      return;                                                  <<01549>>02664000
      end;                                                     <<01549>>02666000
   asmb(tbc uncallablebit);                                    <<01549>>02668000
   if <> then                                                  <<01549>>02670000
      begin <<entry is uncallable>>                            <<01549>>02672000
      if (pcalflag land pcalstatus>=0)                         <<01950>>02674000
      lor (not pcalflag land status>=0) then                   <<01950>>02676000
         begin <<not privileged>>                              <<01549>>02678000
         tos:=savedb;                                          <<01549>>02680000
         asmb(xchd);                                           <<01549>>02682000
         penable;                                              <<01549>>02684000
         abort'proc (0,17,0);  <<uncallableref>>               <<03042>>02686000
         return;                                               <<01549>>02688000
         end;                                                  <<01549>>02690000
      end;                                                     <<01549>>02692000
                                                               <<01549>>02694000
   <<put the delta p into the second stack marker>>            <<01549>>02696000
                                                               <<01549>>02698000
   tos := tos land %37777; << mask off delta p >>              <<04268>>02700000
   tos := p;                                                   <<04268>>02702000
   p := tos lor tos;                                           <<04268>>02704000
   if p.(2:14) > dst(descstinx).codesizefield&lsl(2)           <<04268>>02706000
   then suddendeath(645);                                      <<01680>>02708000
                                                               <<01549>>02710000
   <<check if segment is being traced>>                        <<01549>>02712000
                                                               <<01549>>02714000
   if trace then                                               <<01549>>02716000
      begin                                                    <<01549>>02718000
      tos:=absolute(tracelabel);                               <<01549>>02720000
      if < then                                                <<01549>>02722000
         begin                                                 <<01549>>02724000
         disable;                                              <<01549>>02726000
         asmb(pcal 0);                                         <<01549>>02728000
         end                                                   <<01549>>02730000
      else                                                     <<01549>>02732000
         begin <<trace routine isn't around>>                  <<01549>>02734000
         tos:=savedb;asmb(xchd);penable;                       <<03042>>02736000
         abort'proc (0,22,0);  <<traceabs>>                    <<03042>>02738000
         end;                                                  <<01549>>02740000
      end;                                                     <<01549>>02742000
   tos:=savedb;                                                <<01549>>02744000
   asmb(xchd);                                                 <<01549>>02746000
   penable;                                                    <<01549>>02748000
   end;                                                        <<01549>>02750000
end  <<codeabsence>>;                                          <<01549>>02752000
                                                                        02756000
procedure  trace;                                                       02758000
   option privileged,uncallable;                                        02760000
   begin                                                                02762000
   define  psim = (0:3)#;  << pseudo interrupt mode >>                  02764000
   integer  inst = q+2; << last instruction from x reg >>               02766000
                                                               <<03042>>02768000
   subroutine abort'proc (mode,code,abort'parm);               <<03042>>02770000
      value mode,code,abort'parm;                              <<03042>>02772000
      integer mode,code,abort'parm;                            <<03042>>02774000
   begin                                                       <<03042>>02776000
      comment:  this code places the instruction in x          <<03042>>02778000
         and calls abort. mode, code and abort'parm are        <<03042>>02780000
         as defined for abort;                                 <<03042>>02782000
      x := inst;                                               <<03042>>02784000
      abort (mode,code,abort'parm);                            <<03042>>02786000
   end;                                                        <<03042>>02788000
                                                                        02790000
   tos := x;                                                            02792000
   tos := param;                                                        02794000
   if  <  then   << pcal >>                                             02796000
      begin                                                             02798000
      tos := tos.(8:8); << get cst number >>                            02800000
      asmb(dup);                                                        02802000
      if tos < %300 then x := 0 else                                    02804000
      begin                                                             02806000
         x := 1;                                                        02808000
         tos := tos - %300;                                             02810000
      end;                                                              02812000
      tos := f(tos&lsl(2) + f(x) + 2); << bank # >>                     02814000
      tos := f(x := x + 1); << bank offset >>                           02816000
      tos := tos + f(x := x - 3).(4:12)&lsl(2) - 1 - param.(1:7);       02818000
      asmb(lsea); << get stt of called segment >>                       02820000
      if < then suddendeath(289);                                       02822000
      p := tos.(2:14);                                                  02824000
      ddel;                                                             02826000
      tos := param;                                                     02828000
      tos := inst;                                                      02830000
      tos := 0;                                                         02832000
      tos := f(tracelabel);                                             02834000
      if < then                                                         02836000
      begin                                                             02838000
         asmb(pcal 0);                                                  02840000
         return;                                                        02842000
      end;                                                              02844000
      enable;                                                           02846000
      abort'proc ([8/2,8/0],22,0);<<pop destination marker>>   <<03042>>02848000
      end                                                               02850000
   else                                                                 02852000
      begin  << exit >>                                                 02854000
      tos := p;                                                         02856000
      tos.(0:1) := 0;                                                   02858000
      tos.(1:1) := 0;                                                   02860000
      p := tos;                                                         02862000
      if  =  then                                                       02864000
         begin  <<delayed control-y or software interrupt>>    <<03042>>02866000
         if cpcbpsim = 5 or cpcbdelaysoft = 1 then             <<03042>>02868000
            delayedint                                         <<03042>>02870000
         else                                                  <<03042>>02872000
            abort'proc ([8/1,8/0],22,0);                       <<03042>>02874000
         end else                                                       02876000
         begin << exit trace >>                                         02878000
            if deltaq < 0 then deltaq.(0:1) := 0; << set del q pos >>   02880000
            tos := param;                                               02882000
            tos := inst;                                                02884000
            tos := 0;                                                   02886000
            tos := f(tracelabel);                                       02888000
            if <> then asmb(pcal 0) else                                02890000
            begin                                                       02892000
               enable;                                                  02894000
               abort'proc ([8/1,8/0],22,0);                    <<03042>>02896000
            end;                                                        02898000
         end;                                                           02900000
      tos := tos lor %31400;                                            02902000
      asmb( xeq 0 );                                                    02904000
      help;  << dummy call for linking with debugger >>                 02906000
      end;                                                              02908000
   end;                                                                 02910000
                                                                        02912000
procedure  sttuncallable;                                               02914000
   option privileged,uncallable;                                        02916000
   begin                                                                02918000
   enable;                                                              02920000
                                                                        02922000
   << abort with instr. in xreg >>                             <<03042>>02924000
   abort([8/1,8/0],17,0);                                               02926000
   end;                                                                 02928000
                                                               <<01549>>02930000
                                                               <<01549>>02932000
procedure dataabsence;                                         <<01549>>02934000
option privileged,uncallable,internal;                         <<01549>>02936000
                                                               <<01549>>02938000
comment                                                        <<01549>>02940000
                                                               <<01549>>02942000
dataabsence is the internal interrupt handler for moves        <<01549>>02944000
attempted to an absent data segment. dataabsence runs on       <<01549>>02946000
the trapping process' stack, and firmware has pushed the       <<01549>>02948000
target data segment number into q+1. the process attempt-      <<01549>>02950000
ing the move will have an entry for the required segment       <<01549>>02952000
placed in its sll with the sll memory pointer aimed at it.     <<01549>>02954000
the process will then be waited until the seg is made          <<01549>>02956000
present, then the move will be retried by decrementing         <<01549>>02958000
the p register value in the stack marker and exiting.          <<01549>>02960000
                                                               <<01549>>02962000
;                                                              <<01549>>02964000
                                                               <<01549>>02966000
begin                                                          <<01549>>02968000
                                                               <<01549>>02970000
integer firmwareparm=q+1,                                      <<03042>>02972000
        instr=q+2,                                             <<03042>>02974000
        s0=s-0;                                                <<03042>>02976000
                                                               <<03042>>02978000
tos := x; << set up instr >>                                   <<03042>>02980000
if absolute(absolute(ics'qi)-icspdisablecntcell) > 0 then      <<02093>>02982000
                                                               <<02093>>02984000
   comment:  the purpose of the following code is to cover up  <<02093>>02986000
             a pdisable problem in which an interrupt handler  <<02093>>02988000
             appears to execute a pdisable without a           <<02093>>02990000
             corresponding penable.  this strange problem      <<02093>>02992000
             always appears to leave the pdisable count at 1.  <<02093>>02994000
             if this condition is met, we shall execute a      <<02093>>02996000
             penable on behalf of the defective software       <<02093>>02998000
             [a small prayer is in order here] and continue    <<02093>>03000000
             execution.  otherwise we shall halt the machine.  <<02093>>03002000
             previously, the software crashed the machine      <<02093>>03004000
             with a suddendeath(644).  when this problem is    <<02093>>03006000
             corrected the suddendeath should be implemented;  <<02093>>03008000
                                                               <<02093>>03010000
   if absolute(absolute(ics'qi)-icspdisablecntcell) = 1 then   <<02093>>03012000
      penable   <<it's a miracle>>                             <<02093>>03014000
   else                                                        <<02093>>03016000
      if true then                                             <<02093>>03018000
         assemble (halt 7)  <<the lord giveth and . . . >>     <<02093>>03020000
      else                                                     <<02093>>03022000
         suddendeath(644);  <<leave the sf hook in>>           <<02093>>03024000
                                                               <<02093>>03026000
                                                               <<01549>>03028000
trapsoff;                                                      <<01857>>03030000
pdisable;                                                      <<01549>>03032000
disable;                                                       <<01549>>03034000
<<if firmwareparm = absolute(absolute(4)+3).(1:10) then help>> <<01549>>03036000
if dst(x:=firmwareparm&lsl(2)).datasizefield = 0 then          <<01549>>03038000
   begin <<dad dst entry>>                                     <<01549>>03040000
   dst(x).referencedflag:=0;                                   <<01549>>03042000
   penable;x:=instr;abort([8/1,8/0],17,0);return;              <<03042>>03044000
   end;                                                        <<01549>>03046000
if logical(dst(x:=firmwareparm&lsl(2)+1)).rocflag then         <<01549>>03048000
   begin  <<recoverable>>                                      <<01549>>03050000
   if gclassenabledmask.class0 then                            <<01549>>03052000
      begin  <<measure data seg recovery>>                     <<01549>>03054000
      tos:=measstatxdsbank;                                    <<01549>>03056000
      tos:=measstatxdsbase;                                    <<01549>>03058000
      tos:=tos+c0sub0'segreloff+c'datarecovery;                <<01549>>03060000
      asmb(lsea);                                              <<01549>>03062000
      tos:=tos+1;                                              <<01549>>03064000
      asmb(ssea;ddel);                                         <<01549>>03066000
      end;                                                     <<01549>>03068000
   tos:=%1000d;                                                <<01549>>03070000
   x:=absolute(cpcb)-s0;                                       <<01549>>03072000
   asmb(xchd);                                                 <<01549>>03074000
   recoveroc(firmwareparm,firmwareparm&lsl(2));                <<01549>>03076000
   asmb(xchd);                                                 <<01549>>03078000
   penable;                                                    <<01549>>03080000
   end                                                         <<01549>>03082000
else                                                           <<01549>>03084000
   begin                                                       <<02013>>03086000
   if gclassenabledmask.class0 then                            <<02013>>03088000
      begin  <<measure data trap event>>                       <<02013>>03090000
      tos:=measstatxdsbank;                                    <<02013>>03092000
      tos:=measstatxdsbase;                                    <<02013>>03094000
      tos:=tos+c0sub0'segreloff+c'stopdatafault;               <<02013>>03096000
      asmb(lsea);                                              <<02013>>03098000
      tos:=tos+1;                                              <<02013>>03100000
      asmb(ssea;ddel);                                         <<02013>>03102000
      end;                                                     <<02013>>03104000
   if gclassenabledmask.class15 then                           <<02013>>03106000
      begin <<process level dataseg fault>>                    <<02013>>03108000
      tos:=measprocxdsbank;                                    <<02013>>03110000
      tos:=measprocxdsbase;                                    <<02013>>03112000
      tos:=tos+((abs(cpcb)-abs(pcbb))/pcbsize)*                <<02013>>03114000
           class15'sub0size+cp'stopdstfault;                   <<02013>>03116000
      asmb(lsea);                                              <<02013>>03118000
      tos:=tos+1;                                              <<02013>>03120000
      asmb(ssea;ddel);                                         <<02013>>03122000
      end;                                                     <<02013>>03124000
   <<stuff away reason stopped in pcbx of this process>>       <<02013>>03126000
   <<done unconditionally for history for meas interface>>     <<02013>>03128000
   tos:=abs(abs(ics'qi)-ics'stkbankcell);                      <<02013>>03130000
   tos:=abs(abs(ics'qi)-ics'stkbasecell);                      <<02013>>03132000
   tos:=tos+pxglobsize+measstopreason'idx;                     <<02013>>03134000
   tos:=stopsegfault;                                          <<02013>>03136000
   asmb(ssea;ddel);                                            <<02013>>03138000
   queueonsegment(firmwareparm);                               <<02013>>03140000
   end;                                                        <<02013>>03142000
p:=p-1; <<exit will cause move instruction to be retried>>     <<01549>>03144000
end  <<dataabsence>>;                                          <<01549>>03146000
                                                                        03148000
procedure  poweron;                                                     03150000
   option privileged,uncallable;                                        03152000
begin                                                                   03154000
                                                                        03156000
equate                                                                  03158000
   clockdrt    = 3,     << clock drt # >>                               03160000
   compwait    = %13,   << siodm completor wait state >>                03162000
   consldev    = %74,   << sysdb index >>                               03164000
   crmask      = %70310,<< write cr value to clock >>                   03166000
   cs80type    = %3,    << type for cs80 discs     >>          <<04794>>03168000
   ddltp       = 4,     << dlt pointer index in dit >>                  03170000
   diltp       = 5,     << ilt pointer index in dit >>                  03172000
   dlink       = 1,     << link offset in dit >>                        03174000
   dstat       = 6,     << status index in dit >>                       03176000
   dstop       = 7,     << stop word of trem. dit >>                    03178000
   dtype       = 5,     << dev type index in dlt >>                     03180000
   enableint   = %70351,<< enable clock interrupts >>                   03182000
   enableterm  = %015510,<< escape h to start terminet >>               03184000
   fhdisc      = 1,     << fhd type >>                                  03186000
   icntrl      = 7,     << q & drt index into ilt >>           <<01300>>03188000
   iflag       = 13,     << flags word of ilt >>               <<02501>>03190000
   iflagmaskword = %100037, << ilt flags mask word >>          <<02501>>03192000
   lrmask      = %70210,<< write lr value to clock >>                   03194000
   pfproc      = %144,  << powerfail proc sysdb index >>                03196000
   powerfail   = %72,   << powerfail flag sysdb index >>                03198000
   sysdb       = %1000,                                                 03200000
   systrl      = %12;   << timer request list ptr index >>              03202000
                                                                        03204000
define                                                                  03206000
   chanq       = (1:6)#, << channel queue num. in ilt >>                03210000
   drvrdy      = (3:1)#, << drive ready bit in disc status >>           03212000
   drtn        = (10:6)#,<< drt # in ilt(icntrl) >>            <<02070>>03214000
   iak         = (8:1)#, << int ack bit of dit >>                       03216000
   maxentry    = (0:8)#, << # of entries in the lpdt >>                 03218000
   request     = (3:1)#, << service request bit of dflags >>            03220000
   statef      = (12:4)#,<< siodm state field of dit >>                 03222000
   subtype     = (12:4)#,<< dev subtype field of lpdt >>                03224000
   termtype    = (5:5)#, << terminal type >>                            03226000
   type        = (8:8)#; << type field of dlt >>                        03228000
                                                                        03230000
integer                                                                 03232000
   absqi       = q+7,                                                   03234000
   cr          = q+6,                                                   03236000
   i           = q+3,                                                   03238000
   lr          = q+5,                                                   03240000
   pf          = db+powerfail,                                          03242000
   pfailpin    = db+pfproc,                                             03244000
   sm2         = s-2,                                                   03246000
   sysconsole  = db+consldev,                                           03248000
   sysup       = db+%73; << system up flag >>                           03250000
                                                                        03252000
integer pointer                                                         03254000
  measinfotabptr = %261,  << for clock interface >>            <<01549>>03256000
   busy        = db+%55,                                                03258000
   head        = db+%56,                                                03260000
   lpdt        = db+%10,                                                03262000
   ps0         = s-0,                                                   03264000
   ps1         = s-1,                                                   03266000
   ps2         = s-2,                                                   03268000
   trl         = db+systrl;                                             03270000
                                                                        03272000
double pointer                                                          03274000
   lpdtd       = lpdt;                                                  03276000
                                                                        03278000
array                                                                   03280000
   pfailmsg(0:8) = pb := %6412,"**POWERFAIL**",%6412;                   03282000
                                                                        03284000
   asmb(adds 1;adds 0); << restore s >>                                 03286000
   tos := 0;                                                            03288000
   tos := sysdb;                                                        03290000
   set(db,dl,q,s); << restore other registers >>                        03292000
   abs(absqi+4) := tos; << restore qi + 4 >>                            03294000
   abs(x:=x-1) := tos;                                                  03296000
   abs(x:=x-9) := tos; << qi+3, and qi-6 >>                             03298000
   pf := 2;                                                             03300000
   tos := -1;                                                           03302000
   tos := lpdtd(sysconsole);                                            03304000
   asmb(del,dup; cab,cab); << save copy of ditp >>                      03306000
   mpxcontrol(*,*); << initialize the system console >>                 03308000
   tos := ps0(dstop).termtype;                                          03310000
   delb; << dit pointer >>                                              03312000
   if tos = 6 then                                                      03314000
   begin << terminet, restart motor >>                                  03316000
      write2(enableterm); << start terminet motor >>                    03318000
      asmb(ixbz *+2; br *-1; ixbz *+2; br *-1; ixbz *+2; br *-1);       03320000
      << delay 6 tenths of a second >>                                  03322000
   end;                                                                 03324000
   for x := 0 until 8 do write2(pfailmsg(x)); << output msg to con >>   03326000
   i := 1;                                                              03328000
   do                                                                   03330000
   begin << step through lpdt and clean up resources >>                 03332000
      tos := lpdtd(i);                                                  03334000
      asmb(xch,test);                                                   03336000
      if > and (get'dsdevice(i)<2) and (ps0(diltp)<>0) then    <<01935>>03338000
      begin  <<valid dit pointer and non ds device>>           <<01623>>03340000
         tos := ps0(diltp);                                             03342000
         x := ps0(icntrl).chanq; << i/o channel resource >>    <<01300>>03344000
         if <> then                                                     03346000
         begin << free channel resource >>                              03348000
            busy(x) := 0;                                               03350000
            while dequeue(dlink,x) <> -1 do;                            03352000
         end;                                                           03354000
         tos := ps0(iflag);                                    <<02501>>03356000
         tos := tos land iflagmaskword; <<clear wait bit>>     <<02501>>03358000
         ps1(x) := tos;  << update flags of ilt >>             <<02501>>03360000
         tos := ps1(ddltp);                                             03362000
         tos := ps0(dtype).type; << device type >>                      03364000
         delb;                                                          03366000
         if tos <= cs80type then                               <<04794>>03368000
         begin << reset any request waiting for completion >>           03370000
            if < and sm2.subtype <= 3 then                              03372000
            begin << 7900 or 2888 type disc >>                          03374000
               tos := ps0(icntrl).drtn;                        <<02070>>03376000
wait:          << wait for disc to come ready before continuing >>      03378000
               asmb(tio 0);                                             03380000
               if <> then iofailure(tos,0);                             03382000
               if not tos.drvrdy then go wait;                          03384000
               del;                                                     03386000
            end;                                                        03388000
            if ps1.statef = compwait then                               03390000
            begin << restart the request >>                             03392000
               tos := ps1; << get dflags from dit >>                    03394000
               tos.request := 1;                                        03396000
               tos.iak := 1;                                            03398000
               ps2 := tos;                                              03400000
               ps1(dstat) := -1; << set status to indicate disc err >>  03402000
               masterclear(ps1); << clear i/o condition >>              03404000
            end;                                                        03406000
         end;                                                           03408000
         del; << delete ilt pointer on tos >>                           03410000
      end;                                                              03412000
      ddel; << delete lpdt entry on tos >>                              03414000
   end until (i := i + 1) > lpdt.maxentry;                              03416000
   i := 1;                                                              03418000
   do                                                                   03420000
   begin << now go restart all disc requests >>                         03422000
      checkldev(i);                                                     03424000
      if = and carry then                                               03426000
      begin << it's a disc >>                                           03428000
         tos := lpdtd(i);                                               03430000
         del;                                                           03432000
         tos := 0;                                                      03434000
         awakeio(*,*);                                                  03436000
      end;                                                              03438000
   end until (i := i + 1) > lpdt.maxentry;                              03440000
   abs(absqi-12) := pfailpin; << tell disp to awakw pf process >>       03442000
     awake(pfailpin,junkwaitcode,nowait);                      <<01549>>03444000
   trl(4) := 1; << set timer flag to get dispatched >>                  03446000
   pf := 3; << this will clear writechar if there from previous pf >>   03448000
   if lrv > 0  then          << clock is shared >>             <<01146>>03450000
   begin                                                       <<01146>>03452000
      tos := -1;                                               <<01146>>03454000
      tos := dlabel;                                           <<01549>>03456000
      if <  then  asmb(pcal 0);                                <<01146>>03458000
   end;                                                        <<01146>>03460000
   tos := clockdrt; <<initialize clock>>                                03462000
   tos := cr;                                                           03464000
   tos := crmask;                                                       03466000
   asmb(cio 2; wio 1);                                                  03468000
   tos := lrv;                   << get the limit reg value >> <<01146>>03470000
   if =  then  tos := tos + 100;         << lr value is 100 >> <<01146>>03472000
   tos := lrmask;                                                       03474000
   asmb(cio 2; wio 1);                                                  03476000
   tos := enableint;                                                    03478000
   asmb(cio 1; sin 0; ixit);                                            03480000
end;                                                                    03482000
                                                                        03484000
procedure  callhelp;                                                    03486000
   option  privileged,uncallable;                                       03488000
   begin                                                                03490000
   << build a marker to help, exit through it >>                        03492000
   tos := 0;  << x register >>                                          03494000
   tos := f(f(f(0)+@help.(8:8)*4).(4:12)*4+f(x:=x+3)-1-@help.(1:7));    03496000
   tos := tos.(2:14);   << get rid of uncallable bit >>                 03498000
   push(status);                                                        03500000
   tos.(8:8) := @help;                                                  03502000
   tos := 4;                                                            03504000
   push(s);                                                             03506000
   set(q);                                                              03508000
   end;                                                                 03510000
                                                                        03512000
<< outer block, stt # followed by a call to the routine >>              03514000
asmb(                                                                   03516000
     con 1;   pcal boundsviolation;                                     03518000
     con 2;   pcal illegaladdress;                                      03520000
     con 3;   pcal nonrespondingmodule;                                 03522000
     con 4;   pcal systemparity;                                        03524000
     con 5;   pcal addressparity;                                       03526000
     con 6;   pcal dataparity;                                          03528000
     con 7;   pcal moduleinterrupt;                                     03530000
     con 8;   pcal callhelp;                                            03532000
     con 9;   pcal powerfail;                                           03534000
     con 10;  pcal ghost;                                               03536000
     con 11;  pcal extghost;                                            03538000
     con 12;  pcal ghost;                                               03540000
     con 13;  pcal ghost;                                               03542000
     con 14;  pcal ghost;                                               03544000
     con 15;  pcal ghost;                                               03546000
     con 16;  pcal unimplementedinstruction;                            03548000
     con 17;  pcal sttviolation;                                        03550000
     con 18;  pcal cstviolation;                                        03552000
     con 19;  pcal dstviolation;                                        03554000
     con 20;  pcal stackunderflow;                                      03556000
     con 21;  pcal privilegedmodeviolation;                             03558000
     con 22;  pcal ghost;                                               03560000
     con 23;  pcal ghost;                                               03562000
     con 24;  pcal stackoverflow;                              <<01549>>03564000
     con 25;  pcal usertrap;                                            03566000
     con 26;  pcal ghost;                                               03568000
     con 27;  pcal ghost;                                               03570000
     con 28;  pcal ghost;                                               03572000
     con 29;  pcal ghost;                                               03574000
     con 30;  pcal ghost;                                               03576000
     con 31;  pcal codeabsence;                                         03578000
     con 32;  pcal trace;                                               03580000
     con 33;  pcal sttuncallable;                                       03582000
     con 34;  pcal dataabsence;                                         03584000
     con 35;  pcal poweron;                                             03586000
     con 36;  pcal ghost                                                03588000
);                                                                      03590000
end.                                                                    03592000
