Subversion Repositories pentevo

Rev

Rev 883 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "fdd.h"
  6. #include "upd765.h"
  7.  
  8. #if 0
  9. #define dprintf printf
  10. #else
  11. #define dprintf(...)
  12. #endif
  13.  
  14. #pragma pack(push, 1)
  15. union TDiskInfo
  16. {
  17.     struct
  18.     {
  19.         char Sig[34];
  20.         char Name[14];
  21.         u8 c;
  22.         u8 h;
  23.         u16 TrackSize; // ╥юы№ъю фы  dsk (эх фы  edsk)
  24.         u8 TrackOffsets[]; // c * h, ╥юы№ъю фы  edsk
  25.     };
  26.     u8 Raw[256];
  27. };
  28.  
  29. #ifndef __ICL // icl 19 яюф win эх шьххЄ __builtin_offsetof
  30. static_assert(offsetof(TDiskInfo, TrackOffsets) == 0x34,"");
  31. #endif
  32.  
  33. struct TSecInfo
  34. {
  35.     u8 c;
  36.     u8 h;
  37.     u8 r;
  38.     u8 n; // sector size code
  39.     u8 St1;
  40.     u8 St2;
  41.     u16 DataLen; // ╥юы№ъю фы  edsk
  42. };
  43.  
  44. union  TTrackInfo
  45. {
  46.     struct
  47.     {
  48.         char Sig[13];
  49.         char Reserved[3];
  50.         u8 c;
  51.         u8 h;
  52.         char Reserved2[2];
  53.         u8 n; // sector size code
  54.         u8 NumSec;
  55.         u8 Gap3Len;
  56.         u8 Filler;
  57.         TSecInfo SecInfoList[];
  58.     };
  59.     u8 Raw[256];
  60. };
  61. #pragma pack(pop)
  62.  
  63. int FDD::read_dsk()
  64. {
  65.     dprintf("read_dsk\n");
  66.  
  67.     const auto DiskInfo{ (const TDiskInfo *)snbuf };
  68.  
  69.     auto IsExtended{ memcmp(DiskInfo->Sig, "EXTENDED", 8) == 0};
  70.     if(!IsExtended && memcmp(DiskInfo->Sig, "MV - CPC", 8) != 0)
  71.     {
  72.         return 0;
  73.     }
  74.  
  75.     newdisk(DiskInfo->c, DiskInfo->h);
  76.  
  77.     unsigned Offset{ sizeof(TDiskInfo) };
  78.     for(unsigned c = 0; c < DiskInfo->c; c++)
  79.     {
  80.         for(unsigned h = 0; h < DiskInfo->h; h++)
  81.         {
  82.             auto TrkSize{ IsExtended ? unsigned(DiskInfo->TrackOffsets[c*DiskInfo->h + h] << 8U) : DiskInfo->TrackSize };
  83.             if(TrkSize == 0)
  84.             {
  85.                 continue;
  86.             }
  87.             t.seek(this, c, h, JUST_SEEK);
  88.  
  89.             const auto TrackInfo{ (const TTrackInfo *)(snbuf + Offset) };
  90.             const auto SecDataStart{ snbuf + Offset + sizeof(TTrackInfo) };
  91.             auto SecData{ SecDataStart };
  92.             u8* PrevSecData{ };
  93.  
  94.             bool IsOverlappedSec = false; // Capitan Blood, License to kill
  95.             if(IsExtended)
  96.             {
  97.                 IsOverlappedSec = true;
  98.                 constexpr unsigned SecLen[]{ 128, 256, 512, 1024, 2048, 4096, 6144 };
  99.                 for(unsigned s = 0; s < min(size_t(TrackInfo->NumSec), _countof(SecLen)); s++)
  100.                 {
  101.                     const auto &SecInfo{ TrackInfo->SecInfoList[s] };
  102.                     if(SecLen[s] != SecInfo.DataLen)
  103.                     {
  104.                         IsOverlappedSec = false;
  105.                         break;
  106.                     }
  107.                 }
  108.             }
  109.  
  110.             for(unsigned s = 0; s < TrackInfo->NumSec; s++)
  111.             {
  112.                 const auto &SecInfo{ TrackInfo->SecInfoList[s] };
  113.                 auto SecInfoDataLen{ SecInfo.DataLen };
  114.                 t.hdr[s].c = SecInfo.c;
  115.                 t.hdr[s].s = SecInfo.h;
  116.                 t.hdr[s].n = SecInfo.r;
  117.                 t.hdr[s].l = SecInfo.n;
  118.                 t.hdr[s].c1 = 0;
  119.                 t.hdr[s].c2 = 0;
  120.                 t.hdr[s].wp = nullptr;
  121.                 t.hdr[s].data = SecData;
  122.  
  123.  
  124.                 t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  125.                 if(t.hdr[s].datlen == 0)
  126.                 {
  127.                     t.hdr[s].data = nullptr;
  128.                 }
  129.  
  130.                 // ╟р∙шЄ√ Єшяр ъръ т golden axe (яхЁт√щ ёхъЄюЁ эр ЄЁ¤ъх (ъюф 6, ЁрчьхЁ 8192)
  131.                 // яЁхт√°рхЄ ЁрчьхЁ ЄЁ¤ър, фры№°х шфєЄ юс√э√х ёхъЄюЁр)
  132.                 // ▌ЄюЄ яхЁт√щ ёхъЄюЁ ёюфхЁцшЄ яюыэє■ шэЇюЁьрЎш■ ю тёхщ фюЁюцъх (юёЄры№э√х ёхъЄюЁр ёЇюЁьшЁютрэ√ т чюэх фрээ√ї ¤Єюую ёхъЄюЁр)
  133.                 // ╥ръє■ фюЁюцъє эрфю ёЁрчє чруЁєцрЄ№ т udi ЇюЁьрЄх тюёёЄрэютшт ёшэїЁюшьяєы№ё√ яю срщЄрь A1A1A1 FE/FB
  134.                 // └ шэЇюЁьрЎш■ ю Ёрёъырфъх ш ЁрчьхЁрї ёхъЄюЁют тч Є№ шч юяшёрэш  т dsk (Єрь тё  шэЇюЁьрЎш  яЁюфєсышЁютрэр яю 2 Ёрчр)
  135.                 // ╤эрўрыр т сюы№°юь ёхъЄюЁх, р яюЄюь т ьрыхэ№ъшї ёхъЄюЁрї (ъюЄюЁ√х ЇръЄшўхёъш  ты ■Єё  ёё√ыърьш эр ъєёъш сюы№°юую)
  136. /*
  137.                 // ╩Ёштю ёэ Є√х юсЁрч√ ё чр∙шЄющ юЄ opera soft (эряЁшьхЁ mot)
  138.                 // ╧Ёртшы№эю ёэ Є√щ юсЁрч (corsarios + mutant zone)
  139.                 if(IsExtended && c == 40 && SecInfo.n == 8 && SecInfoDataLen == 0)
  140.                 {
  141.                     const auto &SecInfo{ TrackInfo->SecInfoList[s-1] };
  142.                     auto SecInfoDataLen{ SecInfo.DataLen };
  143.                     t.hdr[s].data = PrevSecData - 0x512;
  144.                     t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  145.                 }
  146. */
  147.                 if((SecInfo.St1 & TUpd765::ST1_DE)) // crc error in address or data
  148.                 {
  149.                     if((SecInfo.St2 & TUpd765::ST2_DD)) // crc error in data
  150.                     {
  151.                         t.hdr[s].c2 = 2;
  152.                         if(IsOverlappedSec)
  153.                         {
  154.                             t.hdr[s].data = nullptr;
  155.                         }
  156.                     }
  157.                     else
  158.                     {
  159.                         t.hdr[s].c1 = 2; // crc error in address
  160. //                    t.hdr[s].data = nullptr;
  161.                     }
  162.                 }
  163.  
  164.                 if(SecInfo.St2 & TUpd765::ST2_CM)
  165.                 {
  166.                     t.hdr[s].Flags = SECHDR::FL_DDAM;
  167.                 }
  168.                 else
  169.                 {
  170.                     t.hdr[s].Flags = 0;
  171.                 }
  172.                 PrevSecData = SecData;
  173.                 SecData += IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  174.             }
  175.             t.s = TrackInfo->NumSec;
  176.             t.format();
  177.             Offset += TrkSize;
  178.         }
  179.     }
  180.     return 1;
  181. }
  182.