📄 sh4rtc.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*
Copyright(c) Renesas Technology Corp. 1998-2003
Module Name:
sh4rtc.c
Revision History:
26th April 1999 Released
*/
#include <windows.h>
#include <nkintr.h>
#include "shx.h"
#include "platform.h"
#define BCD(X) (((X)%10) | (((X)/10)<<4))
#define DEC(X) (((X)&0xf) + (((X)>>4)*10))
#define BCD2(X) ( (((X)/1000)<<12) | (((X%1000)/100)<<8) | (((X%100)/10)<<4) | ((X)%10) )
#define DEC2(X) (((X)&0xf) + ((((X)&0x00f0)>>4)*10) + ((((X)&0x0f00)>>8)*100) + ((((X)&0xf000)>>12)*1000) )
USHORT AlarmYear;
extern int AlarmISR(void);
/*
@func BOOL | OEMGetRealTime | Get the time from the realtime clock
@rdesc none
@comm OEMGetRealTime is called by the Kernel to get the time from the
real time clock. This function can be called reentrantly, and
thus must protect the hardware from multiple accesses.
*/
BOOL OEMGetRealTime(
LPSYSTEMTIME lpst // @parm pointer to memory to return current time
)
{
// DEBUGMSG(1, (TEXT("+OEMGetRealTime()\r\n")));
WRITE_REGISTER_UCHAR(RTC_RCR1, READ_REGISTER_UCHAR(RTC_RCR1) & (~RTC_RCR1_CIE)); // clear CIE flag
do {
WRITE_REGISTER_UCHAR(RTC_RCR1, READ_REGISTER_UCHAR(RTC_RCR1) & (~RTC_RCR1_CF)); // clear carry flag
lpst->wMilliseconds = 0;
lpst->wSecond = DEC(READ_REGISTER_UCHAR(RTC_RSECCNT));
lpst->wMinute = DEC(READ_REGISTER_UCHAR(RTC_RMINCNT));
lpst->wHour = DEC(READ_REGISTER_UCHAR(RTC_RHRCNT));
lpst->wDayOfWeek = READ_REGISTER_UCHAR(RTC_RWKCNT);
lpst->wDay = DEC(READ_REGISTER_UCHAR(RTC_RDAYCNT));
lpst->wMonth = DEC(READ_REGISTER_UCHAR(RTC_RMONCNT));
lpst->wYear = DEC2(READ_REGISTER_USHORT(RTC_RYRCNT));
} while (READ_REGISTER_UCHAR(RTC_RCR1) & RTC_RCR1_CF); // carry occurred
return TRUE;
}
extern BOOL HookInterrupt(int hwIntNumber, FARPROC pfnHandler);
/*
@func BOOL | OEMSetRealTime | Set the realtime clock
@rdesc none
@comm OEMSetRealTime is called by the Kernel to set the real time clock.
This function can be called reentrantly, and thus must protect the
hardware from multiple accesses.
*/
BOOL OEMSetRealTime(
LPSYSTEMTIME lpst // @parm pointer to new time
)
{
DEBUGMSG(1, (TEXT("+OEMSetRealTime()\r\n")));
WRITE_REGISTER_UCHAR(RTC_RCR2, READ_REGISTER_UCHAR(RTC_RCR2) & (~RTC_RCR2_START)); // stop clock
WRITE_REGISTER_UCHAR(RTC_RCR2, READ_REGISTER_UCHAR(RTC_RCR2) | RTC_RCR2_RESET); // reset clock
WRITE_REGISTER_UCHAR(RTC_RSECCNT, BCD(lpst->wSecond));
WRITE_REGISTER_UCHAR(RTC_RMINCNT, BCD(lpst->wMinute));
WRITE_REGISTER_UCHAR(RTC_RHRCNT, BCD(lpst->wHour));
WRITE_REGISTER_UCHAR(RTC_RWKCNT, (BYTE)lpst->wDayOfWeek);
WRITE_REGISTER_UCHAR(RTC_RDAYCNT, BCD(lpst->wDay));
WRITE_REGISTER_UCHAR(RTC_RMONCNT, BCD(lpst->wMonth));
WRITE_REGISTER_USHORT(RTC_RYRCNT, BCD2(lpst->wYear));
WRITE_REGISTER_UCHAR(RTC_RCR2, READ_REGISTER_UCHAR(RTC_RCR2) | RTC_RCR2_START); // start clock
return TRUE;
}
/*
@func BOOL | OEMSetAlarmTime | Set the realtime alarm
@rdesc none
@comm OEMSetAlarmTime is called by the Kernel to set the real time alarm.
This function can be called reentrantly, and thus must protect the
hardware from multiple accesses.
*/
BOOL OEMSetAlarmTime(
LPSYSTEMTIME lpst // @parm pointer to alarm time
)
{
extern BYTE IntrPrio[];
DEBUGMSG(1, (TEXT("+OEMSetAlarmTime()\r\n")));
WRITE_REGISTER_UCHAR(RTC_RCR1, READ_REGISTER_UCHAR(RTC_RCR1) & ~RTC_RCR1_AIE); // disable interrupt
DEBUGMSG(1, (TEXT("1+OEMSetAlarmTime()\r\n")));
HookInterrupt((0x480-0x200)/0x20, AlarmISR);
IntrPrio[(0x480 - 0x200)/0x20] = 0xf;
DEBUGMSG(1, (TEXT("2+OEMSetAlarmTime()\r\n")));
WRITE_REGISTER_USHORT(INTC_IPRA, READ_REGISTER_USHORT(INTC_IPRA) | INTC_IPRA_RTC_INT); // set RTC to pri 15 interrupt
DEBUGMSG(1, (TEXT("3+OEMSetAlarmTime()\r\n")));
WRITE_REGISTER_UCHAR(RTC_RSECAR, BCD(lpst->wSecond) | RTC_RSECAR_ENB);
WRITE_REGISTER_UCHAR(RTC_RMINAR, BCD(lpst->wMinute) | RTC_RMINAR_ENB);
WRITE_REGISTER_UCHAR(RTC_RHRAR, BCD(lpst->wHour) | RTC_RHRAR_ENB);
WRITE_REGISTER_UCHAR(RTC_RWKAR, 0);
WRITE_REGISTER_UCHAR(RTC_RDAYAR, BCD(lpst->wDay) | RTC_RDAYAR_ENB);
WRITE_REGISTER_UCHAR(RTC_RMONAR, BCD(lpst->wMonth) | RTC_RMONAR_ENB);
DEBUGMSG(1, (TEXT("4+OEMSetAlarmTime()\r\n")));
AlarmYear = BCD2(lpst->wYear);
WRITE_REGISTER_UCHAR(RTC_RCR1, (READ_REGISTER_UCHAR(RTC_RCR1) & ~(RTC_RCR1_AIE | RTC_RCR1_AF)) | RTC_RCR1_AIE); // enable interrupt & clear alarm flag
DEBUGMSG(1, (TEXT("-OEMSetAlarmTime()\r\n")));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -