apple2ix/src/test/testui.c

765 lines
24 KiB
C

/*
* Apple // emulator for *ix
*
* This software package is subject to the GNU General Public License
* version 3 or later (your choice) as published by the Free Software
* Foundation.
*
* Copyright 2016 Aaron Culliney
*
*/
#include "testcommon.h"
#include <sys/mman.h>
#define BLANK_DSK "blank.dsk.gz"
static bool test_thread_running = false;
extern pthread_mutex_t interface_mutex; // TODO FIXME : raw access to CPU mutex because stepping debugger ...
static void testui_setup(void *arg) {
test_common_setup();
apple_ii_64k[0][MIXSWITCH_ADDR] = 0x00;
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
if (test_do_reboot) {
run_args.joy_button0 = 0xff; // OpenApple
cpu65_interrupt(ResetSig);
}
}
static void testui_teardown(void *arg) {
}
// ----------------------------------------------------------------------------
// Various Tests ...
#if CONFORMANT_TRACKS
# define BLANK_RUN_BYTE 1208
# define BLANK_TRACK_WIDTH 6384
#else
# define BLANK_RUN_BYTE 1130
# define BLANK_TRACK_WIDTH 6040
#endif
extern uint8_t (*iie_read_peripheral_card)(uint16_t);
static int _assert_blank_boot(void) {
// Disk6 ...
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0xAA);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
ASSERT(disk6.disk[0].is_protected);
const char *file_name = strrchr(disk6.disk[0].file_name, '/');
ASSERT(strcmp(file_name, "/blank.dsk.gz") == 0);
ASSERT(disk6.disk[0].phase == 36);
ASSERT(disk6.disk[0].run_byte == BLANK_RUN_BYTE);
ASSERT(disk6.disk[0].fd > 0);
ASSERT(disk6.disk[0].raw_image_data != 0);
ASSERT(disk6.disk[0].raw_image_data != MAP_FAILED);
ASSERT(disk6.disk[0].whole_len == 143360);
ASSERT(disk6.disk[0].nib_image_data != NULL);
ASSERT(disk6.disk[0].track_width == BLANK_TRACK_WIDTH);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
extern int skew_table_6_do[16];
ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
// VM ...
ASSERT(run_args.softswitches == 0x000100d1);
ASSERT_SHA_BIN("97AADDDF5D20B793C4558A8928227F0B52565A98", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("2C82E33E964936187CA1DABF71AE6148916BD131", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("36F1699537024EC6017A22641FF0EC277AFFD49D", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(run_args.base_ramrd == apple_ii_64k[0]);
ASSERT(run_args.base_ramwrt == apple_ii_64k[0]);
ASSERT(run_args.base_textrd == apple_ii_64k[0]);
ASSERT(run_args.base_textwrt == apple_ii_64k[0]);
ASSERT(run_args.base_hgrrd == apple_ii_64k[0]);
ASSERT(run_args.base_hgrwrt == apple_ii_64k[0]);
ASSERT(run_args.base_stackzp == apple_ii_64k[0]);
ASSERT(run_args.base_c3rom == apple_ii_64k[1]);
ASSERT(run_args.base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(run_args.base_d000_rd == apple_ii_64k[0]);
ASSERT(run_args.base_d000_wrt == language_banks[0] - 0xD000);
ASSERT(run_args.base_e000_rd == apple_ii_64k[0]);
ASSERT(run_args.base_e000_wrt == language_card[0] - 0xE000);
// CPU ...
ASSERT(run_args.cpu65_pc == 0xE783);
ASSERT(run_args.cpu65_ea == 0x1F33);
ASSERT(run_args.cpu65_a == 0xFF);
ASSERT(run_args.cpu65_f == 0x37);
ASSERT(run_args.cpu65_x == 0xFF);
ASSERT(run_args.cpu65_y == 0x00);
ASSERT(run_args.cpu65_sp == 0xF6);
PASS();
}
static int _get_fds(JSON_ref jsonData, int *fdA, int *fdB) {
{
char *pathA = NULL;
bool ret = json_mapCopyStringValue(jsonData, "diskA", &pathA);
ASSERT(ret);
ASSERT(pathA);
bool readOnlyA = true;
ret = json_mapParseBoolValue(jsonData, "readOnlyA", &readOnlyA);
*fdA = -1;
TEMP_FAILURE_RETRY(*fdA = open(pathA, readOnlyA ? O_RDONLY : O_RDWR));
FREE(pathA);
}
{
char *pathB = NULL;
bool ret = json_mapCopyStringValue(jsonData, "diskB", &pathB);
ASSERT(ret);
ASSERT(pathB);
bool readOnlyB = true;
ret = json_mapParseBoolValue(jsonData, "readOnlyB", &readOnlyB);
*fdB = -1;
TEMP_FAILURE_RETRY(*fdB = open(pathB, readOnlyB ? O_RDONLY : O_RDWR));
FREE(pathB);
}
return 0;
}
TEST test_save_state_1() {
test_setup_boot_disk(BLANK_DSK, 1);
BOOT_TO_DOS();
_assert_blank_boot();
char *savData = NULL;
ASPRINTF(&savData, "%s/emulator-test.a2state", HOMEDIR);
int fd = -1;
TEMP_FAILURE_RETRY(fd = open(savData, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR));
ASSERT(fd > 0);
bool ret = emulator_saveState(fd);
ASSERT(ret);
ASSERT_SHA(BOOT_SCREEN);
TEMP_FAILURE_RETRY(close(fd));
FREE(savData);
PASS();
}
TEST test_load_state_1() {
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
char *savData = NULL;
ASPRINTF(&savData, "%s/emulator-test.a2state", HOMEDIR);
int fdState = -1;
TEMP_FAILURE_RETRY(fdState = open(savData, O_RDONLY));
ASSERT(fdState > 0);
bool ret = false;
int fdA = -1;
int fdB = -1;
{
JSON_ref jsonData;
int siz = json_createFromString("{}", &jsonData);
ASSERT(siz > 0);
ret = emulator_stateExtractDiskPaths(fdState, jsonData);
ASSERT(ret);
_get_fds(jsonData, &fdA, &fdB);
json_destroy(&jsonData);
}
ret = emulator_loadState(fdState, fdA, fdB);
ASSERT(ret);
_assert_blank_boot();
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED);
ASSERT_SHA(BOOT_SCREEN);
TEMP_FAILURE_RETRY(close(fdState));
TEMP_FAILURE_RETRY(close(fdA));
TEMP_FAILURE_RETRY(close(fdB));
unlink(savData);
FREE(savData);
PASS();
}
TEST test_load_A2VM_good1() {
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
// write saved state to disk
#include "test/a2vm-good1.h"
const char *homedir = HOMEDIR;
char *savData = NULL;
ASPRINTF(&savData, "%s/a2_emul_a2vm.dat", homedir);
if (savData) {
unlink(savData);
}
FILE *fp = fopen(savData, "w");
ASSERT(fp);
size_t dataSiz = sizeof(data);
if (fwrite(data, 1, dataSiz, fp) != dataSiz) {
ASSERT(false);
}
fflush(fp); fclose(fp); fp = NULL;
// load state and assert
int fdState = -1;
TEMP_FAILURE_RETRY(fdState = open(savData, O_RDONLY));
ASSERT(fdState > 0);
bool ret = false;
int fdA = -1;
int fdB = -1;
{
JSON_ref jsonData;
int siz = json_createFromString("{}", &jsonData);
ASSERT(siz > 0);
ret = emulator_stateExtractDiskPaths(fdState, jsonData);
ASSERT(ret);
_get_fds(jsonData, &fdA, &fdB);
json_destroy(&jsonData);
}
ret = emulator_loadState(fdState, fdA, fdB);
ASSERT(ret);
// Disk6 ... AVOID ASSERT()ing for non-portable things
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0xAA);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
//ASSERT(disk6.disk[0].is_protected);
//const char *file_name = strrchr(disk6.disk[0].file_name, '/');
//ASSERT(strcmp(file_name, "/testdisplay1.dsk") == 0);
ASSERT(disk6.disk[0].phase == 34);
ASSERT(disk6.disk[0].run_byte == 2000);
//ASSERT(disk6.disk[0].fd > 0);
//ASSERT(disk6.disk[0].raw_image_data != 0);
//ASSERT(disk6.disk[0].raw_image_data != MAP_FAILED);
//ASSERT(disk6.disk[0].whole_len == 143360);
//ASSERT(disk6.disk[0].nib_image_data != NULL);
//ASSERT(disk6.disk[0].track_width == BLANK_TRACK_WIDTH);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
//extern int skew_table_6_do[16];
//ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
// VM ...
ASSERT(run_args.softswitches == 0x000343d1);
ASSERT_SHA_BIN("2E3C6163EEAA817B02B00766B9E118D3197D16AF", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("2C82E33E964936187CA1DABF71AE6148916BD131", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("36F1699537024EC6017A22641FF0EC277AFFD49D", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(run_args.base_ramrd == apple_ii_64k[0]);
ASSERT(run_args.base_ramwrt == apple_ii_64k[0]);
ASSERT(run_args.base_textrd == apple_ii_64k[0]);
ASSERT(run_args.base_textwrt == apple_ii_64k[0]);
ASSERT(run_args.base_hgrrd == apple_ii_64k[0]);
ASSERT(run_args.base_hgrwrt == apple_ii_64k[0]);
ASSERT(run_args.base_stackzp == apple_ii_64k[0]);
ASSERT(run_args.base_c3rom == apple_ii_64k[1]);
ASSERT(run_args.base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(run_args.base_d000_rd == apple_ii_64k[0]);
ASSERT(run_args.base_d000_wrt == language_banks[0] - 0xD000);
ASSERT(run_args.base_e000_rd == apple_ii_64k[0]);
ASSERT(run_args.base_e000_wrt == language_card[0] - 0xE000);
// CPU ...
ASSERT(run_args.cpu65_pc == 0xC83D);
ASSERT(run_args.cpu65_ea == 0x004E);
ASSERT(run_args.cpu65_a == 0x0D);
ASSERT(run_args.cpu65_f == 0x35);
ASSERT(run_args.cpu65_x == 0x09);
ASSERT(run_args.cpu65_y == 0x01);
ASSERT(run_args.cpu65_sp == 0xEA);
// ASSERT framebuffer matches expected
ASSERT_SHA("9C654FEF2A672E16D89ED2FB80C593CD2005A026");
TEMP_FAILURE_RETRY(close(fdState));
TEMP_FAILURE_RETRY(close(fdA));
TEMP_FAILURE_RETRY(close(fdB));
unlink(savData);
FREE(savData);
PASS();
}
TEST test_load_A2V2_good1() {
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
// write saved state to disk
#include "test/a2v2-good1.h"
const char *homedir = HOMEDIR;
char *savData = NULL;
ASPRINTF(&savData, "%s/a2_emul_a2v2.dat", homedir);
if (savData) {
unlink(savData);
}
FILE *fp = fopen(savData, "w");
ASSERT(fp);
size_t dataSiz = sizeof(data);
if (fwrite(data, 1, dataSiz, fp) != dataSiz) {
ASSERT(false);
}
fflush(fp); fclose(fp); fp = NULL;
// load state and assert
int fdState = -1;
TEMP_FAILURE_RETRY(fdState = open(savData, O_RDONLY));
ASSERT(fdState > 0);
bool ret = false;
int fdA = -1;
int fdB = -1;
{
JSON_ref jsonData;
int siz = json_createFromString("{}", &jsonData);
ASSERT(siz > 0);
ret = emulator_stateExtractDiskPaths(fdState, jsonData);
ASSERT(ret);
_get_fds(jsonData, &fdA, &fdB);
json_destroy(&jsonData);
}
ret = emulator_loadState(fdState, fdA, fdB);
ASSERT(ret);
// Disk6 ... AVOID ASSERT()ing for non-portable things
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0x96);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
//ASSERT(disk6.disk[0].is_protected);
//const char *file_name = strrchr(disk6.disk[0].file_name, '/');
//ASSERT(strcmp(file_name, "/NSCT.dsk") == 0);
ASSERT(disk6.disk[0].phase == 26);
ASSERT(disk6.disk[0].run_byte == 5562);
//ASSERT(disk6.disk[0].fd > 0);
//ASSERT(disk6.disk[0].raw_image_data != 0);
//ASSERT(disk6.disk[0].raw_image_data != MAP_FAILED);
//ASSERT(disk6.disk[0].whole_len == 143360);
//ASSERT(disk6.disk[0].nib_image_data != NULL);
//ASSERT(disk6.disk[0].track_width == BLANK_TRACK_WIDTH);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
//extern int skew_table_6_do[16];
//ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
// VM ...
ASSERT(run_args.softswitches == 0x000140f5);
ASSERT_SHA_BIN("3B41CCC86A7FCE2A95F1D7A5C4BF7E2AC7A11323", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("54C8611AA3FD1813B1BEE45EF7F4B2303C51C679", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("36F1699537024EC6017A22641FF0EC277AFFD49D", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(run_args.base_ramrd == apple_ii_64k[0]);
ASSERT(run_args.base_ramwrt == apple_ii_64k[0]);
ASSERT(run_args.base_textrd == apple_ii_64k[0]);
ASSERT(run_args.base_textwrt == apple_ii_64k[0]);
ASSERT(run_args.base_hgrrd == apple_ii_64k[0]);
ASSERT(run_args.base_hgrwrt == apple_ii_64k[0]);
ASSERT(run_args.base_stackzp == apple_ii_64k[0]);
ASSERT(run_args.base_c3rom == apple_ii_64k[1]);
ASSERT(run_args.base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(run_args.base_d000_rd == language_banks[0]-0xD000);
ASSERT(run_args.base_d000_wrt == language_banks[0]-0xD000);
ASSERT(run_args.base_e000_rd == language_card[0]-0xE000);
ASSERT(run_args.base_e000_wrt == language_card[0]-0xE000);
// CPU ...
ASSERT(run_args.cpu65_pc == 0xF6EA);
ASSERT(run_args.cpu65_ea == 0x0018);
ASSERT(run_args.cpu65_a == 0x05);
ASSERT(run_args.cpu65_f == 0x33);
ASSERT(run_args.cpu65_x == 0x10);
ASSERT(run_args.cpu65_y == 0x02);
ASSERT(run_args.cpu65_sp == 0xFA);
// Timing ...
long scaleFactor = (long)(cpu_scale_factor * 100.);
ASSERT(scaleFactor == 100);
long altScaleFactor = (long)(cpu_altscale_factor * 100.);
ASSERT(altScaleFactor == 200);
ASSERT(alt_speed_enabled);
// Mockingboard ...
#include "test/a2v2-good1-mb.h"
size_t mbSiz = sizeof(mbData);
mb_testAssertA2V2(mbData, mbSiz);
// ASSERT framebuffer matches expected
ASSERT_SHA("B1CB1C5811B9C629BB077F857CC41DFA8A283E96");
TEMP_FAILURE_RETRY(close(fdState));
TEMP_FAILURE_RETRY(close(fdA));
TEMP_FAILURE_RETRY(close(fdB));
unlink(savData);
FREE(savData);
PASS();
}
TEST test_load_A2V2_good2() {
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
// write saved state to disk
#include "test/a2v2-good2.h"
const char *homedir = HOMEDIR;
char *savData = NULL;
ASPRINTF(&savData, "%s/a2_emul_a2v2-2.dat", homedir);
if (savData) {
unlink(savData);
}
FILE *fp = fopen(savData, "w");
ASSERT(fp);
size_t dataSiz = sizeof(data);
if (fwrite(data, 1, dataSiz, fp) != dataSiz) {
ASSERT(false);
}
fflush(fp); fclose(fp); fp = NULL;
// load state and assert
int fdState = -1;
TEMP_FAILURE_RETRY(fdState = open(savData, O_RDONLY));
ASSERT(fdState > 0);
bool ret = false;
int fdA = -1;
int fdB = -1;
{
JSON_ref jsonData;
int siz = json_createFromString("{}", &jsonData);
ASSERT(siz > 0);
ret = emulator_stateExtractDiskPaths(fdState, jsonData);
ASSERT(ret);
_get_fds(jsonData, &fdA, &fdB);
json_destroy(&jsonData);
}
ret = emulator_loadState(fdState, fdA, fdB);
ASSERT(ret);
// Disk6 ... AVOID ASSERT()ing for non-portable things
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0xAA);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
//ASSERT(disk6.disk[0].is_protected);
//const char *file_name = strrchr(disk6.disk[0].file_name, '/');
//ASSERT(strcmp(file_name, "/u5boot.do") == 0);
ASSERT(disk6.disk[0].phase == 58);
ASSERT(disk6.disk[0].run_byte == 1208);
//ASSERT(disk6.disk[0].fd > 0);
//ASSERT(disk6.disk[0].raw_image_data != 0);
//ASSERT(disk6.disk[0].raw_image_data != MAP_FAILED);
//ASSERT(disk6.disk[0].whole_len == 143360);
//ASSERT(disk6.disk[0].nib_image_data != NULL);
//ASSERT(disk6.disk[0].track_width == BLANK_TRACK_WIDTH);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
//extern int skew_table_6_do[16];
//ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
// VM ...
ASSERT(run_args.softswitches == 0x000140f4);
ASSERT_SHA_BIN("CAD59B53F04DE501A76E0C04750155C838EADAE2", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("B3268356F9F4F4ACAE2F4FF49D4FED1D36535DDA", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("0B6E45306506F92554102485CE9B500C6779D145", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(run_args.base_ramrd == apple_ii_64k[0]);
ASSERT(run_args.base_ramwrt == apple_ii_64k[0]);
ASSERT(run_args.base_textrd == apple_ii_64k[0]);
ASSERT(run_args.base_textwrt == apple_ii_64k[0]);
ASSERT(run_args.base_hgrrd == apple_ii_64k[0]);
ASSERT(run_args.base_hgrwrt == apple_ii_64k[0]);
ASSERT(run_args.base_stackzp == apple_ii_64k[0]);
ASSERT(run_args.base_c3rom == apple_ii_64k[1]);
ASSERT(run_args.base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(run_args.base_d000_rd == language_banks[0]-0xD000);
ASSERT(run_args.base_d000_wrt == language_banks[0]-0xD000);
ASSERT(run_args.base_e000_rd == language_card[0]-0xE000);
ASSERT(run_args.base_e000_wrt == language_card[0]-0xE000);
// CPU ...
ASSERT(run_args.cpu65_pc == 0x8474);
ASSERT(run_args.cpu65_ea == 0x8474);
ASSERT(run_args.cpu65_a == 0x00);
ASSERT(run_args.cpu65_f == 0x73);
ASSERT(run_args.cpu65_x == 0x04);
ASSERT(run_args.cpu65_y == 0x21);
ASSERT(run_args.cpu65_sp == 0xF1);
// Timing ...
long scaleFactor = (long)(cpu_scale_factor * 100.);
ASSERT(scaleFactor == 100);
long altScaleFactor = (long)(cpu_altscale_factor * 100.);
ASSERT(altScaleFactor == 75);
ASSERT(alt_speed_enabled);
// Mockingboard ...
#include "test/a2v2-good2-mb.h"
size_t mbSiz = sizeof(mbData);
mb_testAssertA2V2(mbData, mbSiz);
// ASSERT framebuffer matches expected
ASSERT_SHA("7A60972EF2E95956249454402A42C12E7C8FBF7A");
TEMP_FAILURE_RETRY(close(fdState));
TEMP_FAILURE_RETRY(close(fdA));
TEMP_FAILURE_RETRY(close(fdB));
unlink(savData);
FREE(savData);
PASS();
}
TEST test_load_A2V2_good3() {
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
// write saved state to disk
#include "test/a2v2-good3.h"
const char *homedir = HOMEDIR;
char *savData = NULL;
ASPRINTF(&savData, "%s/a2_emul_a2v2-3.dat", homedir);
if (savData) {
unlink(savData);
}
FILE *fp = fopen(savData, "w");
ASSERT(fp);
size_t dataSiz = sizeof(data);
if (fwrite(data, 1, dataSiz, fp) != dataSiz) {
ASSERT(false);
}
fflush(fp); fclose(fp); fp = NULL;
// load state and assert
int fdState = -1;
TEMP_FAILURE_RETRY(fdState = open(savData, O_RDONLY));
ASSERT(fdState > 0);
bool ret = false;
int fdA = -1;
int fdB = -1;
{
JSON_ref jsonData;
int siz = json_createFromString("{}", &jsonData);
ASSERT(siz > 0);
ret = emulator_stateExtractDiskPaths(fdState, jsonData);
ASSERT(ret);
_get_fds(jsonData, &fdA, &fdB);
json_destroy(&jsonData);
}
ret = emulator_loadState(fdState, fdA, fdB);
ASSERT(ret);
// Disk6 ... AVOID ASSERT()ing for non-portable things ... in particular this a2state file contains Droid content://
// paths that will not be valid (even on the original device), so the disk6_insert() call will have failed.
// emulator_stateRestore() will have logged the fault but continued optimistically
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 1);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0xAA);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
ASSERT(disk6.disk[0].phase == 6);
ASSERT(disk6.disk[0].run_byte == 1141);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
ASSERT(disk6.disk[1].phase == 50);
ASSERT(disk6.disk[1].run_byte == 5277);
ASSERT(!disk6.disk[1].nibblized);
ASSERT(!disk6.disk[1].track_dirty);
// VM ...
ASSERT(run_args.softswitches == 0x000140f4);
ASSERT_SHA_BIN("16A730D3E709F096B693EA4029FC68672CE454B8", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("DF3EE367193484A6A1C28C2BAE0EFEF42E6D19BB", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("343C30374074AB3AEE22581A6477736121390B18", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(run_args.base_ramrd == apple_ii_64k[0]);
ASSERT(run_args.base_ramwrt == apple_ii_64k[0]);
ASSERT(run_args.base_textrd == apple_ii_64k[0]);
ASSERT(run_args.base_textwrt == apple_ii_64k[0]);
ASSERT(run_args.base_hgrrd == apple_ii_64k[0]);
ASSERT(run_args.base_hgrwrt == apple_ii_64k[0]);
ASSERT(run_args.base_stackzp == apple_ii_64k[0]);
ASSERT(run_args.base_c3rom == apple_ii_64k[1]);
ASSERT(run_args.base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(run_args.base_d000_rd == language_banks[0]-0xD000);
ASSERT(run_args.base_d000_wrt == language_banks[0]-0xD000);
ASSERT(run_args.base_e000_rd == language_card[0]-0xE000);
ASSERT(run_args.base_e000_wrt == language_card[0]-0xE000);
// CPU ...
ASSERT(run_args.cpu65_pc == 0x0E9C);
ASSERT(run_args.cpu65_ea == 0x0EB9);
ASSERT(run_args.cpu65_a == 0x00);
ASSERT(run_args.cpu65_f == 0xB0);
ASSERT(run_args.cpu65_x == 0x05);
ASSERT(run_args.cpu65_y == 0x04);
ASSERT(run_args.cpu65_sp == 0xE0);
// Timing ...
long scaleFactor = (long)(cpu_scale_factor * 100.);
ASSERT(scaleFactor == 100);
long altScaleFactor = (long)(cpu_altscale_factor * 100.);
ASSERT(altScaleFactor == 100);
ASSERT(!alt_speed_enabled);
// Mockingboard ...
#include "test/a2v2-good3-mb.h"
size_t mbSiz = sizeof(mbData);
mb_testAssertA2V2(mbData, mbSiz);
// ASSERT framebuffer matches expected
ASSERT_SHA("D92EECDF3C7446097F3E884412D7911DDD968287");
TEMP_FAILURE_RETRY(close(fdState));
TEMP_FAILURE_RETRY(close(fdA));
TEMP_FAILURE_RETRY(close(fdB));
unlink(savData);
FREE(savData);
PASS();
}
// ----------------------------------------------------------------------------
// Test Suite
GREATEST_SUITE(test_suite_ui) {
pthread_mutex_lock(&interface_mutex);
test_thread_running = true;
GREATEST_SET_SETUP_CB(testui_setup, NULL);
GREATEST_SET_TEARDOWN_CB(testui_teardown, NULL);
GREATEST_SET_BREAKPOINT_CB(test_breakpoint, NULL);
// TESTS --------------------------
RUN_TESTp(test_save_state_1);
RUN_TESTp(test_load_state_1);
RUN_TESTp(test_load_A2VM_good1);
RUN_TESTp(test_load_A2V2_good1);
RUN_TESTp(test_load_A2V2_good2);
RUN_TESTp(test_load_A2V2_good3);
#if INTERFACE_TOUCH
# warning TODO : touch joystick(s), keyboard, mouse, menu
#endif
#if INTERFACE_CLASSIC
# warning TODO : menus, stuff-n-things
#endif
// ...
disk6_eject(0);
pthread_mutex_unlock(&interface_mutex);
}
SUITE(test_suite_ui);
GREATEST_MAIN_DEFS();
static char **test_argv = NULL;
static int test_argc = 0;
static int _test_thread(void) {
int argc = test_argc;
char **argv = test_argv;
GREATEST_MAIN_BEGIN();
RUN_SUITE(test_suite_ui);
GREATEST_MAIN_END();
}
static void *test_thread(void *dummyptr) {
_test_thread();
return NULL;
}
void test_ui(int _argc, char **_argv) {
test_argc = _argc;
test_argv = _argv;
srandom(time(NULL));
test_common_init();
pthread_t p;
pthread_create(&p, NULL, (void *)&test_thread, (void *)NULL);
while (!test_thread_running) {
struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
nanosleep(&ts, NULL);
}
pthread_detach(p);
}