mirror of
https://github.com/holub/mame
synced 2025-05-20 12:48:53 +03:00
floppy: Change the internal format to use magnetic cells. Temporarily
move the full-track pll bit extraction in the amiga fdc. [O. Galibert]
This commit is contained in:
parent
45ca548374
commit
19b0135c30
@ -61,7 +61,8 @@ public:
|
||||
void setup_unload_cb(unload_cb cb);
|
||||
void setup_index_pulse_cb(index_pulse_cb cb);
|
||||
|
||||
UINT8* get_buffer() { return m_image->get_buffer(m_cyl,m_ss ^ 1); }
|
||||
UINT32* get_buffer() { return m_image->get_buffer(m_cyl,m_ss ^ 1); }
|
||||
UINT32 get_len() { return m_image->get_track_size(m_cyl,m_ss ^ 1); }
|
||||
|
||||
void mon_w(int state);
|
||||
void index_func();
|
||||
|
@ -37,7 +37,7 @@ int adf_format::identify(floppy_image *image)
|
||||
UINT64 size = image->image_size();
|
||||
if ((size == 901120) || (size == 1802240))
|
||||
{
|
||||
return 100;
|
||||
return 50;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -78,13 +78,11 @@ bool adf_format::load(floppy_image *image)
|
||||
}
|
||||
|
||||
UINT8 *mfm = NULL;
|
||||
image->set_meta_data(80,2,300,(UINT16)253360);
|
||||
image->set_meta_data(80, 2);
|
||||
for(int track=0; track < 80; track++) {
|
||||
for(int side=0; side < 2; side++) {
|
||||
mfm = image->get_buffer(track,side);
|
||||
image->set_track_size(track, side, 16384);
|
||||
image->image_read(sectdata, (track*2 + side)*512*11, 512*11);
|
||||
generate_track(desc, track, side, sectors, 11, 100000, mfm);
|
||||
generate_track(desc, track, side, sectors, 11, 100000, image);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdcore.h"
|
||||
#include "ioprocs.h"
|
||||
#include "flopimg.h"
|
||||
@ -955,15 +956,32 @@ floppy_image::floppy_image(void *fp, const struct io_procs *procs, const floppy_
|
||||
else
|
||||
m_formats = fif;
|
||||
}
|
||||
|
||||
memset(cell_data, 0, sizeof(cell_data));
|
||||
memset(track_size, 0, sizeof(track_size));
|
||||
memset(track_alloc_size, 0, sizeof(track_alloc_size));
|
||||
}
|
||||
|
||||
floppy_image::~floppy_image()
|
||||
{
|
||||
if(m_formats)
|
||||
delete m_formats;
|
||||
close();
|
||||
}
|
||||
|
||||
void floppy_image::ensure_alloc(UINT16 track, UINT8 side)
|
||||
{
|
||||
int idx = (track << 1) + side;
|
||||
if(track_size[idx] > track_alloc_size[idx]) {
|
||||
UINT32 new_size = track_size[idx]*11/10;
|
||||
UINT32 *new_array = global_alloc_array(UINT32, new_size);
|
||||
if(track_alloc_size[idx]) {
|
||||
memcpy(new_array, cell_data[idx], track_alloc_size[idx]*4);
|
||||
global_free(cell_data[idx]);
|
||||
}
|
||||
cell_data[idx] = new_array;
|
||||
track_alloc_size[idx] = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_image::image_read(void *buffer, UINT64 offset, size_t length)
|
||||
{
|
||||
io_generic_read(&m_io, buffer, offset, length);
|
||||
@ -995,12 +1013,10 @@ void floppy_image::close()
|
||||
close_internal(TRUE);
|
||||
}
|
||||
|
||||
void floppy_image::set_meta_data(UINT16 tracks, UINT8 sides, UINT16 rpm, UINT16 bitrate)
|
||||
void floppy_image::set_meta_data(UINT16 _tracks, UINT8 _sides)
|
||||
{
|
||||
m_tracks = tracks;
|
||||
m_sides = sides;
|
||||
m_rpm = rpm;
|
||||
m_bitrate= bitrate;
|
||||
tracks = _tracks;
|
||||
sides = _sides;
|
||||
}
|
||||
|
||||
floppy_image_format_t *floppy_image::identify(int *best)
|
||||
@ -1181,9 +1197,9 @@ void floppy_image_format_t::fixup_crcs(UINT8 *buffer, gen_crc_info *crcs)
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, UINT8 *buffer)
|
||||
void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, floppy_image *image)
|
||||
{
|
||||
memset(buffer, 0, (track_size+7)/8);
|
||||
UINT8 *buffer = global_alloc_array_clear(UINT8, (track_size+7)/8);
|
||||
|
||||
gen_crc_info crcs[MAX_CRC_COUNT];
|
||||
collect_crcs(desc, crcs);
|
||||
@ -1317,5 +1333,47 @@ void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT
|
||||
}
|
||||
|
||||
fixup_crcs(buffer, crcs);
|
||||
|
||||
generate_track_from_bitstream(track, head, buffer, track_size, image);
|
||||
global_free(buffer);
|
||||
}
|
||||
|
||||
void floppy_image_format_t::normalize_times(UINT32 *buffer, int bitlen)
|
||||
{
|
||||
unsigned int total_sum = 0;
|
||||
for(int i=0; i != bitlen; i++)
|
||||
total_sum += buffer[i] & floppy_image::TIME_MASK;
|
||||
|
||||
unsigned int current_sum = 0;
|
||||
for(int i=0; i != bitlen; i++) {
|
||||
UINT32 time = buffer[i] & floppy_image::TIME_MASK;
|
||||
buffer[i] = (buffer[i] & floppy_image::MG_MASK) | (200000000ULL * current_sum / total_sum);
|
||||
current_sum += time;
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_image_format_t::generate_track_from_bitstream(UINT8 track, UINT8 head, const UINT8 *trackbuf, int track_size, floppy_image *image)
|
||||
{
|
||||
// Maximal number of cells which happens when the buffer is all 1
|
||||
image->set_track_size(track, head, track_size+1);
|
||||
UINT32 *dest = image->get_buffer(track, head);
|
||||
UINT32 *base = dest;
|
||||
|
||||
UINT32 cbit = floppy_image::MG_A;
|
||||
UINT32 count = 0;
|
||||
for(int i=0; i != track_size; i++)
|
||||
if(trackbuf[i >> 3] & (0x80 >> (i & 7))) {
|
||||
*dest++ = cbit | (count+1);
|
||||
cbit = cbit == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
|
||||
count = 1;
|
||||
} else
|
||||
count += 2;
|
||||
|
||||
if(count)
|
||||
*dest++ = cbit | count;
|
||||
|
||||
int size = dest - base;
|
||||
normalize_times(base, size);
|
||||
image->set_track_size(track, head, size);
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,9 @@ protected:
|
||||
// "sect" is a vector indexed by sector id
|
||||
// "track_size" is in _cells_, i.e. 100000 for a usual 2us-per-cell track at 300rpm
|
||||
|
||||
void generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, UINT8 *buffer);
|
||||
void generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, floppy_image *image);
|
||||
void generate_track_from_bitstream(UINT8 track, UINT8 head, const UINT8 *trackbuf, int track_size, floppy_image *image);
|
||||
void normalize_times(UINT32 *buffer, int bitlen);
|
||||
|
||||
private:
|
||||
enum { CRC_NONE, CRC_AMIGA, CRC_CCITT };
|
||||
@ -325,14 +327,38 @@ floppy_image_format_t *floppy_image_format_creator()
|
||||
|
||||
// ======================> floppy_image
|
||||
|
||||
#define MAX_FLOPPY_SIDES 2
|
||||
#define MAX_FLOPPY_TRACKS 84
|
||||
#define MAX_TRACK_DATA 16384
|
||||
|
||||
// class representing floppy image
|
||||
class floppy_image
|
||||
{
|
||||
public:
|
||||
// Internal format is close but not identical to the mfi format.
|
||||
//
|
||||
//
|
||||
// Track data consists of a series of 32-bits lsb-first values
|
||||
// representing magnetic cells. Bits 0-27 indicate the absolute
|
||||
// position of the start of the cell (not the size), and bits
|
||||
// 28-31 the type. Type can be:
|
||||
// - 0, MG_A -> Magnetic orientation A
|
||||
// - 1, MG_B -> Magnetic orientation B
|
||||
// - 2, MG_N -> Non-magnetized zone (neutral)
|
||||
// - 3, MG_D -> Damaged zone, reads as neutral but cannot be changed by writing
|
||||
//
|
||||
// The position is in angular units of 1/200,000,000th of a turn.
|
||||
// The last cell implicit end position is of course 200,000,000.
|
||||
//
|
||||
// Unformatted tracks are encoded as zero-size.
|
||||
|
||||
enum {
|
||||
TIME_MASK = 0x0fffffff,
|
||||
MG_MASK = 0xf0000000,
|
||||
MG_SHIFT = 28,
|
||||
|
||||
MG_A = (0 << MG_SHIFT),
|
||||
MG_B = (1 << MG_SHIFT),
|
||||
MG_N = (2 << MG_SHIFT),
|
||||
MG_D = (3 << MG_SHIFT)
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
floppy_image(void *fp, const struct io_procs *procs, const floppy_format_type *formats);
|
||||
virtual ~floppy_image();
|
||||
@ -343,23 +369,31 @@ public:
|
||||
UINT64 image_size();
|
||||
void close();
|
||||
|
||||
void set_meta_data(UINT16 tracks, UINT8 sides, UINT16 rpm, UINT16 bitrate);
|
||||
void set_track_size(UINT16 track, UINT8 side, UINT16 size) { m_track_size[(track << 1) + side] = size; }
|
||||
void set_meta_data(UINT16 tracks, UINT8 sides);
|
||||
void set_track_size(UINT16 track, UINT8 side, UINT32 size) { track_size[(track << 1) + side] = size; ensure_alloc(track, side); }
|
||||
floppy_image_format_t *identify(int *best);
|
||||
UINT8* get_buffer(UINT16 track, UINT8 side) { return m_native_data[(track << 1) + side]; }
|
||||
UINT16 get_track_size(UINT16 track, UINT8 side) { return m_track_size[(track << 1) + side]; }
|
||||
UINT32 *get_buffer(UINT16 track, UINT8 side) { return cell_data[(track << 1) + side]; }
|
||||
UINT32 get_track_size(UINT16 track, UINT8 side) { return track_size[(track << 1) + side]; }
|
||||
|
||||
private:
|
||||
enum {
|
||||
MAX_FLOPPY_SIDES = 2,
|
||||
MAX_FLOPPY_TRACKS = 84
|
||||
};
|
||||
|
||||
void close_internal(bool close_file);
|
||||
struct io_generic m_io;
|
||||
floppy_image_format_t *m_formats;
|
||||
UINT16 m_tracks;
|
||||
UINT8 m_sides;
|
||||
UINT16 m_rpm;
|
||||
UINT16 m_bitrate;
|
||||
|
||||
UINT8 m_native_data[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS][MAX_TRACK_DATA];
|
||||
UINT16 m_track_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS];
|
||||
UINT16 tracks;
|
||||
UINT8 sides;
|
||||
UINT16 rpm;
|
||||
|
||||
UINT32 *cell_data[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS];
|
||||
UINT32 track_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS];
|
||||
UINT32 track_alloc_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS];
|
||||
|
||||
void ensure_alloc(UINT16 track, UINT8 side);
|
||||
};
|
||||
|
||||
#endif /* FLOPIMG_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "emu.h"
|
||||
|
||||
#include "hxcmfm_dsk.h"
|
||||
|
||||
#define MFM_FORMAT_HEADER "HXCMFM"
|
||||
@ -67,22 +69,35 @@ bool mfm_format::load(floppy_image *image)
|
||||
{
|
||||
MFMIMG header;
|
||||
MFMTRACKIMG trackdesc;
|
||||
UINT8 *trackbuf = 0;
|
||||
int trackbuf_size = 0;
|
||||
|
||||
// read header
|
||||
image->image_read(&header,0, sizeof(header));
|
||||
|
||||
image->set_meta_data(header.number_of_track,header.number_of_side,header.floppyRPM,header.floppyBitRate);
|
||||
image->set_meta_data(header.number_of_track, header.number_of_side);
|
||||
|
||||
for(int track=0; track < header.number_of_track; track++) {
|
||||
for(int side=0; side < header.number_of_side; side++) {
|
||||
// read location of
|
||||
image->image_read(&trackdesc,(header.mfmtracklistoffset)+((( track << 1 ) + side)*sizeof(trackdesc)),sizeof(trackdesc));
|
||||
|
||||
image->set_track_size(track, side, trackdesc.mfmtracksize);
|
||||
if(trackdesc.mfmtracksize > trackbuf_size) {
|
||||
if(trackbuf)
|
||||
global_free(trackbuf);
|
||||
trackbuf_size = trackdesc.mfmtracksize;
|
||||
trackbuf = global_alloc_array(UINT8, trackbuf_size);
|
||||
}
|
||||
|
||||
// actual data read
|
||||
image->image_read(image->get_buffer(track,side), trackdesc.mfmtrackoffset, trackdesc.mfmtracksize);
|
||||
image->image_read(trackbuf, trackdesc.mfmtrackoffset, trackdesc.mfmtracksize);
|
||||
|
||||
generate_track_from_bitstream(track, side, trackbuf, trackdesc.mfmtracksize*8, image);
|
||||
}
|
||||
}
|
||||
if(trackbuf)
|
||||
global_free(trackbuf);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -89,41 +89,14 @@ int mfi_format::identify(floppy_image *image)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mfi_format::advance(const UINT32 *trackbuf, UINT32 &cur_cell, UINT32 cell_count, UINT32 time)
|
||||
{
|
||||
if(time >= 200000000) {
|
||||
cur_cell = cell_count;
|
||||
return;
|
||||
}
|
||||
|
||||
while(cur_cell != cell_count-1 && (trackbuf[cur_cell+1] & TIME_MASK) < time)
|
||||
cur_cell++;
|
||||
}
|
||||
|
||||
UINT32 mfi_format::get_next_edge(const UINT32 *trackbuf, UINT32 cur_cell, UINT32 cell_count)
|
||||
{
|
||||
if(cur_cell == cell_count)
|
||||
return 200000000;
|
||||
UINT32 cur_bit = trackbuf[cur_cell] & MG_MASK;
|
||||
cur_cell++;
|
||||
while(cur_cell != cell_count) {
|
||||
UINT32 next_bit = trackbuf[cur_cell] & MG_MASK;
|
||||
if(next_bit != cur_bit)
|
||||
break;
|
||||
}
|
||||
return cur_cell == cell_count ? 200000000 : trackbuf[cur_cell] & TIME_MASK;
|
||||
}
|
||||
|
||||
bool mfi_format::load(floppy_image *image)
|
||||
{
|
||||
header h;
|
||||
entry entries[84*2];
|
||||
image->image_read(&h, 0, sizeof(header));
|
||||
image->image_read(&entries, sizeof(header), h.cyl_count*h.head_count*sizeof(entry));
|
||||
image->set_meta_data(h.cyl_count, h.head_count, 300, (UINT16)253360);
|
||||
image->set_meta_data(h.cyl_count, h.head_count);
|
||||
|
||||
UINT32 *trackbuf = 0;
|
||||
int trackbuf_size = 0;
|
||||
UINT8 *compressed = 0;
|
||||
int compressed_size = 0;
|
||||
|
||||
@ -143,34 +116,16 @@ bool mfi_format::load(floppy_image *image)
|
||||
compressed = global_alloc_array(UINT8, compressed_size);
|
||||
}
|
||||
|
||||
if(ent->uncompressed_size > trackbuf_size) {
|
||||
if(trackbuf)
|
||||
global_free(trackbuf);
|
||||
trackbuf_size = ent->uncompressed_size;
|
||||
trackbuf = global_alloc_array(UINT32, trackbuf_size/4);
|
||||
}
|
||||
|
||||
image->image_read(compressed, ent->offset, ent->compressed_size);
|
||||
|
||||
unsigned int cell_count = ent->uncompressed_size/4;
|
||||
image->set_track_size(cyl, head, cell_count);
|
||||
UINT32 *trackbuf = image->get_buffer(cyl, head);
|
||||
|
||||
uLongf size = ent->uncompressed_size;
|
||||
if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK)
|
||||
return true;
|
||||
|
||||
UINT8 *mfm = image->get_buffer(cyl, head);
|
||||
image->set_track_size(cyl, head, 16384);
|
||||
memset(mfm, 0, 16384);
|
||||
int bit = 0;
|
||||
|
||||
// Extract the bits using a quick-n-dirty software pll
|
||||
// expecting mfm 2us data. Eventually the plls will end
|
||||
// up in the fdc simulations themselves.
|
||||
|
||||
// Neutral/damaged bits are not really taken into account
|
||||
|
||||
// Start by turning the cell times into absolute
|
||||
// positions, it's easier to use that way.
|
||||
|
||||
unsigned int cell_count = ent->uncompressed_size/4;
|
||||
UINT32 cur_time = 0;
|
||||
for(unsigned int i=0; i != cell_count; i++) {
|
||||
UINT32 next_cur_time = cur_time + (trackbuf[i] & TIME_MASK);
|
||||
@ -180,50 +135,12 @@ bool mfi_format::load(floppy_image *image)
|
||||
if(cur_time != 200000000)
|
||||
return true;
|
||||
|
||||
// Then pll the hell out of the bits
|
||||
|
||||
UINT32 cur_cell = 0;
|
||||
UINT32 pll_period = 2000;
|
||||
UINT32 pll_phase = 0;
|
||||
for(;;) {
|
||||
advance(trackbuf, cur_cell, cell_count, pll_phase);
|
||||
if(cur_cell == cell_count)
|
||||
break;
|
||||
|
||||
#if 0
|
||||
printf("%09d: (%d, %09d) - (%d, %09d) - (%d, %09d)\n",
|
||||
pll_phase,
|
||||
trackbuf[cur_cell] >> MG_SHIFT, trackbuf[cur_cell] & TIME_MASK,
|
||||
trackbuf[cur_cell+1] >> MG_SHIFT, trackbuf[cur_cell+1] & TIME_MASK,
|
||||
trackbuf[cur_cell+2] >> MG_SHIFT, trackbuf[cur_cell+2] & TIME_MASK);
|
||||
#endif
|
||||
|
||||
UINT32 next_edge = get_next_edge(trackbuf, cur_cell, cell_count);
|
||||
|
||||
if(next_edge > pll_phase + pll_period) {
|
||||
// free run, zero bit
|
||||
// printf("%09d: %4d - Free run\n", pll_phase, pll_period);
|
||||
pll_phase += pll_period;
|
||||
} else {
|
||||
// Transition in the window, one bit, adjust the period
|
||||
|
||||
mfm[bit >> 3] |= 0x80 >> (bit & 7);
|
||||
|
||||
INT32 delta = next_edge - (pll_phase + pll_period/2);
|
||||
// printf("%09d: %4d - Delta = %d\n", pll_phase, pll_period, delta);
|
||||
|
||||
// The deltas should be lowpassed, the amplification factor tuned...
|
||||
pll_period += delta/2;
|
||||
pll_phase += pll_period;
|
||||
}
|
||||
|
||||
bit++;
|
||||
}
|
||||
image->set_track_size(cyl, head, (bit+7)/8);
|
||||
|
||||
ent++;
|
||||
}
|
||||
|
||||
if(compressed)
|
||||
global_free(compressed);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,6 @@ private:
|
||||
struct entry {
|
||||
unsigned int offset, compressed_size, uncompressed_size;
|
||||
};
|
||||
|
||||
void advance(const UINT32 *trackbuf, UINT32 &cur_cell, UINT32 cell_count, UINT32 time);
|
||||
UINT32 get_next_edge(const UINT32 *trackbuf, UINT32 cur_cell, UINT32 cell_count);
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_MFI_FORMAT;
|
||||
|
Loading…
Reference in New Issue
Block a user