static int check_sequence(struct stream *s, unsigned int nr, uint8_t byte) { while (--nr) { stream_next_bits(s, 16); if ((uint8_t)mfm_decode_bits(bc_mfm, s->word) != byte) break; } return !nr; }
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 *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; }
int stream_next_bit(struct stream *s) { int b; if (s->nr_index >= 5) return -1; s->index_offset++; if ((b = s->type->next_bit(s)) == -1) return -1; s->word = (s->word << 1) | b; if (++s->crc_bitoff == 16) { uint8_t b = mfm_decode_bits(bc_mfm, s->word); s->crc16_ccitt = crc16_ccitt(&b, 1, s->crc16_ccitt); s->crc_bitoff = 0; } return b; }
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 *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; }
void stream_start_crc(struct stream *s) { uint16_t x = htobe16(mfm_decode_bits(bc_mfm, s->word)); s->crc16_ccitt = crc16_ccitt(&x, 2, 0xffff); s->crc_bitoff = 0; }
static void *federation_of_free_traders_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint8_t *block = memalloc(ti->len); unsigned int i, nr_valid_blocks = 0, least_block = ~0u; while ((stream_next_bit(s) != -1) && (nr_valid_blocks != ti->nr_sectors)) { uint32_t idx_off = s->index_offset_bc - 31; uint16_t csum; uint8_t sec, *p; if (s->word != 0x44894489) continue; if (stream_next_bits(s, 32) == -1) goto done; if (mfm_decode_bits(bc_mfm, s->word) != (0xff00 | (tracknr^1))) continue; if (stream_next_bits(s, 16) == -1) goto done; sec = mfm_decode_bits(bc_mfm, (uint16_t)s->word); if ((sec >= ti->nr_sectors) || is_valid_sector(ti, sec)) continue; p = &block[sec * ti->bytes_per_sector]; for (i = csum = 0; i < ti->bytes_per_sector; i++) { if (stream_next_bits(s, 16) == -1) goto done; csum ^= (uint16_t)s->word; p[i] = mfm_decode_bits(bc_mfm, (uint16_t)s->word); } if (stream_next_bits(s, 32) == -1) goto done; if (csum != mfm_decode_bits(bc_mfm, s->word)) continue; set_sector_valid(ti, sec); nr_valid_blocks++; if (least_block > sec) { ti->data_bitoff = idx_off; least_block = sec; } } done: if (nr_valid_blocks == 0) { free(block); return NULL; } for (i = 0; i < ti->nr_sectors; i++) if (is_valid_sector(ti, i)) break; ti->data_bitoff -= i * 0xfc8; return block; }
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; }