{ File : NewBitMapBit.mc Author : Gunawan Santosa Created : 26-Feb-85 14:05:34 ================================================================================================ (BITMAPBIT BitMap X Y NewValue) ================================================================================================ if 0 =< NewValue =< max value for a pixel then: Pixel(X, Y) _ NewValue return old Pixel(X, Y) if NewValue = NIL then: return Pixel(X, Y) else ERROR {UFN} in case (X, Y) outside BitMap then return 0 (and no mods) NOTE: BitMap can also be a window UFN in this case! "BitMap" is a six word record of the following format: 0: BitMapBaseHi -- High word of Virtual Addr of [0, 0] of BitMap {upper left screen corner} 1: BitMapBaseLo -- Low word of Virtual Addr of [0, 0] of BitMap {upper left screen corner} 2: BitMapRasterWidth (words) 3: BitMapHeight (lines) 4: BitMapWidth (Pixels) 5: BitMapBitsPerPixel ({1 or 4 or 8}) fetch stack parameters: S - 4: BitMap S - 2: X S - 0: Y TOS: NewValue Test that the TYPE of BitMap = BitMapType fetch BitMap parameters: BitMapBaseHi -- High word of Virtual Addr of [0, 0] of BitMap {upper left screen corner} BitMapBaseLo -- Low word of Virtual Addr of [0, 0] of BitMap {upper left screen corner} BitMapRasterWidth (words) BitMapHeight (lines) BitMapWidth (Pixels) BitMapBitsPerPixel ({1 or 4 or 8}) calculate word-address of pixel, and pixel-mask read old pixel value store new pixel value if appropriate } Set[BitMapType, 35'd]; {For BitMapBit} Set[L0.BMMULT0, 5]; {For BitMapBit} Set[L0.BMMULT1, 6]; {For BitMapBit} Set[L0.BMB.NR.0B, 0B]; {For BitMapBit} Set[L0.GBMP, 9]; {For BitMapBit} RegDef[uBITMAPLO, U, 3A]; {For BitMapBit, low VA of Bitmap, tmp} RegDef[uBITMAPHI, U,3B]; {For BitMapBit, high VA of Bitmap, tmp} RegDef[uYLo, U, 57]; {For BitMapBit, low word of Y, tmp} RegDef[uBITMAPBASELO, U, 42]; {For BitMapBit, low VA of Bitmapbase, tmp} RegDef[uBITMAPBASEHI, U, 44]; {For BitMapBit, high VA of Bitmapbase, tmp} RegDef[uBITMAPRASTERWIDTH, U, 2]; {For BitMapBit, Bitmaprasterwidth, tmp} RegDef[uBITMAPHEIGHT, U, 3]; {For BitMapBit, Bitmapheight, tmp} RegDef[uBITMAPWIDTH, U, 34]; {For BitMapBit, Bitmapwidth, tmp} RegDef[uBITMAPBITSPERPIXEL, U, 7]; {For BitMapBit, Bitmapbitsperpixel, tmp} RegDef[uDBMBaseLo, U, 30]; {For BitMapBit, low VA of Bitmapbase, tmp} RegDef[uDBMBaseHi, U, 51]; {For BitMapBit, high VA of Bitmapbase, tmp} RegDef[uDBRasterWidth, U, 53]; {For BitMapBit, Bitmaprasterwidth, tmp} RegDef[uDBitMapHeight, U, 56]; {For BitMapBit, Bitmapheight, tmp} RegDef[uDBitMapWidth, U, 55]; {For BitMapBit, Bitmapwidth, tmp} RegDef[uDBitsPerPixel, U, 59]; {For BitMapBit, Bitmapbitsperpixel, tmp} RegDef[uTT1, U, 47]; {For BitMapBit, tmp} RegDef[uMASKL, U, 45]; {For BitMapBit, tmp} RegDef[uZ, U, 35]; {For BitMapBit, tmp} { ======================================================================= Fetch BitMap, X, Y, and NewValue ======================================================================= @FLOATARRAY2: opcode[373'b], Bank _ FAOPBank, L1 _ 3{L1.LFA2prep}, c1; uTOS _ TOS, c2; uTOSH _ TOSH, CROSS[FOP2], c3; at[FOP2], Xbus _ ibNA, XDisp, c1; DISP4[FOP2Disp], L2 _ 0, c2; } TT _ S, rhTT _ nRhS, c3, at[06, 10, FOP2Disp]; {Link value for Bitmap parameters fetch} BR000: MAR _ [rhS, S-1], L1 _ L1.NoFixesB2, c1; {Point to high word of Y} TT _ TT - 2, CANCELBR[$, 2], c2; {Prepare TT to fetch X} Q _ MD, c3; MAR _ [rhS, S+0], L3 _ 0, c1; {Point to low word of Y} Ybus _ Q xor smallpl, ZeroBr, c2; Q _ MD, BRANCH[YNOK, $], c3; MAR _ [rhTT, TT-1], c1; {Point to high word of X} uYLo _ Q, CANCELBR[$, 2], c2; {uYLo is low word of Y} Rx _ MD, c3; MAR _ [rhTT, TT+0], c1; {Point to low word of X} TT _ TT-2, L2 _ 6, c2; {Prepare TT to fetch BitMap} Q _ MD, c3; MAR _ [rhTT, TT-1], c1; Ybus _ Rx xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {uXLo is low word of X} Rx _ MD, BRANCH[XNOK, $], c3; {Rx is high VA of BitMap} MAR _ [rhTT, TT+0], c1; uXLo _ Q, c2; {uXHi is high word of X} TT _ MD, CALL[GetandTestBitMapParams], c3; {TT is low VA of BitMap} {Check Type of Bitmap and fetch Record} Ybus _ Q - 1, ZeroBr, c3, at[6, 10, GetBitMapParamsRet]; {Q contains value of Bitsperpixel} { ====================================================== Determine bits per pixel value ====================================================== } Ybus _ Q xor 4, ZeroBr, BRANCH[$, OneBitperPixel], c1; Ybus _ Q xor 8, ZeroBr, BRANCH[$, FourBitsperPixel], c2; TT _ RRot1 uXLo, BRANCH[IllegalBitsperPixel, EightBitsperPixel], c3; {Divide X by 2} OneBitperPixel: uMASKL _ Q, CANCELBR[$], c2; {Load initial mask value (=1)} TT _ uXLo, GOTO[bmbvalchk], c3; {Load X into TT} FourBitsperPixel: Q _ 0F, CANCELBR[$], c3; {Load initial mask value (=0000000000001111)} uMASKL _ Q, c1; TT _ LShift1 uXLo, SE _ 0, c2; {Divide X by 4} TT _ LShift1 TT, SE _ 0, GOTO[bmbvalchk], c3; {Load the result into TT} EightBitsperPixel: Q _ 0FF, c1; {Load initial mask value (=0000000011111111)} uMASKL _ Q, c2; TT _ TT LRot4, GOTO[bmbvalchk], c3; {Multiply TT by 16} bmbvalchk: Rx _ uBITMAPWIDTH, c1; {Check if X inside Bitmap} Ybus _ Rx - TT - 1, CarryBr, c2; uZ _ TT, BRANCH[XValTooBig, $], c3; {uZ = X * Bits per pixel} TT _ TT and ~0F, c1; {Divide TT by 16} TT _ TT LRot12, c2; uXLo _ TT, c3; {uXLo = X * Bits per pixel / 16} Ybus _ Q - TOS, CarryBr, c1; {Check if NewValue doesn't exceed max value} Rx _ uYLo, BRANCH[PixelValueTooBig, $], c2; TT _ uBITMAPHEIGHT, L0 _ L0.BMMULT0, c3; Q _ TT - Rx - 1, CarryBr, c1;{Calculate the Y offset} TOS _ uBITMAPRASTERWIDTH, BRANCH[YValTooBig, $], c2; CALL[MTPL], c3; {Y*Bitmaprasterwidth} { ================================================================================ Calculate address of pixel(X,Y) ================================================================================ Address = (Y*BITMAPRASTERWIDTH + (X*BITMAPBITSPERPIXEL)/16)+BITMAPBASE} Rx _ uXLo, L1 _ L1.RestoreTosB2, c2, at[L0.BMMULT0, 10, MULCALLER]; Rx _ Rx + Q, CarryBr, c3; {Start adding} Q _ uBITMAPBASELO, BRANCH[RXNC1, RXCR1], c1; {Load low word of base address} RXNC1: GOTO[ADCL], c2; {No carry to high order word} RXCR1: TT _ TT + 1, c2; {Propagate carry to high order word} ADCL: Rx _ Rx + Q, CarryBr, c3; {Set up low word of address} AD11: Q _ uBITMAPBASEHI, BRANCH[RXNC2, RXC2], c1; {Load high word of base address} RXNC2: TT _ TT + Q, GOTO[HINC1], c2; RXC2: TT _ TT + Q + 1, c2; {Propagate carry to high word} HINC1: rhTT _ TT LRot0, GOTO[HINC2], c3; {Set up high word of address} { ================================================================================ Read pixel(X,Y) ================================================================================ } HINC2: Map _ TT _ [rhTT, Rx], c1; L0 _ L0.BMB.NR.0B, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, TT + 0], DISP2[BMCHCK], c1, at[L0.BMB.NR.0B, 10, NRWMapFixCallerB2]; uRx _ Q, c2, at[1, 4, BMCHCK]; TT _ MD, c3; {Store it in TT} Rx _ uBITMAPBITSPERPIXEL , c1; Q _ uZ, L0 _ 0A, c2; {Retrieve X*Bits per pixel} Rx _ Q + Rx, YDisp, c3; { ========================================================================== Allign old pixels values ========================================================================== Rotate left by : (((X*Bitsperpixel) mod 16) + Bitsperpixel) mod 16) } Q _ uMASKL, DISP4[Allign], c1; {Allign old pixel value to right hand side} uTTtmp _ TT, c2, at[0A, 10, AllignRet]; {Save the entire word} TT _ TT and Q, c3; {Mask off unwanted bits} uTT1 _ TT, c1; {Save the old value} Ybus _ TOSH xor smallpl, ZeroBr, c2; {Check if TOSH = 0E} TOS _ uTOS, BRANCH[TSQN, TSOK], c3; {Retrieve new value} { ========================================================================= Allign new pixels values ========================================================================= Rotate left by: (16 - Bitsperpixel) - ((X*Bitsperpixel) mod 16) } TSOK: Q _ uTTtmp, c1; {Retrieve the old word} TT _ Q - TT, c2; {Mask off old value} TT _ TT or TOS, L0 _ 0B, c3; {Put the new value in} Ybus _ 0 - Rx, YDisp, c1; Rx _ uRx, DISP4[Allign], c2; {Allign the new word, restore Rx} S _ S - 6, GOTO[WrNV], c3, at[0B, 10, AllignRet]; {Write new word} TSQN: Ybus _ TOSH or TOS, ZeroBr, c1; {Check if new value is NIL} BRANCH[TSNK, TSN], c2; TSN: TOSH _ smallpl, c3; {Set up TOSH} Xbus _ ib, c1; TOS _ uTT1, c2; {Return old value of pixel (X,Y)} S _ S - 6, GOTO[c1.pc2B2], c3; {Exit point when NewValue is NIL} TSNK: GOTO[ufnZ12], c3; { ======================================================================= Write NewValue into pixel(X, Y) ======================================================================= } WrNV: MAR _ [rhRx, Rx + 0], c1; MDR _ TT , Xbus _ ib, c2; {Write it} TOS _ uTT1, GOTO[c1.pc2B2], c3; {Exit point is here} { ============================================== (X,Y) is outside BITMAP or invalid number ============================================== If X or Y is outside BITMAP, return 0. } XNOK: GOTO[ufnX22], c1; YNOK: GOTO[ufnX22], c1; XYER12: TOS _ 0, Xbus _ ib, c1; {If (X,Y) outside bitmap, return 0} TOSH _ smallpl, c2; S _ S - 6, GOTO[c1.pc2B2], c3; XYER13: TOS _ 0, Xbus _ ib, c1; {If (X,Y) outside bitmap, return 0} bmbsettosh: TOSH _ smallpl, c2; S _ S - 6, GOTO[c1.pc2B2], c3; { ====================================================================== Bitmapbitsperpixel other than 1, 4 or 8, or NewValue exceeds max value ====================================================================== } IllegalBitsperPixel: GOTO[ufnX22], c1; PixelValueTooBig: GOTO[ufnX12], c3; XValTooBig: TOS _ 0, Xbus _ ib, GOTO[bmbsettosh], c1; YValTooBig: TOS _ 0, Xbus _ ib, c3; GOTO[bmbsettosh], c1; { ======================================================================= Map check ======================================================================= } GOTO[NRWLMapFixB2], c2, at[0, 4, BMCHCK]; GOTO[NRWLMapFixB2], c2, at[2, 4, BMCHCK]; GOTO[NRWLMapFixB2], c2, at[3, 4, BMCHCK]; { ======================================================================= Multiplier subroutine ======================================================================= Q = multiplicand TOS = multiplier Rx = counter (TT Q) contains the result, Q is least significant word. } MTPL: Rx _ 10, c*{c1}; TT _ 0, c*{c2}; MLLP: Ybus _ Q and 1, NZeroBr, c*{c3}; Rx _ Rx - 1, ZeroBr, BRANCH[MPL0, MPL1], c*{c1}; MPL0: TT _ DARShift1 (TT + 0), BRANCH[MLLP, MLPE], c*{c2}; MPL1: TT _ DARShift1 (TT + TOS), BRANCH[MLLP, MLPE], c*{c2}; MLPE: Q _ ~Q, L0Disp, c*{c3}; RET[MULCALLER], c*{c1}; { ======================================================================= Test type of Bitmap and fetch record of Bitmap ======================================================================= subroutine to check BitMap type and get BitMap parameters Rx, TT have VA of BitMapTable L3 _ 0{Src}/1{Dst} has six or'd in at exit L2 used for return uses NoFixes if PageFault trashes L0, L1, TT, Rx, Q, rhTT, rhRx values from table are placed into: if Src then : uBITMAPBASEHI if Dst then : uDBMBaseHi uBITMAPBASELO uDBMBaseLo uBITMAPRASTERWIDTH uDRasterWidth uBITMAPHEIGHT uDBitMapHeight uBITMAPWIDTH uDBitMapWidth uBITMAPBITSPERPIXEL uDBitsPerPixel Set[L0.GBMP, 09];{must be odd! uses even also}} GetandTestBitMapParams: MAR _ Q _ [TT, Rx + 0], c1;{not mem ref, byte merge} rhTT _ Rx LRot0, c2; Rx _ Q, rhRx _ crhTypeTable, c3; Rx _ Rx LRot8, c1; Rx _ Rx RShift1, getTypemsBit, c2; Q _ 0FF, c3; MAR _ [rhRx, Rx + 0], c1; Rx _ BitMapType, c2; Rx _ MD xor Rx, c3; GetBitMapParams: Map _ [rhTT, TT], L1 _ L1.NoFixesB2, c1; Ybus _ Q and Rx, ZeroBr, L0 _ L0.GBMP, c2; Rx _ rhRx _ MD, XRefBr, BRANCH[notBitMapufn, $], c3; MAR _ Q _ [rhRx, TT + 0], BRANCH[GBMremapit, $], c1, at[L0.GBMP, 10, RMapFixCallerB2]; Rx _ Q, L3Disp, c2; Q _ MD, L3Disp, DISP3[GBMfixitret, 1] c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest1], c1, at[1, 8, GBMfixitret]; uBITMAPBASEHI _ Q, CANCELBR[$, 2], c2; GBMdest1ret: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest2], c1; uBITMAPBASELO _ Q, BRANCH[$, GBMfixitA, 1], c2; GBMdest2ret: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest3, 2], c1, at[3, 8, GBMfixitret]; uBITMAPRASTERWIDTH _ Q, CANCELBR[$, 2], c2; GBMdest3ret: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest4, 6], L3 _ 6, c1; uBITMAPHEIGHT _ Q, BRANCH[$, GBMfixitB, 1], c2; GBMdest4ret: Q _ MD, L3Disp, c3; MAR _ [rhRx, Rx + 1], BRANCH[$, GBMdest5, 6], c1, at[7, 8, GBMfixitret]; uBITMAPWIDTH _ Q, CANCELBR[$, 2], c2; GBMdest5ret: Q _ MD, L3Disp, c3; BRANCH[$, GBMdest6, 6], L2Disp, c1; uBITMAPBITSPERPIXEL _ Q, DISP4[GetBitMapParamsRet], c2; GBMdest1: uDBMBaseHi _ Q, CANCELBR[GBMdest1ret, 2], c2; GBMdest2: uDBMBaseLo _ Q, BRANCH[GBMdest2ret, GBMfixitA, 1], c2; GBMdest3: uDBRasterWidth _ Q, CANCELBR[GBMdest3ret, 2], c2; GBMdest4: uDBitMapHeight _ Q, BRANCH[GBMdest4ret, GBMfixitB, 1], c2; GBMdest5: uDBitMapWidth _ Q, CANCELBR[GBMdest5ret, 2], c2; GBMdest6: uDBitsPerPixel _ Q, DISP4[GetBitMapParamsRet], c2; GBMremapit: CALL[RLMapFixB2], c2; GBMfixitA: TT _ TT and ~0FF, GOTO[GBMallfixit], c3; GBMfixitB: TT _ TT and ~0FF, GOTO[GBMallfixit], c3; GBMallfixit: Q _ 0FF + 1, c1; TT _ TT + Q, CarryBr, c2; Rx _ 0, BRANCH[GetBitMapParams, GBMfixrh], c3; GBMfixrh: Q _ rhTT, c1; Q _ Q + 1, c2; rhTT _ Q LRot0, GOTO[GetBitMapParams], c3; notBitMapufn: CANCELBR[ufnX22, 3], c1; {END}