Construct operands src/dst from instruction definition, wip
This commit is contained in:
parent
132cc7fb9d
commit
2068cf08e1
@ -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<Instruction<'_>>{
|
||||
let mut idx: usize = 0;
|
||||
let mut instructions: Vec<&InstructionDefinition> =
|
||||
let mut instructions: Vec<Instruction> =
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user