use crate::gameboy::{testutils::*, StepResult};
use crate::registers;
#[test]
fn test_stack() -> StepResult<()> {
let gb = run_program(
7,
&[
0x06, 0x05, 0x0E, 0x08, 0xC5, 0xC5, 0xC5, 0xD1, 0xE1, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::DE),
0x0508
);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::HL),
0x0508
);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFC
);
assert_eq!(gb.read_memory_u16(0xFFFA)?, 0x0508);
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0508);
assert_eq!(gb.read_memory_u16(0xFFF8)?, 0x0508);
assert_eq!(gb.clocks_elapsed(), 88);
Ok(())
}
#[test]
fn test_store_stack_pointer_memory() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0xAB, 0x12, 0x08, 0x00, 0xC0, ],
)?;
assert_eq!(gb.clocks_elapsed(), 32);
assert_eq!(gb.read_memory_u16(0xC000)?, 0x12AB);
Ok(())
}
#[test]
fn test_set_stack_pointer() -> StepResult<()> {
let gb = run_program(
2,
&[
0x21, 0xAB, 0x12, 0xF9, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::SP), 0x12AB);
assert_eq!(gb.clocks_elapsed(), 20);
Ok(())
}
#[test]
fn test_add_stack_pointer_no_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x80, 0xFF, 0xE8, 0x21, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::SP), 0xFFA1);
assert_eq!(gb.clocks_elapsed(), 28);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_add_stack_pointer_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0xFD, 0xFF, 0xE8, 0x04, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::SP), 0x1);
assert_eq!(gb.clocks_elapsed(), 28);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_sub_stack_pointer_no_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x03, 0x00, 0xE8, 0xFE, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::SP), 0x01);
assert_eq!(gb.clocks_elapsed(), 28);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_sub_stack_pointer_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x03, 0x00, 0xE8, 0xFC, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::SP), 0xFFFF);
assert_eq!(gb.clocks_elapsed(), 28);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_load_stack_offset_add_no_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x80, 0xFF, 0xF8, 0x21, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::HL), 0xFFA1);
assert_eq!(gb.clocks_elapsed(), 24);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_load_stack_offset_add_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0xFD, 0xFF, 0xF8, 0x04, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::HL), 0x0001);
assert_eq!(gb.clocks_elapsed(), 24);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_load_stack_offset_sub_no_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x04, 0x00, 0xF8, 0xFD, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::HL), 0x0001);
assert_eq!(gb.clocks_elapsed(), 24);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}
#[test]
fn test_load_stack_offset_sub_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x31, 0x04, 0x00, 0xF8, 0xFB, ],
)?;
assert_eq!(gb.read_register_u16(registers::WordRegister::HL), 0xFFFF);
assert_eq!(gb.clocks_elapsed(), 24);
assert_eq!(gb.cpu.read_flag(registers::Flag::Carry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::HalfCarry), true);
assert_eq!(gb.cpu.read_flag(registers::Flag::Zero), false);
assert_eq!(gb.cpu.read_flag(registers::Flag::AddSubtract), false);
Ok(())
}