/* * Apple // emulator for *nix * * This software package is subject to the GNU General Public License * version 2 or later (your choice) as published by the Free Software * Foundation. * * THERE ARE NO WARRANTIES WHATSOEVER. * */ #include "testcommon.h" #define RESET_INPUT() test_common_setup() #ifdef HAVE_OPENSSL #include #else #error "these tests require OpenSSL libraries (SHA)" #endif static bool test_do_reboot = true; extern unsigned char joy_button0; static void testvm_setup(void *arg) { RESET_INPUT(); apple_ii_64k[0][MIXSWITCH_ADDR] = 0x00; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; apple_ii_64k[0][TESTOUT_ADDR] = 0x00; joy_button0 = 0xff; // OpenApple if (test_do_reboot) { cpu65_interrupt(ResetSig); } } static void testvm_teardown(void *arg) { } static void sha1_to_str(const uint8_t * const md, char *buf) { int i=0; for (int j=0; j AUX 1E00 */ \ " JSR $C311\r" /* call AUXMOVE */ \ " RTS\r" \ "\r" \ "1E80G\r" \ ) #define ASM_DONE() test_type_input("\r") #define ASM_GO() test_type_input("1E00G\r") #define TYPE_80STORE_OFF() \ test_type_input("POKE49152,0:REM C000 80STORE OFF\r") #define TYPE_80STORE_ON() \ test_type_input("POKE49153,0:REM C001 80STORE ON\r") #define ASM_RAMRD_OFF() \ test_type_input(" STA $C002\r") #define ASM_RAMRD_ON() \ test_type_input(" STA $C003\r") #define ASM_RAMWRT_OFF() \ test_type_input(" STA $C004\r") #define ASM_RAMWRT_ON() \ test_type_input(" STA $C005\r") #define TYPE_TEXT_OFF() \ test_type_input("POKE49232,0:REM C050 TEXT OFF\r") #define TYPE_TEXT_ON() \ test_type_input("POKE49233,0:REM C051 TEXT ON\r") #define TYPE_MIXED_OFF() \ test_type_input("POKE49234,0:REM C052 MIXED OFF\r") #define TYPE_MIXED_ON() \ test_type_input("POKE49235,0:REM C053 MIXED ON\r") #define TYPE_PAGE2_OFF() \ test_type_input("POKE49236,0:REM C054 PAGE2 OFF\r") #define TYPE_PAGE2_ON() \ test_type_input("POKE49237,0:REM C055 PAGE2 ON\r") #define ASM_HIRES_OFF() \ test_type_input(" STA $C056\r") #define ASM_HIRES_ON() \ test_type_input(" STA $C057\r") #define TYPE_HIRES_OFF() \ test_type_input("POKE49238,0:REM C056 HIRES OFF\r") #define TYPE_HIRES_ON() \ test_type_input("POKE49239,0:REM C057 HIRES ON\r") #define TYPE_TRIGGER_WATCHPT() \ test_type_input("POKE7987,255:REM TRIGGER DEBUGGER\r") TEST test_PAGE2_on(bool flag_80store, bool flag_hires) { BOOT_TO_DOS(); // setup for testing ... TYPE_PAGE2_OFF(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); if (flag_80store) { TYPE_80STORE_ON(); } else { TYPE_80STORE_OFF(); } if (flag_hires) { TYPE_HIRES_ON(); } else { TYPE_HIRES_OFF(); } TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_PAGE2)); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES)) ); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_PAGE2_ON(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_PAGE2)); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES)) ); switch_save = switch_save | SS_PAGE2; if (flag_80store) { ASSERT(video__current_page == 0); switch_save = switch_save | (SS_TEXTRD|SS_TEXTWRT); ASSERT((void *)base_textrd == (void *)(apple_ii_64k[1])); ASSERT((void *)base_textwrt == (void *)(apple_ii_64k[1])); if (flag_hires) { switch_save = switch_save | (SS_HGRRD|SS_HGRWRT); ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k[1])); ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k[1])); } else { ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged } } else { switch_save = (switch_save | SS_SCREEN); ASSERT(video__current_page = 1); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged } ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_PAGE2_off(bool flag_80store, bool flag_hires) { BOOT_TO_DOS(); // setup for testing ... TYPE_PAGE2_ON(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); if (flag_80store) { TYPE_80STORE_ON(); } else { TYPE_80STORE_OFF(); } if (flag_hires) { TYPE_HIRES_ON(); } else { TYPE_HIRES_OFF(); } TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT( (softswitches & SS_PAGE2)); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES)) ); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_PAGE2_OFF(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES)) ); ASSERT(!(softswitches & (SS_PAGE2|SS_SCREEN))); ASSERT(video__current_page == 0); switch_save = (switch_save & ~(SS_PAGE2|SS_SCREEN)); if (flag_80store) { switch_save = switch_save & ~(SS_TEXTRD|SS_TEXTWRT); ASSERT((void *)base_textrd == (void *)(apple_ii_64k)); ASSERT((void *)base_textwrt == (void *)(apple_ii_64k)); if (flag_hires) { switch_save = switch_save & ~(SS_HGRRD|SS_HGRWRT); ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k)); ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k)); } else { ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged } } else { ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged } ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_TEXT_on() { BOOT_TO_DOS(); // setup for testing ... TYPE_TEXT_OFF(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_TEXT)); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_TEXT_ON(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_TEXT)); ASSERT(video__current_page == save_current_page); switch_save = (switch_save | SS_TEXT); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_TEXT_off() { BOOT_TO_DOS(); // setup for testing ... TYPE_TEXT_ON(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_TEXT)); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_TEXT_OFF(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_TEXT)); ASSERT(video__current_page == save_current_page); switch_save = (switch_save & ~SS_TEXT); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_MIXED_on() { BOOT_TO_DOS(); // setup for testing ... TYPE_MIXED_OFF(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_MIXED)); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_MIXED_ON(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_MIXED)); ASSERT(video__current_page == save_current_page); switch_save = (switch_save | SS_MIXED); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_MIXED_off() { BOOT_TO_DOS(); // setup for testing ... TYPE_MIXED_ON(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_MIXED)); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_MIXED_OFF(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_MIXED)); ASSERT(video__current_page == save_current_page); switch_save = (switch_save & ~SS_MIXED); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_HIRES_on(bool flag_80store, bool flag_page2) { BOOT_TO_DOS(); // setup for testing ... TYPE_HIRES_OFF(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); if (flag_80store) { TYPE_80STORE_ON(); } else { TYPE_80STORE_OFF(); } if (flag_page2) { TYPE_PAGE2_ON(); } else { TYPE_PAGE2_OFF(); } TYPE_TRIGGER_WATCHPT(); c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT(!(softswitches & SS_HIRES)); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_page2 ? (softswitches & SS_PAGE2) : !(softswitches & SS_PAGE2)) ); uint32_t switch_save = softswitches; // run actual test ... RESET_INPUT(); TYPE_HIRES_ON(); TYPE_TRIGGER_WATCHPT(); uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); ASSERT((softswitches & SS_HIRES)); ASSERT( (flag_80store ? (softswitches & SS_80STORE) : !(softswitches & SS_80STORE)) ); ASSERT( (flag_page2 ? (softswitches & SS_PAGE2) : !(softswitches & SS_PAGE2)) ); switch_save = switch_save | SS_HIRES; if (flag_80store) { if (flag_page2) { switch_save = switch_save & ~(SS_HGRRD|SS_HGRWRT); ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k[0])); ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k[0])); } else { switch_save = switch_save | (SS_HGRRD|SS_HGRWRT); ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k[1])); ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k[1])); } } else { ASSERT(base_hgrrd == save_base_hgrrd); // unchanged ASSERT(base_hgrwrt == save_base_hgrwrt); // unchanged } ASSERT(video__current_page == save_current_page); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } TEST test_HIRES_off(bool flag_ramrd, bool flag_ramwrt) { BOOT_TO_DOS(); ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED); /* setup */ ASM_INIT(); ASM_HIRES_ON(); if (flag_ramrd) { ASM_RAMRD_ON(); } else { ASM_RAMRD_OFF(); } if (flag_ramwrt) { ASM_RAMWRT_ON(); } else { ASM_RAMWRT_OFF(); } ASM_TRIGGER_WATCHPT(); /* test */ ASM_HIRES_OFF(); ASM_TRIGGER_WATCHPT(); ASM_DONE(); if (flag_ramrd) { // sets up to copy the test script into auxram (because execution will continue there when RAMRD on) ASM_XFER_TEST_TO_AUXMEM(); } ASM_GO(); c_debugger_go(); if (flag_ramwrt) { ASSERT(apple_ii_64k[1][WATCHPOINT_ADDR] == TEST_FINISHED); } else { ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); } ASSERT((softswitches & SS_HIRES)); ASSERT( (flag_ramrd ? (softswitches & SS_RAMRD) : !(softswitches & SS_RAMRD)) ); ASSERT( (flag_ramwrt ? (softswitches & SS_RAMWRT) : !(softswitches & SS_RAMWRT)) ); uint32_t switch_save = softswitches; uint8_t *save_base_textrd = base_textrd; uint8_t *save_base_textwrt = base_textwrt; uint8_t *save_base_hgrrd = base_hgrrd; uint8_t *save_base_hgrwrt = base_hgrwrt; int save_current_page = video__current_page; apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00; c_debugger_go(); if (flag_ramwrt) { ASSERT(apple_ii_64k[1][WATCHPOINT_ADDR] == TEST_FINISHED); } else { ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED); } ASSERT(!(softswitches & SS_HIRES)); ASSERT( (flag_ramrd ? (softswitches & SS_RAMRD) : !(softswitches & SS_RAMRD)) ); ASSERT( (flag_ramwrt ? (softswitches & SS_RAMWRT) : !(softswitches & SS_RAMWRT)) ); switch_save = switch_save & ~(SS_HIRES|SS_HGRRD|SS_HGRWRT); if (flag_ramrd) { ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k[1])); switch_save = switch_save | SS_HGRRD; } else { ASSERT((void *)base_hgrrd == (void *)(apple_ii_64k[0])); } if (flag_ramwrt) { ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k[1])); switch_save = switch_save | SS_HGRWRT; } else { ASSERT((void *)base_hgrwrt == (void *)(apple_ii_64k[0])); } ASSERT(video__current_page == save_current_page); ASSERT(base_textrd == save_base_textrd); // unchanged ASSERT(base_textwrt == save_base_textwrt); // unchanged ASSERT((softswitches ^ switch_save) == 0); PASS(); } // ---------------------------------------------------------------------------- // Test Suite extern void cpu_thread(void *dummyptr); GREATEST_SUITE(test_suite_vm) { GREATEST_SET_SETUP_CB(testvm_setup, NULL); GREATEST_SET_TEARDOWN_CB(testvm_teardown, NULL); c_read_random(); srandom(0); // force a known sequence test_common_init(/*cputhread*/true); pthread_mutex_lock(&interface_mutex); // TESTS -------------------------- RUN_TESTp(test_boot_disk); RUN_TESTp(test_read_keyboard); RUN_TESTp(test_clear_keyboard); RUN_TESTp(test_read_random); RUN_TESTp(test_PAGE2_on, /*80STORE*/0, /*HIRES*/0); RUN_TESTp(test_PAGE2_on, /*80STORE*/0, /*HIRES*/1); RUN_TESTp(test_PAGE2_on, /*80STORE*/1, /*HIRES*/0); RUN_TESTp(test_PAGE2_on, /*80STORE*/1, /*HIRES*/1); RUN_TESTp(test_PAGE2_off, /*80STORE*/0, /*HIRES*/0); RUN_TESTp(test_PAGE2_off, /*80STORE*/0, /*HIRES*/1); RUN_TESTp(test_PAGE2_off, /*80STORE*/1, /*HIRES*/0); RUN_TESTp(test_PAGE2_off, /*80STORE*/1, /*HIRES*/1); RUN_TESTp(test_TEXT_on); RUN_TESTp(test_TEXT_off); RUN_TESTp(test_MIXED_on); RUN_TESTp(test_MIXED_off); RUN_TESTp(test_HIRES_on, /*80STORE*/0, /*PAGE2*/0); RUN_TESTp(test_HIRES_on, /*80STORE*/0, /*PAGE2*/1); RUN_TESTp(test_HIRES_on, /*80STORE*/1, /*PAGE2*/0); RUN_TESTp(test_HIRES_on, /*80STORE*/1, /*PAGE2*/1); RUN_TESTp(test_HIRES_off, /*RAMRD*/0, /*RAMWRT*/0); RUN_TESTp(test_HIRES_off, /*RAMRD*/0, /*RAMWRT*/1); RUN_TESTp(test_HIRES_off, /*RAMRD*/1, /*RAMWRT*/0); RUN_TESTp(test_HIRES_off, /*RAMRD*/1, /*RAMWRT*/1); // ... c_eject_6(0); pthread_mutex_unlock(&interface_mutex); } SUITE(test_suite_vm); GREATEST_MAIN_DEFS(); int main(int argc, char **argv) { GREATEST_MAIN_BEGIN(); RUN_SUITE(test_suite_vm); GREATEST_MAIN_END(); }