1- use super :: print_title ;
1+ use crate :: bus :: Bus ;
22use bitflags:: bitflags;
33use std:: fmt;
4- use std:: time:: Duration ;
5-
6- mod branch_test;
7- mod group1_test;
8- mod group2_test;
9- mod group3_test;
10- mod op;
11- mod other_test;
12- mod sb1_test;
13- mod sb2_test;
14- mod test_fn;
4+ use nes:: print_title;
5+
6+ // Testing files, not needed now due to BUS and ROM implemenation messing up the tests
7+ // mod branch_test;
8+ // mod group1_test;
9+ // mod group2_test;
10+ // mod group3_test;
11+ // mod op;
12+ // mod other_test;
13+ // mod sb1_test;
14+ // mod sb2_test;
15+ // mod test_fn;
1516
1617type Byte = u8 ;
1718
@@ -38,8 +39,7 @@ pub struct CPU {
3839 pub sp : Byte ,
3940 pub flags : CpuFlags ,
4041 // [0x8000... 0xFFFF] is reserved for program ROM
41- pub memory : [ u8 ; 0xFFFF ] ,
42- pub clock_time : Duration ,
42+ pub bus : Bus ,
4343}
4444
4545#[ derive( Debug ) ]
@@ -80,30 +80,18 @@ impl fmt::Display for AddressingMode {
8080
8181const STACK_RESET : u8 = 0xFD ;
8282const STACK : u16 = 0x0100 ;
83- const PROGRAM_START : usize = 0x0600 ;
84-
85- impl CPU {
86- pub fn new ( ) -> Self {
87- CPU {
88- pc : 0 ,
89- a : 0 ,
90- x : 0 ,
91- y : 0 ,
92- sp : STACK_RESET ,
93- flags : CpuFlags :: from_bits_truncate ( 0b0010_0100 ) ,
94- memory : [ 0 ; 0xFFFF ] ,
95- clock_time : Duration :: from_millis ( 1 ) , // Example value
96- }
97- }
9883
84+ pub trait Mem {
85+ fn mem_read ( & self , addr : u16 ) -> Byte ;
86+ fn mem_write ( & mut self , addr : u16 , data : u8 ) ;
9987 // Used to read address in little endian
10088 fn mem_read_u16 ( & mut self , pos : u16 ) -> u16 {
10189 // If interrupt request is enabled, stop program exectuion
102- if pos == 0xFFFE && self . flags . contains ( CpuFlags :: INTERRUPT_DISABLE ) {
103- // BUG Used for irq handler, mitigating for now
104- println ! ( "mem_read_u16: Detected break. Reading from IRQ handler..." ) ;
105- return 0xFFFF ;
106- }
90+ // if pos == 0xFFFE && self.flags.contains(CpuFlags::INTERRUPT_DISABLE) {
91+ // // BUG Used for irq handler, mitigating for now
92+ // println!("mem_read_u16: Detected break. Reading from IRQ handler...");
93+ // return 0xFFFF;
94+ // }
10795 let lo = self . mem_read ( pos) as u16 ;
10896 let hi = self . mem_read ( pos + 1 ) as u16 ;
10997 ( hi << 8 ) | ( lo as u16 )
@@ -116,21 +104,53 @@ impl CPU {
116104 self . mem_write ( pos, lo) ;
117105 self . mem_write ( pos + 1 , hi) ;
118106 }
107+ }
119108
120- // Resets RAM from $0000 to $07FF
121- // If program_start neds to be changed(eg as in snake, we subtract 1)
122- fn ram_reset ( & mut self ) {
123- for i in 0x0 ..PROGRAM_START as usize {
124- self . memory [ i] = 0 ;
125- }
109+ impl Mem for CPU {
110+ fn mem_read ( & self , addr : u16 ) -> u8 {
111+ self . bus . mem_read ( addr)
126112 }
127113
128- fn fn_reset ( & mut self ) {
129- for i in PROGRAM_START as usize .. 0xFFFF {
130- self . memory [ i] = 0 ;
114+ fn mem_write ( & mut self , addr : u16 , data : u8 ) {
115+ self . bus . mem_write ( addr, data) ;
116+ }
117+
118+ fn mem_read_u16 ( & mut self , pos : u16 ) -> u16 {
119+ self . bus . mem_read_u16 ( pos)
120+ }
121+
122+ fn mem_write_u16 ( & mut self , pos : u16 , data : u16 ) {
123+ self . bus . mem_write_u16 ( pos, data) ;
124+ }
125+ }
126+
127+ impl CPU {
128+ pub fn new ( bus : Bus ) -> Self {
129+ CPU {
130+ pc : 0 ,
131+ a : 0 ,
132+ x : 0 ,
133+ y : 0 ,
134+ sp : STACK_RESET ,
135+ flags : CpuFlags :: from_bits_truncate ( 0b0010_0100 ) ,
136+ bus : bus,
131137 }
132138 }
133139
140+ // // Resets RAM from $0000 to $07FF
141+ // // If program_start neds to be changed(eg as in snake, we subtract 1)
142+ // fn ram_reset(&mut self) {
143+ // for i in 0x0..PROGRAM_START as usize {
144+ // self.memory[i] = 0;
145+ // }
146+ // }
147+
148+ // fn fn_reset(&mut self) {
149+ // for i in PROGRAM_START as usize..0xFFFF {
150+ // self.memory[i] = 0;
151+ // }
152+ // }
153+
134154 // Restores registers and initalizes PC to the 2 byte value at 0xFFFC
135155 pub fn reset ( & mut self ) {
136156 println ! ( "reset: Initalized" ) ;
@@ -140,96 +160,27 @@ impl CPU {
140160 self . flags = CpuFlags :: from_bits_truncate ( 0b00100100 ) ;
141161 self . sp = STACK_RESET ;
142162 self . pc = self . mem_read_u16 ( 0xFFFC ) ;
143- self . ram_reset ( ) ;
144163 }
145164
146165 pub fn load ( & mut self , program : Vec < u8 > ) {
147- println ! ( "load: Initalized" ) ;
148- self . memory [ PROGRAM_START as usize ..( PROGRAM_START as usize + program. len ( ) ) ]
149- . copy_from_slice ( & program[ ..] ) ;
150- self . mem_write_u16 ( 0xFFFC , PROGRAM_START as u16 ) ; // Save reference to program in 0xFFFC
151- println ! ( "load: Finished!" ) ;
166+ for i in 0 ..( program. len ( ) as u16 ) {
167+ self . mem_write ( 0x0000 + i, program[ i as usize ] ) ;
168+ }
169+ self . mem_write_u16 ( 0xFFFC , 0x0000 ) ;
152170 }
153171
154172 // This function is meant for testing, where the test can insert their own values afterwards
155173 pub fn load_and_reset ( & mut self , program : Vec < u8 > ) {
156- self . fn_reset ( ) ;
157174 self . load ( program) ;
158175 self . reset ( ) ;
159176 }
160177
161- pub fn instruction_print ( & self , program : Vec < u8 > ) {
162- let program_len = program. len ( ) ;
163- println ! (
164- "Memory dump ({} bytes from 0x{:04X}):" ,
165- program_len, PROGRAM_START
166- ) ;
167- println ! ( "Addr | Hex | ASCII" ) ;
168- println ! ( "--------+------------------------------------------+------------------" ) ;
169-
170- for i in 0 ..program_len {
171- let addr = PROGRAM_START + i;
172-
173- // Print address at start of each line
174- if i % 16 == 0 {
175- if i > 0 {
176- print ! ( " | " ) ;
177- // Print ASCII representation for previous line
178- for j in i - 16 ..i {
179- let byte = self . memory [ PROGRAM_START + j] ;
180- if byte >= 32 && byte <= 126 {
181- print ! ( "{}" , byte as char ) ;
182- } else {
183- print ! ( "." ) ;
184- }
185- }
186- println ! ( ) ;
187- }
188- print ! ( "{:04X} | " , addr) ;
189- }
190-
191- // Print byte value
192- print ! ( "{:02X} " , self . memory[ addr] ) ;
193-
194- // Add extra space after 8 bytes
195- if i % 16 == 7 {
196- print ! ( " " ) ;
197- }
198- }
199-
200- // Print ASCII for the last line
201- let remaining = program_len % 16 ;
202- if remaining > 0 {
203- // Pad for alignment
204- for i in remaining..16 {
205- // Use 'i' instead of '_'
206- print ! ( " " ) ;
207- if remaining <= 8 && i == 7 {
208- print ! ( " " ) ;
209- }
210- }
211- }
212-
213- print ! ( " | " ) ;
214- let start_idx = program_len - ( if remaining > 0 { remaining } else { 16 } ) ;
215- for j in start_idx..program_len {
216- let byte = self . memory [ PROGRAM_START + j] ;
217- if byte >= 32 && byte <= 126 {
218- print ! ( "{}" , byte as char ) ;
219- } else {
220- print ! ( "." ) ;
221- }
222- }
223- println ! ( "\n " ) ;
224- }
225-
226178 pub fn load_and_run ( & mut self , program : Vec < u8 > ) {
227179 println ! ( "load_and_run: Initalized" ) ;
228180 self . load ( program. clone ( ) ) ;
229181 self . reset ( ) ;
230182 // USED FOR TESTING
231183 println ! ( "Printing out what's in instructions" ) ;
232- self . instruction_print ( program) ;
233184 self . run ( ) ;
234185 }
235186
@@ -252,18 +203,6 @@ impl CPU {
252203 }
253204 }
254205
255- pub fn mem_read ( & self , addr : u16 ) -> Byte {
256- let ret = self . memory [ addr as usize ] ;
257- // self.pc = self.pc.wrapping_add(1);
258- ret
259- }
260-
261- pub fn mem_write ( & mut self , addr : u16 , data : u8 ) {
262- let ret = self . memory [ addr as usize ] = data;
263- // self.pc = self.pc.wrapping_add(1);
264- ret
265- }
266-
267206 pub fn run ( & mut self ) {
268207 self . run_with_callback ( |_| { } ) ;
269208 }
@@ -299,6 +238,7 @@ impl CPU {
299238 // Top is hard coding remaining instructions
300239 if op == 0x0 {
301240 self . brk ( ) ;
241+ return ; // NOTE: Break will return without PC needing to jump anywhere
302242 } else if op == 0x20 {
303243 self . jsr ( ) ;
304244 } else if op == 0x40 {
@@ -466,10 +406,6 @@ impl CPU {
466406 fn pha ( & mut self ) {
467407 println ! ( "pha: Initalized" ) ;
468408 self . stack_push ( self . a ) ;
469- println ! (
470- "pha: Pushed {}" ,
471- self . memory[ ( 0x0100 + self . sp. wrapping_add( 1 ) as u16 ) as usize ]
472- ) ;
473409 }
474410
475411 fn pla ( & mut self ) {
0 commit comments