mtm$monitor_interrupt_handler IDENT

..............................................................................
.                  MONITOR INTERRUPT HANDLER
.  This module is the top-level control module in NOSVE monitor. It contains
.  the procedures that do the following:
.      - EXCHANGE to job mode
.      - decode the job mode MCR when it exchanges back to monitor and
.        call the CYBIL procedures to process the request or condition.
.      - Process EXCHANGE (170 PP) requests by giving control to the 170
.        partner
.      - Process TRAPS that occur in monitor mode.
.      - Call the CPU dispatcher to change the current task
.      - Handle (most) dual CPU interlocking.
.      - This module is the first OS module to begin executing at deadstart. It
.        performs some basic system initialization functions before exchanging
.        to job mode to continue deadstart.
.      - The monitor stack and exchange packages are defined in this module.
.      - The monitor request table is defined in this module.
.
.
.  NOTE: This module must be the first module on the OSF$MONITOR library and
.        must be the first module loaded into the monitor address space.
.
................................................................................
.
.
         page
.
*COPY     SYA$CONSTANTS
.
.  Deck SYA$CYBIL_INTERFACE_PROCEDURES follows but is not listed.
         list,1  0,0,0
*COPY   SYA$CYBIL_INTERFACE_PROCEDURES
         list,1  1,2,0
         page
*COPY   MTA$CPU_STATE_TABLE
*COPY   MTA$SMU_COMMUNICATION_BLOCK
*COPY   OSA$DUAL_STATE_CONTROL_BLOCK
*COPY   OSA$BASIC_REGISTER_EQUATES
*copyc  mta$dft_block
*COPY OSA$KEYPOINT_CLASSES
*copyc sya$xp_and_sf_constants
.
donthing equ     3      .Define symbol from osa$ei_constant_definitions
issuekpt equ     8      .Debug issue keypoint request for 170 trap handler
osktrap  equ  4005      .Trap handler keypoint request
dscb_tef equ  d8st      .Offset into Dual State Control Block to tell DFT
                        .  that this is a THETA with special trap code.
         page
...............................................................................
. XTRACE - This macro is used to keep trace information about what happens.
.    The TRACE buffer is a circular buffer containing a list of the last
.    256 items of interest. Items currently maintained are:
.       0. exchange to job mode. (timestamp)
.       1. exchange from job mode. (timestamp, MCR)
.       2. trap in monitor mode. (timestamp, MCR)
.       3. EXCHANGE to NOS for EXCHREQ trap. (timestamp)
.       4. EXCHANGE back from NOS for EXCHREQ trap. (timestamp, MCR)
.       5. Taskswitch. (timestamp, new task XP RMA)
.    An entry in the trace buffer is 1 word long and contains:
.       bit 0 - 3,  trace id. Same as item number in above list
.       bit 4-31, data dependant on id. Usually MCR or XP RMA.
.       bit 32-63, lower 32 bits of FREE RUNNING CLOCK.
.
.    calling sequence to macro....
.        xtrace  p0,p1,p2,p3
.           p0 - contains trace id (0 .. 5)
.           p1 - contains data to be saved
.           p2, p3 - 2 X-registers that can be used for scratch
.              WARNING - X0 cannot be used for p2.
.           p4 - scratch A register
.
.    NOTE: While system is stepped, it uses a different trace buffer to prevent
.          destroying the primary buffer that may contain useful info.
..............................................................................
.
         PROC
xtrace   pname
f:(0)    bss     0
         local   t1,t2
         la      f:(2,4),a_cst,tracectl+2
         entp    f:(2,3),0
         cpytx   f:(2,3),f:(2,3)
         sx      f:(2,3),f:(2,4),0
         entz    f:(2,3)
         entp    f:(2,2),f:(2,0)
         do      sn:(f:(2,1))=sn:(0)
           shfx  f:(2,2),f:(2,2),x0,60
           iorx  f:(2,3),f:(2,2)
         dend
         do      sn:(f:(2,1))/=sn:(0)
           shfx  f:(2,2),f:(2,2),x0,28
           iorx  f:(2,2),f:(2,1)
           shfx  f:(2,2),f:(2,2),x0,32
           iorx  f:(2,3),f:(2,2)
         dend
         lx      f:(2,2),f:(2,4),8
         isob    f:(2,2),f:(2,2),x0,7007(8)   .WARNING - <tracesiz> dependent.
         incx    f:(2,2),1
         sx      f:(2,2),f:(2,4),8
         sxi     f:(2,3),f:(2,4),f:(2,2),8
t2       bss    0
         pend
         page
..............................................................................
. ERRSTOP - This macro generates a call to the error stop routine to
.           terminate 180 operation after an unrecoverable error has
.           occurred.
.
.         errstop p1
.              where p1 = label on a string that defines the error halt message
..............................................................................
.
         PROC
errstop  pname
f:(0)    addaq   a0,a0,16
         sa      af,a0,-16
         addaq   af,a_root,f:(2,0)
         cpyax   x0,af
         shfx    x0,x0,x0,16
         addxq   x0,x0,31
         sx      x0,a0,-8
         ente    x0,00ff(16)
         addaq   af,a0,-8
         callseg bs_errst,a_bindin,af
         la      af,a0,-16
         addaq   a0,a0,-16
         PEND
         page
..............................................................................
.  Define A and X register usage
.   Note...
.        1. X0, X1, X2, XD, XE and XF are scratch registers
.        2. AE and AF are scratch registers
.        3. AF contains a pointer to 'xpinitv' at deadstart time. It's
.           used only for system initialization
..............................................................................
.
a_root   areg    4                     .Pointer to beginning of mainframe wired.
.                                          (If not A4, MXP must be changed.)
a_cst    areg    5                     .Pointer to CST.
a_xcb    areg    6                     .Pointer to XCB of current task. NIL if idle.
a_dscb   areg    7                     .NOS170 DSCB.
.
x_mcr    xreg    3                     .Scratch reg for MCR
x_clock  xreg    4                     .Contains PIT/FRC values.
x_kef    xreg    5                     .Contains KEF while processing traps and RUNNOS.
x_resume xreg    8                     .Contains RESUME flag while in IDLE 180.
.
.
.  Equates for RUNNOS routine.
.
a_innosx areg    8                     .Pointer to NOS XCB.
a_inret  areg    9                     .Return address.
.
x_inmcr  xreg    6                     .NOS170 MCR.
x_infrc  xreg    7                     .Save for free running clock.
.
.
.  Equates for RQPROC routine.
.
a_rqtbl  areg    10                    .Contains the pointer to REQTBL entry
.
a_rq_ret areg    11                    .Return from RQPROC routine.
a_extret areg    12                    .Return from EXTINT routine.
a_sitret areg    13                    .Return address for PRSIT routine.
.
..
.  Equates for REGISTER SAVE values (X0 for CALLSEG instructions)
.
x_envir1 equ     00c7(16)              .Environment for CALL.
         page


.   Miscellaneous equates.
.
.
m_pdf    equ     00001(16)             .Offset of Process Damaged flag.
.
...............................................................................
.  DEFCST  - This PROC is used to define and initialize the CST.
.            (See deck that defines equates to see definition of fields).
...............................................................................
.
         PROC
defcst   pname
f:(0,0)  bss     0
lpidz    set     0
         while   lpidz<f:(2,0)
         local   cst1
cst1     bssz    cstsize

         org     cst1+memport               .Best guess for memory port mask.
         vfd,8   1**(lpidz*2)               .  (may be changed in BEGIN).
         org     cst1+lpid
         vfd,8   lpidz
         org     cst1+lpid8
         vfd,8   lpidz*8
         org     cst1+cpu_stat
         vfd,8   2
         org     cst1+tracectl
         vfd,16  0
         address r,trace+lpidz*(tracesiz+2)*8
         org     cst1+taskid
         vfd,16,8 1,1
         org     cst1+prior180       .Initial 180 priority and 170 equivalent).
         vfd,24  070308(16)
         org     cst1+jcbp
         vfd,4,12,32 1,mstlen,0
         org     cst1+cp_state+cp_curst
         vfd,8   running
         org     cst1+cp_state+cp_nxtst
         vfd,8   running
         org     cst1+xcbp
         vfd,48  0ffff80000000(16)
         org     cst1+cptime
         vfd,64  0ffffffffffff(16)
         org     cst1+jtime
         vfd,64  07fffffff(16)
         org     cst1+cachtim
         vfd,64  07fffffffffffffff(16)
         org     cst1+maptim
         vfd,64  07fffffffffffffff(16)
         org     cst1+ijlep
         vfd,48  0ffff80000000(16)
         org     cst1+dpint
         vfd,64  07fffffffffffffff(16)
         org     cst1+idlstats+idle_cnt
         vfd,56  1                       . initialize the cpu idle count
         org     cst1+cstsize
lpidz    set     lpidz+1
         dend
         pend
         page
..............................................................................
.               MAINFRAME WIRED
.   Define oss$mainframe_wired data.
.   This data must be at the beginning of the Mainframe-wired segment.
.       !!!! THIS DATA MUST START AT BYTE 0 OF SEGMENT 1 !!!!
.
..............................................................................
oss$mainframe_wired   SECTION working,read+write
         USE     oss$mainframe_wired
         def     root
root     vfd,64  0
         vfd,64  0
.
...................................................................
.
.        NOS/VE memory limits.  Defines the upper and lower bounds of NOS/VE
.        memory, the bounds are RMAs.  During deadstart the memory upper bound
.        is determined by the size of the memory image.
.
.        NOTE:  The memlimit variable is referenced from Cybil, definition is
.        defined by the variable 'osv$180_memory_limits'.
.
...................................................................
memlimit vfd,32  0                     .Lower bound.
         vfd,32  0                     .Upper bound during deadstart.
         vfd,32  0                     .Upper bound after system initialized.
         vfd,32  0                     .?????
.
scb      bss     scbsize               .SCB communication area.
scbvec   equ     scb+scbvecsim         .Vector simulation option.
.
mtv$idle_message_line bss 0            .Message written to line 1 of console
         vfd,8,8 0,1                   .  y position on console
         vfd,8,8 0,0                   .  length
         vfd,32  0                     .  rma field
         bss     80                    .  text of message
         bss     6                     .  space for pointer
.
         align   0,32
cst0     defcst  maxcst                .Define CPU STATE TABLE (CST).
.
os_type  vfd,8   0                     .Operating mode (standalone, NOS, or NOSBE)
os_terms vfd,8   0                     .170 termination status (0=running,
         vfd,48  0                     .  1=mode error, 2=fatal due)
kcb_rma  vfd,64  0                     .RMA pointer to keypoint buffer
         align   0,8
multpro  vfd,64  0                     .Non-zero if more than one cpu is running.
nosjps   vfd,64  0                     .JPS of NOS170 if Dual State active.
dscpu    vfd,64  0                     .Time of first CPU initialization.
bct_pva  vfd,48  01003000001a8(16)     .PVA of the Boot Control Table.
nostab   vfd,48  0100300000000(16)     .If dual state, contains PVA of
.                                        NOS table containing priorities, etc.
eicbadr  vfd,64  71(8)                 .Pointer to EI control block
eicb     vfd,48  01003000001c8(16)     .PVA of EICB pointer word
nosxp    address r,a170_xp             .If dual state, contains PVA of NOS XP
nossegt  address r,a170_st             .Pointer to NOS segment table ..
         vfd,32,32,32  a170_stl*8,0,8  .  ... rest of adaptable pointer to seg table.
.
frc_p    address p,xfrc_p              .Pointer to free running clock time for
.                                       dispatcher to run.
.                                         180 idle routine too early)
mlist    vfd,16  00100(16)             .Memory_link_status.
         align   0,8
ve_vrsn  vfd,32,14,6,6,6  ost$psr,0,ost$nve,if_versn,if_level  .PSR lvl, OS type,
                                       .   i/f version and level. This field is set
                                       .  by LINOS but may be changed by the CHAOSV
                                       .  command.
eiflag   vfd,64  0fffffffffffff(16)    .EXTERNAL INTERRUPT flag. Contains FRC value
                                       .  of when to poll for next IO completion.
                                       .  If a IOU sends an external interrupt, the
                                       .  value of this word is set to one.
eiinc    vfd,64  1000000               .Rate to poll for lost external interrupts.
                                       .  Polling is immediate if EXT INT received
                                       .  and EIFLAG <> 0.
                                       .  NOTE: because of the algorithm used,
                                       .  asyninc must not be larger than this number.
