use crate::{DiskChs, DiskImage};
use std::fmt::{Display, Formatter, Result};
#[derive(Copy, Clone, Debug)]
pub enum CopyProtectionScheme {
FormasterCopyLock(u8),
SoftguardSuperlok(u8),
EaInterlock(u8),
VaultProlok,
XemagXelok(u8),
HlsDuplication,
Undetermined,
}
impl Display for CopyProtectionScheme {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
CopyProtectionScheme::FormasterCopyLock(v) => write!(f, "Formaster CopyLock v{}", v),
CopyProtectionScheme::SoftguardSuperlok(_v) => write!(f, "Softguard Superlok"),
CopyProtectionScheme::EaInterlock(v) => write!(f, "EA Interlock v{}", v),
CopyProtectionScheme::VaultProlok => write!(f, "Vault Prolok"),
CopyProtectionScheme::XemagXelok(v) => write!(f, "XEMAG Xelok v{}", v),
CopyProtectionScheme::HlsDuplication => write!(f, "HLS Duplication"),
CopyProtectionScheme::Undetermined => write!(f, "Likely protected, but scheme undetermined"),
}
}
}
impl DiskImage {
pub fn detect_copy_protection(&self) -> Option<CopyProtectionScheme> {
for track in self.track_iter() {
let track_ch = track.ch();
match track.scan_sector(DiskChs::new(track_ch.c(), track_ch.h(), 1), Some(1)) {
Ok(scan_result) => {
if scan_result.data_crc_error {
return if scan_result.address_crc_error {
Some(CopyProtectionScheme::FormasterCopyLock(2))
} else {
Some(CopyProtectionScheme::FormasterCopyLock(1))
};
}
}
Err(_) => {}
}
if track_ch.c() > 1 {
match track.scan_sector(DiskChs::new(track_ch.c(), track_ch.h(), 1), Some(6)) {
Ok(scan_result) => {
if scan_result.data_crc_error {
return Some(CopyProtectionScheme::SoftguardSuperlok(1));
}
}
Err(_) => {}
}
}
if track.get_sector_ct() == 96 {
return Some(CopyProtectionScheme::EaInterlock(1));
}
}
None
}
}