int TRKCACHE::write_sector(unsigned sec, unsigned char *data) { const SECHDR *h = get_sector(sec); if (!h || !h->data) return 0; unsigned sz = h->datlen; if(h->data != data) memcpy(h->data, data, sz); *(unsigned short*)(h->data+sz) = (unsigned short)wd93_crc(h->data-1, sz+1); return sz; }
void editwm(unsigned addr, u8 byte) { if (editrm(addr) == byte) return; u8 *ptr = editam(addr); if (!ptr) return; *ptr = byte; if (editor == ED_MEM || editor == ED_CMOS || editor == ED_NVRAM) return; if (editor == ED_PHYS) { comp.wd.fdd[mem_disk].optype |= 2; return; } comp.wd.fdd[mem_disk].optype |= 1; // recalc sector checksum findsector(addr); *(u16*)(edited_track.hdr[sector].data + edited_track.hdr[sector].datlen) = wd93_crc(edited_track.hdr[sector].data - 1, edited_track.hdr[sector].datlen + 1); }
void TRKCACHE::seek(FDD *d, unsigned cyl, unsigned side, SEEK_MODE fs) { if ((d == drive) && (sf == fs) && (cyl == TRKCACHE::cyl) && (side == TRKCACHE::side)) return; drive = d; sf = fs; s = 0; TRKCACHE::cyl = cyl; TRKCACHE::side = side; if (cyl >= d->cyls || !d->rawdata) { trkd = 0; return; } assert(cyl < MAX_CYLS); trkd = d->trkd[cyl][side]; trki = d->trki[cyl][side]; trklen = d->trklen[cyl][side]; if (!trklen) { trkd = 0; return; } ts_byte = Z80FQ / (trklen * FDD_RPS); if (fs == JUST_SEEK) return; // else find sectors for (unsigned i = 0; i < trklen - 8; i++) { if (trkd[i] != 0xA1 || trkd[i+1] != 0xFE || !test_i(i)) // Поиск idam continue; if (s == MAX_SEC) errexit("too many sectors"); SECHDR *h = &hdr[s++]; // Заполнение заголовка h->id = trkd + i + 2; // Указатель на заголовок сектора h->c = h->id[0]; h->s = h->id[1]; h->n = h->id[2]; h->l = h->id[3]; h->crc = *(unsigned short*)(trkd+i+6); h->c1 = (wd93_crc(trkd+i+1, 5) == h->crc); h->data = 0; h->datlen = 0; // if (h->l > 5) continue; [vv] unsigned end = min(trklen - 8, i + 8 + 43); // 43-DD, 30-SD // Формирование указателя на зону данных сектора for (unsigned j = i + 8; j < end; j++) { if (trkd[j] != 0xA1 || !test_i(j) || test_i(j+1)) continue; if (trkd[j+1] == 0xF8 || trkd[j+1] == 0xFB) // Найден data am { h->datlen = 128 << (h->l & 3); // [vv] FD1793 use only 2 lsb of sector size code h->data = trkd + j + 2; h->c2 = (wd93_crc(h->data-1, h->datlen+1) == *(unsigned short*)(h->data+h->datlen)); } break; } } }
void TRKCACHE::format() { memset(trkd, 0, trklen); memset(trki, 0, trklen/8 + ((trklen&7) ? 1:0)); unsigned char *dst = trkd; unsigned i; //6250-6144=106 //gap4a(80)+sync0(12)+iam(3)+1+s*(gap1(50)+sync1(12)+idam(3)+1+4+2+gap2(22)+sync2(12)+data_am(3)+1+2) unsigned gap4a = 80; unsigned sync0 = 12; unsigned i_am = 3; unsigned gap1 = 40; unsigned sync1 = 12; unsigned id_am = 3; unsigned gap2 = 22; unsigned sync2 = 12; unsigned data_am = 3; unsigned data_sz = 0; for (unsigned is = 0; is < s; is++) { SECHDR *sechdr = hdr + is; data_sz += (128 << (sechdr->l & 3)); // n } if((gap4a+sync0+i_am+1+data_sz+s*(gap1+sync1+id_am+1+4+2+gap2+sync2+data_am+1+2)) >= MAX_TRACK_LEN) { // Превышение стандартной длины дорожки, сокращаем параметры до минимальных gap4a = 1; sync0 = 1; i_am = 1; gap1 = 1; sync1 = 1; id_am = 1; gap2 = 1; sync2 = 1; data_am = 1; } memset(dst, 0x4E, gap4a); dst += gap4a; // gap4a memset(dst, 0, sync0); dst += sync0; //sync for (i = 0; i < i_am; i++) // iam write(dst++ - trkd, 0xC2, 1); *dst++ = 0xFC; for (unsigned is = 0; is < s; is++) { memset(dst, 0x4E, gap1); dst += gap1; // gap1 // 50 [vv] // fixme: recalculate gap1 only for non standard formats memset(dst, 0, sync1); dst += sync1; //sync for (i = 0; i < id_am; i++) // idam write(dst++ - trkd, 0xA1, 1); *dst++ = 0xFE; SECHDR *sechdr = hdr + is; *dst++ = sechdr->c; // c *dst++ = sechdr->s; // h *dst++ = sechdr->n; // s *dst++ = sechdr->l; // n unsigned crc = wd93_crc(dst-5, 5); // crc if (sechdr->c1 == 1) crc = sechdr->crc; if (sechdr->c1 == 2) crc ^= 0xFFFF; *(unsigned*)dst = crc; dst += 2; if (sechdr->data) { memset(dst, 0x4E, gap2); dst += gap2; // gap2 memset(dst, 0, sync2); dst += sync2; //sync for (i = 0; i < data_am; i++) // data am write(dst++ - trkd, 0xA1, 1); *dst++ = 0xFB; // if (sechdr->l > 5) errexit("strange sector"); // [vv] unsigned len = 128 << (sechdr->l & 3); // data if (sechdr->data != (unsigned char*)1) memcpy(dst, sechdr->data, len); else memset(dst, 0, len); crc = wd93_crc(dst-1, len+1); // crc if (sechdr->c2 == 1) crc = sechdr->crcd; if (sechdr->c2 == 2) crc ^= 0xFFFF; *(unsigned*)(dst+len) = crc; dst += len+2; } } if (dst > trklen + trkd) { printf("additional len=%u\n", dst - (trklen + trkd)); errexit("track too long"); } while (dst < trkd + trklen) *dst++ = 0x4E; }