asyntime vfd,64  0                     .FRC time to next check async activities.
asyninc  vfd,64  200000                .Rate at which asyn activities are checked.
sitvalue vfd,64  50000                 .Default SIT value.
mstacklx vfd,64  mstackl               .Length of monitor stack.
num_cst  vfd,64  maxcst                .Number of cst tables.
lockwait vfd,64,64 0,0                 .Total time/count waiting for dual CPU
                                       .  interlock.
cmax     vfd,64  2147483000            .Maximum number of requests before
                                       .statistic counts must be reset.
         align  0,64
p_mode   vfd,64,64 0,0                 .Processor mode - current processor mode,
.                                       either 0 (system) or an ajl ordinal (job)
no_stop  vfd,64    0                   .Don't stop on DUE error in mtr
rsetilk  vfd,64    0                   .Interlock reset flag
cpu1nos  vfd,8     0                   .CPU 1 is dedicated to NOS
sprior   vfd,8,8,8 7,3,8               .Special dedicated priority values.
         align  0,64
xajl     vfd,64,64 0,0                 .Used during recovery, a copy of p_mode.
retsave  vfd,64    0                   .SIT interrupt return address save

sjmtrxcb vfd,4,12,32 1,mstlen,jrootsiz .Pointer to system job monitor execution
.                                         control block.

.        Define interrupt ports for IOU external interrupts.  This is a mask with bit
.        7 being port 0, bit 6 being port 1, bit 5 being port 2, etc.  Currently all
.        non S0 machines interrupt on port 1 (value of 1) and the S0 interrupts on
.        port 2 (value of 4).  The value of this variable is set early in
.        initialization, it is set to the same value as memport.

intport  vfd,8   1                     .Interrupt port mask for IOU external
                                       . interrupts.
num_proc vfd,8   0                     .Number of processors physically configured.
mtrprior vfd,16  708(16)               .Priority of 180 if control is
                                       . given to 170 via trap in 180 monitor.
cpus_on  vfd,8   0                     .Number of cpus logically on.
         align   0,8
osv_bl   bssz    32                    .osv$build_level
nostime  vfd,64,64 0,0                 .Total time spent in NOS(total, ve_idle).
qstime   vfd,64  0ffffffffffff(16)     .FRC time to make quick sweep call.
mmtime   vfd,64  0ffffffffffff(16)     .FRC time to next call Memory Manager.
swaptime vfd,64  0ffffffffffff(16)     .FRC time to next call job swapper.
scbtime  vfd,64  0                     .FRC time to next check SCB status.
alltime  vfd,64  0ffffffffffff(16)     .FRC time of max async lock wait.
stampt   vfd,64  0                     .Hourly time stamp for trace base.
haltring vfd,8   0                     .Halt CP on MCR fault <= this number.
systemhr vfd,8   0                     .Same as above but for system job only.
asylock  vfd,8   0                     .Asynchronous interrupt lock.
asylocki vfd,8   0                     .Asynchronous interrupt lock for idle loop.
rlock1   vfd,8   0                     .CPU Recovery Lock level 1
rlock2   vfd,8   0                     .CPU Recovery lock level 2
rlock3   vfd,8   0                     .CPU Recovery Lock Level 3
heap_tr  vfd,8   0                     .Enable_heap_trace system attribute.
heap_ver vfd,8   0                     .Verify_heap_linkage system attribute.
fltinj   vfd,8   0                     .Enable fault injection utility.
ve_int   vfd,8   0                     .NOSVE_INTERNAL_OPERATIONS system attribute.
mtvdftb  vfd,48  0ffff80000000(16)     .Pointer to DFT block control word
nossegp  vfd,4,12,32 1,snnosmtr,0      .Pointer to NOS segment
mtrstp   address r,mst                 .Pointer to MTR SEG TABLE
mtrxpp   address r,mxp                 .pointer to mtr xp
mtrstk_p address r,mtrstak             .Pointer to first CPU MTR Stack
dpv$scd_block_p address r,asciiblk
pextiou  address r,extiou
pdpv$scd_time address r,dpv$scd_time
hnsk_p   address p,xhsk_p
endtbls  vfd,16,32    0ffff(16),080000000(16)   .Pointer to mainframe wired heap.
         align   0,8
debug0   bssz    16*8                  .Array of debug values.
.
.
.         The following is a cybil record.  Immediately after deadstart
.         the NOS system time and date and the free running clock value
.         are saved in this record.  During deadstart initialization these
.         values are converted to NOS/VE base system time.
.
         align   0,8
nos_tod  vfd,64  55333357333357333357(8) .NOS time of day (60 bits of display code)
nos_date vfd,64  55433450334350343657(8) .NOS date (60 bits of display code)
cor_frc  vfd,48  0                     .Free running clock corresponding to 'nos_tod'
nosve_bt vfd,8,8,8,8,8,16,48 0,0,0,0,0,0,0    .NOS/VE base time (sec,min,hr,d,m,y,FRC)
.
.         Define symbols to reference NOS date and time in NOS's field length.
.
nostod   equ     3421(8)               .NOS time of day address mask
nosdate  equ     1221(8)               .NOS date address mask
.
.        End of base system time record.
*IF $variable(mtv$test_due_pnd declared) <> 'UNKNOWN'
.
         align   0,8
fk_due   vfd,48  0                     .Time of last "fake" DUE
         def           fk_due
*ELSE
.
. ---------- Declaration code was omitted at compilation time ----------
*IFEND
.
.  Standalone deadstart data
.
nossf    vfd,4,12,32   1,snsfmtr,0     .PVA of nos stack frame in mtr mode
         defg          osv$boot_sdte
         defg          dsv$ssr_sdte
         defg          osv$boot
         defg          osv$boot_is_executing
         align         7,8
osv$boot      vfd,8     0
osv$boot_sdte vfd,64    0
dsv$ssr_sdte  vfd,64    0
osv$boot_is_executing vfd,8 0
.
         align   0,8
tracesiz equ     256                   .Number of trace entries per processor
                                       . (must be power of 2.
                                       . WARNING - TRACE macro must be changed
                                       . if TRACESIZ is changed.
trace    bssz    8*maxcst*(2+tracesiz) .Array to keep trace information
                                       .  of what happens in monitor. See
                                       .  the XTRACE macro.
dtrace   bssz    8*(tracesiz+2)        .Array for recording trace info while system
                                       .  is stepped or idle.
xpinitv  bss     xpsize                .Initial value for all job mode
.                                         exchange packages.
initmxp  bss     xpsize                .initial value of mtr xp.
.
.
.   Error mesasages displayed on error stop.
.
csthalt   vfd,248   c'HALTED VIA CST REQUEST         '
stepmes   vfd,248   c'STEPPED VIA CST REQUEST        '
cpudown   vfd,248   c'CPU FAILED WITH INTERLOCK SET  '
thetadue  vfd,248   c'FATAL: MTR DUE & TRAPS DISABLED'
masksync  vfd,248   c'MTR MASK OUT OF SYNC WITH TRAPS'
          page
.............................................................................
.  MONREQ  -  This proc is used to call a monitor request processor.
.                   monreq   rc, ring, returnadr
.                        rc         - request code, either constant or x-register
.                        ring       - ring number for request validation. Zero implies
.                                       no checking. (rc must be constant if ring = 0)
.                        returnadr  - label to return to. If not supplied, returns
.                                      to next instruction.
.             A pointer to the beginning of the stack frame is passed as the parameter
.             list pointer. NOTE: most procedures called with this macro expect the
.             second parameter to be a pointer to the current CST.
.
..............................................................................
.
         PROC
monreq   pname
         local    ex
f:(0)    bss     0
         do      sn:(f:(2,2))=0
           addpxq  a_rq_ret,x0,ex
         dend
         do      sn:(f:(2,2))/=0
           addpxq  a_rq_ret,x0,f:(2,2)
         dend
         do      sn:(f:(2,1))=sn:(0)
           addaq   a_rqtbl,a_root,reqtbl+rqtbles*f:(2,0)
           addaq   ae,a_bindin,16*f:(2,0)
         dend
         do      sn:(f:(2,1))/=sn:(0)
           shfx    f:(2,0),f:(2,0),x0,4
           cpyaa   ae,a_bindin
           addax   ae,f:(2,0)
           addaq   a_rqtbl,a_root,reqtbl
           addax   a_rqtbl,f:(2,0)
           shfx    f:(2,0),f:(2,0),x0,-1
           addax   a_rqtbl,f:(2,0)
           lbyts,1 f:(2,0),a_rqtbl,x0,rn
           brxge   f:(2,0),f:(2,1),rqproc
           addaq   a_rqtbl,a_root,reqtbl
           addaq   ae,a_bindin,16*rqunim
         dend
         brxeq   x0,x0,rqproc
ex      bss     0
         pend
         page
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. TRAKTEF - This macro enables/disables the MCR mask bit 49
.           (normally unused) to indicate to THETA models 40 - 44
.           what the current state of the trap register is.  This
.           is used as a software workaround for 'stop on error'
.           hardware found only on the THETA processor models
.           listed above.  On other models this information is
.           not used, even though the flag is tracked.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
         proc
traktef  pname
f:(0)    bss     0
         local   tf1,tf2
         ente    x2,m_mcrtef
         entl    x0,r_mm               .Get live register for mtr mask
         cpysx   x1,x0
         do      f:(2,0)=1             .Enable or Disable?
         iorx    x1,x2                 .Set the Traps_Enabled bit in the live
         else                          .  mtr mask
         inhx    x1,x2                 .Clear the Traps_Enabled bit in the live
         dend                          .  mtr mask
         cpyxs   x1,x0
         bss     0
         pend
.............................................................................
.  RQTABLE -  This macro generates monitor request table entries,
.             and binding section pointers. it also increments *MTRQMAX*
.             to indicate the maximum number of requests.
.               (see next page for definition of fields in macro)
..............................................................................
.
.      Define offsets into a request table entry.
.
rqtbles  equ     3*8                   .Size of request table entry.
rn       equ     0                     .Highest RN for the request
il       equ     1                     .Interlock ordinal
rc       equ     2                     .Request code
totalt   equ     1*8                   .Total time for the request
rqcntmax equ     2*8                   .Word with both max and count.
.                                         (max time = left, count = right)
         proc
rqtable  pname
         org     reqtbl+rqtbles*f:(2,0)
         vfd,8   f:(2,1)         .Highest ring number for the call
         vfd,8   f:(2,2)         .Interlock ordinal
         vfd,8   f:(2,0)         .Request code
         vfd,40  0
         bssz    24
.
         do      f:(2,0)>mtrqmax
mtrqmax  set     f:(2,0)
         dend
         org     reqtbl+mtrqmax*rqtbles+rqtbles
         use     binding
         do      sc:(f:(2,3))/=7
         ref     f:(2,3)
         dend
         address ce,f:(2,3)
         use     #lastsec
         pend
.
.   Initialize maximum requests to 0.
.
mtrqmax  set     0
.
.   Define fwa of binding section and reqtable pointers.
.
         use     binding
         def     bindsec
bindsec  bss     0
bs_rqtbl bss     0
         use     #lastsec
.
         page
..............................................................................
.                  MONITOR REQUEST TABLE
.
.    Each monitor request requires an entry in the following table
.    Each entry is specified as follows:
.         RQTABLE    NUM, HIGHRING, INTERLOCK_ORD, PROC
.              NUM - Request code number
.              HIGHRING - Highest ring number that can issue the request.
.                      (0 = request restricted to monitor only).
.              INTERLOCK_ORD - Specifies which interlock to use to serialize
.                     monitor requests on a dual CPU machine.
.                       (0 = no interlock)
.              PROC - Name of procedure to call to process the request.
.
.    NOTE: When making an entry in this table, the following changes also
.       have to be made:
.           1) Define the request code in the deck SYC$MONITOR_REQUEST_CODES
.           2) Add the request name to the table in CLM$DISPLAY_SYSTEM_DATA.
.           3) If no interlock is required to serialize monitor requests and
.              the called procedure sets some other serialization lock (for
.              example, TMV$PTL_LOCK), that OTHER serialization lock MUST BE
.              CHECKED in the procedure MTP$CHECK_FOR_FATAL_ERRORS in the
.              module MTM$PROCESSOR_CONFIGURATION_MGR.
.
..............................................................................
         align   0,32
