2017-02-04 14:49:08 +01:00
|
|
|
/* *************************************
|
2018-11-25 12:32:16 +01:00
|
|
|
* Includes
|
2017-02-04 14:49:08 +01:00
|
|
|
* *************************************/
|
|
|
|
#include "System.h"
|
2017-08-06 04:17:09 +02:00
|
|
|
#include "Pad.h"
|
|
|
|
#include "Menu.h"
|
|
|
|
#include "Gfx.h"
|
|
|
|
#include "MemCard.h"
|
|
|
|
#include "EndAnimation.h"
|
2017-08-10 22:39:31 +02:00
|
|
|
#include "Timer.h"
|
2017-02-04 14:49:08 +01:00
|
|
|
|
|
|
|
/* *************************************
|
2018-11-25 12:32:16 +01:00
|
|
|
* Defines
|
2017-02-04 14:49:08 +01:00
|
|
|
* *************************************/
|
2017-09-16 01:44:42 +02:00
|
|
|
#define FILE_BUFFER_SIZE (128 << 10) // 128 KB
|
2017-02-04 14:49:08 +01:00
|
|
|
|
|
|
|
#define END_STACK_PATTERN (uint32_t) 0x18022015
|
|
|
|
#define BEGIN_STACK_ADDRESS (uint32_t*) 0x801FFF00
|
2018-11-30 01:34:40 +01:00
|
|
|
#define STACK_SIZE (6 << 10) // 6 KiB
|
2017-08-11 22:11:43 +02:00
|
|
|
#define I_MASK (*(volatile unsigned int*)0x1F801074)
|
2018-11-30 01:34:40 +01:00
|
|
|
#define I_STAT (*(volatile unsigned int*)0x1F801070)
|
2017-02-04 14:49:08 +01:00
|
|
|
|
|
|
|
/* *************************************
|
2018-11-25 12:32:16 +01:00
|
|
|
* Local Prototypes
|
2017-02-04 14:49:08 +01:00
|
|
|
* *************************************/
|
2017-05-27 17:10:15 +02:00
|
|
|
static void SystemCheckTimer(bool* timer, uint64_t* last_timer, uint8_t step);
|
2017-02-04 14:49:08 +01:00
|
|
|
static void SystemSetStackPattern(void);
|
2017-08-09 22:51:15 +02:00
|
|
|
static void ISR_RootCounter2(void);
|
2017-02-04 14:49:08 +01:00
|
|
|
|
|
|
|
/* *************************************
|
2018-11-25 12:32:16 +01:00
|
|
|
* Local Variables
|
2017-02-04 14:49:08 +01:00
|
|
|
* *************************************/
|
|
|
|
//Buffer to store any kind of files. It supports files up to 128 kB
|
|
|
|
static uint8_t file_buffer[FILE_BUFFER_SIZE];
|
|
|
|
//Global timer (called by interrupt)
|
|
|
|
static volatile uint64_t global_timer;
|
|
|
|
//Tells whether rand seed has been set
|
|
|
|
static bool rand_seed;
|
|
|
|
//Screen refresh flag (called by interrupt)
|
|
|
|
static volatile bool refresh_needed;
|
2017-08-14 14:29:04 +02:00
|
|
|
// Frames per second measurement
|
|
|
|
static volatile uint8_t fps;
|
|
|
|
static volatile uint8_t temp_fps;
|
2017-02-04 14:49:08 +01:00
|
|
|
//Timers
|
|
|
|
static bool one_second_timer;
|
|
|
|
static bool hundred_ms_timer;
|
|
|
|
static bool five_hundred_ms_timer;
|
|
|
|
//Emergency mode flag. Toggled on pad connected/disconnected
|
|
|
|
static bool emergency_mode;
|
|
|
|
//Critical section is entered (i.e.: when accessing fopen() or other BIOS functions
|
2017-05-01 23:05:51 +02:00
|
|
|
static volatile bool system_busy;
|
2017-07-27 07:41:25 +02:00
|
|
|
// When true, it draws a rectangle on top of all primitives with
|
|
|
|
// information for development purposes.
|
|
|
|
static bool devmenu_flag;
|
2017-08-14 14:29:04 +02:00
|
|
|
// Used for sine-like effect.
|
|
|
|
static unsigned char sine_counter;
|
2017-02-04 14:49:08 +01:00
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-02-04 14:49:08 +01:00
|
|
|
* @name: void SystemInit(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-02-04 14:49:08 +01:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief: Calls main intialization routines.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks: To be called before main loop.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemInit(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
RCNT2_100US_TICK_COUNTER = 0xA560
|
|
|
|
};
|
2018-03-22 20:50:53 +01:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
//Reset global timer
|
|
|
|
global_timer = 0;
|
|
|
|
//Reset 1 second timer
|
|
|
|
one_second_timer = 0;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
//PSXSDK init
|
2017-08-06 04:17:09 +02:00
|
|
|
#ifdef SERIAL_INTERFACE
|
|
|
|
// PSX_INIT_SAVESTATE | PSX_INIT_CD flags are not needed
|
|
|
|
// when coming from OpenSend.
|
|
|
|
PSX_InitEx(0);
|
|
|
|
#else // SERIAL_INTERFACE
|
|
|
|
PSX_InitEx(PSX_INIT_SAVESTATE | PSX_INIT_CD);
|
|
|
|
#endif // SERIAL_INTERFACE
|
|
|
|
|
2018-11-25 18:02:18 +01:00
|
|
|
// SIO init
|
|
|
|
SerialInit();
|
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
//Graphics init
|
|
|
|
GsInit();
|
|
|
|
//Clear VRAM
|
|
|
|
GsClearMem();
|
|
|
|
//Set Video Resolution
|
2017-02-04 14:49:08 +01:00
|
|
|
#ifdef _PAL_MODE_
|
2018-11-25 12:32:16 +01:00
|
|
|
GsSetVideoMode(X_SCREEN_RESOLUTION, Y_SCREEN_RESOLUTION, VMODE_PAL);
|
2017-02-04 14:49:08 +01:00
|
|
|
#else
|
2018-11-25 12:32:16 +01:00
|
|
|
GsSetVideoMode(X_SCREEN_RESOLUTION, Y_SCREEN_RESOLUTION, VMODE_NTSC);
|
2017-02-04 14:49:08 +01:00
|
|
|
#endif //_PAL_MODE_
|
2018-11-25 12:32:16 +01:00
|
|
|
//SPU init
|
|
|
|
SsInit();
|
|
|
|
//Reset all user-handled timers
|
|
|
|
TimerReset();
|
|
|
|
//Pads init
|
|
|
|
PadInit();
|
|
|
|
//Set Drawing Environment
|
|
|
|
GfxInitDrawEnv();
|
|
|
|
//Set Display Environment
|
|
|
|
GfxInitDispEnv();
|
|
|
|
//Set VBlank Handler for screen refresh
|
|
|
|
SetVBlankHandler(&ISR_SystemDefaultVBlank);
|
|
|
|
//Set Primitive List
|
|
|
|
GfxSetDefaultPrimitiveList();
|
|
|
|
// Init memory card
|
|
|
|
MemCardInit();
|
|
|
|
//Initial value for system_busy
|
|
|
|
system_busy = false;
|
2017-07-27 07:41:25 +02:00
|
|
|
//Development menu flag
|
|
|
|
devmenu_flag = false;
|
2017-08-14 14:29:04 +02:00
|
|
|
//Emergency mode flag
|
|
|
|
emergency_mode = false;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
GfxSetGlobalLuminance(NORMAL_LUMINANCE);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemSetStackPattern();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
// Configure root counter 2 so that ISR_RootCounter2
|
|
|
|
// is executed every 100 us.
|
|
|
|
SetRCntHandler(&ISR_RootCounter2, 2, RCNT2_100US_TICK_COUNTER);
|
2017-08-09 22:51:15 +02:00
|
|
|
SystemEnableRCnt2Interrupt();
|
|
|
|
}
|
|
|
|
|
|
|
|
static volatile uint16_t u16_0_01seconds_cnt;
|
2018-03-17 01:43:53 +01:00
|
|
|
static volatile uint16_t u16_0_01seconds_cnt_prev;
|
2017-08-09 22:51:15 +02:00
|
|
|
|
2017-12-29 23:19:43 +01:00
|
|
|
/* *******************************************************************
|
|
|
|
*
|
|
|
|
* @name: void ISR_RootCounter2(void)
|
|
|
|
*
|
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
|
|
|
* @brief:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Executed on RCnt2 ISR every 100 us.
|
2017-12-29 23:19:43 +01:00
|
|
|
*
|
|
|
|
* *******************************************************************/
|
2017-08-09 22:51:15 +02:00
|
|
|
void ISR_RootCounter2(void)
|
|
|
|
{
|
|
|
|
u16_0_01seconds_cnt++;
|
2018-03-17 01:43:53 +01:00
|
|
|
|
|
|
|
if ((int16_t)(u16_0_01seconds_cnt - 1000) >= (int16_t)(u16_0_01seconds_cnt_prev))
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
u16_0_01seconds_cnt_prev = u16_0_01seconds_cnt;
|
|
|
|
//~ DEBUG_PRINT_VAR(u16_0_01seconds_cnt_prev);
|
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-09 22:51:15 +02:00
|
|
|
* @name: void SystemSetRandSeed(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Calls srand() while avoiding multiple calls by setting internal
|
|
|
|
* variable rand_seed to true. Internal variable "global_timer" is
|
|
|
|
* used to generate the new seed.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks:
|
2018-11-25 12:32:16 +01:00
|
|
|
* It is recommended to call it once user has pressed any key.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemSetRandSeed(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
if (rand_seed == false)
|
|
|
|
{
|
|
|
|
rand_seed = true;
|
|
|
|
//Set random seed using global timer as reference
|
|
|
|
srand((unsigned int)global_timer ^ GetRCnt(2));
|
|
|
|
|
|
|
|
Serial_printf("Seed used: %d\n",(unsigned int)global_timer);
|
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @name: bool SystemIsRandSeedSet(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Reportedly, returns whether rand seed has already been set.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks:
|
|
|
|
*
|
|
|
|
* @return:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Reportedly, returns whether rand seed has already been set.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool SystemIsRandSeedSet(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return rand_seed;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @name: bool SystemRefreshNeeded(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief:
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks:
|
|
|
|
*
|
|
|
|
* @return:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Returns whether VSync flag has been enabled.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool SystemRefreshNeeded(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return refresh_needed;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @name: void ISR_SystemDefaultVBlank(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief:
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Called from VSync interrupt. Called 50 times a second in PAL mode,
|
|
|
|
* 60 times a second in NTSC mode.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void ISR_SystemDefaultVBlank(void)
|
|
|
|
{
|
2018-11-23 13:57:38 +01:00
|
|
|
if (System1SecondTick())
|
2017-08-14 14:29:04 +02:00
|
|
|
{
|
|
|
|
fps = temp_fps;
|
|
|
|
temp_fps = 0;
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
refresh_needed = true;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-08-14 14:29:04 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @name: void SystemAcknowledgeFrame(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @brief:
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @remarks:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Called by Game module in order to calculate frames per second.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* *******************************************************************/
|
|
|
|
void SystemAcknowledgeFrame(void)
|
|
|
|
{
|
|
|
|
temp_fps++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @name: void SystemAcknowledgeFrame(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @brief:
|
2018-03-26 08:50:33 +02:00
|
|
|
* Creates a sine-like (more exactly, a sawtooth-like) effect and
|
2017-08-14 14:29:04 +02:00
|
|
|
* stores its value into a variable.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @remarks:
|
2018-11-25 12:32:16 +01:00
|
|
|
* To be called only once, preferibly on SystemCyclic().
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* *******************************************************************/
|
|
|
|
void SystemCalculateSine(void)
|
|
|
|
{
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
SINE_EFFECT_STEP = 24,
|
|
|
|
SINE_EFFECT_MAX = 240
|
|
|
|
};
|
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
static bool sine_decrease = false;
|
2017-08-14 14:29:04 +02:00
|
|
|
|
2017-08-30 23:29:57 +02:00
|
|
|
if (sine_decrease == false)
|
2017-08-14 14:29:04 +02:00
|
|
|
{
|
2017-08-30 23:29:57 +02:00
|
|
|
if (sine_counter < SINE_EFFECT_MAX)
|
2017-08-14 14:29:04 +02:00
|
|
|
{
|
|
|
|
sine_counter += SINE_EFFECT_STEP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sine_decrease = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-08-30 23:29:57 +02:00
|
|
|
if (sine_counter > SINE_EFFECT_STEP)
|
2017-08-14 14:29:04 +02:00
|
|
|
{
|
|
|
|
sine_counter -= SINE_EFFECT_STEP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sine_decrease = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @name: unsigned char SystemGetSineValue(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
|
|
|
* @return:
|
|
|
|
* Returns a value which oscillates like a sine (more exactly, like
|
|
|
|
* a parabola) function to be used wherever you want.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* *******************************************************************/
|
|
|
|
unsigned char SystemGetSineValue(void)
|
|
|
|
{
|
|
|
|
return sine_counter;
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @name: void SystemIncreaseGlobalTimer(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @brief:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Increases internal variable responsible for time handling.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* @remarks:
|
2018-11-25 12:32:16 +01:00
|
|
|
* Usually called from ISR_SystemDefaultVBlank().
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-05-01 23:05:51 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemIncreaseGlobalTimer(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
global_timer++;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-03-17 01:43:53 +01:00
|
|
|
* @name: volatile uint64_t SystemGetGlobalTimer(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @brief: Returns internal global timer value.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2018-03-17 01:43:53 +01:00
|
|
|
volatile uint64_t SystemGetGlobalTimer(void)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return global_timer;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @name: void SystemDisableScreenRefresh(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @brief: Resets VBlank IRQ flag.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemDisableScreenRefresh(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
refresh_needed = false;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @name: bool System1SecondTick(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @return: bool variable with a 1-cycle-length pulse that gets
|
2018-11-25 12:32:16 +01:00
|
|
|
* set each second.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool System1SecondTick(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return one_second_timer;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @name: bool System100msTick(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @return: bool variable with a 1-cycle-length pulse that gets
|
2018-11-25 12:32:16 +01:00
|
|
|
* set every 100 milliseconds.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool System100msTick(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return hundred_ms_timer;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool System500msTick(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @return: bool variable with a 1-cycle-length pulse that gets
|
2018-11-25 12:32:16 +01:00
|
|
|
* set every 500 milliseconds.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool System500msTick(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return five_hundred_ms_timer;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* *******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemRunTimers(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: general timer handler
|
2017-06-03 01:37:55 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @remarks: 1 second, 500 ms and 100 ms ticks get updated here.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************/
|
2017-05-27 17:10:15 +02:00
|
|
|
void SystemRunTimers(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
static uint64_t last_one_second_tick;
|
|
|
|
static uint64_t last_100_ms_tick;
|
|
|
|
static uint64_t last_500_ms_tick;
|
2017-06-03 01:37:55 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemCheckTimer(&one_second_timer, &last_one_second_tick, REFRESH_FREQUENCY);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
#ifdef _PAL_MODE_
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemCheckTimer(&hundred_ms_timer, &last_100_ms_tick, 2 /* 2 * 50 ms = 100 ms */);
|
|
|
|
SystemCheckTimer(&five_hundred_ms_timer, &last_500_ms_tick, 10 /* 10 * 50 ms = 500 ms */);
|
2017-05-25 07:38:58 +02:00
|
|
|
#else // _PAL_MODE_
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemCheckTimer(&hundred_ms_timer, &last_100_ms_tick, 3);
|
2017-05-25 07:38:58 +02:00
|
|
|
#endif // _PAL_MODE_
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ********************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemCheckTimer(bool* timer, uint64_t* last_timer, uint8_t step)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Checks if needed time step has been elapsed. If true, flag gets set.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *******************************************************************************/
|
2017-05-27 17:10:15 +02:00
|
|
|
void SystemCheckTimer(bool* timer, uint64_t* last_timer, uint8_t step)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
if (*timer)
|
|
|
|
{
|
|
|
|
*timer = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (global_timer >= (*last_timer + step) )
|
|
|
|
{
|
|
|
|
*timer = true;
|
|
|
|
*last_timer = global_timer;
|
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemLoadFileToBuffer(char* fname, uint8_t* buffer, uint32_t szBuffer)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Given an input path, it fills a buffer pointed to by "buffer" with
|
|
|
|
* maximum size "szBuffer" with data from CD-ROM.
|
2017-06-03 01:37:55 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: true if file has been loaded successfully, false otherwise.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ****************************************************************************************/
|
2018-11-18 20:03:35 +01:00
|
|
|
bool SystemLoadFileToBuffer(const char* fname, uint8_t* buffer, uint32_t szBuffer)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-07-20 22:36:19 +02:00
|
|
|
#ifdef SERIAL_INTERFACE
|
2018-11-25 12:32:16 +01:00
|
|
|
uint8_t fileSizeBuffer[sizeof (uint32_t)] = {0};
|
2017-07-20 22:36:19 +02:00
|
|
|
uint32_t i;
|
2017-07-27 07:41:25 +02:00
|
|
|
#else // SERIAL_INTERFACE
|
2017-07-20 22:36:19 +02:00
|
|
|
FILE *f;
|
|
|
|
#endif // SERIAL_INTERFACE
|
2018-11-25 12:32:16 +01:00
|
|
|
int32_t size = 0;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
// Wait for possible previous operation from the GPU before entering this section.
|
|
|
|
while ( (SystemIsBusy()) || (GfxIsGPUBusy()) );
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemDisableRCnt2Interrupt();
|
2018-03-26 08:50:33 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
if (fname == NULL)
|
|
|
|
{
|
|
|
|
Serial_printf("SystemLoadFile: NULL fname!\n");
|
|
|
|
return false;
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
memset(buffer,0,szBuffer);
|
2017-07-20 22:36:19 +02:00
|
|
|
|
2018-11-18 20:03:35 +01:00
|
|
|
static char completeFileName[256];
|
|
|
|
|
|
|
|
snprintf(completeFileName, sizeof (completeFileName), "cdrom:\\%s;1", fname);
|
|
|
|
|
2017-07-20 22:36:19 +02:00
|
|
|
#ifdef SERIAL_INTERFACE
|
2018-11-18 20:03:35 +01:00
|
|
|
Serial_printf("#%s@", completeFileName);
|
2017-07-20 22:36:19 +02:00
|
|
|
|
2018-03-10 14:30:40 +01:00
|
|
|
SerialRead(fileSizeBuffer, sizeof (uint32_t) );
|
2017-07-20 22:36:19 +02:00
|
|
|
|
2018-03-10 14:30:40 +01:00
|
|
|
for (i = 0; i < sizeof (uint32_t); i++)
|
2017-07-20 22:36:19 +02:00
|
|
|
{
|
|
|
|
size |= fileSizeBuffer[i] << (i << 3); // (i << 3) == (i * 8)
|
|
|
|
}
|
|
|
|
|
|
|
|
SerialWrite(ACK_BYTE_STRING, 1);
|
|
|
|
|
2017-08-30 23:29:57 +02:00
|
|
|
for (i = 0; i < size; i += SERIAL_DATA_PACKET_SIZE)
|
2017-07-20 22:36:19 +02:00
|
|
|
{
|
|
|
|
uint32_t bytes_to_read;
|
|
|
|
|
|
|
|
// Read actual EXE data into proper RAM address.
|
|
|
|
|
2017-08-30 23:29:57 +02:00
|
|
|
if ( (i + SERIAL_DATA_PACKET_SIZE) >= size)
|
2017-07-20 22:36:19 +02:00
|
|
|
{
|
|
|
|
bytes_to_read = size - i;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bytes_to_read = SERIAL_DATA_PACKET_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SerialRead(file_buffer + i, bytes_to_read);
|
|
|
|
|
2018-03-10 14:30:40 +01:00
|
|
|
SerialWrite(ACK_BYTE_STRING, sizeof (uint8_t)); // Write ACK
|
2017-07-20 22:36:19 +02:00
|
|
|
}
|
2017-07-27 07:41:25 +02:00
|
|
|
#else // SERIAL_INTERFACE
|
|
|
|
|
|
|
|
system_busy = true;
|
2017-07-20 22:36:19 +02:00
|
|
|
|
|
|
|
SystemDisableVBlankInterrupt();
|
|
|
|
|
2018-11-18 20:03:35 +01:00
|
|
|
Serial_printf("Opening %s...\n", completeFileName);
|
|
|
|
|
|
|
|
f = fopen((char*)completeFileName, "r");
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
if (f == NULL)
|
|
|
|
{
|
|
|
|
Serial_printf("SystemLoadFile: file could not be found!\n");
|
|
|
|
//File couldn't be found
|
|
|
|
return false;
|
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
fseek(f, 0, SEEK_END);
|
2017-02-04 14:49:08 +01:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
size = ftell(f);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
if (size > szBuffer)
|
|
|
|
{
|
|
|
|
Serial_printf("SystemLoadFile: Exceeds file buffer size (%d bytes)\n",size);
|
|
|
|
//Bigger than 128 kB (buffer's max size)
|
|
|
|
return false;
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
fseek(f, 0, SEEK_SET); //f->pos = 0;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
fread(buffer, sizeof (char), size, f);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
fclose(f);
|
2017-07-20 22:36:19 +02:00
|
|
|
|
|
|
|
SystemEnableVBlankInterrupt();
|
2018-03-17 01:43:53 +01:00
|
|
|
SystemEnableRCnt2Interrupt();
|
2017-07-20 22:36:19 +02:00
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
system_busy = false;
|
|
|
|
|
2017-07-20 22:36:19 +02:00
|
|
|
#endif // SERIAL_INTERFACE
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
Serial_printf("File \"%s\" loaded successfully!\n",completeFileName);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return true;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemLoadFile(char*fname)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Given an input file name, it loads its conents into internal buffer.
|
2017-06-03 01:37:55 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: true if file has been loaded successfully, false otherwise.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ****************************************************************************************/
|
2018-11-18 20:03:35 +01:00
|
|
|
bool SystemLoadFile(const char* fname)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return SystemLoadFileToBuffer(fname,file_buffer,sizeof (file_buffer));
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name uint8_t* SystemGetBufferAddress(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: Reportedly, returns internal buffer initial address.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *****************************************************************/
|
2017-05-24 07:15:38 +02:00
|
|
|
uint8_t* SystemGetBufferAddress(void)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return file_buffer;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-06 06:52:46 +02:00
|
|
|
/* ******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemClearFileBuffer(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-06 06:52:46 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: Fills internal buffer with zeros
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-06 06:52:46 +02:00
|
|
|
* *****************************************************************/
|
2018-03-20 06:37:23 +01:00
|
|
|
void SystemClearFileBuffer(void)
|
2017-06-06 06:52:46 +02:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
memset(file_buffer, 0, sizeof (file_buffer));
|
2017-06-06 06:52:46 +02:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ******************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name uint32_t SystemRand(uint32_t min, uint32_t max)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: random number between "min" and "max".
|
2017-06-03 01:37:55 +02:00
|
|
|
*
|
|
|
|
* @remarks: rand seed must be set before using this function, or
|
2018-11-25 12:32:16 +01:00
|
|
|
* you will predictable values otherwise!
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* *****************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
uint32_t SystemRand(uint32_t min, uint32_t max)
|
|
|
|
{
|
2017-08-30 23:29:57 +02:00
|
|
|
if (rand_seed == false)
|
2017-08-11 22:11:43 +02:00
|
|
|
{
|
2018-03-17 01:43:53 +01:00
|
|
|
//~ Serial_printf("Warning: calling rand() before srand()\n");
|
2017-08-11 22:11:43 +02:00
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return rand() % (max - min + 1) + min;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ***********************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemSetEmergencyMode(bool value)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Sets emergency mode flag.
|
2017-06-03 01:37:55 +02:00
|
|
|
*
|
|
|
|
* @remarks: emergency mode is set once that a controller is unplugged.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ***********************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemSetEmergencyMode(bool value)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
emergency_mode = value;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ***********************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemGetEmergencyMode(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: returns emergency mode flag.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ***********************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
bool SystemGetEmergencyMode(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return emergency_mode;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ***********************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name volatile bool SystemIsBusy(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: returns system busy flag.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ***********************************************************************/
|
2017-05-01 23:05:51 +02:00
|
|
|
volatile bool SystemIsBusy(void)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
return system_busy;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ****************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemContains_u8(uint8_t value, uint8_t* buffer, size_t sz)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: checks if a certain value is contained in a buffer with size "sz".
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: true if value is contained inside buffer, false otherwise.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ****************************************************************************/
|
2018-11-24 11:56:04 +01:00
|
|
|
bool SystemContains_u8(const uint8_t value, const uint8_t* const buffer, const size_t sz)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
size_t i = 0;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = 0; i < sz; i++)
|
|
|
|
{
|
|
|
|
if (buffer[i] == value)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return false;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-06-03 01:37:55 +02:00
|
|
|
/* ****************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemContains_u16(uint16_t value, uint16_t* buffer, size_t sz)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* @author: Xavier Del Campo
|
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: checks if a certain value is contained in a buffer with size "sz".
|
|
|
|
* Variant for u16 variables.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @return: true if value is contained inside buffer, false otherwise.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-06-03 01:37:55 +02:00
|
|
|
* ****************************************************************************/
|
2018-11-24 11:56:04 +01:00
|
|
|
bool SystemContains_u16(const uint16_t value, const uint16_t* const buffer, const size_t sz)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
size_t i = 0;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = 0; i < sz; i++)
|
|
|
|
{
|
|
|
|
if (buffer[i] == value)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return false;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name bool SystemArrayCompare(unsigned short* arr1, unsigned short* arr2, size_t sz)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Reportedly, it compares two arrays "arr1" and "arr2", with size "sz".
|
2017-07-27 07:41:25 +02:00
|
|
|
*
|
|
|
|
* @return: true if they are equal, false otherwise.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2018-11-25 12:32:16 +01:00
|
|
|
bool SystemArrayCompare(const unsigned short* const arr1, const unsigned short* const arr2, const size_t sz)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
size_t i;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = 0; i < sz; i++)
|
|
|
|
{
|
|
|
|
if (arr1[i] != arr2[i])
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return true;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemPrintStackPointerAddress(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Prints stack usage in percentage via dprintf calls.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemPrintStackPointerAddress(void)
|
|
|
|
{
|
|
|
|
#ifdef PSXSDK_DEBUG // Used to avoid unused variable warning
|
2018-11-25 12:32:16 +01:00
|
|
|
void* ptr = NULL;
|
|
|
|
fix16_t used_bytes = fix16_from_int((int)((void*)BEGIN_STACK_ADDRESS - (void*)&ptr));
|
|
|
|
fix16_t stackPercent = fix16_sdiv(used_bytes,fix16_from_int((int)STACK_SIZE));
|
|
|
|
|
|
|
|
stackPercent = fix16_smul(stackPercent, fix16_from_int((int)100));
|
|
|
|
|
|
|
|
Serial_printf("stackPercent: %d\n", stackPercent);
|
|
|
|
|
|
|
|
Serial_printf("Stack begin pointer: 0x%08X\n"
|
|
|
|
"Stack pointer address: 0x%08X\n"
|
|
|
|
"Used %d%% of stack size.\n"
|
|
|
|
"\tUsed bytes: %d\n",
|
|
|
|
(void*)BEGIN_STACK_ADDRESS,
|
|
|
|
(void*)&ptr,
|
|
|
|
fix16_to_int(stackPercent),
|
|
|
|
fix16_to_int(used_bytes) );
|
2017-02-04 14:49:08 +01:00
|
|
|
#endif // PSXSDK_DEBUG
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemCheckStack(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Compares stack top with expected byte pattern. If does not match, a stack
|
2017-07-27 07:41:25 +02:00
|
|
|
* overflow has been caused, and application returns to a safe state.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemCheckStack(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
const uint32_t* const ptrStack = BEGIN_STACK_ADDRESS - STACK_SIZE;
|
|
|
|
const uint32_t data = *ptrStack;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
if (data != END_STACK_PATTERN)
|
|
|
|
{
|
|
|
|
Serial_printf("Stack overflow?\n");
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
while (1);
|
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
|
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemSetStackPattern(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Sets a determined byte pattern on stack top to detect possible stack
|
2017-07-27 07:41:25 +02:00
|
|
|
* overflow during execution.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-02-04 14:49:08 +01:00
|
|
|
void SystemSetStackPattern(void)
|
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
uint32_t* const ptrStack = BEGIN_STACK_ADDRESS - STACK_SIZE;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
*ptrStack = END_STACK_PATTERN;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name int32_t SystemIndexOfStringArray(char* str, char** array)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Finds string "str" inside an array of strings "array".
|
2017-07-27 07:41:25 +02:00
|
|
|
*
|
|
|
|
* @return Index for a string "str" inside "array". -1 if it could not be found.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2018-11-25 12:32:16 +01:00
|
|
|
int32_t SystemIndexOfStringArray(const char* str, const char* const* array)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
int32_t i;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = 0; array[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
Serial_printf("String to find: %s\nEntry: %s\n", str, array[i]);
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
if (strcmp(str, array[i]) == 0)
|
|
|
|
{
|
|
|
|
Serial_printf("Match! Returning index %d...\n", i);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return -1;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name int32_t SystemIndexOf_U16(uint16_t value, uint16_t* array, uint32_t sz)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: For a uint16_t array, it returns index of a variable "value" inside an array.
|
2017-07-27 07:41:25 +02:00
|
|
|
*
|
|
|
|
* @return Index for a variable "value" inside "array". -1 if it could not be found.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2018-11-24 11:56:04 +01:00
|
|
|
int32_t SystemIndexOf_U16(const uint16_t value, const uint16_t* const array, const uint32_t sz)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
int32_t i;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = 0; i < sz; i++)
|
|
|
|
{
|
|
|
|
if (value == array[i])
|
|
|
|
{
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return -1;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name int32_t SystemIndexOf_U8(uint8_t value, uint8_t* array, uint32_t from, uint32_t sz)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: For a uint8_t array, it returns index of a variable "value" inside an array.
|
2017-07-27 07:41:25 +02:00
|
|
|
* "from" and "size_t" can be used to determine initial/ending positions.
|
|
|
|
*
|
|
|
|
* @return Index for a variable "value" inside "array". -1 if it could not be found.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
|
2018-11-24 11:56:04 +01:00
|
|
|
int32_t SystemIndexOf_U8(const uint8_t value, const uint8_t* const array, const uint32_t from, const uint32_t sz)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
int32_t i;
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
for (i = from; i < sz; i++)
|
|
|
|
{
|
|
|
|
if (value == array[i])
|
|
|
|
{
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
return -1;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
2017-05-01 23:05:51 +02:00
|
|
|
|
2017-08-14 14:29:04 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name volatile uint8_t SystemGetFPS(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* @return: Frames per second
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-14 14:29:04 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
volatile uint8_t SystemGetFPS(void)
|
|
|
|
{
|
|
|
|
return fps;
|
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemCyclicHandler(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: It calls system handlers once an execution cycle has finished.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-05-01 23:05:51 +02:00
|
|
|
void SystemCyclicHandler(void)
|
|
|
|
{
|
2017-08-06 04:17:09 +02:00
|
|
|
UpdatePads();
|
2017-07-27 07:41:25 +02:00
|
|
|
|
|
|
|
SystemIncreaseGlobalTimer();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemRunTimers();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
TimerHandler();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemDisableScreenRefresh();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
MemCardHandler();
|
2017-08-14 14:29:04 +02:00
|
|
|
|
|
|
|
SystemCalculateSine();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2018-11-25 12:32:16 +01:00
|
|
|
SystemCheckStack();
|
2017-05-01 23:05:51 +02:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemDisableVBlankInterrupt(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Reportedly, this routine enables VBLANK interrupt flag.
|
2017-07-27 07:41:25 +02:00
|
|
|
*
|
|
|
|
* @remark: Used when critical timing is needed or GPU activity is not desired
|
2017-09-16 01:44:42 +02:00
|
|
|
* e.g.: when reading files from CD-ROM.
|
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-05-01 23:05:51 +02:00
|
|
|
void SystemDisableVBlankInterrupt(void)
|
|
|
|
{
|
2018-11-30 01:34:40 +01:00
|
|
|
I_MASK &= ~1;
|
2017-05-01 23:05:51 +02:00
|
|
|
}
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemEnableVBlankInterrupt(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Reportedly, this routine enables VBLANK interrupt flag.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
2017-05-01 23:05:51 +02:00
|
|
|
void SystemEnableVBlankInterrupt(void)
|
|
|
|
{
|
2018-11-30 01:34:40 +01:00
|
|
|
I_MASK |= 1;
|
2017-05-01 23:05:51 +02:00
|
|
|
}
|
2017-07-27 07:41:25 +02:00
|
|
|
|
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemReturnToLoader(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Deinitializes PSXSDK library and returns to OpenSend loader,
|
2017-07-27 07:41:25 +02:00
|
|
|
* located at memory address 0x801A0000
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
void SystemReturnToLoader(void)
|
|
|
|
{
|
|
|
|
Serial_printf("Returning to loader...\n");
|
|
|
|
|
|
|
|
EndAnimation();
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
PSX_DeInit();
|
|
|
|
|
|
|
|
__asm__("j 0x801A0000");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemDevMenuToggle(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: It toggles a flag called "devmenu_flag" which, if true, shows information on
|
2017-07-27 07:41:25 +02:00
|
|
|
* top of all drawn primitives for debugging/development purposes.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
void SystemDevMenuToggle(void)
|
|
|
|
{
|
|
|
|
devmenu_flag = devmenu_flag? false: true;
|
2017-08-06 04:17:09 +02:00
|
|
|
}
|
2017-07-27 07:41:25 +02:00
|
|
|
|
2017-08-06 04:17:09 +02:00
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemEnableRCnt2Interrupt(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-06 04:17:09 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Enables bit 6 from I_MASK (0x1F801074)/IRQ6 RCNT2 (System clock / 8)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-06 04:17:09 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
void SystemEnableRCnt2Interrupt(void)
|
|
|
|
{
|
|
|
|
I_MASK |= 1<<6;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemDisableRCnt2Interrupt(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-06 04:17:09 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Disables bit 6 from I_MASK (0x1F801074)/IRQ6 RCNT2 (System clock / 8)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-08-06 04:17:09 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
void SystemDisableRCnt2Interrupt(void)
|
|
|
|
{
|
2018-03-17 01:43:53 +01:00
|
|
|
I_MASK &= ~(1 << 6);
|
2017-07-27 07:41:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ****************************************************************************************
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @name void SystemDevMenu(void)
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* @author: Xavier Del Campo
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2018-11-25 12:32:16 +01:00
|
|
|
* @brief: Shows information on top of all drawn primitives for debugging/development purposes.
|
2017-09-16 01:44:42 +02:00
|
|
|
*
|
2017-07-27 07:41:25 +02:00
|
|
|
* ****************************************************************************************/
|
|
|
|
void SystemDevMenu(void)
|
|
|
|
{
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
DEVMENU_BG_W = 256,
|
|
|
|
DEVMENU_BG_X = (X_SCREEN_RESOLUTION >> 1) - (DEVMENU_BG_W >> 1),
|
|
|
|
DEVMENU_BG_Y = 32,
|
|
|
|
DEVMENU_BG_H = 128,
|
2017-09-16 01:44:42 +02:00
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
DEVMENU_BG_R = 0,
|
|
|
|
DEVMENU_BG_G = 128,
|
|
|
|
DEVMENU_BG_B = 32,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
DEVMENU_TEXT_GAP = 8,
|
|
|
|
|
|
|
|
DEVMENU_PAD1_STATUS_TEXT_X = DEVMENU_BG_X + DEVMENU_TEXT_GAP,
|
|
|
|
DEVMENU_PAD1_STATUS_TEXT_Y = DEVMENU_BG_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
|
|
|
DEVMENU_PAD1_TYPE_TEXT_X = DEVMENU_PAD1_STATUS_TEXT_X,
|
|
|
|
DEVMENU_PAD1_TYPE_TEXT_Y = DEVMENU_PAD1_STATUS_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
|
|
|
DEVMENU_PAD1_ID_TEXT_X = DEVMENU_PAD1_STATUS_TEXT_X,
|
|
|
|
DEVMENU_PAD1_ID_TEXT_Y = DEVMENU_PAD1_TYPE_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
2017-08-06 04:17:09 +02:00
|
|
|
DEVMENU_PAD1_RAW_DATA_TEXT_X = DEVMENU_PAD1_ID_TEXT_X,
|
|
|
|
DEVMENU_PAD1_RAW_DATA_TEXT_Y = DEVMENU_PAD1_ID_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
|
|
|
DEVMENU_PAD2_STATUS_TEXT_X = DEVMENU_PAD1_RAW_DATA_TEXT_X,
|
|
|
|
DEVMENU_PAD2_STATUS_TEXT_Y = DEVMENU_PAD1_RAW_DATA_TEXT_Y + (DEVMENU_TEXT_GAP << 1), // Leave a bigger gap here
|
2017-07-27 07:41:25 +02:00
|
|
|
|
|
|
|
DEVMENU_PAD2_TYPE_TEXT_X = DEVMENU_PAD2_STATUS_TEXT_X,
|
|
|
|
DEVMENU_PAD2_TYPE_TEXT_Y = DEVMENU_PAD2_STATUS_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
|
|
|
DEVMENU_PAD2_ID_TEXT_X = DEVMENU_PAD2_TYPE_TEXT_X,
|
|
|
|
DEVMENU_PAD2_ID_TEXT_Y = DEVMENU_PAD2_TYPE_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
2017-08-06 04:17:09 +02:00
|
|
|
DEVMENU_PAD2_RAW_DATA_TEXT_X = DEVMENU_PAD2_ID_TEXT_X,
|
|
|
|
DEVMENU_PAD2_RAW_DATA_TEXT_Y = DEVMENU_PAD2_ID_TEXT_Y + DEVMENU_TEXT_GAP,
|
|
|
|
|
2017-08-09 22:51:15 +02:00
|
|
|
DEVMENU_ROOTCNT2_TEXT_X = DEVMENU_PAD2_RAW_DATA_TEXT_X,
|
|
|
|
DEVMENU_ROOTCNT2_TEXT_Y = DEVMENU_PAD2_RAW_DATA_TEXT_Y + DEVMENU_TEXT_GAP,
|
2017-07-27 07:41:25 +02:00
|
|
|
};
|
|
|
|
|
2018-11-23 13:57:38 +01:00
|
|
|
if (devmenu_flag)
|
2017-07-27 07:41:25 +02:00
|
|
|
{
|
2018-11-25 12:32:16 +01:00
|
|
|
static const GsRectangle devMenuBg =
|
|
|
|
{
|
|
|
|
.x = DEVMENU_BG_X,
|
|
|
|
.y = DEVMENU_BG_Y,
|
|
|
|
.w = DEVMENU_BG_W,
|
|
|
|
.h = DEVMENU_BG_H,
|
|
|
|
.r = DEVMENU_BG_R,
|
|
|
|
.g = DEVMENU_BG_G,
|
|
|
|
.b = DEVMENU_BG_B,
|
|
|
|
.attribute = ENABLE_TRANS | TRANS_MODE(0)
|
|
|
|
};
|
|
|
|
|
|
|
|
GsSortRectangle((GsRectangle*)&devMenuBg);
|
2017-07-27 07:41:25 +02:00
|
|
|
|
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD1_STATUS_TEXT_X,
|
|
|
|
DEVMENU_PAD1_STATUS_TEXT_Y,
|
|
|
|
"Pad1 connected = %d",
|
|
|
|
PadOneConnected() );
|
|
|
|
|
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD1_TYPE_TEXT_X,
|
|
|
|
DEVMENU_PAD1_TYPE_TEXT_Y,
|
|
|
|
"Pad1 type = 0x%02X",
|
|
|
|
PadOneGetType() );
|
|
|
|
|
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD1_ID_TEXT_X,
|
|
|
|
DEVMENU_PAD1_ID_TEXT_Y,
|
|
|
|
"Pad1 ID = 0x%02X",
|
|
|
|
PadOneGetID() );
|
|
|
|
|
2017-08-06 04:17:09 +02:00
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD1_RAW_DATA_TEXT_X,
|
|
|
|
DEVMENU_PAD1_RAW_DATA_TEXT_Y,
|
|
|
|
"Pad1 raw data = 0x%04X",
|
|
|
|
PadOneGetRawData() );
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD2_STATUS_TEXT_X,
|
|
|
|
DEVMENU_PAD2_STATUS_TEXT_Y,
|
|
|
|
"Pad2 connected = %d",
|
|
|
|
PadTwoConnected() );
|
|
|
|
|
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD2_TYPE_TEXT_X,
|
|
|
|
DEVMENU_PAD2_TYPE_TEXT_Y,
|
|
|
|
"Pad2 type = 0x%02X",
|
|
|
|
PadTwoGetType() );
|
|
|
|
|
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD2_ID_TEXT_X,
|
|
|
|
DEVMENU_PAD2_ID_TEXT_Y,
|
|
|
|
"Pad2 ID = 0x%02X",
|
|
|
|
PadTwoGetID() );
|
|
|
|
|
2017-08-06 04:17:09 +02:00
|
|
|
FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_PAD2_RAW_DATA_TEXT_X,
|
|
|
|
DEVMENU_PAD2_RAW_DATA_TEXT_Y,
|
|
|
|
"Pad2 raw data = 0x%04X",
|
|
|
|
PadTwoGetRawData() );
|
|
|
|
|
2017-08-09 22:51:15 +02:00
|
|
|
/*FontPrintText( &SmallFont,
|
|
|
|
DEVMENU_ROOTCNT2_TEXT_X,
|
|
|
|
DEVMENU_ROOTCNT2_TEXT_Y,
|
|
|
|
"Timer2 = 0x%04X",
|
|
|
|
GetRCnt(2) );*/
|
|
|
|
|
2017-07-27 07:41:25 +02:00
|
|
|
FontPrintText( &SmallFont,
|
2017-08-09 22:51:15 +02:00
|
|
|
DEVMENU_ROOTCNT2_TEXT_X,
|
|
|
|
DEVMENU_ROOTCNT2_TEXT_Y,
|
|
|
|
"Timer2 = 0x%04X, timer2 = 0x%04X",
|
|
|
|
u16_0_01seconds_cnt, GetRCnt(2) );
|
2017-07-27 07:41:25 +02:00
|
|
|
}
|
|
|
|
}
|
2017-12-30 00:58:57 +01:00
|
|
|
|
2018-03-10 14:30:40 +01:00
|
|
|
void SystemGetFileBasename(const char* fileName, char* str, const size_t sz)
|
2017-12-30 00:58:57 +01:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
size_t j = 0;
|
2018-03-10 14:30:40 +01:00
|
|
|
const size_t len = strlen(fileName);
|
2017-12-30 00:58:57 +01:00
|
|
|
|
|
|
|
memset(str, 0, sz);
|
|
|
|
|
|
|
|
for (i = (len - 1); fileName[i] != '\\'; i--);
|
|
|
|
|
|
|
|
i++; // Skip '\\' character.
|
|
|
|
|
2018-11-18 20:03:35 +01:00
|
|
|
for (; fileName[i]; i++)
|
2017-12-30 00:58:57 +01:00
|
|
|
{
|
|
|
|
str[j++] = fileName[i];
|
|
|
|
}
|
|
|
|
}
|