void stream_reset(struct stream *s) { /* Flux-based streams */ s->flux = 0; s->clocked_zeros = 0; s->clock = s->clock_centre; s->nr_index = 0; s->latency = 0; s->index_offset = ~0u>>1; /* bad */ s->type->reset(s); if (s->nr_index == 0) stream_next_index(s); }
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 *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; }
static int check_length(struct stream *s, unsigned int min_bits) { stream_next_index(s); return (s->track_len_bc >= min_bits); }
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; }