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; }
void stream_next_index(struct stream *s) { do { if (stream_next_bit(s) == -1) break; } while (s->index_offset != 0); }
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 *sextett_protection_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint32_t *block; /* Tracks 159 & 161: no data, all same data_bitoff (==0) */ if (tracknr == 159) { /* Track 159 is only a protection track on Disk 1. */ struct track_info *t158 = &d->di->track[158]; return (t158->type == TRKTYP_sextett_protection) ? memalloc(0) : NULL; } else if (tracknr == 161) { /* Track 161: Protection on all disks. */ ti->total_bits &= ~15; return memalloc(0); } /* Disk 1, Track 158: find the key */ while (stream_next_bit(s) != -1) { if (s->word != 0x92459245) continue; ti->data_bitoff = s->index_offset_bc - 31; if (stream_next_bits(s, 32) == -1) break; block = memalloc(4); *block = htobe32(s->word); return block; } return NULL; }
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; }
int stream_next_bits(struct stream *s, unsigned int bits) { unsigned int i; for (i = 0; i < bits; i++) if (stream_next_bit(s) == -1) return -1; return 0; }
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 *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 *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 *unformatted_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct disk_info *di = d->di; struct track_info *ti = &di->track[tracknr]; unsigned int scan_bits = 0, bad = 0, nr_zero = 0; unsigned int lat = s->latency, clk = 2000; unsigned int bad_sectors = 0, nr_sectors = 0; /* Scan for bit sequences that break the MFM encoding rules. * Random noise will obviously do this a *lot*. */ while (stream_next_bit(s) != -1) { if (s->word & 1) { unsigned int new_clk = (s->latency - lat) / (nr_zero + 1); int delta = new_clk - clk; if (delta < 0) delta = -delta; if (((delta*100)/clk) > CLOCK_JITTER_THRESH) bad++; clk = new_clk; lat = s->latency; if (!nr_zero) bad++; nr_zero = 0; } else if (++nr_zero > 3) { bad++; } if (++scan_bits >= SCAN_SECTOR_BITS) { if (bad >= SECTOR_BAD_THRESH) bad_sectors++; nr_sectors++; bad = scan_bits = 0; } } if (bad_sectors < nr_sectors) { unsigned int pc = (bad_sectors*1000)/nr_sectors; if ((pc/10) <= 90) return NULL; printf("*** T%u: Almost certainly unformatted/empty (%u.%u%%)\n", tracknr, pc/10, pc%10); } ti->total_bits = TRK_WEAK; return memalloc(0); /* dummy */ }
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 *gremlin_longtrack_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) { ti->data_bitoff = s->index_offset_bc - 31; if ((s->word != 0x41244124) || !check_sequence(s, 8, 0x00)) continue; if (ti->type != TRKTYP_tiertex_longtrack) ti->total_bits = 105500; return memalloc(0); } 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 *protec_longtrack_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) { ti->data_bitoff = s->index_offset_bc - 31; if ((s->word != 0x4454a525) || !check_sequence(s, 1000, 0x33)) continue; if (!check_length(s, 107200)) break; ti->total_bits = 110000; /* long enough */ return memalloc(0); } return NULL; }
static void *bat_longtrack_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) { ti->data_bitoff = s->index_offset_bc - 31; if ((s->word != 0xaaaa8945) || !check_sequence(s, 6826, 0x00)) continue; if (!check_length(s, 109500)) break; ti->total_bits = 110000; return memalloc(0); } 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 *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 *zoom_prot_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) { ti->data_bitoff = s->index_offset_bc - 15; if (!check_sequence(s, 1000, 0xaa)) continue; if (!check_length(s, 102000)) break; ti->total_bits = 102386; return memalloc(0); } return NULL; }
static void *interceptor_software_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; char *ablk; unsigned int i; init_track_info(ti, TRKTYP_amigados); ablk = handlers[TRKTYP_amigados]->write_raw(d, tracknr, s); if ((ablk == NULL) || (ti->type != TRKTYP_amigados)) goto fail; stream_reset(s); while (stream_next_bit(s) != -1) { /* Sync word 0xa144 precedes the AmigaDOS block by ~2000 bits. */ if ((uint16_t)s->word != 0xa144) continue; ti->data_bitoff = s->index_offset_bc - 15; /* Check for a decent-length zero sequence after the sync. */ for (i = 0; i < 32; i++) if ((stream_next_bits(s, 32) == -1) || mfm_decode_word(s->word)) break; if (i != 32) continue; /* Skip 104400 bits after the sync pattern. Check for 0xa145 * fill pattern, repeating. */ stream_next_bits(s, 104400-32*32); if (s->word != 0xa145a145) continue; init_track_info(ti, TRKTYP_interceptor_software); ti->total_bits = 105550; return ablk; } fail: memfree(ablk); return NULL; }
static void *infogrames_longtrack_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) { ti->data_bitoff = s->index_offset_bc - 15; if ((uint16_t)s->word != 0xa144) continue; if (!check_sequence(s, 6510, 0x00)) continue; if (!check_length(s, 104160)) break; ti->total_bits = 105500; return memalloc(0); } 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 *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 *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 *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 *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 *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; }