static void ratt_dos_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t header, csum, key, step, *dat = (uint32_t *)ti->dat; uint16_t sync; unsigned int i, nr_longs; nr_longs = (ti->len - 6) / 4; csum = header = be32toh(dat[nr_longs]); sync = be16toh(*(uint16_t *)&dat[nr_longs+1]); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, sync); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd_even, 32, ~header); key = 0xeff478edu; step = 0xbffb7e5eu; for (i = 0; i < nr_longs; i++) { tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd_even, 32, be32toh(dat[i]) + key); key += step; csum += be32toh(dat[i]); } tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd_even, 32, -csum); }
static void protec_longtrack_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4454); for (i = 0; i < 6000; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0x33); }
static void bat_longtrack_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x8945); for (i = 0; i < 6840; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); }
static void infogrames_longtrack_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0xa144); for (i = 0; i < 6550; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); }
static void crystals_of_arborea_longtrack_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0xa144); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 32, 0x524f4430); /* "ROD0" */ for (i = 0; i < 6550; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); }
static void gremlin_longtrack_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x41244124); for (i = 0; i < (ti->total_bits/16)-250; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); }
static void zoom_prot_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489 ); for (i = 0; i < 6396; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0xaa); }
static void sink_or_swim_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0xaaaa8914); for (i = 0; i < ti->len/4; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); }
static void alienbreed_protection_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x89248924); for (i = 0; i < 3; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); for (i = 0; i < 1000; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 32, 0); }
static void rtype_a_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x9521); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); csum = amigados_checksum(ti->dat, ti->len); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd, 32, csum); tbuf_bytes(tbuf, SPEED_AVG, bc_mfm_even_odd, ti->len, ti->dat); }
static void back_future3_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x552524a4); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x554a4945); for (i = 0; i < ti->len/4; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); }
static void interceptor_software_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0xa144); for (i = 0; i < 140; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); handlers[TRKTYP_amigados]->read_raw(d, tracknr, tbuf); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); for (i = 0; i < 460; i++) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0xa145); }
static void core_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum = 0, *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x8915); for (i = 0; i < ti->len/4; i++) csum += be32toh(dat[i]); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, csum); for (i = 0; i < ti->len/4; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); }
static void firebird_b_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; unsigned int i; uint8_t *dat = (uint8_t *)ti->dat; if (ti->type == TRKTYP_quartz_a) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x89448944); else { tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x8944a92a); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x8944); } for (i = 0; i < ti->len; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 8, dat[i]); }
static void forgotten_worlds_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t *dat = (uint16_t *)ti->dat, csum; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, (uint16_t)tracknr); for (i = csum =0; i < ti->len/2; i++) { tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, be16toh(dat[i])); csum ^= be16toh(dat[i]); } tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, csum); }
static void federation_of_free_traders_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint8_t *dat = (uint8_t *)ti->dat; unsigned int i, j; for (i = 0; i < ti->nr_sectors; i++) { uint16_t csum = 0, w; /* header */ tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0xff); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, tracknr^1); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, i); /* data */ w = i; /* preceding data byte, so first clock bit is correct */ for (j = 0; j < ti->bytes_per_sector; j++) { w = (w << 8) | dat[j]; csum ^= (uint16_t)mfm_encode_word(w); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, dat[j]); } /* csum */ if (!is_valid_sector(ti, i)) csum = ~csum; /* bad checksum for an invalid sector */ tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, csum); /* gap */ for (j = 0; j < 13; j++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); dat += ti->bytes_per_sector; } }
static void discovery_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t sum, val, *dat = (uint16_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, dat[ti->len/2+2]); val = (ti->type == TRKTYP_sword_sodan) ? 0 : (ti->type == TRKTYP_hybris) ? 0 : dat[ti->len/2+2]; tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, val); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, dat[ti->len/2]); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, ti->len); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, dat[ti->len/2+1]); tbuf_bytes(tbuf, SPEED_AVG, bc_mfm_even_odd, ti->len, dat); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, 0xdead); sum = discovery_sum(be16toh(val), 0); sum = discovery_sum(be16toh(dat[ti->len/2]), sum); sum = discovery_sum(be16toh(ti->len), sum); sum = discovery_sum(be16toh(dat[ti->len/2+1]), sum); for (i = 0 ; i < ti->len/2; i++) sum = discovery_sum(dat[i], sum); sum = discovery_sum(be16toh(0xdead), sum); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, sum); }
static void night_hunter_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t csum, *dat = (uint16_t *)ti->dat, sync; unsigned int i; sync = (ti->type == TRKTYP_night_hunter_a) ? 0x4489 : 0x8944; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, sync); for (i = csum = 0; i < ti->len/2; i++) { tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, be16toh(dat[i])); csum += be16toh(dat[i]); } tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, csum); }
static void dugger_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t dat[7012/4]; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); dat[0] = htobe32(ti->len); dat[1] = htobe32(0x03e90100 | tracknr); memcpy(&dat[2], ti->dat, ti->len); for (i = 0; i < ti->len/4+2; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd_even, 32, be32toh(dat[i])); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_odd_even, 32, amigados_checksum(dat, i*4)); }
static void speedball_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum = 0, *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, 0xfefe); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, ID_THBB); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, ti->len); for (i = 0; i < ti->len/4; i++) csum ^= be32toh(dat[i]); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, csum); tbuf_bytes(tbuf, SPEED_AVG, bc_mfm_even_odd, ti->len, dat); }
static void rtype_b_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum, *dat = (uint32_t *)ti->dat; unsigned int i; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x9521); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); for (i = 0; i < ti->len/4; i++) tbuf_bytes(tbuf, SPEED_AVG, bc_mfm_even_odd, 4, &dat[i]); csum = amigados_checksum(dat, ti->len); csum &= 0x55555555u; csum |= 0xaaaaaaaau; tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, csum); }
static void psygnosis_c_track0_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t *dat = (uint16_t *)(ti->dat + 512*11); unsigned int i, ver, metablk_words; metablk_words = (ti->len - 512*11) / 2; ver = (metablk_words == V1_METABLK_WORDS) ? 1 : 2; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x428a); if (ver == 2) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, checksum(dat, metablk_words, ver)); for (i = 0; i < metablk_words; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, be16toh(dat[i])); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, 0); handlers[TRKTYP_amigados]->read_raw(d, tracknr, tbuf); }
static void psygnosis_a_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat; unsigned int dat_len = ti->len - 4; uint16_t sync; sync = be16toh(*(uint16_t *)&ti->dat[dat_len]); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, sync); sync = be16toh(*(uint16_t *)&ti->dat[dat_len+2]); if (sync) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, sync); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, (~0u << 8) | tracknr); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, amigados_checksum(dat, dat_len)); tbuf_bytes(tbuf, SPEED_AVG, bc_mfm_even_odd, dat_len, dat); }
static void sensible_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat, csum; unsigned int i, enc; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); csum = SOS_SIG + (tracknr ^ 1); for (i = 0; i < ti->len/4; i++) csum += be32toh(dat[i]); for (i = 0; i < 2; i++) { enc = (i == 0) ? bc_mfm_odd : bc_mfm_even; tbuf_bits(tbuf, SPEED_AVG, enc, 32, SOS_SIG); tbuf_bits(tbuf, SPEED_AVG, enc, 32, csum); tbuf_bits(tbuf, SPEED_AVG, enc, 32, tracknr^1); tbuf_bytes(tbuf, SPEED_AVG, enc, ti->len, dat); } }
static void psygnosis_b_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t *dat = (uint16_t *)ti->dat; unsigned int i, j; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, 0xf000); for (i = 0; i < 6; i++) { uint16_t csum = 0; for (j = 0; j < 512; j++) csum += be16toh(dat[j]); if (!is_valid_sector(ti, i)) csum = ~csum; /* bad checksum for an invalid sector */ tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, csum); for (j = 0; j < 512; j++, dat++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, be16toh(*dat)); } }
static void sextett_protection_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = (uint32_t *)ti->dat; unsigned int i; if (tracknr == 158) { /* Disk 1: Key track */ tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x92459245); tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, be32toh(*dat)); } else if (tracknr == 159) { /* Disk 1: Sync track */ tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x92459245); } else if (d->di->track[158].type == TRKTYP_sextett_protection) { /* Disk 1: Landing track */ for (i = 0; i < ti->total_bits/16; i++) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x9245); } else { /* Disk 2: Pattern track */ for (i = 0; i < ti->total_bits/8-1; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 4, 0xa); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 4, 0x9); /* discontinuity */ } }
static void skaermtrolden_hugo_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum, *dat = (uint32_t *)ti->dat; unsigned int i; struct disktag_disk_nr *disktag_disk_nr = (struct disktag_disk_nr *) disk_get_tag_by_id(d, DSKTAG_disk_nr); for (i = csum = 0; i < 5940/4; i++) csum += be32toh(dat[i]); /* NB. Second 4489 sync word modified to 448a to avoid sync issue above. */ tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, (tracknr & 1) ? 0x89448944 : 0x4489448a); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, csum); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, disktag_disk_nr->disk_nr); tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, (tracknr<<16) | tracknr); for (i = 0; i < 5940/4; i++) tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); }
static void arc_development_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum, *dat = (uint32_t *)ti->dat; unsigned int i, sec, base; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489); if (ti->type == TRKTYP_arc_development_b) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, 0); for (sec = base = 0; sec < ti->nr_sectors; sec++) { for (i = csum = 0; i < 512/4; i++) { tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i+base])); csum ^= (uint16_t)be32toh(dat[i+base]); } base += 512/4; tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, csum); } }
static void hellwig_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint32_t csum, *dat = (uint32_t *)ti->dat; enum checksum_type checksum_type = ti->dat[ti->len-1] & 0xf; unsigned int i, nr_sync = ti->dat[ti->len-1] >> 4; while (nr_sync--) tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, 0x4489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0); for (i = csum = 0; i < ti->bytes_per_sector/4; i++) { tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, be32toh(dat[i])); csum += be32toh(dat[i]); } tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 32, (checksum_type == CSUM_zeroes) ? 0x00000000 : (checksum_type == CSUM_ones) ? 0xffffffff : csum); }
static void phantom_fighter_read_raw( struct disk *d, unsigned int tracknr, struct tbuf *tbuf) { struct track_info *ti = &d->di->track[tracknr]; uint16_t csum, *dat = (uint16_t *)ti->dat; unsigned int i, j; tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x44894489); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 8, 0xff); for (i = csum = 0; i < ti->len/2; i++) csum += be16toh(dat[i]); for (j = 0; j < 2; j++) { unsigned int type = j ? bc_mfm_odd : bc_mfm_even; for (i = 0; i < 4; i++) { tbuf_bytes(tbuf, SPEED_AVG, type, 2 * ((i == 3) ? 0x2eb : 0x2ec), &dat[0x2ec*i]); if (i == 3) tbuf_bits(tbuf, SPEED_AVG, type, 16, csum); tbuf_bits(tbuf, SPEED_AVG, bc_mfm, 16, 0xffff); } } }