|
| 1 | +/* |
| 2 | + * intact.c |
| 3 | + * |
| 4 | + * Custom format as used on Intact by Sphinx Software / Grandslam. |
| 5 | + * |
| 6 | + * Written in 2021 by Keir Fraser |
| 7 | + */ |
| 8 | + |
| 9 | +#include <libdisk/util.h> |
| 10 | +#include <private/disk.h> |
| 11 | + |
| 12 | +static uint16_t syncword(unsigned int tracknr) |
| 13 | +{ |
| 14 | + if ((tracknr < 88) || (tracknr > 119)) |
| 15 | + return 0xc630; |
| 16 | + return (tracknr == 118) ? 0x4509 : 0x88c8; |
| 17 | +} |
| 18 | + |
| 19 | +static void *intact_write_raw( |
| 20 | + struct disk *d, unsigned int tracknr, struct stream *s) |
| 21 | +{ |
| 22 | + struct track_info *ti = &d->di->track[tracknr]; |
| 23 | + char *block; |
| 24 | + unsigned int i; |
| 25 | + uint16_t sync = syncword(tracknr); |
| 26 | + |
| 27 | + while (stream_next_bit(s) != -1) { |
| 28 | + |
| 29 | + uint32_t raw; |
| 30 | + uint16_t dat[0xbb9], csum; |
| 31 | + |
| 32 | + if (((uint16_t)s->word != sync) || ((s->word>>16) != 0xaaaa)) |
| 33 | + continue; |
| 34 | + |
| 35 | + ti->data_bitoff = s->index_offset_bc - 15; |
| 36 | + |
| 37 | + if (stream_next_bits(s, 32) == -1) |
| 38 | + goto fail; |
| 39 | + if (s->word != 0x88888888) |
| 40 | + continue; |
| 41 | + |
| 42 | + for (i = 0; i < ARRAY_SIZE(dat); i++) { |
| 43 | + if (stream_next_bits(s, 32) == -1) |
| 44 | + goto fail; |
| 45 | + raw = htobe32(s->word); |
| 46 | + mfm_decode_bytes(bc_mfm_even_odd, 2, &raw, &dat[i]); |
| 47 | + } |
| 48 | + |
| 49 | + csum = 0; |
| 50 | + for (i = 0; i < ARRAY_SIZE(dat)-1; i++) |
| 51 | + csum += be16toh(dat[i]); |
| 52 | + if (csum == be16toh(dat[i])) { |
| 53 | + block = memalloc(ti->len); |
| 54 | + memcpy(block, dat, ti->len); |
| 55 | + set_all_sectors_valid(ti); |
| 56 | + return block; |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | +fail: |
| 61 | + return NULL; |
| 62 | + |
| 63 | +} |
| 64 | + |
| 65 | +static void intact_read_raw( |
| 66 | + struct disk *d, unsigned int tracknr, struct tbuf *tbuf) |
| 67 | +{ |
| 68 | + struct track_info *ti = &d->di->track[tracknr]; |
| 69 | + uint16_t *dat = (uint16_t *)ti->dat, csum = 0; |
| 70 | + unsigned int i; |
| 71 | + |
| 72 | + tbuf_bits(tbuf, SPEED_AVG, bc_raw, 16, syncword(tracknr)); |
| 73 | + tbuf_bits(tbuf, SPEED_AVG, bc_raw, 32, 0x88888888); |
| 74 | + |
| 75 | + for (i = 0; i < ti->len/2; i++) { |
| 76 | + uint16_t x = be16toh(dat[i]); |
| 77 | + tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, x); |
| 78 | + csum += x; |
| 79 | + } |
| 80 | + |
| 81 | + tbuf_bits(tbuf, SPEED_AVG, bc_mfm_even_odd, 16, csum); |
| 82 | +} |
| 83 | + |
| 84 | +struct track_handler intact_handler = { |
| 85 | + .bytes_per_sector = 6000, |
| 86 | + .nr_sectors = 1, |
| 87 | + .write_raw = intact_write_raw, |
| 88 | + .read_raw = intact_read_raw |
| 89 | +}; |
| 90 | + |
| 91 | +/* |
| 92 | + * Local variables: |
| 93 | + * mode: C |
| 94 | + * c-file-style: "Linux" |
| 95 | + * c-basic-offset: 4 |
| 96 | + * tab-width: 4 |
| 97 | + * indent-tabs-mode: nil |
| 98 | + * End: |
| 99 | + */ |
0 commit comments