- added vvfat floppy support (1.44 MB media only / currently not working with

plugins enabled)
- added special characters (0xe5 <-> 0x05) conversion in short filename
This commit is contained in:
Volker Ruppert 2011-01-11 20:14:21 +00:00
parent 4539848451
commit bc60caaccc
5 changed files with 92 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: floppy.cc,v 1.128 2010-11-20 12:37:00 vruppert Exp $
// $Id: floppy.cc,v 1.129 2011-01-11 20:14:21 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2009 The Bochs Project
@ -49,6 +49,7 @@ extern "C" {
}
#endif
#include "iodev.h"
#include "hdimage.h"
#include "floppy.h"
// windows.h included by bochs.h
#ifdef WIN32
@ -135,7 +136,7 @@ void bx_floppy_ctrl_c::init(void)
{
Bit8u i, devtype, cmos_value;
BX_DEBUG(("Init $Id: floppy.cc,v 1.128 2010-11-20 12:37:00 vruppert Exp $"));
BX_DEBUG(("Init $Id: floppy.cc,v 1.129 2011-01-11 20:14:21 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++) {
@ -155,6 +156,7 @@ void bx_floppy_ctrl_c::init(void)
BX_FD_THIS s.media[i].heads = 0;
BX_FD_THIS s.media[i].sectors = 0;
BX_FD_THIS s.media[i].fd = -1;
BX_FD_THIS s.media[i].vvfat_floppy = 0;
BX_FD_THIS s.media_present[i] = 0;
BX_FD_THIS s.device_type[i] = FDRIVE_NONE;
}
@ -1020,7 +1022,13 @@ void bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
{
// 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 = (int)lseek(BX_FD_THIS s.media[drive].fd, offset, SEEK_SET);
if (BX_FD_THIS s.media[drive].vvfat_floppy) {
#if !BX_PLUGINS
ret = BX_FD_THIS s.media[drive].vvfat->lseek(offset, SEEK_SET);
#endif
} else {
ret = (int)lseek(BX_FD_THIS s.media[drive].fd, offset, SEEK_SET);
}
if (ret < 0) {
BX_PANIC(("could not perform lseek() to %d on floppy image file", offset));
return;
@ -1056,7 +1064,13 @@ void bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
else
#endif
{
ret = ::read(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
if (BX_FD_THIS s.media[drive].vvfat_floppy) {
#if !BX_PLUGINS
ret = BX_FD_THIS s.media[drive].vvfat->read(buffer, bytes);
#endif
} else {
ret = ::read(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
}
}
if (ret < int(bytes)) {
/* ??? */
@ -1101,7 +1115,13 @@ void bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
else
#endif
{
ret = ::write(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
if (BX_FD_THIS s.media[drive].vvfat_floppy) {
#if !BX_PLUGINS
ret = BX_FD_THIS s.media[drive].vvfat->write(buffer, bytes);
#endif
} else {
ret = ::write(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
}
}
if (ret < int(bytes)) {
BX_PANIC(("could not perform write() on floppy image file"));
@ -1418,7 +1438,15 @@ unsigned bx_floppy_ctrl_c::set_media_status(unsigned drive, unsigned status)
if (status == 0) {
// eject floppy
if (BX_FD_THIS s.media[drive].fd >= 0) {
close(BX_FD_THIS s.media[drive].fd);
if (BX_FD_THIS s.media[drive].vvfat_floppy) {
#if !BX_PLUGINS
BX_FD_THIS s.media[drive].vvfat->close();
delete BX_FD_THIS s.media[drive].vvfat;
BX_FD_THIS s.media[drive].vvfat_floppy = 0;
#endif
} else {
close(BX_FD_THIS s.media[drive].fd);
}
BX_FD_THIS s.media[drive].fd = -1;
}
BX_FD_THIS s.media_present[drive] = 0;
@ -1501,7 +1529,15 @@ bx_bool bx_floppy_ctrl_c::evaluate_media(Bit8u devtype, Bit8u type, char *path,
//If media file is already open, close it before reopening.
if(media->fd >=0) {
close(media->fd);
if (media->vvfat_floppy) {
#if !BX_PLUGINS
media->vvfat->close();
delete media->vvfat;
media->vvfat_floppy = 0;
#endif
} else {
close(media->fd);
}
media->fd=-1;
}
@ -1521,6 +1557,24 @@ bx_bool bx_floppy_ctrl_c::evaluate_media(Bit8u devtype, Bit8u type, char *path,
return 0;
}
// use virtual VFAT support if requested (currently not compatible with plugins)
#if !BX_PLUGINS
if (!strncmp(path, "vvfat:", 6) && (devtype == FDRIVE_350HD)) {
media->vvfat = hdimage_init_image(BX_HDIMAGE_MODE_VVFAT, 1474560, "");
if (media->vvfat != NULL) {
if (media->vvfat->open(path + 6) == 0) {
media->type = BX_FLOPPY_1_44;
media->tracks = media->vvfat->cylinders;
media->heads = media->vvfat->heads;
media->sectors_per_track = media->vvfat->sectors;
media->sectors = 2880;
media->vvfat_floppy = 1;
media->fd = 0;
}
}
if (media->vvfat_floppy) return 1;
}
#endif
// open media file (image file or device)
media->raw_floppy_win95 = 0;
#ifdef macintosh

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: floppy.h,v 1.36 2010-07-03 05:34:27 vruppert Exp $
// $Id: floppy.h,v 1.37 2011-01-11 20:14:21 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2009 The Bochs Project
@ -45,6 +45,8 @@ typedef struct {
#ifdef WIN32
unsigned char raw_floppy_win95_drv;
#endif
bx_bool vvfat_floppy;
device_image_t *vvfat;
} floppy_t;
class bx_floppy_ctrl_c : public bx_floppy_stub_c {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: hdimage.cc,v 1.26 2011-01-07 18:35:34 vruppert Exp $
// $Id: hdimage.cc,v 1.27 2011-01-11 20:14:21 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2009 The Bochs Project
@ -1851,7 +1851,7 @@ device_image_t *hdimage_init_image(Bit8u image_mode, Bit64u disk_size, const cha
#endif //BX_COMPRESSED_HD_SUPPORT
case BX_HDIMAGE_MODE_VVFAT:
hdimage = new vvfat_image_t(journal);
hdimage = new vvfat_image_t(disk_size, journal);
break;
default:

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vvfat.cc,v 1.15 2011-01-10 21:15:04 vruppert Exp $
// $Id: vvfat.cc,v 1.16 2011-01-11 20:14:21 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2010 The Bochs Project
@ -30,10 +30,10 @@
// - volatile runtime write support using the hdimage redolog_t class
// - ask user on Bochs exit if directory and file changes should be committed
// - handle file attribute changes (system, hidden and read-only)
// - vvfat floppy support (1.44 MB media only)
// TODO:
// - write support: handle file date and time changes
// - vvfat floppy support
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
@ -343,11 +343,12 @@ infosector_t;
#pragma options align=reset
#endif
vvfat_image_t::vvfat_image_t(const char* _redolog_name)
vvfat_image_t::vvfat_image_t(Bit64u size, const char* _redolog_name)
{
first_sectors = new Bit8u[0xc000];
memset(&first_sectors[0], 0, 0xc000);
hd_size = size;
redolog = new redolog_t();
redolog_temp = NULL;
redolog_name = NULL;
@ -555,8 +556,6 @@ void vvfat_image_t::init_fat(void)
}
}
// TODO: in create_short_filename, 0xe5->0x05 is not yet handled!
// TODO: in parse_short_filename, 0x05->0xe5 is not yet handled!
direntry_t* vvfat_image_t::create_short_and_long_name(
unsigned int directory_start, const char* filename, int is_dot)
{
@ -597,6 +596,7 @@ direntry_t* vvfat_image_t::create_short_and_long_name(
else if (entry->name[i]>='a' && entry->name[i]<='z')
entry->name[i]+='A'-'a';
}
if (entry->name[0] == 0xe5) entry->name[0] = 0x05;
// mangle duplicates
while (1) {
@ -1262,17 +1262,29 @@ int vvfat_image_t::open(const char* dirname)
memcpy(&first_sectors[offset_to_bootsector * 0x200], sector_buffer, 0x200);
BX_INFO(("VVFAT: using boot sector from file"));
}
}
if (!use_mbr_file && !use_boot_file) {
if (cylinders == 0) {
cylinders = 1024;
heads = 16;
sectors = 63;
if (hd_size == 1474560) {
// floppy support
cylinders = 80;
heads = 2;
sectors = 18;
offset_to_bootsector = 0;
fat_type = 12;
sectors_per_cluster = 1;
first_cluster_of_root_dir = 0;
root_entries = 224;
reserved_sectors = 1;
} else {
if (cylinders == 0) {
cylinders = 1024;
heads = 16;
sectors = 63;
}
offset_to_bootsector = sectors;
}
sector_count = cylinders * heads * sectors;
offset_to_bootsector = sectors;
}
hd_size = sector_count * 512;
@ -1388,6 +1400,7 @@ direntry_t* vvfat_image_t::read_direntry(Bit8u *buffer, char *filename)
buffer += 32;
} else {
if (!has_lfn) {
if (entry->name[0] == 0x05) entry->name[0] = 0xe5;
memcpy(filename, entry->name, 8);
i = 7;
while ((i > 0) && (filename[i] == ' ')) filename[i--] = 0;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vvfat.h,v 1.8 2011-01-10 21:15:05 vruppert Exp $
// $Id: vvfat.h,v 1.9 2011-01-11 20:14:21 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2010 The Bochs Project
@ -109,7 +109,7 @@ typedef struct mapping_t {
class vvfat_image_t : public device_image_t
{
public:
vvfat_image_t(const char* redolog_name);
vvfat_image_t(Bit64u size, const char* redolog_name);
virtual ~vvfat_image_t();
int open(const char* dirname);