Compare commits

..

3 Commits

Author SHA1 Message Date
Joey Pollack 400e378492 Adds the rest of the group 2 intructions 2 years ago
Joey Pollack e705296cde Adds ROL, LSR, and ROR instructions 2 years ago
Joey Pollack 2ebe9a56b2 Adds ASL instruction 2 years ago

@ -257,37 +257,164 @@ impl Instructions
pub fn ROL(cpu: &mut R6502, bus: &mut dyn Bus)
{
let old_bit_7 = (cpu.working_data & 0x80) > 0;
let carry = cpu.check_flag(Flags::C) as u16;
let result = (cpu.working_data << 1) ^ carry;
cpu.clear_flag(Flags::C);
if old_bit_7
{
cpu.set_flag(Flags::C);
}
cpu.clear_flag(Flags::N);
if result & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
cpu.clear_flag(Flags::Z);
if result == 0
{
cpu.set_flag(Flags::Z);
}
if cpu.addr_mode == ModeID::ACM
{
cpu.a = result as u8;
}
else
{
bus.write(cpu.working_addr, result as u8);
}
}
pub fn LSR(cpu: &mut R6502, bus: &mut dyn Bus)
{
let old_bit_0 = (cpu.working_data & 0x01) > 0;
let carry = cpu.check_flag(Flags::C) as u16;
let result = cpu.working_data >> 1;
cpu.clear_flag(Flags::C);
if old_bit_0
{
cpu.set_flag(Flags::C);
}
cpu.clear_flag(Flags::N);
if result & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
cpu.clear_flag(Flags::Z);
if result == 0
{
cpu.set_flag(Flags::Z);
}
if cpu.addr_mode == ModeID::ACM
{
cpu.a = result as u8;
}
else
{
bus.write(cpu.working_addr, result as u8);
}
}
pub fn ROR(cpu: &mut R6502, bus: &mut dyn Bus)
{
let old_bit_0 = (cpu.working_data & 0x01) > 0;
let carry = cpu.check_flag(Flags::C) as u16;
let temp = carry << 7;
let result = (cpu.working_data >> 1) ^ (carry << 7);
cpu.clear_flag(Flags::C);
if old_bit_0
{
cpu.set_flag(Flags::C);
}
cpu.clear_flag(Flags::N);
if result & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
cpu.clear_flag(Flags::Z);
if result == 0
{
cpu.set_flag(Flags::Z);
}
if cpu.addr_mode == ModeID::ACM
{
cpu.a = result as u8;
}
else
{
bus.write(cpu.working_addr, result as u8);
}
}
pub fn STX(cpu: &mut R6502, bus: &mut dyn Bus)
{
bus.write(cpu.working_addr, cpu.x);
}
pub fn LDX(cpu: &mut R6502, bus: &mut dyn Bus)
{
let data = cpu.working_data as u8;
cpu.x = data;
if cpu.x == 0
{
cpu.set_flag(Flags::Z);
}
if cpu.x & 0x80 != 0
{
cpu.set_flag(Flags::N);
}
}
pub fn DEC(cpu: &mut R6502, bus: &mut dyn Bus)
{
let dec_val = bus.read(cpu.working_addr) - 1;
bus.write(cpu.working_addr, dec_val);
cpu.clear_flag(Flags::Z);
if dec_val == 0
{
cpu.set_flag(Flags::Z);
}
cpu.clear_flag(Flags::N);
if dec_val & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
}
pub fn INC(cpu: &mut R6502, bus: &mut dyn Bus)
{
let dec_val = bus.read(cpu.working_addr) + 1;
bus.write(cpu.working_addr, dec_val);
cpu.clear_flag(Flags::Z);
if dec_val == 0
{
cpu.set_flag(Flags::Z);
}
cpu.clear_flag(Flags::N);
if dec_val & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
}
///////////////////////////////////////////////////////////

