util.c 5.5 KB

#include "ddwriteint.h"


/*
 * extern variables
 */
extern u32              __ddTab[][4292];

/*
 * 指定された領域内に何ブロックとれるかを計算(Long バージョン)
 */
u32 __ddGetnBlksInAreaLong(u32 diskType, s32 startLba, u32 areaSize)
{
  u32 		totalbytes = 0;
  s32 		lba = startLba;
  
  if (areaSize == 0)
    return 0;
  
  while(lba < -12)
  {
    if ( (totalbytes += 192 * 85 + 680) > areaSize )
      return (u32)(lba - startLba);
    lba++;
  }

  while(lba < 0)
  {
    if ( (totalbytes += 19720 + 680) > areaSize )
      return (u32)(lba - startLba);
    lba++;
  }
  
  while(lba < 4292)
  {
    if ( (totalbytes += __ddTab[diskType][lba] + 680) > areaSize )
      return (u32)(lba - startLba);
    lba++;
  }
  
  return (u32)(4292 - startLba);

} /* __ddGetnBlksInAreaLong() */


u32 __ddLba2Byte(u32 type, s32 startLBA, u32 nlbas)
{
  u32 		result = 0;
  s32		endLBA;

  if (nlbas == 0)
    return 0;
  
  endLBA = startLBA + (s32)nlbas;

  while(startLBA < -12)
  {
    result += 192 * 85;
    if (++startLBA >= endLBA)
      return result;
  }

  while(startLBA < 0)
  {
    result += 19720;
    if (++startLBA >= endLBA)
      return result;
  }

  while(1)
  {
    result += __ddTab[type][startLBA];
    if (++startLBA >= endLBA)
      return result;
  }

  return 0;

} /* __ddLba2Byte() */

/*
 * vaddr から nbytes バイトを filldata で埋める関数
 * 32bit ずつ埋めていくことに注意せよ。nbytes は4の倍数が望ましい。
 */
void __ddBfill(void *vaddr, u32 nbytes, u32 filldata)
{
  u32		*ptr,i,j,k;
  u8        *p;
  
  
  ptr = (u32 *)vaddr;
  
  if(( j = nbytes % 4 ) > 0 )
  {
	nbytes -= j;
	k = filldata & 0xFF;
	p = (u8 *)vaddr;
	while(j--) *p++=(u8)k; 
	ptr = (u32 *)p;
  }	

  for(i = 0; i < nbytes/sizeof(u32); i++)
    *ptr++ = filldata;
  
  return;

} /* __ddBfill() */



/*
 * 指定された領域内に何ブロックとれるかを計算
 *
 * +-----------+-.........--+-----------+------------+
 * |   LBA n   | .........  |   LBA m   |  LBA m+1   |
 * +-----------+-.........--+-----------+------------+
 *                               |
 *                              nbytes がここにあるとき
 * 
 * このときは、inNlbas = m-n, outNlbas = m-n+1, oneBlockSize = (LBA m のサイズ)
 * 
 * +-----------+-.........--+-----------+------------+
 * |   LBA n   | .........  |   LBA m   |  LBA m+1   |
 * +-----------+-.........--+-----------+------------+
 *                                      |
 *                                   nbytes がここにあるとき
 * 
 * このときは、inNlbas = outNlbas = m-n+1, oneBlockSize = (LBA m のサイズ)
 * となる。
 * 
 * restBytes は nbytes-inNbytes であらわされる。
 *
 */
u32 __ddGetnBlksInArea(__byteInfo_s *byteInfo,
		       u32 diskType, s32 startLba, u32 nbytes)
{
  u32 totalbytes = 0, totalbytesBefore;
  s32 lba = startLba;
  
  if (nbytes == 0)
  {
    byteInfo->inNlbas = 0;
    byteInfo->inNbytes = 0;
    byteInfo->outNlbas = 0;
    byteInfo->outNbytes = 0;
    byteInfo->restBytes = 0;

    if (startLba < -12)
      byteInfo->oneBlockSize = 192 * 85;
    else if (startLba < 0)
      byteInfo->oneBlockSize = 232 * 85;
    else
      byteInfo->oneBlockSize = __ddTab[diskType][startLba];
    
    return 0;
  }
  
  
  while(lba < -12)
  {
    totalbytesBefore = totalbytes;

    /*
     * 量産用に対応するにはここを変えるべき
     */
    if ( (totalbytes += 192 * 85) >= nbytes )
    {
      byteInfo->outNlbas = (u32)( lba - startLba + 1 );
      byteInfo->outNbytes = totalbytes;
      byteInfo->oneBlockSize = 192 * 85;

      if (totalbytes == nbytes)
      {
	/* ピッタリのときは、in は out と同じになる */
	byteInfo->inNlbas = (u32)( lba - startLba + 1 );
	byteInfo->inNbytes = totalbytes;
      }
      else
      {
	byteInfo->inNlbas = (u32)( lba - startLba );
	byteInfo->inNbytes = totalbytesBefore;
      }
      
      byteInfo->restBytes = nbytes - byteInfo->inNbytes;

      return byteInfo->inNlbas;
      
    }
    
    lba++;
  }

  while(lba < 0)
  {
    totalbytesBefore = totalbytes;

    if ( (totalbytes += 19720) >= nbytes )
    {
      byteInfo->outNlbas = (u32)( lba - startLba + 1 );
      byteInfo->outNbytes = totalbytes;
      byteInfo->oneBlockSize = 232 * 85;

      if (totalbytes == nbytes)
      {
	/* ピッタリのときは、in は out と同じになる */
	byteInfo->inNlbas = (u32)( lba - startLba + 1 );
	byteInfo->inNbytes = totalbytes;
      }
      else
      {
	byteInfo->inNlbas = (u32)( lba - startLba );
	byteInfo->inNbytes = totalbytesBefore;
      }
      
      byteInfo->restBytes = nbytes - byteInfo->inNbytes;

      return byteInfo->inNlbas;
      
    }
    
    lba++;
  }
  
  while(lba < 4292)
  {
    totalbytesBefore = totalbytes;

    if ( (totalbytes += __ddTab[diskType][lba]) >= nbytes )
    {
      byteInfo->outNlbas = (u32)( lba - startLba + 1 );
      byteInfo->outNbytes = totalbytes;
      byteInfo->oneBlockSize = __ddTab[diskType][lba];

      if (totalbytes == nbytes)
      {
	/* ピッタリのときは、in は out と同じになる */
	byteInfo->inNlbas = (u32)( lba - startLba + 1 );
	byteInfo->inNbytes = totalbytes;
      }
      else
      {
	byteInfo->inNlbas = (u32)( lba - startLba );
	byteInfo->inNbytes = totalbytesBefore;
      }
      
      byteInfo->restBytes = nbytes - byteInfo->inNbytes;

      return byteInfo->inNlbas;
      
    }
    
    lba++;
  }
  
  /*
   * LBA 4291 まで全部はいる
   */
  byteInfo->inNlbas = (u32)( 4291 - startLba + 1 );
  byteInfo->outNlbas = (u32)( 4291 - startLba + 1 );

  byteInfo->inNbytes = totalbytes;
  byteInfo->outNbytes = totalbytes;

  byteInfo->restBytes = 0;
  byteInfo->oneBlockSize = __ddTab[diskType][4291];

  return byteInfo->inNlbas;
  
} /* __ddGetnBlksInArea() */