First experimentation with GTK
This commit is contained in:
parent
dabe8f1ff6
commit
7bc9bf9d9f
1 changed files with 107 additions and 16 deletions
121
emulator_shell.c
121
emulator_shell.c
|
@ -2,9 +2,43 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h> // for the uintx_t's
|
#include <stdint.h> // for the uintx_t's
|
||||||
#include <unistd.h> // for sleep
|
#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 disassemble8080(unsigned char* code) {
|
||||||
int opbytes = 1;
|
int opbytes = 1;
|
||||||
|
@ -332,6 +366,9 @@ typedef struct State8080 {
|
||||||
uint8_t *memory;
|
uint8_t *memory;
|
||||||
ConditionCodes cc;
|
ConditionCodes cc;
|
||||||
uint8_t int_enable;
|
uint8_t int_enable;
|
||||||
|
uint8_t shift_offset;
|
||||||
|
uint8_t shift0;
|
||||||
|
uint8_t shift1;
|
||||||
} State8080;
|
} State8080;
|
||||||
|
|
||||||
void unknownInstruction(State8080* state) {
|
void unknownInstruction(State8080* state) {
|
||||||
|
@ -352,6 +389,14 @@ int parity(int x, int size)
|
||||||
return (0 == (p & 0x1));
|
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) {
|
int emulate8080(State8080* state) {
|
||||||
unsigned char *opcode = &(state->memory[state->pc]);
|
unsigned char *opcode = &(state->memory[state->pc]);
|
||||||
|
|
||||||
|
@ -651,7 +696,7 @@ int emulate8080(State8080* state) {
|
||||||
state->sp += 2;
|
state->sp += 2;
|
||||||
break;
|
break;
|
||||||
case 0xd3: // OUT byte
|
case 0xd3: // OUT byte
|
||||||
printf("%c", opcode[1]);
|
//printf("%c", opcode[1]);
|
||||||
state->pc++;
|
state->pc++;
|
||||||
break;
|
break;
|
||||||
case 0xd5: // PUSH D
|
case 0xd5: // PUSH D
|
||||||
|
@ -659,7 +704,10 @@ int emulate8080(State8080* state) {
|
||||||
state->memory[state->sp-2] = state->e;
|
state->memory[state->sp-2] = state->e;
|
||||||
state->sp -= 2;
|
state->sp -= 2;
|
||||||
break;
|
break;
|
||||||
|
case 0xdb: // IN byte
|
||||||
|
//printf("%c", opcode[1]);
|
||||||
|
state->pc++;
|
||||||
|
break;
|
||||||
case 0xe1: // POP H
|
case 0xe1: // POP H
|
||||||
state->l = state->memory[state->sp];
|
state->l = state->memory[state->sp];
|
||||||
state->h = state->memory[state->sp+1];
|
state->h = state->memory[state->sp+1];
|
||||||
|
@ -732,11 +780,7 @@ int emulate8080(State8080* state) {
|
||||||
|
|
||||||
default: unknownInstruction(state); break;
|
default: unknownInstruction(state); break;
|
||||||
}
|
}
|
||||||
printf("\tC=%d,P=%d,S=%d,Z=%d\n", state->cc.cy, state->cc.p,
|
printState(state);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,15 +800,50 @@ void read_Space_Invaders_ROM(State8080* state, const char* filename, int offset)
|
||||||
|
|
||||||
fread(buffer, fsize, 1, file);
|
fread(buffer, fsize, 1, file);
|
||||||
fclose(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
|
//Initializations
|
||||||
|
|
||||||
State8080 *state = (State8080*) malloc(sizeof(State8080));
|
State8080 *state = (State8080*) calloc(1, sizeof(State8080));
|
||||||
memset(state, 0, sizeof(State8080));
|
//memset(state, 0, sizeof(State8080));
|
||||||
state->cc.z = 1;
|
state->cc.z = 1;
|
||||||
state->cc.s = 1;
|
state->cc.s = 1;
|
||||||
state->cc.p = 1;
|
state->cc.p = 1;
|
||||||
|
@ -779,14 +858,26 @@ int main (void) {
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
char done = 0;
|
||||||
|
|
||||||
while (1) {
|
while (!done) {
|
||||||
//Show the command in the code
|
uint8_t* opcode = &state->memory[state->pc];
|
||||||
printf("%d\t\t:", i);
|
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);
|
emulate8080(state);
|
||||||
i++;
|
i++;
|
||||||
sleep(0.00001);
|
sleep(0.00001);
|
||||||
}
|
}
|
||||||
|
gtk_main();
|
||||||
free(state->memory);
|
free(state->memory);
|
||||||
free(state);
|
free(state);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue