@@ -51,9 +51,8 @@ pub enum AddressingMode {
51
51
pub enum Flag {
52
52
Negative ,
53
53
Overflow ,
54
- // TODO
55
- // Break,
56
- // Break2,
54
+ Break2 ,
55
+ Break ,
57
56
Decimal ,
58
57
Interrupt ,
59
58
Zero ,
@@ -218,6 +217,7 @@ impl Cpu {
218
217
self . y = 0 ;
219
218
self . sp = 0xff ;
220
219
self . pc = self . mem_read_u16 ( 0xFFFC ) ;
220
+ self . status = 0 ; // TODO: is this the correct initial state? I see various tests where both break flags are on
221
221
}
222
222
223
223
pub fn run_with_callback < F > ( & mut self , mut callback : F )
@@ -232,6 +232,8 @@ impl Cpu {
232
232
233
233
if let Some ( ( name, size, mode) ) = lookup_opcode ( opcode) {
234
234
match name {
235
+ OpName :: TODO => todo ! ( ) ,
236
+
235
237
OpName :: ASL => self . asl ( & mode) ,
236
238
OpName :: LDA => self . lda ( & mode) ,
237
239
OpName :: LDX => self . ldx ( & mode) ,
@@ -240,7 +242,6 @@ impl Cpu {
240
242
OpName :: STA => self . sta ( & mode) ,
241
243
OpName :: STX => self . stx ( & mode) ,
242
244
OpName :: STY => self . sty ( & mode) ,
243
- OpName :: TODO => todo ! ( ) ,
244
245
OpName :: BIT => self . bit ( & mode) ,
245
246
OpName :: NOP => self . nop ( ) ,
246
247
OpName :: TXS => self . txs ( ) ,
@@ -250,115 +251,19 @@ impl Cpu {
250
251
OpName :: PHP => self . php ( ) ,
251
252
OpName :: PLP => self . plp ( ) ,
252
253
OpName :: ORA => self . ora ( & mode) ,
254
+ OpName :: AND => self . and ( & mode) ,
255
+ OpName :: ADC => self . adc ( & mode) ,
256
+ OpName :: EOR => self . eor ( & mode) ,
257
+ OpName :: CMP => self . cmp ( & mode) ,
258
+ OpName :: CPX => self . cpx ( & mode) ,
259
+ OpName :: CPY => self . cpy ( & mode) ,
253
260
}
254
261
self . pc += size - 1 ;
255
262
256
263
continue ;
257
264
}
258
265
259
266
match opcode {
260
- // AND
261
- 0x29 => {
262
- self . and ( & AddressingMode :: Immediate ) ;
263
- self . pc += 1 ;
264
- }
265
- 0x25 => {
266
- self . and ( & AddressingMode :: ZeroPage ) ;
267
- self . pc += 1 ;
268
- }
269
- 0x35 => {
270
- self . and ( & AddressingMode :: ZeroPageX ) ;
271
- self . pc += 1 ;
272
- }
273
- 0x2D => {
274
- self . and ( & AddressingMode :: Absolute ) ;
275
- self . pc += 2 ;
276
- }
277
- 0x3D => {
278
- self . and ( & AddressingMode :: AbsoluteX ) ;
279
- self . pc += 2 ;
280
- }
281
- 0x39 => {
282
- self . and ( & AddressingMode :: AbsoluteY ) ;
283
- self . pc += 2 ;
284
- }
285
- 0x21 => {
286
- self . and ( & AddressingMode :: IndirectX ) ;
287
- self . pc += 1 ;
288
- }
289
- 0x31 => {
290
- self . and ( & AddressingMode :: IndirectY ) ;
291
- self . pc += 1 ;
292
- }
293
-
294
- // ADC
295
- 0x69 => {
296
- self . adc ( & AddressingMode :: Immediate ) ;
297
- self . pc += 1 ;
298
- }
299
- 0x65 => {
300
- self . adc ( & AddressingMode :: ZeroPage ) ;
301
- self . pc += 1 ;
302
- }
303
- 0x75 => {
304
- self . adc ( & AddressingMode :: ZeroPageX ) ;
305
- self . pc += 1 ;
306
- }
307
- 0x6D => {
308
- self . adc ( & AddressingMode :: Absolute ) ;
309
- self . pc += 2 ;
310
- }
311
- 0x7D => {
312
- self . adc ( & AddressingMode :: AbsoluteX ) ;
313
- self . pc += 2 ;
314
- }
315
- 0x79 => {
316
- self . adc ( & AddressingMode :: AbsoluteY ) ;
317
- self . pc += 2 ;
318
- }
319
- 0x61 => {
320
- self . adc ( & AddressingMode :: IndirectX ) ;
321
- self . pc += 1 ;
322
- }
323
- 0x71 => {
324
- self . adc ( & AddressingMode :: IndirectY ) ;
325
- self . pc += 1 ;
326
- }
327
-
328
- // EOR
329
- 0x49 => {
330
- self . eor ( & AddressingMode :: Immediate ) ;
331
- self . pc += 1 ;
332
- }
333
- 0x45 => {
334
- self . eor ( & AddressingMode :: ZeroPage ) ;
335
- self . pc += 1 ;
336
- }
337
- 0x55 => {
338
- self . eor ( & AddressingMode :: ZeroPageX ) ;
339
- self . pc += 1 ;
340
- }
341
- 0x4D => {
342
- self . eor ( & AddressingMode :: Absolute ) ;
343
- self . pc += 2 ;
344
- }
345
- 0x5D => {
346
- self . eor ( & AddressingMode :: AbsoluteX ) ;
347
- self . pc += 2 ;
348
- }
349
- 0x59 => {
350
- self . eor ( & AddressingMode :: AbsoluteY ) ;
351
- self . pc += 2 ;
352
- }
353
- 0x41 => {
354
- self . eor ( & AddressingMode :: IndirectX ) ;
355
- self . pc += 1 ;
356
- }
357
- 0x51 => {
358
- self . eor ( & AddressingMode :: IndirectY ) ;
359
- self . pc += 1 ;
360
- }
361
-
362
267
// Branch Instructions
363
268
0x10 => self . bpl ( ) ,
364
269
0x30 => self . bmi ( ) ,
@@ -369,68 +274,6 @@ impl Cpu {
369
274
0xD0 => self . bne ( ) ,
370
275
0xF0 => self . beq ( ) ,
371
276
372
- // CMP
373
- 0xC9 => {
374
- self . cmp ( & AddressingMode :: Immediate ) ;
375
- self . pc += 1 ;
376
- }
377
- 0xC5 => {
378
- self . cmp ( & AddressingMode :: ZeroPage ) ;
379
- self . pc += 1 ;
380
- }
381
- 0xD5 => {
382
- self . cmp ( & AddressingMode :: ZeroPageX ) ;
383
- self . pc += 1 ;
384
- }
385
- 0xCD => {
386
- self . cmp ( & AddressingMode :: Absolute ) ;
387
- self . pc += 2 ;
388
- }
389
- 0xDD => {
390
- self . cmp ( & AddressingMode :: AbsoluteX ) ;
391
- self . pc += 2 ;
392
- }
393
- 0xD9 => {
394
- self . cmp ( & AddressingMode :: AbsoluteY ) ;
395
- self . pc += 2 ;
396
- }
397
- 0xC1 => {
398
- self . cmp ( & AddressingMode :: IndirectX ) ;
399
- self . pc += 1 ;
400
- }
401
- 0xD1 => {
402
- self . cmp ( & AddressingMode :: IndirectY ) ;
403
- self . pc += 1 ;
404
- }
405
-
406
- // CPX
407
- 0xE0 => {
408
- self . cpx ( & AddressingMode :: Immediate ) ;
409
- self . pc += 1 ;
410
- }
411
- 0xE4 => {
412
- self . cpx ( & AddressingMode :: ZeroPage ) ;
413
- self . pc += 1 ;
414
- }
415
- 0xEC => {
416
- self . cpx ( & AddressingMode :: Absolute ) ;
417
- self . pc += 2 ;
418
- }
419
-
420
- // CPY
421
- 0xC0 => {
422
- self . cpy ( & AddressingMode :: Immediate ) ;
423
- self . pc += 1 ;
424
- }
425
- 0xC4 => {
426
- self . cpy ( & AddressingMode :: ZeroPage ) ;
427
- self . pc += 1 ;
428
- }
429
- 0xCC => {
430
- self . cpy ( & AddressingMode :: Absolute ) ;
431
- self . pc += 2 ;
432
- }
433
-
434
277
// DEC
435
278
0xC6 => {
436
279
self . dec ( & AddressingMode :: ZeroPage ) ;
@@ -468,7 +311,10 @@ impl Cpu {
468
311
}
469
312
470
313
// BRK
471
- 0x00 => return ,
314
+ 0x00 => {
315
+ // self.set_flag(Flag::Break, true);
316
+ return ;
317
+ }
472
318
473
319
// JSR
474
320
0x20 => {
@@ -945,6 +791,8 @@ impl Cpu {
945
791
fn rti ( & mut self ) {
946
792
self . status = self . stack_pop ( ) ;
947
793
self . pc = self . stack_pop_u16 ( ) ;
794
+ // self.set_flag(Flag::Break, false);
795
+ // self.set_flag(Flag::Break2, true);
948
796
}
949
797
950
798
/// SBC (SuBtract with Carry)
@@ -1009,12 +857,15 @@ impl Cpu {
1009
857
1010
858
/// PHP (PusH Processor status)
1011
859
fn php ( & mut self ) {
1012
- self . stack_push ( self . status )
860
+ self . stack_push ( self . status ) ;
861
+ // self.set_flag(Flag::Break, true);
1013
862
}
1014
863
1015
864
/// PLP (PuLl Processor status)
1016
865
fn plp ( & mut self ) {
1017
- self . status = self . stack_pop ( )
866
+ self . status = self . stack_pop ( ) ;
867
+ // self.set_flag(Flag::Interrupt, true);
868
+ // self.set_flag(Flag::Break, true);
1018
869
}
1019
870
1020
871
//
@@ -1036,8 +887,8 @@ impl Cpu {
1036
887
Flag :: Zero => 1 ,
1037
888
Flag :: Interrupt => 2 ,
1038
889
Flag :: Decimal => 3 ,
1039
- // Flag::Break => 4,
1040
- // Flag::Break2 => 5,
890
+ Flag :: Break => 4 ,
891
+ Flag :: Break2 => 5 ,
1041
892
Flag :: Overflow => 6 ,
1042
893
Flag :: Negative => 7 ,
1043
894
} ;
@@ -1058,8 +909,8 @@ impl Cpu {
1058
909
Flag :: Zero => 1 ,
1059
910
Flag :: Interrupt => 2 ,
1060
911
Flag :: Decimal => 3 ,
1061
- // Flag::Break => 4,
1062
- // Flag::Break2 => 5,
912
+ Flag :: Break => 4 ,
913
+ Flag :: Break2 => 5 ,
1063
914
Flag :: Overflow => 6 ,
1064
915
Flag :: Negative => 7 ,
1065
916
} ;
@@ -1078,30 +929,33 @@ impl Cpu {
1078
929
1079
930
//// Address syntax by mode looks like:
1080
931
1081
- // MODE SYNTAX HEX LEN TIM
1082
- // Immediate SBC #$44 $E9 2 2
1083
- // Zero Page SBC $44 $E5 2 3
1084
- // Zero Page,X SBC $44,X $F5 2 4
1085
- // Absolute SBC $4400 $ED 3 4
1086
- // Absolute,X SBC $4400,X $FD 3 4+
1087
- // Absolute,Y SBC $4400,Y $F9 3 4+
1088
- // Indirect,X SBC ($44,X) $E1 2 6
1089
- // Indirect,Y SBC ($44),Y $F1 2 5+
1090
-
1091
- println ! ( "code = {:02x}" , code) ;
1092
932
if let Some ( op) = lookup_opcode ( code) {
1093
933
let tla = format ! ( "{}" , op. 0 ) ;
1094
934
let addr_block = match op. 2 {
1095
- // AddressingMode::Immediate => todo!(),
1096
- // AddressingMode::ZeroPage => todo!(),
1097
- // AddressingMode::ZeroPageX => todo!(),
1098
- // AddressingMode::ZeroPageY => todo!(),
1099
- // AddressingMode::Absolute => todo!(),
1100
- // AddressingMode::AbsoluteX => todo!(),
1101
- // AddressingMode::AbsoluteY => todo!(),
1102
- // AddressingMode::IndirectX => todo!(),
935
+ AddressingMode :: Immediate => format ! ( "#${:02x}" , param1) ,
936
+ AddressingMode :: ZeroPage => format ! ( "${:02x}" , param1) ,
937
+ AddressingMode :: ZeroPageX => format ! ( "${:02x},X" , param1) ,
938
+ AddressingMode :: ZeroPageY => format ! ( "${:02x},Y" , param1) ,
939
+ AddressingMode :: Absolute => format ! ( "${:02x}{:02x}" , param2, param1) ,
940
+ AddressingMode :: AbsoluteX => format ! ( "${:02x}{:02x},X" , param2, param1) ,
941
+ AddressingMode :: AbsoluteY => format ! ( "${:02x}{:02x},Y" , param2, param1) ,
942
+ AddressingMode :: IndirectX => {
943
+ let added = param1. wrapping_add ( self . x ) ;
944
+ let target = self . mem_read_u16 ( added as u16 ) ;
945
+ let data = self . mem_read ( target) ;
946
+ format ! (
947
+ "(${:02x},X) @ {:02x} = {:04x} = {:02X}" ,
948
+ param1, added, target, data
949
+ )
950
+ }
1103
951
AddressingMode :: IndirectY => {
1104
- format ! ( "(${:02x}),Y = {:04x} @ {:04x}" , param1, param1, param1)
952
+ let val = self . mem_read_u16 ( param1 as u16 ) ;
953
+ let val_plus_y = val + ( self . y as u16 ) ;
954
+ let data = self . mem_read ( val_plus_y) ;
955
+ format ! (
956
+ "(${:02x}),Y = {:04x} @ {:04x} = {:02X}" ,
957
+ param1, val, val_plus_y, data
958
+ )
1105
959
}
1106
960
// AddressingMode::None => todo!(),
1107
961
// AddressingMode::Indirect => todo!(),
@@ -1135,7 +989,7 @@ impl Cpu {
1135
989
)
1136
990
. to_string ( )
1137
991
} else {
1138
- "" . to_string ( )
992
+ "UNKNOWN OP: TODO " . to_string ( )
1139
993
}
1140
994
}
1141
995
}
0 commit comments