mirror of https://github.com/PCSX2/pcsx2.git
235 lines
5.9 KiB
C
235 lines
5.9 KiB
C
//[module] TIMEMANI
|
|
//[processor] IOP
|
|
//[type] ELF-IRX
|
|
//[name] Timer_Manager
|
|
//[version] 0x101
|
|
//[memory map] 0xBF801100, 0xBF801110, 0xBF801120,
|
|
// 0xBF801450
|
|
// 0xBF801480, 0xBF801490, 0xBF8014A0,
|
|
// 0xBF8014B0, 0xBF8014C0
|
|
//[handlers] -
|
|
//[entry point] timrman_start, timrman_stub
|
|
//[made by] [RO]man (roman_ps2dev@hotmail.com) 13 October 2002
|
|
|
|
#include <tamtypes.h>
|
|
|
|
#include "iopdebug.h"
|
|
#include "kloadcore.h"
|
|
#include "kintrman.h"
|
|
|
|
#include "err.h"
|
|
#include "ktimrman.h"
|
|
|
|
#define CONFIG_1450 (*(volatile int*)0xBF801450)
|
|
|
|
struct TIMRMAN{
|
|
int hwreg;
|
|
char source, size;
|
|
short prescale;
|
|
int allocated;
|
|
} t[6]={
|
|
{RTC2, TC_SYSCLOCK, TIMER_SIZE_16, TIMER_PRESCALE_8, 0},
|
|
{RTC5, TC_SYSCLOCK, TIMER_SIZE_32, TIMER_PRESCALE_256, 0},
|
|
{RTC4, TC_SYSCLOCK, TIMER_SIZE_32, TIMER_PRESCALE_256, 0},
|
|
{RTC3, TC_SYSCLOCK|TC_HLINE, TIMER_SIZE_32, TIMER_PRESCALE_1, 0},
|
|
{RTC0, TC_SYSCLOCK|TC_PIXEL|TC_HOLD, TIMER_SIZE_16, TIMER_PRESCALE_1, 0},
|
|
{RTC1, TC_SYSCLOCK|TC_HLINE|TC_HOLD, TIMER_SIZE_16, TIMER_PRESCALE_1, 0}
|
|
};
|
|
|
|
int _start(int argc, char* argv[]);
|
|
|
|
///////////////////////////////////////////////////////////////////////[03]
|
|
void *GetTimersTable(){
|
|
return t; //address of the array
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[04]
|
|
int AllocHardTimer(int source, int size, int prescale){
|
|
register int i;
|
|
int x;
|
|
|
|
if (QueryIntrContext()) return ERROR_INTR_CONTEXT; //intrman
|
|
|
|
CpuSuspendIntr(&x); //intrman
|
|
|
|
for (i=0; i<6; i++)
|
|
if (!t[i].allocated && (t[i].source & source) &&
|
|
(t[i].size==size) && (t[i].prescale>=prescale)){
|
|
t[i].allocated++; //u8
|
|
CpuResumeIntr(x); //intrman
|
|
return t[i].hwreg>>2;
|
|
}
|
|
|
|
CpuResumeIntr(x); //intrman
|
|
return ERROR_NO_TIMER;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[05]
|
|
int ReferHardTimer(int source, int size, int mode, int modemask){
|
|
register int i;
|
|
int x;
|
|
|
|
if (QueryIntrContext()) return ERROR_INTR_CONTEXT; //intrman
|
|
|
|
CpuSuspendIntr(&x); //intrman
|
|
|
|
for (i=0; i<6; i++)
|
|
if (t[i].allocated && (t[i].source & source) && (t[i].size==size) &&
|
|
(int)(GetTimerStatus(t[i].hwreg>>2) & modemask)==mode){
|
|
t[i].allocated++; //u8
|
|
CpuResumeIntr(x); //intrman
|
|
return t[i].hwreg>>2;
|
|
}
|
|
|
|
CpuResumeIntr(x); //intrman
|
|
return ERROR_NO_TIMER;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[10]
|
|
int GetHardTimerIntrCode(int timid){
|
|
switch(timid<<2){
|
|
case RTC2: return INT_RTC2;
|
|
case RTC0: return INT_RTC0;
|
|
case RTC1: return INT_RTC1;
|
|
|
|
case RTC4: return INT_RTC4;
|
|
case RTC3: return INT_RTC3;
|
|
case RTC5: return INT_RTC5;
|
|
}
|
|
return ERROR_UNK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[06]
|
|
int FreeHardTimer(int timid){
|
|
register int i;
|
|
int x;
|
|
|
|
if (QueryIntrContext()) return ERROR_INTR_CONTEXT; //intrman
|
|
|
|
for (i=0; i<6; i++)
|
|
if (t[i].hwreg==(timid<<2))
|
|
break;
|
|
|
|
if ((i<6) && (t[i].allocated)){
|
|
CpuSuspendIntr(&x); //intrman
|
|
t[i].allocated--;
|
|
CpuResumeIntr(x); //intrman
|
|
return ERROR_OK;
|
|
}
|
|
return ERROR_NO_TIMER;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[07]
|
|
void SetTimerMode(int timid, int mode){
|
|
*(volatile short*)((timid<<2)+4) = mode;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[08]
|
|
unsigned int GetTimerStatus(int timid){
|
|
return *(volatile unsigned short*)((timid<<2)+4);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[09]
|
|
void SetTimerCounter(int timid, unsigned int count){
|
|
if ((timid<<2) < RTC3)
|
|
*(volatile short*)((timid<<2)+0)=count;
|
|
else
|
|
*(volatile int*)((timid<<2)+0)=count;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0A]
|
|
unsigned int GetTimerCounter(int timid){
|
|
if ((timid<<2) < RTC3)
|
|
return *(volatile short*)((timid<<2)+0);
|
|
else
|
|
return *(volatile int*)((timid<<2)+0);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0B]
|
|
void SetTimerCompare(int timid, unsigned int compare){
|
|
if ((timid<<2)+8 < RTC3)
|
|
*(volatile short*)((timid<<2)+8)=compare;
|
|
else
|
|
*(volatile int*)((timid<<2)+8)=compare;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0C]
|
|
unsigned int GetTimerCompare(int timid){
|
|
if ((timid<<2)+8 < RTC3)
|
|
return *(volatile short*)((timid<<2)+8);
|
|
else
|
|
return *(volatile int*)((timid<<2)+8);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0D]
|
|
void SetHoldMode(int holdnum, int mode){
|
|
RTC_HOLDMODE=(RTC_HOLDMODE &
|
|
( ~(0xF << (holdnum*4)))) |
|
|
((mode & 0xF) << (holdnum*4));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0E]
|
|
unsigned long GetHoldMode(int holdnum){
|
|
return (RTC_HOLDMODE >> (holdnum*4)) & 0xF;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[0F]
|
|
unsigned long GetHoldReg(int holdnum){
|
|
return *(volatile unsigned int*)(RTC_HOLDREGS + (holdnum*4));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////[01,02]
|
|
void _retonly(){}
|
|
|
|
//////////////////////////////entrypoint///////////////////////////////
|
|
struct export timrman_stub={
|
|
0x41C00000,
|
|
0,
|
|
VER(1, 1), // 1.1 => 0x101
|
|
0,
|
|
"timrman",
|
|
(func)_start, // entrypoint
|
|
(func)_retonly,
|
|
(func)_retonly,
|
|
(func)GetTimersTable,
|
|
(func)AllocHardTimer,
|
|
(func)ReferHardTimer,
|
|
(func)FreeHardTimer,
|
|
(func)SetTimerMode,
|
|
(func)GetTimerStatus,
|
|
(func)SetTimerCounter,
|
|
(func)GetTimerCounter,
|
|
(func)SetTimerCompare,
|
|
(func)GetTimerCompare,
|
|
(func)SetHoldMode,
|
|
(func)GetHoldMode,
|
|
(func)GetHoldReg,
|
|
(func)GetHardTimerIntrCode,
|
|
0
|
|
};
|
|
|
|
//////////////////////////////entrypoint///////////////////////////////[00]
|
|
int _start(int argc, char* argv[]){
|
|
int i;
|
|
u32 PRid;
|
|
|
|
__asm__ (
|
|
"mfc0 %0, $15\n"
|
|
: "=r"(PRid) :
|
|
);
|
|
|
|
|
|
if ((PRid<0x10) || (CONFIG_1450 & 8)) return 1;
|
|
|
|
for (i=5; i>=0; i--) t[i].allocated=0;
|
|
|
|
if( RegisterLibraryEntries(&timrman_stub) > 0 )
|
|
return 1;
|
|
|
|
EnableIntr(INT_RTC5);
|
|
|
|
return 0; //loadcore
|
|
}
|
|
|