PkBadApple/player/pocketlib.h

219 lines
5.1 KiB
C

/****************************************/
/* PocketStation Lib - by Orion_ [2013] */
/****************************************/
// Based on Miko Hoshina & Martin Korth work.
// If you use it, please give credits !
// v3.6
// Optional Functions, don't define this in your main .c file do reduce size
//#define USE_SPRITE
//#define USE_RANDOM
//#define USE_SOUND
#ifndef NULL
#define NULL ((void*)0)
#endif
#ifndef CLOCK_SPEED
#define CLOCK_SPEED CLOCK_4M
#endif
#ifndef FPS
#define FPS 64
#endif
#ifndef SOUND_FREQ
#define SOUND_FREQ 4000 // If 8000Hz, then use CLOCK_8M !
#endif
/**/
#define PAD_BUTTON 0x1
#define PAD_RIGHT 0x2
#define PAD_LEFT 0x4
#define PAD_DOWN 0x8
#define PAD_UP 0x10
#define PAD_STATUS ((IRQ_STATUS_RAW) & 0x1F)
int PadOnRelease, PadOnPress;
/**/
#define LCD_ON 0x40
#define LCD_OFF 0x00
#define LCD_64HZ 0x10
#define LCD_32HZ 0x20
#define LCD_16HZ 0x30
#define LCD_CPEN 0x08
#define LCD_MODE *((volatile unsigned int *)0xD000000)
#define LCD_VRAM(_line_) *((volatile unsigned int *)(0xD000100+(_line_ << 2)))
#define LCD_VRAM_ADRS (volatile unsigned int *)0xD000100
/**/
#define CLOCK_62_5K 0x1
#define CLOCK_125K 0x2
#define CLOCK_250K 0x3
#define CLOCK_500K 0x4
#define CLOCK_1M 0x5
#define CLOCK_2M 0x6
#define CLOCK_4M 0x7
#define CLOCK_8M 0x8
/**/
#define TIMER0_START() *((volatile unsigned int *)(0xA800008)) |= 0x4
#define TIMER1_START() *((volatile unsigned int *)(0xA800018)) |= 0x4
#define TIMER2_START() *((volatile unsigned int *)(0xA800028)) |= 0x4
#define TIMER0_STOP() *((volatile unsigned int *)(0xA800008)) &= ~0x4
#define TIMER1_STOP() *((volatile unsigned int *)(0xA800018)) &= ~0x4
#define TIMER2_STOP() *((volatile unsigned int *)(0xA800028)) &= ~0x4
#define TIMER0_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800000)) = (_x_)
#define TIMER1_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800010)) = (_x_)
#define TIMER2_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800020)) = (_x_)
/**/
#define FIQ_COMM 0x40
#define IRQ_TIMER0 0x80
#define IRQ_TIMER1 0x100
#define IRQ_RTC 0x200
#define IRQ_BATTERY 0x400
#define IRQ_PSCOMM 0x800
#define IRQ_INFRARED 0x1000
#define FIQ_TIMER2 0x2000
#define IRQ_STATUS *((volatile unsigned int *)(0xA000000))
#define IRQ_STATUS_RAW *((volatile unsigned int *)(0xA000004))
#define IRQ_ENABLE *((volatile unsigned int *)(0xA000008))
#define IRQ_DISABLE *((volatile unsigned int *)(0xA00000c))
#define IRQ_CLEAR *((volatile unsigned int *)(0xA000010))
#define IRQ_DISABLE_ALL() IRQ_DISABLE = 0x3FFF;
/**/
#define IOCTL_CONFIG *((volatile unsigned int *)0xD800000)
#define IOCTL_OFF *((volatile unsigned int *)0xD800004)
#define IOCTL_ON *((volatile unsigned int *)0xD800008)
#define IOCTL_DAC *((volatile unsigned int *)0xD800010)
#define IOCTL_DASOUND *((volatile unsigned int *)0xD800014)
#define IOCTL_BATTERY *((volatile unsigned int *)0xD800020)
#define IOCTL_LED 0x02
#define IOCTL_SPEAKER 0x20
#define IOCTL_IRDA 0x40
/****************************************/
// From header.S
// Bios Calls
void *SetCallbacks(int index, void (*function));
int SetCpuSpeed(int speed);
int PrepareExecute(int flag, int dir_index, int param);
void DoExecute(int snapshot_flag);
void SetComOnOff(int flag);
int GetDirIndex(void);
// IRQ/FIQ Asm
void IntIRQ(void);
void IntFIQ(void);
void (*UserIRQ)(void);
int (*UserFIQ)(void); // Return 1 to Skip Library Sound Processing, else return 0
/****************************************/
// IRQ/Timer0 Handler (for VSync)
volatile int VCount;
void IRQ_Handler(void)
{
int status;
status = IRQ_STATUS;
status &= IRQ_ENABLE;
status &= ~(FIQ_TIMER2 | FIQ_COMM); // Clear FIQ Bits
if (status & IRQ_TIMER0)
VCount++;
if (UserIRQ)
UserIRQ();
IRQ_CLEAR = status;
}
/****************************************/
// FIQ/Timer2 Handler (for Sound)
void FIQ_Handler(void)
{
IRQ_CLEAR = FIQ_TIMER2;
}
/****************************************/
// Sync Functions
void VSync()
{
register int cnt = VCount;
register int PadState = PAD_STATUS;
PadOnRelease = PadState;
PadOnRelease ^= PadOnPress;
PadOnRelease &= PadOnPress;
PadOnPress = PadState;
while (VCount == cnt); // Wait For IRQ Timer0
}
/****************************************/
// Init, need to be called at first !
void PocketInit(void)
{
SetCpuSpeed(CLOCK_SPEED);
IRQ_DISABLE_ALL();
UserIRQ = NULL;
UserFIQ = NULL;
VCount = 0;
PadOnRelease = 0;
PadOnPress = 0;
SetCallbacks(1, IntIRQ); // VSync Interrupt
SetCallbacks(2, IntFIQ); // Audio Interrupt
IRQ_CLEAR = IRQ_TIMER0 | FIQ_TIMER2;
IRQ_ENABLE = IRQ_TIMER0 | FIQ_TIMER2;
// Start VSync Timer
TIMER0_SETCOUNT((15625 << CLOCK_SPEED) / FPS);
TIMER0_START();
while (PAD_STATUS & PAD_BUTTON); // Wait for Button Release (Button pressed when comming from Menu)
}
/****************************************/
// Exit, need to be called to exit app !
void PocketExit(void)
{
SetComOnOff(0);
TIMER0_STOP();
TIMER2_STOP();
IRQ_DISABLE_ALL();
IRQ_ENABLE = IRQ_RTC | IRQ_PSCOMM;
PrepareExecute(1, 0, GetDirIndex() | 0x30); // Return to GUI on our Program Icon
DoExecute(0);
}
/****************************************/