Ajout de la gestion de l'execution, mise en place d'un timer pour activer le rafraichissement

This commit is contained in:
Horde Nicolas 2021-07-06 11:44:46 +02:00
parent 59430c290b
commit f5e71076cb
2 changed files with 199 additions and 129 deletions

260
ia86.cpp
View File

@ -153,6 +153,12 @@ std::vector<std::array<std::string, 5>> InstructionWindow::get()
return content; return content;
} }
void InstructionWindow::clear()
{
listview.clear();
listview.redraw();
}
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src) void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
{ {
content=src; content=src;
@ -162,7 +168,7 @@ void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
const finalcut::FStringList line (place.begin(), place.end()); const finalcut::FStringList line (place.begin(), place.end());
listview.insert (line); listview.insert (line);
} }
listview.redraw();
} }
void InstructionWindow::initLayout() void InstructionWindow::initLayout()
@ -178,42 +184,6 @@ void InstructionWindow::adjustSize()
listview.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1)); listview.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
} }
//----------------------------------------------------------------------
// Classe TextFixedWindow
//----------------------------------------------------------------------
TextFixedWindow::TextFixedWindow (finalcut::FWidget* parent)
: finalcut::FDialog{parent}
{
fixedtext.ignorePadding();
fixedtext.setFocus();
}
std::string TextFixedWindow::get()
{
std::stringstream out;
out << fixedtext.getText();
return out.str();
}
void TextFixedWindow::set(std::string str)
{
fixedtext.setText(str);
}
void TextFixedWindow::initLayout()
{
fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2});
FDialog::initLayout();
}
void TextFixedWindow::adjustSize()
{
finalcut::FDialog::adjustSize();
fixedtext.setGeometry (FPoint{2, 3}, FSize(getWidth()-2, getHeight() - 2));
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe TextEditWindow // Classe TextEditWindow
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -221,32 +191,49 @@ void TextFixedWindow::adjustSize()
TextEditWindow::TextEditWindow (finalcut::FWidget* parent) TextEditWindow::TextEditWindow (finalcut::FWidget* parent)
: finalcut::FDialog{parent} : finalcut::FDialog{parent}
{ {
fixedtext.ignorePadding(); scrolltext.ignorePadding();
fixedtext.setFocus(); scrolltext.setFocus();
}
void TextEditWindow::onClose(finalcut::FCloseEvent*)
{
return;
}
void TextEditWindow::append(const finalcut::FString& str)
{
scrolltext.append(str);
scrolltext.scrollBy (0, 10);
} }
std::string TextEditWindow::get() std::string TextEditWindow::get()
{ {
std::stringstream out; return scrolltext.getText().toString () ;
out << fixedtext.getText();
return out.str();
} }
void TextEditWindow::set(std::string str) void TextEditWindow::set(const finalcut::FString& str)
{ {
fixedtext.setText(str); scrolltext.clear();
scrolltext.append(str);
scrolltext.redraw();
} }
void TextEditWindow::clear()
{
scrolltext.clear();
}
void TextEditWindow::initLayout() void TextEditWindow::initLayout()
{ {
fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2}); scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
FDialog::initLayout(); FDialog::initLayout();
} }
void TextEditWindow::adjustSize() void TextEditWindow::adjustSize()
{ {
finalcut::FDialog::adjustSize(); finalcut::FDialog::adjustSize();
fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2}); scrolltext.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -271,6 +258,18 @@ void TextWindow::append(const finalcut::FString& str)
scrolltext.scrollBy (0, 10); scrolltext.scrollBy (0, 10);
} }
std::string TextWindow::get()
{
return scrolltext.getText().toString () ;
}
void TextWindow::set(const finalcut::FString& str)
{
scrolltext.clear();
scrolltext.append(str);
scrolltext.redraw();
}
void TextWindow::clear() void TextWindow::clear()
{ {
scrolltext.clear(); scrolltext.clear();
@ -387,14 +386,7 @@ Code *Assembler::Assemble(std::string source,uint32_t address)
VMEngine::VMEngine(TextWindow *log) : log(log) VMEngine::VMEngine(TextWindow *log) : log(log)
{ {
std::stringstream out; Init();
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
if (err != UC_ERR_OK) {
out << "Impossible d'initialiser la machine virtuelle: " << err;
log->append(out.str());
}
else
log->append("Initialisation de l'ordinateur IA86");
} }
// Level 1 : IP AL // Level 1 : IP AL
// Level 2 : IP AX // Level 2 : IP AX
@ -507,7 +499,63 @@ std::string VMEngine::getRegs(int level)
return out.str(); return out.str();
} }
void VMEngine::Init()
{
std::stringstream out;
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
if (err != UC_ERR_OK) {
out << "Impossible d'initialiser la machine virtuelle: " << err;
log->append(out.str());
}
else
log->append("Initialisation de l'ordinateur IA86");
}
void VMEngine::Close()
{
uc_close(uc);
}
void VMEngine::Halt(Code *code)
{
code->executed=false;
}
void VMEngine::Configure(State *init, Code *code) void VMEngine::Configure(State *init, Code *code)
{
Close();
Init();
code->assembled=false;
code->initialized=false;
code->executed=false;
log->append("Mappage de la mémoire virtuelle");
uc_mem_map(uc, init->dump.regs.eip, 1 * 1024 * 1024, UC_PROT_ALL);
}
void VMEngine::Prepare(State *init, Code *code)
{
SetMem(init, code);
SetRegs(init, code);
}
void VMEngine::SetMem(State *init, Code *code)
{
err = uc_mem_write(uc, init->dump.regs.eip, code->content, code->size);
if (err)
{
code->initialized=false;
log->append("Erreur de copie mémoire dans la machine virtuelle");
return;
}
else
{
code->initialized=true;
log->append("Chargement en mémoire de la machine virtuelle, taille: "+to_string(code->size));
}
}
void VMEngine::SetRegs(State *init, Code *code)
{ {
std::stringstream out; std::stringstream out;
out << "Configuration initiale de l'ordinateur IA86:\n "; out << "Configuration initiale de l'ordinateur IA86:\n ";
@ -593,16 +641,6 @@ void VMEngine::Configure(State *init, Code *code)
else else
out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " "; out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " ";
log->append(out.str()); log->append(out.str());
uc_mem_map(uc, init->dump.regs.eip, 1 * 1024 * 1024, UC_PROT_ALL);
err = uc_mem_write(uc, init->dump.regs.eip, code->content, code->size);
if (err)
{
code->loaded=false;
log->append("Erreur de copie mémoire dans la machine virtuelle");
return;
}
else
code->loaded=true;
} }
void VMEngine::Run(Code *code,uint32_t start, uint32_t stop, uint64_t timeout) void VMEngine::Run(Code *code,uint32_t start, uint32_t stop, uint64_t timeout)
@ -641,6 +679,7 @@ void Menu::initNow()
void Menu::initCore() void Menu::initCore()
{ {
addTimer (50);
loadGoal(); loadGoal();
} }
@ -663,20 +702,16 @@ void Menu::initWindows()
regs.show(); regs.show();
flags.setText ("Drapeaux"); flags.setText ("Drapeaux");
flags.setGeometry ( FPoint { 60, 01 }, FSize{15, 15} ); flags.setGeometry ( FPoint { 60, 01 }, FSize{15, 15} );
flags.show();
stack.setText ("Pile"); stack.setText ("Pile");
stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} ); stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} );
stack.show();
mem.setText ("Mémoire"); mem.setText ("Mémoire");
mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} ); mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} );
mem.show();
tuto.setText ("Guide"); tuto.setText ("Guide");
tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} ); tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} );
tuto.setResizeable(); tuto.setResizeable();
tuto.show(); tuto.show();
screen.setText ("Ecran"); screen.setText ("Ecran");
screen.setGeometry ( FPoint { 105, 18 }, FSize{80, 25} ); screen.setGeometry ( FPoint { 105, 18 }, FSize{80, 25} );
screen.show();
debug.setText ("Instructions"); debug.setText ("Instructions");
debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} ); debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} );
debug.setResizeable(); debug.setResizeable();
@ -702,6 +737,17 @@ void Menu::initWindows()
void Menu::AdjustWindows() void Menu::AdjustWindows()
{ {
log.setGeometry ( FPoint { 63, 45 }, FSize{60, 11} );
edit.setGeometry ( FPoint { 01, 17 }, FSize{39, 27} );
view.setGeometry ( FPoint { 01, 45 }, FSize{60, 11} );
regs.setGeometry ( FPoint { 01, 01 }, FSize{40, 15} );
flags.setGeometry ( FPoint { 60, 01 }, FSize{15, 15} );
stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} );
mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} );
tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} );
screen.setGeometry ( FPoint { 105, 18 }, FSize{80, 25} );
debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} );
scenar.setGeometry ( FPoint { 187, 01 }, FSize{23, 55} );
flags.hide(); flags.hide();
stack.hide(); stack.hide();
mem.hide(); mem.hide();
@ -729,7 +775,7 @@ void Menu::initMenus()
New.setStatusbarMessage ("Debuter une nouvelle partie"); New.setStatusbarMessage ("Debuter une nouvelle partie");
Quit.addAccelerator (FKey::Meta_x); Quit.addAccelerator (FKey::Meta_x);
Quit.setStatusbarMessage ("Quitter IA86"); Quit.setStatusbarMessage ("Quitter IA86");
Run.addAccelerator (FKey::Meta_f9); Run.addAccelerator (FKey::F9);
Run.setStatusbarMessage ("Exécuter le programme - seul un breakpoint arrête"); Run.setStatusbarMessage ("Exécuter le programme - seul un breakpoint arrête");
TraceInto.addAccelerator (FKey::F7); TraceInto.addAccelerator (FKey::F7);
TraceInto.setStatusbarMessage ("Pas à pas détaillé - entre dans les CALL"); TraceInto.setStatusbarMessage ("Pas à pas détaillé - entre dans les CALL");
@ -737,15 +783,20 @@ void Menu::initMenus()
StepOver.setStatusbarMessage ("Pas à pas - ne rentre pas dans les CALL"); StepOver.setStatusbarMessage ("Pas à pas - ne rentre pas dans les CALL");
Assemble.addAccelerator (FKey::F2); Assemble.addAccelerator (FKey::F2);
Assemble.setStatusbarMessage ("Assemble le source vers du code machine"); Assemble.setStatusbarMessage ("Assemble le source vers du code machine");
Rearange.addAccelerator (FKey::F1); Rearange.addAccelerator (FKey::Meta_r);
Rearange.setStatusbarMessage ("Reorganise les fenêtres dans leur état initial"); Rearange.setStatusbarMessage ("Reorganise les fenêtres dans leur état initial");
Breakpoint.addAccelerator (FKey::F5); Breakpoint.addAccelerator (FKey::F5);
Breakpoint.setStatusbarMessage ("Enlève ou met un point d'arrêt"); Breakpoint.setStatusbarMessage ("Enlève ou met un point d'arrêt");
End.addAccelerator (FKey::Meta_f2); End.addAccelerator (FKey::F6);
End.setStatusbarMessage ("Termine le programme et remet à zéro la machine IA86"); End.setStatusbarMessage ("Termine le programme et remet à zéro la machine IA86");
About.setStatusbarMessage ("A propos de IA86"); About.setStatusbarMessage ("A propos de IA86");
} }
void Menu::onTimer (finalcut::FTimerEvent* ev)
{
refresh();
}
void Menu::initMenusCallBack() void Menu::initMenusCallBack()
{ {
Quit.addCallback Quit.addCallback
@ -785,6 +836,12 @@ void Menu::initMenusCallBack()
this, this,
&Menu::step &Menu::step
); );
End.addCallback
(
"clicked",
this,
&Menu::end
);
} }
void Menu::initMisc() void Menu::initMisc()
@ -825,11 +882,24 @@ void Menu::onClose (finalcut::FCloseEvent* ev)
void Menu::loadGoal() void Menu::loadGoal()
{ {
log.append("Chargement du scénario "+goals[scenar.getselected()].title);
view.setText("Objectif: "+goals[scenar.getselected()].title); view.setText("Objectif: "+goals[scenar.getselected()].title);
view.clear(); view.clear();
view.append(goals[scenar.getselected()].description); view.append(goals[scenar.getselected()].description);
tuto.clear();
tuto.append(goals[scenar.getselected()].help);
regs.set("En attente d'initialisation...");
edit.set(goals[scenar.getselected()].code); edit.set(goals[scenar.getselected()].code);
AdjustWindows(); AdjustWindows();
debug.clear();
vm.Configure(&goals[scenar.getselected()].init,code);
end();
}
void Menu::end()
{
regs.set("En attente d'initialisation...");
vm.Halt(code);
} }
void Menu::compile() void Menu::compile()
@ -838,44 +908,47 @@ void Menu::compile()
debug.set(unasmer.Desassemble(code)); debug.set(unasmer.Desassemble(code));
} }
void Menu::verify() bool Menu::verify()
{ {
if (!code->assembled)
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return false;
}
if (!code->initialized)
vm.Prepare(&goals[scenar.getselected()].init,code);
if (!code->initialized)
return false;
return true;
}
void Menu::refresh()
{
if (!code->executed)
finalcut::FApplication::setDarkTheme();
else
finalcut::FApplication::setDefaultTheme();
auto root_widget = getRootWidget();
root_widget->resetColors();
root_widget->redraw();
} }
void Menu::exec() void Menu::exec()
{ {
if (!code->assembled) if (!verify()) return;
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return;
}
if (!code->executed)
vm.Configure(&goals[scenar.getselected()].init,code);
vm.Run(code,code->address,code->address+code->size,0); vm.Run(code,code->address,code->address+code->size,0);
regs.set(vm.getRegs(goals[scenar.getselected()].level)); regs.set(vm.getRegs(goals[scenar.getselected()].level));
} }
void Menu::trace() void Menu::trace()
{ {
if (!code->assembled) if (!verify()) return;
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return;
}
if (!code->executed)
vm.Configure(&goals[scenar.getselected()].init,code);
} }
void Menu::step() void Menu::step()
{ {
if (!code->assembled) if (!verify()) return;
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return;
}
if (!code->executed)
vm.Configure(&goals[scenar.getselected()].init,code);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -890,6 +963,7 @@ int main (int argc, char* argv[])
main_dlg.setSize ({50, 14}); main_dlg.setSize ({50, 14});
main_dlg.setShadow(); main_dlg.setShadow();
main_dlg.show(); main_dlg.show();
finalcut::FApplication::setDarkTheme();
finalcut::FWidget::setMainWidget (&main_dlg); finalcut::FWidget::setMainWidget (&main_dlg);
//usleep(5 * 1000000); //usleep(5 * 1000000);
main_dlg.hide(); main_dlg.hide();

64
ia86.h
View File

@ -3,9 +3,12 @@ using std::cout; using std::endl;
using std::vector; using std::string; using std::vector; using std::string;
using FKey = finalcut::FKey; using FKey = finalcut::FKey;
using finalcut::FColor;
using finalcut::FPoint; using finalcut::FPoint;
using finalcut::FRect;
using finalcut::FSize; using finalcut::FSize;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Types & classes mineures // Types & classes mineures
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -137,8 +140,8 @@ class Code
size_t size; size_t size;
unsigned char *content; unsigned char *content;
bool assembled; bool assembled;
bool initialized;
bool executed; bool executed;
bool loaded;
}; };
class ScenarioWindow final : public finalcut::FDialog class ScenarioWindow final : public finalcut::FDialog
@ -178,6 +181,7 @@ class InstructionWindow final : public finalcut::FDialog
// Method // Method
std::vector<std::array<std::string, 5>> get(); std::vector<std::array<std::string, 5>> get();
void set(std::vector<std::array<std::string, 5>> src); void set(std::vector<std::array<std::string, 5>> src);
void clear();
private: private:
// Method // Method
std::vector<std::array<std::string, 5>> content; std::vector<std::array<std::string, 5>> content;
@ -187,29 +191,6 @@ class InstructionWindow final : public finalcut::FDialog
finalcut::FListView listview{this}; finalcut::FListView listview{this};
}; };
class TextFixedWindow final : public finalcut::FDialog
{
public:
// Constructor
explicit TextFixedWindow (finalcut::FWidget* = nullptr);
// Disable copy constructor
TextFixedWindow (const TextFixedWindow&) = delete;
// Destructor
~TextFixedWindow() override = default;
// Disable copy assignment operator (=)
TextFixedWindow& operator = (const TextFixedWindow&) = delete;
// Method
std::string get();
void set(std::string str);
private:
// Method
void initLayout() override;
void adjustSize() override;
// Data members
finalcut::FLabel fixedtext{this};
};
class TextEditWindow final : public finalcut::FDialog class TextEditWindow final : public finalcut::FDialog
{ {
public: public:
@ -222,14 +203,17 @@ class TextEditWindow final : public finalcut::FDialog
// Disable copy assignment operator (=) // Disable copy assignment operator (=)
TextEditWindow& operator = (const TextEditWindow&) = delete; TextEditWindow& operator = (const TextEditWindow&) = delete;
// Method // Method
void append(const finalcut::FString&);
void clear();
std::string get(); std::string get();
void set(std::string str); void set(const finalcut::FString&);
private: private:
// Method // Method
void onClose(finalcut::FCloseEvent*) override;
void initLayout() override; void initLayout() override;
void adjustSize() override; void adjustSize() override;
// Data members // Data members
finalcut::FLabel fixedtext{this}; finalcut::FTextView scrolltext{this};
}; };
class TextWindow final : public finalcut::FDialog class TextWindow final : public finalcut::FDialog
@ -246,6 +230,8 @@ class TextWindow final : public finalcut::FDialog
// Method // Method
void append(const finalcut::FString&); void append(const finalcut::FString&);
void clear(); void clear();
std::string get();
void set(const finalcut::FString&);
private: private:
// Method // Method
void onClose(finalcut::FCloseEvent*) override; void onClose(finalcut::FCloseEvent*) override;
@ -291,9 +277,15 @@ class VMEngine
public: public:
VMEngine(TextWindow *log); VMEngine(TextWindow *log);
void Configure(State *init,Code *code); void Configure(State *init,Code *code);
void Halt(Code *code);
void Run(Code *code, uint32_t start, uint32_t stop, uint64_t timeout); void Run(Code *code, uint32_t start, uint32_t stop, uint64_t timeout);
std::string getRegs(int level); std::string getRegs(int level);
void Prepare(State *init, Code *code);
void SetMem(State *init, Code *code);
void SetRegs(State *init, Code *code);
private: private:
void Init();
void Close();
uc_engine *uc; uc_engine *uc;
uc_err err; uc_err err;
TextWindow *log; TextWindow *log;
@ -314,6 +306,8 @@ class Menu final : public finalcut::FDialog
void loadGoal(); void loadGoal();
private: private:
Code *code = new Code(); Code *code = new Code();
void onTimer (finalcut::FTimerEvent*) override;
void refresh();
void configureFileMenuItems(); void configureFileMenuItems();
void initMenusCallBack (); void initMenusCallBack ();
void initMenus(); void initMenus();
@ -321,10 +315,11 @@ class Menu final : public finalcut::FDialog
void initNow(); void initNow();
void initCore(); void initCore();
void compile(); void compile();
void end();
void exec(); void exec();
void trace(); void trace();
void step(); void step();
void verify(); bool verify();
void AdjustWindows(); void AdjustWindows();
void initWindows(); void initWindows();
void splash(); void splash();
@ -358,13 +353,13 @@ class Menu final : public finalcut::FDialog
finalcut::FStatusBar Statusbar{this}; finalcut::FStatusBar Statusbar{this};
TextWindow log{this}; TextWindow log{this};
TextWindow view{this}; TextWindow view{this};
InstructionWindow debug{this}; InstructionWindow debug{this};
TextFixedWindow regs{this}; TextWindow regs{this};
TextFixedWindow flags{this}; TextWindow flags{this};
TextFixedWindow stack{this}; TextWindow stack{this};
TextFixedWindow mem{this}; TextWindow mem{this};
TextFixedWindow tuto{this}; TextWindow tuto{this};
TextFixedWindow screen{this}; TextWindow screen{this};
TextEditWindow edit{this}; TextEditWindow edit{this};
ScenarioWindow scenar{this}; ScenarioWindow scenar{this};
VMEngine vm{&log}; VMEngine vm{&log};
@ -372,3 +367,4 @@ class Menu final : public finalcut::FDialog
Desassembler unasmer{&log}; Desassembler unasmer{&log};
}; };