diff --git a/.bad/.gitignore b/.bad/.gitignore
new file mode 100644
index 0000000..b58b603
--- /dev/null
+++ b/.bad/.gitignore
@@ -0,0 +1,5 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.bad/modules.xml b/.bad/modules.xml
new file mode 100644
index 0000000..b4bd04a
--- /dev/null
+++ b/.bad/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.bad/mos6502.iml b/.bad/mos6502.iml
new file mode 100644
index 0000000..02e7b41
--- /dev/null
+++ b/.bad/mos6502.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.bad/vcs.xml b/.bad/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.bad/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/mos6502.iml b/.idea/mos6502.iml
index fa80a9b..95a2172 100644
--- a/.idea/mos6502.iml
+++ b/.idea/mos6502.iml
@@ -6,6 +6,8 @@
+
+
diff --git a/cli/src/bin/decode.rs b/cli/src/bin/decode.rs
index fa5a43e..fb6e2b6 100644
--- a/cli/src/bin/decode.rs
+++ b/cli/src/bin/decode.rs
@@ -1,11 +1,22 @@
use core::instruction::Instruction;
use core::address_mode::AddressMode;
+use core::operand::Operand;
+use core::operation::Operation;
fn main() {
println!("Taxation is Theft");
- // Instruction::from_bytes(vec![0b11100011]);
+ let instructions = vec![(
+ Instruction {
+ op: Operation::NOP,
+ mode: AddressMode::Implied,
+ operand: Operand::None,
+ }, &[0xea]
+ )];
- // let instruction = Instruction::ADC(AddressMode::Immediate);
- // println!("Instruction = {:?}", instruction.to_string());
+ for (op, bytes) in instructions {
+ assert_eq!(Instruction::decode(bytes), Some(op));
+ }
+ // let instruction = Instruction::decode(&[0xea]);
+ // println!("NOP Decoded -> {:?}", instruction);
}
diff --git a/core/src/instruction.rs b/core/src/instruction.rs
index fa20365..e931014 100644
--- a/core/src/instruction.rs
+++ b/core/src/instruction.rs
@@ -15,6 +15,7 @@ pub struct Instruction {
impl Instruction {
pub fn decode(bytes: &[u8]) -> Option {
+ println!("DECODING : {bytes:?}");
let opcode = bytes.get(0).copied()?;
let info = INSTRUCTION_TABLE[opcode as usize]?;
@@ -25,14 +26,18 @@ impl Instruction {
let hi = *bytes.get(2)?;
Operand::Word(u16::from_le_bytes([lo, hi]))
}
- _ => return None,
+ _ => Operand::None,
};
- Some(Instruction {
+ let return_value = Some(Instruction {
op: info.operation,
mode: info.mode,
operand,
- })
+ });
+
+ println!("RETURNING: {:?}", return_value);
+
+ return_value
}
}
@@ -41,7 +46,7 @@ impl Instruction {
mod test {
use crate::address_mode::AddressMode::*;
use crate::instruction::Instruction;
- use crate::operation::Operation::ADC;
+ use crate::operation::Operation::{ADC, INY, LSR};
use super::*;
#[test]
@@ -75,14 +80,14 @@ mod test {
(vec![0x24, 0xab], Instruction { op: BIT, mode: ZeroPage, operand: Operand::Byte(0xab) }),
(vec![0x2c, 0xcd, 0xab], Instruction { op: BIT, mode: Absolute, operand: Operand::Word(0xabcd) }),
// BCC, BCS, BEQ, BMI, BNE, BPL, BVC, BVS
- (vec![0x10, 0xab], Instruction { op: BPL, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0x30, 0xab], Instruction { op: BMI, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0x50, 0xab], Instruction { op: BVC, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0x70, 0xab], Instruction { op: BVS, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0x90, 0xab], Instruction { op: BCC, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0xb0, 0xab], Instruction { op: BCS, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0xd0, 0xab], Instruction { op: BNE, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0xf0, 0xab], Instruction { op: BEQ, mode: Immediate, operand: Operand::Byte(0xab) }),
+ (vec![0x10, 0xab], Instruction { op: BPL, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0x30, 0xab], Instruction { op: BMI, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0x50, 0xab], Instruction { op: BVC, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0x70, 0xab], Instruction { op: BVS, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0x90, 0xab], Instruction { op: BCC, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0xb0, 0xab], Instruction { op: BCS, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0xd0, 0xab], Instruction { op: BNE, mode: Implied, operand: Operand::Byte(0xab) }),
+ (vec![0xf0, 0xab], Instruction { op: BEQ, mode: Implied, operand: Operand::Byte(0xab) }),
// BRK
(vec![0x00], Instruction { op: BRK, mode: Implied, operand: Operand::None }),
// CLC, CLD, CLI, CLV
@@ -129,7 +134,7 @@ mod test {
(vec![0xee, 0xcd, 0xab], Instruction { op: INC, mode: Absolute, operand: Operand::Word(0xabcd) }),
(vec![0xfe, 0xcd, 0xab], Instruction { op: INC, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
(vec![0xe8], Instruction { op: INX, mode: Implied, operand: Operand::None }),
- (vec![0xc8], Instruction { op: INX, mode: Implied, operand: Operand::None }),
+ (vec![0xc8], Instruction { op: INY, mode: Implied, operand: Operand::None }),
// JMP, JSR
(vec![0x4c, 0xcd, 0xab], Instruction { op: JMP, mode: Absolute, operand: Operand::Word(0xabcd) }),
(vec![0x6c, 0xcd, 0xab], Instruction { op: JMP, mode: Indirect, operand: Operand::Word(0xabcd) }),
@@ -146,21 +151,21 @@ mod test {
// LDX
(vec![0xa2, 0xab], Instruction { op: LDX, mode: Immediate, operand: Operand::Byte(0xab) }),
(vec![0xa6, 0xab], Instruction { op: LDX, mode: ZeroPage, operand: Operand::Byte(0xab) }),
- (vec![0xb6, 0xab], Instruction { op: LDX, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
+ (vec![0xb6, 0xab], Instruction { op: LDX, mode: ZeroPageY, operand: Operand::Byte(0xab) }),
(vec![0xae, 0xcd, 0xab], Instruction { op: LDX, mode: Absolute, operand: Operand::Word(0xabcd) }),
- (vec![0xbe, 0xcd, 0xab], Instruction { op: LDX, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
+ (vec![0xbe, 0xcd, 0xab], Instruction { op: LDX, mode: AbsoluteY, operand: Operand::Word(0xabcd) }),
// LDY
- (vec![0xa2, 0xab], Instruction { op: LDY, mode: Immediate, operand: Operand::Byte(0xab) }),
- (vec![0xa6, 0xab], Instruction { op: LDY, mode: ZeroPage, operand: Operand::Byte(0xab) }),
- (vec![0xb6, 0xab], Instruction { op: LDY, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
- (vec![0xae, 0xcd, 0xab], Instruction { op: LDY, mode: Absolute, operand: Operand::Word(0xabcd) }),
- (vec![0xbe, 0xcd, 0xab], Instruction { op: LDY, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
+ (vec![0xa0, 0xab], Instruction { op: LDY, mode: Immediate, operand: Operand::Byte(0xab) }),
+ (vec![0xa4, 0xab], Instruction { op: LDY, mode: ZeroPage, operand: Operand::Byte(0xab) }),
+ (vec![0xb4, 0xab], Instruction { op: LDY, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
+ (vec![0xac, 0xcd, 0xab], Instruction { op: LDY, mode: Absolute, operand: Operand::Word(0xabcd) }),
+ (vec![0xbc, 0xcd, 0xab], Instruction { op: LDY, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
// LSR
- (vec![0x4a, 0xab], Instruction { op: LDY, mode: Accumulator, operand: Operand::Byte(0xab) }),
- (vec![0x46, 0xab], Instruction { op: LDY, mode: ZeroPage, operand: Operand::Byte(0xab) }),
- (vec![0x56, 0xab], Instruction { op: LDY, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
- (vec![0x4e, 0xcd, 0xab], Instruction { op: LDY, mode: Absolute, operand: Operand::Word(0xabcd) }),
- (vec![0x5e, 0xcd, 0xab], Instruction { op: LDY, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
+ (vec![0x4a], Instruction { op: LSR, mode: Accumulator, operand: Operand::None }),
+ (vec![0x46, 0xab], Instruction { op: LSR, mode: ZeroPage, operand: Operand::Byte(0xab) }),
+ (vec![0x56, 0xab], Instruction { op: LSR, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
+ (vec![0x4e, 0xcd, 0xab], Instruction { op: LSR, mode: Absolute, operand: Operand::Word(0xabcd) }),
+ (vec![0x5e, 0xcd, 0xab], Instruction { op: LSR, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
// NOP
(vec![0xea], Instruction { op: NOP, mode: Implied, operand: Operand::None }),
// ORA
@@ -178,13 +183,13 @@ mod test {
(vec![0x68], Instruction { op: PLA, mode: Implied, operand: Operand::None }),
(vec![0x28], Instruction { op: PLP, mode: Implied, operand: Operand::None }),
// ROL
- (vec![0x2a, 0xab], Instruction { op: ROL, mode: Accumulator, operand: Operand::Byte(0xab) }),
+ (vec![0x2a], Instruction { op: ROL, mode: Accumulator, operand: Operand::None }),
(vec![0x26, 0xab], Instruction { op: ROL, mode: ZeroPage, operand: Operand::Byte(0xab) }),
(vec![0x36, 0xab], Instruction { op: ROL, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
(vec![0x2e, 0xcd, 0xab], Instruction { op: ROL, mode: Absolute, operand: Operand::Word(0xabcd) }),
(vec![0x3e, 0xcd, 0xab], Instruction { op: ROL, mode: AbsoluteX, operand: Operand::Word(0xabcd) }),
// ROR
- (vec![0x6a, 0xab], Instruction { op: ROR, mode: Accumulator, operand: Operand::Byte(0xab) }),
+ (vec![0x6a], Instruction { op: ROR, mode: Accumulator, operand: Operand::None }),
(vec![0x66, 0xab], Instruction { op: ROR, mode: ZeroPage, operand: Operand::Byte(0xab) }),
(vec![0x76, 0xab], Instruction { op: ROR, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
(vec![0x6e, 0xcd, 0xab], Instruction { op: ROR, mode: Absolute, operand: Operand::Word(0xabcd) }),
@@ -215,7 +220,7 @@ mod test {
(vec![0x91, 0xab], Instruction { op: STA, mode: IndirectY, operand: Operand::Byte(0xab) }),
// STX
(vec![0x86, 0xab], Instruction { op: STX, mode: ZeroPage, operand: Operand::Byte(0xab) }),
- (vec![0x96, 0xab], Instruction { op: STX, mode: ZeroPageX, operand: Operand::Byte(0xab) }),
+ (vec![0x96, 0xab], Instruction { op: STX, mode: ZeroPageY, operand: Operand::Byte(0xab) }),
(vec![0x8e, 0xcd, 0xab], Instruction { op: STX, mode: Absolute, operand: Operand::Word(0xabcd) }),
// STY
(vec![0x84, 0xab], Instruction { op: STY, mode: ZeroPage, operand: Operand::Byte(0xab) }),
@@ -230,13 +235,12 @@ mod test {
(vec![0x98], Instruction { op: TYA, mode: Implied, operand: Operand::None })
];
for (bytes, instruction) in params {
- let result = Instruction::decode(&bytes);
- if let Some(instruction) = result {
- assert_eq!(Instruction::decode(&bytes).unwrap(), instruction)
+ let result1 = Instruction::decode(&bytes);
+ if let Some(instruction1) = result1 {
+ assert_eq!(instruction, instruction1)
} else {
println!("Failed to decode {:?}", bytes);
}
-
}
}
-}
\ No newline at end of file
+}
diff --git a/core/src/instruction_table.rs b/core/src/instruction_table.rs
index 094c7ce..2aac88d 100644
--- a/core/src/instruction_table.rs
+++ b/core/src/instruction_table.rs
@@ -256,13 +256,13 @@ pub const INSTRUCTION_TABLE: [Option; 256] = {
table[ISA_OP_CMP_ABSX as usize] = Some(OpInfo {
operation: CMP,
mode: AddressMode::AbsoluteX,
- length: 2,
+ length: 3,
cycles: 4,
});
table[ISA_OP_CMP_ABSY as usize] = Some(OpInfo {
operation: CMP,
mode: AddressMode::AbsoluteY,
- length: 2,
+ length: 3,
cycles: 4,
});
table[ISA_OP_CMP_INDX as usize] = Some(OpInfo {
diff --git a/core/src/mos6502cpu.rs b/core/src/mos6502cpu.rs
index faf2537..aa95535 100644
--- a/core/src/mos6502cpu.rs
+++ b/core/src/mos6502cpu.rs
@@ -1,3 +1,4 @@
+use crate::instruction::Instruction;
use crate::mos6502flags::{Mos6502Flag, Mos6502Flags};
pub const SIZE_1KB: usize = 1024 * 1024;
@@ -103,6 +104,15 @@ impl Mos6502Cpu {
/// Returns
/// AddressBus, DataBus, RW flag
pub fn tick(&mut self) -> (u16, u8, bool) {
+
+ let num_microsteps_left = 0;
+
+ if num_microsteps_left == 0 {
+ // load the microstep buffer with what steps to run
+ // set the counter to the number of steps left
+ }
+ // run 1 microcode step
+
(0,0,false)
}
@@ -114,4 +124,8 @@ impl Mos6502Cpu {
pub fn dump_data(&self) -> ( u16, u8, u8, u8, u16, u8) {
(self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus)
}
+
+ fn run_microstep(&self, instruction: Instruction, step: u8) {
+
+ }
}