diff --git a/emulator_shell.c b/emulator_shell.c index e03d7ed..13340f0 100644 --- a/emulator_shell.c +++ b/emulator_shell.c @@ -3,10 +3,10 @@ #include // for the uintx_t's #include // for sleep #include +#include -// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -o emulator +// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -lpthread -o emulator -#define FREQUENCY 500 #define WIDTH 224 #define HEIGHT 256 @@ -986,16 +986,6 @@ void keyUp( uint8_t key) } } -void simulateNanoseconds(unsigned int numNanoseconds) -{ - struct timespec sleepTime; - sleepTime.tv_sec = 0; - sleepTime.tv_nsec = numNanoseconds; - - // Pause the program execution for the specified duration - nanosleep(&sleepTime, NULL); -} - typedef struct cpu_data { char done; int total_cycles_count; @@ -1008,18 +998,24 @@ typedef struct cpu_data { static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) { int x, y; - for (y = 0; y < HEIGHT; y++) { - for (x = 0; x < WIDTH; x++) { + int upscaleFactor = 4; + + for (x = 0; x < WIDTH; x++) { + for (y = 0; y < HEIGHT; y++) { if (bitmap[y * WIDTH + x]) { - cairo_rectangle(cr, x, y, 1, 1); - cairo_fill(cr); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white + } else { + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black } + + cairo_rectangle(cr, x * upscaleFactor, y * upscaleFactor, upscaleFactor, upscaleFactor); + cairo_fill(cr); } } } -static gboolean cpu(gpointer user_data) { - cpu_data *cpu = user_data; +void *cpu(void* arg) { + cpu_data *cpu = (cpu_data*) arg; char done = cpu->done; State8080* state = cpu->state; int counter; @@ -1028,10 +1024,10 @@ static gboolean cpu(gpointer user_data) { counter = emulate8080(cpu->state); cpu->total_cycles_count += counter; - simulateNanoseconds(FREQUENCY * counter); // EMULATION OF THE PROCESSOR ŠPEED + usleep(counter / 2); // EMULATION OF THE PROCESSOR ŠPEED if ((cpu->total_cycles_count > 16000000) && (state->int_enable)) //1/60 second has elapsed { - gtk_widget_queue_draw(user_data); + //redraw screen() will be handeled by the gtk_main() function if (which_interrupt == 2) { generateInterrupt(state, 2); //interrupt 2 cpu->total_cycles_count = 0; @@ -1067,7 +1063,6 @@ int main (int argc, char *argv[]) { // GTK INIT gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - g_print("Test\n"); gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); gtk_window_set_title(GTK_WINDOW(window), "Lux8080-Emulator"); g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL); @@ -1077,24 +1072,27 @@ int main (int argc, char *argv[]) { // DRAWING AREA INIT bitmap = &(state->memory[0x2400]); GtkWidget *drawing_area = gtk_drawing_area_new(); + gtk_widget_set_app_paintable(drawing_area, TRUE); gtk_container_add(GTK_CONTAINER(window), drawing_area); g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_callback), NULL); gtk_widget_show_all(window); - - - // CPU INIT + // CPU INIT cpu_data *cpu_eco = malloc(sizeof(cpu_data)); cpu_eco->state = state; cpu_eco->drawing_area = drawing_area; cpu_eco->done = 0; cpu_eco->total_cycles_count = 0; - g_idle_add(cpu, cpu_eco); - - - //MAIN LOOP & TERMINATION + // PTHREAD + pthread_t pid; + pthread_create(&pid, NULL, cpu, (void*) cpu_eco); + + + //MAIN LOOP & TERMINATION //gtk_widget_queue_draw + g_timeout_add(16, (GSourceFunc)gtk_widget_queue_draw, drawing_area); gtk_main(); + pthread_join(pid, NULL); free(state->memory); free(state); free(cpu_eco);