219 lines
5.1 KiB
C
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);
|
||
|
}
|
||
|
|
||
|
/****************************************/
|