by critor » 20 Nov 2016, 12:52
Voilà - jour historique, la toute première ROM TI-84 Plus T vient enfin d'être créée et de tourner sur un émulateur :

Ce n'est pas un dump, c'est une pseudo-ROM générée à partir du fichier 8xu avec l'outil xxu2rom :
- Code: Select all
// romto8xu.cpp : définit le point d'entrée pour l'application console.
//
// 512K : TI-73 0C-15 0A 10 160Kio 163840
// 512K : TI-83 Plus 0C-15 0A 10 160Kio 163840
// 1024K : TI-84 Plus 0C-29 1E 30 480Kio 491520
// 1024K : TI-82 Advanced 0C-29 1E 30 480Kio
// 2048K : TI-83 Plus Silver Edition 0C-69 5E 94 1504Kio 1540Ko
// 2048K : TI-84 Plus Silver Edition 0C-69 5E 94 1504Kio 1540Ko
// 2048K : TI-84 Plus T 0C-69 5E 94 1504Kio
// 4096K : TI-84 Plus C Silver Edition 0C-E3 D8 216 3456Kio 3539Ko
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "time.h"
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define DATE_SIZE 8
#define NZONES 5
#define NMODELS 6
#define NUPDS 5
#define IHX_PAGELINE_SIZE 7
#define IHX_INTERLINE_SIZE 5
#define IHX_DATALINE_HEADSIZE 4
#define IHX_DATA_SIZE 32
#define IHX_DATALINE_SIZE (IHX_DATALINE_HEADSIZE+IHX_DATA_SIZE+1)
uint8_t imodel_id[NMODELS] ={2, 4, 0xA, 0xB, 0x1B, 0xF};
char* imodel_name[NMODELS] ={"TI-73", "TI-83 Plus", "TI-84 Plus", "TI-82 Advanced", "TI-84 Plus T", "TI-84 Plus C Silver Edition"};
uint8_t imodel_upd[NMODELS] ={0, 0, 1, 2, 3, 4};
uint8_t imodel_hwrev[NMODELS] ={0, 1, 3, 3, 3, 5};
uint8_t imodel_type[NMODELS] ={0x74, 0x73, 0x73, 0x73, 0x73, 0x73};
uint8_t imodel_irom_minpgsize[NMODELS]={0, 0, 0, 1, 2, 3};
uint8_t imodel_irom_maxpgsize[NMODELS]={2, 2, 2, 1, 2, 3};
uint8_t imodel_irom_defpgsize[NMODELS]={0, 0, 1, 1, 2, 3};
#define NROMS 4
#define PAGE_SIZE 0x4000
#define MAXPAGES 0x100 // 4MB
#define VALID_OFFSET 0x56
#define VERSION_OFFSET 0x64
#define NEWLINE "\r\n"
#define NEWLINE_SIZE strlen(NEWLINE)
#define FOOTER " -- CONVERT 2.6 --\r\n\x1A"
#define FOOTER_SIZE strlen(FOOTER)
uint32_t irom_pgsize[NROMS]={MAXPAGES/8, MAXPAGES/4, MAXPAGES/2, MAXPAGES};
char* izone_name[NZONES]={"OS part #1", "Applications", "Signature #2 (2048-bits)", "OS part #2", "Signature #1 (512-bits)"};
// OS1 endapp sig2 OS2 sig1
uint32_t irom_izone_pgoffset[NROMS][NZONES]={
{0, 0x16, -1, 0x18, 0x1A}, // 512K
{0, 0x2A, 0x30, 0x34, 0x3A}, // 1024K
{0, 0x6A, 0x70, 0x74, 0x7A}, // 2048K
{0, 0xE4, 0xE4, 0xE8, 0xFA} // 4096K
};
uint32_t irom_izone_pgsize[NROMS][NZONES]={
{8, 0x0A, 0, 0x06, 0}, // 512K
{8, 0x1E, 4, 0x0A, 0}, // 1024K
{8, 0x5E, 4, 0x0A, 0}, // 2048K
{8, 0xD7, 4, 0x0D, 0} // 4096K
};
uint32_t iupd_izone_pgoffset[NUPDS][NZONES]={
{0, -1, -1, 0x18, -1}, // TI-73 / TI-83 Plus
{0, -1, 0x10, 0x14, -1}, // TI-84 Plus
{0, 0x2A, 0x30, 0x34, -1}, // TI-82 Advanced
{0, 0x6A, 0x70, 0x74, -1}, // TI-84 Plus T
{0, -1, 0xE4, 0xE8, -1} // TI-84 Plus C Silver Edition
};
uint32_t iupd_izone_pgsize[NUPDS][NZONES]={
{8, 0, 0, 0x06, 0}, // TI-73 / TI-83 Plus
{8, 0, 4, 0x0A, 0}, // TI-84 Plus
{8, 0x0E, 4, 0x0A, 0}, // TI-82 Advanced
{8, 0x1E, 4, 0x0A, 0}, // TI-84 Plus T
{8, 0, 4, 0x0D, 0} // TI-84 Plus C Silver Edition
};
char rombuffer[MAXPAGES*PAGE_SIZE];
#define BUFFER_SIZE (2*(IHX_DATALINE_SIZE+1)+1)
int romind=0;
int romgetc()
{ unsigned char c = rombuffer[romind++];
return c;
}
uint8_t decinhex(uint8_t val) {
return ((val/10)<<4)|(val%10);
}
void addck(uint8_t* array, uint32_t size) {
uint32_t i;
uint8_t ck=0;
for(i=0;i<size-1;i++)
ck-=array[i];
array[size-1]=ck;
}
void fputbytes(uint8_t* array, uint32_t size, FILE* file) {
uint32_t i;
char tmp[3];
if(size)
fputs(":",file);
for(i=0;i<size;i++) {
sprintf(tmp,"%02X",array[i]);
fputs(tmp,file);
}
}
int main(int argc, char* argv[])
{ char* hexa="0123456789ABCDEF";
int mode=0, tromsize;
int c,h=0,page=0, i, j, k;
FILE* rom;
FILE* upd;
uint8_t t;
uint8_t irom=0;
uint8_t imodel=0;
uint8_t idmodel=0;
uint8_t iupd;
uint32_t izone,ipage;
uint8_t updinter[IHX_INTERLINE_SIZE]={0,0,0,1};
addck(updinter,IHX_INTERLINE_SIZE);
printf("+---------+\n");
printf("! xxu2rom !\n");
printf("+---------+\n");
printf(" X. Andreani\n\n");
char* rompath=0;
char* updpath=0;
for(i=1;i<argc;i++) {
if(!strcmp(argv[i],"-size "))
i++;
if(i<argc)
tromsize=strtol(argv[i],NULL,10);
if(!updpath)
updpath=argv[i];
else if(!rompath)
rompath=argv[i];
}
while(irom_pgsize[irom]*PAGE_SIZE/1024<tromsize && irom<NROMS-1)
irom++;
if( !rompath || !updpath)
{ printf("ERROR: missing or bad arguments\n");
printf("Usage: %s source.??u dest.rom [-serom]\n", argv[0]);
printf("-size : target ROM size in KB (valid values : 512, 1024, 2048, 4096)\n");
return 0;
}
upd=fopen(updpath,"rb");
if(!upd)
{ printf("UPD file open error\n");
return 0;
}
memset(rombuffer,0xFF,MAXPAGES*PAGE_SIZE);
rom=fopen(rompath,"r+");
if(!rom)
{ rom=fopen(rompath,"w+");
if(!rom) {
printf("ROM file open error\n");
fclose(upd);
return 0;
}
}
fseek(upd,0x4E,SEEK_SET);
uint8_t updhead[IHX_DATALINE_SIZE];
uint8_t updhead2[IHX_DATALINE_SIZE];
memset(updhead2,0xFF,IHX_DATALINE_SIZE);
char buffer[2*IHX_DATALINE_SIZE+3];
int8_t curpage=-1;
uint16_t delta=0;
while(!feof(upd)) {
fscanf(upd,":");
fgets(buffer,BUFFER_SIZE,upd);
uint8_t n;
sscanf(buffer,"%02hhX",&n);
for(i=0;i<n+IHX_DATALINE_HEADSIZE;i++)
sscanf(buffer+2*i,"%02hhX",&(updhead[i]));
n=updhead[0];
uint16_t pgoffs=((updhead[1]&((1<<6)-1))<<8)|updhead[2];
pgoffs+=delta;
if(n==2 && !pgoffs) {
curpage=updhead[IHX_DATALINE_HEADSIZE+1];
printf("update page %02x",curpage);
for(i=NZONES-1;i>0;i--)
if(curpage>=iupd_izone_pgoffset[imodel_upd[imodel]][i])
break;
curpage=curpage+irom_izone_pgoffset[irom][i]-iupd_izone_pgoffset[imodel_upd[imodel]][i];
printf(" -> ROM page %02x\n",curpage);
}
else if(curpage<0 && n) {
uint32_t datasize = IHX_DATALINE_SIZE-IHX_DATALINE_HEADSIZE;
uint8_t* ptr8000=getFieldDataPtr(updhead+IHX_DATALINE_HEADSIZE,0x8000,1,datasize);
uint8_t* ptr=getFieldDataPtr(ptr8000,0x8010,1,datasize);
idmodel=*ptr;
imodel=0;
while(imodel<NMODELS && imodel_id[imodel]!=idmodel)
imodel++;
if(imodel>=NMODELS) {
printf("ERROR: unknown target model\n");
break;
}
printf("Target model :\n"),
printf("- ID ... \t0x%02X\n",idmodel);
printf("- name ... \t%s\n",imodel_name[imodel]);
if(!tromsize)
irom=imodel_irom_defpgsize[imodel];
irom=(irom<imodel_irom_minpgsize[imodel])?imodel_irom_minpgsize[imodel]:irom;
irom=(irom>imodel_irom_maxpgsize[imodel])?imodel_irom_maxpgsize[imodel]:irom;
printf("- ROM ... \t%dKB\n",irom_pgsize[irom]*PAGE_SIZE/1024);
memcpy(updhead2,updhead,IHX_DATALINE_SIZE);
}
else if(curpage>=0 && n) {
// printf("write page %x offset %x = %x\n",curpage,pgoffs,curpage*PAGE_SIZE+pgoffs);
memcpy(rombuffer+curpage*PAGE_SIZE+pgoffs,updhead+IHX_DATALINE_HEADSIZE,n);
}
else if(curpage>0 && !n && !delta) { // RSA 512-bits signature special case
curpage=irom_izone_pgoffset[irom][NZONES-1];
printf("update page sig1 -> ROM page %x\n",curpage);
memcpy(rombuffer+curpage*PAGE_SIZE,updhead2+IHX_DATALINE_HEADSIZE,updhead2[0]);
delta=0x100-2;
}
}
if(imodel<NMODELS) {
rombuffer[VALID_OFFSET]=0x5A;
rombuffer[irom_izone_pgoffset[irom][NZONES-1]*PAGE_SIZE+0x100-2]=0xFF;
rombuffer[irom_izone_pgoffset[irom][NZONES-1]*PAGE_SIZE+0x100-1]=0xFF;
int r=fwrite(rombuffer,1,irom_pgsize[irom]*PAGE_SIZE,rom);
}
fclose(upd);
return 0;
}
La pseudo-ROM générée n'est pas directement utilisable sur un émulateur.
Il reste une dernière étape : copier un Boot Code compatible sur les deux dernières pages.
Je n'ai pas le Boot Code TI-84 Plus T car on n'a jamais plus y exécuter de l'assembleur, la faille de la TI-82 Advanced y ayant été corrigée.
Mais un Boot Code TI-84 Plus Silver Edition semble convenir :

Les apps venant avec l'OS
(cas des TI-82 Advanced et TI-84 Plus T) sont correctement installées par défaut :
