1
0
Fork 0

Added missing FCB-functions

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@256
This commit is contained in:
Ulf Wohlers 2002-09-03 12:07:58 +00:00
parent 4072e14107
commit 33c702a8e4
4 changed files with 270 additions and 27 deletions

View file

@ -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;
};

View file

@ -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 */

View file

@ -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) {

View file

@ -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) {