reqtbl   bssz    0
         rqtable 0,15,1,tmp$process_unknown_req_fault
         rqtable 1,13,0,tmp$cycle
         rqtable 2,13,0,tmp$delay
         rqtable 3,0,0,tmp$process_unknown_req_fault
         rqtable 4,1,1,iop$io_processor
         rqtable 5,13,1,mmp$advise_request_processor
         rqtable 6,13,1,mmp$advise_request_processor
         rqtable 7,13,1,mmp$advise_request_processor
         rqtable 8,2,1,tmp$create_task
         rqtable 9,0,1,pr_pf
         rqtable 10,2,1,tmp$create_job
         rqtable 11,2,1,tmp$exit_job
         rqtable 12,13,1,mmp$free_flush
         rqtable 13,13,1,mmp$free_flush
         rqtable 14,1,1,mmp$mtr_change_segment_table
         rqtable 15,0,0,iop$check_active_pps
         rqtable 16,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 17,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 18,3,1,jsp$mtr_job_swapping_requests
         rqtable 19,3,0,mtp$mtr_step_unstep_system
         rqtable 20,0,1,tmp$process_task_mcr_fault
         rqtable 21,15,1,tmp$mtr_process_system_error
         rqtable 22,3,0,tmp$fetch_task_statistics
         rqtable 23,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 24,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 25,13,0,tmp$mtr_ready_task
         rqtable 26,3,0,tmp$mtr_set_system_flag
         rqtable 27,15,1,tmp$mtr_wait
         rqtable 28,1,1,mmp$mtr_lock_ring_1_stack
         rqtable 29,3,1,tmp$mtr_send_signal
         rqtable 30,1,1,mmp$mtr_set_get_segment_length
         rqtable 31,6,1,mmp$mtr_read_write_io
         rqtable 32,3,1,tmp$job_recovery_requests
         rqtable 33,1,1,mmp$mtr_ring1_segment_request
         rqtable 34,2,1,tmp$task_exit
         rqtable 35,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 36,3,1,tmp$mtr_update_job_task_enviro
         rqtable 37,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 38,13,1,mmp$mtr_lock_unlock_pages
         rqtable 39,13,1,mmp$mtr_lock_unlock_pages
         rqtable 40,13,1,mmp$mtr_fetch_pva_unwritten_pgs
         rqtable 41,1,1,dmp$mtr_allocate_front_end
         rqtable 42,1,1,dmp$mtr_deallocate_front_end
         rqtable 43,1,1,dmp$apply_mat_changes
         rqtable 44,1,1,iop$tape_queue_request
         rqtable 45,1,1,iop$translate_byte_address
         rqtable 46,3,1,cmp$monitor_routines
         rqtable 47,3,1,tmp$mtr_ready_system_task
         rqtable 48,13,1,mmp$mtr_lock_unlock_segment
         rqtable 49,3,1,dsp$issue_dft_request
         rqtable 50,13,1,mmp$mtr_wait_io_completion
         rqtable 51,0,0,tmp$switch_task
         rqtable 52,0,0,mtp$process_short_warning
         rqtable 53,0,0,mtp$monitor_system_status
         rqtable 54,0,1,iop$process_io_completions
         rqtable 55,3,0,dpp$display_request
         rqtable 56,0,0,dpp$process_scd_block
         rqtable 57,3,1,osp$process_job_keypoint_req
         rqtable 58,0,1,mmp$periodic_call
         rqtable 59,0,0,mtp$process_due
         rqtable 60,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 61,0,1,jsp$swap_polling
         rqtable 62,0,0,mtp$process_170_mtr_requests
         rqtable 63,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 64,1,1,iop$request_processor
         rqtable 65,3,0,dsp$access_logging_data
         rqtable 66,0,0,dsp$process_dft_entry
         rqtable 67,3,1,jmp$mtr_job_scheduler_requests
         rqtable 68,1,1,mmp$mtr_fetch_offset_mod_pages
         rqtable 69,13,1,mmp$process_assign_pages_req
         rqtable 70,13,1,mmp$free_flush
         rqtable 71,1,1,rfp$queue_data_fragments
         rqtable 72,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 73,3,1,dfp$mtr_file_server_request
         rqtable 74,6,1,mmp$process_move_pages_request
         rqtable 75,3,1,mmp$process_assign_contig_mem
         rqtable 76,1,1,dmp$mtr_reallocate_front_end
         rqtable 77,1,1,mmp$mtr_r1_server_seg_request
         rqtable 78,1,1,mtp$process_cpu_state_change
         rqtable 79,3,1,sfp$mtr_stats_facility_requests
         rqtable 80,3,1,dsp$mtr_manage_system_ds_status
         rqtable 81,3,1,jmp$update_serv_class_stats_req
         rqtable 82,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 83,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 84,0,0,tmp$process_unknown_req_fault  .FREE
         rqtable 85,3,0,mtp$inject_hardware_fault
         rqtable 86,1,1,mmp$quick_sweep
         rqtable 87,1,0,tmp$mtr_ready_task_list
         page
..............................................................................
.  Define the interlock array.  Initially only one lock word
.  is used by the various request processors.
.      One word per entry, word 0 not used.
.            bit 0     0 = lock clear, 1 = lock set
.            bit 32 - 63 = CST offset of CPU that has lock set.
.
. NOTE: If this record changes, be sure to make corresponding changes to the
. CYBIL record declaration MTT$REQUEST_INTERLOCK_TABLE.
..............................................................................
.
.      Define offsets into interlock table.
.
maxilo   equ     6                     .Array size is 0..5
ilsize   equ     8                     .Size of interlock table entry.
ilflag   equ     0                     .Interlock flag
lockcp   equ     2                     .^CST of locking cpu
rinfo    equ     8                     .Recovery information.
.
.
.
         align   0,8
il_tbl   bssz    maxilo*ilsize         .Interlock array.
         page
..............................................................................
.      Define  request codes for requests issued internally by monitor.
.          These request codes must match the values defined in
.          SYC$MONITOR_REQUEST_CODES.
.        NOTE: only requests actually used by monitor are defined here.
..............................................................................
.
rqunim   equ     0                     .Unimplemented request code
rqpf     equ     9                     .Code for PAGE FAULT.
check_pp equ     15                    .iop$check_active_pps
rqfault  equ     20                    .Code for MCR/UCR faults.
tsksw    equ     51                    .task switch
pswarn   equ     52                    .process short warning
mon_smu  equ     53                    .monitor_smu_status
proc_io  equ     54                    .process_io_completions
ascii_kb equ     56                    .process ascii keyboard
per_call equ     58                    .periodic_call
proc_due equ     59                    .process_due
swap_job equ     61                    .poll job swapping
mm_ei    equ     62                    .process_170_mtr_requests
proc_dft equ     66                    .process DFT block
proc_cpu equ     78                    .process_cpu_state_change
qs_call  equ     86                    .quick_sweep
         page
..............................................................................
. Define entry points into this module and the External names
. of the entry points
..............................................................................
         defg    rlock1
         defg    rlock2
         defg    rlock3
         defg    asylock
         defg    haltring,systemhr
         defg    mmtime,nostime
         defg    qstime
         defg    alltime
         defg    no_stop
         def     swaptime,scbtime
         defg    sitvalue,fltinj
         defg    dpv$scd_block_p
         def     mtv$idle_message_line
         def     dpv$scd_time
         defg    extiou
         def     mtrprior
         def     nosxp
         def     nosjps
         defg    nostab
         defg    bct_pva
         def     trace,dtrace
         def     nossegp
         defg    kcb_rma
         defg    nosve_bt,nos_tod,mlist
         defg    endtbls,memlimit,cst0
         defg    xpinitv,os_type,scb,scbvec
         def     os_terms
         defg    reqtbl
         def     il_tbl
         defg    multpro
         def     eiflag
         defg    lockwait
         def     sjmtrxcb
         defg    debug0
         defg    intport
         def     asyntime,asyntime
         defg    num_proc
         defg    initmxp
         def     mtrstk_p
         defg    osv_bl
         def     idle,async,exchloop,rqproc,extrq,traprtn
         def     int,nossegt
         defg    cpus_on
         defg    num_cst
         defg    mstacklx
         def     mtvdftb
         defg    heap_tr
         defg    heap_ver
         defg    ve_int
         defg    p_mode
         defg    nosve_bt
         defg    xajl
         defg    cpu1nos
heap_tr  ALIAS   syv$enable_heap_trace
heap_ver ALIAS   syv$verify_heap_linkage
ve_int   ALIAS   syv$nosve_internal_operations
p_mode   ALIAS   mtv$processor_mode
cpu1nos  ALIAS   MTV$CPU1_DEDICATED_TO_NOS
no_stop  ALIAS   mtv$no_stop
xajl     ALIAS   mtv$executing_ajl_at_failure
initmxp  ALIAS   OSV$INITIAL_MONITOR_XP
mtrstk_p ALIAS   mtv$first_cpu_monitor_stack_p
fltinj   ALIAS   syv$enable_fault_injection
mstacklx ALIAS   osv$monitor_stack_length
num_cst  ALIAS   osv$maximum_cst_tables
num_proc ALIAS   osv$cpus_physically_configured
cpus_on  ALIAS   osv$cpus_logically_on
lockwait ALIAS   osv$monitor_interlock_wait_time
sjmtrxcb ALIAS   mtv$system_job_monitor_xcb_p
eiflag   ALIAS   osv$external_interrupt_time
intport  ALIAS   osv$external_interrupt_selector
asyntime ALIAS   OSV$TIME_TO_CHECK_ASYN
asyninc  ALIAS   OSV$RATE_TO_CHECK_ASYN
multpro  ALIAS   OSV$MULTIPROCESSOR_RUNNING
debug0   ALIAS   osv$debug
mtrprior ALIAS   OSV$MONITOR_PRIORITY
reqtbl   ALIAS   MTV$REQUEST_TABLE
il_tbl   ALIAS   mtv$request_interlock_table
xfrc_p   ALIAS   TMV$TIME_TO_CALL_DISPATCHER
         ref     xfrc_p
xhsk_p   ALIAS   DSV$CPU_PP_COMMUNICATION_BLOCK
         ref     xhsk_p
nosjps   ALIAS   MTV$NOS_JPS
sitvalue ALIAS   OSV$DEFAULT_SIT_VALUE
os_type  ALIAS   OSV$170_OS_TYPE
os_terms ALIAS   OSV$170_OS_TERMINATION_STATUS
nossegp  ALIAS   MTV$NOS_SEG_P
nostime  ALIAS   MTV$TOTAL_NOS_CPU_TIME
haltring ALIAS   MTV$HALT_CPU_RING_NUMBER
systemhr ALIAS   MTV$SYSTEM_HALTRING
extiou   ALIAS   OSV$IOU_EXTERNAL_INTERRUPT
mtvdftb  ALIAS   mtv$dft_block_p
scb      ALIAS   MTV$SCB
scbvec   ALIAS   MTV$SCB_VECTOR_SIM_ATTRIBUTE
nosxp    ALIAS   MTV$NS_XP_P
nostab   ALIAS   MTV$NST_P
bct_pva  ALIAS   DSV$BOOT_CONTROL_TABLE_P
nossegt  ALIAS   MTV$NOS_SEGMENT_TABLE_P
dtrace   ALIAS   MTV$DUMMY_TRACE_BUFFER
trace    ALIAS   MTV$TRACE_BUFFER
osv_bl   ALIAS   osv$build_level
ENDTBLS  ALIAS   OSV$MAINFRAME_WIRED_HEAP
memlimit ALIAS   OSV$180_MEMORY_LIMITS
MMTIME   ALIAS   MMV$TIME_TO_CALL_MEM_MGR
QSTIME   ALIAS   MMV$TIME_TO_CALL_QUICK_SWEEP
scbtime  ALIAS   MTV$TIME_TO_CHECK_SCB_STATUS
asylock  ALIAS   MTV$ASYNC_LOCK
rlock1   ALIAS   MTV$RECOVERY_LOCK1
rlock2   ALIAS   MTV$RECOVERY_LOCK2
rlock3   ALIAS   MTV$RECOVERY_LOCK3
alltime  ALIAS   MTV$MAX_ASYNC_LOCK_TIME
CST0     ALIAS   MTV$CST0
XPINITV  ALIAS   MTV$XP_INITIAL_VALUE
kcb_rma  ALIAS   syv$pmf_cb_rm_word_address
ROOT     ALIAS   MTV$ROOT
BEGIN    ALIAS   MTP$BEGIN
BINDSEC  ALIAS   MTV$BINDING_SECTION
NOSVE_BT ALIAS   OSV$BASE_SYSTEM_TIME
NOS_TOD  ALIAS   SYV$NOS_SYSTEM_TIME
MLIST    ALIAS   MTV$MLI_STATUS
SWAPTIME ALIAS   JSV$TIME_TO_CALL_JOB_SWAPPER
.
.  The following are XDCLed so that the KEYPOINT analyzer can determine which
.  part of this module is executing when analyzing KEYPOINT files. If any changes
.  are made to these names or to the RELATIVE positions of the routines, the
.  KEYPOINT analyzer must be changed.
.
ASYNC    ALIAS   MTP$CHECK_ASYNC_ACTIVITY
IDLE     ALIAS   MTP$MONITOR_IDLE_LOOP
EXCHLOOP ALIAS   MTP$PROCESS_JOB_EXCH_REQ
TRAPRTN  ALIAS   MTP$TRAP_HANDLER
RQPROC   ALIAS   MTP$CALL_MONITOR_REQUEST
EXTRQ    ALIAS   MTP$PROCESS_EXTERNAL_INTERRUPT
         page
