{Mouses Standard Subsystem}

   %systemstring(7) Version       = "3.1:B"

   %conststring(16) Diag Prog     = "SUBSYS:MDIAG"
   %conststring(14) Sub Init      = "SUBSYS:SUBINIT"
   %conststring(14) Batch File    = "SUBSYS:BATCH"
   %conststring(13) Standard      = "SUBSYS:STANDARD"

   %constinteger Wsp  = 7,     {work space pointer}
                 Code = 14,    {code base}
                 Gla  = 13,    {gla base}
                 Link = 15     {subroutine link}

   %constinteger H = x'FFFF'

   %constinteger    Diag Stack       = 1200,  {stack required to run MDIAG (bytes)}
                    Basic Stack Size = 8      {god given stack size}

   %owninteger      Subsys Limit              {subsystem stack limit}
   %ownshortinteger State         = -10       {0=forground, 1=background}

   %constinteger  Opt Monitor =    1,
                  Opt Dump    =    2,
                  Opt Verify  =    4,
                  Opt Xdump   =   64,
                  Opt Quick   =  512,
                  Opt Trace   = 1024

   %systeminteger OPTIONS       = Opt Quick,
                  DEFAULT STACK =   10,     {60K for now}
                  DEFAULT TIME  =   60,     {one minute}
                  TT MODE       =    0,     {Terminal mode}
                  Obey Level    =    0

   %externalstring(17) Console int    = ""
   %externalstring(17) Prompt text    = ""
   %externalstring(17) Command prompt = "Command: "
   %externalstring(15) Error File     = ""
   %externalstring(7)  Search owner   = ""

   %recordformat Filefm(%integer Unit, Owner, Name1, Name2)

   %recordformat Parmfm(%shortinteger    Dsno, Dact, Ssno, Sact,
                        (%integer        P1,P2,P3,P4,P5,P6        %or
                         %record(Filefm) File                     %or
                         %string(23)     Text))

   %recordformat Contfm(%integer      Ps, Pc,
                        %integerarray R(0:15),
                        %integer      Eps, Epc,
                        %integerarray Er(0:15),
                                      Efpr(0:7))

   %recordformat restfm(%string(31)%array IO(1:6),
                        %integer Modifier,
                        %string(63) Parameter)

   %recordformat Command Fm(%string(31)         Command,
                           ((%string(31)         In1,  In2,  In3,
                                                Out1, Out2, Out3   %or
                            %string(31) %array  In, Out(1:3) %or
                            %string(31) %array IO(1:6)),
                            %integer            Modifier,
                            %string(63)         Parameter) %or
                           %record(Restfm) Rest)

   %external %record(Command fm) Command

   %owninteger Seg Mask     = 2_1111 1111 1111 1111,
               Current Segs = 0,
               Work Segs    = 0


   %owninteger C Level = 0          {current contingency level}

   %recordformat Eventfm(%integer    Event,
                                     Sub,
                                     Extra,
                         %string(63) Message,
                         %integer    Pc,
                                     X)

   %externalrecord(eventfm) EVENT = 0

!*******************************
!
!         {diagnostic routine}
!
         %routine REPORT(%string(23) TEXT)
            %record(parmfm) p
            p_text <- text.tostring(nl)
            svc(4, p)
         %end

!*******************************

   %include   "Sysinc:Ascii.inc"
   %include   "Sysinc:Direct.inc"
   %include   "Subsys:specs"
   %include   "Subsys:io.imp"
   %include   "Subsys:general.imp"
   %include   "Subsys:filerts.imp"
   %include   "Subsys:loader.imp"
   %include "Parse.imp"
   %include   "bci.imp"



!========= SUBSYSTEM ENTRY POINT =========

!      Control reaches here when the subsystem
!      is loaded by the system.
!      The floating-point registers contain the startup
!      message.

