Added missing FCB-functions
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@256
This commit is contained in:
parent
4072e14107
commit
33c702a8e4
4 changed files with 270 additions and 27 deletions
|
@ -188,6 +188,14 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset);
|
|||
bool DOS_FCBClose(Bit16u seg,Bit16u offset);
|
||||
bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset);
|
||||
bool DOS_FCBFindNext(Bit16u seg,Bit16u offset);
|
||||
Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u numBlocks);
|
||||
bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks);
|
||||
bool DOS_FCBCreate(Bit16u seg,Bit16u offset);
|
||||
Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec);
|
||||
bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec);
|
||||
bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec);
|
||||
bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset);
|
||||
bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset);
|
||||
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change);
|
||||
/* Extra DOS Interrupts */
|
||||
void DOS_SetupMisc(void);
|
||||
|
@ -249,6 +257,8 @@ public:
|
|||
void Set_filesize(Bit32u a);
|
||||
void Set_date(Bit16u a);
|
||||
void Set_time(Bit16u a);
|
||||
void Set_current_record(Bit8u a);
|
||||
void Set_random_record(Bit32u a);
|
||||
// others nog yet handled
|
||||
Bit8u Get_drive(void);
|
||||
void Get_filename(char* a);
|
||||
|
@ -258,6 +268,8 @@ public:
|
|||
Bit32u Get_filesize(void);
|
||||
Bit16u Get_date(void);
|
||||
Bit16u Get_time(void);
|
||||
Bit8u Get_current_record(void);
|
||||
Bit32u Get_random_record(void);
|
||||
private:
|
||||
PhysPt off;
|
||||
};
|
||||
|
|
|
@ -202,19 +202,64 @@ static Bitu DOS_21Handler(void) {
|
|||
break;
|
||||
|
||||
case 0x13: /* Delete File using FCB */
|
||||
if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
else reg_al = 0xFF;
|
||||
break;
|
||||
case 0x14: /* Sequential read from FCB */
|
||||
reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0);
|
||||
LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x15: /* Sequential write to FCB */
|
||||
if (DOS_FCBWrite(SegValue(ds),reg_dx,0)) reg_al = 0x00;
|
||||
else reg_al = 0x01;
|
||||
LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x16: /* Create or truncate file using FCB */
|
||||
case 0x17: /* Rename file using FCB */
|
||||
if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
else reg_al = 0x01;
|
||||
LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x17: /* Rename file using FCB */
|
||||
if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
else reg_al = 0xFF;
|
||||
break;
|
||||
case 0x21: /* Read random record from FCB */
|
||||
{ DOS_FCB fcb(SegValue(ds),reg_dx);
|
||||
Bit8u curRec = fcb.Get_current_record();
|
||||
Bit16u curBlock = fcb.Get_current_block();
|
||||
reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0);
|
||||
fcb.Set_current_record(curRec);
|
||||
fcb.Set_current_block(curBlock);
|
||||
}
|
||||
LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x22: /* Write random record to FCB */
|
||||
{ DOS_FCB fcb(SegValue(ds),reg_dx);
|
||||
Bit8u curRec = fcb.Get_current_record();
|
||||
Bit16u curBlock = fcb.Get_current_block();
|
||||
if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00;
|
||||
else reg_al = 0x01;
|
||||
fcb.Set_current_record(curRec);
|
||||
fcb.Set_current_block(curBlock);
|
||||
}
|
||||
LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x23: /* Get file size for FCB */
|
||||
if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00;
|
||||
else reg_al = 0xFF;
|
||||
break;
|
||||
case 0x24: /* Set Random Record number for FCB */
|
||||
{ DOS_FCB fcb(SegValue(ds),reg_dx);
|
||||
fcb.Set_random_record(fcb.Get_current_block()*128+fcb.Get_current_record());
|
||||
} break;
|
||||
case 0x27: /* Random block read from FCB */
|
||||
case 0x28: /* Random Block read to FCB */
|
||||
LOG_ERROR("DOS:Unhandled call %02X, FCB Stuff",reg_ah);
|
||||
reg_al=0xff; /* FCB Calls FAIL */
|
||||
//CALLBACK_SCF(true); not needed.
|
||||
reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx);
|
||||
LOG_DEBUG("DOS:0x27 FCB-Random read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x28: /* Random Block write to FCB */
|
||||
if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00;
|
||||
else reg_al = 0x01;
|
||||
LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al);
|
||||
break;
|
||||
|
||||
case 0x29: /* Parse filename into FCB */
|
||||
|
|
|
@ -208,6 +208,12 @@ void DOS_FCB::Set_date(Bit16u a){
|
|||
void DOS_FCB::Set_time(Bit16u a){
|
||||
mem_writew(off+offsetof(sFCB,time)+FCB_EXTENDED,a);
|
||||
}
|
||||
void DOS_FCB::Set_current_record(Bit8u a){
|
||||
mem_writeb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED,a);
|
||||
}
|
||||
void DOS_FCB::Set_random_record(Bit32u a){
|
||||
mem_writed(off+offsetof(sFCB,rel_record)+FCB_EXTENDED,a);
|
||||
}
|
||||
Bit8u DOS_FCB::Get_drive(void){
|
||||
return mem_readb(off+offsetof(sFCB,drive)+FCB_EXTENDED);
|
||||
}
|
||||
|
@ -232,6 +238,12 @@ Bit16u DOS_FCB::Get_date(void){
|
|||
Bit16u DOS_FCB::Get_time(void){
|
||||
return mem_readw(off+offsetof(sFCB,time)+FCB_EXTENDED);
|
||||
}
|
||||
Bit8u DOS_FCB::Get_current_record(void){
|
||||
return mem_readb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED);
|
||||
}
|
||||
Bit32u DOS_FCB::Get_random_record(void){
|
||||
return mem_readd(off+offsetof(sFCB,rel_record)+FCB_EXTENDED);
|
||||
}
|
||||
|
||||
|
||||
void DOS_ParamBlock::InitExec(RealPt cmdtail) {
|
||||
|
|
|
@ -583,27 +583,13 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *
|
|||
fcb.Set_ext(ext);
|
||||
*change=string-backup;
|
||||
return retwaarde;
|
||||
|
||||
|
||||
|
||||
}
|
||||
bool DOS_FCBOpen(Bit16u seg,Bit16u offset) {
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
if(!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error.
|
||||
|
||||
struct stat stat_block;
|
||||
if(!Drives[drive]->FileStat(fullname, &stat_block)) return false;
|
||||
fcb.Set_filesize((Bit32u)stat_block.st_size);
|
||||
Bit16u constant = 0;
|
||||
fcb.Set_current_block(constant);
|
||||
constant=0x80;
|
||||
fcb.Set_record_size(constant);
|
||||
|
||||
struct tm *time;
|
||||
if((time=localtime(&stat_block.st_mtime))!=0){
|
||||
void DOS_FCBSetDateTime(DOS_FCB& fcb,struct stat& stat_block)
|
||||
{
|
||||
Bit16u constant;
|
||||
struct tm *time;
|
||||
if((time=localtime(&stat_block.st_mtime))!=0){
|
||||
|
||||
constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */
|
||||
fcb.Set_time(constant);
|
||||
|
@ -616,9 +602,28 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) {
|
|||
constant=4;
|
||||
fcb.Set_date(constant);
|
||||
}
|
||||
fcb.Set_drive(drive +1);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
bool DOS_FCBOpen(Bit16u seg,Bit16u offset) {
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
if(!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error.
|
||||
|
||||
struct stat stat_block;
|
||||
if(!Drives[drive]->FileStat(fullname, &stat_block)) return false;
|
||||
fcb.Set_filesize((Bit32u)stat_block.st_size);
|
||||
Bit16u constant = 0;
|
||||
fcb.Set_current_block(constant);
|
||||
constant=0x80;
|
||||
fcb.Set_record_size(constant);
|
||||
|
||||
DOS_FCBSetDateTime(fcb,stat_block);
|
||||
|
||||
fcb.Set_drive(drive +1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DOS_FCBClose(Bit16u seg,Bit16u offset)
|
||||
{ DOS_FCB fcb(seg,offset);
|
||||
|
@ -707,6 +712,175 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DOS_FCBCreate(Bit16u seg,Bit16u offset)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
DOS_File* file;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
|
||||
if (!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
if (!Drives[drive]->FileCreate(&file,fullname,0)) return false;
|
||||
// Set Date & time
|
||||
struct stat stat_block;
|
||||
Drives[drive]->FileStat(fullname, &stat_block);
|
||||
DOS_FCBSetDateTime(fcb,stat_block);
|
||||
file->Close();
|
||||
// Clear fcb
|
||||
fcb.Set_record_size(128); // ?
|
||||
fcb.Set_current_record(0);
|
||||
fcb.Set_random_record(0);
|
||||
fcb.Set_filesize(0);
|
||||
return true;
|
||||
};
|
||||
|
||||
Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
DOS_File* file;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
// Open file
|
||||
if (!FCB_MakeName (&fcb, fullname, &drive)) return 0x01;
|
||||
if (!Drives[drive]->FileOpen(&file,fullname,OPEN_READ)) return 0x01;
|
||||
// Position file
|
||||
Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size();
|
||||
if (!file->Seek(&filePos,0x00)) { file->Close(); return 0x01; }; // end of file
|
||||
// Calculate target
|
||||
Bit8u* target = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size());
|
||||
// Read record
|
||||
Bit16u toRead = fcb.Get_record_size();
|
||||
if (!file->Read(target,&toRead)) { file->Close(); return 0x01; };
|
||||
// fill with 0
|
||||
memset(target+toRead,0,fcb.Get_record_size()-toRead);
|
||||
// Update record
|
||||
Bit8u curRec = fcb.Get_current_record() + 1;
|
||||
if (curRec>128) {
|
||||
fcb.Set_current_record(0);
|
||||
fcb.Set_current_block(fcb.Get_current_block()+1);
|
||||
} else
|
||||
fcb.Set_current_record(curRec);
|
||||
|
||||
file->Close();
|
||||
// check for error
|
||||
if (toRead<fcb.Get_record_size()) return 0x03;
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
DOS_File* file;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
// Open file
|
||||
if (!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
if (!Drives[drive]->FileOpen(&file,fullname,OPEN_WRITE)) return false;
|
||||
// Position file
|
||||
Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size();
|
||||
if (!file->Seek(&filePos,0x00)) { file->Close(); return false; }; // end of file
|
||||
// Calculate source
|
||||
Bit8u* source = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size());
|
||||
// Write record
|
||||
Bit16u toWrite = fcb.Get_record_size();
|
||||
if (!file->Write(source,&toWrite)) { file->Close(); return false; };
|
||||
// Update size
|
||||
Bit32u fsize = fcb.Get_filesize() + toWrite;
|
||||
fcb.Set_filesize(fsize);
|
||||
// Update Date & Time
|
||||
struct stat stat_block;
|
||||
Drives[drive]->FileStat(fullname, &stat_block);
|
||||
DOS_FCBSetDateTime(fcb,stat_block);
|
||||
// Update record
|
||||
Bit8u curRec = fcb.Get_current_record() + 1;
|
||||
if (curRec>128) {
|
||||
fcb.Set_current_record(0);
|
||||
fcb.Set_current_block(fcb.Get_current_block()+1);
|
||||
} else
|
||||
fcb.Set_current_record(curRec);
|
||||
|
||||
file->Close();
|
||||
return (toWrite==fcb.Get_record_size());
|
||||
};
|
||||
|
||||
Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit16u recno = 0;
|
||||
Bit8u error;
|
||||
// Calculate block&rec
|
||||
fcb.Set_current_block (Bit16u(fcb.Get_random_record() / 128));
|
||||
fcb.Set_current_record(Bit8u (fcb.Get_random_record() % 127));
|
||||
// Read records
|
||||
for (int i=0; i<numRec; i++) {
|
||||
error = DOS_FCBRead(seg,offset,i);
|
||||
if (error!=0x00) break;
|
||||
};
|
||||
// update fcb
|
||||
fcb.Set_random_record(fcb.Get_current_block()*128+fcb.Get_current_record());
|
||||
return error;
|
||||
};
|
||||
|
||||
bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit16u recno = 0;
|
||||
bool noerror = true;
|
||||
// Calculate block&rec
|
||||
fcb.Set_current_block (Bit16u(fcb.Get_random_record() / 128));
|
||||
fcb.Set_current_record(Bit8u (fcb.Get_random_record() % 127));
|
||||
// Read records
|
||||
for (int i=0; i<numRec; i++) {
|
||||
noerror = DOS_FCBWrite(seg,offset,i);
|
||||
if (!noerror) break;
|
||||
};
|
||||
// update fcb
|
||||
fcb.Set_random_record(fcb.Get_current_block()*128+fcb.Get_current_record());
|
||||
return noerror;
|
||||
};
|
||||
|
||||
bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
DOS_File* file;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
// Open file
|
||||
if (!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
if (!Drives[drive]->FileOpen(&file,fullname,OPEN_WRITE)) return false;
|
||||
struct stat stat_block;
|
||||
if(!Drives[drive]->FileStat(fullname, &stat_block)) { file->Close(); return false; };
|
||||
Bit32u fsize = (Bit32u)stat_block.st_size;
|
||||
//compute the size and update the fcb
|
||||
fcb.Set_random_record(fsize / fcb.Get_record_size());
|
||||
if ((fsize % fcb.Get_record_size())!=0) fcb.Set_random_record(fcb.Get_random_record()+1);
|
||||
fcb.Set_filesize(fsize);
|
||||
return true;
|
||||
};
|
||||
|
||||
bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset)
|
||||
{
|
||||
DOS_FCB fcb(seg,offset);
|
||||
Bit8u drive;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
// Open file
|
||||
if (!FCB_MakeName (&fcb, fullname, &drive)) return false;
|
||||
return Drives[drive]->FileUnlink(fullname);
|
||||
};
|
||||
|
||||
bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset)
|
||||
{
|
||||
Bit8u olddrive,newdrive;
|
||||
DOS_FCB fcbold(seg,offset);
|
||||
DOS_FCB fcbnew(seg,offset+16);
|
||||
char oldfullname[DOS_PATHLENGTH];
|
||||
char newfullname[DOS_PATHLENGTH];
|
||||
if (!FCB_MakeName (&fcbold, oldfullname, &olddrive)) return false;
|
||||
if (!FCB_MakeName (&fcbnew, newfullname, &newdrive)) return false;
|
||||
//TODO Test for different drives maybe
|
||||
return (Drives[newdrive]->Rename(oldfullname,newfullname));
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
bool DOS_FileExists(char * name) {
|
||||
|
|
Loading…
Add table
Reference in a new issue