: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;