Skip to content

Commit 710623d

Browse files
committed
more opcodes, trace getting closer
also exploring BREAK and status behavior to try to get the registers correct in trace
1 parent 1279376 commit 710623d

File tree

2 files changed

+101
-208
lines changed

2 files changed

+101
-208
lines changed

src/core.rs

Lines changed: 50 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ pub enum AddressingMode {
5151
pub enum Flag {
5252
Negative,
5353
Overflow,
54-
// TODO
55-
// Break,
56-
// Break2,
54+
Break2,
55+
Break,
5756
Decimal,
5857
Interrupt,
5958
Zero,
@@ -218,6 +217,7 @@ impl Cpu {
218217
self.y = 0;
219218
self.sp = 0xff;
220219
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
221221
}
222222

223223
pub fn run_with_callback<F>(&mut self, mut callback: F)
@@ -232,6 +232,8 @@ impl Cpu {
232232

233233
if let Some((name, size, mode)) = lookup_opcode(opcode) {
234234
match name {
235+
OpName::TODO => todo!(),
236+
235237
OpName::ASL => self.asl(&mode),
236238
OpName::LDA => self.lda(&mode),
237239
OpName::LDX => self.ldx(&mode),
@@ -240,7 +242,6 @@ impl Cpu {
240242
OpName::STA => self.sta(&mode),
241243
OpName::STX => self.stx(&mode),
242244
OpName::STY => self.sty(&mode),
243-
OpName::TODO => todo!(),
244245
OpName::BIT => self.bit(&mode),
245246
OpName::NOP => self.nop(),
246247
OpName::TXS => self.txs(),
@@ -250,115 +251,19 @@ impl Cpu {
250251
OpName::PHP => self.php(),
251252
OpName::PLP => self.plp(),
252253
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),
253260
}
254261
self.pc += size - 1;
255262

256263
continue;
257264
}
258265

259266
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-
362267
// Branch Instructions
363268
0x10 => self.bpl(),
364269
0x30 => self.bmi(),
@@ -369,68 +274,6 @@ impl Cpu {
369274
0xD0 => self.bne(),
370275
0xF0 => self.beq(),
371276

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-
434277
// DEC
435278
0xC6 => {
436279
self.dec(&AddressingMode::ZeroPage);
@@ -468,7 +311,10 @@ impl Cpu {
468311
}
469312

470313
// BRK
471-
0x00 => return,
314+
0x00 => {
315+
// self.set_flag(Flag::Break, true);
316+
return;
317+
}
472318

473319
// JSR
474320
0x20 => {
@@ -945,6 +791,8 @@ impl Cpu {
945791
fn rti(&mut self) {
946792
self.status = self.stack_pop();
947793
self.pc = self.stack_pop_u16();
794+
// self.set_flag(Flag::Break, false);
795+
// self.set_flag(Flag::Break2, true);
948796
}
949797

950798
/// SBC (SuBtract with Carry)
@@ -1009,12 +857,15 @@ impl Cpu {
1009857

1010858
/// PHP (PusH Processor status)
1011859
fn php(&mut self) {
1012-
self.stack_push(self.status)
860+
self.stack_push(self.status);
861+
// self.set_flag(Flag::Break, true);
1013862
}
1014863

1015864
/// PLP (PuLl Processor status)
1016865
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);
1018869
}
1019870

1020871
//
@@ -1036,8 +887,8 @@ impl Cpu {
1036887
Flag::Zero => 1,
1037888
Flag::Interrupt => 2,
1038889
Flag::Decimal => 3,
1039-
// Flag::Break => 4,
1040-
// Flag::Break2 => 5,
890+
Flag::Break => 4,
891+
Flag::Break2 => 5,
1041892
Flag::Overflow => 6,
1042893
Flag::Negative => 7,
1043894
};
@@ -1058,8 +909,8 @@ impl Cpu {
1058909
Flag::Zero => 1,
1059910
Flag::Interrupt => 2,
1060911
Flag::Decimal => 3,
1061-
// Flag::Break => 4,
1062-
// Flag::Break2 => 5,
912+
Flag::Break => 4,
913+
Flag::Break2 => 5,
1063914
Flag::Overflow => 6,
1064915
Flag::Negative => 7,
1065916
};
@@ -1078,30 +929,33 @@ impl Cpu {
1078929

1079930
//// Address syntax by mode looks like:
1080931

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);
1092932
if let Some(op) = lookup_opcode(code) {
1093933
let tla = format!("{}", op.0);
1094934
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+
}
1103951
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+
)
1105959
}
1106960
// AddressingMode::None => todo!(),
1107961
// AddressingMode::Indirect => todo!(),
@@ -1135,7 +989,7 @@ impl Cpu {
1135989
)
1136990
.to_string()
1137991
} else {
1138-
"".to_string()
992+
"UNKNOWN OP: TODO".to_string()
1139993
}
1140994
}
1141995
}

0 commit comments

Comments
 (0)