void C_Fdd::format_trd() { static const uint8_t lv[3][16] = { { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }, { 1,9,2,10,3,11,4,12,5,13,6,14,7,15,8,16 }, { 1,12,7,2,13,8,3,14,9,4,15,10,5,16,11,6 } }; newdisk(MAX_CYLS, 2); for (unsigned c = 0; c < cyls; c++) { for (unsigned side = 0; side < 2; side++) { t.seek(this, c, side, JUST_SEEK); t.s = 16; for (unsigned sn = 0; sn < 16; sn++) { unsigned s = lv[interleave][sn]; t.hdr[sn].n = s; t.hdr[sn].l = 1; t.hdr[sn].c = c; t.hdr[sn].s = 0; t.hdr[sn].c1 = t.hdr[sn].c2 = 0; t.hdr[sn].data = (uint8_t *)1; } t.format(); } } }
int FDD::read_fdi() { newdisk(snbuf[4], snbuf[6]); strncpy(dsc, (char*)snbuf + *(u16*)(snbuf+8), sizeof dsc); int res = 1; u8 *trk = snbuf + 0x0E + *(u16*)(snbuf+0x0C); u8 *dat = snbuf + *(u16*)(snbuf+0x0A); for (unsigned c = 0; c < snbuf[4]; c++) { for (unsigned s = 0; s < snbuf[6]; s++) { t.seek(this, c,s, JUST_SEEK); u8 *t0 = dat + *(unsigned*)trk; unsigned ns = trk[6]; trk += 7; for (unsigned sec = 0; sec < ns; sec++) { *(unsigned*)&t.hdr[sec] = *(unsigned*)trk; t.hdr[sec].c1 = 0; if (trk[4] & 0x40) t.hdr[sec].data = 0; else { t.hdr[sec].data = t0 + *(u16*)(trk+5); if (t.hdr[sec].data+128 > snbuf+snapsize) return 0; t.hdr[sec].c2 = (trk[4] & (1<<(trk[3] & 3))) ? 0:2; // [vv] } /* [vv] if (t.hdr[sec].l>5) { t.hdr[sec].data = 0; if (!(trk[4] & 0x40)) res = 0; } */ trk += 7; } t.s = ns; t.format(); } } return res; }
void FDD::format_pro() { newdisk(80, 2); for(unsigned c = 0; c < cyls; c++) { for (unsigned h = 0; h < 2; h++) { t.seek(this, c, h, JUST_SEEK); t.s = 5; for(unsigned s = 0; s < 5; s++) { unsigned n = (c == 0 && h == 0) ? sn0[s] : sn[s]; t.hdr[s].n = n; t.hdr[s].l = 3; t.hdr[s].c = c; t.hdr[s].s = h; t.hdr[s].c1 = t.hdr[s].c2 = 0; t.hdr[s].data = (unsigned char*)1; } t.format(); } } }
int FDD::read_td0() { if (*(short*)snbuf == WORD2('t','d')) { // packed disk u8 *tmp = (u8*)malloc(snapsize); memcpy(tmp, snbuf+12, snapsize-12); snapsize = 12+unpack_lzh(tmp, snapsize-12, snbuf+12); ::free(tmp); //*(short*)snbuf = WORD2('T','D'); } char dscbuffer[sizeof(dsc)]; *dscbuffer = 0; u8 *start = snbuf+12; if (snbuf[7] & 0x80) // coment record { start += 10; unsigned len = *(u16*)(snbuf+14); start += len; if (len >= sizeof dsc) len = sizeof(dsc)-1; memcpy(dscbuffer, snbuf+12+10, len); dscbuffer[len] = 0; } u8 *td0_src = start; unsigned max_cyl = 0, max_head = 0; for (;;) { u8 s = *td0_src; // Sectors if (s == 0xFF) break; max_cyl = max(max_cyl, td0_src[1]); // PhysTrack max_head = max(max_head, td0_src[2]); // PhysSide td0_src += 4; // sizeof(track_rec) for (; s; s--) { u8 flags = td0_src[4]; td0_src += 6; // sizeof(sec_rec) assert(td0_src <= snbuf + snapsize); if (td0_src > snbuf + snapsize) return 0; td0_src += *(u16*)td0_src + 2; // data_len } } newdisk(max_cyl+1, max_head+1); memcpy(dsc, dscbuffer, sizeof dsc); td0_src = start; for (;;) { u8 t0[16384]; u8 *dst = t0; u8 *trkh = td0_src; td0_src += 4; // sizeof(track_rec) if (*trkh == 0xFF) break; t.seek(this, trkh[1], trkh[2], JUST_SEEK); unsigned s = 0; for (unsigned se = 0; se < trkh[0]; se++) { TTd0Sec *SecHdr = (TTd0Sec *)td0_src; unsigned sec_size = 128U << (SecHdr->n & 3); // [vv] u8 flags = SecHdr->flags; // printf("fl=%x\n", flags); // printf("c=%d, h=%d, s=%d, n=%d\n", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n); if (flags & (TD0_SEC_NO_ID | TD0_SEC_NO_DATA | TD0_SEC_NO_DATA2)) // skip sectors with no data & sectors without headers { td0_src += sizeof(TTd0Sec); // sizeof(sec_rec) unsigned src_size = *(u16*)td0_src; // printf("sz=%d\n", src_size); td0_src += 2; // data_len u8 *end_packed_data = td0_src + src_size; /* u8 method = *td0_src++; printf("m=%d\n", method); switch(method) { case 0: { char name[MAX_PATH]; sprintf(name, "%02d-%d-%03d-%d.trk", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n); FILE *f = fopen(name, "wb"); fwrite(td0_src, 1, src_size - 1, f); fclose(f); break; } case 1: { unsigned n = *(u16*)td0_src; td0_src += 2; u16 data = *(u16*)td0_src; printf("len=%d, data=%04X\n", n, data); break; } } */ td0_src = end_packed_data; continue; } // c, h, s, n t.hdr[s].c = SecHdr->c; t.hdr[s].s = SecHdr->h; t.hdr[s].n = SecHdr->s; t.hdr[s].l = SecHdr->n; t.hdr[s].c1 = t.hdr[s].c2 = 0; t.hdr[s].data = dst; td0_src += sizeof(TTd0Sec); // sizeof(sec_rec) unsigned src_size = *(u16*)td0_src; td0_src += 2; // data_len u8 *end_packed_data = td0_src + src_size; memset(dst, 0, sec_size); switch (*td0_src++) // Method { case 0: // raw sector memcpy(dst, td0_src, src_size-1); break; case 1: // repeated 2-byte pattern { unsigned n = *(u16*)td0_src; td0_src += 2; u16 data = *(u16*)td0_src; for (unsigned i = 0; i < n; i++) *(u16*)(dst+2*i) = data; break; } case 2: // RLE block { u16 data; u8 s; u8 *d0 = dst; do { switch (*td0_src++) { case 0: // Zero count means a literal data block for (s = *td0_src++; s; s--) *dst++ = *td0_src++; break; case 1: // repeated fragment s = *td0_src++; data = *(u16*)td0_src; td0_src += 2; for ( ; s; s--) { *(u16*)dst = data; dst += 2; } break; default: goto shit; } } while (td0_src < end_packed_data); dst = d0; break; } default: // error! shit: errexit("bad TD0 file"); } dst += sec_size; td0_src = end_packed_data; s++; } t.s = s; t.format(); } return 1; }