Nugget
Loading...
Searching...
No Matches
Macros | Functions | Variables
timers.c File Reference
#include "common/hardware/counters.h"
#include "common/hardware/gpu.h"
#include "common/hardware/hwregs.h"
#include "common/syscalls/syscalls.h"
#include "exotic/cester.h"
Include dependency graph for timers.c:

Macros

#define PCSX_TESTS   0
 
#define CESTER_MAYBE_TEST   CESTER_TEST
 
#define CESTER_NO_SIGNAL
 
#define CESTER_NO_TIME
 
#define EXIT_SUCCESS   0
 
#define EXIT_FAILURE   1
 
#define BUSY_WAIT(n)   do { for (int _bw = (n); _bw > 0; _bw--) __asm__ volatile(""); } while(0)
 

Functions

 CESTER_BODY (static int s_interruptsWereEnabled;)
 
 CESTER_TEST (timerTargetResetHitsTarget, timer_tests, COUNTERS[2].target=0x0010;COUNTERS[2].mode=TM_RESET_TARGET;BUSY_WAIT(500);uint16_t mode=COUNTERS[2].mode;cester_assert_cmp((int)(mode &TM_HIT_TARGET), !=, 0);) CESTER_TEST(timerTargetResetNoOverflow
 
 BUSY_WAIT (500)
 
 cester_assert_int_eq (0,(int)(mode &TM_HIT_OVERFLOW))
 
 CESTER_TEST (timerSysclockDiv8Ratio, timer_tests, COUNTERS[2].target=0xFFFF;COUNTERS[2].mode=TM_CLK_DIV8;BUSY_WAIT(1000);uint16_t div8_val=COUNTERS[2].value;COUNTERS[2].target=0xFFFF;COUNTERS[2].mode=0;BUSY_WAIT(1000);uint16_t sys_val=COUNTERS[2].value;int ratio=sys_val/(div8_val ? div8_val :1);cester_assert_cmp(ratio, >=, 6);cester_assert_cmp(ratio,<=, 10);) CESTER_TEST(timerModeWriteResetsCounter
 
 BUSY_WAIT (50000)
 
 cester_assert_cmp ((int) before, >, 0)
 
 cester_assert_cmp (after,<, 10)
 
 CESTER_TEST (timerHitTargetFlagSetAndCleared, timer_tests, COUNTERS[2].target=0x1000;COUNTERS[2].mode=TM_RESET_TARGET;BUSY_WAIT(50000);(void) COUNTERS[2].mode;(void) COUNTERS[2].mode;COUNTERS[2].mode=TM_RESET_TARGET;BUSY_WAIT(50000);uint16_t mode1=COUNTERS[2].mode;uint16_t mode2=COUNTERS[2].mode;int flag1=(mode1 &TM_HIT_TARGET) ? 1 :0;int flag2=(mode2 &TM_HIT_TARGET) ? 1 :0;cester_assert_int_eq(1, flag1);cester_assert_int_eq(0, flag2);) CESTER_TEST(timerHitOverflowFlagSetAndCleared
 
 BUSY_WAIT (100000)
 
 cester_assert_cmp ((int)(mode1 &TM_HIT_OVERFLOW), !=, 0)
 
 cester_assert_int_eq (0,(int)(mode2 &TM_HIT_OVERFLOW))
 
 CESTER_TEST (timerIrqPulseModeBit10, timer_tests, COUNTERS[2].target=0x0080;COUNTERS[2].mode=TM_RESET_TARGET|TM_IRQ_TARGET|TM_IRQ_REPEAT;BUSY_WAIT(1000);uint16_t mode=COUNTERS[2].mode;cester_assert_cmp((int)(mode &TM_IRQ_REQUEST), !=, 0);) CESTER_TEST(timerIrqToggleModeBit10
 
 BUSY_WAIT (200)
 
 for (int i=0;i< 50;i++)
 
 cester_assert_int_eq (1, saw_zero)
 
 cester_assert_int_eq (1, saw_one)
 
 CESTER_TEST (timerRc2SyncMode0Stop, timer_tests, COUNTERS[2].target=0xFFFF;COUNTERS[2].mode=TM_SYNC_EN|TM_SYNC_MODE(0);BUSY_WAIT(50000);uint16_t v1=COUNTERS[2].value;BUSY_WAIT(50000);uint16_t v2=COUNTERS[2].value;cester_assert_int_eq(0,(int)(uint16_t)(v2 - v1));) CESTER_TEST(timerRc2SyncMode1Free
 
 cester_assert_cmp ((int)(uint16_t)(v2 - v1), >, 0)
 
 CESTER_TEST (timerRc2SyncMode2Free, timer_tests, COUNTERS[2].target=0xFFFF;COUNTERS[2].mode=TM_SYNC_EN|TM_SYNC_MODE(2);BUSY_WAIT(50000);uint16_t v1=COUNTERS[2].value;BUSY_WAIT(50000);uint16_t v2=COUNTERS[2].value;cester_assert_cmp((int)(uint16_t)(v2 - v1), >, 0);) CESTER_TEST(timerRc2SyncMode3Stop
 
 cester_assert_int_eq (0,(int)(uint16_t)(v2 - v1))
 
 CESTER_MAYBE_TEST (timerC0GateMode0PauseDuringHblank, timer_tests, COUNTERS[0].target=0xFFFF;COUNTERS[0].mode=TM_SYNC_EN|TM_SYNC_MODE(0);BUSY_WAIT(20000);uint16_t gated=COUNTERS[0].value;COUNTERS[0].mode=0;BUSY_WAIT(20000);uint16_t free_val=COUNTERS[0].value;cester_assert_cmp((int) gated,<,(int) free_val);) CESTER_TEST(timerC0GateMode1ResetAtHblank
 
 cester_assert_cmp ((int) val,<, 0x2000)
 
 CESTER_MAYBE_TEST (timerC0GateMode2ResetPauseOutside, timer_tests, COUNTERS[0].target=0xFFFF;COUNTERS[0].mode=TM_SYNC_EN|TM_SYNC_MODE(2);BUSY_WAIT(50000);uint16_t val=COUNTERS[0].value;cester_assert_cmp((int) val,<, 0x2000);) CESTER_TEST(timerC0GateMode3FreeAfterHblank
 
 if (diff< 0) diff
 
 cester_assert_cmp (diff,<, 0x2000)
 
 CESTER_TEST (timerPE2Scenario, timer_tests, COUNTERS[2].target=0x1000;COUNTERS[2].mode=TM_CLK_DIV8|TM_IRQ_REPEAT|TM_RESET_TARGET|TM_IRQ_TARGET;BUSY_WAIT(50000);uint16_t count=COUNTERS[2].value;cester_assert_cmp((int) count, >, 100);cester_assert_cmp((int) count,<, 0x1000);) CESTER_TEST(timerDotclockRate
 
 while (COUNTERS[1].value< 10)
 
 cester_assert_cmp (dots_per_line, >=, 330)
 
 cester_assert_cmp (dots_per_line,<=, 860)
 
 CESTER_BODY (static int measureDotsPerLine(int scanlines) { COUNTERS[1].target=0xFFFF;COUNTERS[1].mode=TM_CLK_EXTERNAL;COUNTERS[0].target=0xFFFF;COUNTERS[0].mode=TM_CLK_EXTERNAL;COUNTERS[1].mode=TM_CLK_EXTERNAL;COUNTERS[0].mode=TM_CLK_EXTERNAL;while(COUNTERS[1].value< scanlines) {} int dots=COUNTERS[0].value;int lines=COUNTERS[1].value;return(dots+lines/2)/lines;})
 
 waitVSync ()
 
 measureDotsPerLine (50)
 
 cester_assert_cmp (dpl, >=, 341 - 1)
 
 cester_assert_cmp (dpl,<=, 341+1)
 
 CESTER_MAYBE_TEST (timerDotclock256PAL, timer_tests, struct DisplayModeConfig cfg={ HR_256, VR_240, VM_PAL, CD_15BITS, VI_OFF, HRE_NORMAL };setDisplayMode(&cfg);waitVSync();waitVSync();measureDotsPerLine(50);int dpl=measureDotsPerLine(50);cester_assert_cmp(dpl, >=, 340 - 1);cester_assert_cmp(dpl,<=, 340+1);) CESTER_MAYBE_TEST(timerDotclock320NTSC
 
 cester_assert_cmp (dpl, >=, 426 - 1)
 
 cester_assert_cmp (dpl,<=, 426+1)
 
 CESTER_MAYBE_TEST (timerDotclock320PAL, timer_tests, struct DisplayModeConfig cfg={ HR_320, VR_240, VM_PAL, CD_15BITS, VI_OFF, HRE_NORMAL };setDisplayMode(&cfg);waitVSync();waitVSync();measureDotsPerLine(50);int dpl=measureDotsPerLine(50);cester_assert_cmp(dpl, >=, 426 - 1);cester_assert_cmp(dpl,<=, 426+1);) CESTER_MAYBE_TEST(timerDotclock512NTSC
 
 cester_assert_cmp (dpl, >=, 682 - 1)
 
 cester_assert_cmp (dpl,<=, 682+1)
 
 CESTER_MAYBE_TEST (timerDotclock512PAL, timer_tests, struct DisplayModeConfig cfg={ HR_512, VR_240, VM_PAL, CD_15BITS, VI_OFF, HRE_NORMAL };setDisplayMode(&cfg);waitVSync();waitVSync();measureDotsPerLine(50);int dpl=measureDotsPerLine(50);cester_assert_cmp(dpl, >=, 681 - 1);cester_assert_cmp(dpl,<=, 681+1);) CESTER_MAYBE_TEST(timerDotclock640NTSC
 
 cester_assert_cmp (dpl, >=, 853 - 1)
 
 cester_assert_cmp (dpl,<=, 853+1)
 
 CESTER_MAYBE_TEST (timerDotclock640PAL, timer_tests, struct DisplayModeConfig cfg={ HR_640, VR_240, VM_PAL, CD_15BITS, VI_OFF, HRE_NORMAL };setDisplayMode(&cfg);waitVSync();waitVSync();measureDotsPerLine(50);int dpl=measureDotsPerLine(50);cester_assert_cmp(dpl, >=, 851 - 1);cester_assert_cmp(dpl,<=, 851+1);) CESTER_MAYBE_TEST(timerDotclock368NTSC
 
 cester_assert_cmp (dpl, >=, 487 - 1)
 
 cester_assert_cmp (dpl,<=, 487+1)
 

Variables

 timer_tests
 
COUNTERS[2] target = 0x0010
 
COUNTERS[2] mode = TM_RESET_TARGET
 
void COUNTERS[2] value
 
uint16_t before = COUNTERS[2].value
 
int after = COUNTERS[2].value
 
uint16_t mode1 = COUNTERS[2].mode
 
uint16_t mode2 = COUNTERS[2].mode
 
int saw_zero = 0
 
int saw_one = 0
 
uint16_t v1 = COUNTERS[2].value
 
uint16_t v2 = COUNTERS[2].value
 
uint16_t val = COUNTERS[0].value
 
uint16_t free_val = COUNTERS[0].value
 
uint16_t gated = COUNTERS[0].value
 
int diff = (int)free_val - (int)gated
 
int dots = COUNTERS[0].value
 
int lines = COUNTERS[1].value
 
int dots_per_line = dots / lines
 
setDisplayMode & cfg = { HR_320, VR_240, VM_NTSC, CD_15BITS, VI_OFF, HRE_NORMAL }
 
int dpl = measureDotsPerLine(50)
 

Macro Definition Documentation

◆ BUSY_WAIT

#define BUSY_WAIT (   n)    do { for (int _bw = (n); _bw > 0; _bw--) __asm__ volatile(""); } while(0)

◆ CESTER_MAYBE_TEST

#define CESTER_MAYBE_TEST   CESTER_TEST

◆ CESTER_NO_SIGNAL

#define CESTER_NO_SIGNAL

◆ CESTER_NO_TIME

#define CESTER_NO_TIME

◆ EXIT_FAILURE

#define EXIT_FAILURE   1

◆ EXIT_SUCCESS

#define EXIT_SUCCESS   0

◆ PCSX_TESTS

#define PCSX_TESTS   0

Function Documentation

◆ BUSY_WAIT() [1/4]

BUSY_WAIT ( 100000  )

◆ BUSY_WAIT() [2/4]

BUSY_WAIT ( 200  )

◆ BUSY_WAIT() [3/4]

BUSY_WAIT ( 500  )

◆ BUSY_WAIT() [4/4]

BUSY_WAIT ( 50000  )

◆ cester_assert_cmp() [1/18]

cester_assert_cmp ( (int before,
 
)

◆ cester_assert_cmp() [2/18]

cester_assert_cmp ( (int val)

◆ cester_assert_cmp() [3/18]

cester_assert_cmp ( (int)(mode1 &TM_HIT_OVERFLOW ,
,
 
)

◆ cester_assert_cmp() [4/18]

cester_assert_cmp ( (int)(uint16_t)(v2 - v1 ,
 
)

◆ cester_assert_cmp() [5/18]

cester_assert_cmp ( after  )

◆ cester_assert_cmp() [6/18]

cester_assert_cmp ( diff  )

◆ cester_assert_cmp() [7/18]

cester_assert_cmp ( dots_per_line  ,
>=  ,
330   
)

◆ cester_assert_cmp() [8/18]

cester_assert_cmp ( dots_per_line  ,
<=  ,
860   
)

◆ cester_assert_cmp() [9/18]

cester_assert_cmp ( dpl  ,
>=  ,
341 -  1 
)

◆ cester_assert_cmp() [10/18]

cester_assert_cmp ( dpl  ,
>=  ,
426 -  1 
)

◆ cester_assert_cmp() [11/18]

cester_assert_cmp ( dpl  ,
>=  ,
487 -  1 
)

◆ cester_assert_cmp() [12/18]

cester_assert_cmp ( dpl  ,
>=  ,
682 -  1 
)

◆ cester_assert_cmp() [13/18]

cester_assert_cmp ( dpl  ,
>=  ,
853 -  1 
)

◆ cester_assert_cmp() [14/18]

cester_assert_cmp ( dpl  ,
<=  ,
341+  1 
)

◆ cester_assert_cmp() [15/18]

cester_assert_cmp ( dpl  ,
<=  ,
426+  1 
)

◆ cester_assert_cmp() [16/18]

cester_assert_cmp ( dpl  ,
<=  ,
487+  1 
)

◆ cester_assert_cmp() [17/18]

cester_assert_cmp ( dpl  ,
<=  ,
682+  1 
)

◆ cester_assert_cmp() [18/18]

cester_assert_cmp ( dpl  ,
<=  ,
853+  1 
)

◆ cester_assert_int_eq() [1/5]

cester_assert_int_eq ( ,
(int)(mode &TM_HIT_OVERFLOW  
)

◆ cester_assert_int_eq() [2/5]

cester_assert_int_eq ( ,
(int)(mode2 &TM_HIT_OVERFLOW  
)

◆ cester_assert_int_eq() [3/5]

cester_assert_int_eq ( ,
(int)(uint16_t)(v2 - v1  
)

◆ cester_assert_int_eq() [4/5]

cester_assert_int_eq ( ,
saw_one   
)

◆ cester_assert_int_eq() [5/5]

cester_assert_int_eq ( ,
saw_zero   
)

◆ CESTER_BODY() [1/2]

◆ CESTER_BODY() [2/2]

CESTER_BODY ( static int s_interruptsWereEnabled;  )

◆ CESTER_MAYBE_TEST() [1/6]

CESTER_MAYBE_TEST ( timerC0GateMode0PauseDuringHblank  ,
timer_tests  ,
COUNTERS.  target[0] = 0xFFFF;  COUNTERS[0].mode = TM_SYNC_EN | TM_SYNC_MODE(0); BUSY_WAIT(20000); uint16_t gated = COUNTERS[0].valueCOUNTERS[0].mode = 0; BUSY_WAIT(20000); uint16_t free_val = COUNTERS[0].value;  cester_assert_cmp((int)gated, <, (int)free_val); 
)

◆ CESTER_MAYBE_TEST() [2/6]

CESTER_MAYBE_TEST ( timerC0GateMode2ResetPauseOutside  ,
timer_tests  ,
COUNTERS.  target[0] = 0xFFFF; COUNTERS[0].mode = TM_SYNC_EN | TM_SYNC_MODE(2); BUSY_WAIT(50000); uint16_t val = COUNTERS[0].value;  cester_assert_cmp((int)val, <, 0x2000); 
)

◆ CESTER_MAYBE_TEST() [3/6]

CESTER_MAYBE_TEST ( timerDotclock256PAL  ,
timer_tests  ,
struct DisplayModeConfig  cfg = HR_256VR_240VM_PALCD_15BITSVI_OFFHRE_NORMAL }; setDisplayMode(&cfg); waitVSync(); waitVSync(); measureDotsPerLine(50); int dpl = measureDotsPerLine(50); cester_assert_cmp(dpl, >=, 340 - 1); cester_assert_cmp(dpl, <=, 340 + 1); 
)

◆ CESTER_MAYBE_TEST() [4/6]

CESTER_MAYBE_TEST ( timerDotclock320PAL  ,
timer_tests  ,
struct DisplayModeConfig  cfg = HR_320VR_240VM_PALCD_15BITSVI_OFFHRE_NORMAL }; setDisplayMode(&cfg); waitVSync(); waitVSync(); measureDotsPerLine(50); int dpl = measureDotsPerLine(50); cester_assert_cmp(dpl, >=, 426 - 1); cester_assert_cmp(dpl, <=, 426 + 1); 
)

◆ CESTER_MAYBE_TEST() [5/6]

CESTER_MAYBE_TEST ( timerDotclock512PAL  ,
timer_tests  ,
struct DisplayModeConfig  cfg = HR_512VR_240VM_PALCD_15BITSVI_OFFHRE_NORMAL }; setDisplayMode(&cfg); waitVSync(); waitVSync(); measureDotsPerLine(50); int dpl = measureDotsPerLine(50); cester_assert_cmp(dpl, >=, 681 - 1); cester_assert_cmp(dpl, <=, 681 + 1); 
)

◆ CESTER_MAYBE_TEST() [6/6]

CESTER_MAYBE_TEST ( timerDotclock640PAL  ,
timer_tests  ,
struct DisplayModeConfig  cfg = HR_640VR_240VM_PALCD_15BITSVI_OFFHRE_NORMAL }; setDisplayMode(&cfg); waitVSync(); waitVSync(); measureDotsPerLine(50); int dpl = measureDotsPerLine(50); cester_assert_cmp(dpl, >=, 851 - 1); cester_assert_cmp(dpl, <=, 851 + 1); 
)

◆ CESTER_TEST() [1/7]

CESTER_TEST ( timerHitTargetFlagSetAndCleared  ,
timer_tests  ,
COUNTERS.  target[2] = 0x1000; COUNTERS[2].mode = TM_RESET_TARGETBUSY_WAIT(50000); (void)COUNTERS[2].mode; (void)COUNTERS[2].mode;  COUNTERS[2].mode = TM_RESET_TARGETBUSY_WAIT(50000); uint16_t mode1 = COUNTERS[2].mode; uint16_t mode2 = COUNTERS[2].modeint flag1 = (mode1 & TM_HIT_TARGET) ? 1 : 0; int flag2 = (mode2 & TM_HIT_TARGET) ? 1 : 0;  cester_assert_int_eq(1, flag1);  cester_assert_int_eq(0, flag2); 
)

◆ CESTER_TEST() [2/7]

CESTER_TEST ( timerIrqPulseModeBit10  ,
timer_tests  ,
COUNTERS.  target[2] = 0x0080; COUNTERS[2].mode = TM_RESET_TARGET | TM_IRQ_TARGET | TM_IRQ_REPEATBUSY_WAIT(1000); uint16_t mode = COUNTERS[2].mode;  cester_assert_cmp((int)(mode & TM_IRQ_REQUEST), !=, 0); 
)

◆ CESTER_TEST() [3/7]

CESTER_TEST ( timerPE2Scenario  ,
timer_tests  ,
COUNTERS.  target[2] = 0x1000; COUNTERS[2].mode = TM_CLK_DIV8 | TM_IRQ_REPEAT | TM_RESET_TARGET | TM_IRQ_TARGET;  BUSY_WAIT(50000); uint16_t count = COUNTERS[2].value;  cester_assert_cmp((int)count, >, 100); cester_assert_cmp((int)count, <, 0x1000); 
)

◆ CESTER_TEST() [4/7]

CESTER_TEST ( timerRc2SyncMode0Stop  ,
timer_tests  ,
COUNTERS.  target[2] = 0xFFFF; COUNTERS[2].mode = TM_SYNC_EN | TM_SYNC_MODE(0); BUSY_WAIT(50000); uint16_t v1 = COUNTERS[2].valueBUSY_WAIT(50000); uint16_t v2 = COUNTERS[2].valuecester_assert_int_eq(0, (int)(uint16_t)(v2 - v1)); 
)

◆ CESTER_TEST() [5/7]

CESTER_TEST ( timerRc2SyncMode2Free  ,
timer_tests  ,
COUNTERS.  target[2] = 0xFFFF; COUNTERS[2].mode = TM_SYNC_EN | TM_SYNC_MODE(2); BUSY_WAIT(50000); uint16_t v1 = COUNTERS[2].valueBUSY_WAIT(50000); uint16_t v2 = COUNTERS[2].valuecester_assert_cmp((int)(uint16_t)(v2 - v1), >, 0); 
)

◆ CESTER_TEST() [6/7]

CESTER_TEST ( timerSysclockDiv8Ratio  ,
timer_tests  ,
COUNTERS.  target[2] = 0xFFFF; COUNTERS[2].mode = TM_CLK_DIV8BUSY_WAIT(1000); uint16_t div8_val = COUNTERS[2].value;  COUNTERS[2].target = 0xFFFF; COUNTERS[2].mode = 0; BUSY_WAIT(1000); uint16_t sys_val = COUNTERS[2].value;  int ratio = sys_val / (div8_val ? div8_val : 1); cester_assert_cmp(ratio, >=, 6); cester_assert_cmp(ratio, <=, 10); 
)

◆ CESTER_TEST() [7/7]

CESTER_TEST ( timerTargetResetHitsTarget  ,
timer_tests  ,
COUNTERS.  target[2] = 0x0010; COUNTERS[2].mode = TM_RESET_TARGETBUSY_WAIT(500); uint16_t mode = COUNTERS[2].mode;  cester_assert_cmp((int)(mode & TM_HIT_TARGET), !=, 0); 
)

◆ for()

for ( )

◆ if()

if ( )

◆ measureDotsPerLine()

measureDotsPerLine ( 50  )

◆ waitVSync()

waitVSync ( )

◆ while()

while ( )

Variable Documentation

◆ after

int after = COUNTERS[2].value

◆ before

uint16_t before = COUNTERS[2].value

◆ cfg

setDisplayMode & cfg = { HR_320, VR_240, VM_NTSC, CD_15BITS, VI_OFF, HRE_NORMAL }

◆ diff

int diff = (int)free_val - (int)gated

◆ dots

int dots = COUNTERS[0].value

◆ dots_per_line

int dots_per_line = dots / lines

◆ dpl

◆ free_val

uint16_t free_val = COUNTERS[0].value

◆ gated

uint16_t gated = COUNTERS[0].value

◆ lines

int lines = COUNTERS[1].value

◆ mode

◆ mode1

uint16_t mode1 = COUNTERS[2].mode

◆ mode2

uint16_t mode2 = COUNTERS[2].mode

◆ saw_one

int saw_one = 0

◆ saw_zero

int saw_zero = 0

◆ target

COUNTERS [0] target = 0x0010

◆ timer_tests

timer_tests

◆ v1

uint16_t v1 = COUNTERS[2].value

◆ v2

uint16_t v2 = COUNTERS[2].value

◆ val

uint16_t val = COUNTERS[0].value

◆ value

void COUNTERS [2] value