mirror of
https://github.com/mre/mos6502.git
synced 2024-06-04 18:29:36 +00:00
Merge 0f1c01ce60
into 4847744518
This commit is contained in:
commit
54196929d8
12
src/cpu.rs
12
src/cpu.rs
|
@ -310,6 +310,11 @@ impl<M: Bus, V: Variant> CPU<M, V> {
|
|||
self.branch_if_positive(addr);
|
||||
}
|
||||
|
||||
(Instruction::BRA, OpInput::UseRelative(rel)) => {
|
||||
let addr = self.registers.program_counter.wrapping_add(rel);
|
||||
self.branch(addr);
|
||||
}
|
||||
|
||||
(Instruction::BRK, OpInput::UseImplied) => {
|
||||
for b in self.registers.program_counter.wrapping_sub(1).to_be_bytes() {
|
||||
self.push_on_stack(b);
|
||||
|
@ -575,6 +580,9 @@ impl<M: Bus, V: Variant> CPU<M, V> {
|
|||
(Instruction::STY, OpInput::UseAddress(addr)) => {
|
||||
self.memory.set_byte(addr, self.registers.index_y);
|
||||
}
|
||||
(Instruction::STZ, OpInput::UseAddress(addr)) => {
|
||||
self.memory.set_byte(addr, 0);
|
||||
}
|
||||
|
||||
(Instruction::TAX, OpInput::UseImplied) => {
|
||||
let val = self.registers.accumulator;
|
||||
|
@ -1007,6 +1015,10 @@ impl<M: Bus, V: Variant> CPU<M, V> {
|
|||
}
|
||||
}
|
||||
|
||||
fn branch(&mut self, addr: u16) {
|
||||
self.registers.program_counter = addr;
|
||||
}
|
||||
|
||||
fn branch_if_positive(&mut self, addr: u16) {
|
||||
if !self.registers.status.contains(Status::PS_NEGATIVE) {
|
||||
self.registers.program_counter = addr;
|
||||
|
|
|
@ -55,6 +55,7 @@ pub enum Instruction {
|
|||
BMI, // Branch if Minus............... | .. ..... PC = N
|
||||
BNE, // Branch if Not Equal........... | .. ..... PC = !Z
|
||||
BPL, // Branch if Positive............ | .. ..... PC = Z
|
||||
BRA, // Unconditional BRAnch.......... | .. B.... S PC =
|
||||
BRK, // BReaK......................... | .. B.... S PC =
|
||||
BVC, // Branch if oVerflow Clear...... | .. ..... PC = !V
|
||||
BVS, // Branch if oVerflow Set........ | .. ..... PC = V
|
||||
|
@ -99,6 +100,7 @@ pub enum Instruction {
|
|||
STA, // STore Accumulator............. | .. ..... M = A
|
||||
STX, // STore X register.............. | .. ..... M = X
|
||||
STY, // STore Y register.............. | .. ..... M = Y
|
||||
STZ, // STore Zero.................... | .. ..... M = Y
|
||||
TAX, // Transfer Accumulator to X..... | N. ...Z. X = A
|
||||
TAY, // Transfer Accumulator to Y..... | N. ...Z. Y = A
|
||||
TSX, // Transfer Stack pointer to X... | N. ...Z. X = S
|
||||
|
@ -455,24 +457,15 @@ pub struct Ricoh2a03;
|
|||
|
||||
impl crate::Variant for Ricoh2a03 {
|
||||
fn decode(opcode: u8) -> Option<(Instruction, AddressingMode)> {
|
||||
match opcode {
|
||||
0x61 => Some((Instruction::ADCnd, AddressingMode::IndexedIndirectX)),
|
||||
0x65 => Some((Instruction::ADCnd, AddressingMode::ZeroPage)),
|
||||
0x69 => Some((Instruction::ADCnd, AddressingMode::Immediate)),
|
||||
0x6d => Some((Instruction::ADCnd, AddressingMode::Absolute)),
|
||||
0x71 => Some((Instruction::ADCnd, AddressingMode::IndirectIndexedY)),
|
||||
0x75 => Some((Instruction::ADCnd, AddressingMode::ZeroPageX)),
|
||||
0x79 => Some((Instruction::ADCnd, AddressingMode::AbsoluteY)),
|
||||
0x7d => Some((Instruction::ADCnd, AddressingMode::AbsoluteX)),
|
||||
0xe1 => Some((Instruction::SBCnd, AddressingMode::IndexedIndirectX)),
|
||||
0xe5 => Some((Instruction::SBCnd, AddressingMode::ZeroPage)),
|
||||
0xe9 => Some((Instruction::SBCnd, AddressingMode::Immediate)),
|
||||
0xed => Some((Instruction::SBCnd, AddressingMode::Absolute)),
|
||||
0xf1 => Some((Instruction::SBCnd, AddressingMode::IndirectIndexedY)),
|
||||
0xf5 => Some((Instruction::SBCnd, AddressingMode::ZeroPageX)),
|
||||
0xf9 => Some((Instruction::SBCnd, AddressingMode::AbsoluteY)),
|
||||
0xfd => Some((Instruction::SBCnd, AddressingMode::AbsoluteX)),
|
||||
_ => Nmos6502::decode(opcode),
|
||||
// It's the same as on NMOS, but doesn't support decimal mode.
|
||||
match Nmos6502::decode(opcode) {
|
||||
Some((Instruction::ADC, addressing_mode)) => {
|
||||
Some((Instruction::ADCnd, addressing_mode))
|
||||
}
|
||||
Some((Instruction::SBC, addressing_mode)) => {
|
||||
Some((Instruction::SBCnd, addressing_mode))
|
||||
}
|
||||
something_else => something_else,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -483,13 +476,10 @@ pub struct RevisionA;
|
|||
|
||||
impl crate::Variant for RevisionA {
|
||||
fn decode(opcode: u8) -> Option<(Instruction, AddressingMode)> {
|
||||
match opcode {
|
||||
0x66 => None,
|
||||
0x6a => None,
|
||||
0x6e => None,
|
||||
0x76 => None,
|
||||
0x7e => None,
|
||||
_ => Nmos6502::decode(opcode),
|
||||
// It's the same as on NMOS, but has no ROR instruction.
|
||||
match Nmos6502::decode(opcode) {
|
||||
Some((Instruction::ROR, _)) => None,
|
||||
something_else => something_else,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,7 +491,14 @@ impl crate::Variant for Cmos6502 {
|
|||
fn decode(opcode: u8) -> Option<(Instruction, AddressingMode)> {
|
||||
// TODO: We obviously need to add the other CMOS instructions here.
|
||||
match opcode {
|
||||
0x1a => Some((Instruction::INC, AddressingMode::Accumulator)),
|
||||
0x3a => Some((Instruction::DEC, AddressingMode::Accumulator)),
|
||||
0x6c => Some((Instruction::JMP, AddressingMode::Indirect)),
|
||||
0x80 => Some((Instruction::BRA, AddressingMode::Relative)),
|
||||
0x64 => Some((Instruction::STZ, AddressingMode::ZeroPage)),
|
||||
0x74 => Some((Instruction::STZ, AddressingMode::ZeroPageX)),
|
||||
0x9c => Some((Instruction::STZ, AddressingMode::Absolute)),
|
||||
0x9e => Some((Instruction::STZ, AddressingMode::AbsoluteX)),
|
||||
_ => Nmos6502::decode(opcode),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user