From e03353b64c63678084b26cc826c63b78f50e320a Mon Sep 17 00:00:00 2001 From: Dannii Date: Sun, 9 Oct 2011 11:53:44 +1000 Subject: [PATCH 1/7] Updated with several more tests --- tests/czech.inf | 1683 ++++++++++++++++++++++++++++++++ tests/czech.z5 | Bin 0 -> 13312 bytes tests/etude.z5 | Bin 0 -> 16896 bytes tests/praxix.inf | 2375 +++++++++++++++++++++++++++++++++++++++++++++ tests/praxix.z5 | Bin 0 -> 28160 bytes tests/unicode.inf | 123 +++ tests/unicode.z5 | Bin 0 -> 4608 bytes 7 files changed, 4181 insertions(+) create mode 100644 tests/czech.inf create mode 100644 tests/czech.z5 create mode 100644 tests/etude.z5 create mode 100644 tests/praxix.inf create mode 100644 tests/praxix.z5 create mode 100644 tests/unicode.inf create mode 100644 tests/unicode.z5 diff --git a/tests/czech.inf b/tests/czech.inf new file mode 100644 index 0000000..686befc --- /dev/null +++ b/tests/czech.inf @@ -0,0 +1,1683 @@ +!! CZECH: Comprehensive Z-machine Emulation CHecker +!! +!! Fairly thoroughly test z-machine stuff. +!! +!! Based on nitfol test script, by Evin Robertson, which was placed in +!! the public domain. +!! Amir Karger massively modified it, changed its name, and un-public'ed it. +!! See README.txt for license. (Basically, use/copy/modify, but be nice.) + + + +! Force Inform to use abbreviations +Switches e; + +Constant TEST_VERSION "0.8"; + +!! +!! USAGE NOTES: +!! +!! * To run tests, just compile this with Inform (I used 6.21.) and run +!! the resulting file with your favorite intepreter. +!! +!! * After every test (except print tests) a '.' is printed. +!! The current test number is printed each time a set of tests is started, +!! and whenever a test fails. +!! +!! * At the end, you'll get a summary of passed tests, failed tests, and print +!! tests. (The computer can't test whether a print test was successful.) +!! +!! * Many tests print a string when they fail describing exactly what went +!! wrong, so you can look in the code for that string and see exactly +!! what test failed. If no string is printed out, count tests from the +!! beginning of the set until the test number that failed. +!! +!! * Compile with -v[3468] to test different Z-machine versions. +!! (Inform's default is -v5.) +!! +!! * A set of tests can be skipped. See Main(). +!! +!! * subroutines, print, and some jumps are needed to do +!! most testing. If they have major bugs, the whole script may break. +!! (E.g., You need to call_vn2 (call in v3) just to get to "Main" routine.) +!! Local/Global variables and stack also need to work at least somewhat. + +!-------------------------------------------------------------------- +! Main() calls a bunch of test_* subs. +! test_* subs each test a set of functionality, e.g., arithmetic operators +! do_* subs generally test one op, sometimes two (like load/store) +! assert* routines test that the expected value was obtained, and +! sometimes print a test description, too. +!-------------------------------------------------------------------- +! Still need to test: +! - test globals, locals, stack as ops more thoroughly +! - moreheader stuff +! - IO (streams, read_char, fancy print stuff) +! - *_table +! - fancy IO: time, split_window, get_mouse, streams, etc. +! - read, tokenise +! - save/restore? restart? +! - See TODO throughout the file for more stringent testing ideas +! Steal David Kinder's Unicode.inf? (Win2002 Examples dir) +! Steal etude stuff? +! Steal nitfol's crashme.inf, randomization print test? +!-------------------------------------------------------------------- +! More notes for writing tests: +! - In general, use assembly (@ commands) instead of Inform. We're testing +! how the Z-machine performs on the opcodes, not how Inform translates stuff +! E.g., Use @print instead of print so inform uses @print instead of +! @print_paddr even for long strings. +! And I never use (string) or (char), which load in a bunch of extra code. +! - Use assert whenever possible. Otherwise, call p() or f() +! after testing to increment the count of failed & passed tests +! Or call pt() for a print test, where the user needs to decide whether +! the test was successful. '.' is also printed for every call to p() or f() +! ("assert*()" appears to consistently map to @call_vn2.) +! - Certain things are done in a roundabout way to avoid using complex opcodes. +! This is especially true of assert* routines, which can be called from +! anywhere in the testing process. +! - This file is designed to require NO I/O. Other test files can test +! I/O stuff. We can still test opcodes like read/print by using streams. + +! Version-specific constants - Ifdef these to test only certain versions +! Someday, we'll need a IS_V6 here for V6-specific opcodes. +Iftrue #version_number >= 4; + Constant V4PLUS = 1; +Endif; +Iftrue #version_number >= 5; + Constant V5PLUS = 1; +Endif; + +! [Evin] couldn't figure out how to do negative numbers in inform assembly, so +! here's constants for the numbers I use +Constant n1 -1; +Constant n2 -2; +Constant n3 -3; +Constant n4 -4; +Constant n5 -5; +Constant n500 -500; +Constant n32768 -32768; + +! TODO I could test globals by confirming that g00 changes when I try to +! change the first Global I declare. + +! CAREFUL about declaring new globals! Declaration order matters, e.g. +! for "@load [i] -> j", where i refers to a Global var. +Global count; +Global Testnum; +Global Passed; +Global Failed; +Global Print_Tests; +Global Gtemp; +!Global Gtemp2; +Global Ga; Global Gb; ! hack used to get assert routines to work in v3 +!Global Standard; + +Abbreviate "xyzzy"; + +Array mytable -> 256; +!Array mysecond -> 256; + +! Make this sub the first in the test program, so that the string +! in it is the first string in high memory. +! TODO Don't know how to find first string's address, though! +![ make_a_string; +! print "^print_paddr: This long string should be printed.^"; +!]; + +! ---------------------------------------------------------------------- +! Assert Routines: did we get expected output? + +! Main assert function. +! desc is an optional arg which is a short string describing the exact +! test run. Note that the program already writes which opcode we're testing, +! so only use this for saying what *aspect* of that opcode is being tested. +! See calls in the code for examples. +[ assert0 actual expected desc; + if (expected ~= actual) { + print "^^ERROR [",Testnum,"] "; + ! Print description if we got one +#Ifdef V5PLUS; + @check_arg_count 3 ?~no_desc; +#Ifnot; ! fake a check_arg_count + @jz desc ?no_desc; +#Endif; + print "("; + @print_paddr desc; + print ")"; + + .no_desc; + f(); + print " Expected ", expected, "; got ", actual, "^^"; + !@quit; + } else { + p(); + } +]; + +! Problem: the "(string)" command requires Inform to pull in a whole +! bunch of code requiring a whole bunch of new ops, which I don't want +! to use for assert commands + +! Special assert for Unary ops +! TODO allow this to take an optional desc also, to give the test's REASON. +[ assert1 actual expected op a; + a = Ga; ! Hack so we can call with only 3 args for v3. + if (expected ~= actual) { + f(); + !print (string) op, a; + print "^^ERROR [", Testnum, "] ("; + @print_paddr op; + print " ", a, ")"; + print " Expected ", expected, "; got ", actual, "^"; + !@quit; + } else { + p(); + } +]; + +! Special assert for Binary ops +! TODO allow this to take an optional desc also, to give the test's REASON. +[ assert2 actual expected op a b; + a = Ga; b = Gb; ! Hack so we can call with only 3 args for v3. + if (expected ~= actual) { + f(); +! print a, (string) op, b; + print "^^[", Testnum, "] ("; + print a, " "; + @print_paddr op; + print " ", b, ")"; + print " Expected ", expected, "; got ", actual, "^"; + !@quit; + } else { + p(); + } +]; + +! For a print test, don't print out a dot & don't try and figure out +! if it was successful +[ pt; + Testnum++; + Print_Tests++; +]; + +! Passed a test +[ p; + @print "."; + Testnum++; + Passed++; +]; + +! Failed a test +[ f; + Testnum++; + Failed++; +]; + +! ---------------------------------------------------------------------- +! These subs run tests on a particular set of ops +! First argument is whether to skip the tests + +[ test_jumps skip i; + print "Jumps"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + print "jump"; + jump j2; ! Using "@jump" with label name crashes + .j1; + print "bad!"; @quit; + .j2; p(); + + ! Note that some of these jumps are > 63 bytes away, some less, + ! so we'll test short and long form of branching. + print "je"; + ! TODO test "je sp a b c" to make sure not multi-popping stack, etc. + @je 5 5 ?~bad; p(); + @je 5 n5 ?bad; p(); + @je n5 5 ?bad; p(); + @je n5 n5 ?~bad; p(); + @je 32767 n32768 ?bad; p(); + @je n32768 n32768 ?~bad; p(); + @je 5 4 5 ?~bad; p(); + @je 5 4 3 5 ?~bad; p(); + @je 5 4 5 3 ?~bad; p(); + @je 5 4 3 2 ?bad; p(); + + print "jg"; + @jg 5 5 ?bad; p(); + @jg 1 0 ?~bad; p(); + @jg 0 1 ?bad; p(); + @jg n1 n2 ?~bad; p(); + @jg n2 n1 ?bad; p(); + @jg 1 n1 ?~bad; p(); + @jg n1 1 ?bad; p(); + + print "jl"; + @jl 5 5 ?bad; p(); + @jl 1 0 ?bad; p(); + @jl 0 1 ?~bad; p(); + @jl n1 n2 ?bad; p(); + @jl n2 n1 ?~bad; p(); + @jl 1 n1 ?bad; p(); + @jl n1 1 ?~bad; p(); + + print "jz"; + @jz 0 ?~bad; p(); + @jz 1 ?bad; p(); + @jz n4 ?bad; p(); + + print "offsets"; + i = do_jump_return(0); + assert0(i, 0, "branch 0"); + i = do_jump_return(1); + assert0(i, 1, "branch 1"); + rtrue; + +.bad; + print "^bad [", Testnum, "]!^"; + @print "Quitting tests because jumps don't work!"; + @quit; + +]; + +! Test that offset of 0/1 returns instead of branching. +! TODO in theory we should test all jump opcodes to make sure they can +! return false/true +[ do_jump_return i; + @je i 0 ?~j1; + @jz 0 ?rfalse; + return 97; + .j1; + @je i 1 ?~j2; + @jz 0 ?rtrue; + return 98; + .j2; + return 99; +]; + +! ---- VARIABLES ---------------------------------- +[ test_variables skip i n; + print "Variables"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + print "push/pull"; + @push 9; + @push 8; + @pull i; + assert0(i, 8, "pull to local"); + @pull Gtemp; + assert0(Gtemp, 9, "pull to global"); + +#Ifndef V5PLUS; + print "pop"; + @push 7; + @push 6; + @pop; ! popped value gets thrown away + @pull i; + assert0(i, 7); +#Endif; + + print "store"; + @store i 5; + assert0(i, 5); + print "load"; + n = 5; i = 6; + @load i sp; + @pull n; + assert0(i, n); + + print "dec"; + do_dec( 5, 4); + do_dec( 0, -1); + do_dec(-8, -9); + do_dec(-32768, 32767); + ! Should decrement top of stack and not pop it + @push 1; + @push 10; + @dec sp; + @pull n; + assert0(n, 9, "dec sp"); + @pull n; + assert0(n, 1, "dec sp"); + count = 3; + @dec count; + assert0(count, 2, "dec global"); + + print "inc"; + do_inc( 5, 6); + do_inc(-1, 0); + do_inc(-8, -7); + do_inc(32767, -32768); + @push 1; + @push 10; + @inc sp; + @pull n; + assert0(n, 11, "inc sp"); + @pull n; + assert0(n, 1, "inc sp"); + count = 3; + @inc count; + assert0(count, 4, "inc global"); + + print "^ dec_chk"; + n = 3; + @dec_chk n 1000 ?~bad1; p(); ! 2 + @dec_chk n 1 ?bad1; p(); ! 1 + @dec_chk n 1 ?~bad1; p(); ! 0 + @dec_chk n 0 ?~bad1; p(); ! -1 + @dec_chk n n2 ?bad1; p(); ! -2 + @dec_chk n n2 ?~bad1; p(); ! -3 + @dec_chk n 1000 ?~bad1; p(); ! -4 + @dec_chk n n500 ?bad1; p(); ! -5 + @push 1; + @push 10; + @dec_chk sp 5 ?bad1; p(); + @pull n; + assert0(n, 9, "dec_chk sp"); + @pull n; + assert0(n, 1, "dec_chk sp"); + jump not_bad1; +.bad1; + print "^bad [", Testnum, "]^"; + f(); +.not_bad1; + + print "inc_chk"; + n = -6; + @inc_chk n n500 ?~bad2; p(); ! -5 + @inc_chk n 1000 ?bad2; p(); ! -4 + @inc_chk n n3 ?bad2; p(); ! -3 + @inc_chk n n3 ?~bad2; p(); ! -2 + @inc_chk n 0 ?bad2; p(); ! -1 + @inc_chk n 1 ?bad2; p(); ! 0 + @inc_chk n 1 ?bad2; p(); ! 1 + @inc_chk n 1 ?~bad2; p(); ! 2 + @inc_chk n 1000 ?bad2; p(); ! 3 + jump not_bad2; +.bad2; + print "^bad [", Testnum, "]!^"; + f(); +.not_bad2; + + rtrue; +]; + +[ do_inc a expect; + Ga = a; + @inc a; + assert1(a, expect, "++"); +]; + +[ do_dec a expect; + Ga = a; + @dec a; + assert1(a, expect, "--"); +]; + +! ---- ARITH ---------------------------------- +[ test_arithmetic skip; + print "Arithmetic ops"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + print "add"; + do_add( 5, 3, 8); + do_add( 3, 5, 8); + do_add(-5, 3, -2); + do_add(-5, -3, -8); + do_add(-3, -5, -8); + do_add(-3, 5, 2); + do_add(32765, 6, -32765); + + print "sub"; + do_sub(8, 5, 3); + do_sub(8, 3, 5); + do_sub(-2, -5, 3); + do_sub(-8, -5, -3); + do_sub(-8, -3, -5); + do_sub(2, -3, 5); + do_sub(-32765, 32765, 6); + + print "^ mul"; + do_mul( 0, 123, 0); + do_mul(123, 0, 0); + do_mul( 8, 9, 72); + do_mul( 9, 8, 72); + do_mul( 11, -5, -55); + do_mul(-11, 5, -55); + do_mul(-11, -5, 55); + do_mul(-32768, -1, -32768); + + print "div"; + do_div(-11, 2, -5); + do_div(-11, -2, 5); + do_div( 11, -2, -5); + do_div( 5, 1, 5); + do_div( 5, 2, 2); + do_div( 5, 3, 1); + do_div( 5, 5, 1); + do_div( 5, 6, 0); + do_div(5, 32767, 0); + do_div(32767, -32768, 0); + do_div(-32768, 32767, -1); +! do_div(-32768, -1, -32768); + + print "mod"; + do_mod(-13, 5, -3); + do_mod( 13, -5, 3); + do_mod(-13, -5, -3); + do_mod( 5, 1, 0); + do_mod( 5, 2, 1); + do_mod( 5, 3, 2); + do_mod( 5, 5, 0); + do_mod( 5, 6, 5); + do_mod(5, 32767, 5); + do_mod(32767, -32768, 32767); + do_mod(-32768, 32767, -1); +! do_mod(-32768, -1, 0); + + rtrue; +]; + +[ do_add a b expect c; + @add a b -> c; Ga = a; Gb = b; + assert2(c, expect, "+"); +]; + +[ do_sub a b expect c; + @sub a b -> c; Ga = a; Gb = b; + assert2(c, expect, "-"); +]; + +[ do_mul a b expect c; + @mul a b -> c; Ga = a; Gb = b; + assert2(c, expect, "*"); +]; + +[ do_div a b expect c; + @div a b -> c; Ga = a; Gb = b; + assert2(c, expect, "/"); +]; + +[ do_mod a b expect c; + @mod a b -> c; Ga = a; Gb = b; + assert2(c, expect, "%"); +]; + +! ---- LOGICAL ---------------------------------- +[ test_logical skip; + print "Logical ops"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + print "not"; + do_not(0, ~0); + do_not(123, ~123); + do_not($5555, $aaaa); + do_not($aaaa, $5555); + + print "and"; + do_and( 5, 3, 1); + do_and( 3, 5, 1); + do_and(-3, -3, -3); + do_and(-3, 5, 5); + do_and(-3, -5, -7); + + print "or"; + do_or($1234, $4321, $5335); + do_or($4321, $1234, $5335); + do_or($1234, 0, $1234); + do_or($1030, $ffff, $ffff); + do_or($ffff, $0204, $ffff); + +#Ifdef V5PLUS; + print "art_shift"; + do_art( 0, 1, 0); + do_art( 0, -1, 0); + do_art( 1, 5, 32); + do_art( 1, -1, 0); + do_art(85, 1, 170); + do_art(85, -2, 21); + do_art(-9, 5, -288); + do_art(-9, -5, -1); + + print "log_shift"; + do_log( 0, 1, 0); + do_log( 0, -1, 0); + do_log( 1, 5, 32); + do_log( 1, -1, 0); + do_log(85, 1, 170); + do_log(85, -2, 21); + do_log(-9, 5, -288); + do_log(-9, -5, 2047); +#Endif; + + rtrue; +]; + +#Ifdef V5PLUS; +[ do_art a b expect c; + @art_shift a b -> c; Ga = a; Gb = b; + assert2(c, expect, "<<"); +]; + +[ do_log a b expect c; + @log_shift a b -> c; Ga = a; Gb = b; + assert2(c, expect, "<<"); +]; +#Endif; + +! Write 'not' instead of '~' so we can print with print_paddr +[ do_not a expect c; + !@"VAR:56S" a -> c; ! @not a -> c; (bug in inform) + @not a -> c; ! (No longer a bug in inform?) + Ga = a; + assert1(c, expect, "not"); +]; + +[ do_and a b expect c; + @and a b -> c; Ga = a; Gb = b; + assert2(c, expect, "&"); +]; + +[ do_or a b expect c; + @or a b -> c; Ga = a; Gb = b; + assert2(c, expect, "|"); +]; + +! ---- MEMORY ACCESS ---------------------------------- +[ test_memory skip i j k n; + print "Memory"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + print "loadw"; + ! Bytes 04-05 of file are beg. of high mem. + ! Bytes 06-07 are address of main. + ! main() is guaranteed to be first sub in Inform! + @loadw 0 2 -> i; + @loadw 0 3 -> j; + @add i 1 -> k; + assert0(j, k); + + print "loadb"; + @loadb 0 4 -> j; + @loadb 0 5 -> k; + @mul j 256 -> sp; + @add sp k -> k; + assert0(i, k); + @loadb mytable 0 -> n; + assert0(n, 0); + + print "storeb"; + @storeb mytable 0 123; + @loadb mytable 0 -> n; + assert0(n, 123); + @loadw mytable 0 -> n; + assert0(n, $7b00, "word from two bytes"); + print "storew"; + @storew mytable 5 $1234; + @loadw mytable 5 -> n; + assert0(n, $1234); + @loadb mytable 10 -> n; + assert0(n, $12, "first byte of stored word"); + @loadb mytable 11 -> n; + assert0(n, $34, "second byte of stored word"); + ! TODO load/store numbers > 32K + + rtrue; +]; + +! ---- PRINT opcodes ---------------------------------- +[ test_print skip i; + @print "^^^"; + print "Print opcodes"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + ! Note: pt()'s best location is after you print what should come out + ! and before you actually print it. But we may get some off-by-ones + @print "Tests should look like... '[Test] opcode (stuff): stuff'"; + @print "^print_num (0, 1, -1, 32767,-32768, -1): "; pt(); + @print_num 0; print ", "; + i = 1; + @print_num i; print ", "; pt(); + @print_num n1; print ", "; pt(); + @print_num 32767; print ", "; pt(); + @print_num n32768; print ", "; pt(); + i = 65535; + @print_num i; pt(); + print "^[", Testnum+1, "] "; + print "print_char (abcd): "; + @print_char 'a'; pt(); + @print_char 98; pt(); + i = 99; + @print_char i; pt(); + @push 100; pt(); + @print_char sp; + print "^[", Testnum+1, "] "; + print "new_line:^"; pt(); + @new_line; + @print "There should be an empty line above this line.^"; + i = do_print_ret(); pt(); ! test printing AND return + assert0(i, 1); + + ! TODO Once we have objects, print_addr of first word in dictionary. + + ! I could also write stuff to globalvars (as long as I knew what + ! offset they'd have) then load the address from 0->0c and print_addr. + @print "^print_addr (Hello.): "; pt(); + @storew mytable 0 $11aa; ! 4 13 10: Shift-He + @storew mytable 1 $4634; ! 17 17 20: llo + @storew mytable 2 $1645; ! 5 18 5: A2 . A2 + @storew mytable 3 $9ca5; ! 7 5 5: \n space-fill + ! FYI xyzzy is 77df ffc5 +! print mytable->1; + @print_addr mytable; + @print "^print_paddr (A long string that Inform will put in high memory):^"; + pt(); + print "A long string that Inform will put in high memory"; + ! Break up print statement to NOT use abbrev in parenthetical part + print "^Abbreviations (I love 'xyz"; print "zy' [two times]): "; pt(); + i = "I love 'xyzzy' "; + @print_paddr i; + pt(); + @print " I love 'xyzzy'^"; + ! TODO @print_paddr sp, global vars + ! TODO test word wrapping + + print "^[", Testnum+1, "] "; + @print "print_obj (Test Object #1Test Object #2): "; pt(); + @print_obj Obj1; pt(); + @print_obj Obj2; +! TODO long test object name + + ! TODO print many more complicated things, Unicode, whatever + ! TODO use unfinished abbreviations. + + rtrue; +]; + +! ---- SUBROUTINES ---------------------------------- +[ test_subroutines skip i n; + print "Subroutines"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + i = 0; + Gtemp = 0; +#Ifdef V4PLUS; + print "call_1s"; + Gtemp = 2; + @call_1s do_call_1s -> i; + assert0(Gtemp, 3); + print "call_2s"; + @call_2s do_call_2s 6 -> i; + assert0(i, 5); + + print "call_vs2"; + i = 0; + @call_vs2 do_call_vs2 1 2 3 4 5 6 7 ->i; + assert0(Gtemp, 9); + assert0(i, 5); + print "call_vs"; + i = 0; + @call_vs do_call 1 2 3 ->i; + assert0(i, 5); + +#Ifnot; ! v3 + print "call"; + @call do_call 1 2 3 ->i; +#Endif; + + ! Test results of call/call_vs, depending on game version + assert0(Gtemp, 7); + print "ret"; + assert0(i, 5); + ! TODO call_vs2 with fewer than 7 args. Make sure locals don't get set etc. + +#Ifdef V5PLUS; + print "^ call_1n"; + @call_1n do_call_1n; + assert0(Gtemp, 1); + print "call_2n"; + @call_2n do_call_2n 6; + assert0(Gtemp, 5); + print "call_vn"; + @call_vn do_call_vn 1 2 3; + assert0(Gtemp, 10); + print "call_vn2"; + @call_vn2 do_call_vn2 1 2 3 4 5 6 7; + assert0(Gtemp, 11); +#Endif; + + print "^ "; + print "rtrue"; + i = 2; + i = do_rtrue(); + assert0(i, 1); + i = 2; + print "rfalse"; + i = do_rfalse(); + assert0(i, 0); + i = do_ret_popped(); + assert0(i, 5, "return from ret_popped"); + + ! Computed calls + print "^ Computed call"; + i = 1; + n = do_computed_call1; +#Ifdef V4PLUS; @call_1s n -> i; #Ifnot; @call n -> i; #Endif; + assert0(i, 5); + @push 1; + @push do_computed_call2; +#Ifdef V4PLUS; @call_1s sp -> i; #Ifnot; @call sp -> i; #Endif; + assert0(i, 6); + @pull i; + assert0(i, 1); + ! TODO Spec14 describes @call_1s [i] syntax. Is that different than above? + + ! TODO test call_v's more extensively. call with variables (and stack?) + ! Make sure variables don't get changed! Call with too many args. + +#Ifdef V5PLUS; + print "^ check_arg_count"; + count = 0; do_check_check_arg_count(); + count = 1; do_check_check_arg_count(1); + count = 2; do_check_check_arg_count(2, 1); + count = 3; do_check_check_arg_count(3, 2, 1); + count = 4; do_check_check_arg_count(4, 3, 2, 1); + count = 5; do_check_check_arg_count(5, 4, 3, 2, 1); + count = 6; do_check_check_arg_count(6, 5, 4, 3, 2, 1); + count = 7; do_check_check_arg_count(7, 6, 5, 4, 3, 2, 1); +#Endif; + + rtrue; +]; ! end of test_subroutines + +#Ifdef V5PLUS; +[ do_check_check_arg_count a b c d e g h n; + for(n = 1: n <= count: n++) { + @check_arg_count n ?~bad; + } + p(); + for(: n <= 7: n++) { + @check_arg_count n ?bad; + } + p(); + a=b=c=d=e=h=g=0; ! make compiler happy + return; + + .bad; + f(); + + print "^[", Testnum, "] claimed argument ", n, " was "; + if(n <= count) + print "not given when it was.^"; + else + print "given when it was not.^"; + !@quit; +]; +#Endif; + +#Ifdef V5PLUS; +[ do_call_1n; + Gtemp = 1; +]; + +[ do_call_2n arg0; + assert0(arg0, 6); + Gtemp = 5; +]; + +[ do_call_vn a b c; + a=b; ! keep compiler quiet + assert0(c, 3); + Gtemp = 10; +]; + +[ do_call_vn2 a b c d e f g; + a=b=c=d=e=f; ! keep compiler quiet + assert0(g, 7); + Gtemp = 11; +]; +#Endif; + +#Ifdef V4PLUS; +[ do_call_1s; + Gtemp = 3; + @ret 5; +]; + +[ do_call_2s arg0; + assert0(arg0, 6); + @ret 5; +]; + +[ do_call_vs2 a b c d e f g; + a=b=c=d=e=f; ! keep compiler quiet + assert0(g, 7); + Gtemp = 9; + @ret 5; +]; + +#Endif; + +[ do_call i j k; ! called by call OR call_vs + assert0(i, 1); + assert0(j, 2); + assert0(k, 3); + Gtemp = 7; + @ret 5; +]; + +[ do_rtrue; + @rtrue; +]; + +[ do_rfalse; + @rfalse; +]; + +[ do_print_ret; + @print_ret "print_ret (should have newline after this)"; +]; + +[ do_ret_popped; + @push 5; + print "ret_popped"; + @ret_popped; +]; + +[ do_computed_call1; + @ret 5; +]; + +[ do_computed_call2; + @ret 6; +]; + +! ---- OBJECTS ---------------------------------- +Attribute attr1; +Attribute attr2; +Attribute attr3; +Attribute attr4; +Property propa 11; +Property propb 12; +Property propc 13; +Property propd 14; +Property prope 15; + +Object Obj1 "Test Object #1" + has attr1 attr2 + with propa 1, + propb 2, + propd 4 5 6; + +Object Obj2 "Test Object #2" Obj1 + has attr3 attr4 + with propa 2, + propd 4; + +Object Obj3 "Test Object #3" Obj1 + with propa 3, + propd 4; + +Object Obj4 "Test Object #4" Obj3 + with propa 4, + propd 4; + +#Ifdef V4PLUS; ! limit of 4-byte properties +! This object is only valid on standard 1.0 interpreters because of +! the 64 byte property. +Object Obj5 "" + with propa 1, + propb 1 2 3, + propc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29, + prope 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32; +#Endif; + +Object Obj6 "test of an object with a shortname which is about as long as they get these days even though this one only uses the first alphabet which means this is destined to be a runon sentence since i am not using any punctuation or uppercase well i guess that means this is more boring than it need be but it makes the size calculation easier on me when i am writing this program and this mostly assumes your zmachine is capabable of outputting text with correct zscii decoding because after all if it could not then you probably would not even be running this program because it would definitely be too boring to run something which cannot even communicate its results to you when you really want to know what they are abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs the end" + with prope 10000; + +[ test_objects skip; + print "Objects"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + ! TODO Copy tests from test.inf. + ! TODO Test object 0 + ! TODO object with no properties + ! TODO pass an optional desc - subs check_arg_count & pass desc to assert + ! LOTS OF STUFF!!! + print "get_parent"; + do_get_parent(Obj1, 0); + do_get_parent(Obj2, Obj1); + do_get_parent(Obj3, Obj1); + do_get_parent(Obj4, Obj3); + print "get_sibling"; + do_get_sibling(Obj1, 0); + do_get_sibling(Obj2, Obj3); + do_get_sibling(Obj3, 0); + do_get_sibling(Obj4, 0); + print "get_child"; + do_get_child(Obj1, Obj2); + do_get_child(Obj2, 0); + do_get_child(Obj3, Obj4); + do_get_child(Obj4, 0); + print "jin"; + do_jin(Obj1, Obj2, 0); + do_jin(Obj1, Obj1, 0); + do_jin(Obj2, Obj1, 1); + do_jin(Obj2, Obj3, 0); + do_jin(Obj3, Obj1, 1); + do_jin(Obj4, Obj3, 1); + do_jin(Obj4, Obj1, 0); ! must be *direct* parent + + print "^ test_attr"; + do_test_attr(Obj1, attr1, 1); + do_test_attr(Obj1, attr2, 1); + do_test_attr(Obj1, attr3, 0); + do_test_attr(Obj1, attr4, 0); + do_test_attr(Obj2, attr1, 0); + do_test_attr(Obj2, attr3, 1); + print "set_attr"; + do_set_attr(Obj1, attr3); + do_set_attr(Obj1, attr4); + do_set_attr(Obj1, attr1); ! test setting already set bit + do_set_attr(Obj1, attr2); + print "clear_attr"; + do_clear_attr(Obj2, attr3); + do_clear_attr(Obj2, attr4); + do_clear_attr(Obj2, attr1); ! test clearing already unset bit + do_clear_attr(Obj2, attr2); + print "set/clear/test_attr"; + do_big_attr_test(Obj3); + + print "^ get_next_prop"; + do_get_next_prop(Obj1, 0, propd); + do_get_next_prop(Obj1, propd, propb); + do_get_next_prop(Obj1, propb, propa); + do_get_next_prop(Obj1, propa, 0); + do_get_next_prop(Obj6, 0, prope); + do_get_next_prop(Obj6, prope, 0); + + ! TODO figure out how to get a one-byte property + ! Test stuffing a word into one-byte property. + print "get_prop_len/get_prop_addr"; + do_prop_len(Obj1, propa, 2); + do_prop_len(Obj1, propb, 2); + do_prop_len(Obj1, propd, 6); + do_prop_len(Obj6, prope, 2); + + print "^ get_prop"; + do_prop(Obj1, propa, 1); + do_prop(Obj1, propb, 2); + do_prop(Obj1, propc, 13); + do_prop(Obj2, propd, 4); + do_prop(Obj1, prope, 15); + do_prop(Obj6, propa, 11); + do_prop(Obj6, propb, 12); + do_prop(Obj6, propc, 13); + do_prop(Obj6, propd, 14); + do_prop(Obj6, prope, 10000); + + print "put_prop "; + @put_prop Obj1 propa 2; + do_prop(Obj1, propa, 2); + @put_prop Obj1 propb 4; + do_prop(Obj1, propb, 4); + @put_prop Obj2 propd 8; + do_prop(Obj2, propd, 8); + @put_prop Obj6 prope 5000; + do_prop(Obj6, prope, 5000); + ! Test other things didn't change + do_prop(Obj1, propc, 13); + do_prop(Obj1, prope, 15); + do_prop(Obj6, propa, 11); + do_prop(Obj6, propb, 12); + do_prop(Obj6, propc, 13); + do_prop(Obj6, propd, 14); + + print "^ remove"; + @remove_obj Obj3; + do_get_parent(Obj3, 0); + do_get_parent(Obj4, Obj3); ! confirm didn't change + print "insert"; + @insert_obj Obj4 Obj1; + do_get_parent(Obj4, Obj1); + do_get_sibling(Obj4, Obj2); + do_get_sibling(Obj2, 0); + do_get_child(Obj1, Obj4); + @insert_obj Obj3 Obj4; ! insert parentless object + do_get_child(Obj4, Obj3); + do_get_parent(Obj3, Obj4); + +#Ifdef V4PLUS; +! if(Standard >= 1) { + print "^ Spec1.0 length-64 props"; + do_get_next_prop(Obj5, 0, prope); + do_get_next_prop(Obj5, prope, propc); + do_get_next_prop(Obj5, propc, propb); + do_get_next_prop(Obj5, propb, propa); + do_get_next_prop(Obj5, propa, 0); + do_prop_len(Obj5, propa, 2); + do_prop_len(Obj5, propb, 6); + do_prop_len(Obj5, propc, 58); + do_prop_len(Obj5, prope, 64); + do_prop(Obj5, propa, 1); + @put_prop Obj5 propa 3; + do_prop(Obj5, propa, 3); +! } +#Endif; + + rtrue; +]; + +[ do_get_parent ch par i; + @get_parent ch -> i; + assert0(i, par); +]; + +[ do_get_sibling sib1 sib2 i; + @get_sibling sib1 -> i ?sib_label; + assert0(i, 0); ! make sure i only jumped if non-zero + .sib_label; + assert0(i, sib2); +]; + +[ do_get_child par ch i; + @get_child par -> i ?child_label; + assert0(i, 0); ! make sure i only jumped if non-zero + .child_label; + assert0(i, ch); +]; + +[ do_jin ch par expect; + @jin ch par ?is_in; + assert0(expect, 0); + return; + .is_in; + assert0(expect, 1); + return; +]; + +[ do_test_attr obj attr expect; + @test_attr obj attr ?test_attr_label; + assert0(expect, 0); ! make sure i only jumped if expect is non-zero + return; + .test_attr_label; + assert0(expect, 1); +]; + +! This does depend on test_attr working too. +[ do_set_attr obj attr; + @set_attr obj attr; + @test_attr obj attr ?set_attr_label; + assert0(0, 1); ! this should never happen! + return; + .set_attr_label; + p(); +]; + +! This does depend on test_attr working too. +[ do_clear_attr obj attr; + @clear_attr obj attr; + @test_attr obj attr ?~clear_attr_label; + assert0(1, 0); ! this should never happen! + return; + .clear_attr_label; + p(); +]; + +! Test that we can set/clear/test all attributes +[ do_big_attr_test obj i j k; +#Ifdef V4PLUS; + k = 48; +#Ifnot; + k = 32; +#Endif; + @store j 0; + for(i = 0: i < k: i++) { + @set_attr obj i; + @test_attr obj i ?good_set_label; + j++; ! number of failed sets + .good_set_label; + } + assert0(j,0, "set_attr/test_attr"); + @store j 0; + + for(i = 0: i < k: i++) { + @clear_attr obj i; + @test_attr obj i ?~good_clear_label; + j++; ! number of failed clears + .good_clear_label; + } + assert0(j,0, "clear_attr/test_attr"); + return; +]; + +[ do_prop obj prop expect i; + @get_prop obj prop -> i; Ga = obj; Gb = prop; + assert2(i, expect, "."); +]; + +[ do_get_next_prop obj prop next_prop i; + @get_next_prop obj prop -> i; Ga = obj; Gb = prop; + assert2(i, next_prop, "next"); +]; + +[ do_prop_len obj prop expect i j; + @get_prop_addr obj prop -> i; + @get_prop_len i -> j; Ga = obj; Gb = prop; + assert2(j, expect, ".#"); + !assert0(j, expect); +]; + +! ---- INDIRECT VARIABLES ---------------------------------- +! Indirect-able opcodes: inc, dec, inc_chk, dec_chk, store, pull, load +! Spec Version 1.1 (draft7): "an indirect reference to the stack +! pointer does not push or pull the top item of the stack - it is read +! or written in place." +! Based on my tests (see rec.arts.int-fiction 20031028), this seems to mean +! that, e.g., for load, you NEVER pop the stack, for all cases +! (a) load sp; (b) load [sp]; (c) i=0; load [i]; (d) sp=0; load [sp]; +[ test_indirect skip i; + print "Indirect Opcodes"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + ! We don't have 100 tests, but we skip a bunch of i's to allow + ! room for more tests. + for (i = 0: i < 100: i++) { + do_indirect(i); + } +]; + +! Run one indirect test. Push stuff onto stack, then do one command, +! see the result +! TODO add store, pull, inc, dec, inc_chk, dec_chk +! Overall rules: +! - Do NOT push/pop for "foo sp": write in place +! - DO pop for "foo [sp]". However, if top of stack is 0, only pop ONCE. +! - "bar = 0; foo [bar]" yields EXACTLY the same results as "foo sp" +! ("push 0; foo [sp] is also identical to "foo sp".) +[ do_indirect which result local2 spointer lpointer gpointer rpointer + top_of_stack which_str expectr expect1 expect2; + local2 = 51; + Gtemp = 61; + result = 71; + spointer = 0; ! stack + rpointer = 2; ! points to 'result' + lpointer = 3; ! local2 + gpointer = 21; ! '21' means 6th global, which is (hopefully!) Gtemp + expectr = 999; ! don't test 'result' unless we change this value + + @push 41; @push 42; @push 43; @push 44; @push 45; + switch (which) { + ! load -> result + 0: print "load"; + @load sp -> result; ! compiles as 'load 0 -> result' + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load sp -> result"; + 1: @load [spointer] -> result; + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load [spointer] -> result"; + 2: @push lpointer; @load [sp] -> result; + expectr = 51; expect1 = 45; expect2 = 44; + which_str = "load [sp=lpointer] -> result"; + 3: @push spointer; @load [sp] -> result; + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load [sp=spointer] -> result"; + + ! load -> sp + 4: @load sp -> sp; + expect1 = 45; expect2 = 45; + which_str = "load sp -> sp"; + 5: @push lpointer; @load [sp] -> sp; + expect1 = 51; expect2 = 45; + which_str = "load [sp=lpointer] -> sp"; + 6: @push spointer; @load [sp] -> sp; + expect1 = 45; expect2 = 45; + which_str = "load [sp=spointer] -> sp"; + + ! store + 10: print "store"; + @store sp 83; + expect1 = 83; expect2 = 44; + which_str = "store sp 83"; + 11: @store [spointer] 83; + expect1 = 83; expect2 = 44; + which_str = "store [spointer] 83"; + 12: @push spointer; @store [sp] 83; + expect1 = 83; expect2 = 44; + which_str = "store [sp=spointer] 83"; + + 13: @store [rpointer] 83; + expectr = 83; expect1 = 45; expect2 = 44; + which_str = "store [rpointer] 83"; + 14: @push rpointer; @store [sp] 83; + expectr = 83; expect1 = 45; expect2 = 44; + which_str = "store [sp=rpointer] 83"; + + 15: @store result sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store result sp"; + 16: @store sp sp; + expect1 = 45; expect2 = 43; + which_str = "store sp sp"; + 17: @push spointer; @store [sp] sp; + expect1 = 45; expect2 = 43; + which_str = "store [sp=spointer] sp"; + + 18: @store [rpointer] sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store [rpointer] sp"; + 19: @push rpointer; @store [sp] sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store [sp=rpointer] sp"; + + ! pull + 20: print "^ pull"; + @pull result; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull result"; + 21: @pull [rpointer]; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull [rpointer]"; + 22: @push rpointer; @pull [sp]; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull [sp=rpointer]"; + + 23: @pull sp; + expect1 = 45; expect2 = 43; + which_str = "pull sp"; + 24: @push spointer; @pull [sp]; + expect1 = 45; expect2 = 43; + which_str = "pull [sp=spointer]"; + 25: @pull [spointer]; + expect1 = 45; expect2 = 43; + which_str = "pull [spointer]"; + + ! inc + 30: print "inc"; + @inc result; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc [rpointer]"; + 31: @inc [rpointer]; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc [rpointer]"; + 32: @push rpointer; @inc [sp]; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc [sp=rpointer]"; + + 33: @inc sp; + expect1 = 46; expect2 = 44; + which_str = "inc sp"; + 34: @inc [spointer]; + expect1 = 46; expect2 = 44; + which_str = "inc [spointer]"; + 35: @push spointer; @inc [sp]; + expect1 = 46; expect2 = 44; + which_str = "inc [sp=spointer]"; + + ! dec + 40: print "dec"; + @dec result; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec [rpointer]"; + 41: @dec [rpointer]; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec [rpointer]"; + 42: @push rpointer; @dec [sp]; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec [sp=rpointer]"; + + 43: @dec sp; + expect1 = 44; expect2 = 44; + which_str = "dec sp"; + 44: @dec [spointer]; + expect1 = 44; expect2 = 44; + which_str = "dec [spointer]"; + 45: @push spointer; @dec [sp]; + expect1 = 44; expect2 = 44; + which_str = "dec [sp=spointer]"; + + ! inc_chk + 50: print "^ inc_chk"; + which_str = "inc_chk [rpointer]"; + @inc_chk result 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + 51: which_str = "inc_chk [rpointer]"; + @inc_chk [rpointer] 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + 52: which_str = "inc_chk [sp=rpointer]"; + @push rpointer; @inc_chk [sp] 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + + 53: which_str = "inc_chk sp"; + @inc_chk sp 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + 54: which_str = "inc_chk [spointer]"; + @inc_chk [spointer] 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + 55: which_str = "inc_chk [sp=spointer]"; + @push spointer; @inc_chk [sp] 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + + ! dec_chk + 60: print "dec_chk"; + which_str = "dec_chk [rpointer]"; + @dec_chk result 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + 61: which_str = "dec_chk [rpointer]"; + @dec_chk [rpointer] 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + 62: which_str = "dec_chk [sp=rpointer]"; + @push rpointer; @dec_chk [sp] 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + + 63: which_str = "dec_chk sp"; + @dec_chk sp 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + 64: which_str = "dec_chk [spointer]"; + @dec_chk [spointer] 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + 65: which_str = "dec_chk [sp=spointer]"; + @push spointer; @dec_chk [sp] 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + + + default: rfalse; ! do nothing. + } + + ! Test results + @je expectr 999 ?skip_expectr; + assert0(result, expectr, which_str); + .skip_expectr; + @pull top_of_stack; + assert0(top_of_stack, expect1, which_str); + @pull top_of_stack; + assert0(top_of_stack, expect2, which_str); + !print which, " ", result, " ", top_of_stack, " "; + !print stack2, " ", stack3, " "; + !@print_paddr which_str; + !print "^"; + + ! TODO test "je sp a b c" to make sure not multi-popping stack, etc. + ! TODO Test globals here + + rtrue; + + ! If you got here, inc_chk/dec_chk broke + .bad_indirect_inc; + ! Assert will give silly numbers, but correct which_str + assert0(result, 123, which_str); + rfalse; +]; + +! ---- MISC stuff ---------------------------------- +[ test_misc skip i j; + print "Misc"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + print " [", Testnum+1, "]: "; + + print "test"; + @test $ffff $ffff ?~bad; p(); + @test $ffff 0 ?~bad; p(); + @test $1234 $4321 ?bad; p(); + jump good_test; + .bad; + f(); + print "^bad [", Testnum, "]!^"; + .good_test; + + ! TODO randomizer table from nitfol test? + print "random"; + @random -32000 -> i; + @random $100 -> i; + @random -32000 -> j; + @random $100 -> j; + assert0(i, j); + + ! I can't think of a way to test for a bad checksum... + print "verify"; + i = 0; + @verify ?good_verify; + i = 1; + .good_verify; + assert0(i, 0); + +#Ifdef V5PLUS; + print "piracy"; + i = 0; + @piracy ?good_piracy; + i = 1; + .good_piracy; + assert0(i, 0); +#Endif; + + rtrue; +]; + +! ---- Header ---------------------------------- + + +!Global standard; + +[ test_header skip flags i j; + print "Header"; + @jz skip ?skipped; + print " skipped"; + rfalse; +.skipped; + !print " [", Testnum+1, "]: "; + print " (No tests)"; +! standard = 0->50; + @loadb 0 50 -> i; + @loadb 0 51 -> j; + if(i || j) + print "^ standard ", i, ".", j, " "; + !print "interpreter ", 0->30, (char) 0->31; + @loadb 0 30 -> i; + print "^ interpreter ", i, " "; + @loadb 0 31 -> i; + @print_char i; + @loadb 0 30 -> i; + print " ("; say_platform(i); print ")"; + + for(i = 0: i < 2: i++) { + if(i == 0) + print "^ Flags on: "; + else + print "^ Flags off: "; + + @loadb 0 1 -> flags; +#Ifdef V4PLUS; + do_say_flags(i, flags & 1, "color"); + do_say_flags(i, flags & 2, "pictures"); + do_say_flags(i, flags & 4, "boldface"); + do_say_flags(i, flags & 8, "italic"); + do_say_flags(i, flags & 16, "fixed-space"); + do_say_flags(i, flags & 32, "sound"); + do_say_flags(i, flags & 128, "timer"); +#Ifnot; + do_say_flags(i, flags & 2, "time game"); + do_say_flags(i, flags & 4, "story file split"); + do_say_flags(i, flags & 16, "NO status"); + do_say_flags(i, flags & 32, "screen-splitting"); + do_say_flags(i, flags & 64, "variable-pitch-default"); +#Endif; + + !flags2 + @loadw 0 8 -> flags; + do_say_flags(i, flags & 1, "transcripting on"); + do_say_flags(i, flags & 2, "fixed-pitch on"); +#Ifdef V5PLUS; + ! TODO comment out v6 stuff if #version_number == 5 + do_say_flags(i, flags & 4, "redraw pending"); + do_say_flags(i, flags & 8, "using pictures"); + do_say_flags(i, flags & 16, "using undo"); + do_say_flags(i, flags & 32, "using mouse"); + do_say_flags(i, flags & 64, "using colors"); + do_say_flags(i, flags & 128, "using sound"); + do_say_flags(i, flags & 256, "using menus"); +#Endif; + } + +#Ifdef V4PLUS; + ! These are all width x height + print "^ Screen size: ", 0->33, "x", 0->32; +#Endif; +#Ifdef V5PLUS; + print "; in ", 0->38, "x", 0->39, " units: ", 0-->17, "x", 0-->18; + print "^ Default color: "; + say_color(0->45); print " on "; say_color(0->44); +#Endif; +! TODO v6 has font width/height switched + + @loadb 0 56 -> i; + if (i) { + print "^ User: "; + for(i = 56: i < 64: i++) + @loadb 0 i -> j; + @print_char j; + } +]; + +[ do_say_flags i cond text; + if((~~cond) == i) { + @print_paddr text; + print ", "; + } +]; + +#Ifdef V5PLUS; +[ say_color c; + switch(c) { + 0: print "current"; return; + 1: print "default"; return; + 2: print "black"; return; + 3: print "red"; return; + 4: print "green"; return; + 5: print "yellow"; return; + 6: print "blue"; return; + 7: print "magenta"; return; + 8: print "cyan"; return; + 9: print "white"; return; + 10: print "light grey"; return; + 11: print "medium grey"; return; + 12: print "dark grey"; return; + } + print "UNKNOWN"; +]; +#Endif; + +[ say_platform p; + switch(p) { + 1: print "DECSystem-20"; return; + 2: print "Apple IIe"; return; + 3: print "Macintosh"; return; + 4: print "Amiga"; return; + 5: print "Atari ST"; return; + 6: print "IBM PC"; return; + 7: print "Commodore 128"; return; + 8: print "Commodore 64"; return; + 9: print "Apple IIc"; return; + 10: print "Apple IIgs"; return; + 11: print "Tandy Color"; return; + } +]; + +! ---------------------------------------------------------------------- +! MAIN calls a bunch of subs. Each one runs a set of related tests. +!---------------------- MAIN + +[ Main; + + Testnum = 0; Passed = 0; Failed = 0; Print_Tests = 0; + @print "CZECH: the Comprehensive Z-machine Emulation CHecker, version "; + ! It's not entirely cool to be using print_paddr before testing. + ! So sue me. + @print_paddr TEST_VERSION; + @print "^Test numbers appear in [brackets].^"; + + pt(); + @print "^print works or you wouldn't be seeing this.^^"; + +! Standard = 0->50; +! if(0->50 || 0->51) +! print "Standard ", 0->50, ".", 0->51, " "; +! print "interpreter ", 0->30, (char) 0->31; + + ! If jumps don't work, we just give up. + + ! Now test sets of functionality. + ! Argument of 1 means SKIP tests, 0 means DON'T skip the tests + ! Note that there may be stack ops,e.g., in the arithmetic test, and + ! those won't get skipped just because you call test_stack with '1'. + ! MOST tests in earlier subs won't + ! depend on functionality tested in later subs, but simple + ! jump, stack, call, print functionality is needed for almost all tests. + test_jumps(0); @print "^"; + test_variables(0); @print "^"; + test_arithmetic(0); @print "^"; + test_logical(0); @print "^"; + test_memory(0); @print "^"; + test_subroutines(0); @print "^"; + test_objects(0); @print "^"; + test_indirect(0); @print "^"; + test_misc(0); @print "^"; + test_header(0); @print "^"; + test_print(0); @print "^"; + + print "^^Performed ", Testnum, " tests.^"; + print "Passed: ", Passed, ", Failed: ", Failed; + print ", Print tests: ", Print_Tests, "^"; + if (Passed + Failed + Print_Tests ~= Testnum) { + @print "^ERROR - Total number of tests should equal"; + @print " passed + failed + print tests!^^"; + } + print "Didn't crash: hooray!^"; + print "Last test: quit!^"; + @quit; + .bad_quit; + print "Quit didn't work!^"; + rtrue; +]; + +!! [Evin wrote that "Stock Inform has too many bugs to compile this." +!! but that seems not to be true with Inform 6.21.] + +! vim: tw=78 sw=3 diff --git a/tests/czech.z5 b/tests/czech.z5 new file mode 100644 index 0000000000000000000000000000000000000000..e323a200adfddc96532b00fc77b495589ce7c60f GIT binary patch literal 13312 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 J*8hZm{|THQ#c2Ql literal 0 HcmV?d00001 diff --git a/tests/etude.z5 b/tests/etude.z5 new file mode 100644 index 0000000000000000000000000000000000000000..9bb0e3fe3fde050afadcfa1813fa92a6c7686936 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/tests/praxix.inf b/tests/praxix.inf new file mode 100644 index 0000000..185a1c1 --- /dev/null +++ b/tests/praxix.inf @@ -0,0 +1,2375 @@ +! Praxix - a Z-Machine unit test +! by Zarf and Dannii +! Public domain, but please share your changes so we can improve the tests + +! The indirect test is Copyright (C) 2003, Amir Karger + +Constant Story "Praxix"; +Constant Headline "A Z-code interpreter unit test^"; +Release 1; + +! To compile this canonically, do "inform praxix.inf". No other +! options. + +Constant HDR_GAMERELEASE $02; ! word +Constant HDR_GAMEFLAGS $10; ! word +Constant HDR_GAMESERIAL $12; ! six ASCII characters +Constant HDR_SPECREVISION $32; ! word + +Array buffer -> 123; ! Buffer for parsing main line of input +Array parse buffer 63; ! Parse table mirroring it + +Global failures = 0; +Global total_failures = 0; + +[ Main ix; + ! deal with some compiler warnings + ix = PrintShortName; + + new_line; + Banner(); + new_line; + + LookSub(); + TestLoop(); + + print "^Goodbye.^"; +]; + +[ Keyboard; + while (true) { + print ">"; + buffer->0 = 120; + parse->0 = 15; + read buffer parse; + if (parse->1) + break; + } +]; + +[ Banner i; + if (Story ~= 0) { + #IfV5; style bold; #Endif; + print (string) Story; + #IfV5; style roman; #Endif; + } + if (Headline ~= 0) print ": ", (string) Headline; + print "Release ", (HDR_GAMERELEASE-->0) & $03ff, " / Serial number "; + for (i=0 : i<6 : i++) print (char) HDR_GAMESERIAL->i; + print " / Inform v"; inversion; + print ", compiler options "; + #Ifdef STRICT_MODE; + print "S"; + #Endif; ! STRICT_MODE + #Ifdef INFIX; + print "X"; + #Ifnot; + #Ifdef DEBUG; + print "D"; + #Endif; ! DEBUG + #Endif; ! INFIX + new_line; +]; + +[ Version; + ! Print the version number + print HDR_SPECREVISION->0, ".", HDR_SPECREVISION->1; +]; + +[ TestLoop wd paddr plen ix obj found; + while (true) { + new_line; + if (failures) { + print failures, " uncounted test failures!^^"; + failures = 0; + } + + Keyboard(); + wd = parse-->1; + + if (wd == 'quit' or 'q//') + return; + + found = nothing; + + objectloop (obj ofclass TestClass) { + paddr = obj.&name; + plen = obj.#name / WORDSIZE; + for (ix=0 : ixix == wd) { + found = obj; + break; + } + } + if (found) + break; + } + + if (~~found) { + print "I don't understand that command.^"; + continue; + } + + found.testfunc(); + } +]; + +Attribute meta; + +Class TestClass + with + short_name 0, + testfunc TestNothing, + fail_count; + +[ PrintShortName obj addr; + if (obj provides short_name && obj.short_name) { + print (string) obj.short_name; + rtrue; + } + if (obj ofclass TestClass) { + addr = obj.&name; + print (address) (addr-->0); + rtrue; + } + print (object) obj; +]; + +! Print out in base 16 a byte or word +[ Hex val byte nibble i; + print "$"; + for (i=0 : i<2 : i++) + { + @log_shift val (-8) -> byte; + @log_shift val (8) -> val; + if (byte == 0 && i == 0) + continue; + nibble = byte & $0F; + @log_shift byte (-4) -> byte; + if (byte <= 9) + print (char) (byte+'0'); + else + print (char) (byte-10+'A'); + if (nibble <= 9) + print (char) (nibble+'0'); + else + print (char) (nibble-10+'A'); + } +]; + +[ check val wanted; + if (val == wanted) { + print val; + rtrue; + } + failures++; + print val, " (should be ", wanted, " FAIL)"; + rfalse; +]; + +[ check_unspecified val wanted; + if (val == wanted) { + print val, " (Unspecified)"; + rtrue; + } + print val, " (Unspecified but ", wanted, " is suggested)"; + rfalse; +]; + +[ check_hex val wanted; + if (val == wanted) { + print (Hex) val; + rtrue; + } + failures++; + print (Hex) val, " (should be ", (Hex) wanted, " FAIL)"; + rfalse; +]; + +[ check_hex_unspecified val wanted; + if (val == wanted) { + print (Hex) val, " (Unspecified)"; + rtrue; + } + print (Hex) val, " (Unspecified but ", wanted, " is suggested)"; + rfalse; +]; + +[ check_hex_min val min; + if (val >= min) { + print (Hex) val; + rtrue; + } + failures++; + print (Hex) val, " (should be >= ", (Hex) min, " FAIL)"; + rfalse; +]; + +[ count_failures val; + print "^"; + if (failures) { + val = failures; + total_failures = total_failures + failures; + failures = 0; + print_ret val, " tests failed."; + } + else { + "Passed."; + } +]; + +TestClass LookAction + with name 'look' 'l//' 'help' '?//', + testfunc LookSub, + has meta; + +TestClass AllAction + with name 'all', + testfunc [ obj startfail res ix; + print "All tests:^"; + startfail = total_failures; + objectloop (obj ofclass TestClass) { + if (obj has meta) + continue; + + res = total_failures; + print "^"; + obj.testfunc(); + obj.fail_count = total_failures - res; + } + res = total_failures - startfail; + if (res == 0) { + "^All tests passed."; + } + else { + print "^", res, " tests failed overall: "; + ix = 0; + objectloop (obj ofclass TestClass) { + if (obj.fail_count) { + if (ix) + print ", "; + print (name) obj, " (", obj.fail_count, ")"; + ix++; + } + } + "."; + } + ], + has meta; + +[ TestNothing; + "Nothing happens."; +]; + +[ LookSub obj ix; + print "A voice booooms out: Welcome to the test chamber.^^"; + print "Type ~help~ to repeat this message, ~quit~ to exit, + ~all~ to run all tests, or one of the following test options: "; + + ix = 0; + objectloop (obj ofclass TestClass) { + if (obj has meta) + continue; + if (ix) print ", "; + print "~", (name) obj, "~"; + ix++; + } + print "."; + new_line; + if (total_failures) { + print "^", total_failures, " tests have failed so far in this run.^"; + } +]; + +Global testglobal; +Global testglobal2; + +TestClass OperandTest + with name 'operand', + testfunc [ ix val; + print "Basic operand values:^^"; + + testglobal = 1; + ix = 1; + val = (ix == testglobal); + print "(1==1)="; check(val, 1); print ", "; + val = (1 == testglobal); + print "(1==1)="; check(val, 1); print ", "; + val = (1 == ix); + print "(1==1)="; check(val, 1); print ", "; + @push 1; + val = 1; + @je 1 sp ?jump1; + val = 0; + .jump1; + print "(1==1)="; check(val, 1); print "^"; + + testglobal = -2; + ix = -2; + val = (ix == testglobal); + print "(-2==-2)="; check(val, 1); print ", "; + val = (-2 == testglobal); + print "(-2==-2)="; check(val, 1); print ", "; + val = (-2 == ix); + print "(-2==-2)="; check(val, 1); print ", "; + @push (-2); + val = 1; + @je (-2) sp ?jump2; + val = 0; + .jump2; + print "(-2==-2)="; check(val, 1); print "^"; + + count_failures(); + ]; + + +TestClass ArithTest + with name 'arith', + testfunc [ val; + print "Integer arithmetic:^^"; + + @add 2 2 val; + print "2+2="; check(val, 4); print ", "; + @add (-2) (-3) val; + print "-2+-3="; check(val, -5); print ", "; + @add 3 (-4) val; + print "3+-4="; check(val, -1); print ", "; + @add (-4) 5 val; + print "-4+5="; check(val, 1); print ", "; + @add $7FFF $7FFE val; + print "$7FFF+$7FFE="; check(val, -3); print ", "; + @add $8000 $8000 val; + print "$8000+$8000="; check(val, 0); print "^"; + testglobal = 6; testglobal2 = 8; + @add testglobal testglobal2 val; + print "Globals 6+8="; check(val, 14); print ", "; + testglobal = $7FFE; testglobal2 = $7FFD; + @add testglobal testglobal2 val; + print "$7FFE+$7FFD="; check(val, -5); print "^"; + + @sub 2 2 val; + print "2-2="; check(val, 0); print ", "; + @sub (-2) 3 val; + print "-2-3="; check(val, -5); print ", "; + @sub 3 4 val; + print "3-4="; check(val, -1); print ", "; + @sub (-4) (-5) val; + print "-4-(-5)="; check(val, 1); print ", "; + @sub $7FFF $7FFE val; + print "$7FFF-$7FFE="; check(val, 1); print ", "; + @sub $8000 $8001 val; + print "$8000-$8001="; check(val, -1); print ", "; + @sub $7FFF $8001 val; + print "$7FFF-$8001="; check(val, -2); print "^"; + testglobal = 6; testglobal2 = 8; + @sub testglobal testglobal2 val; + print "Globals 6-8="; check(val, -2); print ", "; + testglobal = $7FFD; testglobal2 = $7FFE; + @sub testglobal testglobal2 val; + print "$7FFD-$7FFE="; check(val, -1); print "^"; + + @mul 2 2 val; + print "2*2="; check(val, 4); print ", "; + @mul (-2) (-3) val; + print "-2*-3="; check(val, 6); print ", "; + @mul 3 (-4) val; + print "3*-4="; check(val, -12); print ", "; + @mul (-4) 5 val; + print "-4*5="; check(val, -20); print ", "; + @mul $100 $100 val; + print "$100*$100 (trunc)="; check(val, 0); print ", "; + @mul 311 373 val; + print "311*373 (trunc)="; check_hex(val, -15069); print "^"; + testglobal = -6; testglobal2 = -8; + @mul testglobal testglobal2 val; + print "Globals -6*-8="; check(val, 48); print ", "; + testglobal = -311; testglobal2 = 373; + @mul testglobal testglobal2 val; + print "Globals -311*373="; check(val, 15069); print "^"; + + @div 12 3 val; + print "12/3="; check(val, 4); print ", "; + @div 11 2 val; + print "11/2="; check(val, 5); print ", "; + @div (-11) 2 val; + print "-11/2="; check(val, -5); print ", "; + @div 11 (-2) val; + print "11/-2="; check(val, -5); print ", "; + @div (-11) (-2) val; + print "-11/-2="; check(val, 5); print ", "; + @div $7fff 2 val; + print "$7fff/2="; check_hex(val, $3fff); print ", "; + @div $7fff (-2) val; + print "$7fff/-2="; check_hex(val, -$3fff); print ", "; + @div (-$7fff) 2 val; + print "-$7fff/2="; check_hex(val, -$3fff); print ", "; + @div (-$7fff) (-2) val; + print "-$7fff/-2="; check_hex(val, $3fff); print ", "; + @div $8000 2 val; + print "$8000/2="; check_hex(val, $C000); print ", "; + @div $8000 (-2) val; + print "$8000/(-2)="; check_hex(val, $4000); print ", "; + @div $8000 1 val; + print "$8000/1="; check_hex(val, $8000); print "^"; + + testglobal = -48; testglobal2 = -8; + @div testglobal testglobal2 val; + print "Globals -48/-8="; check(val, 6); print ", "; + testglobal = 48; testglobal2 = 7; + @div testglobal testglobal2 val; + print "48/7="; check(val, 6); print ", "; + testglobal = 48; testglobal2 = -7; + @div testglobal testglobal2 val; + print "48/-7="; check(val, -6); print ", "; + testglobal = -48; testglobal2 = 7; + @div testglobal testglobal2 val; + print "-48/7="; check(val, -6); print ", "; + testglobal = -48; testglobal2 = -7; + @div testglobal testglobal2 val; + print "-48/-7="; check(val, 6); print "^"; + + @mod 12 3 val; + print "12%3="; check(val, 0); print ", "; + @mod 13 5 val; + print "13%5="; check(val, 3); print ", "; + @mod (-13) 5 val; + print "-13%5="; check(val, -3); print ", "; + @mod 13 (-5) val; + print "13%-5="; check(val, 3); print ", "; + @mod (-13) (-5) val; + print "-13%-5="; check(val, -3); print ", "; + @mod $7fff 11 val; + print "$7fff%11="; check(val, 9); print ", "; + @mod (-$7fff) 11 val; + print "-$7fff%11="; check(val, -9); print ", "; + @mod $7fff (-11) val; + print "$7fff%-11="; check(val, 9); print ", "; + @mod (-$7fff) (-11) val; + print "-$7fff%-11="; check(val, -9); print ", "; + @mod $8000 7 val; + print "$8000%7="; check(val, -1); print ", "; + @mod $8000 (-7) val; + print "$8000%-7="; check(val, -1); print ", "; + @mod $8000 2 val; + print "$8000%2="; check(val, 0); print ", "; + @mod $8000 (-2) val; + print "$8000%-2="; check(val, 0); print ", "; + @mod $8000 1 val; + print "$8000%1="; check(val, 0); print "^"; + + testglobal = 49; testglobal2 = 8; + @mod testglobal testglobal2 val; + print "Globals 49%8="; check(val, 1); print ", "; + testglobal = 49; testglobal2 = -8; + @mod testglobal testglobal2 val; + print "49%-8="; check(val, 1); print ", "; + testglobal = -49; testglobal2 = 8; + @mod testglobal testglobal2 val; + print "-49%8="; check(val, -1); print ", "; + testglobal = -49; testglobal2 = -8; + @mod testglobal testglobal2 val; + print "-49%-8="; check(val, -1); print "^"; + + count_failures(); + ]; + +TestClass CompoundArithTest + with name 'comarith' 'comparith', + testfunc [ val xloc yloc zloc; + print "Compound arithmetic expressions:^^"; + + testglobal = 7; + yloc = 2; + zloc = -4; + val = (testglobal + yloc) * zloc; + print "(7+2)*-4="; check(val, -36); print "^"; + + xloc = $7FFF; + yloc = 2; + zloc = 16; + val = (xloc + yloc) / zloc; + print "($7FFF+2)/16="; check(val, -$7FF); print "^"; + + xloc = -$7FFF; + yloc = -2; + zloc = 16; + val = (xloc + yloc) / zloc; + print "(-$7FFF+-2)/16="; check(val, $7FF); print "^"; + + xloc = -26103; + yloc = -32647; + val = (xloc + yloc) / 9; + print "(-26103+-32647)/9="; check(val, 754); print "^"; + + xloc = -$7FFF; + yloc = 2; + zloc = 16; + val = (xloc - yloc) / zloc; + print "(-$7FFF-2)/16="; check(val, $7FF); print "^"; + + xloc = $7FFF; + yloc = -2; + zloc = 16; + val = (xloc - yloc) / zloc; + print "($7FFF--2)/16="; check(val, -$7FF); print "^"; + + xloc = -26103; + yloc = 32647; + val = (xloc - yloc) / 9; + print "(-26103-32647)/9="; check(val, 754); print "^"; + + xloc = $100; + yloc = $100; + zloc = 16; + val = (xloc * yloc) / zloc + 1; + print "($100*$100)/16+1="; check(val, 1); print "^"; + + xloc = 311; + yloc = 373; + zloc = 16; + val = (xloc * yloc) / zloc; + print "(311*373)/16="; check(val, -941); print "^"; + + xloc = 311; + zloc = 16; + val = (xloc * -373) / zloc; + print "(311*-373)/16="; check(val, 941); print "^"; + + yloc = 373; + val = (111 * yloc) / 16; + print "(111*373)/16="; check(val, -1508); print "^"; + + yloc = -373; + val = (111 * yloc) / 16; + print "(111*-373)/16="; check(val, 1508); print "^"; + + count_failures(); + ]; + +TestClass BitwiseTest + with name 'bitwise' 'bits' 'bit', + testfunc [ val; + print "Bitwise arithmetic:^^"; + + @and 0 0 val; + print "0&0="; check_hex(val, 0); print ", "; + @and $FFFF 0 val; + print "$FFFF&0="; check_hex(val, 0); print ", "; + @and $FFFF $FFFF val; + print "$FFFF&$FFFF="; check_hex(val, $FFFF); print ", "; + @and $013F $F310 val; + print "$013F&$F310="; check_hex(val, $0110); print ", "; + @and $F731 $137F val; + print "$F731&$137F="; check_hex(val, $1331); print ", "; + @and $35 $56 val; + print "$35&56="; check_hex(val, $14); print "^"; + + @or 0 0 val; + print "0|0="; check_hex(val, 0); print ", "; + @or $FFFF 0 val; + print "$FFFF|0="; check_hex(val, $FFFF); print ", "; + @or $FFFF $FFFF val; + print "$FFFF|$FFFF="; check_hex(val, $FFFF); print ", "; + @or $3700 $0012 val; + print "$3700|$0012="; check_hex(val, $3712); print ", "; + @or $35 $56 val; + print "$35|56="; check_hex(val, $77); print "^"; + + @not 0 val; + print "!0="; check_hex(val, $FFFF); print ", "; + @not 1 val; + print "!1="; check_hex(val, $FFFE); print ", "; + @not $F val; + print "!$F="; check_hex(val, $FFF0); print ", "; + @not $7FFF val; + print "!$7FFF="; check_hex(val, $8000); print ", "; + @not $8000 val; + print "!$8000="; check_hex(val, $7FFF); print ", "; + @not $FFFD val; + print "!$FFFD="; check_hex(val, $2); print "^"; + + count_failures(); + ]; + +TestClass ShiftTest + with name 'shift', + testfunc [ val res ix; + print "Bit shifts:^^"; + + @log_shift $11 0 val; + print "$11u<<0="; check_hex(val, $11); print ", "; + @log_shift $11 1 val; + print "$11u<<1="; check_hex(val, $22); print ", "; + @log_shift $11 4 val; + print "$11u<<4="; check_hex(val, $110); print ", "; + @log_shift $11 10 val; + print "$11u<<10="; check_hex(val, $4400); print ", "; + @log_shift $11 15 val; + print "$11u<<15="; check_hex(val, $8000); print ", "; + @log_shift $11 16 val; + print "$11u<<16="; check_hex_unspecified(val, 0); print ", "; + @log_shift (-2) 0 val; + print "-2u<<0="; check(val, -2); print ", "; + @log_shift (-2) 1 val; + print "-2u<<1="; check(val, -4); print ", "; + @log_shift (-2) 7 val; + print "-2u<<7="; check(val, -256); print ", "; + @log_shift (-2) 15 val; + print "-2u<<15="; check(val, 0); print "^"; + + testglobal = 1; + res = 1; + for (ix=0 : ix<16 : ix++) { + @log_shift testglobal ix val; + print "1u<<", ix, "="; check_hex(val, res); print ", "; + res = res+res; + } + @log_shift testglobal ix val; + print "1u<<", ix, "="; check_hex_unspecified(val, 0); print "^"; + + @log_shift $4001 (0) val; + print "$4001u>>-0="; check_hex(val, $4001); print ", "; + @log_shift $4001 (-1) val; + print "$4001u>>-1="; check_hex(val, $2000); print ", "; + @log_shift $4001 (-6) val; + print "$4001u>>-6="; check_hex(val, $100); print ", "; + @log_shift $4001 (-11) val; + print "$4001u>>-11="; check_hex(val, $8); print ", "; + @log_shift $4001 (-15) val; + print "$4001u>>-15="; check_hex(val, $0); print ", "; + @log_shift $4001 (-16) val; + print "$4001u>>-16="; check_hex_unspecified(val, $0); print "^"; + + @log_shift $7FFF (0) val; + print "$7FFFu>>-0="; check_hex(val, $7FFF); print ", "; + @log_shift $7FFF (-1) val; + print "$7FFFu>>-1="; check_hex(val, $3FFF); print ", "; + @log_shift $7FFF (-2) val; + print "$7FFFu>>-2="; check_hex(val, $1FFF); print ", "; + @log_shift $7FFF (-6) val; + print "$7FFFu>>-6="; check_hex(val, $1FF); print ", "; + @log_shift $7FFF (-12) val; + print "$7FFFu>>-12="; check_hex(val, $7); print ", "; + @log_shift $7FFF (-15) val; + print "$7FFFu>>-15="; check_hex(val, $0); print ", "; + @log_shift $7FFF (-16) val; + print "$7FFFu>>-16="; check_hex_unspecified(val, $0); print "^"; + + @log_shift (-1) (0) val; + print "-1u>>-0="; check_hex(val, -1); print ", "; + @log_shift (-1) (-1) val; + print "-1u>>-1="; check_hex(val, $7FFF); print ", "; + @log_shift (-1) (-2) val; + print "-1u>>-2="; check_hex(val, $3FFF); print ", "; + @log_shift (-1) (-6) val; + print "-1u>>-6="; check_hex(val, $3FF); print ", "; + @log_shift (-1) (-12) val; + print "-1u>>-12="; check_hex(val, $F); print ", "; + @log_shift (-1) (-13) val; + print "-1u>>-13="; check_hex(val, $7); print ", "; + @log_shift (-1) (-15) val; + print "-1u>>-15="; check_hex(val, $1); print ", "; + @log_shift (-1) (-16) val; + print "-1u>>-16="; check_hex_unspecified(val, $0); print ", "; + @log_shift (-1) (-17) val; + print "-1u>>-17="; check_hex_unspecified(val, $0); print "^"; + + testglobal = -1; + res = $7fff; + for (ix=-1 : ix>-16 : ix--) { + @log_shift testglobal ix val; + print "-1u>>", ix, "="; check_hex(val, res); print ", "; + res = res / 2; + } + @log_shift testglobal ix val; + print "-1u>>", ix, "="; check_hex_unspecified(val, 0); print "^"; + + @art_shift $11 0 val; + print "$11s<<0="; check_hex(val, $11); print ", "; + @art_shift $11 1 val; + print "$11s<<1="; check_hex(val, $22); print ", "; + @art_shift $11 4 val; + print "$11s<<4="; check_hex(val, $110); print ", "; + @art_shift $11 10 val; + print "$11s<<10="; check_hex(val, $4400); print ", "; + @art_shift $11 15 val; + print "$11s<<15="; check_hex(val, $8000); print ", "; + @art_shift $11 16 val; + print "$11s<<16="; check_hex_unspecified(val, 0); print ", "; + @art_shift (-2) 0 val; + print "-2s<<0="; check(val, -2); print ", "; + @art_shift (-2) 1 val; + print "-2s<<1="; check(val, -4); print ", "; + @art_shift (-2) 7 val; + print "-2s<<7="; check(val, -256); print ", "; + @art_shift (-2) 15 val; + print "-2s<<15="; check(val, 0); print "^"; + + testglobal = 1; + res = 1; + for (ix=0 : ix<16 : ix++) { + @art_shift testglobal ix val; + print "1s<<", ix, "="; check_hex(val, res); print ", "; + res = res+res; + } + @art_shift testglobal ix val; + print "1s<<", ix, "="; check_hex_unspecified(val, 0); print "^"; + + @art_shift $4001 (0) val; + print "$4001s>>-0="; check_hex(val, $4001); print ", "; + @art_shift $4001 (-1) val; + print "$4001s>>-1="; check_hex(val, $2000); print ", "; + @art_shift $4001 (-6) val; + print "$4001s>>-6="; check_hex(val, $100); print ", "; + @art_shift $4001 (-11) val; + print "$4001s>>-11="; check_hex(val, $8); print ", "; + @art_shift $4001 (-15) val; + print "$4001s>>-15="; check_hex(val, $0); print ", "; + @art_shift $4001 (-16) val; + print "$4001s>>-16="; check_hex_unspecified(val, $0); print "^"; + + @art_shift $7FFF (0) val; + print "$7FFFs>>-0="; check_hex(val, $7FFF); print ", "; + @art_shift $7FFF (-1) val; + print "$7FFFs>>-1="; check_hex(val, $3FFF); print ", "; + @art_shift $7FFF (-2) val; + print "$7FFFs>>-2="; check_hex(val, $1FFF); print ", "; + @art_shift $7FFF (-6) val; + print "$7FFFs>>-6="; check_hex(val, $1FF); print ", "; + @art_shift $7FFF (-12) val; + print "$7FFFs>>-12="; check_hex(val, $7); print ", "; + @art_shift $7FFF (-13) val; + print "$7FFFs>>-13="; check_hex(val, $3); print ", "; + @art_shift $7FFF (-14) val; + print "$7FFFs>>-14="; check_hex(val, $1); print ", "; + @art_shift $7FFF (-15) val; + print "$7FFFs>>-15="; check_hex(val, $0); print ", "; + @art_shift $7FFF (-16) val; + print "$7FFFs>>-16="; check_hex_unspecified(val, $0); print "^"; + + @art_shift (-1) (0) val; + print "-1s>>-0="; check(val, -1); print ", "; + @art_shift (-1) (-1) val; + print "-1s>>-1="; check(val, -1); print ", "; + @art_shift (-1) (-15) val; + print "-1s>>-15="; check(val, -1); print ", "; + @art_shift (-1) (-16) val; + print "-1s>>-16="; check_hex_unspecified(val, -1); print ", "; + @art_shift (-1) (-17) val; + print "-1s>>-17="; check_hex_unspecified(val, -1); print "^"; + + @art_shift (-1000) (0) val; + print "-1000s>>-0="; check(val, -1000); print ", "; + @art_shift (-1000) (-1) val; + print "-1000s>>-1="; check(val, -500); print ", "; + @art_shift (-1000) (-2) val; + print "-1000s>>-2="; check(val, -250); print ", "; + @art_shift (-1000) (-4) val; + print "-1000s>>-4="; check(val, -63); print ", "; + @art_shift (-1000) (-6) val; + print "-1000s>>-6="; check(val, -16); print ", "; + @art_shift (-1000) (-9) val; + print "-1000s>>-9="; check(val, -2); print ", "; + @art_shift (-1000) (-15) val; + print "-1000s>>-15="; check(val, -1); print ", "; + @art_shift (-1000) (-16) val; + print "-1000s>>-16="; check_hex_unspecified(val, -1); print ", "; + @art_shift (-1000) (-17) val; + print "-1000s>>-17="; check_hex_unspecified(val, -1); print "^"; + + testglobal = -1; + for (ix=0 : ix>-16 : ix--) { + @art_shift testglobal ix val; + print "-1s>>", ix, "="; check(val, -1); print ", "; + } + @art_shift testglobal ix val; + print "-1s>>", ix, "="; check_hex_unspecified(val, -1); print "^"; + + count_failures(); + ]; + +TestClass IncrementTest + with name 'inc' 'dec' 'increment' 'decrement', + testfunc [ val; + print "Increment/decrement:^^"; + + val = 0; + @inc val; + print "0++="; check(val, 1); print ", "; + val = 1; + @inc val; + print "1++="; check(val, 2); print ", "; + val = -1; + @inc val; + print "-1++="; check(val, 0); print ", "; + val = -10; + @inc val; + print "-10++="; check(val, -9); print ", "; + val = $7FFF; + @inc val; + print "$7FFF++="; check_hex(val, $8000); print ", "; + val = $C000; + @inc val; + print "$C000++="; check_hex(val, $C001); print "^"; + + testglobal = 0; + @inc testglobal; + print "0++="; check(testglobal, 1); print ", "; + testglobal = 1; + @inc testglobal; + print "1++="; check(testglobal, 2); print ", "; + testglobal = -1; + @inc testglobal; + print "-1++="; check(testglobal, 0); print ", "; + testglobal = -10; + @inc testglobal; + print "-10++="; check(testglobal, -9); print ", "; + testglobal = $7FFF; + @inc testglobal; + print "$7FFF++="; check_hex(testglobal, $8000); print ", "; + testglobal = $C000; + @inc testglobal; + print "$C000++="; check_hex(testglobal, $C001); print "^"; + + @push 0; + @inc sp; + @pull val; + print "0++="; check(val, 1); print ", "; + @push 1; + @inc sp; + @pull val; + print "1++="; check(val, 2); print ", "; + @push -1; + @inc sp; + @pull val; + print "-1++="; check(val, 0); print ", "; + @push -10; + @inc sp; + @pull val; + print "-10++="; check(val, -9); print ", "; + @push $7FFF; + @inc sp; + @pull val; + print "$7FFF++="; check_hex(val, $8000); print ", "; + @push $C000; + @inc sp; + @pull val; + print "$C000++="; check_hex(val, $C001); print "^"; + + val = 0; + @dec val; + print "0--="; check(val, -1); print ", "; + val = 1; + @dec val; + print "1--="; check(val, 0); print ", "; + val = -1; + @dec val; + print "-1--="; check(val, -2); print ", "; + val = 10; + @dec val; + print "10--="; check(val, 9); print ", "; + val = $8000; + @dec val; + print "$8000--="; check_hex(val, $7FFF); print ", "; + val = $C000; + @dec val; + print "$C000--="; check_hex(val, $BFFF); print "^"; + + testglobal = 0; + @dec testglobal; + print "0--="; check(testglobal, -1); print ", "; + testglobal = 1; + @dec testglobal; + print "1--="; check(testglobal, 0); print ", "; + testglobal = -1; + @dec testglobal; + print "-1--="; check(testglobal, -2); print ", "; + testglobal = 10; + @dec testglobal; + print "10--="; check(testglobal, 9); print ", "; + testglobal = $8000; + @dec testglobal; + print "$8000--="; check_hex(testglobal, $7FFF); print ", "; + testglobal = $C000; + @dec testglobal; + print "$C000--="; check_hex(testglobal, $BFFF); print "^"; + + @push 0; + @dec sp; + @pull val; + print "0--="; check(val, -1); print ", "; + @push 1; + @dec sp; + @pull val; + print "1--="; check(val, 0); print ", "; + @push -1; + @dec sp; + @pull val; + print "-1--="; check(val, -2); print ", "; + @push 10; + @dec sp; + @pull val; + print "10--="; check(val, 9); print ", "; + @push $8000; + @dec sp; + @pull val; + print "$8000--="; check_hex(val, $7FFF); print ", "; + @push $C000; + @dec sp; + @pull val; + print "$C000--="; check_hex(val, $BFFF); print "^"; + + count_failures(); + ]; + +TestClass IncrementBranchTest + with name 'incchk' 'decchk' 'inccheck' 'deccheck', + testfunc [ val res; + print "Increment/decrement and branch:^^"; + + res = 0; + val = 1; + @inc_chk res 0 ?jump1a; + val = 0; + .jump1a; + print "++0="; check(res, 1); print ","; check(val, 1); print ", "; + + res = 1; + val = 1; + @inc_chk res 0 ?jump1b; + val = 0; + .jump1b; + print "++1="; check(res, 2); print ","; check(val, 1); print ", "; + + res = -1; + val = 1; + @inc_chk res 0 ?jump1c; + val = 0; + .jump1c; + print "++-1="; check(res, 0); print ","; check(val, 0); print ", "; + + res = 100; + val = 1; + @inc_chk res 0 ?jump1d; + val = 0; + .jump1d; + print "++100="; check(res, 101); print ","; check(val, 1); print ", "; + + res = -10; + val = 1; + @inc_chk res 0 ?jump1e; + val = 0; + .jump1e; + print "++-10="; check(res, -9); print ","; check(val, 0); print ", "; + + res = $7FFF; + val = 1; + @inc_chk res 0 ?jump1f; + val = 0; + .jump1f; + print "++$7FFF="; check_hex(res, $8000); print ","; check(val, 0); print ", "; + + res = $C000; + val = 1; + @inc_chk res 0 ?jump1g; + val = 0; + .jump1g; + print "++$C000="; check_hex(res, $C001); print ","; check(val, 0); print "^"; + + + testglobal2 = 0; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2a; + testglobal = 0; + .jump2a; + print "++0="; check(testglobal2, 1); print ","; check(testglobal, 1); print ", "; + + testglobal2 = 1; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2b; + testglobal = 0; + .jump2b; + print "++1="; check(testglobal2, 2); print ","; check(testglobal, 1); print ", "; + + testglobal2 = -1; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2c; + testglobal = 0; + .jump2c; + print "++-1="; check(testglobal2, 0); print ","; check(testglobal, 0); print ", "; + + testglobal2 = 100; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2d; + testglobal = 0; + .jump2d; + print "++100="; check(testglobal2, 101); print ","; check(testglobal, 1); print ", "; + + testglobal2 = -10; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2e; + testglobal = 0; + .jump2e; + print "++-10="; check(testglobal2, -9); print ","; check(testglobal, 0); print ", "; + + testglobal2 = $7FFF; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2f; + testglobal = 0; + .jump2f; + print "++$7FFF="; check_hex(testglobal2, $8000); print ","; check(testglobal, 0); print ", "; + + testglobal2 = $C000; + testglobal = 1; + @inc_chk testglobal2 0 ?jump2g; + testglobal = 0; + .jump2g; + print "++$C000="; check_hex(testglobal2, $C001); print ","; check(testglobal, 0); print "^"; + + + @push 0; + val = 1; + @inc_chk sp 0 ?jump3a; + val = 0; + .jump3a; + @pull res; + print "++0="; check(res, 1); print ","; check(val, 1); print ", "; + + @push 1; + val = 1; + @inc_chk sp 0 ?jump3b; + val = 0; + .jump3b; + @pull res; + print "++1="; check(res, 2); print ","; check(val, 1); print ", "; + + @push -1; + val = 1; + @inc_chk sp 0 ?jump3c; + val = 0; + .jump3c; + @pull res; + print "++-1="; check(res, 0); print ","; check(val, 0); print ", "; + + @push 100; + val = 1; + @inc_chk sp 0 ?jump3d; + val = 0; + .jump3d; + @pull res; + print "++100="; check(res, 101); print ","; check(val, 1); print ", "; + + @push -10; + val = 1; + @inc_chk sp 0 ?jump3e; + val = 0; + .jump3e; + @pull res; + print "++-10="; check(res, -9); print ","; check(val, 0); print ", "; + + @push $7FFF; + val = 1; + @inc_chk sp 0 ?jump3f; + val = 0; + .jump3f; + @pull res; + print "++$7FFF="; check_hex(res, $8000); print ","; check(val, 0); print ", "; + + @push $C000; + val = 1; + @inc_chk sp 0 ?jump3g; + val = 0; + .jump3g; + @pull res; + print "++$C000="; check_hex(res, $C001); print ","; check(val, 0); print "^"; + + + res = 0; + val = 1; + @dec_chk res 0 ?jump4a; + val = 0; + .jump4a; + print "--0="; check(res, -1); print ","; check(val, 1); print ", "; + + res = 1; + val = 1; + @dec_chk res 0 ?jump4b; + val = 0; + .jump4b; + print "--1="; check(res, 0); print ","; check(val, 0); print ", "; + + res = -1; + val = 1; + @dec_chk res 0 ?jump4c; + val = 0; + .jump4c; + print "---1="; check(res, -2); print ","; check(val, 1); print ", "; + + res = 100; + val = 1; + @dec_chk res 0 ?jump4d; + val = 0; + .jump4d; + print "--100="; check(res, 99); print ","; check(val, 0); print ", "; + + res = -10; + val = 1; + @dec_chk res 0 ?jump4e; + val = 0; + .jump4e; + print "---10="; check(res, -11); print ","; check(val, 1); print ", "; + + res = $8000; + val = 1; + @dec_chk res 0 ?jump4f; + val = 0; + .jump4f; + print "--$8000="; check_hex(res, $7FFF); print ","; check(val, 0); print ", "; + + res = $C000; + val = 1; + @dec_chk res 0 ?jump4g; + val = 0; + .jump4g; + print "--$C000="; check_hex(res, $BFFF); print ","; check(val, 1); print "^"; + + + testglobal2 = 0; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5a; + testglobal = 0; + .jump5a; + print "--0="; check(testglobal2, -1); print ","; check(testglobal, 1); print ", "; + + testglobal2 = 1; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5b; + testglobal = 0; + .jump5b; + print "--1="; check(testglobal2, 0); print ","; check(testglobal, 0); print ", "; + + testglobal2 = -1; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5c; + testglobal = 0; + .jump5c; + print "---1="; check(testglobal2, -2); print ","; check(testglobal, 1); print ", "; + + testglobal2 = 100; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5d; + testglobal = 0; + .jump5d; + print "--100="; check(testglobal2, 99); print ","; check(testglobal, 0); print ", "; + + testglobal2 = -10; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5e; + testglobal = 0; + .jump5e; + print "---10="; check(testglobal2, -11); print ","; check(testglobal, 1); print ", "; + + testglobal2 = $8000; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5f; + testglobal = 0; + .jump5f; + print "--$8000="; check_hex(testglobal2, $7FFF); print ","; check(testglobal, 0); print ", "; + + testglobal2 = $C000; + testglobal = 1; + @dec_chk testglobal2 0 ?jump5g; + testglobal = 0; + .jump5g; + print "--$C000="; check_hex(testglobal2, $BFFF); print ","; check(testglobal, 1); print "^"; + + + @push 0; + val = 1; + @dec_chk sp 0 ?jump6a; + val = 0; + .jump6a; + @pull res; + print "--0="; check(res, -1); print ","; check(val, 1); print ", "; + + @push 1; + val = 1; + @dec_chk sp 0 ?jump6b; + val = 0; + .jump6b; + @pull res; + print "--1="; check(res, 0); print ","; check(val, 0); print ", "; + + @push -1; + val = 1; + @dec_chk sp 0 ?jump6c; + val = 0; + .jump6c; + @pull res; + print "---1="; check(res, -2); print ","; check(val, 1); print ", "; + + @push 100; + val = 1; + @dec_chk sp 0 ?jump6d; + val = 0; + .jump6d; + @pull res; + print "--100="; check(res, 99); print ","; check(val, 0); print ", "; + + @push -10; + val = 1; + @dec_chk sp 0 ?jump6e; + val = 0; + .jump6e; + @pull res; + print "---10="; check(res, -11); print ","; check(val, 1); print ", "; + + @push $8000; + val = 1; + @dec_chk sp 0 ?jump6f; + val = 0; + .jump6f; + @pull res; + print "--$8000="; check_hex(res, $7FFF); print ","; check(val, 0); print ", "; + + @push $C000; + val = 1; + @dec_chk sp 0 ?jump6g; + val = 0; + .jump6g; + @pull res; + print "--$C000="; check_hex(res, $BFFF); print ","; check(val, 1); print "^"; + + + res = 50; + val = 1; + @inc_chk res 60 ?jumpxa; + val = 0; + .jumpxa; + print "++50="; check(res, 51); print ","; check(val, 0); print ", "; + + res = 70; + val = 1; + @inc_chk res 60 ?jumpxb; + val = 0; + .jumpxb; + print "++70="; check(res, 71); print ","; check(val, 1); print ", "; + + res = -50; + val = 1; + @inc_chk res (-60) ?jumpxc; + val = 0; + .jumpxc; + print "++-50="; check(res, -49); print ","; check(val, 1); print ", "; + + res = -70; + val = 1; + @inc_chk res (-60) ?jumpxd; + val = 0; + .jumpxd; + print "++-70="; check(res, -69); print ","; check(val, 0); print ", "; + + res = -50; + val = 1; + @inc_chk res 60 ?jumpxe; + val = 0; + .jumpxe; + print "++-50="; check(res, -49); print ","; check(val, 0); print ", "; + + res = 50; + val = 1; + @inc_chk res (-60) ?jumpxf; + val = 0; + .jumpxf; + print "++50="; check(res, 51); print ","; check(val, 1); print "^"; + + + res = 50; + val = 1; + @dec_chk res 60 ?jumpya; + val = 0; + .jumpya; + print "--50="; check(res, 49); print ","; check(val, 1); print ", "; + + res = 70; + val = 1; + @dec_chk res 60 ?jumpyb; + val = 0; + .jumpyb; + print "--70="; check(res, 69); print ","; check(val, 0); print ", "; + + res = -50; + val = 1; + @dec_chk res (-60) ?jumpyc; + val = 0; + .jumpyc; + print "---50="; check(res, -51); print ","; check(val, 0); print ", "; + + res = -70; + val = 1; + @dec_chk res (-60) ?jumpyd; + val = 0; + .jumpyd; + print "---70="; check(res, -71); print ","; check(val, 1); print ", "; + + res = -50; + val = 1; + @dec_chk res 60 ?jumpye; + val = 0; + .jumpye; + print "---50="; check(res, -51); print ","; check(val, 1); print ", "; + + res = 50; + val = 1; + @dec_chk res (-60) ?jumpyf; + val = 0; + .jumpyf; + print "--50="; check(res, 49); print ","; check(val, 0); print "^"; + + + count_failures(); + ]; + +Array array1 --> $1357 $FDB9 $0011 $FFEE; +Array array2 --> 4; + +TestClass ArrayTest + with name 'array' 'loadw' 'loadb' 'storew' 'storeb', + testfunc [ val ix addr; + print "Array loads and stores:^^"; + + addr = array1; + @loadw array1 0 -> val; + print "a-->0="; check_hex(val, $1357); print ", "; + @loadw addr 0 -> val; + print "a-->0="; check_hex(val, $1357); print ", "; + + ix = 1; + @loadw array1 ix -> val; + print "a-->1="; check_hex(val, $FDB9); print ", "; + @loadw addr ix -> val; + print "a-->1="; check_hex(val, $FDB9); print ", "; + + testglobal = 2; + @loadw array1 testglobal -> val; + print "a-->2="; check_hex(val, $0011); print ", "; + @loadw addr testglobal -> val; + print "a-->2="; check_hex(val, $0011); print ", "; + + @push 3; + @loadw array1 sp -> val; + print "a-->3="; check_hex(val, $FFEE); print ", "; + @push 3; + @loadw addr sp -> val; + print "a-->3="; check_hex(val, $FFEE); print "^"; + + addr = array1+3; + @loadw addr (-1) -> val; + print "a+3-->-1="; check_hex(val, $57FD); print ", "; + @loadw addr 0 -> val; + print "a+3-->0="; check_hex(val, $B900); print ", "; + @loadw addr 1 -> val; + print "a+3-->1="; check_hex(val, $11FF); print ", "; + testglobal = array1+3; + @loadw testglobal (-1) -> val; + print "a+3-->-1="; check_hex(val, $57FD); print ", "; + @loadw testglobal 0 -> val; + print "a+3-->0="; check_hex(val, $B900); print ", "; + @loadw testglobal 1 -> val; + print "a+3-->1="; check_hex(val, $11FF); print "^"; + + + addr = array1; + @loadb array1 0 -> val; + print "a->0="; check_hex(val, $13); print ", "; + @loadb addr 0 -> val; + print "a->0="; check_hex(val, $13); print ", "; + + ix = 1; + @loadb array1 ix -> val; + print "a->1="; check_hex(val, $57); print ", "; + @loadb addr ix -> val; + print "a->1="; check_hex(val, $57); print ", "; + + testglobal = 2; + @loadb array1 testglobal -> val; + print "a->2="; check_hex(val, $FD); print ", "; + @loadb addr testglobal -> val; + print "a->2="; check_hex(val, $FD); print ", "; + + @push 3; + @loadb array1 sp -> val; + print "a->3="; check_hex(val, $B9); print ", "; + @push 3; + @loadb addr sp -> val; + print "a->3="; check_hex(val, $B9); print "^"; + + addr = array1+3; + @loadb addr (-1) -> val; + print "a+3->-1="; check_hex(val, $FD); print ", "; + @loadb addr 0 -> val; + print "a+3->0="; check_hex(val, $B9); print ", "; + @loadb addr 1 -> val; + print "a+3->1="; check_hex(val, $00); print ", "; + testglobal = array1+3; + @loadb testglobal (-1) -> val; + print "a+3->-1="; check_hex(val, $FD); print ", "; + @loadb testglobal 0 -> val; + print "a+3->0="; check_hex(val, $B9); print ", "; + @loadb testglobal 1 -> val; + print "a+3->1="; check_hex(val, $00); print "^"; + + + addr = array2; + @storew array2 0 $1201; + @loadw array2 0 -> val; + print "a-->0="; check_hex(val, $1201); print ", "; + @storew addr 0 $2302; + @loadw array2 0 -> val; + print "a-->0="; check_hex(val, $2302); print ", "; + + ix = 1; + @storew array2 ix $3403; + @loadw array2 1 -> val; + print "a-->1="; check_hex(val, $3403); print ", "; + @storew addr ix $4504; + @loadw array2 1 -> val; + print "a-->1="; check_hex(val, $4504); print ", "; + + testglobal = 2; + @storew array2 testglobal $5605; + @loadw array2 2 -> val; + print "a-->2="; check_hex(val, $5605); print ", "; + @storew addr testglobal $6706; + @loadw array2 2 -> val; + print "a-->2="; check_hex(val, $6706); print ", "; + + @push 3; + @storew array2 sp $7807; + @loadw array2 3 -> val; + print "a-->3="; check_hex(val, $7807); print ", "; + @push 3; + @storew addr sp $8908; + @loadw array2 3 -> val; + print "a-->3="; check_hex(val, $8908); print "^"; + + addr = array2+4; + @storew addr (-1) $AB0A; + @loadw array2 1 -> val; + print "a-->-1="; check_hex(val, $AB0A); print ", "; + @storew addr 0 $BC0B; + @loadw array2 2 -> val; + print "a-->0="; check_hex(val, $BC0B); print ", "; + @storew addr 1 $CD0C; + @loadw array2 3 -> val; + print "a-->1="; check_hex(val, $CD0C); print ", "; + + testglobal = array2+4; + @storew testglobal (-1) $BA1B; + @loadw array2 1 -> val; + print "a-->-1="; check_hex(val, $BA1B); print ", "; + @storew testglobal 0 $CB1C; + @loadw array2 2 -> val; + print "a-->0="; check_hex(val, $CB1C); print ", "; + @storew testglobal 1 $DC1D; + @loadw array2 3 -> val; + print "a-->1="; check_hex(val, $DC1D); print "^"; + + + addr = array2; + @storeb array2 0 $12; + @loadb array2 0 -> val; + print "a->0="; check_hex(val, $12); print ", "; + @storeb addr 0 $23; + @loadb array2 0 -> val; + print "a->0="; check_hex(val, $23); print ", "; + + ix = 1; + @storeb array2 ix $34; + @loadb array2 1 -> val; + print "a->1="; check_hex(val, $34); print ", "; + @storeb addr ix $45; + @loadb array2 1 -> val; + print "a->1="; check_hex(val, $45); print ", "; + + testglobal = 2; + @storeb array2 testglobal $56; + @loadb array2 2 -> val; + print "a->2="; check_hex(val, $56); print ", "; + @storeb addr testglobal $67; + @loadb array2 2 -> val; + print "a->2="; check_hex(val, $67); print ", "; + + @push 3; + @storeb array2 sp $78; + @loadb array2 3 -> val; + print "a->3="; check_hex(val, $78); print ", "; + @push 3; + @storeb addr sp $89; + @loadb array2 3 -> val; + print "a->3="; check_hex(val, $89); print "^"; + + addr = array2+4; + @storeb addr (-1) $AB; + @loadb array2 3 -> val; + print "a->-1="; check_hex(val, $AB); print ", "; + @storeb addr 0 $BC; + @loadb array2 4 -> val; + print "a->0="; check_hex(val, $BC); print ", "; + @storeb addr 1 $CD; + @loadb array2 5 -> val; + print "a->1="; check_hex(val, $CD); print ", "; + + testglobal = array2+4; + @storeb testglobal (-1) $BA; + @loadb array2 3 -> val; + print "a->-1="; check_hex(val, $BA); print ", "; + @storeb testglobal 0 $CB; + @loadb array2 4 -> val; + print "a->0="; check_hex(val, $CB); print ", "; + @storeb testglobal 1 $DC; + @loadb array2 5 -> val; + print "a->1="; check_hex(val, $DC); print "^"; + + ix = $F1; + @storeb array2 0 ix; + ix = $E2; + @storeb array2 1 ix; + @loadw array2 0 -> val; + print "$F1 concat $E2 = "; check_hex(val, $F1E2); print "^"; + + ix = $9876; + @storew array2 1 ix; + @loadb array2 2 -> val; + print "$9876 = "; check_hex(val, $98); print " "; + @loadb array2 3 -> val; + print "concat "; check_hex(val, $76); print "^"; + + count_failures(); + ]; + +TestClass UndoTest + with name 'undo', + testfunc [ val loc; + print "Undo:^^"; + + val = HDR_GAMEFLAGS-->0; ! "Flags 2" byte + if (val & 16) + print "Interpreter claims to support undo.^^"; + else + print "Interpreter claims to not support undo. (Continuing test anyway...)^^"; + + print "Using a local variable for @@64save_undo result:^"; + loc = 99; + testglobal = 999; + @save_undo val; + if (val == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (val == 0) { + print "@@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (val == 1) { + print "Undo saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + failures++; + print "Restoring undo...^"; + @restore_undo val; + if (val == 0) { + print "@@64restore_undo failed (value 0)!^"; + } + else { + print "@@64restore_undo failed with unknown return value: ", val, "^"; + } + failures++; + count_failures(); + return; + } + else if (val ~= 2) { + print "Unknown @@64save_undo return value: ", val, "^"; + failures++; + count_failures(); + return; + } + print "Undo succeeded, return value "; check(val, 2); print ".^"; + print "loc="; check(loc, 99); print " glob="; check(testglobal, 999); print "^"; + + print "Using a global variable for @@64save_undo result:^"; + loc = 98; + testglobal = 998; + @save_undo testglobal2; + if (testglobal2 == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (testglobal2 == 0) { + print "@@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (testglobal2 == 1) { + print "Undo saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + failures++; + print "Restoring undo...^"; + @restore_undo testglobal2; + if (testglobal2 == 0) { + print "@@64restore_undo failed (value 0)!^"; + } + else { + print "@@64restore_undo failed with unknown return value: ", testglobal2, "^"; + } + failures++; + count_failures(); + return; + } + else if (testglobal2 ~= 2) { + print "Unknown @@64save_undo return value: ", testglobal2, "^"; + failures++; + count_failures(); + return; + } + print "Undo succeeded, return value "; check(testglobal2, 2); print ".^"; + print "loc="; check(loc, 98); print " glob="; check(testglobal, 998); print "^"; + + print "Calling @@64save_undo within a function or two:^"; + loc = 97; + testglobal = 997; + val = undo_depth_check(); + if (val == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (val == 0) { + print "@@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (val == 1) { + print "Undo saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + failures++; + print "Restoring undo...^"; + @restore_undo val; + if (val == 0) { + print "@@64restore_undo failed (value 0)!^"; + } + else { + print "@@64restore_undo failed with unknown return value: ", val, "^"; + } + failures++; + count_failures(); + return; + } + else if (val ~= 2) { + print "Unknown @@64save_undo return value: ", val, "^"; + failures++; + count_failures(); + return; + } + print "Undo succeeded, return value "; check(val, 2); print ".^"; + print "loc="; check(loc, 97); print " glob="; check(testglobal, 997); print "^"; + @check_arg_count 3 ?~ok; + print "Error: test method wrongly got argument 3!^"; + failures++; + .ok; + + print "Using the stack for @@64save_undo result:^"; + loc = 98; + testglobal = 998; + testglobal2 = -99; + @save_undo sp; + @pull testglobal2; + if (testglobal2 == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (testglobal2 == 0) { + print "@@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (testglobal2 == 1) { + print "Undo saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + testglobal2 = -99; + failures++; + print "Restoring undo...^"; + @restore_undo sp; + @pull testglobal2; + if (testglobal2 == 0) { + print "@@64restore_undo failed (value 0)!^"; + } + else { + print "@@64restore_undo failed with unknown return value: ", testglobal2, "^"; + } + failures++; + count_failures(); + return; + } + else if (testglobal2 ~= 2) { + print "Unknown @@64save_undo return value: ", testglobal2, "^"; + failures++; + count_failures(); + return; + } + print "Undo succeeded, return value "; check(testglobal2, 2); print ".^"; + print "loc="; check(loc, 98); print " glob="; check(testglobal, 998); print "^"; + + print "Checking @@64save_undo saves the stack correctly:^"; + @push 9; + loc = 99; + testglobal = 999; + testglobal2 = -999; + @save_undo val; + if (val == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (val == 0) { + print "@@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (val == 1) { + print "Undo saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + testglobal2 = -777; + @pull val; + print "guard="; check(val, 9); print "^"; + val = 7; + failures++; + print "Restoring undo...^"; + @restore_undo testglobal2; + if (testglobal2 == 0) { + print "@@64restore_undo failed (value 0)!^"; + } + else { + print "@@64restore_undo failed with unknown return value: ", testglobal2, "^"; + } + failures++; + count_failures(); + return; + } + else if (val ~= 2) { + print "Unknown @@64save_undo return value: ", val, "^"; + failures++; + count_failures(); + return; + } + print "Undo succeeded, return value "; check(val, 2); print ".^"; + print "loc="; check(loc, 99); print " glob="; check(testglobal, 999); print " glob2="; check(testglobal2, -999); print "^"; + + @pull val; + print "guard="; check(val, 9); print "^"; + + count_failures(); + ]; + +[ undo_depth_check; + return undo_depth_check2(11, 22, 33); +]; + +[ undo_depth_check2 foo bar baz val; + bar = 1; + foo = bar; + baz = foo; + @save_undo val; + @check_arg_count 3 ?ok; + print "Error: undo_depth_check2 did not get argument 3!^"; + failures++; + .ok; + return val; +]; + +TestClass MultiUndoTest + with name 'multiundo', + testfunc [ val loc; + print "Multi-level undo:^(Note: this capability is not required by the spec.)^^"; + + val = HDR_GAMEFLAGS-->0; ! "Flags 2" byte + if (val & 16) + print "Interpreter claims to support undo.^^"; + else + print "Interpreter claims to not support undo. (Continuing test anyway...)^^"; + + loc = 99; + testglobal = 999; + @save_undo val; + if (val == -1) { + print "Undo is not available on this interpreter.^"; + count_failures(); + return; + } + if (val == 0) { + print "First @@64save_undo failed!^"; + failures++; + count_failures(); + return; + } + if (val == 1) { + print "Undo 1 saved...^"; + ! The following changes will be undone. + loc = 77; + testglobal = 777; + failures++; + + @save_undo val; + if (val == -1) { + print "Undo returned ~unavailable~, even though it was available the first time.^"; + count_failures(); + return; + } + if (val == 0) { + print "Second @@64save_undo failed! This interpreter apparently doesn't support multi-level undo. This should not be considered a bug.^"; + failures--; ! cancel the previous failure + count_failures(); + return; + } + if (val == 1) { + print "Undo 2 saved...^"; + ! The following changes will be undone. + loc = 55; + testglobal = 555; + failures++; + + print "Restoring undo 2...^"; + @restore_undo val; + if (val == 0) { + print "Second @@64restore_undo failed (value 0)!^"; + } + else { + print "Second @@64restore_undo failed with unknown return value: ", val, "^"; + } + failures++; + count_failures(); + return; + } + else if (val ~= 2) { + print "Unknown @@64save_undo return value: ", val, "^"; + failures++; + count_failures(); + return; + } + + print "Undo 2 succeeded, return value "; check(val, 2); print ".^"; + print "loc="; check(loc, 77); print " glob="; check(testglobal, 777); print "^"; + + print "Restoring undo 1...^"; + @restore_undo val; + if (val == 0) { + print "First @@64restore_undo failed (value 0)!^"; + } + else { + print "First @@64restore_undo failed with unknown return value: ", val, "^"; + } + failures++; + count_failures(); + return; + } + else if (val ~= 2) { + print "Unknown @@64save_undo return value: ", val, "^"; + failures++; + count_failures(); + return; + } + print "Undo 1 succeeded, return value "; check(val, 2); print ".^"; + print "loc="; check(loc, 99); print " glob="; check(testglobal, 999); print "^"; + + count_failures(); + ]; + +! The Indirect test is copied more-or-less whole from czech.inf +! (as of Oct 1 2010). Comments copied also: +! +! Indirect-able opcodes: inc, dec, inc_chk, dec_chk, store, pull, load +! Spec Version 1.1 (draft7): "an indirect reference to the stack +! pointer does not push or pull the top item of the stack - it is read +! or written in place." +! Based on my tests (see rec.arts.int-fiction 20031028), this seems to mean +! that, e.g., for load, you NEVER pop the stack, for all cases +! (a) load sp; (b) load [sp]; (c) i=0; load [i]; (d) sp=0; load [sp]; +! +! Overall rules: +! - Do NOT push/pop for "foo sp": write in place +! - DO pop for "foo [sp]". However, if top of stack is 0, only pop ONCE. +! - "bar = 0; foo [bar]" yields EXACTLY the same results as "foo sp" +! ("push 0; foo [sp] is also identical to "foo sp".) +! +TestClass IndirectTest + with name 'indirect', + testfunc [ ix; + print "Indirect opcodes:^^"; + + for (ix = 0: ix < 100: ix++) { + do_indirect_test(ix); + } + + count_failures(); + ]; + +[ do_indirect_test which + result local2 spointer lpointer rpointer + top_of_stack which_str expectr expect1 expect2; + + ! First, set up everything we're going to need. + + local2 = 51; + ! Gtemp = 61; + result = 71; + spointer = 0; ! stack + rpointer = 2; ! points to 'result' + lpointer = 3; ! local2 + ! gpointer = 21; ! '21' means 6th global, which is (hopefully!) Gtemp + expectr = 999; ! don't test 'result' unless we change this value + + @push 41; @push 42; @push 43; @push 44; @push 45; + switch (which) { + + ! load -> result + 0: + @load sp -> result; ! compiles as 'load 0 -> result' + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load sp -> result"; + 1: + @load [spointer] -> result; + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load [spointer] -> result"; + 2: + @push lpointer; @load [sp] -> result; + expectr = 51; expect1 = 45; expect2 = 44; + which_str = "load [sp=lpointer] -> result"; + 3: + @push spointer; @load [sp] -> result; + expectr = 45; expect1 = 45; expect2 = 44; + which_str = "load [sp=spointer] -> result"; + + ! load -> sp + 4: + @load sp -> sp; + expect1 = 45; expect2 = 45; + which_str = "load sp -> sp"; + 5: + @push lpointer; @load [sp] -> sp; + expect1 = 51; expect2 = 45; + which_str = "load [sp=lpointer] -> sp"; + 6: + @push spointer; @load [sp] -> sp; + expect1 = 45; expect2 = 45; + which_str = "load [sp=spointer] -> sp"; + + ! store + 10: + @store sp 83; + expect1 = 83; expect2 = 44; + which_str = "store sp 83"; + 11: + @store [spointer] 83; + expect1 = 83; expect2 = 44; + which_str = "store [spointer] 83"; + 12: + @push spointer; @store [sp] 83; + expect1 = 83; expect2 = 44; + which_str = "store [sp=spointer] 83"; + + 13: + @store [rpointer] 83; + expectr = 83; expect1 = 45; expect2 = 44; + which_str = "store [rpointer] 83"; + 14: + @push rpointer; @store [sp] 83; + expectr = 83; expect1 = 45; expect2 = 44; + which_str = "store [sp=rpointer] 83"; + + 15: + @store result sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store result sp"; + 16: + @store sp sp; + expect1 = 45; expect2 = 43; + which_str = "store sp sp"; + 17: + @push spointer; @store [sp] sp; + expect1 = 45; expect2 = 43; + which_str = "store [sp=spointer] sp"; + + 18: + @store [rpointer] sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store [rpointer] sp"; + 19: + @push rpointer; @store [sp] sp; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "store [sp=rpointer] sp"; + + ! pull + 20: + @pull result; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull result"; + 21: + @pull [rpointer]; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull [rpointer]"; + 22: + @push rpointer; @pull [sp]; + expectr = 45; expect1 = 44; expect2 = 43; + which_str = "pull [sp=rpointer]"; + + 23: + @pull sp; + expect1 = 45; expect2 = 43; + which_str = "pull sp"; + 24: + @push spointer; @pull [sp]; + expect1 = 45; expect2 = 43; + which_str = "pull [sp=spointer]"; + 25: + @pull [spointer]; + expect1 = 45; expect2 = 43; + which_str = "pull [spointer]"; + + ! inc + 30: + @inc result; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc result"; + 31: + @inc [rpointer]; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc [rpointer]"; + 32: + @push rpointer; @inc [sp]; + expectr = 72; expect1 = 45; expect2 = 44; + which_str = "inc [sp=rpointer]"; + + 33: + @inc sp; + expect1 = 46; expect2 = 44; + which_str = "inc sp"; + 34: + @inc [spointer]; + expect1 = 46; expect2 = 44; + which_str = "inc [spointer]"; + 35: + @push spointer; @inc [sp]; + expect1 = 46; expect2 = 44; + which_str = "inc [sp=spointer]"; + + ! dec + 40: + @dec result; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec result"; + 41: + @dec [rpointer]; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec [rpointer]"; + 42: + @push rpointer; @dec [sp]; + expectr = 70; expect1 = 45; expect2 = 44; + which_str = "dec [sp=rpointer]"; + + 43: + @dec sp; + expect1 = 44; expect2 = 44; + which_str = "dec sp"; + 44: + @dec [spointer]; + expect1 = 44; expect2 = 44; + which_str = "dec [spointer]"; + 45: + @push spointer; @dec [sp]; + expect1 = 44; expect2 = 44; + which_str = "dec [sp=spointer]"; + + ! inc_chk + 50: + which_str = "inc_chk result"; + @inc_chk result 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + 51: + which_str = "inc_chk [rpointer]"; + @inc_chk [rpointer] 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + 52: + which_str = "inc_chk [sp=rpointer]"; + @push rpointer; @inc_chk [sp] 72 ?bad_indirect_inc; + expectr = 72; expect1 = 45; expect2 = 44; + + 53: + which_str = "inc_chk sp"; + @inc_chk sp 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + 54: + which_str = "inc_chk [spointer]"; + @inc_chk [spointer] 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + 55: + which_str = "inc_chk [sp=spointer]"; + @push spointer; @inc_chk [sp] 46 ?bad_indirect_inc; + expect1 = 46; expect2 = 44; + + ! dec_chk + 60: + which_str = "dec_chk result"; + @dec_chk result 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + 61: + which_str = "dec_chk [rpointer]"; + @dec_chk [rpointer] 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + 62: + which_str = "dec_chk [sp=rpointer]"; + @push rpointer; @dec_chk [sp] 70 ?bad_indirect_inc; + expectr = 70; expect1 = 45; expect2 = 44; + + 63: + which_str = "dec_chk sp"; + @dec_chk sp 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + 64: + which_str = "dec_chk [spointer]"; + @dec_chk [spointer] 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + 65: + which_str = "dec_chk [sp=spointer]"; + @push spointer; @dec_chk [sp] 44 ?bad_indirect_inc; + expect1 = 44; expect2 = 44; + + default: + rfalse; ! no test here; do nothing. + } + + ! Test results + print (string) which_str, ": "; + @je expectr 999 ?skip_expectr; + check(result, expectr); print ", "; + .skip_expectr; + @pull top_of_stack; + check(top_of_stack, expect1); print ", "; + @pull top_of_stack; + check(top_of_stack, expect2); + + new_line; + rtrue; + + ! If you got here, inc_chk/dec_chk broke + .bad_indirect_inc; + print (string) which_str, ": "; + check(result, 123); + new_line; + rfalse; +]; + +! The lengths here must exceed the number of characters printed (below) +! by at least 3. +Array streambuf -> 170; +Array streambufcmp -> 170; + +! The StreamTrip test sends every legal, printable ZSCII character to +! a memory stream, and then reads them back. They should all survive +! the journey unscathed. +! +! Note that character 9 (tab) and 10 (unix newline) are not legal for +! output. (Despite the fact that Zork 1 uses tabs for indenting +! the temple book's text.) (Tab is legal in V6, but this test is for +! v5/8.) +! +! Printing character 0 is legal, but doesn't generate output. It should +! not count towards the stream count either. (See 3.8.2.1.) +! +TestClass StreamTripTest + with name 'streamtrip', + short_name "streamtrip", + testfunc [ ix len pos ch; + print "Memory stream round-trip:^^"; + + @output_stream 3 streambuf; + pos = 0; + @print_char 13; ! newline + streambufcmp->pos = 13; pos++; + for (ix=32 : ix <= 126 : ix++) { + streambufcmp->pos = ix; pos++; + @print_char ix; + } + for (ix=155 : ix <= 223 : ix++) { + streambufcmp->pos = ix; pos++; + @print_char ix; + } + ! no streambufcmp output for the no-op + @print_char 0; ! no-op + @print_char 64; ! @-sign + streambufcmp->pos = 64; pos++; + @output_stream -3; + + ix = streambuf; + len = ix-->0; + print "Number of characters written: "; check(pos, 166); new_line; + print "Number of characters read: "; check(len, 166); new_line; + + for (ix=0 : ixix; + if (streambuf->(ix+2) ~= ch) { + print "Mismatch for ", ch, " '"; + @print_char ch; + print "': "; + check(streambuf->(ix+2), ch); + new_line; + } + } + + count_failures(); + ]; + +TestClass specfixes + with name 'specfixes' 'fixes', + testfunc [ val ; + print "Z-Machine 1.1 Updates/Clarifications:^^"; + + ! Operand evalution + ! Opcode operands are always evaluated from first to last + print "Operand evalution: "; + @push 2; + @push 4; + @sub sp sp -> val; + print "4-2="; check(val, 2); print "^"; + + ! Indirect variable references + ! An indirect reference to the stack pointer does not push or pull the top item of the stack - it is read or written in place. + print "Indirect variable references:^"; + @push 9; + @push 5; + @dec sp; + @pull val; + @pull val; + print "@@64dec: guard="; check(val, 9); print "^"; + @push 9; + @push 7; + @dec_chk sp 2 ?jumpfail; + @pull val; + @pull val; + print "@@64dec_chk: guard="; check(val, 9); print "^"; + @push 9; + @push 5; + @inc sp; + @pull val; + @pull val; + print "@@64inc: guard="; check(val, 9); print "^"; + @push 9; + @push 2; + @inc_chk sp 7 ?jumpfail; + @pull val; + @pull val; + print "@@64inc_chk: guard="; check(val, 9); print "^"; + ! Push an extra value in case @load fails - we don't want a stack underflow + @push 1; + @push 9; + @load sp -> val; + @pull val; + print "@@64load: guard="; check(val, 9); print "^"; + @push 9; + @pull sp; + @pull val; + print "@@64pull: guard="; check(val, 9); print "^"; + @push 9; + @push 1; + @store sp 2; + @pull val; + @pull val; + print "@@64store: guard="; check(val, 9); print "^"; + + ! @je + ! @je can take between 2 and 4 operands. + print "@@64je operands: "; + val = 1; + @je 1 0 1 ?je1; + val = 0; + .je1; + print "3: "; check(val, 1); + val = 1; + @je 1 0 0 1 ?je2; + val = 0; + .je2; + print ", 4: "; check(val, 1); print "^"; + + ! @get_prop_len + ! @get_prop_len 0 must return 0. + val = 1; + print "@@64get_prop_len 0: "; + @get_prop_len 0 -> val; + check(val, 0); print "^"; + + !### @set_cursor + !### @output_stream + !### Mouse + !### Sound + + count_failures(); + return; + + .jumpfail; + failures++; + count_failures(); + ]; + +TestClass gestalt + with name 'spec12' 'gestalt', + testfunc [ val ; + print "Z-Machine 1.2 (@@64gestalt):^^"; + + ! Check we're in a 1.2 version interpreter + val = HDR_SPECREVISION-->0; + if (val < $0102) + { + print "Stopping, interpreter is only version "; Version(); print ".^"; + return; + } + + print "Ok, interpreter is version "; Version(); print ".^^"; + + ! Checking non-existant selector + @"EXT:30S" 0 0 -> val; + print "Selector 0 (non-existant): 0="; check(val, 0); print "^"; + + ! Checking Standard Revision selector + @"EXT:30S" 1 0 -> val; + print "Selector 1 (Standard Revision): $0102<= "; check_hex_min(val, $0102); print "^"; + + ! Other core selectors + @"EXT:30S" $2000 0 -> val; + print "Selector $2000 (@@64set_font 0): "; check_hex_min(val, 1); print "^"; + + @"EXT:30S" $2001 0 -> val; + print "Selector $2001 (Streams 3/4): "; check_hex_min(val, 1); print "^"; + + @"EXT:30S" $2002 0 -> val; + print "Selector $2002 (@@call_vs2): "; check_hex_min(val, 1); print "^"; + + count_failures(); + return; + ]; diff --git a/tests/praxix.z5 b/tests/praxix.z5 new file mode 100644 index 0000000000000000000000000000000000000000..0902fbcc269795ac75bec22da7c86ad0f66945aa GIT binary patch literal 28160 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
W0K=BNckBK!%5N1qndws;JL8%@ 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 literal 0 HcmV?d00001 diff --git a/tests/unicode.inf b/tests/unicode.inf new file mode 100644 index 0000000..2f49ba7 --- /dev/null +++ b/tests/unicode.inf @@ -0,0 +1,123 @@ +! Unicode Test v1.0 +! +! David Kinder, 2002. +! + +Switches xv5; +Release 1; + +Zcharacter table + '@{a9}' '@{2122}' '@{20ac}'; + +[ main; + + print "^Unicode Test v1.0, by David Kinder^"; + new_line; + + print "Testing the Unicode table. This sentence should end with Euro, copyright and trademark symbols @{20ac} @{a9} @{2122}^"; + new_line; + + print "Now, testing print_unicode()...^"; + charsets(); + new_line; + + print "Now, testing input (ESC to quit)...^"; + input_unicode(); +]; + +[ input_unicode key; + + print "Try inputing a character. Since the Euro symbol is declared in this file's Zcharacter table, "; + print "it can be input even though it is not part of ISO Latin-1.^"; + while (1) + { + @read_char 1 -> key; + + if (key == $1b) + quit; + + font off; + print "ZSCII $", (hex) key, " = "; + font on; + + switch (key) + { + 8: print "delete"; + 13: print "return"; + 129: print "cursor up"; + 130: print "cursor down"; + 131: print "cursor left"; + 132: print "cursor right"; + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144: print "function key ", key-132; + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154: print "keypad key ", key-145; + 252: print "menu click"; + 253: print "mouse double-click"; + 254: print "mouse single-click"; + default: print (char) key; + } + new_line; + } +]; + +[ charsets; + + charset("Basic Latin",$0020,3); + charset("Latin-1 Supplement",$00a0,3); + charset("Latin Extended-A",$0100,4); + charset("Greek and Coptic",$0360,5); + charset("Cyrillic",$0400,8); + charset("Arabic",$0600,8); +]; + +[ charset title start lines i; + + font off; + new_line; + print (string) title; + new_line; + + for (i = 0: i < lines: i++) + charrow(start+(i*32)); + font on; +]; + +[ charrow start i; + + print (hex) start, " : "; + for (i = 0: i < 32: i++) + charout(start+i); + new_line; +]; + +[ charout c exist; + + @"EXT:12S" c -> exist; + if (exist & 1) + @"EXT:11" c; + else + print (char) ' '; +]; + +[ hex x y; + + y = (x & $7f00) / $100; + if (x < 0) + y = y + $80; + x = x & $ff; + print (hexdigit) y/$10, (hexdigit) y, (hexdigit) x/$10, (hexdigit) x; +]; + +[ hexdigit x; + + x = x % $10; + switch (x) + { + 0 to 9: print x; + 10: print "a"; + 11: print "b"; + 12: print "c"; + 13: print "d"; + 14: print "e"; + 15: print "f"; + } +]; + diff --git a/tests/unicode.z5 b/tests/unicode.z5 new file mode 100644 index 0000000000000000000000000000000000000000..8f60e05a28cc3b90f683b3d959846ef559a0195c GIT binary patch literal 4608 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 literal 0 HcmV?d00001 From 2fe7c148558f355e442eb829c54b5d42f1bc9b56 Mon Sep 17 00:00:00 2001 From: Dannii Date: Sun, 9 Oct 2011 12:20:21 +1000 Subject: [PATCH 2/7] Add Zarf's StreamOp test --- tests/praxix.inf | 44 ++++++++++++++++++++++++++++++++++++++++++++ tests/praxix.z5 | Bin 28160 -> 28672 bytes 2 files changed, 44 insertions(+) diff --git a/tests/praxix.inf b/tests/praxix.inf index 185a1c1..b20043d 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -176,6 +176,17 @@ Class TestClass rfalse; ]; +[ check_arr_3 arr v0 v1 v2; + if (arr->0 == v0 && arr->1 == v1 && arr->2 == v2) { + print v0, " ", v1, " ", v2; + rtrue; + } + failures++; + print arr->0, " ", arr->1, " ", arr->2; + print " (should be ", v0, " ", v1, " ", v2, " FAIL)"; + rfalse; +]; + [ check_hex val wanted; if (val == wanted) { print (Hex) val; @@ -2246,6 +2257,39 @@ TestClass StreamTripTest count_failures(); ]; +TestClass StreamOpTest + with name 'streamop', + short_name "streamop", + testfunc [ len; + print "Memory stream opcodes:^^"; + + @output_stream 3 streambuf; + @print_paddr "abc"; + @output_stream -3; + + len = (streambuf+0)-->0; + check(len, 3); print " characters written: "; + check_arr_3(streambuf+2, 'a', 'b', 'c'); new_line; + + @output_stream 3 streambuf; + @print_num 789; + @output_stream -3; + + len = (streambuf+0)-->0; + check(len, 3); print " characters written: "; + check_arr_3(streambuf+2, '7', '8', '9'); new_line; + + @output_stream 3 streambuf; + @print_char 'x'; + @output_stream -3; + + len = (streambuf+0)-->0; + check(len, 1); print " characters written: "; + check_arr_3(streambuf+2, 'x', '8', '9'); new_line; + + count_failures(); + ]; + TestClass specfixes with name 'specfixes' 'fixes', testfunc [ val ; diff --git a/tests/praxix.z5 b/tests/praxix.z5 index 0902fbcc269795ac75bec22da7c86ad0f66945aa..0ab2a529fd9a9bcc71c6967e53131113dac61047 100644 GIT binary patch delta 11296 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 delta 10862 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 Date: Mon, 14 Nov 2011 10:27:50 +1000 Subject: [PATCH 3/7] Added tests for @catch, @throw, @copy_table, @print_table, @scan_table, @set_colour, @set_true_colour --- tests/praxix.inf | 299 ++++++++++++++++++++++++++++++++++++++++++++--- tests/praxix.z5 | Bin 28672 -> 31744 bytes 2 files changed, 286 insertions(+), 13 deletions(-) diff --git a/tests/praxix.inf b/tests/praxix.inf index b20043d..abe90c3 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -4,6 +4,14 @@ ! The indirect test is Copyright (C) 2003, Amir Karger +! TODO: +! @encode_text +! @erase_line +! @get_cursor +! @set_font +! Consider making this test suite non-interactive, and have another test suite for interactive tests +! Move too any tests which are manually confirmed by eye, so that all of Praxix can be summed up by "All tests passed" + Constant Story "Praxix"; Constant Headline "A Z-code interpreter unit test^"; Release 1; @@ -216,6 +224,19 @@ Class TestClass rfalse; ]; +[ check_array test gold len func + ix testch goldch; + for (ix=0 : ixix; + testch = test->ix; + if (testch ~= goldch) { + func(goldch, ix); + check(testch, goldch); + new_line; + } + } +]; + [ count_failures val; print "^"; if (failures) { @@ -286,6 +307,9 @@ TestClass AllAction ix++; } print "."; + + print "^(Some tests check unspecified behaviour, and their results will be marked by (Unspecified).)^"; + new_line; if (total_failures) { print "^", total_failures, " tests have failed so far in this run.^"; @@ -2217,7 +2241,7 @@ Array streambufcmp -> 170; TestClass StreamTripTest with name 'streamtrip', short_name "streamtrip", - testfunc [ ix len pos ch; + testfunc [ ix len pos; print "Memory stream round-trip:^^"; @output_stream 3 streambuf; @@ -2243,20 +2267,17 @@ TestClass StreamTripTest print "Number of characters written: "; check(pos, 166); new_line; print "Number of characters read: "; check(len, 166); new_line; - for (ix=0 : ixix; - if (streambuf->(ix+2) ~= ch) { - print "Mismatch for ", ch, " '"; - @print_char ch; - print "': "; - check(streambuf->(ix+2), ch); - new_line; - } - } + check_array( streambuf+2, streambufcmp, len, Streamtripprint ); count_failures(); ]; +[ Streamtripprint ch; + print "Mismatch for ", ch, " '"; + @print_char ch; + print "': "; +]; + TestClass StreamOpTest with name 'streamop', short_name "streamop", @@ -2266,8 +2287,9 @@ TestClass StreamOpTest @output_stream 3 streambuf; @print_paddr "abc"; @output_stream -3; - + len = (streambuf+0)-->0; + print "@@64print_paddr: "; check(len, 3); print " characters written: "; check_arr_3(streambuf+2, 'a', 'b', 'c'); new_line; @@ -2276,6 +2298,7 @@ TestClass StreamOpTest @output_stream -3; len = (streambuf+0)-->0; + print "@@64print_num: "; check(len, 3); print " characters written: "; check_arr_3(streambuf+2, '7', '8', '9'); new_line; @@ -2284,12 +2307,203 @@ TestClass StreamOpTest @output_stream -3; len = (streambuf+0)-->0; + print "@@64print_char: "; check(len, 1); print " characters written: "; check_arr_3(streambuf+2, 'x', '8', '9'); new_line; count_failures(); ]; - + +TestClass Throwcatch + with name 'throwcatch' 'throw' 'catch', + short_name "throwcatch", + testfunc [ val; + print "@@64throw/@@64catch:^^"; + + testglobal = 0; + testglobal2 = 0; + + val = Throwfunc1(); + + print "The function with @@64catch will be returned with the value of @@64throw: "; check(val, 1); print "^"; + print "Intermediate functions should not set their storers.^testglobal="; check(testglobal, 0); print "^"; + print "testglobal2="; check(testglobal2, 0); print "^"; + + count_failures(); + ]; + +[ Throwfunc1 val; + print "Throwfunc1^"; + val = Throwfunc2(); + print "Returning from Throwfunc1^^"; + return val; +]; + +[ Throwfunc2 val; + print "Throwfunc2^"; + @catch -> val; + val = Throwfunc3(val); + print "Returning from Throwfunc2^"; + return 2; +]; + +[ Throwfunc3 val; + print "Throwfunc3^"; + testglobal = Throwfunc4(val); + print "Returning from Throwfunc3^"; + return 3; +]; + +[ Throwfunc4 val; + print "Throwfunc4^"; + testglobal2 = Throwfunc5(val); + print "Returning from Throwfunc4^"; + return 4; +]; + +[ Throwfunc5 val; + print "Throwfunc5^About to @@64throw - should then return from Throwfunc1^"; + @throw 1 val; + print "Returning from Throwfunc5^"; + return 5; +]; + +Array tables_data -> 256; +Array copy_table_reference -> +$00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0a $0b $0c $0d $0e $0f +$00 $01 $02 $03 $04 $05 $06 $07 $18 $19 $1a $1b $1c $1d $1e $1f +$30 $31 $32 $33 $34 $35 $36 $37 $28 $29 $2a $2b $2c $2d $2e $2f +$30 $31 $32 $33 $34 $35 $36 $37 $38 $39 $3a $3b $3c $3d $3e $3f +$40 $41 $42 $43 $44 $45 $46 $47 $44 $45 $46 $47 $4c $4d $4e $4f +$54 $55 $56 $57 $54 $55 $56 $57 $58 $59 $5a $5b $5c $5d $5e $5f +$60 $61 $62 $63 $60 $61 $62 $63 $60 $61 $62 $63 $6c $6d $6e $6f +$00 $00 $00 $00 $00 $00 $00 $00 $78 $79 $7a $7b $7c $7d $7e $7f; + +TestClass Tables + with name 'tables' 'table', + testfunc [ val val2 ix; + print "*_table tests:^^"; + + for (ix=0 : ix<256 : ix++) { + tables_data->ix = ix; + } + + print "@@64print_table - should print the alphabet in upper then lower case:^"; + val = tables_data + $41; + @print_table val 26 2 6; + + print "^^@@64scan_table:"; + print "^Default form, first word: "; + @scan_table $0001 tables_data 128 -> val ?~bad_scan_table; + check(val, tables_data); + print "^Default form, another word: "; + @scan_table $8081 tables_data 128 -> val ?~bad_scan_table; + check(val, tables_data + $80); + print "^Manually specified default form: "; + @scan_table $8081 tables_data 128 $82 -> val ?~bad_scan_table; + check(val, tables_data + $80); + print "^Default form, nonexistent word: "; + @scan_table $0102 tables_data 128 -> val ?bad_scan_table; + check(val, 0); + + print "^Byte form, first byte: "; + @scan_table $00 tables_data 256 $01 -> val ?~bad_scan_table; + check(val, tables_data); + print "^Byte form, another byte: "; + @scan_table $80 tables_data 256 $01 -> val ?~bad_scan_table; + check(val, tables_data + $80); + print "^Byte form, nonexistent byte: "; + @scan_table $100 tables_data 256 $01 -> val ?bad_scan_table; + check(val, 0); + + print "^Longer form, first word: "; + @scan_table $0001 tables_data 64 $84 -> val ?~bad_scan_table; + check(val, tables_data); + print "^Longer form, another word: "; + @scan_table $8081 tables_data 64 $84 -> val ?~bad_scan_table; + check(val, tables_data + $80); + print "^Longer form, a word which will be skipped: "; + @scan_table $0203 tables_data 64 $84 -> val ?bad_scan_table; + check(val, 0); + + print "^Longer byte form, first byte: "; + @scan_table $00 tables_data 64 $04 -> val ?~bad_scan_table; + check(val, tables_data); + print "^Longer byte form, another byte: "; + @scan_table $80 tables_data 64 $04 -> val ?~bad_scan_table; + check(val, tables_data + $80); + print "^Longer byte form, a byte which will be skipped: "; + @scan_table $02 tables_data 64 $04 -> val ?bad_scan_table; + check(val, 0); + + print "^Default form, word after length of table: "; + @scan_table $8081 tables_data 63 -> val ?bad_scan_table; + check(val, 0); + print "^Longer form, word after length of table: "; + @scan_table $8081 tables_data 31 $84 -> val ?bad_scan_table; + check(val, 0); + + .copy_table; + print "^^@@64copy_table:^"; + print "Copying forward, non-overlapping.^"; + val = tables_data + $10; + @copy_table tables_data val 8; + val2 = copy_table_reference + $10; + check_array( val, val2, 16, Copytableprint ); + + print "Copying backwards, non-overlapping.^"; + val = tables_data + $20; + val2 = tables_data + $30; + @copy_table val2 val 8; + val2 = copy_table_reference + $20; + check_array( val, val2, 16, Copytableprint ); + + print "Copying forward, overlapping, non-corrupting.^"; + val = tables_data + $40; + val2 = tables_data + $44; + @copy_table val val2 8; + val2 = copy_table_reference + $40; + check_array( val, val2, 16, Copytableprint ); + + print "Copying backward, overlapping, non-corrupting.^"; + val = tables_data + $50; + val2 = tables_data + $54; + @copy_table val2 val 8; + val2 = copy_table_reference + $50; + check_array( val, val2, 16, Copytableprint ); + + print "Copying forward, overlapping, corrupting.^"; + val = tables_data + $60; + val2 = tables_data + $64; + @copy_table val val2 (-8); + val2 = copy_table_reference + $60; + check_array( val, val2, 16, Copytableprint ); + + print "Using @@64copy_table to zero out an array.^"; + val = tables_data + $70; + @copy_table val 0 8; + val2 = copy_table_reference + $70; + check_array( val, val2, 16, Copytableprint ); + + val = failures; + + print "Checking final table (failures are not counted twice).^"; + check_array( tables_data, copy_table_reference, 128, Copytableprint ); + + failures = val; + count_failures(); + return; + + .bad_scan_table; + print "^Bad @@64scan_table branch."; + failures++; + jump copy_table; + ]; + +[ Copytableprint ch ix; + print "Mismatch for index ", ix, ": "; +]; + TestClass specfixes with name 'specfixes' 'fixes', testfunc [ val ; @@ -2381,6 +2595,65 @@ TestClass specfixes count_failures(); ]; +Array basic_color_set --> $0000 $001D $0340 $03BD $59A0 $7C1F $77A0 $7FFF $5AD6 $4631 $2D6B; + +Array rainbow_set --> $001f $007f $00bf $00ff $013f $019f $01df $023f $027f $02bf $02ff $035f $039f $03df $03fd $03fb $03f9 $03f6 $03f4 $03f2 $03ef $03ed $03eb $03e8 $03e6 $03e4 $03e1 $07e0 $0fe0 $1be0 $23e0 $2be0 $33e0 $3fe0 $47e0 $53e0 $5be0 $63e0 $6be0 $77e0 $7fe0 $7f80 $7f40 $7f00 $7ec0 $7e60 $7e20 $7dc0 $7d80 $7d40 $7d00 $7ca0 $7c60 $7c00 $7c01 $7c04 $7c06 $7c09 $7c0b $7c0d $7c0f $7c12 $7c14 $7c17 $7c19 $7c1b $7c1d $781f $701f $641f $5c1f $541f $4c1f $401f $381f $2c1f $241f $1c1f $141f $081f; + +TestClass spec11 + with name 'spec11', + testfunc [ i val; + print "Z-Machine 1.1 tests:^^"; + + ! Check we're in a 1.1 version interpreter + val = HDR_SPECREVISION-->0; + if (val < $0101) + { + print "Stopping, interpreter is only version "; Version(); print ".^"; + return; + } + + print "Ok, interpreter is version "; Version(); print ".^^"; + + ! Test @set_true_colour by printing a rainbow + print "Checking @@64set_true_colour by printing a pretty rainbow (ultimate prettiness of rainbow depends on the observer's tastes):^^"; + + @set_text_style 8; + for (i=0 : i<80 : i++) + { + val = rainbow_set-->i; + @"EXT:13" -1 val; + print " "; + } + @set_colour 1 1; + @set_text_style 0; + print "^^"; + + ! Check the recommended colour set + print "Checking if the basic colour set uses the recommended true colours:^^"; + + @set_text_style 8; + print "Recommended: "; + for (i=0 : i<11 : i++) + { + val = basic_color_set-->i; + @"EXT:13" -1 val; + print " "; + } + @set_colour 1 1; + print "^Interpreter: "; + for (i=2 : i<13 : i++) + { + @set_colour 1 i; + print " "; + } + @set_colour 1 1; + @set_text_style 0; + print "^"; + + !count_failures(); + return; + ]; + TestClass gestalt with name 'spec12' 'gestalt', testfunc [ val ; diff --git a/tests/praxix.z5 b/tests/praxix.z5 index 0ab2a529fd9a9bcc71c6967e53131113dac61047..d9b7304406cf7bd7b828d8476a19d975c3eebc17 100644 GIT binary patch delta 14406 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 delta 11435 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 From cb6420d933ba354d4e2b330f5c873f8b63284278 Mon Sep 17 00:00:00 2001 From: Dannii Date: Sat, 10 Dec 2011 10:23:28 +1000 Subject: [PATCH 4/7] Fix some URLs and a typo in Praxix --- tests/praxix.inf | 4 +++- tests/praxix.z5 | Bin 31744 -> 31744 bytes 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/praxix.inf b/tests/praxix.inf index abe90c3..8de79ff 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -11,6 +11,8 @@ ! @set_font ! Consider making this test suite non-interactive, and have another test suite for interactive tests ! Move too any tests which are manually confirmed by eye, so that all of Praxix can be summed up by "All tests passed" +! Maybe add tests for @loadw/@storew etc to check they are casting array+word correctly +! 1.1 spec unicode texts Constant Story "Praxix"; Constant Headline "A Z-code interpreter unit test^"; @@ -2685,7 +2687,7 @@ TestClass gestalt print "Selector $2001 (Streams 3/4): "; check_hex_min(val, 1); print "^"; @"EXT:30S" $2002 0 -> val; - print "Selector $2002 (@@call_vs2): "; check_hex_min(val, 1); print "^"; + print "Selector $2002 (@@64call_vs2): "; check_hex_min(val, 1); print "^"; count_failures(); return; diff --git a/tests/praxix.z5 b/tests/praxix.z5 index d9b7304406cf7bd7b828d8476a19d975c3eebc17..270d33429a1673e2fd50821c89f88ee659656e97 100644 GIT binary patch delta 15 WcmZqp!PxMFae^3=k=aIx7u5hWJq9lT delta 15 WcmZqp!PxMFae^3=p~*&x7u5hWEe0$A From 217b0cadcc9a6cc2f39b714567f3802f958fd2ef Mon Sep 17 00:00:00 2001 From: Dannii Date: Tue, 27 Dec 2011 08:34:34 +1000 Subject: [PATCH 5/7] Fixed the @copy_table test based on feedback from Chris Spiegel. --- tests/praxix.inf | 4 ++-- tests/praxix.z5 | Bin 31744 -> 31744 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/praxix.inf b/tests/praxix.inf index 8de79ff..6472511 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -2376,8 +2376,8 @@ $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0a $0b $0c $0d $0e $0f $00 $01 $02 $03 $04 $05 $06 $07 $18 $19 $1a $1b $1c $1d $1e $1f $30 $31 $32 $33 $34 $35 $36 $37 $28 $29 $2a $2b $2c $2d $2e $2f $30 $31 $32 $33 $34 $35 $36 $37 $38 $39 $3a $3b $3c $3d $3e $3f -$40 $41 $42 $43 $44 $45 $46 $47 $44 $45 $46 $47 $4c $4d $4e $4f -$54 $55 $56 $57 $54 $55 $56 $57 $58 $59 $5a $5b $5c $5d $5e $5f +$40 $41 $42 $43 $40 $41 $42 $43 $44 $45 $46 $47 $4c $4d $4e $4f +$54 $55 $56 $57 $58 $59 $5a $5b $58 $59 $5a $5b $5c $5d $5e $5f $60 $61 $62 $63 $60 $61 $62 $63 $60 $61 $62 $63 $6c $6d $6e $6f $00 $00 $00 $00 $00 $00 $00 $00 $78 $79 $7a $7b $7c $7d $7e $7f; diff --git a/tests/praxix.z5 b/tests/praxix.z5 index 270d33429a1673e2fd50821c89f88ee659656e97..9eaf6d760dda6f39d6fee55c863d044593039dfe 100644 GIT binary patch delta 3594 zcmcImeNa@_6~E`cw=1yOu*=7O!M+6%P?r^>MiV2Ex3I{UfGpr5Q7|S98l$QCXeQ%y z7bjzr$$KT!D<%`8QY$(}V}PxRl+;aZ8uOuXl3E+J>0l<3klLh}bj;F**Yn;AV)c*y zQr%RQkVAoK$~pBg`B&V1q(jvX}h3i&$N#>}ueD0B+jg%^dFgqMY# z!Y*OA&@Jo{_6vK3j{ocL0pS(lpzx|-cunXP!om@uUwD(%>91tXA!Rfro|IFf{*+SZ zJQY|z30M$bJ7t?LrBL)175hq-R4%QmuB&fY9%x+A6gC?VPzbPrLVi8E1xNyypx z(MXV{k}s->{Zb;TY%kTcHxR9a}JcVE#~RL zZb`|GW?4??NtvXi^L!2w6>N8xnW{P~}!?Dn*sA9g5JtQ1?)T(YV_#|TYaOS>km!i3r z6HxZJnIq90%OSQWrPvVj99A2~MpCR0X7Q=BrXG?VuNx^b0^Fi`T5#5wnt%I;16}41 zG44>rEIU36Z%?(y!xyYaD8oG)6?`ZQT|Yw^ajCj4<0+J(j2e_5XB0vpoRnFX1b++P zH`iy*D>o4+0~2o3d$QvSZj0=Q%4t)Kbj_*iB<{;&@d~`%0g6&4r-PR)l{a8+$&KCQsEcr%yzv?-Jp2=@_Bx{~`v6dy%*a_b}XQAf3WGIq+ z-8)(Ju0e=>Q!iPKZ*1US@sfJRA-wioG)mhcHNxI{zQ9o|6lX>46-wIiZ=y?cX~R{v>C zpqx3&D(*VlX*$TOcSKGbR4?SD7N>oqwm9vdx9D#=$GXaD3#+jmGQ!`T?)FL&*`x0F)Dt7;Hguf1c#D2BZV*5m*Zc%a7cO!M_^|qX0rUzK2< zsLTnd+x2fYP-Rb3eEQP%g%jmSKtyF;6WX0T`?e~5O@fZhYUg6vOXQ@e%&%9CxB2*4 zq08g&5m8y7#&nvI&qrp3J{h;{5S2xm#mdu?(7;435@{Ee0?p!J8>;Q#V$W2k7iaS% zFSIU}uSDjGN}N$@EoeuNdzy3xLjq+L$+d)H#%`EUQM#r^_l)X4f_u?~dm3 zzXtW6sq8Faa_w2DWe@m$)_}k%L@$xJ&)tT8j_c$k<-F`{W^eg_lD7V;F4S)54{ZUu z`HTw{5_Mw`B0C>tm33dhQ|ylV0@%Vf*4uKQz3QWe{z4wwb2TPh^vkPLRQJWuo-z)- z#17X_%h;m^Gr^C!hJJ`UV)&Wpc>Jiy_fL*E2f*xjR$bx>h5an^Us$tsH z4^+2D;Kvt$XkL#@^74R5c7DS4HdMf0!vARaGZ@R~5PH0W0#wP)OYCf8jze}{9tp-7 zfq0?jA$+sn#lNRV?aerdq%_U|j@{dsi9Ky;T&p_6@eWL=N)}A$97wfBv-s~3zy=-@ zTp5IbEM&5x70U|t#l<=9uv}<)#d_&`9TtkKaFP1&l@NZ=ZG8eL-^Eu%6Knxt2GE|1 zJ9xsOjZ7ds)w_4e$hWHQ$fx zw={cD?`h6M{j=tLE+FKy#1^kDkgSYJM8A&eDxz*j66o-NppqS4+mZ=Ma|iG(&Zw4! zg7f+OMk))%?B&(z-YONI+9C^0Vb{6o`s@X68-0$vwPwM>^<ochJ8T7MI~5LbvpNa&s} zu2h|u;tE9$%5YvnjTbpuF`5(6bX^gLD{#&N@N(SA(VW*}u>N2i-dM60H(-PZ3{`z6 z0itd0vpnhDgQqL%wk7g-3#}J;jcXB7Xk>h$_%KH`Hoj0Na$JlJb$t=XPq6VZHWi-I zD=OZf-h%5nPV$l!h5fCZ{PtPi<;QQ)|7kdF~6gtQhcj0vKj^}(cM_dFLb0= zt%4P_IdcQIqraEpb)mCA7{rbwMz6gMps_ delta 3517 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 I8_NXozho3 Date: Fri, 22 Nov 2013 20:20:43 +1000 Subject: [PATCH 6/7] Add a press-any-key test file --- tests/praxix.inf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/praxix.inf b/tests/praxix.inf index 6472511..9b367a6 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -9,6 +9,9 @@ ! @erase_line ! @get_cursor ! @set_font +! @call 0 +! @random - check it's a good distribution +! @print_table - check line breaks are only printed between lines ! Consider making this test suite non-interactive, and have another test suite for interactive tests ! Move too any tests which are manually confirmed by eye, so that all of Praxix can be summed up by "All tests passed" ! Maybe add tests for @loadw/@storew etc to check they are casting array+word correctly From c6091c0d6aceb29770ece1fc83e849cb6f959370 Mon Sep 17 00:00:00 2001 From: Dannii Willis Date: Thu, 29 Mar 2018 16:41:58 +1000 Subject: [PATCH 7/7] Z-Machine 1.2: Remove the selectors for former spec issues now that the spec has been fixed --- tests/praxix.inf | 10 ---------- tests/praxix.z5 | Bin 31744 -> 31744 bytes 2 files changed, 10 deletions(-) diff --git a/tests/praxix.inf b/tests/praxix.inf index 9b367a6..c3e3afa 100644 --- a/tests/praxix.inf +++ b/tests/praxix.inf @@ -2682,16 +2682,6 @@ TestClass gestalt @"EXT:30S" 1 0 -> val; print "Selector 1 (Standard Revision): $0102<= "; check_hex_min(val, $0102); print "^"; - ! Other core selectors - @"EXT:30S" $2000 0 -> val; - print "Selector $2000 (@@64set_font 0): "; check_hex_min(val, 1); print "^"; - - @"EXT:30S" $2001 0 -> val; - print "Selector $2001 (Streams 3/4): "; check_hex_min(val, 1); print "^"; - - @"EXT:30S" $2002 0 -> val; - print "Selector $2002 (@@64call_vs2): "; check_hex_min(val, 1); print "^"; - count_failures(); return; ]; diff --git a/tests/praxix.z5 b/tests/praxix.z5 index 9eaf6d760dda6f39d6fee55c863d044593039dfe..87f83a7ab4e33422807d0eff15d7b80c8e06771d 100644 GIT binary patch delta 3493 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 Yr!_aD{y}d_qPXo(!Op&ftt