mirror of
https://github.com/holub/mame
synced 2025-06-25 05:44:23 +03:00
floppy: Handle half and quarter tracks [O. Galibert]
This commit is contained in:
parent
54aeef2210
commit
c6da8ca408
@ -273,6 +273,7 @@ void floppy_image_device::device_start()
|
|||||||
mon = 1;
|
mon = 1;
|
||||||
|
|
||||||
cyl = 0;
|
cyl = 0;
|
||||||
|
subcyl = 0;
|
||||||
ss = 0;
|
ss = 0;
|
||||||
stp = 1;
|
stp = 1;
|
||||||
wpt = 0;
|
wpt = 0;
|
||||||
@ -535,9 +536,51 @@ void floppy_image_device::stp_w(int state)
|
|||||||
if (dskchg==0) dskchg = 1;
|
if (dskchg==0) dskchg = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
subcyl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void floppy_image_device::seek_phase_w(int phases)
|
||||||
|
{
|
||||||
|
int cur_pos = (cyl << 2) | subcyl;
|
||||||
|
int req_pos;
|
||||||
|
switch(phases) {
|
||||||
|
case 0x1: req_pos = 0; break;
|
||||||
|
case 0x3: req_pos = 1; break;
|
||||||
|
case 0x2: req_pos = 2; break;
|
||||||
|
case 0x6: req_pos = 3; break;
|
||||||
|
case 0x4: req_pos = 4; break;
|
||||||
|
case 0xc: req_pos = 5; break;
|
||||||
|
case 0x8: req_pos = 6; break;
|
||||||
|
case 0x9: req_pos = 7; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opposite phase, don't move
|
||||||
|
if(((cur_pos ^ req_pos) & 7) == 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int next_pos = (cur_pos & ~7) | req_pos;
|
||||||
|
if(next_pos < cur_pos-4)
|
||||||
|
next_pos += 8;
|
||||||
|
else if(next_pos > cur_pos+4)
|
||||||
|
next_pos -= 8;
|
||||||
|
if(next_pos < 0)
|
||||||
|
next_pos = 0;
|
||||||
|
else if(next_pos > (tracks-1)*4)
|
||||||
|
next_pos = (tracks-1)*4;
|
||||||
|
cyl = next_pos >> 2;
|
||||||
|
subcyl = next_pos & 3;
|
||||||
|
|
||||||
|
if(TRACE_STEP && (next_pos != cur_pos))
|
||||||
|
logerror("%s: track %d.%d\n", tag(), cyl, subcyl);
|
||||||
|
|
||||||
|
/* Update disk detection if applicable */
|
||||||
|
if (exists())
|
||||||
|
if (dskchg==0)
|
||||||
|
dskchg = 1;
|
||||||
|
}
|
||||||
|
|
||||||
int floppy_image_device::find_index(UINT32 position, const UINT32 *buf, int buf_size)
|
int floppy_image_device::find_index(UINT32 position, const UINT32 *buf, int buf_size)
|
||||||
{
|
{
|
||||||
int spos = (buf_size >> 1)-1;
|
int spos = (buf_size >> 1)-1;
|
||||||
|
@ -105,6 +105,7 @@ public:
|
|||||||
bool ss_r() { return ss; }
|
bool ss_r() { return ss; }
|
||||||
bool twosid_r();
|
bool twosid_r();
|
||||||
|
|
||||||
|
void seek_phase_w(int phases);
|
||||||
void stp_w(int state);
|
void stp_w(int state);
|
||||||
void dir_w(int state) { dir = state; }
|
void dir_w(int state) { dir = state; }
|
||||||
void ss_w(int state) { ss = state; }
|
void ss_w(int state) { ss = state; }
|
||||||
@ -164,7 +165,7 @@ protected:
|
|||||||
|
|
||||||
attotime revolution_start_time, rev_time;
|
attotime revolution_start_time, rev_time;
|
||||||
UINT32 revolution_count;
|
UINT32 revolution_count;
|
||||||
int cyl;
|
int cyl, subcyl;
|
||||||
|
|
||||||
bool image_dirty;
|
bool image_dirty;
|
||||||
int ready_counter;
|
int ready_counter;
|
||||||
|
@ -72,7 +72,6 @@ void wozfdc_device::device_start()
|
|||||||
|
|
||||||
void wozfdc_device::device_reset()
|
void wozfdc_device::device_reset()
|
||||||
{
|
{
|
||||||
current_cyl = 0;
|
|
||||||
floppy = NULL;
|
floppy = NULL;
|
||||||
active = MODE_IDLE;
|
active = MODE_IDLE;
|
||||||
phases = 0x00;
|
phases = 0x00;
|
||||||
@ -199,22 +198,8 @@ void wozfdc_device::phase(int ph, bool on)
|
|||||||
else
|
else
|
||||||
phases &= ~(1 << ph);
|
phases &= ~(1 << ph);
|
||||||
|
|
||||||
if(floppy && active) {
|
if(floppy && active)
|
||||||
int cph = current_cyl & 3;
|
floppy->seek_phase_w(phases);
|
||||||
int pcyl = current_cyl;
|
|
||||||
if(!(phases & (1 << cph))) {
|
|
||||||
if(current_cyl < 70 && (phases & (1 << ((cph+1) & 3))))
|
|
||||||
current_cyl++;
|
|
||||||
if(current_cyl && (phases & (1 << ((cph+3) & 3))))
|
|
||||||
current_cyl--;
|
|
||||||
if(current_cyl != pcyl && !(current_cyl & 1)) {
|
|
||||||
floppy->dir_w(current_cyl < pcyl);
|
|
||||||
floppy->stp_w(true);
|
|
||||||
floppy->stp_w(false);
|
|
||||||
floppy->stp_w(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wozfdc_device::control(int offset)
|
void wozfdc_device::control(int offset)
|
||||||
@ -238,10 +223,8 @@ void wozfdc_device::control(int offset)
|
|||||||
case 0x9:
|
case 0x9:
|
||||||
switch(active) {
|
switch(active) {
|
||||||
case MODE_IDLE:
|
case MODE_IDLE:
|
||||||
if(floppy) {
|
if(floppy)
|
||||||
floppy->mon_w(false);
|
floppy->mon_w(false);
|
||||||
current_cyl = floppy->get_cyl() << 1;
|
|
||||||
}
|
|
||||||
active = MODE_ACTIVE;
|
active = MODE_ACTIVE;
|
||||||
if(floppy)
|
if(floppy)
|
||||||
lss_start();
|
lss_start();
|
||||||
|
@ -60,7 +60,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
const UINT8 *m_rom_p6;
|
const UINT8 *m_rom_p6;
|
||||||
UINT8 current_cyl, last_6502_write;
|
UINT8 last_6502_write;
|
||||||
bool mode_write, mode_load;
|
bool mode_write, mode_load;
|
||||||
int active;
|
int active;
|
||||||
UINT8 phases;
|
UINT8 phases;
|
||||||
|
@ -947,19 +947,13 @@ floppy_image::floppy_image(int _tracks, int _heads, UINT32 _form_factor)
|
|||||||
form_factor = _form_factor;
|
form_factor = _form_factor;
|
||||||
variant = 0;
|
variant = 0;
|
||||||
|
|
||||||
memset(cell_data, 0, sizeof(cell_data));
|
track_array.resize(tracks*4+1);
|
||||||
memset(track_size, 0, sizeof(track_size));
|
for(int i=0; i<tracks*4+1; i++)
|
||||||
memset(track_alloc_size, 0, sizeof(track_alloc_size));
|
track_array[i].resize(heads);
|
||||||
memset(write_splice, 0, sizeof(write_splice));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
floppy_image::~floppy_image()
|
floppy_image::~floppy_image()
|
||||||
{
|
{
|
||||||
for (int i=0;i<MAX_FLOPPY_TRACKS;i++) {
|
|
||||||
for (int j=0;j<MAX_FLOPPY_HEADS;j++) {
|
|
||||||
global_free_array(cell_data[i][j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void floppy_image::get_maximal_geometry(int &_tracks, int &_heads)
|
void floppy_image::get_maximal_geometry(int &_tracks, int &_heads)
|
||||||
@ -970,7 +964,7 @@ void floppy_image::get_maximal_geometry(int &_tracks, int &_heads)
|
|||||||
|
|
||||||
void floppy_image::get_actual_geometry(int &_tracks, int &_heads)
|
void floppy_image::get_actual_geometry(int &_tracks, int &_heads)
|
||||||
{
|
{
|
||||||
int maxt = tracks-1, maxh = heads-1;
|
int maxt = tracks*4, maxh = heads-1;
|
||||||
|
|
||||||
while(maxt >= 0) {
|
while(maxt >= 0) {
|
||||||
for(int i=0; i<=maxh; i++)
|
for(int i=0; i<=maxh; i++)
|
||||||
@ -987,22 +981,29 @@ void floppy_image::get_actual_geometry(int &_tracks, int &_heads)
|
|||||||
maxh--;
|
maxh--;
|
||||||
}
|
}
|
||||||
head_done:
|
head_done:
|
||||||
_tracks = maxt+1;
|
_tracks = (maxt+4)/4;
|
||||||
_heads = maxh+1;
|
_heads = maxh+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int floppy_image::get_resolution() const
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
for(int i=0; i<tracks*4+1; i++)
|
||||||
|
for(int j=0; j<heads; j++)
|
||||||
|
if(track_array[i][j].track_size)
|
||||||
|
mask |= 1 << (i & 3);
|
||||||
|
if(mask & 0xa)
|
||||||
|
return 2;
|
||||||
|
if(mask & 0x4)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void floppy_image::ensure_alloc(int track, int head)
|
void floppy_image::ensure_alloc(int track, int head)
|
||||||
{
|
{
|
||||||
if(track_size[track][head] > track_alloc_size[track][head]) {
|
track_info &tr = track_array[track][head];
|
||||||
UINT32 new_size = track_size[track][head]*11/10;
|
if(tr.track_size > tr.cell_data.count())
|
||||||
UINT32 *new_array = global_alloc_array(UINT32, new_size);
|
tr.cell_data.resize_keep_and_clear_new(tr.track_size);
|
||||||
if(track_alloc_size[track][head]) {
|
|
||||||
memcpy(new_array, cell_data[track][head], track_alloc_size[track][head]*4);
|
|
||||||
global_free_array(cell_data[track][head]);
|
|
||||||
}
|
|
||||||
cell_data[track][head] = new_array;
|
|
||||||
track_alloc_size[track][head] = new_size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *floppy_image::get_variant_name(UINT32 form_factor, UINT32 variant)
|
const char *floppy_image::get_variant_name(UINT32 form_factor, UINT32 variant)
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "osdcore.h"
|
#include "osdcore.h"
|
||||||
#include "ioprocs.h"
|
#include "ioprocs.h"
|
||||||
#include "opresolv.h"
|
#include "opresolv.h"
|
||||||
|
#include "coretmpl.h"
|
||||||
|
|
||||||
#ifndef LOG_FORMATS
|
#ifndef LOG_FORMATS
|
||||||
#define LOG_FORMATS if (0) printf
|
#define LOG_FORMATS if (0) printf
|
||||||
@ -637,7 +638,13 @@ floppy_image_format_t *floppy_image_format_creator()
|
|||||||
//! form factor can be physically inserted in a reader that handles
|
//! form factor can be physically inserted in a reader that handles
|
||||||
//! it. The second half indicates the variants which are usually
|
//! it. The second half indicates the variants which are usually
|
||||||
//! detectable by the reader, such as density and number of sides.
|
//! detectable by the reader, such as density and number of sides.
|
||||||
|
//!
|
||||||
|
//! Resolution is quarter-track. The optional subtrack parameter is
|
||||||
|
//! 0-3:
|
||||||
|
//! - 0 = Track itself
|
||||||
|
//! - 1 = 1st quarter track
|
||||||
|
//! - 2 = Half track
|
||||||
|
//! - 3 = 2nd quarter track
|
||||||
|
|
||||||
class floppy_image
|
class floppy_image
|
||||||
{
|
{
|
||||||
@ -682,7 +689,7 @@ public:
|
|||||||
M2FM = 0x4D32464D, //!< "M2FM", modified modified frequency modulation
|
M2FM = 0x4D32464D, //!< "M2FM", modified modified frequency modulation
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
|
|
||||||
|
|
||||||
//! floppy_image constructor
|
//! floppy_image constructor
|
||||||
@ -703,21 +710,25 @@ public:
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param track
|
@param track
|
||||||
|
@param subtrack
|
||||||
@param head
|
@param head
|
||||||
@param size size of this track
|
@param size size of this track
|
||||||
*/
|
*/
|
||||||
void set_track_size(int track, int head, UINT32 size) { track_size[track][head] = size; ensure_alloc(track, head); }
|
void set_track_size(int track, int head, UINT32 size, int subtrack = 0) { track_array[track*4+subtrack][head].track_size = size; ensure_alloc(track*4+subtrack, head); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param track track number
|
@param track
|
||||||
|
@param subtrack
|
||||||
@param head head number
|
@param head head number
|
||||||
@return a pointer to the data buffer for this track and head
|
@return a pointer to the data buffer for this track and head
|
||||||
*/
|
*/
|
||||||
UINT32 *get_buffer(int track, int head) { return cell_data[track][head]; }
|
UINT32 *get_buffer(int track, int head, int subtrack = 0) { return track_array[track*4+subtrack][head].cell_data; }
|
||||||
|
|
||||||
//! @return the track size
|
//! @return the track size
|
||||||
//! @param track
|
//! @param track
|
||||||
|
//! @param subtrack
|
||||||
//! @param head
|
//! @param head
|
||||||
UINT32 get_track_size(int track, int head) { return track_size[track][head]; }
|
UINT32 get_track_size(int track, int head, int subtrack = 0) { return track_array[track*4+subtrack][head].track_size; }
|
||||||
|
|
||||||
//! Sets the write splice position.
|
//! Sets the write splice position.
|
||||||
//! The "track splice" information indicates where to start writing
|
//! The "track splice" information indicates where to start writing
|
||||||
@ -727,18 +738,22 @@ public:
|
|||||||
//! representation is the angular position relative to the index.
|
//! representation is the angular position relative to the index.
|
||||||
|
|
||||||
/*! @param track
|
/*! @param track
|
||||||
|
@param subtrack
|
||||||
@param head
|
@param head
|
||||||
@param pos the position
|
@param pos the position
|
||||||
*/
|
*/
|
||||||
void set_write_splice_position(int track, int head, UINT32 pos) { write_splice[track][head] = pos; }
|
void set_write_splice_position(int track, int head, UINT32 pos, int subtrack = 0) { track_array[track*4+subtrack][head].write_splice = pos; }
|
||||||
//! @return the current write splice position.
|
//! @return the current write splice position.
|
||||||
UINT32 get_write_splice_position(int track, int head) const { return write_splice[track][head]; }
|
UINT32 get_write_splice_position(int track, int head, int subtrack = 0) const { return track_array[track*4+subtrack][head].write_splice; }
|
||||||
//! @return the maximal geometry supported by this format.
|
//! @return the maximal geometry supported by this format.
|
||||||
void get_maximal_geometry(int &tracks, int &heads);
|
void get_maximal_geometry(int &tracks, int &heads);
|
||||||
|
|
||||||
//! @return the current geometry of the loaded image.
|
//! @return the current geometry of the loaded image.
|
||||||
void get_actual_geometry(int &tracks, int &heads);
|
void get_actual_geometry(int &tracks, int &heads);
|
||||||
|
|
||||||
|
//! @return the track resolution (0=full track, 1 = half-track, 2 = quarter track)
|
||||||
|
int get_resolution() const;
|
||||||
|
|
||||||
//! Returns the variant name for the particular disk form factor/variant
|
//! Returns the variant name for the particular disk form factor/variant
|
||||||
//! @param form_factor
|
//! @param form_factor
|
||||||
//! @param variant
|
//! @param variant
|
||||||
@ -746,20 +761,21 @@ public:
|
|||||||
static const char *get_variant_name(UINT32 form_factor, UINT32 variant);
|
static const char *get_variant_name(UINT32 form_factor, UINT32 variant);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum {
|
|
||||||
MAX_FLOPPY_HEADS = 2,
|
|
||||||
MAX_FLOPPY_TRACKS = 84
|
|
||||||
};
|
|
||||||
|
|
||||||
int tracks, heads;
|
int tracks, heads;
|
||||||
|
|
||||||
UINT32 form_factor, variant;
|
UINT32 form_factor, variant;
|
||||||
|
|
||||||
UINT32 *cell_data[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
|
struct track_info {
|
||||||
UINT32 track_size[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
|
dynamic_array<UINT32> cell_data;
|
||||||
UINT32 track_alloc_size[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
|
UINT32 track_size;
|
||||||
UINT32 write_splice[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
|
UINT32 write_splice;
|
||||||
|
|
||||||
|
track_info() { track_size = write_splice = 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// track number multiplied by 4 then head
|
||||||
|
// last array size may be bigger than actual track size
|
||||||
|
dynamic_array<dynamic_array<track_info> > track_array;
|
||||||
|
|
||||||
void ensure_alloc(int track, int head);
|
void ensure_alloc(int track, int head);
|
||||||
};
|
};
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
Mess floppy image structure:
|
Mess floppy image structure:
|
||||||
|
|
||||||
- header with signature, number of cylinders, number of heads. Min
|
- header with signature, number of cylinders, number of heads. Min
|
||||||
track and min head are considered to always be 0.
|
track and min head are considered to always be 0. The two top bits
|
||||||
|
of the cylinder count is the resolution: 0=tracks, 1=half tracks,
|
||||||
|
2=quarter tracks.
|
||||||
|
|
||||||
- vector of track descriptions, looping on cylinders and sub-lopping
|
- vector of track descriptions, looping on cylinders with the given
|
||||||
on heads, each description composed of:
|
resolution and sub-lopping on heads, each description composed of:
|
||||||
- offset of the track data in bytes from the start of the file
|
- offset of the track data in bytes from the start of the file
|
||||||
- size of the compressed track data in bytes (0 for unformatted)
|
- size of the compressed track data in bytes (0 for unformatted)
|
||||||
- size of the uncompressed track data in bytes (0 for unformatted)
|
- size of the uncompressed track data in bytes (0 for unformatted)
|
||||||
@ -97,7 +99,8 @@ int mfi_format::identify(io_generic *io, UINT32 form_factor)
|
|||||||
|
|
||||||
io_generic_read(io, &h, 0, sizeof(header));
|
io_generic_read(io, &h, 0, sizeof(header));
|
||||||
if(memcmp( h.sign, sign, 16 ) == 0 &&
|
if(memcmp( h.sign, sign, 16 ) == 0 &&
|
||||||
h.cyl_count <= 160 &&
|
(h.cyl_count & CYLINDER_MASK) <= 84 &&
|
||||||
|
(h.cyl_count >> RESOLUTION_SHIFT) < 3 &&
|
||||||
h.head_count <= 2 &&
|
h.head_count <= 2 &&
|
||||||
(!form_factor || !h.form_factor || h.form_factor == form_factor))
|
(!form_factor || !h.form_factor || h.form_factor == form_factor))
|
||||||
return 100;
|
return 100;
|
||||||
@ -107,22 +110,24 @@ int mfi_format::identify(io_generic *io, UINT32 form_factor)
|
|||||||
bool mfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
bool mfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||||
{
|
{
|
||||||
header h;
|
header h;
|
||||||
entry entries[84*2];
|
entry entries[84*2*4];
|
||||||
io_generic_read(io, &h, 0, sizeof(header));
|
io_generic_read(io, &h, 0, sizeof(header));
|
||||||
io_generic_read(io, &entries, sizeof(header), h.cyl_count*h.head_count*sizeof(entry));
|
int resolution = h.cyl_count >> RESOLUTION_SHIFT;
|
||||||
|
h.cyl_count &= CYLINDER_MASK;
|
||||||
|
io_generic_read(io, &entries, sizeof(header), (h.cyl_count << resolution)*h.head_count*sizeof(entry));
|
||||||
|
|
||||||
image->set_variant(h.variant);
|
image->set_variant(h.variant);
|
||||||
|
|
||||||
dynamic_buffer compressed;
|
dynamic_buffer compressed;
|
||||||
|
|
||||||
entry *ent = entries;
|
entry *ent = entries;
|
||||||
for(unsigned int cyl=0; cyl != h.cyl_count; cyl++)
|
for(unsigned int cyl=0; cyl <= (h.cyl_count - 1) << 2; cyl += 4 >> resolution)
|
||||||
for(unsigned int head=0; head != h.head_count; head++) {
|
for(unsigned int head=0; head != h.head_count; head++) {
|
||||||
image->set_write_splice_position(cyl, head, ent->write_splice);
|
image->set_write_splice_position(cyl >> 2, head, ent->write_splice, cyl & 3);
|
||||||
|
|
||||||
if(ent->uncompressed_size == 0) {
|
if(ent->uncompressed_size == 0) {
|
||||||
// Unformatted track
|
// Unformatted track
|
||||||
image->set_track_size(cyl, head, 0);
|
image->set_track_size(cyl >> 2, head, 0, cyl & 3);
|
||||||
ent++;
|
ent++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -132,8 +137,8 @@ bool mfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
|||||||
io_generic_read(io, compressed, ent->offset, ent->compressed_size);
|
io_generic_read(io, compressed, ent->offset, ent->compressed_size);
|
||||||
|
|
||||||
unsigned int cell_count = ent->uncompressed_size/4;
|
unsigned int cell_count = ent->uncompressed_size/4;
|
||||||
image->set_track_size(cyl, head, cell_count);
|
image->set_track_size(cyl >> 2, head, cell_count, cyl & 3);
|
||||||
UINT32 *trackbuf = image->get_buffer(cyl, head);
|
UINT32 *trackbuf = image->get_buffer(cyl >> 2, head, cyl & 3);
|
||||||
|
|
||||||
uLongf size = ent->uncompressed_size;
|
uLongf size = ent->uncompressed_size;
|
||||||
if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK)
|
if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK)
|
||||||
@ -158,18 +163,19 @@ bool mfi_format::save(io_generic *io, floppy_image *image)
|
|||||||
{
|
{
|
||||||
int tracks, heads;
|
int tracks, heads;
|
||||||
image->get_actual_geometry(tracks, heads);
|
image->get_actual_geometry(tracks, heads);
|
||||||
|
int resolution = image->get_resolution();
|
||||||
int max_track_size = 0;
|
int max_track_size = 0;
|
||||||
for(int track=0; track<tracks; track++)
|
for(int track=0; track <= (tracks-1) << 2; track += 4 >> resolution)
|
||||||
for(int head=0; head<heads; head++) {
|
for(int head=0; head<heads; head++) {
|
||||||
int tsize = image->get_track_size(track, head);
|
int tsize = image->get_track_size(track >> 2, head, track & 3);
|
||||||
if(tsize > max_track_size)
|
if(tsize > max_track_size)
|
||||||
max_track_size = tsize;
|
max_track_size = tsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
header h;
|
header h;
|
||||||
entry entries[84*2];
|
entry entries[84*2*4];
|
||||||
memcpy(h.sign, sign, 16);
|
memcpy(h.sign, sign, 16);
|
||||||
h.cyl_count = tracks;
|
h.cyl_count = tracks | (resolution << RESOLUTION_SHIFT);
|
||||||
h.head_count = heads;
|
h.head_count = heads;
|
||||||
h.form_factor = image->get_form_factor();
|
h.form_factor = image->get_form_factor();
|
||||||
h.variant = image->get_variant();
|
h.variant = image->get_variant();
|
||||||
@ -178,20 +184,20 @@ bool mfi_format::save(io_generic *io, floppy_image *image)
|
|||||||
|
|
||||||
memset(entries, 0, sizeof(entries));
|
memset(entries, 0, sizeof(entries));
|
||||||
|
|
||||||
int pos = sizeof(header) + tracks*heads*sizeof(entry);
|
int pos = sizeof(header) + (tracks << resolution)*heads*sizeof(entry);
|
||||||
int epos = 0;
|
int epos = 0;
|
||||||
UINT32 *precomp = global_alloc_array(UINT32, max_track_size);
|
UINT32 *precomp = global_alloc_array(UINT32, max_track_size);
|
||||||
UINT8 *postcomp = global_alloc_array(UINT8, max_track_size*4 + 1000);
|
UINT8 *postcomp = global_alloc_array(UINT8, max_track_size*4 + 1000);
|
||||||
|
|
||||||
for(int track=0; track<tracks; track++)
|
for(int track=0; track <= (tracks-1) << 2; track += 4 >> resolution)
|
||||||
for(int head=0; head<heads; head++) {
|
for(int head=0; head<heads; head++) {
|
||||||
int tsize = image->get_track_size(track, head);
|
int tsize = image->get_track_size(track >> 2, head, track & 3);
|
||||||
if(!tsize) {
|
if(!tsize) {
|
||||||
epos++;
|
epos++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(precomp, image->get_buffer(track, head), tsize*4);
|
memcpy(precomp, image->get_buffer(track >> 2, head, track & 3), tsize*4);
|
||||||
for(int j=0; j<tsize-1; j++)
|
for(int j=0; j<tsize-1; j++)
|
||||||
precomp[j] = (precomp[j] & floppy_image::MG_MASK) |
|
precomp[j] = (precomp[j] & floppy_image::MG_MASK) |
|
||||||
((precomp[j+1] & floppy_image::TIME_MASK) -
|
((precomp[j+1] & floppy_image::TIME_MASK) -
|
||||||
@ -206,14 +212,14 @@ bool mfi_format::save(io_generic *io, floppy_image *image)
|
|||||||
entries[epos].offset = pos;
|
entries[epos].offset = pos;
|
||||||
entries[epos].uncompressed_size = tsize*4;
|
entries[epos].uncompressed_size = tsize*4;
|
||||||
entries[epos].compressed_size = csize;
|
entries[epos].compressed_size = csize;
|
||||||
entries[epos].write_splice = image->get_write_splice_position(track, head);
|
entries[epos].write_splice = image->get_write_splice_position(track >> 2, head, track & 3);
|
||||||
epos++;
|
epos++;
|
||||||
|
|
||||||
io_generic_write(io, postcomp, pos, csize);
|
io_generic_write(io, postcomp, pos, csize);
|
||||||
pos += csize;
|
pos += csize;
|
||||||
}
|
}
|
||||||
|
|
||||||
io_generic_write(io, entries, sizeof(header), tracks*heads*sizeof(entry));
|
io_generic_write(io, entries, sizeof(header), (tracks << resolution)*heads*sizeof(entry));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ private:
|
|||||||
MG_A = (0 << MG_SHIFT),
|
MG_A = (0 << MG_SHIFT),
|
||||||
MG_B = (1 << MG_SHIFT),
|
MG_B = (1 << MG_SHIFT),
|
||||||
MG_N = (2 << MG_SHIFT),
|
MG_N = (2 << MG_SHIFT),
|
||||||
MG_D = (3 << MG_SHIFT)
|
MG_D = (3 << MG_SHIFT),
|
||||||
|
|
||||||
|
RESOLUTION_SHIFT = 30,
|
||||||
|
CYLINDER_MASK = 0x3fffffff
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char sign[16];
|
static const char sign[16];
|
||||||
|
Loading…
Reference in New Issue
Block a user