sceSystimer usage (hardware stopwatch)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

sceSystimer usage (hardware stopwatch)

Post by adrahil »

Here are header+stubs alongside with a stupid example of how to use it. The timing is a little strange, as it doesn't seem to be exactly microseconds. Anyway, here it is:

pspsystimer.h:

Code: Select all

/*
 * PSP Software Development Kit - http://www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * pspsystimer.h - Prototypes for the sceSystimer library.
 *
 * Copyright &#40;c&#41; 2007 Iaroslav Gaponenko <[email protected]>
 *
 * $Id&#58; pspctrl_kernel.h 2015 2006-10-05 20&#58;23&#58;07Z tyranid $
 */

#ifndef __SYSTIMER_H__
#define __SYSTIMER_H__

#ifdef __cplusplus
extern "C" &#123;
#endif

typedef int SceSysTimerId;

/**
 * Allocate a new SysTimer timer instance.
 *
 * @return SysTimerId on success, < 0 on error
 */
SceSysTimerId sceSTimerAlloc&#40;void&#41;;

/**
 * Free an instance of a SysTimer timer.
 *
 * @param timer - The timer id.
 *
 */
void sceSTimerFree&#40;SceSysTimerId timer&#41;;

/**
 * Start the SysTimer timer count.
 *
 * @param timer - The timer id.
 *
 */
void sceSTimerStartCount&#40;SceSysTimerId timer&#41;;

/**
 * Stop the current SysTimer timer count.
 *
 * @param timer - The timer id.
 *
 */
void sceSTimerStopCount&#40;SceSysTimerId timer&#41;;

/**
 * Reset the current SysTimer timer count.
 *
 * @param timer - The timer id.
 *
 */
void sceSTimerResetCount&#40;SceSysTimerId timer&#41;;

/**
 * Get the current SysTimer timer count.
 *
 * @param timer - The timer id.
 * @param count - The pointer to an integer into which the count will be written.
 *
 */
void sceSTimerGetCount&#40;SceSysTimerId timer, int* count&#41;;

/**
 * Setup a SysTimer handler
 *
 * @param timer - The timer id.
 * @param cycle - The timer cycle in microseconds &#40;???&#41;. Maximum&#58; 4194303 which represents ~1/10 seconds.
 * @param handler - The handler function. Has to return -1.
 * @param unk1 - Unknown. Pass 0.
 *
 */
void sceSTimerSetHandler&#40;SceSysTimerId timer, int cycle, int &#40;*handler&#41;&#40;void&#41;, int unk1&#41;;

/* Unknown functions. */
//probably something to set the cycle of an active timer.
void SysTimerForKernel_53231A15&#40;SceSysTimerId timer, int unk1&#41;;
//more complex. computes some ratio &#40;unk2/unk1&#41; and saves both parameters into the hardware registers. Might be some sort of scaling factor?
void SysTimerForKernel_B53534B4&#40;SceSysTimerId timer, int unk1, int unk2&#41;;



#ifdef __cplusplus
&#125;
#endif

#endif
SysTimerForKernel.S:

Code: Select all

        .set noreorder
 
#include "pspstub.s"
 
        STUB_START      "SysTimerForKernel",0x00010011,0x00090005
        STUB_FUNC       0x228EDAE4,sceSTimerGetCount
        STUB_FUNC       0x4A01F9D3,sceSTimerStopCount
        STUB_FUNC       0x53231A15,SysTimerForKernel_53231A15
        STUB_FUNC       0x54BB5DB4,sceSTimerResetCount
        STUB_FUNC       0x975D8E84,sceSTimerSetHandler
        STUB_FUNC       0xA95143E2,sceSTimerStartCount
        STUB_FUNC       0xB53534B4,SysTimerForKernel_B53534B4
        STUB_FUNC       0xC105CF38,sceSTimerFree
        STUB_FUNC       0xC99073E3,sceSTimerAlloc
        STUB_END
Now, the sample. Use the standard makefile and link to the stub file.

main.c:

Code: Select all

/*
 * PSP Software Development Kit - http&#58;//www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * main.c - Simple Systimer example
 *
 * Copyright &#40;c&#41; 2007 Iaroslav Gaponenko <[email protected]>
 *
 * $Id&#58; main.c 1888 2006-05-01 08&#58;47&#58;04Z tyranid $
 * $HeadURL$
 */
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "pspsystimer.h"

#define printf pspDebugScreenPrintf

/* Define the module info section */
PSP_MODULE_INFO&#40;"systimer", 0x1000, 1, 1&#41;;

/* Define the main thread's attribute value &#40;optional&#41; */
PSP_MAIN_THREAD_ATTR&#40;THREAD_ATTR_VFPU&#41;;

SceSysTimerId timer;
int tic = 0;

int my_tick_handler&#40;void&#41;&#123;
  static int div;
  div++;
  //arrange to get more or less seconds...
  if&#40;div > 12&#41;&#123; 
    div = 0;
    if&#40;tic&#41;&#123;
      pspDebugScreenPrintf&#40;"Tac!\n"&#41;;
    &#125;else&#123;
      pspDebugScreenPrintf&#40;"Tic!\n"&#41;;
    &#125;
    tic = ~tic;
  &#125;
  return -1;
&#125;

int main&#40;int argc, char *argv&#91;&#93;&#41; &#123;

  pspDebugScreenInit&#40;&#41;;
  pspDebugScreenPrintf&#40;"SysTimer sample by Adrahil.\n"&#41;;

  timer = sceSTimerAlloc&#40;&#41;;
  sceSTimerStartCount&#40;timer&#41;;
  sceSTimerSetHandler&#40;timer, 4194303, my_tick_handler, 0&#41;;

  sceKernelSleepThreadCB&#40;&#41;;
  return 0;

&#125;
What else can I say :3 Your PSP is now transformed into a 300$ stopwatch! Enjoy it! (Seriously, the only advantage of this method is that it uses some hardware timer at 0xbc50XXXX...) I shouldn't even have to mention that because of this reason it requires kernel mode :P
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

Post by harleyg »

Nice stuff adrahil. :)
Post Reply