Graphics Ansatz (DOESN'T WORK)
This commit is contained in:
parent
8d6beee1fd
commit
2b343e6dca
1 changed files with 67 additions and 78 deletions
145
emulator_shell.c
145
emulator_shell.c
|
@ -7,6 +7,9 @@
|
||||||
// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -o emulator
|
// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -o emulator
|
||||||
|
|
||||||
#define FREQUENCY 500
|
#define FREQUENCY 500
|
||||||
|
#define WIDTH 224
|
||||||
|
#define HEIGHT 256
|
||||||
|
|
||||||
void keyDown(uint8_t key);
|
void keyDown(uint8_t key);
|
||||||
void keyUp(uint8_t key);
|
void keyUp(uint8_t key);
|
||||||
|
|
||||||
|
@ -81,13 +84,14 @@ static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer u
|
||||||
|
|
||||||
//===== EMULATOR SETUP =====
|
//===== EMULATOR SETUP =====
|
||||||
|
|
||||||
uint8_t in_port; //GLOBAL VAR
|
//GLOBAL VARIABLES
|
||||||
char which_interrupt = 1; //GLOBAL VAR
|
uint8_t in_port;
|
||||||
|
char which_interrupt;
|
||||||
|
|
||||||
//GLOBAL GRAPHICS
|
//GLOBAL GRAPHICS
|
||||||
uint8_t *bitmap = NULL;
|
uint8_t *bitmap = NULL;
|
||||||
int bitmap_width = 224;
|
|
||||||
int bitmap_height = 256;
|
|
||||||
|
|
||||||
typedef struct ConditionCodes {
|
typedef struct ConditionCodes {
|
||||||
//bitfields for condition codes
|
//bitfields for condition codes
|
||||||
|
@ -992,65 +996,58 @@ void simulateNanoseconds(unsigned int numNanoseconds)
|
||||||
nanosleep(&sleepTime, NULL);
|
nanosleep(&sleepTime, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct cpu_data {
|
||||||
|
char done;
|
||||||
|
int total_cycles_count;
|
||||||
|
GtkWidget* drawing_area;
|
||||||
|
State8080 *state;
|
||||||
|
|
||||||
|
} cpu_data;
|
||||||
|
|
||||||
// ===== GTK GRAPHICS =====
|
// ===== GTK GRAPHICS =====
|
||||||
|
|
||||||
// Callback function to handle the "draw" signal of the Drawing Area
|
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||||
gboolean draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data)
|
int x, y;
|
||||||
{
|
for (y = 0; y < HEIGHT; y++) {
|
||||||
// Check if the bitmap image data is available
|
for (x = 0; x < WIDTH; x++) {
|
||||||
if (bitmap != NULL && bitmap_width > 0 && bitmap_height > 0)
|
if (bitmap[y * WIDTH + x]) {
|
||||||
{
|
cairo_rectangle(cr, x, y, 1, 1);
|
||||||
// Get the width and height of the drawing area
|
|
||||||
int width, height;
|
|
||||||
gtk_widget_get_size_request(widget, &width, &height);
|
|
||||||
|
|
||||||
// Calculate the width and height of each pixel
|
|
||||||
int pixel_width = width / bitmap_width;
|
|
||||||
int pixel_height = height / bitmap_height;
|
|
||||||
|
|
||||||
// Iterate over each pixel in the bitmap image
|
|
||||||
for (int y = 0; y < bitmap_height; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < bitmap_width; x++)
|
|
||||||
{
|
|
||||||
// Determine the color of the pixel
|
|
||||||
unsigned char pixel = bitmap[y * bitmap_width + x];
|
|
||||||
|
|
||||||
// Set the color based on the pixel value
|
|
||||||
if (pixel == 0)
|
|
||||||
{
|
|
||||||
// Black pixel
|
|
||||||
cairo_set_source_rgb(cr, 0, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// White pixel
|
|
||||||
cairo_set_source_rgb(cr, 1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the pixel
|
|
||||||
cairo_rectangle(cr, x * pixel_width, y * pixel_height, pixel_width, pixel_height);
|
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
static gboolean cpu(gpointer user_data) {
|
||||||
|
cpu_data *cpu = user_data;
|
||||||
|
char done = cpu->done;
|
||||||
|
State8080* state = cpu->state;
|
||||||
|
int counter;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
counter = emulate8080(cpu->state);
|
||||||
|
cpu->total_cycles_count += counter;
|
||||||
|
|
||||||
|
simulateNanoseconds(FREQUENCY * counter); // 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);
|
||||||
|
if (which_interrupt == 2) {
|
||||||
|
generateInterrupt(state, 2); //interrupt 2
|
||||||
|
cpu->total_cycles_count = 0;
|
||||||
|
which_interrupt = 1;
|
||||||
|
} else {
|
||||||
|
generateInterrupt(state, 1); //interrupt 1
|
||||||
|
cpu->total_cycles_count = 0;
|
||||||
|
which_interrupt = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
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);
|
|
||||||
g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL);
|
|
||||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
|
||||||
|
|
||||||
// EMULATOR INIT
|
// EMULATOR INIT
|
||||||
|
|
||||||
State8080 *state = (State8080*) calloc(1, sizeof(State8080)); //memset obsolte with calloc
|
State8080 *state = (State8080*) calloc(1, sizeof(State8080)); //memset obsolte with calloc
|
||||||
|
@ -1067,9 +1064,17 @@ int main (int argc, char *argv[]) {
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000);
|
read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000);
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
||||||
|
|
||||||
|
// GTK INIT
|
||||||
// DRAWING AREA 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);
|
||||||
|
g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL);
|
||||||
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
|
||||||
|
// DRAWING AREA INIT
|
||||||
bitmap = &(state->memory[0x2400]);
|
bitmap = &(state->memory[0x2400]);
|
||||||
GtkWidget *drawing_area = gtk_drawing_area_new();
|
GtkWidget *drawing_area = gtk_drawing_area_new();
|
||||||
gtk_container_add(GTK_CONTAINER(window), drawing_area);
|
gtk_container_add(GTK_CONTAINER(window), drawing_area);
|
||||||
|
@ -1078,36 +1083,20 @@ int main (int argc, char *argv[]) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
char done = 0;
|
|
||||||
int counter;
|
|
||||||
int total_count = 0;
|
|
||||||
|
|
||||||
while (!done) {
|
//MAIN LOOP & TERMINATION
|
||||||
counter = emulate8080(state);
|
|
||||||
total_count += counter;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
simulateNanoseconds(FREQUENCY * counter); // EMULATION OF THE PROCESSOR ŠPEED
|
|
||||||
if ((total_count > 16000000) && (state->int_enable)) //1/60 second has elapsed
|
|
||||||
{
|
|
||||||
gtk_widget_queue_draw(drawing_area);
|
|
||||||
if (which_interrupt == 2) {
|
|
||||||
generateInterrupt(state, 2); //interrupt 2
|
|
||||||
total_count = 0;
|
|
||||||
which_interrupt = 1;
|
|
||||||
} else {
|
|
||||||
generateInterrupt(state, 1); //interrupt 0
|
|
||||||
total_count = 0;
|
|
||||||
which_interrupt = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_main();
|
gtk_main();
|
||||||
free(state->memory);
|
free(state->memory);
|
||||||
free(state);
|
free(state);
|
||||||
|
free(cpu_eco);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue