#include #include "console.h" #include "screen.h" #include "charmap.h" #define MEM30 0x90140030 #define MEM20 0x90140020 #define MEM10 0x90140810 #define CONFIG_FILE "/documents/ndless/noverII.cfg.tns" #define BASE 12 #define MULT_BITS_MAX 8 #define MULT_BITS 6 #define DIV1_BITS 5 #define DIV2_BITS 4 typedef unsigned char u8; typedef unsigned short int u16; typedef unsigned long int u32; u8 mode = 1; u8 mult_orig; u8 div1_orig; u8 div2_orig; u8 mult_last; u8 div1_last; u8 div2_last; typedef struct { u32 config30; u32 config20; u32 config10; u8 auto_mode; // 1 starting | 2 looking | 4 validating u32 autoconfig30; u32 autoconfig20; u32 autoconfig10; u8 last_fail_mult1; // crash config to recheck u8 last_fail_mult2; // crash config to avoid } state; void calcPi() { int a[52514],b,c=52514,d,e,f=1e4,g,h; for(;b=c-=14;h=e+d/f) for(e=d%=f;g=--b*2;d/=g) { d=d*b+f*(h?a[b]:f/5); a[b]=d%--g; } } u8 copy(char* src, char* dst) { FILE* in = fopen(src,"rb"); FILE* out = fopen(dst,"wb"); char buf[1024]; int read = 0; while(read = fread(buf,1,1024,in)) fwrite(buf,read,1,out); fclose(in); fclose(out); return 1; } u32 bits_max(u8 b) { return (1<1) { (*d1)--; return 1; } return 0; } u8 increaseFreq2(u8* m, u8* d1, u8* d2) { if(*d2) { (*d2)--; return 1; } return 0; } u8 decreaseBase(u8* m, u8* d1, u8* d2) { if(*m) { (*m)--; return 1; } return 0; } u8 decreaseFreq1(u8* m, u8* d1, u8* d2) { if(*d1warnh || valwarnh || val> 24)&bits_max(MULT_BITS); *d1 = (config30 >> 16)&bits_max(DIV1_BITS); *d2 = (config20 >> 20)&bits_max(DIV2_BITS); } extern short int sscreen[SCREEN_PIXELS]; void removeTFiles() { remove("/documents/ndless/startup/z/z.tns"); rmdir("/documents/ndless/startup/z/"); } void consolehead() { resetConsole(); memcpy(getScreen(),sscreen,SCREEN_SIZE); displn("",0,1); displn("",0,1); displn("",0,1); displn("",0,1); displn("",0,1); displn("",0,1); displn("",0,1); displn("",0,1); displn(" *=^.^=* Welcome to NoverII *=^.^=* ",0,1); displn("",0,1); } int consolefoot() { displn("",0,1); displn("Setup may crash or freeze :",0,1); displn("-In case of a freeze, reset the Nspire",0,1); displn("-In both cases, reenable Ndless to go on",0,1); displn("",0,0); displn("Disconnect the USB.",0,1); displn("",0,1); disp("Starting in... ",0,1); return timer(10); } int main(int argc, char* argv[]) { state mystate; printf("Running %s\n",argv[0]); memset(&mystate,0,sizeof(state)); u32 orig_config30 = getMem(MEM30); u32 orig_config20 = getMem(MEM20); u32 orig_config10 = getMem(MEM10); u8 hwtype = nl_hwtype(); u8 hwsubtype = nl_hwsubtype(); u8 s = getState(&mystate); if(!nl_isstartup()) mystate.auto_mode=0; if(nl_isstartup() && hwtype==1 && hwsubtype==2) { if(s && !mystate.auto_mode) { setConfig(mystate.config30,mystate.config20,mystate.config10); return; } else if(!mystate.auto_mode) { mystate.auto_mode=1; mystate.autoconfig30=orig_config30; mystate.autoconfig20=orig_config20; mystate.autoconfig10=orig_config10; mystate.last_fail_mult1=0; mystate.last_fail_mult2=0; } } int c=0; initScreen(); startScreen(); convertRGB565(sscreen); if (hwtype!=1 || hwsubtype!=2) { consolehead(); disp("FATAL : This a TI-Nspire ",0,1); if(!hwtype) displn("classic",0,1); else if(hwsubtype==0) displn("CX",0,1); else if(hwsubtype==1) displn("CM",0,1); else displn("Unknown",0,1); displn("NoverII requires a TI-Nspire CX II",0,1); displn("",0,1); displn("Press a key to exit...",0,1); while(any_key_pressed()); while(!any_key_pressed()); consolefoot(0); c=-1; } mystate.config30=orig_config30; mystate.config20=orig_config20; mystate.config10=orig_config10; mult_orig=getMultConfig(orig_config30,orig_config20,orig_config10); div1_orig=getDiv1Config(orig_config30,orig_config20,orig_config10); div2_orig=getDiv2Config(orig_config30,orig_config20,orig_config10); div1_last=div1_orig; div2_last=div2_orig; mult_last=mult_orig; u32 last_config30=orig_config30; u32 last_config20=orig_config20; u32 last_config10=orig_config10; unsigned char* buf = malloc(SCREEN_SIZE); memcpy(buf,sscreen,SCREEN_SIZE); while(!isKeyPressed(KEY_NSPIRE_ESC) && c>=0) { c=0; if(mystate.auto_mode) { int i=0; if(mystate.auto_mode==1) { consolehead(); displn("Config not found.",0,1); displn("Setup is going to start.",0,1); i=consolefoot(1); } else if(mystate.autoconfig30!=getMem(MEM30)) { // unexpected reboot (crash/freeze) consolehead(); int j = getBaseConfig(mystate.autoconfig30,mystate.autoconfig20,mystate.autoconfig10); disp("Reset detected : ",0,1); dispi(j,0,1); disp(" MHz ",0,1); int last_fail_mult=getMultConfig(mystate.autoconfig30,mystate.autoconfig20,mystate.autoconfig10); if(!mystate.last_fail_mult2 || mystate.last_fail_mult2+1base) if(!decreaseBaseConfig(&(mystate.autoconfig30),&(mystate.autoconfig20),&(mystate.autoconfig10))) break; } else if(mystate.autoconfig30!=getMem(MEM30)) { // unexpected reboot (crash/freeze) displn("Reset detected - recovering...",0,1); int last_fail_mult=getMultConfig(mystate.autoconfig30,mystate.autoconfig20,mystate.autoconfig10); if(!mystate.last_fail_mult2) mystate.last_fail_mult2=last_fail_mult; else { if(mystate.last_fail_mult2+1>=last_fail_mult) { mystate.last_fail_mult1=min(last_fail_mult,mystate.last_fail_mult2); mystate.last_fail_mult2=0; } else mystate.last_fail_mult2=last_fail_mult; } } // keep on looking for best safe config else if(!(mystate.auto_mode&4)) { if(!increaseBaseConfig(&(mystate.autoconfig30),&(mystate.autoconfig20),&(mystate.autoconfig10))) mystate.auto_mode=0; // max config reached } else { // validating config (using safe margin) decreaseBaseConfig(&(mystate.autoconfig30),&(mystate.autoconfig20),&(mystate.autoconfig10)); decreaseBaseConfig(&(mystate.autoconfig30),&(mystate.autoconfig20),&(mystate.autoconfig10)); mystate.auto_mode=0; } while(mystate.last_fail_mult1 && getMultConfig(mystate.autoconfig30,mystate.autoconfig20,mystate.autoconfig10)>=mystate.last_fail_mult1) { // best config reached if(!decreaseBaseConfig(&(mystate.autoconfig30),&(mystate.autoconfig20),&(mystate.autoconfig10))) break; mystate.auto_mode|=4; } dispStateConfig(buf, mystate.autoconfig30, mystate.autoconfig20, mystate.autoconfig10); memcpy(getScreen(),buf,SCREEN_SIZE); setConfig(last_config30,last_config20,last_config10); if(!mystate.auto_mode) { removeTFiles(); mystate.config30=mystate.autoconfig30; mystate.config20=mystate.autoconfig20; mystate.config10=mystate.autoconfig10; c=-1; } setState(&mystate); setConfig(mystate.autoconfig30,mystate.autoconfig20,mystate.autoconfig10); } else { dispStateConfig(buf, mystate.config30, mystate.config20, mystate.config10); memcpy(getScreen(),buf,SCREEN_SIZE); while(!isKeyPressed(KEY_NSPIRE_ESC) && !c) { if(isKeyPressed(KEY_NSPIRE_VAR)) setState(&mystate); if(isKeyPressed(KEY_NSPIRE_SHIFT)) if(getState(&mystate)) c=1; if(isKeyPressed(KEY_NSPIRE_UP) || isKeyPressed(KEY_NSPIRE_8)) { mode--; if(mode<=0) mode=3; c=1; } if(isKeyPressed(KEY_NSPIRE_DOWN) || isKeyPressed(KEY_NSPIRE_2)) { mode=(mode%3)+1; c=1; } if(mode==1) { if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseBaseConfig(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseBaseConfig(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; } else if(mode==2) { if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseFreq1Config(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseFreq1Config(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; } else if(mode==3) { if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseFreq2Config(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseFreq2Config(&(mystate.config30),&(mystate.config20),&(mystate.config10))) c=1; } if(isKeyPressed(KEY_NSPIRE_ENTER) || isKeyPressed(KEY_NSPIRE_CLICK) || isKeyPressed(KEY_NSPIRE_5)) { last_config30=mystate.config30; last_config20=mystate.config20; last_config10=mystate.config10; mult_last=getMultConfig(last_config30,last_config20,last_config10); div1_last=getDiv1Config(last_config30,last_config20,last_config10); div2_last=getDiv2Config(last_config30,last_config20,last_config10); setConfig(last_config30,last_config20,last_config10); c=1; } if(c) msleep(200); } } } stopScreen(); free(buf); return 0; }