From 2068cf08e1bfa7aed25c54f4e073b764493a1988 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 17 Apr 2025 23:28:39 +0800 Subject: [PATCH] Construct operands src/dst from instruction definition, wip --- src/sim6502.rs | 57 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/sim6502.rs b/src/sim6502.rs index 9c9e546..178a0f5 100644 --- a/src/sim6502.rs +++ b/src/sim6502.rs @@ -4,9 +4,10 @@ use InstructionName::*; use AddressingShort::*; use Register::*; use Flag::*; +use Operand::*; pub enum Addressing { - Implicit, + Implied, Accumulator, Immediate, ZeroPage, @@ -85,6 +86,9 @@ impl_indexing!([u8; 4], Register); #[derive(Debug)] pub enum Operand { None, + Immediate(u8), + MemAddr(u16), + Reg(Register) } pub struct Cpu { @@ -136,7 +140,6 @@ impl Cpu { } } - pub fn rotate_shift(&mut self, inst: &Instruction, head_bit: u8, tail_bit: u8) { let val = self.load(&inst.src_opr); let bit = val & head_bit; @@ -190,6 +193,23 @@ const INSTRUCTION_DEFS: [InstructionDefinition; 256] = instruction_defs![ /*Fx*/{BEQ,Rel},{SBC,InY},{KIL,Imp},{ISC,InY},{NOP,ZPX},{SBC,ZPX},{INC,ZPX},{ISC,ZPX},{SED,Imp},{SBC,AbY},{NOP,Imp},{ISC,AbY},{NOP,AbX},{SBC,AbX},{INC,AbX},{ISC,AbX}, ]; +fn get_operands(data: &[u8], def: &InstructionDefinition, addr: AddressingShort) -> (Operand, Operand) { + let src = match (addr, def.name) { + (Imm,_) => Immediate(data[1]), + (Acc,_) | (_,STA) | (_,TAX) | (_,TAY) => Reg(A), + (_,STX) | (_,TXA) | (_,TXS) | (_,INX) | (_,DEX) => Reg(X), + (_,STY) | (_,TYA) | (_,INY) | (_,DEY) => Reg(Y), + _ => None, + }; + let dst = match (addr, def.name) { + (_,LDA) | (_,TXA) | (_,TYA) => Reg(A), + (_,LDX) | (_,TSX) | (_,TAX) => Reg(X), + (_,LDY) | (_,TAY) => Reg(Y), + _ => None, + }; + (src, dst) +} + fn execute(cpu: &mut Cpu, inst: &Instruction) { match inst.name { // Access @@ -328,26 +348,37 @@ fn execute(cpu: &mut Cpu, inst: &Instruction) { // Unofficial/Illegal AHX | ALR | ANC | ARR | AXS | DCP | ISC | LAX | LAS | RLA | RRA | SAX | SHX | SHY | SLO | SRE | TAS | XAA => {}, - } } -pub fn decode_instructions(data: &[u8], bytes_to_read: i32) -> Vec<&InstructionDefinition>{ +pub fn decode_instructions(data: &[u8], bytes_to_read: i32) -> Vec>{ let mut idx: usize = 0; - let mut instructions: Vec<&InstructionDefinition> = + let mut instructions: Vec = Vec::with_capacity((bytes_to_read / 2) as usize); while (idx as i32) < bytes_to_read { - let mut processed = 0; - let inst = &INSTRUCTION_DEFS[data[idx] as usize]; - instructions.push(inst); - processed += match inst.addressing { - Imp | Acc => 1, - Imm | ZPg | Rel | AbI - | ZPX | InX | InY => 2, + let mut processed: i32 = 0; + let def = &INSTRUCTION_DEFS[data[idx] as usize]; + + processed += match def.addressing { + Imp | Acc => 1, + Imm | ZPg | Rel | AbI | ZPX | InX | InY => 2, ZPY | AbX | AbY | Abs => 3, }; - idx += processed + + let (src_opr, dst_opr) = get_operands(&data[idx..], &def, def.addressing); + + let instruction = Instruction { + opcode: data[idx] as u8, + name: def.name, + src_opr, + dst_opr, + bytes_read: processed, + raw_data: &data[idx..idx+(processed as usize)], + }; + + instructions.push(instruction); + idx += processed as usize; } instructions }