Endre escribió:
Porque PC no lee formatos de otras máquinas. Necesitas un programa que extraiga, convierta o edite el contenido de otras plataformas, como hacen ST Recover y MSA Aconverter para Atari.
¿ES ESTO? ¿HAY QUE PREPARAR EL DISQUETE?
http://mda.smartelectronix.com/akai/akaiinfo.htm
14. PC floppy drive programming
Code for the adisk4 program is provided here showing how to re-program the floppy drive for Akai disk access and includes read, write and format functions. Note that the code is primitive both in style and content! The software will work under DOS and Windows 3.x/95/98, but not NT which blocks direct disk access.
Not all PCs can read all Akai disks. Some modern PCs are obviously not as "IBM Compatible" as they should be, but problems can also be caused by the long hard life many Akai floppy drives have had. Some problems can be solved by using a disk formatted in Akai format by the PC rather than the sampler.
http://mda.smartelectronix.com/akai/adisk4-c.txt
// AKAI Disk Utilities - Copyright(c)1996-1999 Paul Kellett
//
// You may use any part of this code for any purpose!
//
// Version 4.1 (November 1999)
// Compiled with Borland Turbo C++ for DOS using "compact" memory model
//
//
// Background info:
//
// In the (IBM compatible) PC BIOS, the vector at interrupt 1E points to a table
// of floppy disk controller parameters. The table usually resembles the following:
//
// Byte Value Description
// ------------------------------------------------------------------
// 0 223 Specifications part 1
// 1 2 Specifications part 2
// 2 37 Motor run time
// 3 2 Block size: 0=128, 1=256, 2=512, 3=1024 bytes
// 4 18 Last sector number
// 5 27 Sector search gap
// 6 255 Data transfer length
// 7 108 Gap between sectors
// 8 246 ASCII code of format symbol
// 9 15 Head settle time
// 10 8 Speed up time
//
// The actual values vary a little depending on the PC and if Windows is running.
// You should always leave the table in the same state you found it!
//
// To adjust the table, you need to be able to call interrupts to execute BIOS
// functions. This is no problem in DOS and Windows 3.x, 95 and 98 (so long as
// your compiler actually supports interrupts) but an executable running under
// Windows NT (and probably Win2000) is not allowed direct access so a service
// or driver must be written.
#include <dos.h>
#include <stdio.h>
#define GETSEG(p) ((unsigned)(((unsigned long)((void far *)p))>>16))
#define GETOFS(p) ((unsigned)((void far *)p))
#define LO 5 //disk density
#define HI 10
#define S900 0 //sampler family
#define S1000 3
#define S3000 12
#define FORMAT 1 //mode
#define WRITE 2
#define READ 3
#define LIST 4
#define IMAGE 5
int diskfmt(int drv, int sid, int trk);
int diskread(int drv, int dens, int blk, int secs, char far *buffer);
int diskwrite(int drv, int dens, int blk, int secs, char far *buffer);
int akai2asci(int cod);
int asci2akai(int cod);
void help(int err);
union REGS reg;
struct SREGS sreg; //interrupts
struct FormatTable
{
unsigned char trk;
unsigned char sid;
unsigned char sec;
unsigned char len;
};
struct DirTable //disk table of contents
{
unsigned char name[13];
unsigned char type;
unsigned char orig;
long int length;
unsigned int start;
};
int diskfmt(int drv, int sid, int trk) //format a track
{
struct FormatTable ft[11];
int i;
for(i=0;i<10;i++)
{
ft
.trk=trk;
ft.sid=sid;
ft.sec=i+1;
ft.len=3; // 1024 bytes per sector
}
reg.h.ah=5;
reg.h.al=10; // 10 sectors per track (low density doesn't seem to work)
reg.h.dh=sid;
reg.h.dl=drv;
reg.h.ch=trk;
reg.x.bx=GETOFS(ft);
sreg.es=GETSEG(ft);
int86x(0x13,®,®,&sreg);
return(reg.h.ah);
}
int diskread(int drv, int dens, int blk, int secs, char far *buffer) //read sector(s)
{
reg.h.ah=2;
reg.h.al=secs;
reg.h.dh=(blk/dens)%2;
reg.h.dl=drv;
reg.h.ch=blk/(2*dens);
reg.h.cl=1+(blk%dens);
reg.x.bx=GETOFS(buffer);
sreg.es=GETSEG(buffer);
int86x(0x13,®,®,&sreg);
return(reg.h.ah);
}
int diskwrite(int drv, int dens, int blk, int secs, char far *buffer) //write sector(s)
{
reg.h.ah=3;
reg.h.al=secs;
reg.h.dh=(blk/dens)%2;
reg.h.dl=drv;
reg.h.ch=blk/(2*dens);
reg.h.cl=1+(blk%dens);
reg.x.bx=GETOFS(buffer);
sreg.es=GETSEG(buffer);
int86x(0x13,®,®,&sreg);
return(reg.h.ah);
}
int akai2asci(int cod) //convert between ASCII and Akai character sets
{
if(cod>=0 && cod<10)
{
return(cod+48);
}
if(cod>10 && cod<37)
{
return(cod+54);
}
switch(cod)
{
case 37: return(35); // #
case 38: return(43); // +
case 39: return(45); // -
case 40: return(46); // .
default: return(32);
}
}
int asci2akai(int cod)
{
if(cod>47 && cod<58)
{
return(cod-48);
}
if(cod>64 && cod<91)
{
return(cod-54);
}
if(cod>96 && cod<123)
{
return(cod-86);
}
switch(cod)
{
case 35: return(37);
case 43: return(38);
case 45: return(39);
case 46: return(40);
default: return(10);
}
}
void main(int argc, char *argv[])
{
unsigned int oldseg, oldofs, newseg, newofs; //floppy parameter table vector
unsigned int er; //error code returned by bios functions
unsigned int drv=0; //0=A: 1=B:
unsigned int dens=HI; //density (sectors per track)
unsigned int map[1600]; //sector map
unsigned int mode=0; //see above
unsigned formode; //format as S900, S1000 or S3000 family
unsigned int type, ext, i, j, k, n=999, errcode=0;
unsigned char bufdma[10250];
unsigned char param[16], buffer[10250], label[13];
unsigned char far *ptr;
struct DirTable entry[64]; //table of contents
FILE *fl, *fp;
bufdma[1]=1;
//parse command line////////////////////////////////////////////////////////////////
if(*(argv[1])=='B' || *(argv[1])=='b')
if(*(argv[1]+1)==':') {drv=1; ++argv; argc--;} //select B: drive
if(*(argv[1])=='R' || *(argv[1])=='r')
{
mode=READ; //read file ...get file type number
if(*(argv[1]+1)>47 && *(argv[1]+1)<58) ext=(int)(*(argv[1]+1) - 48);
if(*(argv[1]+2)>47 && *(argv[1]+2)<58) ext=10 * ext + (int)(*(argv[1]+2) - 48);
if(*(argv[1]+3)>47 && *(argv[1]+3)<58) ext=10 * ext + (int)(*(argv[1]+3) - 48);
}
if(*(argv[1])=='W' || *(argv[1])=='w')
{
mode=WRITE; //write file ...get file type number
if(*(argv[1]+1)>47 && *(argv[1]+1)<58) ext=(int)(*(argv[1]+1) - 48);
if(*(argv[1]+2)>47 && *(argv[1]+2)<58) ext=10 * ext + (int)(*(argv[1]+2) - 48);
if(*(argv[1]+3)>47 && *(argv[1]+3)<58) ext=10 * ext + (int)(*(argv[1]+3) - 48);
}
if(*(argv[1])=='F' || *(argv[1])=='f')
{
mode=FORMAT; //format disk ...get sampler family
switch(*(argv[1]+1))
{
case '9': formode=S900; break;
case '1': formode=S1000; break;
default : formode=S3000;
}
}
if(*(argv[1])=='D' || *(argv[1])=='d') mode=LIST; //disk directory listing
if(*(argv[1])=='I' || *(argv[1])=='i') mode=IMAGE; //copy whole disk image
printf("\nAkai Floppy Disk Utilities v4");
printf("\nCopyright(c)1999 Paul Kellett");
printf("\nhttp://www.maxim.abel.co.uk/\n\n");
if(mode==0) //nothing on command line ...show help and terminate
{
puts(" Usage: ADISK4 [B:] d - Directory");
puts(" ADISK4 [B:] r### \"AKAINAME\" DOSNAME.EXT - Read File");
puts(" ADISK4 [B:] w### DOSNAME.EXT \"AKAINAME\" - Write File");
puts(" ADISK4 [B:] f@ \"LABEL\" - Format Disk");
puts(" ADISK4 [B:] i - Disk Image");
puts(" ");
puts(" ### = ASCII code of file type");
puts(" @ = Sampler family 9, 1 or 3");
exit(0);
}
//re-program floppy drive///////////////////////////////////////////////////////////
reg.h.ah=0x35;
reg.h.al=0x1E;
int86x(0x21,®,®,&sreg); // Read floppy parameter vector
oldseg=sreg.es;
oldofs=reg.x.bx;
for(i=0;i<16;i++) // make copy of parameter table
{
ptr=MK_FP(oldseg,oldofs+i);
param = *ptr;
}
// With Microsoft C you must write to the table directly...
// (char __far *)ptr=MK_FP(oldseg,oldofs+3); *ptr=3; etc.
param[3]=3; // 1024 bytes per block
param[4]=dens; // 10 blocks per track
param[8]=0; // Don't format with ö
newseg=GETSEG(param);
newofs=GETOFS(param);
reg.h.ah=0x25;
reg.h.al=0x1E;
reg.x.dx=newofs;
sreg.ds=newseg;
int86x(0x21,®,®,&sreg); // Set vector to new parameters
reg.h.ah=0;
reg.h.dl=drv;
int86(0x13,®,®); // Reset floppy controller
if(reg.h.ah) printf("\nError %Xh setting up floppy!\n",reg.h.ah);
//format disk////////////////////////////////////////////////////////////////////
if(mode==FORMAT || mode==IMAGE)
{
if(mode==FORMAT)
{
printf("\nFormatting drive %c: for Akai ",'A'+drv);
switch(formode)
{
case S1000: printf("S1000\n"); break;
case S3000: printf("S3000\n"); break;
default: printf("S950\n");
}
i=0; //tidy up label
while(i<12 && *(argv[2]+i)) {label=asci2akai(*(argv[2]+i)); i++;}
while(i<12) { label=10; i++; }
er=diskfmt(drv, 0, 0); //clear 'disk changed' error
errcode=3; //assume faliure
if(er==0 || er==6)
{
printf("________________________________________");
printf("_______________________________________\r");
er=0;
for(i=0;i<80;i++)
if(diskfmt(drv, 0, i) + diskfmt(drv, 1, i))
{
printf("_"); //error - disk probably corrupt
er++;
}
else
{
printf("#");
}
for(i=0;i<2048;i++) buffer=0;
if(formode==S900) //write S900 label (no entries or map)
{
for(i=0;i<12;i++) buffer[640+i]=label;
er+=diskwrite(drv,10,4,1,buffer);
}
if(formode==S1000)
{
for(i=0;i<64 ;i++) buffer[i*24+23]=3; //S1000 toc
for(i=0;i<4 ;i++) buffer[1537+(2*i)]=64; //S1000 map
er+=diskwrite(drv,10,0,2,buffer);
for(i=0;i<2048;i++) buffer=0; //S1000 label
for(i=0;i<12 ;i++) buffer[640+i]=label;
buffer[652]=0; buffer[653]=0; buffer[654]=0; buffer[655]=3;
buffer[656]=0; buffer[657]=1; buffer[658]=1; buffer[659]=0;
buffer[660]=0; buffer[661]=0; buffer[662]=50; buffer[663]=9;
buffer[664]=12;buffer[665]=255; er+=diskwrite(drv,10,4,2,buffer);
}
if(formode==S3000)
{
for(i=0;i<64;i++)
{
for(j=0;j<12;j++) buffer[i*24+j]=32; // dummy S1000 toc
buffer[i*24+15]=1; buffer[i*24+23]=12;
}
buffer[16]=255; // S3000 series ID
for(i=0;i<17;i++) buffer[1537+2*i]=64; // S3000 map
er+=diskwrite(drv,10,0,2,buffer);
for(i=0;i<2048;i++) buffer=0; //S3000 label
for(i=0;i<12;i++) buffer[640+i]=label;
buffer[652]=0 ;buffer[653]=0 ;buffer[654]=0 ;buffer[655]=12;
buffer[656]=0 ;buffer[657]=1 ;buffer[658]=1 ;buffer[659]=0 ;
buffer[660]=0 ;buffer[661]=0 ;buffer[662]=50;buffer[663]=9 ;
buffer[664]=12;buffer[665]=255; er+=diskwrite(drv,10,4,2,buffer);
}
if(er==0) errcode=0;
}
}
else //copy whole disk image
{
if((fp=fopen("adisk4.img","wb"))==NULL)
{
errcode=4;
}
else
{
printf("\nSaving disk image\n");
printf("________________________________________");
printf("_______________________________________\r");
k=0;
for(i=0;i<160;i++)
{
er=diskread(drv,dens,i*10,10,buffer); //read 10 sectors at once for speed
if(er!=0) er=diskread(drv,dens,i*10,10,buffer); //and try again if error
if(er!=0) er=diskread(drv,dens,i*10,10,buffer);
for(j=0;j<9216;j++) fputc(buffer[j],fp);
er=diskread(drv,dens,9+i*10,1,buffer); //for some reason 10th sector
if(er!=0) er=diskread(drv,dens,9+i*10,1,buffer); //may be corrupt so read again
if(er!=0) er=diskread(drv,dens,9+i*10,1,buffer);
for(j=0;j<1024;j++) fputc(buffer[j],fp);
k++; if(k==2) { printf("#"); k=0; }
}
fclose(fp);
}
}
}
else //get sector map and table of contents for file transfer...
{
reread:
er=diskread(drv,dens,dens-1,1,buffer); //debugging: if(er)help(er);
if(er) //try reading disk
{
switch (er)
{
case 2:
case 4: if(dens==HI)
{
dens=LO; goto reread; //if HI fails, try LO else not Akai
}
else
{
printf("Disk in drive %c: is not Akai format!",'A'+drv);
}
break;
case 6: goto reread; // clear disk change message
default: help(er); //doesn't look like it, but program exits here!
}
}
else
{
er=diskread(drv,dens,3,2,buffer); //read 5 sectors (in 2 chunks as 5th gets corrupted!)
if(er){printf("\nMap: "); help(er);}
for(i=0;i<2048;i++) buffer[3072+i]=buffer;
diskread(drv,dens,0,3,buffer);
if(dens==LO)
{ // Get sector map
for(i=0;i<800;i++)
{
map=buffer[1536+2*i]+256*buffer[1537+2*i];
}
for(i=800;i<1600;i++)map=1; // make space not on disk unavailable
for(i=0;i<12;i++) label=akai2asci(buffer[3136+i]); label[12]=0;
label[12]=0; //get label
}
else
{
for(i=0;i<1600;i++)
{
map=buffer[1536+2*i]+256*buffer[1537+2*i];
}
for(i=0;i<12;i++) label=akai2asci(buffer[4736+i]); label[12]=0;
}
if(buffer[22]==0 && buffer[23]==0) type=S900; else type=S1000;
if(buffer[16]==255) // S3000 series
{
er=diskread(drv,dens,5,5,buffer); //read S3000 TOC
if(er){printf("\nS3000: "); help(er);}
type=S3000;
}
for(i=0;i<64;i++) // Read 64 entries
{
if(type==S900)
{
for(j=0;j<12;j++) entry.name[j]=buffer[i*24+j];
entry.name[10]=32; entry.name[11]=32;
}
else
for(j=0;j<12;j++) entry.name[j]=akai2asci(buffer[i*24+j]);
entry.name[12]=0;
entry.orig=entry.type=buffer[i*24+16];
entry.length=buffer[i*24+18]+256*buffer[i*24+19];
entry.length=buffer[i*24+17]+256*entry.length;
entry.start=buffer[i*24+20]+256L*buffer[i*24+21];
}
if(mode==READ) ///////////////////////////
{
i=0;
while(i<64 && n==999) //look for matching name & ext
{
if(entry.type==ext) //for wanted type and name...
{
k=0; j=0;
while(j<12 && *(argv[2]+j))
{
if(*(argv[2]+j)==entry.name[j]) k++;
if(*(argv[2]+j)==(entry.name[j]+32) && entry.name[j]>64) k++;
j++;
}
while(j<12)
{
if(entry.name[j]==32) k++;
j++;
}
if(k==12) n=i; //found complete match for filename
}
i++;
}
if(n==999)
{
errcode=5;
}
else
{
if((fp=fopen(argv[3],"wb"))==NULL)
{
errcode=4;
}
else
{
printf("Reading \"%s\"\n",argv[2]);
while(entry[n].length>1024)
{
diskread(drv, dens, entry[n].start, 1, buffer);
entry[n].start=map[entry[n].start];
entry[n].length-=1024;
for(i=0;i<1024;i++) fputc(buffer,fp);
}
diskread(drv, dens, entry[n].start, 1, buffer);
for(i=0;i<entry[n].length;i++) fputc(buffer,fp);
fclose(fp);
}
}
}
if(mode==WRITE) //////////////////////////
{
i=0;
while(i<64 && n==999) //look for matching name & ext
{
if(entry.type==ext) //for wanted type and name...
{
k=0; j=0;
while(j<12 && *(argv[3]+j))
{
if(*(argv[3]+j)==entry.name[j]) k++;
if(*(argv[3]+j)==(entry.name[j]+32) && entry.name[j]>64) k++;
j++;
}
while(j<12)
{
if(entry.name[j]==32) k++;
j++;
}
if(k==12) //found complete match
{
n=i;
printf("Deleting %s\n",entry[n].name);
}
}
i++;
}
if(n==999) //no match, use first free slot
{
i=0; while(i<64 && entry.type) i++;
if(i<64) n=i;
}
if(n==999)
{
errcode=5;
}
else //found slot...
{
if((fp=fopen(argv[2],"rb"))==NULL)
{
errcode=4;
}
else
{
printf("Writing %s to \"%s\"\n",argv[2],argv[3]);
//while(feof(fp)==0)...
//write file!!
fclose(fp);
}
//write TOC (deletes entry if file not found)
}
}
}
}
reg.h.ah=0x25;
reg.h.al=0x1E;
reg.x.dx=oldofs;
sreg.ds=oldseg;
int86x(0x21,®,®,&sreg); //restore old floppy parameter vector
reg.h.ah=0;
reg.h.dl=drv;
int86(0x13,®,®); //reset controller
if(reg.h.ah) printf("\nError %Xh resettingfloppy!\n",reg.h.ah);
diskread(drv,18,0,1,buffer); //switch light off
//output results to log file//////////////////////////////////////////////////////
fl=fopen("adisk4.log","w");
if(mode==LIST && errcode==0) //directory listing
{
fprintf(fl,"Akai ");
switch(type)
{
case S1000: fprintf(fl,"S1000 "); break;
case S3000: fprintf(fl,"S3000 "); break;
default: fprintf(fl,"S900 ");
}
if(dens==LO) fprintf(fl,"LOW"); else fprintf(fl,"HIGH");
fprintf(fl," DENSITY \"%s\"\n", label);
k=0;
for(i=0;i<64;i++)
if(entry.type)
{
fprintf(fl,"%s\t%d\t%ld\n", entry.name, entry.type, entry.length);
printf("%s\t%d\t", entry.name, entry.type);
k++;
if(k==3) { printf("\n"); k=0; }
}
printf("\n");
}
else //success or faliure message
{
switch(errcode)
{
case 1: fprintf(fl,"No Akai disk found!\n"); break;
case 2: fprintf(fl,"Disk is write protected!\n"); break;
case 3: fprintf(fl,"Disk Error!\n"); break;
case 4: fprintf(fl,"File Error!\n"); break;
case 5: fprintf(fl,"File not found!\n"); break;
default: fprintf(fl,"Finished!\n"); break;
}
}
fclose(fl);
}
void help(int err) //error messages
{
switch(err)
{
case 1: printf("\nInvalid command!\n"); break;
case 2: printf("\nAddress not found!\n"); break;
case 3: printf("\nDisk write protected!\n"); break;
case 4: printf("\nSector not found!\n"); break;
case 5: printf("\nReset failed!\n"); break;
case 6: printf("\nDisk changed!\n"); break;
case 7: printf("\nBad parameter table!\n"); break;
case 8: printf("\nDMA overrun!\n"); break;
case 9: printf("\nDMA across 64k boundary!\n"); break;
case 0x0A: printf("\nBad sector!\n"); break;
case 0x0B: printf("\nBad track!\n"); break;
case 0x0C: printf("\nMedia type not found!\n"); break;
case 0x0D: printf("\nBad number of sectors!\n"); break;
case 0x10: printf("\nUncorrectable read error!\n"); break;
case 0x11: printf("\nCorrected read error!\n"); break;
case 0x20: printf("\nController faliure!\n"); break;
case 0x40: printf("\nTrack not found!\n"); break;
case 0x80: printf("\nNo disk!\n"); break;
case 0xAA: printf("\nFloppy not ready!\n"); break;
case 0xBB: printf("\nUndefined error!\n"); break;
case 0xCC: printf("\nWrite fault!\n"); break;
case 0xE0: printf("\nStatus error!\n"); break;
case 0xFF: printf("\nNo Disk!\n"); break;
case 9999: puts("** Copyright (c)1999 Paul Kellett - http://www.maxim.abel.co.uk **");
}
}