:TITLE[JasmineHalftone]; %Edit by Fiala 16 July 1981: Harmonize with Pilot; change register assignments to use more of available Stack registers; eliminate returnLoc register; add prefix jh to register names. Edit by Fiala 7 January 1981: Harmonize with Alto system; bum many mi. Created by Maleson 3 April 1980. Floyd-Steinberg error distribution halftoning, "REPLACE" mode doesn't work for all modes (save space) % SetTask[0]; *jhTemp1 (RM 5) and jhTemp2 (RM 7) are also used. :IF[AltoMode]; ********************************** RV4[jhErrorVec,jhErrorVecHi,jhScreenWord,jhScreenWordHi,44]; RV4[jhBitCount,jhBitmapWidth,jhPixelArray,jhPixelArrayHi,50]; RV4[jhNInputPixels,jhBlackVal,jhRange,jhNOutputDots,10]; RV2[jhAddrTemp,jhAddrTempHi,14]; RV[jhCascadeRight,56]; RV[jhCascadeDiag,57]; RV[jhBitVal,66]; RV[jhJCtr,67]; RV[jhX,2]; RV[jhVal,3]; RV[jhErrorTemp,4]; RV[jhTemp1,5]; RV[jhTemp2,7]; :ELSE; ****************************************** *It seems that RM 6, 16-17 and 70-73 are available temporaries. RV4[jhErrorVec,jhErrorVecHi,jhScreenWord,jhScreenWordHi,44]; RV4[jhBitCount,jhBitmapWidth,jhPixelArray,jhPixelArrayHi,50]; RV4[jhNInputPixels,jhBlackVal,jhRange,jhNOutputDots,10]; RV2[jhAddrTemp,jhAddrTempHi,14]; RV[jhCascadeRight,56]; RV[jhCascadeDiag,57]; RV[jhBitVal,66]; RV[jhJCtr,67]; RV[jhX,2]; RV[jhVal,3]; RV[jhErrorTemp,4]; RV[jhTemp1,5]; RV[jhTemp2,7]; :ENDIF; ***************************************** OnPage[HalftonePage]; ***Find out whether MDShi should be used here and/or in Jasmine.Mc instead of ***0C for the high base register value. @JHalfTone: jhAddrTempHi _ 0C, At[PrintLine]; T _ Stack; jhAddrTemp _ T; PFetch4[jhAddrTemp,jhErrorVec,4]; PFetch4[jhAddrTemp,jhBitCount,10]; T _ LSh[jhErrorVecHi,10], Task; jhErrorVecHi _ (jhErrorVecHi) + T + 1; T _ LSh[jhScreenWordHi,10]; jhScreenWordHi _ (jhScreenWordHi) + T; *no +1, for negative adds; PFetch4[jhAddrTemp,jhNInputPixels,0], Task; T _ LSh[jhPixelArrayHi,10]; jhPixelArrayHi _ (jhPixelArrayHi) + T + 1; T _ LdF[jhBitCount,14,4]; jhBitVal _ 17C; jhBitVal _ (jhBitVal) - T; CycleControl _ jhBitVal; jhBitVal _ 100000C; *jhBitVal _ 100000b rsh (jhBitCount[12d:15d]) jhBitVal _ WFA[jhBitVal]; T _ jhBitCount; PFetch1[jhErrorVec,jhCascadeRight]; T _ jhNOutputDots; jhJCtr _ (Zero) - T; jhCascadeDiag _ Zero; jhCascadeRight _ (LSh[jhCascadeRight,2]) - 1; T _ jhNInputPixels; jhTemp1 _ T; T _ LdF[jhBitmapWidth,4,1]; jhNInputPixels _ (jhNInputPixels) + T; jhX _ T, GoTo[forX0]; *subroutines: pieces used by all four modes GetPixel: T _ RSh[jhX,1], GoTo[xDone,ALU<0]; PFetch1[jhPixelArray,jhVal]; T _ jhBlackVal; LU _ jhX, GoTo[xOdd,R Odd]; xEven: jhVal _ T _ (RSh[jhVal,10]) - T, GoTo[blackCheck]; xOdd: jhVal _ T _ (RHMask[jhVal]) - T, GoTo[blackCheck]; blackCheck: LU _ (jhRange) - T, GoTo[blackOK,ALU>=0]; jhVal _ Zero, Return; blackOK: T _ jhRange, GoTo[whiteOK,ALU>=0]; jhVal _ T, Return; whiteOK: Return; OrBlack: PFetch1[jhScreenWord,jhTemp2]; T _ jhBitVal; jhTemp2 _ (jhTemp2) or T, Return; NotWhite: PFetch1[jhScreenWord,jhTemp2]; T _ jhBitVal; jhTemp2 _ (jhTemp2) and not T, Return; StoreVal: PStore1[jhScreenWord,jhTemp2], Return; GetError: jhCascadeRight _ (RSh[jhCascadeRight,1]) or T, GoTo[a1,R Odd]; a0: T _ (RSh[jhCascadeRight,1]) or T, GoTo[a00,R Even]; a01: jhCascadeRight _ (jhCascadeRight) + 1; a00: jhErrorTemp _ T, GoTo[haveError]; a1: T _ (RSh[jhCascadeRight,1]) or T, GoTo[a10,R Even]; a11: jhErrorTemp _ T _ (Zero) + T + 1, GoTo[haveError]; a10: jhCascadeRight _ (jhCascadeRight) + 1, GoTo[a00]; haveError: jhCascadeDiag _ (jhCascadeDiag) + T; T _ jhBitCount; PStore1[jhErrorVec,jhCascadeDiag], Return; GetNext: PFetch1[jhErrorVec,jhTemp2]; T _ jhErrorTemp; jhCascadeDiag _ T; T _ jhTemp2; jhCascadeRight _ (jhCascadeRight) + T; T _ jhTemp1, Return; xDone: LoadPageExternal[opPage3]; GoToExternal[P7TailLoc]; forX0: LU _ (jhNInputPixels) - T - 1, Call[GetPixel]; T _ jhJCtr, GoTo[jDone0,R>=0]; whileJ0: T _ jhVal; jhCascadeRight _ (jhCascadeRight) + T; T _ jhRange, GoTo[White0,ALU>=0]; Black0: T _ LdF[jhBitCount,0,14], Call[OrBlack]; T _ LdF[jhBitCount,0,14], Call[StoreVal]; EndDot0: T _ (jhCascadeRight) and (100000C), Call[GetError]; jhBitCount _ T _ (jhBitCount) + 1, Call[GetNext]; jhJCtr _ (jhJCtr) + T; jhBitVal _ RCy[jhBitVal,1], GoTo[whileJ0,ALU<0]; jDone0: T _ jhNOutputDots; jhJCtr _ (jhJCtr) - T; jhX _ T _ (jhX) + 1, GoTo[forX0]; *could save 7 mi if jhJCtr still negative White0: jhCascadeRight _ (jhCascadeRight) - T; T _ LdF[jhBitCount,0,14], Call[NotWhite]; T _ LdF[jhBitCount,0,14]; PStore1[jhScreenWord,jhTemp2], GoTo[EndDot0]; :END[JasmineHalftone]; (2048)\f5