// romto8xu.cpp : définit le point d'entrée pour l'application console. // #define PAGE_SIZE (16*1024) #include "stdio.h" #include "string.h" #include "stdlib.h" char rombuffer[0x400000]; int romind=0; int romsize=0; int romgetc() { unsigned char c = rombuffer[romind++]; return c; } void readversion(int* a, int* b, int i) { *a=0; *b=0; int* t = a; while(rombuffer[i]!=' ' && rombuffer[i]!=0) { char c = rombuffer[i]; if(c!=' ' && c && c!='.') *t=(*t)*10+(c-'0'); else if(c=='.') t=b; i++; } } int romfind(char* str) { int n = strlen(str); char* tmp = (char*) malloc(n+1); tmp[n]=0; int i; for(i=0;i=romsize) i=-1; free(tmp); return i; } int main(int argc, char* argv[]) { char buffer[77],buffer2[17]; char* hexa="0123456789ABCDEF"; int mode, tromsize; int c,i,h=0,page=0; FILE* rom; FILE* upd; printf("\n+----------+\n"); printf("! ROMto8XU !\n"); printf("+----------+\n"); printf(" X. Andreani\n\n"); printf("Extracts a TI OS from a z80 Flash-ROM file\n"); printf("and generates a matching update file.\n\n"); printf("ROMs of the following models are supported:\n"); printf("* TI-73\n"); printf("* TI-83+\t* TI-83+SE\n"); printf("* TI-84+\t* TI-84+SE\t* TI-84+nSpire(Keypad)\n"); printf("* TI-84+C\n"); printf("TI .clc files (ROM + RAM backup) are also supported.\n\n"); printf("Update files will be written in the .73u, .8xu or .8cu format.\n\n"); printf("To be installable on a true calculator, the generated\n"); printf("update file may need to be signed with the correct key.\n\n"); if( argc<4 ) { printf("ERROR: too few arguments\n"); printf("Usage: %s source.rom dest.8xu mode\n", argv[0]); printf(" where mode is 7 (TI-73), 3 (TI-83), 4 (TI-84+ 512bits RSA), 5 (TI-84+ 2048bits RSA), 6 (TI-84+C)\n"); return 0; } mode=*argv[3]-'0'; if(mode!=7 && mode!=3 && mode!=4 && mode!=5 && mode!=6) { printf("ERROR: unknown mode\n"); printf(" where mode is 7 (TI-73), 3 (TI-83), 4 (TI-84+ 512bits RSA), 5 (TI-84+ 2048bits RSA), 6 (TI-84+C)\n"); return 0; } rom=fopen(argv[1],"rb"); if(!rom) { printf("Source file open error\n"); return 0; } upd=fopen(argv[2],"w"); if(!rom) { fclose(rom); printf("Dest file open error\n"); return 0; } fseek(rom,0,SEEK_END); tromsize=ftell(rom); fseek(rom,0,SEEK_SET); int npages = 0; romsize = PAGE_SIZE; while(tromsize>=2*romsize) { romsize*=2; } npages = romsize/PAGE_SIZE; fread(rombuffer, 1, romsize, rom); fclose(rom); printf("Detected ROM: %iKB (%i pages)\n",npages*PAGE_SIZE/1024,npages); int mpages = 0x20; int lpages = mpages-3; if( mode==6) { mpages = 0x100; lpages = mpages-4; } int v1=0,v2=0; int b = romfind("BASE Code"); if(b>0) { readversion(&v1,&v2,b+10); printf("OS version: %i.%i\n",v1,v2); } else printf("Warning: version string not found\n"); fwrite("**TIFL**",1,8,upd); fputc(v1,upd); fputc(v2,upd); fwrite("\1\0\1\1\1\1",1,7,upd); if(mode==7) fwrite("BASECODE",1,8,upd); else fwrite("basecode",1,8,upd); fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",1,23,upd); if(mode==7) fwrite("t",1,1,upd); else fwrite("s",1,1,upd); fwrite("#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",1,25,upd); if( mode==7 ) fwrite("Ln\0:17000000800F0003801C80110280210180312880A0807F000380000B",1,61,upd); if( mode==3 ) fwrite("Nn\0:18000000800F0000000080110480210180310D80A101807F0000000043",1,63,upd); if( mode==4 || mode==5) fwrite("˜Ö\n\0:1B000000800F0000000080110A80210280311580A103808112807F000000001C",1,69,upd); if( mode==6 ) fwrite("—Ý\0:1B000000800F0000000080110F80210480310080A105808121807F0000000019",1,69,upd); fwrite("\n",1,1,upd); strcpy(buffer2,":0200000200xx..\n"); strcpy(buffer,":20hhh000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..\n\0"); fwrite(":00000001FF\n",1,12,upd); while(page<=lpages) { printf("Extracting page %i...\n",page); buffer2[11]=hexa[page/16]; buffer2[12]=hexa[page%16]; int k=252-page; buffer2[13]=hexa[k/16]; buffer2[14]=hexa[k%16]; fwrite(buffer2,1,16,upd); while(h<2048) { k=32; for(i=0;i<32;i++) { c=romgetc(); if((c==0x5A && page==0 && h==4) || ((((mode==4 || mode==5) && page==0x1A) || (mode==6 && page==0xFA)) && (h>=0x400 && h<0x420))) c=0xFF; k=k+c; *(buffer+9+2*i)=hexa[(c-(c%16))/16]; *(buffer+9+2*i+1)=hexa[c%16]; } *(buffer+5)=hexa[h%16]; *(buffer+4)=hexa[(h/16)%16]; *(buffer+3)=hexa[h/256]; k=k+(h%256)*16; k=k+h/16; k=k%256; k=(256-k)%256; buffer[73]=hexa[k/16]; buffer[74]=hexa[k%16]; fwrite(buffer, 1, 76, upd); h=h+2; if(h==1024) { buffer2[12]='1'; buffer2[13]='F'; buffer2[14]='B'; fwrite(buffer2,1,16,upd); } } h=1024; if(page==0) page++; page++; if(page==8) { int t = 0; if(mode==6) // TI-84+C t = 28; else if(mode==4) // TI-84+ 512-bits RSA t = 12; else if(mode==5) // TI-84+ 2048-bits RSA t = 16; else // TI-73/83+ t = 8; page=mpages-t; romind = (npages-t)*PAGE_SIZE; } } fwrite(":00000001FF\n",1,12,upd); romind = (npages-6)*PAGE_SIZE+0x100; *(buffer+9 )='0'; *(buffer+10)='2'; *(buffer+11)='0'; *(buffer+12)='D'; for(h=0;h<=4;h+=2) { int k=32; for(i=0;i<32;i++) { if(h==0 && i==0) c=0x02; else if(h==0 && i==1) c=0x0D; else c=romgetc(); k=k+c; *(buffer+9+2*i)=hexa[(c-(c%16))/16]; *(buffer+9+2*i+1)=hexa[c%16]; } *(buffer+5)=hexa[h%16]; *(buffer+4)=hexa[(h/16)%16]; *(buffer+3)=hexa[h/256]; k=k+(h%256)*16; k=k+h/16; k=k%256; k=(256-k)%256; buffer[73]=hexa[k/16]; buffer[74]=hexa[k%16]; fwrite(buffer, 1, 76, upd); } fwrite(":00000001FF -- CONVERT 2.6 --\n",1,32,upd); fclose(upd); return 0; }