static void *skaermtrolden_hugo_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; struct disktag_disk_nr *disktag_disk_nr = (struct disktag_disk_nr *) disk_get_tag_by_id(d, DSKTAG_disk_nr); while (stream_next_bit(s) != -1) { uint32_t csum, sum, disk, trk, raw[5940/2]; unsigned int i; char *block; int bad_original_sync; /* Accept our own rewritten second sync word (4489 -> 448a). */ if ((s->word&~3) != ((tracknr & 1) ? 0x89448944 : 0x44894488)) continue; bad_original_sync = (s->word == 0x44894489); ti->data_bitoff = s->index_offset - 31; if (stream_next_bytes(s, raw, 24) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, &raw[0], &csum); csum = be32toh(csum); mfm_decode_bytes(bc_mfm_even_odd, 4, &raw[2], &disk); disk = be32toh(disk); mfm_decode_bytes(bc_mfm_even_odd, 4, &raw[4], &trk); trk = be32toh(trk); if (!disktag_disk_nr) disktag_disk_nr = (struct disktag_disk_nr *) disk_set_tag(d, DSKTAG_disk_nr, 4, &disk); if (disk != disktag_disk_nr->disk_nr) continue; if (trk != ((tracknr<<16) | tracknr)) continue; if (stream_next_bytes(s, raw, sizeof(raw)) == -1) goto fail; for (i = sum = 0; i < 5940/4; i++) { mfm_decode_bytes(bc_mfm_even_odd, 4, &raw[2*i], &raw[i]); sum += be32toh(raw[i]); } /* See header comment for why we accept incorrect checksum MSB. */ if ((sum != csum) && !(bad_original_sync && (sum == (csum & 0x7fffffff)))) continue; block = memalloc(ti->len); memcpy(block, raw, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *hellwig_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[ti->bytes_per_sector/4], csum, sum; enum checksum_type checksum_type; unsigned int i, two_sync; char *block; if ((uint16_t)s->word != 0x4489) continue; ti->data_bitoff = s->index_offset_bc - 15; if (stream_next_bits(s, 16) == -1) goto fail; two_sync = (s->word == 0x44894489); if (two_sync && (stream_next_bits(s, 16) == -1)) goto fail; if (s->word != 0x44892aaa) continue; for (i = sum = 0; i < ARRAY_SIZE(dat); i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &dat[i]); sum += be32toh(dat[i]); } if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &csum); csum = be32toh(csum); if (csum == 0) { checksum_type = CSUM_zeroes; } else if (csum == 0xffffffff) { checksum_type = CSUM_ones; } else { checksum_type = CSUM_data; if (csum != sum) continue; } ti->len += 1; block = memalloc(ti->len); memcpy(block, dat, ti->len-1); block[ti->len-1] = checksum_type | ((two_sync?2:1) << 4); ti->total_bits = 102000; set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *speedball_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t dat[10000], track_len, csum; uint32_t idx_off = s->index_offset_bc - 31; unsigned int i; void *block; if (s->word != 0x44894489) continue; if (stream_next_bits(s, 32) == -1) goto fail; if (mfm_decode_word(s->word) != 0xfefe) continue; if (stream_next_bytes(s, dat, 3*8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, &dat[0], &dat[0]); if (be32toh(dat[0]) != ID_THBB) continue; mfm_decode_bytes(bc_mfm_even_odd, 4, &dat[2], &dat[2]); track_len = be32toh(dat[2]); if (track_len != 5952) /* track length is always 5952 */ continue; mfm_decode_bytes(bc_mfm_even_odd, 4, &dat[4], &dat[4]); csum = be32toh(dat[4]); if (stream_next_bytes(s, dat, track_len*2) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, track_len, dat, dat); for (i = 0; i < track_len / 4; i++) csum ^= be32toh(dat[i]); if (csum != 0) continue; ti->data_bitoff = idx_off; set_all_sectors_valid(ti); ti->bytes_per_sector = ti->len = track_len; block = memalloc(ti->len); memcpy(block, dat, ti->len); return block; } fail: return NULL; }
static void *firebird_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint16_t *block = memalloc(ti->len); while (stream_next_bit(s) != -1) { uint32_t idx_off = s->index_offset_bc - 31; uint8_t dat[2*(ti->len+2)]; if (s->word != 0x89448944) continue; stream_start_crc(s); if (stream_next_bits(s, 16) == -1) goto fail; if (s->word != 0x89448944) continue; if (ti->type == TRKTYP_firebird) { if (stream_next_bits(s, 16) == -1) goto fail; if (mfm_decode_word((uint16_t)s->word) != 0xff) continue; } else if (ti->type == TRKTYP_afterburner_data) { if (stream_next_bytes(s, dat, 6) == -1) goto fail; mfm_decode_bytes(bc_mfm, 3, dat, dat); if ((dat[0] != 0x41) || (dat[1] != 0x42) || (dat[2] != (tracknr/2))) continue; } if (stream_next_bytes(s, dat, sizeof(dat)) == -1) goto fail; if (s->crc16_ccitt != 0) continue; mfm_decode_bytes(bc_mfm, ti->len, dat, block); ti->data_bitoff = idx_off; if (ti->type == TRKTYP_ikplus) ti->data_bitoff -= 2*16; /* IK+ has a pre-sync header */ set_all_sectors_valid(ti); return block; } fail: free(block); return NULL; }
static void *bat_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t csum, dat[0x629*2]; unsigned int i; char *block; if ((uint16_t)s->word != 0x8945) continue; ti->data_bitoff = s->index_offset_bc - 15; if (stream_next_bytes(s, dat, sizeof(dat)) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, sizeof(dat)/2, dat, dat); csum = tracknr ^ 1; for (i = 0; i < 0x628; i++) csum += be32toh(dat[i]); if (csum != be32toh(dat[0x628])) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 105500; return block; } return NULL; }
static void *sink_or_swim_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[ti->len/4]; unsigned int i; char *block; if (s->word != 0xaaaa8914) continue; ti->data_bitoff = s->index_offset_bc - 31; for (i = 0; i < ti->len/4; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &dat[i]); } block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *rtype_b_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { unsigned int i; uint32_t raw_dat[2*ti->len/4]; uint32_t csum = 0; char *block; if ((uint16_t)s->word != 0x9521) continue; ti->data_bitoff = s->index_offset - 15; if (stream_next_bits(s, 16) == -1) goto fail; if (mfm_decode_bits(bc_mfm, (uint16_t)s->word) != 0) continue; if (stream_next_bytes(s, raw_dat, 2*ti->len) == -1) goto fail; for (i = 0; i < ti->len/4; i++) mfm_decode_bytes(bc_mfm_even_odd, 4, &raw_dat[2*i], &raw_dat[i]); csum = amigados_checksum(raw_dat, ti->len); csum &= 0x55555555u; csum |= 0xaaaaaaaau; if (stream_next_bytes(s, &raw_dat[ti->len/4], 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, &raw_dat[ti->len/4], &raw_dat[ti->len/4]); if (csum != be32toh(raw_dat[ti->len/4])) continue; block = memalloc(ti->len); memcpy(block, raw_dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 105500; return block; } fail: return NULL; }
static void *forgotten_worlds_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint16_t raw[2], dat[ti->len/2], trk, sum, csum; unsigned int i; char *block; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset_bc - 31; if (stream_next_bytes(s, raw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &trk); if(tracknr != be16toh(trk)) continue; for (i = sum = 0; i < ARRAY_SIZE(dat); i++) { if (stream_next_bytes(s, raw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &dat[i]); sum ^= be16toh(dat[i]); } if (stream_next_bytes(s, raw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &csum); if(sum != be16toh(csum)) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 100500; return block; } fail: return NULL; }
static void *psygnosis_b_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; char *block = memalloc(ti->len); unsigned int j, k, nr_valid_blocks = 0; while ((stream_next_bit(s) != -1) && (nr_valid_blocks != ti->nr_sectors)) { uint16_t raw_dat[6*513]; uint32_t idx_off, new_valid = 0; if ((uint16_t)s->word != 0x4489) continue; idx_off = s->index_offset_bc - 15; if (stream_next_bits(s, 32) == -1) goto done; if (s->word != 0x552aaaaa) continue; for (j = 0; j < sizeof(raw_dat)/2; j++) { uint32_t dat; if (stream_next_bytes(s, &dat, 4) == -1) goto done; mfm_decode_bytes(bc_mfm_even_odd, 2, &dat, &raw_dat[j]); } for (j = 0; j < 6; j++) { uint16_t *sec = &raw_dat[j*513]; uint16_t csum = be16toh(*sec++), c = 0; for (k = 0; k < 512; k++) c += be16toh(sec[k]); if ((c == csum) && !is_valid_sector(ti, j)) { memcpy(&block[j*1024], sec, 1024); set_sector_valid(ti, j); nr_valid_blocks++; new_valid++; } } if (new_valid) ti->data_bitoff = idx_off; } done: if (nr_valid_blocks == 0) { free(block); return NULL; } return block; }
static void *dugger_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[7012/4]; unsigned int i; char *block; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset_bc - 31; if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 4, raw, &dat[0]); if ((ti->len = be32toh(dat[0])) > 7000) continue; for (i = 1; i < ti->len/4+3; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 4, raw, &dat[i]); } if ((be32toh(dat[1]) != (0x03e90100 | tracknr)) || (amigados_checksum(dat, i*4) != 0)) continue; ti->bytes_per_sector = ti->len; block = memalloc(ti->len); memcpy(block, &dat[2], ti->len); set_all_sectors_valid(ti); ti->total_bits = 105500; return block; } fail: return NULL; }
static void *night_hunter_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint16_t raw[2], dat[ti->len/2], sum, csum, sync; unsigned int i; char *block; sync = (ti->type == TRKTYP_night_hunter_a) ? 0x4489 : 0x8944; if ((uint16_t)s->word != sync) continue; ti->data_bitoff = s->index_offset - 15; for (i = sum = 0; i < ARRAY_SIZE(dat); i++) { if (stream_next_bytes(s, raw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &dat[i]); sum += be16toh(dat[i]); } if (stream_next_bytes(s, raw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &csum); if (csum != be16toh(sum)) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 100500; return block; } fail: return NULL; }
static void *psygnosis_c_track0_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint16_t dat[V1_METABLK_WORDS+1], raw[2]; char *ablk, *block; unsigned int i, metablk_words, ver; init_track_info(ti, TRKTYP_amigados); ablk = handlers[TRKTYP_amigados]->write_raw(d, tracknr, s); if ((ablk == NULL) || (ti->type != TRKTYP_amigados)) goto fail; for (ver = 1; ver <= 2; ver++) { stream_reset(s); metablk_words = (ver == 1) ? V1_METABLK_WORDS : V2_METABLK_WORDS; while (stream_next_bit(s) != -1) { if ((uint16_t)s->word != 0x428a) continue; ti->data_bitoff = s->index_offset - 15; if ((ver == 2) && ((stream_next_bits(s, 16) == -1) || ((uint16_t)s->word != 0xaaaa))) continue; for (i = 0; i < (metablk_words + 1); i++) { if (stream_next_bytes(s, raw, 4) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, 2, raw, &dat[i]); } if (checksum(&dat[1], metablk_words, ver) != be16toh(dat[0])) continue; init_track_info(ti, TRKTYP_psygnosis_c_track0); ti->len += metablk_words*2; ti->total_bits = 105500; block = memalloc(ti->len); memcpy(block, ablk, 512*11); memcpy(&block[512*11], &dat[1], metablk_words*2); memfree(ablk); return block; } } fail: memfree(ablk); return NULL; }
static void *core_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *block = memalloc(ti->len); while (stream_next_bit(s) != -1) { uint32_t raw[2], csum; unsigned int i; if ((uint16_t)s->word != 0x8915) continue; ti->data_bitoff = s->index_offset - 15; if (stream_next_bytes(s, raw, sizeof(raw)) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &csum); csum = be32toh(csum); for (i = 0; i < ti->len/4; i++) { if (stream_next_bytes(s, raw, sizeof(raw)) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &block[i]); csum -= be32toh(block[i]); } if (csum) continue; set_all_sectors_valid(ti); return block; } fail: free(block); return NULL; }
static void *puffys_saga_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint16_t dat[2*2818], csum; unsigned int i; char *block; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset - 31; for (i = 0; i < 30; i++) { if (stream_next_bits(s, 32) == -1) goto fail; if (mfm_decode_bits(bc_mfm, s->word)) break; } if (i != 30) continue; if (stream_next_bits(s, 16) == -1) goto fail; if ((uint16_t)s->word != 0x4444) continue; if (stream_next_bytes(s, dat, sizeof(dat)) == -1) goto fail; mfm_decode_bytes(bc_mfm, sizeof(dat)/2, dat, dat); csum = 0; for (i = 1; i < 2818; i++) csum += be16toh(dat[i]); if ((be16toh(dat[0]) != csum) || (be16toh(dat[1]) != (tracknr/2))) continue; block = memalloc(ti->len); memcpy(block, &dat[2], ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *back_future3_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[ti->len/4], sum; unsigned int i; char *block; if ((uint16_t)s->word != 0x4489) continue; ti->data_bitoff = s->index_offset - 15; if (stream_next_bits(s, 32) == -1) goto fail; if (s->word != 0x552524a4) continue; if (stream_next_bits(s, 32) == -1) goto fail; if (s->word != 0x554a4945) continue; for (i = sum = 0; i < ti->len/4; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &dat[i]); if ( i < ti->len/4 - 1) sum += be32toh(dat[i]); } /* Only verify the checksum on those tracks that are not * listed in the track_array*/ if (find_track(tracknr) == 0) if (sum != be32toh(dat[i-1])) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *firebird_b_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t sync; uint8_t raw[2], dat[ti->len], sum; unsigned int i; char *block; sync = (ti->type == TRKTYP_quartz_a) ? 0x89448944 : 0x8944a92a; if (s->word != sync) continue; if (ti->type == TRKTYP_quartz_b) { if (stream_next_bits(s, 16) == -1) goto fail; if ((uint16_t)s->word != 0x8944) continue; ti->data_bitoff = s->index_offset_bc - 47; } else ti->data_bitoff = s->index_offset_bc - 31; for (i = sum = 0; i < ti->len; i++) { if (stream_next_bytes(s, raw, 2) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 1, raw, &dat[i]); } if (dat[2] != tracknr/2) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 100500; return block; } fail: return NULL; }
static void *phantom_fighter_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint16_t dat[0x1760], csum; unsigned int i; char *block; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset_bc - 31; if (stream_next_bits(s, 16) == -1) goto fail; for (i = 0; i < 8; i++) { if (stream_next_bytes(s, &dat[0x2ec*i], 0x2ec*2) == -1) goto fail; if (stream_next_bits(s, 32) == -1) goto fail; } mfm_decode_bytes(bc_mfm_even_odd, 0x1760, dat, dat); for (i = csum = 0; i < ti->len/2; i++) csum += be16toh(dat[i]); if (csum != be16toh(dat[ti->len/2])) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *rtype_a_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint8_t raw_dat[2*ti->len]; uint32_t csum; char *block; if ((uint16_t)s->word != 0x9521) continue; ti->data_bitoff = s->index_offset - 15; if (stream_next_bits(s, 16) == -1) goto fail; if (mfm_decode_bits(bc_mfm, (uint16_t)s->word) != 0) continue; if (stream_next_bits(s, 32) == -1) goto fail; csum = mfm_decode_bits(bc_mfm_odd, s->word); if (stream_next_bytes(s, raw_dat, 2*ti->len) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, ti->len, raw_dat, raw_dat); if (amigados_checksum(raw_dat, ti->len) != csum) continue; block = memalloc(ti->len); memcpy(block, raw_dat, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *sensible_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; char *block; while (stream_next_bit(s) != -1) { uint32_t raw_dat[2*(12+ti->len)/4], csum = 0; unsigned int i; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset - 31; if (stream_next_bytes(s, raw_dat, sizeof(raw_dat)) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 12+ti->len, raw_dat, raw_dat); if ((be32toh(raw_dat[0]) != SOS_SIG) || ((uint8_t)be32toh(raw_dat[2]) != (tracknr^1))) continue; for (i = 0; i < ARRAY_SIZE(raw_dat)/2; i++) csum += be32toh(raw_dat[i]); csum -= be32toh(raw_dat[1]) * 2; if (csum != 0) continue; block = memalloc(ti->len); memcpy(block, &raw_dat[3], ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *alienbreed_protection_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *dat = memalloc(3 * sizeof(uint32_t)); uint32_t x[2]; unsigned int i; while (stream_next_bit(s) != -1) { if (s->word != 0x89248924) continue; ti->data_bitoff = s->index_offset - 31; /* Get the data longs. */ for (i = 0; i < 3; i++) { stream_next_bytes(s, x, sizeof(x)); mfm_decode_bytes(bc_mfm_even_odd, 4, x, &dat[i]); } /* Check for a long sequence of zeroes */ for (i = 0; i < 1000; i++) { stream_next_bits(s, 32); if (mfm_decode_bits(bc_mfm, s->word) != 0) break; } if (i == 1000) goto found; } memfree(dat); return NULL; found: ti->len = 3 * sizeof(uint32_t); return dat; }
static void *crystals_of_arborea_longtrack_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint32_t raw[2]; while (stream_next_bit(s) != -1) { ti->data_bitoff = s->index_offset_bc - 15; if (s->word != 0xaaaaa144) continue; stream_next_bytes(s, raw, 8); mfm_decode_bytes(bc_mfm, 4, raw, raw); if (be32toh(raw[0]) != 0x524f4430) /* "ROD0" */ continue; if (!check_sequence(s, 6500, 0x00)) continue; if (!check_length(s, 104128)) break; ti->total_bits = 110000; return memalloc(0); } return NULL; }
static void *ratt_dos_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; unsigned int max_longs = ti->bytes_per_sector / 4; uint16_t sync = 0x4522; if (tracknr != 2) { struct track_info *t2 = &d->di->track[2]; struct ratt_file *f = (struct ratt_file *)&t2->dat[0xbc]; if ((t2->type != TRKTYP_ratt_dos_1800) && (t2->type != TRKTYP_ratt_dos_1810)) return NULL; while (f->name[0] != '\0') { uint8_t last_trk = f->first_trk + f->nr_trks - 1; if ((f->first_trk <= 80) && (last_trk >= 80)) last_trk++; if ((f->first_trk <= tracknr) && (last_trk >= tracknr)) goto found; f++; } return NULL; found: sync = be16toh(((uint16_t *)t2->dat)[6+f->sync_idx]); } while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[0x604], header, csum, key, step; unsigned int i, nr_longs; char *block; if ((uint16_t)s->word != sync) continue; ti->data_bitoff = s->index_offset_bc - 15; if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 4, raw, raw); header = csum = ~be32toh(raw[0]); if ((nr_longs = (uint16_t)csum) == 0) nr_longs = max_longs; if (nr_longs > max_longs) return NULL; key = 0xeff478edu; step = 0xbffb7e5eu; for (i = 0; i < nr_longs; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 4, raw, &dat[i]); dat[i] = htobe32(be32toh(dat[i]) - key); key += step; csum += be32toh(dat[i]); } if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_odd_even, 4, raw, raw); csum += be32toh(raw[0]); if (csum != 0) continue; ti->len = ti->bytes_per_sector = nr_longs * 4 + 6; block = memalloc(ti->len); memcpy(block, dat, nr_longs * 4); *(uint32_t *)&block[nr_longs * 4] = htobe32(header); *(uint16_t *)&block[nr_longs * 4 + 4] = htobe16(sync); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *arc_development_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[12*512/4]; uint16_t csum, sum, craw[2]; unsigned int i, base; unsigned int sec; char *block; /* Both formats have at least one sync word. */ if ((uint16_t)s->word != 0x4489) continue; ti->data_bitoff = s->index_offset_bc - 15; if (s->word == 0x44894489) { /* Two sync words is format B. */ ti->type = TRKTYP_arc_development_b; ti->data_bitoff = s->index_offset_bc - 31; } else if (ti->type == TRKTYP_arc_development_b) { /* Format B must have two sync words. */ continue; } if (stream_next_bits(s, 32) == -1) goto fail; if (mfm_decode_bits(bc_mfm, s->word) != 0) continue; for (sec = base = 0; sec < ti->nr_sectors; sec++) { for (i = sum = 0; i < 512/4; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &dat[i+base]); sum ^= (uint16_t)be32toh(dat[i+base]); } base += 512/4; if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &csum); if (sum != be16toh(csum)) goto fail; } /* Some releases use long tracks (for no good reason). */ stream_next_index(s); ti->total_bits = (s->track_len_bc > 107000) ? 111000 : (s->track_len_bc > 102000) ? 105500 : 100000; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); return block; } fail: return NULL; }
static void *psygnosis_a_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; char *block; while (stream_next_bit(s) != -1) { uint32_t raw_dat[2*ti->len/4], hdr, csum; uint16_t sync = s->word; bool_t two_sync; if ((sync != 0x4489) && (sync != 0x4429)) continue; ti->data_bitoff = s->index_offset - 15; /* Check for second sync mark */ if (stream_next_bits(s, 16) == -1) goto fail; two_sync = ((uint16_t)s->word == sync); /* Read the track number and checksum. If there's no second sync mark, * the first 16 bits of the header info is already streamed. */ if (stream_next_bits(s, two_sync ? 32 : 16) == -1) goto fail; raw_dat[0] = htobe32(s->word); if (stream_next_bytes(s, &raw_dat[1], 12) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, &raw_dat[0], &hdr); mfm_decode_bytes(bc_mfm_even_odd, 4, &raw_dat[2], &csum); hdr = be32toh(hdr); csum = be32toh(csum); if (hdr != (0xffffff00u | tracknr)) continue; if (stream_next_bytes(s, raw_dat, sizeof(raw_dat)) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, ti->len, raw_dat, raw_dat); if (amigados_checksum(raw_dat, ti->len) != csum) continue; /* Some titles (Armourgeddon, Obitus...) mastered with long tracks. */ stream_next_index(s); if (s->track_bitlen > 103000) ti->total_bits = 105500; block = memalloc(ti->len + 4); *(uint16_t *)&block[ti->len] = htobe16(sync); *(uint16_t *)&block[ti->len+2] = two_sync ? htobe16(sync) : 0; memcpy(block, raw_dat, ti->len); set_all_sectors_valid(ti); ti->len += 4; /* for the sync marks */ return block; } fail: return NULL; }
static void *zoom_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; while (stream_next_bit(s) != -1) { uint32_t raw[2], dat[ti->len/4], csum; unsigned int i; char *block; if ((uint16_t)s->word != 0x4489) continue; /* Track 118 on the NTSC version only has * 2 sync words and the PAL version has * three.*/ if (s->word == 0xaaaa4489) { if (stream_next_bits(s, 16) == -1) goto fail; if ((uint16_t)s->word != 0x4489) continue; ti->data_bitoff = s->index_offset_bc - 31; if (ti->type == TRKTYP_zoom_b) { if (stream_next_bits(s, 16) == -1) goto fail; if ((uint16_t)s->word != 0x4489) continue; ti->data_bitoff = s->index_offset_bc - 47; } } else { if (stream_next_bits(s, 32) == -1) goto fail; if (s->word != 0x44894489) continue; ti->data_bitoff = s->index_offset_bc - 47; } for (i = 0; i < ti->len/4; i++) { if (stream_next_bytes(s, raw, 8) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 4, raw, &dat[i]); } if((uint8_t)(0xff&be32toh(dat[0])) != (uint8_t)~(tracknr^~1)) continue; csum = 0; for (i = csum = 0; i < ti->len/4 - 5; i++) csum ^= be32toh(dat[i+2]); if (csum != be32toh(dat[1])) continue; block = memalloc(ti->len); memcpy(block, dat, ti->len); set_all_sectors_valid(ti); ti->total_bits = 102300; return block; } fail: return NULL; }
static void *discovery_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint16_t sync, csum, sum, chk1, chk2, len1, len2;; uint16_t raw[2*ti->len/2], dat[(ti->len+6)/2], craw[2]; unsigned int i, k; char *block; for (k = 0; k < ARRAY_SIZE(syncs); k++) { sync = syncs[k]; while (stream_next_bit(s) != -1) { if ((uint16_t)s->word != sync) continue; ti->data_bitoff = s->index_offset_bc - 15; if (stream_next_bytes(s, craw, 4) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &sum); if (ti->type != TRKTYP_hybris && be16toh(sum) != sync) continue; if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &chk1); if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &len1); if (be16toh(len1) != (uint16_t)ti->len) continue; if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &len2); if (stream_next_bytes(s, raw, 2*ti->len) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, ti->len, raw, dat); if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &chk2); sum = discovery_sum(sum,0); sum = discovery_sum(chk1,sum); sum = discovery_sum(len1,sum); sum = discovery_sum(len2,sum); for (i = 0 ; i < ti->len/2; i++) sum = discovery_sum(dat[i], sum); sum = discovery_sum(chk2,sum); if (stream_next_bytes(s, craw, 4) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &csum); if (sum != be16toh(csum)) continue; /* No calculation for the data length and chk1 depends * on length in cases when the length is less than 0x1880. * dat is extended by 6 bytes. */ dat[ti->len/2] = be16toh(chk1); dat[ti->len/2+1] = be16toh(len2); dat[ti->len/2+2] = sync; stream_next_index(s); ti->total_bits = (s->track_len_bc > 102500) ? (s->track_len_bc > 104400) ? 108000 : 104300 : 102300; block = memalloc(ti->len+6); memcpy(block, dat, ti->len+6); set_all_sectors_valid(ti); return block; } stream_reset(s); } fail: return NULL; }