# HG changeset patch # User Michael Pavone # Date 1437898264 25200 # Node ID 792be135d3af9ba6f091ae5c374a8811fcfe55b3 # Parent 9aff36a172b2e1a6d6d053300c280f31f3811ef3 Spawn a terminal for the debugger when needed if we are not already attached to one diff -r 9aff36a172b2 -r 792be135d3af Makefile --- a/Makefile Sun Jul 26 01:09:05 2015 -0700 +++ b/Makefile Sun Jul 26 01:11:04 2015 -0700 @@ -5,6 +5,7 @@ ifeq ($(OS),Windows) MEM:=mem_win.o +TERMINAL:=terminal_win.o BLASTEM:=blastem.exe CC:=wine gcc.exe CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL2" -DGLEW_STATIC @@ -14,6 +15,7 @@ else MEM:=mem.o +TERMINAL:=terminal.o BLASTEM:=blastem ifeq ($(OS),Darwin) @@ -99,7 +101,7 @@ AUDIOOBJS=ym2612.o psg.o wave.o CONFIGOBJS=config.o tern.o util.o -MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o romdb.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) +MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o romdb.o $(TERMINAL) $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) ifeq ($(CPU),x86_64) CFLAGS+=-DX86_64 -m64 @@ -119,9 +121,12 @@ ifeq ($(OS),Windows) MAINOBJS+= glew32s.lib +ALL=$(BLASTEM) +else +ALL= dis zdis stateview vgmplay blastem termhelper endif -all : dis zdis stateview vgmplay blastem +all : $(ALL) $(BLASTEM) : $(MAINOBJS) $(CC) -o $(BLASTEM) $(MAINOBJS) $(LDFLAGS) @@ -188,4 +193,4 @@ vasmz80_mot -Fbin -spaces -o $@ $< clean : - rm -rf dis trans stateview test_x86 gen_fib *.o + rm -rf $(ALL) trans ztestrun ztestgen *.o diff -r 9aff36a172b2 -r 792be135d3af debug.c --- a/debug.c Sun Jul 26 01:09:05 2015 -0700 +++ b/debug.c Sun Jul 26 01:11:04 2015 -0700 @@ -8,6 +8,7 @@ #endif #include "render.h" #include "util.h" +#include "terminal.h" static bp_def * breakpoints = NULL; static bp_def * zbreakpoints = NULL; @@ -287,6 +288,7 @@ static uint16_t branch_t; static uint16_t branch_f; z80inst inst; + init_terminal(); //Check if this is a user set breakpoint, or just a temporary one bp_def ** this_bp = find_breakpoint(&zbreakpoints, address); if (*this_bp) { @@ -473,6 +475,9 @@ static uint32_t branch_t; static uint32_t branch_f; m68kinst inst; + + init_terminal(); + sync_components(context, 0); //probably not necessary, but let's play it safe address &= 0xFFFFFF; diff -r 9aff36a172b2 -r 792be135d3af termhelper.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/termhelper.c Sun Jul 26 01:11:04 2015 -0700 @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include "terminal.h" + +char buf[4096]; + +void copy_data(int to, int from) +{ + ssize_t bytes = read(from, buf, sizeof(buf)); + while (bytes > 0) + { + ssize_t written = write(to, buf, bytes); + if (written == -1) { + exit(1); + } + bytes -= written; + } +} + +int main(int argc, char **argv) +{ + //these will block so order is important + int input_fd = open(INPUT_PATH, O_WRONLY); + int output_fd = open(OUTPUT_PATH, O_RDONLY); + fd_set read_fds; + FD_ZERO(&read_fds); + for (;;) + { + FD_SET(STDIN_FILENO, &read_fds); + FD_SET(output_fd, &read_fds); + select(output_fd+1, &read_fds, NULL, NULL, NULL); + + if (FD_ISSET(STDIN_FILENO, &read_fds)) { + copy_data(input_fd, STDIN_FILENO); + } + if (FD_ISSET(output_fd, &read_fds)) { + copy_data(STDOUT_FILENO, output_fd); + } + } + return 0; +} diff -r 9aff36a172b2 -r 792be135d3af terminal.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/terminal.c Sun Jul 26 01:11:04 2015 -0700 @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "terminal.h" + +pid_t child; + +void cleanup_terminal() +{ + kill(child, SIGKILL); + unlink(INPUT_PATH); + unlink(OUTPUT_PATH); +} + +void init_terminal() +{ + static char init_done; + if (!init_done) { + if (!(isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))) { +#ifndef __APPLE__ + //check to see if x-terminal-emulator exists, just use xterm if it doesn't + char *term = system("which x-terminal-emulator > /dev/null") ? "xterm" : "x-terminal-emulator"; +#endif + //get rid of FIFO's if they already exist + unlink(INPUT_PATH); + unlink(OUTPUT_PATH); + //create FIFOs for talking to helper process in terminal app + mkfifo(INPUT_PATH, 0666); + mkfifo(OUTPUT_PATH, 0666); + + //close existing file descriptors + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + child = fork(); + if (child == -1) { + //error, oh well + warning("Failed to fork for terminal spawn"); + } else if (!child) { + //child process, exec our terminal emulator +#ifdef __APPLE__ + execlp("open", "open", "./termhelper", NULL); +#else + execlp(term, term, "-title", "BlastEm Debugger", "-e", "./termhelper", NULL); +#endif + } else { + //connect to the FIFOs, these will block so order is important + open(INPUT_PATH, O_RDONLY); + open(OUTPUT_PATH, O_WRONLY); + atexit(cleanup_terminal); + if (-1 == dup(STDOUT_FILENO)) { + fatal_error("failed to dup STDOUT to STDERR after terminal fork"); + } + } + } + + init_done = 1; + } +} diff -r 9aff36a172b2 -r 792be135d3af terminal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/terminal.h Sun Jul 26 01:11:04 2015 -0700 @@ -0,0 +1,9 @@ +#ifndef TERMINAL_H_ +#define TERMINAL_H_ + +void init_terminal(); + +#define INPUT_PATH "/tmp/blastem_input" +#define OUTPUT_PATH "/tmp/blastem_output" + +#endif //TERMINAL_H_ diff -r 9aff36a172b2 -r 792be135d3af terminal_win.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/terminal_win.c Sun Jul 26 01:11:04 2015 -0700 @@ -0,0 +1,13 @@ +#include +#include + +void init_terminal() +{ + static init_done; + if (!init_done) { + AllocConsole(); + freopen("CONIN$", "r", stdin); + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); + } +} diff -r 9aff36a172b2 -r 792be135d3af util.c --- a/util.c Sun Jul 26 01:09:05 2015 -0700 +++ b/util.c Sun Jul 26 01:11:04 2015 -0700 @@ -116,6 +116,35 @@ exit(1); } +void warning(char *format, ...) +{ + va_list args; + va_start(args, format); +#ifndef _WIN32 + if (headless || (isatty(STDERR_FILENO) && isatty(STDIN_FILENO))) { + vfprintf(stderr, format, args); + } else { +#endif + size_t size = strlen(format) * 2; + char *buf = malloc(size); + size_t actual = vsnprintf(buf, size, format, args); + if (actual >= size) { + actual++; + free(buf); + buf = malloc(actual); + va_end(args); + va_start(args, format); + vsnprintf(buf, actual, format, args); + } + fputs(buf, stderr); + render_infobox("BlastEm Info", buf); + free(buf); +#ifndef _WIN32 + } +#endif + va_end(args); +} + void info_message(char *format, ...) { va_list args; diff -r 9aff36a172b2 -r 792be135d3af util.h --- a/util.h Sun Jul 26 01:09:05 2015 -0700 +++ b/util.h Sun Jul 26 01:11:04 2015 -0700 @@ -29,5 +29,7 @@ void fatal_error(char *format, ...); //Prints an information message to stdout and to a message box if not in headless mode and not attached to a console void info_message(char *format, ...); +//Prints an information message to stderr and to a message box if not in headless mode and not attached to a console +void warning(char *format, ...); #endif //UTIL_H_