use crate::gameboy::{testutils::*, StepResult};
use crate::registers;
#[test]
fn test_jump() -> StepResult<()> {
let gb = run_program(
1,
&[
0xC3, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2013
);
assert_eq!(gb.clocks_elapsed(), 16);
Ok(())
}
#[test]
fn test_jump_if_carry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x37, 0xDA, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2013
);
assert_eq!(gb.clocks_elapsed(), 20);
let gb = run_program(
2,
&[
0x3F, 0xDA, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 4
);
assert_eq!(gb.clocks_elapsed(), 16);
Ok(())
}
#[test]
fn test_jump_if_nocarry() -> StepResult<()> {
let gb = run_program(
2,
&[
0x37, 0xD2, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 4
);
assert_eq!(gb.clocks_elapsed(), 16);
let gb = run_program(
2,
&[
0x3F, 0xD2, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2013
);
assert_eq!(gb.clocks_elapsed(), 20);
Ok(())
}
#[test]
fn test_jump_if_zero() -> StepResult<()> {
let gb = run_program(
2,
&[
0xBF, 0xCA, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2013
);
assert_eq!(gb.clocks_elapsed(), 20);
let gb = run_program(
2,
&[
0xC6, 1, 0xCA, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 5
);
assert_eq!(gb.clocks_elapsed(), 20);
Ok(())
}
#[test]
fn test_jump_if_nonzero() -> StepResult<()> {
let gb = run_program(
2,
&[
0xBF, 0xC2, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 4
);
assert_eq!(gb.clocks_elapsed(), 16);
let gb = run_program(
2,
&[
0xC6, 1, 0xC2, 0x13, 0x20, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2013
);
assert_eq!(gb.clocks_elapsed(), 24);
Ok(())
}
#[test]
fn test_register_jump() -> StepResult<()> {
let gb = run_program(
3,
&[
0x26, 0x20, 0x2E, 0x31, 0xE9, ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x2031
);
assert_eq!(gb.clocks_elapsed(), 20);
Ok(())
}
#[test]
fn test_relative_jump() -> StepResult<()> {
let gb = run_program(
1,
&[
0x18,
(-4i8).to_le_bytes()[0], ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START - 2
);
assert_eq!(gb.clocks_elapsed(), 12);
let gb = run_program(
1,
&[
0x18,
(4i8).to_le_bytes()[0], ],
)?;
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 6
);
assert_eq!(gb.clocks_elapsed(), 12);
Ok(())
}
#[test]
fn test_relative_jump_if() -> StepResult<()> {
let gb = run_program(
4,
&[
0x37, 0x38, 0x02, 0x76, 0x30, 0x02, 0x06, 0x12, 0x00, 0x76, ], )?;
assert_eq!(gb.cpu.read_register_u8(registers::ByteRegister::B), 0x12);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 8
);
assert_eq!(gb.clocks_elapsed(), 32);
Ok(())
}
#[test]
fn test_relative_jump_backwards() -> StepResult<()> {
let gb = run_program(
4,
&[
0x18, 0x03, 0x76, 0x06, 0x12, 0x37, 0x38, 0xFB, ], )?;
assert_eq!(gb.cpu.read_register_u8(registers::ByteRegister::B), 0x12);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 5
);
assert_eq!(gb.clocks_elapsed(), 36);
Ok(())
}
#[test]
fn test_call() -> StepResult<()> {
let gb = run_program(
1,
&[
0xCD, 0x20, 0x30, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0203);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x3020
);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFC
);
assert_eq!(gb.clocks_elapsed(), 24);
Ok(())
}
#[test]
fn test_call_system() -> StepResult<()> {
let gb = run_program(
1,
&[
0xCF, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0201);
assert_eq!(gb.cpu.read_register_u16(registers::WordRegister::PC), 0x08);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFC
);
assert_eq!(gb.clocks_elapsed(), 16);
Ok(())
}
#[test]
fn test_return() -> StepResult<()> {
let gb = run_program(
2,
&[
0xCD, 0x06, 0x02, 0x00, 0x00, 0x00, 0xC9, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0203);
assert_eq!(gb.cpu.read_register_u16(registers::WordRegister::PC), 0x203);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFE
);
assert_eq!(gb.clocks_elapsed(), 40);
Ok(())
}
#[test]
fn test_return_if() -> StepResult<()> {
let gb = run_program(
3,
&[
0xCD, 0x06, 0x02, 0x00, 0x00, 0x00, 0x37, 0xD8, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0203);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFE
);
assert_eq!(gb.cpu.read_register_u16(registers::WordRegister::PC), 0x203);
assert_eq!(gb.clocks_elapsed(), 48);
let gb = run_program(
3,
&[
0xCD, 0x06, 0x02, 0x00, 0x00, 0x00, 0x3F, 0xD8, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0203);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::SP),
0xFFFC
);
assert_eq!(gb.cpu.read_register_u16(registers::WordRegister::PC), 0x208);
assert_eq!(gb.clocks_elapsed(), 36);
Ok(())
}
#[test]
fn test_call_if() -> StepResult<()> {
let gb = run_program(
2,
&[
0x37, 0xDC, 0x20, 0x30, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0204);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
0x3020
);
assert_eq!(gb.clocks_elapsed(), 28);
let gb = run_program(
2,
&[
0x3F, 0xDC, 0x20, 0x30, ],
)?;
assert_eq!(gb.read_memory_u16(0xFFFC)?, 0x0000);
assert_eq!(
gb.cpu.read_register_u16(registers::WordRegister::PC),
PROGRAM_START + 4
);
assert_eq!(gb.clocks_elapsed(), 16);
Ok(())
}