use std::fmt;
pub mod skew;
pub mod dpb;
pub mod bpb;
pub mod fat;
pub mod blocks;
#[derive(thiserror::Error,Debug)]
pub enum Error {
#[error("unsupported disk kind")]
UnsupportedDiskKind,
#[error("incompatible disk kind")]
IncompatibleDiskKind,
#[error("problem accessing sector")]
SectorAccess
}
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
pub enum Block {
D13([usize;2]),
DO([usize;2]),
PO(usize),
CPM((usize,u8,u16)),
FAT((u64,u8)),
D64([usize;2])
}
impl Block {
pub fn get_lsecs(&self,secs_per_track: usize) -> Vec<[usize;2]> {
match self {
Self::D13([t,s]) => vec![[*t,*s]],
Self::DO([t,s]) => vec![[*t,*s]],
Self::PO(_) => panic!("function `get_lsecs` not appropriate for ProDOS"),
Self::CPM((block,bsh,off)) => {
let mut ans: Vec<[usize;2]> = Vec::new();
let lsecs_per_block = 1 << bsh;
for sec_count in block*lsecs_per_block..(block+1)*lsecs_per_block {
ans.push([*off as usize + sec_count/secs_per_track , 1 + sec_count%secs_per_track]);
}
ans
},
Self::FAT((sec1,secs)) => {
let mut ans: Vec<[usize;2]> = Vec::new();
for sec in (*sec1 as usize)..(*sec1 as usize)+(*secs as usize) {
ans.push([sec/secs_per_track , sec%secs_per_track]);
}
ans
},
Self::D64([t,s]) => vec![[*t,*s]]
}
}
}
impl fmt::Display for Block {
fn fmt(&self,f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::D13([t,s]) => write!(f,"D13 track {} sector {}",t,s),
Self::DO([t,s]) => write!(f,"DOS track {} sector {}",t,s),
Self::PO(b) => write!(f,"ProDOS block {}",b),
Self::CPM((b,s,o)) => write!(f,"CPM block {} shift {} offset {}",b,s,o),
Self::FAT((s1,secs)) => write!(f,"FAT cluster sec1 {} secs {}",s1,secs),
Self::D64([t,s]) => write!(f,"D64 track {} sector {}",t,s)
}
}
}