{ File Name: ChainBlt.mc Description: ChainBlt writes out a pattern of alternating runs of zeros and runs of ones. This operation is very similar to BLTLineGray except for the parameters that are passed to the instruction and the amount of data that can be processed. A run of data can be up to 64K bits long. The processing steps are as follows : get parameters from stack, check length, fetch the count of the run from base address; check page fault, if no page fault, bring in pages to write the run, set up BltLineGray parameters, call BltlineGray to write the run, decrement length; check if done, if not, update destination bit address,increment base address, toggle the writeBit, and check for any interrupts;if no, then go back to loop for the next run. If interrupt happened, it will branch to interrupt handler and back to the entrance of CHAINBLT after that. Page fault will be handlered the same except it will branch to page fault handler. Author: MYT Created: July 19, 1986 July 30, 1986 mass assembler Aug. 03, 1986 length <= 0 Aug. 04, 1986 goto writerun Aug 05, stackP correct Aug 06, interrupt checking ok Aug 08, move to bank 1 Aug 12, fix bug in calling parameters to BumpBitAddress Aug 13, bug in page fault from ComMap Edited: Sep 18, optimization xxx Last Edited: Oct 08, complete testing optimization codes xxx } { Copyright (C) 1986 by XEROX corporation. All rights reserved.} @CHAINBLT: {**************************************************************************************** POP Parameters from stack ****************************************************************************************} {length = TOS} rhchainbaseh ← STK, pop, c1, at [09,10,ESCAn]; rchainbasel ← STK, pop, c2; writebit ← STK, pop, c3; DBit ← STK, pop, c1; rhdsthigh ← STK, pop, c2; rdstlow ← STK, pop, L0 ← L0.ChainBlt, c3; {**************************************************************************************** Check length ****************************************************************************************} ChkLength: [] ← length, ZeroBr, pop, c1;{ length is a cardinal*opt* } rchaintemp ← rdstlow,BRANCH[$,ChainExit3], c2;{ xxx*opt* } { save r1 = rdstlow before call MapSrc } {***************************************************************************************** Fetch word at base address *****************************************************************************************} Fetch: CALL [MapSrc], c3; { xxx*opt*} { MapSrc routine called here } bitWidth ← MD,L2 ← 0, c3, MapSrcRet[L0.ChainBlt]; {L2 is caller to save register} {**************************************************************************************** Call ComMap to determine pages needed to write the run, L1 - Src/Dst mapping flag (0/1), L3 - caller, *****************************************************************************************} chkdata: L3 ← L3.ChainBlt, CALL[SaveChainReg], c1; L1 ← 1, CALL[ComMap], c3, at [0,10,SaveChainRegRet]; writebit ← USavewritebit, BRANCH[WriteRun,ToPageFault], c2, at [L3.ChainBlt,10,ComMapRet]; {restore write bit value } {**************************************************************************************** If page ok, set up parameters to call BLTLineGray to write the run *****************************************************************************************} WriteRun: GCount ← USavecount, c3; { set function = 0 } temp ← 0, c1; { set up starting bit to write out the run } DstBit ← USavedstbit, c2; { set up destination address to write the run } rhVirtualH ← USavedsthigh, c3; rVirtualL ← USavedstlow, c1; { set up grey word } [] ← writebit, ZeroBr, L3 ← L3.ChainBltBLG, c2; Grayword ← 0, BRANCH[WriteOne,$], c3; WriteZero: GOTO[CallBLTLineGray], c1; WriteOne: Grayword ← ~ Grayword, c1; CallBLTLineGray: CALL[BLGSubEntry], c2; ChkStkP: L5 ← 2, CALL[RestoreChainReg], c3, at [L3.ChainBltBLG,10,BLTLineGrayRet]; {8/4/86} {**************************************************************************************** decrement length variable, check if more run to perform; *****************************************************************************************} ChkExit: length ← length - 1, ZeroBr, c2, at [2,10,RestoreChainRegRet]; USavelength ← length, BRANCH[$,ChainExit1], c3; {**************************************************************************************** set up parameters to call BumpBitAddress *****************************************************************************************} ToBump: offset ← bitWidth, L4 ← L4.ChainBlt, c1; {bitnum = DBit} rwrdaddl ← USavedstlow, c2; rwrdaddh ← USavedsthigh, CALL[BBASubEntry], c3; { BumpBitAddress is here c1 - c2 } ResBump: Q ← rwrdaddh, c3, at[9,10,BumpBitAddressRet]; rhdsthigh ← Q LRot0, c1; writebit ← USavewritebit, c2; {restore write bit value } rdstlow ← rwrdaddl, c3; rchainbasel ← USavechainbasel, c1; Q ← USavechainbaseh, c2; rhchainbaseh ← Q LRot0, c3; {**************************************************************************************** Get next run *****************************************************************************************} rchainbasel ← rchainbasel + 1, CarryBr, c1; {increment word base to point to next location} MesaIntBr, BRANCH[ChkInt,$], c2; Q ← rhchainbaseh, CANCELBR[$], c3; Q ← Q + 1, c1; rhchainbaseh ← Q LRot0, MesaIntBr, c2; {**************************************************************************************** toggle the writebit *****************************************************************************************} ChkInt: writebit ← writebit xor 1,BRANCH[$,YesInt], c3;{toggle the bit } L0 ← L0.ChainBlt, c1;{xxx} rchaintemp ← rdstlow, GOTO[Fetch], c2;{save R1 to rchaintemp in case page fault happens xxx} {**************************************************************************************** interrupt checking *****************************************************************************************} YesInt: stackP ← 2, c1; Q ← rhdsthigh, c2; STK ← rdstlow, push, c3; STK ← Q, push, c1; STK ← DBit, push, c2; STK ← writebit, push, c3; Yes5: Q ← rhchainbaseh, c1; Yes6: STK ← rchainbasel, push, c2; STK ← Q, GOTO[Bank1Interrupt], c3; {TOS = length} {**************************************************************************************** page fault case *****************************************************************************************} ToPageFault: rchaintemp ← USavedstlow, c3; {restore base address to rchaintemp = rdstlow 8/12 corrected } length ← USavelength, c1; uFaultParm0 ← VD, c2;{set up fault 8/13} T ← Q, c3;{set up fault virtual address 8/13} Q ← rhVD, c1; uFaultParm1 ← Q, c2; rchainbasel ← USavechainbasel, c3;{8/12} Noop, c1; GOTO[PageFaultChain], c2; {**************************************************************************************** save parameters on the stack, if page fault happened *****************************************************************************************} PageFaultChain: stackP ← 2, c3, MapSrcF[L0.ChainBlt]; Q ← rhdsthigh, c1; STK ← rchaintemp, push, c2; {push rdstlow} STK ← Q, push, c3; STK ← DBit, push, c1; STK ← writebit, push, c2; Q ← rhchainbaseh, c3; STK ← rchainbasel, push, c1; STK ← Q, GOTO [Bank1Fault], c2; {TOS = length} {**************************************************************************************** Exit from mesa *****************************************************************************************} ChainExit1: Noop, c1; Noop, c2; ChainExit3: CANCELBR[Bank1NxtInstc1], c3;