mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import { STORAGE_TYPES } from './constants';
|
|
import { Directory } from './directory';
|
|
import type { byte, word } from 'js/types';
|
|
import { ProDOSVolume } from '.';
|
|
import { FileEntry } from './file_entry';
|
|
|
|
export function uint32ToDate(val: word) {
|
|
// yyyyyyy m|mmmm ddddd|000hhhhh|00mmmmmm
|
|
|
|
if (val) {
|
|
const yearMonthDay = val & 0xffff;
|
|
const hourMinute = val >> 16;
|
|
|
|
const year = yearMonthDay >> 9;
|
|
const month = (yearMonthDay & 0x01E0) >> 5;
|
|
const day = yearMonthDay & 0x001F;
|
|
|
|
const hour = hourMinute >> 8;
|
|
const min = hourMinute & 0xff;
|
|
|
|
return new Date(year < 70 ? 2000 + year : 1900 + year, month - 1, day, hour, min);
|
|
}
|
|
return new Date(0);
|
|
}
|
|
|
|
export function dateToUint32(date: Date) {
|
|
// yyyyyyy m|mmmm ddddd|000hhhhh|00mmmmmm
|
|
|
|
let val = 0;
|
|
|
|
if (date) {
|
|
const year = date.getFullYear() - 1900;
|
|
const month = date.getMonth() + 1;
|
|
const day = date.getDate();
|
|
|
|
const hour = date.getHours();
|
|
const min = date.getMinutes();
|
|
|
|
const yearMonthDay = year << 9 | month << 5 | day;
|
|
const hourMinute = hour << 8 | min;
|
|
val = hourMinute << 16 | yearMonthDay;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
export function readFileName(block: DataView, offset: word, nameLength: byte, caseBits: word) {
|
|
let name = '';
|
|
if (!(caseBits & 0x8000)) {
|
|
caseBits = 0;
|
|
}
|
|
// File is deleted, brute force old name
|
|
if (nameLength === 0) {
|
|
nameLength = 15;
|
|
}
|
|
for (let idx = 0; idx < nameLength; idx++) {
|
|
caseBits <<= 1;
|
|
const char = String.fromCharCode(block.getUint8(offset + idx) & 0x7f);
|
|
name += caseBits & 0x8000 ? char.toLowerCase() : char;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
export function writeFileName(block: DataView, offset: word, name: string) {
|
|
let caseBits = 0;
|
|
for (let idx = 0; idx < name.length; idx++) {
|
|
caseBits <<= 1;
|
|
let charCode = name.charCodeAt(idx);
|
|
if (charCode > 0x60 && charCode < 0x7B) {
|
|
caseBits |= 0x1;
|
|
charCode -= 0x20;
|
|
}
|
|
block.setUint8(offset + idx, charCode);
|
|
}
|
|
return caseBits;
|
|
}
|
|
|
|
export function dumpDirectory(volume: ProDOSVolume, dirEntry: FileEntry, depth: string) {
|
|
const dir = new Directory(volume, dirEntry);
|
|
let str = '';
|
|
|
|
for (let idx = 0; idx < dir.entries.length; idx++) {
|
|
const fileEntry = dir.entries[idx];
|
|
if (fileEntry.storageType !== STORAGE_TYPES.DELETED) {
|
|
str += depth + fileEntry.name + '\n';
|
|
if (fileEntry.storageType === STORAGE_TYPES.DIRECTORY) {
|
|
str += dumpDirectory(volume, fileEntry, depth + ' ');
|
|
}
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
export function dump(volume: ProDOSVolume) {
|
|
const vdh = volume.vdh();
|
|
let str = vdh.name;
|
|
for (let idx = 0; idx < vdh.entries.length; idx++) {
|
|
const fileEntry = vdh.entries[idx];
|
|
str += fileEntry.name + '\n';
|
|
if (fileEntry.storageType === STORAGE_TYPES.DIRECTORY) {
|
|
str += dumpDirectory(volume, fileEntry, ' ');
|
|
}
|
|
}
|
|
return str;
|
|
}
|