1141cc406Sopenharmony_ci/* @file plustek-pp_dac.c
2141cc406Sopenharmony_ci * @brief all the shading function formerly found in shading.c.
3141cc406Sopenharmony_ci *        don't ask me why I called this file dac.c...
4141cc406Sopenharmony_ci *
5141cc406Sopenharmony_ci * based on sources acquired from Plustek Inc.
6141cc406Sopenharmony_ci * Copyright (C) 1998 Plustek Inc.
7141cc406Sopenharmony_ci * Copyright (C) 2000-2004 Gerhard Jaeger <gerhard@gjaeger.de>
8141cc406Sopenharmony_ci * also based on the work done by Rick Bronson
9141cc406Sopenharmony_ci *
10141cc406Sopenharmony_ci * History:
11141cc406Sopenharmony_ci * - 0.30 - initial version
12141cc406Sopenharmony_ci * - 0.31 - no changes
13141cc406Sopenharmony_ci * - 0.32 - no changes
14141cc406Sopenharmony_ci * - 0.33 - added some comments
15141cc406Sopenharmony_ci * - 0.34 - slight changes
16141cc406Sopenharmony_ci * - 0.35 - removed SetInitialGainRAM from structure pScanData
17141cc406Sopenharmony_ci * - 0.36 - added dacP96001WaitForShading and changed dacP96WaitForShading to
18141cc406Sopenharmony_ci *          dacP96003WaitForShading
19141cc406Sopenharmony_ci *        - changes, due to define renaming
20141cc406Sopenharmony_ci * - 0.37 - removed dacP98FillShadingDarkToShadingRegister()
21141cc406Sopenharmony_ci *        - removed // comments
22141cc406Sopenharmony_ci *        - some code cleanup
23141cc406Sopenharmony_ci * - 0.38 - added P12 stuff
24141cc406Sopenharmony_ci * - 0.39 - no changes
25141cc406Sopenharmony_ci * - 0.40 - disabled the A3I stuff
26141cc406Sopenharmony_ci * - 0.41 - no changes
27141cc406Sopenharmony_ci * - 0.42 - changed include names
28141cc406Sopenharmony_ci * - 0.43 - no changes
29141cc406Sopenharmony_ci * .
30141cc406Sopenharmony_ci * <hr>
31141cc406Sopenharmony_ci * This file is part of the SANE package.
32141cc406Sopenharmony_ci *
33141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or
34141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as
35141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the
36141cc406Sopenharmony_ci * License, or (at your option) any later version.
37141cc406Sopenharmony_ci *
38141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but
39141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
40141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41141cc406Sopenharmony_ci * General Public License for more details.
42141cc406Sopenharmony_ci *
43141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License
44141cc406Sopenharmony_ci * along with this program.  If not, see <https://www.gnu.org/licenses/>.
45141cc406Sopenharmony_ci *
46141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for
47141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE.
48141cc406Sopenharmony_ci *
49141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files
50141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the
51141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public
52141cc406Sopenharmony_ci * License.  Your use of that executable is in no way restricted on
53141cc406Sopenharmony_ci * account of linking the SANE library code into it.
54141cc406Sopenharmony_ci *
55141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why
56141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public
57141cc406Sopenharmony_ci * License.
58141cc406Sopenharmony_ci *
59141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in
60141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that
61141cc406Sopenharmony_ci * those changes may be distributed with this exception intact.
62141cc406Sopenharmony_ci *
63141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice
64141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications.
65141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice.
66141cc406Sopenharmony_ci * <hr>
67141cc406Sopenharmony_ci */
68141cc406Sopenharmony_ci#include "plustek-pp_scan.h"
69141cc406Sopenharmony_ci
70141cc406Sopenharmony_ci/************************** local definitions ********************************/
71141cc406Sopenharmony_ci
72141cc406Sopenharmony_ci/***************************** global vars ***********************************/
73141cc406Sopenharmony_ci
74141cc406Sopenharmony_cistatic const Byte a_bCorrectTimesTable[4] = {0, 1, 2, 4};
75141cc406Sopenharmony_ci
76141cc406Sopenharmony_cistatic ULong dwADCPipeLine = 4 * 4;
77141cc406Sopenharmony_cistatic ULong dwReadyLen;
78141cc406Sopenharmony_ci
79141cc406Sopenharmony_ci/*************************** local functions *********************************/
80141cc406Sopenharmony_ci
81141cc406Sopenharmony_ci/**
82141cc406Sopenharmony_ci */
83141cc406Sopenharmony_cistatic void dacP98AdjustGainAverage( pScanData ps )
84141cc406Sopenharmony_ci{
85141cc406Sopenharmony_ci	pUChar pDest, pSrce;
86141cc406Sopenharmony_ci    ULong  dw, dw1;
87141cc406Sopenharmony_ci    UShort wSum;
88141cc406Sopenharmony_ci
89141cc406Sopenharmony_ci    pDest = pSrce = ps->pScanBuffer1;
90141cc406Sopenharmony_ci
91141cc406Sopenharmony_ci    for (dw1 = 0; dw1 < (2560 * 3) / 16; dw1++, pDest++) {
92141cc406Sopenharmony_ci		for (dw = 0, wSum = 0; dw < 16; dw++, pSrce++)
93141cc406Sopenharmony_ci		    wSum += *pSrce;
94141cc406Sopenharmony_ci
95141cc406Sopenharmony_ci		*pDest = wSum / 16;
96141cc406Sopenharmony_ci    }
97141cc406Sopenharmony_ci}
98141cc406Sopenharmony_ci
99141cc406Sopenharmony_ci/**
100141cc406Sopenharmony_ci */
101141cc406Sopenharmony_cistatic void dacP98FillDarkDAC( pScanData ps )
102141cc406Sopenharmony_ci{
103141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x20, ps->bRedDAC   );
104141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x21, ps->bGreenDAC );
105141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x22, ps->bBlueDAC  );
106141cc406Sopenharmony_ci}
107141cc406Sopenharmony_ci
108141cc406Sopenharmony_ci/**
109141cc406Sopenharmony_ci */
110141cc406Sopenharmony_cistatic void dacP98SetReadFBKRegister( pScanData ps )
111141cc406Sopenharmony_ci{
112141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
113141cc406Sopenharmony_ci
114141cc406Sopenharmony_ci    ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE + _SCAN_1ST_AVERAGE;
115141cc406Sopenharmony_ci
116141cc406Sopenharmony_ci    IOSelectLampSource( ps );
117141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
118141cc406Sopenharmony_ci
119141cc406Sopenharmony_ci	ps->AsicReg.RD_Motor0Control = _MotorOn;
120141cc406Sopenharmony_ci	ps->AsicReg.RD_StepControl 	 = _MOTOR0_SCANSTATE;
121141cc406Sopenharmony_ci	ps->AsicReg.RD_Origin 		 = 4;
122141cc406Sopenharmony_ci	ps->AsicReg.RD_Pixels 		 = 512;
123141cc406Sopenharmony_ci	ps->AsicReg.RD_Motor1Control = 0;
124141cc406Sopenharmony_ci	ps->AsicReg.RD_Motor0Control = 0;
125141cc406Sopenharmony_ci
126141cc406Sopenharmony_ci	ps->AsicReg.RD_ModelControl  = _LED_CONTROL + _LED_ACTIVITY;
127141cc406Sopenharmony_ci
128141cc406Sopenharmony_ci    if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
129141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi = 300;
130141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl += _ModelDpi300;
131141cc406Sopenharmony_ci
132141cc406Sopenharmony_ci    } else {
133141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi = 600;
134141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl += _ModelDpi600;
135141cc406Sopenharmony_ci    }
136141cc406Sopenharmony_ci}
137141cc406Sopenharmony_ci
138141cc406Sopenharmony_ci/**
139141cc406Sopenharmony_ci */
140141cc406Sopenharmony_cistatic UShort dacP98CalDarkOff( pScanData ps, UShort wChDarkOff,
141141cc406Sopenharmony_ci							    UShort wDACCompareHigh, UShort wDACOffset )
142141cc406Sopenharmony_ci{
143141cc406Sopenharmony_ci    UShort wTemp;
144141cc406Sopenharmony_ci
145141cc406Sopenharmony_ci    if ((_CCD_518 == ps->Device.bCCDID) || (_CCD_535 == ps->Device.bCCDID)) {
146141cc406Sopenharmony_ci		wTemp = wChDarkOff + wDACOffset;
147141cc406Sopenharmony_ci	} else  {
148141cc406Sopenharmony_ci
149141cc406Sopenharmony_ci		if (_CCD_3797 == ps->Device.bCCDID) {
150141cc406Sopenharmony_ci		    if (wChDarkOff > wDACOffset) {
151141cc406Sopenharmony_ci				wTemp = wChDarkOff - wDACOffset;
152141cc406Sopenharmony_ci			} else {
153141cc406Sopenharmony_ci				wTemp = 0;
154141cc406Sopenharmony_ci			}
155141cc406Sopenharmony_ci		} else {
156141cc406Sopenharmony_ci		    if (wChDarkOff > wDACCompareHigh) {
157141cc406Sopenharmony_ci				wTemp = wChDarkOff - wDACCompareHigh;
158141cc406Sopenharmony_ci			} else {
159141cc406Sopenharmony_ci				wTemp = 0;
160141cc406Sopenharmony_ci			}
161141cc406Sopenharmony_ci		}
162141cc406Sopenharmony_ci    }
163141cc406Sopenharmony_ci    return wTemp;
164141cc406Sopenharmony_ci}
165141cc406Sopenharmony_ci
166141cc406Sopenharmony_ci/**
167141cc406Sopenharmony_ci */
168141cc406Sopenharmony_cistatic Bool dacP98AdjustDAC( UShort DarkOff, UShort wHigh,
169141cc406Sopenharmony_ci							 UShort wLow, pUChar pbReg, Bool *fDACStopFlag )
170141cc406Sopenharmony_ci{
171141cc406Sopenharmony_ci    if (DarkOff > wHigh) {
172141cc406Sopenharmony_ci		if ((DarkOff - wHigh) > 10) {
173141cc406Sopenharmony_ci		    if ((DarkOff - wHigh) > 2550)
174141cc406Sopenharmony_ci				*pbReg += ((DarkOff - wHigh) / 20);
175141cc406Sopenharmony_ci		    else
176141cc406Sopenharmony_ci			*pbReg += ((DarkOff - wHigh) / 10);
177141cc406Sopenharmony_ci		} else
178141cc406Sopenharmony_ci	    	*pbReg += 1;
179141cc406Sopenharmony_ci
180141cc406Sopenharmony_ci		if (!(*pbReg))
181141cc406Sopenharmony_ci		    *pbReg = 0xff;
182141cc406Sopenharmony_ci
183141cc406Sopenharmony_ci		*fDACStopFlag = _FALSE;
184141cc406Sopenharmony_ci		return _FALSE;
185141cc406Sopenharmony_ci
186141cc406Sopenharmony_ci    } else {
187141cc406Sopenharmony_ci		if (DarkOff < wLow) {
188141cc406Sopenharmony_ci		    if (DarkOff > 0)
189141cc406Sopenharmony_ci				*pbReg -= 2;
190141cc406Sopenharmony_ci		    else
191141cc406Sopenharmony_ci				*pbReg -= 10;
192141cc406Sopenharmony_ci
193141cc406Sopenharmony_ci		    *fDACStopFlag = _FALSE;
194141cc406Sopenharmony_ci		    return _FALSE;
195141cc406Sopenharmony_ci		} else
196141cc406Sopenharmony_ci		    return _TRUE;
197141cc406Sopenharmony_ci	}
198141cc406Sopenharmony_ci}
199141cc406Sopenharmony_ci
200141cc406Sopenharmony_ci/**
201141cc406Sopenharmony_ci */
202141cc406Sopenharmony_cistatic Bool dacP98CheckChannelDarkLevel( pScanData ps )
203141cc406Sopenharmony_ci{
204141cc406Sopenharmony_ci	Bool fDACStopFlag = _TRUE;
205141cc406Sopenharmony_ci
206141cc406Sopenharmony_ci    dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Red,
207141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpHi.Colors.Red,
208141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpLo.Colors.Red,
209141cc406Sopenharmony_ci			         &ps->bRedDAC, &fDACStopFlag );
210141cc406Sopenharmony_ci    dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Green,
211141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpHi.Colors.Green,
212141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpLo.Colors.Green,
213141cc406Sopenharmony_ci			         &ps->bGreenDAC, &fDACStopFlag );
214141cc406Sopenharmony_ci    dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Blue,
215141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue,
216141cc406Sopenharmony_ci                     ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue,
217141cc406Sopenharmony_ci			         &ps->bBlueDAC, &fDACStopFlag );
218141cc406Sopenharmony_ci
219141cc406Sopenharmony_ci    return  fDACStopFlag;
220141cc406Sopenharmony_ci}
221141cc406Sopenharmony_ci
222141cc406Sopenharmony_ci/** Average left offset 30, 16 pixels as each color's dark level
223141cc406Sopenharmony_ci */
224141cc406Sopenharmony_cistatic void dacP98FillChannelDarkLevelControl( pScanData ps )
225141cc406Sopenharmony_ci{
226141cc406Sopenharmony_ci    DataPointer p;
227141cc406Sopenharmony_ci	ULong	    dwPos, dw, dwSum;
228141cc406Sopenharmony_ci
229141cc406Sopenharmony_ci    if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
230141cc406Sopenharmony_ci		dwPos = 0x10 * 3;
231141cc406Sopenharmony_ci	} else {
232141cc406Sopenharmony_ci		dwPos = 0x20 * 2;
233141cc406Sopenharmony_ci	}
234141cc406Sopenharmony_ci
235141cc406Sopenharmony_ci    for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos), dwSum = 0, dw = 16;
236141cc406Sopenharmony_ci	     dw; dw--, p.pw++) {
237141cc406Sopenharmony_ci		dwSum += (ULong)(*p.pw);
238141cc406Sopenharmony_ci	}
239141cc406Sopenharmony_ci
240141cc406Sopenharmony_ci	ps->Shade.DarkOffset.Colors.Red = (UShort)(dwSum / 16);
241141cc406Sopenharmony_ci
242141cc406Sopenharmony_ci    for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos + 1024), dwSum = 0, dw = 16;
243141cc406Sopenharmony_ci	    dw; dw--, p.pw++) {
244141cc406Sopenharmony_ci		dwSum += (ULong)(*p.pw);
245141cc406Sopenharmony_ci	}
246141cc406Sopenharmony_ci
247141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Green = (UShort)(dwSum / 16);
248141cc406Sopenharmony_ci
249141cc406Sopenharmony_ci    for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos + 1024 * 2), dwSum = 0, dw = 16;
250141cc406Sopenharmony_ci	    dw; dw--, p.pw++) {
251141cc406Sopenharmony_ci		dwSum += (ULong)(*p.pw);
252141cc406Sopenharmony_ci	}
253141cc406Sopenharmony_ci
254141cc406Sopenharmony_ci	ps->Shade.DarkOffset.Colors.Blue = (UShort)(dwSum / 16);
255141cc406Sopenharmony_ci}
256141cc406Sopenharmony_ci
257141cc406Sopenharmony_ci/**
258141cc406Sopenharmony_ci */
259141cc406Sopenharmony_cistatic void dacP98AdjustGain( pScanData ps )
260141cc406Sopenharmony_ci{
261141cc406Sopenharmony_ci	DataPointer	p;
262141cc406Sopenharmony_ci	ULong		dw;
263141cc406Sopenharmony_ci	UShort		w;
264141cc406Sopenharmony_ci    Byte		b[3];
265141cc406Sopenharmony_ci    pUChar		pbReg[3];
266141cc406Sopenharmony_ci
267141cc406Sopenharmony_ci    dacP98AdjustGainAverage( ps );
268141cc406Sopenharmony_ci
269141cc406Sopenharmony_ci    pbReg[0] = &ps->bRedGainIndex;
270141cc406Sopenharmony_ci    pbReg[1] = &ps->bGreenGainIndex;
271141cc406Sopenharmony_ci    pbReg[2] = &ps->bBlueGainIndex;
272141cc406Sopenharmony_ci
273141cc406Sopenharmony_ci    for (w = 0, p.pb = ps->pScanBuffer1; w < 3; w++) {
274141cc406Sopenharmony_ci
275141cc406Sopenharmony_ci		for (dw = 2560 / 16, b [w] = 0; dw; dw--, p.pb++) {
276141cc406Sopenharmony_ci		    if (b [w] < *p.pb)
277141cc406Sopenharmony_ci				b [w] = *p.pb;
278141cc406Sopenharmony_ci		}
279141cc406Sopenharmony_ci		if (b[w] < _GAIN_LOW) {
280141cc406Sopenharmony_ci		    if ((_GAIN_P98_HIGH - b[w]) < b[w])
281141cc406Sopenharmony_ci				*(pbReg[w]) += 1;
282141cc406Sopenharmony_ci		    else
283141cc406Sopenharmony_ci				*(pbReg[w]) += 4;
284141cc406Sopenharmony_ci		} else {
285141cc406Sopenharmony_ci		    if (b[w] > _GAIN_P98_HIGH)
286141cc406Sopenharmony_ci				*(pbReg[w]) -= 1;
287141cc406Sopenharmony_ci		}
288141cc406Sopenharmony_ci    }
289141cc406Sopenharmony_ci}
290141cc406Sopenharmony_ci
291141cc406Sopenharmony_ci/**
292141cc406Sopenharmony_ci */
293141cc406Sopenharmony_cistatic void dacP98CheckLastGain( pScanData ps )
294141cc406Sopenharmony_ci{
295141cc406Sopenharmony_ci    DataPointer p;
296141cc406Sopenharmony_ci 	ULong	    dw;
297141cc406Sopenharmony_ci    UShort	    w;
298141cc406Sopenharmony_ci    Byte	    b[3];
299141cc406Sopenharmony_ci    pUChar	    pbReg[3];
300141cc406Sopenharmony_ci
301141cc406Sopenharmony_ci    dacP98AdjustGainAverage( ps );
302141cc406Sopenharmony_ci
303141cc406Sopenharmony_ci    pbReg[0] = &ps->bRedGainIndex;
304141cc406Sopenharmony_ci    pbReg[1] = &ps->bGreenGainIndex;
305141cc406Sopenharmony_ci    pbReg[2] = &ps->bBlueGainIndex;
306141cc406Sopenharmony_ci
307141cc406Sopenharmony_ci    for (w = 0, p.pb = ps->pScanBuffer1; w < 3; w++) {
308141cc406Sopenharmony_ci		for (dw = 2560 / 16, b [w] = 0; dw; dw--, p.pb++) {
309141cc406Sopenharmony_ci		    if (b[w] < *p.pb)
310141cc406Sopenharmony_ci				b[w] = *p.pb;
311141cc406Sopenharmony_ci		}
312141cc406Sopenharmony_ci
313141cc406Sopenharmony_ci		if (b[w] > _GAIN_P98_HIGH) {
314141cc406Sopenharmony_ci		    *(pbReg [w]) -= 1;
315141cc406Sopenharmony_ci		}
316141cc406Sopenharmony_ci    }
317141cc406Sopenharmony_ci}
318141cc406Sopenharmony_ci
319141cc406Sopenharmony_ci/**
320141cc406Sopenharmony_ci */
321141cc406Sopenharmony_cistatic void dacP98FillGainInitialRestRegister( pScanData ps )
322141cc406Sopenharmony_ci{
323141cc406Sopenharmony_ci	ps->OpenScanPath( ps );
324141cc406Sopenharmony_ci
325141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegThresholdGapControl, ps->AsicReg.RD_ThresholdGapCtrl );
326141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegModelControl, ps->AsicReg.RD_ModelControl );
327141cc406Sopenharmony_ci
328141cc406Sopenharmony_ci	ps->CloseScanPath( ps );
329141cc406Sopenharmony_ci}
330141cc406Sopenharmony_ci
331141cc406Sopenharmony_ci/**
332141cc406Sopenharmony_ci */
333141cc406Sopenharmony_cistatic void dacP98SetInitialGainRegister( pScanData ps )
334141cc406Sopenharmony_ci{
335141cc406Sopenharmony_ci	DacP98FillGainOutDirectPort( ps );	   	/* R/G/B GainOut to scanner		*/
336141cc406Sopenharmony_ci    dacP98FillGainInitialRestRegister( ps );/* Model Control2, LED, Correct.*/
337141cc406Sopenharmony_ci}
338141cc406Sopenharmony_ci
339141cc406Sopenharmony_ci/** Find the most ideal intensity for each color (RGB)
340141cc406Sopenharmony_ci */
341141cc406Sopenharmony_cistatic void dacP98SetRGBGainRegister( pScanData ps )
342141cc406Sopenharmony_ci{
343141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeIdle );
344141cc406Sopenharmony_ci
345141cc406Sopenharmony_ci	ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
346141cc406Sopenharmony_ci    IOSelectLampSource( ps );
347141cc406Sopenharmony_ci
348141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
349141cc406Sopenharmony_ci    dacP98SetInitialGainRegister( ps );
350141cc406Sopenharmony_ci
351141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl   = _ModeScan;
352141cc406Sopenharmony_ci    ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE;
353141cc406Sopenharmony_ci    ps->AsicReg.RD_Motor0Control = _MotorOn + _MotorDirForward + _MotorHEightStep;
354141cc406Sopenharmony_ci    ps->AsicReg.RD_XStepTime 	 = ps->bSpeed4;
355141cc406Sopenharmony_ci
356141cc406Sopenharmony_ci    if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
357141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi300;
358141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin = 32 +  60 + 4;
359141cc406Sopenharmony_ci    } else {
360141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi600;
361141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin = 64 + 120 + 4;
362141cc406Sopenharmony_ci    }
363141cc406Sopenharmony_ci    ps->AsicReg.RD_Dpi    = 300;
364141cc406Sopenharmony_ci    ps->AsicReg.RD_Pixels = 2560;
365141cc406Sopenharmony_ci
366141cc406Sopenharmony_ci	IOPutOnAllRegisters( ps );
367141cc406Sopenharmony_ci}
368141cc406Sopenharmony_ci
369141cc406Sopenharmony_ci/**
370141cc406Sopenharmony_ci */
371141cc406Sopenharmony_cistatic void dacP98FillRGBMap( pUChar pBuffer )
372141cc406Sopenharmony_ci{
373141cc406Sopenharmony_ci    ULong  dw, dw1;
374141cc406Sopenharmony_ci	pULong pdw = (pULong)(pBuffer);
375141cc406Sopenharmony_ci
376141cc406Sopenharmony_ci    for( dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101 ) {
377141cc406Sopenharmony_ci		*pdw++ = dw1;
378141cc406Sopenharmony_ci		*pdw++ = dw1;
379141cc406Sopenharmony_ci		*pdw++ = dw1;
380141cc406Sopenharmony_ci		*pdw++ = dw1;
381141cc406Sopenharmony_ci    }
382141cc406Sopenharmony_ci}
383141cc406Sopenharmony_ci
384141cc406Sopenharmony_ci/** here we download the current mapping table
385141cc406Sopenharmony_ci */
386141cc406Sopenharmony_cistatic void dacP98DownloadMapTable( pScanData ps, pUChar pBuffer )
387141cc406Sopenharmony_ci{
388141cc406Sopenharmony_ci    Byte  bAddr;
389141cc406Sopenharmony_ci    ULong i;
390141cc406Sopenharmony_ci
391141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegScanControl,
392141cc406Sopenharmony_ci	   			(Byte)((ps->AsicReg.RD_ScanControl & 0xfc) | _SCAN_BYTEMODE));
393141cc406Sopenharmony_ci
394141cc406Sopenharmony_ci    for( i = 3, bAddr = _MAP_ADDR_RED; i--; bAddr += _MAP_ADDR_SIZE ) {
395141cc406Sopenharmony_ci
396141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegModeControl, _ModeMappingMem );
397141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegMemoryLow, 0);
398141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegMemoryHigh, bAddr );
399141cc406Sopenharmony_ci
400141cc406Sopenharmony_ci    	IOMoveDataToScanner( ps, pBuffer, 4096 );
401141cc406Sopenharmony_ci    	pBuffer += 4096;
402141cc406Sopenharmony_ci    }
403141cc406Sopenharmony_ci
404141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
405141cc406Sopenharmony_ci}
406141cc406Sopenharmony_ci
407141cc406Sopenharmony_ci/**
408141cc406Sopenharmony_ci */
409141cc406Sopenharmony_cistatic void dacP98DownloadShadingTable( pScanData ps,
410141cc406Sopenharmony_ci                                        pUChar pBuffer, ULong size )
411141cc406Sopenharmony_ci{
412141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, _ModeShadingMem );
413141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegMemoryLow,  0 );
414141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegMemoryHigh, 0 );
415141cc406Sopenharmony_ci
416141cc406Sopenharmony_ci    /* set 12 bits output color */
417141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegScanControl,
418141cc406Sopenharmony_ci					  (Byte)(ps->AsicReg.RD_ScanControl | _SCAN_12BITMODE));
419141cc406Sopenharmony_ci
420141cc406Sopenharmony_ci	/* MoveDataToShadingRam() */
421141cc406Sopenharmony_ci    IOMoveDataToScanner( ps ,pBuffer, size );
422141cc406Sopenharmony_ci
423141cc406Sopenharmony_ci    if( _ASIC_IS_98003 == ps->sCaps.AsicID )
424141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegModeControl, _ModeScan );
425141cc406Sopenharmony_ci    else
426141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
427141cc406Sopenharmony_ci
428141cc406Sopenharmony_ci    DacP98FillShadingDarkToShadingRegister( ps );
429141cc406Sopenharmony_ci}
430141cc406Sopenharmony_ci
431141cc406Sopenharmony_ci/** Build a linear map for asic (this model is 12-bit scanner, there are 4096
432141cc406Sopenharmony_ci *  map entries but just generate 256 level output, so the content must be 0 to
433141cc406Sopenharmony_ci *  255), then fill the shading buffer (the first 3k), and map table (the last
434141cc406Sopenharmony_ci *  1k) to asic for R & G & B channels.
435141cc406Sopenharmony_ci *
436141cc406Sopenharmony_ci *  I need pScanBuffer2 size = 5400 * 2 * 3
437141cc406Sopenharmony_ci *  pScanBuffer1 size = 256 * 16 * 2
438141cc406Sopenharmony_ci */
439141cc406Sopenharmony_cistatic void dacP98SetInitialGainRAM( pScanData ps )
440141cc406Sopenharmony_ci{
441141cc406Sopenharmony_ci    memset( ps->pScanBuffer2, 0xff, (5400 * 2 * 3));
442141cc406Sopenharmony_ci
443141cc406Sopenharmony_ci	dacP98DownloadShadingTable( ps, ps->pScanBuffer2, (5400 * 2 * 3));
444141cc406Sopenharmony_ci
445141cc406Sopenharmony_ci    dacP98FillRGBMap( ps->pScanBuffer1 );		   	/* Fill 12 Bits R Map */
446141cc406Sopenharmony_ci    dacP98FillRGBMap( ps->pScanBuffer1 + 4096 );    /* Fill 12 Bits G Map */
447141cc406Sopenharmony_ci    dacP98FillRGBMap( ps->pScanBuffer1 + 8192 );    /* Fill 12 Bits B Map */
448141cc406Sopenharmony_ci
449141cc406Sopenharmony_ci	dacP98DownloadMapTable( ps, ps->pScanBuffer1 );
450141cc406Sopenharmony_ci}
451141cc406Sopenharmony_ci
452141cc406Sopenharmony_ci/** Find the most ideal intensity for each color (RGB)
453141cc406Sopenharmony_ci */
454141cc406Sopenharmony_cistatic void dacP98AdjustRGBGain( pScanData ps )
455141cc406Sopenharmony_ci{
456141cc406Sopenharmony_ci	int bCorrectTimes;
457141cc406Sopenharmony_ci
458141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98AdjustRGBGain()\n" );
459141cc406Sopenharmony_ci
460141cc406Sopenharmony_ci	ps->OpenScanPath( ps );
461141cc406Sopenharmony_ci	dacP98SetInitialGainRAM( ps );	/* set shading ram and read out data to */
462141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
463141cc406Sopenharmony_ci
464141cc406Sopenharmony_ci    ps->bRedGainIndex   = 0x02;
465141cc406Sopenharmony_ci	ps->bGreenGainIndex = 0x02;
466141cc406Sopenharmony_ci	ps->bBlueGainIndex  = 0x02;
467141cc406Sopenharmony_ci
468141cc406Sopenharmony_ci    for (bCorrectTimes = 10; bCorrectTimes; bCorrectTimes-- ) {
469141cc406Sopenharmony_ci
470141cc406Sopenharmony_ci		dacP98SetRGBGainRegister( ps );	   	 /* shading the most brightness &*/
471141cc406Sopenharmony_ci		ps->PauseColorMotorRunStates( ps );	 /* stop scan states			 */
472141cc406Sopenharmony_ci		IOReadOneShadingLine( ps, ps->pScanBuffer1, 2560UL );
473141cc406Sopenharmony_ci		dacP98AdjustGain( ps );
474141cc406Sopenharmony_ci    }
475141cc406Sopenharmony_ci
476141cc406Sopenharmony_ci    dacP98SetRGBGainRegister( ps );		/* shading the most brightness &	*/
477141cc406Sopenharmony_ci	ps->PauseColorMotorRunStates( ps ); /* stop scan states                */
478141cc406Sopenharmony_ci
479141cc406Sopenharmony_ci    IOReadOneShadingLine( ps, ps->pScanBuffer1, 2560UL );
480141cc406Sopenharmony_ci
481141cc406Sopenharmony_ci    dacP98CheckLastGain( ps );
482141cc406Sopenharmony_ci	DacP98FillGainOutDirectPort( ps );
483141cc406Sopenharmony_ci}
484141cc406Sopenharmony_ci
485141cc406Sopenharmony_ci/**
486141cc406Sopenharmony_ci */
487141cc406Sopenharmony_cistatic void dacP98SetAdjustShadingRegister( pScanData ps )
488141cc406Sopenharmony_ci{
489141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98SetAdjustShadingRegister()\n" );
490141cc406Sopenharmony_ci
491141cc406Sopenharmony_ci	IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeIdle );
492141cc406Sopenharmony_ci
493141cc406Sopenharmony_ci	ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE + _SCAN_1ST_AVERAGE;
494141cc406Sopenharmony_ci	IOSelectLampSource( ps );
495141cc406Sopenharmony_ci
496141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegScanControl,
497141cc406Sopenharmony_ci							ps->AsicReg.RD_ScanControl );
498141cc406Sopenharmony_ci
499141cc406Sopenharmony_ci	ps->AsicReg.RD_ModeControl 	 = _ModeScan;
500141cc406Sopenharmony_ci	ps->AsicReg.RD_Motor0Control = _MotorOn + _MotorHEightStep + _MotorDirForward;
501141cc406Sopenharmony_ci	ps->AsicReg.RD_XStepTime 	 = ps->bSpeed1;
502141cc406Sopenharmony_ci	ps->AsicReg.RD_ModelControl  = _LED_ACTIVITY + _LED_CONTROL;
503141cc406Sopenharmony_ci
504141cc406Sopenharmony_ci    if (ps->bSetScanModeFlag & _ScanMode_AverageOut) {
505141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi 	  = 300;
506141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels = 2700;
507141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl += _ModelDpi300;
508141cc406Sopenharmony_ci    } else {
509141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi 	  = 600;
510141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels = 5400;
511141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl += _ModelDpi600;
512141cc406Sopenharmony_ci    }
513141cc406Sopenharmony_ci	ps->AsicReg.RD_Origin = 4;
514141cc406Sopenharmony_ci
515141cc406Sopenharmony_ci	IOPutOnAllRegisters( ps );
516141cc406Sopenharmony_ci}
517141cc406Sopenharmony_ci
518141cc406Sopenharmony_ci/**
519141cc406Sopenharmony_ci */
520141cc406Sopenharmony_cistatic void dacP98ReadShadingScanLine( pScanData ps )
521141cc406Sopenharmony_ci{
522141cc406Sopenharmony_ci	TimerDef timer;
523141cc406Sopenharmony_ci
524141cc406Sopenharmony_ci	MiscStartTimer( &timer, _SECOND );
525141cc406Sopenharmony_ci
526141cc406Sopenharmony_ci    ps->Scan.bFifoSelect = ps->RegGFifoOffset;
527141cc406Sopenharmony_ci
528141cc406Sopenharmony_ci    while((IOReadFifoLength( ps ) < dwReadyLen) &&
529141cc406Sopenharmony_ci		   !MiscCheckTimer(&timer)) {
530141cc406Sopenharmony_ci		_DO_UDELAY( 1 );
531141cc406Sopenharmony_ci	}
532141cc406Sopenharmony_ci
533141cc406Sopenharmony_ci    IOReadColorData( ps, ps->pScanBuffer2, ps->dwShadingLen );
534141cc406Sopenharmony_ci}
535141cc406Sopenharmony_ci
536141cc406Sopenharmony_ci/**
537141cc406Sopenharmony_ci */
538141cc406Sopenharmony_cistatic void dacP98GainResize( pUShort pValue, UShort wResize)
539141cc406Sopenharmony_ci{
540141cc406Sopenharmony_ci	DataType Data;
541141cc406Sopenharmony_ci    Byte	 bTemp;
542141cc406Sopenharmony_ci
543141cc406Sopenharmony_ci    Data.dwValue = ((ULong) *pValue) * (ULong) wResize / 100;
544141cc406Sopenharmony_ci
545141cc406Sopenharmony_ci    if (0x1000 <= Data.dwValue)
546141cc406Sopenharmony_ci		Data.wValue = 0xfff;
547141cc406Sopenharmony_ci
548141cc406Sopenharmony_ci    Data.wValue *= 16;
549141cc406Sopenharmony_ci
550141cc406Sopenharmony_ci    bTemp = Data.wOverlap.b1st;
551141cc406Sopenharmony_ci    Data.wOverlap.b1st = Data.wOverlap.b2nd;
552141cc406Sopenharmony_ci    Data.wOverlap.b2nd = bTemp;
553141cc406Sopenharmony_ci
554141cc406Sopenharmony_ci    *pValue = Data.wValue;
555141cc406Sopenharmony_ci}
556141cc406Sopenharmony_ci
557141cc406Sopenharmony_ci/**
558141cc406Sopenharmony_ci */
559141cc406Sopenharmony_cistatic void dacP98SortHilightShadow( pScanData ps, pUShort pwData,
560141cc406Sopenharmony_ci					 			     ULong dwHilightOff, ULong dwShadowOff )
561141cc406Sopenharmony_ci{
562141cc406Sopenharmony_ci	ULong   dwLines, dwPixels;
563141cc406Sopenharmony_ci    UShort  wVCmp, wTmp;
564141cc406Sopenharmony_ci    pUShort pw;
565141cc406Sopenharmony_ci
566141cc406Sopenharmony_ci    for (dwPixels = 0; dwPixels < (ps->dwShadingPixels - 4); dwPixels++) {
567141cc406Sopenharmony_ci
568141cc406Sopenharmony_ci		pw    = (pUShort)ps->Shade.pHilight + dwHilightOff + dwPixels;
569141cc406Sopenharmony_ci		wVCmp = pwData[dwPixels] & 0xfffU;
570141cc406Sopenharmony_ci
571141cc406Sopenharmony_ci		for (dwLines = _DEF_BRIGHTEST_SKIP; dwLines--; pw += 5400UL) {
572141cc406Sopenharmony_ci		    if (wVCmp > *pw) {
573141cc406Sopenharmony_ci				wTmp  = wVCmp;
574141cc406Sopenharmony_ci				wVCmp = *pw;
575141cc406Sopenharmony_ci				*pw   = wTmp;
576141cc406Sopenharmony_ci		    }
577141cc406Sopenharmony_ci		}
578141cc406Sopenharmony_ci    }
579141cc406Sopenharmony_ci    for (dwPixels = 0; dwPixels < (ps->dwShadingPixels - 4); dwPixels++) {
580141cc406Sopenharmony_ci
581141cc406Sopenharmony_ci		pw    = ps->pwShadow + dwShadowOff + dwPixels;
582141cc406Sopenharmony_ci		wVCmp = pwData [dwPixels] & 0xfffU;
583141cc406Sopenharmony_ci
584141cc406Sopenharmony_ci		for (dwLines = _DEF_DARKEST_SKIP; dwLines--; pw += 5400UL) {
585141cc406Sopenharmony_ci
586141cc406Sopenharmony_ci		    if (wVCmp < *pw) {
587141cc406Sopenharmony_ci				wTmp  = wVCmp;
588141cc406Sopenharmony_ci				wVCmp = *pw;
589141cc406Sopenharmony_ci				*pw   = wTmp;
590141cc406Sopenharmony_ci	    	}
591141cc406Sopenharmony_ci		}
592141cc406Sopenharmony_ci    }
593141cc406Sopenharmony_ci}
594141cc406Sopenharmony_ci
595141cc406Sopenharmony_ci/**
596141cc406Sopenharmony_ci */
597141cc406Sopenharmony_cistatic void dacP98WriteBackToShadingRAM( pScanData ps )
598141cc406Sopenharmony_ci{
599141cc406Sopenharmony_ci	ULong   dw;
600141cc406Sopenharmony_ci
601141cc406Sopenharmony_ci	pUShort	pBuffer = (pUShort)ps->pScanBuffer2;
602141cc406Sopenharmony_ci
603141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98WriteBackToShadingRAM()\n" );
604141cc406Sopenharmony_ci
605141cc406Sopenharmony_ci    if (ps->DataInf.wPhyDataType >= COLOR_TRUE24) {
606141cc406Sopenharmony_ci
607141cc406Sopenharmony_ci		for (dw = 0; dw < 5400; dw++) {
608141cc406Sopenharmony_ci
609141cc406Sopenharmony_ci		    *pBuffer = ((pUShort)ps->pScanBuffer1)[dw] -
610141cc406Sopenharmony_ci                                            ps->Shade.DarkOffset.Colors.Red;
611141cc406Sopenharmony_ci			dacP98GainResize( pBuffer,
612141cc406Sopenharmony_ci                              ps->Shade.pCcdDac->GainResize.Colors.Red );
613141cc406Sopenharmony_ci		    pBuffer ++;
614141cc406Sopenharmony_ci
615141cc406Sopenharmony_ci		    *pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400] -
616141cc406Sopenharmony_ci                                            ps->Shade.DarkOffset.Colors.Green;
617141cc406Sopenharmony_ci			dacP98GainResize( pBuffer,
618141cc406Sopenharmony_ci                              ps->Shade.pCcdDac->GainResize.Colors.Green );
619141cc406Sopenharmony_ci		    pBuffer ++;
620141cc406Sopenharmony_ci
621141cc406Sopenharmony_ci		    *pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400 * 2] -
622141cc406Sopenharmony_ci                                             ps->Shade.DarkOffset.Colors.Blue;
623141cc406Sopenharmony_ci			dacP98GainResize( pBuffer,
624141cc406Sopenharmony_ci                              ps->Shade.pCcdDac->GainResize.Colors.Blue );
625141cc406Sopenharmony_ci		    pBuffer ++;
626141cc406Sopenharmony_ci		}
627141cc406Sopenharmony_ci
628141cc406Sopenharmony_ci    } else {
629141cc406Sopenharmony_ci		for (dw = 0; dw < 5400; dw++) {
630141cc406Sopenharmony_ci
631141cc406Sopenharmony_ci			DataType Data;
632141cc406Sopenharmony_ci			Byte	 bTemp;
633141cc406Sopenharmony_ci
634141cc406Sopenharmony_ci		    *pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400] -
635141cc406Sopenharmony_ci                                            ps->Shade.DarkOffset.Colors.Green;
636141cc406Sopenharmony_ci
637141cc406Sopenharmony_ci		    Data.wValue = (*pBuffer) * 16;
638141cc406Sopenharmony_ci		    bTemp = Data.wOverlap.b1st;
639141cc406Sopenharmony_ci	    	Data.wOverlap.b1st = Data.wOverlap.b2nd;
640141cc406Sopenharmony_ci		    Data.wOverlap.b2nd = bTemp;
641141cc406Sopenharmony_ci		    *pBuffer = Data.wValue;
642141cc406Sopenharmony_ci		    pBuffer++;
643141cc406Sopenharmony_ci		}
644141cc406Sopenharmony_ci
645141cc406Sopenharmony_ci    }
646141cc406Sopenharmony_ci	dacP98DownloadShadingTable( ps, ps->pScanBuffer2, (5400 * 2 * 3));
647141cc406Sopenharmony_ci}
648141cc406Sopenharmony_ci
649141cc406Sopenharmony_ci/**
650141cc406Sopenharmony_ci */
651141cc406Sopenharmony_cistatic void dacP98ShadingRunLoop( pScanData ps )
652141cc406Sopenharmony_ci{
653141cc406Sopenharmony_ci	int		    i;
654141cc406Sopenharmony_ci	DataPointer p;
655141cc406Sopenharmony_ci
656141cc406Sopenharmony_ci    p.pb = ps->a_nbNewAdrPointer;
657141cc406Sopenharmony_ci
658141cc406Sopenharmony_ci    switch( ps->IO.portMode ) {
659141cc406Sopenharmony_ci	case _PORT_SPP:
660141cc406Sopenharmony_ci	case _PORT_BIDI:
661141cc406Sopenharmony_ci	    *p.pw++ = 0;
662141cc406Sopenharmony_ci	    for (i = 0; i < 7; i++)
663141cc406Sopenharmony_ci			*p.pdw++ = 0x00800700;
664141cc406Sopenharmony_ci	    *p.pw = 0;
665141cc406Sopenharmony_ci	    break;
666141cc406Sopenharmony_ci
667141cc406Sopenharmony_ci	default:
668141cc406Sopenharmony_ci	    *p.pb++ = 0;
669141cc406Sopenharmony_ci	    for (i = 0; i < 15; i++)
670141cc406Sopenharmony_ci			*p.pw++ = 0xf888;
671141cc406Sopenharmony_ci	    *p.pb = 0;
672141cc406Sopenharmony_ci    }
673141cc406Sopenharmony_ci
674141cc406Sopenharmony_ci	IOSetToMotorRegister( ps );
675141cc406Sopenharmony_ci}
676141cc406Sopenharmony_ci
677141cc406Sopenharmony_ci/**
678141cc406Sopenharmony_ci */
679141cc406Sopenharmony_cistatic void dacP98Adjust12BitShading( pScanData ps )
680141cc406Sopenharmony_ci{
681141cc406Sopenharmony_ci	DataPointer pd, pt;
682141cc406Sopenharmony_ci    ULong		dw, dw1, dwLoop;
683141cc406Sopenharmony_ci
684141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98Adjust12BitShading()\n" );
685141cc406Sopenharmony_ci
686141cc406Sopenharmony_ci    memset( ps->pScanBuffer1, 0, (5400 * 4 * 3));
687141cc406Sopenharmony_ci
688141cc406Sopenharmony_ci    if( ps->Shade.pHilight && (_Shading_32Times == ps->bShadingTimeFlag)) {
689141cc406Sopenharmony_ci
690141cc406Sopenharmony_ci		memset( ps->Shade.pHilight, 0, (ps->dwHilight * 2UL));
691141cc406Sopenharmony_ci
692141cc406Sopenharmony_ci		for (dw = 0; dw < ps->dwShadow; dw++)
693141cc406Sopenharmony_ci		    ps->pwShadow[dw] = 0xfff;
694141cc406Sopenharmony_ci    }
695141cc406Sopenharmony_ci
696141cc406Sopenharmony_ci	/*
697141cc406Sopenharmony_ci	 * in the original code this function does not exist !
698141cc406Sopenharmony_ci	 * (of course the code behind the function does ;-)
699141cc406Sopenharmony_ci	 */
700141cc406Sopenharmony_ci	dacP98SetAdjustShadingRegister( ps );
701141cc406Sopenharmony_ci
702141cc406Sopenharmony_ci    dacP98ShadingRunLoop( ps );
703141cc406Sopenharmony_ci    _DODELAY( 24 );
704141cc406Sopenharmony_ci
705141cc406Sopenharmony_ci    if ((ps->DataInf.dwScanFlag & SCANDEF_TPA ) ||
706141cc406Sopenharmony_ci	  	(_Shading_32Times == ps->bShadingTimeFlag)) {
707141cc406Sopenharmony_ci		dwLoop = 32;
708141cc406Sopenharmony_ci	} else {
709141cc406Sopenharmony_ci		if (_Shading_16Times == ps->bShadingTimeFlag) {
710141cc406Sopenharmony_ci		   dwLoop = 16;
711141cc406Sopenharmony_ci		} else {
712141cc406Sopenharmony_ci		   dwLoop = 4;
713141cc406Sopenharmony_ci		}
714141cc406Sopenharmony_ci    }
715141cc406Sopenharmony_ci
716141cc406Sopenharmony_ci    for (dw1 = 0; dw1 < dwLoop; dw1++) {
717141cc406Sopenharmony_ci
718141cc406Sopenharmony_ci        ps->Scan.bFifoSelect = ps->RegGFifoOffset;
719141cc406Sopenharmony_ci
720141cc406Sopenharmony_ci		dacP98ReadShadingScanLine( ps );
721141cc406Sopenharmony_ci
722141cc406Sopenharmony_ci		if((_Shading_32Times == ps->bShadingTimeFlag) && ps->Shade.pHilight ) {
723141cc406Sopenharmony_ci
724141cc406Sopenharmony_ci		    dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2, 0, 0 );
725141cc406Sopenharmony_ci	    	dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2 +
726141cc406Sopenharmony_ci												  ps->dwShadingPixels,
727141cc406Sopenharmony_ci						       	     ps->dwHilightCh, ps->dwShadowCh );
728141cc406Sopenharmony_ci
729141cc406Sopenharmony_ci		    dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2 +
730141cc406Sopenharmony_ci												  ps->dwShadingPixels * 2,
731141cc406Sopenharmony_ci							       	  ps->dwHilightCh * 2, ps->dwShadowCh * 2);
732141cc406Sopenharmony_ci		}
733141cc406Sopenharmony_ci
734141cc406Sopenharmony_ci	    /* SumAdd12BitShadingR */
735141cc406Sopenharmony_ci		pd.pw  = (pUShort)ps->pScanBuffer2;
736141cc406Sopenharmony_ci		pt.pdw = (pULong)(ps->pScanBuffer1 + dwADCPipeLine);
737141cc406Sopenharmony_ci
738141cc406Sopenharmony_ci		for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
739141cc406Sopenharmony_ci		    *pt.pdw += (ULong)(*pd.pw & 0x0fff);
740141cc406Sopenharmony_ci
741141cc406Sopenharmony_ci	    /* SumAdd10BitShadingG */
742141cc406Sopenharmony_ci		if( ps->bSetScanModeFlag & _ScanMode_AverageOut )
743141cc406Sopenharmony_ci		    pd.pw = (pUShort)(ps->pScanBuffer2 + 2700 * 2);
744141cc406Sopenharmony_ci		else
745141cc406Sopenharmony_ci		    pd.pw = (pUShort)(ps->pScanBuffer2 + 5400 * 2);
746141cc406Sopenharmony_ci
747141cc406Sopenharmony_ci		pt.pdw = (pULong)(ps->pScanBuffer1 + 5400 * 4 + dwADCPipeLine);
748141cc406Sopenharmony_ci
749141cc406Sopenharmony_ci		for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
750141cc406Sopenharmony_ci	    	*pt.pdw += (ULong)(*pd.pw & 0x0fff);
751141cc406Sopenharmony_ci
752141cc406Sopenharmony_ci	    /* SumAdd12BitShadingB */
753141cc406Sopenharmony_ci		if( ps->bSetScanModeFlag & _ScanMode_AverageOut )
754141cc406Sopenharmony_ci		    pd.pw = (pUShort)(ps->pScanBuffer2 + 2700 * 4);
755141cc406Sopenharmony_ci		else
756141cc406Sopenharmony_ci	    	pd.pw = (pUShort)(ps->pScanBuffer2 + 5400 * 4);
757141cc406Sopenharmony_ci
758141cc406Sopenharmony_ci		pt.pdw = (pULong)(ps->pScanBuffer1 + 5400 * 8 + dwADCPipeLine);
759141cc406Sopenharmony_ci
760141cc406Sopenharmony_ci		for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
761141cc406Sopenharmony_ci		    *pt.pdw += (ULong)(*pd.pw * 94 / 100 & 0x0fff);
762141cc406Sopenharmony_ci
763141cc406Sopenharmony_ci		/* one line */
764141cc406Sopenharmony_ci		if (IOReadFifoLength( ps ) <= 2500)
765141cc406Sopenharmony_ci	    	IORegisterDirectToScanner( ps, ps->RegRefreshScanState );
766141cc406Sopenharmony_ci    }
767141cc406Sopenharmony_ci
768141cc406Sopenharmony_ci    TPAP98001AverageShadingData( ps );
769141cc406Sopenharmony_ci
770141cc406Sopenharmony_ci	ps->OpenScanPath( ps );
771141cc406Sopenharmony_ci	dacP98WriteBackToShadingRAM( ps );
772141cc406Sopenharmony_ci	ps->CloseScanPath( ps );
773141cc406Sopenharmony_ci}
774141cc406Sopenharmony_ci
775141cc406Sopenharmony_ci/**
776141cc406Sopenharmony_ci */
777141cc406Sopenharmony_cistatic Bool dacP98WaitForShading( pScanData ps )
778141cc406Sopenharmony_ci{
779141cc406Sopenharmony_ci    Byte oldLineControl;
780141cc406Sopenharmony_ci
781141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98WaitForShading()\n" );
782141cc406Sopenharmony_ci
783141cc406Sopenharmony_ci	/*
784141cc406Sopenharmony_ci	 * before getting the shading data, (re)init the ASIC
785141cc406Sopenharmony_ci	 */
786141cc406Sopenharmony_ci    ps->InitialSetCurrentSpeed( ps );
787141cc406Sopenharmony_ci	ps->ReInitAsic( ps, _TRUE );
788141cc406Sopenharmony_ci
789141cc406Sopenharmony_ci	IOCmdRegisterToScanner( ps, ps->RegLineControl,
790141cc406Sopenharmony_ci							ps->AsicReg.RD_LineControl );
791141cc406Sopenharmony_ci
792141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Red   = 0;
793141cc406Sopenharmony_ci	ps->Shade.DarkOffset.Colors.Green = 0;
794141cc406Sopenharmony_ci	ps->Shade.DarkOffset.Colors.Blue  = 0;
795141cc406Sopenharmony_ci
796141cc406Sopenharmony_ci	/*
797141cc406Sopenharmony_ci	 * according to the scan mode, switch on the lamp
798141cc406Sopenharmony_ci	 */
799141cc406Sopenharmony_ci    IOSelectLampSource( ps );
800141cc406Sopenharmony_ci    IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
801141cc406Sopenharmony_ci
802141cc406Sopenharmony_ci    if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
803141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi300;
804141cc406Sopenharmony_ci	} else {
805141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi600;
806141cc406Sopenharmony_ci	}
807141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegModelControl,
808141cc406Sopenharmony_ci							ps->AsicReg.RD_ModelControl );
809141cc406Sopenharmony_ci
810141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeScan);
811141cc406Sopenharmony_ci
812141cc406Sopenharmony_ci    oldLineControl = ps->AsicReg.RD_LineControl;
813141cc406Sopenharmony_ci	IOSetXStepLineScanTime( ps, _DEFAULT_LINESCANTIME );
814141cc406Sopenharmony_ci
815141cc406Sopenharmony_ci	/* set line control */
816141cc406Sopenharmony_ci	IOCmdRegisterToScanner( ps, ps->RegLineControl,
817141cc406Sopenharmony_ci							ps->AsicReg.RD_LineControl );
818141cc406Sopenharmony_ci
819141cc406Sopenharmony_ci	/* Wait for Sensor to position */
820141cc406Sopenharmony_ci	if( !ps->GotoShadingPosition( ps ))
821141cc406Sopenharmony_ci		return _FALSE;
822141cc406Sopenharmony_ci
823141cc406Sopenharmony_ci    ps->AsicReg.RD_LineControl = oldLineControl;
824141cc406Sopenharmony_ci    IOCmdRegisterToScanner( ps, ps->RegLineControl,
825141cc406Sopenharmony_ci							ps->AsicReg.RD_LineControl );
826141cc406Sopenharmony_ci
827141cc406Sopenharmony_ci    dwADCPipeLine = 4 * 4;
828141cc406Sopenharmony_ci
829141cc406Sopenharmony_ci    if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
830141cc406Sopenharmony_ci		dwReadyLen			= 2500;
831141cc406Sopenharmony_ci		ps->dwShadingLen	= 2700 * 2;
832141cc406Sopenharmony_ci		ps->dwShadingPixels	= 2700;
833141cc406Sopenharmony_ci    } else {
834141cc406Sopenharmony_ci		dwReadyLen			= 5000;
835141cc406Sopenharmony_ci		ps->dwShadingLen	= 5400 * 2;
836141cc406Sopenharmony_ci		ps->dwShadingPixels	= 5400;
837141cc406Sopenharmony_ci    }
838141cc406Sopenharmony_ci
839141cc406Sopenharmony_ci	dacP98AdjustRGBGain		( ps );
840141cc406Sopenharmony_ci	DacP98AdjustDark		( ps );
841141cc406Sopenharmony_ci	dacP98Adjust12BitShading( ps );
842141cc406Sopenharmony_ci
843141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
844141cc406Sopenharmony_ci	DacP98FillShadingDarkToShadingRegister( ps );
845141cc406Sopenharmony_ci
846141cc406Sopenharmony_ci	if ( COLOR_BW != ps->DataInf.wPhyDataType )
847141cc406Sopenharmony_ci		dacP98DownloadMapTable( ps, ps->a_bMapTable );
848141cc406Sopenharmony_ci
849141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
850141cc406Sopenharmony_ci
851141cc406Sopenharmony_ci    return _TRUE;
852141cc406Sopenharmony_ci}
853141cc406Sopenharmony_ci
854141cc406Sopenharmony_ci/** Set RAM bank and size, then write the data to it
855141cc406Sopenharmony_ci */
856141cc406Sopenharmony_cistatic void dacP96FillWhole4kRAM( pScanData ps, pUChar pBuf )
857141cc406Sopenharmony_ci{
858141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
859141cc406Sopenharmony_ci
860141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegMemAccessControl,
861141cc406Sopenharmony_ci		    			  ps->Asic96Reg.RD_MemAccessControl );
862141cc406Sopenharmony_ci
863141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl = _ModeProgram;
864141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
865141cc406Sopenharmony_ci
866141cc406Sopenharmony_ci    IOMoveDataToScanner( ps, pBuf, ps->ShadingBankSize );
867141cc406Sopenharmony_ci
868141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl = _ModeScan;
869141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
870141cc406Sopenharmony_ci
871141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
872141cc406Sopenharmony_ci}
873141cc406Sopenharmony_ci
874141cc406Sopenharmony_ci/**
875141cc406Sopenharmony_ci */
876141cc406Sopenharmony_cistatic void	dacP96FillChannelDarkOffset( pScanData ps )
877141cc406Sopenharmony_ci{
878141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
879141cc406Sopenharmony_ci
880141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegRedChDarkOffset,
881141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_RedChDarkOff );
882141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegGreenChDarkOffset,
883141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_GreenChDarkOff );
884141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegBlueChDarkOffset,
885141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_BlueChDarkOff );
886141cc406Sopenharmony_ci
887141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
888141cc406Sopenharmony_ci}
889141cc406Sopenharmony_ci
890141cc406Sopenharmony_ci/**
891141cc406Sopenharmony_ci */
892141cc406Sopenharmony_cistatic void dacP96FillEvenOddControl( pScanData ps )
893141cc406Sopenharmony_ci{
894141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
895141cc406Sopenharmony_ci
896141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegRedChEvenOffset,
897141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_RedChEvenOff );
898141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegGreenChEvenOffset,
899141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_GreenChEvenOff );
900141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegBlueChEvenOffset,
901141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_BlueChEvenOff );
902141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegRedChOddOffset,
903141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_RedChOddOff );
904141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegGreenChOddOffset,
905141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_GreenChOddOff );
906141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegBlueChOddOffset,
907141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_BlueChOddOff );
908141cc406Sopenharmony_ci
909141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
910141cc406Sopenharmony_ci}
911141cc406Sopenharmony_ci
912141cc406Sopenharmony_ci/** Used for capture data to pScanData->pPrescan16.
913141cc406Sopenharmony_ci *  Used to replace:
914141cc406Sopenharmony_ci *	1) ReadFBKScanLine (3 * 1024, 5)
915141cc406Sopenharmony_ci *	2) ReadOneScanLine (3 * 2560, 11)
916141cc406Sopenharmony_ci *	4) ReadShadingScanLine (3 * 1280, 6)
917141cc406Sopenharmony_ci */
918141cc406Sopenharmony_cistatic void dacP96ReadDataWithinOneSecond( pScanData ps,
919141cc406Sopenharmony_ci										   ULong dwLen, Byte bBlks )
920141cc406Sopenharmony_ci{
921141cc406Sopenharmony_ci	TimerDef timer;
922141cc406Sopenharmony_ci
923141cc406Sopenharmony_ci    MiscStartTimer( &timer, _SECOND );
924141cc406Sopenharmony_ci
925141cc406Sopenharmony_ci    while((IODataRegisterFromScanner( ps, ps->RegFifoOffset) < bBlks) &&
926141cc406Sopenharmony_ci	   		!MiscCheckTimer(&timer));
927141cc406Sopenharmony_ci
928141cc406Sopenharmony_ci    IOReadScannerImageData( ps, ps->pPrescan16, dwLen );
929141cc406Sopenharmony_ci}
930141cc406Sopenharmony_ci
931141cc406Sopenharmony_ci/**
932141cc406Sopenharmony_ci */
933141cc406Sopenharmony_cistatic void dacP96GetEvenOddOffset( pUChar pb, pWordVal pwv )
934141cc406Sopenharmony_ci{
935141cc406Sopenharmony_ci	ULong	dw;
936141cc406Sopenharmony_ci    UShort	we, wo;
937141cc406Sopenharmony_ci
938141cc406Sopenharmony_ci    for (dw = 8, we = wo = 0; dw; dw-- ) {
939141cc406Sopenharmony_ci		we += *pb++;
940141cc406Sopenharmony_ci		wo += *pb++;
941141cc406Sopenharmony_ci    }
942141cc406Sopenharmony_ci
943141cc406Sopenharmony_ci    pwv->b1st = (Byte)(we >> 3);
944141cc406Sopenharmony_ci    pwv->b2nd = (Byte)(wo >> 3);
945141cc406Sopenharmony_ci}
946141cc406Sopenharmony_ci
947141cc406Sopenharmony_ci/**
948141cc406Sopenharmony_ci */
949141cc406Sopenharmony_cistatic void dacP96SumAverageShading( pScanData ps, pUChar pDest, pUChar pSrce )
950141cc406Sopenharmony_ci{
951141cc406Sopenharmony_ci	ULong  dw;
952141cc406Sopenharmony_ci	UShort wLeft[6];
953141cc406Sopenharmony_ci	UShort wSumL, wSumR;
954141cc406Sopenharmony_ci
955141cc406Sopenharmony_ci    pSrce += ps->Offset70 + ps->Device.DataOriginX;
956141cc406Sopenharmony_ci    pDest += ps->Offset70 + ps->Device.DataOriginX;
957141cc406Sopenharmony_ci
958141cc406Sopenharmony_ci    wLeft[0] = wLeft[1] = wLeft[2] =
959141cc406Sopenharmony_ci	wLeft[3] = wLeft[4] = wLeft[5] = (UShort)*pSrce;
960141cc406Sopenharmony_ci
961141cc406Sopenharmony_ci    wSumL = wLeft[0] * 6;
962141cc406Sopenharmony_ci    wSumR = (UShort)pSrce[1] + pSrce[2] + pSrce[3] + pSrce[4] +
963141cc406Sopenharmony_ci		            pSrce[5] + pSrce[6];
964141cc406Sopenharmony_ci
965141cc406Sopenharmony_ci/*  for (dw = 2772; dw; dw--, pSrce++, pDest++) */
966141cc406Sopenharmony_ci    for (dw = ps->BufferSizePerModel - 6; dw; dw--, pSrce++, pDest++) {
967141cc406Sopenharmony_ci
968141cc406Sopenharmony_ci		*pDest = (Byte)(((UShort)*pSrce * 4 + wSumL + wSumR) / 16);
969141cc406Sopenharmony_ci		wSumL  = wSumL - wLeft [0] + (UShort)*pSrce;
970141cc406Sopenharmony_ci
971141cc406Sopenharmony_ci		wLeft[0] = wLeft[1];
972141cc406Sopenharmony_ci		wLeft[1] = wLeft[2];
973141cc406Sopenharmony_ci		wLeft[2] = wLeft[3];
974141cc406Sopenharmony_ci		wLeft[3] = wLeft[4];
975141cc406Sopenharmony_ci		wLeft[4] = wLeft[5];
976141cc406Sopenharmony_ci		wLeft[5] = (UShort)*pSrce;
977141cc406Sopenharmony_ci		wSumR = wSumR - (UShort) *(pSrce + 1) + (UShort) *(pSrce + 7);
978141cc406Sopenharmony_ci    }
979141cc406Sopenharmony_ci}
980141cc406Sopenharmony_ci
981141cc406Sopenharmony_ci/**
982141cc406Sopenharmony_ci */
983141cc406Sopenharmony_cistatic void dacP96WriteLinearGamma( pScanData ps,
984141cc406Sopenharmony_ci								    pUChar pBuf, ULong dwEntries, Byte bBank )
985141cc406Sopenharmony_ci{
986141cc406Sopenharmony_ci	ULong   dw;
987141cc406Sopenharmony_ci    pULong	pdw = (pULong)(pBuf + ps->ShadingBufferSize);
988141cc406Sopenharmony_ci
989141cc406Sopenharmony_ci    for (dw = 0; dwEntries; pdw++, dwEntries--, dw += 0x01010101)
990141cc406Sopenharmony_ci		*pdw = dw;
991141cc406Sopenharmony_ci
992141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = bBank;
993141cc406Sopenharmony_ci
994141cc406Sopenharmony_ci    dacP96FillWhole4kRAM( ps, pBuf );
995141cc406Sopenharmony_ci}
996141cc406Sopenharmony_ci
997141cc406Sopenharmony_ci/**
998141cc406Sopenharmony_ci */
999141cc406Sopenharmony_cistatic void dacP96FillChannelShadingOffset( pScanData ps )
1000141cc406Sopenharmony_ci{
1001141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
1002141cc406Sopenharmony_ci
1003141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegRedChShadingOffset,
1004141cc406Sopenharmony_ci					  ps->Asic96Reg.u28.RD_RedChShadingOff);
1005141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegGreenChShadingOffset,
1006141cc406Sopenharmony_ci					  ps->Asic96Reg.u29.RD_GreenChShadingOff);
1007141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegBlueChShadingOffset,
1008141cc406Sopenharmony_ci					  ps->Asic96Reg.RD_BlueChShadingOff);
1009141cc406Sopenharmony_ci
1010141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
1011141cc406Sopenharmony_ci}
1012141cc406Sopenharmony_ci
1013141cc406Sopenharmony_ci/**
1014141cc406Sopenharmony_ci */
1015141cc406Sopenharmony_cistatic void dacP96GetHilightShadow( pScanData ps,
1016141cc406Sopenharmony_ci									pUChar pBuf, pUChar pChOff, pUChar pHigh )
1017141cc406Sopenharmony_ci{
1018141cc406Sopenharmony_ci 	ULong dw;
1019141cc406Sopenharmony_ci
1020141cc406Sopenharmony_ci	/* GetShadingImageExtent (ps) */
1021141cc406Sopenharmony_ci	if (ps->DataInf.wAppDataType < COLOR_256GRAY)
1022141cc406Sopenharmony_ci		dw = (ULong)(ps->DataInf.crImage.cx & 0xfff8);
1023141cc406Sopenharmony_ci	else
1024141cc406Sopenharmony_ci		dw = (ULong)ps->DataInf.crImage.cx;
1025141cc406Sopenharmony_ci
1026141cc406Sopenharmony_ci    for( pBuf += ps->DataInf.crImage.x, *pChOff = 0xff, *pHigh = 0;
1027141cc406Sopenharmony_ci		 dw; dw--, pBuf++ ) {
1028141cc406Sopenharmony_ci
1029141cc406Sopenharmony_ci		if (*pChOff < *pBuf) {
1030141cc406Sopenharmony_ci		    if (*pHigh < *pBuf)
1031141cc406Sopenharmony_ci				*pHigh = *pBuf; /* brightest */
1032141cc406Sopenharmony_ci		} else
1033141cc406Sopenharmony_ci		    *pChOff = *pBuf;	/* darkest */
1034141cc406Sopenharmony_ci    }
1035141cc406Sopenharmony_ci}
1036141cc406Sopenharmony_ci
1037141cc406Sopenharmony_ci/**
1038141cc406Sopenharmony_ci */
1039141cc406Sopenharmony_cistatic void dacP96ReadColorShadingLine( pScanData ps )
1040141cc406Sopenharmony_ci{
1041141cc406Sopenharmony_ci    Byte	 b2ndDiscard, b3rdDiscard, b1stReadLines, b2ndReadLines;
1042141cc406Sopenharmony_ci    Byte	 b3rdReadLines;
1043141cc406Sopenharmony_ci	ULong	 dw;
1044141cc406Sopenharmony_ci    DataType Data;
1045141cc406Sopenharmony_ci
1046141cc406Sopenharmony_ci    /* ClearScanBuffer1 (ps) */
1047141cc406Sopenharmony_ci	/* buffer to keep sum of data */
1048141cc406Sopenharmony_ci    memset( ps->pScanBuffer1, 0, ps->BufferForDataRead1 );
1049141cc406Sopenharmony_ci
1050141cc406Sopenharmony_ci    b2ndDiscard   = ps->b2ndLinesOffset;
1051141cc406Sopenharmony_ci    b3rdDiscard   = ps->b1stLinesOffset;
1052141cc406Sopenharmony_ci    b1stReadLines = b2ndReadLines = b3rdReadLines = 8;
1053141cc406Sopenharmony_ci
1054141cc406Sopenharmony_ci    while( _TRUE ) {
1055141cc406Sopenharmony_ci
1056141cc406Sopenharmony_ci		/* ReadShadingScanLine(ps) */
1057141cc406Sopenharmony_ci		dacP96ReadDataWithinOneSecond( ps, ps->ShadingScanLineLen,
1058141cc406Sopenharmony_ci					 				   ps->ShadingScanLineBlks );
1059141cc406Sopenharmony_ci
1060141cc406Sopenharmony_ci		if (b1stReadLines) {
1061141cc406Sopenharmony_ci
1062141cc406Sopenharmony_ci		    b1stReadLines--;
1063141cc406Sopenharmony_ci
1064141cc406Sopenharmony_ci	    	/* SumAdd10BitShadingR */
1065141cc406Sopenharmony_ci		    for (dw = 0; dw < ps->BufferSizeBase; dw++)
1066141cc406Sopenharmony_ci    			((pUShort)ps->pScanBuffer1)[dw] += (UShort)ps->pPrescan16 [dw];
1067141cc406Sopenharmony_ci		}
1068141cc406Sopenharmony_ci
1069141cc406Sopenharmony_ci		if (!b2ndDiscard) {
1070141cc406Sopenharmony_ci		    if (b2ndReadLines) {
1071141cc406Sopenharmony_ci				b2ndReadLines--;
1072141cc406Sopenharmony_ci				/* SumAdd10BitShadingG */
1073141cc406Sopenharmony_ci				for (dw = ps->BufferSizeBase;dw < (ULong)ps->BufferSizeBase * 2;dw++) {
1074141cc406Sopenharmony_ci				    ((pUShort)ps->pScanBuffer1)[dw] +=
1075141cc406Sopenharmony_ci													(UShort)ps->pPrescan16[dw];
1076141cc406Sopenharmony_ci				}
1077141cc406Sopenharmony_ci		    }
1078141cc406Sopenharmony_ci		} else
1079141cc406Sopenharmony_ci		    b2ndDiscard--;
1080141cc406Sopenharmony_ci
1081141cc406Sopenharmony_ci		if (!b3rdDiscard) {
1082141cc406Sopenharmony_ci		    if (b3rdReadLines) {
1083141cc406Sopenharmony_ci				b3rdReadLines--;
1084141cc406Sopenharmony_ci				/* SumAdd10BitShadingB */
1085141cc406Sopenharmony_ci				for (dw = ps->BufferSizeBase * 2;
1086141cc406Sopenharmony_ci						dw < (ULong)ps->BufferSizeBase * 3; dw++) {
1087141cc406Sopenharmony_ci				    ((pUShort)ps->pScanBuffer1)[dw] +=
1088141cc406Sopenharmony_ci													(UShort)ps->pPrescan16[dw];
1089141cc406Sopenharmony_ci				}
1090141cc406Sopenharmony_ci		    } else
1091141cc406Sopenharmony_ci				break;
1092141cc406Sopenharmony_ci		} else
1093141cc406Sopenharmony_ci		    b3rdDiscard--;
1094141cc406Sopenharmony_ci
1095141cc406Sopenharmony_ci		IORegisterDirectToScanner( ps, ps->RegRefreshScanState );
1096141cc406Sopenharmony_ci    }
1097141cc406Sopenharmony_ci
1098141cc406Sopenharmony_ci    for (dw = 0; dw < (ULong)ps->BufferSizeBase * 3; dw++) {
1099141cc406Sopenharmony_ci
1100141cc406Sopenharmony_ci		Data.wOverlap.b1st =
1101141cc406Sopenharmony_ci		Data.wOverlap.b2nd = (Byte)(((pUShort)ps->pScanBuffer1)[dw] / 8);
1102141cc406Sopenharmony_ci		((pUShort)ps->pPrescan16)[dw] = Data.wValue;
1103141cc406Sopenharmony_ci    }
1104141cc406Sopenharmony_ci}
1105141cc406Sopenharmony_ci
1106141cc406Sopenharmony_ci/**
1107141cc406Sopenharmony_ci */
1108141cc406Sopenharmony_cistatic void dacP96SetShadingGainProc( pScanData ps, Byte bHigh, ULong dwCh )
1109141cc406Sopenharmony_ci{
1110141cc406Sopenharmony_ci	Byte	bDark, bGain, bGainX2, bGainX4, bMask;
1111141cc406Sopenharmony_ci	pUChar	pbChDark, pbSrce, pbDest;
1112141cc406Sopenharmony_ci	ULong	dw;
1113141cc406Sopenharmony_ci
1114141cc406Sopenharmony_ci    pbChDark = NULL, pbSrce = NULL, pbDest = NULL;
1115141cc406Sopenharmony_ci    bDark = 0, bGain = 0, bGainX2 = 0, bGainX4 = 0, bMask = 0;
1116141cc406Sopenharmony_ci
1117141cc406Sopenharmony_ci    switch( dwCh ) {
1118141cc406Sopenharmony_ci
1119141cc406Sopenharmony_ci	case 0: 	/* red */
1120141cc406Sopenharmony_ci	    pbChDark = &ps->Asic96Reg.u28.RD_RedChShadingOff;
1121141cc406Sopenharmony_ci	    pbSrce   = ps->pPrescan16;
1122141cc406Sopenharmony_ci	    pbDest   = ps->pScanBuffer1 + ps->Offset70 + ps->Device.DataOriginX;
1123141cc406Sopenharmony_ci	    bGainX2  = 1;
1124141cc406Sopenharmony_ci	    bGainX4  = 3;
1125141cc406Sopenharmony_ci	    bMask    = 0x3c;
1126141cc406Sopenharmony_ci	    break;
1127141cc406Sopenharmony_ci
1128141cc406Sopenharmony_ci	case 1: 	/* green */
1129141cc406Sopenharmony_ci	    pbChDark = &ps->Asic96Reg.u29.RD_GreenChShadingOff;
1130141cc406Sopenharmony_ci	    pbSrce   = ps->pPrescan16 + ps->BufferSizePerModel;
1131141cc406Sopenharmony_ci	    pbDest   = ps->pScanBuffer1 + ps->Offset70 + ps->ShadingBankSize +
1132141cc406Sopenharmony_ci				   ps->Device.DataOriginX;
1133141cc406Sopenharmony_ci	    bGainX2  = 4;
1134141cc406Sopenharmony_ci	    bGainX4  = 0x0c;
1135141cc406Sopenharmony_ci	    bMask    = 0x33;
1136141cc406Sopenharmony_ci	    break;
1137141cc406Sopenharmony_ci
1138141cc406Sopenharmony_ci	case 2:
1139141cc406Sopenharmony_ci	    pbChDark = &ps->Asic96Reg.RD_BlueChShadingOff;
1140141cc406Sopenharmony_ci	    pbSrce   = ps->pPrescan16 + ps->BufferSizePerModel * 2;
1141141cc406Sopenharmony_ci	    pbDest   = ps->pScanBuffer1 + ps->Offset70 + ps->ShadingBankSize * 2 +
1142141cc406Sopenharmony_ci				   ps->Device.DataOriginX;
1143141cc406Sopenharmony_ci	    bGainX2  = 0x10;
1144141cc406Sopenharmony_ci	    bGainX4  = 0x30;
1145141cc406Sopenharmony_ci	    bMask    = 0x0f;
1146141cc406Sopenharmony_ci    }
1147141cc406Sopenharmony_ci
1148141cc406Sopenharmony_ci    bDark = *pbChDark;
1149141cc406Sopenharmony_ci    if ((bHigh -= bDark) > 60U) {
1150141cc406Sopenharmony_ci		/* Hilight - Shadow > 60, Quality not so good */
1151141cc406Sopenharmony_ci		bGain = bGainX2;		/* Gain x 2 */
1152141cc406Sopenharmony_ci		if (bHigh > 120U)
1153141cc406Sopenharmony_ci		    bGain = bGainX4;	/* Poor quality, Gain x 4 */
1154141cc406Sopenharmony_ci    } else
1155141cc406Sopenharmony_ci		bGain = 0;
1156141cc406Sopenharmony_ci
1157141cc406Sopenharmony_ci    ps->Asic96Reg.RD_ShadingCorrectCtrl &= bMask;
1158141cc406Sopenharmony_ci    ps->Asic96Reg.RD_ShadingCorrectCtrl |= bGain;
1159141cc406Sopenharmony_ci
1160141cc406Sopenharmony_ci    if (!bGain) {
1161141cc406Sopenharmony_ci		/* GammaGain1 (ps) */
1162141cc406Sopenharmony_ci		for (dw = ps->BufferSizePerModel; dw; dw--, pbSrce++, pbDest++)
1163141cc406Sopenharmony_ci		    if (*pbSrce > bDark)
1164141cc406Sopenharmony_ci				*pbDest = (*pbSrce - bDark) * 4;
1165141cc406Sopenharmony_ci	    	else
1166141cc406Sopenharmony_ci				*pbDest = 0;
1167141cc406Sopenharmony_ci    } else
1168141cc406Sopenharmony_ci		if (bGain == bGainX2) {
1169141cc406Sopenharmony_ci			/* GammaGain2 */
1170141cc406Sopenharmony_ci		    for (dw = ps->BufferSizePerModel; dw; dw--, pbSrce++, pbDest++)
1171141cc406Sopenharmony_ci				if (*pbSrce > bDark)
1172141cc406Sopenharmony_ci				    *pbDest = (*pbSrce - bDark) * 2;
1173141cc406Sopenharmony_ci				else
1174141cc406Sopenharmony_ci				    *pbDest = 0;
1175141cc406Sopenharmony_ci		} else {
1176141cc406Sopenharmony_ci			/* GammaGain4 (ps) */
1177141cc406Sopenharmony_ci			memcpy( pbDest, pbSrce, ps->BufferSizePerModel );
1178141cc406Sopenharmony_ci		    *pbChDark = 0;
1179141cc406Sopenharmony_ci		}
1180141cc406Sopenharmony_ci}
1181141cc406Sopenharmony_ci
1182141cc406Sopenharmony_ci/**
1183141cc406Sopenharmony_ci */
1184141cc406Sopenharmony_cistatic void dacP96FillShadingAndGammaTable( pScanData ps )
1185141cc406Sopenharmony_ci{
1186141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankRed;		/* R */
1187141cc406Sopenharmony_ci	dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
1188141cc406Sopenharmony_ci
1189141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankGreen;	/* G */
1190141cc406Sopenharmony_ci	dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
1191141cc406Sopenharmony_ci
1192141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankBlue;	/* B */
1193141cc406Sopenharmony_ci	dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
1194141cc406Sopenharmony_ci}
1195141cc406Sopenharmony_ci
1196141cc406Sopenharmony_ci/**
1197141cc406Sopenharmony_ci */
1198141cc406Sopenharmony_cistatic void dacP96SetInitialGainRAM( pScanData ps )
1199141cc406Sopenharmony_ci{
1200141cc406Sopenharmony_ci    ULong  dw, dw1;
1201141cc406Sopenharmony_ci	pULong pdw = (pULong)(ps->pPrescan16 + ps->ShadingBufferSize);
1202141cc406Sopenharmony_ci
1203141cc406Sopenharmony_ci	memset( ps->pPrescan16, 0xff, ps->ShadingBufferSize );
1204141cc406Sopenharmony_ci
1205141cc406Sopenharmony_ci    for (dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101, pdw++)
1206141cc406Sopenharmony_ci		*pdw = dw1;
1207141cc406Sopenharmony_ci
1208141cc406Sopenharmony_ci	dacP96FillShadingAndGammaTable( ps );
1209141cc406Sopenharmony_ci}
1210141cc406Sopenharmony_ci
1211141cc406Sopenharmony_ci/**
1212141cc406Sopenharmony_ci */
1213141cc406Sopenharmony_cistatic void dacP96Adjust10BitShading( pScanData ps )
1214141cc406Sopenharmony_ci{
1215141cc406Sopenharmony_ci	pULong	pdw;
1216141cc406Sopenharmony_ci	ULong	dw;
1217141cc406Sopenharmony_ci	Byte	bRedHigh, bGreenHigh, bBlueHigh;
1218141cc406Sopenharmony_ci
1219141cc406Sopenharmony_ci    /* ShadingMotorRunLoop(ps)
1220141cc406Sopenharmony_ci	 * set scan states as:
1221141cc406Sopenharmony_ci     *	 40h, 00, 00, 00, 40h, 01, 03, 02, ... (repeat)
1222141cc406Sopenharmony_ci     * so, read a R/G/B line every 2 steps
1223141cc406Sopenharmony_ci	 */
1224141cc406Sopenharmony_ci    pdw = (pULong)ps->a_nbNewAdrPointer;
1225141cc406Sopenharmony_ci    for (dw = 0; dw < 4; dw++) {
1226141cc406Sopenharmony_ci		*pdw++ = 0x40;
1227141cc406Sopenharmony_ci		*pdw++ = 0x02030140;
1228141cc406Sopenharmony_ci	}
1229141cc406Sopenharmony_ci
1230141cc406Sopenharmony_ci    dacP96SetInitialGainRAM( ps);	/* initiates the shading buffers and maps */
1231141cc406Sopenharmony_ci
1232141cc406Sopenharmony_ci    /* SetAdjustShadingRegister(ps) */
1233141cc406Sopenharmony_ci    /* Prepare Physical/2 dpi, 8.5" scanning condition for reading the shading area */
1234141cc406Sopenharmony_ci    ps->AsicReg.RD_ScanControl    = ps->bLampOn | _SCAN_BYTEMODE;
1235141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MotorControl = ps->IgnorePF | ps->MotorOn |
1236141cc406Sopenharmony_ci									_MotorDirForward;
1237141cc406Sopenharmony_ci    ps->AsicReg.RD_ModelControl   = ps->Device.ModelCtrl | _ModelWhiteIs0;
1238141cc406Sopenharmony_ci    ps->AsicReg.RD_Dpi    		  = ps->PhysicalDpi / 2;
1239141cc406Sopenharmony_ci    ps->AsicReg.RD_Origin 		  = (UShort)(ps->Offset70 +
1240141cc406Sopenharmony_ci                                             ps->Device.DataOriginX);
1241141cc406Sopenharmony_ci    ps->AsicReg.RD_Pixels 		  = ps->BufferSizeBase;
1242141cc406Sopenharmony_ci    IOPutOnAllRegisters( ps );
1243141cc406Sopenharmony_ci
1244141cc406Sopenharmony_ci    ps->Asic96Reg.RD_ShadingCorrectCtrl = _ShadingRCorrectX4|_ShadingGCorrectX4|
1245141cc406Sopenharmony_ci									      _ShadingBCorrectX4;
1246141cc406Sopenharmony_ci	IOCmdRegisterToScanner( ps, ps->RegShadingCorrectCtrl,
1247141cc406Sopenharmony_ci						 			    ps->Asic96Reg.RD_ShadingCorrectCtrl );
1248141cc406Sopenharmony_ci
1249141cc406Sopenharmony_ci    /* Read shaded data and do average */
1250141cc406Sopenharmony_ci	dacP96ReadColorShadingLine( ps );
1251141cc406Sopenharmony_ci
1252141cc406Sopenharmony_ci    /* ExpandAndAverage (ps) ------------------------------------------------*/
1253141cc406Sopenharmony_ci/*
1254141cc406Sopenharmony_ci	 for (dw = 0; dw < 1280 * 3; dw++)
1255141cc406Sopenharmony_ci   {
1256141cc406Sopenharmony_ci	Data.wOverlap.b1st =
1257141cc406Sopenharmony_ci	Data.wOverlap.b2nd = (Byte)(((pUShort) ps->pScanBuffer1)[dw] / 8);
1258141cc406Sopenharmony_ci	((pULong) ps->pPrescan16)[dw] = Data.wValue;
1259141cc406Sopenharmony_ci  }
1260141cc406Sopenharmony_ci*/
1261141cc406Sopenharmony_ci	/* CalculateShadingOffset (ps); */
1262141cc406Sopenharmony_ci    dacP96GetHilightShadow( ps, ps->pPrescan16,
1263141cc406Sopenharmony_ci						&ps->Asic96Reg.u28.RD_RedChShadingOff, &bRedHigh );
1264141cc406Sopenharmony_ci
1265141cc406Sopenharmony_ci    dacP96GetHilightShadow( ps, ps->pPrescan16 + ps->BufferSizePerModel,
1266141cc406Sopenharmony_ci			      &ps->Asic96Reg.u29.RD_GreenChShadingOff, &bGreenHigh );
1267141cc406Sopenharmony_ci
1268141cc406Sopenharmony_ci    dacP96GetHilightShadow( ps, ps->pPrescan16 + ps->BufferSizePerModel * 2,
1269141cc406Sopenharmony_ci				      &ps->Asic96Reg.RD_BlueChShadingOff, &bBlueHigh );
1270141cc406Sopenharmony_ci
1271141cc406Sopenharmony_ci	/* SubTheImageDataBase (ps) */
1272141cc406Sopenharmony_ci	dacP96SetShadingGainProc( ps, bRedHigh,   0 );	/* red	 */
1273141cc406Sopenharmony_ci	dacP96SetShadingGainProc( ps, bGreenHigh, 1 );	/* green */
1274141cc406Sopenharmony_ci	dacP96SetShadingGainProc( ps, bBlueHigh,  2 );	/* blue	 */
1275141cc406Sopenharmony_ci	dacP96FillChannelShadingOffset( ps );
1276141cc406Sopenharmony_ci
1277141cc406Sopenharmony_ci	IOCmdRegisterToScanner( ps, ps->RegShadingCorrectCtrl,
1278141cc406Sopenharmony_ci						    ps->Asic96Reg.RD_ShadingCorrectCtrl );
1279141cc406Sopenharmony_ci
1280141cc406Sopenharmony_ci	dacP96SumAverageShading( ps, ps->pPrescan16, ps->pScanBuffer1 );
1281141cc406Sopenharmony_ci	dacP96SumAverageShading( ps, ps->pPrescan16 + ps->ShadingBankSize,
1282141cc406Sopenharmony_ci			  			     ps->pScanBuffer1 + ps->ShadingBankSize );
1283141cc406Sopenharmony_ci	dacP96SumAverageShading( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
1284141cc406Sopenharmony_ci					         ps->pScanBuffer1 + ps->ShadingBankSize * 2 );
1285141cc406Sopenharmony_ci
1286141cc406Sopenharmony_ci    /* --------------------------------------------------------------------- */
1287141cc406Sopenharmony_ci
1288141cc406Sopenharmony_ci    /* PrewriteBackToGammaShadingRAM( ps) */
1289141cc406Sopenharmony_ci    dacP96WriteLinearGamma( ps, ps->pPrescan16, 256, ps->ShadingBankRed );
1290141cc406Sopenharmony_ci   	dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize, 256,
1291141cc406Sopenharmony_ci							ps->ShadingBankGreen );
1292141cc406Sopenharmony_ci   	dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
1293141cc406Sopenharmony_ci    					    256, ps->ShadingBankBlue );
1294141cc406Sopenharmony_ci}
1295141cc406Sopenharmony_ci
1296141cc406Sopenharmony_ci/**
1297141cc406Sopenharmony_ci */
1298141cc406Sopenharmony_cistatic Bool dacP96003WaitForShading( pScanData ps )
1299141cc406Sopenharmony_ci{
1300141cc406Sopenharmony_ci	int 		bCorrectTimes;
1301141cc406Sopenharmony_ci	DataPointer	p;
1302141cc406Sopenharmony_ci    ULong		dw;
1303141cc406Sopenharmony_ci    UShort		w;
1304141cc406Sopenharmony_ci    WordVal 	wv;
1305141cc406Sopenharmony_ci	pUChar		pbReg[3];
1306141cc406Sopenharmony_ci    Byte		b[3];
1307141cc406Sopenharmony_ci
1308141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP96003WaitForShading()\n" );
1309141cc406Sopenharmony_ci
1310141cc406Sopenharmony_ci    /* TurnOnLamp () */
1311141cc406Sopenharmony_ci	ps->AsicReg.RD_ScanControl |= ps->bLampOn;
1312141cc406Sopenharmony_ci	IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
1313141cc406Sopenharmony_ci
1314141cc406Sopenharmony_ci	ps->Asic96Reg.RD_LedControl = _LedActControl | _LedMotorActEnable;
1315141cc406Sopenharmony_ci	IOCmdRegisterToScanner(ps, ps->RegLedControl, ps->Asic96Reg.RD_LedControl);
1316141cc406Sopenharmony_ci
1317141cc406Sopenharmony_ci    if ( ps->GotoShadingPosition( ps )) {
1318141cc406Sopenharmony_ci
1319141cc406Sopenharmony_ci    	/* AdjustRGBGain () =================================================*/
1320141cc406Sopenharmony_ci		ps->Asic96Reg.RD_RedGainOut  = ps->Asic96Reg.RD_GreenGainOut =
1321141cc406Sopenharmony_ci		ps->Asic96Reg.RD_BlueGainOut = 8;
1322141cc406Sopenharmony_ci		ps->Asic96Reg.u26.RD_ModelControl2 = _Model2DirectOutPort;
1323141cc406Sopenharmony_ci
1324141cc406Sopenharmony_ci		IOCmdRegisterToScanner(ps, ps->RegModelControl2, _Model2DirectOutPort);
1325141cc406Sopenharmony_ci
1326141cc406Sopenharmony_ci		for ( bCorrectTimes = 4; bCorrectTimes >= 1; bCorrectTimes-- ) {
1327141cc406Sopenharmony_ci
1328141cc406Sopenharmony_ci			ps->PauseColorMotorRunStates( ps );
1329141cc406Sopenharmony_ci
1330141cc406Sopenharmony_ci			/* SetRGBGainRegister () ----------------------------------------*/
1331141cc406Sopenharmony_ci		    ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
1332141cc406Sopenharmony_ci		    dacP96SetInitialGainRAM( ps );
1333141cc406Sopenharmony_ci
1334141cc406Sopenharmony_ci		    /* SetInitialGainRegister () ++++++++++++++++++++++++++++++++++++*/
1335141cc406Sopenharmony_ci		    ps->Asic96Reg.u28.RD_RedChShadingOff	=
1336141cc406Sopenharmony_ci			ps->Asic96Reg.u29.RD_GreenChShadingOff	=
1337141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_BlueChShadingOff		=
1338141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChDarkOff		 	=
1339141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_GreenChDarkOff			=
1340141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_BlueChDarkOff			=
1341141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChEvenOff			=
1342141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_GreenChEvenOff			=
1343141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_BlueChEvenOff			=
1344141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChOddOff			=
1345141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_GreenChOddOff			=
1346141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_BlueChOddOff			= 0;
1347141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_ShadingCorrectCtrl = _ShadingRCorrectX4 |
1348141cc406Sopenharmony_ci					 					    	  _ShadingGCorrectX4 |
1349141cc406Sopenharmony_ci											      _ShadingBCorrectX4;
1350141cc406Sopenharmony_ci
1351141cc406Sopenharmony_ci			dacP96FillChannelShadingOffset( ps );
1352141cc406Sopenharmony_ci		    dacP96FillChannelDarkOffset( ps );
1353141cc406Sopenharmony_ci			dacP96FillEvenOddControl( ps );
1354141cc406Sopenharmony_ci
1355141cc406Sopenharmony_ci		    /* FillGainOutDirectPort (); */
1356141cc406Sopenharmony_ci			ps->OpenScanPath( ps );
1357141cc406Sopenharmony_ci			IODataToRegister( ps, ps->RegRedGainOutDirect,
1358141cc406Sopenharmony_ci							  ps->Asic96Reg.RD_RedGainOut );
1359141cc406Sopenharmony_ci			IODataToRegister( ps, ps->RegGreenGainOutDirect,
1360141cc406Sopenharmony_ci							  ps->Asic96Reg.RD_GreenGainOut );
1361141cc406Sopenharmony_ci			IODataToRegister( ps, ps->RegBlueGainOutDirect,
1362141cc406Sopenharmony_ci							  ps->Asic96Reg.RD_BlueGainOut );
1363141cc406Sopenharmony_ci
1364141cc406Sopenharmony_ci		    /* FillGainInitialRestRegister (); */
1365141cc406Sopenharmony_ci		    IODataToRegister( ps, ps->RegModelControl2,
1366141cc406Sopenharmony_ci							  ps->Asic96Reg.u26.RD_ModelControl2 );
1367141cc406Sopenharmony_ci			IODataToRegister( ps, ps->RegThresholdGapControl,
1368141cc406Sopenharmony_ci			 			      ps->AsicReg.RD_ThresholdGapCtrl );
1369141cc406Sopenharmony_ci			IODataToRegister( ps, ps->RegLedControl,
1370141cc406Sopenharmony_ci							  ps->Asic96Reg.RD_LedControl );
1371141cc406Sopenharmony_ci
1372141cc406Sopenharmony_ci		    IODataToRegister( ps, ps->RegShadingCorrectCtrl,
1373141cc406Sopenharmony_ci						      ps->Asic96Reg.RD_ShadingCorrectCtrl );
1374141cc406Sopenharmony_ci
1375141cc406Sopenharmony_ci			ps->CloseScanPath( ps );
1376141cc406Sopenharmony_ci
1377141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_MotorControl = 0;
1378141cc406Sopenharmony_ci			IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
1379141cc406Sopenharmony_ci
1380141cc406Sopenharmony_ci			ps->AsicReg.RD_ModeControl    = _ModeScan;
1381141cc406Sopenharmony_ci			ps->AsicReg.RD_ScanControl    = ps->bLampOn | _SCAN_BYTEMODE;
1382141cc406Sopenharmony_ci			ps->Asic96Reg.RD_MotorControl = (ps->IgnorePF |
1383141cc406Sopenharmony_ci										     ps->MotorOn | _MotorDirForward);
1384141cc406Sopenharmony_ci
1385141cc406Sopenharmony_ci			ps->AsicReg.RD_Origin       = 142;
1386141cc406Sopenharmony_ci			ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
1387141cc406Sopenharmony_ci            ps->AsicReg.RD_Dpi          = ps->PhysicalDpi;
1388141cc406Sopenharmony_ci			ps->AsicReg.RD_Pixels       = ps->BufferSizePerModel;
1389141cc406Sopenharmony_ci
1390141cc406Sopenharmony_ci			IOPutOnAllRegisters( ps );
1391141cc406Sopenharmony_ci
1392141cc406Sopenharmony_ci			/*---------------------------------------------------------------*/
1393141cc406Sopenharmony_ci
1394141cc406Sopenharmony_ci		    /* ReadOneScanLine (); */
1395141cc406Sopenharmony_ci		    dacP96ReadDataWithinOneSecond( ps, ps->OneScanLineLen, 11 );
1396141cc406Sopenharmony_ci
1397141cc406Sopenharmony_ci			/* AdjustGain () */
1398141cc406Sopenharmony_ci			/*	FindTheMaxGain (), AdjustGainOutData (); */
1399141cc406Sopenharmony_ci
1400141cc406Sopenharmony_ci		    pbReg[0] = &ps->Asic96Reg.RD_RedGainOut;
1401141cc406Sopenharmony_ci		    pbReg[1] = &ps->Asic96Reg.RD_GreenGainOut;
1402141cc406Sopenharmony_ci	    	pbReg[2] = &ps->Asic96Reg.RD_BlueGainOut;
1403141cc406Sopenharmony_ci
1404141cc406Sopenharmony_ci		    for (w = 0, p.pb = ps->pPrescan16; w < 3; w++) {
1405141cc406Sopenharmony_ci/* CHANGE: org was:	for (dw = 2560, b[w] = 0; dw; dw--, p.pb++) { */
1406141cc406Sopenharmony_ci				for (dw = (ps->OneScanLineLen/3), b[w] = 0; dw; dw--, p.pb++) {
1407141cc406Sopenharmony_ci
1408141cc406Sopenharmony_ci				    if (b[w] < *p.pb)
1409141cc406Sopenharmony_ci						b[w] = *p.pb;
1410141cc406Sopenharmony_ci				}
1411141cc406Sopenharmony_ci
1412141cc406Sopenharmony_ci				if (b[w] < _GAIN_LOW)
1413141cc406Sopenharmony_ci				    *(pbReg[w]) += a_bCorrectTimesTable[bCorrectTimes - 1];
1414141cc406Sopenharmony_ci				else
1415141cc406Sopenharmony_ci				    if (b[w] > _GAIN_P96_HIGH)
1416141cc406Sopenharmony_ci						*(pbReg[w]) -= a_bCorrectTimesTable[bCorrectTimes - 1];
1417141cc406Sopenharmony_ci		    }
1418141cc406Sopenharmony_ci		}
1419141cc406Sopenharmony_ci
1420141cc406Sopenharmony_ci    	/*===================================================================*/
1421141cc406Sopenharmony_ci
1422141cc406Sopenharmony_ci	    /* SonyFBK ()/ToshibaFBK ()====================================*/
1423141cc406Sopenharmony_ci		/*FillRGBDarkLevel0Table (); */
1424141cc406Sopenharmony_ci		memset( ps->pPrescan16, 0xff, ps->ShadingBankSize );
1425141cc406Sopenharmony_ci
1426141cc406Sopenharmony_ci		for( dw = 0, p.pb = ps->pPrescan16 + ps->ShadingBufferSize;
1427141cc406Sopenharmony_ci                                    		    dw <=255; dw++, p.pb++ ) {
1428141cc406Sopenharmony_ci		    *p.pb = (Byte) dw;
1429141cc406Sopenharmony_ci		}
1430141cc406Sopenharmony_ci
1431141cc406Sopenharmony_ci		dacP96FillShadingAndGammaTable( ps );
1432141cc406Sopenharmony_ci
1433141cc406Sopenharmony_ci		ps->PauseColorMotorRunStates( ps );
1434141cc406Sopenharmony_ci
1435141cc406Sopenharmony_ci		/* SetReadFBKRegister () */
1436141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl = 0;
1437141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
1438141cc406Sopenharmony_ci
1439141cc406Sopenharmony_ci		ps->AsicReg.RD_ModeControl    = _ModeScan;
1440141cc406Sopenharmony_ci		ps->AsicReg.RD_ScanControl    = ps->bLampOn | _SCAN_BYTEMODE;
1441141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl = ps->IgnorePF | ps->MotorOn |
1442141cc406Sopenharmony_ci								        _MotorDirForward;
1443141cc406Sopenharmony_ci
1444141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin       = 22;
1445141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
1446141cc406Sopenharmony_ci        ps->AsicReg.RD_Dpi          = ps->PhysicalDpi;
1447141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels       = ps->FBKScanLineLenBase;
1448141cc406Sopenharmony_ci
1449141cc406Sopenharmony_ci		IOPutOnAllRegisters( ps );
1450141cc406Sopenharmony_ci
1451141cc406Sopenharmony_ci		/* ReadFBKScanLine () */
1452141cc406Sopenharmony_ci		dacP96ReadDataWithinOneSecond( ps, ps->FBKScanLineLen,
1453141cc406Sopenharmony_ci													   ps->FBKScanLineBlks );
1454141cc406Sopenharmony_ci
1455141cc406Sopenharmony_ci	    /*===================================================================*/
1456141cc406Sopenharmony_ci		if ( ps->fSonyCCD ) {
1457141cc406Sopenharmony_ci
1458141cc406Sopenharmony_ci		    /* FillChannelDarkLevelControl (); */
1459141cc406Sopenharmony_ci		    for ( p.pb = ps->pPrescan16 + 32, w = 0, dw = 16;
1460141cc406Sopenharmony_ci				  dw; dw--, p.pb++) {
1461141cc406Sopenharmony_ci				  w += (UShort) *p.pb;
1462141cc406Sopenharmony_ci			}
1463141cc406Sopenharmony_ci
1464141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChDarkOff = (Byte)(w / 16);
1465141cc406Sopenharmony_ci
1466141cc406Sopenharmony_ci		    for ( p.pb = ps->pPrescan16 + 32 + ps->FBKScanLineLenBase, w = 0, dw = 16;
1467141cc406Sopenharmony_ci				  dw; dw--, p.pb++ ) {
1468141cc406Sopenharmony_ci				w += (UShort)*p.pb;
1469141cc406Sopenharmony_ci			}
1470141cc406Sopenharmony_ci
1471141cc406Sopenharmony_ci			ps->Asic96Reg.RD_GreenChDarkOff = (Byte)(w / 16);
1472141cc406Sopenharmony_ci
1473141cc406Sopenharmony_ci	    	for ( p.pb = ps->pPrescan16 + 32 + ps->FBKScanLineLenBase * 2, w = 0, dw = 16;
1474141cc406Sopenharmony_ci				  dw; dw--,	p.pb++) {
1475141cc406Sopenharmony_ci				w += (UShort)*p.pb;
1476141cc406Sopenharmony_ci			}
1477141cc406Sopenharmony_ci
1478141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_BlueChDarkOff = (Byte)(w / 16);
1479141cc406Sopenharmony_ci
1480141cc406Sopenharmony_ci		    dacP96FillChannelDarkOffset( ps );
1481141cc406Sopenharmony_ci
1482141cc406Sopenharmony_ci		} else {
1483141cc406Sopenharmony_ci
1484141cc406Sopenharmony_ci		    /* FillToshibaDarkLevelControl (); */
1485141cc406Sopenharmony_ci			dacP96GetEvenOddOffset( ps->pPrescan16 + 32, &wv );
1486141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChEvenOff = wv.b1st;
1487141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_RedChOddOff  = wv.b2nd;
1488141cc406Sopenharmony_ci
1489141cc406Sopenharmony_ci			dacP96GetEvenOddOffset( ps->pPrescan16 + 32 + ps->FBKScanLineLenBase, &wv );
1490141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_GreenChEvenOff = wv.b1st;
1491141cc406Sopenharmony_ci		    ps->Asic96Reg.RD_GreenChOddOff = wv.b2nd;
1492141cc406Sopenharmony_ci
1493141cc406Sopenharmony_ci			dacP96GetEvenOddOffset( ps->pPrescan16 + 32 + ps->FBKScanLineLenBase * 2, &wv );
1494141cc406Sopenharmony_ci			ps->Asic96Reg.RD_BlueChEvenOff = wv.b1st;
1495141cc406Sopenharmony_ci			ps->Asic96Reg.RD_BlueChOddOff  = wv.b2nd;
1496141cc406Sopenharmony_ci
1497141cc406Sopenharmony_ci			dacP96FillEvenOddControl( ps );
1498141cc406Sopenharmony_ci		}
1499141cc406Sopenharmony_ci
1500141cc406Sopenharmony_ci		/*	SetInitialGainRAM (); */
1501141cc406Sopenharmony_ci		dacP96Adjust10BitShading( ps );
1502141cc406Sopenharmony_ci
1503141cc406Sopenharmony_ci		return _TRUE;
1504141cc406Sopenharmony_ci    }
1505141cc406Sopenharmony_ci
1506141cc406Sopenharmony_ci    return _FALSE;
1507141cc406Sopenharmony_ci}
1508141cc406Sopenharmony_ci
1509141cc406Sopenharmony_ci/**
1510141cc406Sopenharmony_ci */
1511141cc406Sopenharmony_cistatic void dacP96001ToSetShadingAddress( pScanData ps, pUChar pData )
1512141cc406Sopenharmony_ci{
1513141cc406Sopenharmony_ci    ps->OpenScanPath( ps );
1514141cc406Sopenharmony_ci
1515141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegMemAccessControl,
1516141cc406Sopenharmony_ci											ps->Asic96Reg.RD_MemAccessControl);
1517141cc406Sopenharmony_ci
1518141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl = _ModeProgram;
1519141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, _ModeProgram );
1520141cc406Sopenharmony_ci
1521141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
1522141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegMotorControl, ps->Asic96Reg.RD_MotorControl);
1523141cc406Sopenharmony_ci
1524141cc406Sopenharmony_ci    memset( ps->pScanBuffer1, 0, (64 + 8 + ps->Offset70));
1525141cc406Sopenharmony_ci  	memcpy( ps->pScanBuffer1 + 64 + 8 + ps->Offset70, pData,
1526141cc406Sopenharmony_ci    												_BUF_SIZE_BASE_CONST * 2 );
1527141cc406Sopenharmony_ci
1528141cc406Sopenharmony_ci    IOMoveDataToScanner( ps, ps->pScanBuffer1,
1529141cc406Sopenharmony_ci							_BUF_SIZE_BASE_CONST * 2 + 64 + 8 + ps->Offset70 );
1530141cc406Sopenharmony_ci
1531141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl = _ModeScan;
1532141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, _ModeScan );
1533141cc406Sopenharmony_ci
1534141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
1535141cc406Sopenharmony_ci}
1536141cc406Sopenharmony_ci
1537141cc406Sopenharmony_ci/**
1538141cc406Sopenharmony_ci */
1539141cc406Sopenharmony_cistatic void dacP96001WriteBackToColorShadingRam( pScanData ps )
1540141cc406Sopenharmony_ci{
1541141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3a);
1542141cc406Sopenharmony_ci    dacP96001ToSetShadingAddress( ps, ps->pPrescan16 );
1543141cc406Sopenharmony_ci
1544141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3e);
1545141cc406Sopenharmony_ci    dacP96001ToSetShadingAddress( ps, ps->pPrescan16 + _BUF_SIZE_BASE_CONST*2);
1546141cc406Sopenharmony_ci
1547141cc406Sopenharmony_ci    ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3c);
1548141cc406Sopenharmony_ci    dacP96001ToSetShadingAddress( ps, ps->pPrescan16 + _BUF_SIZE_BASE_CONST*4);
1549141cc406Sopenharmony_ci}
1550141cc406Sopenharmony_ci
1551141cc406Sopenharmony_ci/**
1552141cc406Sopenharmony_ci */
1553141cc406Sopenharmony_cistatic void dacP96001ModifyShadingColor( pByte pData, Byte bMul )
1554141cc406Sopenharmony_ci{
1555141cc406Sopenharmony_ci    UShort w;
1556141cc406Sopenharmony_ci	ULong  dw;
1557141cc406Sopenharmony_ci
1558141cc406Sopenharmony_ci    for ( dw = 0; dw < _BUF_SIZE_BASE_CONST * 2; dw++ ) {
1559141cc406Sopenharmony_ci
1560141cc406Sopenharmony_ci		w = (UShort)(Byte)(~pData[dw]) * bMul / 100U;
1561141cc406Sopenharmony_ci
1562141cc406Sopenharmony_ci		if (w >= 255U)
1563141cc406Sopenharmony_ci	    	pData[dw] = 0;
1564141cc406Sopenharmony_ci		else
1565141cc406Sopenharmony_ci		    pData[dw] = (Byte)~w;
1566141cc406Sopenharmony_ci    }
1567141cc406Sopenharmony_ci}
1568141cc406Sopenharmony_ci
1569141cc406Sopenharmony_ci/**
1570141cc406Sopenharmony_ci */
1571141cc406Sopenharmony_cistatic Byte dacP96001FBKReading( pScanData ps, Byte bValue,
1572141cc406Sopenharmony_ci								 Byte bReg, pByte pbSave, Bool bFBKModify )
1573141cc406Sopenharmony_ci{
1574141cc406Sopenharmony_ci    TimerDef timer;
1575141cc406Sopenharmony_ci    UShort	 w, wSum;
1576141cc406Sopenharmony_ci    Byte	 addrSeq[8] = { 0x40, 0x20, 0x10, 0x08, 4, 2, 1, 0 };
1577141cc406Sopenharmony_ci    Byte	 bTemp, bFBKTemp, bFBKIndex;
1578141cc406Sopenharmony_ci
1579141cc406Sopenharmony_ci    if( bFBKModify ) {
1580141cc406Sopenharmony_ci		bFBKIndex = 3;
1581141cc406Sopenharmony_ci		bFBKTemp = *pbSave;
1582141cc406Sopenharmony_ci    } else {
1583141cc406Sopenharmony_ci		bFBKTemp = 0x80;
1584141cc406Sopenharmony_ci		bFBKIndex = 0;
1585141cc406Sopenharmony_ci    }
1586141cc406Sopenharmony_ci
1587141cc406Sopenharmony_ci    while( _TRUE ) {
1588141cc406Sopenharmony_ci
1589141cc406Sopenharmony_ci		*pbSave = bFBKTemp;
1590141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, bReg, bFBKTemp );
1591141cc406Sopenharmony_ci
1592141cc406Sopenharmony_ci		/* SetColorRunTable (BYTE) */
1593141cc406Sopenharmony_ci		memset( ps->a_nbNewAdrPointer, bValue, _SCANSTATE_BYTES );
1594141cc406Sopenharmony_ci		MotorSetConstantMove( ps, 0 );
1595141cc406Sopenharmony_ci
1596141cc406Sopenharmony_ci		/* SetReadFBK (pScanData) */
1597141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
1598141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1599141cc406Sopenharmony_ci										ps->Asic96Reg.RD_MotorControl );
1600141cc406Sopenharmony_ci
1601141cc406Sopenharmony_ci		ps->AsicReg.RD_ModeControl  = _ModeScan;
1602141cc406Sopenharmony_ci		ps->AsicReg.RD_ScanControl  = _SCAN_BYTEMODE | ps->bLampOn;
1603141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl =
1604141cc406Sopenharmony_ci					(_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0 );
1605141cc406Sopenharmony_ci
1606141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi    = 300;
1607141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin = 22;
1608141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels = 1024;
1609141cc406Sopenharmony_ci		IOPutOnAllRegisters( ps );
1610141cc406Sopenharmony_ci
1611141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl =
1612141cc406Sopenharmony_ci						  	   (ps->FullStep | ps->MotorOn | _MotorDirForward);
1613141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1614141cc406Sopenharmony_ci											   ps->Asic96Reg.RD_MotorControl );
1615141cc406Sopenharmony_ci
1616141cc406Sopenharmony_ci		MiscStartTimer( &timer, _SECOND );
1617141cc406Sopenharmony_ci		while((IODataRegisterFromScanner( ps, ps->RegFifoOffset) < 1) &&
1618141cc406Sopenharmony_ci													!MiscCheckTimer( &timer ));
1619141cc406Sopenharmony_ci
1620141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
1621141cc406Sopenharmony_ci		IOReadScannerImageData( ps, ps->pScanBuffer1, 64 );
1622141cc406Sopenharmony_ci
1623141cc406Sopenharmony_ci		for( w = 26, wSum = 0; w < 42; w++)
1624141cc406Sopenharmony_ci		    wSum += ps->pScanBuffer1[w];
1625141cc406Sopenharmony_ci
1626141cc406Sopenharmony_ci		wSum >>= 4;
1627141cc406Sopenharmony_ci		bTemp = addrSeq[bFBKIndex++];
1628141cc406Sopenharmony_ci
1629141cc406Sopenharmony_ci		if( bTemp ) {
1630141cc406Sopenharmony_ci		    if( wSum < 0xfe )
1631141cc406Sopenharmony_ci				bFBKTemp += bTemp;
1632141cc406Sopenharmony_ci		    else
1633141cc406Sopenharmony_ci				bFBKTemp -= bTemp;
1634141cc406Sopenharmony_ci		} else {
1635141cc406Sopenharmony_ci		    return bFBKTemp;
1636141cc406Sopenharmony_ci		}
1637141cc406Sopenharmony_ci    }
1638141cc406Sopenharmony_ci}
1639141cc406Sopenharmony_ci
1640141cc406Sopenharmony_ci/**
1641141cc406Sopenharmony_ci */
1642141cc406Sopenharmony_cistatic Bool dacP96001WaitForShading( pScanData ps )
1643141cc406Sopenharmony_ci{
1644141cc406Sopenharmony_ci	Bool   bFBKModify;
1645141cc406Sopenharmony_ci    Byte   bRSave;
1646141cc406Sopenharmony_ci    Byte   bGSave;
1647141cc406Sopenharmony_ci    Byte   bBSave;
1648141cc406Sopenharmony_ci    ULong  dw;
1649141cc406Sopenharmony_ci    pULong pdw;
1650141cc406Sopenharmony_ci
1651141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP96001WaitForShading()\n" );
1652141cc406Sopenharmony_ci
1653141cc406Sopenharmony_ci    ps->AsicReg.RD_ScanControl |= ps->bLampOn;
1654141cc406Sopenharmony_ci    IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
1655141cc406Sopenharmony_ci
1656141cc406Sopenharmony_ci    if ( ps->GotoShadingPosition( ps )) {
1657141cc406Sopenharmony_ci
1658141cc406Sopenharmony_ci		_DODELAY( 250 );
1659141cc406Sopenharmony_ci
1660141cc406Sopenharmony_ci	    /* AdjustMostWideOffset70 (pScanData) -------------------------------*/
1661141cc406Sopenharmony_ci		/* FillABitGray (pScanData)*/
1662141cc406Sopenharmony_ci		memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
1663141cc406Sopenharmony_ci		ps->a_nbNewAdrPointer[8]  =
1664141cc406Sopenharmony_ci		ps->a_nbNewAdrPointer[24] = 0x30;
1665141cc406Sopenharmony_ci
1666141cc406Sopenharmony_ci		MotorSetConstantMove( ps, 32 );
1667141cc406Sopenharmony_ci
1668141cc406Sopenharmony_ci		/* SetMaxWideRegister (pScanData) */
1669141cc406Sopenharmony_ci		ps->AsicReg.RD_ModeControl = _ModeScan;
1670141cc406Sopenharmony_ci		ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE | ps->bLampOn;
1671141cc406Sopenharmony_ci
1672141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl =
1673141cc406Sopenharmony_ci 							  (ps->MotorOn | ps->IgnorePF | _MotorDirForward);
1674141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl =
1675141cc406Sopenharmony_ci					  (_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0);
1676141cc406Sopenharmony_ci
1677141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi    = 300;
1678141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin = 64 + 8;
1679141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels = 2700;
1680141cc406Sopenharmony_ci		IOPutOnAllRegisters( ps );
1681141cc406Sopenharmony_ci
1682141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1683141cc406Sopenharmony_ci                                ps->Asic96Reg.RD_MotorControl );
1684141cc406Sopenharmony_ci
1685141cc406Sopenharmony_ci		/* ReadMaxWideLine */
1686141cc406Sopenharmony_ci		dacP96ReadDataWithinOneSecond( ps, 2700, 5 );
1687141cc406Sopenharmony_ci
1688141cc406Sopenharmony_ci	    /* AdjustOffset70Proc (pScanData)------------------------------------*/
1689141cc406Sopenharmony_ci		{
1690141cc406Sopenharmony_ci		    ULong dwSum, dw, dwLeft, dwCenter;
1691141cc406Sopenharmony_ci
1692141cc406Sopenharmony_ci		    /* AverageWideBank (pScanData) */
1693141cc406Sopenharmony_ci		    for( dwSum = 0, dw = 0; dw < 2700; dw++ )
1694141cc406Sopenharmony_ci				dwSum += (ULong)ps->pPrescan16[dw];
1695141cc406Sopenharmony_ci
1696141cc406Sopenharmony_ci			dwSum /= 2700UL;
1697141cc406Sopenharmony_ci
1698141cc406Sopenharmony_ci		    if( dwSum <= 0x80 ) {
1699141cc406Sopenharmony_ci
1700141cc406Sopenharmony_ci				memcpy( ps->pScanBuffer1, ps->pPrescan16, 140 );
1701141cc406Sopenharmony_ci				memcpy( ps->pScanBuffer1 + 140,
1702141cc406Sopenharmony_ci       						ps->pPrescan16 + _BUF_SIZE_BASE_CONST * 2, 140);
1703141cc406Sopenharmony_ci
1704141cc406Sopenharmony_ci				/* BlackOffsetCheck (pScanData) */
1705141cc406Sopenharmony_ci				for( dw = dwLeft = 0; dw < 140; dw++ ) {
1706141cc406Sopenharmony_ci				    if( ps->pScanBuffer1[dw] >= 0xe0 )
1707141cc406Sopenharmony_ci						dwLeft++;
1708141cc406Sopenharmony_ci				    else
1709141cc406Sopenharmony_ci						break;
1710141cc406Sopenharmony_ci				}
1711141cc406Sopenharmony_ci
1712141cc406Sopenharmony_ci				/* WhiteOffsetCheck (pScanData) */
1713141cc406Sopenharmony_ci				for( dw = 140, dwCenter = 0; dw < 280; dw++ ) {
1714141cc406Sopenharmony_ci				    if( ps->pScanBuffer1[dw] < 0xe0 )
1715141cc406Sopenharmony_ci						dwCenter++;
1716141cc406Sopenharmony_ci				    else
1717141cc406Sopenharmony_ci						break;
1718141cc406Sopenharmony_ci				}
1719141cc406Sopenharmony_ci
1720141cc406Sopenharmony_ci				if (dwLeft) {
1721141cc406Sopenharmony_ci				    ps->Offset70 = (dwLeft + dwCenter) / 2 + 14;
1722141cc406Sopenharmony_ci				} else {
1723141cc406Sopenharmony_ci				    if (dwCenter == 140)
1724141cc406Sopenharmony_ci						ps->Offset70 = 70;
1725141cc406Sopenharmony_ci		    		else
1726141cc406Sopenharmony_ci						ps->Offset70 = dwCenter / 2 + 2;
1727141cc406Sopenharmony_ci				}
1728141cc406Sopenharmony_ci	    	}
1729141cc406Sopenharmony_ci		}
1730141cc406Sopenharmony_ci
1731141cc406Sopenharmony_ci		memset( ps->pPrescan16, 0, ps->BufferSizePerModel * 3 );
1732141cc406Sopenharmony_ci		dacP96001WriteBackToColorShadingRam( ps );
1733141cc406Sopenharmony_ci
1734141cc406Sopenharmony_ci		/* SetFBK */
1735141cc406Sopenharmony_ci		if((IODataRegisterFromScanner(ps, ps->RegReadIOBufBus) & 0x0f) == 0x0f)
1736141cc406Sopenharmony_ci	    	bFBKModify = 0;
1737141cc406Sopenharmony_ci		else
1738141cc406Sopenharmony_ci		    bFBKModify = 1;
1739141cc406Sopenharmony_ci
1740141cc406Sopenharmony_ci		dacP96001FBKReading(ps, 0x10, ps->RegRedDCAdjust,  &bRSave,bFBKModify);
1741141cc406Sopenharmony_ci		dacP96001FBKReading(ps, 0x30, ps->RegGreenDCAdjust,&bGSave,bFBKModify);
1742141cc406Sopenharmony_ci		dacP96001FBKReading(ps, 0x20, ps->RegBlueDCAdjust, &bBSave,bFBKModify);
1743141cc406Sopenharmony_ci
1744141cc406Sopenharmony_ci		ps->OpenScanPath( ps );
1745141cc406Sopenharmony_ci		IODataToRegister( ps, ps->RegRedDCAdjust,   (Byte)(bRSave + 2));
1746141cc406Sopenharmony_ci		IODataToRegister( ps, ps->RegGreenDCAdjust, (Byte)(bGSave + 2));
1747141cc406Sopenharmony_ci		IODataToRegister( ps, ps->RegBlueDCAdjust,  bBSave);
1748141cc406Sopenharmony_ci		ps->CloseScanPath( ps );
1749141cc406Sopenharmony_ci
1750141cc406Sopenharmony_ci		/* Turn off and then turn on motor */
1751141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1752141cc406Sopenharmony_ci				         (Byte)(ps->Asic96Reg.RD_MotorControl & ~ps->MotorOn));
1753141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1754141cc406Sopenharmony_ci											   ps->Asic96Reg.RD_MotorControl );
1755141cc406Sopenharmony_ci
1756141cc406Sopenharmony_ci		/* FillABitColor (pScanData) */
1757141cc406Sopenharmony_ci		pdw = (pULong)ps->a_nbNewAdrPointer;
1758141cc406Sopenharmony_ci		for( dw = 0; dw < 4; dw++) {
1759141cc406Sopenharmony_ci		    *pdw++ = 0x40;
1760141cc406Sopenharmony_ci		    *pdw++ = 0x2030140;
1761141cc406Sopenharmony_ci		}
1762141cc406Sopenharmony_ci
1763141cc406Sopenharmony_ci		IOSetToMotorRegister( ps );
1764141cc406Sopenharmony_ci
1765141cc406Sopenharmony_ci		/* SetShadingRegister (pScanData) */
1766141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
1767141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1768141cc406Sopenharmony_ci												ps->Asic96Reg.RD_MotorControl );
1769141cc406Sopenharmony_ci		ps->AsicReg.RD_ModeControl    = _ModeScan;
1770141cc406Sopenharmony_ci		ps->AsicReg.RD_LineControl    = ps->TimePerLine;
1771141cc406Sopenharmony_ci		ps->AsicReg.RD_ScanControl    = _SCAN_BYTEMODE | ps->bLampOn;
1772141cc406Sopenharmony_ci		ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
1773141cc406Sopenharmony_ci
1774141cc406Sopenharmony_ci		ps->AsicReg.RD_ModelControl =
1775141cc406Sopenharmony_ci						(_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0);
1776141cc406Sopenharmony_ci		ps->AsicReg.RD_Dpi    = 150;
1777141cc406Sopenharmony_ci		ps->AsicReg.RD_Origin = (UShort)(64 + 8 + ps->Offset70);
1778141cc406Sopenharmony_ci		ps->AsicReg.RD_Pixels = ps->BufferSizeBase;
1779141cc406Sopenharmony_ci		IOPutOnAllRegisters( ps );
1780141cc406Sopenharmony_ci
1781141cc406Sopenharmony_ci		IOCmdRegisterToScanner( ps, ps->RegMotorControl,
1782141cc406Sopenharmony_ci					    (Byte)(ps->MotorOn | ps->IgnorePF | _MotorDirForward));
1783141cc406Sopenharmony_ci
1784141cc406Sopenharmony_ci		dacP96ReadColorShadingLine( ps );
1785141cc406Sopenharmony_ci
1786141cc406Sopenharmony_ci		/* ModifyShadingColor (pScanData) */
1787141cc406Sopenharmony_ci		dacP96001ModifyShadingColor( ps->pPrescan16, 103 );
1788141cc406Sopenharmony_ci		dacP96001ModifyShadingColor( ps->pPrescan16 +
1789141cc406Sopenharmony_ci											_BUF_SIZE_BASE_CONST * 2 * 2, 97);
1790141cc406Sopenharmony_ci		dacP96001WriteBackToColorShadingRam( ps );
1791141cc406Sopenharmony_ci		return _TRUE;
1792141cc406Sopenharmony_ci    }
1793141cc406Sopenharmony_ci    return _FALSE;
1794141cc406Sopenharmony_ci}
1795141cc406Sopenharmony_ci
1796141cc406Sopenharmony_ci/**
1797141cc406Sopenharmony_ci */
1798141cc406Sopenharmony_cistatic void dacP98003GainOffsetToDAC( pScanData ps, Byte ch, Byte reg, Byte d )
1799141cc406Sopenharmony_ci{
1800141cc406Sopenharmony_ci    if( ps->Device.bDACType == _DA_SAMSUNG8531 ) {
1801141cc406Sopenharmony_ci
1802141cc406Sopenharmony_ci    	IODataToRegister( ps, ps->RegADCAddress, 0 );
1803141cc406Sopenharmony_ci    	IODataToRegister( ps, ps->RegADCData, ch );
1804141cc406Sopenharmony_ci    	IODataToRegister( ps, ps->RegADCSerialOutStr, ch);
1805141cc406Sopenharmony_ci    }
1806141cc406Sopenharmony_ci
1807141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegADCAddress, reg );
1808141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegADCData, d );
1809141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegADCSerialOutStr, d );
1810141cc406Sopenharmony_ci}
1811141cc406Sopenharmony_ci
1812141cc406Sopenharmony_ci/**
1813141cc406Sopenharmony_ci */
1814141cc406Sopenharmony_cistatic void dacP98003AdjustRGBGain( pScanData ps )
1815141cc406Sopenharmony_ci{
1816141cc406Sopenharmony_ci    ULong i;
1817141cc406Sopenharmony_ci    Byte  bHi[3];
1818141cc406Sopenharmony_ci
1819141cc406Sopenharmony_ci    DBG( DBG_LOW, "dacP98003AdjustRGBGain()\n" );
1820141cc406Sopenharmony_ci
1821141cc406Sopenharmony_ci    ps->Shade.Gain.Colors.Red   =
1822141cc406Sopenharmony_ci    ps->Shade.Gain.Colors.Green =
1823141cc406Sopenharmony_ci    ps->Shade.Gain.Colors.Blue  =  ps->Shade.bUniGain;
1824141cc406Sopenharmony_ci
1825141cc406Sopenharmony_ci    ps->Shade.Hilight.Colors.Red   =
1826141cc406Sopenharmony_ci    ps->Shade.Hilight.Colors.Green =
1827141cc406Sopenharmony_ci    ps->Shade.Hilight.Colors.Blue  = 0;
1828141cc406Sopenharmony_ci
1829141cc406Sopenharmony_ci    ps->Shade.bGainHigh = _GAIN_P98003_HIGH;
1830141cc406Sopenharmony_ci    ps->Shade.bGainLow  = _GAIN_P98003_LOW;
1831141cc406Sopenharmony_ci
1832141cc406Sopenharmony_ci    ps->Shade.fStop = _FALSE;
1833141cc406Sopenharmony_ci
1834141cc406Sopenharmony_ci    for( i = 10; i-- && !ps->Shade.fStop; ) {
1835141cc406Sopenharmony_ci
1836141cc406Sopenharmony_ci        ps->Shade.fStop = _TRUE;
1837141cc406Sopenharmony_ci
1838141cc406Sopenharmony_ci        /* SetRGBGainRegister () */
1839141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
1840141cc406Sopenharmony_ci
1841141cc406Sopenharmony_ci        ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
1842141cc406Sopenharmony_ci        IOSelectLampSource( ps );
1843141cc406Sopenharmony_ci    	IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
1844141cc406Sopenharmony_ci
1845141cc406Sopenharmony_ci        DacP98003FillToDAC( ps, &ps->Device.RegDACGain, &ps->Shade.Gain );
1846141cc406Sopenharmony_ci
1847141cc406Sopenharmony_ci        ps->AsicReg.RD_ModeControl   = _ModeScan;
1848141cc406Sopenharmony_ci        ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE;
1849141cc406Sopenharmony_ci        ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
1850141cc406Sopenharmony_ci
1851141cc406Sopenharmony_ci    	if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
1852141cc406Sopenharmony_ci	        ps->AsicReg.RD_Origin = (UShort)ps->Device.DataOriginX >> 1;
1853141cc406Sopenharmony_ci    	else
1854141cc406Sopenharmony_ci	        ps->AsicReg.RD_Origin = (UShort)ps->Device.DataOriginX;
1855141cc406Sopenharmony_ci
1856141cc406Sopenharmony_ci        ps->AsicReg.RD_Dpi    = 300;
1857141cc406Sopenharmony_ci        ps->AsicReg.RD_Pixels = 2560;
1858141cc406Sopenharmony_ci
1859141cc406Sopenharmony_ci    	/* PauseColorMotorRunStates () */
1860141cc406Sopenharmony_ci    	memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
1861141cc406Sopenharmony_ci	    ps->a_nbNewAdrPointer[1] = 0x77;
1862141cc406Sopenharmony_ci
1863141cc406Sopenharmony_ci	    IOPutOnAllRegisters( ps );
1864141cc406Sopenharmony_ci
1865141cc406Sopenharmony_ci    	_DODELAY( 70 );
1866141cc406Sopenharmony_ci
1867141cc406Sopenharmony_ci        /* read one shading line and work on it */
1868141cc406Sopenharmony_ci	    if( IOReadOneShadingLine( ps, (pUChar)ps->Bufs.b1.pShadingRam, 2560)) {
1869141cc406Sopenharmony_ci
1870141cc406Sopenharmony_ci        	if ( ps->DataInf.wPhyDataType <= COLOR_256GRAY ) {
1871141cc406Sopenharmony_ci
1872141cc406Sopenharmony_ci        		bHi[1] = DacP98003SumGains(
1873141cc406Sopenharmony_ci                                 (pUChar)ps->Bufs.b1.pShadingRam + 2560, 2560);
1874141cc406Sopenharmony_ci		        if( bHi[1] )
1875141cc406Sopenharmony_ci        		    DacP98003AdjustGain( ps, _CHANNEL_GREEN, bHi[1] );
1876141cc406Sopenharmony_ci		        else {
1877141cc406Sopenharmony_ci        		    ps->Shade.fStop = _FALSE;
1878141cc406Sopenharmony_ci		        }
1879141cc406Sopenharmony_ci    	    } else {
1880141cc406Sopenharmony_ci        		bHi[0] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam, 2560);
1881141cc406Sopenharmony_ci		        bHi[1] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam + 2560, 2560);
1882141cc406Sopenharmony_ci        		bHi[2] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam + 5120, 2560);
1883141cc406Sopenharmony_ci
1884141cc406Sopenharmony_ci		        if (!bHi[0] || !bHi[1] || !bHi[2] ) {
1885141cc406Sopenharmony_ci        		    ps->Shade.fStop = _FALSE;
1886141cc406Sopenharmony_ci		        } else {
1887141cc406Sopenharmony_ci        		    DacP98003AdjustGain( ps, _CHANNEL_RED,   bHi[0] );
1888141cc406Sopenharmony_ci        		    DacP98003AdjustGain( ps, _CHANNEL_GREEN, bHi[1] );
1889141cc406Sopenharmony_ci        		    DacP98003AdjustGain( ps, _CHANNEL_BLUE,  bHi[2] );
1890141cc406Sopenharmony_ci		        }
1891141cc406Sopenharmony_ci    	    }
1892141cc406Sopenharmony_ci	    } else
1893141cc406Sopenharmony_ci    	    ps->Shade.fStop = _FALSE;
1894141cc406Sopenharmony_ci    }
1895141cc406Sopenharmony_ci
1896141cc406Sopenharmony_ci#ifdef DEBUG
1897141cc406Sopenharmony_ci    if( !ps->Shade.fStop )
1898141cc406Sopenharmony_ci        DBG( DBG_LOW, "dacP98003AdjustRGBGain() - all loops done!!!\n" );
1899141cc406Sopenharmony_ci#endif
1900141cc406Sopenharmony_ci
1901141cc406Sopenharmony_ci    DacP98003FillToDAC( ps, &ps->Device.RegDACGain, &ps->Shade.Gain );
1902141cc406Sopenharmony_ci}
1903141cc406Sopenharmony_ci
1904141cc406Sopenharmony_ci/**
1905141cc406Sopenharmony_ci */
1906141cc406Sopenharmony_cistatic UShort dacP98003SumDarks( pScanData ps, pUShort data )
1907141cc406Sopenharmony_ci{
1908141cc406Sopenharmony_ci    UShort i, loop;
1909141cc406Sopenharmony_ci
1910141cc406Sopenharmony_ci    if( ps->Device.bCCDID == _CCD_3799 ) {
1911141cc406Sopenharmony_ci    	if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
1912141cc406Sopenharmony_ci    	    data += 0x18;
1913141cc406Sopenharmony_ci	    else
1914141cc406Sopenharmony_ci	        data += 0x30;
1915141cc406Sopenharmony_ci    } else {
1916141cc406Sopenharmony_ci    	if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
1917141cc406Sopenharmony_ci	        data += 0x18;
1918141cc406Sopenharmony_ci    	else
1919141cc406Sopenharmony_ci	        data += 0x20;
1920141cc406Sopenharmony_ci    }
1921141cc406Sopenharmony_ci
1922141cc406Sopenharmony_ci    for( i = 0, loop = 16; loop--; data++ )
1923141cc406Sopenharmony_ci    	i += *data;
1924141cc406Sopenharmony_ci    i >>= 4;
1925141cc406Sopenharmony_ci
1926141cc406Sopenharmony_ci    return i;
1927141cc406Sopenharmony_ci}
1928141cc406Sopenharmony_ci
1929141cc406Sopenharmony_ci/**
1930141cc406Sopenharmony_ci */
1931141cc406Sopenharmony_cistatic void dacP98003AdjustShadingWaveform( pScanData ps )
1932141cc406Sopenharmony_ci{
1933141cc406Sopenharmony_ci    Byte	       b;
1934141cc406Sopenharmony_ci    UShort         count, wR, wG, wB, tmp;
1935141cc406Sopenharmony_ci    DataType       var;
1936141cc406Sopenharmony_ci    DataPointer    pvar, psum;
1937141cc406Sopenharmony_ci    RBGPtrDef      cp;
1938141cc406Sopenharmony_ci    pRGBUShortDef  pRGB, pwsum;
1939141cc406Sopenharmony_ci
1940141cc406Sopenharmony_ci    DBG( DBG_LOW, "dacP98003AdjustShadingWaveForm()\n" );
1941141cc406Sopenharmony_ci
1942141cc406Sopenharmony_ci    memset( &cp, 0, sizeof(RBGPtrDef));
1943141cc406Sopenharmony_ci    memset( ps->Bufs.b2.pSumBuf, 0, (5400 * 3 * 2));
1944141cc406Sopenharmony_ci
1945141cc406Sopenharmony_ci    /* SetAdjustShadingRegister () */
1946141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
1947141cc406Sopenharmony_ci
1948141cc406Sopenharmony_ci    ps->AsicReg.RD_LineControl    = _LOBYTE(ps->Shade.wExposure);
1949141cc406Sopenharmony_ci    ps->AsicReg.RD_ExtLineControl = _HIBYTE(ps->Shade.wExposure);
1950141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegExtendedLineControl,
1951141cc406Sopenharmony_ci                      ps->AsicReg.RD_ExtLineControl );
1952141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl );
1953141cc406Sopenharmony_ci
1954141cc406Sopenharmony_ci    ps->AsicReg.RD_XStepTime    = _LOBYTE(ps->Shade.wExposure);
1955141cc406Sopenharmony_ci    ps->AsicReg.RD_ExtXStepTime = _HIBYTE(ps->Shade.wExposure);
1956141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegExtendedXStep, ps->AsicReg.RD_ExtXStepTime );
1957141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegXStepTime, ps->AsicReg.RD_XStepTime );
1958141cc406Sopenharmony_ci
1959141cc406Sopenharmony_ci    ps->AsicReg.RD_ModeControl   = _ModeScan;
1960141cc406Sopenharmony_ci    ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE;
1961141cc406Sopenharmony_ci    ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
1962141cc406Sopenharmony_ci
1963141cc406Sopenharmony_ci   	if( ps->Shade.bIntermediate & _ScanMode_AverageOut ) {
1964141cc406Sopenharmony_ci
1965141cc406Sopenharmony_ci    	ps->AsicReg.RD_Dpi     = 300;
1966141cc406Sopenharmony_ci    	ps->AsicReg.RD_Pixels  = 2700;
1967141cc406Sopenharmony_ci    	ps->Shade.shadingBytes = 2700 * 2;
1968141cc406Sopenharmony_ci    } else {
1969141cc406Sopenharmony_ci    	ps->AsicReg.RD_Dpi     = 600;
1970141cc406Sopenharmony_ci    	ps->AsicReg.RD_Pixels  = 5400;
1971141cc406Sopenharmony_ci    	ps->Shade.shadingBytes = 5400 * 2;
1972141cc406Sopenharmony_ci    }
1973141cc406Sopenharmony_ci    ps->AsicReg.RD_Origin = _SHADING_BEGINX;
1974141cc406Sopenharmony_ci
1975141cc406Sopenharmony_ci    for( pvar.pdw = (pULong)ps->a_nbNewAdrPointer,
1976141cc406Sopenharmony_ci         var.dwValue = _SCANSTATE_BYTES >> 2; var.dwValue--; pvar.pdw++) {
1977141cc406Sopenharmony_ci    	*pvar.pdw = 0x00f00080;
1978141cc406Sopenharmony_ci    }
1979141cc406Sopenharmony_ci
1980141cc406Sopenharmony_ci    ps->Scan.fRefreshState = _FALSE;
1981141cc406Sopenharmony_ci    IOPutOnAllRegisters( ps );
1982141cc406Sopenharmony_ci    _DODELAY( 55 );
1983141cc406Sopenharmony_ci
1984141cc406Sopenharmony_ci    /* SetupHilightShadow () */
1985141cc406Sopenharmony_ci    if( ps->Shade.pHilight ) {
1986141cc406Sopenharmony_ci
1987141cc406Sopenharmony_ci        memset( ps->Shade.pHilight, 0,
1988141cc406Sopenharmony_ci    	        ps->Shade.shadingBytes * ps->Shade.skipHilight * 3 );
1989141cc406Sopenharmony_ci
1990141cc406Sopenharmony_ci        memset((pUChar)ps->Shade.pHilight +
1991141cc406Sopenharmony_ci                ps->Shade.shadingBytes * ps->Shade.skipHilight * 3, 0xff,
1992141cc406Sopenharmony_ci			    ps->Shade.shadingBytes * ps->Shade.skipShadow * 3 );
1993141cc406Sopenharmony_ci    }
1994141cc406Sopenharmony_ci
1995141cc406Sopenharmony_ci
1996141cc406Sopenharmony_ci    for( count = 32; count--;) {
1997141cc406Sopenharmony_ci
1998141cc406Sopenharmony_ci        IOReadOneShadingLine( ps,
1999141cc406Sopenharmony_ci                             ((pUChar)ps->Bufs.b1.pShadingRam)+_SHADING_BEGINX,
2000141cc406Sopenharmony_ci	                                                     ps->Shade.shadingBytes );
2001141cc406Sopenharmony_ci
2002141cc406Sopenharmony_ci	    /* SaveHilightShadow() */
2003141cc406Sopenharmony_ci    	if( ps->Shade.pHilight ) {
2004141cc406Sopenharmony_ci
2005141cc406Sopenharmony_ci           	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2006141cc406Sopenharmony_ci
2007141cc406Sopenharmony_ci        		cp.red.usp   = ps->Bufs.b1.pShadingRam + _SHADING_BEGINX;
2008141cc406Sopenharmony_ci		        cp.green.usp = cp.red.usp   + ps->AsicReg.RD_Pixels;
2009141cc406Sopenharmony_ci        		cp.blue.usp  = cp.green.usp + ps->AsicReg.RD_Pixels;
2010141cc406Sopenharmony_ci		        pvar.pusrgb = (pRGBUShortDef)ps->Shade.pHilight +
2011141cc406Sopenharmony_ci                                                         _SHADING_BEGINX;
2012141cc406Sopenharmony_ci
2013141cc406Sopenharmony_ci        		for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2014141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2015141cc406Sopenharmony_ci        		    pRGB = pvar.pusrgb++;
2016141cc406Sopenharmony_ci		            wR = *cp.red.usp;
2017141cc406Sopenharmony_ci        		    wG = *cp.green.usp;
2018141cc406Sopenharmony_ci		            wB = *cp.blue.usp;
2019141cc406Sopenharmony_ci
2020141cc406Sopenharmony_ci        		    for( b = ps->Shade.skipHilight; b--;
2021141cc406Sopenharmony_ci                                               pRGB += ps->AsicReg.RD_Pixels) {
2022141cc406Sopenharmony_ci
2023141cc406Sopenharmony_ci            			if( wR > pRGB->Red ) {
2024141cc406Sopenharmony_ci            			    tmp = wR;
2025141cc406Sopenharmony_ci			                wR  = pRGB->Red;
2026141cc406Sopenharmony_ci            			    pRGB->Red = tmp;
2027141cc406Sopenharmony_ci			            }
2028141cc406Sopenharmony_ci            			if( wG > pRGB->Green ) {
2029141cc406Sopenharmony_ci            			    tmp = wG;
2030141cc406Sopenharmony_ci			                wG  = pRGB->Green;
2031141cc406Sopenharmony_ci            			    pRGB->Green = tmp;
2032141cc406Sopenharmony_ci			            }
2033141cc406Sopenharmony_ci            			if( wB > pRGB->Blue ) {
2034141cc406Sopenharmony_ci            			    tmp = wB;
2035141cc406Sopenharmony_ci			                wB  = pRGB->Blue;
2036141cc406Sopenharmony_ci            			    pRGB->Blue = tmp;
2037141cc406Sopenharmony_ci			            }
2038141cc406Sopenharmony_ci        		    }
2039141cc406Sopenharmony_ci
2040141cc406Sopenharmony_ci        		    wR = *cp.red.usp++;
2041141cc406Sopenharmony_ci		            wG = *cp.green.usp++;
2042141cc406Sopenharmony_ci        		    wB = *cp.blue.usp++;
2043141cc406Sopenharmony_ci		            for(b = ps->Shade.skipShadow; b--;
2044141cc406Sopenharmony_ci                                               pRGB += ps->AsicReg.RD_Pixels) {
2045141cc406Sopenharmony_ci
2046141cc406Sopenharmony_ci            			if (wR < pRGB->Red) {
2047141cc406Sopenharmony_ci            			    tmp = wR;
2048141cc406Sopenharmony_ci			                wR  = pRGB->Red;
2049141cc406Sopenharmony_ci            			    pRGB->Red = tmp;
2050141cc406Sopenharmony_ci			            }
2051141cc406Sopenharmony_ci            			if (wG < pRGB->Green) {
2052141cc406Sopenharmony_ci            			    tmp = wG;
2053141cc406Sopenharmony_ci			                wG  = pRGB->Green;
2054141cc406Sopenharmony_ci            			    pRGB->Green = tmp;
2055141cc406Sopenharmony_ci			            }
2056141cc406Sopenharmony_ci            			if (wB < pRGB->Blue) {
2057141cc406Sopenharmony_ci            			    tmp = wB;
2058141cc406Sopenharmony_ci			                wB  = pRGB->Blue;
2059141cc406Sopenharmony_ci            			    pRGB->Blue = tmp;
2060141cc406Sopenharmony_ci			            }
2061141cc406Sopenharmony_ci        		    }
2062141cc406Sopenharmony_ci    	        }
2063141cc406Sopenharmony_ci
2064141cc406Sopenharmony_ci    	    } else {
2065141cc406Sopenharmony_ci
2066141cc406Sopenharmony_ci        		cp.green.usp = ps->Bufs.b1.pShadingRam +
2067141cc406Sopenharmony_ci                               ps->AsicReg.RD_Pixels + _SHADING_BEGINX;
2068141cc406Sopenharmony_ci        		cp.blue.usp  = (pUShort) ps->Shade.pHilight + _SHADING_BEGINX;
2069141cc406Sopenharmony_ci
2070141cc406Sopenharmony_ci        		for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2071141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2072141cc406Sopenharmony_ci        		    cp.red.usp = cp.blue.usp++;
2073141cc406Sopenharmony_ci		            wG = *cp.green.usp;
2074141cc406Sopenharmony_ci        		    for( b = ps->Shade.skipHilight; b--;
2075141cc406Sopenharmony_ci	                                    cp.red.usp += ps->AsicReg.RD_Pixels) {
2076141cc406Sopenharmony_ci            			if( wG > *cp.red.usp ) {
2077141cc406Sopenharmony_ci            			    tmp = wG;
2078141cc406Sopenharmony_ci			                wG  = *cp.red.usp;
2079141cc406Sopenharmony_ci            			    *cp.red.usp = tmp;
2080141cc406Sopenharmony_ci			            }
2081141cc406Sopenharmony_ci        		    }
2082141cc406Sopenharmony_ci		            wG = *cp.green.usp++;
2083141cc406Sopenharmony_ci        		    for (b = ps->Shade.skipShadow; b--;
2084141cc406Sopenharmony_ci                  		                cp.red.usp += ps->AsicReg.RD_Pixels) {
2085141cc406Sopenharmony_ci            			if( wG < *cp.red.usp ) {
2086141cc406Sopenharmony_ci            			    tmp = wG;
2087141cc406Sopenharmony_ci			                wG  = *cp.red.usp;
2088141cc406Sopenharmony_ci            			    *cp.red.usp = tmp;
2089141cc406Sopenharmony_ci			            }
2090141cc406Sopenharmony_ci        		    }
2091141cc406Sopenharmony_ci		        }
2092141cc406Sopenharmony_ci    	    }
2093141cc406Sopenharmony_ci	    }
2094141cc406Sopenharmony_ci
2095141cc406Sopenharmony_ci    	/* AddToSumBuffer() */
2096141cc406Sopenharmony_ci       	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2097141cc406Sopenharmony_ci
2098141cc406Sopenharmony_ci    	    cp.red.usp   = ps->Bufs.b1.pShadingRam + _SHADING_BEGINX;
2099141cc406Sopenharmony_ci	        cp.green.usp = cp.red.usp   + ps->AsicReg.RD_Pixels;
2100141cc406Sopenharmony_ci	        cp.blue.usp  = cp.green.usp + ps->AsicReg.RD_Pixels;
2101141cc406Sopenharmony_ci
2102141cc406Sopenharmony_ci    	    pvar.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2103141cc406Sopenharmony_ci
2104141cc406Sopenharmony_ci	        for( var.dwValue = (ULong)ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2105141cc406Sopenharmony_ci     	         var.dwValue--;
2106141cc406Sopenharmony_ci                 pvar.pulrgb++, cp.red.usp++, cp.green.usp++, cp.blue.usp++) {
2107141cc406Sopenharmony_ci        		pvar.pulrgb->Red   += (ULong)*cp.red.usp;
2108141cc406Sopenharmony_ci		        pvar.pulrgb->Green += (ULong)*cp.green.usp;
2109141cc406Sopenharmony_ci        		pvar.pulrgb->Blue  += (ULong)*cp.blue.usp;
2110141cc406Sopenharmony_ci	        }
2111141cc406Sopenharmony_ci
2112141cc406Sopenharmony_ci    	} else {
2113141cc406Sopenharmony_ci
2114141cc406Sopenharmony_ci    	    cp.green.usp = ps->Bufs.b1.pShadingRam + ps->AsicReg.RD_Pixels +
2115141cc406Sopenharmony_ci                                                               _SHADING_BEGINX;
2116141cc406Sopenharmony_ci	        pvar.pdw  = (pULong)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2117141cc406Sopenharmony_ci	        for(var.dwValue = (ULong)ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2118141cc406Sopenharmony_ci                            	    var.dwValue--; pvar.pdw++, cp.green.usp++) {
2119141cc406Sopenharmony_ci		        *pvar.pdw += (ULong)*cp.green.usp;
2120141cc406Sopenharmony_ci    	    }
2121141cc406Sopenharmony_ci        }
2122141cc406Sopenharmony_ci
2123141cc406Sopenharmony_ci   	    if( IOReadFifoLength( ps ) < ps->AsicReg.RD_Pixels )
2124141cc406Sopenharmony_ci           IORegisterToScanner( ps, ps->RegRefreshScanState );
2125141cc406Sopenharmony_ci    }
2126141cc406Sopenharmony_ci
2127141cc406Sopenharmony_ci    /* AverageAfterSubHilightShadow() */
2128141cc406Sopenharmony_ci    if( ps->Shade.pHilight ) {
2129141cc406Sopenharmony_ci
2130141cc406Sopenharmony_ci        if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2131141cc406Sopenharmony_ci
2132141cc406Sopenharmony_ci      	    psum.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2133141cc406Sopenharmony_ci	        pwsum       = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2134141cc406Sopenharmony_ci	        pvar.pusrgb = (pRGBUShortDef)ps->Shade.pHilight + _SHADING_BEGINX;
2135141cc406Sopenharmony_ci
2136141cc406Sopenharmony_ci      	    for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2137141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2138141cc406Sopenharmony_ci           		pRGB = pvar.pusrgb++;
2139141cc406Sopenharmony_ci
2140141cc406Sopenharmony_ci	            for( b = ps->Shade.skipHilight + ps->Shade.skipShadow;
2141141cc406Sopenharmony_ci                                        b--; pRGB += ps->AsicReg.RD_Pixels ) {
2142141cc406Sopenharmony_ci
2143141cc406Sopenharmony_ci           		    psum.pulrgb->Red   -= (ULong)pRGB->Red;
2144141cc406Sopenharmony_ci    	            psum.pulrgb->Green -= (ULong)pRGB->Green;
2145141cc406Sopenharmony_ci           		    psum.pulrgb->Blue  -= (ULong)pRGB->Blue;
2146141cc406Sopenharmony_ci	            }
2147141cc406Sopenharmony_ci
2148141cc406Sopenharmony_ci           		pwsum->Red   = (UShort)(psum.pulrgb->Red   / ps->Shade.dwDiv);
2149141cc406Sopenharmony_ci    	        pwsum->Green = (UShort)(psum.pulrgb->Green / ps->Shade.dwDiv);
2150141cc406Sopenharmony_ci           		pwsum->Blue  = (UShort)(psum.pulrgb->Blue  / ps->Shade.dwDiv);
2151141cc406Sopenharmony_ci       	    	psum.pulrgb++;
2152141cc406Sopenharmony_ci	            pwsum++;
2153141cc406Sopenharmony_ci   	        }
2154141cc406Sopenharmony_ci        } else {
2155141cc406Sopenharmony_ci       	    cp.green.ulp = (pULong)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2156141cc406Sopenharmony_ci            cp.blue.usp  = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2157141cc406Sopenharmony_ci   	        pvar.pw      = (pUShort)ps->Shade.pHilight  + _SHADING_BEGINX;
2158141cc406Sopenharmony_ci
2159141cc406Sopenharmony_ci       	    for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2160141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2161141cc406Sopenharmony_ci           		cp.red.usp = pvar.pw++;
2162141cc406Sopenharmony_ci
2163141cc406Sopenharmony_ci    	        for( b = ps->Shade.skipHilight + ps->Shade.skipShadow;
2164141cc406Sopenharmony_ci                                     b--; cp.red.usp += ps->AsicReg.RD_Pixels )
2165141cc406Sopenharmony_ci   		            *cp.green.ulp -= *cp.red.usp;
2166141cc406Sopenharmony_ci
2167141cc406Sopenharmony_ci           		*cp.blue.usp = (UShort)(*cp.green.ulp / ps->Shade.dwDiv);
2168141cc406Sopenharmony_ci           		cp.blue.usp++;
2169141cc406Sopenharmony_ci	            cp.green.ulp++;
2170141cc406Sopenharmony_ci       	    }
2171141cc406Sopenharmony_ci        }
2172141cc406Sopenharmony_ci    } else {
2173141cc406Sopenharmony_ci       	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2174141cc406Sopenharmony_ci
2175141cc406Sopenharmony_ci   	        psum.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf  + _SHADING_BEGINX;
2176141cc406Sopenharmony_ci            pwsum       = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2177141cc406Sopenharmony_ci
2178141cc406Sopenharmony_ci   	        for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2179141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2180141cc406Sopenharmony_ci           		pwsum->Red   = (UShort)(psum.pulrgb->Red   >> 5);
2181141cc406Sopenharmony_ci    	        pwsum->Green = (UShort)(psum.pulrgb->Green >> 5);
2182141cc406Sopenharmony_ci           		pwsum->Blue  = (UShort)(psum.pulrgb->Blue  >> 5);
2183141cc406Sopenharmony_ci	            psum.pulrgb++;
2184141cc406Sopenharmony_ci       		    pwsum++;
2185141cc406Sopenharmony_ci       	    }
2186141cc406Sopenharmony_ci        } else {
2187141cc406Sopenharmony_ci   	        cp.green.ulp = (pULong)ps->Bufs.b2.pSumBuf  + _SHADING_BEGINX;
2188141cc406Sopenharmony_ci            cp.blue.usp  = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2189141cc406Sopenharmony_ci
2190141cc406Sopenharmony_ci   	        for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2191141cc406Sopenharmony_ci                                                              var.dwValue--;) {
2192141cc406Sopenharmony_ci           		*cp.blue.usp = (UShort)(*cp.green.ulp >> 5);
2193141cc406Sopenharmony_ci           		cp.blue.usp++;
2194141cc406Sopenharmony_ci       	    	cp.green.ulp++;
2195141cc406Sopenharmony_ci       	    }
2196141cc406Sopenharmony_ci        }
2197141cc406Sopenharmony_ci    }
2198141cc406Sopenharmony_ci
2199141cc406Sopenharmony_ci    /* Process negative & transparency here */
2200141cc406Sopenharmony_ci    if( ps->DataInf.dwScanFlag & SCANDEF_TPA )
2201141cc406Sopenharmony_ci   	    TPAP98003FindCenterPointer( ps );
2202141cc406Sopenharmony_ci
2203141cc406Sopenharmony_ci    if( ps->DataInf.dwScanFlag & SCANDEF_Negative )
2204141cc406Sopenharmony_ci		TPAP98003Reshading( ps );
2205141cc406Sopenharmony_ci
2206141cc406Sopenharmony_ci    pRGB = (pRGBUShortDef)&ps->Shade.pCcdDac->GainResize;
2207141cc406Sopenharmony_ci
2208141cc406Sopenharmony_ci   	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2209141cc406Sopenharmony_ci
2210141cc406Sopenharmony_ci        	pwsum = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2211141cc406Sopenharmony_ci
2212141cc406Sopenharmony_ci       	    for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2213141cc406Sopenharmony_ci                                                            var.dwValue--;) {
2214141cc406Sopenharmony_ci
2215141cc406Sopenharmony_ci  	        if ((short)(pwsum->Red -= ps->Shade.DarkOffset.Colors.Red) > 0) {
2216141cc406Sopenharmony_ci       	    	pwsum->Red = pwsum->Red * pRGB->Red / 100U;
2217141cc406Sopenharmony_ci	            if( pwsum->Red > 0xfff )
2218141cc406Sopenharmony_ci       		        pwsum->Red = 0xfff;
2219141cc406Sopenharmony_ci       	    } else
2220141cc406Sopenharmony_ci               	pwsum->Red = 0;
2221141cc406Sopenharmony_ci
2222141cc406Sopenharmony_ci       	    if((short)(pwsum->Green -= ps->Shade.DarkOffset.Colors.Green) > 0) {
2223141cc406Sopenharmony_ci               	pwsum->Green = pwsum->Green * pRGB->Green / 100U;
2224141cc406Sopenharmony_ci           	    if( pwsum->Green > 0xfff )
2225141cc406Sopenharmony_ci               	    pwsum->Green = 0xfff;
2226141cc406Sopenharmony_ci           	} else
2227141cc406Sopenharmony_ci               	pwsum->Green = 0;
2228141cc406Sopenharmony_ci
2229141cc406Sopenharmony_ci       	    if ((short)(pwsum->Blue -= ps->Shade.DarkOffset.Colors.Blue) > 0) {
2230141cc406Sopenharmony_ci           	    pwsum->Blue = pwsum->Blue * pRGB->Blue / 100U;
2231141cc406Sopenharmony_ci               	if( pwsum->Blue > 0xfff )
2232141cc406Sopenharmony_ci    	            pwsum->Blue = 0xfff;
2233141cc406Sopenharmony_ci           	} else
2234141cc406Sopenharmony_ci               	pwsum->Blue = 0;
2235141cc406Sopenharmony_ci
2236141cc406Sopenharmony_ci           	wR = (UShort)(pwsum->Red >> 4);
2237141cc406Sopenharmony_ci         	pwsum->Red <<= 12;
2238141cc406Sopenharmony_ci   	        pwsum->Red |= wR;
2239141cc406Sopenharmony_ci            wR = (UShort)(pwsum->Green >> 4);
2240141cc406Sopenharmony_ci       	    pwsum->Green <<= 12;
2241141cc406Sopenharmony_ci   	        pwsum->Green |= wR;
2242141cc406Sopenharmony_ci       	    wR = (UShort)(pwsum->Blue>> 4);
2243141cc406Sopenharmony_ci       	    pwsum->Blue <<= 12;
2244141cc406Sopenharmony_ci   	        pwsum->Blue |= wR;
2245141cc406Sopenharmony_ci       	    pwsum++;
2246141cc406Sopenharmony_ci       	}
2247141cc406Sopenharmony_ci   } else {
2248141cc406Sopenharmony_ci
2249141cc406Sopenharmony_ci       	cp.green.usp = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
2250141cc406Sopenharmony_ci
2251141cc406Sopenharmony_ci   	    for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
2252141cc406Sopenharmony_ci                                                            var.dwValue--;) {
2253141cc406Sopenharmony_ci
2254141cc406Sopenharmony_ci   	        if((short)(*cp.green.usp -= ps->Shade.DarkOffset.Colors.Green) > 0) {
2255141cc406Sopenharmony_ci
2256141cc406Sopenharmony_ci           		*cp.green.usp = *cp.green.usp * pRGB->Green / 100U;
2257141cc406Sopenharmony_ci           		if( *cp.green.usp > 0xfff )
2258141cc406Sopenharmony_ci           		    *cp.green.usp = 0xfff;
2259141cc406Sopenharmony_ci            } else
2260141cc406Sopenharmony_ci           		*cp.green.usp = 0;
2261141cc406Sopenharmony_ci
2262141cc406Sopenharmony_ci       	    wR = (UShort)(*cp.green.usp >> 4);
2263141cc406Sopenharmony_ci   	        *cp.green.usp <<= 12;
2264141cc406Sopenharmony_ci       	    *cp.green.usp |= wR;
2265141cc406Sopenharmony_ci
2266141cc406Sopenharmony_ci       	    cp.green.usp++;
2267141cc406Sopenharmony_ci        }
2268141cc406Sopenharmony_ci    }
2269141cc406Sopenharmony_ci
2270141cc406Sopenharmony_ci    /* DownloadShadingAndSetDark() */
2271141cc406Sopenharmony_ci    dacP98DownloadShadingTable( ps, ps->Bufs.b2.pSumBuf, (5400 * 3 * 2));
2272141cc406Sopenharmony_ci}
2273141cc406Sopenharmony_ci
2274141cc406Sopenharmony_ci/**
2275141cc406Sopenharmony_ci */
2276141cc406Sopenharmony_cistatic void dacP98003AdjustDark( pScanData ps )
2277141cc406Sopenharmony_ci{
2278141cc406Sopenharmony_ci    ULong  i;
2279141cc406Sopenharmony_ci    UShort wDarks[3];
2280141cc406Sopenharmony_ci
2281141cc406Sopenharmony_ci    DBG( DBG_LOW, "dacP98003AdjustDark()\n" );
2282141cc406Sopenharmony_ci
2283141cc406Sopenharmony_ci    ps->Shade.DarkDAC.Colors = ps->Shade.pCcdDac->DarkDAC.Colors;
2284141cc406Sopenharmony_ci    ps->Shade.fStop = _FALSE;
2285141cc406Sopenharmony_ci
2286141cc406Sopenharmony_ci    for( i = 16; i-- && !ps->Shade.fStop;) {
2287141cc406Sopenharmony_ci
2288141cc406Sopenharmony_ci    	ps->Shade.fStop = _TRUE;
2289141cc406Sopenharmony_ci
2290141cc406Sopenharmony_ci    	/* FillDarkToDAC() */
2291141cc406Sopenharmony_ci        DacP98003FillToDAC( ps, &ps->Device.RegDACOffset, &ps->Shade.DarkDAC );
2292141cc406Sopenharmony_ci
2293141cc406Sopenharmony_ci        IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
2294141cc406Sopenharmony_ci
2295141cc406Sopenharmony_ci        ps->AsicReg.RD_ScanControl = (_SCAN_12BITMODE + _SCAN_1ST_AVERAGE);
2296141cc406Sopenharmony_ci        IOSelectLampSource( ps );
2297141cc406Sopenharmony_ci    	IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
2298141cc406Sopenharmony_ci
2299141cc406Sopenharmony_ci        ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE;
2300141cc406Sopenharmony_ci        ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
2301141cc406Sopenharmony_ci
2302141cc406Sopenharmony_ci        ps->AsicReg.RD_Origin = _SHADING_BEGINX;
2303141cc406Sopenharmony_ci        ps->AsicReg.RD_Pixels = 512;
2304141cc406Sopenharmony_ci
2305141cc406Sopenharmony_ci    	if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
2306141cc406Sopenharmony_ci	        ps->AsicReg.RD_Dpi = 300;
2307141cc406Sopenharmony_ci    	else
2308141cc406Sopenharmony_ci	        ps->AsicReg.RD_Dpi = 600;
2309141cc406Sopenharmony_ci
2310141cc406Sopenharmony_ci
2311141cc406Sopenharmony_ci    	/* PauseColorMotorRunStates () */
2312141cc406Sopenharmony_ci    	memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
2313141cc406Sopenharmony_ci	    ps->a_nbNewAdrPointer[1] = 0x77;
2314141cc406Sopenharmony_ci
2315141cc406Sopenharmony_ci	    IOPutOnAllRegisters( ps );
2316141cc406Sopenharmony_ci    	_DODELAY( 70 );
2317141cc406Sopenharmony_ci
2318141cc406Sopenharmony_ci        /* read one shading line and work on it */
2319141cc406Sopenharmony_ci	    if( IOReadOneShadingLine(ps, (pUChar)ps->Bufs.b1.pShadingRam, 512*2)) {
2320141cc406Sopenharmony_ci
2321141cc406Sopenharmony_ci        	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2322141cc406Sopenharmony_ci
2323141cc406Sopenharmony_ci            	wDarks[0] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam );
2324141cc406Sopenharmony_ci                wDarks[1] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
2325141cc406Sopenharmony_ci                                               ps->AsicReg.RD_Pixels );
2326141cc406Sopenharmony_ci		        wDarks[2] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
2327141cc406Sopenharmony_ci                                               ps->AsicReg.RD_Pixels * 2UL);
2328141cc406Sopenharmony_ci
2329141cc406Sopenharmony_ci                if( !wDarks[0] || !wDarks[1] || !wDarks[2] ) {
2330141cc406Sopenharmony_ci		            ps->Shade.fStop = _FALSE;
2331141cc406Sopenharmony_ci		        } else {
2332141cc406Sopenharmony_ci		            ps->Shade.DarkOffset.wColors[0] = wDarks[0];
2333141cc406Sopenharmony_ci		            ps->Shade.DarkOffset.wColors[1] = wDarks[1];
2334141cc406Sopenharmony_ci		            ps->Shade.DarkOffset.wColors[2] = wDarks[2];
2335141cc406Sopenharmony_ci		            (*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
2336141cc406Sopenharmony_ci                                               _CHANNEL_RED, wDarks[0] );
2337141cc406Sopenharmony_ci		            (*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
2338141cc406Sopenharmony_ci                                               _CHANNEL_GREEN, wDarks[1] );
2339141cc406Sopenharmony_ci        		    (*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
2340141cc406Sopenharmony_ci                                               _CHANNEL_BLUE, wDarks[2] );
2341141cc406Sopenharmony_ci	        	}
2342141cc406Sopenharmony_ci	        } else {
2343141cc406Sopenharmony_ci        		wDarks[1] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
2344141cc406Sopenharmony_ci                                               ps->AsicReg.RD_Pixels );
2345141cc406Sopenharmony_ci        		if (!wDarks[1] )
2346141cc406Sopenharmony_ci        		    ps->Shade.fStop = _FALSE;
2347141cc406Sopenharmony_ci        		else {
2348141cc406Sopenharmony_ci        		    ps->Shade.DarkOffset.wColors[1] = wDarks[1];
2349141cc406Sopenharmony_ci		            (*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
2350141cc406Sopenharmony_ci                                               _CHANNEL_GREEN, wDarks[1] );
2351141cc406Sopenharmony_ci        		}
2352141cc406Sopenharmony_ci	        }
2353141cc406Sopenharmony_ci    	} else
2354141cc406Sopenharmony_ci            ps->Shade.fStop = _FALSE;
2355141cc406Sopenharmony_ci    }
2356141cc406Sopenharmony_ci
2357141cc406Sopenharmony_ci    /* CalculateDarkDependOnCCD() */
2358141cc406Sopenharmony_ci   	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2359141cc406Sopenharmony_ci    	(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_RED   );
2360141cc406Sopenharmony_ci    	(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_GREEN );
2361141cc406Sopenharmony_ci    	(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_BLUE  );
2362141cc406Sopenharmony_ci    } else
2363141cc406Sopenharmony_ci    	(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_GREEN );
2364141cc406Sopenharmony_ci}
2365141cc406Sopenharmony_ci
2366141cc406Sopenharmony_ci/**
2367141cc406Sopenharmony_ci */
2368141cc406Sopenharmony_cistatic Bool dacP98003WaitForShading( pScanData ps )
2369141cc406Sopenharmony_ci{
2370141cc406Sopenharmony_ci    ULong i, tmp;
2371141cc406Sopenharmony_ci    Byte  bScanControl;
2372141cc406Sopenharmony_ci
2373141cc406Sopenharmony_ci	DBG( DBG_LOW, "dacP98003WaitForShading()\n" );
2374141cc406Sopenharmony_ci
2375141cc406Sopenharmony_ci	/*
2376141cc406Sopenharmony_ci	 * before getting the shading data, (re)init the ASIC
2377141cc406Sopenharmony_ci	 */
2378141cc406Sopenharmony_ci	ps->ReInitAsic( ps, _TRUE );
2379141cc406Sopenharmony_ci
2380141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Red   = 0;
2381141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Green = 0;
2382141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Blue  = 0;
2383141cc406Sopenharmony_ci
2384141cc406Sopenharmony_ci    IORegisterToScanner( ps, ps->RegResetMTSC );
2385141cc406Sopenharmony_ci
2386141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegModelControl, ps->AsicReg.RD_ModelControl);
2387141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegMotorDriverType,
2388141cc406Sopenharmony_ci                                            ps->AsicReg.RD_MotorDriverType );
2389141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegScanControl1,
2390141cc406Sopenharmony_ci                                        (_SCANSTOPONBUFFULL| _MFRC_BY_XSTEP));
2391141cc406Sopenharmony_ci    ps->GotoShadingPosition( ps );
2392141cc406Sopenharmony_ci
2393141cc406Sopenharmony_ci    bScanControl = ps->AsicReg.RD_ScanControl;
2394141cc406Sopenharmony_ci
2395141cc406Sopenharmony_ci    /* SetShadingMapForGainDark */
2396141cc406Sopenharmony_ci    memset( ps->Bufs.b2.pSumBuf, 0xff, (5400 * 3 * 2));
2397141cc406Sopenharmony_ci
2398141cc406Sopenharmony_ci    /* DownloadShadingAndSetDark() */
2399141cc406Sopenharmony_ci    dacP98DownloadShadingTable( ps, ps->Bufs.b2.pSumBuf, (5400 * 3 * 2));
2400141cc406Sopenharmony_ci
2401141cc406Sopenharmony_ci    for( i = 0, tmp = 0; i < 1024; tmp += 0x01010101, i += 4 ) {
2402141cc406Sopenharmony_ci    	ps->Bufs.b1.Buf.pdw[i]   =
2403141cc406Sopenharmony_ci    	ps->Bufs.b1.Buf.pdw[i+1] =
2404141cc406Sopenharmony_ci    	ps->Bufs.b1.Buf.pdw[i+2] =
2405141cc406Sopenharmony_ci    	ps->Bufs.b1.Buf.pdw[i+3] = tmp;
2406141cc406Sopenharmony_ci    }
2407141cc406Sopenharmony_ci
2408141cc406Sopenharmony_ci    memcpy( ps->Bufs.b1.pShadingMap + 4096, ps->Bufs.b1.pShadingMap, 4096 );
2409141cc406Sopenharmony_ci    memcpy( ps->Bufs.b1.pShadingMap + 8192, ps->Bufs.b1.pShadingMap, 4096 );
2410141cc406Sopenharmony_ci    dacP98DownloadMapTable( ps, ps->Bufs.b1.pShadingMap );
2411141cc406Sopenharmony_ci
2412141cc406Sopenharmony_ci    DBG( DBG_LOW, "wExposure = %u\n", ps->Shade.wExposure);
2413141cc406Sopenharmony_ci    DBG( DBG_LOW, "wXStep    = %u\n", ps->Shade.wXStep);
2414141cc406Sopenharmony_ci
2415141cc406Sopenharmony_ci    ps->AsicReg.RD_LineControl    = (_LOBYTE(ps->Shade.wExposure));
2416141cc406Sopenharmony_ci    ps->AsicReg.RD_ExtLineControl = (_HIBYTE(ps->Shade.wExposure));
2417141cc406Sopenharmony_ci    IODataToRegister(ps, ps->RegExtendedLineControl,
2418141cc406Sopenharmony_ci                                            ps->AsicReg.RD_ExtLineControl );
2419141cc406Sopenharmony_ci    IODataToRegister(ps, ps->RegLineControl, ps->AsicReg.RD_LineControl );
2420141cc406Sopenharmony_ci
2421141cc406Sopenharmony_ci    dacP98003AdjustRGBGain( ps );
2422141cc406Sopenharmony_ci    dacP98003AdjustDark( ps );
2423141cc406Sopenharmony_ci    dacP98003AdjustShadingWaveform( ps );
2424141cc406Sopenharmony_ci
2425141cc406Sopenharmony_ci    ps->AsicReg.RD_ScanControl = bScanControl;
2426141cc406Sopenharmony_ci
2427141cc406Sopenharmony_ci	/* here we have to download the table in any case...*/
2428141cc406Sopenharmony_ci	dacP98DownloadMapTable( ps, ps->a_bMapTable );
2429141cc406Sopenharmony_ci
2430141cc406Sopenharmony_ci    MotorP98003BackToHomeSensor( ps );
2431141cc406Sopenharmony_ci
2432141cc406Sopenharmony_ci    return _TRUE;
2433141cc406Sopenharmony_ci}
2434141cc406Sopenharmony_ci
2435141cc406Sopenharmony_ci/************************ exported functions *********************************/
2436141cc406Sopenharmony_ci
2437141cc406Sopenharmony_ci/**
2438141cc406Sopenharmony_ci */
2439141cc406Sopenharmony_ci_LOC int DacInitialize( pScanData ps )
2440141cc406Sopenharmony_ci{
2441141cc406Sopenharmony_ci	DBG( DBG_HIGH, "DacInitialize()\n" );
2442141cc406Sopenharmony_ci
2443141cc406Sopenharmony_ci	if( NULL == ps )
2444141cc406Sopenharmony_ci		return _E_NULLPTR;
2445141cc406Sopenharmony_ci
2446141cc406Sopenharmony_ci	/*
2447141cc406Sopenharmony_ci	 * depending on the asic, we set some functions
2448141cc406Sopenharmony_ci	 */
2449141cc406Sopenharmony_ci	if( _ASIC_IS_98003 == ps->sCaps.AsicID ) {
2450141cc406Sopenharmony_ci
2451141cc406Sopenharmony_ci		ps->WaitForShading = dacP98003WaitForShading;
2452141cc406Sopenharmony_ci
2453141cc406Sopenharmony_ci    } else if( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
2454141cc406Sopenharmony_ci
2455141cc406Sopenharmony_ci		ps->WaitForShading = dacP98WaitForShading;
2456141cc406Sopenharmony_ci
2457141cc406Sopenharmony_ci	} else if( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
2458141cc406Sopenharmony_ci
2459141cc406Sopenharmony_ci		ps->WaitForShading = dacP96003WaitForShading;
2460141cc406Sopenharmony_ci
2461141cc406Sopenharmony_ci	} else if( _ASIC_IS_96001 == ps->sCaps.AsicID ) {
2462141cc406Sopenharmony_ci
2463141cc406Sopenharmony_ci		ps->WaitForShading = dacP96001WaitForShading;
2464141cc406Sopenharmony_ci
2465141cc406Sopenharmony_ci	} else {
2466141cc406Sopenharmony_ci
2467141cc406Sopenharmony_ci		DBG( DBG_HIGH , "NOT SUPPORTED ASIC !!!\n" );
2468141cc406Sopenharmony_ci		return _E_NOSUPP;
2469141cc406Sopenharmony_ci	}
2470141cc406Sopenharmony_ci	return _OK;
2471141cc406Sopenharmony_ci}
2472141cc406Sopenharmony_ci
2473141cc406Sopenharmony_ci/** Fill out the R/G/B GainOut value
2474141cc406Sopenharmony_ci */
2475141cc406Sopenharmony_ci_LOC void DacP98FillGainOutDirectPort( pScanData ps )
2476141cc406Sopenharmony_ci{
2477141cc406Sopenharmony_ci	ps->OpenScanPath( ps );
2478141cc406Sopenharmony_ci
2479141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x28, ps->bRedGainIndex   );
2480141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x29, ps->bGreenGainIndex );
2481141cc406Sopenharmony_ci    IODataRegisterToDAC( ps, 0x2a, ps->bBlueGainIndex  );
2482141cc406Sopenharmony_ci
2483141cc406Sopenharmony_ci	ps->CloseScanPath( ps );
2484141cc406Sopenharmony_ci}
2485141cc406Sopenharmony_ci
2486141cc406Sopenharmony_ci/**
2487141cc406Sopenharmony_ci */
2488141cc406Sopenharmony_ci_LOC void DacP98FillShadingDarkToShadingRegister( pScanData ps )
2489141cc406Sopenharmony_ci{
2490141cc406Sopenharmony_ci	pUChar pValue;
2491141cc406Sopenharmony_ci	Byte   bReg;
2492141cc406Sopenharmony_ci
2493141cc406Sopenharmony_ci	DBG( DBG_LOW, "DacP98FillShadingDarkToShadingRegister()\n" );
2494141cc406Sopenharmony_ci
2495141cc406Sopenharmony_ci	ps->AsicReg.RD_RedDarkOff   = ps->Shade.DarkOffset.Colors.Red;
2496141cc406Sopenharmony_ci    ps->AsicReg.RD_GreenDarkOff = ps->Shade.DarkOffset.Colors.Green;
2497141cc406Sopenharmony_ci    ps->AsicReg.RD_BlueDarkOff  = ps->Shade.DarkOffset.Colors.Blue;
2498141cc406Sopenharmony_ci
2499141cc406Sopenharmony_ci    pValue = (pUChar)&ps->AsicReg.RD_RedDarkOff;
2500141cc406Sopenharmony_ci    for (bReg = ps->RegRedChDarkOffsetLow; bReg <= ps->RegBlueChDarkOffsetHigh;
2501141cc406Sopenharmony_ci	 	 bReg++, pValue++) {
2502141cc406Sopenharmony_ci
2503141cc406Sopenharmony_ci		IODataToRegister( ps, bReg, *pValue );
2504141cc406Sopenharmony_ci	}
2505141cc406Sopenharmony_ci}
2506141cc406Sopenharmony_ci
2507141cc406Sopenharmony_ci/**
2508141cc406Sopenharmony_ci */
2509141cc406Sopenharmony_ci_LOC void DacP98AdjustDark( pScanData ps )
2510141cc406Sopenharmony_ci{
2511141cc406Sopenharmony_ci	Byte bCorrectTimes;		/* used to be a global var !*/
2512141cc406Sopenharmony_ci
2513141cc406Sopenharmony_ci	DBG( DBG_LOW, "DacP98AdjustDark()\n" );
2514141cc406Sopenharmony_ci
2515141cc406Sopenharmony_ci    ps->Shade.pCcdDac->DarkDAC.Colors.Red   = ps->bsPreRedDAC;
2516141cc406Sopenharmony_ci    ps->Shade.pCcdDac->DarkDAC.Colors.Green = ps->bsPreGreenDAC;
2517141cc406Sopenharmony_ci    ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = ps->bsPreBlueDAC;
2518141cc406Sopenharmony_ci
2519141cc406Sopenharmony_ci    if( ps->DataInf.dwScanFlag & SCANDEF_Negative ) {
2520141cc406Sopenharmony_ci		bCorrectTimes = 6;
2521141cc406Sopenharmony_ci	} else {
2522141cc406Sopenharmony_ci		bCorrectTimes = 5;
2523141cc406Sopenharmony_ci	}
2524141cc406Sopenharmony_ci
2525141cc406Sopenharmony_ci/* CHANGE
2526141cc406Sopenharmony_ci** original code seems to be buggy : for (bCorrectTimes ; bCorrectTimes--;) {
2527141cc406Sopenharmony_ci*/
2528141cc406Sopenharmony_ci	for (;bCorrectTimes ; bCorrectTimes-- ) {
2529141cc406Sopenharmony_ci
2530141cc406Sopenharmony_ci    	ps->OpenScanPath( ps );
2531141cc406Sopenharmony_ci  		dacP98FillDarkDAC( ps );
2532141cc406Sopenharmony_ci		dacP98SetReadFBKRegister( ps );
2533141cc406Sopenharmony_ci       	ps->CloseScanPath( ps );
2534141cc406Sopenharmony_ci
2535141cc406Sopenharmony_ci    	IOPutOnAllRegisters( ps );
2536141cc406Sopenharmony_ci
2537141cc406Sopenharmony_ci		ps->PauseColorMotorRunStates( ps );		/* stop scan states */
2538141cc406Sopenharmony_ci
2539141cc406Sopenharmony_ci		IOReadOneShadingLine( ps, ps->pScanBuffer1, 512*2 );
2540141cc406Sopenharmony_ci
2541141cc406Sopenharmony_ci		dacP98FillChannelDarkLevelControl( ps );
2542141cc406Sopenharmony_ci
2543141cc406Sopenharmony_ci		if(dacP98CheckChannelDarkLevel( ps ))
2544141cc406Sopenharmony_ci	    	break;
2545141cc406Sopenharmony_ci    }
2546141cc406Sopenharmony_ci
2547141cc406Sopenharmony_ci	ps->Shade.DarkOffset.Colors.Red=
2548141cc406Sopenharmony_ci                dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Red,
2549141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkCmpHi.Colors.Red,
2550141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkOffSub.Colors.Red );
2551141cc406Sopenharmony_ci
2552141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Green =
2553141cc406Sopenharmony_ci                dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Green,
2554141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkCmpHi.Colors.Green,
2555141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkOffSub.Colors.Green );
2556141cc406Sopenharmony_ci
2557141cc406Sopenharmony_ci    ps->Shade.DarkOffset.Colors.Blue  =
2558141cc406Sopenharmony_ci                dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Blue,
2559141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue,
2560141cc406Sopenharmony_ci                                  ps->Shade.pCcdDac->DarkOffSub.Colors.Blue );
2561141cc406Sopenharmony_ci}
2562141cc406Sopenharmony_ci
2563141cc406Sopenharmony_ci/**
2564141cc406Sopenharmony_ci */
2565141cc406Sopenharmony_ci_LOC void DacP96WriteBackToGammaShadingRAM( pScanData ps )
2566141cc406Sopenharmony_ci{
2567141cc406Sopenharmony_ci	/* ModifyGammaShadingOffset(ps) */
2568141cc406Sopenharmony_ci    ps->OpenScanPath( ps);
2569141cc406Sopenharmony_ci
2570141cc406Sopenharmony_ci    IODataToRegister( ps, ps->RegRedChShadingOffset,
2571141cc406Sopenharmony_ci					  ps->Asic96Reg.u28.RD_RedChShadingOff );
2572141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegGreenChShadingOffset,
2573141cc406Sopenharmony_ci	     (Byte)((ULong)ps->Asic96Reg.u29.RD_GreenChShadingOff * 96UL/100UL));
2574141cc406Sopenharmony_ci
2575141cc406Sopenharmony_ci	IODataToRegister( ps, ps->RegBlueChShadingOffset,
2576141cc406Sopenharmony_ci			    (Byte)((ULong)ps->Asic96Reg.RD_BlueChShadingOff * 91UL/100UL));
2577141cc406Sopenharmony_ci
2578141cc406Sopenharmony_ci    ps->CloseScanPath( ps );
2579141cc406Sopenharmony_ci
2580141cc406Sopenharmony_ci	dacP96WriteLinearGamma( ps, ps->pPrescan16, 256, ps->ShadingBankRed);
2581141cc406Sopenharmony_ci	dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize,
2582141cc406Sopenharmony_ci           										    256, ps->ShadingBankGreen);
2583141cc406Sopenharmony_ci	dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
2584141cc406Sopenharmony_ci					  					            256, ps->ShadingBankBlue);
2585141cc406Sopenharmony_ci}
2586141cc406Sopenharmony_ci
2587141cc406Sopenharmony_ci/**
2588141cc406Sopenharmony_ci */
2589141cc406Sopenharmony_ci_LOC void DacP98003FillToDAC( pScanData ps, pRGBByteDef regs, pColorByte data )
2590141cc406Sopenharmony_ci{
2591141cc406Sopenharmony_ci   	if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
2592141cc406Sopenharmony_ci
2593141cc406Sopenharmony_ci        dacP98003GainOffsetToDAC( ps, _DAC_RED, regs->Red, data->Colors.Red );
2594141cc406Sopenharmony_ci        dacP98003GainOffsetToDAC( ps, _DAC_GREENCOLOR,
2595141cc406Sopenharmony_ci                                            regs->Green, data->Colors.Green );
2596141cc406Sopenharmony_ci        dacP98003GainOffsetToDAC( ps, _DAC_BLUE,
2597141cc406Sopenharmony_ci                                            regs->Blue, data->Colors.Blue );
2598141cc406Sopenharmony_ci    } else {
2599141cc406Sopenharmony_ci        dacP98003GainOffsetToDAC( ps, _DAC_GREENMONO, regs->Green,
2600141cc406Sopenharmony_ci                                          			      data->Colors.Green );
2601141cc406Sopenharmony_ci    }
2602141cc406Sopenharmony_ci}
2603141cc406Sopenharmony_ci
2604141cc406Sopenharmony_ci/**
2605141cc406Sopenharmony_ci */
2606141cc406Sopenharmony_ci_LOC void DacP98003AdjustGain( pScanData ps, ULong color, Byte hilight )
2607141cc406Sopenharmony_ci{
2608141cc406Sopenharmony_ci    if( hilight < ps->Shade.bGainLow ) {
2609141cc406Sopenharmony_ci
2610141cc406Sopenharmony_ci        if( ps->Shade.Hilight.bColors[color] < ps->Shade.bGainHigh ) {
2611141cc406Sopenharmony_ci
2612141cc406Sopenharmony_ci    	    ps->Shade.fStop = _FALSE;
2613141cc406Sopenharmony_ci    	    ps->Shade.Hilight.bColors[color] = hilight;
2614141cc406Sopenharmony_ci
2615141cc406Sopenharmony_ci    	    if( hilight <= (Byte)(ps->Shade.bGainLow - hilight))
2616141cc406Sopenharmony_ci        		ps->Shade.Gain.bColors[color] += ps->Shade.bGainDouble;
2617141cc406Sopenharmony_ci	        else
2618141cc406Sopenharmony_ci    		    ps->Shade.Gain.bColors[color]++;
2619141cc406Sopenharmony_ci	    }
2620141cc406Sopenharmony_ci    } else {
2621141cc406Sopenharmony_ci    	if( hilight > ps->Shade.bGainHigh ) {
2622141cc406Sopenharmony_ci    	    ps->Shade.fStop = _FALSE;
2623141cc406Sopenharmony_ci	        ps->Shade.Hilight.bColors[color] = hilight;
2624141cc406Sopenharmony_ci    	    ps->Shade.Gain.bColors[color]--;
2625141cc406Sopenharmony_ci    	} else
2626141cc406Sopenharmony_ci    	    ps->Shade.Hilight.bColors[color] = hilight;
2627141cc406Sopenharmony_ci	}
2628141cc406Sopenharmony_ci
2629141cc406Sopenharmony_ci    if( ps->Shade.Gain.bColors[color] > ps->Shade.bMaxGain ) {
2630141cc406Sopenharmony_ci        ps->Shade.Gain.bColors[color] = ps->Shade.bMaxGain;
2631141cc406Sopenharmony_ci    }
2632141cc406Sopenharmony_ci}
2633141cc406Sopenharmony_ci
2634141cc406Sopenharmony_ci/**
2635141cc406Sopenharmony_ci */
2636141cc406Sopenharmony_ci_LOC Byte DacP98003SumGains( pUChar pb, ULong pixelsLine )
2637141cc406Sopenharmony_ci{
2638141cc406Sopenharmony_ci    Byte   bHilight, tmp;
2639141cc406Sopenharmony_ci    ULong  dwPixels, dwAve;
2640141cc406Sopenharmony_ci    UShort sum;
2641141cc406Sopenharmony_ci
2642141cc406Sopenharmony_ci    for( bHilight = 0, dwPixels = pixelsLine >> 4; dwPixels--; ) {
2643141cc406Sopenharmony_ci
2644141cc406Sopenharmony_ci    	for( sum = 0, dwAve = 16; dwAve--; pb++)
2645141cc406Sopenharmony_ci	        sum += (UShort)*pb;
2646141cc406Sopenharmony_ci
2647141cc406Sopenharmony_ci    	sum >>= 4;
2648141cc406Sopenharmony_ci        tmp = (Byte)sum;
2649141cc406Sopenharmony_ci
2650141cc406Sopenharmony_ci	    if( tmp > bHilight )
2651141cc406Sopenharmony_ci	        bHilight = tmp;
2652141cc406Sopenharmony_ci    }
2653141cc406Sopenharmony_ci    return bHilight;
2654141cc406Sopenharmony_ci}
2655141cc406Sopenharmony_ci
2656141cc406Sopenharmony_ci/* END PLUSTEK-PP_DAC.C .....................................................*/
2657