#include #include "console.h" #include "screen.h" #include "charmap.h" #define MEM1 0x900B0000 #define MEM2 0x900B000C #define CONFIG_FILE "/documents/ndless/nover.cfg.tns" #define BASE_MAX (has_colors?378:300) #define BASE_MIN (has_colors?0:27) #define CPU_MAX (has_colors?BASE_MAX:BASE_MAX/2) #define AHB_MAX CPU_MAX #define AHB_CX_WARN 66 #define AHB_CXCR4_WARN 78 int base_orig; int cpu_orig; int ahb_orig; int base_last; int cpu_last; int ahb_last; int m=1; typedef struct { int config; int auto_mode; // 1 starting | 2 looking | 4 validating int autoconfig; int last_fail_base1; // crash config to recheck int last_fail_base2; // 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; } } int 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; } int increaseCPU(unsigned int* b3, unsigned int* r1) { if(*r1>1 || (*b3==0b10 || *b3==0 && has_colors)) { if(*r1>1) (*r1)--; else *b3=0b01; return 1; } return 0; } int decreaseAHB(unsigned int* r2) { if(*r2<0b111) { (*r2)++; return 1; } return 0; } int increaseAHB(unsigned int* r2) { if((*r2>0 && has_colors) || *r2>1) { (*r2)--; return 1; } return 0; } int decreaseCPU(unsigned int* b3, unsigned int* r1) { if(*r1<0b1111111 || *b3==0b01) { if(*b3==0b01) { *b3=0b10; *r1=1; } else (*r1)++; return 1; } return 0; } int increaseBase(int* b1, int* b2) { if((*b2>0 && !has_colors) || (*b2<0b111111 && has_colors)) { if(*b1) { *b1=0; if(has_colors) *b2=8; else *b2=0b100000; } if(has_colors) (*b2)++; else (*b2)--; return 1; } return 0; } int increaseBaseconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(increaseBase(&b1,&b2)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int decreaseBase(int* b1, int* b2) { if((!*b1 && !has_colors) || (*b2>0 && has_colors)) { if(*b1 && has_colors) { *b1=0; *b2=8; } if(!*b1) { if(has_colors) { (*b2)--; } else { if(*b2<0b11111) (*b2)++; else *b1=1; } } return 1; } return 0; } int decreaseBaseconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(decreaseBase(&b1,&b2)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int decreaseAHBconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(decreaseAHB(&r2)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int increaseAHBconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(increaseAHB(&r2)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int decreaseCPUconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(decreaseCPU(&b3,&r1)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int increaseCPUconfig(int* config) { int b1,b2,b3,r1,r2; extrConfig(*config,&b1,&b2,&b3,&r1,&r2); if(increaseCPU(&b3,&r1)) { *config=makeConfig(b1,b2,b3,r1,r2); return 1; } return 0; } int getState( state* mystate) { FILE* h=fopen(CONFIG_FILE,"r"); if(h) { memset(mystate,0,sizeof(state)); fread(mystate,1,sizeof(state),h); fclose(h); return 1; } return 0; } int setState( state* mystate) { FILE* h=fopen(CONFIG_FILE,"w"); if(h) { fwrite(mystate,sizeof(state),1,h); fclose(h); return 1; } return 0; } void delState() { remove(CONFIG_FILE); } void drawBar(unsigned char* buf, int x1, int y1, int x2, int y2, char* title, int min, int maxth, int max, int val, int def, int last, int selected, int r, int g, int b, int warnh, int warnl) { int x=x1+(x2-x1)*(val-min)/(maxth-min); int xr=x1+(x2-x1)*(def-min)/(maxth-min); int xm=x1+(x2-x1)*(max-min)/(maxth-min); int xl=x1+(x2-x1)*(last-min)/(maxth-min); char* w=""; char tmp[42]; if(val<0) x=x2; if(last<0) xl=x2; if(def<0) xr=x2; sprintf(tmp,"%i",min); drwBufStr(buf,x1+2,y1,tmp,0,1); drwBufVert(buf,x1,y1,y1+CHAR_HEIGHT); if(max==maxth) { sprintf(tmp,"%i",maxth); drwBufStr(buf,x2-strlen(tmp)*CHAR_WIDTH,y1,tmp,0,1); drwBufVert(buf,x2,y1,y2-CHAR_HEIGHT); } else { sprintf(tmp,"%i",max); drwBufStr(buf,xm+2,y1,tmp,0,1); drwBufVert(buf,xm,y1,y2-CHAR_HEIGHT); } if(!has_colors) { r=r/2; g=g/2; b=b=b/2; } setCurColorRGB(r,g,b); drawBufFullBox(buf,x1+2,y1+2+CHAR_HEIGHT,x,y2-2-CHAR_HEIGHT); setCurColorRGB(0,0,0); drwBufBox(buf,x1,y1+CHAR_HEIGHT,xm,y2-CHAR_HEIGHT); if(selected) { drwBufBox(buf,x1+1,y1+CHAR_HEIGHT+1,xm-1,y2-CHAR_HEIGHT-1); drwBufBox(buf,x1,y1+CHAR_HEIGHT-1,xm,y2-CHAR_HEIGHT+1); } if(val>warnh || valwarnh || val>8; if(has_colors) *b2 = (config & 0b00111111000000000000000)>>15; else *b2 = (config & 0b00111110000000000000000)>>16; *b3=0; if(has_colors) *b3 = (config & 0b11000000000000000000000)>>21; *r1 = (config & 0b00000000000000011111110)>>1; *r2 = (config & 0b00000000111000000000000)>>12; } int getBase(int b1, int b2) { int base; if(has_colors) { base = 48; if(!b1) base = 6*b2; } else { base = 27; if(!b1) base = 300 - 6*b2; } return base; } int getBaseconfig(int config) { int b1,b2,b3,r1,r2; extrConfig(config,&b1,&b2,&b3,&r1,&r2); return getBase(b1,b2); } int getDivisor1(int r1, int b3) { int d = r1*2; if(has_colors && b3==0b01) d=d/2; return d; } int getDivisor2(int r2) { if(has_colors) r2++; return r2; } 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 Nover *=^.^=* ",0,1); displn("",0,1); } int consolefoot() { displn("",0,1); displn("Setup will crash at least 2 times.",0,1); displn("Reenable Ndless each time to go on.",0,1); displn("",0,0); displn("",0,1); disp("Starting in... ",0,1); return timer(10); } int main(int argc, char* argv[]) { state mystate; memset(&mystate,0,sizeof(state)); int orig_config = getMem(MEM1); int hw_type = nl_hwtype(); int hw_subtype = nl_hwsubtype(); int s = getState(&mystate); if(nl_isstartup() && (!hw_type || hw_type && hw_subtype<=1)) { if(s && !mystate.auto_mode) { setConfig(mystate.config); return; } else if(!mystate.auto_mode) { mystate.auto_mode=1; mystate.autoconfig=orig_config; mystate.last_fail_base1=0; mystate.last_fail_base2=0; } } int c=0; initScreen(); startScreen(); convertRGB565(sscreen); if (hw_type && hw_subtype>=2) { consolehead(); disp("FATAL : This a TI-Nspire ",0,1); if(hw_subtype==2) displn("CX II",0,1); else displn("unknown",0,1); displn("Nover requires a TI-Nspire CX/CM/classic",0,1); displn("",0,1); displn("Press a key to exit...",0,1); while(any_key_pressed()); while(!any_key_pressed()); c=-1; } mystate.config=orig_config; // int ahbm=has_colors?((screenType()==SCR_240x320_565)?AHB_CXCR4_WARN:AHB_CX_WARN):AHB_MAX; int ahbm=has_colors?(AHB_CXCR4_WARN):AHB_MAX; unsigned char* buf = malloc(SCREEN_SIZE); base_orig=getBaseconfig(orig_config); cpu_orig=getCPUconfig(orig_config); ahb_orig=getAHBconfig(orig_config); cpu_last=cpu_orig; ahb_last=ahb_orig; base_last=base_orig; int last_config=orig_config; 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(); } else if(mystate.autoconfig!=getMem(MEM1)) // unexpected reboot (crash/freeze) { consolehead(); int j = getBaseconfig(mystate.autoconfig); disp("Reset detected : ",0,1); dispi(j,0,1); disp(" MHz ",0,1); int last_fail_base=getBaseconfig(mystate.autoconfig); if(!mystate.last_fail_base2 || mystate.last_fail_base2+6cpu) if(!decreaseBaseconfig(&(mystate.autoconfig))) break; } else if(mystate.autoconfig!=getMem(MEM1)) // unexpected reboot (crash/freeze) { displn("Reset detected - recovering...",0,1); int last_fail_base=getBaseconfig(mystate.autoconfig); if(!mystate.last_fail_base2) mystate.last_fail_base2=last_fail_base; else { if(mystate.last_fail_base2+6>=last_fail_base) { mystate.last_fail_base1=min(last_fail_base,mystate.last_fail_base2); mystate.last_fail_base2=0; } else mystate.last_fail_base2=last_fail_base; } } // keep on looking for best safe config else if(!(mystate.auto_mode&4)) { if(!increaseBaseconfig(&(mystate.autoconfig))) mystate.auto_mode=0; // max config reached } else // validating config (using safe margin) { decreaseBaseconfig(&(mystate.autoconfig)); decreaseBaseconfig(&(mystate.autoconfig)); mystate.auto_mode=0; } while(mystate.last_fail_base1 && getBaseconfig(mystate.autoconfig)>=mystate.last_fail_base1) { // best config reached if(!decreaseBaseconfig(&(mystate.autoconfig))) break; mystate.auto_mode|=4; } while(getAHBconfig(mystate.autoconfig)<=ahbm) if(!increaseAHBconfig(&(mystate.autoconfig))) break; while(getAHBconfig(mystate.autoconfig)>ahbm) if(!decreaseAHBconfig(&(mystate.autoconfig))) break; dispcpuconfig(buf, mystate.autoconfig); memcpy(getScreen(),buf,SCREEN_SIZE); setConfig(last_config); if(!mystate.auto_mode) { removeTFiles(); mystate.config=mystate.autoconfig; c=-1; } setState(&mystate); setConfig(mystate.autoconfig); } else { dispcpuconfig(buf, mystate.config); memcpy(getScreen(),buf,SCREEN_SIZE); while(!isKeyPressed(KEY_NSPIRE_ESC) && !c) {/* if(isKeyPressed(KEY_NSPIRE_A)) { delState(); mystate.auto_mode=1; c=1; }*/ 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)) { m--; if(m<=0) m=3; c=1; } if(isKeyPressed(KEY_NSPIRE_DOWN) || isKeyPressed(KEY_NSPIRE_2)) { m++; if(m>3) m=1; c=1; } if(m==1) { if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseBaseconfig(&(mystate.config))) c=1; if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseBaseconfig(&(mystate.config))) c=1; } else if(m==2) { if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseCPUconfig(&(mystate.config))) c=1; if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseCPUconfig(&(mystate.config))) c=1; } else if(m==3) { if((isKeyPressed(KEY_NSPIRE_MINUS) || isKeyPressed(KEY_NSPIRE_4) || isKeyPressed(KEY_NSPIRE_LEFT))) if(decreaseAHBconfig(&(mystate.config))) c=1; if((isKeyPressed(KEY_NSPIRE_PLUS) || isKeyPressed(KEY_NSPIRE_6) || isKeyPressed(KEY_NSPIRE_RIGHT))) if(increaseAHBconfig(&(mystate.config))) c=1; } if(isKeyPressed(KEY_NSPIRE_ENTER) || isKeyPressed(KEY_NSPIRE_CLICK) || isKeyPressed(KEY_NSPIRE_5)) { last_config=mystate.config; base_last=getBaseconfig(last_config); cpu_last=getCPUconfig(last_config); ahb_last=getAHBconfig(last_config); setConfig(last_config); c=1; } if(c) wait(200); } } } stopScreen(); free(buf); return 0; }