use crate::*;
const DATA_ADDR: u64 = 0x7000;
fn write_f64(mem: u64, addr: u64, val: f64) {
let mut emu = emu64();
emu.maps.write_bytes_slice(addr, &val.to_le_bytes());
}
fn read_f64(mem: u64, addr: u64) -> f64 {
let emu = emu64();
let mut buf = [0u8; 8];
emu.maps.read_bytes_buff(&mut buf, addr);
f64::from_le_bytes(buf)
}
const C0_BIT: u16 = 0x0100; const C2_BIT: u16 = 0x0400; const C3_BIT: u16 = 0x4000;
#[test]
fn test_fcom_equal() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 5.0);
emu.maps.write_f64(0x2008, 5.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 5.0, "ST(0) should be unchanged");
assert_eq!(val2, 5.0, "ST(1) should be unchanged");
}
#[test]
fn test_fcom_greater_than() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 5.0);
emu.maps.write_f64(0x2008, 10.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 10.0, "ST(0) should be 10.0");
assert_eq!(val2, 5.0, "ST(1) should be 5.0");
}
#[test]
fn test_fcom_less_than() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 7.0);
emu.maps.write_f64(0x2008, 3.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 3.0, "ST(0) should be 3.0");
assert_eq!(val2, 7.0, "ST(1) should be 7.0");
}
#[test]
fn test_fcom_zero_equal() {
let mut emu = emu64();
let code = [
0xD9, 0xEE, 0xD9, 0xEE, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 0.0);
assert_eq!(val2, 0.0);
}
#[test]
fn test_fcom_positive_negative_zero() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xD9, 0xEE, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, -0.0);
emu.run(None).unwrap();
}
#[test]
fn test_fcomp_equal() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 5.0);
emu.maps.write_f64(0x2008, 5.0);
emu.run(None).unwrap();
let val = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(
val, 5.0,
"After FCOMP, ST(0) should contain the remaining value"
);
}
#[test]
fn test_fcomp_greater() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 3.0);
emu.maps.write_f64(0x2008, 8.0);
emu.run(None).unwrap();
let val = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(val, 3.0);
}
#[test]
fn test_fcomp_less() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 9.0);
emu.maps.write_f64(0x2008, 2.0);
emu.run(None).unwrap();
let val = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(val, 9.0);
}
#[test]
fn test_fcomp_with_constant() {
let mut emu = emu64();
let code = [
0xD9, 0xE8, 0xD9, 0xE8, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let val = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(val, 1.0);
}
#[test]
fn test_fcompp_equal() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xDE, 0xD9, 0xD9, 0xE8, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 4.0);
emu.maps.write_f64(0x2008, 4.0);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(
marker, 1.0,
"Stack should be empty after FCOMPP, FLD1 should work"
);
}
#[test]
fn test_fcompp_greater() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xDE, 0xD9, 0xD9, 0xE8, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 2.0);
emu.maps.write_f64(0x2008, 6.0);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(marker, 1.0);
}
#[test]
fn test_fcompp_less() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xDE, 0xD9, 0xD9, 0xEE, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 8.0);
emu.maps.write_f64(0x2008, 3.0);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(marker, 0.0);
}
#[test]
fn test_fcompp_with_constants() {
let mut emu = emu64();
let code = [
0xD9, 0xEE, 0xD9, 0xE8, 0xDE, 0xD9, 0xD9, 0xEB, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert!((marker - std::f64::consts::PI).abs() < 1e-15);
}
#[test]
fn test_fcom_infinity_greater() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 100.0);
emu.maps.write_f64(0x2008, f64::INFINITY);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, f64::INFINITY);
assert_eq!(val2, 100.0);
}
#[test]
fn test_fcom_negative_infinity_less() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 0.0);
emu.maps.write_f64(0x2008, f64::NEG_INFINITY);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, f64::NEG_INFINITY);
assert_eq!(val2, 0.0);
}
#[test]
fn test_fcom_infinities_equal() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::INFINITY);
emu.maps.write_f64(0x2008, f64::INFINITY);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, f64::INFINITY);
assert_eq!(val2, f64::INFINITY);
}
#[test]
fn test_fcom_infinities_different() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::NEG_INFINITY);
emu.maps.write_f64(0x2008, f64::INFINITY);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, f64::INFINITY);
assert_eq!(val2, f64::NEG_INFINITY);
}
#[test]
fn test_fcom_nan_vs_number() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 5.0);
emu.maps.write_f64(0x2008, f64::NAN);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert!(val1.is_nan());
assert_eq!(val2, 5.0);
}
#[test]
fn test_fcom_number_vs_nan() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::NAN);
emu.maps.write_f64(0x2008, 10.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 10.0);
assert!(val2.is_nan());
}
#[test]
fn test_fcom_nan_vs_nan() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::NAN);
emu.maps.write_f64(0x2008, f64::NAN);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert!(val1.is_nan());
assert!(val2.is_nan());
}
#[test]
fn test_fcom_very_close_numbers() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1.0);
emu.maps.write_f64(0x2008, 1.0 + 1e-15);
emu.run(None).unwrap();
}
#[test]
fn test_fcom_negative_numbers() {
let mut emu = emu64(); let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, -10.0);
emu.maps.write_f64(0x2008, -5.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, -5.0);
assert_eq!(val2, -10.0);
}
#[test]
fn test_fcom_mixed_signs() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, -3.0);
emu.maps.write_f64(0x2008, 3.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 3.0);
assert_eq!(val2, -3.0);
}
#[test]
fn test_fcom_tiny_numbers() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1e-100);
emu.maps.write_f64(0x2008, 2e-100);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 2e-100);
assert_eq!(val2, 1e-100);
}
#[test]
fn test_fcom_huge_numbers() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1e100);
emu.maps.write_f64(0x2008, 2e100);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 2e100);
assert_eq!(val2, 1e100);
}
#[test]
fn test_fcom_sequence() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x04, 0x25, 0x10, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x10, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1.0);
emu.maps.write_f64(0x2008, 2.0);
emu.maps.write_f64(0x2010, 3.0);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
let val3 = emu.maps.read_f64(0x3010).unwrap();
assert_eq!(val1, 3.0);
assert_eq!(val2, 2.0);
assert_eq!(val3, 1.0);
}
#[test]
fn test_mixed_compare_operations() {
let mut emu = emu64();
let code = [
0xD9, 0xE8, 0xD9, 0xE8, 0xD8, 0xD1, 0xD9, 0xE8, 0xD8, 0xD9, 0xDE, 0xD9, 0xD9, 0xEE, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(marker, 0.0);
}
#[test]
fn test_fcom_with_arithmetic() {
let mut emu = emu64();
let code = [
0xD9, 0xE8, 0xD9, 0xE8, 0xDE, 0xC1, 0xD9, 0xE8, 0xD9, 0xE8, 0xDE, 0xC1, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 2.0);
assert_eq!(val2, 2.0);
}
#[test]
fn test_fcom_fractions() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 0.25);
emu.maps.write_f64(0x2008, 0.5);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 0.5);
assert_eq!(val2, 0.25);
}
#[test]
fn test_fcomp_negative_values() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, -10.0);
emu.maps.write_f64(0x2008, -5.0);
emu.run(None).unwrap();
let val = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(val, -10.0);
}
#[test]
fn test_fcompp_pi_comparison() {
let mut emu = emu64();
let code = [
0xD9, 0xEB, 0xD9, 0xEB, 0xDE, 0xD9, 0xD9, 0xE8, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(marker, 1.0);
}
#[test]
fn test_fcom_denormal_numbers() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
let denormal1 = f64::MIN_POSITIVE / 2.0;
let denormal2 = f64::MIN_POSITIVE / 4.0;
emu.maps.write_f64(0x2000, denormal2);
emu.maps.write_f64(0x2008, denormal1);
emu.run(None).unwrap();
}
#[test]
fn test_fcom_max_values() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::MAX);
emu.maps.write_f64(0x2008, f64::MAX);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, f64::MAX);
assert_eq!(val2, f64::MAX);
}
#[test]
fn test_fcomp_sequential() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x04, 0x25, 0x10, 0x20, 0x00, 0x00, 0xD8, 0xD9, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1.0);
emu.maps.write_f64(0x2008, 2.0);
emu.maps.write_f64(0x2010, 3.0);
emu.run(None).unwrap();
}
#[test]
fn test_fcom_powers_of_ten() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1e10);
emu.maps.write_f64(0x2008, 1e20);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 1e20);
assert_eq!(val2, 1e10);
}
#[test]
fn test_fcompp_negative_infinity() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xDE, 0xD9, 0xD9, 0xEB, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, f64::NEG_INFINITY);
emu.maps.write_f64(0x2008, f64::NEG_INFINITY);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert!((marker - std::f64::consts::PI).abs() < 1e-15);
}
#[test]
fn test_fcom_epsilon() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, 1.0);
emu.maps.write_f64(0x2008, 1.0 + f64::EPSILON);
emu.run(None).unwrap();
}
#[test]
fn test_fcom_mixed_sign_small() {
let mut emu = emu64();
let code = [
0xDD, 0x04, 0x25, 0x00, 0x20, 0x00, 0x00, 0xDD, 0x04, 0x25, 0x08, 0x20, 0x00, 0x00, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.maps.write_f64(0x2000, -0.001);
emu.maps.write_f64(0x2008, 0.001);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert_eq!(val1, 0.001);
assert_eq!(val2, -0.001);
}
#[test]
fn test_fcompp_after_arithmetic() {
let mut emu = emu64();
let code = [
0xD9, 0xE8, 0xD9, 0xE8, 0xDE, 0xC1, 0xD9, 0xE8, 0xD9, 0xE8, 0xDE, 0xC9, 0xDE, 0xD9, 0xD9, 0xEE, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let marker = emu.maps.read_f64(0x3000).unwrap();
assert_eq!(marker, 0.0);
}
#[test]
fn test_fcom_constants_comparison() {
let mut emu = emu64();
let code = [
0xD9, 0xEB, 0xD9, 0xEA, 0xD8, 0xD1, 0xDD, 0x1C, 0x25, 0x00, 0x30, 0x00, 0x00, 0xDD, 0x1C, 0x25, 0x08, 0x30, 0x00, 0x00, 0xF4, ];
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let val1 = emu.maps.read_f64(0x3000).unwrap();
let val2 = emu.maps.read_f64(0x3008).unwrap();
assert!((val1 - std::f64::consts::LOG2_E).abs() < 1e-15);
assert!((val2 - std::f64::consts::PI).abs() < 1e-15);
}