From 7bc9bf9d9f460d233dced7145401c78a91e4126c Mon Sep 17 00:00:00 2001 From: Luxdragon Date: Sat, 13 Jan 2024 22:38:02 +0100 Subject: [PATCH] First experimentation with GTK --- emulator_shell.c | 123 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 16 deletions(-) diff --git a/emulator_shell.c b/emulator_shell.c index 08c90e9..22c2971 100644 --- a/emulator_shell.c +++ b/emulator_shell.c @@ -2,9 +2,43 @@ #include #include // for the uintx_t's #include // for sleep -#include // for memset +#include -// gcc emulator_shell.c -o emulator +// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -o emulator + +static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) +{ + switch (event->keyval) + { + case GDK_KEY_Left: + // Code to be executed when the left arrow key is pressed down + g_print("Left arrow key pressed down\n"); + break; + case GDK_KEY_Right: + // Code to be executed when the right arrow key is pressed down + g_print("Right arrow key pressed down\n"); + break; + } + + return FALSE; +} + +static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer user_data) +{ + switch (event->keyval) + { + case GDK_KEY_Left: + // Code to be executed when the left arrow key is released + g_print("Left arrow key released\n"); + break; + case GDK_KEY_Right: + // Code to be executed when the right arrow key is released + g_print("Right arrow key released\n"); + break; + } + + return FALSE; +} int disassemble8080(unsigned char* code) { int opbytes = 1; @@ -331,7 +365,10 @@ typedef struct State8080 { uint16_t pc; uint8_t *memory; ConditionCodes cc; - uint8_t int_enable; + uint8_t int_enable; + uint8_t shift_offset; + uint8_t shift0; + uint8_t shift1; } State8080; void unknownInstruction(State8080* state) { @@ -352,6 +389,14 @@ int parity(int x, int size) return (0 == (p & 0x1)); } +void printState(State8080* state) { + printf("\tC=%d,P=%d,S=%d,Z=%d\n", state->cc.cy, state->cc.p, + state->cc.s, state->cc.z); + printf("\tA $%02x B $%02x C $%02x D $%02x E $%02x H $%02x L $%02x SP %04x\n", + state->a, state->b, state->c, state->d, + state->e, state->h, state->l, state->sp); +} + int emulate8080(State8080* state) { unsigned char *opcode = &(state->memory[state->pc]); @@ -651,7 +696,7 @@ int emulate8080(State8080* state) { state->sp += 2; break; case 0xd3: // OUT byte - printf("%c", opcode[1]); + //printf("%c", opcode[1]); state->pc++; break; case 0xd5: // PUSH D @@ -659,7 +704,10 @@ int emulate8080(State8080* state) { state->memory[state->sp-2] = state->e; state->sp -= 2; break; - + case 0xdb: // IN byte + //printf("%c", opcode[1]); + state->pc++; + break; case 0xe1: // POP H state->l = state->memory[state->sp]; state->h = state->memory[state->sp+1]; @@ -732,11 +780,7 @@ int emulate8080(State8080* state) { default: unknownInstruction(state); break; } - printf("\tC=%d,P=%d,S=%d,Z=%d\n", state->cc.cy, state->cc.p, - state->cc.s, state->cc.z); - printf("\tA $%02x B $%02x C $%02x D $%02x E $%02x H $%02x L $%02x SP %04x\n", - state->a, state->b, state->c, state->d, - state->e, state->h, state->l, state->sp); + printState(state); } @@ -756,15 +800,50 @@ void read_Space_Invaders_ROM(State8080* state, const char* filename, int offset) fread(buffer, fsize, 1, file); fclose(file); - } -int main (void) { +uint8_t machineIn(State8080* state, uint8_t port) { + uint8_t a; + switch(port) { + case 3: + { + uint16_t v = (state->shift1<<8) | (state->shift0); + a = ((v >> (8-state->shift_offset)) & 0xff); + } + break; + } + return a; +} + +uint8_t machineOut(State8080* state, uint8_t port, uint8_t value) { + uint8_t a; + switch(port) { + case 2: + { + state->shift_offset = value & 0x7; + } break; + case 4: + { + state->shift0 = state->shift1; + state->shift1 = value; + break; + } + } +} + +int main (int argc, char *argv[]) { + gtk_init(&argc, &argv); + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_print("Test\n"); + g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL); + g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL); + gtk_widget_show(window); + //Initializations - State8080 *state = (State8080*) malloc(sizeof(State8080)); - memset(state, 0, sizeof(State8080)); + State8080 *state = (State8080*) calloc(1, sizeof(State8080)); + //memset(state, 0, sizeof(State8080)); state->cc.z = 1; state->cc.s = 1; state->cc.p = 1; @@ -779,14 +858,26 @@ int main (void) { read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800); int i = 0; + char done = 0; - while (1) { - //Show the command in the code + while (!done) { + uint8_t* opcode = &state->memory[state->pc]; printf("%d\t\t:", i); + + if (*opcode == 0xdb) { + uint8_t port = opcode[1]; + state->a = machineIn(state, port); + state->pc++; + } else if (*opcode == 0xd3) { + uint8_t port = opcode[1]; + machineOut(state, port, 0x00); + state->pc++; + } emulate8080(state); i++; sleep(0.00001); } + gtk_main(); free(state->memory); free(state); return 0;