1
1
use crate :: { util, video, playfield} ;
2
2
3
+ // enum for crash type
4
+ // struct for crash params
5
+
6
+ #[ derive( Debug ) ]
7
+ struct Params {
8
+ lines : u8 ,
9
+ pushdown : u8 ,
10
+ }
11
+
12
+
3
13
pub fn fuzz ( ) {
4
14
let mut emu = util:: emulator ( Some ( util:: OG_ROM ) ) ;
5
15
16
+ for lines in 0 ..=4 {
17
+ let params = Params {
18
+ lines,
19
+ pushdown : 0 , // 0 / 8
20
+ } ;
21
+ let result = check ( & mut emu, & params) ;
22
+
23
+ if result. is_some ( ) {
24
+ println ! ( "crash @ {:?} {:?}" , result. unwrap( ) , params) ;
25
+ }
26
+ }
27
+
28
+ }
29
+
30
+ fn check ( emu : & mut util:: NesState , params : & Params ) -> Option < u16 > {
6
31
emu. reset ( ) ;
7
32
8
- util:: run_n_vblanks ( & mut emu, 8 ) ;
33
+ util:: run_n_vblanks ( emu, 8 ) ;
9
34
10
35
let p1_score = 0x73 ;
11
36
let score = 0x53 ;
@@ -23,19 +48,19 @@ pub fn fuzz() {
23
48
let p1_current_piece = 0x62 ;
24
49
let auto_repeat_y = 0x4E ;
25
50
let p1_auto_repeat_y = 0x6E ;
51
+ let frame_counter = 0xB1 ;
52
+ let vrow = 0x49 ;
53
+ let p1_vrow = 0x69 ;
26
54
let push_down = 0x4F ;
27
55
let p1_push_down = 0x6F ;
28
56
let render_flags = 0xA3 ;
29
57
let clear_count = 0xD8 ;
30
- let play_state = 0x48 ;
31
58
let p1_play_state = 0x68 ;
32
59
33
- let nmi_label = 0x8005 ;
34
- let switch_label = 0xAC82 ;
35
60
emu. memory . iram_raw [ game_mode] = 4 ;
36
61
emu. registers . pc = main_loop;
37
62
38
- util:: run_n_vblanks ( & mut emu, 7 ) ;
63
+ util:: run_n_vblanks ( emu, 7 ) ;
39
64
40
65
emu. memory . iram_raw [ level_number] = 154 ;
41
66
emu. memory . iram_raw [ p1_level_number] = 154 ;
@@ -52,11 +77,11 @@ pub fn fuzz() {
52
77
53
78
emu. memory . iram_raw [ render_flags] = 7 ;
54
79
55
- util:: run_n_vblanks ( & mut emu, 1 ) ;
80
+ util:: run_n_vblanks ( emu, 1 ) ;
56
81
57
82
// playfield::clear(&mut emu);
58
83
59
- playfield:: set_str_addr ( & mut emu, 0x400 , match 1 {
84
+ playfield:: set_str_addr ( emu, 0x400 , match params . lines {
60
85
0 => "" ,
61
86
1 => "##### ####" ,
62
87
2 => "##### ####\n ##### ####" ,
@@ -73,64 +98,37 @@ pub fn fuzz() {
73
98
emu. memory . iram_raw [ p1_y] = 0x12 ;
74
99
emu. memory . iram_raw [ auto_repeat_y] = 0 ;
75
100
emu. memory . iram_raw [ p1_auto_repeat_y] = 0 ;
76
- // emu.memory.iram_raw[push_down] = 8;
77
- // emu.memory.iram_raw[p1_push_down] = 8;
101
+ emu. memory . iram_raw [ frame_counter] = 0 ;
102
+ emu. memory . iram_raw [ vrow] = 0 ;
103
+ emu. memory . iram_raw [ p1_vrow] = 0 ;
104
+ emu. memory . iram_raw [ push_down] = params. pushdown ;
105
+ emu. memory . iram_raw [ p1_push_down] = params. pushdown ;
78
106
// emu.memory.iram_raw[clear_count] = 9;
79
107
// emu.memory.iram_raw[clear_count+1] = 5;
80
108
// emu.memory.iram_raw[clear_count+2] = 5;
81
109
// emu.memory.iram_raw[clear_count+3] = 5;
82
110
83
- // set framecounter, vramrow
111
+ util :: run_n_vblanks ( emu , 28 ) ;
84
112
85
- ' outer: for _ in 0 ..30 {
86
- if emu. memory . iram_raw [ play_state] == 5 || emu. memory . iram_raw [ p1_play_state] == 5 {
87
- break ;
88
- }
89
-
90
- let address = ( ( emu. registers . s ) as u16 ) + 0x0102 ;
91
- let address1 = ( ( emu. registers . s ) as u16 ) + 0x0103 ;
113
+ let result = loop {
114
+ emu. cycle ( ) ;
92
115
93
- loop {
94
- emu. cycle ( ) ;
95
- if emu. registers . pc < 0x800 { println ! ( "1" ) ; break ' outer } ;
96
- if emu. registers . pc == nmi_label { println ! ( "2" ) ; break } ;
97
- }
116
+ if emu. registers . pc == 0xAc95 {
117
+ // read 00-01 and see if it's a corrupted value (you can catch orange-blue by checking if $01 is $00 and reds by checking if $00-01 are (and these are in the order you would see in memory, not the actual jump destination) : 20 82, AA A9(not a crash), 2C 20, 82 AA(satan, not crash), A9 EF
98
118
99
- println ! ( "-----------------" ) ;
100
- loop {
101
- emu. cycle ( ) ;
102
- println ! ( "0" ) ;
103
- if emu. registers . pc < 0x800 { println ! ( "1" ) ; break ' outer } ;
104
- if emu. registers . pc == 0xAc95 { println ! ( "2" ) ;
105
-
106
- println ! ( "PC: {:04x}" , emu. registers. pc) ;
107
- emu. memory . iram_raw [ 0x100 ..0x200 ] . iter ( ) . enumerate ( ) . for_each ( |( i, b) | {
108
- if ( i % 16 ) == 0 { print ! ( "\n {:04x}: " , i + 0x100 ) ; }
109
- print ! ( "{:02x} " , b) ;
110
- } ) ;
111
- println ! ( "" ) ;
112
- print ! ( "{:02x} " , emu. memory. iram_raw[ address as usize ] ) ;
113
- println ! ( "{:02x}" , emu. memory. iram_raw[ address1 as usize ] ) ;
114
-
115
- print ! ( "{:02x} " , emu. memory. iram_raw[ 0 ] ) ;
116
- println ! ( "{:02x}" , emu. memory. iram_raw[ 1 ] ) ;
117
- println ! ( "SP: {:02x}" , emu. registers. s) ;
118
- println ! ( "SL: {:02x}" , emu. ppu. current_scanline) ;
119
-
120
- break } ;
121
- }
122
- }
123
- println ! ( "-----------------" ) ;
119
+ let tmp0 = emu. memory . iram_raw [ 0 ] ;
120
+ let tmp1 = emu. memory . iram_raw [ 1 ] ;
121
+ let tmp = ( ( tmp0 as u16 ) << 8 ) + tmp1 as u16 ;
124
122
125
- print ! ( "{:02x} " , emu. memory. iram_raw[ 0 ] ) ;
126
- println ! ( "{:02x}" , emu. memory. iram_raw[ 1 ] ) ;
123
+ if tmp1 == 0 || tmp == 0x2082 || tmp == 0x2C20 || tmp == 0x82AA || tmp == 0xa9ef {
124
+ break Some ( tmp) ;
125
+ }
126
+ } ;
127
127
128
- println ! ( "PC: {:04x}" , emu. registers. pc) ;
129
-
130
- video:: preview ( & mut emu) ;
131
-
132
-
133
- println ! ( "PD: {:02x}" , emu. memory. iram_raw[ p1_push_down] ) ;
128
+ if emu. memory . iram_raw [ p1_play_state] == 1 {
129
+ break None ;
130
+ }
131
+ } ;
134
132
135
- // uncrash by replacing the PC
133
+ return result ;
136
134
}
0 commit comments