aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2023-01-30 23:16:44 +0100
committerMarvin Borner2023-01-30 23:16:44 +0100
commit82f6a5ef2b2ca2ec31afabdca9d0141bc732c6e7 (patch)
tree09d564355a649d7238ea5a5a49c94efb168a532c
parent9f770358c43ccf3730e85c3a6bbb00d0b492ecbb (diff)
More gui => more bugsHEADmain
-rw-r--r--inc/cpu.h5
-rw-r--r--inc/gui.h5
-rw-r--r--src/cpu.c22
-rw-r--r--src/gui.c125
-rw-r--r--src/main.c3
5 files changed, 115 insertions, 45 deletions
diff --git a/inc/cpu.h b/inc/cpu.h
index ca85a2f..e0caf50 100644
--- a/inc/cpu.h
+++ b/inc/cpu.h
@@ -6,9 +6,10 @@
#include <err.h>
struct cpu_interface {
- void (*reg_names)(const char *names, int n);
+ void (*reg_names)(const char *names[], int n);
void (*reg_update)(int reg, uint64_t val);
- void (*instr_done)(char *instr);
+ void (*instr_push)(char *instr);
+ void (*instr_pop)(void);
};
enum registers {
diff --git a/inc/gui.h b/inc/gui.h
index e8a583d..3dfcc1b 100644
--- a/inc/gui.h
+++ b/inc/gui.h
@@ -9,9 +9,10 @@ struct gui_interface {
err (*step_prev)(void);
};
-void gui_reg_names(const char *names, int n);
+void gui_reg_names(const char *names[], int n);
void gui_reg_update(int reg, uint64_t value);
-void gui_instr_done(char *instr);
+void gui_instr_push(char *instr);
+void gui_instr_pop(void);
void gui_register_interface(struct gui_interface *gui);
void gui_init(void);
diff --git a/src/cpu.c b/src/cpu.c
index 21b9f19..bce36a2 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -104,6 +104,13 @@ static err (*neg_instructions[256])(void);
static uint64_t regs[REGISTERS_COUNT] = { 0 };
static struct rip_history *rip_history;
+static char instruction_response_factory[256] = { 0 };
+
+static const char *register_names[REGISTERS_COUNT] = {
+ "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI",
+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
+};
+
static void print_state(void)
{
logln("rip=%x, rax=%x, rcx=%x, rdx=%x, rbx=%x, rsp=%x, rbp=%x, rsi=%x, rdi=%x,\nr8=%x, r9=%x, r10=%x, r11=%x, r12=%x, r13=%x, r14=%x, r15=%x",
@@ -129,6 +136,7 @@ static err pos_opcode(void)
uint8_t op = U8();
// TODO: is_*, j*
if (op == 0x05) {
+ sprintf(instruction_response_factory, "syscall");
return linux_call();
}
return ERR;
@@ -137,7 +145,10 @@ static err pos_opcode(void)
static err pos_mov_r32_rm32(void)
{
uint8_t modrm = U8();
- SET_R32(REG(), GET_RM32());
+ uint8_t reg = REG();
+ uint32_t val = GET_RM32();
+ sprintf(instruction_response_factory, "mov %s, %x", register_names[reg],
+ val);
return OK;
}
@@ -145,12 +156,16 @@ static err pos_mov_r32_imm32(void)
{
rip--;
uint8_t reg = U8() - 0xb8;
- SET_R32(reg, U32());
+ uint32_t val = U32();
+ SET_R32(reg, val);
+ sprintf(instruction_response_factory, "mov %s, %#x",
+ register_names[reg], val);
return OK;
}
static err pos_nop(void)
{
+ sprintf(instruction_response_factory, "nop");
return OK;
}
@@ -167,6 +182,7 @@ static err pos_int(void)
static void initialize(void)
{
+ interface->reg_names(register_names, REGISTERS_COUNT);
for (int i = 0; i < 256; i++) {
pos_instructions[i] = pos_unknown_instruction;
neg_instructions[i] = neg_unknown_instruction;
@@ -220,6 +236,7 @@ err cpu_next(void)
return END;
logln("%x", instr);
err ret = pos_instructions[instr]();
+ interface->instr_push(instruction_response_factory);
print_state();
struct rip_history *next = malloc(sizeof(*next));
@@ -239,6 +256,7 @@ err cpu_prev(void)
if (!instr)
return ERR;
err ret = neg_instructions[instr]();
+ interface->instr_pop();
print_state();
free(rip_history);
diff --git a/src/gui.c b/src/gui.c
index 297ff6f..38d983f 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -9,7 +9,10 @@ enum stepper_response_type {
};
static struct gui_interface *interface;
+static GtkWindow *main;
+static GtkStringList *execution_list;
+// TODO: Either beautify or use InfoBar
static void error_dialog(GtkWindow *parent, const char *msg)
{
GtkWidget *dialog = gtk_dialog_new_with_buttons(
@@ -24,61 +27,102 @@ static void error_dialog(GtkWindow *parent, const char *msg)
gtk_widget_show(dialog);
}
-static void stepper_response(GtkWidget *widget, enum stepper_response_type type)
+static void stepper_handle_response(err ret)
{
- err ret = OK;
-
- switch (type) {
- case STEP_PREV:
- ret = interface->step_prev();
- break;
- case STEP_NEXT:
- ret = interface->step_next();
- break;
- default:
- break;
- }
-
if (ret == END || ret == ERR) {
- error_dialog(GTK_WINDOW(widget),
+ error_dialog(main,
ret == END ? "Reached end" : "An error occured");
}
}
-static void init_stepper_dialog(GtkWindow *parent)
+static void stepper_next(void)
{
- GtkWidget *stepper = gtk_dialog_new_with_buttons(
- "Stepper", parent,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "Previous",
- 1, "Next", 2, NULL);
+ stepper_handle_response(interface->step_next());
+}
- GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(stepper));
- GtkWidget *label = gtk_label_new("Stepper");
+static void stepper_prev(void)
+{
+ stepper_handle_response(interface->step_prev());
+}
- g_signal_connect_swapped(stepper, "response",
- G_CALLBACK(stepper_response), stepper);
+static void init_menu(void)
+{
+ GtkWidget *header = gtk_header_bar_new();
- gtk_box_append(GTK_BOX(content), label);
- gtk_widget_show(stepper);
+ GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_add_css_class(box, "linked");
+
+ GtkWidget *prev = gtk_button_new_from_icon_name("go-previous-symbolic");
+ gtk_box_append(GTK_BOX(box), prev);
+
+ GtkWidget *next = gtk_button_new_from_icon_name("go-next-symbolic");
+ gtk_box_append(GTK_BOX(box), next);
+
+ g_signal_connect(prev, "clicked", G_CALLBACK(stepper_prev), prev);
+ g_signal_connect(next, "clicked", G_CALLBACK(stepper_next), next);
+
+ gtk_header_bar_pack_end(GTK_HEADER_BAR(header), box);
+ gtk_window_set_titlebar(main, header);
+}
+
+static void setup_execution_list(GtkSignalListItemFactory *self,
+ GtkListItem *item, gpointer data)
+{
+ (void)self;
+ (void)data;
+ GtkWidget *test = gtk_label_new(0);
+ gtk_label_set_xalign(GTK_LABEL(test), 0);
+ gtk_list_item_set_child(item, test);
}
-static void init_execution_window(GtkApplication *app)
+static void bind_execution_list(GtkSignalListItemFactory *self,
+ GtkListItem *item, gpointer data)
{
- GtkWidget *execution = gtk_application_window_new(app);
- gtk_window_set_title(GTK_WINDOW(execution), "Execution");
- gtk_window_set_default_size(GTK_WINDOW(execution), 200, 200);
- gtk_widget_show(execution);
+ (void)self;
+ (void)data;
+ GtkWidget *test = gtk_list_item_get_child(item);
+ GtkStringObject *str = gtk_list_item_get_item(item);
+ gtk_label_set_text(GTK_LABEL(test), gtk_string_object_get_string(str));
+}
- init_stepper_dialog(GTK_WINDOW(execution));
+static GtkWidget *init_execution_list(void)
+{
+ const char *array[] = { NULL };
+ execution_list = gtk_string_list_new((const char *const *)array);
+ GtkNoSelection *model =
+ gtk_no_selection_new(G_LIST_MODEL(execution_list));
+
+ GtkListItemFactory *factory = gtk_signal_list_item_factory_new();
+ g_signal_connect(factory, "setup", G_CALLBACK(setup_execution_list), 0);
+ g_signal_connect(factory, "bind", G_CALLBACK(bind_execution_list), 0);
+ return gtk_list_view_new(GTK_SELECTION_MODEL(model), factory);
+}
+
+static void init_main_window(GtkApplication *app)
+{
+ main = GTK_WINDOW(gtk_application_window_new(app));
+ gtk_window_set_title(main, "Simsalasim");
+ gtk_window_set_default_size(main, 200, 200);
+
+ GtkWidget *paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_window_set_child(main, paned);
+
+ GtkWidget *left = init_execution_list();
+ gtk_paned_set_start_child(GTK_PANED(paned), left);
+
+ GtkWidget *right = gtk_label_new("end");
+ gtk_paned_set_end_child(GTK_PANED(paned), right);
}
static void activate(GtkApplication *app, gpointer user_data)
{
(void)user_data;
- init_execution_window(app);
+ init_main_window(app);
+ init_menu();
+ gtk_widget_show(GTK_WIDGET(main));
}
-void gui_reg_names(const char *names, int n)
+void gui_reg_names(const char *names[], int n)
{
(void)names;
(void)n;
@@ -90,9 +134,16 @@ void gui_reg_update(int reg, uint64_t value)
(void)value;
}
-void gui_instr_done(char *instr)
+static int execution_list_length = 0;
+void gui_instr_push(char *instr)
+{
+ gtk_string_list_take(execution_list, instr);
+ execution_list_length++;
+}
+
+void gui_instr_pop(void)
{
- (void)instr;
+ gtk_string_list_remove(execution_list, --execution_list_length);
}
void gui_register_interface(struct gui_interface *gui)
@@ -102,8 +153,6 @@ void gui_register_interface(struct gui_interface *gui)
void gui_init(void)
{
- g_object_set(gtk_settings_get_default(),
- "gtk-application-prefer-dark-theme", TRUE, NULL);
GtkApplication *app = gtk_application_new("de.melvars.simsalasim",
G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
diff --git a/src/main.c b/src/main.c
index 244b715..7f5ad67 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,8 @@
static struct cpu_interface cpu = {
.reg_names = gui_reg_names,
.reg_update = gui_reg_update,
- .instr_done = gui_instr_done,
+ .instr_push = gui_instr_push,
+ .instr_pop = gui_instr_pop,
};
static struct gui_interface gui = {