// S C A N P U T D O T S // This code is never run-- microcode does it all get "PressInternals.df" get "PressParams.df" // outgoing procedures external [ ScanPutDots ScanPutHalfTone ] // incoming procedures external [ //PRESS PressError //PRESSML Ugt ] // incoming statics external [ mpSBuf //Map from scan-line to buffer ScanBuf //core buffer ] //ScanPutDots(s,v) // Puts out one scanline of dots. S is scanline number (0 to BANDWidth-1) // v is pointer to BEDots entry. // **** This routine also in microcode **** let ScanPutDots(s,v) be [ let Bdim=v>>BEDots.Bdim // - # bits to output let Bcount=DotsDeltaConst let Bmagnify=v>>BEDots.Bmagnify let wordout=0 //Output word let Bbit=(v>>BEDots.Bstart) let Bword=mpSBuf!s+(v>>BEDots.Bstart rshift 4) let Bincr=v>>BEDots.Bincr let Bit=nil let InBit=(#20-v>>BEDots.BitPhase) let InAdr=v>>BEDots.BitBuf let wordin=@InAdr InAdr=InAdr+1 [ [ //Getabit if InBit eq 0 then [ InBit=#20 wordin=@InAdr InAdr=InAdr+1 ] let mask=(table [ 0;#1;#2;#4;#10;#20;#40; #100;#200;#400;#1000;#2000;#4000; #10000;#20000;#40000;#100000 ] )!InBit InBit=InBit-1 Bit=(wordin&mask) if Bmagnify then break Bcount=Bcount-v>>BEDots.Bdelta if Bcount ls 0 then [ Bcount=Bcount+DotsDeltaConst break ] ] repeat [ //Putabit if Bit then [ let OrBit=(table [ #100000;#40000;#20000;#10000; #4000;#2000;#1000;#400;#200;#100; #40;#20;#10;#4;#2;#1 ] )!Bbit wordout=wordout%OrBit ] Bbit=Bbit+Bincr if (Bbit𫙠) ne 0 then [ Bbit=(Bincr ls 0)? 15,0 compileif DebugSw then [ let ScanBufLast=ScanBuf-(ScanBuf!-1)-2 if Ugt(ScanBuf,Bword) % Ugt(Bword,ScanBufLast) then PressError(1601) ] @Bword=@Bword%wordout //No opaque yet Bword=Bword+Bincr wordout=0 ] Bdim=Bdim+1 if Bdim eq 0 then [ @Bword=@Bword%wordout return //All done! ] unless Bmagnify then break Bcount=Bcount-v>>BEDots.Bdelta if Bcount ls 0 then [ Bcount=Bcount+DotsDeltaConst break ] ] repeat ] repeat //Many, many bits! ] //ScanPutHalfTone(s,v) // Puts out one scanline of dots. S is scanline number (0 to BANDWidth-1) // v is pointer to BEDots entry. // **** This routine also in microcode **** and ScanPutHalfTone(s,v) be [ let Bdim=v>>BEDots.Bdim // - # bits to output let Bcount=DotsDeltaConst let Bmagnify=v>>BEDots.Bmagnify let wordout=0 //Output word let Bbit=(v>>BEDots.Bstart) let Bword=mpSBuf!s+(v>>BEDots.Bstart rshift 4) let Bincr=v>>BEDots.Bincr let Sample=nil let sampleSize=v>>BEDots.Code let InSample=(#20-(v>>BEDots.BitPhase)*sampleSize) let InAdr=v>>BEDots.BitBuf let wordin=@InAdr InAdr=InAdr+1 let Mask=-1 rshift (16-sampleSize) let OrBitTable= table [ #100000;#40000;#20000;#10000; #4000;#2000;#1000;#400;#200;#100; #40;#20;#10;#4;#2;#1 ] let screenAddr=v>>BEDots.ScreenAddress let screenMod=v>>BEDots.ScreenModulus let screenCount=0 let screen=0 //if screening, put screen value here //the following variables can be S registers in the microcode implementation let CascadeDiag=0 //error moving diagonally let black=v>>BEDots.IMin let white=v>>BEDots.IMax let range=(white-black)*4 let threshold=black-white let error=0 //holds 50% error moving from left, and is also used as a temp let error1=0 //holds 25% error let ErrorBuffer=v>>BEDots.ErrorBuffer-Bdim //indexed by Bdim //since Bdim<0, add in -Bdim [ [ //Get a sample point if InSample ls sampleSize then [ InSample=#20 wordin=@InAdr InAdr=InAdr+1 ] InSample=InSample-sampleSize Sample=((wordin rshift InSample)&Mask)-black Sample=Sample*4 //*4 to avoid errors on 25% error calculation if Bmagnify then break Bcount=Bcount-v>>BEDots.Bdelta if Bcount ls 0 then [ Bcount=Bcount+DotsDeltaConst break ] ] repeat [ //Put out next bit(s) for this sample point //add screen frequency, if called for unless screenAddr eq 0 do [ screen=screenAddr!screenCount screenCount=(screenCount+1) rem screenMod ] //read incoming error value error=ErrorBuffer!Bdim + error //down error from last line + error from left error=error-(Sample+screen) test error ge threshold then wordout=wordout%(OrBitTable!Bbit) or error=error+range //now, compute cascading error to put out // distribution is : Down 25%, Diag 25%, Right 50% error=error/2 //50% error (error is a signed number) error1=error/2 //25% error ErrorBuffer!Bdim=CascadeDiag+error1 //previous diagonal error + new down error CascadeDiag=error1 Bbit=Bbit+Bincr if (Bbit𫙠) ne 0 then [ Bbit=(Bincr ls 0)? 15,0 compileif DebugSw then [ let ScanBufLast=ScanBuf-(ScanBuf!-1)-2 if Ugt(ScanBuf,Bword) % Ugt(Bword,ScanBufLast) then PressError(1601) ] @Bword=@Bword%wordout //No opaque yet Bword=Bword+Bincr wordout=0 ] Bdim=Bdim+1 if Bdim eq 0 then [ @Bword=@Bword%wordout return //All done! ] unless Bmagnify then break Bcount=Bcount-v>>BEDots.Bdelta if Bcount ls 0 then [ Bcount=Bcount+DotsDeltaConst break ] ] repeat ] repeat //Many, many bits! ]