Sync with MESS, OG's work credited in MESS already (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2012-01-14 13:48:41 +00:00
parent fda11532bf
commit b12f0240a8
6 changed files with 484 additions and 31 deletions

View File

@ -99,7 +99,8 @@
#include <stdio.h>
#include <assert.h>
#include "formats/ap_dsk35.h"
#include "emu.h"
#include "ap_dsk35.h"
struct apple35_tag
{
@ -1185,3 +1186,297 @@ LEGACY_FLOPPY_OPTIONS_START( apple35_iigs )
SECTOR_LENGTH([512])
FIRST_SECTOR_ID([0]))
LEGACY_FLOPPY_OPTIONS_END
dc42_format::dc42_format() : floppy_image_format_t()
{
}
const char *dc42_format::name() const
{
return "dc42";
}
const char *dc42_format::description() const
{
return "DiskCopy 4.2 image";
}
const char *dc42_format::extensions() const
{
return "dc42";
}
bool dc42_format::supports_save() const
{
return true;
}
int dc42_format::identify(io_generic *io, UINT32 form_factor)
{
UINT8 h[0x54];
int size = io_generic_size(io);
if(size < 0x54)
return 0;
io_generic_read(io, h, 0, 0x54);
int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43];
int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47];
return dsize > 0 && tsize >= 0 && size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0 ? 100 : 0;
}
const floppy_image_format_t::desc_e dc42_format::mac_gcr[] = {
{ SECTOR_LOOP_START, 0, -1 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xd5aa96, 24 },
{ CRC_MACHEAD_START, 0 },
{ TRACK_ID_GCR6 },
{ SECTOR_ID_GCR6 },
{ TRACK_HEAD_ID_GCR6 },
{ SECTOR_INFO_GCR6 },
{ CRC_END, 0 },
{ CRC, 0 },
{ RAWBITS, 0xdeaaff, 24 },
{ RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 },
{ RAWBITS, 0xd5aaad, 24 },
{ SECTOR_ID_GCR6 },
{ SECTOR_DATA_MAC, -1 },
{ RAWBITS, 0xdeaaff, 24 },
{ RAWBITS, 0xff, 8 },
{ SECTOR_LOOP_END },
{ END },
};
bool dc42_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
UINT8 h[0x54];
io_generic_read(io, h, 0, 0x54);
int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43];
int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47];
UINT8 encoding = h[0x50];
UINT8 format = h[0x51];
if((encoding != 0x00 || format != 0x02) && (encoding != 0x01 || format != 0x22)) {
logerror("dc42: Unsupported encoding/format combination %02x\%02x\n", encoding, format);
return false;
}
UINT8 sector_data[(512+12)*12];
memset(sector_data, 0, sizeof(sector_data));
desc_s sectors[12];
int pos_data = 0x54;
int pos_tag = 0x54+dsize;
int head_count = encoding == 1 ? 2 : 1;
for(int track=0; track < 80; track++) {
for(int head=0; head < head_count; head++) {
int ns = 12 - (track/16);
int si = 0;
for(int i=0; i<ns; i++) {
UINT8 *data = sector_data + (512+12)*i;
sectors[si].data = data;
sectors[si].size = 512+12;
sectors[si].sector_id = i;
sectors[si].sector_info = format;
if(tsize) {
io_generic_read(io, data, pos_tag, 12);
pos_tag += 12;
}
io_generic_read(io, data+12, pos_data, 512);
pos_data += 512;
si = (si + 2) % ns;
if(si == 0)
si++;
}
generate_track(mac_gcr, track, head, sectors, ns, 6208*ns, image);
}
}
return true;
}
UINT8 dc42_format::gb(const UINT8 *buf, int ts, int &pos, int &wrap)
{
UINT8 v = 0;
int w1 = wrap;
while(wrap != w1+2 && !(v & 0x80)) {
v = v << 1 | ((buf[pos >> 3] >> (7-(pos & 7))) & 1);
pos++;
if(pos == ts) {
pos = 0;
wrap++;
}
}
return v;
}
void dc42_format::update_chk(const UINT8 *data, int size, UINT32 &chk)
{
for(int i=0; i<size; i+=2) {
chk += (data[i] << 8) | data[i+1];
chk = (chk >> 1) | (chk << 31);
}
}
bool dc42_format::save(io_generic *io, floppy_image *image)
{
int g_tracks, g_heads;
image->get_actual_geometry(g_tracks, g_heads);
if(g_heads == 0)
g_heads = 1;
UINT8 h[0x54];
memset(h, 0, 0x54);
strcpy((char *)h+1, "Unnamed");
h[0] = 7;
int nsect = 16*(12+11+10+9+8)*g_heads;
UINT32 dsize = nsect*512;
UINT32 tsize = nsect*12;
h[0x40] = dsize >> 24;
h[0x41] = dsize >> 16;
h[0x42] = dsize >> 8;
h[0x43] = dsize;
h[0x44] = tsize >> 24;
h[0x45] = tsize >> 16;
h[0x46] = tsize >> 8;
h[0x47] = tsize;
h[0x50] = g_heads == 2 ? 0x01 : 0x00;
h[0x51] = g_heads == 2 ? 0x22 : 0x02;
h[0x52] = 0x01;
h[0x53] = 0x00;
UINT32 dchk = 0;
UINT32 tchk = 0;
int pos_data = 0x54;
int pos_tag = 0x54+dsize;
for(int track=0; track < 80; track++) {
for(int head=0; head < g_heads; head++) {
UINT8 sectdata[(512+12)*12];
memset(sectdata, 0, sizeof(sectdata));
int nsect = 12-(track/16);
UINT8 buf[13000];
int ts;
generate_bitstream_from_track(track, head, 200000000/(6208*nsect), buf, ts, image);
int pos = 0;
int wrap = 0;
int hb = 0;
for(;;) {
UINT8 v = gb(buf, ts, pos, wrap);
if(v == 0xff)
hb = 1;
else if(hb == 1 && v == 0xd5)
hb = 2;
else if(hb == 2 && v == 0xaa)
hb = 3;
else if(hb == 3 && v == 0x96)
hb = 4;
else
hb = 0;
if(hb == 4) {
UINT8 h[7];
for(int i=0; i<7; i++)
h[i] = gb(buf, ts, pos, wrap);
UINT8 v2 = gcr6bw_tb[h[2]];
UINT8 v3 = gcr6bw_tb[h[3]];
UINT8 tr = gcr6bw_tb[h[0]] | (v2 & 1 ? 0x40 : 0x00);
UINT8 se = gcr6bw_tb[h[1]];
UINT8 si = v2 & 0x20 ? 1 : 0;
// UINT8 ds = v3 & 0x20 ? 1 : 0;
// UINT8 fmt = v3 & 0x1f;
UINT8 c1 = (tr^se^v2^v3) & 0x3f;
UINT8 chk = gcr6bw_tb[h[4]];
if(chk == c1 && tr == track && si == head && se < nsect) {
int opos = pos;
int owrap = wrap;
hb = 0;
for(int i=0; i<20 && hb != 4; i++) {
v = gb(buf, ts, pos, wrap);
if(v == 0xff)
hb = 1;
else if(hb == 1 && v == 0xd5)
hb = 2;
else if(hb == 2 && v == 0xaa)
hb = 3;
else if(hb == 3 && v == 0xad)
hb = 4;
else
hb = 0;
}
if(hb == 4) {
UINT8 *dest = sectdata+(512+12)*se;
gb(buf, ts, pos, wrap); // Ignore the sector byte
UINT8 ca = 0, cb = 0, cc = 0;
for(int i=0; i<522/3+1; i++) {
UINT8 e0 = gb(buf, ts, pos, wrap);
UINT8 e1 = gb(buf, ts, pos, wrap);
UINT8 e2 = gb(buf, ts, pos, wrap);
UINT8 e3 = i == 522/3 ? 0x96 : gb(buf, ts, pos, wrap);
UINT8 va, vb, vc;
gcr6_decode(e0, e1, e2, e3, va, vb, vc);
cc = (cc << 1) | (cc >> 7);
va = va ^ cc;
int suma = ca + va + (cc & 1);
ca = suma;
vb = vb ^ ca;
int sumb = cb + vb + (suma >> 8);
cb = sumb;
vc = vc ^ cb;
cc = cc + vc + (sumb >> 8);
*dest++ = va;
*dest++ = vb;
if(i != 522/3)
*dest++ = vc;
}
} else {
pos = opos;
wrap = owrap;
}
}
hb = 0;
}
if(wrap)
break;
}
for(int i=0; i<nsect; i++) {
UINT8 *data = sectdata + (512+12)*i;
io_generic_write(io, data, pos_tag, 12);
io_generic_write(io, data+12, pos_data, 512);
pos_tag += 12;
pos_data += 512;
if(track || head || i)
update_chk(data, 12, tchk);
update_chk(data+12, 512, dchk);
}
}
}
h[0x48] = dchk >> 24;
h[0x49] = dchk >> 16;
h[0x4a] = dchk >> 8;
h[0x4b] = dchk;
h[0x4c] = tchk >> 24;
h[0x4d] = tchk >> 16;
h[0x4e] = tchk >> 8;
h[0x4f] = tchk;
io_generic_write(io, h, 0, 0x54);
return true;
}
const floppy_format_type FLOPPY_DC42_FORMAT = &floppy_image_format_creator<dc42_format>;

