DIRECTORY RasterOp USING [Offset], Basics; RasterOpCharBltImpl: PROGRAM IMPORTS Basics EXPORTS RasterOp = BEGIN OPEN Basics; Word: TYPE = WORD; WordPtr: TYPE = LONG POINTER TO Word; Offset: TYPE = RasterOp.Offset; bpw: CARDINAL = BITS[Word]; upw: CARDINAL = SIZE[Word]; bpu: CARDINAL = BITS[UNIT]; OrBlt: PUBLIC PROC [src: WordPtr, dst: WordPtr, offset: Offset, bpc: CARDINAL, upl: INT, lines: INT] = { sw: Word; dw: Word; tw: Word ¬ offset+bpc; shiftL: Offset; GetD: PROC [dstOff: CARDINAL] = INLINE {dw ¬ (dst+dstOff)­}; GetS: PROC [srcOff: CARDINAL] = INLINE {sw ¬ (src+srcOff)­}; Put: PROC [dstOff: CARDINAL] = INLINE {(dst+dstOff)­ ¬ dw}; Func: PROC = INLINE {dw ¬ BITOR[dw, sw]}; FuncT: PROC = INLINE {dw ¬ BITOR[dw, tw]}; FuncShR: PROC = INLINE {tw ¬ BITRSHIFT[sw, offset]; FuncT[]}; FuncShL: PROC = INLINE {tw ¬ BITLSHIFT[sw, shiftL]; FuncT[]}; BumpD: PROC = INLINE {dst ¬ dst + upl}; SELECT TRUE FROM bpc <= bpw => { IF tw <= bpw THEN { IF offset = 0 THEN { DoOne: PROC = INLINE {GetD[0]; Func[]; Put[0]}; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; } ELSE { DoOne: PROC = INLINE {GetD[0]; FuncShR[]; Put[0]}; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; }; } ELSE { DoOne: PROC = INLINE { GetD[0]; FuncShR[]; Put[0]; GetD[upw]; FuncShL[]; Put[upw]; }; shiftL ¬ bpw - offset; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; }; }; bpc <= bpw*2 => { IF offset = 0 THEN { WHILE lines > 0 DO GetD[0]; GetS[0]; Func[]; Put[0]; GetD[upw]; GetS[upw]; Func[]; Put[upw]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; RETURN; } ELSE { shiftL ¬ bpw - offset; IF tw <= bpw*2 THEN { WHILE lines > 0 DO GetD[upw*0]; <> GetS[upw*0]; FuncShR[]; Put[upw*0]; GetD[upw*1]; FuncShL[]; GetS[upw*1]; FuncShR[]; Put[upw*1]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; } ELSE { WHILE lines > 0 DO GetD[upw*0]; <> GetS[upw*0]; FuncShR[]; Put[upw*0]; GetD[upw*1]; FuncShL[]; GetS[upw*1]; FuncShR[]; Put[upw*1]; GetD[upw*2]; FuncShL[]; <> <> Put[upw*2]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; }; RETURN; }; }; ENDCASE => { rem: CARD; IF offset = 0 THEN { bpc ¬ bpc - bpw; WHILE lines > 0 DO nextDst: WordPtr = dst + upl; rem ¬ bpc; GetD[0]; GetS[0]; Func[]; Put[0]; DO dst ¬ dst + upw; src ¬ src + upw; GetD[0]; GetS[0]; Func[]; Put[0]; IF rem <= bpw THEN EXIT; rem ¬ rem - bpw; ENDLOOP; dst ¬ nextDst; src ¬ src + upw; lines ¬ lines - 1; ENDLOOP; RETURN; } ELSE { shiftL ¬ bpw - offset; WHILE lines > 0 DO nextDst: WordPtr = dst + upl; rem ¬ bpc; GetD[0]; DO GetS[0]; FuncShR[]; Put[0]; dst ¬ dst + upw; GetD[0]; FuncShL[]; src ¬ src + upw; IF rem <= bpw THEN EXIT; rem ¬ rem - bpw; ENDLOOP; Put[0]; dst ¬ nextDst; lines ¬ lines - 1; ENDLOOP; RETURN; }; }; }; AndCBlt: PUBLIC PROC [src: WordPtr, dst: WordPtr, offset: Offset, bpc: CARDINAL, upl: INT, lines: INT] = { sw: Word; dw: Word; tw: Word ¬ offset+bpc; shiftL: Offset; GetD: PROC [dstOff: CARDINAL] = INLINE {dw ¬ (dst+dstOff)­}; GetS: PROC [srcOff: CARDINAL] = INLINE {sw ¬ (src+srcOff)­}; Put: PROC [dstOff: CARDINAL] = INLINE {(dst+dstOff)­ ¬ dw}; Func: PROC = INLINE {dw ¬ BITAND[dw, BITNOT[sw]]}; FuncT: PROC = INLINE {dw ¬ BITAND[dw, BITNOT[tw]]}; FuncShR: PROC = INLINE {tw ¬ BITRSHIFT[sw, offset]; FuncT[]}; FuncShL: PROC = INLINE {tw ¬ BITLSHIFT[sw, shiftL]; FuncT[]}; BumpD: PROC = INLINE {dst ¬ dst + upl}; SELECT TRUE FROM bpc <= bpw => { IF tw <= bpw THEN { IF offset = 0 THEN { DoOne: PROC = INLINE {GetD[0]; Func[]; Put[0]}; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; } ELSE { DoOne: PROC = INLINE {GetD[0]; FuncShR[]; Put[0]}; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; }; } ELSE { DoOne: PROC = INLINE { GetD[0]; FuncShR[]; Put[0]; GetD[upw]; FuncShL[]; Put[upw]; }; shiftL ¬ bpw - offset; DO IF lines >= 4 THEN { GetS[0*upw]; DoOne[]; BumpD[]; GetS[1*upw]; DoOne[]; BumpD[]; GetS[2*upw]; DoOne[]; BumpD[]; GetS[3*upw]; DoOne[]; BumpD[]; src ¬ src + upw*4; lines ¬ lines - 4; LOOP; }; IF lines = 0 THEN RETURN; GetS[0*upw]; DoOne[]; IF lines = 1 THEN RETURN; GetS[1*upw]; BumpD[]; DoOne[]; IF lines = 2 THEN RETURN; GetS[2*upw]; BumpD[]; DoOne[]; RETURN; ENDLOOP; }; }; bpc <= bpw*2 => { IF offset = 0 THEN { WHILE lines > 0 DO GetD[0]; GetS[0]; Func[]; Put[0]; GetD[upw]; GetS[upw]; Func[]; Put[upw]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; RETURN; } ELSE { shiftL ¬ bpw - offset; IF tw <= bpw*2 THEN { WHILE lines > 0 DO GetD[upw*0]; <> GetS[upw*0]; FuncShR[]; Put[upw*0]; GetD[upw*1]; FuncShL[]; GetS[upw*1]; FuncShR[]; Put[upw*1]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; } ELSE { WHILE lines > 0 DO GetD[upw*0]; <> GetS[upw*0]; FuncShR[]; Put[upw*0]; GetD[upw*1]; FuncShL[]; GetS[upw*1]; FuncShR[]; Put[upw*1]; GetD[upw*2]; FuncShL[]; <> <> Put[upw*2]; src ¬ src + upw*2; dst ¬ dst + upl; lines ¬ lines - 1; ENDLOOP; }; RETURN; }; }; ENDCASE => { rem: CARD; IF offset = 0 THEN { bpc ¬ bpc - bpw; WHILE lines > 0 DO nextDst: WordPtr = dst + upl; rem ¬ bpc; GetD[0]; GetS[0]; Func[]; Put[0]; DO dst ¬ dst + upw; src ¬ src + upw; GetD[0]; GetS[0]; Func[]; Put[0]; IF rem <= bpw THEN EXIT; rem ¬ rem - bpw; ENDLOOP; dst ¬ nextDst; src ¬ src + upw; lines ¬ lines - 1; ENDLOOP; RETURN; } ELSE { shiftL ¬ bpw - offset; WHILE lines > 0 DO nextDst: WordPtr = dst + upl; rem ¬ bpc; GetD[0]; DO GetS[0]; FuncShR[]; Put[0]; dst ¬ dst + upw; GetD[0]; FuncShL[]; src ¬ src + upw; IF rem <= bpw THEN EXIT; rem ¬ rem - bpw; ENDLOOP; Put[0]; dst ¬ nextDst; lines ¬ lines - 1; ENDLOOP; RETURN; }; }; }; FillWords: PUBLIC PROC [dst: WordPtr, len: INT, fill: Word] = { WHILE len >= 8 DO (dst+0*upw)­ ¬ fill; (dst+1*upw)­ ¬ fill; (dst+2*upw)­ ¬ fill; (dst+3*upw)­ ¬ fill; (dst+4*upw)­ ¬ fill; (dst+5*upw)­ ¬ fill; (dst+6*upw)­ ¬ fill; (dst+7*upw)­ ¬ fill; dst ¬ dst + 8*upw; len ¬ len - 8; ENDLOOP; IF len >= 4 THEN { (dst+0*upw)­ ¬ fill; (dst+1*upw)­ ¬ fill; (dst+2*upw)­ ¬ fill; (dst+3*upw)­ ¬ fill; dst ¬ dst + 4*upw; len ¬ len - 4; }; IF len >= 2 THEN { (dst+0*upw)­ ¬ fill; (dst+1*upw)­ ¬ fill; dst ¬ dst + 2*upw; len ¬ len - 2; }; IF len >= 1 THEN { (dst+0*upw)­ ¬ fill; }; }; END. ŠRasterOpCharBltImpl.mesa Copyright Σ 1988, 1990, 1991 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) October 29, 1990 1:58 pm PST Michael Plass, October 1, 1991 11:09 am PDT Each scan line fits in a single dst word The aligned case, no shifting Unaligned, but still in one dst word Each scan line fits in a single src word, 2 dst words Each char is 2 words per scan line Two-word aligned Two-word unaligned Two src words, two dst words Two src words, three dst words Multi-word transfers Multi-word aligned Multi-word unaligned Each scan line fits in a single dst word The aligned case, no shifting Unaligned, but still in one dst word Each scan line fits in a single src word, 2 dst words Each char is 2 words per scan line Two-word aligned Two-word unaligned Two src words, two dst words Two src words, three dst words Multi-word transfers Multi-word aligned Multi-word unaligned Κ Α•NewlineDelimiter –(cedarcode) style˜head™Icodešœ Οeœ=™HL™0L™+—˜šΟk ˜ Lšœ žœ ˜Lšœ˜——šœΟn œž˜Lšžœ˜Lšžœ ˜Lšœžœžœ˜L˜Lšœžœžœ˜Lš œ žœžœžœžœ˜%Lšœžœ žœ˜L˜Lšœžœžœ˜Lšœžœžœ˜Lšœžœžœžœ˜L˜š Ÿœžœžœ3žœžœ žœ˜hL˜Lšœ ˜ Lšœ ˜ Lšœ˜Lšœ˜L˜LšŸœžœ žœžœ˜LšŸœžœžœž œ˜>LšŸœžœžœ˜'L˜šžœžœž˜˜šžœ ˜ šžœ˜L™(šžœ ˜ šžœ˜L™LšŸœžœžœ˜/šž˜šžœ žœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜Lšžœ˜L˜—Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ˜Lšžœ˜—L˜—šžœ˜L™$LšŸœžœžœ˜2šž˜šžœ žœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜Lšžœ˜L˜—Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ˜Lšžœ˜—L˜——L˜—šžœ˜L™5šŸœžœžœ˜Lšœ˜Lšœ˜L˜—Lšœ˜šž˜šžœ žœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜Lšžœ˜L˜—Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ žœžœ˜Lšœ˜Lšžœ˜Lšžœ˜—L˜——L˜—šœ˜L™"šžœ ˜ šžœ˜L™šžœ ž˜Lšœ!˜!Lšœ'˜'Lšœ˜Lšœ˜L˜Lšžœ˜—Lšžœ˜L˜—šžœ˜L™Lšœ˜šžœ ˜šžœ˜L™šžœ ž˜Lšœ;˜;Lšœ;˜;L˜Lšœ˜L˜Lšžœ˜—L˜—šžœ˜L™šžœ ž˜Lšœ;˜;Lšœ;˜;Lšœ<˜