1use core::convert::From;
2
3#[derive(Copy, Clone, PartialEq, Eq, Debug)]
11pub struct Address {
12 base: u16,
13 ramp: u8,
14}
15
16impl Address {
17 const PCWORD_MASK: u16 = (crate::SPM_PAGESIZE_BYTES - 1) as u16;
18 const PCPAGE_MASK: u16 = !Self::PCWORD_MASK;
19
20 fn new(base: u32) -> Self {
21 Self {
22 base: base as u16,
23 ramp: (base >> 16) as u8,
24 }
25 }
26
27 pub fn into_page_aligned(self) -> Self {
31 Self {
32 base: self.base & Self::PCPAGE_MASK,
33 ramp: self.ramp,
34 }
35 }
36
37 pub fn word(&self) -> u16 {
39 self.base & Self::PCWORD_MASK
40 }
41
42 pub fn ramp(&self) -> u8 {
44 self.ramp
45 }
46}
47
48impl From<u16> for Address {
49 fn from(i: u16) -> Self {
50 Self::new(i as u32)
51 }
52}
53
54impl From<u8> for Address {
55 fn from(i: u8) -> Self {
56 Self::new(i as u32)
57 }
58}
59
60impl From<u32> for Address {
61 fn from(i: u32) -> Self {
62 Self::new(i)
63 }
64}
65
66impl From<Address> for u32 {
67 fn from(address: Address) -> u32 {
68 address.base as u32 + ((address.ramp as u32) << 16)
69 }
70}
71
72impl From<Address> for u16 {
73 fn from(address: Address) -> u16 {
74 address.base
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn it_aligns_addess_to_page() {
84 let start_address = crate::SPM_PAGESIZE_BYTES as u32 * 8 + 17;
85 let address: Address = start_address.into();
86
87 assert_eq!(
88 address.into_page_aligned(),
89 Address::new(crate::SPM_PAGESIZE_BYTES as u32 * 8)
90 );
91 }
92
93 #[test]
94 fn it_masks_pcword_part() {
95 let start_address = crate::SPM_PAGESIZE_BYTES as u32 * 8 + 17;
96 let address: Address = start_address.into();
97
98 assert_eq!(address.word(), 17);
99 }
100}