{ File : LispBitMapBit.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, 1E]; {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, NegBr, 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, NegBr, c1; {Check if NewValue doesn't exceed max value} Rx ← uYLo, BRANCH[$, PixelValueTooBig], c2; TT ← uBITMAPHEIGHT, L0 ← L0.BMMULT0, c3; Q ← TT - Rx - 1, NegBr, 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[ufnZ1], 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[ufnX2], c1; YNOK: GOTO[ufnX2], 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[ufnX2], c1; PixelValueTooBig: GOTO[ufnX1], 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[ufnX2, 3], c1; {END}