         PAGE
.***********************************************************************
.
.        osi$privilaged_170_instructions
.
.***********************************************************************
.        PIF        PRIVILAGED INSTRUCTION FAULT HANDLER.
.
.        THIS ROUTINE PROCESSES INSTRUCTIONS OF THE FORM:
.
.        9/017 3/i 3/j 15/op 30/k
.
.        i  = OPTIONAL X REGISTER.
.        j  = OPTIONAL X REGISTER.
.        op = FUNCTION CODE.
.        k  = OPTIONAL CONSTANT PARAMETER.
.
.        The function codes handled by EI are the following:
.        0001 - SET INTERFACE BLOCK.
.        0002 - PREPARE FOR NOS/VE DEADSTART.
.        0040 - read and set pit.
.        0701 - ECS/CM TO CM COPY.
.        0702 - CM TO ECS/CM COPY.
.        0703 - CACHE INVALIDATE.
.        1001 - mini-link memory transfer.
.        1002 - initialize pvas for mini-link.
.        1003 - Return value of pva.
.        2777 - Inject hardware faults.
.
.        The function codes handled by NOS trap handler are the following:
.        0003 - Revert to NOS standalone operation.
.        1001 - Mini-link memory transfer.
.        2000 - Unprivilaged memory link.
.        2001 - Console display driver.
.        2002 - NOS/ve status.
.
.        REQUESTS 1,701,702 REQUIRE RA=0.  ALL REMAINING REQUESTS  ARE
.        VALIDATED  BASED  ON  THE  VALIDATION FIELD IN THE DUAL STATE
.        BLOCK.  THE VALIDATION ACCORDING TO THE FOLLOWING TABLE.
.
.            0 -   777  V1.
.         1000 -  1777  V2.
.         2000 -  3777  V3.
.         4000 -  7777  V4.
.        10000 - 17777  V5.
.        20000 - 37777  V6.
.        40000 - 77777  V7.
.
.        define symbolic names for function codes.
.
dscb     equ       1                   .define DSCB pointer
scpu     equ       2                   .stop CPU
rspt     equ       40(8)               .read and set pit
eccp     equ       701(8)              .ECS/CM to CM copy
cecp     equ       702(8)              .CM to ECS/CM copy
cinv     equ       703(8)              .cache invalidate
cpcm     equ       1001(8)             .Copy CM between C180 and C170
cpva     equ       1002(8)             .Define PVA for function cpcm
rpva     equ       1003(8)             .Return value of PVA
mliu     equ       2000(8)             .Memory Link Interface Unprivileged
nvst     equ       2002(8)             .NOS/ve status request
ihfu     equ       2777(8)             .Inject hardware fault
.
PIF      bss       0
.
.        VALIDATE INSTRUCTION POSITION.
.
         lbyts,6   X2,a_psa,x0,xp_p
         ISOB      X3,X2,X0,7502(8)    .ISOLATE PARCEL DESCRIPTOR
         BRRNE     X3,X0,IIP           .IF NOT AT PARCEL 0
.
.        VALIDATE TRAP017 INSTRUCTION FIELDS.
.
         CPYXA     a8,X2               .(a8) = P
         LX        xc,a8,0             .(xc) = TRAP017 INSTRUCTION
         ISOB      X5,xc,X0,2316(8)    .INSTRUCTION TYPE
         ISOB      x_reg1,xc,X0,1502(8)  .ISOLATE REGISTER NUMBER
         isob      x_reg2,xc,x0,2002(8)  .second register number
.
.        VERIFY ACCESS PERMISSION, EITHER RA=0 OR THE PROPER
.        BIT SET IN THE TRAP 180 FIELD IN THE D7JP WORD OF
.        THE DUAL STATE CONTROL BLOCK.
.
         brreq     x_rac,x0,pif2       .if RA=0 permission
.
.        CHECK PRIVILAGE BIT IS SET.
.
pif1     bss       0
         entl      x0,r_pid
         cpysx     x1,x0               .fetch processor number
         mulxq     x1,x1,8
         LBYTS,1   X6,a_dscb,x1,d7jp+5  .VALIDATION BITS
         SHFX      X9,X5,X0,-8
         ENTL      X0,1
         IORX      X9,X0
         ANDX      X6,X9
         BRRGT     X6,X9,IIP           .IF NOT VALIDATED
         ADDX      X6,X6
         BRRGE     X9,X6,IIP           .IF NOT VALIDATED
PIF2     BSS       0
         addpxq    a4,x0,reqtable
         sbyts,2   x5,a4,x0,req_end-reqtable
