First experimentation with GTK

This commit is contained in:
Luxdragon 2024-01-13 22:38:02 +01:00
parent dabe8f1ff6
commit 7bc9bf9d9f

View file

@ -2,9 +2,43 @@
#include <stdlib.h>
#include <stdint.h> // for the uintx_t's
#include <unistd.h> // for sleep
#include <string.h> // for memset
#include <gtk/gtk.h>
// 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;