..............................................................................
.
.   Define Stack Segment and exchange packages for monitor mode.
.   The monitor exchange packages and segment table are located at
.   the beginning of the monitor stack.
.
..............................................................................
mstackl  equ     xpsize+(mstlen+ajllen+1)*8+mstksize
mts$monitor_stack SECTION extwork,read+write,,0,8,mstackl
         use     mts$monitor_stack
         def     mtrstak,mst
         defg    mxp
bgnstak  bss     0
mxp      bssz    xpsize
mst      bssz    mstlen*8+ajllen*8+8
mtrstak  bss     mstksize
mtrstake bss     0
         xpa     mxp,2,begin
         xpa     mxp,xptos,mtrstak,0
         xpareg  mxp,a_tos,mtrstak,mstkfram
         xpareg  mxp,a_csf,mtrstak,0
         xpareg  mxp,a_psa,nil
         xpareg  mxp,a_bindin,bindsec
         xpareg  mxp,a_root,root,0
         xpareg  mxp,5,nil
         xpareg  mxp,6,nil
         xpareg  mxp,7,nil
         xpareg  mxp,8,nil
         xpareg  mxp,9,nil
         xpareg  mxp,10,nil
         xpareg  mxp,11,nil
         xpareg  mxp,12,nil
         xpareg  mxp,13,nil
         xpareg  mxp,14,nil
         xpareg  mxp,15,nil
         xpv     mxp,xpstal,mst-bgnstak,16 .Segment table address
         xpv     mxp,xpstl,mstlen+ajllen,16 .Segment table length
         xpv     mxp,xpmm,m_mtrmsk,16  .Monitor mask
         xpv     mxp,xpum,m_usrmsk,16  .User mask
         xpv     mxp,xpkm,0,16
         xpv     mxp,xppit,0ffff(16),16  .Monitor PIT
         xpv     mxp,xppit+8,0ffff(16),16
         xpv     mxp,xplrn,1,16
         xpa     mxp,xptp,bs_trap,0
         xpv     mxp,xpflgte,00000(16),16
         xpv     mxp,xpbc2,cst0,16
         xpv     mxp,248,cst0,32  .Set offset and length of CST0 into XE
         xpv     mxp,252,cstsize,32
         org     mtrstake
mxp      alias   MTV$MONITOR_EXCHANGE_PACKAGE
mst      alias   MTV$MONITOR_SEGMENT_TABLE
         page
..............................................................................
.
.   Define Binding Section
.       (note - the RQTABLE macro puts entries here also)
..............................................................................
         USE     BINDING
.
         def     bs_trap
BS_TRAP  ALIAS   MTV$TRAP_CBP
bs_trap  address ce,traprtn                 .Used for monitor XP trap ptr.
bs_root  address p,root
.
         ref     MTP$ERROR_STOP
         ref     MTP$MTR_ERROR_STOP
         ref     OSP$PROCESS_MTR_PAGE_FAULT
         ref     TMV$PTL_LOCK
.
bs_errst address c,MTP$ERROR_STOP
bs_merrs address c,MTP$MTR_ERROR_STOP
bs_pgflt address ce,OSP$PROCESS_MTR_PAGE_FAULT
bs_ptlok address p,TMV$PTL_LOCK
         page
..............................................................................
.
.   BOOT - Execution at deadstart starts here. Save a copy of the job
.          XP, reset the clock, and jump to the location that exchanges
.          to job mode.
..............................................................................
.
         USE     CODE
         def     begin
begin    bss     0                     .This is where execution begins
         ente    x0,63(16)             .Initialize KBP register
         isom    x1,x0,2020(8),x0      .NOT CORRECT FOR MULTIPROCESSOR
         cpyxs   x1,x0                 .Need to do in every processor
         ente    x0,r_bc
         cpysx   x1,x0                 .Get  base constant.
         cpyax   x2,a_root
         addx    x1,x2                 .Form pointer to cst
         cpyxa   a_cst,x1
         sa      a_cst,a_csf,10        .Save CST_P for p-list.
         entl    x0,r_eid              .Save EID in CST.
         cpysx   x0,x0
         sx      x0,a_cst,elem_id
         entp    x0,0                  .Start cache and map purging
         sx      x0,a_cst,cachtim
         sx      x0,a_cst,maptim
         traktef 0                     .Clear the Traps_Enabled bit in MCR mask
         lx      x1,a_root,dscpu       .Check if this is first CPU.
         brxne   x1,x0,begin5          .Jump if not first CPU.
.
.   The following is initialization code executed ONLY on the first CPU to start.
.
         entl    x0,r_eid              .Check element id to turn off DUE
         cpysx   x1,x0                 .  mask bit on CYBER 2000
         isob    x1,x1,x0,(40*64+7)    .High order 7 bits of model number
                                       .  from element id
         ente    x2,46(16)             .CYBER 2000 Model 46
         brreq   x1,x2,begin1_a
         incx    x2,2                  .CYBER 2000 Model 48
         brreq   x1,x2,begin1_a
         brreq   x0,x0,begin1_b
.
begin1_a entl    x0,r_mm               .Get live register for mtr mask
         cpysx   x1,x0                 .Clear the due bit in the live
         ente    x2,m_mcrdue           .mtr mask for CYBER 2000
         inhx    x1,x2
         cpyxs   x1,x0
.
begin1_b sx      xd,a_root,osv$boot_sdte
         ente    x1,1000(16)+mstlen    .Set up pointer to system jobmonitor
         shfx    x1,x1,x0,32           .  XCB.
         addxq   x1,x1,jr_mxcb
         cpyxa   a_xcb,x1
         entp    x1,1
         sbyts,1 x1,a_root,x0,osv$boot
.
         la      a_dscb,a_root,nostab  . Build pointer to the dscb
         addax   a_dscb,xf

         lbyts,1 x1,a_dscb,x0,dscb_tef . Get the first byte of the D8ST
                                       . field of dual state control block
         ente    x2,2                  . Set bit to let DFT know about
         iorx    x1,x2                 .   THETA Trap code version
         sbyts,1 x1,a_dscb,x0,dscb_tef . Replace the first byte of the D8ST
.
         la      ae,a_root,mtrstp      . Update NOS st from mtr st
         la      af,a_root,nossegt
         lbyts,8 x1,ae,x0,snnthmtr*8
         sbyts,8 x1,af,x0,snnth170*8
         lbyts,8 x1,ae,x0,snsfmtr*8
         sbyts,8 x1,af,x0,snsf170*8
         sbyts,8 x1,a_root,x0,dsv$ssr_sdte  . Tell job mode the STE of SSR
         lbyts,8 x1,ae,x0,12(16)*8
         sbyts,8 x1,af,x0,12(16)*8
.
         sa      a_xcb,a_cst,xcbp      .Store xcb pointer in CST.
         tpage   x1,a_xcb              .Save RMA of XCB in CST.
         sx      x1,a_cst,xcbrma
         entl    x0,r_jps              .Update JPS.
         cpyxs   x1,x0
         tpage   x1,a7
         la      ad,a_root,nostab      .FWA of NOS field length.
         sa      a_dscb,a_root,nostab  .Save dscb pointer
         cpytx   x1,x1                 .Reset time task began execution.
         sx      x1,a_root,scb+scbnsrv
         entl    x0,r_eid
         sx      x1,a_root,dscpu       .Set time of CPU initialization.
         cpysx   xe,x0                 .Save element id.
         entp    x6,5                  .High order 4 bits of S0 model number.
         isob    xe,xe,x0,(40*64+3)    .High order 4 bits of model number from
                                       . element id.

.  Set up memory and interrupt port mask based on processor.

         lbyts,1 x1,a_cst,x0,memport   .Memory and interrupt port mask for non S0
         brrne   xe,x6,begin2_5        .Jump if not an S0.
         incr    x1,3                  .If S0, change port 0 (int sel = 1) to a 4,
         entp    x2,4                  .  port 1 (int sel = 4) to an 8.
         brxeq   x1,x2,begin2_5        .If cpu 0, then 4 is the right answer,
         entp    x1,8                  .  otherwise 8 is the answer.
begin2_5 bss     0
         sbyts,1 x1,a_cst,x0,memport   .Set up port number mask for ext interrupts.
         sbyts,1 x1,a_root,x0,intport
         lx      xe,a_root,ve_vrsn     .ve os type, dscb version/level
         sx      xe,a_dscb,d8ty        .Save in block
.
.    Set the NOS/VE memory limits.  Both upper bounds are set to the RMA of
.    the SSR.  The deadstart upper bound may be reset before first page fault
.    based on the image size.
.
         lx      x1,a_dscb,d7cm+8      .Fetch memory limits
         isob    xe,x1,x0,(64-48)*100(8)+24-1  .Isolate ve fwa DIV 10000(8)
         shfx    xe,xe,x0,12
         sbyts,4 xe,a_root,x0,memlimit
         la      ae,a_root,nossf               .Set upper bounds to the SSR RMA
         tpage   xe,ae
         sbyts,4 xe,a_root,x0,memlimit+8       .Upperbound.
         sbyts,4 xe,a_root,x0,memlimit+4       .Upperbound during deadstart.
.
.   Fetch and store pointer to the DFT block
.     r_pointer: offset, r_upper, r_lower, size
.     rma of r_pointer = r_upper*10000000(8) + r_lower*1000(8) + offset*10(8)
.
         lbyts,2 x6,a_dscb,x0,dscm+3*8+2 .Load r_upper into x6
         shfx    x6,x6,x0,7*3            .Shift: r_upper * 10000000(8)
         lbyts,2 xb,a_dscb,x0,dscm+3*8+4 .Load r_lower into xb
         shfx    xb,xb,x0,3*3            .Shift: r_lower * 1000(8)
         addx    x6,xb                   .Add r_lower to r_upper
         lbyts,2 xb,a_dscb,x0,dscm+3*8+0 .Load offset into xb
         shfx    xb,xb,x0,1*3            .Shift: offset * 10(8)
         addx    x6,xb                   .Add offset to (r_upper + r_lower)
         entp    xb,sn170mcb
         sa      a_dscb,a_root,mtvdftb   .Save base ptr: ring and segment
         sbyts,1 xb,a_root,x0,mtvdftb+1  .Set cache bypass segment number for
                                         . DFT buffer.
         sbyts,4 x6,a_root,x0,mtvdftb+2  .Store dft offset in ptr
.
         entp    x0,0
         lx      xe,a_dscb,d7ty        .Determine STATE
         isob    x1,xe,x0,5605(8)
         sbyts,1 x1,a_root,x0,os_type

         la      ae,a_root,eicb        .Load EICB Pointer
         isob    x2,xe,x0,nostod       .Isolate time of day pointer
         isob    xe,xe,x0,nosdate      .Isolate date pointer
         lxi     x2,ad,x2,0            .Time of day (display code)
         lxi     xe,ad,xe,0            .Date (display code)
         cpytx   x1,x0                 .Free running clock
         sx      x2,a_root,nos_tod
         sx      x2,a_root,nos_date
         sbyts,6 x1,a_root,x0,cor_frc

.
.        IF THIS IS CYBER 2000,
.        Clear the monitor mode monitor mask bit 48 of the monitor
.        exchange package and bit 48 in the monitor mask register, and
.        clear the monitor mode monitor mask bit 48 of the job mode monitor
.        mask bit 48 of the job exchange package.
.
begin4   ente    x6,0                  .Init register to 0 to use for due bit
                                       .If CYBER 2000 use reg to clear mtr mask
         sx      x6,a_root,no_stop     .Initialize the DUE stop flag
         entl    x0,r_eid              .Check element id to turn off due
         cpysx   x1,x0                 .mask on CYBER 2000
         isob    x1,x1,x0,(40*64+7)    .High order 7 bits of model number
                                       .from element id
         ente    x2,46(16)             .CYBER 2000 Model 46
         brreq   x1,x2,begin4_a
         incx    x2,2                  .CYBER 2000 Model 48
         brreq   x1,x2,begin4_a
         brreq   x0,x0,begin4_b
