{ File name: BLTLineGray.mc Description: BLTLineGray Opcodes ------- BLTLineGray ------- Author: Prabir Mohanty Created: June 2, 1986 } { Copyright (C) 1986 by Xerox Corporation. All rights reserved.} @BLTLINEGRAY: at[ 07, 10, ESCAn ] {********************************************************************************* P O P A R G U M E N T S *********************************************************************************} GCount ← STK, pop, L3 ← 0, c1; temp ← STK, pop, c2; {temp does functions} DstBit ← STK, pop, c3; rhVirtualH ← STK, pop, c1; rVirtualL ← STK, fXpop, fZpop, c2; { Apply Source Function to the Grayword. } { Also the link register L2 is set up for the appropriate destination function. } {Entry point for callers: ChainBLT, TrapzInit} BLGSubEntry: [] ← temp and 1, ZeroBr, c3;{ Test Src function.} rhFunction ← temp LRot0 , XDisp,BRANCH[ ComplementSrc, NullFn], c1; ComplementSrc: Grayword ← ~Grayword,DISP4[LoadDstFunc,09], c2; NullFn: DISP4[LoadDstFunc,09], c2; L2 ← 0, c3, at [ 09, 10, LoadDstFunc ]; rTemp ← GCount, NZeroBr, GOTO[ CallMapDst1 ], c1; L2 ← 8, c3, at [ 0B, 10, LoadDstFunc ]; rTemp ← GCount, NZeroBr, GOTO[ CallMapDst1 ], c1; L2 ← 0A, c3, at [ 0D, 10, LoadDstFunc ]; rTemp ← GCount, NZeroBr, GOTO[ CallMapDst1 ], c1; L2 ← 0C, c3, at [ 0F, 10, LoadDstFunc ]; rTemp ← GCount, NZeroBr, GOTO[ CallMapDst1 ], c1; {********************************************************************************* CODE TO READ NEXT WORD AND CALL ADDRESS CONVERSION IN CASE OF PAGE CROSS *********************************************************************************} ReadNextWord0: rRealDest ← rRealDest - 1, CANCELBR[$,0F], c2; GCount ← rTemp + 0F + 1, GOTO[ReadNextWord2], c3; ReadNextWord1: rRealDest ← rRealDest - 1, c2; GCount ← rTemp + 0F + 1, c3; ReadNextWord2: rRealDest ← MAR ← [rhRealDest, rRealDest + 1], c1;{Addr of source word} [] ← GCount, ZeroBr, BRANCH[ $, PageCarry, 1], c2; SourceData ←MD, BRANCH[CheckBitNumAndCount, BGEXIT], c3; PageCarry0: Noop, c2; PageCarry: { If page carry, update vitual page and remap to get the new real address } rVirtualL ← rVirtualL and ~0FF, CANCELBR[$,1], c3;{mask out low order 8 bits} rVirtualL ← rVirtualL + r0100, CarryBr, { Add hex 100} c1; { Add 1 to rhVirtualH just in case of carry and update if carry } Q ← rhVirtualH + 1,LOOPHOLE[byteTiming],BRANCH[RestoreVirtlow,$], c2; { Update if page carry } rhVirtualH ← Q LRot0, GOTO[CallMapDst0], c3; RestoreVirtlow: Noop, c3; CallMapDst0: rTemp ← GCount, NZeroBr, c1; CallMapDst1: Q ← rhFunction, pCall0, BRANCH[BGDoneWriting,$], c2; {set srcFunc to null, since Grayword has desired value now (no more complementing)} temp ← Q and ~1, CALL[ MapDst] c3, at[L0.BLTLineGray,10]; SourceData ← MD,GOTO [ CheckBitNumAndCount ] c3,MapDstRet[L0.BLTLineGray]; {********************************************************************************* CODE TO DECIDE WHETHER IT IS A BOUNDARY CASE OR FULL WORD CASE *********************************************************************************} CheckBitNumAndCount: { Check if Bitno = 0. } [] ← DstBit, ZeroBr, c1; { Check if GCount >= 16, Branch to ZBitNo if Bitno = 0 or to NZBitNo if it is nonzero } rTemp ← GCount - 0F - 1, CarryBr, BRANCH[NonZeroDstBit, ZeroDstBit], c2; NonZeroDstBit: CANCELBR[$,1], rTemp ← rTemp + DstBit, NegBr, c3; temp ← 010 - DstBit, L0 ← L0.BLTLineGrayStart, BRANCH[ StartCase, UniqueCase ], c1; ZeroDstBit: { Also if GCount >=16 branch to FullWordRead0 which is the full word case, else to ENDCase } temp ← Grayword, BRANCH[ ENDCase, FullWordRead0], c3; StartCase: { Start case occurs when the line to be BLTLineGrayed starts on any bit other than Princops bit 0 and extends for one or more words. In this case, the first word(which is only partially BLTLineGrayed due to nonzero starting bit#) is processed through start case. } {Get a mask of (16 - dst bit#) of 1's right justified in the register temp and rest of temp set to zero } rhTemp ← temp LRot0, CALL[ RMaskN], c2; { The unmodified portion of new Source word is prepared. The bits from 0 to DstBit -1 of the dst word falls into this unmodified portion. Other bits are set to zero. } Q ← (~temp ) and SourceData, c3, RMaskNRet[L0.BLTLineGrayStart]; { The modified portion of dst word is prepared. The bits from DstBit# to bit15 of the new word to be wriiten to dst Word location should have the new information. Other bits are set to zero. } tempC ← temp, c1; temp ← temp and Grayword, L2Disp, c2; tempC ← tempC and SourceData, DISP4[SPerformFn], c3; GOTO[ MixSrcDst0 ], c1, at [ 0, 10, SPerformFn]; temp ← temp and tempC, GOTO[ MixSrcDst0 ], c1, at [08, 10, SPerformFn]; temp ← temp or tempC, GOTO[ MixSrcDst0 ], c1, at [0A, 10, SPerformFn]; temp ← temp xor tempC, GOTO[ MixSrcDst0 ], c1, at [0C, 10, SPerformFn]; { Prepare the word to be written in temp. } MixSrcDst0: temp ← Q or temp, c2; DstBit ← 0, ZeroBr, GOTO[FullWordWrite0], c3; FullWordRead0: MAR ← [ rhRealDest, rRealDest + 0 ], L2Disp, GOTO[DispFn], c1; FullWordRead: MAR ← [ rhRealDest, rRealDest + 0 ], L2Disp, BRANCH[ReadNextWord0, $], c1, at[0E,10,BLGCTRL]; DispFn: DISP4[GPerformFn], c2; temp ← Grayword, GOTO[FullWordWrite0], c3, at[0,10,GPerformFn]; temp ← MD and Grayword, GOTO[FullWordWrite0], c3, at[08,10,GPerformFn]; temp ← MD or Grayword, GOTO[FullWordWrite0], c3, at[0A,10,GPerformFn]; temp ← MD xor Grayword, GOTO[FullWordWrite0], c3, at[0C,10,GPerformFn]; FullWordWrite0: MAR ← [ rhRealDest, rRealDest + 0 ], CANCELBR[$,1], c1; MDR ← temp, rRealDest ← rRealDest + 1, PgCarryBr, L2Disp, GOTO[BranchPcarry], c2; FullWordWrite: MAR ← [ rhRealDest, rRealDest + 0 ],BRANCH[ReadNextWord1, $ ], c1, at[6,10,BLGCTRL]; MDR ← Grayword, rRealDest ← rRealDest + 1 , PgCarryBr, L2Disp, c2; { GCount ← GCount + destination bit# - 16 for Start case and GCount ← GCount - 16 for FullWordwrite case. This value minus 16 was previously calculated and stored in register rTemp. } BranchPcarry:rTemp ← rTemp -0F -1, CarryBr, DISP4[BLGCTRL,6], c3; GCount ← rTemp + 0F + 1, CANCELBR[PageCarry0,1], c1, at[0F,10,BLGCTRL]; GCount ← rTemp + 0F + 1, CANCELBR[PageCarry0,1], c1, at[07,10,BLGCTRL]; UniqueCase: { This case occurs when the starting bit# is nonzero (following Princ Ops naming convention) and the count(the number of bits to be BLTLineGrayed) is so small that the ending bit is in the same word as the starting bit. } { Get a mask of GCount 1's right justified in the register temp and rest of temp is zero } rhTemp ← GCount LRot0, c2; L0 ← L0.BLTLineGrayUnique, rTemp ← - rTemp, CALL[ RMaskN], c3; { The output of RMaskN is set up in temp. } { Left rotate temp by (16 - dst bit # - count) bits. Since rTemp contains (GCount + dst bit# - 16), we just negate it to get the right value. This is done in the microinstruction which precedes this comment.} { The input data to subroutine LRotateN is set up in Q. } Q ← temp, L0 ← L0.BLTLineGray, c1,RMaskNRet[L0.BLTLineGrayUnique]; rhTemp ← rTemp LRot0, CALL[ LRotateN], c2; tempC ← SourceData, c2,LRotateNRet[L0.BLTLineGray]; { The unmodified portions of new Source word is prepared. The bits from 0 to DstBit -1 and bits from DstBit+GCount till end of word fall into this unmodified portion. Other bits are set to zero. } SourceData ← (~rTemp ) and SourceData, c3; tempC ← rTemp and tempC, Xbus ← rhFunction, XDisp, c1; { The modified portion of Source word is prepared. } rTemp ← rTemp and Grayword, DISP4[ UPerformFn, 09], c2; GOTO[ MixSrcDst1 ], c3, at [09, 10, UPerformFn]; rTemp ← rTemp and tempC,GOTO[ MixSrcDst1 ], c3, at [0B, 10, UPerformFn]; rTemp ← rTemp or tempC,GOTO[ MixSrcDst1 ], c3, at [0D, 10, UPerformFn]; rTemp ← rTemp xor tempC,GOTO[ MixSrcDst1 ], c3, at [0F, 10, UPerformFn]; { Prepare the word to be written in rTemp. } MixSrcDst1: Noop, c1; rTemp ← SourceData or rTemp, c2; GOTO[ Finalwrite ] c3; ENDCase: {Get a mask of (16 - GCount) of 1's right justified in the register temp and rest of temp set to zero } rTemp ← - rTemp , L0 ← L0.BLTLineGrayEnd, c1; rhTemp ← rTemp LRot0, CALL[ RMaskN], c2; tempC ← SourceData, c3, RMaskNRet[L0.BLTLineGrayEnd]; SourceData ← (~temp) and SourceData, c1; { The unmodified portion of dst word is prepared in tempC. The bits from updated GCount to bit# 16 of the Source word falls into this unmodified portion. Other bits are set to zero. } tempC ← temp and tempC, Xbus ← rhFunction, XDisp, c2; { The modified portion of Grayword is prepared. } Grayword ← (~temp) and Grayword, DISP4[EPerformFn,09] c3; GOTO[ MixSrcDst2 ], c1, at [09, 10, EPerformFn]; Grayword ← Grayword and SourceData, GOTO[ MixSrcDst2 ], c1, at [0B, 10, EPerformFn]; Grayword ← Grayword or SourceData, GOTO[ MixSrcDst2 ], c1, at [0D, 10, EPerformFn]; Grayword ← Grayword xor SourceData, GOTO[ MixSrcDst2 ], c1, at [0F, 10, EPerformFn]; MixSrcDst2: { Prepare the word to be written in temp. } tempC ← tempC or Grayword, c2; rTemp ← tempC, c3; Finalwrite: MAR ← [ rhRealDest, rRealDest + 0 ], c1; MDR ← rTemp, c2; BGDoneWriting: GOTO[BGEXIT] c3; BGEXIT: L3Disp, c1; DISP4[ BLTLineGrayRet ], c2; {********** E X I T T O M E S A **************} pop, GOTO[Bank1NxtInstc1], c3, at[0, 10, BLTLineGrayRet ]; {********************************************************************************* T h e P a g e F a u l t C a s e: save parameters in stack ********************************************************************************} { Save all the parameters in the stack in case , there is a page fault or write protect fault and so pass control to Fault handlers. } Q ← rhVirtualH, push, c3,MapDstF[L0.BLTLineGray]; STK ← rVirtualL, push, c1; STK ← Q, push, c2; STK ← DstBit, push, c3; STK ← temp, push, c1; STK ← rTemp, GOTO[Bank1Fault], c2;