6502

minimal 6502 emulator written in C
Index Commits Files Refs README LICENSE
commit a2a21b54011e12761f6b51f6343f9491a05b1cc5
parent 352bf38c54d2ed852e4ade7478c03267c1ec37f7
Author: mjkloeckner <martinjkloeckner@gmail.com>
Date:   Sat, 29 Apr 2023 13:05:01 -0300

improve tui by using termios library

Diffstat:
M6502.c | 17+++++++----------
Mmain.c | 28++++++++++++++++++++--------
Atui.c | 41+++++++++++++++++++++++++++++++++++++++++
Atui.h | 7+++++++
4 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/6502.c b/6502.c
@@ -141,17 +141,14 @@ void print_reg(uint8_t reg) {
 void CPU_dump(void) {
     INS aux = decode[MEM_read(cpu.pc)];
 
-    printf("\033[?25l"); /* hide cursor */
-
-    printf("    a:   %02X (%3d)            N V - B D I Z C\n", cpu.ac, cpu.ac);
-    printf("    x:   %02X (%3d)            ", cpu.x, cpu.x);
+    printf("  a:   %02X (%3d)              N V - B D I Z C\n"
+            "  x:   %02X (%3d)              ", cpu.ac, cpu.ac, cpu.x, cpu.x);
     print_reg(cpu.st);
-    printf("    y:   %02X (%3d)\n", cpu.y, cpu.y);
-    printf("   sp:   %02X\n", cpu.sp);
-    printf("   pc: %04X -> %02X (%s)(%s)\n", cpu.pc, mem.ram[cpu.pc], aux.name, CPU_mode_name(aux.mode));
-    printf("\033[5A");
-
-    printf("\033[?25h"); /* re-enable cursor */
+    printf("  y:   %02X (%3d)\n"
+            " sp:   %02X\n"
+            " pc: %04X -> %02X (%s)(%s)\n"
+            "\033[5A", cpu.y, cpu.y, cpu.sp, cpu.pc, mem.ram[cpu.pc], aux.name,
+            CPU_mode_name(aux.mode));
 }
 
 uint16_t CPU_get_pc(void) {
diff --git a/main.c b/main.c
@@ -1,8 +1,15 @@
+#define _POSIX_C_SOURCE 199309L
+
 #include "6502.h"
+#include "tui.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <signal.h>
+
+#include <time.h>
+#define usleep(t) nanosleep((const struct timespec[]){{0, t * 1000L}}, NULL)
 
 #define INPUT_FILE_PATH    "6502_functional_test.bin"
 
@@ -18,6 +25,10 @@ void CPU_brk(uint16_t pc) {
     }
 }
 
+void sig_handler(int signo) {
+    if (signo == SIGINT) brk = true;
+}
+
 int main (void) {
     INS ins;
 
@@ -37,22 +48,23 @@ int main (void) {
     /* initialize registers from memmory */
     CPU_reset();
 
-    int c = 0;
+    set_input_mode();
+    signal(SIGINT, sig_handler);
+    signal (SIGQUIT, sig_handler);
+    atexit (reset_input_mode);
+
     do {
-        if(c == 'c') brk = false;
+        /* set break point at pc 0x336d */
         CPU_brk(0x336d);
 
-        /* Fetch an instruction and increment pc */
         CPU_fetch(&ins);
-
         CPU_dump();
-        /* MEM_dump_last_six(); */
-        /* MEM_dump_page(0x0000); */
-        /* MEM_dump_page(0x0100); */
 
         /* Execute instruction */
         if(CPU_exec(ins) != 0) brk = true;
-    } while(brk ? ((c = getchar()) != 'q') : true);
+        usleep(100);
+    } while(!brk);
 
+    reset_input_mode();
     return 0;
 }
diff --git a/tui.c b/tui.c
@@ -0,0 +1,41 @@
+#include "tui.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+
+/* variable to remember original terminal attributes. */
+static struct termios default_attributes;
+
+void reset_input_mode (void) {
+    tcsetattr(STDIN_FILENO, TCSANOW, &default_attributes);
+
+    /* restore cursor */
+    printf("\033[?25h");
+}
+
+void set_input_mode (void) {
+    struct termios tattr;
+
+    /* Make sure stdin is a terminal. */
+    if (!isatty(STDIN_FILENO)) {
+        fprintf (stderr, "Not a terminal.\n");
+        exit (EXIT_FAILURE);
+    }
+
+    /* Save the terminal attributes so we can restore them later. */
+    tcgetattr(STDIN_FILENO, &default_attributes);
+    atexit(reset_input_mode);
+
+    /* hide cursor */
+    printf("\033[?25l");
+
+    /* Set the terminal modes. */
+    tcgetattr(STDIN_FILENO, &tattr);
+    tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+    tattr.c_cc[VMIN] = 1;
+    tattr.c_cc[VTIME] = 0;
+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &tattr);
+}
diff --git a/tui.h b/tui.h
@@ -0,0 +1,7 @@
+#ifndef __TUI_H__
+#define __TUI_H__
+
+void reset_input_mode (void);
+void set_input_mode (void);
+
+#endif