rtc.c 5.95 KB
#include "ultra64.h"
#include "os_bb.h"
#include "bcp.h"
#include "os_bb.h" 
#include "bbskapi.h" 
#include "libfb.h" 

#include "rtc.h"


#define DMA_QUEUE_SIZE	200
#define PRINTF		osSyncPrintf

#define IDE_PRINT
#define SCREEN_LOW
#ifdef SCREEN_LOW
static u16 cfb[2][320*240] __attribute__((aligned(64)));
#else
static u16 cfb[2][640*480] __attribute__((aligned(64)));
#endif


/*
 * Thread and stack structures
 */
char   bootStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread idleThread;
static char     idleThreadStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread mainThread;
static char     mainThreadStack[STACKSIZE] __attribute__ ((aligned (8)));


/*
 * Message queues and message buffers used by this app 
 */
static OSMesg           PiMessages[DMA_QUEUE_SIZE], dmaMessageBuf;
static OSMesgQueue      PiMessageQ, dmaMessageQ;

static OSMesg           SiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      SiMessageQ, contMessageQ;

/*
 * Local variables and routines
 */

static void		idleproc(char *);
static void		mainproc(char *);

void
boot(void)
{
    osInitialize();
    osCreateThread(&idleThread, 1, (void(*)(void *))idleproc, (void *)0,
                   idleThreadStack+STACKSIZE, 8);
    osStartThread(&idleThread);
}


static void
idleproc(char *argv)		/* priority 8 */
{
    osCreateViManager(OS_PRIORITY_VIMGR);
#ifdef SCREEN_LOW
    fbInit(FB_LOW_RES);
#else
    fbInit(FB_HIGH_RES);
#endif

    /*
     * Start PI Mgr for access to cartridge - start before the debugger
     */
    osCreatePiManager((OSPri) OS_PRIORITY_PIMGR, &PiMessageQ, PiMessages,
            DMA_QUEUE_SIZE);

    osCreateMesgQueue(&dmaMessageQ, &dmaMessageBuf, 1);
    osCreateMesgQueue(&SiMessageQ, SiMessages, DMA_QUEUE_SIZE);
    osSetEventMesg(OS_EVENT_SI, &SiMessageQ, (OSMesg)DMA_QUEUE_SIZE);

    /*
     * The main thread's priority must be the same or lower than the original
     * idle's thread priority. This allows the idle thread to change its
     * priority to 0 before the main thread starts execution.
     */
    osCreateThread(&mainThread, 3, (void(*)(void *))mainproc, argv,
           mainThreadStack+STACKSIZE/8, (OSPri)7);
    osStartThread(&mainThread);

    osSetThreadPri(0, OS_PRIORITY_IDLE);
    for(;;);                                    /* idle thread */
}

static OSMesgQueue	retraceMessageQ;
static OSMesg		dummyMessage, retraceMessageBuf;

OSContStatus statusData[MAXCONTROLLERS];
OSContPad controllerData[MAXCONTROLLERS];
static u16 lastbutton[MAXCONTROLLERS];

static int no_controller = 1;
static void
initController(void)
{
    int i;
    u8 pattern;

    osCreateMesgQueue(&contMessageQ, &dummyMessage, 1);
    osSetEventMesg(OS_EVENT_SI, &contMessageQ, (OSMesg) 0);

    osContInit(&contMessageQ, &pattern, &statusData[0]);

    for (i = 0; i < MAXCONTROLLERS; i++) {
        if ((pattern & (1 << i)) &&
            !(statusData[i].errno & CONT_NO_RESPONSE_ERROR)) {
            no_controller = 0;
        }
    }
}


#define NR_DATE 	7
u8 _d[NR_DATE];
const u8 lower[] = { 0,  1,  1, 1,  0,  0,  0 };
const u8 upper[] = {99, 12, 31, 7, 23, 59, 59 };
const u8 map[] = { 3, 1, 2, 0, 4, 5, 6 };
int which = 3, _w;

