Further commands

This commit is contained in:
Luxdragon 2024-01-20 12:31:11 +01:00
parent 0b2aeb182f
commit 0b1a59a4d4

View file

@ -7,9 +7,6 @@
// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -lpthread -o emulator
#define WIDTH 224
#define HEIGHT 256
void keyDown(uint8_t key);
void keyUp(uint8_t key);
@ -88,6 +85,7 @@ static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer u
uint8_t in_port;
char which_interrupt;
uint8_t upscaleFactor = 2;
uint8_t lauteco = 90;
//GLOBAL GRAPHICS
uint8_t *bitmap = NULL;
@ -780,6 +778,19 @@ int emulate8080(State8080* state) {
state->pc += 2;
}
break;
case 0x3b: // DCX SP
{
state->sp--;
}
break;
case 0x3c: // INR A
{
state->a++;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
}
break;
case 0x3d: // DCR A
{
state->a--;
@ -788,10 +799,14 @@ int emulate8080(State8080* state) {
state->cc.p = parity(state->a, 8);
}
break;
case 0x3e: // MVI A, byte
state->a = opcode[1];
state->pc++;
break;
case 0x3f: // CMC
state->cc.cy = 0;
break;
case 0x41: // MOV B, C
state->b = state->c;
break;
@ -1008,22 +1023,128 @@ int emulate8080(State8080* state) {
state->cc.cy = (1 == (x & 1));
}
break;
case 0xa0: // ANA B
state->a = state->a & state->b;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa1: // ANA C
state->a = state->a & state->c;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa2: // ANA D
state->a = state->a & state->d;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa3: // ANA E
state->a = state->a & state->e;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa4: // ANA H
state->a = state->a & state->h;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa5: // ANA L
state->a = state->a & state->l;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xa6: // ANA HL
{
uint16_t adress = (state->h << 8) | state->l;
state->a = state->a & state->memory[adress];
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
}
break;
case 0xa7: // ANA A
state->a &= state->a;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = 0;
state->cc.ac = 0;
state->cc.cy = state->cc.ac = 0;
break;
case 0xa8: // XRA B
state->a ^= state->b;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xa9: // XRA C
state->a ^= state->c;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xaa: // XRA D
state->a ^= state->d;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xab: // XRA E
state->a ^= state->e;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xac: // XRA H
state->a ^= state->h;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xad: // XRA L
state->a ^= state->d;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = state->cc.ac = 0;
break;
case 0xae: // XRA HL
{
uint16_t adress = (state->h << 8) | state->l;
state->a ^= state->memory[adress];
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
}
break;
case 0xaf: // XRA A
state->a ^= state->a;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
state->cc.cy = 0;
state->cc.ac = 0;
state->cc.cy = state->cc.ac = 0;
break;
case 0xb0: // ORA B
state->a |= state->b;
@ -1032,6 +1153,41 @@ int emulate8080(State8080* state) {
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb1: // ORA C
state->a |= state->c;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb2: // ORA D
state->a |= state->d;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb3: // ORA E
state->a |= state->e;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb4: // ORA H
state->a |= state->h;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb5: // ORA L
state->a |= state->l;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xb6: // ORA M
{
uint16_t offset = (state->h<<8) | (state->l);
@ -1042,6 +1198,13 @@ int emulate8080(State8080* state) {
state->cc.p = parity(state->a, 8);
}
break;
case 0xb7: // ORA A
state->a |= state->a;
state->cc.cy = state->cc.ac = 0;
state->cc.z = (state->a == 0);
state->cc.s = (0x80 == (state->a & 0x80));
state->cc.p = parity(state->a, 8);
break;
case 0xc0: // RNZ
{
if (state->cc.z == 0) {
@ -1118,6 +1281,19 @@ int emulate8080(State8080* state) {
}
}
break;
case 0xcc: // CZ adress
{
if (state->cc.z == 1) {
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = (ret >> 8) & 0xff;
state->memory[state->sp-2] = ret & 0xff;
state->sp -= 2;
state->pc = (opcode[2] << 8) | opcode[1];
} else {
state->pc += 2;
}
}
break;
case 0xcd: // CALL adress
{
@ -1128,6 +1304,32 @@ int emulate8080(State8080* state) {
state->pc = (opcode[2] << 8) | opcode[1];
}
break;
case 0xce: // ACI byte
{
uint16_t answer = (uint16_t) state->a + (uint16_t) opcode[1] + state->cc.cy;
state->cc.z = ((answer & 0xff) == 0);
state->cc.s = (((answer & 0xff) & 0x80) == 0x80);
state->cc.p = parity(answer & 0xff, 8);
state->cc.cy = (answer > 0xff);
state->a = answer & 0xff;
state->pc++;
}
break;
case 0xcf: // RST 1
{
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = (ret >> 8) & 0xff;
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = 0x08;
}
break;
case 0xd0: // RNC
if (state->cc.cy == 0) {
state->pc = state->memory[state->sp] | (state->memory[state->sp+1]<<8);
state->sp += 2;
}
break;
case 0xd1: // POP D
state->e = state->memory[state->sp];
state->d = state->memory[state->sp+1];
@ -1149,11 +1351,44 @@ int emulate8080(State8080* state) {
state->pc++;
}
break;
case 0xd4: // CNC Adress
{
if (state->cc.cy == 0) {
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = ((ret >> 8) & 0xff);
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = (opcode[2] << 8) | opcode[1];
} else {
state->pc += 2;
}
}
break;
case 0xd5: // PUSH D
state->memory[state->sp-1] = state->d;
state->memory[state->sp-2] = state->e;
state->sp -= 2;
break;
case 0xd6: // SUI Byte
{
uint8_t x = state->a - opcode[1];
state->cc.z = (x&0xff == 0);
state->cc.s = (0x80 == ((x&0xff) & 0x80));
state->cc.p = parity(x&0xff, 8);
state->cc.cy = (state->a < opcode[1]);
state->a = x;
state->pc++;
}
break;
case 0xd7: // RST 2
{
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = ((ret >> 8) & 0xff);
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = 0x10;
}
break;
case 0xd8: // RC
{
if (state->cc.cy != 0) {
@ -1178,6 +1413,46 @@ int emulate8080(State8080* state) {
state->pc++;
}
break;
case 0xdc: // CC Adress
{
if (state->cc.cy != 0) {
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = ((ret >> 8) & 0xff);
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = (opcode[2] << 8) | opcode[1];
} else {
state->pc += 2;
}
}
break;
case 0xde: // SBI byte
{
uint16_t x = state->a - opcode[1] - state->cc.cy;
state->cc.z = (x&0xff == 0);
state->cc.s = (0x80 == ((x&0xff) & 0x80));
state->cc.p = parity(x&0xff, 8);
state->cc.cy = (x > 0xff);
state->a = x & 0xff;
state->pc++;
}
break;
case 0xdf: // RST 3
{
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = ((ret >> 8) & 0xff);
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = 0x18;
}
break;
case 0xe0: // RPO
if (state->cc.p == 0)
{
state->pc = state->memory[state->sp] | (state->memory[state->sp+1]<<8);
state->sp += 2;
}
break;
case 0xe1: // POP H
state->l = state->memory[state->sp];
state->h = state->memory[state->sp+1];
@ -1349,11 +1624,60 @@ int emulate8080(State8080* state) {
state->memory[state->sp-2] = (state->cc.z | (state->cc.s << 1) | (state->cc.p << 2) | (state->cc.cy << 3) | (state->cc.ac << 4));
state->sp -= 2;
break;
case 0xf6: // ORI
{
uint8_t x = state->a | opcode[1];
state->cc.z = (x == 0);
state->cc.s = (0x80 == (x & 0x80));
state->cc.p = parity(x, 8);
case 0xfb: // EI
state->int_enable = 1; break;
state->cc.cy = 0;
state->a = x;
state->pc++;
}
break;
case 0xf7: // RST 6
{
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = (ret >> 8) & 0xff;
state->memory[state->sp-2] = (ret & 0xff);
state->sp -=2;
state->pc = 0x30;
}
break;
case 0xf8: //RM
if (state->cc.s != 0)
{
state->pc = state->memory[state->sp] | (state->memory[state->sp+1]<<8);
state->sp += 2;
}
break;
case 0xf9: // SPHL
state->sp = state->l | (state->h << 8);
break;
case 0xfa: // JM
if (state->cc.s != 0)
state->pc = (opcode[2] << 8) | opcode[1];
else
state->pc += 2;
break;
case 0xfb: // EI
state->int_enable = 1;
break;
case 0xfc: // CM
{
if (state->cc.s != 0) {
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = (ret >> 8) & 0xff;
state->memory[state->sp-2] = (ret & 0xff);
state->sp -= 2;
state->pc = (opcode[2] << 8) | opcode[1];
} else {
state->pc += 2;
}
}
break;
case 0xfe: // CPI byte
{
uint8_t x = state->a - opcode[1];
@ -1364,7 +1688,15 @@ int emulate8080(State8080* state) {
state->pc++;
}
break;
case 0xff: // RST 7
{
uint16_t ret = state->pc+2;
state->memory[state->sp-1] = (ret >> 8) & 0xff;
state->memory[state->sp-2] = (ret & 0xff);
state->sp -=2;
state->pc = 0x38;
}
break;
default: unknownInstruction(state); break;
}
printState(state);
@ -1485,9 +1817,9 @@ void *cpu(void* arg) {
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
uint8_t *video = malloc(sizeof(uint8_t) * 256 * 256); // Adjusted size
// Clear the drawing area
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_paint(cr);
// Clear the drawing area if you want
//cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
//cairo_paint(cr);
// Copying the bitmap to video output
for (int i = 0; i < 224; i++) {
@ -1505,7 +1837,7 @@ static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
}
// Rendering the graphics
for (int x = 0; x < 256; x++) {
for (int x = 0; x < 224; x++) {
for (int y = 0; y < 256; y++) {
if (video[y*256 + x]) {
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
@ -1523,11 +1855,9 @@ static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
void on_about_clicked(GtkToolButton *toolbutton, gpointer user_data) {
GtkWidget *dialog = gtk_about_dialog_new();
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog), "Turi's Super Duper Emulatinator");
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "This is a super duper emulatinator created by Turi.");
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("Luka.png", NULL);
gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), pixbuf);
g_object_unref(pixbuf);
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog), "Lux8080-Emulator");
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "This is a simple Intel 8080-Emulator for Space Invaders using C and GTK. Following the guide of @realemulator101");
gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), "your logo");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
@ -1577,8 +1907,8 @@ int main (int argc, char *argv[]) {
// GTK init
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
gtk_window_set_title(GTK_WINDOW(window), "Luxulator");
gtk_window_set_default_size(GTK_WINDOW(window), 448, 550);
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);