insert[d0lang]; insert[GlobalDefs]; TITLE [Halftone -- April 3, 1980 7:52 AM]; * Floyd-Steinberg error distribution halftoning, * "REPLACE" mode, doesn't work for all modes (save space) SET TASK[0]; ONPAGE[InitPage]; * Registers for test program * Available Temps: 40-53 56-57, 64, 66-67, 72-73 * Available Unused: 14, 70-71 RV [nInputPixels,40]; RV [blackVal,41]; RV [range,42]; RV [nOutputDots,43]; RV [errorVec,44]; RV [errorVecHi,45]; RV [screenWord,46]; RV [screenWordHi,47]; RV [bitCount,50]; RV [bitmapWidth,51]; RV [pixelArray,52]; RV [pixelArrayHi,53]; RV [AddrTemp,10]; *same as Stack7 RV [AddrTempHi,11]; RV [CascadeRight,56]; RV [CascadeDiag,57]; RV [errorTemp,72]; RV [bitval,66]; RV [jctr,67]; RV [x,70]; RV [val,71]; RV [returnLoc,73], * New names for standard registers * At locations SET [PrintLine,ADD[LSHIFT[InitPage,10],000]]; * Starting location SET [bLoc,ADD[LSHIFT[InitPage,10],020]]; * SET [modeLoc,ADD[LSHIFT[InitPage,10],040]]; * SET [modeLoc1,ADD[LSHIFT[InitPage,10],060]]; * * halftone stuff AT[PrintLine], AddrTempHi _ (0c); T _ Stack; AddrTemp _ T; PFetch4[AddrTemp,errorVec,4]; useCTask; T _ APC&APCTask; returnLoc _ T; 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]; DISPATCH[bitCount,14,4]; pixelArrayHi _ (pixelArrayHi)+T+1,DISP[b0]; *bit selection dispatch table b0: bitval _ (100000c),GOTO[b20],AT[bLoc,0]; b1: bitval _ (40000c),GOTO[b20],AT[bLoc,1]; b2: bitval _ (20000c),GOTO[b20],AT[bLoc,2]; b3: bitval _ (10000c),GOTO[b20],AT[bLoc,3]; b4: bitval _ (4000c),GOTO[b20],AT[bLoc,4]; b5: bitval _ (2000c),GOTO[b20],AT[bLoc,5]; b6: bitval _ (1000c),GOTO[b20],AT[bLoc,6]; b7: bitval _ (400c),GOTO[b20],AT[bLoc,7]; b10: bitval _ (200c),GOTO[b20],AT[bLoc,10]; b11: bitval _ (100c),GOTO[b20],AT[bLoc,11]; b12: bitval _ (40c),GOTO[b20],AT[bLoc,12]; b13: bitval _ (20c),GOTO[b20],AT[bLoc,13]; b14: bitval _ (10c),GOTO[b20],AT[bLoc,14]; b15: bitval _ (4c),GOTO[b20],AT[bLoc,15]; b16: bitval _ (2c),GOTO[b20],AT[bLoc,16]; b17: bitval _ (1c),GOTO[b20],AT[bLoc,17]; b20: 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: 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: APC&APCTask _ returnLoc; RETURN; forX0: LU _ (nInputPixels) - T - 1,CALL[GetPixel]; *5 instrs 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]; *3 instrs T _ LDF[bitCount,0,14],CALL[StoreVal]; *1 instr EndDot0: T _ (CascadeRight) AND (100000c),CALL[GetError]; *6.5 instrs bitCount _ T _ (bitCount) + 1,CALL[GetNext]; *6 instrs 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]; *3 instrs T _ LDF[bitCount,0,14]; *1 instr PStore1[screenWord,Stack6],GOTO[EndDot0]; % the rest of this stuff is deleted for space with jasmine code forX1: LU _ (nInputPixels) - T - 1,CALL[GetPixel]; *5 instrs T _ jctr,GOTO[jDone1,R>=0]; whileJ1: T _ val; CascadeRight _ (CascadeRight)+T; T_range,GOTO[White1,ALU>=0]; Black1: T _ LDF[bitCount,0,14],CALL[OrBlack]; *3 instrs T _ LDF[bitCount,0,14],CALL[StoreVal]; *1 instr EndDot1: T _ (CascadeRight) AND (100000c),CALL[GetError]; *6.5 instrs bitCount _ T _ (bitCount) - 1,CALL[GetNext]; *6 instrs jctr _ (jctr) + T; bitVal _ LCY[bitVal,1],GOTO[whileJ1,ALU<0]; jDone1: T _ nOutputDots; jctr _ (jctr) - T; x _ T _ (x) + 1,GOTO[forX1]; *could save 7 instructions if jctr still negative White1: CascadeRight _ (CascadeRight) - T; T _ LDF[bitCount,0,14],CALL[NotWhite]; *3 instrs T _ LDF[bitCount,0,14]; *1 instr PStore1[screenWord,Stack6],GOTO[EndDot1]; forX2: LU _ (nInputPixels) - T - 1,CALL[GetPixel]; *5 instrs T _ jctr,GOTO[jDone2,R>=0]; whileJ2: T _ val; CascadeRight _ (CascadeRight)+T; T_LDF[bitmapWidth,5,13],GOTO[White2,ALU>=0]; Black2: Stack5 _ T _ (Stack5) - T,CALL[OrBlack]; *3 instrs T _ Stack5,CALL[StoreVal]; *1 instr EndDot2: T _ (CascadeRight) AND (100000c),CALL[GetError]; *6.5 instrs bitCount _ T _ (bitCount) + 1,CALL[GetNext]; *6 instrs jctr _ (jctr) + T; GOTO[whileJ2,ALU<0]; jDone2: T _ nOutputDots; jctr _ (jctr) - T; x _ T _ (x) + 1,GOTO[forX2]; *could save 7 instructions if jctr still negative White2: Stack5 _ (Stack5) - T; T _ range; CascadeRight _ (CascadeRight) - T; T _ LDF[bitCount,0,14],CALL[NotWhite]; *3 instrs T _ LDF[bitCount,0,14]; *1 instr PStore1[screenWord,Stack6],GOTO[EndDot2]; forX3: GOTO[xDone]; END; LU _ (nInputPixels) - T - 1,CALL[GetPixel]; *5 instrs T _ jctr,GOTO[jDone3,R>=0]; whileJ3: T _ val; CascadeRight _ (CascadeRight)+T; T_LDF[bitmapWidth,5,13],GOTO[White3,ALU>=0]; Black3: Stack5 _ T _ (Stack5) + T,CALL[OrBlack]; *3 instrs T _ Stack5,CALL[StoreVal]; *1 instr EndDot3: T _ (CascadeRight) AND (100000c),CALL[GetError]; *6.5 instrs bitCount _ T _ (bitCount) + 1,CALL[GetNext]; *6 instrs jctr _ (jctr) + T; GOTO[whileJ3,ALU<0]; jDone3: T _ nOutputDots; jctr _ (jctr) - T; x _ T _ (x) + 1,GOTO[forX3]; *could save 7 instructions if jctr still negative White3: Stack5 _ (Stack5) + T; T _ range; CascadeRight _ (CascadeRight) - T; T _ LDF[bitCount,0,14],CALL[NotWhite]; *3 instrs T _ LDF[bitCount,0,14]; *1 instr PStore1[screenWord,Stack6],GOTO[EndDot3]; % e6(706)\f1 665b2B1820b53B355b7B74b8B79f0b8f1B37b8B448b7B130b5B74b14B155b14B35b6f0B8f1b1B54b14B44b14B269b15B135f0 18f1 38b14B155b14B35b6f0B8f1b1B54b14B44b14B269b15B127b14B174b14B23b6f0B8f1b1B54b14B44b14B282b15B98b14B36b14B174b14B23b6f0B8f1b1B54b14B44b14B282b15B \f1