begin4_a ente    x6,m_mcrdue           .Save the due bit for CYBER 2000
.
begin4_b addaq   af,a_root,xpinitv     .Save the job exchange package
         lbyts,2 x1,a_xcb,x0,xpmm      .Get the mtr mask in the job xp
         inhx    x1,x6                 .Inhibit due bit if CYBER 2000
         sbyts,2 x1,a_xcb,x0,xpmm      .Store mtr mask in the job xp
         movb,a_xcb,x0 af,x1 0,9,255,0 0,9,255,0
         movb,a_xcb,x0 af,x1 0,9,xpsize-255,255 0,9,xpsize-255,255
.
.        Clear the monitor mode monitor mask bit 49 of the monitor
.        exchange package and bit 49 in the monitor mask register.
.
         traktef 0                     .NO-OP; trap bit already disabled
         iorx    x6,x2                 .  X2 = m_mcrtef; "OR" with DUE bit
                                       .  (if there is one) in X6
         la      ae,a_root,mtrxpp      .move original xp to
         addaq   af,a_root,initmxp     .mainframe wired.
         lbyts,2 x1,ae,x0,xpmm         .Get the mtr mask in the mtr xp
         inhx    x1,x6                 .Inhibit TEF bit on all models,
                                       .  inhibit due bit if CYBER 2000
         sbyts,2 x1,ae,x0,xpmm         .Store mtr mask in the mtr xp
         movb,ae,x0 af,x1 0,9,255,0 0,9,255,0
         movb,ae,x0 af,x1 0,9,xpsize-255,255 0,9,xpsize-255,255
         entl    x0,r_jps              .Save current JPS in CST.
         cpysx   x0,x0
         sx      x0,a_cst,xcbrma
         brxeq   x0,x0,begin22
.
.    The following code is initialization code for all cpus EXCEPT the first.
.
begin5   bss     0
         la      a_dscb,a_root,nostab  .Pointer to interface block
         entp    x1,1
         sbyts,1 x1,a_cst,x0,caldisp   .Call dispatcher.
.
.    Complete processor initialization for ALL processors.
.
begin22  lx      x1,a_root,sitvalue    .Reset SIT.
         entl    x0,r_sit
         cpyxs   x1,x0
         entp    x0,0
         sbyts,1 x0,a_cst,x0,cpu_stat  .Set cpu status running
         entl    x0,0                  .Get the current free running clock.
         cpytx   x2,x0                 .
         sx      x2,a_cst,cpwell       .Update cpu alive flag.
         sx      x2,a_root,qstime      .Initialize quick sweep time to now.
         entp    x0,1
         sbyts,1 x0,a_root,x0,multpro  .Set osv$multiprocessor_running to TRUE.
         traktef 1                     .Enable TEF mask bit
         entl    x0,r_te               .Enable traps
         cpyxs   x0,x0
         page
..............................................................................
.  Check Interrupt/Dispatch Flags - (TOP OF MAIN LOOP)
.     Control comes here when the 'dispflag' in the CST is set. This code processes
.     asynchronous conditions (such as IO completions and periodic conditions).
.     The task switch routine is called if the 'call dispatcher' flag in the CST is set.
..............................................................................
.
intdislp bss     0                     .Begin of interrupt-dispatch-loop.
         entl    x0,r_pit              .Save monitor clock.
         cpysx   x_clock,x0
.
.  Process asynchronous interrupts (EXT INT, Console input, Memory manager,
.            Job swapper, etc.)
.
async    entl    x0,0                  .Check if time to check async
         cpytx   x2,x0                 .  activities.
         lx      x1,a_root,asyntime    .Get time of next async activity.
         sbyts,1 x0,a_cst,x0,asyncp    .Clear async flag in CST.

         sx      x2,a_cst,cpwell       .Update cpu alive flag.

         brxge   x1,x2,tswit           .Jump if not time for async activity.

. ****** The next two lines are inactive ******.

.        lbyts,1 xf,a_root,x0,rlock1   .Check CPU Recovery lock level 1.
.        brxne   x0,xf,tswit           .Skip other checks if set.
.                                      . just sort of idle while waiting.
         lbyts,1 xf,a_cst,x0,ext_int   .Check external interrupt flags in cst.
         brxeq   xf,x0,async2          .Jump if no external interrupt flags.
         addpxq  a_extret,x0,async1    .Set up return from ext int processor.
         brxgt   xf,x0,extrq           .Process external interrupts.
async1   entl    x0,0                  .Restore X0 and X2--call to extrq
         cpytx   x2,x0                 .  changed them.

                                       . I moved the next statement here to
                                       . prevent a DFT, negative SIT condition
                                       . it used to reside after the lock check.


 .       sx      x2,a_root,scb+scbnsrv .Update '180 alive' flag.

async2   addaq   ae,a_root,asylock
         lbset   x1,ae,x0              .Test and set lock
         brrgt   x1,x0,tswit           .Jump if another processor is already
 .                                        processing asynchronous work.
         sx      x2,a_root,scb+scbnsrv .Update '180 alive' flag
         lx      x1,a_root,asyninc     .Update time to next check async.
         lx      xe,a_root,eiflag      .Fetch ext interrupt flag.
         addx    x1,x2
         sx      x1,a_root,asyntime
         brxgt   xe,x2,async6          .Jump if no ext interrupts to process.
         lx      x1,a_root,eiinc
         la      ae,a_root,pextiou
         entl    x0,0
         addx    x1,x2
         sx      x1,a_root,eiflag      .Set new value of clock + increment.
         sx      x0,ae,0               .Clear IOU address
         monreq  proc_io
         entp    x2,0
         cpytx   x2,x2
.
async6   la      ae,a_root,pdpv$scd_time
         lx      x1,ae,0               .Test if time to call keyboard rtn.
         brxgt   x1,x2,async8          .Jump if not time
         monreq  ascii_kb
         entp    x2,0
         cpytx   x2,x2
.
async8   la      ae,a_root,mtvdftb     .Fetch pointer to DFT block.
         lx      x1,ae,dftcw           .Get DFT control word.
         shfx    x1,x1,x0,62           .Check E8 field.
         brxge   x1,x0,async12         .Jump if not set.
         monreq  proc_dft              .NOTE!! May exit with E8 still set.
         entp    x2,0                  .  If so, recall in a few hundred
         cpytx   x2,x2                 .  milliseconds.
.
async12  lx      x1,a_root,scbtime     .Check if time to look at SCB status.
         brxge   x1,x2,async15         .Jump if SCB check not required.
         lbyts,1 xf,a_root,x0,rlock2      .Check CPU Recovery level 2
         monreq  mon_smu
         brxne   x0,xf,async15         .Dont check pps if lock set
         monreq  check_pp              .iop$check_active_pps
         entp    x2,0
         cpytx   x2,x2
.
async15  lx      x1,a_root,swaptime    .Check if time to call job swapper.
         brxge   x1,x2,async20         .Jump if job swapper call not needed.
         monreq  swap_job
         entp    x2,0
         cpytx   x2,x2
.
async20  lx      x1,a_root,mmtime      .Check if time to call Mem Mgr.
         brxge   x1,x2,async21         .Jump if Mem Mgr call not needed.
         monreq  per_call
         entp    x2,0
         cpytx   x2,x2


async21  lx      x1,a_root,qstime      .Check to see if quick sweep needed.
         brxge   x1,x2,async50         .Jump if not needed.
         monreq  qs_call
         entp    x2,0
         cpytx   x2,x2

.
async50  entl    x0,0
         sbyts,1 x0,a_root,x0,asylock  .Clear lock
         brreq   x0,x0,async           .Check for more work before exiting
.
.  Call the task switch routine if necessary.
.     (NOTE - the following is similar to MONREQ/RQPROC but is inline for
.             performance.)
.
tswit    lx      x1,a_cst,discntl      .Check if task switch required.
         la      a_xcb,a_cst,xcbp      .XCB will be NIL if task exited!
         shfx    x1,x1,x0,-32
         cpyax   xe,a_xcb              .XE must have XCB adr if branch to tsckpr.
         brxeq   x1,x0,tsckpr          .Jump if task switch not needed.
         brrgt   x0,xe,tswit4          .Jump if NIL XCB (processor idle).
         lbyts,2 x1,a_xcb,x0,xppit     .Calculate JOB MODE time
         lbyts,2 x2,a_xcb,x0,xppit+8
         lx      xf,a_cst,jtime
         shfx    x1,x1,x0,16
         addx    x2,x1
         ents    x2                    .Sign extend job mode time
         subx    xf,x2
         sx      xf,a_cst,jtime
         isom    x1,x0,4037(8)         .Save monitor mode time in CST.
         subx    x1,x_clock
         sx      x1,a_cst,mtime
tswit4   addaq   a_rqtbl,a_root,reqtbl+rqtbles*tsksw
         addaq   ae,a_bindin,16*tsksw
         entl    x0,r_pit
         cpysx   x2,x0                 .Get current PIT
         cpyaa   af,a_csf
         ente    x0,x_envir1           .Process the request
         callseg bs_rqtbl,ae,af
         lx      xe,a_rqtbl,totalt     .Update total and max time
         lx      xd,a_rqtbl,rqcntmax
         entl    x0,r_pit
         cpysx   xf,x0                 .Calculate time to process the request
         subx    x2,xf
         addx    xe,x2
         sx      xe,a_rqtbl,totalt
         incr    xd,1
         lx      xf,a_root,cmax        .Fetch maximum stat count.
         cpyrr   x1,xd
         subx    x1,xf
         brrgt   x0,x1,tswit41         .Less than max.
         ente    x1,0
         cpyrr   xd,x1                 .Reset request count value.
tswit41  shfc    xe,xd,x0,32           .Check if new maximum time.
         brrge   xe,x2,tswit5          .  Jump if not new max.
         cpyrr   xe,x2
         shfc    xd,xe,x0,32
tswit5   lx      x1,a_cst,cptime       .Get tasks timeslice.
         la      a_xcb,a_cst,xcbp      .Reload pointer to current XCB.
         sx      xd,a_rqtbl,rqcntmax
         isom    x_clock,x0,4037(8)    .Reset monitor clock.
         entl    x0,r_sit              .Reset SIT.
         cpyxs   x1,x0                 .Copy timeslice to SIT.
         entp    x1,0                  .Reset CST fields -
         sbyts,4 x1,a_cst,x0,discntl   .Clear task switch control flags.
         sx      x1,a_cst,mtime        .  monitor mode time
         cpyax   xe,a_xcb              .!! XCB adr must be in XE for TSCKPR.

         lbyts,1 xf,a_cst,x0,lpid      .Save the XCB pointer for next recovery
         shfc    xf,xf,x0,3
         lbyts,1 xd,a_cst,x0,ajlo      .Get the ajl ordinal that is running
         sbyts,8 xd,a_root,xf,p_mode   .to determine executing jobs.

         brrgt   x0,xe,tswit8          .Skip next part if XCB is NIL.

. The following "process not damaged" code is commented
. out until I determine what I really want to do.

.
. Force the "Process Not Damaged" flag to  true since we have
. seen no DUE up to this point. This will ensure that the flag is
. set when we reenter the job.
.
.        lbyts,1 x1,a_xcb,x0,xpflgte   .Load Process not Damaged flag
.        ente    x2,m_pdf              .flag bit
.        iorx    x1,x2                 .Force the flag to TRUE
.        sbyts,1 x1,a_xcb,x0,xpflgte      .Save the new flag value in the XCB
.
. End of Process Damaged code.


         lbyts,2 x1,a_xcb,x0,xppit     .Reset JOB MODE time
         lbyts,2 x2,a_xcb,x0,xppit+8
         shfx    x1,x1,x0,16
         addx    x2,x1
         ents    x2                    .Sign extend
         sx      x2,a_cst,jtime
         tpage   x1,a_xcb              .Save RMA of XCB in CST.
         sx      x1,a_cst,xcbrma
         entl    x0,r_jps              .Update JPS.
         cpyxs   x1,x0
tswit8   bss     0
         xtrace  5,x1,x2,xd,ae
