some decode. some encode. some to_string
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
use std::ops::Add;
|
||||
use crate::mos6502cpu::Mos6502Cpu;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum AddressMode {
|
||||
Accumulator,
|
||||
Immediate(u8),
|
||||
ZeroPage(u8),
|
||||
ZeroPageX(u8),
|
||||
Absolute(u16),
|
||||
AbsoluteX(u16),
|
||||
AbsoluteY(u16),
|
||||
IndirectX(u8),
|
||||
IndirectY(u8),
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
// Instruction OP Codes
|
||||
|
||||
/// ADC
|
||||
pub const ISA_OP_ADC_I: u8 = 0x69;
|
||||
pub const ISA_OP_ADC_Z: u8 = 0x65;
|
||||
pub const ISA_OP_ADC_ZX: u8 = 0x75;
|
||||
pub const ISA_OP_ADC_ABS: u8 = 0x6d;
|
||||
pub const ISA_OP_ADC_ABSX: u8 = 0x7d;
|
||||
pub const ISA_OP_ADC_ABSY: u8 = 0x79;
|
||||
pub const ISA_OP_ADC_INDX: u8 = 0x61;
|
||||
pub const ISA_OP_ADC_INDY: u8 = 0x71;
|
||||
/// AND
|
||||
pub const ISA_OP_AND_I: u8 = 0x29;
|
||||
pub const ISA_OP_AND_Z: u8 = 0x25;
|
||||
pub const ISA_OP_AND_ZX: u8 = 0x35;
|
||||
pub const ISA_OP_AND_ABS: u8 = 0x2d;
|
||||
pub const ISA_OP_AND_ABSX: u8 = 0x3d;
|
||||
pub const ISA_OP_AND_ABSY: u8 = 0x39;
|
||||
pub const ISA_OP_AND_INDX: u8 = 0x21;
|
||||
pub const ISA_OP_AND_INDY: u8 = 0x31;
|
||||
|
||||
/// ASL
|
||||
pub const ISA_OP_ASL_A: u8 = 0x0a;
|
||||
pub const ISA_OP_ASL_Z: u8 = 0x06;
|
||||
pub const ISA_OP_ASL_ZX: u8 = 0x16;
|
||||
pub const ISA_OP_ASL_ABS: u8 = 0x0e;
|
||||
pub const ISA_OP_ASL_ABSX: u8 = 0x1e;
|
||||
|
||||
/// BCC
|
||||
pub const ISA_OP_BCC: u8 = 0x90;
|
||||
|
||||
/// BCS
|
||||
pub const ISA_OP_BCS: u8 = 0xb0;
|
||||
|
||||
/// BEQ
|
||||
pub const ISA_OP_BEQ: u8 = 0xf0;
|
||||
/// BIT
|
||||
|
||||
pub const ISA_OP_BIT_ZP: u8 = 0x24;
|
||||
pub const ISA_OP_BIT_ABS: u8 = 0x2c;
|
||||
|
||||
/// BMI
|
||||
pub const ISA_OP_BMI: u8 = 0x30;
|
||||
|
||||
/// BNE
|
||||
pub const ISA_OP_BNE: u8 = 0xd0;
|
||||
|
||||
/// BPL
|
||||
pub const ISA_OP_BPL: u8 = 0x10;
|
||||
|
||||
/// BRK
|
||||
pub const ISA_OP_BRK: u8 = 0x00;
|
||||
/// BVC
|
||||
|
||||
pub const ISA_OP_BVC: u8 = 0x50;
|
||||
|
||||
/// BVS
|
||||
pub const ISA_OP_BVS: u8 = 0x70;
|
||||
|
||||
pub const ISA_OP_CLC: u8 = 0x18;
|
||||
|
||||
pub const ISA_OP_CLD: u8 = 0xd8;
|
||||
|
||||
pub const ISA_OP_CLI: u8 = 0x58;
|
||||
|
||||
pub const ISA_OP_CLV: u8 = 0xb8;
|
||||
|
||||
pub const ISA_OP_CMP_I: u8 = 0xc9;
|
||||
pub const ISA_OP_CMP_ZP: u8 = 0xc5;
|
||||
pub const ISA_OP_CMP_ZPX: u8 = 0xd5;
|
||||
pub const ISA_OP_CMP_ABS: u8 = 0xcd;
|
||||
pub const ISA_OP_CMP_ABSX: u8 = 0xdd;
|
||||
pub const ISA_OP_CMP_INDX: u8 = 0xc1;
|
||||
pub const ISA_OP_CMP_INDY: u8 = 0xd1;
|
||||
|
||||
pub const ISA_OP_CPX_I: u8 = 0xe0;
|
||||
pub const ISA_OP_CPX_ZP: u8 = 0xe4;
|
||||
pub const ISA_OP_CPX_ABS: u8 = 0xec;
|
||||
|
||||
pub const ISA_OP_CPY_I: u8 = 0xc0;
|
||||
pub const ISA_OP_CPY_ZP: u8 = 0xc4;
|
||||
pub const ISA_OP_CPY_ABS: u8 = 0xcc;
|
||||
|
||||
pub const ISA_OP_DEC_ZP: u8 = 0xc6;
|
||||
pub const ISA_OP_DEC_ZPX: u8 = 0xd6;
|
||||
pub const ISA_OP_DEC_ABS: u8 = 0xce;
|
||||
pub const ISA_OP_DEC_ABSX: u8 = 0xde;
|
||||
|
||||
pub const ISA_OP_DEX: u8 = 0xca;
|
||||
|
||||
pub const ISA_OP_DEY: u8 = 0x88;
|
||||
|
||||
pub const ISA_OP_EOR_I: u8 = 0x49;
|
||||
pub const ISA_OP_EOR_ZP: u8 = 0x45;
|
||||
pub const ISA_OP_EOR_ZPX: u8 = 0x55;
|
||||
pub const ISA_OP_EOR_ABS: u8 = 0x4d;
|
||||
pub const ISA_OP_EOR_ABSX: u8 = 0x5d;
|
||||
pub const ISA_OP_EOR_ABSY: u8 = 0x59;
|
||||
pub const ISA_OP_EOR_INDX: u8 = 0x41;
|
||||
pub const ISA_OP_EOR_INDY: u8 = 0x51;
|
||||
|
||||
pub const ISA_OP_INC_ZP: u8 = 0xe6;
|
||||
pub const ISA_OP_INC_ZPX: u8 = 0xf6;
|
||||
pub const ISA_OP_INC_ABS: u8 = 0xee;
|
||||
pub const ISA_OP_INC_ABSX: u8 = 0xfe;
|
||||
|
||||
|
||||
pub const ISA_OP_INX: u8 = 0xe8;
|
||||
|
||||
pub const ISA_OP_INY: u8 = 0xc8;
|
||||
|
||||
pub const ISA_OP_JMP_ABS: u8 = 0x4c;
|
||||
pub const ISA_OP_JMP_IND: u8 = 0x6c;
|
||||
|
||||
pub const ISA_OP_JSR: u8 = 0x20;
|
||||
|
||||
pub const ISA_OP_LDA_I: u8 = 0xA9;
|
||||
pub const ISA_OP_LDA_Z: u8 = 0xA5;
|
||||
pub const ISA_OP_LDA_ZX: u8 = 0xB5;
|
||||
pub const ISA_OP_LDA_ABS: u8 = 0xAD;
|
||||
pub const IAS_OP_LDA_ABSX: u8 = 0xBD;
|
||||
pub const ISA_OP_LDA_ABSY: u8 = 0xB9;
|
||||
pub const ISA_OP_LDA_INDX: u8 = 0xA1;
|
||||
pub const ISA_OP_LDA_INDY: u8 = 0xB1;
|
||||
|
||||
pub const ISA_OP_LDX_I: u8 = 0xa2;
|
||||
pub const ISA_OP_LDX_ZP: u8 = 0xa6;
|
||||
pub const ISA_OP_LDX_ZPY: u8 = 0x86;
|
||||
pub const ISA_OP_LDX_ABS: u8 = 0xae;
|
||||
pub const ISA_OP_LDX_ABSY: u8 = 0xbe;
|
||||
|
||||
pub const ISA_OP_LDY_I: u8 = 0xa0;
|
||||
pub const ISA_OP_LDY_ZP: u8 = 0xa4;
|
||||
pub const ISA_OP_LDY_ZPX: u8 = 0xb4;
|
||||
pub const ISA_OP_LDY_ABS: u8 = 0xac;
|
||||
pub const ISA_OP_LDY_ABSX: u8 = 0xac;
|
||||
pub const ISA_OP_LSR_A: u8 = 0x4a;
|
||||
pub const ISA_OP_LSR_ZP: u8 = 0x46;
|
||||
pub const ISA_OP_LSR_ZPX: u8 = 0x56;
|
||||
pub const ISA_OP_LSR_ABS: u8 = 0x4e;
|
||||
pub const ISA_OP_LSR_ABSX: u8 = 0x5e;
|
||||
|
||||
pub const ISA_OP_NOP: u8 = 0xEA;
|
||||
|
||||
pub const ISA_OP_ORA_I: u8 = 0x09;
|
||||
pub const ISA_OP_ORA_ZP: u8 = 0x05;
|
||||
pub const ISA_OP_ORA_ZPX: u8 = 0x15;
|
||||
pub const ISA_OP_ORA_ABS: u8 = 0x0d;
|
||||
pub const ISA_OP_ORA_ABSX: u8 = 0x1d;
|
||||
pub const ISA_OP_ORA_ABSY: u8 = 0x19;
|
||||
pub const ISA_OP_ORA_INDX: u8 = 0x01;
|
||||
pub const ISA_OP_ORA_INDY: u8 = 0x11;
|
||||
|
||||
pub const ISA_OP_PHA: u8 = 0x48;
|
||||
|
||||
pub const ISA_OP_PHP: u8 = 0x08;
|
||||
///
|
||||
pub const ISA_OP_PLA: u8 = 0x68;
|
||||
///
|
||||
pub const ISA_OP_PLP: u8 = 0x28;
|
||||
|
||||
///
|
||||
///
|
||||
pub const ISA_OP_ROL_A: u8 = 0x2a;
|
||||
pub const ISA_OP_ROL_ZP: u8 = 0x26;
|
||||
pub const ISA_OP_ROL_ZPX: u8 = 0x36;
|
||||
pub const ISA_OP_ROL_ABS: u8 = 0x2e;
|
||||
pub const ISA_OP_ROL_ABSX: u8 = 0x3e;
|
||||
|
||||
///
|
||||
pub const ISA_OP_ROR_A: u8 = 0x6a;
|
||||
pub const ISA_OP_ROR_ZP: u8 = 0x66;
|
||||
pub const ISA_OP_ROR_ZPX: u8 = 0x76;
|
||||
pub const ISA_OP_ROR_ABS: u8 = 0x6e;
|
||||
pub const ISA_OP_ROR_ABSX: u8 = 0x7e;
|
||||
pub const ISA_OP_RTI: u8 = 0x40;
|
||||
pub const ISA_OP_RTS: u8 = 0x60;
|
||||
pub const ISA_OP_SBC_I: u8 = 0xe9;
|
||||
pub const ISA_OP_SBC_ZP: u8 = 0xe5;
|
||||
pub const ISA_OP_SBC_ZPX: u8 = 0xf5;
|
||||
pub const ISA_OP_SBC_ABS: u8 = 0xed;
|
||||
pub const ISA_OP_SBC_ABSX: u8 = 0xfd;
|
||||
pub const ISA_OP_SBC_ABSY: u8 = 0xf9;
|
||||
pub const ISA_OP_SBC_INDX: u8 = 0xe1;
|
||||
pub const ISA_OP_SBC_INDY: u8 = 0xf1;
|
||||
pub const ISA_OP_SEC: u8 = 0x38;
|
||||
pub const ISA_OP_SED: u8 = 0xf8;
|
||||
pub const ISA_OP_SEI: u8 = 0x78;
|
||||
pub const ISA_OP_STA_ZP: u8 = 0x85;
|
||||
pub const ISA_OP_STA_ZPX: u8 = 0x95;
|
||||
pub const ISA_OP_STA_ABS: u8 = 0x8d;
|
||||
pub const ISA_OP_STA_ABSX: u8 = 0x9d;
|
||||
pub const ISA_OP_STA_ABSY: u8 = 0x99;
|
||||
pub const ISA_OP_STA_INDX: u8 = 0x81;
|
||||
pub const ISA_OP_STA_INDY: u8 = 0x91;
|
||||
pub const ISA_OP_STX_ZP: u8 = 0x86;
|
||||
pub const ISA_OP_STX_ZPX: u8 = 0x96;
|
||||
pub const ISA_OP_STX_ABS: u8 = 0x8e;
|
||||
pub const ISA_OP_STY_ZP: u8 = 0x84;
|
||||
pub const ISA_OP_STY_ZPX: u8 = 0x94;
|
||||
pub const ISA_OP_STY_ABS: u8 = 0x8c;
|
||||
pub const ISA_OP_TAX: u8 = 0xaa;
|
||||
pub const ISA_OP_TAY: u8 = 0xa8;
|
||||
pub const ISA_OP_TSX: u8 = 0xba;
|
||||
pub const ISA_OP_TXA: u8 = 0x8a;
|
||||
pub const ISA_OP_TXS: u8 = 0x9a;
|
||||
pub const ISA_OP_TYA: u8 = 0x98;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,74 @@
|
||||
use crate::address_mode::AddressMode::*;
|
||||
use crate::constants::*;
|
||||
use crate::instruction::Instruction;
|
||||
use crate::instruction::Instruction::*;
|
||||
|
||||
pub struct Decoder {}
|
||||
|
||||
|
||||
impl Decoder {
|
||||
/// decode
|
||||
///
|
||||
/// Returns the decoded instruction or a NOP.
|
||||
/// NOP will be returned when an instruction without a valid parameter
|
||||
/// and more data is required to decode.
|
||||
pub fn decode(decode_from: Vec<u8>) -> Instruction {
|
||||
NOP
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
|
||||
#[test]
|
||||
fn valid_decodes() {
|
||||
let params = vec![
|
||||
(vec![ISA_OP_ADC_I, 0xab], ADC(Immediate(0xab))),
|
||||
(vec![ISA_OP_ADC_Z, 0xab], ADC(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ADC_ZX, 0xab], ADC(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ADC_ABS, 0xab, 0xcd], ADC(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ADC_ABSX, 0xcd, 0xab], ADC(AbsoluteX(0xabcd))),
|
||||
(vec![ISA_OP_ADC_ABSY, 0xcd, 0xab], ADC(AbsoluteY(0xabcd))),
|
||||
(vec![ISA_OP_ADC_INDX, 0xab], ADC(IndirectX(0xab))),
|
||||
(vec![ISA_OP_ADC_INDY, 0xcd], ADC(IndirectY(0xcd))),
|
||||
|
||||
(vec![ISA_OP_AND_I, 0xab], AND(Immediate(0xab))),
|
||||
(vec![ISA_OP_AND_Z, 0xab], AND(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_AND_ZX, 0xab], AND(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_AND_ABS, 0xcd, 0xab], AND(Absolute(0xabcd))),
|
||||
|
||||
(vec![ISA_OP_ASL_A], ASL(Accumulator)),
|
||||
(vec![ISA_OP_ASL_Z, 0xab], ASL(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ASL_ZX, 0xab], ASL(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ASL_ABS, 0xab, 0xcd], ASL(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ASL_ABSX, 0xab, 0xcd], ASL(AbsoluteX(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BCC, 0xab], BCC(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BEQ, 0xab], BEQ(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BIT_ZP, 0xab], BIT(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_BIT_ABS, 0xab, 0xcd], BIT(Absolute(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BMI, 0xab], BMI(Immediate(0xab))),
|
||||
(vec![ISA_OP_BNE, 0xab], BNE(Immediate(0xab))),
|
||||
(vec![ISA_OP_BPL, 0xab], BPL(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVC, 0xab], BVC(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVS, 0xab], BVS(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BRK], BRK),
|
||||
|
||||
];
|
||||
|
||||
for (bytes, instruction) in params {
|
||||
println!("Expecting {:?} to be {:?}", bytes, instruction);
|
||||
|
||||
assert_eq!(
|
||||
Decoder::decode(bytes),
|
||||
instruction
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
use crate::address_mode::AddressMode::*;
|
||||
use crate::constants::*;
|
||||
use crate::instruction::Instruction;
|
||||
use crate::instruction::Instruction::*;
|
||||
|
||||
pub struct Encoder {}
|
||||
|
||||
impl Encoder {
|
||||
pub fn encode(to_encode: Instruction) -> Vec<u8> {
|
||||
match to_encode {
|
||||
// ADC(_) => {}
|
||||
// AND(_) => {}
|
||||
// ASL(_) => {}
|
||||
BCC(mode) => {
|
||||
match mode {
|
||||
Immediate(address)=> {
|
||||
vec![ISA_OP_BCC, address]
|
||||
}
|
||||
_ => NOP.to_bytes()
|
||||
}
|
||||
}
|
||||
// BCS(_) => {}
|
||||
// BEQ(_) => {}
|
||||
// BIT(_) => {}
|
||||
// BMI(_) => {}
|
||||
// BNE(_) => {}
|
||||
// BPL(_) => {}
|
||||
// BRK => {}
|
||||
// BVC(_) => {}
|
||||
// BVS(_) => {}
|
||||
// CLC => {}
|
||||
// CLD => {}
|
||||
// CLI => {}
|
||||
// CLV => {}
|
||||
// CMP(_) => {}
|
||||
// CPX(_) => {}
|
||||
// CPY(_) => {}
|
||||
// DEC(_) => {}
|
||||
// DEX => {}
|
||||
// DEY => {}
|
||||
// EOR(_) => {}
|
||||
// INC(_) => {}
|
||||
// INX => {}
|
||||
// INY => {}
|
||||
// JMP(_) => {}
|
||||
// JSR(_) => {}
|
||||
// LDA(_) => {}
|
||||
// LDX(_) => {}
|
||||
// LDY(_) => {}
|
||||
// LSR(_) => {}
|
||||
// NOP => {}
|
||||
// ORA(_) => {}
|
||||
// PHA => {}
|
||||
// PHP => {}
|
||||
// PLA => {}
|
||||
// PLP => {}
|
||||
// ROL(_) => {}
|
||||
// ROR(_) => {}
|
||||
// RTI => {}
|
||||
// RTS => {}
|
||||
// SBC(_) => {}
|
||||
// SEC => {}
|
||||
// SED => {}
|
||||
// SEI => {}
|
||||
// STA(_) => {}
|
||||
// STX(_) => {}
|
||||
// STY(_) => {}
|
||||
// TAX => {}
|
||||
// TAY => {}
|
||||
// TSX => {}
|
||||
// TXA => {}
|
||||
// TXS => {}
|
||||
// TYA => {}
|
||||
_ => NOP.to_bytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::constants::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn adc_decode() {
|
||||
let params = vec![
|
||||
(vec![ISA_OP_ADC_I, 0xab], ADC(Immediate(0xab))),
|
||||
(vec![ISA_OP_ADC_Z, 0xab], ADC(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ADC_ZX, 0xab], ADC(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ADC_ABS, 0xab, 0xcd], ADC(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ADC_ABSX, 0xcd, 0xab], ADC(AbsoluteX(0xabcd))),
|
||||
(vec![ISA_OP_ADC_ABSY, 0xcd, 0xab], ADC(AbsoluteY(0xabcd))),
|
||||
(vec![ISA_OP_ADC_INDX, 0xab], ADC(IndirectX(0xab))),
|
||||
(vec![ISA_OP_ADC_INDY, 0xcd], ADC(IndirectY(0xcd))),
|
||||
|
||||
(vec![ISA_OP_AND_I, 0xab], AND(Immediate(0xab))),
|
||||
(vec![ISA_OP_AND_Z, 0xab], AND(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_AND_ZX, 0xab], AND(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_AND_ABS, 0xcd, 0xab], AND(Absolute(0xabcd))),
|
||||
|
||||
(vec![ISA_OP_ASL_A], ASL(Accumulator)),
|
||||
(vec![ISA_OP_ASL_Z, 0xab], ASL(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ASL_ZX, 0xab], ASL(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ASL_ABS, 0xab, 0xcd], ASL(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ASL_ABSX, 0xab, 0xcd], ASL(AbsoluteX(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BCC, 0xab], BCC(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BEQ, 0xab], BEQ(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BIT_ZP, 0xab], BIT(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_BIT_ABS, 0xab, 0xcd], BIT(Absolute(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BMI, 0xab], BMI(Immediate(0xab))),
|
||||
(vec![ISA_OP_BNE, 0xab], BNE(Immediate(0xab))),
|
||||
(vec![ISA_OP_BPL, 0xab], BPL(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVC, 0xab], BVC(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVS, 0xab], BVS(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BRK], BRK),
|
||||
|
||||
];
|
||||
|
||||
for (bytes, instruction) in params {
|
||||
let encoded = Encoder::encode(bytes);
|
||||
assert_eq!(encoded, instruction.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use crate::mos6502flags::Mos6502Flag;
|
||||
|
||||
pub enum MicrocodeStep {
|
||||
ReadRegisterA,
|
||||
ReadRegisterX,
|
||||
ReadRegisterY,
|
||||
ReadFlag(Mos6502Flag),
|
||||
WriteRegisterA,
|
||||
WriteRegisterX,
|
||||
WriteRegisterY,
|
||||
WriteFlag(Mos6502Flag, bool),
|
||||
ReadMemory(u16),
|
||||
WriteMemory(u16, u8),
|
||||
ALUAdd(u8, u8),
|
||||
ALUSub(u8, u8),
|
||||
ALUAddC(u8, u8, bool),
|
||||
ALUSubC(u8, u8, bool),
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
pub mod encode;
|
||||
pub mod decoder;
|
||||
pub mod microcode_steps;
|
||||
@@ -0,0 +1,6 @@
|
||||
pub mod address_mode;
|
||||
pub mod mos6502cpu;
|
||||
pub mod instruction;
|
||||
pub mod mos6502flags;
|
||||
pub mod isa;
|
||||
pub mod constants;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
use crate::mos6502flags::{Mos6502Flag, Mos6502Flags};
|
||||
|
||||
pub const SIZE_1KB: usize = 1024 * 1024;
|
||||
pub const SIZE_64KB: usize = SIZE_1KB * 64;
|
||||
|
||||
pub struct Mos6502Cpu {
|
||||
memory: [u8; SIZE_64KB],
|
||||
a: u8,
|
||||
x: u8,
|
||||
y: u8,
|
||||
flags: Mos6502Flags,
|
||||
pc: u16,
|
||||
s: u8,
|
||||
microcode_step: u8
|
||||
}
|
||||
|
||||
impl Mos6502Cpu {
|
||||
pub fn new() -> Mos6502Cpu {
|
||||
Mos6502Cpu {
|
||||
memory: [0; SIZE_64KB],
|
||||
a: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
flags: Mos6502Flags::default(),
|
||||
pc: 0,
|
||||
s: 0xfd,
|
||||
microcode_step: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peek_flag(&self, flag_to_read: Mos6502Flag) -> bool {
|
||||
self.flags.flag(flag_to_read)
|
||||
}
|
||||
pub fn poke_flag(&mut self, flag_to_set: Mos6502Flag, new_value: bool) {
|
||||
if new_value { self.flags.set_flag(flag_to_set) } else { self.flags.clear_flag(flag_to_set) }
|
||||
}
|
||||
|
||||
pub fn peek(&self, offset: u16) -> u8 {
|
||||
self.memory[offset as usize]
|
||||
}
|
||||
|
||||
pub fn poke(&mut self, offset: u16, value: u8) {
|
||||
self.memory[offset as usize] = value
|
||||
}
|
||||
|
||||
pub fn peek_a(&self) -> u8 {
|
||||
self.a
|
||||
}
|
||||
pub fn poke_a(&mut self, new_a: u8) {
|
||||
self.a = new_a;
|
||||
}
|
||||
|
||||
pub fn peek_x(&self) -> u8 {
|
||||
self.x
|
||||
}
|
||||
|
||||
pub fn poke_x(&mut self, new_x: u8) {
|
||||
self.x = new_x
|
||||
}
|
||||
|
||||
pub fn peek_y(&self) -> u8 {
|
||||
self.y
|
||||
}
|
||||
|
||||
pub fn poke_y(&mut self, new_y: u8) {
|
||||
self.y = new_y
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
pub enum Mos6502Flag {
|
||||
Carry,
|
||||
Zero,
|
||||
Interrupt,
|
||||
Decimal,
|
||||
Break,
|
||||
Overflow,
|
||||
Negative
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Mos6502Flags {
|
||||
carry: bool,
|
||||
zero: bool,
|
||||
interrupt: bool,
|
||||
decimal: bool,
|
||||
break_flag: bool,
|
||||
overflow: bool,
|
||||
negative: bool,
|
||||
}
|
||||
|
||||
impl Mos6502Flags {
|
||||
|
||||
pub fn set_flag(&mut self, flag_to_set: Mos6502Flag) {
|
||||
self.change_flag(flag_to_set, true);
|
||||
}
|
||||
|
||||
pub fn clear_flag(&mut self, flag_to_clear: Mos6502Flag) {
|
||||
self.change_flag(flag_to_clear, false);
|
||||
}
|
||||
|
||||
fn change_flag(&mut self, flag_to_change: Mos6502Flag, new_value: bool) {
|
||||
match flag_to_change {
|
||||
Mos6502Flag::Carry => {
|
||||
self.carry = new_value
|
||||
}
|
||||
Mos6502Flag::Zero => {
|
||||
self.zero = new_value
|
||||
}
|
||||
Mos6502Flag::Interrupt => {
|
||||
self.interrupt = new_value
|
||||
}
|
||||
Mos6502Flag::Decimal => {
|
||||
self.decimal = new_value
|
||||
}
|
||||
Mos6502Flag::Break => {
|
||||
self.break_flag = new_value
|
||||
}
|
||||
Mos6502Flag::Overflow => {
|
||||
self.overflow = new_value
|
||||
}
|
||||
Mos6502Flag::Negative => {
|
||||
self.negative = new_value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flag(&self, flag_to_read: Mos6502Flag) -> bool {
|
||||
match flag_to_read {
|
||||
Mos6502Flag::Carry => {
|
||||
self.carry
|
||||
}
|
||||
Mos6502Flag::Zero => {
|
||||
self.zero
|
||||
}
|
||||
Mos6502Flag::Interrupt => {
|
||||
self.interrupt
|
||||
}
|
||||
Mos6502Flag::Decimal => {
|
||||
self.decimal
|
||||
}
|
||||
Mos6502Flag::Break => {
|
||||
self.break_flag
|
||||
}
|
||||
Mos6502Flag::Overflow => {
|
||||
self.overflow
|
||||
}
|
||||
Mos6502Flag::Negative => {
|
||||
self.negative
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let expected = Mos6502Flag::default();
|
||||
|
||||
assert_eq!(expected,
|
||||
Mos6502Flag::default());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user