void simul(Machine *pmach, bool debug) { trace("Executing", pmach, pmach->_text[pmach->_pc], pmach->_pc); while(pmach->_pc < pmach->_textsize && decode_execute(pmach, pmach->_text[pmach->_pc++])) { if (debug) debug = debug_ask(pmach); trace("Executing", pmach, pmach->_text[pmach->_pc], pmach->_pc); } }
/*! * Simulation * * La boucle de simualtion est très simple : recherche de l'instruction * suivante (pointée par le compteur ordinal \c _pc) puis décodage et exécution * de l'instruction. * * Cette fonction fait appel aux fonctions <exec.c:decode_execute>, <exec.c:trace> et <debug.c:ask_debug> * * \param pmach la machine en cours d'exécution * \param debug mode de mise au point (pas à apas) ? */ void simul(Machine *pmach, bool debug){ do{ //on imprime la trace d'execution de l'instruction trace("EXECUTING", pmach, pmach->_text[pmach->_pc], pmach->_pc); //si le parametre debug est vrai, on passe en mode debug if(debug) debug = debug_ask(pmach); if(pmach->_pc >= pmach->_textsize) error(ERR_SEGTEXT, pmach->_pc); } //tant que pc ne dépasse pas la taille du segment d'instructions et que la procedure decode_execute retourne vrai while(decode_execute(pmach, pmach->_text[pmach->_pc++])); }
/*! * Appel de la fonction error() si la valeur de pc est plus grande * que la valeur de textsize. * * Affichage de la ligne à exécuter avec la fonction trace(). * * Décodage et exécution de l'instruction avec la fonction decode_execute(). * * Lancement de la fonction de débugage avec debug_ask(). * * On incrémente la valeur de PC à chaque itération de la boucle. * * \param pmach la machine en cours d'exécution * \param debug mode de mise au point (pas à apas) ? */ void simul(Machine *pmach, bool debug) { bool execute = true; while(execute) { if (pmach->_pc >= pmach->_textsize) { error(ERR_SEGTEXT, pmach->_pc); } pmach->_pc = pmach->_pc + 1; trace("Executing", pmach, pmach->_text[pmach->_pc - 1], pmach->_pc - 1); execute = decode_execute(pmach, pmach->_text[pmach->_pc - 1]); if (debug) { debug = debug_ask(pmach); } } }
/*! * La boucle de simualtion est très simple : recherche de l'instruction * suivante (pointée par le compteur ordinal \c _pc) puis décodage et exécution * de l'instruction. * * \param pmach la machine en cours d'exécution * \param debug mode de mise au point (pas à apas) ? */ void simul(Machine *pmach, bool debug) { bool stop = true; //decode_execute retourne false si on est à la fin du programme : while (stop) { //On trace l'exécution courrante : trace("Executing", pmach, pmach->_text[pmach->_pc], pmach->_pc); if (pmach->_pc >= pmach->_textsize) { error(ERR_SEGTEXT, pmach->_pc - 1); } stop = decode_execute(pmach, pmach->_text[pmach->_pc++]); //Si on est en mode debug on ne fait qu'une ligne a la fois if (debug) debug = debug_ask(pmach); } }
/*! * Cette fonction gère le dialogue pour l'option \c -d (debug). Dans ce mode, * elle est invoquée après l'exécution de chaque instruction. Elle affiche le * menu de mise au point et on exécute le choix de l'utilisateur. Si cette * fonction retourne faux, on abandonne le mode de mise au point interactive * pour les instructions suivantes et jusqu'à la fin du programme. * * \param mach la machine/programme en cours de simulation * \return vrai si l'on doit continuer en mode debug, faux sinon */ bool debug_ask(Machine *pmach){ printf("DEBUG? "); char commande = '\n'; bool premier = true; char rep; while( (rep=getchar()) != '\n' && rep != EOF){ if(premier) commande = rep; premier = false; }; switch(commande){ case 'h': printf("Available commands :\n\th\thelp\n\tc\tcontinue (exit interactive debug mode)\n\ts\tstep by step (next instruction)\n\tRET\tstep by step (next instruction)\n\tr\tprint registers\n\td\tprint data memory\n\tt\tprint text (program) memory\n\tp\tprint text (program) memory\n\tm\tprint registers and data memory\n"); break; case 'c': return false; break; case 's': return true; break; case 'r': print_cpu(pmach); break; case 'd': print_data(pmach); break; case 't': print_program(pmach); break; case 'p': print_program(pmach); break; case 'm': print_cpu(pmach); print_data(pmach); break; case '\n': return true; break; default: break; } return debug_ask(pmach); }