.
.
tsckpr   bss     0
         brrgt   x0,xe,tsckpr3         .Jump if 180 is idle.
         brxeq   x0,x0,async90
.
tsckpr3  lx      x1,a_cst,discntl      .Go to async if flags are set.
         brxne   x1,x0,async
         lbyts,1 x2,a_cst,x0,nextstat  .Test if CPU is being turned off/down.
         brxne   x2,x0,idle            .  Go to idle loop if being turned off/down.
         lbyts,1 x2,a_root,x0,rlock1   . See if we are to skip task activation
         brxne   x2,x0,idle            .  if so, go idle.


tsckpr5  traktef 1                     .Enable TEF mask bit
         entl    x0,r_te               .Enable traps                            ).
         cpyxs   x0,x0
         cpyax   x2,a_xcb              .Test for idle system.
         brrgt   x2,x0,async90         .Run user task if system not idle.
         lx      x1,a_cst,discntl      .Cycle the loop if task switch/async.
         brxne   x1,x0,async
.
.  Idle if no 180 task was found ready.
.
idle     bss     0
         ente    x2,7                  .Set the "no stop" on DUE flag
         sx      x2,a_root,no_stop
         entl    x0,r_mm               .Get the monitor mask
         cpysx   x1,x0                 .Disable asynchronous traps
         ente    x2,(m_mcrasy+m_mcrsw) . and short_warning
         inhx    x1,x2
         cpyxs   x1,x0
idle3    bss     0
         lbyts,1 x1,a_cst,x0,nextstat  .Check the next_state of this CPU
         brxeq   x1,x0,idle4           .If state <> ON THEN CPU state changed
         ente    x0,x_envir1           .Set up call to mtp$process_cpu_state_change
         cpyaa   af,a_csf
         addaq   ae,a_bindin,16*proc_cpu
         callseg bs_rqtbl,ae,af        .Call mtp$process_cpu_state_change
idle4    enta    x0,40018(16)          .Kill some time by doing a
         shfx    x0,x0,x0,44           . double precision divide
         entp    x1,0
         divd    x0,x0
idle5    addpxq  a_extret,x0,idle5     .Branch if EXT INT is set - return
         brcr    8,0,extrq             .  to retest again - loop til no EXT INT
         lx      x1,a_cst,discntl      .Exit when flags are set
         brxne   x1,x0,idle10
         addpxq  a_sitret,x0,idle5
         brcr    11,0,prsit            .Branch if SIT is set - return to idle5.
         brcr    2,2,idle10            .Fall out if short_warning is set.
         lbyts,1 x1,a_cst,x0,caldisp   .Exit idle loop if call_dispatcher
         brxne   x1,x0,idle10          . is set
.
         entp    x0,0                  .Read microsecond clock
         cpytx   x2,x0
         la      af,a_root,frc_p       .Get FRC time to call dispatcher
         lx      x1,af,0
         brxge   x1,x2,idle3           .Jump if not time to call dispatcher
         entp    x0,1
         lbset   x1,af,x0              .Test/set bit 1 of FRC time-if already
         brrne   x1,x0,idle3           . set stay in idle loop-another processor
.                                      . is updating the timed wait queue
idle9    entp    x1,1                  .Exit idle loop and call dispatcher.
         sbyts,1 x1,a_cst,x0,caldisp
.
idle10   lx      x1,a_root,sitvalue    .Put big number in SIT to reduce
         entl    x0,r_sit              .  likelyhood of unnecessary SIT.

         cpyxs   x1,x0
         entl    x0,r_mm               .Restore monitor mask.
         cpysx   x1,x0
         ente    x2,(m_mcrasy+m_mcrsw)
         iorx    x1,x2
         cpyxs   x1,x0


         sx      x2,a_root,no_stop     .Clear the no stop on DUE flag

         brxeq   x0,x0,async
.
.  Reload PIT for current 180 task.
.
async90  entl    x0,r_pit              .Reload monitor clock (PIT).
         cpyxs   x_clock,x0
.
.   End of task switch loop.
         page
...............   beginning of critical region ............
.
.               CRITICAL REGION - between labels BCRIT1 and ECRIT1
.
.   If any changes are made in thie following code,
.   be sure to look at the code in the trap handler.
.   Under certain circumstances, P will be reset to the beginning
.   of the critical region.
.
.
BCRIT1   bss     0
exchloop bss     0
         lx      x1,a_cst,discntl      .Get async/taskswitch flags.
         brxne   x1,x0,intdislp        .Jump if async or taskswitch.
         lbyts,2 x2,a_cst,x0,taskid    .Get taskid of current task.
         sbyts,2 x1,a_xcb,x0,xpmcr     .Clear user's MCR



         la      a_xcb,a_cst,xcbp      .reload pointer to current xcb
         cpyax   xe,a_xcb              .Must be in xe
         lbyts,1 xf,a_cst,x0,lpid      .Save the XCB pointer for next recovery
         shfc    xf,xf,x0,3
         lbyts,1 xd,a_cst,x0,ajlo      .Get the ajl ordinal that is running
         sbyts,8 xd,a_root,xf,p_mode   .to determine executing jobs.




         xtrace  0,0,x1,x0,ae
         shfx    x2,x2,x0,13
ECRIT1   exchange
...............   end of critical region ............
.
.
.   Get the MCR from the user XP.
.
*IF $variable(mtv$test_due_pnd declared) <> 'UNKNOWN'
         lx      xd,a_root,debug0+2*8  .Get the id of the CPU to be tested
         lbyts,1 x1,a_cst,x0,lpid      .Get the current CPUs id
         brxne   xd,x1,go_on2          .Check to see if this CPU is to be tested
         lx      xd,a_root,fk_due      .Get the last time we caused a DUE
         entp    x1,0                  .Get the current time
         cpytx   x1,x1
         subx    x1,xd                 .Determine the time interval
         ente    xd,0F424(16)          .Generate 1 second (in microseconds)
         shfx    xd,xd,x0,4
         brxgt   xd,x1,go_on2          .Dont execute if less than a second
         lx      xd,a_root,debug0      .Check to see if a DUE should be forced
         brxeq   xd,x0,go_on2          .If we have cause enough DUEs, go on
         lbyts,1 x1,a_cst,x0,ajlo      .Get the AJL ordinal of current task
         brxeq   x1,x0,go_on2          .Dont do this in the system job
         cpyax   x1,a_xcb              .Find out which task is executing in the job
         ente    x2,100(16)
         brreq   x1,x2,go_on2          .Dont do this in $JOBMNTR
         lbyts,1 x1,a_xcb,x0,2         .Get p.rn from XCB
         shfx    x1,x1,x0,-4
         entp    x2,3
         brxge   x2,x1,go_on2          .Dont do if ring <= 3
         entp    x1,1
         ente    x0,6*64
         sbit    x1,a_xcb,0,x0         .set MCR DUE
         lx      x2,a_root,debug0+1*8  .Get value of debug0[1] = PND
         brxeq   x2,x0,go_on1          .IF PND = true, set PND flag
         ente    x0,131
         sbit    x1,a_xcb,0,x0         .set PND
go_on1   decx    xd,1
         sx      xd,a_root,debug0
         entp    x1,0                  .Get the current time
         cpytx   x1,x1
         sx      x1,a_root,fk_due      .Store the time we caused a DUE
go_on2   bss     0
*ELSE
. ---------- Test code was omitted at compilation time ----------
*IFEND
         lbyts,2 x_mcr,a_xcb,x0,xpmcr  .Get MCR from user XP
         xtrace  1,x_mcr,x1,x0,ae      .Save MCR in trace buffer.
.
.
.   Process hardware errors - (DUE, SHORT WARNING).
.
ckhdw    ente    x1,m_mcrhdw           .Check for hardware errors
         andx    x1,x_mcr
         brreq   x1,x0,ckasync
         shfc    x1,x_mcr,x0,18        .Check for short warning.
         brrge   x1,x0,ckdue           .Jump if no short warning.
         monreq  pswarn
.
ckdue    shfc    x1,x_mcr,x0,16        .Check for DUE.
         brrge   x1,x0,ckasync
         purge   x0,2                  .Purge cache and map.
         purge   x0,15
         entp    x1,0                  .Set up plist
         sx      x1,a_csf,0
         sa      a_xcb,a_csf,18
         monreq  proc_due
         ente    x_mcr,m_mcrasy        .Force async interrupts since these
.                                         may be invalid because of DUE.
.
.   Process asynchronous interrupts.
.
ckasync  ente    x1,m_mcrasy           .Check for asynchronous interrupt
         andx    x1,x_mcr
         brreq   x1,x0,ckuser          .Jump if no asynchronous interrupt
         entl    x0,r_pit              .Stop the monitor clock.
         cpysx   x_clock,x0
         shfc    x1,x_mcr,x0,27        .Check for SIT.
         brrge   x1,x0,ckextint        .Jump if no SIT.
         addpxq  a_sitret,x0,ckextint  .Set up return address.
         brxeq   x0,x0,prsit           .Go process SIT interrupt.
ckextint shfx    x1,x_mcr,x0,24        .Check for EXT INT
         addpxq  a_extret,x0,ckexch
         brrgt   x0,x1,extrq           .Jump if  EXT INT.
ckexch   ente    x1,m_mcrexs           .Clear SIT and EXTINT.
         inhx    x_mcr,x1
         sbyts,2 x_mcr,a_xcb,x0,xpmcr  .Clear MCR - see trap handler.
.
.   Process faults normally handled in job mode via trap handler.
.
ckuser   ente    x1,j_mcrusr           .Check for condition that will
         andx    x1,x_mcr              .be processed in job mode          .
         brreq   x1,x0,ckpf            .Jump if no job mode request
         purge   x0,15                 .Purge required after INV SEG.
         monreq  rqfault,0,exchloop
.
.   Check for a Page Fault.
.
ckpf     shfx    x1,x_mcr,x0,57        .Check for a page fault.
         brxge   x1,x0,ckmcall         .Jump if no page fault.
         monreq  rqpf,0,exchloop
.
.   Check for a System Call request.
.
ckmcall  shfx    x1,x_mcr,x0,58        .Check for a SYSTEM CALL.
         brxge   x1,x0,ckucr           .Jump if no SYSTEM CALL.
         lbyts,1 x1,a_xcb,x0,xpxregs   .Get request code
         lbyts,1 x2,a_xcb,x0,2         .Get p.rn from XCB
         addaq   ae,a_xcb,xpxregs      .Set up plist to point to
         sa      ae,a_csf,0            .X_regs of current task
         ente    xe,mtrqmax            .Check for max req code.
         brxge   xe,x1,ckmcall5        .Jump if ok.
         entp    x1,0
ckmcall5 shfx    x2,x2,x0,-4
         monreq  x1,x2,exchloop
.
.   If control gets here, there is a chance that the MCR value was zero
.   (except for possible async/sel interrupts). Check for a UCR fault that
.   caused a monitor exchange because traps were disabled.
.
ckucr    lbyts,2 x1,a_xcb,x0,xpucr     .Check for fatal UCR faults.
         ente    x0,j_usrabt
         andx    x1,x0
         brxeq   x1,x0,exchloop        .Jump if no fatal faults.
         lbyts,2 x1,a_xcb,x0,xpflgte   .Check for traps enabled
         isob    x1,x1,x0,7601(8)
         decr    x1,2
         brreq   x1,x0,exchloop        .Jump if traps not disabled
         monreq  rqfault,0,exchloop
         page
..............................................................................
.
.   Trap Handling Routine for traps that occur in Monitor Mode
.
..............................................................................
         align   0,8
traprtn  bss     0
         entl    x0,r_pit              .Save PIT
         cpysx   x_clock,x0
         entl    x0,r_kef0             .Save and clear KEF.
         cpysx   x_kef,x0
         cpyxs   x0,x0
         la      a_root,a_bindin,bs_root
.
trtheta  ente    x2,m_mcrtef           .Check MCR mask trap enable flag
         entl    x0,r_mm               . in the monitor mask.
         cpysx   x1,x0
         andx    x1,x2                 .If MCR mask bit is set,
         brxne   x1,x0,trcnt1          . continue to handle the trap
.
. Mask bit for traps enabled NOT set
.
         lbyts,2 x_mcr,a_psa,x0,sfsa_mcr  .Get the MCR
         shfc    x1,x_mcr,x0,48        .Check for the presence of a DUE
         brxge   x1,x0,trsync          .If DUE, halt
         errstop thetadue
         halt                          .Should not return.
trsync   errstop masksync              .MCR mask out of sync; halt
         halt                          .Should not return.
