mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-08 16:29:27 +00:00
"HEADLESS" CPP define and envvar switches
* Allows running emulator in headless mode (default for some tests) * setting HEADLESS=1 envvar from commandline will force headless operation
This commit is contained in:
parent
22bf206626
commit
8b0325d60d
18
Makefile.am
18
Makefile.am
|
@ -86,22 +86,22 @@ A2_TEST_CFLAGS = -DTESTING=1 -Isrc/greatest
|
|||
TESTS = testcpu testdisplay testvm
|
||||
check_PROGRAMS = testcpu testdisplay testvm
|
||||
|
||||
testcpu_SOURCES = src/test/testcpu.c $(A2_TEST_SOURCES) $(EXTRA_apple2ix_SOURCES)
|
||||
testcpu_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS)
|
||||
testcpu_SOURCES = src/test/testcpu.c $(A2_TEST_SOURCES) $(VM_SRC) $(META_SRC) $(VIDEO_SRC)
|
||||
testcpu_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS) -UAUDIO_ENABLED -UINTERFACE_CLASSIC -DHEADLESS=1
|
||||
testcpu_LDFLAGS = $(apple2ix_LDFLAGS)
|
||||
testcpu_DEPENDENCIES = $(apple2ix_DEPENDENCIES)
|
||||
testcpu_DEPENDENCIES = @VM_O@ @META_O@
|
||||
|
||||
testdisplay_SOURCES = src/test/testdisplay.c $(A2_TEST_SOURCES) $(VM_SRC) $(META_SRC)
|
||||
testdisplay_SOURCES = src/test/testdisplay.c $(A2_TEST_SOURCES) $(VM_SRC) $(META_SRC) $(VIDEO_SRC)
|
||||
# HACK FIXME TODO NOTE: why don't these CFLAGS here pass down to the .S and .c files in the subdirectories?
|
||||
testdisplay_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS) -UAUDIO_ENABLED -UVIDEO_X11 -UINTERFACE_CLASSIC
|
||||
testdisplay_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS) -UAUDIO_ENABLED -UINTERFACE_CLASSIC -DHEADLESS=0
|
||||
testdisplay_LDFLAGS = $(apple2ix_LDFLAGS)
|
||||
testdisplay_DEPENDENCIES = @VM_O@ @META_O@
|
||||
testdisplay_DEPENDENCIES = @VM_O@ @META_O@ @VIDEO_O@
|
||||
|
||||
testvm_SOURCES = src/test/testvm.c $(A2_TEST_SOURCES) $(VM_SRC) $(META_SRC)
|
||||
testvm_SOURCES = src/test/testvm.c $(A2_TEST_SOURCES) $(VM_SRC) $(META_SRC) $(VIDEO_SRC)
|
||||
# HACK FIXME TODO NOTE: why don't these CFLAGS here pass down to the .S and .c files in the subdirectories?
|
||||
testvm_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS) -UAUDIO_ENABLED -UVIDEO_X11 -UINTERFACE_CLASSIC
|
||||
testvm_CFLAGS = $(apple2ix_CFLAGS) $(A2_TEST_CFLAGS) -UAUDIO_ENABLED -UINTERFACE_CLASSIC -DHEADLESS=0
|
||||
testvm_LDFLAGS = $(apple2ix_LDFLAGS)
|
||||
testvm_DEPENDENCIES = @VM_O@ @META_O@
|
||||
testvm_DEPENDENCIES = @VM_O@ @META_O@ @VIDEO_O@
|
||||
|
||||
###############################################################################
|
||||
# Misc
|
||||
|
|
|
@ -129,11 +129,10 @@ AC_SEARCH_LIBS(XShmAttach, Xext, [
|
|||
AC_MSG_WARN([Building emulator without support of X11 MITSHM extension...])
|
||||
], [-lX11])
|
||||
|
||||
AC_DEFINE(VIDEO_X11, 1, [Enable common X11 video])
|
||||
|
||||
VIDEO_O="src/video/xvideo.o"
|
||||
AC_SUBST(VIDEO_O)
|
||||
|
||||
AC_DEFINE(HEADLESS, 0, [Set to 1 to disable video output driver])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Sound ...
|
||||
|
|
|
@ -577,9 +577,9 @@ void video_plotchar( int x, int y, int scheme, unsigned char c )
|
|||
_plot_char80(&d,&s);
|
||||
}
|
||||
|
||||
#ifdef VIDEO_X11
|
||||
extern void X11_video_init();
|
||||
extern void X11_video_shutdown();
|
||||
#if !HEADLESS
|
||||
extern void video_driver_init();
|
||||
extern void video_driver_shutdown();
|
||||
#endif
|
||||
void video_init() {
|
||||
|
||||
|
@ -590,15 +590,19 @@ void video_init() {
|
|||
memset(video__fb1,0,SCANWIDTH*SCANHEIGHT);
|
||||
memset(video__fb2,0,SCANWIDTH*SCANHEIGHT);
|
||||
|
||||
#ifdef VIDEO_X11
|
||||
X11_video_init();
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
video_driver_init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_shutdown(void)
|
||||
{
|
||||
#ifdef VIDEO_X11
|
||||
X11_video_shutdown();
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
video_driver_shutdown();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1151,7 +1151,8 @@ static int begin_cpu_stepping() {
|
|||
}
|
||||
|
||||
#ifdef TESTING
|
||||
video_sync(0);
|
||||
extern void testing_video_sync();
|
||||
testing_video_sync();
|
||||
#else
|
||||
if ((ch = c_mygetch(0)) != -1) {
|
||||
break;
|
||||
|
|
|
@ -38,6 +38,7 @@ char disk_path[DISKSIZE];
|
|||
|
||||
int apple_mode = IIE_MODE;
|
||||
int sound_volume = 2;
|
||||
bool is_headless = false;
|
||||
color_mode_t color_mode = COLOR;
|
||||
a2_video_mode_t a2_video_mode = VIDEO_1X;
|
||||
joystick_mode_t joy_mode = JOY_OFF;
|
||||
|
@ -194,6 +195,12 @@ static char * clean_string(char *x)
|
|||
/* Load the configuration. Must be called *once* at start. */
|
||||
void load_settings(void)
|
||||
{
|
||||
/* running a headless emulator? */
|
||||
char *headless = getenv("HEADLESS");
|
||||
if (headless && (strncasecmp(headless, "1", 2) == 0) ) {
|
||||
is_headless = true;
|
||||
}
|
||||
|
||||
/* set system defaults before user defaults. */
|
||||
strcpy(disk_path, "./disks");
|
||||
strcpy(system_path, "./rom");
|
||||
|
|
|
@ -53,6 +53,7 @@ extern char disk_path[DISKSIZE];
|
|||
|
||||
extern int apple_mode; /* undocumented instructions or //e mode */
|
||||
extern int sound_volume;
|
||||
extern bool is_headless;
|
||||
extern color_mode_t color_mode;
|
||||
extern a2_video_mode_t a2_video_mode;
|
||||
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
snprintf(msgbuf, MSG_SIZE, MSG_FLAGS0, regA, val, result, buf0, cpu65_current.a, buf1); \
|
||||
ASSERTm(msgbuf, cpu65_current.f == flags);
|
||||
|
||||
void testing_video_sync() {
|
||||
// user input and video output not simulated in this test
|
||||
}
|
||||
|
||||
static void testcpu_setup(void *arg) {
|
||||
|
||||
//reinitialize();
|
||||
|
@ -130,6 +134,30 @@ static void flags_to_string(uint8_t flags, char *buf) {
|
|||
(flags & C_Flag_6502) ? 'C' : '-' );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Stub functions because I've reached diminishing returns with the build system ...
|
||||
//
|
||||
// NOTE: You'd think the commandline CFLAGS set specifically for this test program would pass down to the sources in
|
||||
// subdirectories, but it apparently isn't. GNU buildsystem bug? Also see HACK FIXME TODO NOTE in Makefile.am
|
||||
//
|
||||
|
||||
uint8_t c_MB_Read(uint16_t addr) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void c_MB_Write(uint16_t addr, uint8_t byte) {
|
||||
}
|
||||
|
||||
uint8_t c_PhasorIO(uint16_t addr) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void SpkrToggle() {
|
||||
}
|
||||
|
||||
void c_interface_print(int x, int y, const int cs, const char *s) {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ADC instructions
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ static unsigned int input_length = 0;
|
|||
static unsigned int input_counter = 0;
|
||||
static bool test_do_reboot = true;
|
||||
|
||||
static struct timespec t0 = { 0 };
|
||||
static struct timespec ti = { 0 };
|
||||
|
||||
extern unsigned char joy_button0;
|
||||
|
||||
static void testdisplay_setup(void *arg) {
|
||||
|
@ -45,6 +48,11 @@ static void testdisplay_teardown(void *arg) {
|
|||
|
||||
static void testdisplay_breakpoint(void *arg) {
|
||||
fprintf(GREATEST_STDOUT, "set breakpoint on testdisplay_breakpoint to check for problems...\n");
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
video_sync(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sha1_to_str(const uint8_t * const md, char *buf) {
|
||||
|
@ -58,7 +66,18 @@ static void sha1_to_str(const uint8_t * const md, char *buf) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// test video functions and stubs
|
||||
|
||||
void video_sync(int ignored) {
|
||||
void testing_video_sync(int ignored) {
|
||||
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &ti);
|
||||
struct timespec deltat = timespec_diff(t0, ti, NULL);
|
||||
if (deltat.tv_sec || (deltat.tv_nsec >= NANOSECONDS/15) ) {
|
||||
video_sync(0);
|
||||
ti = t0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (input_counter >= input_length) {
|
||||
return;
|
||||
|
@ -434,7 +453,11 @@ GREATEST_SUITE(test_suite_display) {
|
|||
pthread_mutex_lock(&interface_mutex);
|
||||
|
||||
c_debugger_set_watchpoint(WATCHPOINT_ADDR);
|
||||
c_debugger_set_timeout(5);
|
||||
if (is_headless) {
|
||||
c_debugger_set_timeout(5);
|
||||
} else {
|
||||
c_debugger_set_timeout(0);
|
||||
}
|
||||
|
||||
// TESTS --------------------------
|
||||
|
||||
|
|
|
@ -12,40 +12,49 @@
|
|||
#include "greatest.h"
|
||||
#include "testcommon.h"
|
||||
|
||||
#define RESET_INPUT() \
|
||||
input_counter = 0; \
|
||||
input_length = 0; \
|
||||
input_str[0] = '\0'
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#error "these tests require OpenSSL libraries (SHA)"
|
||||
#endif
|
||||
|
||||
static char *input_str = NULL; // ASCII
|
||||
static char input_str[TESTBUF_SZ]; // ASCII
|
||||
static unsigned int input_length = 0;
|
||||
static unsigned int input_counter = 0;
|
||||
static bool test_do_reboot = true;
|
||||
|
||||
static struct timespec t0 = { 0 };
|
||||
static struct timespec ti = { 0 };
|
||||
|
||||
extern unsigned char joy_button0;
|
||||
|
||||
static void testvm_setup(void *arg) {
|
||||
apple_ii_64k[0][MIXSWITCH_ADDR] = 0x00;
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
apple_ii_64k[0][TESTOUT_ADDR] = 0x00;
|
||||
input_counter = 0;
|
||||
input_length = 0;
|
||||
RESET_INPUT();
|
||||
joy_button0 = 0xff; // OpenApple
|
||||
if (test_do_reboot) {
|
||||
cpu65_interrupt(ResetSig);
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &t0);
|
||||
}
|
||||
|
||||
static void testvm_teardown(void *arg) {
|
||||
if (input_str) {
|
||||
free(input_str);
|
||||
}
|
||||
input_str = NULL;
|
||||
}
|
||||
|
||||
static void testvm_breakpoint(void *arg) {
|
||||
fprintf(GREATEST_STDOUT, "set breakpoint on testvm_breakpoint to check for problems...\n");
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
video_sync(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sha1_to_str(const uint8_t * const md, char *buf) {
|
||||
|
@ -59,7 +68,22 @@ static void sha1_to_str(const uint8_t * const md, char *buf) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// test video functions and stubs
|
||||
|
||||
void video_sync(int ignored) {
|
||||
void testing_video_sync() {
|
||||
|
||||
#if !HEADLESS
|
||||
if (!is_headless) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &ti);
|
||||
struct timespec deltat = timespec_diff(t0, ti, NULL);
|
||||
if (deltat.tv_sec || (deltat.tv_nsec >= NANOSECONDS/15) ) {
|
||||
video_sync(0);
|
||||
ti = t0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!input_length) {
|
||||
input_length = strlen(input_str);
|
||||
}
|
||||
|
||||
if (input_counter >= input_length) {
|
||||
return;
|
||||
|
@ -67,7 +91,6 @@ void video_sync(int ignored) {
|
|||
|
||||
uint8_t ch = (uint8_t)input_str[input_counter];
|
||||
if (ch == '\n') {
|
||||
fprintf(stderr, "converting '\\n' to '\\r' in test input string...");
|
||||
ch = '\r';
|
||||
}
|
||||
|
||||
|
@ -124,7 +147,7 @@ TEST test_read_keyboard() {
|
|||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0x00);
|
||||
|
||||
input_str = strdup("RUN TESTGETKEY\rZ");
|
||||
strcpy(input_str, "RUN TESTGETKEY\rZ");
|
||||
input_length = strlen(input_str);
|
||||
c_debugger_go();
|
||||
|
||||
|
@ -140,8 +163,7 @@ TEST test_clear_keyboard() {
|
|||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0x00);
|
||||
|
||||
input_str = strdup("RUN TESTCLEARKEY\rZA");
|
||||
input_length = strlen(input_str);
|
||||
strcpy(input_str, "RUN TESTCLEARKEY\rZA");
|
||||
c_debugger_go();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
@ -151,15 +173,14 @@ TEST test_clear_keyboard() {
|
|||
}
|
||||
|
||||
TEST test_read_random() {
|
||||
SKIPm("random numbers current b0rken...");
|
||||
SKIPm("random numbers currently b0rken...");
|
||||
|
||||
BOOT_TO_DOS();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0x00);
|
||||
|
||||
input_str = strdup("RUN TESTRND\r");
|
||||
input_length = strlen(input_str);
|
||||
strcpy(input_str, "RUN TESTRND\r");
|
||||
c_debugger_go();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
@ -201,7 +222,11 @@ GREATEST_SUITE(test_suite_vm) {
|
|||
pthread_mutex_lock(&interface_mutex);
|
||||
|
||||
c_debugger_set_watchpoint(WATCHPOINT_ADDR);
|
||||
c_debugger_set_timeout(5);
|
||||
if (is_headless) {
|
||||
c_debugger_set_timeout(5);
|
||||
} else {
|
||||
c_debugger_set_timeout(0);
|
||||
}
|
||||
|
||||
// TESTS --------------------------
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ static void c_initialize_colors() {
|
|||
//XStoreColors(display, cmap, colors, 256);
|
||||
}
|
||||
|
||||
#if !defined(TESTING)
|
||||
// Map X keysyms into Apple//ix internal-representation scancodes.
|
||||
static int keysym_to_scancode(void) {
|
||||
int rc = XkbKeycodeToKeysym(display, xevent.xkey.keycode, 0, 0);
|
||||
|
@ -452,6 +453,7 @@ static int keysym_to_scancode(void) {
|
|||
assert(rc < 0x80);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void post_image() {
|
||||
// copy Apple //e video memory into XImage uint32_t buffer
|
||||
|
@ -558,11 +560,18 @@ extern void c_handle_input(int scancode, int pressed);
|
|||
|
||||
/* FIXME: blocking not implemented... */
|
||||
void video_sync(int block) {
|
||||
if (is_headless) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int flash_count = 0;
|
||||
// post the image and loop waiting for it to finish and
|
||||
// also process other input events
|
||||
post_image();
|
||||
|
||||
#ifdef TESTING
|
||||
// no input processing if test-driven ...
|
||||
#else
|
||||
bool keyevent = true;
|
||||
do {
|
||||
#ifdef HAVE_X11_SHM
|
||||
|
@ -595,6 +604,7 @@ void video_sync(int block) {
|
|||
c_handle_input(scancode, pressed);
|
||||
|
||||
} while (keyevent);
|
||||
#endif
|
||||
|
||||
switch (++flash_count)
|
||||
{
|
||||
|
@ -786,7 +796,7 @@ void video_set_mode(a2_video_mode_t mode) {
|
|||
_size_hints_set_fixed();
|
||||
}
|
||||
|
||||
void X11_video_init() {
|
||||
void video_driver_init() {
|
||||
XSetWindowAttributes attribs;
|
||||
unsigned long attribmask;
|
||||
int x, y; /* window position */
|
||||
|
@ -797,18 +807,15 @@ void X11_video_init() {
|
|||
char *window_name = "Apple //ix";
|
||||
char *icon_name = window_name;
|
||||
//GC gc;
|
||||
char *progname; /* name this program was invoked by */
|
||||
char *displayname = NULL;
|
||||
|
||||
if (argv == NULL) {
|
||||
LOG("No command line arguments, won't initialize xvideo ...");
|
||||
return;
|
||||
LOG("No command line arguments ...");
|
||||
argc = 0;
|
||||
} else {
|
||||
parseArgs();
|
||||
}
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
parseArgs();
|
||||
|
||||
if (!(size_hints = XAllocSizeHints()))
|
||||
{
|
||||
fprintf(stderr, "cannot allocate memory for SizeHints\n");
|
||||
|
@ -977,7 +984,7 @@ void X11_video_init() {
|
|||
wm_hints->input = True;
|
||||
wm_hints->flags = StateHint | IconPixmapHint /* | InputHint*/;
|
||||
|
||||
class_hints->res_name = progname;
|
||||
class_hints->res_name = "apple2ix";
|
||||
class_hints->res_class = "Apple2";
|
||||
|
||||
_size_hints_set_fixed();
|
||||
|
@ -1024,7 +1031,7 @@ void X11_video_init() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void X11_video_shutdown(void)
|
||||
void video_driver_shutdown(void)
|
||||
{
|
||||
_destroy_image();
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in New Issue
Block a user