1
0
Fork 0

Added FAT image access and DOS booter functionality

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1757
This commit is contained in:
Dean Beeler 2004-04-03 19:24:59 +00:00
parent 57a7795ae0
commit d0e2bfa15f
7 changed files with 2024 additions and 48 deletions

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_programs.cpp,v 1.22 2004-01-10 14:03:34 qbix79 Exp $ */
/* $Id: dos_programs.cpp,v 1.23 2004-04-03 19:21:28 canadacow Exp $ */
#include <stdlib.h>
#include <string.h>
@ -28,9 +28,13 @@
#include "regs.h"
#include "callback.h"
#include "cdrom.h"
#include "dos_system.h"
#include "dos_inc.h"
#include "bios.h"
void MSCDEX_SetCDInterface(int intNr, int forceCD);
void IMGMOUNT_ProgramStart(Program * * make);
class MOUNT : public Program {
public:
@ -196,6 +200,150 @@ static void MEM_ProgramStart(Program * * make) {
*make=new MEM;
}
extern Bit32u floppytype;
class BOOT : public Program {
private:
FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize) {
Bit8u drive;
FILE *tmpfile;
char fullname[DOS_PATHLENGTH];
localDrive* ldp=0;
if (!DOS_MakeName((char *)filename,fullname,&drive)) return NULL;
ldp=(localDrive*)Drives[drive];
tmpfile = ldp->GetSystemFilePtr(fullname, "r");
if(tmpfile == NULL) {
WriteOut("Bootdisk file does not exist. Failing.\n");
return NULL;
}
fclose(tmpfile);
tmpfile = ldp->GetSystemFilePtr(fullname, "rb+");
if(tmpfile == NULL) {
WriteOut("Cannot open bootdisk file. Failing.\n");
return NULL;
}
fseek(tmpfile,0L, SEEK_END);
*ksize = (ftell(tmpfile) / 1024);
*bsize = ftell(tmpfile);
return tmpfile;
}
void printError(void) {
WriteOut("This command boots DosBox from either a floppy or hard disk image.\n\n");
WriteOut("For this command, one can specify a succession of floppy disks swappable\n");
WriteOut("by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n");
WriteOut("no drive letter is specified, this defaults to booting from the A drive.\n");
WriteOut("The only bootable drive letters are A, C, and D. For booting from a hard\n");
WriteOut("drive (C or D), the image should have already been mounted using the\n");
WriteOut("IMGMOUNT command.\n\n");
WriteOut("The syntax of this command is:\n\n");
WriteOut("BOOT [diskimg1.img diskimg2.img] [-l driveletter]\n");
}
public:
void Run(void) {
FILE *usefile;
Bitu i;
Bit32u floppysize, rombytesize;
Bit8u drive;
if(!cmd->GetCount()) {
printError();
return;
}
i=0;
drive = 'A';
while(i<cmd->GetCount()) {
if(cmd->FindCommand(i+1, temp_line)) {
if(temp_line == "-l") {
/* Specifying drive... next argument then is the drive */
i++;
if(cmd->FindCommand(i+1, temp_line)) {
drive=toupper(temp_line[0]);
if ((drive != 'A') && (drive != 'C') && (drive != 'D')) {
printError();
return;
}
} else {
printError();
return;
}
i++;
continue;
}
WriteOut("Opening image file: %s\n", temp_line.c_str());
usefile = getFSFile((Bit8u *)temp_line.c_str(), &floppysize, &rombytesize);
if(usefile != NULL) {
if(diskSwap[i] != NULL) delete diskSwap[i];
diskSwap[i] = new imageDisk(usefile, (Bit8u *)temp_line.c_str(), floppysize, false);
} else {
WriteOut("Cannot open %s", temp_line.c_str());
return;
}
}
i++;
}
swapPosition = 0;
swapInDisks();
if(imageDiskList[drive-65]==NULL) {
WriteOut("Unable to boot off of drive %c", drive);
return;
}
WriteOut("Booting from drive %c...\n", drive);
bootSector bootarea;
imageDiskList[drive-65]->Read_Sector(0,0,1,(Bit8u *)&bootarea);
for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]);
SegSet16(cs, 0);
reg_ip = 0x7c00;
/* Most likely a PCJr ROM */
/* Write it to E000:0000 */
/* Code inoperable at the moment */
/*
Bit8u rombuff[65536];
fseek(tmpfile,512L, SEEK_SET);
rombytesize-=512;
fread(rombuff, 1, rombytesize, tmpfile);
fclose(tmpfile);
for(i=0;i<rombytesize;i++) real_writeb(0xe000,i,rombuff[i]);
SegSet16(cs,0xe000);
SegSet16(ds,0x0060);
SegSet16(es,0x0060);
SegSet16(ss,0x0060);
reg_ip = 0x0;
reg_sp = 0x0;
reg_cx = 0xffff;
DEBUG_EnableDebugger();
*/
}
};
static void BOOT_ProgramStart(Program * * make) {
*make=new BOOT;
}
// LOADFIX
@ -351,4 +499,6 @@ void DOS_SetupPrograms(void) {
PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart);
PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart);
PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart);
PROGRAMS_MakeFile("BOOT.COM",BOOT_ProgramStart);
PROGRAMS_MakeFile("IMGMOUNT.COM", IMGMOUNT_ProgramStart);
}

