Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1294 lines
37 KiB

  1. // $Header: G:/SwDev/WDM/Video/bt848/rcs/Pisces.cpp 1.15 1998/05/04 23:48:53 tomz Exp $
  2. #include "pisces.h"
  3. #include <stdlib.h>
  4. /*
  5. */
  6. BtPisces::BtPisces( DWORD *xtals ) : Engine_(), Inited_( false ),
  7. Even_( CAPTURE_EVEN, VF_Even,&COLOR_EVEN, &WSWAP_EVEN, &BSWAP_EVEN ),
  8. Odd_( CAPTURE_ODD, VF_Odd, &COLOR_ODD, &WSWAP_ODD, &BSWAP_ODD ),
  9. VBIE_( CAPTURE_VBI_EVEN ), VBIO_( CAPTURE_VBI_ODD ), Update_( false ),
  10. nSkipped_( 0 ), Paused_( false ),
  11. Starter_( ),
  12. SyncEvenEnd1_( ),
  13. SyncEvenEnd2_( ),
  14. SyncOddEnd1_( ),
  15. SyncOddEnd2_( ),
  16. PsDecoder_( xtals ),
  17. dwPlanarAdjust_( 0 ),
  18. CONSTRUCT_COLORCONTROL,
  19. CONSTRUCT_INTERRUPTSTATUS,
  20. CONSTRUCT_INTERRUPTMASK,
  21. CONSTRUCT_CONTROL,
  22. CONSTRUCT_CAPTURECONTROL,
  23. CONSTRUCT_COLORFORMAT,
  24. CONSTRUCT_GPIOOUTPUTENABLECONTROL,
  25. CONSTRUCT_GPIODATAIO
  26. {
  27. Trace t("BtPisces::BtPisces()");
  28. Init();
  29. }
  30. BtPisces::~BtPisces()
  31. {
  32. Trace t("BtPisces::~BtPisces()");
  33. Engine_.Stop();
  34. InterruptMask = 0;
  35. InterruptStatus = AllFs;
  36. // prevent risc program destructor from gpf-ing
  37. SyncEvenEnd1_.SetParent( NULL );
  38. SyncEvenEnd2_.SetParent( NULL );
  39. SyncOddEnd1_.SetParent( NULL );
  40. SyncOddEnd2_.SetParent( NULL );
  41. // free the association array now
  42. int ArrSize = sizeof( InterruptToIdx_ ) / sizeof( InterruptToIdx_ [0] );
  43. while ( --ArrSize >= 0 )
  44. delete InterruptToIdx_ [ArrSize];
  45. // now is the Skippers_' turn
  46. ArrSize = sizeof( Skippers_ ) / sizeof( Skippers_ [0] );
  47. while ( --ArrSize >= 0 )
  48. delete Skippers_ [ArrSize];
  49. }
  50. /* Method: BtPisces::GetIdxFromStream
  51. * Purpose: Returns starting index in the program array for a field
  52. * Input: aStream: StreamInfo & - reference
  53. * Output: int : Index
  54. */
  55. int BtPisces::GetIdxFromStream( Field &aStream )
  56. {
  57. Trace t("BtPisces::GetIdxFromStream()");
  58. switch ( aStream.GetStreamID() ) {
  59. case VS_Field1:
  60. return OddStartLocation;
  61. case VS_Field2:
  62. return EvenStartLocation;
  63. case VS_VBI1:
  64. return VBIOStartLocation;
  65. case VS_VBI2:
  66. return VBIEStartLocation;
  67. default:
  68. return 0;
  69. }
  70. }
  71. /* Method: BtPisces::CreateSyncCodes
  72. * Purpose: Creates the risc programs with sync codes needed between data risc
  73. * programs
  74. * Input: None
  75. * Output: ErrorCode
  76. */
  77. bool BtPisces::CreateSyncCodes()
  78. {
  79. Trace t("BtPisces::CreateSyncCodes()");
  80. bool bRet = SyncEvenEnd1_.Create( SC_VRE ) == Success &&
  81. SyncEvenEnd2_.Create( SC_VRE ) == Success &&
  82. SyncOddEnd1_.Create( SC_VRO ) == Success &&
  83. SyncOddEnd2_.Create( SC_VRO ) == Success &&
  84. Starter_.Create( SC_VRO ) == Success;
  85. DebugOut((1, "*** BtPisces::CreateSyncCodes SyncEvenEnd1_(%x)\n", &SyncEvenEnd1_));
  86. DebugOut((1, "*** BtPisces::CreateSyncCodes SyncEvenEnd2_(%x)\n", &SyncEvenEnd2_));
  87. DebugOut((1, "*** BtPisces::CreateSyncCodes SyncOddEnd1_(%x)\n", &SyncOddEnd1_));
  88. DebugOut((1, "*** BtPisces::CreateSyncCodes SyncOddEnd2_(%x)\n", &SyncOddEnd2_));
  89. DebugOut((1, "*** BtPisces::CreateSyncCodes Starter_(%x)\n", &Starter_));
  90. return( bRet );
  91. }
  92. /* Method: BtPisces::Init
  93. * Purpose: Performs all necessary initialization
  94. * Input: None
  95. * Output: None
  96. */
  97. void BtPisces::Init()
  98. {
  99. Trace t("BtPisces::Init()");
  100. InterruptStatus = AllFs;
  101. InterruptStatus = 0;
  102. GAMMA = 1;
  103. // initialize the arrays
  104. CreatedProgs_.Clear() ;
  105. ActiveProgs_.Clear() ;
  106. // fill in the skippers array and make each program a 'skipper'
  107. DataBuf buf;
  108. // [!!!] [TMZ]
  109. // Engine_.CreateProgram constants look questionable
  110. for ( int i = 0; i < sizeof( Skippers_ ) / sizeof( Skippers_ [0] ); i++ ) {
  111. if ( i & 1 ) {
  112. MSize s( 10, 10 );
  113. Skippers_ [i] = Engine_.CreateProgram( s, 10 * 2, CF_VBI, buf, true, 0, false );
  114. DebugOut((1, "Creating Skipper[%d] == %x\n", i, Skippers_[i]));
  115. Engine_.Skip( Skippers_ [i] );
  116. } else {
  117. MSize s( 768, 12 );
  118. // now create skippers for the VBI streams
  119. Skippers_ [i] = Engine_.CreateProgram( s, 768 * 2, CF_VBI, buf, true, 0, false );
  120. DebugOut((1, "Creating Skipper[%d] == %x\n", i, Skippers_[i]));
  121. }
  122. if ( !Skippers_ [i] )
  123. return;
  124. }
  125. // create associations between Created and Skippers
  126. int link = 0;
  127. for ( i = 0; i < sizeof( SkipperIdxArr_ ) / sizeof( SkipperIdxArr_ [0] ); i++ ) {
  128. SkipperIdxArr_ [i] = link;
  129. i += link & 1; // advance past the sync program entry
  130. link++;
  131. }
  132. // fill in constant elements; see the table in the .h file
  133. CreatedProgs_ [2] = &SyncOddEnd1_;
  134. CreatedProgs_ [8] = &SyncOddEnd2_;
  135. CreatedProgs_ [5] = &SyncEvenEnd1_;
  136. CreatedProgs_ [11] = &SyncEvenEnd2_;
  137. // set corresponding sync bits
  138. if ( !CreateSyncCodes() )
  139. return;
  140. // initialize association array now
  141. int ArrSize = sizeof( InterruptToIdx_ ) / sizeof( InterruptToIdx_ [0] );
  142. while ( --ArrSize >= 0 ) {
  143. if ( ( InterruptToIdx_ [ArrSize] = new IntrIdxAss() ) == 0 )
  144. return;
  145. }
  146. Even_.SetFrameRate( 333667 );
  147. Odd_. SetFrameRate( 333667 );
  148. VBIE_.SetFrameRate( 333667 );
  149. VBIO_.SetFrameRate( 333667 );
  150. Odd_. SetStreamID( VS_Field1 );
  151. Even_.SetStreamID( VS_Field2 );
  152. VBIO_.SetStreamID( VS_VBI1 );
  153. VBIE_.SetStreamID( VS_VBI2 );
  154. // finally, can wipe out the prespiration from the forehead
  155. Inited_ = true;
  156. }
  157. /* Method: BtPisces::AssignIntNumbers
  158. * Purpose: Assigns numbers to RISC programs that generate interrupt
  159. * Input: None
  160. * Output: None
  161. */
  162. void BtPisces::AssignIntNumbers()
  163. {
  164. Trace t("BtPisces::AssignIntNumbers()");
  165. int IntrCnt = 0;
  166. int limit = ActiveProgs_.NumElements() ;
  167. int idx;
  168. // initialize InterruptToIdx_ array
  169. for ( idx = 0; idx < limit; idx++ ) {
  170. IntrIdxAss item( idx, -1 );
  171. *InterruptToIdx_ [idx] = item;
  172. }
  173. // assign numbers in front of starting program
  174. bool first = true;
  175. for ( idx = 0; idx < (int) ActiveProgs_.NumElements() ; idx++ ) {
  176. RiscPrgHandle pProg = ActiveProgs_ [idx];
  177. //if not skipped and generates an interrupt assign number
  178. if ( pProg && pProg->IsInterrupting() ) {
  179. if ( first == true ) {
  180. first = false;
  181. pProg->ResetStatus();
  182. Skippers_ [SkipperIdxArr_ [idx] ]->ResetStatus();
  183. } else {
  184. pProg->SetToCount();
  185. Skippers_ [SkipperIdxArr_ [idx] ]->SetToCount();
  186. }
  187. IntrIdxAss item( IntrCnt, idx );
  188. *InterruptToIdx_ [IntrCnt] = item;
  189. IntrCnt++;
  190. }
  191. }
  192. }
  193. /* Method: BtPisces::LinkThePrograms
  194. * Purpose: Creates links between the created programs
  195. * Input: None
  196. * Output: None
  197. */
  198. void BtPisces::LinkThePrograms()
  199. {
  200. Trace t("BtPisces::LinkThePrograms()");
  201. DebugOut((1, "*** Linking Programs\n"));
  202. RiscPrgHandle hParent = ActiveProgs_.First(),
  203. hChild = NULL,
  204. hVeryFirst = NULL,
  205. hLastChild = NULL ;
  206. if (hParent) {
  207. if ( hParent->IsSkipped() ) {
  208. int idx = ActiveProgs_.GetIndex(hParent) ;
  209. hParent = Skippers_ [SkipperIdxArr_ [idx] ] ;
  210. }
  211. while (hParent) {
  212. if (!hVeryFirst)
  213. hVeryFirst = hParent ;
  214. if ( hChild = ActiveProgs_.Next()) {
  215. if ( hChild->IsSkipped() ) {
  216. int idx = ActiveProgs_.GetIndex(hChild) ;
  217. hChild = Skippers_ [SkipperIdxArr_ [idx] ] ;
  218. }
  219. hLastChild = hChild;
  220. Engine_.Chain( hParent, hChild ) ;
  221. }
  222. hParent = hChild ;
  223. }
  224. // initial jump
  225. Engine_.Chain( &Starter_, hVeryFirst ) ;
  226. // now create the loop
  227. Engine_.Chain( hLastChild ? hLastChild : hVeryFirst, hVeryFirst ) ;
  228. }
  229. }
  230. /* Method: BtPisces::ProcessSyncPrograms()
  231. * Purpose: This function unlinks the helper sync programs
  232. * Input: None
  233. * Output: None
  234. */
  235. void BtPisces::ProcessSyncPrograms()
  236. {
  237. Trace t("BtPisces::ProcessSyncPrograms()");
  238. for ( int i = 0; i < (int) ActiveProgs_.NumElements(); i += ProgsWithinField ) {
  239. if ( !ActiveProgs_ [i] && !ActiveProgs_ [i+1] ) {
  240. ActiveProgs_ [i+2] = NULL;
  241. } else {
  242. ActiveProgs_ [i+2] = CreatedProgs_ [i+2];
  243. }
  244. }
  245. }
  246. /* Method: BtPisces::ProcessPresentPrograms
  247. * Purpose:
  248. * Input: None
  249. * Output: None
  250. */
  251. void BtPisces::ProcessPresentPrograms()
  252. {
  253. Trace t("BtPisces::ProcessPresentPrograms()");
  254. // link in/out helper sync programs
  255. ProcessSyncPrograms();
  256. // and now is time to cross link the programs
  257. LinkThePrograms();
  258. // and now figure out the numbers programs use for interrupts
  259. AssignIntNumbers();
  260. }
  261. /* Method: BtPisces::AddProgram
  262. * Purpose: Creates new RISC program and inserts it in the chain at a proper place
  263. * Input: aStream: StreamInfo & - reference to the stream to add a program for
  264. * NumberToAdd: int - number of programs to add
  265. * Output:
  266. * Note: Basically this internal function performs a loop 2 times
  267. * //4. Tries to get another buffer to establish double buffering
  268. * //5. If buffer is available it creates another RISC program with it
  269. * //6. Then it has to link the program in...
  270. */
  271. RiscPrgHandle BtPisces::AddProgram( Field &ToStart, int NumberToAdd )
  272. {
  273. Trace t("BtPisces::AddProgram()");
  274. DebugOut((1, "BtPisces::AddProgram()\n"));
  275. int StartIdx = GetIdxFromStream( ToStart );
  276. SyncCode Sync;
  277. int SyncIdx;
  278. bool rsync;
  279. if ( StartIdx <= OddStartLocation ) {
  280. Sync = SC_VRO;
  281. SyncIdx = OddSyncStartLoc;
  282. rsync = false;
  283. } else {
  284. Sync = SC_VRE;
  285. SyncIdx = EvenSyncStartLoc;
  286. rsync = bool( StartIdx == EvenStartLocation );
  287. }
  288. // have to know what is the size of the image to produce
  289. MRect r;
  290. ToStart.GetDigitalWindow( r );
  291. // RISC engine operates on absolute sizes, not rectangles
  292. MSize s = r.Size();
  293. int BufCnt = 0;
  294. int Idx = StartIdx;
  295. for ( ; BufCnt < NumberToAdd; BufCnt++ ) {
  296. // init sync programs with a premise tha no data program exists
  297. CreatedProgs_ [SyncIdx]->Create( Sync, true );
  298. // obtain the next buffer from queue ( entry is removed from container )
  299. DataBuf buf = ToStart.GetNextBuffer();
  300. // can create a RISC program now.
  301. RiscPrgHandle hProgram = Engine_.CreateProgram( s, ToStart.GetBufPitch(),
  302. ToStart.GetColorFormat(), buf, ToStart.Interrupt_, dwPlanarAdjust_, rsync );
  303. // store this program
  304. CreatedProgs_ [Idx] = hProgram;
  305. DebugOut((1, "Creating RiscProgram[%d] == %x\n", Idx, CreatedProgs_ [Idx]));
  306. if ( !hProgram ) {
  307. Idx -= DistBetweenProgs;
  308. if ( Idx >= 0 ) {
  309. // clean up previous program
  310. Engine_.DestroyProgram( CreatedProgs_ [Idx] );
  311. CreatedProgs_ [Idx] = NULL;
  312. }
  313. return NULL;
  314. }
  315. // make sure we unskip the program when buffer becomes available
  316. if ( !buf.pData_ ) {
  317. hProgram->SetSkipped(); // do not have enough buffers to support double buffering
  318. nSkipped_++;
  319. }
  320. // assign stream to program; makes it easy during interrupt
  321. hProgram->SetTag( &ToStart );
  322. SyncIdx += DistBetweenProgs;
  323. Idx += DistBetweenProgs; // skip the location intended for the other program
  324. } /* endfor */
  325. return CreatedProgs_ [StartIdx];
  326. }
  327. /* Method: BtPisces::Create
  328. * Purpose: This functions starts the stream.
  329. * Input: aStream: StreamInfo & - reference to a stream to start
  330. * Output: Address of the Starter_
  331. * Note: After the Start 2 entries in the CreatedProgs_ are created. Starting
  332. * location is 4 for even and 1 for odd. Increment is 6. So if it is the first
  333. * invocation and there is enough ( 2 ) buffers present entries [1] and [7]
  334. * or [4] and [10] will be filled with newly created RISC programs. When programs
  335. * exist for one field only they are doubly linked. When programs exist for
  336. * both fields they alternate, i.e. 0->2->1->3->0... When one of the fields
  337. * has 1 program only, programs are linked like this: 0->2->1->0->2...(numbers
  338. * are indexes in the CreatedProgs_ array ). Alternating programs makes for
  339. * maximum frame rate.
  340. */
  341. ErrorCode BtPisces::Create( Field &ToCreate )
  342. {
  343. Trace t("BtPisces::Create()");
  344. // running full-steam, nothing to create
  345. if ( ToCreate.IsStarted() == true )
  346. return Success;
  347. int StartIdx = GetIdxFromStream( ToCreate );
  348. if ( CreatedProgs_ [StartIdx] )
  349. return Success; // not running yet, but exists
  350. // call into internal function that adds new RISC program
  351. if ( ! AddProgram( ToCreate, MaxProgsForField ) )
  352. return Fail;
  353. return Success;
  354. }
  355. /* Method: BtPisces::Start
  356. * Purpose: Starts given stream ( by putting in in the Active_ array
  357. * Input: ToStart: Field &
  358. */
  359. void BtPisces::Start( Field & ToStart )
  360. {
  361. Trace t("BtPisces::Start()");
  362. // DebugOut((1, "BtPisces::Start\n"));
  363. if ( ToStart.IsStarted() == true )
  364. return;
  365. // all we need to do at this point is to create a proper starter
  366. // and link the programs in.
  367. int idx = GetIdxFromStream( ToStart );
  368. // this loop will enable LinkThePrograms to see programs for this stream
  369. for ( int i = 0; i < MaxProgsForField; i++, idx += DistBetweenProgs ) {
  370. ActiveProgs_ [idx] = CreatedProgs_ [idx];
  371. }
  372. // all I want to do at this point is call Restart.
  373. // do not signal the buffers
  374. Update_ = false;
  375. Restart();
  376. Update_ = true;
  377. }
  378. /* Method: BtPisces::Stop
  379. * Purpose: This function stops a stream. Called when PAUSE SRB is received
  380. * Input: aStream: StreamInfo & - reference to a stream to start
  381. * Output: None
  382. */
  383. void BtPisces::Stop( Field &ToStop )
  384. {
  385. Trace t("BtPisces::Stop()");
  386. // DebugOut((1, "BtPisces::Stop\n"));
  387. Engine_.Stop(); // no more interrupts
  388. int StartIdx = GetIdxFromStream( ToStop );
  389. // prevent unneeded syncronization interrupts
  390. IMASK_SCERW = 0;
  391. // it is time to pause the stream now
  392. ToStop.Stop();
  393. bool Need2Restart = false;
  394. // go through the array of programs and killing ones for this field (stream)
  395. for ( int i = 0; i < MaxProgsForField; i++, StartIdx += DistBetweenProgs ) {
  396. RiscPrgHandle ToDie = CreatedProgs_ [StartIdx];
  397. if ( !ToDie ) // this should never happen
  398. continue;
  399. if ( ToDie->IsSkipped() )
  400. nSkipped_--;
  401. DebugOut((1, "about to destroy idx = %d\n", StartIdx ) );
  402. Engine_.DestroyProgram( ToDie );
  403. CreatedProgs_ [StartIdx] = NULL;
  404. ActiveProgs_ [StartIdx] = NULL; // in case Pause wasn't called
  405. Need2Restart = true;
  406. } /* endfor */
  407. // nobody's around anymore
  408. if ( !CreatedProgs_.CountDMAProgs() ) {
  409. Engine_.Stop();
  410. InterruptMask = 0;
  411. InterruptStatus = AllFs;
  412. nSkipped_ = 0;
  413. } else {
  414. if ( Need2Restart ) {
  415. Restart(); // relink the programs and start ones that are alive
  416. IMASK_SCERW = 1; // re-enable the sync error interrupts
  417. }
  418. }
  419. }
  420. /* Method: BtPisces::Pause
  421. * Purpose: This function stops a stream. Called when PAUSE SRB is received
  422. * Input: aStream: Field & - reference to a stream to start
  423. * Output: None
  424. */
  425. void BtPisces::Pause( Field &ToPause )
  426. {
  427. Trace t("BtPisces::Pause()");
  428. // DebugOut((1, "BtPisces::Pause\n"));
  429. Engine_.Stop(); // no more interrupts
  430. if ( !ToPause.IsStarted() )
  431. return;
  432. int StartIdx = GetIdxFromStream( ToPause );
  433. // prevent unneeded syncronization interrupts
  434. IMASK_SCERW = 0;
  435. // it is time to pause the stream now
  436. // ToPause.Stop(); - done in Restart
  437. // go through the array of programs and killing ones for this field (stream)
  438. for ( int i = 0; i < MaxProgsForField; i++, StartIdx += DistBetweenProgs ) {
  439. ActiveProgs_ [StartIdx] = NULL;
  440. } /* endfor */
  441. Restart(); // relink the programs and start ones that are alive
  442. }
  443. /* Method: BtPisces::PairedPause
  444. * Purpose: This is a hacky function that pauses 2 streams at once
  445. * Input: idx: index of the second program in the second field
  446. * Output: None
  447. */
  448. void BtPisces::PairedPause( int idx )
  449. {
  450. Trace t("BtPisces::PairedPause()");
  451. // DebugOut((1, "BtPisces::PairedPause\n"));
  452. Engine_.Stop(); // no more interrupts
  453. // go through the array of programs and killing ones for this field (stream)
  454. for ( int i = 0; i < MaxProgsForField; i++, idx -= DistBetweenProgs ) {
  455. ActiveProgs_ [idx] = NULL;
  456. ActiveProgs_ [idx-ProgsWithinField] = NULL;
  457. } /* endfor */
  458. Restart(); // relink the programs and start ones that are alive
  459. }
  460. /* Method: BtPisces::GetStarted
  461. * Purpose: Figures out the channels that are started
  462. * Input:
  463. * Output: None
  464. */
  465. void BtPisces::GetStarted( bool &EvenWasStarted, bool &OddWasStarted,
  466. bool &VBIEWasStarted, bool &VBIOWasStarted )
  467. {
  468. Trace t("BtPisces::GetStarted()");
  469. VBIEWasStarted = ( ActiveProgs_ [VBIEStartLocation] ? TRUE : FALSE);
  470. EvenWasStarted = ( ActiveProgs_ [EvenStartLocation] ? TRUE : FALSE);
  471. VBIOWasStarted = ( ActiveProgs_ [VBIOStartLocation] ? TRUE : FALSE);
  472. OddWasStarted = ( ActiveProgs_ [OddStartLocation] ? TRUE : FALSE);
  473. }
  474. /* Method: BtPisces::RestartStreams
  475. * Purpose: Restarts streams that were started
  476. * Input:
  477. * Output: None
  478. */
  479. void BtPisces::RestartStreams( bool EvenWasStarted, bool OddWasStarted,
  480. bool VBIEWasStarted, bool VBIOWasStarted )
  481. {
  482. Trace t("BtPisces::RestartStream()");
  483. // vbi programs are first to execute, so enable them first
  484. if ( VBIOWasStarted )
  485. VBIO_.Start();
  486. if ( OddWasStarted )
  487. Odd_.Start();
  488. if ( VBIEWasStarted )
  489. VBIE_.Start();
  490. if ( EvenWasStarted )
  491. Even_.Start();
  492. }
  493. /* Method: BtPisces::CreateStarter
  494. * Purpose: Creates proper sync code for the bootstrap program
  495. * Input: EvenWasStarted: bool
  496. * Output: None
  497. */
  498. void BtPisces::CreateStarter( bool EvenWasStarted )
  499. {
  500. Trace t("BtPisces::CreateStarter()");
  501. Starter_.Create( EvenWasStarted ? SC_VRE : SC_VRO, true );
  502. DebugOut((1, "*** BtPisces::CreateStarter(%x) buf(%x)\n", &Starter_ , Starter_.GetPhysProgAddr( )));
  503. }
  504. /* Method: BtPisces::Restart
  505. * Purpose: Restarts the capture process. Called by ISR and Stop()
  506. * Input: None
  507. * Output: None
  508. */
  509. void BtPisces::Restart()
  510. {
  511. Trace t("BtPisces::Restart()");
  512. bool EvenWasStarted, OddWasStarted, VBIEWasStarted, VBIOWasStarted;
  513. GetStarted( EvenWasStarted, OddWasStarted, VBIEWasStarted, VBIOWasStarted );
  514. DebugOut((2, "BtPisces::Restart - Even WasStarted (%d)\n", EvenWasStarted));
  515. DebugOut((2, "BtPisces::Restart - Odd WasStarted (%d)\n", OddWasStarted));
  516. DebugOut((2, "BtPisces::Restart - VBIE WasStarted (%d)\n", VBIEWasStarted));
  517. DebugOut((2, "BtPisces::Restart - VBIO WasStarted (%d)\n", VBIOWasStarted));
  518. Engine_.Stop(); // No more interrupts!
  519. Odd_.Stop();
  520. Even_.Stop();
  521. VBIE_.Stop();
  522. VBIO_.Stop();
  523. Engine_.Stop(); // No more interrupts!
  524. #if 1
  525. if ( OddWasStarted )
  526. {
  527. Odd_.CancelSrbList();
  528. }
  529. if ( EvenWasStarted )
  530. {
  531. Even_.CancelSrbList();
  532. }
  533. if ( VBIEWasStarted )
  534. {
  535. VBIE_.CancelSrbList();
  536. }
  537. if ( VBIOWasStarted )
  538. {
  539. VBIO_.CancelSrbList();
  540. }
  541. #endif
  542. // this will never happen, probably
  543. if ( !EvenWasStarted && !OddWasStarted && !VBIEWasStarted && !VBIOWasStarted )
  544. return;
  545. InterruptStatus = AllFs; // clear all the status bits
  546. CreateStarter( bool( EvenWasStarted || VBIEWasStarted ) );
  547. ProcessPresentPrograms();
  548. // DumpRiscPrograms();
  549. Engine_.Start( Starter_ );
  550. RestartStreams( EvenWasStarted, OddWasStarted, VBIEWasStarted, VBIOWasStarted );
  551. OldIdx_ = -1;
  552. InterruptMask = RISC_I | FBUS_I | OCERR_I | SCERR_I |
  553. RIPERR_I | PABORT_I | EN_TRITON1_BUG_FIX;
  554. }
  555. /* Method: BtPisces::Skip
  556. * Purpose: Forces a given program to be skipped by the RISC engine
  557. * Input: ToSkip: RiscPrgHandle - program to be skipped
  558. * Output: None
  559. * Note: If the number of skipped programs equals total number of programs, the
  560. * RISC engine is stopped
  561. */
  562. void BtPisces::Skip( int idx )
  563. {
  564. Trace t("BtPisces::Skip()");
  565. // get the program and skip it
  566. RiscPrgHandle ToSkip = ActiveProgs_ [idx];
  567. if ( ToSkip->IsSkipped() )
  568. return;
  569. ToSkip->SetSkipped();
  570. nSkipped_++;
  571. //skip by linking the Skipper_ in instead of the skippee
  572. RiscPrgHandle SkipeeParent = ToSkip->GetParent();
  573. RiscPrgHandle SkipeeChild = ToSkip->GetChild();
  574. // get the skipper for this program
  575. RiscPrgHandle pSkipper = Skippers_ [SkipperIdxArr_ [idx] ];
  576. Engine_.Chain( pSkipper, SkipeeChild );
  577. Engine_.Chain( SkipeeParent, pSkipper );
  578. DebugOut((1, "BtPisces::Skipped %d Skipper %d\n", idx, SkipperIdxArr_ [idx] ) );
  579. }
  580. inline bool IsFirst( int idx )
  581. {
  582. Trace t("BtPisces::IsFirst()");
  583. return bool( idx == OddStartLocation || idx == VBIOStartLocation ||
  584. idx - DistBetweenProgs == OddStartLocation ||
  585. idx - DistBetweenProgs == VBIOStartLocation );
  586. }
  587. inline bool IsLast( int idx )
  588. {
  589. Trace t("BtPisces::IsLast()");
  590. return bool((idx == (VBIEStartLocation + DistBetweenProgs)) ||
  591. (idx == (EvenStartLocation + DistBetweenProgs)));
  592. }
  593. /* Method: BtPisces::GetPassed
  594. * Purpose: Calculates number of programs that have executed since last interrupt
  595. * Input: None
  596. * Output: int: number of passed
  597. */
  598. int BtPisces::GetPassed()
  599. {
  600. Trace t("BtPisces::GetPassed()");
  601. // figure out which RISC program caused an interrupt
  602. int ProgCnt = RISCS;
  603. int numActive = ActiveProgs_.CountDMAProgs() ;
  604. if ( ProgCnt >= numActive ) {
  605. DebugOut((1, "ProgCnt = %d, larger than created\n", ProgCnt ) );
  606. }
  607. // now see how many programs have interrupted since last time and process them all
  608. if ( ProgCnt == OldIdx_ ) {
  609. DebugOut((1, "ProgCnt is the same = %d\n", ProgCnt ) );
  610. }
  611. int passed;
  612. if ( ProgCnt < OldIdx_ ) {
  613. passed = numActive - OldIdx_ + ProgCnt; // you spin me like a record, baby - round, round...
  614. } else
  615. passed = ProgCnt - OldIdx_;
  616. // The following line of code was VERY bad !!!
  617. // This caused crashes when the system got busy and had interrupts backed up.
  618. // if ( ProgCnt == OldIdx_ )
  619. // passed = numActive;
  620. OldIdx_ = ProgCnt;
  621. return passed;
  622. }
  623. /* Method: BtPisces::GetProgram
  624. * Purpose: Finds a RISC program based on its position
  625. * Input: None
  626. * Output: None
  627. */
  628. inline RiscPrgHandle BtPisces::GetProgram( int pos, int &idx )
  629. {
  630. Trace t("BtPisces::GetProgram()");
  631. int nActiveProgs = ActiveProgs_.CountDMAProgs( );
  632. if ( nActiveProgs == 0 )
  633. {
  634. idx = 0;
  635. return ( NULL );
  636. }
  637. IntrIdxAss *item;
  638. item = InterruptToIdx_ [ pos % nActiveProgs ];
  639. idx = item->Idx;
  640. DEBUG_ASSERT( idx != -1 );
  641. return (idx == -1) ? NULL : ActiveProgs_ [idx];
  642. }
  643. /* Method: BtPisces::ProcessRISCIntr
  644. * Purpose: Handles interrupts caused by the RISC programs
  645. * Input: None
  646. * Output: None
  647. */
  648. void BtPisces::ProcessRISCIntr()
  649. {
  650. PHW_STREAM_REQUEST_BLOCK gpCurSrb = 0;
  651. Trace t("BtPisces::ProcessRISCIntr()");
  652. // this line must be before GetPassed(), as OldIdx_ is changed by that function
  653. int pos = OldIdx_ + 1;
  654. // measure elapsed time
  655. int passed = GetPassed();
  656. DebugOut((1, " passed = %d\n", passed ) );
  657. while ( passed-- > 0 ) {
  658. int idx;
  659. RiscPrgHandle Rspnsbl = GetProgram( pos, idx );
  660. pos++;
  661. // last chance to prevent a disaster...
  662. if ( !Rspnsbl || !Rspnsbl->IsInterrupting() ) {
  663. DebugOut((1, " no resp or not intr\n" ) );
  664. continue;
  665. }
  666. // get conveniently saved stream from the program
  667. Field &Interrupter = *(Field *)Rspnsbl->GetTag();
  668. gpCurSrb = Rspnsbl->pSrb_; // [TMZ] [!!!]
  669. DebugOut((1, "'idx(%d), pSrb(%x)\n", idx, gpCurSrb));
  670. bool paired = Interrupter.GetPaired();
  671. if ( Interrupter.IsStarted() != true ) {
  672. DebugOut((1, " not started %d\n", idx ) );
  673. continue;
  674. }
  675. if ( IsFirst( idx ) && paired ) {
  676. DebugOut((1, " continue pair %d\n", idx ) );
  677. continue;
  678. }
  679. LONGLONG *pL = (LONGLONG *)Rspnsbl->GetDataBuffer();
  680. if ( !pL )
  681. {
  682. DebugOut((1, "null buffer in interrupt, ignore this interrupt\n"));
  683. //continue;
  684. }
  685. else
  686. {
  687. DebugOut((1, "good buffer in interrupt\n"));
  688. }
  689. // now make sure all buffers are written to
  690. if ( !pL || Rspnsbl->IsSkipped() ) {
  691. // want to call notify, so ProcessBufferAtInterrupt is called
  692. DebugOut((1, " skipped %d\n", idx ) );
  693. Interrupter.Notify( (PVOID)idx, true );
  694. Interrupter.SetReady( true );
  695. } else {
  696. BOOL test1 = FALSE;
  697. BOOL test2 = FALSE;
  698. BOOL test3 = FALSE;
  699. if ( 1
  700. //*pL != 0xAAAAAAAA33333333 && (test1 = TRUE) &&
  701. //*(pL + 1) != 0xBBBBBBBB22222222 && (test2 = TRUE) &&
  702. //Interrupter.GetReady() && (test3 = TRUE)
  703. ) {
  704. // here buffer is available
  705. DebugOut((1, " notify %d, addr - %x\n", idx,
  706. Rspnsbl->GetDataBuffer() ) );
  707. //#pragma message("*** be very carefull zeroing buffers!!!")
  708. //Rspnsbl->SetDataBuffer( 0 ); // [TMZ] try to fix buffer re-use bug
  709. Interrupter.Notify( (PVOID)idx, false );
  710. Interrupter.SetReady( true );
  711. } else {
  712. // add code for the paired streams here
  713. DebugOut((1, " not time %d (%d, %d, %d)\n", idx , test1, test2, test3));
  714. // this if/else takes care of this cases:
  715. // 1. first buffer for a field is not written to
  716. // 2. second buffer for a field is written to ( this can happen when
  717. // both programs were updated at the same time, but the timing was
  718. // such that first did not start executing, but second was );
  719. // so this if/else prevents sending buffers back out of order
  720. if ( Interrupter.GetReady() ) // it is always true before it is ever false
  721. Interrupter.SetReady( false );
  722. else
  723. // make sure that things are correct when the loop is entered later
  724. // the field must be set to 'ready'
  725. Interrupter.SetReady( true );
  726. }
  727. }
  728. } /* endwhile */
  729. }
  730. /* Method: BtPiscess::ProcessBufferAtInterrupt
  731. * Purpose: Called by a video channel to perform risc program modifications
  732. * if needed
  733. * Input: pTag: PVOID - pointer to some data ( risc program pointer )
  734. * Output: None
  735. */
  736. void BtPisces::ProcessBufferAtInterrupt( PVOID pTag )
  737. {
  738. Trace t("BtPisces::ProcessBufferAtInterrupt()");
  739. int idx = (int)pTag;
  740. RiscPrgHandle Rspnsbl = ActiveProgs_ [idx];
  741. if ( !Rspnsbl ) {
  742. DebugOut((1, "PBAI: no responsible\n"));
  743. return; // can this really happen ??
  744. }
  745. // get conveniently saved field from the program
  746. Field &Interrupter = *(Field *)Rspnsbl->GetTag();
  747. // see if there is a buffer in the queue and get it
  748. DataBuf buf = Interrupter.GetNextBuffer();
  749. DebugOut((1, "Update %d %x\n", idx, buf.pData_ ) );
  750. // if buffer is not available skip the program
  751. if ( !buf.pData_ ) {
  752. DebugOut((1, "Buffer not available, skipping %d\n", idx ) );
  753. Skip( idx );
  754. } else {
  755. if ( Rspnsbl->IsSkipped() )
  756. nSkipped_--;
  757. Engine_.ChangeAddress( Rspnsbl, buf );
  758. LinkThePrograms();
  759. }
  760. }
  761. /* Method: BtPisces::Interrupt
  762. * Purpose: Called by ISR to initiate the processing of an interrupt
  763. * Input: None
  764. * Output: None
  765. */
  766. State BtPisces::Interrupt()
  767. {
  768. Trace t("BtPisces::Interrupt()");
  769. DebugOut((2, "BtPisces::Interrupt()\n"));
  770. extern BYTE *gpjBaseAddr;
  771. DWORD IntrStatus = *(DWORD*)(gpjBaseAddr+0x100);
  772. State DidWe = Off;
  773. if ( IntrStatus & RISC_I ) {
  774. DebugOut((2, "RISC_I\n"));
  775. ProcessRISCIntr();
  776. *(DWORD*)(gpjBaseAddr+0x100) = RISC_I; // reset the status bit
  777. DidWe = On;
  778. }
  779. if ( IntrStatus & FBUS_I ) {
  780. DebugOut((2, "FBUS\n"));
  781. *(DWORD*)(gpjBaseAddr+0x100) = FBUS_I; // reset the status bit
  782. DidWe = On;
  783. }
  784. if ( IntrStatus & FTRGT_I ) {
  785. DebugOut((2, "FTRGT\n"));
  786. *(DWORD*)(gpjBaseAddr+0x100) = FTRGT_I; // reset the status bit
  787. DidWe = On; //[TMZ]
  788. }
  789. if ( IntrStatus & FDSR_I ) {
  790. DebugOut((2, "FDSR\n"));
  791. *(DWORD*)(gpjBaseAddr+0x100) = FDSR_I; // reset the status bit
  792. DidWe = On; //[TMZ]
  793. }
  794. if ( IntrStatus & PPERR_I ) {
  795. DebugOut((2, "PPERR\n"));
  796. *(DWORD*)(gpjBaseAddr+0x100) = PPERR_I; // reset the status bit
  797. DidWe = On; //[TMZ]
  798. }
  799. if ( IntrStatus & RIPERR_I ) {
  800. DebugOut((2, "RIPERR\n"));
  801. *(DWORD*)(gpjBaseAddr+0x100) = RIPERR_I; // reset the status bit
  802. Restart();
  803. DidWe = On;
  804. }
  805. if ( IntrStatus & PABORT_I ) {
  806. DebugOut((2, "PABORT\n"));
  807. *(DWORD*)(gpjBaseAddr+0x100) = PABORT_I; // reset the status bit
  808. DidWe = On;
  809. }
  810. if ( IntrStatus & OCERR_I ) {
  811. DebugOut((2, "OCERR\n"));
  812. DidWe = On;
  813. DebugOut((0, "Stopping RiscEngine due to OCERR\n")); // [!!!] [TMZ] why not restart?
  814. Engine_.Stop();
  815. *(DWORD*)(gpjBaseAddr+0x100) = OCERR_I; // reset the status bit
  816. }
  817. if ( IntrStatus & SCERR_I ) {
  818. DebugOut((0, "SCERR\n"));
  819. DidWe = On;
  820. *(DWORD*)(gpjBaseAddr+0x100) = SCERR_I; // reset the status bit
  821. Restart(); // [TMZ] [!!!] this royally screws us over sometimes, figure it out.
  822. *(DWORD*)(gpjBaseAddr+0x100) = SCERR_I; // reset the status bit
  823. }
  824. return DidWe;
  825. }
  826. // resource allocation group
  827. /* Method: BtPisces::AllocateStream
  828. * Purpose: This function allocates a stream for use by a video channel
  829. * Input: StrInf: StreamInfo & - reference to the stream information structure
  830. * Output:
  831. */
  832. ErrorCode BtPisces::AllocateStream( Field *&ToAllocate, VideoStream st )
  833. {
  834. Trace t("BtPisces::AllocateStream()");
  835. switch ( st ) {
  836. case VS_Field1:
  837. ToAllocate = &Odd_;
  838. break;
  839. case VS_Field2:
  840. ToAllocate = &Even_;
  841. break;
  842. case VS_VBI1:
  843. ToAllocate = &VBIO_;
  844. break;
  845. case VS_VBI2:
  846. ToAllocate = &VBIE_;
  847. break;
  848. }
  849. return Success;
  850. }
  851. /* Method: BtPisces::SetBrightness
  852. * Purpose: Changes brightness of the captured image
  853. * Input:
  854. * Output:
  855. */
  856. void BtPisces::SetBrightness( DWORD value )
  857. {
  858. Trace t("BtPisces::SetBrightness()");
  859. PsDecoder_.SetBrightness( value );
  860. }
  861. /* Method: BtPisces::SetSaturation
  862. * Purpose:
  863. * Input:
  864. * Output:
  865. */
  866. void BtPisces::SetSaturation( DWORD value )
  867. {
  868. Trace t("BtPisces::SetSaturation()");
  869. PsDecoder_.SetSaturation( value );
  870. }
  871. /* Method: BtPisces::SetConnector
  872. * Purpose:
  873. * Input:
  874. * Output:
  875. */
  876. void BtPisces::SetConnector( DWORD value )
  877. {
  878. Trace t("BtPisces::SetConnector()");
  879. PsDecoder_.SetVideoInput( Connector( value ) );
  880. }
  881. /* Method: BtPisces::SetContrast
  882. * Purpose:
  883. * Input:
  884. * Output:
  885. */
  886. void BtPisces::SetContrast( DWORD value )
  887. {
  888. Trace t("BtPisces::SetContrast()");
  889. PsDecoder_.SetContrast( value );
  890. }
  891. /* Method: BtPisces::SetHue
  892. * Purpose:
  893. * Input:
  894. * Output:
  895. */
  896. void BtPisces::SetHue( DWORD value )
  897. {
  898. Trace t("BtPisces::SetHue()");
  899. PsDecoder_.SetHue( value );
  900. }
  901. /* Method: BtPisces::SetSVideo
  902. * Purpose:
  903. * Input:
  904. * Output:
  905. */
  906. void BtPisces::SetSVideo( DWORD )
  907. {
  908. Trace t("BtPisces::SetSVideo()");
  909. }
  910. /* Method: BtPisces::
  911. * Purpose:
  912. * Input: value: DWORD
  913. * Output:
  914. */
  915. void BtPisces::SetFormat( DWORD value )
  916. {
  917. Trace t("BtPisces::SetFormat()");
  918. PsDecoder_.SetVideoFormat( VideoFormat( value ) );
  919. // let the scaler know format has changed
  920. Even_.VideoFormatChanged( VideoFormat( value ) );
  921. Odd_.VideoFormatChanged( VideoFormat( value ) );
  922. }
  923. /* Method: BtPisces::GetSaturation
  924. * Purpose:
  925. * Input: pData: PLONG
  926. * Output:
  927. */
  928. LONG BtPisces::GetSaturation()
  929. {
  930. Trace t("BtPisces::GetSaturation()");
  931. return PsDecoder_.GetSaturation();
  932. }
  933. /* Method: BtPisces::GetHue
  934. * Purpose:
  935. * Input: pData: PLONG
  936. * Output:
  937. */
  938. LONG BtPisces::GetHue()
  939. {
  940. Trace t("BtPisces::GetHue()");
  941. return PsDecoder_.GetHue();
  942. }
  943. /* Method: BtPisces::GetBrightness
  944. * Purpose:
  945. * Input: pData: PLONG
  946. * Output:
  947. */
  948. LONG BtPisces::GetBrightness()
  949. {
  950. Trace t("BtPisces::GetBrightness()");
  951. return PsDecoder_.GetBrightness();
  952. }
  953. /* Method: BtPisces::GetSVideo
  954. * Purpose:
  955. * Input: pData: PLONG
  956. * Output:
  957. */
  958. LONG BtPisces::GetSVideo()
  959. {
  960. Trace t("BtPisces::GetSVideo()");
  961. return 0;
  962. }
  963. /* Method: BtPisces::GetContrast
  964. * Purpose:
  965. * Input: pData: PLONG
  966. * Output:
  967. */
  968. LONG BtPisces::GetContrast()
  969. {
  970. Trace t("BtPisces::GetContrast()");
  971. return PsDecoder_.GetContrast();
  972. }
  973. /* Method: BtPisces::GetFormat
  974. * Purpose:
  975. * Input: pData: PLONG
  976. * Output:
  977. */
  978. LONG BtPisces::GetFormat()
  979. {
  980. Trace t("BtPisces::GetFormat()");
  981. return PsDecoder_.GetVideoFormat();
  982. }
  983. /* Method: BtPisces::GetConnector
  984. * Purpose:
  985. * Input: pData: PLONG
  986. * Output:
  987. */
  988. LONG BtPisces::GetConnector()
  989. {
  990. Trace t("BtPisces::GetConnector()");
  991. return PsDecoder_.GetVideoInput();
  992. }
  993. // scaler group
  994. /* Method: BtPisces::SetAnalogWindow
  995. * Purpose:
  996. * Input:
  997. * Output:
  998. */
  999. ErrorCode BtPisces::SetAnalogWindow( MRect &r, Field &aField )
  1000. {
  1001. Trace t("BtPisces::SetAnalogWindow()");
  1002. return aField.SetAnalogWindow( r );
  1003. }
  1004. /* Method: BtPisces::SetDigitalWindow
  1005. * Purpose:
  1006. * Input:
  1007. * Output:
  1008. */
  1009. ErrorCode BtPisces::SetDigitalWindow( MRect &r, Field &aField )
  1010. {
  1011. Trace t("BtPisces::SetDigitalWindow()");
  1012. return aField.SetDigitalWindow( r );
  1013. }
  1014. // color space converter group
  1015. /* Method: BtPisces::SetPixelFormat
  1016. * Purpose:
  1017. * Input:
  1018. * Output:
  1019. */
  1020. void BtPisces::SetPixelFormat( ColFmt aFormat, Field &aField )
  1021. {
  1022. Trace t("BtPisces::SetPixelFormat()");
  1023. aField.SetColorFormat( aFormat );
  1024. }
  1025. /* Method: BtPisces::GetPixelFormat
  1026. * Purpose:
  1027. * Input:
  1028. * Output:
  1029. */
  1030. ColFmt BtPisces::GetPixelFormat( Field &aField )
  1031. {
  1032. Trace t("BtPisces::GetPixelFormat()");
  1033. return aField.GetColorFormat();
  1034. }
  1035. void BtPisces::TurnVFilter( State s )
  1036. {
  1037. Trace t("BtPisces::TurnVFilter()");
  1038. Even_.TurnVFilter( s );
  1039. Odd_.TurnVFilter( s );
  1040. }
  1041. /* Method:
  1042. * Purpose: returns video standards supported by the board
  1043. */
  1044. LONG BtPisces::GetSupportedStandards()
  1045. {
  1046. Trace t("BtPisces::GetSupportedStandards()");
  1047. return PsDecoder_.GetSupportedStandards();
  1048. }
  1049. void BtPisces::DumpRiscPrograms()
  1050. {
  1051. LONG x;
  1052. // Dump the links
  1053. DebugOut((0, "------------------------------------------------\n"));
  1054. for( x = 0; x < 12; x++ )
  1055. {
  1056. if ( CreatedProgs_[x] )
  1057. {
  1058. DebugOut((0, "Created #%02d addr(%x) paddr(%x) jaddr(%x)\n", x, CreatedProgs_[x], CreatedProgs_[x]->GetPhysProgAddr( ), *(CreatedProgs_[x]->pChainAddress_ + 1)));
  1059. }
  1060. }
  1061. for( x = 0; x < 8; x++ )
  1062. {
  1063. if ( Skippers_[x] )
  1064. {
  1065. DebugOut((0, "Skipper #%02d addr(%x) paddr(%x) jaddr(%x)\n", x, Skippers_[x], Skippers_[x]->GetPhysProgAddr( ), *(Skippers_[x]->pChainAddress_ + 1)));
  1066. }
  1067. }
  1068. DebugOut((0, "------------------------------------------------\n"));
  1069. return ;
  1070. /////////////////////////////////////////////////
  1071. for( x = 0; x < 12; x++ ) {
  1072. DebugOut((0, "Active Program # %d(%x) buf(%x)\n", x, ActiveProgs_[x], ActiveProgs_[x]?ActiveProgs_[x]->GetPhysProgAddr( ):-1));
  1073. }
  1074. for( x = 0; x < 12; x++ ) {
  1075. DebugOut((0, "Created Program # %d(%x) buf(%x)\n", x, CreatedProgs_[x], CreatedProgs_[x]?CreatedProgs_[x]->GetPhysProgAddr( ):-1));
  1076. }
  1077. for( x = 0; x < 8; x++ ) {
  1078. DebugOut((0, "Skipper Program # %d(%x) buf(%x)\n", x, Skippers_[x], Skippers_[x]?Skippers_[x]->GetPhysProgAddr( ):-1));
  1079. }
  1080. DebugOut((2, "---------------------------------\n"));
  1081. DebugOut((2, "Dumping ActiveProgs_\n"));
  1082. DebugOut((2, "---------------------------------\n"));
  1083. for( x = 0; x < 12; x++ ) {
  1084. DebugOut((1, "Active Program # %d\n", x));
  1085. ActiveProgs_[x]->Dump();
  1086. }
  1087. DebugOut((2, "---------------------------------\n"));
  1088. DebugOut((2, "Dumping CreatedProgs_\n"));
  1089. DebugOut((2, "---------------------------------\n"));
  1090. for( x = 0; x < 12; x++ ) {
  1091. DebugOut((1, "Created Program # %d\n", x));
  1092. CreatedProgs_[x]->Dump();
  1093. }
  1094. DebugOut((2, "---------------------------------\n"));
  1095. DebugOut((2, "Dumping Skippers_\n"));
  1096. DebugOut((2, "---------------------------------\n"));
  1097. for( x = 0; x < 8; x++ ) {
  1098. DebugOut((1, "Skipper Program # %d\n", x));
  1099. Skippers_[x]->Dump();
  1100. }
  1101. }