View File

@ -21,5 +21,27 @@ int apple35_sectors_per_track(floppy_image_legacy *image, int track);
LEGACY_FLOPPY_OPTIONS_EXTERN(apple35_mac);
LEGACY_FLOPPY_OPTIONS_EXTERN(apple35_iigs);
class dc42_format : public floppy_image_format_t
{
public:
dc42_format();
virtual int identify(io_generic *io, UINT32 form_factor);
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
virtual bool supports_save() const;
private:
static const desc_e mac_gcr[];
UINT8 gb(const UINT8 *buf, int ts, int &pos, int &wrap);
void update_chk(const UINT8 *data, int size, UINT32 &chk);
};
extern const floppy_format_type FLOPPY_DC42_FORMAT;
#endif /* AP_DSK35_H */

View File

@ -1034,6 +1034,7 @@ bool floppy_image_format_t::type_no_data(int type) const
{
return type == CRC_CCITT_START ||
type == CRC_AMIGA_START ||
type == CRC_MACHEAD_START ||
type == CRC_END ||
type == SECTOR_LOOP_START ||
type == SECTOR_LOOP_END ||
@ -1062,6 +1063,9 @@ void floppy_image_format_t::collect_crcs(const desc_e *desc, gen_crc_info *crcs)
case CRC_AMIGA_START:
crcs[desc[i].p1].type = CRC_AMIGA;
break;
case CRC_MACHEAD_START:
crcs[desc[i].p1].type = CRC_MACHEAD;
break;
}
for(int i=0; desc[i].type != END; i++)
@ -1077,6 +1081,7 @@ int floppy_image_format_t::crc_cells_size(int type) const
switch(type) {
case CRC_CCITT: return 32;
case CRC_AMIGA: return 64;
case CRC_MACHEAD: return 8;
default: return 0;
}
}
@ -1086,6 +1091,14 @@ bool floppy_image_format_t::bit_r(const UINT32 *buffer, int offset)
return (buffer[offset] & floppy_image::MG_MASK) == MG_1;
}
UINT32 floppy_image_format_t::bitn_r(const UINT32 *buffer, int offset, int count)
{
UINT32 r = 0;
for(int i=0; i<count; i++)
r = (r << 1) | bit_r(buffer, offset+i);
return r;
}
void floppy_image_format_t::bit_w(UINT32 *buffer, int offset, bool val, UINT32 size)
{
buffer[offset] = (val ? MG_1 : MG_0) | size;
@ -1151,6 +1164,15 @@ void floppy_image_format_t::fixup_crc_ccitt(UINT32 *buffer, const gen_crc_info *
mfm_w(buffer, offset, 16, calc_crc_ccitt(buffer, crc->start, crc->end));
}
void floppy_image_format_t::fixup_crc_machead(UINT32 *buffer, const gen_crc_info *crc)
{
UINT8 v = 0;
for(int o = crc->start; o < crc->end; o+=8)
v = v ^ gcr6bw_tb[bitn_r(buffer, o, 8)];
int offset = crc->write;
raw_w(buffer, offset, 8, gcr6fw_tb[v]);
}
void floppy_image_format_t::fixup_crcs(UINT32 *buffer, gen_crc_info *crcs)
{
for(int i=0; i != MAX_CRC_COUNT; i++)
@ -1158,6 +1180,7 @@ void floppy_image_format_t::fixup_crcs(UINT32 *buffer, gen_crc_info *crcs)
switch(crcs[i].type) {
case CRC_AMIGA: fixup_crc_amiga(buffer, crcs+i); break;
case CRC_CCITT: fixup_crc_ccitt(buffer, crcs+i); break;
case CRC_MACHEAD: fixup_crc_machead(buffer, crcs+i); break;
}
if(crcs[i].fixup_mfm_clock) {
int offset = crcs[i].write + crc_cells_size(crcs[i].type);
@ -1167,6 +1190,28 @@ void floppy_image_format_t::fixup_crcs(UINT32 *buffer, gen_crc_info *crcs)
}
}
UINT32 floppy_image_format_t::gcr6_encode(UINT8 va, UINT8 vb, UINT8 vc)
{
UINT32 r;
r = gcr6fw_tb[((va >> 2) & 0x30) | ((vb >> 4) & 0x0c) | ((vc >> 6) & 0x03)] << 24;
r |= gcr6fw_tb[va & 0x3f] << 16;
r |= gcr6fw_tb[vb & 0x3f] << 8;
r |= gcr6fw_tb[vc & 0x3f];
return r;
}
void floppy_image_format_t::gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc)
{
e0 = gcr6bw_tb[e0];
e1 = gcr6bw_tb[e1];
e2 = gcr6bw_tb[e2];
e3 = gcr6bw_tb[e3];
va = ((e0 << 2) & 0xc0) | e1;
vb = ((e0 << 4) & 0xc0) | e2;
vc = ((e0 << 6) & 0xc0) | e3;
}
int floppy_image_format_t::calc_sector_index(int num, int interleave, int skew, int total_sectors, int track_head)
{
int i = 0;
@ -1227,14 +1272,26 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
mfm_w(buffer, offset, 8, track);
break;
case TRACK_ID_GCR6:
raw_w(buffer, offset, 8, gcr6fw_tb[track & 0x3f]);
break;
case HEAD_ID:
mfm_w(buffer, offset, 8, head);
break;
case TRACK_HEAD_ID_GCR6:
raw_w(buffer, offset, 8, gcr6fw_tb[(track & 0x40 ? 1 : 0) | (head ? 0x20 : 0)]);
break;
case SECTOR_ID:
mfm_w(buffer, offset, 8, sect[sector_idx].sector_id);
break;
case SECTOR_ID_GCR6:
raw_w(buffer, offset, 8, gcr6fw_tb[sect[sector_idx].sector_id]);
break;
case SIZE_ID: {
int size = sect[sector_idx].size;
int id;
@ -1243,6 +1300,10 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
break;
}
case SECTOR_INFO_GCR6:
raw_w(buffer, offset, 8, gcr6fw_tb[sect[sector_idx].sector_info]);
break;
case OFFSET_ID_O:
mfm_half_w(buffer, offset, 7, track*2+head);
break;
@ -1272,7 +1333,7 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
sector_loop_start = index;
sector_idx = desc[index].p1;
sector_cnt = sector_idx;
sector_limit = desc[index].p2;
sector_limit = desc[index].p2 == -1 ? sector_idx+sect_count-1 : desc[index].p2;
sector_idx = calc_sector_index(sector_cnt,sector_interleave,sector_skew,sector_limit+1,track*2 + head);
break;
@ -1292,6 +1353,7 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
case CRC_AMIGA_START:
case CRC_CCITT_START:
case CRC_MACHEAD_START:
crcs[desc[index].p1].start = offset;
break;
@ -1325,6 +1387,34 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
break;
}
case SECTOR_DATA_MAC: {
const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
const UINT8 *data = csect->data;
int size = csect->size;
UINT8 ca = 0, cb = 0, cc = 0;
for(int i=0; i < size; i+=3) {
int dt = size-i;
UINT8 va = data[i];
UINT8 vb = dt > 1 ? data[i+1] : 0;
UINT8 vc = dt > 2 ? data[i+2] : 0;
cc = (cc << 1) | (cc >> 7);
int suma = ca + va + (cc & 1);
ca = suma;
va = va ^ cc;
int sumb = cb + vb + (suma >> 8);
cb = sumb;
vb = vb ^ ca;
cc = cc + vc + (sumb >> 8);
vc = vc ^ cb;
int nb = dt > 2 ? 32 : dt > 1 ? 24 : 16;
raw_w(buffer, offset, nb, gcr6_encode(va, vb, vc) >> (32-nb));
}
raw_w(buffer, offset, 32, gcr6_encode(ca, cb, cc));
break;
}
default:
printf("%d.%d.%d (%d) unhandled\n", desc[index].type, desc[index].p1, desc[index].p2, index);
break;
@ -1467,6 +1557,39 @@ void floppy_image_format_t::generate_track_from_levels(int track, int head, UINT
image->set_write_splice_position(track, head, splice_angular_pos);
}
const UINT8 floppy_image_format_t::gcr6fw_tb[0x40] =
{
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
const UINT8 floppy_image_format_t::gcr6bw_tb[0x100] =
{
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x04, 0x05, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x00, 0x00, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1c, 0x1d, 0x1e,
0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x2a, 0x2b, 0x00, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
0x00, 0x00, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
};
// Atari ST Fastcopy Pro layouts
#define SECTOR_42_HEADER(cid) \

View File

@ -264,9 +264,13 @@ protected:
RAW, // One 16 bits word in p1 to be written raw, msb first, repeated p2 times
RAWBITS, // A value of p2 bits in p1 to be copied as-is, msb first
TRACK_ID, // Track id byte, mfm-encoded
TRACK_ID_GCR6, // Track id low 6 bits, gcr6-encoded
HEAD_ID, // Head id byte, mfm-encoded
TRACK_HEAD_ID_GCR6, // Track id 7th bit + head, gc6-encoded
SECTOR_ID, // Sector id byte, mfm-encoded
SECTOR_ID_GCR6, // Sector id byte, gcr6-encoded
SIZE_ID, // Sector size code on one byte [log2(size/128)], mfm-encoded
SECTOR_INFO_GCR6, // Sector info byte, gcr6-encoded
OFFSET_ID_O, // Offset (track*2+head) byte, odd bits, mfm-encoded
OFFSET_ID_E, // Offset (track*2+head) byte, even bits, mfm-encoded
SECTOR_ID_O, // Sector id byte, odd bits, mfm-encoded
@ -277,9 +281,11 @@ protected:
SECTOR_DATA, // Sector data to mfm-encode, which in p1, -1 for the current one per the sector id
SECTOR_DATA_O, // Sector data to mfm-encode, odd bits only, which in p1, -1 for the current one per the sector id
SECTOR_DATA_E, // Sector data to mfm-encode, even bits only, which in p1, -1 for the current one per the sector id
SECTOR_DATA_MAC, // Transformed sector data + checksum, mac style, id in p1, -1 for the current one per the sector id
CRC_CCITT_START, // Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
CRC_AMIGA_START, // Start an amiga checksum calculation, p1 = crc id
CRC_MACHEAD_START, // Start of the mac gcr6 sector header checksum calculation (xor of pre-encode 6-bits values, gcr6-encoded)
CRC_END, // End the checksum, p1 = crc id
CRC, // Write a checksum in the apporpriate format, p1 = crc id
@ -293,6 +299,7 @@ protected:
int size; // Sector size, int bytes
const UINT8 *data; // Sector data
UINT8 sector_id; // Sector ID
UINT8 sector_info; // Sector free byte
};
@ -320,6 +327,8 @@ protected:
// Normalize the times in a cell buffer to sum up to 200000000
void normalize_times(UINT32 *buffer, int bitlen);
// Some conversion tables
static const UINT8 gcr6fw_tb[0x40], gcr6bw_tb[0x100];
// Some useful descriptions shared by multiple formats
@ -414,14 +423,17 @@ protected:
void get_track_data_mfm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, UINT8 *sectdata);
bool bit_r(const UINT32 *buffer, int offset);
UINT32 bitn_r(const UINT32 *buffer, int offset, int count);
void bit_w(UINT32 *buffer, int offset, bool val, UINT32 size = 1000);
UINT16 calc_crc_ccitt(const UINT32 *buffer, int start, int end);
void raw_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
void mfm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
void mfm_half_w(UINT32 *buffer, int &offset, int start_bit, UINT32 val, UINT32 size = 1000);
UINT32 gcr6_encode(UINT8 va, UINT8 vb, UINT8 vc);
void gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc);
private:
enum { CRC_NONE, CRC_AMIGA, CRC_CCITT };
enum { CRC_NONE, CRC_AMIGA, CRC_CCITT, CRC_MACHEAD };
enum { MAX_CRC_COUNT = 64 };
struct gen_crc_info {
int type, start, end, write;
@ -434,6 +446,7 @@ private:
int crc_cells_size(int type) const;
void fixup_crc_amiga(UINT32 *buffer, const gen_crc_info *crc);
void fixup_crc_ccitt(UINT32 *buffer, const gen_crc_info *crc);
void fixup_crc_machead(UINT32 *buffer, const gen_crc_info *crc);
void fixup_crcs(UINT32 *buffer, gen_crc_info *crcs);
void collect_crcs(const desc_e *desc, gen_crc_info *crcs);