looklook 0.7.0

Descriptive signal synthesiser.
// Copyright 2026 Gabriel Bjørnager Jensen.
//
// This file is part of LOOKLOOK.
//
// LOOKLOOK is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later ver-
// sion.
//
// LOOKLOOK is distributed in the hope that it will be useful, but WITHOUT ANY WAR-
// RANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License along
// with LOOKLOOK. If not, see <https://www.gnu.org/licenses/>.

//! The [`Regs`] type.

use crate::isa::{An, Dn};
use crate::vm::{Int, Sr};

/// Regsisters.
#[derive(Debug)]
pub struct Regs {
	/// The data registers `D0` through `D7`.
	data: [Int<4>; 8],

	/// The address registers `A0` through `A7`.
	address: [Int<4>; 8],

	/// The `PC` programme counter.
	pc: Int<4>,

	/// The `SR` status register.
	sr: Sr,
}

impl Regs {
	/// Constructs a new, default stack.
	#[inline]
	#[must_use]
	pub const fn new() -> Self {
		Self {
			data:    [Default::default(); _],
			address: [Default::default(); _],
			pc:      Default::default(),
			sr:      Default::default(),
		}
	}

	/// Copies a data register.
	#[inline]
	#[must_use]
	pub const fn data(&self, index: Dn) -> Int<4> {
		self.data[index.as_usize()]
	}

	/// Mutably borrows a data register.
	#[inline]
	pub const fn data_mut(&mut self, index: Dn) -> &mut Int<4> {
		&mut self.data[index.as_usize()]
	}

	/// Copies an address register.
	#[inline]
	#[must_use]
	pub const fn address(&self, index: An) -> Int<4> {
		self.address[index.as_usize()]
	}

	/// Mutably borrows an address register.
	#[inline]
	pub const fn address_mut(&mut self, index: An) -> &mut Int<4> {
		&mut self.address[index.as_usize()]
	}

	/// Copies the programme counter.
	#[inline(always)]
	#[must_use]
	pub const fn pc(&self) -> Int<4> {
		self.pc
	}

	/// Mutably borrows the programme counter.
	#[inline(always)]
	#[must_use]
	pub const fn pc_mut(&mut self) -> &mut Int<4> {
		&mut self.pc
	}

	/// Increments the programme counter by a specific amount.
	///
	/// The result is truncated to fit `32` bits.
	#[inline]
	pub const fn inc_pc(&mut self, value: u32) {
		let result = self.pc.as_u32().wrapping_add(value);
		self.pc = Int::from_u32(result);
	}

	/// Copies the status register.
	#[inline(always)]
	#[must_use]
	pub const fn sr(&self) -> Sr {
		self.sr
	}

	/// Mutably borrows the status register.
	#[inline(always)]
	#[must_use]
	pub const fn sr_mut(&mut self) -> &mut Sr {
		&mut self.sr
	}

	/// Resets all entire registers.
	#[inline]
	pub const fn clear(&mut self) {
		*self = Self::new();
	}
}

const impl Default for Regs {
	#[inline(always)]
	fn default() -> Self {
		const { Self::new() }
	}
}