// Copyright 2004 Marc Plouhinec /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // TI82Library par Marc Plouhinec // email: m_plouhinec@yahoo.fr // site : www.thebestof.tk //Date de crétation du programme: 30/06/2004 //Dernière mise à jour le: 13/07/2004 //Ce programme créer une table contenant les adresses à modifier pour SNG pour l'initialisation de la librairie. //Ce logiciel s'aide du fichier .lst généré par TASM lors de la compilation de la source .ASM //Il cherche d'abord tous les labels "label:". Il stocke ensuite leurs adresses puis il recherche tous les liens vers ces labels. //On donne au logiciel un fichier asm et un fichier .lst et il renvoie un fichier .tabl #include "stdafx.h" #include FILE* fichier_lst; FILE* fichier_tabl; char Labels[260][200];//200 labels possibles dont le nom fait au maximum 256 lettres (il reste 4 octets pour l'adresse) char LabelsIndex=0; int Table[200]; char TableIndex=0; fpos_t InitPos; char nom[50]; char *PointeurVersChaine; char* nom_tabl( char *chaine ) { PointeurVersChaine = chaine; for (int Temp = 0; *(PointeurVersChaine+Temp)!='.';Temp++) { nom[Temp]=*(PointeurVersChaine+Temp); } nom[Temp]='.'; nom[Temp+1]='T'; nom[Temp+2]='A'; nom[Temp+3]='B'; nom[Temp+4]='L'; nom[Temp+5]=0; return nom; } char* nom_lst( char *chaine ) { PointeurVersChaine = chaine; for (int Temp = 0; *(PointeurVersChaine+Temp)!='.';Temp++) { nom[Temp]=*(PointeurVersChaine+Temp); } nom[Temp]='.'; nom[Temp+1]='L'; nom[Temp+2]='S'; nom[Temp+3]='T'; nom[Temp+4]=0; return nom; } bool EstCeUnChiffreHexa(char Donnee) { if(Donnee >= 0x30 && Donnee <= 0x39) return true; if(Donnee >= 0x41 && Donnee <= 0x46) return true; if(Donnee >= 0x61 && Donnee <= 0x66) return true; return false; } bool EstCeUneLettreOuUnChiffre(char Donnee) { if(Donnee >= 0x30 && Donnee <= 0x39) return true; if(Donnee >= 0x41 && Donnee <= 0x5A) return true; if(Donnee >= 0x61 && Donnee <= 0x7A) return true; if(Donnee == '_') return true; return false; } void ChargeLabels() { //On se place au début d'une ligne, on cherche une ligne du type: //XXXX YYYY label: //XXXX et YYYY sont des nombres en hexadécimal char Donnee = 0; int i; char YYYY[4]; fpos_t pos; while ((Donnee = fgetc(fichier_lst)) != EOF) { //On est au début d'une ligne if(!EstCeUnChiffreHexa(Donnee)) goto FiniLaLigne; //On passe XXXX if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne; if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne; if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne; YYYY[0]=Donnee; //On passe YYYY if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne; YYYY[1]=Donnee; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne; YYYY[2]=Donnee; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne; YYYY[3]=Donnee; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne; // On cherche si c'est un "label:" ou un "label = $-x" fgetpos( fichier_lst, &pos ); while(EstCeUneLettreOuUnChiffre(Donnee = fgetc(fichier_lst))); fsetpos( fichier_lst, &pos ); if(Donnee != ':' && Donnee != ' ') goto FiniLaLigne; if(Donnee == ' ')// On a un "label = $-x" { int A,B,C,D,ecart; //On est sûr que c'est un label, on stocke son nom et son adresse: i = 0; while(EstCeUneLettreOuUnChiffre(Donnee = fgetc(fichier_lst))) { Labels[i][LabelsIndex]=Donnee; i++; } fgetc(fichier_lst); fgetc(fichier_lst); fgetc(fichier_lst); if(fgetc(fichier_lst) == '+') { //On additionne l'adresse ecart = fgetc(fichier_lst)-0x30; if(YYYY[0] <=0x39) A=YYYY[0]-0x30; else A=YYYY[0]-0x41+10; if(YYYY[1] <=0x39) B=YYYY[1]-0x30; else B=YYYY[1]-0x41+10; if(YYYY[2] <=0x39) C=YYYY[2]-0x30; else C=YYYY[2]-0x41+10; if(YYYY[3] <=0x39) D=YYYY[3]-0x30; else D=YYYY[3]-0x41+10; A=A*16*16*16+B*16*16+C*16+D+ecart; YYYY[0]=A/(0x1000); YYYY[1]=A/(0x100)-YYYY[0]*0x10; YYYY[2]=A/(0x10)-YYYY[1]*0x10-YYYY[0]*0x100; YYYY[3]=A-YYYY[2]*0x10-YYYY[1]*0x100-YYYY[0]*0x1000; for(int ii = 0; ii<4; ii++) { if(YYYY[ii]>=0 && YYYY[ii] <=9) YYYY[ii] += 0x30; if(YYYY[ii]>=10 && YYYY[ii] <=15) YYYY[ii] += 0x41-10; } } else { //On soustrait l'adresse ecart = fgetc(fichier_lst)-0x30; if(YYYY[0] <=0x39) A=YYYY[0]-0x30; else A=YYYY[0]-0x41+10; if(YYYY[1] <=0x39) B=YYYY[1]-0x30; else B=YYYY[1]-0x41+10; if(YYYY[2] <=0x39) C=YYYY[2]-0x30; else C=YYYY[2]-0x41+10; if(YYYY[3] <=0x39) D=YYYY[3]-0x30; else D=YYYY[3]-0x41+10; A=A*16*16*16+B*16*16+C*16+D-ecart; YYYY[0]=A/(0x1000); YYYY[1]=A/(0x100)-YYYY[0]*0x10; YYYY[2]=A/(0x10)-YYYY[1]*0x10-YYYY[0]*0x100; YYYY[3]=A-YYYY[2]*0x10-YYYY[1]*0x100-YYYY[0]*0x1000; for(int ii = 0; ii<4; ii++) { if(YYYY[ii]>=0 && YYYY[ii] <=9) YYYY[ii] += 0x30; if(YYYY[ii]>=10 && YYYY[ii] <=15) YYYY[ii] += 0x41-10; } } Labels[256][LabelsIndex]=YYYY[0]; Labels[257][LabelsIndex]=YYYY[1]; Labels[258][LabelsIndex]=YYYY[2]; Labels[259][LabelsIndex]=YYYY[3]; LabelsIndex++; } else { //On est sûr que c'est un label, on stocke son nom et son adresse: i = 0; while(EstCeUneLettreOuUnChiffre(Donnee = fgetc(fichier_lst))) { Labels[i][LabelsIndex]=Donnee; i++; } Labels[256][LabelsIndex]=YYYY[0]; Labels[257][LabelsIndex]=YYYY[1]; Labels[258][LabelsIndex]=YYYY[2]; Labels[259][LabelsIndex]=YYYY[3]; LabelsIndex++; } FiniLaLigne: while ((fgetc(fichier_lst)) != 10); } } char InstructionUtilisantDesAdressesFixes() { //Renvoie 0 si ce n'est pas une instruction utilisant une adresse fixe //sinon on renvoie le nombre de caractère entre le déut de l'opcode et l'adresse fpos_t pos; fgetpos( fichier_lst, &pos ); /* Liste des instruction utilisant des adresses fixes: CALL C,* DC 3 NOP 1 CALL M,* FC 3 NOP 1 CALL NC,* D4 3 NOP 1 CALL NZ,* C4 3 NOP 1 CALL P,* F4 3 NOP 1 CALL PE,* EC 3 NOP 1 CALL PO,* E4 3 NOP 1 CALL Z,* CC 3 NOP 1 CALL * CD 3 NOP 1 JP C,* DA 3 NOP 1 JP M,* FA 3 NOP 1 JP NC,* D2 3 NOP 1 JP NZ,* C2 3 NOP 1 JP P,* F2 3 NOP 1 JP PE,* EA 3 NOP 1 JP PO,* E2 3 NOP 1 JP Z,* CA 3 NOP 1 JP * C3 3 NOP 1 LD (*),A 32 3 NOP 1 LD (*),BC 43ED 4 NOP 1 LD (*),DE 53ED 4 NOP 1 LD (*),HL 22 3 NOP 1 LD (*),IX 22DD 4 NOP 1 LD (*),IY 22FD 4 NOP 1 LD (*),SP 73ED 4 NOP 1 LD A,(*) 3A 3 NOP 1 LD BC,(*) 4BED 4 NOP 1 LD BC,* 01 3 NOP 1 LD DE,(*) 5BED 4 NOP 1 LD DE,* 11 3 NOP 1 LD HL,(*) 2A 3 NOP 1 LD HL,* 21 3 NOP 1 LD IX,(*) 2ADD 4 NOP 1 LD IX,* 21DD 4 NOP 1 LD IY,(*) 2AFD 4 NOP 1 LD IY,* 21FD 4 NOP 1 LD SP,(*) 7BED 4 NOP 1 LD SP,* 31 3 NOP 1 */ char Opcode[11]; for (int i= 0; i< 11; i++) Opcode[i]=fgetc(fichier_lst); //CALL if(Opcode[0]=='D' && Opcode[1]=='C') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='F' && Opcode[1]=='C') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='D' && Opcode[1]=='4') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='4') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='F' && Opcode[1]=='4') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='C') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='4') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='C') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='D') { fsetpos( fichier_lst, &pos ); return 3; } //JP if(Opcode[0]=='D' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='F' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='D' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='F' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='C' && Opcode[1]=='3') { fsetpos( fichier_lst, &pos ); return 3; } //LD if(Opcode[0]=='3' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='4' && Opcode[4]=='3') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='5' && Opcode[4]=='3') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='2' && Opcode[1]=='2') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='D' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='2') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='F' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='2') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='7' && Opcode[4]=='3') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='3' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='4' && Opcode[4]=='B') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='0' && Opcode[1]=='1') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='5' && Opcode[4]=='B') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='1' && Opcode[1]=='1') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='2' && Opcode[1]=='A') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='2' && Opcode[1]=='1') { fsetpos( fichier_lst, &pos ); return 3; } if(Opcode[0]=='D' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='A') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='F' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='A') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='D' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='1') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='F' && Opcode[1]=='D' && Opcode[3]=='2' && Opcode[4]=='1') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='E' && Opcode[1]=='D' && Opcode[3]=='7' && Opcode[4]=='B') { fsetpos( fichier_lst, &pos ); return 6; } if(Opcode[0]=='3' && Opcode[1]=='1') { fsetpos( fichier_lst, &pos ); return 3; } fsetpos( fichier_lst, &pos ); return 0; } bool VerifiePasDeDBouDW() { fpos_t pos,pos2; char Donnee = 0; char TEMP[3]; fgetpos( fichier_lst, &pos ); while (Donnee != 10 && Donnee != ';' ) { fgetpos( fichier_lst, &pos2 ); TEMP[0]=fgetc(fichier_lst); TEMP[1]=fgetc(fichier_lst); TEMP[2]=fgetc(fichier_lst); if(TEMP[0] == '.') { if(TEMP[1]=='D' || TEMP[1]=='d') { if(TEMP[2] == 'B' || TEMP[2] == 'b' || TEMP[2] == 'W' || TEMP[2] == 'w') {fsetpos( fichier_lst, &pos ); return false;}; } } fsetpos( fichier_lst, &pos2 ); Donnee=fgetc(fichier_lst); } fsetpos( fichier_lst, &pos ); return true; } void ChercheLiensAvecLabel(int Label) { //On se place devant une instruction puis on regarde l'opcode (si c'est une instruction appellant un label, on regarde si on ne le connait pas) char Donnee; int i; char YYYY[4]; char ZZZZ[4]; char A,B,C,D; while ((Donnee = fgetc(fichier_lst)) != EOF) { //On est au début d'une ligne if(!EstCeUnChiffreHexa(Donnee)) goto FiniLaLigne2; //On passe XXXX if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne2; if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne2; if(!EstCeUnChiffreHexa(fgetc(fichier_lst))) goto FiniLaLigne2; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne2; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne2; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne2; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne2; YYYY[0]=Donnee; //On passe YYYY if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne2; YYYY[1]=Donnee; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne2; YYYY[2]=Donnee; if(!EstCeUnChiffreHexa(Donnee = fgetc(fichier_lst))) goto FiniLaLigne2; YYYY[3]=Donnee; if(fgetc(fichier_lst) != ' ') goto FiniLaLigne2; //On est au début de l'opcode Donnee=InstructionUtilisantDesAdressesFixes(); if(!Donnee) goto FiniLaLigne2; for (i = 0; i< Donnee; i++) fgetc(fichier_lst); //Ici on pointe vers l'adresse ZZZZ[0]=fgetc(fichier_lst); ZZZZ[1]=fgetc(fichier_lst); fgetc(fichier_lst);//passe l'espace ZZZZ[2]=fgetc(fichier_lst); ZZZZ[3]=fgetc(fichier_lst); if(Labels[258][Label]==ZZZZ[0] && Labels[259][Label]==ZZZZ[1] && Labels[256][Label]==ZZZZ[2] && Labels[257][Label]==ZZZZ[3]) { //On a trouvé l'adresse! //Faut juste vérifier qu'il n'y a pas de .DB sur la ligne if(VerifiePasDeDBouDW()) { //Table[TableIndex]=(YYYY[0]-0x30)*16*16*16+(YYYY[1]-0x30)*16*16+(YYYY[2]-0x30)*16+(YYYY[3]-0x30); if(YYYY[0] <=0x39) A=YYYY[0]-0x30; else A=YYYY[0]-0x41+10; if(YYYY[1] <=0x39) B=YYYY[1]-0x30; else B=YYYY[1]-0x41+10; if(YYYY[2] <=0x39) C=YYYY[2]-0x30; else C=YYYY[2]-0x41+10; if(YYYY[3] <=0x39) D=YYYY[3]-0x30; else D=YYYY[3]-0x41+10; Table[TableIndex]=A*16*16*16+B*16*16+C*16+D; if(Donnee==3) Table[TableIndex]=Table[TableIndex]+1; if(Donnee==6) Table[TableIndex]=Table[TableIndex]+2; TableIndex++; } } FiniLaLigne2: while ((fgetc(fichier_lst)) != 10); } } void EcritTable() { char YYYY[4]; for (int i=0; i=0 && YYYY[ii] <=9) fputc(YYYY[ii]+0x30,fichier_tabl); if(YYYY[ii]>=10 && YYYY[ii] <=15) fputc(YYYY[ii]+0x41-10,fichier_tabl); } fputc(0x0d,fichier_tabl); fputc(0x0a,fichier_tabl); } } int main(int argc, char* argv[]) { //Initialisation printf("\nTI82Library v1.0 (02/07/2004) par Marc Plouhinec\nemail: m_plouhinec@yahoo.fr site: www.thebestof.tk\n\n"); if (argc != 2) { printf("syntaxe: TI82Library fichier.asm\n"); return 0; } //On ouvre le fichier .LST en lecture if (!(fichier_lst = fopen(nom_lst(argv[1]), "r"))) { fprintf(stderr, "Erreur: Impossible de lire: %s\n", nom_lst(argv[1])); return 2; } if (!(fichier_tabl = fopen(nom_tabl(argv[1]), "wb"))) { fprintf(stderr, "Erreur: Impossible de creer le fichier: %s\n", nom_tabl(argv[1])); return 3; } fgetpos( fichier_lst, &InitPos ); ChargeLabels(); for (int Label=0; Label < LabelsIndex-1; Label++) { fsetpos( fichier_lst, &InitPos ); ChercheLiensAvecLabel(Label); } //On ecrit maintenant la table EcritTable(); return 0; }