static void
update(void) {
    osBbRtcSet(_d[0], _d[1], _d[2], _d[3], _d[4], _d[5], _d[6]);
}

static void
processButton(u16 button, int lastbutton)
{
    if (button & D_JPAD && !(lastbutton & D_JPAD)) {
	if (_d[which] == lower[which]) _d[which] = upper[which];
	else _d[which]--;
	update();
    }

    if (button & U_JPAD && !(lastbutton & U_JPAD)) {
	if (_d[which] == upper[which]) _d[which] = lower[which];
	else _d[which]++;
	update();
    }

    if (button & R_JPAD && !(lastbutton & R_JPAD)) {
	if (++_w >= NR_DATE) _w = 0;
	which = map[_w];
    }

    if (button & L_JPAD && !(lastbutton & L_JPAD)) {
	if (--_w < 0) _w = NR_DATE-1;
	which = map[_w];
    }

    if (button & B_BUTTON && !(lastbutton & B_BUTTON)) {
    }

    if (button & A_BUTTON && !(lastbutton & A_BUTTON)) {
    }

    if (button & START_BUTTON && !(lastbutton & START_BUTTON)) {
	skExit();
    }

    if ((button & Z_TRIG) && !(lastbutton & Z_TRIG)) {
    }
}

static void
readControllers(void)
{
    int i;
    OSContPad *pad;

    osRecvMesg(&contMessageQ, &dummyMessage, OS_MESG_BLOCK); 
    osContGetReadData(controllerData);

    for (i = 0; i < MAXCONTROLLERS; ++i) {
        pad = &controllerData[i];
        if (pad->button) {
            processButton(pad->button, lastbutton[i]);
        }
        lastbutton[i] = pad->button;
    }
}

static void 
mainproc(char *argv)		{
    const char* month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
	                  "Aug", "Sep", "Oct", "Nov", "Dec" };
    const char* day[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    const u8 pos[] = { 3, 7, 10, 15, 19, 22, 25 };
    /* dow month day year hour min sec */
    /* year month day dow hour min sec */
    //const u8 pos[] = { 15, 7, 10, 3, 19, 22, 25 };

    osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
    osViSetEvent(&retraceMessageQ, dummyMessage, 1);
    osViBlack(1);
    osViSwapBuffer(cfb);
    fbSetBg(fbBlack);
    fbClear();
    osViBlack(0);
    osWritebackDCacheAll();
    osViSwapBuffer(cfb);
    initController();
    osBbRtcInit();

    for(;;) {
	int i;
	osRecvMesg(&retraceMessageQ, NULL, OS_MESG_BLOCK);
	osContStartReadData(&contMessageQ);
	osBbRtcGet(_d+0, _d+1, _d+2, _d+3, _d+4, _d+5, _d+6);
	for(i = 0; i < 7; i++) {
	    if (_d[i] > upper[i]) _d[i] = upper[i];
	    if (_d[i] < lower[i]) _d[i] = lower[i];
	}
	readControllers();
	osBbRtcGet(_d+0, _d+1, _d+2, _d+3, _d+4, _d+5, _d+6);
	for(i = 0; i < 7; i++) {
	    if (_d[i] > upper[i]) _d[i] = upper[i];
	    if (_d[i] < lower[i]) _d[i] = lower[i];
	}
	//PRINTF("%d %d %d %d %d %d %d\n", _d[0], _d[1], _d[2], _d[3], _d[4], _d[5], _d[6]);
	fbPrintf(fbWhite, 7, 10, "%3s %3s %2d 20%02d  %02d:%02d:%02d\n", day[_d[3]-1], month[_d[1]-1], _d[2], _d[0], _d[4], _d[5], _d[6]);
	fbPrintf(fbWhite, 7, 11, "                                             ");
	fbPrintf(fbWhite, 6+pos[_w], 11, "-");
	osWritebackDCacheAll();
    }
}