use crate::core::SyncBlock;
pub const Q65_SYNC_POSITIONS: [u32; 22] = [
0, 8, 11, 12, 14, 21, 22, 25, 26, 32, 34, 37, 45, 49, 54, 59, 61, 65, 68, 73, 75, 84,
];
pub const Q65_DATA_POSITIONS: [u32; 63] = {
let mut out = [0u32; 63];
let mut k = 0usize;
let mut i = 0u32;
while i < 85 {
let mut is_sync = false;
let mut j = 0usize;
while j < 22 {
if Q65_SYNC_POSITIONS[j] == i {
is_sync = true;
break;
}
j += 1;
}
if !is_sync {
out[k] = i;
k += 1;
}
i += 1;
}
out
};
const SYNC_TONE: [u8; 1] = [0];
pub const Q65_SYNC_BLOCKS: [SyncBlock; 22] = {
let mut blocks = [SyncBlock {
start_symbol: 0,
pattern: &SYNC_TONE,
}; 22];
let mut i = 0usize;
while i < 22 {
blocks[i] = SyncBlock {
start_symbol: Q65_SYNC_POSITIONS[i],
pattern: &SYNC_TONE,
};
i += 1;
}
blocks
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sync_and_data_positions_partition_85() {
let mut seen = [false; 85];
for &p in &Q65_SYNC_POSITIONS {
assert!(p < 85, "sync pos {p} out of range");
assert!(!seen[p as usize], "duplicate sync pos {p}");
seen[p as usize] = true;
}
for &p in &Q65_DATA_POSITIONS {
assert!(p < 85, "data pos {p} out of range");
assert!(!seen[p as usize], "duplicate data pos {p}");
seen[p as usize] = true;
}
assert!(seen.iter().all(|&b| b), "some position uncovered");
}
#[test]
fn sync_positions_are_strictly_ascending() {
for w in Q65_SYNC_POSITIONS.windows(2) {
assert!(w[0] < w[1], "sync positions not ascending: {w:?}");
}
}
#[test]
fn sync_blocks_match_positions() {
assert_eq!(Q65_SYNC_BLOCKS.len(), 22);
for (i, block) in Q65_SYNC_BLOCKS.iter().enumerate() {
assert_eq!(block.start_symbol, Q65_SYNC_POSITIONS[i]);
assert_eq!(block.pattern, &[0u8]);
}
}
#[test]
fn data_positions_strictly_ascending() {
for w in Q65_DATA_POSITIONS.windows(2) {
assert!(w[0] < w[1], "data positions not ascending: {w:?}");
}
}
}