:TITLE[JasmineHalftone]; *Last edited by Fiala 7 January 1981, by Maleson 3 April 1980 *Floyd-Steinberg error distribution halftoning, * "REPLACE" mode, * doesn't work for all modes (save space) *Available RM Temps: 44-53 56-57, 66-73; available Unused: 0 **These assignments require that the Mesa stack must not be allowed longer **than 4 words when this code is run. RV4[errorVec,errorVecHi,screenWord,screenWordHi,44]; RV4[bitCount,bitmapWidth,pixelArray,pixelArrayHi,50]; RV4[nInputPixels,blackVal,range,nOutputDots,10]; RV2[AddrTemp,AddrTempHi,14]; RV[CascadeRight,56]; RV[CascadeDiag,57]; RV[bitVal,66]; RV[jctr,67]; RV[x,70]; RV[val,71]; RV[errorTemp,72]; RV[returnLoc,73], SetTask[0]; OnPage[HalftonePage]; *halftone stuff AddrTempHi _ 0C, At[PrintLine]; T _ Stack; AddrTemp _ T, UseCTask; T _ APCTask&APC; returnLoc _ T; PFetch4[AddrTemp,errorVec,4]; PFetch4[AddrTemp,bitCount,10]; T _ LSh[errorVecHi,10], Task; errorVecHi _ (errorVecHi) + T + 1; T _ LSh[screenWordHi,10]; screenWordHi _ (screenWordHi) + T; *no +1, for negative adds; PFetch4[AddrTemp,nInputPixels,0], Task; T _ LSh[pixelArrayHi,10]; pixelArrayHi _ (pixelArrayHi) + T + 1; T _ LdF[bitCount,14,4]; bitVal _ 17C; bitVal _ (bitVal) - T; CycleControl _ bitVal; bitVal _ 100000C; *bitVal _ 100000b rsh (bitCount[12d:15d]) bitVal _ WFA[bitVal]; T _ bitCount; PFetch1[errorVec,CascadeRight]; T _ nOutputDots; jctr _ (Zero) - T; CascadeDiag _ Zero; CascadeRight _ (LSh[CascadeRight,2]) - 1; T _ nInputPixels; Stack4 _ T; T _ LdF[bitmapWidth,4,1]; nInputPixels _ (nInputPixels) + T; x _ T, Goto[forX0]; *subroutines: pieces used by all four modes GetPixel: T _ RSh[x,1], Goto[xDone,ALU<0]; PFetch1[pixelArray,val]; T _ blackVal; LU _ x, Goto[xOdd,R Odd]; xEven: val _ T _ (RSh[val,10]) - T, Goto[blackCheck]; xOdd: val _ T _ (RHMask[val]) - T, Goto[blackCheck]; blackCheck: LU _ (range) - T, Goto[blackOK,ALU>=0]; val _ Zero, Return; blackOK: T _ range, Goto[whiteOK,ALU>=0]; val _ T, Return; whiteOK: xDone1: Return; OrBlack: PFetch1[screenWord,Stack6]; T _ bitVal; Stack6 _ (Stack6) or T, Return; NotWhite: PFetch1[screenWord,Stack6]; T _ bitVal; Stack6 _ (Stack6) and not T, Return; StoreVal: PStore1[screenWord,Stack6], Return; GetError: CascadeRight _ (RSh[CascadeRight,1]) or T, Goto[a1,R Odd]; a0: T _ (RSh[CascadeRight,1]) or T, Goto[a00,R Even]; a01: CascadeRight _ (CascadeRight) + 1; a00: errorTemp _ T, Goto[haveError]; a1: T _ (RSh[CascadeRight,1]) or T, Goto[a10,R Even]; a11: errorTemp _ T _ (Zero) + T + 1, Goto[haveError]; a10: CascadeRight _ (CascadeRight) + 1, Goto[a00]; haveError: CascadeDiag _ (CascadeDiag) + T; T _ bitCount; PStore1[errorVec,CascadeDiag], Return; GetNext: PFetch1[errorVec,Stack6]; T _ errorTemp; CascadeDiag _ T; T _ Stack6; CascadeRight _ (CascadeRight) + T; T _ Stack4, Return; xDone: APCTask&APC _ returnLoc, Goto[xDone1]; forX0: LU _ (nInputPixels) - T - 1, Call[GetPixel]; T _ jctr, Goto[jDone0,R>=0]; whileJ0: T _ val; CascadeRight _ (CascadeRight) + T; T _ range, Goto[White0,ALU>=0]; Black0: T _ LdF[bitCount,0,14], Call[OrBlack]; T _ LdF[bitCount,0,14], Call[StoreVal]; EndDot0: T _ (CascadeRight) AND (100000C), Call[GetError]; bitCount _ T _ (bitCount) + 1, Call[GetNext]; jctr _ (jctr) + T; bitVal _ RCy[bitVal,1], Goto[whileJ0,ALU<0]; jDone0: T _ nOutputDots; jctr _ (jctr) - T; x _ T _ (x) + 1, Goto[forX0]; *could save 7 instructions if jctr still negative White0: CascadeRight _ (CascadeRight) - T; T _ LdF[bitCount,0,14], Call[NotWhite]; T _ LdF[bitCount,0,14]; PStore1[screenWord,Stack6], Goto[EndDot0]; :END;