Bug fixes
[rodin/chimara.git] / interpreters / nitfol / crashme.inf
1 ! Self-modifying reproducing Z-code.
2 !
3 ! Generates random junk and sees how the interpreter behaves.  If it's clever
4 ! it shouldn't die except for @quit and stack overflow.
5 !
6 ! inform \$MAX_STATIC_DATA=40000 crashme.inf
7 !
8 ! Written by Evin Robertson 1999.  Placed in public domain.
9
10 Array randstuff -> 32767;
11 Array checkfix  -> 257;
12
13 Global replay = 0;
14
15 Array filename string "CRASHME.MEM";
16
17 #iftrue (#version_number <= 3);
18 Constant Granularity = 2;
19 Constant FileMult = 2;
20 #endif;
21
22 #iftrue (#version_number >= 4 && #version_number <= 5);
23 Constant Granularity = 4;
24 Constant FileMult = 4;
25 #endif;
26
27 #iftrue (#version_number >= 6 && #version_number <= 7);
28 Constant Granularity = 4;
29 Constant FileMult = 8;
30 #endif;
31
32 #iftrue (#version_number == 8);
33 Constant Granularity = 8;
34 Constant FileMult = 8;
35 #endif;
36
37
38 [ Main i a g r c l t game_size checksum;
39    game_size = FileMult * (0-->13); ! game size
40    
41    r = randstuff % Granularity;
42    if(r)
43       r = Granularity - r;
44
45    a = randstuff + r;
46    c = a / Granularity;
47    l = 32767 - r;
48
49    if(replay) {
50       print "You are running crashme's output. This will repeat the test run which generated this output.^";
51    } else {
52       print "This program generates random Z-code which is run to test the robustness of your Z-machine interpreter. Most likely this will infinite loop. Do not run if you can't kill your interpreter when it is tightly looping.^Will attempt to write CRASHME.MEM which should be a valid Z-machine game which contains the same code that will be run.^";
53    }
54    print "Press 'q' to abort.^";
55    @read_char 1 -> i;
56    if(i == 'Q' or 'q')
57       @quit;
58    
59    replay++;
60    
61
62    if(replay == 1) {
63       for(i=0: i < l: i++)
64          a->i = random(256) - 1;
65       for(i=0: i < 13: i++)
66          a->i = (emptyfunc * Granularity)->i;
67       
68       checksum = 0;
69       for(i=0: i < l: i++)
70          checksum = checksum + a->i;
71       g = 0-->6;  ! globals location
72       for(i=0: i < 480: i++)
73          checksum = checksum + g->i;
74       
75       for(i=0: i < 257: i++) {
76          if(-255 <= checksum && checksum <= 0) {
77             checkfix->i = -checksum;
78             break;
79          } else {
80             checkfix->i = 255;
81             checksum = checksum + 255;
82          }
83       }
84       #IFV5; @save 0 game_size filename -> t; #ENDIF;
85    }
86    
87    ! reduce the chances that it'll attempt to write over the same file
88    for(i=0: i <= 11: i++)
89       filename->i = 0;
90    
91    @call_vn c;
92    print "^Done.^";
93 ];
94
95 [ emptyfunc;
96    print "starting...^";
97 ];