Subversion Repositories pentevo

Rev

Rev 796 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "wd93crc.h"
  6.  
  7. #include "util.h"
  8.  
  9. void TRKCACHE::seek(FDD *d, unsigned cyl, unsigned side, SEEK_MODE fs)
  10. {
  11.    if ((d == drive) && (sf == fs) && (cyl == TRKCACHE::cyl) && (side == TRKCACHE::side))
  12.        return;
  13.  
  14.    drive = d; sf = fs; s = 0;
  15.    TRKCACHE::cyl = cyl; TRKCACHE::side = side;
  16.    if (cyl >= MAX_CYLS || side >= d->sides || !d->rawdata)
  17.    {
  18.        trkd = nullptr;
  19.        return;
  20.    }
  21.  
  22.    assert(cyl < MAX_CYLS);
  23.  
  24.    if(cyl >= d->cyls) // ╤ыєўрщ єтхышўхэш  ЁрчьхЁр фшёър яЁш ЇюЁьрЄшЁютрэшш фюяюыэшЄхы№э√ї фюЁюцхъ фю MAX_CYLS
  25.    {
  26.        if(fs != JUST_SEEK)
  27.        {
  28.            trkd = nullptr;
  29.            return;
  30.        }
  31.  
  32.        d->cyls = cyl + 1;
  33.    }
  34.  
  35.    trkd = d->trkd[cyl][side];
  36.    trki = d->trki[cyl][side];
  37.    trkwp = d->trkwp[cyl][side];
  38.    trklen = d->trklen[cyl][side];
  39.    if (!trklen)
  40.    {
  41.        trkd = nullptr;
  42.        return;
  43.    }
  44.  
  45.    ts_byte = Z80FQ / (trklen * FDD_RPS);
  46.    if (fs == JUST_SEEK)
  47.        return; // else find sectors
  48.  
  49.    for (unsigned i = 0; i < trklen - 8; i++)
  50.    {
  51.       if (trkd[i] != 0xA1 || trkd[i+1] != 0xFE || !test_i(i)) // ╧юшёъ idam
  52.           continue;
  53.  
  54.       if (s == MAX_SEC)
  55.           errexit("too many sectors");
  56.  
  57.       SECHDR *h = &hdr[s++]; // ╟ряюыэхэшх чруюыютър
  58.       h->id = trkd + i + 2; // ╙ърчрЄхы№ эр чруюыютюъ ёхъЄюЁр
  59.       h->c = h->id[0];
  60.       h->s = h->id[1];
  61.       h->n = h->id[2];
  62.       h->l = h->id[3];
  63.       h->crc = *(unsigned short*)(trkd+i+6);
  64.       h->c1 = (wd93_crc(trkd+i+1, 5) == h->crc);
  65.       h->data = nullptr;
  66.       h->datlen = 0;
  67.       h->wp_start = 0;
  68. //      if (h->l > 5) continue; [vv]
  69.  
  70.       unsigned end = min(trklen - 8, i + 8 + 43); // 43-DD, 30-SD
  71.  
  72.       // ╘юЁьшЁютрэшх єърчрЄхы  эр чюэє фрээ√ї ёхъЄюЁр
  73.       for (unsigned j = i + 8; j < end; j++)
  74.       {
  75.          if (trkd[j] != 0xA1 || !test_i(j) || test_i(j+1))
  76.              continue;
  77.  
  78.          if (trkd[j+1] == 0xF8 || trkd[j+1] == 0xFB) // ═рщфхэ data am
  79.          {
  80.             h->datlen = 128U << (h->l & 3); // [vv] FD1793 use only 2 lsb of sector size code
  81.             h->data = trkd + j + 2;
  82.             h->c2 = (wd93_crc(h->data-1, h->datlen+1) == *(unsigned short*)(h->data+h->datlen));
  83.  
  84.             if(trkwp)
  85.             {
  86.                 for(unsigned b = 0; b < h->datlen; b++)
  87.                 {
  88.                     if(test_wp(j + 2 + b))
  89.                     {
  90.                         h->wp_start = j + 2; // ┼ёЄ№ їюЄ с√ юфшэ ёсющэ√щ срщЄ
  91.                         break;
  92.                     }
  93.                 }
  94.             }
  95.          }
  96.          break;
  97.       }
  98.    }
  99. }
  100.  
  101. void TRKCACHE::format()
  102. {
  103.    if(!trkd) // ╥Ё¤ъ схч фрээ√ї (ЇюЁьрЄшЁютрэшх эх эєцэю)
  104.    {
  105.        return;
  106.    }
  107.    memset(trkd, 0, trklen);
  108.    memset(trki, 0, unsigned(trklen + 7U) >> 3);
  109.    memset(trkwp, 0, unsigned(trklen + 7U) >> 3);
  110.  
  111.    unsigned char *dst = trkd;
  112.  
  113.    unsigned i;
  114.  
  115.    //6250-6144=106
  116.    //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)
  117.    unsigned gap4a = 80;
  118.    unsigned sync0 = 12;
  119.    unsigned i_am = 3;
  120.    unsigned gap1 = 40;
  121.    unsigned sync1 = 12;
  122.    unsigned id_am = 3;
  123.    unsigned gap2 = 22;
  124.    unsigned sync2 = 12;
  125.    unsigned data_am = 3;
  126.  
  127.    unsigned data_sz = 0;
  128.    for (unsigned is = 0; is < s; is++)
  129.    {
  130.       SECHDR *sechdr = hdr + is;
  131.       data_sz += (128U << (sechdr->l & 3)); // n
  132.    }
  133.  
  134.    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)
  135.    { // ╧Ёхт√°хэшх ёЄрэфрЁЄэющ фышэ√ фюЁюцъш, ёюъЁр∙рхь ярЁрьхЄЁ√ фю ьшэшьры№э√ї
  136.        gap4a = 1;
  137.        sync0 = 1;
  138.        i_am = 1;
  139.        gap1 = 1;
  140.        sync1 = 1;
  141.        id_am = 1;
  142.        gap2 = 1;
  143.        sync2 = 1;
  144.        data_am = 1;
  145.    }
  146.  
  147.    memset(dst, 0x4E, gap4a); dst += gap4a; // gap4a
  148.    memset(dst, 0, sync0); dst += sync0; //sync
  149.  
  150.    for (i = 0; i < i_am; i++) // iam
  151.        write(unsigned(dst++ - trkd), 0xC2, 1);
  152.    *dst++ = 0xFC;
  153.  
  154.    for (unsigned is = 0; is < s; is++)
  155.    {
  156.       memset(dst, 0x4E, gap1); dst += gap1; // gap1 // 50 [vv] // fixme: recalculate gap1 only for non standard formats
  157.       memset(dst, 0, sync1); dst += sync1; //sync
  158.       for (i = 0; i < id_am; i++) // idam
  159.           write(unsigned(dst++ - trkd), 0xA1, 1);
  160.       *dst++ = 0xFE;
  161.  
  162.       SECHDR *sechdr = hdr + is;
  163.       *dst++ = sechdr->c; // c
  164.       *dst++ = sechdr->s; // h
  165.       *dst++ = sechdr->n; // s
  166.       *dst++ = sechdr->l; // n
  167.  
  168.       unsigned crc = wd93_crc(dst-5, 5); // crc
  169.       if (sechdr->c1 == 1)
  170.           crc = sechdr->crc;
  171.       if (sechdr->c1 == 2)
  172.           crc ^= 0xFFFF;
  173.       *(unsigned*)dst = crc;
  174.       dst += 2;
  175.  
  176.       if (sechdr->data)
  177.       {
  178.          memset(dst, 0x4E, gap2); dst += gap2; // gap2
  179.          memset(dst, 0, sync2); dst += sync2; //sync
  180.          for (i = 0; i < data_am; i++) // data am
  181.              write(unsigned(dst++ - trkd), 0xA1, 1);
  182.          *dst++ = 0xFB;
  183.  
  184. //         if (sechdr->l > 5) errexit("strange sector"); // [vv]
  185.          unsigned len = 128U << (sechdr->l & 3); // data
  186.          if (sechdr->data != (unsigned char*)1)
  187.          {
  188.              memcpy(dst, sechdr->data, len);
  189.              if(sechdr->wp) // ╩юяшЁютрэшх сшЄютющ ърЁЄ√ ёсющэ√ї срщЄют
  190.              {
  191.                  unsigned wp_start = unsigned(dst - trkd);
  192.                  sechdr->wp_start = wp_start;
  193.                  for(unsigned b = 0; b < len; b++)
  194.                  {
  195.                      if(test_bit(sechdr->wp, b))
  196.                      {
  197.                          set_wp(wp_start + b);
  198.                      }
  199.                  }
  200.              }
  201.          }
  202.          else
  203.              memset(dst, 0, len);
  204.  
  205.          crc = wd93_crc(dst-1, len+1); // crc
  206.          if (sechdr->c2 == 1)
  207.              crc = sechdr->crcd;
  208.          if (sechdr->c2 == 2)
  209.              crc ^= 0xFFFF;
  210.          *(unsigned*)(dst+len) = crc;
  211.              dst += len+2;
  212.       }
  213.    }
  214.    if (dst > trklen + trkd)
  215.    {
  216.        printf("cyl=%u, h=%u, additional len=%u\n", cyl, side, unsigned(dst - (trklen + trkd)));
  217.        errexit("track too long");
  218.    }
  219.    while (dst < trkd + trklen)
  220.        *dst++ = 0x4E;
  221. }
  222.  
  223. #if 1
  224. void TRKCACHE::dump()
  225. {
  226.    printf("\n%u/%u:", cyl, side);
  227.    if (!trkd) { printf("<e>"); return; }
  228.    if (!sf) { printf("<n>"); return; }
  229.    for (unsigned i = 0; i < s; i++)
  230.       printf("%c%02X-%02X-%02X-%02X,%c%c%c", i?' ':'<', hdr[i].c,hdr[i].s,hdr[i].n,hdr[i].l, hdr[i].c1?'+':'-', hdr[i].c2?'+':'-', hdr[i].data?'d':'h');
  231.    printf(">");
  232. }
  233. #endif
  234.  
  235. unsigned TRKCACHE::write_sector(unsigned sec, unsigned char *data)
  236. {
  237.    const SECHDR *h = get_sector(sec);
  238.    if (!h || !h->data)
  239.        return 0;
  240.    unsigned sz = h->datlen;
  241.    if(h->data != data)
  242.       memcpy(h->data, data, sz);
  243.    *(unsigned short*)(h->data+sz) = (unsigned short)wd93_crc(h->data-1, sz+1);
  244.    return sz;
  245. }
  246.  
  247. const SECHDR *TRKCACHE::get_sector(unsigned sec) const
  248. {
  249.    unsigned i;
  250.    for (i = 0; i < s; i++)
  251.    {
  252.       if (hdr[i].n == sec)
  253.           break;
  254.    }
  255.    if (i == s)
  256.        return nullptr;
  257.  
  258. //   dump();
  259.  
  260.    if (/*(hdr[i].l & 3) != 1 ||*/ hdr[i].c != cyl) // [vv]
  261.        return nullptr;
  262.    return &hdr[i];
  263. }
  264.  
  265.