.
. The code at TRCNT1 does what the macro TRAKTEF 0 would do normally.
.
trcnt1   entl    x0,r_mm               . traktef  0
         cpysx   x1,x0                 .Get live register for mtr mask
         ente    x2,m_mcrtef           .Clear the Traps_Enabled bit in the live
         inhx    x1,x2                 .  mtr mask for THETA
         cpyxs   x1,x0                 .Set live register for mtr mask
trcnt2   la      a_dscb,a_root,nostab
         ente    x0,r_bc
         cpysx   x1,x0                 .get  base constant.
         cpyax   x2,a_root
         addx    x1,x2                 .form pointer to cst
         cpyxa   a_cst,x1
         addaq   a0,a0,mstkfram
         sa      a_cst,a_csf,10        .Save CST_P in p-list.
.
         lbyts,2 x_mcr,a_psa,x0,sfsa_mcr .Get MCR
         la      a_xcb,a_cst,xcbp      .reload pointer to current xcb
         cpyax   xe,a_xcb              .Must be in xe
         lbyts,1 xf,a_cst,x0,lpid      .Save the XCB pointer for next recovery
         shfc    xf,xf,x0,3
         lbyts,1 xd,a_cst,x0,ajlo      .Get the ajl ordinal that is running
         sbyts,8 xd,a_root,xf,p_mode   .to determine executing jobs.


         xtrace  2,x_mcr,x1,x0,ae      .Save MCR in trace buffer.
.
.   DO NOT halt the processor if a DUE or SHORT WARNING occurred.
.
         ente    x1,m_mcrhlt+m_mcrhdw  .Check for fatal errors.
         andx    x1,x_mcr
         brxeq   x1,x0,trhdwx
         shfc    x1,x_mcr,x0,50        .Check short warning.
         brxge   x1,x0,trckdue
         monreq  pswarn
.
trckdue  shfc    x1,x_mcr,x0,48        .Check DUE.
         brxge   x1,x0,trhdw5
         ente    x_mcr,m_mcrasy        .Force all async interrupts.
         purge   x0,2                  .Purge cache and map.
         purge   x0,15
         entp    x1,2                  .Set up plist
         sx      x1,a_csf,0            .Store code to indicate DUE in monitor.
         sa      a2,a_csf,18           .Store pointer to save area.
         monreq  proc_due
.
trhdw5   ente    x1,m_mcrhlt           .Halt if any fatal
         andx    x1,x_mcr              .  conditions are set
         brxeq   x1,x0,trhdwx
trstop   ente    x0,00ff(16)
         callseg bs_merrs,a_bindin,ae  .Call mtp$mtr_error_stop.
         halt                          .should not return, halt if it does
trhdwx   bss     0
.
. Process page fault in monitor mode
.
         ente    x1,m_mcrpf
         andx    x1,x_mcr
         brxeq   x1,x0,nopf            .If no page fault
         sa      a2,a_csf,2            .Plist = a2
         addaq   ae,a_csf,16           .Plist = VAR halt
         sa      ae,a_csf,8
         cpyaa   ae,a_csf
         ente    x0,x_envir1
         callseg bs_pgflt,a_bindin,ae
         lbyts,1 x1,a_csf,x0,16        .Get returned value of halt
         sa      a_cst,a_csf,10        .Re-save CST_P in p-list.
         brxne   x1,x0,trstop          .Jump if fatal error
         ente    x1,m_mcrpf            .Dont reset P if MCR=0040 ONLY.
         brxeq   x1,x_mcr,trresex
nopf     bss     0
.
.  If the trap occurred between the labels BCRIT1 and ECRIT1, reset the
.  trapped 'P' address to the label BCRIT1.
.
         lbyts,4 x1,a_psa,x0,4         .Get P from SFSA.
         addpxq  ae,x0,ecrit1
         cpyax   x2,ae
         brrgt   x1,x2,trresex
         addpxq  ae,x0,bcrit1
         cpyax   x2,ae
         brrgt   x2,x1,trresex
         sa      ae,a_psa,2
.
. The following field definition is used to support the PSFSA instruction which is
. required for CYBER-2000 but is not available in the ASSEMBLER language yet.
. When it is available, replace the VFD line with the following line:
.        psfsa                      .Purge the SFSA pushdown (CYBER-2000 only)
.
         vfd,16   0701(16)          .Purge SFSA pushdown (CYBER-2000 only)
trresex  bss     0
.
.  Protect against the case where 1) a SIT or EXT INT occurred in 180 job
.  mode to cause an exchange to monitor and 2) prior to processing the
.  SIT/EXT INT an EXCH occurred to cause a trap.
.
         la      a_xcb,a_cst,xcbp      .Fetch XCB pointer.
         cpyax   x1,a_xcb              .Skip this check if NIL.
         brrgt   x0,x1,trnom
         lbyts,2 x1,a_xcb,x0,xpmcr     .Fetch MCR from current XP.
         iorx    x_mcr,x1              .Merge with trapped MCR.
         ente    x2,m_mcrasy
         inhx    x1,x2
         sbyts,2 x1,a_xcb,x0,xpmcr     .Store MCR less asynch bits.
trnom    bss     0
.
.  Process asynchronous interrupts.
.
         ente    x1,m_mcrasy           .Check for asynchronous interrupts.
         andx    x1,x_mcr
         brxeq   x1,x0,trasy15         .Jump if no asynchronous interrupts.
         shfc    x1,x_mcr,x0,27        .Check for SIT.
         brrge   x1,x0,trasy5          .Jump if no SIT.
         addpxq  a_sitret,x0,trasy5    .Set up return address.
         brxeq   x0,x0,prsit           .Go process SIT interrupt.
trasy5   shfx    x1,x_mcr,x0,24        .Check for EXT INT
         addpxq  a_extret,x0,trasy8
         brrgt   x0,x1,extrq           .Jump if  EXT INT
trasy8   bss     0
.
.   Halt processor if fatal UCR fault occurred.
.
trasy15  ente    x1,m_usrabt           .Check for fatal UCR fault
         lbyts,2 x2,a_psa,x0,sfsa_ucr .Get UCR
         andx    x1,x2
         brxne   x1,x0,trstop          .Jump if fatal error
.
.   If the trap occurred in the critical area of the trap handler, POP the
.   previous stack frame and let this frame - the new trap handler - take
.   care of setting trap enable flags.
.
         lbyts,4 x1,a_psa,x0,4         .Get P from SFSA.
         addpxq  ae,x0,rqproc          .Address of end of critical TH region
         cpyax   x2,ae
         brrge   x1,x2,trexit
         addpxq  ae,x0,trexit          .Address of beginning of critical TH region
         cpyax   x2,ae
         brrgt   x2,x1,trexit
         pop                           .POP the previous stack frame (Trap Handler)
                                       . and become the real trap handler
.
.   Set TRAP ENABLE DELAY and return.
.
trexit   bss     0
         entl    x0,r_ted              .Set trap enable delay
         cpyxs   x0,x0
         traktef 1                     .Enable Traps_Enabled bit in MCR mask
         entl    x0,r_kef0             .Restore KEF.
         cpyxs   x_kef,x0
         entl    x0,r_pit              .Restore PIT
         cpyxs   x_clock,x0
         return
         page
..............................................................................
.
.      This routine updates the request statistics and calls the
.      appropriate request processor.
.      Interlocking of most monitor functions is performed by this routine.
.
.      Entry condition:
.           a_rqtbl  - pointer to request table entry for request.
.           ae       - pointer to binding section entry for request proc.
.           a_rq_ret - return address
.
..............................................................................
.
rqproc   bss     0
         lx      x1,a_root,multpro     .Test for multiple processors.
         entl    x0,r_pit              .Get current PIT
         cpysx   x2,x0                 .!! X2 contains PIT thruout this proc.
         brxeq   x1,x0,rqpr14          .Jump if not multi_processor
         lbyts,1 x1,a_rqtbl,x0,il      .Test if request must be interlocked.
         brxeq   x1,x0,rqpr14          .  jump if interlock not required
         addaq   af,a_root,il_tbl      .Calc pointer to interlock word.
         shfx    x1,x1,x0,3
         addax   af,x1                 .PVA of interlock table
         entp    x0,0                  .Try to set lock
         lbset   x1,af,x0
         brreq   x1,x0,rqpr12          .Jump if interlock obtained.
.
rqpr4    entp    x0,0                  .Keep trying to set lock.
         lbset   x1,af,x0
         brreq   x1,x0,rqpr6           .Jump if lock obtained.
         entp    x1,1                  .Kill some time by doing a
         divx    x1,x1                 .  divide
         lbyts,1 x1,a_cst,x0,cp_state+cp_nxtst  .check for step cpu request
         brxne   x1,x0,rqpr5
         lx      x1,af,0               .Get the ID of locking CPU
         brreq   x1,x0,rqpr4           .Jump if not still locked
         lbyts,1 xd,a_root,x1,nextstat .Get next state of locking CPU
         brxeq   xd,x0,rqpr4           .Jump if locking CPU still ON
         lbyts,1 x1,a_root,x1,cpstreas .Get next state of locking CPU
         entp    xd,4                  .ordinal 4 is down by operator
         brxeq   x1,xd,rqpr4           .Jump if down by operator
         entp    xd,1
         sx      xd,a_root,rsetilk     .Flag fact that we cleared interlock
         entp    xd,0
         sx      xd,af,0               .Reset the interlock word
         brxeq   x0,xd,rqpr4           .Get lock
         errstop cpudown               .  else halt with fatal error.
         halt                          .Should not return.
rqpr5    errstop stepmes
         brxeq   x0,x0,rqpr4           .Continue trying to get the lock.
.
rqpr6    entl    x0,r_pit              .Restore PIT- don't charge user for wait.
         cpysx   x1,x0                 .Read PIT to calc wait time.
         lx      xd,a_root,lockwait    .Update lock wait time and count.
         lx      xe,a_root,lockwait+8
         subx    x1,x2
         notx    x1,x1
         addx    x1,xd
         sx      x1,a_root,lockwait
         incx    xe,1
         sx      xe,a_root,lockwait+8
         cpyxs   x2,x0
.
rqpr12   cpyax   x1,af                 .x1 = pva of interlock table
         sa      a_cst,af,lockcp       .Store ID of locking CPU

rqpr14   bss     0                     .x1 = zero if no interlock.
         ente    x0,x_envir1           .Process the request
         cpyaa   af,a_csf
         callseg bs_rqtbl,ae,af
         entl    x0,r_pit
         cpysx   xd,x0                 .Calculate time to process the request
         lx      xe,a_rqtbl,totalt     .Update total and max time
         lx      xf,a_rqtbl,rqcntmax
         subx    x2,xd
         addx    xe,x2
         sx      xe,a_rqtbl,totalt
         incr    xf,1

         lx      xd,a_root,cmax        .Fetch maximum stat count.
         cpyrr   xe,xf
         subx    xe,xd
         brrgt   x0,xe,rqpr15          .Less than max.
         ente    xe,0
         cpyrr   xf,xe                 .Reset request count value.

rqpr15   shfc    xe,xf,x0,32           .Check if new maximum time.
         brrge   xe,x2,rqpr20          .  Jump if not new max.
         cpyrr   xe,x2
         shfc    xf,xe,x0,32
rqpr20   sx      xf,a_rqtbl,rqcntmax
         brxeq   x1,x0,rqpr30          .Exit if no lock
         entl    x0,0
         cpyxa   af,x1
         sx      x0,af,ilflag          .Clear lock
rqpr30   brdir   a_rq_ret,x0           .Return
         page
..............................................................................
.
.  This routine is called whenever a SIT interrupt occurs.
.
..............................................................................
.
prsit    bss     0
         sa      a_sitret,a_cst,return .save the return address
         entp    xf,1                  .Set up X15 with 'TRUE'.
         entp    x0,0                  .Set up X0 with 'FALSE'.
         cpytx   x2,x0                 .Free running clock ->X2.
         sx      x2,a_root,scb+scbnsrv .Update '180 alive' flag.
         sx      x2,a_cst,cpwell       .Update cpu alive flag.
         sbyts,1 xf,a_cst,x0,caldisp
.
                                       .If not an internal NOSVE site, poll
         lbyts,1 xe,a_root,x0,ve_int   .for lost external interrupts.
         brxne   xe,x0,prsit2          .Internal sites, hang if lost ext int.
         lbyts,1 xe,a_cst,x0,ext_int   .Check external interrupt flags in cst.
         brxeq   xe,x0,prsit2          .Jump if no external interrupt flags.
         addpxq  a_extret,x0,prsit2    .Set up return from ext int processor.
         brxgt   xe,x0,extrq           .Process external interrupts.