PIF3     lbyts,2   x6,a4,x0,4
         addaq     a4,a4,6
         brrne     x6,x5,pif3          .if not found
         brdir     a4,x0               .process routine
.
.        entry to process invalid functions.
.
pif4     entp      x0,1                .abort for invalid function
         SHFX      X0,X0,X0,47
         SX        X0,a_psa,xp_cx0     .STORE ILLEGAL FUNCTION BIT
         BRREQ     X0,X0,IIP
.
.        define macro FN017 to generate table of 017 functions.
.
fn017#v  set       0
.
         PROC
fn017    pname
         do        fn017#v=0
reqtable equ       $-4
fn017#v  set       1
         dend
         do        sn:(f:(2,0))=sn:(end)
req_end  vfd,16    0
         else
         vfd,16    f:(2,0)
         brreq     x0,x0,f:(2,1)
         dend
         PEND
         PAGE
...
.        BCM        - SIMULATE BLOCK CM MOVE.
.
.        THIS SUBROUTINE  SIMULATES  THE  EXECUTION  OF  THE  EXTENDED
.        011/012  *RE*/*WE* ECS INSTRUCTIONS.  THIS ROUTINE IS ENTERED
.        WHEN  A  017  TRAP  IS  OCCURS  AND  IT  VALIDATES  THAT  THE
.        INSTRUCTION IS ON A WORD BOUNDARY AND THAT THE SUBFUNCTION IS
.        EITHER A *RE* OR *WE* SIMULATED FUNCTION  CODE.   THIS  BLOCK
.        MOVE  PROVIDES FOR A CM TO ECS, ECS TO CM, AND CM TO CM COPY.
.        IN EVERY CASE, THE MOVE PROCEEDS FROM LOW TO HIGH MEMORY  AND
.        OVERLAPPING  MOVES  WHERE THE DESTINATION OVERLAPS THE SOURCE
.        ARE NOT PROVIDED FOR.  AFTER EVERY 56 WORD BLOCK A  CHECK  IS
.        MADE FOR A PP EXCHANGE.  IF THE PP EXCHANGE BIT IS SET IN THE
.        MCR,  A  RETURN  IS MADE TO THE C170 STATE AFTER FIRST SAVING
.        THE COUNT OF BLOCKS COPIED IN THE INSTRUCTION BITS 18-30  AND
.        SETTING  THE  RESUME  BIT  IN  THE EXIT MODE FLAGS.  WHEN THE
.        INSTRUCTION IS SUBSEQUENTLY RE-EXECUTED THE  SIMULATION  WILL
.        BE  RESUMED  AT THE POINT OF INTERRUPTION.  THE FORMAT OF THE
.        SIMULATED INSTRUCTION IS THE FOLLOWING.
.
.        9/017, 3/B, 3/0, 15/V, 9/R, 18/K
.
.        B = B-REGISTER TO  USE FOR COMPUTING TRANSFER LENGTH.
.        V = 00701 - FOR *RE*,  00702 - FOR *WE*.
.        R = BLOCKS TRANSFERED IF INTERRUPTED.
.        K = CONSTANT USED FOR COMPUTING TRANSFER LENGTH.
.
.        X0 = 1/C, 29/CM, 1/F, 29/ECS
.
.        C = FLAG FOR CM TO CM COPY.
.        CM= CM ADDRESS FOR TRANSFER.
.        F = FLAG REGISTER BIT.
.        ECS=ECS/CM ADDRESS FOR TRANSFER.
.
.        ENTRY CONDITIONS
.
.        (a_nos) = NOS os pva.
.        (a_rac) = Pva of job fl.
.        (a8)    = Pva of jobs program counter.
.        (x_reg1)= B-register designator.
.        (x_flc) = Fl of C170 job.
.        (xc)    = Instruction causing trap.
.        (x5)    = Function from instruction.
.        (x6)    = o'701'
.        (X8)    = C170 X0 REGISTER.
.
bcm      addxq     x5,x5,-701(8)       .set flag for 011/012
         ISOM      XB,X0,5621(8)       .FORM MASK FOR K-FIELD
         ANDX      xc,XB
.
.        form RAE and FLE.
.
         lbyts,4   x2,a_psa,x0,xp_fle
         lbyts,4   x4,a_psa,x0,xp_rae
         cpyaa     a6,a_nos
         shfx      x4,x4,x0,3
         addax     a6,x4
.
.        FORM WORD COUNT OF TRANSFER (BI+K).
.
         LXI       x4,a_psa,x_reg1,xp_cb0/8*8 .B REGISTER CONTENTS
         ANDX      X4,XB               .ADD B-REGISTER TO K USING
         SHFX      x9,xc,X0,-17        .ONES COMPLEMENT ARITHMETIC
         SHFX      XD,X4,X0,-17
         ADDR      xc,x9
         ADDR      X4,XD
         ADDR      xc,X4               .xc = LENGTH OF TRANSFER
         ANDX      xc,XB               .TRIM ANY CARRY
.
.        CHECK FOR ADDRESS OUT OF RANGE CONDITION.
.
         lx        x8,a_psa,xp_cx0     .fetch c170 X0
         ISOB      XA,X8,X0,0534(8)    .FWA OF MOVE
         SHFX      X4,XA,X0,3          .FORM BYTE ADDRESS
         ADDR      XA,xc
         BRRGT     XA,x_flc,AOR1       .IF LWA OF MOVE IS BEYOND FL
         ISOB      XA,X8,X0,4334(8)    .XA=FWA IN ECS/CM
         SHFX      X8,X8,X0,4
         BRXGE     X8,X0,BCM1          .IF ECS MOVE
         CPYXX     X2,x_flc            .USE CM RA/FL INSTEAD OF ECS
         CPYAA     A6,a_rac
BCM1     SHFX      X9,XA,X0,3          .X9=BYTE ADDRESS OF FWA IN ECS/CM
         ADDR      xa,xc               .LWA IN ECS
         BRRGT     XA,X2,AOR1          .IF LWA IN ECS BEYOND FL
.
.        SET SOURCE AND DESTINATION BASED ON INSTRUCTION TYPE.
.
         cpyaa     a4,a_rac
         ADDAX     A4,X4               .A4 = ABS FWA OF MOVE IN CM
         ADDAX     A6,X9               .A6 = ABS FWA OF MOVE IN ECS/CM
         BRREQ     X5,X0,BCM2          .IF *RE* INSTRUCTION
         CPYAA     A7,A4               .SWAP SOURCE AND DESTINATION
         CPYAA     A4,A6               .FOR COPY FROM ECS TO CM
         CPYAA     A6,A7
.
.        RESTART INSTRUCTION IN MID TRANSFER IF NECESSARY.
.
BCM2     ENTL      X0,BSCIF
         ENTP      X2,0
         LBIT      XB,a_psa,xp_em+1,x0 .GET INTERRUPTED FLAG
         SBIT      X2,a_psa,xp_em+1,x0 .AND ENSURE THAT IT IS CLEAR
         ENTE      X1,4*14*8           .BLOCK COUNT IN BYTES
         ENTE      X0,0110E(16)        .LOAD MULTIPLE DESCRIPTOR
         SHFX      xf,xc,X0,3          .XF = TRANSFER LENGTH IN BYTES
         CPYXA     A5,XF               .SAVE ORIGINAL TRANSFER LENGTH
         BRREQ     XB,X0,BCM3          .IF NOT INTERUPTED
         LX        XE,a8,0
         ISOB      X3,XE,X0,4213(8)    .ISOLATE BLOCK COUNT TO X3
         INSB      XE,X2,X0,4213(8)    .CLEAR BLOCK COUNT
         SX        XE,a8,0
         MULR      X3,X1               .WORDS ALREADY TRANSFERED
         SUBR      XF,X3               .DECREMENT WORDS TO TRANSFER
         ADDAX     A4,X3               .INCREMENT SOURCE ADDRESS
         ADDAX     A6,X3               .AND DESTINATION ADDRESS
.
.        MOVE LARGE CHUNKS OF 4*14 WORDS.
.
BCM3     BRRGT     X1,XF,BCM4          .IF SMALL BLOCK TO MOVE
         LMULT     X0,A6,0
         SMULT     X0,A4,0
         LMULT     X0,A6,14*8
         SMULT     X0,A4,14*8
         LMULT     X0,A6,2*14*8
         SMULT     X0,A4,2*14*8
         LMULT     X0,A6,3*14*8
         SMULT     X0,A4,3*14*8
         ENTE      X1,4*14*8           .BLOCK SIZE IN BYTES
         SUBR      XF,X1
         ADDAX     A4,X1               .INCREMENT ADDRESSES
         ADDAX     A6,X1
         BRCR      5,3,BCM3            .IF NO C170 PP EXCHANGE
         ENTL      X0,BMF
         LBIT      XB,a_psa,xp_mf,X0   .FETCH MONITOR FLAG
         ENTE      X0,0110E(16)
         BRRNE     XB,X0,BCM3          .IF MOVE IN MONITOR MODE
         CPYAX     X3,A5               .RETRIEVE STARTING WORD COUNT
         SUBR      X3,XF               .WORDS TRANSFERED
         DIVR      X3,X1               .FORM BLOCK COUNT
         LX        XF,a8,0             .INSTRUCTION
         INSB      XF,X3,X0,4213(8)    .INSERT BLOCK COUNT
         SX        XF,a8,0
         BRREQ     X0,X0,PII02
.
.        MOVE UP TO 3 CHUNKS OF 15 WORDS.
.
BCM4     ENTX      X1,14*8
         BRRGE     X1,XF,BCM6          .IF SMALLER THEN A SMALL CHUNK
BCM5     LMULT     X0,A6,0
         SMULT     X0,A4,0
         ENTX      X1,14*8
         ADDAX     A4,X1               .INCREMENT ADDRESSES
         ADDAX     A6,X1
         SUBR      XF,X1
         BRRGT     XF,X1,BCM5          .CHECK FOR MORE TRANSFERS
.
.        MOVE LAST CHUNK OF 0-14 WORDS.
.
BCM6     ENTE      X0,01100(16)
         BRREQ     XF,X0,trap4         .IF NO WORDS TO TRANSFER
         SHFX      XF,XF,X0,-3         .COUNT OF WORDS REMAINING
         IORX      X0,XF               .FORM DESCRIPTOR FOR LAST TRANSFER
         LMULT     X0,A6,0
         SMULT     X0,A4,0
         BRREQ     X0,X0,trap4         .RETURN WITH INSTRUCTION COMPLETE
         page
.
.        read_set_pit
.
.        This instruction allows the C170 monitor to more accuratly
.        track the time used by a 170 job running in dual state.
.
.        9/017, 3/0, 3/0, 15/00040, 30/0
.
.        X0 = Contents of PIT when read.
.
read_set_pit bss   0
         ente      x3,0c9(16)          .PIT register
         cpysx     x1,x3
         sxi       x1,a_psa,x0,xp_cx0
         entn      x1,1
         cpyxs     x1,x3               .reset PIT
         brreq     x0,x0,trap4         .return
         page
.
.        BMI       - Buffer Memory Invalidate.
.
.        This instruction allows the C170 monitor to purge cache.
.
.        9/017, 3/Xj, 3/Xk, 15/00703, 30/0
.
.        Xj = FWA of memory to purge relative to cyber 170 exchange package RA.
.        Xk = Length of memory (in words) to purge.
.
.        ENTRY CONDITIONS.
.
.        (a_nos) = NOS os pva.
.        (x_reg1)= ordinal of Xj.
.        (x_reg2)= ordinal of Xk.
.        (x_flc) = Field length of MONITOR.
.
bmi      lxi       x_reg1,a_psa,x_reg1,xp_cx0
         lxi       x_reg2,a_psa,x_reg2,xp_cx0
         isob      x_reg1,x_reg1,x0,0473(8)  .isolate 60 bits
         isob      x_reg2,x_reg2,x0,0473(8)  .isolate 60 bits
         brxge     x_reg1,x0,bmi1      .if cm cache purge
         lbyts,4   x6,a_psa,x0,xp_rae  .RA for ecs
         lbyts,4   x_flc,a_psa,x0,xp_fle .FL for ecs
         shfx      x6,x6,x0,3
         ents      x_reg1              .clear upper part of address
         cpyaa     a_rac,a_nos
         addax     a_rac,x6            .form pva for rae
bmi1     bss       0
         shfx      x8,x_reg2,x0,-9+3   .length in bytes/512.
         addx      x_reg2,x_reg1
         brrge     x_reg2,x_flc,aor    .if bad address combination
         shfx      x6,x_reg1,x0,3
         shfx      x7,x_reg2,x0,3
         cpyax     x5,a_rac
         ente      x_reg2,64
         addx      x6,x5
         addx      x7,x5
         brrge     x_reg2,x8,bmi2      .if purge of less than cache size.

.        Purging more than size of cache, purge all of cache, it is quicker.

         purge     x6,2                .purge all cache.
         brreq     x0,x0,trap4         .return.

bmi2     purge     x6,3                .purge cache for 512 block of cm
         addxq     x6,x6,512
         brrgt     x7,x6,bmi2          .if more cache to purge
         purge     x6,3
         brreq     x0,x0,trap4         .cache purge complete
         page
.
.        IHF - Inject hardware fault.
.                  This function issues the special instructions that will cause
.                  specific hardware faults.
.
.        DESIGN:
.                  Special microcode is required that actually causes the desired
.                  hardware fault.  The special microcode recoginizes specific
.                  unimplemented instructions that are issued and dependent on the
.                  J and K fields causes a specific fault.  The J field specifies the
.                  kind of hardware fault and the K field specifies an X register
.                  that contains the RMA of a word in memory with a parity error.
.                  This word in memory has to be preconditioned with a parity error
.                  before deadstart using CMSE or MDD.
.
.        ENTRY:
.                  9/017, 3/Xi, 3/Xj, 15/2777, 30/0
.                  Xi = 40/0,
.                       8/mode, =0 implies job, =1 implies monitor.
.                       8/traps enabled, =0 implies traps disabled, =1 implies traps
.                         enabled.
.                       8/fault kind.
.                  Xj = RMA of word in memory with parity error.
.
.                  (a_nos) = NOS os pva.
.                  (x_reg1) = ordinal of Xi.
.                  (x_reg2) = ordinal of Xj.
.
.        EXIT:
.                  Specified hardware fault is injected if no errors.
.
.                  Exit is to 'trap2' if control is returned after fault injected
.                  or errors in parameters, following values returned in X0 of
.                  callers stack frame (170):
.                     30/1, implies NOS/VE not up.
.                     30/error code, = 0 implies no error, = 1 implies unknown
.                        hardware fault kind.
.

ihf      bss       0
         lxi       x_reg1,a_psa,x_reg1,xp_cx0
         lxi       x_reg2,a_psa,x_reg2,xp_cx0  .RMA of word in memory with parity
                                               . error.
         isob      xa,x_reg1,x0,(40*64)+7  .Mode, monitor or job.
         isob      x6,x_reg1,x0,(48*64)+15  .Trap enable flag and fault kind.
         isob      x5,x_reg1,x0,(56*64)+7  .Fault kind.
         brreq     xa,x0,ihf5          .If job mode.

.        Cause error in monitor mode, issue request to monitor to cause error.  Format
.        of request is as follows:
.                  X0 = 16/0
.                       8/traps enabled flag.
.                       8/fault kind.
.                       32/monitor request code.
.                  X1 = RMA of parity error.

         entp      x0,mtrr#ihf
         shfc      x6,x6,x0,32
         cpyxx     x1,x_reg2           .RMA of parity error.
         iorx      x0,x6               .Monitor request code and parameters for
                                       . request.
         exchange                      .Process monitor request.
         brreq     x0,x0,ihf15         .Return with error status.

.        Inject desired fault in job mode.

ihf5     bss       0
         ente      xa,ihfpl            .jump table length.
         shfc      x5,x5,x0,1          .(jump table index)/2.
         entp      x2,0                .Set known hardware fault kind.
         brrge     xa,x5,ihf10         .If known hardware fault kind.
         entp      x2,1                .Set unknown hardware fault kind.
ihf10    bss     0
         brreq     x2,x0,ihf20         .If known hardware fault kind.

.        Return with error status.

ihf15    bss       0
         cpyxx     x0,x2
         brreq     x0,x0,trap2         .Return with error.

.        x2 = 0, no error.
.        x5 - (jump table index)/2.

ihf20    bss       0
         addpxq    aa,x5,ihfp          .address in jump table to process
                                       . hardware fault kind.
         brdir     aa,x0               .cause specified hardware fault.


.        Define a jump table for each hardware fault kind to cause.

ihfp     bss       0
         brreq     x0,x0,retry         .cause successful retry.
         brreq     x0,x0,exchange      .cause exchange fault.
         brreq     x0,x0,itrap         .cause trap fault.
         brreq     x0,x0,halt          .cause halt fault.
         brreq     x0,x0,pdm_halt      .cause pdm halt fault.
         brreq     x0,x0,swerr         .software error, error stop.
ihfpl    equ       $-ihfp              .length of jump table.


..
.        CMM - Clear synchronous bits in monitor mask register to force processor
.              halt in job mode.  This is required for error processing to work
.              correctly for some errors.
.
.        ENTRY:
.                  Aa = return address.
.
.        EXIT:
.                  The synchronous monitor mask bits in this task's exchange
.                  package are cleared.
.

cmm      bss       0                   .entry.
         ente      x6,80(16)           .subfunction request to clear synchronous
                                       . monitor mask bits.
         entp      x0,mtrr#ihf         .monitor request code.
         shfc      x6,x6,x0,32
         iorx      x0,x6
         exchange
         brdir     aa,x0               .Return.

.        Cause successful retry error.

retry    bss     0
         vfd,32    0fd0e0000(16)       .condition microcode.
         vfd,32    0fe0e0000(16)       .cause hardware fault.
         brreq     x0,x0,ihf15         .Return.

.        Cause exchange error.

exchange bss     0
         vfd,32    0fd1e0000(16)       .condition microcode.
         vfd,32    0fe1e0000(16)       .cause hardware fault.
         brreq     x0,x0,ihf15         .Return.

.        Cause trap error.

itrap    bss     0
         vfd,32    0fd2e0000(16)       .condition microcode.
         vfd,32    0fe2e0000(16)       .cause hardware fault.
         brreq     x0,x0,ihf15         .Return.

.        Cause halt error.

halt     bss     0
         addpxq    aa,x0,halt5         .return address.
         brreq     x0,x0,cmm           .clear bits in monitor mask to halt processor
                                       . on error.
halt5    bss       0
         vfd,32    0fd3e0000(16)       .condition microcode.
         vfd,32    0fe3e0000(16)       .cause hardware fault.
         brreq     x0,x0,ihf15         .Return.

.        Cause PDM halt error.

pdm_halt bss     0
         vfd,32    0fd4e0000(16)       .condition microcode.
         vfd,32    0fe4e0000(16)       .cause hardware fault.
         brreq     x0,x0,ihf15         .Return.

.        Cause software error, error stop.

swerr    bss     0
         addpxq    aa,x0,swerr5        .return address.
         brreq     x0,x0,cmm           .clear bits in monitor mask to halt processor
                                       . on error.
swerr5   bss       0
         halt
         brreq     x0,x0,ihf15         .Return.

         page
.
.        minilink - c170 | c180 memory transfer routine.
.
.        entry :
.
.        TRAP    Xi,Xj,1001
.
.        Xi = pointer to parameter block.
.        Xj = pointer to the data block.
.
.        Parameter block format.
.
. Xi +0  length = words of c170 data to be copied.
. Xi +1  packing type =
.           0 = nos to nos/ve, 60 to 64.
.           1 = nos/ve to nos, 64 to 60.
.           2 = nos to nos/ve, 32 to 64.
.           3 = nos/ve to nos, 64 to 32.
.           4 = nos to nos/ve, 60 to 60.
.           5 = nos/ve to nos, 60 to 60.
.           6 = clear nos/ve memory.
. Xi +2  address space descriptor in bits 56 to 63.
.           0 = from/to dual state control block.
.           1 = from/to NOS/VE proper.
.           2 = from/to SSR.
.           3 = from/to NOS/VE mainframe wired.
.           4 = from DFT buffer, pva must be established previously.
. Xi +3  Byte offset from C180 PVA.
.
. Xj +0  data area for copy.
.
minilink bss       0
.
.        fetch and verify x_reg1 and x_reg2.
.
         lxi       x8,a_psa,x_reg1,xp_cx0
         brrge     x8,x_flc,aor1       .if outside fl
         shfx      x9,x8,x0,3
         incr      x8,4
         brrge     x8,x_flc,aor1       .if outside fl
         lxi       x8,a_psa,x_reg2,xp_cx0 .fetch address of data
         brrge     x8,x_flc,aor1       .if outside fl
.
.        fetch data length and verify data block within fl.
.
         lbyts,2   xa,a_rac,x9,6       .fetch data length
         shfx      xb,x8,x0,3          .byte offset from ra
         addr      x8,xa
         brrgt     x8,x_flc,aor1       .if outside fl
         cpyaa     ab,a_rac
         addax     ab,xb               .start of data area
.
.        form pva descriptor.
.
         lbyts,1   x4,a_rac,x9,2*8+7   .fetch nos/ve pva descriptor
         ente      x2,pva_table_len
         shfx      x4,x4,x0,3
         brrge     x4,x2,iip           .if invalid pva
         lbyts,6   x7,a_static,x4,pva_table
         brxeq     x7,x0,iip           .if pva not defined
         cpyxa     aa,x7
.
.        fetch and verify packing type.
.
         lbyts,1   x7,a_rac,x9,8+7     .fetch packing type
         shfx      x7,x7,x0,1
         ente      x2,cptbll
         brrge     x7,x2,iip           .if not valid packing type
         addpxq    a7,x7,cptbl
.
.        fetch and verify offset to pva.
.
         lbyts,4   x8,a_rac,x9,3*8+4   .fetch offset to pva
         addax     aa,x8
         tpage     x1,aa
         brrge     x0,x1,aor1          .if page not present
         cpyaa     a8,aa
         shfx      x7,x7,x0,-2
         addpxq    a6,x0,cptbm         .multiplier for data length
         lbyts,1   x7,a6,x7,0
         mulr      x7,xa
         shfx      x9,x7,x0,-1
         decr      x9,1                .position of final byte
         addax     a8,x9
         tpage     x1,a8
         brrge     x0,x1,aor1          .if final page missing
         cpyax     x1,aa
         purge     x1,3                .purge cache at start of block
.
.        special case check for the DSCB.
.
         addr      x9,x8               .offset of last byte to move.
         brrne     x4,x0,mini1         .if source/dest not dscb
         ente      x2,dscbl+15         .add 15 to allow for even block size
         brrgt     x9,x2,aor1          .if outside dscb
         brreq     x0,x0,mini14        .complete transfer.
.
.        Verify address within DFT buffers.
.
mini1    bss       0
         ente      x6,4*8
         brrne     x4,x6,mini14        .if source not DFT buffer.
         lbyts,6   x3,a_static,x0,pva_of_first_dftb
         lbyts,2   x6,a_static,x4,pva_table-2  .DFT buffer index.
         brxeq     x3,x0,iip           .if pva not defined.
         cpyxa     a8,x3
         lxi       x7,a8,x6,0          .word to determine length of DFT buffer.
         brrne     x6,x0,mini11        .if not initial part of DFT buffer.
.
.        Determine length of fixed portion of DFT buffer.  This is done in one
.        of two ways depending on the DFT revision level.  Because the length
.        of the 170 CM block size must be an even number, 15 must be added to
.        the length in either case.
.
.        For revision level = 1 the length of the fixed DFT buffer equals
.            the number of maintenance register buffers (nbuf) * 8 + the length
.            of the mainframe element counters buffer (mecbl) + the length of
.            the fixed portion of the DFT buffer (dftbfl) + 15 (to allow for an
.            even block size).
.
.        For revision level > 1 the length of the fixed DFT buffer equals
.            the number of maintenance register buffers (nbuf) * 8 + the length
.            of the mainframe element counters buffer (mecbl) + the number of
.            pointer words (po) * 8 + 15 (to allow for an even block size).
.

         isob      x6,x7,x0,(40*100(8)+7)  .nbuf, number of maintenance
                                           .register buffers.

         isob      xb,x7,x0,(16*100(8)+7)  .DFT revision level.
         isob      x2,x7,x0,(4*100(8)+3)  .po, number of buffer pointers.
         ente      x7,dftbfl+mecbl+15  .initialize for revision level = 1.
         entp      x3,1
         brreq     x3,xb,mini9         .if revision level = 1.
         shfx      x2,x2,x0,3          .po*8.
         ente      x7,mecbl+15         .length of mainframe element counters.
         addr      x7,x2
mini9    shfx      x6,x6,x0,3          .nbuf*8.
         addr      x7,x6               .length of fixed part of DFT buffer.
         brrgt     x9,x7,aor1          .if outside of DFT buffer.
         brreq     x0,x0,mini14        .complete transfer.
.
.        Check if within variable portion of DFT buffer.
.
mini11   bss       0
         isob      x6,x7,x0,6017(8)
         shfx      x6,x6,x0,3
         ente      x7,15               .add 15 to allow for even block size
         addr      x6,x7
         brrgt     x9,x6,aor1          .if outside of variable part of DFT buffer.
.
.        preset and check for instruction interrupt.
.
mini14   entp      x6,0
         entp      x7,0
         entl      x0,bscif
         lbit      xb,a_psa,xp_em+1,x0 .fetch interrupted bit
         brreq     xb,x0,mini15        .if not interrupted
         entp      xb,0
         sbit      xb,a_psa,xp_em+1,x0 .clear interrupted bit
         lbyts,3   x6,a_psa,x0,xp_cx0+1
         lbyts,3   x7,a_psa,x0,xp_cx0+4
mini15   entp      x0,0
         brdir     a7,x0               .branch into table
.
cptbl    bss       0
         brreq     x0,x0,nv60to64      .pack 60 to 64
         brreq     x0,x0,vn64to60      .unpack 64 into 60
         brreq     x0,x0,nv32to64      .pack 32 into 64
         brreq     x0,x0,vn64to32      .unpack 64 into 32
         brreq     x0,x0,nv60to60      .copy nos to nos/ve
         brreq     x0,x0,vn60to60      .copy nos/ve to nos
         brreq     x0,x0,clearve       .clear nos/ve cm
cptbll   equ       $-cptbl
.
cptbm    bss       0
         vfd,8     15                  .60 - 64 bit packing
         vfd,8     8                   .32 - 64 bit packing
         vfd,8     16                  .60 - 60 bit packing
         vfd,8     16                  .memory clear
.
.
.
nv60to64 bss       0                   .pack 60 into 64
         isob      x9,xa,x0,7700(8)
         brrne     x9,x0,aor1          .if not even sized block
mini2    lxi       x3,ab,x6,0
         lxi       x2,ab,x6,8
         insb      x2,x3,x0,0003(8)
         shfx      x3,x3,x0,-4
         sbyts,7   x3,aa,x7,0
         sbyts,8   x2,aa,x7,7
         incr      x7,15
         incr      x6,2
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,mini2           .if no pending exchange
         brreq     x0,x0,mini6         .process exchange interrupt
.
nv32to64 bss       0                   .pack 32 into 64
         lxi       x2,ab,x6,0
         sbyts,4   x2,aa,x7,0
         incr      x7,4
         incr      x6,1
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,nv32to64        .if no exchange pending
         brreq     x0,x0,mini6         .process exchange interrupt
.
nv60to60 bss       0                   .copy 60 to 60
         isob      x1,x8,x0,7502(8)
         brrne     x1,x0,iip           .if invalid starting pva
mini3    bss       0
         lxi       x2,ab,x6,0
         isob      x2,x2,x0,(4*64)+59  .Ensure bits 0 to 3 are zero
         sxi       x2,aa,x7,0
         incr      x7,1
         incr      x6,1
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,mini3           .if no exchange pending
         brreq     x0,x0,mini6         .process exchange interrupt
.
vn64to60 bss       0                   .pack 64 into 60
         isob      x9,xa,x0,7700(8)
         brrne     x9,x0,aor1          .if not even sized block
mini4    lbyts,8   x2,aa,x7,0
         lbyts,7   x3,aa,x7,8
         insb      x3,x2,x0,0403(8)
         shfx      x2,x2,x0,-4
         sxi       x2,ab,x6,0
         sxi       x3,ab,x6,8
         incr      x6,2
         incr      x7,15
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,mini4           .if no exchange pending
         brreq     x0,x0,mini6         .process exchange interrupt
.
vn64to32 bss       0                   .pack 64 into 32
         lbyts,4   x2,aa,x7,0
         sxi       x2,ab,x6,0
         incr      x7,4
         incr      x6,1
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,vn64to32        .if no exchange pending
         brreq     x0,x0,mini6         .process exchange interrupt
.
vn60to60 bss       0                   .copy data
         isob      x1,x8,x0,7502(8)
         brrne     x1,x0,iip           .if invalid starting pva
mini5    bss       0
         lxi       x2,aa,x7,0
         sxi       x2,ab,x6,0
         incr      x7,1
         incr      x6,1
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,mini5           .if no exchange pending
         brreq     x0,x0,mini6         .process exchange interrupt
.
clearve  bss       0                   .clear nos/ve memory
         sbyts,8   x0,aa,x7,0
         incr      x6,1
         incr      x7,8
         brrge     x6,xa,trap2         .if copy complete
         brcr      5,3,clearve         .if no exchange pending
mini6    sbyts,3   x6,a_psa,x0,xp_cx0+1
         sbyts,3   x7,a_psa,x0,xp_cx0+4
         brreq     x0,x0,pii02         .do instruction interrupt
         page
.
.        fetch_pva - Return the value of the specified PVA into Xk.
.
.        Instruction format.
.        017jk 01003 0000000000
.
.        Xj = PVA descriptor.
.          0 = Environment Interface Communications block.
.          1 = Optional PVA 1.
.          2 = Optional PVA 2.
.          3 = Optional PVA 3.
.
fetch_pva bss      0
         lxi       x1,a_psa,x_reg1,xp_cx0  .fetch PVA descriptor
         shfx      x1,x1,x0,3
         brrgt     x0,x1,iip           .if illegal PVA
         ente      x3,pva_table_len
         brrge     x1,x3,iip           .if invalid PVA descriptor
         lbyts,6   x2,a_static,x1,pva_table
         ents      x2                  .clear ring and segment
         sxi       x2,a_psa,x_reg2,xp_cx0  .store PVA value
         brreq     x0,x0,trap2         .exit
.
.***  End common deck OSI$PRIVILAGED_170_INSTRUCTIONS