%externalroutine subsystem %alias "%GO"
   %record(parmfm) P, Q
   %record(Contfm) Cont       {contingency info at outer level}
   %label          Trap
   %integer        N
   %ownstring(23)  Batch  In = "T:"
   %ownstring(15)  Batch Out = "T:"

   *lhi_0,EVENT
   *st_0,4(Gla)               {prepare for events}
   *st_0,8(Gla)               {new standard}
   *stme_0,P

   *st_Wsp,N
   *stm_Gla,Old State
   Subsys Limit = N&x'F0000'+Basic Stack Size*1024-200
   Stack Limit  = Subsys Limit

   Seg Mask = Seg Mask !! 1<<(Old State_ Gla>>16)  %c
                       !! 1<<(Old State_Code>>16)  %c
                       !! 1<<(N>>16)
   SubsysFile_Code Segment = Old State_Code&x'F0000'
   SubsysFile_ Gla Segment = Old State_Gla
   SubsysFile_Code Base    = SubsysFile_Code Segment+16
   SubsysFile_ Gla Base    = SubsysFile_ Gla Segment
   SubsysFile_Head        == Record(SubsysFile_Code Base)
   SubsysFile_Defs         = SubsysFile_Head_Defs_N
   SubsysFile_Specs        = SubsysFile_Head_Specs_N
   SubsysFile_Code Head    = SubsysFile_Code Base+SubsysFile_Head_Code Disp&H*2
   SubsysFile_ Gla Head    = SubsysFile_ Gla Base
   SubsysFile_Stack Limit == Integer(SubsysFile_Gla Segment)
   SubsysFile_Stack Limit  = Subsys Limit
   SubsysFile_Options      = No Decode
   Relocate(SubsysFile)

   A Limit     = Addr(Alias Text(Max Alias))
   Alias Limit = Addr(Alias Text(0))

   %if P_Dact = 2 %start                        {a batch job}
      State = -10+1
      Q_File_Unit  = 0;     Q_File_Owner = 0
      Q_File_Name1 = P_P5;  Q_File_Name2 = P_P6
      Unpack(P_File, Batch In)
      Unpack(Q_File, Batch Out)
   %finish

            Init Streams
More:       Unstack Conts(0)
            *la_15,Trap
            *st_15,Cont+4
            *stm_0,Cont+8
            *ahi_wsp,300
            C Level = Contingency(Cont)
            %cycle
               Stack Limit            = Subsys Limit
               SubsysFile_Stack Limit = Stack Limit

               Current Segs = Seg Mask
               Work    Segs = 0
               Loaded Files = 0
               Obey Level   = 0
               Skipping     = 0
               A Limit      = Addr(Alias Text(Max Alias))
               %unless Addr(Alias Text(0)) <= Alias Limit <= A Limit %start
                  Alias Limit = Addr(Alias Text(0))
                  Console("All LETs removed")
               %finish
               %unless 0 <= Lib Limit <= 7 %start
                  Lib Limit = 0
                  Console("LIB list cleared")
               %finish
               Lib(N)_Use = 0 %for N = 1,1,7

               Obey(Batch In, Batch Out, Version)
               Stop %if State # 0
            %repeat

Trap:


      {Base level contingencies come here
      {There are two cases:
      {      1   A terminal interrupt has occurred, in which case
      {          either the global string "INT MESSAGE" is set
      {      2   A contingency is fired at the current level (Int:.)

      *stme_0,P
      N = -1
      %if P_Dact = -2 %start                             {shutdown}
         P_Dact = -1
         Shortinteger(Addr(P_P2)) = 1<<8+'.'             {pretend INT:.}
      %finish
      %if P_Dact = -1 %start                             {INT:something}
         Console Int = String(Addr(P_P2))
         N = Charno(Console Int, 1)
         %if N # '.' %start
            P_P2 = 0
            P_P2 = 256 %if N = '?'
            P_P3 = P_P1
            P_P1 = Addr(Cont)
            Svc(27, P)                                    {Resume}
         %finish
         {Int:.}
         P_P1 = 0;  P_P2 = 1;  P_P3 = 0;  Svc(6, P)       {kill output}
      %finish
      Stack Limit            = Subsys Limit
      SubsysFile_Stack Limit = Subsys Limit
      Stop %if State # 0                                  {Terminate batch job}
      Init Streams
      Console ("*Subsystem failure") %if N < 0
      Dump Contingency(Cont) %if Options&Opt Xdump # 0
      ->More

%end

%endoffile
