- raw floppy access now supported in Win 9x (patch from Ben Lunt)
This commit is contained in:
parent
c757b06db8
commit
9d01ce4bfc
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: floppy.cc,v 1.72 2004-02-08 18:38:26 vruppert Exp $
|
||||
// $Id: floppy.cc,v 1.73 2004-05-31 14:47:12 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -132,7 +132,7 @@ bx_floppy_ctrl_c::init(void)
|
||||
{
|
||||
Bit8u i;
|
||||
|
||||
BX_DEBUG(("Init $Id: floppy.cc,v 1.72 2004-02-08 18:38:26 vruppert Exp $"));
|
||||
BX_DEBUG(("Init $Id: floppy.cc,v 1.73 2004-05-31 14:47:12 vruppert Exp $"));
|
||||
DEV_dma_register_8bit_channel(2, dma_read, dma_write, "Floppy Drive");
|
||||
DEV_register_irq(6, "Floppy Drive");
|
||||
for (unsigned addr=0x03F2; addr<=0x03F7; addr++) {
|
||||
@ -1007,9 +1007,12 @@ bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
|
||||
if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
#endif
|
||||
{
|
||||
ret = lseek(BX_FD_THIS s.media[drive].fd, offset, SEEK_SET);
|
||||
if (ret < 0) {
|
||||
BX_PANIC(("could not perform lseek() on floppy image file"));
|
||||
// don't need to seek the file if we are using Win95 type direct access
|
||||
if (!BX_FD_THIS s.media[drive].raw_floppy_win95) {
|
||||
ret = lseek(BX_FD_THIS s.media[drive].fd, offset, SEEK_SET);
|
||||
if (ret < 0) {
|
||||
BX_PANIC(("could not perform lseek() on floppy image file"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1018,8 +1021,31 @@ bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
|
||||
if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
ret = fd_read((char *) buffer, offset, bytes);
|
||||
else
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
// if using Win95 direct access
|
||||
if (BX_FD_THIS s.media[drive].raw_floppy_win95) {
|
||||
DWORD ret_cnt = 0;
|
||||
DIOC_REGISTERS reg;
|
||||
HANDLE hFile = CreateFile("\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
BX_PANIC(("Could not open floppy device under Win95 for read"));
|
||||
reg.reg_ECX = bytes >> 9; // / 512
|
||||
reg.reg_EDX = offset >> 9; // / 512
|
||||
reg.reg_EBX = (DWORD) buffer;
|
||||
reg.reg_EAX = BX_FD_THIS s.media[drive].raw_floppy_win95_drv;
|
||||
DeviceIoControl(hFile, VWIN32_DIOC_DOS_INT25,
|
||||
®, sizeof(reg), ®, sizeof(reg), &ret_cnt, NULL);
|
||||
CloseHandle(hFile);
|
||||
// I don't know why this returns 28 instead of 512, but it works
|
||||
if (ret_cnt == 28)
|
||||
ret = 512;
|
||||
} else {
|
||||
#endif
|
||||
ret = ::read(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
|
||||
#ifdef WIN32
|
||||
}
|
||||
#endif
|
||||
if (ret < int(bytes)) {
|
||||
/* ??? */
|
||||
if (ret > 0) {
|
||||
@ -1040,8 +1066,31 @@ bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
|
||||
if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
ret = fd_write((char *) buffer, offset, bytes);
|
||||
else
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
// if using Win95 direct access
|
||||
if (BX_FD_THIS s.media[drive].raw_floppy_win95) {
|
||||
DWORD ret_cnt = 0;
|
||||
DIOC_REGISTERS reg;
|
||||
HANDLE hFile = CreateFile("\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
BX_PANIC(("Could not open floppy device under Win95"));
|
||||
reg.reg_ECX = bytes >> 9; // / 512
|
||||
reg.reg_EDX = offset >> 9; // / 512
|
||||
reg.reg_EBX = (DWORD) buffer;
|
||||
reg.reg_EAX = BX_FD_THIS s.media[drive].raw_floppy_win95_drv;
|
||||
DeviceIoControl(hFile, VWIN32_DIOC_DOS_INT26,
|
||||
®, sizeof(reg), ®, sizeof(reg), (LPDWORD) &ret_cnt, NULL);
|
||||
CloseHandle(hFile);
|
||||
// I don't know why this returns 28 instead of 512, but it works
|
||||
if (ret_cnt == 28)
|
||||
ret = 512;
|
||||
} else {
|
||||
#endif
|
||||
ret = ::write(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
|
||||
#ifdef WIN32
|
||||
}
|
||||
#endif
|
||||
if (ret < int(bytes)) {
|
||||
BX_PANIC(("could not perform write() on floppy image file"));
|
||||
}
|
||||
@ -1406,6 +1455,7 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
|
||||
// open media file (image file or device)
|
||||
media->write_protected = 0;
|
||||
media->raw_floppy_win95 = 0;
|
||||
#ifdef macintosh
|
||||
media->fd = 0;
|
||||
if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
@ -1417,8 +1467,34 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
hFile = CreateFile(sTemp, GENERIC_READ, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
BX_ERROR(("Cannot open floppy drive"));
|
||||
return(0);
|
||||
// try to open it with Win95 style
|
||||
hFile = CreateFile("\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
BX_ERROR(("Cannot open floppy drive"));
|
||||
return(0);
|
||||
}
|
||||
media->raw_floppy_win95 = 1;
|
||||
media->raw_floppy_win95_drv = toupper(path[0]) - 'A';
|
||||
}
|
||||
// if using Win95 direct access, get params this way
|
||||
if (media->raw_floppy_win95) {
|
||||
DWORD ret_cnt = 0;
|
||||
DIOC_REGISTERS reg;
|
||||
BLOCK_DEV_PARAMS params;
|
||||
reg.reg_EAX = 0x440D;
|
||||
reg.reg_ECX = 0x0860;
|
||||
reg.reg_EDX = (DWORD) ¶ms;
|
||||
reg.reg_EBX = media->raw_floppy_win95_drv+1;
|
||||
//reg.reg_Flags = 0x0001; // assume error (carry flag is set)
|
||||
if (DeviceIoControl(hFile, VWIN32_DIOC_DOS_IOCTL ,
|
||||
®, sizeof(reg), ®, sizeof(reg), &ret_cnt, NULL)) {
|
||||
tracks = params.cylinders;
|
||||
heads = params.num_heads;
|
||||
spt = params.sects_per_track;
|
||||
} else {
|
||||
CloseHandle(hFile);
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
if (!DeviceIoControl(hFile, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg), &bytes, NULL)) {
|
||||
BX_ERROR(("No media in floppy drive"));
|
||||
@ -1429,9 +1505,11 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
heads = (unsigned)dg.TracksPerCylinder;
|
||||
spt = (unsigned)dg.SectorsPerTrack;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
media->fd = open(sTemp, BX_RDWR);
|
||||
CloseHandle(hFile);
|
||||
// if using Win95 direct access, don't open the file
|
||||
if (!media->raw_floppy_win95)
|
||||
media->fd = open(sTemp, BX_RDWR);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDWR);
|
||||
}
|
||||
@ -1439,28 +1517,31 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
media->fd = open(path, BX_RDWR);
|
||||
#endif
|
||||
|
||||
if (media->fd < 0) {
|
||||
BX_INFO(( "tried to open '%s' read/write: %s",path,strerror(errno) ));
|
||||
// try opening the file read-only
|
||||
media->write_protected = 1;
|
||||
// Don't open the handle if using Win95 style direct access
|
||||
if (!media->raw_floppy_win95) {
|
||||
if (media->fd < 0) {
|
||||
BX_INFO(( "tried to open '%s' read/write: %s",path,strerror(errno) ));
|
||||
// try opening the file read-only
|
||||
media->write_protected = 1;
|
||||
#ifdef macintosh
|
||||
media->fd = 0;
|
||||
if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
media->fd = 0;
|
||||
if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
if (raw_floppy == 1) {
|
||||
media->fd = open(sTemp, BX_RDONLY);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
}
|
||||
if (raw_floppy == 1) {
|
||||
media->fd = open(sTemp, BX_RDONLY);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
}
|
||||
#else
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
#endif
|
||||
if (media->fd < 0) {
|
||||
// failed to open read-only too
|
||||
BX_INFO(( "tried to open '%s' read only: %s",path,strerror(errno) ));
|
||||
media->type = type;
|
||||
return(0);
|
||||
if (media->fd < 0) {
|
||||
// failed to open read-only too
|
||||
BX_INFO(( "tried to open '%s' read only: %s",path,strerror(errno) ));
|
||||
media->type = type;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: floppy.h,v 1.17 2004-02-07 14:34:34 vruppert Exp $
|
||||
// $Id: floppy.h,v 1.18 2004-05-31 14:47:12 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -45,6 +45,10 @@ typedef struct {
|
||||
unsigned heads; /* number of heads */
|
||||
unsigned type;
|
||||
unsigned write_protected;
|
||||
unsigned char raw_floppy_win95;
|
||||
#ifdef WIN32
|
||||
unsigned char raw_floppy_win95_drv;
|
||||
#endif
|
||||
} floppy_t;
|
||||
|
||||
class bx_floppy_ctrl_c : public bx_floppy_stub_c {
|
||||
@ -137,3 +141,46 @@ public:
|
||||
BX_FD_SMF void increment_sector(void);
|
||||
BX_FD_SMF bx_bool evaluate_media(unsigned type, char *path, floppy_t *floppy);
|
||||
};
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// used for direct floppy access in Win95
|
||||
#define VWIN32_DIOC_DOS_IOCTL 1
|
||||
#define VWIN32_DIOC_DOS_INT25 2
|
||||
#define VWIN32_DIOC_DOS_INT26 3
|
||||
|
||||
typedef struct _DIOC_REGISTERS {
|
||||
DWORD reg_EBX;
|
||||
DWORD reg_EDX;
|
||||
DWORD reg_ECX;
|
||||
DWORD reg_EAX;
|
||||
DWORD reg_EDI;
|
||||
DWORD reg_ESI;
|
||||
DWORD reg_Flags;
|
||||
} DIOC_REGISTERS, *PDIOC_REGISTERS;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct _BLOCK_DEV_PARAMS {
|
||||
BYTE features;
|
||||
BYTE dev_type;
|
||||
WORD attribs;
|
||||
WORD cylinders;
|
||||
BYTE media_type;
|
||||
// BPB
|
||||
WORD bytes_per_sector;
|
||||
BYTE sect_per_cluster;
|
||||
WORD reserved_sectors;
|
||||
BYTE fats;
|
||||
WORD root_entries;
|
||||
WORD tot_sectors;
|
||||
BYTE media_id;
|
||||
WORD sects_per_fat;
|
||||
WORD sects_per_track;
|
||||
WORD num_heads;
|
||||
WORD hidden_sectors;
|
||||
BYTE remainder[5];
|
||||
} BLOCK_DEV_PARAMS, *PBLOCK_DEV_PARAMS;
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user