@ -2,7 +2,7 @@
#![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers};
use crate::r6502::{R6502, Bus, Registers, Flags};
/////////////////////////////////////////////////////////////////////
// GROUP ONE
@ -172,4 +172,289 @@ mod SBC;
// GROUP TWO
/////////////////////////////////////////////////////////////////////
// TODO: TEST ASL
#[test]
fn ASL()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to left shift the value in the accumulator
bus.write(addr, 0x0A); // ASL - Accumulator mode
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x98);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x30 in the A register?
assert_eq!(0x30, cpu.debug_get_reg(Registers::A));
assert_eq!(0, cpu.check_flag(Flags::Z), "Zero flag should not be set");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry flag should be set");
assert_eq!(0, cpu.check_flag(Flags::N), "Negative flag should not be set");
}
#[test]
fn ASL_ZP0()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Write the value into memory
bus.write(0x05, 0x98);
// Program to left shift the value in the accumulator
bus.write(addr, 0x06); // ASL - Zero Page mode
bus.write(addr + 1, 0x05); // Zero Page pointer
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x30 in memory?
assert_eq!(0x30, bus.read(0x05));
assert_eq!(0, cpu.check_flag(Flags::Z), "Zero flag should not be set");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry flag should be set");
assert_eq!(0, cpu.check_flag(Flags::N), "Negative flag should not be set");
}
#[test]
fn ROL()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to left shift the value in the accumulator
bus.write(addr, 0x2A); // ROL - Accumulator mode
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x80);
cpu.set_flag(Flags::C);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x01 in the A register?
assert_eq!(0x01, cpu.debug_get_reg(Registers::A));
assert_eq!(0, cpu.check_flag(Flags::Z), "Zero flag should not be set");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry flag should be set");
assert_eq!(0, cpu.check_flag(Flags::N), "Negative flag should not be set");
}
#[test]
fn LSR()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to left shift the value in the accumulator
bus.write(addr, 0x4A); // LSR - Accumulator mode
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x81);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x40 in the A register?
assert_eq!(0x40, cpu.debug_get_reg(Registers::A));
assert_eq!(0, cpu.check_flag(Flags::Z), "Zero flag should not be set");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry flag should be set");
assert_eq!(0, cpu.check_flag(Flags::N), "Negative flag should not be set");
}
#[test]
fn ROR()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to left shift the value in the accumulator
bus.write(addr, 0x6A); // ROR - Accumulator mode
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x81);
cpu.set_flag(Flags::C);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0xC0 in the A register?
assert_eq!(0xC0, cpu.debug_get_reg(Registers::A));
assert_eq!(0, cpu.check_flag(Flags::Z), "Zero flag should not be set");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry flag should be set");
assert_eq!(1, cpu.check_flag(Flags::N), "Negative flag should be set");
}
#[test]
fn STX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// STX $0A
bus.write(addr, 0x86); // STX - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x0F);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x0A?
assert_eq!(0x0F, bus.read(0x0A));
}
#[test]
fn LDX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to load 0x08 into the accumulator
bus.write(addr, 0xA2); // LDX - Immediate mode
bus.write(addr + 1, 0x08); // Argument
// Restart cpu
cpu.reset(&mut bus);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x08 in the X register?
assert_eq!(0x08, cpu.debug_get_reg(Registers::X));
}
#[test]
fn DEC()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// put value to decrement into memory
bus.write(0x08, 0x10);
// Program to load 0x08 into the accumulator
bus.write(addr, 0xC6); // DEC - Zero Page
bus.write(addr + 1, 0x08); // Argument
// Restart cpu
cpu.reset(&mut bus);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F in memory at 0x08?
assert_eq!(0x0F, bus.read(0x08));
}
#[test]
fn INC()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Put value to decrement into memory
bus.write(0x08, 0x10);
// Program to load 0x08 into the accumulator
bus.write(addr, 0xE6); // INC - Zero Page
bus.write(addr + 1, 0x08); // Argument
// Restart cpu
cpu.reset(&mut bus);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x11 in memory at 0x08?
assert_eq!(0x11, bus.read(0x08));
}

@ -40,14 +40,14 @@ Instructions:
✔ 111 SBC @done(23-11-09 13:24)
GROUP TWO:
☐ 000 ASL
☐ 001 ROL
☐ 010 LSR
☐ 011 ROR
☐ 100 STX
☐ 101 LDX
☐ 110 DEC
☐ 111 INC
✔ 000 ASL @done(23-11-30 17:31)
✔ 001 ROL @done(23-11-30 17:49)
✔ 010 LSR @done(23-11-30 18:12)
✔ 011 ROR @done(23-11-30 18:12)
✔ 100 STX @done(24-01-08 13:46)
✔ 101 LDX @done(24-01-08 14:21)
✔ 110 DEC @done(24-01-08 15:59)
✔ 111 INC @done(24-01-08 16:01)
GROUP THREE:
☐ 001 BIT

Loading…
Cancel
Save