use core::{cmp::Ordering, ffi::CStr, marker::PhantomData, ops::AddAssign};
use crate::{
hal::{basic::BasicRom, Basic},
pac::{
basic,
kernal::{self, F40},
peripheral,
},
};
pub struct FAC<'a, ROM> {
_fac: peripheral::FAC,
_cur: PhantomData<&'a ROM>,
}
impl<'a> FAC<'a, Basic> {
pub fn with_basic<CHAREN>(fac: peripheral::FAC, basic: &'a BasicRom<'_, CHAREN>) -> Self {
let _ = basic;
Self {
_fac: fac,
_cur: PhantomData,
}
}
}
impl<'a> FAC<'a, Basic> {
pub fn load(&mut self, value: &F40) {
unsafe { basic::movfm(value) };
}
pub fn read(&mut self) -> F40 {
let mut ret = F40::zero();
unsafe { basic::movmf(&mut ret) };
ret
}
pub fn load_i16(&mut self, value: i16) {
unsafe { basic::givayf(value) }
}
pub fn to_i16(&mut self) -> i16 {
unsafe { basic::facinx() }
}
pub fn load_from_arg(&mut self, arg: &ARG) {
let _ = arg;
unsafe { basic::movaf() };
}
pub fn copy_to_arg(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::movfa() };
}
pub fn to_cstr<'s>(&mut self, fpstr: &'s mut FPSTR) -> &'s CStr {
let _ = fpstr;
let val = self.read();
let ptr = unsafe { basic::fout() };
self.load(&val);
unsafe { CStr::from_ptr(ptr) }
}
pub fn into_cstr<'s>(&mut self, fpstr: &'s mut FPSTR) -> &'s CStr {
let _ = fpstr;
let ptr = unsafe { basic::fout() };
self.load_i16(0);
unsafe { CStr::from_ptr(ptr) }
}
pub fn floor(&mut self) {
unsafe { basic::int() };
}
pub fn negate(&mut self) {
unsafe { basic::negop() };
}
pub fn add_assign(&mut self, rhs: &F40, arg: &mut ARG) {
let _ = arg;
unsafe { basic::fadd(rhs) }
}
pub fn sub_from(&mut self, value: &F40, arg: &mut ARG) {
let _ = arg;
unsafe { basic::fsub(value) };
}
pub fn mul_assign(&mut self, rhs: &F40, arg: &mut ARG) {
let _ = arg;
unsafe { basic::fmult(rhs) }
}
pub fn mul_10(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::mul10() };
}
pub fn divide(&mut self, value: &F40, arg: &mut ARG) {
let _ = arg;
unsafe { basic::fdiv(value) };
}
pub fn sqrt(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::sqr() };
}
pub fn exp(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::exp() };
}
pub fn ln(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::log() };
}
pub fn cos(&mut self) {
unsafe { kernal::cos() }
}
pub fn sin(&mut self) {
unsafe { kernal::sin() }
}
pub fn tan(&mut self) {
unsafe { kernal::tan() }
}
pub fn arctan(&mut self) {
unsafe { kernal::atn() }
}
pub fn poly1<const N: usize>(&mut self, poly: &kernal::Polynomial<kernal::OddTerms, N>) {
unsafe { poly.poly() };
}
pub fn poly2<const N: usize>(&mut self, poly: &kernal::Polynomial<kernal::AllTerms, N>) {
unsafe { poly.poly() };
}
pub fn abs(&mut self) {
unsafe { basic::abs() };
}
pub fn abs_div_10(&mut self, arg: &mut ARG) {
let _ = arg;
unsafe { basic::div10() };
}
pub fn signum(&mut self) {
unsafe { basic::sgn() };
}
pub fn is_positive(&self) -> bool {
matches!(unsafe { basic::sign() }, Ordering::Greater)
}
pub fn is_negative(&self) -> bool {
matches!(unsafe { basic::sign() }, Ordering::Less)
}
}
impl<'a> PartialEq<F40> for FAC<'a, Basic> {
fn eq(&self, other: &F40) -> bool {
matches!(self.partial_cmp(other), Some(Ordering::Equal))
}
}
impl<'a> PartialOrd<F40> for FAC<'a, Basic> {
fn partial_cmp(&self, other: &F40) -> Option<Ordering> {
Some(unsafe { basic::fcomp(other) })
}
}
impl<'a> AddAssign<&ARG> for FAC<'a, Basic> {
fn add_assign(&mut self, rhs: &ARG) {
let _ = rhs;
unsafe { basic::faddt() }
}
}
pub struct ARG {
_arg: peripheral::ARG,
}
impl ARG {
pub fn new(arg: peripheral::ARG) -> Self {
Self { _arg: arg }
}
pub fn load_from_fac<'a>(&mut self, fac: &mut FAC<'a, Basic>) {
fac.copy_to_arg(self);
}
pub fn sub<'a>(&mut self, fac: &mut FAC<'a, Basic>) {
let _ = fac;
unsafe { basic::fsubt() };
}
pub fn divf<'a>(&mut self, value: &F40, fac: &mut FAC<'a, Basic>) {
let _ = fac;
unsafe { basic::fdivarg(value) };
}
pub fn div<'a>(&mut self, fac: &mut FAC<'a, Basic>) {
let _ = fac;
unsafe { basic::fdivt() };
}
pub fn powf<'a>(&mut self, value: &F40, fac: &mut FAC<'a, Basic>) {
let _ = fac;
unsafe { basic::fpwr(value) };
}
pub fn pow<'a>(&self, fac: &mut FAC<'a, Basic>) {
let _ = fac;
unsafe { basic::fpwrt() };
}
}
pub struct FPSTR {
_fpstr: peripheral::FPSTR,
}
impl FPSTR {
pub fn new(fpstr: peripheral::FPSTR) -> Self {
Self { _fpstr: fpstr }
}
}