mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
Sync with MESS (no whatsnew)
This commit is contained in:
parent
f5ffd68141
commit
e18eceb3f1
@ -613,31 +613,32 @@ const floppy_image_format_t::desc_e a2_16sect_format::mac_gcr[] = {
|
||||
|
||||
bool a2_16sect_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
{
|
||||
/* TODO: rewrite me properly
|
||||
UINT8 sector_data[(256)*16];
|
||||
memset(sector_data, 0, sizeof(sector_data));
|
||||
|
||||
UINT8 sector_data[(256)*16];
|
||||
memset(sector_data, 0, sizeof(sector_data));
|
||||
desc_s sectors[16];
|
||||
int format = 0;
|
||||
int pos_data = 0;
|
||||
|
||||
desc_s sectors[16];
|
||||
int format = 0;
|
||||
int pos_data = 0;
|
||||
int head_count = 1;
|
||||
|
||||
int head_count = 1;
|
||||
|
||||
for(int track=0; track < 35; track++) {
|
||||
for(int head=0; head < head_count; head++) {
|
||||
for(int si=0; si<16; si++) {
|
||||
UINT8 *data = sector_data + (256)*si;
|
||||
sectors[si].data = data;
|
||||
sectors[si].size = 256;
|
||||
sectors[si].sector_id = si;
|
||||
sectors[si].sector_info = format;
|
||||
io_generic_read(io, data, pos_data, 256);
|
||||
pos_data += 256;
|
||||
}
|
||||
generate_track(mac_gcr, track, head, sectors, 16, 3104*16, image);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
for(int track=0; track < 35; track++) {
|
||||
for(int head=0; head < head_count; head++) {
|
||||
for(int si=0; si<16; si++) {
|
||||
UINT8 *data = sector_data + (256)*si;
|
||||
sectors[si].data = data;
|
||||
sectors[si].size = 256;
|
||||
sectors[si].sector_id = si;
|
||||
sectors[si].sector_info = format;
|
||||
io_generic_read(io, data, pos_data, 256);
|
||||
pos_data += 256;
|
||||
}
|
||||
generate_track(mac_gcr, track, head, sectors, 16, 3104*16, image);
|
||||
}
|
||||
}
|
||||
return true;*/
|
||||
return false; // I hope that throws an error...
|
||||
}
|
||||
|
||||
UINT8 a2_16sect_format::gb(const UINT8 *buf, int ts, int &pos, int &wrap)
|
||||
@ -664,10 +665,15 @@ bool a2_16sect_format::save(io_generic *io, floppy_image *image)
|
||||
int g_tracks, g_heads;
|
||||
int visualgrid[16][35]; // visualizer grid, cleared/initialized below
|
||||
#define NOTFOUND 0
|
||||
// address mark was found
|
||||
#define ADDRFOUND 1
|
||||
// address checksum is good
|
||||
#define ADDRGOOD 2
|
||||
// data mark was found (requires addrfound and sane values)
|
||||
#define DATAFOUND 4
|
||||
// data checksum is good
|
||||
#define DATAGOOD 8
|
||||
// data postamble is good
|
||||
#define DATAPOST 16
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 35; j++) {
|
||||
@ -686,12 +692,14 @@ bool a2_16sect_format::save(io_generic *io, floppy_image *image)
|
||||
int nsect = 16;
|
||||
UINT8 buf[130000]; // originally 13000, multiread dfi disks need larger
|
||||
int ts;
|
||||
fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2);
|
||||
generate_bitstream_from_track(track, head, 200000000/(3104*nsect*1), buf, ts, image); // 3104 needs tweaking, *3 is 3x multiread from a dfi disk
|
||||
fprintf(stderr,"done.\n");
|
||||
//fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2);
|
||||
//~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected
|
||||
generate_bitstream_from_track(track, head, 200000000/(3104*nsect*3), buf, ts, image); // 3104 needs tweaking, *3 is 3x multiread from a dfi disk
|
||||
//fprintf(stderr,"done.\n");
|
||||
int pos = 0;
|
||||
int wrap = 0;
|
||||
int hb = 0;
|
||||
int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3
|
||||
for(;;) {
|
||||
UINT8 v = gb(buf, ts, pos, wrap);
|
||||
if(v == 0xff)
|
||||
@ -700,8 +708,10 @@ fprintf(stderr,"done.\n");
|
||||
hb = 2;
|
||||
else if(hb == 2 && v == 0xaa)
|
||||
hb = 3;
|
||||
else if(hb == 3 && v == 0x96)
|
||||
else if(hb == 3 && ((v == 0x96) || (v == 0xab))) { // 0x96 = dos 3.3/16sec, 0xab = dos 3.21 and below/13sec
|
||||
hb = 4;
|
||||
if (v == 0xab) dosver = 1;
|
||||
}
|
||||
else
|
||||
hb = 0;
|
||||
|
||||
@ -735,9 +745,13 @@ fprintf(stderr,"done.\n");
|
||||
else
|
||||
hb = 0;
|
||||
}
|
||||
if(hb == 4) {
|
||||
if((hb == 4)&&(dosver == 0)) {
|
||||
visualgrid[se][track/2] |= DATAFOUND;
|
||||
UINT8 *dest = sectdata+(256)*se;
|
||||
int prodos_translate[16] = {
|
||||
0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
|
||||
0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F
|
||||
};
|
||||
UINT8 *dest = sectdata+(256)*prodos_translate[se];
|
||||
UINT8 data[0x157];
|
||||
UINT32 dpost = 0;
|
||||
UINT8 c = 0;
|
||||
@ -766,22 +780,40 @@ fprintf(stderr,"done.\n");
|
||||
// now decode it into 256 bytes
|
||||
// but only write it if the bitfield of the track shows datagood is NOT set.
|
||||
// if it is set we don't want to overwrite a guaranteed good read with a bad one
|
||||
if ((visualgrid[se][track/2]&DATAGOOD)==0) {
|
||||
// TODO:
|
||||
// if the current read is good but the postamble isn't, write it in.
|
||||
// if the current read isn't good but the postamble is, its better than nothing.
|
||||
// if past read had a bad checksum or bad postamble...
|
||||
#ifndef USE_OLD_BEST_SECTOR_PRIORITY
|
||||
if (((visualgrid[se][track/2]&DATAGOOD)==0)||((visualgrid[se][track/2]&DATAPOST)==0)) {
|
||||
// if the current read is good, and postamble is good, write it in, no matter what.
|
||||
// if the current read is good and the current postamble is bad, write it in unless the postamble was good before
|
||||
// if the current read is bad and the current postamble is good and the previous read had neither good, write it in
|
||||
// if the current read isn't good and neither is the postamble but nothing better
|
||||
// has been written before, write it anyway.
|
||||
for(int i=0x56; i<0x156; i++) {
|
||||
UINT8 dv = data[i];
|
||||
*dest++ = dv;
|
||||
if ( ((data[0x156] == c) && (dpost&0xFFFF00)==0xDEAA00) ||
|
||||
(((data[0x156] == c) && (dpost&0xFFFF00)!=0xDEAA00) && ((visualgrid[se][track/2]&DATAPOST)==0)) ||
|
||||
(((data[0x156] != c) && (dpost&0xFFFF00)==0xDEAA00) && (((visualgrid[se][track/2]&DATAGOOD)==0)&&(visualgrid[se][track/2]&DATAPOST)==0)) ||
|
||||
(((data[0x156] != c) && (dpost&0xFFFF00)!=0xDEAA00) && (((visualgrid[se][track/2]&DATAGOOD)==0)&&(visualgrid[se][track/2]&DATAPOST)==0))
|
||||
) {
|
||||
for(int i=0x56; i<0x156; i++) {
|
||||
UINT8 dv = data[i];
|
||||
*dest++ = dv;
|
||||
}
|
||||
}
|
||||
}
|
||||
// do some checking
|
||||
if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00) {
|
||||
printf("Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD");
|
||||
#else
|
||||
if ((visualgrid[se][track/2]&DATAGOOD)==0) {
|
||||
for(int i=0x56; i<0x156; i++) {
|
||||
UINT8 dv = data[i];
|
||||
*dest++ = dv;
|
||||
}
|
||||
}
|
||||
else visualgrid[se][track/2] |= DATAGOOD;
|
||||
#endif
|
||||
// do some checking
|
||||
if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00)
|
||||
fprintf(stderr,"Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD");
|
||||
if (data[0x156] == c) visualgrid[se][track/2] |= DATAGOOD;
|
||||
if ((dpost&0xFFFF00)==0xDEAA00) visualgrid[se][track/2] |= DATAPOST;
|
||||
} else if ((hb == 4)&&(dosver == 1)) {
|
||||
fprintf(stderr,"ERROR: We don't handle dos sectors below 3.3 yet!\n");
|
||||
} else {
|
||||
pos = opos;
|
||||
wrap = owrap;
|
||||
@ -804,14 +836,14 @@ fprintf(stderr,"done.\n");
|
||||
for (int j = 0; j < 35; j++) {
|
||||
printf("T%2d: ",j);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (visualgrid[i][j] == NOTFOUND) printf("-NF-");
|
||||
if (visualgrid[i][j] == NOTFOUND) printf("-NF- ");
|
||||
else {
|
||||
if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" ");
|
||||
if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" ");
|
||||
if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" ");
|
||||
if (visualgrid[i][j] & DATAGOOD) printf("D"); else printf(" ");
|
||||
if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" ");
|
||||
}
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -31,10 +31,34 @@
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
/* DONE:
|
||||
* Support auto-identification heuristics for determining disk image speed,
|
||||
capture clock rate, and number of multireads per image.
|
||||
* TODO:
|
||||
* Scale captured data based on the guessed clock rate and samplerate to match
|
||||
the internal 200mhz representation
|
||||
* Handle 0xFF bytes properly
|
||||
* Correctly note exact index timing.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "dfi_dsk.h"
|
||||
#include <zlib.h>
|
||||
#define NUMBER_OF_MULTIREADS 1
|
||||
#define NUMBER_OF_MULTIREADS 3
|
||||
// threshholds for brickwall windowing
|
||||
//define MIN_CLOCKS 65
|
||||
#define MIN_CLOCKS 40
|
||||
//define MAX_CLOCKS 260
|
||||
#define MAX_CLOCKS 270
|
||||
#define MIN_THRESH (MIN_CLOCKS*(clock_rate/25000000))
|
||||
#define MAX_THRESH (MAX_CLOCKS*(clock_rate/25000000))
|
||||
// constants to help guess clockrate and rpm
|
||||
// constant is 25mhz / 6 revolutions per second (360rpm) = 4166667 +- 2.5%
|
||||
#define REV25_MIN 4062500
|
||||
#define REV25_MAX 4270833
|
||||
// define the following to show a histogram per track
|
||||
//define TRACK_HISTOGRAM 1
|
||||
#undef TRACK_HISTOGRAM
|
||||
|
||||
dfi_format::dfi_format() : floppy_image_format_t()
|
||||
{
|
||||
@ -64,6 +88,8 @@ int dfi_format::identify(io_generic *io, UINT32 form_factor)
|
||||
{
|
||||
char sign[4];
|
||||
io_generic_read(io, sign, 0, 4);
|
||||
if (memcmp(sign, "DFER", 4))
|
||||
fatalerror("Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n");
|
||||
return memcmp(sign, "DFE2", 4) ? 0 : 100;
|
||||
}
|
||||
|
||||
@ -72,8 +98,10 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
int size = io_generic_size(io);
|
||||
int pos = 4;
|
||||
UINT8 *data = 0;
|
||||
int data_size = 0;
|
||||
|
||||
int data_size = 0; // size of currently allocated array for a track
|
||||
int onerev_time = 0; // time for one revolution, used to guess clock and rpm for DFE2 files
|
||||
unsigned long clock_rate = 100000000; // sample clock rate in megahertz
|
||||
int rpm=360; // drive rpm
|
||||
while(pos < size) {
|
||||
UINT8 h[10];
|
||||
io_generic_read(io, h, pos, 10);
|
||||
@ -82,12 +110,15 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
// Ignore sector
|
||||
UINT32 tsize = (h[6] << 24) | (h[7] << 16) | (h[8] << 8) | h[9];
|
||||
|
||||
// if the position-so-far-in-file plus 10 (for the header) plus track size
|
||||
// is larger than the size of the file, free buffers and bail out
|
||||
if(pos+tsize+10 > size) {
|
||||
if(data)
|
||||
global_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
// reallocate the data array if it gets too small
|
||||
if(tsize > data_size) {
|
||||
if(data)
|
||||
global_free(data);
|
||||
@ -95,21 +126,26 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
data = global_alloc_array(UINT8, data_size);
|
||||
}
|
||||
|
||||
io_generic_read(io, data, pos+16, tsize);
|
||||
pos += tsize+10;
|
||||
tsize--; // Drop the extra 0x00 at the end
|
||||
pos += 10; // skip the header, we already read it
|
||||
io_generic_read(io, data, pos, tsize);
|
||||
pos += tsize; // for next time we read, increment to the beginning of next header
|
||||
|
||||
int index_time = 0;
|
||||
int index_count = 0;
|
||||
int total_time = 0;
|
||||
int index_time = 0; // what point the last index happened
|
||||
int index_count = 0; // number of index pulses per track
|
||||
int index_polarity = 0; // current polarity of index
|
||||
int total_time = 0; // total sampled time per track
|
||||
for(int i=0; i<tsize; i++) {
|
||||
UINT8 v = data[i];
|
||||
if (v == 0xFF) { fprintf(stderr,"DFI stream contained a 0xFF at t%d, position%d, THIS SHOULD NEVER HAPPEN!\n", track, i); exit(1); }
|
||||
if((v & 0x7f) == 0x7f)
|
||||
total_time += 0x7f;
|
||||
else {
|
||||
total_time += v & 0x7f;
|
||||
if((v & 0x80) && (index_count<NUMBER_OF_MULTIREADS)) {
|
||||
index_time = total_time;///NUMBER_OF_MULTIREADS;
|
||||
if((v & 0x80)==0) total_time += v & 0x7f;
|
||||
if(v & 0x80) {
|
||||
index_time = total_time;
|
||||
if (onerev_time == 0) onerev_time = total_time;
|
||||
//index_polarity ^= 1;
|
||||
//index_count =+ index_polarity;
|
||||
index_count++;
|
||||
}
|
||||
}
|
||||
@ -117,6 +153,32 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
|
||||
if(!track && !head)
|
||||
fprintf(stderr, "%02d:%d tt=%10d it=%10d\n", track, head, total_time, index_time);
|
||||
if(!track && !head) {
|
||||
fprintf(stderr, "index_count: %d, onerev_time: %d\n", index_count, onerev_time);
|
||||
if ((onerev_time > REV25_MIN) && (onerev_time < REV25_MAX)) {
|
||||
fprintf(stderr, "Guess: speed: 360rpm, clock 25MHz\n");
|
||||
clock_rate = 25000000; rpm = 360;
|
||||
} else if ((onerev_time > REV25_MIN*1.2) && (onerev_time < REV25_MAX*1.2)) {
|
||||
fprintf(stderr, "Guess: speed: 300rpm, clock 25MHz\n");
|
||||
clock_rate = 25000000; rpm = 300;
|
||||
} else if ((onerev_time > REV25_MIN*2) && (onerev_time < REV25_MAX*2)) {
|
||||
fprintf(stderr, "Guess: speed: 360rpm, clock 50MHz\n");
|
||||
clock_rate = 50000000; rpm = 360;
|
||||
} else if ((onerev_time > (REV25_MIN*2)*1.2) && (onerev_time < (REV25_MAX*2)*1.2)) {
|
||||
fprintf(stderr, "Guess: speed: 300rpm, clock 50MHz\n");
|
||||
clock_rate = 50000000; rpm = 300;
|
||||
} else if ((onerev_time > REV25_MIN*4) && (onerev_time < REV25_MAX*4)) {
|
||||
fprintf(stderr, "Guess: speed: 360rpm, clock 100MHz\n");
|
||||
clock_rate = 100000000; rpm = 360;
|
||||
} else if ((onerev_time > (REV25_MIN*4)*1.2) && (onerev_time < (REV25_MAX*4)*1.2)) {
|
||||
fprintf(stderr, "Guess: speed: 300rpm, clock 100MHz\n");
|
||||
clock_rate = 100000000; rpm = 300;
|
||||
} else
|
||||
fprintf(stderr, "WARNING: Cannot Guess Speed! Assuming 360rpm, 100Mhz clock!\n");
|
||||
fprintf(stderr,"Actual rpm based on index: %f\n", ((double)clock_rate/(double)onerev_time)*60);
|
||||
}
|
||||
|
||||
rpm += 0; // HACK: prevent GCC 4.6+ from warning "variable set but unused"
|
||||
|
||||
if(!index_time)
|
||||
index_time = total_time;
|
||||
@ -124,26 +186,68 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
image->set_track_size(track, head, tsize);
|
||||
|
||||
int cur_time = 0;
|
||||
int prev_time = 0;
|
||||
#ifdef TRACK_HISTOGRAM
|
||||
// histogram
|
||||
int time_buckets[4096];
|
||||
for (int i = 0; i < 4096; i++)
|
||||
time_buckets[i] = 0;
|
||||
#endif
|
||||
index_count = 0;
|
||||
int index_polarity = 0;
|
||||
index_polarity = 0;
|
||||
UINT32 mg = floppy_image::MG_A;
|
||||
UINT32 *buf = image->get_buffer(track, head);
|
||||
int tpos = 0;
|
||||
buf[tpos++] = mg;
|
||||
for(int i=0; i<tsize; i++) {
|
||||
UINT8 v = data[i];
|
||||
if((v & 0x7f) == 0x7f) // 0x7F or 0xFF: no transition, but a carry
|
||||
cur_time += 0x7f;
|
||||
if((v & 0x7f) == 0x7f) {// 0x7F or 0xFF: no transition, but a carry
|
||||
cur_time += 0x7f; // should this be done if v&80 is also set?
|
||||
if(v & 0x80) { // 0xFF an index, note the index (TODO: actually do this!) and do not add number
|
||||
index_polarity ^= 1;
|
||||
index_count += index_polarity;
|
||||
//if (index_count == NUMBER_OF_MULTIREADS) break;
|
||||
}
|
||||
}
|
||||
else if((v & 0x80) == 0) { // 0x00-0x7E: not an index or carry, add the number and store transition
|
||||
cur_time += v & 0x7f;
|
||||
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
|
||||
buf[tpos++] = mg | UINT32(200000000ULL*cur_time/index_time);
|
||||
int trans_time = cur_time - prev_time;
|
||||
#ifdef TRACK_HISTOGRAM
|
||||
time_buckets[(trans_time<4096)?trans_time:4095]++;
|
||||
#endif
|
||||
// cur_time and onerev_time need to be converted to something standard, so we'll stick with 300rpm at the standard 200mhz rate that mfi uses internally
|
||||
// TODO for 4/22/2012: ACTUALLY DO THIS RESCALING STEP
|
||||
// filter out spurious crap
|
||||
//if (trans_time <= MIN_THRESH) fprintf(stderr, "DFI: Throwing out short transition of length %d\n", trans_time);
|
||||
//if ((prev_time == 0) || ((trans_time > MIN_THRESH))) {
|
||||
if ((prev_time == 0) || ((trans_time > MIN_THRESH) && (trans_time <= MAX_THRESH))) {
|
||||
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
|
||||
buf[tpos++] = mg | UINT32((200000000ULL*cur_time)/index_time);
|
||||
prev_time = cur_time;
|
||||
}
|
||||
if (trans_time > MAX_THRESH) { // we probably missed a transition
|
||||
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
|
||||
if (((track%2)==0)&&(head==0)) fprintf(stderr,"missed transition, total time for transition is %d\n",trans_time);
|
||||
buf[tpos++] = mg | UINT32((200000000ULL*(cur_time-(trans_time/2)))/index_time); // generate imaginary transition at half period
|
||||
buf[tpos++] = mg | UINT32(200000000ULL*cur_time/index_time); // generate transition now
|
||||
prev_time = cur_time;
|
||||
}
|
||||
} else if(v & 0x80) { // 0x80-0xFF an index, note the index (TODO: actually do this!) and do not add number
|
||||
index_polarity ^= 1;
|
||||
index_count += index_polarity;
|
||||
if (index_count == NUMBER_OF_MULTIREADS) break;
|
||||
}
|
||||
}
|
||||
#ifdef TRACK_HISTOGRAM
|
||||
if (((track%2)==0)&&(head==0)) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
fprintf(stderr,"%4d:%4d ", i, time_buckets[i]);
|
||||
if (((i+1)%10)==0) fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
#endif
|
||||
index_count = 0;
|
||||
image->set_track_size(track, head, tpos);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user