modularize
This commit is contained in:
170
webroot/js/filesystems/base.js
Normal file
170
webroot/js/filesystems/base.js
Normal file
@@ -0,0 +1,170 @@
|
||||
// Base filesystem class that defines the common interface for all filesystem implementations
|
||||
|
||||
import { parseHex, validateInput, checkDependencies, updateResultItem } from '../utils.js';
|
||||
|
||||
export class BaseFilesystem {
|
||||
constructor(name, variants = []) {
|
||||
this.name = name;
|
||||
this.variants = variants; // Array of variant configurations
|
||||
}
|
||||
|
||||
// Abstract method to be implemented by subclasses
|
||||
getVariants() {
|
||||
return this.variants;
|
||||
}
|
||||
|
||||
// Generate HTML for constants section
|
||||
generateConstantsHTML(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return '';
|
||||
|
||||
return `
|
||||
<div class="section constants">
|
||||
<h2>Konstanten</h2>
|
||||
<div class="input-grid">
|
||||
${variant.constants.map(constant => `
|
||||
<div class="input-group">
|
||||
<label for="${constant.id}">${constant.label} <span class="unit-indicator">(${constant.unit})</span>:</label>
|
||||
<input type="text" id="${constant.id}" value="${constant.default}" placeholder="${constant.default}">
|
||||
<div class="error-message" id="${constant.id}-error"></div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Generate HTML for input parameters section
|
||||
generateInputsHTML(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return '';
|
||||
|
||||
return `
|
||||
<div class="section">
|
||||
<h2>Eingabeparameter</h2>
|
||||
<div class="input-grid">
|
||||
${variant.inputs.map(input => `
|
||||
<div class="input-group">
|
||||
<label for="${input.id}">${input.label} <span class="unit-indicator">(${input.unit})</span>:</label>
|
||||
<input type="text" id="${input.id}" placeholder="${input.placeholder}">
|
||||
<div class="error-message" id="${input.id}-error"></div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Generate HTML for results section
|
||||
generateResultsHTML(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return '';
|
||||
|
||||
return `
|
||||
<div class="section results">
|
||||
<h2>Berechnete Werte</h2>
|
||||
${variant.resultGroups.map(group => `
|
||||
<div class="result-group">
|
||||
<h3>${group.name}</h3>
|
||||
${group.results.map(result => `
|
||||
<div class="result-item" data-deps="${result.dependencies.join(',')}">
|
||||
<span class="result-label" data-formula="${result.formula}">${result.label}:</span>
|
||||
<div class="result-value-container">
|
||||
<span class="result-value" id="${result.id}">-</span>
|
||||
<button class="copy-btn" onclick="copyToClipboard('${result.id}')">📋</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Generate HTML for formulas section
|
||||
generateFormulasHTML(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return '';
|
||||
|
||||
return `
|
||||
<div class="section formulas">
|
||||
<h2>Berechnungsformeln ${this.name}</h2>
|
||||
<div class="formula-box">
|
||||
${variant.formulas.map(formula => `
|
||||
<div class="formula"><span class="calculated">${formula.name}</span> = ${formula.expression}</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Generate complete tab content HTML
|
||||
generateTabContentHTML(variantId, calculatorHTML) {
|
||||
return `
|
||||
<div class="tab-content" id="${variantId}">
|
||||
<div class="constants-calculator-container">
|
||||
${this.generateConstantsHTML(variantId)}
|
||||
<div class="section hex-calculator">
|
||||
<h2>Hex-Rechner</h2>
|
||||
${calculatorHTML}
|
||||
</div>
|
||||
</div>
|
||||
${this.generateInputsHTML(variantId)}
|
||||
${this.generateResultsHTML(variantId)}
|
||||
${this.generateFormulasHTML(variantId)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Abstract method for calculations - to be implemented by subclasses
|
||||
calculate(variantId) {
|
||||
throw new Error('calculate method must be implemented by subclass');
|
||||
}
|
||||
|
||||
// Setup input event listeners for this filesystem
|
||||
setupInputListeners(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return;
|
||||
|
||||
const allInputIds = [
|
||||
...variant.constants.map(c => c.id),
|
||||
...variant.inputs.map(i => i.id)
|
||||
];
|
||||
|
||||
allInputIds.forEach(inputId => {
|
||||
const input = document.getElementById(inputId);
|
||||
if (input) {
|
||||
input.addEventListener('input', () => {
|
||||
validateInput(inputId, input.value);
|
||||
this.calculate(variantId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get all input values for a variant
|
||||
getInputValues(variantId) {
|
||||
const variant = this.variants.find(v => v.id === variantId);
|
||||
if (!variant) return {};
|
||||
|
||||
const values = {};
|
||||
|
||||
// Get constants
|
||||
variant.constants.forEach(constant => {
|
||||
const element = document.getElementById(constant.id);
|
||||
if (element) {
|
||||
values[constant.id] = parseHex(element.value) || 0;
|
||||
}
|
||||
});
|
||||
|
||||
// Get inputs
|
||||
variant.inputs.forEach(input => {
|
||||
const element = document.getElementById(input.id);
|
||||
if (element) {
|
||||
values[input.id] = parseHex(element.value);
|
||||
}
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
398
webroot/js/filesystems/fat.js
Normal file
398
webroot/js/filesystems/fat.js
Normal file
@@ -0,0 +1,398 @@
|
||||
// FAT filesystem implementation (FAT12/16 and FAT32)
|
||||
|
||||
import { BaseFilesystem } from './base.js';
|
||||
import { checkDependencies, updateResultItem } from '../utils.js';
|
||||
|
||||
export class FATFilesystem extends BaseFilesystem {
|
||||
constructor() {
|
||||
super('FAT', [
|
||||
{
|
||||
id: 'fat1216',
|
||||
name: 'FAT12/16',
|
||||
constants: [
|
||||
{ id: 'baseOffset1216', label: 'Basis-Offset', unit: 'Bytes', default: '0x0' },
|
||||
{ id: 'sectorSize1216', label: 'Sektorgröße', unit: 'Bytes', default: '0x200' }
|
||||
],
|
||||
inputs: [
|
||||
{ id: 'reservedSectors1216', label: 'Reservierte Sektoren', unit: 'Anzahl', placeholder: '0x1' },
|
||||
{ id: 'numFATs1216', label: 'Anzahl FATs', unit: 'Anzahl', placeholder: '0x2' },
|
||||
{ id: 'fatSizeSectors1216', label: 'FAT-Größe', unit: 'Sektoren', placeholder: '0x4000' },
|
||||
{ id: 'maxRootEntries1216', label: 'Max. Root-Einträge', unit: 'Anzahl', placeholder: '0x200' },
|
||||
{ id: 'partitionSizeInSectors1216', label: 'Partitionsgröße', unit: 'Sektoren', placeholder: '0x4015' },
|
||||
{ id: 'clusterSizeSectors1216', label: 'Clustergröße', unit: 'Sektoren', placeholder: '0x2' },
|
||||
{ id: 'clusterNumber1216', label: 'Cluster-Nummer', unit: 'Nummer', placeholder: '0x2' }
|
||||
],
|
||||
resultGroups: [
|
||||
{
|
||||
name: 'FAT-Struktur',
|
||||
results: [
|
||||
{ id: 'fatStart1216', label: 'FAT-Bereich Anfang (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216'], formula: 'reservedSectors × sectorSize + baseOffset' },
|
||||
{ id: 'fatStartSector1216', label: 'FAT-Bereich Anfang (Sektor)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216'], formula: 'fatStart ÷ sectorSize' },
|
||||
{ id: 'fatSize1216', label: 'FAT-Bereich Größe (Bytes)', dependencies: ['numFATs1216', 'fatSizeSectors1216', 'sectorSize1216'], formula: 'numFATs × fatSizeSectors × sectorSize' },
|
||||
{ id: 'fat2Start1216', label: 'FAT2 Anfang (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'fatSizeSectors1216'], formula: 'fatStart + (fatSizeSectors × sectorSize)' },
|
||||
{ id: 'fatEnd1216', label: 'FAT-Bereich Ende (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216'], formula: 'fatStart + fatSize' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Root-Directory',
|
||||
results: [
|
||||
{ id: 'rootDirStart1216', label: 'Root-Directory Anfang (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216'], formula: 'fatEnd' },
|
||||
{ id: 'rootDirSize1216', label: 'Root-Directory Größe (Bytes)', dependencies: ['maxRootEntries1216'], formula: 'maxRootEntries × 0x20' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Daten-Bereich',
|
||||
results: [
|
||||
{ id: 'dataStart1216', label: 'Daten-Bereich Anfang (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'], formula: 'fatEnd + rootDirSize' },
|
||||
{ id: 'dataStartSector1216', label: 'Daten-Bereich Anfang (Sektor)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'], formula: 'dataStart ÷ sectorSize' },
|
||||
{ id: 'dataSize1216', label: 'Daten-Bereich Größe (Bytes)', dependencies: ['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSectors1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'], formula: '(partitionSizeInSectors × sectorSize) - (dataStart - baseOffset)' },
|
||||
{ id: 'clusterSize1216', label: 'Cluster-Größe (Bytes)', dependencies: ['sectorSize1216', 'clusterSizeSectors1216'], formula: 'sectorSize × clusterSizeSectors' },
|
||||
{ id: 'numClusters1216', label: 'Anzahl Cluster', dependencies: ['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSectors1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216'], formula: 'dataSize ÷ clusterSize' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Spezifischer Cluster',
|
||||
results: [
|
||||
{ id: 'clusterStart1216', label: 'Cluster Anfang (Bytes)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216', 'clusterNumber1216'], formula: 'dataStart + (clusterNumber - 0x2) × clusterSize' },
|
||||
{ id: 'clusterStartSector1216', label: 'Cluster Anfang (Sektor)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216', 'clusterNumber1216'], formula: 'clusterStart ÷ sectorSize' },
|
||||
{ id: 'fatEntryPos1216', label: 'FAT-Eintrag Position (Bytes, nur FAT16)', dependencies: ['reservedSectors1216', 'sectorSize1216', 'baseOffset1216', 'clusterNumber1216'], formula: 'fatStart + (clusterNumber × 2) für FAT16' }
|
||||
]
|
||||
}
|
||||
],
|
||||
formulas: [
|
||||
{ name: 'FAT-Bereich Anfang', expression: 'Reservierte Sektoren × Sektorgröße + Basis-Offset' },
|
||||
{ name: 'FAT-Bereich Größe', expression: 'Anzahl FATs × FAT-Größe in Sektoren × Sektorgröße' },
|
||||
{ name: 'FAT2 Anfang', expression: 'FAT-Bereich Anfang + FAT-Größe in Bytes' },
|
||||
{ name: 'FAT-Bereich Ende', expression: 'FAT-Bereich Anfang + FAT-Bereich Größe' },
|
||||
{ name: 'Root-Directory Größe', expression: 'Max. Root-Einträge × 0x20' },
|
||||
{ name: 'Daten-Bereich Anfang', expression: 'FAT-Bereich Ende + Root-Directory Größe' },
|
||||
{ name: 'Daten-Bereich Größe', expression: '(Partitionsgröße × Sektorgröße) - (Daten-Bereich Anfang - Basis-Offset)' },
|
||||
{ name: 'Cluster-Größe', expression: 'Sektorgröße × Cluster-Größe in Sektoren' },
|
||||
{ name: 'Anzahl Cluster', expression: 'Daten-Bereich Größe ÷ Cluster-Größe' },
|
||||
{ name: 'Cluster Anfang', expression: 'Daten-Bereich Anfang + (Cluster-Nummer - 0x2) × Cluster-Größe' },
|
||||
{ name: 'FAT-Eintrag Position', expression: 'FAT-Bereich Anfang + (Cluster-Nummer × Eintraggröße)' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'fat32',
|
||||
name: 'FAT32',
|
||||
constants: [
|
||||
{ id: 'baseOffset32', label: 'Basis-Offset', unit: 'Bytes', default: '0x0' },
|
||||
{ id: 'sectorSize32', label: 'Sektorgröße', unit: 'Bytes', default: '0x200' }
|
||||
],
|
||||
inputs: [
|
||||
{ id: 'reservedSectors32', label: 'Reservierte Sektoren', unit: 'Anzahl', placeholder: '0x20' },
|
||||
{ id: 'numFATs32', label: 'Anzahl FATs', unit: 'Anzahl', placeholder: '0x2' },
|
||||
{ id: 'fatSizeSectors32', label: 'FAT-Größe', unit: 'Sektoren', placeholder: '0x20000' },
|
||||
{ id: 'rootDirCluster32', label: 'Root-Directory Cluster', unit: 'Nummer', placeholder: '0x2' },
|
||||
{ id: 'partitionSizeInSectors32', label: 'Partitionsgröße', unit: 'Sektoren', placeholder: '0x100000' },
|
||||
{ id: 'clusterSizeSectors32', label: 'Clustergröße', unit: 'Sektoren', placeholder: '0x8' },
|
||||
{ id: 'clusterNumber32', label: 'Cluster-Nummer', unit: 'Nummer', placeholder: '0x2' }
|
||||
],
|
||||
resultGroups: [
|
||||
{
|
||||
name: 'FAT-Struktur',
|
||||
results: [
|
||||
{ id: 'fatStart32', label: 'FAT-Bereich Anfang (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32'], formula: 'reservedSectors × sectorSize + baseOffset' },
|
||||
{ id: 'fatStartSector32', label: 'FAT-Bereich Anfang (Sektor)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32'], formula: 'fatStart ÷ sectorSize' },
|
||||
{ id: 'fatSize32', label: 'FAT-Bereich Größe (Bytes)', dependencies: ['numFATs32', 'fatSizeSectors32', 'sectorSize32'], formula: 'numFATs × fatSizeSectors × sectorSize' },
|
||||
{ id: 'fat2Start32', label: 'FAT2 Anfang (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'fatSizeSectors32'], formula: 'fatStart + (fatSizeSectors × sectorSize)' },
|
||||
{ id: 'fatEnd32', label: 'FAT-Bereich Ende (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: 'fatStart + fatSize' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Daten-Bereich',
|
||||
results: [
|
||||
{ id: 'dataStart32', label: 'Daten-Bereich Anfang (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: 'fatEnd' },
|
||||
{ id: 'dataStartSector32', label: 'Daten-Bereich Anfang (Sektor)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: 'dataStart ÷ sectorSize' },
|
||||
{ id: 'dataSize32', label: 'Daten-Bereich Größe (Bytes)', dependencies: ['partitionSizeInSectors32', 'sectorSize32', 'reservedSectors32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: '(partitionSizeInSectors × sectorSize) - (dataStart - baseOffset)' },
|
||||
{ id: 'clusterSize32', label: 'Cluster-Größe (Bytes)', dependencies: ['sectorSize32', 'clusterSizeSectors32'], formula: 'sectorSize × clusterSizeSectors' },
|
||||
{ id: 'numClusters32', label: 'Anzahl Cluster', dependencies: ['partitionSizeInSectors32', 'sectorSize32', 'reservedSectors32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32'], formula: 'dataSize ÷ clusterSize' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Spezifischer Cluster',
|
||||
results: [
|
||||
{ id: 'clusterStart32', label: 'Cluster Anfang (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32', 'clusterNumber32'], formula: 'dataStart + (clusterNumber - 0x2) × clusterSize' },
|
||||
{ id: 'clusterStartSector32', label: 'Cluster Anfang (Sektor)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32', 'clusterNumber32'], formula: 'clusterStart ÷ sectorSize' },
|
||||
{ id: 'fatEntryPos32', label: 'FAT-Eintrag Position (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'clusterNumber32'], formula: 'fatStart + (clusterNumber × 4)' },
|
||||
{ id: 'rootDirPos32', label: 'Root-Directory Position (Bytes)', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32', 'rootDirCluster32'], formula: 'dataStart + (rootDirCluster - 0x2) × clusterSize' }
|
||||
]
|
||||
}
|
||||
],
|
||||
formulas: [
|
||||
{ name: 'FAT-Bereich Anfang', expression: 'Reservierte Sektoren × Sektorgröße + Basis-Offset' },
|
||||
{ name: 'FAT-Bereich Größe', expression: 'Anzahl FATs × FAT-Größe in Sektoren × Sektorgröße' },
|
||||
{ name: 'FAT2 Anfang', expression: 'FAT-Bereich Anfang + FAT-Größe in Bytes' },
|
||||
{ name: 'FAT-Bereich Ende', expression: 'FAT-Bereich Anfang + FAT-Bereich Größe' },
|
||||
{ name: 'Daten-Bereich Anfang', expression: 'FAT-Bereich Ende (kein festes Root Directory)' },
|
||||
{ name: 'Daten-Bereich Größe', expression: '(Partitionsgröße × Sektorgröße) - (Daten-Bereich Anfang - Basis-Offset)' },
|
||||
{ name: 'Cluster-Größe', expression: 'Sektorgröße × Cluster-Größe in Sektoren' },
|
||||
{ name: 'Anzahl Cluster', expression: 'Daten-Bereich Größe ÷ Cluster-Größe' },
|
||||
{ name: 'Cluster Anfang', expression: 'Daten-Bereich Anfang + (Cluster-Nummer - 0x2) × Cluster-Größe' },
|
||||
{ name: 'FAT-Eintrag Position', expression: 'FAT-Bereich Anfang + (Cluster-Nummer × 4)' },
|
||||
{ name: 'Root-Directory Position', expression: 'Daten-Bereich Anfang + (Root-Directory Cluster - 0x2) × Cluster-Größe' }
|
||||
]
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
calculate(variantId) {
|
||||
const values = this.getInputValues(variantId);
|
||||
const results = {};
|
||||
|
||||
if (variantId === 'fat1216') {
|
||||
this.calculateFAT1216(values, results);
|
||||
} else if (variantId === 'fat32') {
|
||||
this.calculateFAT32(values, results);
|
||||
}
|
||||
}
|
||||
|
||||
calculateFAT1216(values, results) {
|
||||
const suffix = '1216';
|
||||
|
||||
// FAT Start
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`])) {
|
||||
results.fatStart = values.reservedSectors1216 * values.sectorSize1216 + values.baseOffset1216;
|
||||
results.fatStartSector = Math.floor(results.fatStart / values.sectorSize1216);
|
||||
updateResultItem(`fatStart${suffix}`, results.fatStart, true,
|
||||
`0x${values.reservedSectors1216.toString(16)} × 0x${values.sectorSize1216.toString(16)} + 0x${values.baseOffset1216.toString(16)} = 0x${results.fatStart.toString(16)}`);
|
||||
updateResultItem(`fatStartSector${suffix}`, results.fatStartSector, true,
|
||||
`0x${results.fatStart.toString(16)} ÷ 0x${values.sectorSize1216.toString(16)} = 0x${results.fatStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatStart${suffix}`, 0, false);
|
||||
updateResultItem(`fatStartSector${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT Size
|
||||
if (checkDependencies([`numFATs${suffix}`, `fatSizeSectors${suffix}`, `sectorSize${suffix}`])) {
|
||||
results.fatSize = values.numFATs1216 * values.fatSizeSectors1216 * values.sectorSize1216;
|
||||
updateResultItem(`fatSize${suffix}`, results.fatSize, true,
|
||||
`0x${values.numFATs1216.toString(16)} × 0x${values.fatSizeSectors1216.toString(16)} × 0x${values.sectorSize1216.toString(16)} = 0x${results.fatSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT2 Start
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `fatSizeSectors${suffix}`]) && results.fatStart !== undefined) {
|
||||
results.fat2Start = results.fatStart + (values.fatSizeSectors1216 * values.sectorSize1216);
|
||||
updateResultItem(`fat2Start${suffix}`, results.fat2Start, true,
|
||||
`0x${results.fatStart.toString(16)} + 0x${(values.fatSizeSectors1216 * values.sectorSize1216).toString(16)} = 0x${results.fat2Start.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fat2Start${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT End
|
||||
if (results.fatStart !== undefined && results.fatSize !== undefined) {
|
||||
results.fatEnd = results.fatStart + results.fatSize;
|
||||
updateResultItem(`fatEnd${suffix}`, results.fatEnd, true,
|
||||
`0x${results.fatStart.toString(16)} + 0x${results.fatSize.toString(16)} = 0x${results.fatEnd.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatEnd${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Root Directory Size
|
||||
if (checkDependencies(['maxRootEntries1216'])) {
|
||||
results.rootDirSize = values.maxRootEntries1216 * 0x20;
|
||||
updateResultItem('rootDirSize1216', results.rootDirSize, true,
|
||||
`0x${values.maxRootEntries1216.toString(16)} × 0x20 = 0x${results.rootDirSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem('rootDirSize1216', 0, false);
|
||||
}
|
||||
|
||||
// Root Directory Start
|
||||
if (results.fatEnd !== undefined) {
|
||||
results.rootDirStart = results.fatEnd;
|
||||
updateResultItem('rootDirStart1216', results.rootDirStart, true,
|
||||
`0x${results.fatEnd.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem('rootDirStart1216', 0, false);
|
||||
}
|
||||
|
||||
// Data Start
|
||||
if (results.fatEnd !== undefined && results.rootDirSize !== undefined) {
|
||||
results.dataStart = results.fatEnd + results.rootDirSize;
|
||||
results.dataStartSector = Math.floor(results.dataStart / values.sectorSize1216);
|
||||
updateResultItem('dataStart1216', results.dataStart, true,
|
||||
`0x${results.fatEnd.toString(16)} + 0x${results.rootDirSize.toString(16)} = 0x${results.dataStart.toString(16)}`);
|
||||
updateResultItem('dataStartSector1216', results.dataStartSector, true,
|
||||
`0x${results.dataStart.toString(16)} ÷ 0x${values.sectorSize1216.toString(16)} = 0x${results.dataStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem('dataStart1216', 0, false);
|
||||
updateResultItem('dataStartSector1216', 0, false);
|
||||
}
|
||||
|
||||
// Data Size
|
||||
const requiredForDataSize = [`partitionSizeInSectors${suffix}`, `sectorSize1216`, `reservedSectors${suffix}`, `baseOffset1216`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, 'maxRootEntries1216'];
|
||||
if (checkDependencies(requiredForDataSize) && results.dataStart !== undefined) {
|
||||
const partitionSizeBytes = values.partitionSizeInSectors1216 * values.sectorSize1216;
|
||||
results.dataSize = partitionSizeBytes - (results.dataStart - values.baseOffset1216);
|
||||
updateResultItem(`dataSize${suffix}`, results.dataSize, true,
|
||||
`(0x${values.partitionSizeInSectors1216.toString(16)} × 0x${values.sectorSize1216.toString(16)}) - (0x${results.dataStart.toString(16)} - 0x${values.baseOffset1216.toString(16)}) = 0x${results.dataSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`dataSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Cluster Size
|
||||
if (checkDependencies([`sectorSize1216`, `clusterSizeSectors${suffix}`])) {
|
||||
results.clusterSize = values.sectorSize1216 * values.clusterSizeSectors1216;
|
||||
updateResultItem(`clusterSize${suffix}`, results.clusterSize, true,
|
||||
`0x${values.sectorSize1216.toString(16)} × 0x${values.clusterSizeSectors1216.toString(16)} = 0x${results.clusterSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`clusterSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Number of Clusters
|
||||
if (results.dataSize !== undefined && results.clusterSize !== undefined && results.clusterSize > 0) {
|
||||
results.numClusters = Math.floor(results.dataSize / results.clusterSize);
|
||||
updateResultItem(`numClusters${suffix}`, results.numClusters, true,
|
||||
`0x${results.dataSize.toString(16)} ÷ 0x${results.clusterSize.toString(16)} = 0x${results.numClusters.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`numClusters${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Specific Cluster Start
|
||||
const requiredForCluster = [`reservedSectors${suffix}`, `sectorSize1216`, `baseOffset1216`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, 'maxRootEntries1216', `clusterSizeSectors${suffix}`, `clusterNumber${suffix}`];
|
||||
if (checkDependencies(requiredForCluster) && results.dataStart !== undefined && results.clusterSize !== undefined) {
|
||||
results.clusterStart = results.dataStart + (values.clusterNumber1216 - 0x2) * results.clusterSize;
|
||||
results.clusterStartSector = Math.floor(results.clusterStart / values.sectorSize1216);
|
||||
updateResultItem(`clusterStart${suffix}`, results.clusterStart, true,
|
||||
`0x${results.dataStart.toString(16)} + (0x${values.clusterNumber1216.toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.clusterStart.toString(16)}`);
|
||||
updateResultItem(`clusterStartSector${suffix}`, results.clusterStartSector, true,
|
||||
`0x${results.clusterStart.toString(16)} ÷ 0x${values.sectorSize1216.toString(16)} = 0x${results.clusterStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`clusterStart${suffix}`, 0, false);
|
||||
updateResultItem(`clusterStartSector${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT Entry Position
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize1216`, `baseOffset1216`, `clusterNumber${suffix}`]) && results.fatStart !== undefined) {
|
||||
const entrySize = 2; // FAT16 uses 2 bytes per entry
|
||||
results.fatEntryPos = results.fatStart + (values.clusterNumber1216 * entrySize);
|
||||
updateResultItem(`fatEntryPos${suffix}`, results.fatEntryPos, true,
|
||||
`0x${results.fatStart.toString(16)} + (0x${values.clusterNumber1216.toString(16)} × ${entrySize}) = 0x${results.fatEntryPos.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatEntryPos${suffix}`, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
calculateFAT32(values, results) {
|
||||
const suffix = '32';
|
||||
|
||||
// FAT Start
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`])) {
|
||||
results.fatStart = values.reservedSectors32 * values.sectorSize32 + values.baseOffset32;
|
||||
results.fatStartSector = Math.floor(results.fatStart / values.sectorSize32);
|
||||
updateResultItem(`fatStart${suffix}`, results.fatStart, true,
|
||||
`0x${values.reservedSectors32.toString(16)} × 0x${values.sectorSize32.toString(16)} + 0x${values.baseOffset32.toString(16)} = 0x${results.fatStart.toString(16)}`);
|
||||
updateResultItem(`fatStartSector${suffix}`, results.fatStartSector, true,
|
||||
`0x${results.fatStart.toString(16)} ÷ 0x${values.sectorSize32.toString(16)} = 0x${results.fatStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatStart${suffix}`, 0, false);
|
||||
updateResultItem(`fatStartSector${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT Size
|
||||
if (checkDependencies([`numFATs${suffix}`, `fatSizeSectors${suffix}`, `sectorSize${suffix}`])) {
|
||||
results.fatSize = values.numFATs32 * values.fatSizeSectors32 * values.sectorSize32;
|
||||
updateResultItem(`fatSize${suffix}`, results.fatSize, true,
|
||||
`0x${values.numFATs32.toString(16)} × 0x${values.fatSizeSectors32.toString(16)} × 0x${values.sectorSize32.toString(16)} = 0x${results.fatSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT2 Start
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `fatSizeSectors${suffix}`]) && results.fatStart !== undefined) {
|
||||
results.fat2Start = results.fatStart + (values.fatSizeSectors32 * values.sectorSize32);
|
||||
updateResultItem(`fat2Start${suffix}`, results.fat2Start, true,
|
||||
`0x${results.fatStart.toString(16)} + 0x${(values.fatSizeSectors32 * values.sectorSize32).toString(16)} = 0x${results.fat2Start.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fat2Start${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT End
|
||||
if (results.fatStart !== undefined && results.fatSize !== undefined) {
|
||||
results.fatEnd = results.fatStart + results.fatSize;
|
||||
updateResultItem(`fatEnd${suffix}`, results.fatEnd, true,
|
||||
`0x${results.fatStart.toString(16)} + 0x${results.fatSize.toString(16)} = 0x${results.fatEnd.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatEnd${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Data Start (FAT32 has no fixed root directory)
|
||||
if (results.fatEnd !== undefined) {
|
||||
results.dataStart = results.fatEnd;
|
||||
results.dataStartSector = Math.floor(results.dataStart / values.sectorSize32);
|
||||
updateResultItem('dataStart32', results.dataStart, true,
|
||||
`0x${results.fatEnd.toString(16)}`);
|
||||
updateResultItem('dataStartSector32', results.dataStartSector, true,
|
||||
`0x${results.dataStart.toString(16)} ÷ 0x${values.sectorSize32.toString(16)} = 0x${results.dataStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem('dataStart32', 0, false);
|
||||
updateResultItem('dataStartSector32', 0, false);
|
||||
}
|
||||
|
||||
// Data Size
|
||||
const requiredForDataSize = [`partitionSizeInSectors${suffix}`, `sectorSize32`, `reservedSectors${suffix}`, `baseOffset32`, `numFATs${suffix}`, `fatSizeSectors${suffix}`];
|
||||
if (checkDependencies(requiredForDataSize) && results.dataStart !== undefined) {
|
||||
const partitionSizeBytes = values.partitionSizeInSectors32 * values.sectorSize32;
|
||||
results.dataSize = partitionSizeBytes - (results.dataStart - values.baseOffset32);
|
||||
updateResultItem(`dataSize${suffix}`, results.dataSize, true,
|
||||
`(0x${values.partitionSizeInSectors32.toString(16)} × 0x${values.sectorSize32.toString(16)}) - (0x${results.dataStart.toString(16)} - 0x${values.baseOffset32.toString(16)}) = 0x${results.dataSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`dataSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Cluster Size
|
||||
if (checkDependencies([`sectorSize32`, `clusterSizeSectors${suffix}`])) {
|
||||
results.clusterSize = values.sectorSize32 * values.clusterSizeSectors32;
|
||||
updateResultItem(`clusterSize${suffix}`, results.clusterSize, true,
|
||||
`0x${values.sectorSize32.toString(16)} × 0x${values.clusterSizeSectors32.toString(16)} = 0x${results.clusterSize.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`clusterSize${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Number of Clusters
|
||||
if (results.dataSize !== undefined && results.clusterSize !== undefined && results.clusterSize > 0) {
|
||||
results.numClusters = Math.floor(results.dataSize / results.clusterSize);
|
||||
updateResultItem(`numClusters${suffix}`, results.numClusters, true,
|
||||
`0x${results.dataSize.toString(16)} ÷ 0x${results.clusterSize.toString(16)} = 0x${results.numClusters.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`numClusters${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Specific Cluster Start
|
||||
const requiredForCluster = [`reservedSectors${suffix}`, `sectorSize32`, `baseOffset32`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, `clusterSizeSectors${suffix}`, `clusterNumber${suffix}`];
|
||||
if (checkDependencies(requiredForCluster) && results.dataStart !== undefined && results.clusterSize !== undefined) {
|
||||
results.clusterStart = results.dataStart + (values.clusterNumber32 - 0x2) * results.clusterSize;
|
||||
results.clusterStartSector = Math.floor(results.clusterStart / values.sectorSize32);
|
||||
updateResultItem(`clusterStart${suffix}`, results.clusterStart, true,
|
||||
`0x${results.dataStart.toString(16)} + (0x${values.clusterNumber32.toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.clusterStart.toString(16)}`);
|
||||
updateResultItem(`clusterStartSector${suffix}`, results.clusterStartSector, true,
|
||||
`0x${results.clusterStart.toString(16)} ÷ 0x${values.sectorSize32.toString(16)} = 0x${results.clusterStartSector.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`clusterStart${suffix}`, 0, false);
|
||||
updateResultItem(`clusterStartSector${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// FAT Entry Position
|
||||
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize32`, `baseOffset32`, `clusterNumber${suffix}`]) && results.fatStart !== undefined) {
|
||||
const entrySize = 4; // FAT32 uses 4 bytes per entry
|
||||
results.fatEntryPos = results.fatStart + (values.clusterNumber32 * entrySize);
|
||||
updateResultItem(`fatEntryPos${suffix}`, results.fatEntryPos, true,
|
||||
`0x${results.fatStart.toString(16)} + (0x${values.clusterNumber32.toString(16)} × ${entrySize}) = 0x${results.fatEntryPos.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem(`fatEntryPos${suffix}`, 0, false);
|
||||
}
|
||||
|
||||
// Root Directory Position (FAT32 specific)
|
||||
const requiredForRootPos = [`reservedSectors${suffix}`, `sectorSize32`, `baseOffset32`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, `clusterSizeSectors${suffix}`, `rootDirCluster32`];
|
||||
if (checkDependencies(requiredForRootPos) && results.dataStart !== undefined && results.clusterSize !== undefined) {
|
||||
results.rootDirPos = results.dataStart + (values.rootDirCluster32 - 0x2) * results.clusterSize;
|
||||
updateResultItem('rootDirPos32', results.rootDirPos, true,
|
||||
`0x${results.dataStart.toString(16)} + (0x${values.rootDirCluster32.toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.rootDirPos.toString(16)}`);
|
||||
} else {
|
||||
updateResultItem('rootDirPos32', 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user