.
prsit2   lx      xf,a_root,alltime     .Get time async lock has been set
         brxge   x2,xf,prsit3          .max time has been exceeded
         lx      x1,a_root,sitvalue    .Reset SIT.
         entl    x0,r_sit
         cpyxs   x1,x0
         brdir   a_sitret,x0


prsit3   monreq  mon_smu               .We got here because the system is in a
.                                       severe thrashing state and probably
.                                       spending all it's time processing memory
.                                       requests. We need to notify DFT that we
.                                       are still alive so it doesn't shut us
.                                       down with a Z617 error.
.
         entp    x0,0
         cpytx   x2,x0
         lx      x1,a_root,sitvalue     .Reset SIT
         entl    x0,r_sit
         cpyxs   x1,x0
         la      a_sitret,a_cst,return
         brdir   a_sitret,x0           .Go back to what we were doing


runexit  brdir   a_inret,x0            .Return to where called from
         page
..............................................................................
.  EXTERNAL INTERRUPT PROCESSOR
.        entry conditions:
.           a_extret - return address
..............................................................................
.
extrq    lx      x1,a_root,multpro
         brxeq   x1,x0,extrq5          .Jump if not multiprocessor
         entp    x2,0
         entl    x0,tsk_sw
         lx      x1,a_cst,ext_int
         shfc    x1,x1,x0,tsk_sw
         brxge   x1,x0,extrq1          .Jump if no task switch
         sbit    x2,a_cst,ext_int,x0
         entl    x0,1
         sbyts,1 x0,a_cst,x0,caldisp   .Set task switch flag
extrq1   entl    x0,pur_ca
         shfc    x1,x1,x0,pur_ca-tsk_sw+64
         brxge   x1,x0,extrq2          .Jump if cache purge not needed
         sbit    x2,a_cst,ext_int,x0
         cpytx   x0,x2                 .Free running clock
         purge   x0,2                  .Purge cache
         sx      x0,a_cst,cachtim
extrq2   entl    x0,pur_map
         shfc    x1,x1,x0,pur_map-pur_ca+64
         brxge   x1,x0,extrq3          .Jump if map purge not needed
         sbit    x2,a_cst,ext_int,x0
         cpytx   x0,x2                 .Free running clock
         purge   x0,15                 .Purge map
         sx      x0,a_cst,maptim
extrq3   entl    x0,step_pr
         shfc    x1,x1,x0,step_pr-pur_map+64
         brxge   x1,x0,extrq4          .Jump if no error halt
         entl    x0,1
         sbyts,1 x0,a_cst,x0,caldisp   .Call dispatcher to process STEP
extrq4   lbyts,1 x1,a_cst,x0,memport   .Dont check IO completions if
         lbyts,1 x2,a_root,x0,intport  . IOU doesnt send them to this CPU.
         brxne   x1,x2,extrqx
extrq5   la      ae,a_root,pextiou
         lx      x1,ae,0               .Exit if no external interrupts
         brxeq   x1,x0,extrq6          . have been sent by IOU.
         entl    x0,1
         sx      x0,a_root,eiflag      .Set flag that ext interrupt.
         sx      x0,a_root,asyntime
         sbyts,1 x0,a_cst,x0,asyncp
extrq6   la      ae,a_root,dpv$scd_block_p
         addaq   ae,ae,4
         entp    x0,0
         lbset   x1,ae,x0
         brrne   x1,x0,extrq7          .If SCD block not updated
         monreq  ascii_kb
.
extrq7   entl    x0,r_eid              .Get EID.
         cpysx   x1,x0
         isob    x1,x1,x0,(40*64+7)    .High order 7 bits of model number from
                                       . element id.
         ente    x2,46(16)             .CYBER 2000 Model 46
         brreq   x1,x2,thetasit
         incx    x2,2                  .CYBER 2000 Model 48
         brreq   x1,x2,thetasit
.
extrqx   brdir   a_extret,x0
.
thetasit entl    x0,r_sit              .Get the current SIT value
         cpysx   x1,x0
         brrgt   x1,x0,extrqx          .If not negative, jump to exit
         lx      x1,a_root,sitvalue    .Reset SIT.
         entl    x0,r_sit
         cpyxs   x1,x0
         brxeq   x0,x0,extrqx
         page
..............................................................................
.
.        MTP$IDLE_180  routine to idle 180.
.
.        This routine is called to put 180 into an idle state. Only
.        the system console is kept alive and only the monitor window
.        will respond to commands. If dual state is present, 180 will idle
.        and give control to NOS/NOS-BE. Depending on why the system idled,
.        the system may be able to be resumed via a RESUME_SYSTEM command.
.
.            mtp$idle_180 (resume_permitted: boolean)
.
..............................................................................
         align     0,8
idle180  ALIAS     MTP$IDLE_180
idle180  procedur
idleres  param     val,subrange,1
.
         ploadx    x_resume,idleres            .Load RESUME_ALLOWED - A4
.                                                gets clobbered later.
         la        a_root,a_bindin,bs_root

.                                              .Disable the dedicated NOS flag
i1801    la        a_dscb,a_root,nostab
         addaq     a0,a0,mstkfram
         entl      x0,r_pit                    .Save PIT - dont charge current task
         cpysx     x_clock,x0                  . for idle time.
         ente      x0,r_bc
         cpysx     x1,x0                       .Get  base constant.
         cpyax     x2,a_root
         addx      x1,x2                       .Form pointer to cst
         cpyxa     a_cst,x1
         sa        a_cst,a_csf,10              .Save CST_P in p-list.
.
         traktef   1                           .Enable TEF mask bit
         entl      x0,r_te                     .Enable traps in case we got here via
         cpyxs     x0,x0                       . trap handler.
.
i180a    entp      xe,0                        .Set 180 priority to 0.
         entp      x0,0                        .Set lock for calling
         addaq     af,a_root,asylocki          .  mtp$monitor_system_status.
         lbset     x1,af,x0
         brrgt     x1,x0,i180f                 .Jump if already locked.
         la        ae,a_root,mtvdftb           .Fetch pointer to DFT block.
         lx        x1,ae,dftcw                 .Get DFT control word.
         shfx      x1,x1,x0,62                 .Check E8 field.
         brxge     x1,x0,i180e                 .Jump if not set.
         ente      x0,00ff(16)
         addaq     ae,a_bindin,16*proc_dft     .Set up call to dsp$process_dft_block.
         callseg   bs_rqtbl,ae,a0              .Call dsp$process_dft_block.
i180e    bss       0
         ente      x0,00ff(16)
         addaq     ae,a_bindin,16*mon_smu
         callseg   bs_rqtbl,ae,a0              .Call mtp$monitor_system_status.
         entp      x0,0                        .Clear call environment.
         sbyts,1   x0,af,x0,0                  .Clear lock.
i180f    bss       0
         brcr      2,0,i180g                   .Clear shortwarning from MCR.
i180g    lbyts,1   x1,a_root,x0,scb+scbstepr   .Loop if STEP still requested.
         brrne     x1,x0,i180a
         brxeq     x_resume,x0,i180a           .Loop if resume not permitted.
.
         entl      x0,r_pit                    .Restore PIT.
         cpyxs     x_clock,x0
         return
         page
.........................................................................
.
.   This routine is called from cybil to send interrupts to other processors.
.
.      PROCEDURE [XREF] mtp$interrupt_processor (port_mask: 0..255)
.
.........................................................................
.
int     alias    MTP$INTERRUPT_PROCESSOR
int     procedur
intmask param    val,subrange,1
        ploadx   x2,intmask
        intrupt  x2,0
        return
        page
........................................................................
.
.   MTP$SPIN_CPU
.      Routine to make a CPU spin in a tight loop indefinitely.
.
.   This routine is called by a CPU which is about to be deconfigured
.   out of the system due to hardware errors or an operator request.
.   The CPU spins in a very tight loop, only checking whether it should
.   continue to spin.  The intent is to have the CPU executing as little
.   as possible before it is completely removed from the system
.   configuration.  The CPU is expected to be executing this portion of
.   code when Dedicated Fault Tolerance (DFT) stops a CPU which has been
.   operational.  The boolean indicating whether or not the CPU should
.   continue to spin will be changed asynchronously by another CPU.
.
.   PROCEDURE mtp$spin_cpu;
.
........................................................................
         align     0,8
spin_cpu ALIAS   mtp$spin_cpu
spin_cpu procedur
cpu_id   param   val,subrange,1
.
         la      a_root,a_bindin,bs_root
.
         ente    x0,r_bc
         cpysx   x1,x0                 .Get the base constant
         cpyax   x2,a_root
         addx    x1,x2                 .Form a pointer to the CST
         cpyxa   a_cst,x1
.
. Place the CPU into a spin, during which time it performs no useful system
. operations except purging its cache and maps.  The CPU will be downed in
. the MRT after this point and therefore will never return to be used
. in the system.
.
spin_1   purge   x0,2                  .purge cache
         purge   x0,15                 .purge map
         brxeq   x0,x0,spin_1          .Spin
.
. The CPU should never reach the following statements.
.
         entp    x_infrc,0             .Get current time
         cpytx   x_infrc,x_infrc
         sx      x1,a_cst,cachtim      .Store time of last purge for cache
         sx      x1,a_cst,maptim       .Store time of last purge for maps
         entl    x0,r_pit              .Restore the PIT
         cpyxs   x_clock,x0
         return
        page
..............................................................................

. The following is the definition of the oss$mainframe_wired_cb section.
. It will ALWAYS be cache bypass
..............................................................................
.
oss$mainframe_wired_cb  SECTION working,read+write
         use     oss$mainframe_wired_cb
osv$mainframe_wired_cb_heap  vfd,16,32    0ffff(16),080000000(16)   .Pointer to heap
         defg    osv$mainframe_wired_cb_heap
.
.        The following is the definition of the communication block to
.        talk to the NOS/VE ascii console.
.
         align   0,8
asciiblk bss     0                     .ascii console communications block
         vfd,8   0                     .input buffer id
         vfd,8,8,8 0,0,0               .character buffer
         vfd,32  0                     .rma of last output entry processed
         vfd,8   0                     .console driver command
         vfd,8   0                     .hold display flag
         vfd,8   0                     .echo line size
         vfd,8   0                     .undefined
         vfd,32  0                     .rma of output list
.
         align   0,8
extiou   vfd,64  1                     .IOU sets this word non-zero when
                                       . sending external interrupt.
dpv$scd_time  vfd,64 0

         align   0,16
a170_xp  bssz    xpsize
a170_st  bssz    a170_stl*8
.
.      Set up the NOS XP.
.
.  Initialize the NOS170 Exchange Package
.
.
         ref     mtp$170_trap_handler
a170xpin bss     0
         xpa     a170_xp,2,mtp$170_trap_handler
         xpareg  a170_xp,a_tos,nil
         xpareg  a170_xp,a_csf,nil
         xpareg  a170_xp,a_psa,nil
         xpv     a170_xp,a_bindin*8+10,01000(16)+snsf170,16
         xpareg  a170_xp,a_plist,nil
         xpareg  a170_xp,5,nil
         xpareg  a170_xp,6,nil
         xpareg  a170_xp,7,nil
         xpareg  a170_xp,8,nil
         xpareg  a170_xp,9,nil
         xpareg  a170_xp,10,nil
         xpareg  a170_xp,11,nil
         xpareg  a170_xp,12,nil
         xpareg  a170_xp,13,nil
         xpareg  a170_xp,14,nil
         xpareg  a170_xp,15,nil
         xpv     a170_xp,xpstl,a170_stl,16
         xpv     a170_xp,xpmm,0fbfc(16),16
         xpv     a170_xp,xpum,0ff7f(16),16
         xpv     a170_xp,xpkm,0ffff(16),16
         xpv     a170_xp,xppit,0000f(16),16
         xpv     a170_xp,xppit+8,04240(16),16
         xpv     a170_xp,xplrn,1,16
         xpv     a170_xp,xpflgte,00002(16),16
.
         org     a170_st+snnos170*8
         vfd,64  09a11ffff00000000(16) .STE for NOS
         org     a170_st+snsf170*8
         vfd,64  00000000000000000(16) .STE for NOS stack
         org       a170_st+snnth170*8
         vfd,64  0be11800100000000(16) .STE for NOS trap handler
         org     a170xpin
         end     begin


