amw-zero/6502-rs — pull request #9 by typelist (2014-10-04 21:09:53+00:00)
Title: Orthogonal AddressingMode handling; implement all addressing modes for ADC, LDA, LDX, LDY

We can factor out the addressing-mode-processing code that's common to all instructions by letting the addressing modes have different kinds of output.

```rust
pub enum AMOut /* poorly named, sorry */ {
UseImplied,
UseImmediate(u8),
UseRelative(i8),
UseAddress(Address),
}

impl AddressingMode {
pub fn process(self, machine: &Machine, arr: &[u8]) -> AMOut {
// ...
}
}
```

This means we only need to handle 2 cases for ADC when executing the instruction. Either it operates on an address (no matter how we got that address--that's the AddressingMode's job), or it operates on an immediate value:

```rust
impl Machine {
pub fn execute_instruction(&mut self, decoded_instr: DecodedInstr) {
match decoded_instr {
(ADC, UseImmediate(val)) => {
self.add_with_carry(val as i8);
},
(ADC, UseAddress(addr)) => {
let val = self.memory.get_byte(addr) as i8;
self.add_with_carry(val);
},

(LDA, UseImmediate(val)) => {
self.load_accumulator(val as i8);
},
(LDA, UseAddress(addr)) => {
let val = self.memory.get_byte(addr);
self.load_accumulator(val as i8);
},

(_, _) => {
// could fail! here
}
}
}

// ...
}
```

The logic that's common to LDA and ADC could be factored out more, but it's a start.