SCMGR.C
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:25k
源码类别:

DVD

开发平台:

Others

  1. /****************************************************************************************
  2.  *  Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
  3.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  4.  *
  5.  *  File: $Workfile: SCMGR.C $             
  6.  *
  7.  * Description: 
  8.  * ============
  9.  * 
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision: 7 $
  14.  * Last Modified by $Author: Leonh $ at $Modtime: 11/19/03 12:58p $ 
  15.  ****************************************************************************************
  16.  * Updates:
  17.  ****************************************************************************************
  18.  * $Log: /I76/I76_Common/I76_Reference/Playcore/ScPad/SCMGR.C $
  19.  * 
  20.  * 7     11/20/03 1:54p Leonh
  21.  * remove the useless code
  22.  * 
  23.  * 6     11/15/03 7:11p Leslie
  24.  * Replace old  Video API Low Level Files with new ones
  25.  * 
  26.  * 5     11/06/03 15:17 Eyalr
  27.  * 
  28.  * 4     10/23/03 11:41a Leslie
  29.  * add the function for read RAW data from SDRAM 
  30.  * 
  31.  * 3     03-07-09 10:23 Leonh
  32.  * cache enable
  33.  * 
  34.  * 9     23/05/02 14:09 Ettim
  35.  * Adding support for an absolute 32 bit address on the scratch pad.
  36.  * 
  37.  * 8     23/04/02 9:36 Nirm
  38.  * - Added dependency in "Config.h".
  39.  * 
  40.  * 7     4/03/02 18:11 Nirm
  41.  * Code cleanup.
  42.  * 
  43.  * 6     3/03/02 15:01 Nirm
  44.  * - Code cleanup;
  45.  * - Enhanced efficiency.
  46.  * 
  47.  * 5     30/01/02 20:26 Nirm
  48.  * Replaced min() with MIN().
  49.  * 
  50.  * 4     16/01/02 15:55 Atai
  51.  * Change debug printing
  52.  * 
  53.  * 3     9/01/02 16:53 Nirm
  54.  * Corrected Include-Paths.
  55.  * 
  56.  * 2     30/12/01 13:16 Atai
  57.  * correct varaible initial assignment
  58.  ****************************************************************************************/
  59. #include "Config.h" // Global Configuration - do not remove!
  60. #ifdef _DEBUG
  61. #undef IFTRACE
  62. #define IFTRACE if (gTraceScPad)
  63. #include "DebugDbgMain.h"
  64. #endif //_DEBUG
  65. #include "Includemath-macro.h"
  66. #include "KerneluITRONRTOS.h"
  67. #include "PlaycoreAuxCacheAuxCache.h"
  68. #include "PlaycoreScPadSCMGR.h"
  69. #include "PlaycoreScPadScLLMgr.h"
  70. #include "Decoderlow_levelDEC_LL_Reg.h"
  71. /////////////////////////////////////////////////////////////////////////////
  72. // Constants and Enumerations
  73. // (2^SC_CLUSTER_EXP = Cluster Size in Bytes) for the SC Dynamic Memory 
  74. #define SC_CLUSTER_EXP 6
  75. #define SC_BYTES_PER_CLUSTER (0x1 << SC_CLUSTER_EXP) // = 64 Bytes = 16 DWORDS
  76. #define SC_DWORDS_PER_CLUSTER (SC_BYTES_PER_CLUSTER / sizeof(DWORD))
  77. // Size (in DWORDs) of the SC Dynamic Memory
  78. #define SC_DYNAMIC_SZ (WORD)(wSC_CLUSTERS_CNT * SC_DWORDS_PER_CLUSTER)
  79. // Define the Dynamic Memory Allocation Base
  80. #ifdef DVD_VR_SUPPORT
  81. #define SC_BASEDYN_ADDR (WORD)0 //the position of dynamic memory is in the front of the scratch-pad
  82. #else
  83. #define SC_BASEDYN_ADDR (WORD)(wSC_SDRAM_SZ - SC_DYNAMIC_SZ)
  84. #endif
  85. /////////////////////////////////////////////////////////////////////////////
  86. // Macros
  87. /////////////////////////////////////////////////////////////////////////////
  88. // Globals and Singletons
  89. static CONST BYTE g_aAllocBitMap[8]= { 0x80, 0xC0, 0xE0, 0xF0, 
  90.    0xF8, 0xFC, 0xFE, 0xFF };
  91. /////////////////////////////////////////////////////////////////////////////
  92. // Implementation of Public Services
  93. /////////////////////////////////////////////////////////////////////////////
  94. // sc_Init()
  95. //
  96. // Description: Initializes the Scratch-Pad and fills its contents with
  97. // some desired value.
  98. //
  99. // Input: i_wInitVal - The desired value to fill the memory with.
  100. // Output: None
  101. // In/Out: None
  102. // Return: TRUE if the Scratch-Pad was successfully initialized;
  103. // FALSE otherwise.
  104. //
  105. // Remarks:
  106. BOOL sc_Init(WORD i_wInitVal)
  107. {
  108. BYTE bArrayElementTemp;
  109. int  i;
  110. BOOL bSuccess;
  111. // Clear the Memory-Clusters Registry, and set the last Entry to 0xFF,
  112. // to increase efficiency during allocations.
  113. // memset(g_aMemClustersRegistry, 0, (bSizeof_MemClustersRegistry-1));
  114. // memset(g_aMemClustersRegistry, 0, (bSizeof_MemClustersRegistry-1));
  115. bArrayElementTemp = 0x00;
  116. for(i=0; i<bSizeof_MemClustersRegistry-1; i++)
  117.    {
  118.   sc_SetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)i,
  119. (WORD)1, (BYTE *)&bArrayElementTemp);
  120.    }
  121. bSuccess = sc_ll_Init(i_wInitVal);
  122. // g_aMemClustersRegistry[bSizeof_MemClustersRegistry-1]= 0xFF;
  123. bArrayElementTemp = 0xFF;
  124. sc_SetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)(bSizeof_MemClustersRegistry-1),
  125. (WORD)1, (BYTE *)&bArrayElementTemp);
  126. return bSuccess;
  127. }
  128. /////////////////////////////////////////////////////////////////////////////
  129. // sc_Read()
  130. //
  131. // Description: Reads a sequence of successive Containers from the Scratch-
  132. // Pad.
  133. //
  134. // Input: i_hAddress - The Source-Address to read from;
  135. // i_uContainersCnt - The number of Containers to read.
  136. // Output: o_pDestBuff - Points to a buffer of Containers, which will
  137. //   receive the data read.
  138. // In/Out: None
  139. // Return: Number of successfully read Containers.
  140. //
  141. // Remarks:
  142. WORD sc_Read(WORD i_hAddress, WORD i_uContainersCnt, Sc_cont *o_pDestBuff)
  143. {
  144. return sc_ll_Read(i_hAddress, i_uContainersCnt, &o_pDestBuff->dwDWORD);
  145. }
  146. WORD sc_Read32(UINT32 i_hAddress, WORD i_uContainersCnt, Sc_cont *o_pDestBuff)
  147. {
  148. return sc_ll_Read32(i_hAddress, i_uContainersCnt, &o_pDestBuff->dwDWORD);
  149. }
  150. /////////////////////////////////////////////////////////////////////////////
  151. // sc_Write()
  152. //
  153. // Description: Writes a sequence of successive Containers to the Scratch-
  154. // Pad.
  155. //
  156. // Input: i_hAddress - The Target-Address to write to;
  157. // i_uContainersCnt - The number of Containers to write;
  158. // i_pSourceBuff - Points to a buffer of Containers, which holds
  159. // data to write.
  160. // Output: None
  161. // In/Out: None
  162. // Return: Number of successfully written Containers.
  163. //
  164. // Remarks:
  165. WORD sc_Write(WORD i_hAddress, WORD i_uContainersCnt, 
  166.   const Sc_cont *i_pSourceBuff)
  167. {
  168. return sc_ll_Write(i_hAddress, i_uContainersCnt, 
  169.    (DWORD *)&i_pSourceBuff->dwDWORD);
  170. }
  171. WORD sc_Write32(UINT32 i_hAddress, WORD i_uContainersCnt, 
  172.   const Sc_cont *i_pSourceBuff)
  173. {
  174. return sc_ll_Write32(i_hAddress, i_uContainersCnt, 
  175.    (DWORD *)&i_pSourceBuff->dwDWORD);
  176. }
  177. /////////////////////////////////////////////////////////////////////////////
  178. // sc_Malloc()
  179. //
  180. // Description: Allocates memory from the Dynamic section of the Scratch-Pad.
  181. //
  182. // Input: i_uContainersCnt - Holds the number of Containers to allocate.
  183. // Output: None
  184. // In/Out: None
  185. // Return: The Address of the newly allocated Memory; NULL_HANDLE if the
  186. // request couldn't be satisfied.
  187. //
  188. // Remarks:
  189. // - The minimal allocation is of a single Cluster. If the number of 
  190. //   requested Containers is not an integer multiple of a Cluster, then
  191. //   the request is rounded upwards, towards the closest Cluster boundary.
  192. //   In this case, Memory gets wasted.
  193. // - The allocation is done using the Memory-Clusters Registry, and the
  194. //   search utilizes either the "Best-Fit" or the "First-Fit" algorithm,
  195. //   depending on the corresponding compilation-switch.
  196. #define SC_BESTFIT_ALLOCATION_ALGORITHM
  197. WORD sc_Malloc(UINT16 i_uContainersCnt)
  198. {
  199. STATUS_REG SRkeep;
  200.    BYTE bArrayElementTemp;
  201. UINT8 uRegistryPos, uSlotPos;
  202. UINT16 uFreeClustersCnt;
  203. UINT16 uRequestedClustersCnt= ((i_uContainersCnt + (SC_DWORDS_PER_CLUSTER-1)) / SC_DWORDS_PER_CLUSTER);
  204. struct BestFit_TAG {
  205. UINT8 uRegistryPos;
  206. UINT8 uSlotPos;
  207. UINT16 uClustersCnt;
  208. } BestFit;
  209. // Search for the best-fit allocation
  210. BestFit.uRegistryPos= 0;
  211. BestFit.uSlotPos= 0;
  212. BestFit.uClustersCnt= 0xFFFF;
  213. uFreeClustersCnt= 0;
  214. // Critical-Section Start
  215. SRkeep = InterruptDisable();
  216. // Scan all the Memory-Clusters Registry Bytes
  217. for (uRegistryPos=0; uRegistryPos < bSizeof_MemClustersRegistry; uRegistryPos++) {
  218. UINT8 uSlotMask= 0x80;
  219. // Scan all the Bits (slots) within each Registry Byte
  220. for (uSlotPos=0; uSlotPos < 8; uSlotPos++) {
  221. // Check if the current Slot is Allocated or Free
  222. sc_GetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)uRegistryPos, (WORD)1, (BYTE *)&bArrayElementTemp);
  223. // if (0 == (g_aMemClustersRegistry[uRegistryPos] & uSlotMask)) {
  224.         if (0 == (bArrayElementTemp & uSlotMask)) {
  225. // Free Cluster
  226. uFreeClustersCnt++;
  227. }
  228. else {
  229. // Allocated Cluster: Check if the amount of Free clusters found so far 
  230. // satisfies the request.
  231. // If it does, and if the amount is samller than the Best-Fit, make it the new
  232. // Best-Fit.
  233. if ((uFreeClustersCnt >= uRequestedClustersCnt) &&
  234. (uFreeClustersCnt < BestFit.uClustersCnt))
  235. {
  236. UINT16 uChunkStart= (((uRegistryPos * 8) + uSlotPos) - uFreeClustersCnt);
  237. BestFit.uRegistryPos= (uChunkStart / 8);
  238. BestFit.uSlotPos= (uChunkStart % 8);
  239. BestFit.uClustersCnt= uFreeClustersCnt;
  240. #ifndef SC_BESTFIT_ALLOCATION_ALGORITHM
  241. break;
  242. #endif //SC_BESTFIT_ALLOCATION_ALGORITHM
  243. }
  244. // Reset the amount of Free clusters
  245. uFreeClustersCnt= 0;
  246. }
  247. // Move to the next Slot
  248. uSlotMask >>= 1;
  249. }
  250. }
  251. // Now, check if anything was found
  252. if (0xFFFF != BestFit.uClustersCnt) {
  253. BYTE ucAllocMask;
  254. // Allocate the free Clusters
  255. uRegistryPos= BestFit.uRegistryPos;
  256. uSlotPos= BestFit.uSlotPos;
  257. // Handle an allocation from an aligned slot
  258. while (uRequestedClustersCnt > 0) {
  259. uFreeClustersCnt= MIN(uRequestedClustersCnt, (8 - uSlotPos));
  260. ucAllocMask= (g_aAllocBitMap[uFreeClustersCnt-1] >> uSlotPos);
  261.          
  262. // g_aMemClustersRegistry[uRegistryPos++] |= ucAllocMask;
  263.   sc_GetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)uRegistryPos, (WORD)1, (BYTE *)&bArrayElementTemp);
  264.           bArrayElementTemp |= ucAllocMask;
  265. sc_SetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)uRegistryPos,(WORD)1, (BYTE *)&bArrayElementTemp);
  266. uRegistryPos++;
  267. uRequestedClustersCnt -= uFreeClustersCnt;
  268. uSlotPos= 0;
  269. }
  270. }
  271. // Critical-Section End
  272. set_SR(SRkeep);
  273. // Prepare the return value
  274. if (0xFFFF == BestFit.uClustersCnt) {
  275. dbg_printf(("WARNING: sc_Malloc() Failed [1]: Request cannot be satisfied.n"));
  276. return NULL_HANDLE;
  277. }
  278. return (SC_BASEDYN_ADDR + 
  279. (SC_DWORDS_PER_CLUSTER * ((BestFit.uRegistryPos * 8) + BestFit.uSlotPos)));
  280. }
  281. /////////////////////////////////////////////////////////////////////////////
  282. // sc_Free()
  283. //
  284. // Description: Frees memory that was previously allocated using sc_Malloc().
  285. //
  286. // Input: i_hAddress - The Address of the Memory to free;
  287. // i_uContainersCnt - The number of Containers to free.
  288. // Output: None
  289. // In/Out: None
  290. // Return: TRUE if the memory was freed successfully; FALSE otherwise.
  291. //
  292. // Remarks:
  293. // - The minimal deallocation is of a single Cluster. If the number of 
  294. //   requested Containers is not an integer multiple of a Cluster, then
  295. //   the request is rounded upwards, towards the closest Cluster boundary.
  296. BOOL sc_Free(WORD i_hAddress, UINT16 i_uContainersCnt)
  297. {
  298. BYTE bArrayElementTemp;
  299. STATUS_REG SRkeep;
  300. BYTE  ucFreeMask;
  301. UINT8 uRegistryPos, uSlotPos;
  302. UINT16 uClustersCnt;
  303. UINT16 uFreedClustersCnt= ((i_uContainersCnt + (SC_DWORDS_PER_CLUSTER-1)) / SC_DWORDS_PER_CLUSTER);
  304. // Make sure that there's anything to free
  305. if (0 == uFreedClustersCnt) {
  306. dbg_printf(("WARNING: sc_Free() Failed [1]: Nothing to free.n"));
  307. return FALSE;
  308. }
  309. #ifdef _DEBUG
  310. // Verify validity of the supplied Address
  311. if (i_hAddress < SC_BASEDYN_ADDR) {
  312. tr_printf(("FATAL: sc_Free() Failed [2]: Invalid Dynamic-Memory address.n"));
  313. return FALSE;
  314. }
  315. #endif //_DEBUG
  316. // Compute the Memory-Clusters Registry Entry corresponding to the supplied Address
  317. uClustersCnt= ((i_hAddress - SC_BASEDYN_ADDR) / SC_DWORDS_PER_CLUSTER);
  318. uRegistryPos= (uClustersCnt / 8);
  319. uSlotPos= (uClustersCnt % 8);
  320. #ifdef _DEBUG
  321. // Verify that the Clusters to be freed have not yet been freed
  322. uClustersCnt= uFreedClustersCnt;
  323. while (uClustersCnt > 0) {
  324. UINT8 uCurrClustersCnt= MIN(uClustersCnt, (8 - uSlotPos));
  325. ucFreeMask= (g_aAllocBitMap[uCurrClustersCnt-1] >> uSlotPos);
  326. sc_GetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)(uRegistryPos), (WORD)1, (BYTE *)&bArrayElementTemp);
  327. uRegistryPos++;
  328. // if (ucFreeMask != (g_aMemClustersRegistry[uRegistryPos++] & ucFreeMask)) {
  329.       if (ucFreeMask != (bArrayElementTemp & ucFreeMask)) {
  330. dbg_printf(("WARNING: sc_Free() Failed [3]: Attempting to free an unallocated Cluster.n"));
  331. return FALSE;
  332. }
  333. uSlotPos= 0;
  334. uClustersCnt -= uCurrClustersCnt;
  335. }
  336. // Prepare for the deallocation (recompute Registry Entry)
  337. uClustersCnt= ((i_hAddress - SC_BASEDYN_ADDR) / SC_DWORDS_PER_CLUSTER);
  338. uRegistryPos= (uClustersCnt / 8);
  339. uSlotPos= (uClustersCnt % 8);
  340. #endif //_DEBUG
  341. // Critical-Section Start
  342. SRkeep = InterruptDisable();
  343. // Actually free the Clusters
  344. uClustersCnt= uFreedClustersCnt;
  345. while (uClustersCnt > 0) {
  346. UINT8 uCurrClustersCnt= MIN(uClustersCnt, (8 - uSlotPos));
  347. ucFreeMask= (g_aAllocBitMap[uCurrClustersCnt-1] >> uSlotPos);
  348. // g_aMemClustersRegistry[uRegistryPos++] &= (~ucFreeMask);
  349. sc_GetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)uRegistryPos, (WORD)1, (BYTE *)&bArrayElementTemp);
  350. bArrayElementTemp &= (~ucFreeMask);
  351. sc_SetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)(uRegistryPos), (WORD)1, (BYTE *)&bArrayElementTemp);
  352. uRegistryPos++;
  353. uSlotPos= 0;
  354. uClustersCnt -= uCurrClustersCnt;
  355. }
  356. // Critical-Section End
  357. set_SR(SRkeep);
  358. return TRUE;
  359. }
  360. /////////////////////////////////////////////////////////////////////////////
  361. // sc_CopyFromDisc()
  362. //
  363. // Description: Copies data from the disc directly into the Scratch-Pad
  364. // memory.
  365. //
  366. // Input: i_dwStartLBN - Holds the Start-LBN of the data to copy;
  367. // i_dwOffset - Holds the offset, in Bytes, from the Start-LBN;
  368. // i_uBytesCnt - Gives the total number of Bytes to copy;
  369. // i_hSourceAddress - Holds the Destination-Address in the
  370. //    Scratch-Pad.
  371. // Output: None
  372. // In/Out: None
  373. // Return: TRUE if the data was successfully copied; FALSE otherwise.
  374. //
  375. // Remarks:
  376. #define CONTAINERS_PER_TRANSFER 4
  377. BOOL sc_CopyFromDisc(DWORD i_dwStartLBN, DWORD i_dwOffset, WORD i_uBytesCnt, 
  378.  WORD i_hDestinationAddress)
  379. {
  380. BYTE aBuffer[CONTAINERS_PER_TRANSFER * BYTE_PER_CONTAINER];
  381. UINT8 cbCurrTransferSize;
  382. while (i_uBytesCnt > 0) {
  383. // Compute the size of the current Transfer
  384. cbCurrTransferSize= (UINT8)MIN(i_uBytesCnt, sizeof(aBuffer));
  385. // Read the data
  386. if (! AuxCache_GetBytes(i_dwStartLBN, i_dwOffset, cbCurrTransferSize, aBuffer)) {
  387. tr_printf(("FATAL: sc_CopyFromDisc() Failed [1]n"));
  388. return FALSE;
  389. }
  390. // Copy the data to the Scratch-Pad
  391. if (0 == CONTAINER_MOD(cbCurrTransferSize)) {
  392. // The Transfer is of an integer number of Containers
  393. sc_Write(i_hDestinationAddress, CONTAINER_COUNT(cbCurrTransferSize), 
  394.  (const Sc_cont *)aBuffer);
  395. }
  396. else {
  397.   // The Transfer is not of an integer number of Containers
  398. sc_SetBytes(i_hDestinationAddress, 0, cbCurrTransferSize, aBuffer);
  399. }
  400. // Prepare for the next Transfer
  401. i_dwOffset += (DWORD)cbCurrTransferSize;
  402. i_hDestinationAddress += CONTAINERS_PER_TRANSFER;
  403. i_uBytesCnt -= cbCurrTransferSize;
  404. }
  405. return TRUE;
  406. }
  407. BOOL sc_CopyFromDisc32(DWORD i_dwStartLBN, DWORD i_dwOffset, WORD i_uBytesCnt, 
  408.  DWORD i_hDestinationAddress)
  409. {
  410. BYTE aBuffer[CONTAINERS_PER_TRANSFER * BYTE_PER_CONTAINER];
  411. UINT8 cbCurrTransferSize;
  412. while (i_uBytesCnt > 0) {
  413. // Compute the size of the current Transfer
  414. cbCurrTransferSize= (UINT8)MIN(i_uBytesCnt, sizeof(aBuffer));
  415. // Read the data
  416. if (! AuxCache_GetBytes(i_dwStartLBN, i_dwOffset, cbCurrTransferSize, aBuffer)) {
  417. tr_printf(("FATAL: sc_CopyFromDisc() Failed [1]n"));
  418. return FALSE;
  419. }
  420. // Copy the data to the Scratch-Pad
  421. if (0 == CONTAINER_MOD(cbCurrTransferSize)) {
  422. // The Transfer is of an integer number of Containers
  423. sc_Write32(i_hDestinationAddress, CONTAINER_COUNT(cbCurrTransferSize), 
  424.  (const Sc_cont *)aBuffer);
  425. }
  426. else {
  427.   // The Transfer is not of an integer number of Containers
  428. sc_SetBytes32(i_hDestinationAddress, 0, cbCurrTransferSize, aBuffer);
  429. }
  430. // Prepare for the next Transfer
  431. i_dwOffset += (DWORD)cbCurrTransferSize;
  432. i_hDestinationAddress += CONTAINERS_PER_TRANSFER;
  433. i_uBytesCnt -= cbCurrTransferSize;
  434. }
  435. return TRUE;
  436. }
  437. /////////////////////////////////////////////////////////////////////////////
  438. // sc_GetBytes()
  439. //
  440. // Description: Retrieves Bytes from the Scratch-Pad memory.
  441. //
  442. // Input: i_hSourceAddress - The Source Address from which to retrieve
  443. //    the Bytes;
  444. // i_cbOffset - An offset, in Bytes, from the given Address;
  445. // i_cbSize - The amount of Bytes to get.
  446. //
  447. // Output: o_pDestBuff - Points to a buffer, which will receive the
  448. //   requested Bytes.
  449. // In/Out: None
  450. // Return: None
  451. //
  452. // Remarks:
  453. void sc_GetBytes(WORD i_hSourceAddress, WORD i_cbOffset, WORD i_cbSize, BYTE *o_pDestBuff)
  454. {
  455. UINT8 cbInitialOffset;
  456. UINT16 uTransferSize;
  457. UINT16 uDestPos= 0;
  458. // Adjust the Source-Address
  459. i_hSourceAddress += CONTAINER_NORM(i_cbOffset);
  460. cbInitialOffset= CONTAINER_MOD(i_cbOffset);
  461. // If there is an initial Byte offset, first collect these Bytes
  462. if (0 != cbInitialOffset) {
  463. Sc_cont scFirstCont;
  464. // Read the first Container
  465. sc_Read(i_hSourceAddress++, 1, &scFirstCont);
  466. // Copy only the relevant Bytes
  467. uTransferSize= MIN(i_cbSize, (BYTE_PER_CONTAINER - cbInitialOffset));
  468. memcpy(&o_pDestBuff[0], &scFirstCont.ucBYTE[cbInitialOffset], uTransferSize);
  469. // Update the number of Bytes read, and the position in the Destination Buffer
  470. i_cbSize -= uTransferSize;
  471. uDestPos= uTransferSize;
  472. }
  473. // Now read as many Containers as possible, in an aligned manner
  474. uTransferSize= CONTAINER_NORM(i_cbSize);
  475. if (uTransferSize > 0) {
  476. sc_Read(i_hSourceAddress, uTransferSize, (Sc_cont *)&o_pDestBuff[uDestPos]);
  477. // Update the Source-Address
  478. i_hSourceAddress += uTransferSize;
  479. // Update the number of Bytes read, and the position in the Destination Buffer
  480. i_cbSize -= (uTransferSize * BYTE_PER_CONTAINER);
  481. uDestPos += (uTransferSize * BYTE_PER_CONTAINER);
  482. }
  483. // Read any remaining Bytes
  484. if (i_cbSize > 0) {
  485. Sc_cont scLastCont;
  486. // Read the last Container
  487. sc_Read(i_hSourceAddress, 1, &scLastCont);
  488. // Copy only the relevant Bytes
  489. memcpy(&o_pDestBuff[uDestPos], &scLastCont.ucBYTE[0], i_cbSize);
  490. }
  491. return;
  492. }
  493. void sc_GetBytes32(UINT32 i_hSourceAddress, WORD i_cbOffset, WORD i_cbSize, BYTE *o_pDestBuff)
  494. {
  495. UINT8 cbInitialOffset;
  496. UINT16 uTransferSize;
  497. UINT16 uDestPos= 0;
  498. // Adjust the Source-Address
  499. i_hSourceAddress += CONTAINER_NORM(i_cbOffset);
  500. cbInitialOffset= CONTAINER_MOD(i_cbOffset);
  501. // If there is an initial Byte offset, first collect these Bytes
  502. if (0 != cbInitialOffset) {
  503. Sc_cont scFirstCont;
  504. // Read the first Container
  505. sc_Read32(i_hSourceAddress++, 1, &scFirstCont);
  506. // Copy only the relevant Bytes
  507. uTransferSize= MIN(i_cbSize, (BYTE_PER_CONTAINER - cbInitialOffset));
  508. memcpy(&o_pDestBuff[0], &scFirstCont.ucBYTE[cbInitialOffset], uTransferSize);
  509. // Update the number of Bytes read, and the position in the Destination Buffer
  510. i_cbSize -= uTransferSize;
  511. uDestPos= uTransferSize;
  512. }
  513. // Now read as many Containers as possible, in an aligned manner
  514. uTransferSize= CONTAINER_NORM(i_cbSize);
  515. if (uTransferSize > 0) {
  516. sc_Read32(i_hSourceAddress, uTransferSize, (Sc_cont *)&o_pDestBuff[uDestPos]);
  517. // Update the Source-Address
  518. i_hSourceAddress += (UINT32)uTransferSize;
  519. // Update the number of Bytes read, and the position in the Destination Buffer
  520. i_cbSize -= (uTransferSize * BYTE_PER_CONTAINER);
  521. uDestPos += (uTransferSize * BYTE_PER_CONTAINER);
  522. }
  523. // Read any remaining Bytes
  524. if (i_cbSize > 0) {
  525. Sc_cont scLastCont;
  526. // Read the last Container
  527. sc_Read32(i_hSourceAddress, 1, &scLastCont);
  528. // Copy only the relevant Bytes
  529. memcpy(&o_pDestBuff[uDestPos], &scLastCont.ucBYTE[0], i_cbSize);
  530. }
  531. return;
  532. }
  533. /////////////////////////////////////////////////////////////////////////////
  534. // sc_SetBytes()
  535. //
  536. // Description: Writes Bytes to the Scratch-Pad memory.
  537. //
  538. // Input: i_hDestinationAddress - The Destination Address of the Bytes
  539. // to set;
  540. // i_cbOffset - An offset, in Bytes, from the given Address;
  541. // i_cbSize - The amount of Bytes to set;
  542. // i_pSrcBuff - Points to a Source Buffer from which to copy
  543. //  the data.
  544. // Output: None
  545. // In/Out: None
  546. // Return: None
  547. //
  548. // Remarks:
  549. void sc_SetBytes(WORD i_hDestinationAddress, WORD i_cbOffset, WORD i_cbSize, 
  550.  const BYTE *i_pSrcBuff)
  551. {
  552. UINT8 cbInitialOffset;
  553. UINT16 uTransferSize;
  554. UINT16 uSrcPos= 0;
  555. // Adjust the Destination-Address
  556. i_hDestinationAddress += CONTAINER_NORM(i_cbOffset);
  557. cbInitialOffset= CONTAINER_MOD(i_cbOffset);
  558. // If there is an initial Byte offset, first set these Bytes
  559. if (0 != cbInitialOffset) {
  560. Sc_cont scFirstCont;
  561. // Read the first Container
  562. sc_Read(i_hDestinationAddress, 1, &scFirstCont);
  563. // Copy only the relevant Bytes
  564. uTransferSize= MIN(i_cbSize, (BYTE_PER_CONTAINER - cbInitialOffset));
  565. memcpy(&scFirstCont.ucBYTE[cbInitialOffset], &i_pSrcBuff[0], uTransferSize);
  566. // Write the first Container back
  567. sc_Write(i_hDestinationAddress++, 1, &scFirstCont);
  568. // Update the number of Bytes written, and the position in the Destination Buffer
  569. i_cbSize -= uTransferSize;
  570. uSrcPos= uTransferSize;
  571. }
  572. // Now write as many Containers as possible, in an aligned manner
  573. uTransferSize= CONTAINER_NORM(i_cbSize);
  574. if (uTransferSize > 0) {
  575. sc_Write(i_hDestinationAddress, uTransferSize, (const Sc_cont *)&i_pSrcBuff[uSrcPos]);
  576. // Update the Destination-Address
  577. i_hDestinationAddress += uTransferSize;
  578. // Update the number of Bytes read, and the position in the Source Buffer
  579. i_cbSize -= (uTransferSize * BYTE_PER_CONTAINER);
  580. uSrcPos += (uTransferSize * BYTE_PER_CONTAINER);
  581. }
  582. // Write any remaining Bytes
  583. if (i_cbSize > 0) {
  584. Sc_cont scLastCont;
  585. // Read the last Container
  586. sc_Read(i_hDestinationAddress, 1, &scLastCont);
  587. // Copy only the relevant Bytes
  588. memcpy(&scLastCont.ucBYTE[0], &i_pSrcBuff[uSrcPos], i_cbSize);
  589. // Write the last Container back
  590. sc_Write(i_hDestinationAddress, 1, &scLastCont);
  591. }
  592. return;
  593. }
  594. void sc_SetBytes32(UINT32 i_hDestinationAddress, WORD i_cbOffset, WORD i_cbSize, 
  595.  const BYTE *i_pSrcBuff)
  596. {
  597. UINT8 cbInitialOffset;
  598. UINT16 uTransferSize;
  599. UINT16 uSrcPos= 0;
  600. // Adjust the Destination-Address
  601. i_hDestinationAddress += CONTAINER_NORM(i_cbOffset);
  602. cbInitialOffset= CONTAINER_MOD(i_cbOffset);
  603. // If there is an initial Byte offset, first set these Bytes
  604. if (0 != cbInitialOffset) {
  605. Sc_cont scFirstCont;
  606. // Read the first Container
  607. sc_Read32(i_hDestinationAddress, 1, &scFirstCont);
  608. // Copy only the relevant Bytes
  609. uTransferSize= MIN(i_cbSize, (BYTE_PER_CONTAINER - cbInitialOffset));
  610. memcpy(&scFirstCont.ucBYTE[cbInitialOffset], &i_pSrcBuff[0], uTransferSize);
  611. // Write the first Container back
  612. sc_Write32(i_hDestinationAddress++, 1, &scFirstCont);
  613. // Update the number of Bytes written, and the position in the Destination Buffer
  614. i_cbSize -= uTransferSize;
  615. uSrcPos= uTransferSize;
  616. }
  617. // Now write as many Containers as possible, in an aligned manner
  618. uTransferSize= CONTAINER_NORM(i_cbSize);
  619. if (uTransferSize > 0) {
  620. sc_Write32(i_hDestinationAddress, uTransferSize, (const Sc_cont *)&i_pSrcBuff[uSrcPos]);
  621. // Update the Destination-Address
  622. i_hDestinationAddress += (UINT32)uTransferSize;
  623. // Update the number of Bytes read, and the position in the Source Buffer
  624. i_cbSize -= (uTransferSize * BYTE_PER_CONTAINER);
  625. uSrcPos += (uTransferSize * BYTE_PER_CONTAINER);
  626. }
  627. // Write any remaining Bytes
  628. if (i_cbSize > 0) {
  629. Sc_cont scLastCont;
  630. // Read the last Container
  631. sc_Read32(i_hDestinationAddress, 1, &scLastCont);
  632. // Copy only the relevant Bytes
  633. memcpy(&scLastCont.ucBYTE[0], &i_pSrcBuff[uSrcPos], i_cbSize);
  634. // Write the last Container back
  635. sc_Write32(i_hDestinationAddress, 1, &scLastCont);
  636. }
  637. return;
  638. }
  639. /////////////////////////////////////////////////////////////////////////////
  640. // sc_PrintStatus()
  641. //
  642. // Description: Prints-out the current allocation status
  643. //
  644. // Input: None
  645. // Output: None
  646. // In/Out: None
  647. // Return: None
  648. //
  649. // Remarks:
  650. #ifdef _DEBUG
  651. void sc_PrintStatus(void)
  652. {
  653. UINT8 uRegistryPos, uSlotPos;
  654.    BYTE bArrayElementTemp;
  655. dbg_printf(("Scratch-Pad Allocation-status:n"));
  656. for (uRegistryPos=0; uRegistryPos < (bSizeof_MemClustersRegistry - 1); uRegistryPos++) {
  657. BYTE ucClusterMask= 0x80;
  658. if (0 == (uRegistryPos % 4)) {
  659. dbg_printf(("tClusters [%03d .. %03d] => ", 
  660. (uRegistryPos * 8), ((uRegistryPos+3) * 8) ));
  661. }
  662. for (uSlotPos=0; uSlotPos < 8; uSlotPos++) {
  663. sc_GetBytes(SC_MEMORY_CLUSTERS_REGISTRY_ADDR, (WORD)uRegistryPos, (WORD)1, (BYTE *)&bArrayElementTemp);
  664. // dbg_printf(("%c", ((0 == (g_aMemClustersRegistry[uRegistryPos] & ucClusterMask)) ? 
  665.          dbg_printf(("%c", ((0 == (bArrayElementTemp & ucClusterMask)) ? 
  666. '0' : '1') ));
  667. ucClusterMask >>= 1;
  668. }
  669. dbg_printf(("%c", (3 == (uRegistryPos % 4)) ? 'n' : ' '));
  670. }
  671. return;
  672. }
  673. #endif //_DEBUG