setrtc.c 1.51 KB

#include <ultra64.h>

#ifndef	_LONGCMD
#include <leo.h>
#else
#include <leosp.h>
#endif

static u32 __yearCheck(u8 yearhi, u8 yearlo);

extern 	s32	__leoActive;

s32 LeoSetRTC(LEOCmd *cmdBlock, LEODiskTime *RTCdata, OSMesgQueue *mq)
{

  /* 
   * Check for existence of Leo Manager 
   */
  if (!__leoActive) {
    return(-1);
  }
  
  /*
   * 年が指定範囲(1996 - 2095)に収まっているかチェック
   */
  if (__yearCheck(RTCdata->yearhi, RTCdata->yearlo))
  {
    osSendMesg(mq, (OSMesg)LEO_ERROR_ILLEGAL_TIMER_VALUE, OS_MESG_BLOCK);
    
    return 0;
  }

  /*
   * Fill up command block
   */
  cmdBlock->header.command	= LEO_COMMAND_SET_TIMER;
  cmdBlock->header.reserve1	= 0;
  cmdBlock->header.control	= 0;
  cmdBlock->header.reserve3	= 0;
  
  bcopy((void *)RTCdata, (void *)&(cmdBlock->data.time), sizeof(LEODiskTime));
  
  if (mq != NULL)
  {
    cmdBlock->header.control 	|= LEO_CONTROL_POST;
    cmdBlock->header.post	= mq;
  }
  
  leoCommand((void *)cmdBlock);
  
  return 0;

} /* LeoSetRTC */


#define BCD2DEC(a)	((a) - ( (a) >> 4 )*6)

/*
 * 年が指定範囲に収まっているかのチェック
 * 入力は両方とも BCD
 * 返り値は OK なら 0, ダメなら 1
 */
static u32 __yearCheck(u8 yearhi, u8 yearlo)
{
  u32		year;

  /* BCD としておかしいか? */
  if ( ((yearlo & 0x0f) > 0x09) || ((yearlo & 0xf0) > 0x90)
      || ((yearhi & 0x0f) > 0x09) || ((yearhi & 0xf0) > 0x90) )
    return 1;

  /* BCD から 10進へ変換 */
  year = BCD2DEC(yearhi) * 100 + BCD2DEC(yearlo);
 
  if ( (year < 1996) || (year > 2095) )
    return 1;
  
  return 0;
  
}