9f107b5f80
- fetch: Go CLI tool for searching, downloading, and extracting AKAI sampler ISOs from archive.org - scripts/extract_wavs.sh: Shell script driving akaiutil to convert samples to WAV - Dockerfile: Multi-stage build packaging akaiutil + fetch - third_party/akaiutil: Vendored akaiutil v4.6.7 source (GPLv2) - docs/akaiutil.md: Full akaiutil reference
675 lines
30 KiB
C
Executable File
675 lines
30 KiB
C
Executable File
#ifndef __AKAIUTIL_H
|
|
#define __AKAIUTIL_H
|
|
/*
|
|
* Copyright (C) 2008,2010,2012,2018,2019,2020,2021 Klaus Michael Indlekofer. All rights reserved.
|
|
*
|
|
* m.indlekofer@gmx.de
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
|
|
#include "commoninclude.h"
|
|
|
|
|
|
|
|
/* AKAI S900/S1000/S3000 filesystems */
|
|
|
|
/* Note: all data types are little endian */
|
|
|
|
|
|
|
|
/* floppy */
|
|
|
|
/* floppy filesystem blocksize */
|
|
#define AKAI_FL_BLOCKSIZE 0x0400 /* 1KB */
|
|
/* Note: must be == AKAI_FL_SECSIZE (low-level floppy sector size, defined in akaiutil_io.h) */
|
|
#if defined(AKAI_FL_SECSIZE)&&(AKAI_FL_BLOCKSIZE!=AKAI_FL_SECSIZE)
|
|
#error "AKAI_FL_BLOCKSIZE!=AKAI_FL_SECSIZE"
|
|
#endif
|
|
|
|
#define AKAI_FLL_SIZE 0x0320 /* low-density floppy size in floppy blocks (800KB) */
|
|
#define AKAI_FLH_SIZE 0x0640 /* high-density floppy size in floppy blocks (1.6MB) */
|
|
|
|
|
|
|
|
/* harddisk */
|
|
|
|
/* harddisk filesystem blocksize */
|
|
#define AKAI_HD_BLOCKSIZE 0x2000 /* 8KB */
|
|
|
|
/* S900 harddisk */
|
|
#define AKAI_HD9_MAXSIZE 0x1fff /* max. harddisk size in harddisk blocks (approx. 64MB) */
|
|
#define AKAI_HD9_DEFSIZE 0x09c4 /* default harddisk size in harddisk blocks (approx. 19.5MB) */
|
|
#define AKAI_HD9_SH205SIZE 0x0a29 /* "Atari SH205" harddisk size in harddisk blocks (approx. 20.3MB) */
|
|
#define AKAI_HD9_SUPRA20MSIZE 0x09c4 /* "Supra 20M" harddisk size in harddisk blocks (approx. 19.5MB) */
|
|
#define AKAI_HD9_SUPRA30MSIZE 0x0ee4 /* "Supra 30M" harddisk size in harddisk blocks (approx. 29.8MB) */
|
|
#define AKAI_HD9_SUPRA60MSIZE 0x1dc8 /* "Supra 60M" harddisk size in harddisk blocks (approx. 59.6MB) */
|
|
|
|
/* S1000/S3000 harddisk */
|
|
#define AKAI_HD_MAXSIZE 0xffff /* max. harddisk size in harddisk blocks (approx. 512MB, Note: for 16bit block numbers) */
|
|
|
|
/* S1000/S3000 harddisk sampler partition */
|
|
#define AKAI_PART_MAXSIZE 0x1e00 /* max. sampler partition size in harddisk blocks (60MB) */
|
|
#define AKAI_PART_NUM 18 /* max. number of sampler partitions per harddisk */
|
|
|
|
/* S1100/S3000 harddisk DD partition */
|
|
/* Note: max. DD partition size in harddisk blocks is AKAI_HD_MAXSIZE */
|
|
#define AKAI_DDPART_CBLKS 0x20 /* number of blocks per DD partition cluster */
|
|
#define AKAI_DDPART_NUM 18 /* max. number of DD partitions per harddisk */
|
|
|
|
|
|
|
|
/* max. disk size in bytes, Note: fits into 32bit */
|
|
#define AKAI_DISKSIZE_MAX (AKAI_HD_MAXSIZE*AKAI_HD_BLOCKSIZE)
|
|
|
|
|
|
|
|
/* names */
|
|
|
|
#define AKAI_NAME_LEN_S900 10 /* for S900 */
|
|
#define AKAI_NAME_LEN 12 /* for S1000/S3000 */
|
|
|
|
|
|
|
|
/* FAT (for floppies and harddisk sampler partitions) */
|
|
|
|
#define AKAI_FAT_CODE_FREE 0x0000 /* free block */
|
|
#define AKAI_FAT_CODE_BAD 0x2000 /* bad block */
|
|
#define AKAI_FAT_CODE_SYS900FL 0x0000 /* block reserved for system (S900 floppy), warning: same as for free block!!! */
|
|
#define AKAI_FAT_CODE_SYS900HD 0xffff /* block reserved for system (S900 harddisk) */
|
|
#define AKAI_FAT_CODE_SYS 0x4000 /* block reserved for system (S1000/S3000) */
|
|
#define AKAI_FAT_CODE_DIREND900HD 0x8000 /* end of chain for volume directory (S900 harddisk) */
|
|
#define AKAI_FAT_CODE_DIREND1000HD 0x4000 /* end of chain for volume directory (S1000 harddisk), warning: same as for system block!!! */
|
|
#define AKAI_FAT_CODE_DIREND3000 0x8000 /* end of chain for volume directory (S3000) */
|
|
#define AKAI_FAT_CODE_FILEEND900 0x8000 /* end of chain for file (S900) */
|
|
#define AKAI_FAT_CODE_FILEEND 0xc000 /* end of chain for file (S1000/S3000) */
|
|
|
|
|
|
|
|
/* DD FAT (for S1100/S3000 harddisk DD partition) */
|
|
|
|
#define AKAI_DDFAT_CODE_FREE 0x0000 /* free cluster */
|
|
#define AKAI_DDFAT_CODE_BAD 0x2000 /* bad cluster */
|
|
#define AKAI_DDFAT_CODE_SYS 0x8000 /* cluster reserved for system (header cluster) */
|
|
#define AKAI_DDFAT_CODE_END 0xffff /* end of chain */
|
|
|
|
|
|
|
|
/* OS versions for volumes and files */
|
|
|
|
#define AKAI_OSVER_S900VOL 0x0000 /* OS version of S900/S950 volume (zero) */
|
|
#define AKAI_OSVER_S1000MAX 0x0428 /* max. OS version of S1000 ("4.40") */
|
|
#define AKAI_OSVER_S1100MAX 0x091e /* max. OS version of S1100 ("9.30") */
|
|
#define AKAI_OSVER_S3000MAX 0x1100 /* max. OS version of S3000 ("17.00") */
|
|
|
|
|
|
|
|
/* file */
|
|
|
|
#define AKAI_FILE_SIZEMAX 0xffffff /* max. file size in bytes (approx. 16MB, Note: for 24bit size in volume directory entry for file) */
|
|
|
|
/* entry in volume directory for file */
|
|
struct akai_voldir_entry_s{
|
|
/* Note: S900 uses first AKAI_NAME_LEN900 chars in name, rest is zero */
|
|
u_char name[AKAI_NAME_LEN]; /* file name */
|
|
#define AKAI_FILE_TAGNUM 0x04 /* number of tags in volume directory entry for file */
|
|
#define AKAI_FILE_TAGFREE 0x00 /* invalid tag number, means: free tag entry for S3000 */
|
|
#define AKAI_FILE_TAGS1000 0x20 /* invalid tag number, default for S1000 */
|
|
/* Note: valid tag numbers are 1, ..., AKAI_PARTHEAD_TAGNUM */
|
|
/* Note: S900 has no tags, all zero */
|
|
u_char tag[AKAI_FILE_TAGNUM]; /* tags */
|
|
#define AKAI_FTYPE_FREE 0x00 /* invalid file type, means: free entry in volume directory */
|
|
u_char type; /* file type */
|
|
u_char size[3]; /* file size in bytes (Note: 24bit) */
|
|
u_char start[2]; /* start block within partition */
|
|
u_char osver[2]; /* if S1000/S3000: OS version */
|
|
/* if S900 compressed file: number of un-compressed floppy blocks */
|
|
/* else: zero */
|
|
}; /* Note: should be 0x0018 Bytes */
|
|
|
|
|
|
|
|
/* volume parameters */
|
|
/* Note: S900 has no volume parameters */
|
|
struct akai_volparam_s{
|
|
u_char progselmidich1; /* program select MIDI channel-1 */
|
|
u_char progselomni; /* MIDI OMNI for program select */
|
|
u_char progselenab; /* program select enable */
|
|
u_char prognr1; /* selected program number-1 */
|
|
u_char playinominovrr; /* MIDI OMNI override for play input */
|
|
u_char sysexch1; /* MIDI system exclusive channel-1 */
|
|
u_char dummy1[42]; /* XXX */
|
|
}; /* Note: should be 0x0030 Bytes */
|
|
|
|
|
|
|
|
/* harddisk volumes */
|
|
|
|
/* harddisk volume directory of files */
|
|
#define AKAI_VOLDIR_ENTRIES_S900HD 128 /* total number of volume directory entries for S900 */
|
|
#define AKAI_VOLDIR_ENTRIES_S1000HD 126 /* total number of volume directory entries for S1000 */
|
|
#define AKAI_VOLDIR_ENTRIES_S3000HD 510 /* total number of volume directory entries for S3000 */
|
|
#define AKAI_VOLDIR_ENTRIES_1BLKHD 341 /* max. number of volume directory entries in 1 harddisk block */
|
|
|
|
/* S900 harddisk volume */
|
|
struct akai_voldir900hd_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S900HD]; /* volume directory entries for files */
|
|
u_char dummy1[0x1400]; /* XXX */
|
|
}; /* Note: should be 1 harddisk block */
|
|
#define AKAI_VOLDIR900HD_BLKS 1
|
|
|
|
/* S1000 harddisk volume */
|
|
struct akai_voldir1000hd_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S1000HD]; /* volume directory entries for files */
|
|
struct akai_volparam_s param; /* volume parameters */
|
|
u_char dummy1[0x1400]; /* XXX */
|
|
}; /* Note: should be 1 harddisk block */
|
|
#define AKAI_VOLDIR1000HD_BLKS 1
|
|
|
|
/* S3000 harddisk volume */
|
|
struct akai_voldir3000hd_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S3000HD]; /* volume directory entries for files */
|
|
struct akai_volparam_s param; /* volume parameters */
|
|
u_char dummy1[0x1000]; /* XXX */
|
|
}; /* Note: should be 2 harddisk blocks */
|
|
#define AKAI_VOLDIR3000HD_BLKS 2
|
|
|
|
|
|
|
|
/* floppy volumes */
|
|
|
|
/* floppy volume directory of files */
|
|
#define AKAI_VOLDIR_ENTRIES_S1000FL 64 /* number of volume directory entries total for S900 and S1000 floppy */
|
|
#define AKAI_VOLDIR_ENTRIES_S3000FL 510 /* number of volume directory entries total for S3000 floppy */
|
|
|
|
/* floppy volume label */
|
|
/* Note: S900 has no floppy volume label, all zero */
|
|
struct akai_flvol_label_s{
|
|
u_char name[AKAI_NAME_LEN]; /* volume name */
|
|
u_char dummy1[2]; /* XXX */
|
|
u_char osver[2]; /* OS version */
|
|
struct akai_volparam_s param; /* volume parameters */
|
|
}; /* Note: should be 0x0040 Bytes */
|
|
|
|
/* low-density floppy header */
|
|
/* Note: S900 and S1000 floppy volume directory is within floppy header */
|
|
struct akai_fllhead_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S1000FL]; /* volume directory entries for files */
|
|
#define AKAI_FAT_ENTRIES_FLL AKAI_FLL_SIZE /* number of FAT entries */
|
|
u_char fatblk[AKAI_FAT_ENTRIES_FLL][2]; /* FAT entries for floppy blocks: next block or special code */
|
|
/* Note: S900 has no floppy volume label, all zero */
|
|
struct akai_flvol_label_s label; /* label */
|
|
u_char dummy1[0x0380]; /* XXX */
|
|
}; /* Note: should be 4 floppy blocks */
|
|
#define AKAI_FLLHEAD_BLKS 4
|
|
|
|
/* high-density floppy header */
|
|
/* Note: S900 and S1000 floppy volume directory is within floppy header */
|
|
/* Note: low- and high-density floppy headers are identical */
|
|
/* up to first AKAI_FAT_ENTRIES_FLL FAT-entries */
|
|
struct akai_flhhead_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S1000FL]; /* volume directory entries for files */
|
|
#define AKAI_FAT_ENTRIES_FLH AKAI_FLH_SIZE /* number of FAT entries */
|
|
u_char fatblk[AKAI_FAT_ENTRIES_FLH][2]; /* FAT entries for floppy blocks: next block or special code */
|
|
/* Note: S900 has no floppy volume label, all zero */
|
|
struct akai_flvol_label_s label; /* label */
|
|
u_char dummy1[0x0140]; /* XXX */
|
|
}; /* Note: should be 5 floppy blocks */
|
|
#define AKAI_FLHHEAD_BLKS 5
|
|
|
|
/* S3000 floppy volume directory (behind header) */
|
|
struct akai_voldir3000fl_s{
|
|
struct akai_voldir_entry_s file[AKAI_VOLDIR_ENTRIES_S3000FL]; /* volume directory entries for files */
|
|
u_char dummy1[0x0030]; /* Note: volume parameters are in floppy header */
|
|
}; /* Note: should be 12 floppy blocks */
|
|
#define AKAI_VOLDIR3000FL_BLKS 12
|
|
#define AKAI_VOLDIR3000FLL_BSTART 4 /* start block for low-density */
|
|
#define AKAI_VOLDIR3000FLH_BSTART 5 /* start block for high-density */
|
|
/* flag for S3000 floppy: invalid type of first file in floppy header */
|
|
#define AKAI_VOLDIR3000FL_FTYPE 0xff /* invalid file type, used as flag for S3000 floppy volume */
|
|
|
|
|
|
|
|
/* generic volume */
|
|
/* Note: first file starts at byte 0 in first block */
|
|
union akai_voldir_u{
|
|
struct akai_voldir900hd_s s900hd;
|
|
struct akai_voldir1000hd_s s1000hd;
|
|
struct akai_voldir3000hd_s s3000hd;
|
|
/* Note: S900 and S1000 floppy volume is within floppy header */
|
|
struct akai_voldir3000fl_s s3000fl;
|
|
};
|
|
|
|
|
|
|
|
/* entry in root directory for volume on S900 harddisk */
|
|
struct akai_hd9rootdir_entry_s{
|
|
u_char name[AKAI_NAME_LEN_S900]; /* volume name */
|
|
#define AKAI_VOL_START_INACT 0x0000 /* inactive */
|
|
u_char start[2]; /* start block on harddisk */
|
|
}; /* Note: should be 0x000c Bytes */
|
|
|
|
|
|
|
|
/* S900 harddisk header */
|
|
struct akai_hd9head_s{
|
|
#define AKAI_HD9ROOTDIR_ENTRIES 128 /* number of root directory entries for volumes */
|
|
struct akai_hd9rootdir_entry_s vol[AKAI_HD9ROOTDIR_ENTRIES]; /* root directory for volumes */
|
|
u_char size[2]; /* harddisk size in harddisk blocks */
|
|
#define AKAI_HD9FLAG1_SIZEVALID 0xff /* if size[] is valid */
|
|
u_char flag1; /* XXX */
|
|
u_char flag2; /* XXX */
|
|
#define AKAI_HD9FAT0_ENTRIES 0x0cfe /* number of copied FAT entries */
|
|
u_char fatblk0[AKAI_HD9FAT0_ENTRIES][2]; /* copy of first FAT entries */
|
|
#define AKAI_HD9FAT_ENTRIES AKAI_HD9_MAXSIZE /* max. number of FAT entries */
|
|
u_char fatblk[AKAI_HD9FAT_ENTRIES][2]; /* FAT entries for harddisk blocks: next block or special code */
|
|
u_char dummy1[0x6000-AKAI_HD9FAT_ENTRIES*2]; /* XXX */
|
|
}; /* Note: should be 4 harddisk blocks */
|
|
#define AKAI_HD9HEAD_BLKS 4
|
|
|
|
|
|
|
|
/* entry in root directory for volume in S1000/S3000 harddisk sampler partition */
|
|
struct akai_rootdir_entry_s{
|
|
u_char name[AKAI_NAME_LEN]; /* volume name */
|
|
#define AKAI_VOL_TYPE_INACT 0x00 /* inactive */
|
|
#define AKAI_VOL_TYPE_S1000 0x01 /* S1000 */
|
|
#define AKAI_VOL_TYPE_S3000 0x03 /* S3000 or CD3000 */
|
|
#define AKAI_VOL_TYPE_CD3000 0x07 /* CD3000 CD-ROM (compatible with AKAI_VOL_TYPE_S3000) */
|
|
u_char type; /* volume type */
|
|
#define AKAI_VOL_LNUM_OFF 0
|
|
#define AKAI_VOL_LNUM_MIN 1
|
|
#define AKAI_VOL_LNUM_MAX 128
|
|
u_char lnum; /* load number */
|
|
u_char start[2]; /* start block within partition */
|
|
}; /* Note: should be 0x0010 Bytes */
|
|
|
|
|
|
|
|
/* S1000/S3000 harddisk sampler and DD partition table (only in first sampler partition) */
|
|
struct akai_parttab_s{
|
|
#define AKAI_PARTTAB_MAGICNUM 128 /* number of fields */
|
|
#define AKAI_PARTTAB_MAGICVAL 9999 /* magic base value */
|
|
u_char magic[AKAI_PARTTAB_MAGICNUM][2]; /* magic fields, indicate S1000/S3000 harddisk partition table, only in first sampler partition */
|
|
u_char partnum; /* number of sampler partitions, only in first sampler partition */
|
|
u_char ddpartnum; /* number of DD partitions */
|
|
u_char part[AKAI_PART_NUM+1][2]; /* sampler partition table, only in first sampler partition */
|
|
u_char ddpart[AKAI_DDPART_NUM+1][2]; /* DD partition table, only in first sampler partition */
|
|
u_char dummy1[0x0100-2-2*(AKAI_PART_NUM+1)-2*(AKAI_DDPART_NUM+1)]; /* XXX */
|
|
}; /* Note: should be 0x0202 Bytes */
|
|
|
|
|
|
|
|
/* S1000/S3000 harddisk sampler partition header */
|
|
struct akai_parthead_s{
|
|
u_char size[2]; /* partition size in harddisk blocks */
|
|
#define AKAI_PARTHEAD_MAGICNUM 98 /* number of fields */
|
|
#define AKAI_PARTHEAD_MAGICVAL 3333 /* magic base value */
|
|
u_char magic[AKAI_PARTHEAD_MAGICNUM][2]; /* magic fields, indicate S1000/S3000 harddisk sampler partition */
|
|
u_char chksum[4]; /* checksum of all above */
|
|
#define AKAI_ROOTDIR_ENTRIES 100 /* number of root directory entries for volumes */
|
|
struct akai_rootdir_entry_s vol[AKAI_ROOTDIR_ENTRIES]; /* root directory for volumes */
|
|
#define AKAI_FAT_ENTRIES AKAI_PART_MAXSIZE /* max. number of FAT entries */
|
|
u_char fatblk[AKAI_FAT_ENTRIES][2]; /* FAT entries for sampler partition blocks: next block or special code */
|
|
u_char dummy1[0x00f6]; /* XXX */
|
|
struct akai_parttab_s parttab; /* partition table, only in first sampler partition */
|
|
#define AKAI_PARTHEAD_TAGSMAGIC "TAGS" /* magic for tags */
|
|
u_char tagsmagic[4]; /* magic for tags */
|
|
#define AKAI_PARTHEAD_TAGNUM 26 /* number of tags */
|
|
u_char tag[AKAI_PARTHEAD_TAGNUM][AKAI_NAME_LEN]; /* tag names */
|
|
u_char dummy2[0x1a00-4-AKAI_PARTHEAD_TAGNUM*AKAI_NAME_LEN]; /* XXX */
|
|
}; /* Note: should be 3 harddisk blocks */
|
|
#define AKAI_PARTHEAD_BLKS 3
|
|
|
|
|
|
|
|
/* S1100/S3000 DD take header (directory entry in DD partition header) */
|
|
/* XXX should be defined in akaiutil_take.h, but must be in akaiutil.h due to dependencies */
|
|
struct akai_ddtake_s{
|
|
u_char name[AKAI_NAME_LEN]; /* name */
|
|
u_char cstarts[2]; /* start cluster for sample */
|
|
u_char cstarte[2]; /* start cluster for envelope */
|
|
u_char wstart[4]; /* sample start word (16bit) */
|
|
u_char wend[4]; /* sample end word (16bit) */
|
|
#define AKAI_DDTAKESTAT_FREE 0x00 /* free directory entry */
|
|
#define AKAI_DDTAKESTAT_USED 0x01 /* used directory entry */
|
|
u_char stat; /* directory entry status */
|
|
#define AKAI_DDTAKESTYPE_MONO 0x00 /* sample type mono */
|
|
#define AKAI_DDTAKESTYPE_STEREO 0x01 /* sample type stereo */
|
|
u_char stype; /* sample type */
|
|
u_char srate[2]; /* sample rate in Hz */
|
|
u_char vspeed[2]; /* varispeed (signed) */
|
|
u_char finerate[2]; /* fine rate (signed) */
|
|
u_char wstartm[4]; /* edit marker sample start word (16bit) */
|
|
u_char wendm[4]; /* edit marker sample end word (16bit) */
|
|
u_char fadein[2]; /* fade in time in ms */
|
|
u_char fadeout[2]; /* fade out time in ms */
|
|
u_char stlvl; /* stereo output level */
|
|
u_char pan; /* panning (signed) */
|
|
u_char stmix; /* stereo mix (ON=0x01, OFF=0x00) */
|
|
u_char midich1; /* MIDI channel-1 */
|
|
u_char midinote; /* MIDI note */
|
|
u_char startm; /* start mode */
|
|
u_char deemph; /* de-emphasis (ON=0x01, OFF=0x00) */
|
|
u_char dummy1[5]; /* XXX */
|
|
u_char predel[2]; /* pre-delay time in ms */
|
|
u_char outlvl; /* output level */
|
|
u_char outch; /* output channel pair */
|
|
u_char fxbus; /* FX bus */
|
|
u_char sendlvl; /* send level */
|
|
u_char dummy2[2]; /* XXX */
|
|
}; /* Note: should be 0x0040 Bytes */
|
|
|
|
|
|
|
|
/* S1100/S3000 harddisk DD partition header */
|
|
struct akai_ddparthead_s{
|
|
#define AKAI_DDFAT_ENTRIES 0x07ff /* max. number of DD FAT entries (AKAI_HD_MAXSIZE/AKAI_DDPART_CBLKS) */
|
|
u_char fatcl[AKAI_DDFAT_ENTRIES][2]; /* FAT entries for DD partition clusters: next cluster or special code */
|
|
u_char dummy1[0x2000-AKAI_DDFAT_ENTRIES*2]; /* XXX */
|
|
#define AKAI_DDTAKE_MAXNUM 256 /* max. number of DD takes */
|
|
struct akai_ddtake_s take[AKAI_DDTAKE_MAXNUM]; /* directory of DD takes */
|
|
}; /* Note: should be 3 harddisk blocks (rest of cluster is junk) */
|
|
#define AKAI_DDPARTHEAD_BLKS 3
|
|
|
|
#define AKAI_DDTAKE_ENVBLKSIZW 128 /* envelope block size in words */
|
|
#define AKAI_DDTAKE_ENVMAXVAL 0x20 /* max. envelope value */
|
|
|
|
|
|
|
|
/* generic header */
|
|
union akai_head_u{
|
|
struct akai_fllhead_s fll; /* low-density floppy header */
|
|
struct akai_flhhead_s flh; /* high-density floppy header */
|
|
struct akai_hd9head_s hd9; /* S900 harddisk header */
|
|
struct akai_parthead_s hd; /* S1000/S3000 harddisk sampler partition header */
|
|
struct akai_ddparthead_s dd; /* S1000/S3000 harddisk DD partition header */
|
|
};
|
|
/* Note: see comment above: */
|
|
/* may access files and first blocks in FAT via */
|
|
/* high-density floppy header also for low-density floppy case */
|
|
|
|
|
|
|
|
/* CD-ROM info header in S1000/S3000 sampler partition */
|
|
struct akai_cdinfohead_s{
|
|
u_char fnum[2]; /* number of files */
|
|
u_char volesiz[AKAI_ROOTDIR_ENTRIES][2]; /* size of volume directory entries for files in bytes */
|
|
u_char cdlabel[AKAI_NAME_LEN]; /* CD-ROM label */
|
|
}; /* Note: should be 0x00d6 Bytes */
|
|
/* Note: followed by voldir entries of files */
|
|
#define AKAI_CDINFO_BLK AKAI_PARTHEAD_BLKS /* start block (following sampler partition header) */
|
|
#define AKAI_CDINFO_MINSIZB 3 /* min. size in harddisk blocks */
|
|
#define AKAI_CDINFO_DEFLABEL "CDROM" /* XXX default label */
|
|
|
|
|
|
|
|
/* private data structures */
|
|
|
|
/* disk */
|
|
struct disk_s{
|
|
u_int index; /* disk index */
|
|
int fd; /* disk file descriptor */
|
|
#ifdef _VISUALCPP
|
|
int fldrn; /* floppy drive number (or -1 if none) */
|
|
#endif /* _VISUALCPP */
|
|
int readonly; /* read-only flag */
|
|
OFF64_T startoff; /* start offset in bytes */
|
|
u_int totsize; /* size in bytes */
|
|
#define DISK_TYPE_FLL 1 /* low-density floppy */
|
|
#define DISK_TYPE_FLH 2 /* high-density floppy */
|
|
#define DISK_TYPE_HD9 9 /* S900 harddisk */
|
|
#define DISK_TYPE_HD 3 /* S1000/S3000 harddisk */
|
|
u_int type; /* disk type */
|
|
u_int blksize; /* blocksize in bytes */
|
|
u_int bsize; /* size in blocks */
|
|
};
|
|
|
|
/* partition */
|
|
struct part_s{
|
|
struct disk_s *diskp; /* pointer to disk */
|
|
int valid; /* check passed */
|
|
#define PART_TYPE_FLL DISK_TYPE_FLL /* low-density floppy */
|
|
#define PART_TYPE_FLH DISK_TYPE_FLH /* high-density floppy */
|
|
#define PART_TYPE_HD9 DISK_TYPE_HD9 /* S900 harddisk */
|
|
#define PART_TYPE_HD DISK_TYPE_HD /* S1000/S3000 harddisk sampler partition */
|
|
#define PART_TYPE_DD 4 /* S1100/S3000 harddisk DD partition (at end of harddisk) */
|
|
u_int type; /* partition type */
|
|
u_int index; /* index on disk */
|
|
u_int blksize; /* blocksize in bytes */
|
|
u_int bstart; /* start block on disk */
|
|
u_int bsize; /* size in blocks */
|
|
u_int csize; /* if DD partition: size in clusters */
|
|
u_int bsyssize; /* if not DD partition: reserved blocks for system (partition header or floppy header) */
|
|
u_int bfree; /* free blocks */
|
|
u_int bbad; /* bad blocks */
|
|
u_char (*fat)[2]; /* start of FAT */
|
|
union akai_head_u head; /* whole header */
|
|
u_int volnummax; /* if not DD partition: max. number of volumes */
|
|
char letter; /* letter (ASCII) */
|
|
};
|
|
/* Note: fat points into original part_s head => must not use(!) a copy of a part_s !!! */
|
|
|
|
/* volume */
|
|
struct vol_s{
|
|
struct part_s *partp; /* pointer to partition */
|
|
u_int index; /* index in root directory */
|
|
#define AKAI_VOL_TYPE_S900 0xf9 /* fake type for S900, not valid for type in S1000/S3000 root directory */
|
|
u_int type; /* volume type */
|
|
u_int lnum; /* load number */
|
|
u_int osver; /* OS version */
|
|
#define VOL_DIRBLKS AKAI_VOLDIR3000FL_BLKS /* XXX max. number of volume blocks */
|
|
u_int dirblk[VOL_DIRBLKS]; /* directory blocks */
|
|
u_int fimax; /* max. file entries */
|
|
struct akai_voldir_entry_s *file; /* pointer to start of files */
|
|
struct akai_volparam_s *param; /* pointer to volume parameters */
|
|
union akai_voldir_u dir; /* whole volume directory (except for S900 and S1000 floppy) */
|
|
char name[AKAI_NAME_LEN+1]; /* name (ASCII), +1 for '\0' */
|
|
};
|
|
/* Note: file, param point into original vol_s dir => must not use(!) a copy of a vol_s !!! */
|
|
/* => use akai_copy_vol() to obtain a self-contained copy of a vol_s */
|
|
/* Note: must be careful with partp if part_s behind it has changed/disappeared !!! */
|
|
/* this should never be a problem since system-wide unique and static part[] */
|
|
|
|
/* sampler file */
|
|
struct file_s{
|
|
struct vol_s *volp; /* pointer to volume */
|
|
u_int index; /* index in volume directory */
|
|
u_int bstart; /* start block */
|
|
u_int size; /* size in bytes */
|
|
u_int type; /* type */
|
|
u_int osver; /* OS version */
|
|
u_char tag[AKAI_FILE_TAGNUM]; /* tags */
|
|
char name[AKAI_NAME_LEN+4+1]; /* name (ASCII), +4 for ".<type>", +1 for '\0' */
|
|
};
|
|
/* Note: must be careful with volp if vol_s behind it has changed/disappeared !!! */
|
|
/* this could be a problem with non-unique curvolp/curvol_buf */
|
|
|
|
|
|
|
|
/* disks */
|
|
#ifndef DISK_NUM_MAX
|
|
#define DISK_NUM_MAX 64 /* XXX */
|
|
#endif
|
|
extern struct disk_s disk[DISK_NUM_MAX]; /* disks, Note: one for each disk, system-wide */
|
|
extern u_int disk_num; /* number of disks */
|
|
|
|
/* partitions */
|
|
#ifndef PART_NUM_MAX
|
|
#define PART_NUM_MAX 512 /* XXX */
|
|
#endif
|
|
extern struct part_s part[PART_NUM_MAX]; /* partitions, Note: one for each partition, system-wide */
|
|
extern u_int part_num; /* number of partitions */
|
|
|
|
|
|
|
|
/* current directory */
|
|
extern struct disk_s *curdiskp; /* current disk pointer into disk[], NULL if system-level */
|
|
/* Note: unique, fixed mapping to each file */
|
|
extern struct part_s *curpartp; /* current partition pointer into part[], NULL if disk-level */
|
|
/* Note: unique, fixed mapping to each partition */
|
|
extern struct vol_s *curvolp; /* current volume pointer into curvol_buf, NULL if disk- or partition-level */
|
|
/* Note: neither fixed nor unique mapping to each volume!!! */
|
|
extern struct vol_s curvol_buf; /* current volume buffer, Note: only one buffer, might change volume identity!!! */
|
|
|
|
/* for operations with current directory, Note: one instance only, not recursive!!! */
|
|
extern int savecurfd;
|
|
extern struct part_s *savecurpartp;
|
|
extern struct vol_s *savecurvolp;
|
|
extern struct vol_s savecurvol_buf;
|
|
extern int savecurvolmodflag; /* modifier flag */
|
|
extern char savecurvolname[AKAI_NAME_LEN+1]; /* +1 for '\0' */
|
|
|
|
/* Note: dirnamebuf[] must be large enough to contain path of max. possible size */
|
|
#define DIRNAMEBUF_LEN 256 /* XXX */
|
|
extern char dirnamebuf[DIRNAMEBUF_LEN+1]; /* +1 for '\0' */
|
|
|
|
extern u_char curfiltertag[AKAI_FILE_TAGNUM];
|
|
|
|
|
|
|
|
/* Declarations */
|
|
|
|
#ifndef PSEUDODISK_NUM_MAX
|
|
#define PSEUDODISK_NUM_MAX 8 /* XXX max. number of pseudo-disks per file descriptor */
|
|
#endif
|
|
extern int open_disk(char *name,int readonly,OFF64_T startoff,u_int pseudodisksize,u_int pseudodisknum);
|
|
extern void close_alldisks(void);
|
|
|
|
#ifndef AKAI_DISKSIZE_GRAN
|
|
#define AKAI_DISKSIZE_GRAN 2048 /* XXX disk size granularity in bytes, compatible with CD-ROM */
|
|
#endif
|
|
extern u_int akai_disksize(int fd,OFF64_T startoff,u_int disksizemax);
|
|
|
|
extern int akai_io_blks(struct part_s *pp,u_char *buf,u_int bstart,u_int bsize,int cachealloc,int mode);
|
|
|
|
extern int akai_openreadonly_extfile(char *name);
|
|
extern int akai_check_extwavname(char *wavname);
|
|
|
|
extern void akai_countfree_part(struct part_s *pp);
|
|
extern int akai_check_fatblk(u_int blk,u_int bsize,u_int bsyssize);
|
|
extern int print_fatchain(struct part_s *pp,u_int blk);
|
|
extern int akai_free_fatchain(struct part_s *pp,u_int bstart,int writeflag);
|
|
extern int akai_allocate_fatchain(struct part_s *pp,u_int bsize,u_int *bstartp,u_int bcont0,u_int endcode);
|
|
|
|
extern int akai_scanbad(struct part_s *pp,int markflag);
|
|
|
|
extern int akai_read_file(int outfd,u_char *outbuf,struct file_s *fp,u_int begin,u_int end);
|
|
extern int akai_write_file(int inpfd,u_char *inpbuf,struct file_s *fp,u_int begin,u_int end);
|
|
|
|
extern int print_ddfatchain(struct part_s *pp,u_int cstart);
|
|
extern u_int akai_count_ddfatchain(struct part_s *pp,u_int cstart);
|
|
extern int akai_free_ddfatchain(struct part_s *pp,u_int cstart,int writeflag);
|
|
extern int akai_allocate_ddfatchain(struct part_s *pp,u_int csize,u_int *cstartp,u_int ccont0);
|
|
|
|
extern int akai_export_ddfatchain(struct part_s *pp,u_int cstart,u_int bstart,u_int bsize,int outfd,u_char *outbuf);
|
|
extern int akai_import_ddfatchain(struct part_s *pp,u_int cstart,u_int bstart,u_int bsize,int inpfd,u_char *inpbuf);
|
|
|
|
extern char akai2ascii(u_char c);
|
|
extern char akai2ascii900(u_char c);
|
|
extern void akai2ascii_name(u_char *aname,char *name,int s900flag);
|
|
extern void akai2ascii_filename(u_char *aname,u_char ft,u_int osver,char *name,int s900flag);
|
|
extern u_char ascii2akai(char a);
|
|
extern u_char ascii2akai900(char a);
|
|
extern void ascii2akai_name(char *name,u_char *aname,int s900flag);
|
|
extern u_char ascii2akai_filename(char *name,u_char *aname,u_int *osverp,int s900flag);
|
|
|
|
extern void akai_vol_info(struct vol_s *vp,u_int ai,int verbose);
|
|
extern void akai_list_vol(struct vol_s *vp,u_char *filtertagp);
|
|
extern int akai_read_voldir(struct vol_s *vp);
|
|
extern int akai_write_voldir(struct vol_s *vp,u_int fi);
|
|
extern void akai_copy_structvol(struct vol_s *srcvp,struct vol_s *dstvp);
|
|
extern int akai_get_vol(struct part_s *pp,struct vol_s *vp,u_int vi);
|
|
extern int akai_find_vol(struct part_s *pp,struct vol_s *vp,char *name);
|
|
extern int akai_rename_vol(struct vol_s *vp,char *name,u_int lnum,u_int osver,struct akai_volparam_s *parp);
|
|
#define AKAI_CREATE_VOL_NOINDEX ((u_int)-1) /* no user-supplied index */
|
|
extern int akai_create_vol(struct part_s *pp,struct vol_s *vp,u_int type,u_int index,char *name,u_int lnum,struct akai_volparam_s *parp);
|
|
extern int akai_wipe_vol(struct vol_s *vp,int delflag);
|
|
|
|
extern void akai_list_volparam(struct akai_volparam_s *parp,int listflag);
|
|
extern void akai_init_volparam(struct akai_volparam_s *parp,int s3000flag);
|
|
|
|
extern void akai_print_lnum(u_int lnum);
|
|
extern u_int akai_get_lnum(char *name);
|
|
|
|
extern int copy_tags(struct part_s *srcpp,struct part_s *dstpp);
|
|
extern void akai_list_tags(struct part_s *pp);
|
|
extern int akai_rename_tag(struct part_s *pp,char *name,u_int ti,int wipeflag);
|
|
|
|
extern void akai_print_cdinfo(struct part_s *pp,int verbose);
|
|
extern int akai_set_cdinfo(struct part_s *pp,char *cdlabel);
|
|
|
|
extern void akai_part_info(struct part_s *pp,int verbose);
|
|
extern void akai_list_part(struct part_s *pp,int recflag,u_char *filtertagp);
|
|
extern struct part_s *akai_find_part(struct disk_s *dp,char *name);
|
|
extern void print_fat(struct part_s *pp);
|
|
|
|
extern void akai_disk_info(struct disk_s *dp,int verbose);
|
|
extern void akai_list_disk(struct disk_s *dp,int recflag,u_char *filtertagp);
|
|
extern void akai_list_alldisks(int recflag,u_char *filtertagp);
|
|
|
|
extern void akai_sort_filetags(u_char *tagp);
|
|
extern int akai_set_filetag(u_char *tagp,u_int ti);
|
|
extern int akai_clear_filetag(u_char *tagp,u_int ti);
|
|
extern int akai_match_filetags(u_char *filtertagp,u_char *testtagp);
|
|
extern int akai_get_file(struct vol_s *vp,struct file_s *fp,u_int fi);
|
|
extern int akai_find_file(struct vol_s *vp,struct file_s *fp,char *name);
|
|
extern int akai_rename_file(struct file_s *fp,char *name,struct vol_s *vp,u_int dstindex,u_char *tagp,u_int osver);
|
|
#define AKAI_CREATE_FILE_NOINDEX ((u_int)-1) /* no user-supplied index */
|
|
extern int akai_create_file(struct vol_s *vp,struct file_s *fp,u_int size,u_int index,char *name,u_int osver,u_char *tagp);
|
|
extern void akai_fvol1000_initfile(struct akai_voldir_entry_s *ep,u_int osver,u_int tag);
|
|
extern int akai_delete_file(struct file_s *fp);
|
|
|
|
extern int akai_rename_ddtake(struct part_s *pp,u_int ti,char *name);
|
|
extern int akai_delete_ddtake(struct part_s *pp,u_int ti);
|
|
|
|
extern void akai_fix_partheadmagic(struct part_s *pp);
|
|
extern int akai_check_partheadmagic(struct part_s *pp);
|
|
extern void akai_fix_parttabmagic(struct akai_parttab_s *ptp);
|
|
extern int akai_check_parttabmagic(struct akai_parttab_s *ptp);
|
|
|
|
extern int akai_scan_floppy(struct disk_s *dp);
|
|
extern int akai_scan_harddisk9(struct disk_s *dp);
|
|
extern int akai_scan_ddpart(struct disk_s *dp,struct akai_parttab_s *ptp,u_int bstart,u_int pi);
|
|
extern int akai_scan_disk(struct disk_s *dp,int floppyenable);
|
|
|
|
extern int akai_wipe_part(struct part_s *pp,int wipeflag,struct part_s *plistp,u_int pimax,int cdromflag);
|
|
extern int akai_wipe_harddisk(struct disk_s *dp,u_int bsize,u_int totb,int s3000flag,int cdromflag);
|
|
extern int akai_wipe_harddisk9(struct disk_s *dp,u_int totb);
|
|
extern int akai_wipe_floppy(struct disk_s *dp,int lodensflag,int s3000flag,int s900flag);
|
|
|
|
extern int change_curdir(char *name,u_int vi,char *lastname,int checklast);
|
|
extern int change_curdir_home(void);
|
|
extern void save_curdir(int modflag);
|
|
extern void restore_curdir(void);
|
|
extern void curdir_info(int verbose,char *pathbuf);
|
|
extern void list_curdir(int recflag);
|
|
extern void list_curfiltertags(void);
|
|
|
|
extern int copy_file(struct file_s *srcfp,struct vol_s *dstvp,struct file_s *dstfp,u_int dstindex,char *dstname,int delflag);
|
|
extern int copy_vol_allfiles(struct vol_s *srcvp,struct part_s *dstpp,char *dstname,int delflag,int verbose);
|
|
extern int copy_part_allvols(struct part_s *srcpp,struct part_s *dstpp,int delflag,int verbose);
|
|
|
|
extern int check_curnosamplervol(void);
|
|
extern int check_curnosamplerpart(void);
|
|
extern int check_curnoddpart(void);
|
|
extern int check_curnopart(void);
|
|
|
|
|
|
|
|
#endif /* !__AKAIUTIL_H */
|