1271
src/dos/drive_fat.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_local.cpp,v 1.45 2004-03-04 19:49:21 qbix79 Exp $ */
/* $Id: drive_local.cpp,v 1.46 2004-04-03 19:23:06 canadacow Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -103,6 +103,17 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
return true;
};
FILE * localDrive::GetSystemFilePtr(char * name, char * type) {
char newname[CROSS_LEN];
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
dirCache.ExpandName(newname);
return fopen(newname,type);
}
bool localDrive::FileUnlink(char * name) {
char newname[CROSS_LEN];
strcpy(newname,basedir);

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drives.h,v 1.19 2004-01-10 14:03:34 qbix79 Exp $ */
/* $Id: drives.h,v 1.20 2004-04-03 19:22:33 canadacow Exp $ */
#ifndef _DRIVES_H__
#define _DRIVES_H__
@ -24,6 +24,7 @@
#include <sys/types.h>
#include "dos_system.h"
#include "shell.h" /* for DOS_Shell */
#include "bios.h" /* for fatDrive */
bool WildFileCmp(const char * file, const char * wild);
@ -31,6 +32,7 @@ class localDrive : public DOS_Drive {
public:
localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
virtual FILE *GetSystemFilePtr(char * name, char * type);
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
virtual bool FileUnlink(char * name);
virtual bool RemoveDir(char * dir);
@ -61,6 +63,127 @@ private:
} allocation;
};
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct bootstrap {
Bit8u nearjmp[3];
Bit8u oemname[8];
Bit16u bytespersector;
Bit8u sectorspercluster;
Bit16u reservedsectors;
Bit8u fatcopies;
Bit16u rootdirentries;
Bit16u totalsectorcount;
Bit8u mediadescriptor;
Bit16u sectorsperfat;
Bit16u sectorspertrack;
Bit16u headcount;
/* 32-bit FAT extensions */
Bit32u hiddensectorcount;
Bit32u totalsecdword;
Bit8u bootcode[474];
Bit8u magic1; /* 0x55 */
Bit8u magic2; /* 0xaa */
} GCC_ATTRIBUTE(packed);
struct direntry {
Bit8u entryname[11];
Bit8u attrib;
Bit8u NTRes;
Bit8u milliSecondStamp;
Bit16u crtTime;
Bit16u crtDate;
Bit16u accessDate;
Bit16u hiFirstClust;
Bit16u modTime;
Bit16u modDate;
Bit16u loFirstClust;
Bit32u entrysize;
} GCC_ATTRIBUTE(packed);
struct partTable {
Bit8u booter[446];
struct {
Bit8u bootflag;
Bit8u beginchs[3];
Bit8u parttype;
Bit8u endchs[3];
Bit32u absSectStart;
Bit32u partSize;
} pentry[4];
Bit8u magic1; /* 0x55 */
Bit8u magic2; /* 0xaa */
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
class fatDrive : public DOS_Drive {
public:
fatDrive(const char * sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector);
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
virtual bool FileUnlink(char * name);
virtual bool RemoveDir(char * dir);
virtual bool MakeDir(char * dir);
virtual bool TestDir(char * dir);
virtual bool FindFirst(char * _dir,DOS_DTA & dta);
virtual bool FindNext(DOS_DTA & dta);
virtual bool GetFileAttr(char * name,Bit16u * attr);
virtual bool Rename(char * oldname,char * newname);
virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
virtual bool FileExists(const char* name);
virtual bool FileStat(const char* name, FileStat_Block * const stat_block);
virtual Bit8u GetMediaByte(void);
virtual bool isRemote(void);
public:
Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos);
Bit32u getSectorSize(void);
Bit32u getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector);
bool allocateCluster(Bit32u useCluster, Bit32u prevCluster);
Bit32u appendCluster(Bit32u startCluster);
void deleteClustChain(Bit32u startCluster);
Bit32u getFirstFreeClust(void);
bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum);
bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum);
imageDisk *loadedDisk;
private:
Bit32u getClusterValue(Bit32u clustNum);
void setClusterValue(Bit32u clustNum, Bit32u clustValue);
Bit32u getClustFirstSect(Bit32u clustNum);
bool FindNextInternal(Bit32u dirClustNumber, DOS_DTA & dta, direntry *foundEntry);
bool getDirClustNum(char * dir, Bit32u * clustNum, bool parDir);
bool getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry);
bool addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry);
void zeroOutCluster(Bit32u clustNumber);
bool getEntryName(char *fullname, char *entname);
friend void DOS_Shell::CMD_SUBST(char* args);
struct {
char srch_dir[CROSS_LEN];
} srchInfo[MAX_OPENDIRS];
struct {
Bit16u bytes_sector;
Bit8u sectors_cluster;
Bit16u total_clusters;
Bit16u free_clusters;
Bit8u mediaid;
} allocation;
bootstrap bootbuffer;
Bit8u fattype;
Bit32u CountOfClusters;
Bit32u partSectOff;
Bit32u firstDataSector;
Bit32u firstRootDirSect;
Bit32u cwdDirCluster;
Bit32u dirPosition; /* Position in directory search */
};
class cdromDrive : public localDrive
{
public: